from unittest.mock import patch import pytest from scripts.llm_triage import ( get_context, get_prompt, parse_llm_response, run_triage, ) # ── Mocks ────────────────────────────────────────────────────────────────── @pytest.fixture def mock_files(tmp_path): """Creates mock files for the triage script.""" (tmp_path / ".loop/retro").mkdir(parents=True) (tmp_path / "scripts").mkdir(parents=True) (tmp_path / ".loop/queue.json").write_text("[]") (tmp_path / ".loop/retro/summary.json").write_text("{}") (tmp_path / ".loop/retro/deep-triage.jsonl").write_text("") (tmp_path / "scripts/deep_triage_prompt.md").write_text("This is the prompt.") return tmp_path def test_get_prompt(mock_files): """Tests that the prompt is read correctly.""" with patch("scripts.llm_triage.PROMPT_PATH", mock_files / "scripts/deep_triage_prompt.md"): prompt = get_prompt() assert prompt == "This is the prompt." def test_get_context(mock_files): """Tests that the context is constructed correctly.""" with patch("scripts.llm_triage.QUEUE_PATH", mock_files / ".loop/queue.json"), \ patch("scripts.llm_triage.SUMMARY_PATH", mock_files / ".loop/retro/summary.json"), \ patch("scripts.llm_triage.RETRO_PATH", mock_files / ".loop/retro/deep-triage.jsonl"): context = get_context() assert "CURRENT QUEUE (.loop/queue.json):\\n[]" in context assert "CYCLE SUMMARY (.loop/retro/summary.json):\\n{}" in context assert "LAST DEEP TRIAGE RETRO:\\n" in context def test_parse_llm_response(): """Tests that the LLM's response is parsed correctly.""" response = '{"queue": [1, 2, 3], "retro": {"a": 1}}' queue, retro = parse_llm_response(response) assert queue == [1, 2, 3] assert retro == {"a": 1} @patch("scripts.llm_triage.get_llm_client") @patch("scripts.llm_triage.GiteaClient") def test_run_triage(mock_gitea_client, mock_llm_client, mock_files): """Tests the main triage logic.""" mock_llm_client.return_value.chat.return_value = { "message": { "content": '{"queue": [{"issue": 1}], "retro": {"issues_closed": [2], "issues_created": [{"title": "New Issue", "body": "This is a new issue."}]}}' } } with ( patch("scripts.llm_triage.PROMPT_PATH", mock_files / "scripts/deep_triage_prompt.md"), patch("scripts.llm_triage.QUEUE_PATH", mock_files / ".loop/queue.json"), patch("scripts.llm_triage.SUMMARY_PATH", mock_files / ".loop/retro/summary.json"), patch("scripts.llm_triage.RETRO_PATH", mock_files / ".loop/retro/deep-triage.jsonl"), ): run_triage() # Check that the queue and retro files were written assert (mock_files / ".loop/queue.json").read_text() == '[{"issue": 1}]' assert (mock_files / ".loop/retro/deep-triage.jsonl").read_text() == '{"issues_closed": [2], "issues_created": [{"title": "New Issue", "body": "This is a new issue."}]}\n' # Check that the Gitea client was called correctly mock_gitea_client.return_value.close_issue.assert_called_once_with(2) mock_gitea_client.return_value.create_issue.assert_called_once_with( "New Issue", "This is a new issue." )