from __future__ import annotations import json import tempfile import unittest from contextlib import redirect_stdout from io import StringIO from pathlib import Path from isphere_ai_bridge.cli import main from isphere_ai_bridge.draft_queue import DraftQueue from isphere_ai_bridge.models import Draft from isphere_ai_bridge.mock_db import create_mock_msglib class DraftQueueTests(unittest.TestCase): def test_append_drafts_writes_pending_queue_and_redacted_audit_event(self) -> None: with tempfile.TemporaryDirectory() as tmp: queue_path = Path(tmp) / "drafts.jsonl" audit_path = Path(tmp) / "audit.jsonl" queue = DraftQueue( queue_path=queue_path, audit_path=audit_path, clock=lambda: "2026-07-05T01:40:00+08:00", ) draft = Draft( message_id="msg-001", conversation_id="alice@example", draft_text="Draft only. Please review before sending.", source_message_ref="MsgLib.db#tblPersonMsg:msg-001", ) entries = queue.append_drafts([draft]) self.assertEqual(1, len(entries)) self.assertEqual("pending_review", entries[0]["status"]) self.assertEqual("msg-001", entries[0]["message_id"]) self.assertEqual("Draft only. Please review before sending.", entries[0]["draft_text"]) queue_lines = queue_path.read_text(encoding="utf-8").splitlines() self.assertEqual(1, len(queue_lines)) queue_record = json.loads(queue_lines[0]) self.assertEqual(entries[0]["draft_id"], queue_record["draft_id"]) self.assertEqual("pending_review", queue_record["status"]) audit_lines = audit_path.read_text(encoding="utf-8").splitlines() self.assertEqual(1, len(audit_lines)) audit_record = json.loads(audit_lines[0]) self.assertEqual("draft_created", audit_record["event_type"]) self.assertEqual(entries[0]["draft_id"], audit_record["draft_id"]) self.assertIn("content_sha256", audit_record) self.assertNotIn("draft_text", audit_record) def test_queue_drafts_cli_appends_drafts_and_audit_events(self) -> None: with tempfile.TemporaryDirectory() as tmp: root = Path(tmp) db_path = create_mock_msglib(root / "MsgLib.db") queue_path = root / "drafts.jsonl" audit_path = root / "audit.jsonl" stdout = StringIO() with redirect_stdout(stdout): exit_code = main( [ "queue-drafts", "--db", str(db_path), "--queue", str(queue_path), "--audit", str(audit_path), "--limit", "2", ] ) self.assertEqual(0, exit_code) output = json.loads(stdout.getvalue()) self.assertEqual(2, output["queued"]) self.assertEqual(2, len(queue_path.read_text(encoding="utf-8").splitlines())) audit_records = [ json.loads(line) for line in audit_path.read_text(encoding="utf-8").splitlines() ] self.assertEqual(2, len(audit_records)) self.assertNotIn("draft_text", audit_records[0]) if __name__ == "__main__": unittest.main()