"""Tests for agent temp artifact detection and preflight warnings (#261).""" import json import os import sys import tempfile import unittest from unittest.mock import patch sys.path.insert(0, str(__import__("pathlib").Path(__file__).resolve().parent.parent)) import agent_temp_artifacts import mcp_server class TestAgentTempArtifactPatterns(unittest.TestCase): def test_detects_root_level_encode_emit_inline(self): porcelain = ( "?? _encode_commit_payload.py\n" "?? _emit_payload.py\n" "?? _inline_b64.py\n" ) self.assertEqual( agent_temp_artifacts.find_agent_temp_artifacts_from_porcelain(porcelain), ["_emit_payload.py", "_encode_commit_payload.py", "_inline_b64.py"], ) def test_ignores_nested_and_unrelated_untracked(self): porcelain = ( "?? scripts/_encode_x.py\n" "?? README-draft.md\n" " M task_capability_map.py\n" ) self.assertEqual( agent_temp_artifacts.find_agent_temp_artifacts_from_porcelain(porcelain), [], ) class TestPreflightWarnings(unittest.TestCase): def setUp(self): self._snapshot = ( mcp_server._preflight_whoami_called, mcp_server._preflight_capability_called, ) mcp_server._preflight_whoami_called = True mcp_server._preflight_capability_called = True def tearDown(self): mcp_server._preflight_whoami_called, mcp_server._preflight_capability_called = ( self._snapshot ) @patch( "mcp_server._get_workspace_porcelain", return_value="?? _encode_commit_payload.py\n", ) def test_assess_preflight_surfaces_warning_not_block(self, _porcelain): status = mcp_server.assess_preflight_status() self.assertTrue(status["preflight_ready"]) self.assertEqual(status["preflight_block_reasons"], []) self.assertEqual(len(status["preflight_warnings"]), 1) self.assertIn("_encode_commit_payload.py", status["preflight_warnings"][0]) # Issue-write tools are profile-gated (#69); gitea_lock_issue requires # gitea.issue.comment (see task_capability_map), so the gate must be # seeded exactly like tests/test_mcp_server.py::TestIssueLocking (#359). ISSUE_WRITE_ENV = { "GITEA_ALLOWED_OPERATIONS": ( "gitea.issue.create,gitea.issue.close,gitea.issue.comment" ), } class TestIssueLockArtifactWarning(unittest.TestCase): def setUp(self): self._lock_dir = tempfile.TemporaryDirectory() env = {**ISSUE_WRITE_ENV, "GITEA_ISSUE_LOCK_DIR": self._lock_dir.name} self._env_patcher = patch.dict(os.environ, env, clear=True) self._env_patcher.start() def tearDown(self): self._env_patcher.stop() self._lock_dir.cleanup() @patch( "mcp_server.issue_duplicate_context_fetcher", return_value=([], [], {"status": "not_claimed"}), ) @patch("mcp_server.api_get_all", return_value=[]) @patch("mcp_server._auth", return_value="token x") @patch("mcp_server._resolve", return_value=("h", "o", "r")) @patch("issue_lock_worktree.read_worktree_git_state") def test_lock_success_includes_artifact_warning(self, mock_state, *_mocks): mock_state.return_value = { "current_branch": "master", "porcelain_status": "?? _emit_payload.py\n", "base_equivalent": True, "inspected_git_root": "/scratch/wt", "base_branch": "origin/master", } result = mcp_server.gitea_lock_issue( issue_number=261, branch_name="docs/issue-261-agent-artifact-cleanup", remote="prgs", ) self.assertTrue(result["success"]) self.assertIn("warnings", result) self.assertIn("_emit_payload.py", result["warnings"][0]) if __name__ == "__main__": unittest.main()