"""Tests for OutcomeParser.""" import json import pytest from aucourt_ingest.processing.outcome_parser import OutcomeParser, VALID_VERDICTS @pytest.fixture def parser(): return OutcomeParser() class TestHeadnotePattern: def test_held_conviction_quashed(self, parser): text = "HELD: conviction quashed. The appeal is allowed." result = parser.parse(text) assert result["verdict"] == "conviction_quashed" assert result["resolution_method"] == "held" def test_held_acquittal(self, parser): text = "HELD: the accused is acquitted of all charges." result = parser.parse(text) assert result["verdict"] == "not_guilty" class TestAppealPatterns: def test_appeal_allowed(self, parser): text = "The Court orders that the appeal is allowed." result = parser.parse(text) assert result["verdict"] == "appeal_allowed" def test_appeal_dismissed(self, parser): text = "The appeal is dismissed." result = parser.parse(text) assert result["verdict"] == "appeal_dismissed" def test_convictions_quashed(self, parser): text = "Appeal allowed. Convictions on counts 1 and 3 are quashed." result = parser.parse(text) # "Appeal allowed" matches first — this is correct priority behavior assert result["verdict"] == "appeal_allowed" def test_set_aside(self, parser): text = "The convictions are set aside." result = parser.parse(text) assert result["verdict"] == "conviction_quashed" class TestGuiltyNotGuiltyPatterns: def test_guilty(self, parser): text = "The jury returns a verdict of guilty on the charge of murder." result = parser.parse(text) assert result["verdict"] == "guilty" def test_not_guilty(self, parser): text = "The jury returns a verdict of not guilty." result = parser.parse(text) assert result["verdict"] == "not_guilty" def test_found_guilty(self, parser): text = "The Court found the accused guilty." result = parser.parse(text) assert result["verdict"] == "guilty" class TestHungJury: def test_hung_jury(self, parser): text = "After three days of deliberation, the jury was unable to reach a verdict and was discharged." result = parser.parse(text) assert result["verdict"] == "hung" class TestSentenceExtraction: def test_sentence_found(self, parser): text = "I sentence the offender to imprisonment for 25 years." result = parser.parse(text) assert result["sentence"] is not None assert "25" in result["sentence"] class TestExonerationSources: def test_exoneration_lookup(self, tmp_path): exon_data = {"john smith_2015": {"verdict": "conviction_quashed", "notes": "Wrongful conviction"}} p = tmp_path / "exoneration.json" p.write_text(json.dumps(exon_data)) parser = OutcomeParser() parser.load_exoneration_sources(p) result = parser.parse("some text", case_name="John Smith", year=2015) assert result["verdict"] == "conviction_quashed" assert result["resolution_method"] == "exoneration" class TestAppealCrossReference: def test_appeal_allowed_updates_original(self, parser): updated = parser.apply_appeal_cross_reference("guilty", "appeal_allowed") assert updated == "conviction_quashed" def test_appeal_dismissed_keeps_original(self, parser): updated = parser.apply_appeal_cross_reference("guilty", "appeal_dismissed") assert updated == "guilty" def test_no_appeal_keeps_original(self, parser): updated = parser.apply_appeal_cross_reference("not_guilty", None) assert updated == "not_guilty" class TestNoMatch: def test_no_verdict_found(self, parser): text = "The Court heard submissions from both parties regarding procedural matters." result = parser.parse(text) assert result["verdict"] is None assert result["resolution_method"] is None def test_empty_text(self, parser): result = parser.parse("") assert result["verdict"] is None