import pytest from audita.errors import AuditaValidationError from audita.schemas import parse_glossary_yaml, parse_source_transcript_json, parse_transcript_json def test_valid_transcript_parses(): segments = parse_transcript_json( """ [ {"id": 1, "speaker": "Eric", "start": 0.0, "end": 1.25, "text": "Then Lyra."} ] """ ) assert len(segments) == 1 assert segments[0].id == 1 assert segments[0].speaker == "Eric" def test_transcript_rejects_extra_fields(): with pytest.raises(AuditaValidationError): parse_transcript_json( """ [ {"id": 1, "speaker": "Eric", "start": 0.0, "end": 1.25, "text": "Hi", "extra": true} ] """ ) def test_transcript_rejects_bad_timestamps(): with pytest.raises(AuditaValidationError): parse_transcript_json( """ [ {"id": 1, "speaker": "Eric", "start": 2.0, "end": 1.0, "text": "Hi"} ] """ ) def test_transcript_rejects_missing_id(): with pytest.raises(AuditaValidationError): parse_transcript_json( """ [ {"speaker": "Eric", "start": 0.0, "end": 1.0, "text": "Hi"} ] """ ) def test_transcript_rejects_duplicate_ids(): with pytest.raises(AuditaValidationError): parse_transcript_json( """ [ {"id": 1, "speaker": "Eric", "start": 0.0, "end": 1.0, "text": "Hi"}, {"id": 1, "speaker": "Mike", "start": 1.0, "end": 2.0, "text": "There"} ] """ ) def test_transcript_rejects_nonsequential_ids(): with pytest.raises(AuditaValidationError): parse_transcript_json( """ [ {"id": 1, "speaker": "Eric", "start": 0.0, "end": 1.0, "text": "Hi"}, {"id": 3, "speaker": "Mike", "start": 1.0, "end": 2.0, "text": "There"} ] """ ) def test_transcript_rejects_zero_or_negative_id(): with pytest.raises(AuditaValidationError): parse_transcript_json( """ [ {"id": 0, "speaker": "Eric", "start": 0.0, "end": 1.0, "text": "Hi"} ] """ ) def test_transcript_rejects_noninteger_id(): with pytest.raises(AuditaValidationError): parse_transcript_json( """ [ {"id": 1.5, "speaker": "Eric", "start": 0.0, "end": 1.0, "text": "Hi"} ] """ ) def test_transcript_rejects_empty_input(): with pytest.raises(AuditaValidationError): parse_transcript_json("[]") def test_source_transcript_accepts_missing_ids(): segments = parse_source_transcript_json( """ [ {"speaker": "Eric", "start": 0.0, "end": 1.0, "text": "Hi"} ] """ ) assert segments[0].id is None assert segments[0].speaker == "Eric" def test_source_transcript_accepts_present_nonsequential_ids(): segments = parse_source_transcript_json( """ [ {"id": 10, "speaker": "Eric", "start": 0.0, "end": 1.0, "text": "Hi"}, {"id": 4, "speaker": "Mike", "start": 1.0, "end": 2.0, "text": "There"} ] """ ) assert [segment.id for segment in segments] == [10, 4] def test_source_transcript_rejects_extra_fields(): with pytest.raises(AuditaValidationError): parse_source_transcript_json( """ [ {"speaker": "Eric", "start": 0.0, "end": 1.0, "text": "Hi", "extra": true} ] """ ) def test_source_transcript_rejects_bad_timestamps(): with pytest.raises(AuditaValidationError): parse_source_transcript_json( """ [ {"speaker": "Eric", "start": 2.0, "end": 1.0, "text": "Hi"} ] """ ) def test_source_transcript_rejects_empty_values(): with pytest.raises(AuditaValidationError): parse_source_transcript_json( """ [ {"speaker": "", "start": 0.0, "end": 1.0, "text": "Hi"} ] """ ) def test_source_transcript_rejects_invalid_json(): with pytest.raises(AuditaValidationError): parse_source_transcript_json("{") def test_valid_glossary_parses(): glossary = parse_glossary_yaml( """ glossary: - name: "Lyra" category: npc summary: "Lyra is a hostile NPC." """ ) assert glossary.glossary[0].name == "Lyra" assert glossary.glossary[0].plural is None def test_glossary_accepts_optional_plural(): glossary = parse_glossary_yaml( """ glossary: - name: "Godfrey" plural: "Godfreys" category: npc summary: "Godfrey is an NPC." """ ) assert glossary.glossary[0].plural == "Godfreys" def test_glossary_rejects_empty_plural(): with pytest.raises(AuditaValidationError): parse_glossary_yaml( """ glossary: - name: "Godfrey" plural: "" category: npc summary: "Godfrey is an NPC." """ ) def test_glossary_rejects_empty_entries(): with pytest.raises(AuditaValidationError): parse_glossary_yaml("glossary: []") def test_glossary_rejects_extra_fields(): with pytest.raises(AuditaValidationError): parse_glossary_yaml( """ glossary: - name: "Lyra" category: npc summary: "Lyra is a hostile NPC." extra: "nope" """ )