import json import shlex from tamq.cli import main from tamq.store import Store async def service_is_down(): return False def test_manual_send_inbox_and_ack_use_window_repository_identity(tmp_path, monkeypatch, capsys): monkeypatch.setenv("TAMQ_STATE_DIR", str(tmp_path / "state")) monkeypatch.setenv("TAMQ_REPO", "flex-auth") monkeypatch.setattr("tamq.cli.ping", service_is_down) monkeypatch.setattr("tamq.cli.validate_targets", lambda repos: None) assert main(["send", "tO:audit-core:", "review", "this"]) == 0 message_id = capsys.readouterr().out.strip() assert main(["inbox", "--repo", "audit-core", "--json"]) == 0 row = json.loads(capsys.readouterr().out) assert row["message_id"] == message_id assert row["sender_repo"] == "flex-auth" assert row["target_repo"] == "audit-core" assert row["body"] == "review this" assert row["provenance"] == "operator_input" assert main(["ack", message_id]) == 0 capsys.readouterr() assert main(["inbox", "--repo", "audit-core"]) == 0 assert capsys.readouterr().out == "" def test_inbox_requires_repository_outside_managed_window(tmp_path, monkeypatch, capsys): monkeypatch.setenv("TAMQ_STATE_DIR", str(tmp_path / "state")) monkeypatch.delenv("TAMQ_REPO", raising=False) assert main(["inbox"]) == 2 assert "requires --repo" in capsys.readouterr().err def test_human_inbox_uses_readable_origin_framing(tmp_path, monkeypatch, capsys): monkeypatch.setenv("TAMQ_STATE_DIR", str(tmp_path / "state")) monkeypatch.setattr("tamq.cli.validate_targets", lambda repos: None) store = Store(tmp_path / "state" / "tamq.sqlite3") store.add( "flex-auth", "audit-core", "first\nsecond\x1b[31m", provenance="operator_input", ) store.close() assert main(["inbox", "--repo", "audit-core"]) == 0 assert capsys.readouterr().out == ( "From:flex-auth/o: first\nFrom:flex-auth/o: second\\x1b[31m\n" ) def test_inbox_filter_logs_and_acknowledges_successful_messages(tmp_path, monkeypatch, capsys): monkeypatch.setenv("TAMQ_STATE_DIR", str(tmp_path / "state")) monkeypatch.setattr("tamq.cli.validate_targets", lambda repos: None) store = Store(tmp_path / "state" / "tamq.sqlite3") store.add("flex-auth", "audit-core", "review 'quoted' $value", provenance="operator_input") store.add("railiance-platform", "audit-core", "second", provenance="worker_output") store.close() log = tmp_path / "messages.log" assert main([ "inbox", "--repo", "audit-core", "--filter", f"cat >> {shlex.quote(str(log))}", ]) == 0 assert log.read_text(encoding="utf-8") == ( "From:flex-auth/o: review 'quoted' $value\n" "From:railiance-platform: second\n" ) assert main(["inbox", "--repo", "audit-core"]) == 0 assert capsys.readouterr().out == "" def test_failed_inbox_filter_leaves_current_and_later_messages_pending(tmp_path, monkeypatch, capsys): monkeypatch.setenv("TAMQ_STATE_DIR", str(tmp_path / "state")) monkeypatch.setattr("tamq.cli.validate_targets", lambda repos: None) store = Store(tmp_path / "state" / "tamq.sqlite3") first_id = store.add("a", "audit-core", "first") second_id = store.add("b", "audit-core", "second") store.close() assert main(["inbox", "--repo", "audit-core", "--filter", "false"]) == 1 assert first_id in capsys.readouterr().err assert main(["inbox", "--repo", "audit-core", "--json"]) == 0 rows = [json.loads(line) for line in capsys.readouterr().out.splitlines()] assert [row["message_id"] for row in rows] == [first_id, second_id] def test_inbox_filter_rejects_non_pending_and_json_modes(tmp_path, monkeypatch, capsys): monkeypatch.setenv("TAMQ_STATE_DIR", str(tmp_path / "state")) monkeypatch.setattr("tamq.cli.validate_targets", lambda repos: None) assert main(["inbox", "--repo", "audit-core", "--all", "--filter", "cat"]) == 2 assert "cannot be combined" in capsys.readouterr().err assert main(["inbox", "--repo", "audit-core", "--json", "--filter", "cat"]) == 2 assert "cannot be combined" in capsys.readouterr().err assert main(["inbox", "--repo", "audit-core", "--filter", " "]) == 2 assert "must not be empty" in capsys.readouterr().err