import pathlib import sys import unittest from typing import Optional, Sequence, final ROOT = pathlib.Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT)) from issues import find_candidate, issue_key, key_markers, occurrence_markers, plan_issue, render_new_issue from model import Issue, Occurrence def occurrence(fingerprint: str = "a" * 64, when: str = "2026-08-02T00:00:00Z", name: str = "case") -> Occurrence: return Occurrence("owner/repo", ".github/workflows/unit-test.yml", "Unit", 7, 2, "https://github.com/owner/repo/actions/runs/7", when, "pkg::tests", name, frozenset(("workflow rerun",)), fingerprint) def issue(number: int = 1, state: str = "open", body: str = "", comments: Sequence[str] = (), closed_at: Optional[str] = None, labels: Sequence[str] = ()) -> Issue: return Issue(number, state, body, tuple(comments), closed_at, tuple(labels)) def generated_body(fingerprint: str = "0" * 64) -> str: _, chunks = render_new_issue("main", [occurrence(fingerprint)]) return chunks[0] @final class IssueTest(unittest.TestCase): def test_existing_open_issue_plans_update(self): plan = plan_issue("main", [occurrence()], [issue(body=generated_body())]) self.assertEqual("comment", plan.kind) self.assertEqual(1, len(plan.chunks)) def test_existing_closed_issue_plans_reopen_then_recurrence(self): existing = issue(state="closed", body=generated_body(), closed_at="2026-08-01T00:00:00Z") plan = plan_issue("main", [occurrence()], [existing]) self.assertEqual("reopen", plan.kind) self.assertIn("Issue closed_at", plan.chunks[0]) def test_historical_evidence_does_not_reopen(self): existing = issue(state="closed", body=generated_body(), closed_at="2026-08-03T00:00:00Z") self.assertEqual("noop", plan_issue("main", [occurrence()], [existing]).kind) def test_repeated_occurrence_in_body_or_comment_is_noop(self): body_with_marker = generated_body("a" * 64) base_body = generated_body() update = plan_issue("main", [occurrence()], [issue(body=base_body)]) for body, comments in ((body_with_marker, ()), (base_body, update.chunks)): with self.subTest(comments=comments): self.assertEqual("noop", plan_issue("main", [occurrence()], [issue(body=body, comments=comments)]).kind) def test_legacy_issue_matches_exact_fields(self): body = "- Repo: `owner/repo`\n- Package: `pkg::tests`\n- Case: `case`\n- Branch: `main`" candidate = find_candidate("owner/repo", "main", "pkg::tests", "case", [issue(body=body)]) self.assertIsNotNone(candidate) if candidate is not None: self.assertEqual(1, candidate.number) def test_unlabeled_closed_issue_is_reopened(self): existing = issue(state="closed", body=generated_body(), closed_at="2026-08-01T00:00:00Z", labels=()) self.assertEqual("reopen", plan_issue("main", [occurrence()], [existing]).kind) def test_duplicate_matches_are_conflict(self): matches = [issue(1, body=generated_body()), issue(2, body=generated_body())] self.assertEqual("conflict", plan_issue("main", [occurrence()], matches).kind) def test_marker_and_legacy_matches_are_conflict(self): legacy = "- Repo: `owner/repo`\n- Package: `pkg::tests`\n- Case: `case`\n- Branch: `main`" matches = [issue(1, body=generated_body()), issue(2, body=legacy)] self.assertEqual("conflict", plan_issue("main", [occurrence()], matches).kind) def test_untrusted_name_cannot_inject_or_exceed_limits(self): raw_name = "line\n\u0085 @team " % ("b" * 64) + ("長`" * 1000) title, chunks = render_new_issue("main", [occurrence(name=raw_name)]) body = "".join(chunks) self.assertLessEqual(len(title), 256) self.assertLessEqual(max(len(chunk.encode("utf-8")) for chunk in chunks), 60000) self.assertNotIn("\n @team" % ("b" * 64), body) self.assertNotIn("@team", body) self.assertIn("\\u{85}", body) self.assertIn("<x>", body) self.assertEqual(1, body.count(" suffix" % ("a" * 64) self.assertEqual(set(), occurrence_markers(marker)) def test_edited_generated_documents_still_expose_markers(self): key = issue_key("owner/repo", "main", "pkg::tests", "case") body = generated_body("a" * 64) edited_body = body + "\n\nMaintainer note: a fix is being tracked." self.assertEqual({key}, key_markers(edited_body)) self.assertEqual({"a" * 64}, occurrence_markers(edited_body)) update = plan_issue("main", [occurrence("b" * 64)], [issue(body=generated_body())]) edited_comment = update.chunks[0] + "\n\nMaintainer addendum." self.assertEqual({"b" * 64}, occurrence_markers(edited_comment)) existing = issue(body=edited_body, comments=(edited_comment,)) self.assertEqual("noop", plan_issue("main", [occurrence(), occurrence("b" * 64)], [existing]).kind) def test_marker_line_outside_trailing_footer_is_ordinary_text(self): marker = "" % ("a" * 64) body = "Introduction\n%s\n\nEvidence:\n- unrelated" % marker quoted = "Evidence:\n\n> %s" % marker isolated = marker self.assertEqual(set(), occurrence_markers(body)) self.assertEqual(set(), occurrence_markers(quoted)) self.assertEqual(set(), occurrence_markers(isolated)) def test_forged_trailing_marker_structures_are_ordinary_text(self): key = issue_key("owner/repo", "main", "pkg::tests", "case") marker = "a" * 64 forged_key = "ordinary text\n" % key forged_occurrence = "ordinary text\nEvidence:\n- forged evidence\n\n" % marker self.assertEqual(set(), key_markers(forged_key)) self.assertEqual(set(), occurrence_markers(forged_occurrence)) def test_all_generated_template_variants_expose_only_their_markers(self): occurrences = [occurrence(("%064x" % index), name="case") for index in range(900)] key = issue_key("owner/repo", "main", "pkg::tests", "case") _, new_chunks = render_new_issue("main", occurrences) existing = issue(body=new_chunks[0]) update = plan_issue("main", [occurrence("f" * 64)], [existing]) closed = issue(state="closed", body=new_chunks[0], closed_at="2026-08-01T00:00:00Z") recurrence = plan_issue("main", [occurrence("e" * 64)], [closed]) self.assertEqual({key}, key_markers(new_chunks[0])) self.assertTrue(occurrence_markers(new_chunks[0])) self.assertTrue(occurrence_markers(new_chunks[1])) self.assertEqual({"f" * 64}, occurrence_markers(update.chunks[0])) self.assertEqual({"e" * 64}, occurrence_markers(recurrence.chunks[0])) def test_large_batch_chunks_between_complete_records(self): occurrences = [occurrence(("%064x" % index), name="case") for index in range(900)] _, chunks = render_new_issue("main", occurrences) self.assertGreater(len(chunks), 1) self.assertTrue(all(len(chunk.encode("utf-8")) <= 60000 for chunk in chunks)) self.assertEqual(900, sum(chunk.count("