"""Post-merge moot validation wording + label tests (#529, criteria 1/4/5).""" import unittest from post_merge_validation import ( BASELINE_ACCEPTED_OUTCOME, BLOCKED_OUTCOME, CLEAN_PASS_OUTCOME, LABEL_BASELINE_ACCEPTED, LABEL_BLOCKED, LABEL_CLEAN_PASS, LABEL_POST_MERGE_MOOT, POST_MERGE_MOOT_OUTCOME, assess_post_merge_validation, process_state_label, ) from final_report_validator import assess_final_report_validator from issue_workflow_labels import CANONICAL_LABELS, VALIDATION_LABELS _MOOT_PROOF = ( "Validation status: post-merge moot validation\n" "PR state: merged\n" "Merge commit sha: 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b\n" "Validation finding: full suite passed, for the record.\n" ) class TestPostMergeValidation(unittest.TestCase): def test_not_applicable_when_no_merged_or_moot_signal(self): result = assess_post_merge_validation( "Review decision: approve. Validation: full suite passed." ) self.assertFalse(result["block"]) self.assertTrue(result["skipped"]) def test_active_approval_on_merged_pr_blocked(self): report = ( "PR is already merged. Review decision: approve. " "Validation: full suite passed." ) result = assess_post_merge_validation(report) self.assertTrue(result["block"]) self.assertEqual(result["outcome"], POST_MERGE_MOOT_OUTCOME) self.assertEqual(result["process_state_label"], LABEL_POST_MERGE_MOOT) def test_active_approval_on_merged_pr_via_structured_signal_blocked(self): report = "Review decision: approve. Validation: full suite passed." result = assess_post_merge_validation(report, pr_merged_or_closed=True) self.assertTrue(result["block"]) def test_moot_wording_without_proof_blocked(self): report = "Recording post-merge moot validation for this PR." result = assess_post_merge_validation(report) self.assertTrue(result["block"]) self.assertTrue(result["reasons"]) def test_moot_wording_with_full_proof_allowed(self): result = assess_post_merge_validation(_MOOT_PROOF) self.assertFalse(result["block"]) self.assertEqual(result["outcome"], POST_MERGE_MOOT_OUTCOME) def test_merged_signal_only_guides_without_blocking(self): result = assess_post_merge_validation( "PR was already merged before review; recording findings." ) self.assertFalse(result["block"]) self.assertTrue(result["safe_next_action"]) def test_process_state_label_mapping(self): self.assertEqual(process_state_label(CLEAN_PASS_OUTCOME), LABEL_CLEAN_PASS) self.assertEqual( process_state_label(BASELINE_ACCEPTED_OUTCOME), LABEL_BASELINE_ACCEPTED ) self.assertEqual(process_state_label(BLOCKED_OUTCOME), LABEL_BLOCKED) self.assertEqual( process_state_label(POST_MERGE_MOOT_OUTCOME), LABEL_POST_MERGE_MOOT ) self.assertIsNone(process_state_label("nonsense")) class TestValidationLabelsRegistered(unittest.TestCase): def test_validation_labels_are_canonical(self): for label in ( LABEL_CLEAN_PASS, LABEL_BASELINE_ACCEPTED, LABEL_BLOCKED, LABEL_POST_MERGE_MOOT, ): self.assertIn(label, VALIDATION_LABELS) self.assertIn(label, CANONICAL_LABELS) class TestPostMergeValidationWiredIntoReview(unittest.TestCase): def test_review_pr_blocks_active_approval_on_merged_pr(self): report = ( "PR is already merged. Review decision: approve. " "Validation: full suite passed." ) result = assess_final_report_validator(report, "review_pr") self.assertTrue(result["blocked"]) self.assertTrue( any( f["rule_id"] == "reviewer.post_merge_validation" for f in result["findings"] ) ) def test_review_pr_allows_proven_post_merge_moot(self): result = assess_final_report_validator(_MOOT_PROOF, "review_pr") self.assertFalse( any( f["rule_id"] == "reviewer.post_merge_validation" for f in result["findings"] ) ) if __name__ == "__main__": unittest.main()