diff --git a/tests/test_mcp_server.py b/tests/test_mcp_server.py index 328e749..044d76b 100644 --- a/tests/test_mcp_server.py +++ b/tests/test_mcp_server.py @@ -3158,6 +3158,12 @@ class TestPreflightVerification(unittest.TestCase): self.orig_whoami_violation = mcp_server._preflight_whoami_violation self.orig_capability_violation = mcp_server._preflight_capability_violation self.orig_resolved_role = mcp_server._preflight_resolved_role + self.orig_process_start = mcp_server._process_start_porcelain + self.orig_whoami_baseline = mcp_server._preflight_whoami_baseline_porcelain + self.orig_capability_baseline = mcp_server._preflight_capability_baseline_porcelain + self.orig_whoami_files = mcp_server._preflight_whoami_violation_files + self.orig_capability_files = mcp_server._preflight_capability_violation_files + self.orig_reviewer_files = mcp_server._preflight_reviewer_violation_files # Reset state for each test mcp_server._preflight_whoami_called = False @@ -3165,6 +3171,13 @@ class TestPreflightVerification(unittest.TestCase): mcp_server._preflight_whoami_violation = False mcp_server._preflight_capability_violation = False mcp_server._preflight_resolved_role = None + mcp_server._process_start_porcelain = "" + mcp_server._preflight_whoami_baseline_porcelain = None + mcp_server._preflight_capability_baseline_porcelain = None + mcp_server._preflight_whoami_violation_files = [] + mcp_server._preflight_capability_violation_files = [] + mcp_server._preflight_reviewer_violation_files = [] + os.environ["GITEA_TEST_PORCELAIN"] = "" def tearDown(self): # Restore real global variables @@ -3174,30 +3187,42 @@ class TestPreflightVerification(unittest.TestCase): mcp_server._preflight_whoami_violation = self.orig_whoami_violation mcp_server._preflight_capability_violation = self.orig_capability_violation mcp_server._preflight_resolved_role = self.orig_resolved_role - if "GITEA_TEST_FORCE_DIRTY" in os.environ: - del os.environ["GITEA_TEST_FORCE_DIRTY"] + mcp_server._process_start_porcelain = self.orig_process_start + mcp_server._preflight_whoami_baseline_porcelain = self.orig_whoami_baseline + mcp_server._preflight_capability_baseline_porcelain = self.orig_capability_baseline + mcp_server._preflight_whoami_violation_files = self.orig_whoami_files + mcp_server._preflight_capability_violation_files = self.orig_capability_files + mcp_server._preflight_reviewer_violation_files = self.orig_reviewer_files + for key in ("GITEA_TEST_FORCE_DIRTY", "GITEA_TEST_PORCELAIN"): + if key in os.environ: + del os.environ[key] def test_preflight_whoami_violation(self): import mcp_server os.environ["GITEA_TEST_FORCE_DIRTY"] = "1" - mcp_server._preflight_capability_called = True mcp_server.record_preflight_check("whoami") self.assertTrue(mcp_server._preflight_whoami_violation) + mcp_server.record_preflight_check("capability", resolved_role="author") with self.assertRaises(RuntimeError) as ctx: mcp_server.verify_preflight_purity() self.assertIn("Workspace file edits occurred before gitea_whoami verification", str(ctx.exception)) + self.assertIn("Offending files:", str(ctx.exception)) def test_preflight_capability_violation(self): import mcp_server + mcp_server.record_preflight_check("whoami") os.environ["GITEA_TEST_FORCE_DIRTY"] = "1" - mcp_server._preflight_whoami_called = True mcp_server.record_preflight_check("capability", resolved_role="author") self.assertTrue(mcp_server._preflight_capability_violation) with self.assertRaises(RuntimeError) as ctx: mcp_server.verify_preflight_purity() - self.assertIn("Workspace file edits occurred before gitea_resolve_task_capability verification", str(ctx.exception)) + self.assertIn( + "Workspace file edits occurred before gitea_resolve_task_capability verification", + str(ctx.exception), + ) + self.assertIn("Offending files:", str(ctx.exception)) def test_preflight_not_called_fails_closed(self): import mcp_server @@ -3213,16 +3238,16 @@ class TestPreflightVerification(unittest.TestCase): def test_preflight_reviewer_mutation_violation(self): import mcp_server - mcp_server._preflight_whoami_called = True - mcp_server._preflight_capability_called = True - mcp_server._preflight_resolved_role = "reviewer" + mcp_server.record_preflight_check("whoami") + mcp_server.record_preflight_check("capability", resolved_role="reviewer") - # When dirty, reviewer edits are blocked - os.environ["GITEA_TEST_FORCE_DIRTY"] = "1" + # Session-owned reviewer edits after capability are blocked. + os.environ["GITEA_TEST_PORCELAIN"] = " M reviewer_edit.py\n" with self.assertRaises(RuntimeError) as ctx: mcp_server.verify_preflight_purity() self.assertIn("Reviewer profile is forbidden from modifying tracked workspace files", str(ctx.exception)) + self.assertIn("reviewer_edit.py", str(ctx.exception)) - # When clean, reviewer is allowed - del os.environ["GITEA_TEST_FORCE_DIRTY"] + # Foreign pre-existing dirty state does not block when unchanged. + os.environ["GITEA_TEST_PORCELAIN"] = "" mcp_server.verify_preflight_purity()