feat(stage11): audio integration — STT for interviews, podcasts, press conferences with timestamped claims
This commit is contained in:
637
tests/models/test_audio.py
Normal file
637
tests/models/test_audio.py
Normal file
@@ -0,0 +1,637 @@
|
||||
"""Tests für Pydantic v2 Schemas und SQLAlchemy Models der Audio Evidence Extraction (Stage 11)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from nsct.models.audio import (
|
||||
AudioClaimSchema,
|
||||
AudioRequestSchema,
|
||||
AudioReportSchema,
|
||||
AudioSegmentType,
|
||||
AudioSpeakerType,
|
||||
AudioTranscriptSegmentSchema,
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Enums
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestAudioSegmentTypeEnum:
|
||||
"""Prüft die Enums AudioSegmentType und AudioSpeakerType."""
|
||||
|
||||
def test_audio_segment_type_values(self):
|
||||
assert AudioSegmentType.INTERVIEW.value == "interview"
|
||||
assert AudioSegmentType.PODCAST.value == "podcast"
|
||||
assert AudioSegmentType.PRESSEKONFERENZ.value == "pressekonferenz"
|
||||
assert AudioSegmentType.REDEN.value == "reden"
|
||||
assert AudioSegmentType.SONSTIGE.value == "sonstige"
|
||||
|
||||
def test_audio_speaker_type_values(self):
|
||||
assert AudioSpeakerType.SPOECHTENANTWORTER.value == "sprechantenworter"
|
||||
assert AudioSpeakerType.FRAGENSTELLER.value == "fragensteller"
|
||||
assert AudioSpeakerType.MODERATOR.value == "moderator"
|
||||
assert AudioSpeakerType.SONSTIGE.value == "sonstige"
|
||||
|
||||
def test_invalid_segment_type(self):
|
||||
with pytest.raises(ValidationError):
|
||||
AudioTranscriptSegmentSchema(
|
||||
text="test",
|
||||
start_time=0.0,
|
||||
end_time=1.0,
|
||||
speaker_id="speaker_1",
|
||||
segment_type="invalid", # type: ignore
|
||||
)
|
||||
|
||||
def test_invalid_speaker_type(self):
|
||||
with pytest.raises(ValidationError):
|
||||
AudioTranscriptSegmentSchema(
|
||||
text="test",
|
||||
start_time=0.0,
|
||||
end_time=1.0,
|
||||
speaker_id="speaker_1",
|
||||
speaker_type="invalid", # type: ignore
|
||||
)
|
||||
|
||||
def test_all_segment_types(self):
|
||||
for st in AudioSegmentType:
|
||||
schema = AudioTranscriptSegmentSchema(
|
||||
text="test content",
|
||||
start_time=0.0,
|
||||
end_time=1.0,
|
||||
speaker_id="speaker_1",
|
||||
)
|
||||
assert isinstance(schema, AudioTranscriptSegmentSchema)
|
||||
|
||||
def test_all_speaker_types(self):
|
||||
for st in AudioSpeakerType:
|
||||
schema = AudioTranscriptSegmentSchema(
|
||||
text="test content",
|
||||
start_time=0.0,
|
||||
end_time=1.0,
|
||||
speaker_id="speaker_1",
|
||||
)
|
||||
assert isinstance(schema, AudioTranscriptSegmentSchema)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# AudioTranscriptSegmentSchema
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestAudioTranscriptSegmentSchema:
|
||||
"""Tests für AudioTranscriptSegmentSchema — Pflichtfelder, Defaults, Frozen."""
|
||||
|
||||
@pytest.fixture
|
||||
def base_kwargs(self):
|
||||
return {
|
||||
"text": "Dies ist ein Testtranskript.",
|
||||
"start_time": 0.0,
|
||||
"end_time": 5.0,
|
||||
"speaker_id": "speaker_1",
|
||||
}
|
||||
|
||||
def test_create_valid_segment(self, base_kwargs):
|
||||
segment = AudioTranscriptSegmentSchema(**base_kwargs)
|
||||
assert segment.text == "Dies ist ein Testtranskript."
|
||||
assert segment.start_time == 0.0
|
||||
assert segment.end_time == 5.0
|
||||
assert segment.speaker_id == "speaker_1"
|
||||
assert segment.confidence == 0.5
|
||||
|
||||
def test_defaults(self, base_kwargs):
|
||||
segment = AudioTranscriptSegmentSchema(**base_kwargs)
|
||||
assert segment.confidence == 0.5
|
||||
|
||||
def test_frozen(self, base_kwargs):
|
||||
segment = AudioTranscriptSegmentSchema(**base_kwargs)
|
||||
with pytest.raises(Exception):
|
||||
segment.text = "modified"
|
||||
|
||||
def test_missing_text(self, base_kwargs):
|
||||
with pytest.raises(ValidationError):
|
||||
AudioTranscriptSegmentSchema(
|
||||
start_time=base_kwargs["start_time"],
|
||||
end_time=base_kwargs["end_time"],
|
||||
speaker_id=base_kwargs["speaker_id"],
|
||||
)
|
||||
|
||||
def test_empty_text(self, base_kwargs):
|
||||
with pytest.raises(ValidationError, match="text darf nicht nur aus Whitespaces bestehen"):
|
||||
AudioTranscriptSegmentSchema(
|
||||
text=" ",
|
||||
start_time=base_kwargs["start_time"],
|
||||
end_time=base_kwargs["end_time"],
|
||||
speaker_id=base_kwargs["speaker_id"],
|
||||
)
|
||||
|
||||
def test_missing_speaker_id(self, base_kwargs):
|
||||
with pytest.raises(ValidationError):
|
||||
AudioTranscriptSegmentSchema(
|
||||
text=base_kwargs["text"],
|
||||
start_time=base_kwargs["start_time"],
|
||||
end_time=base_kwargs["end_time"],
|
||||
)
|
||||
|
||||
def test_empty_speaker_id(self, base_kwargs):
|
||||
with pytest.raises(ValidationError, match="speaker_id darf nicht leer sein"):
|
||||
AudioTranscriptSegmentSchema(
|
||||
text=base_kwargs["text"],
|
||||
start_time=base_kwargs["start_time"],
|
||||
end_time=base_kwargs["end_time"],
|
||||
speaker_id=" ",
|
||||
)
|
||||
|
||||
def test_missing_start_time(self, base_kwargs):
|
||||
with pytest.raises(ValidationError):
|
||||
AudioTranscriptSegmentSchema(
|
||||
text=base_kwargs["text"],
|
||||
end_time=base_kwargs["end_time"],
|
||||
speaker_id=base_kwargs["speaker_id"],
|
||||
)
|
||||
|
||||
def test_missing_end_time(self, base_kwargs):
|
||||
with pytest.raises(ValidationError):
|
||||
AudioTranscriptSegmentSchema(
|
||||
text=base_kwargs["text"],
|
||||
start_time=base_kwargs["start_time"],
|
||||
speaker_id=base_kwargs["speaker_id"],
|
||||
)
|
||||
|
||||
def test_negative_start_time(self, base_kwargs):
|
||||
with pytest.raises(ValidationError):
|
||||
AudioTranscriptSegmentSchema(
|
||||
text=base_kwargs["text"],
|
||||
start_time=-1.0,
|
||||
end_time=base_kwargs["end_time"],
|
||||
speaker_id=base_kwargs["speaker_id"],
|
||||
)
|
||||
|
||||
def test_end_before_start(self):
|
||||
with pytest.raises(ValidationError, match="end_time muss nach start_time liegen"):
|
||||
AudioTranscriptSegmentSchema(
|
||||
text="test",
|
||||
start_time=10.0,
|
||||
end_time=5.0,
|
||||
speaker_id="speaker_1",
|
||||
)
|
||||
|
||||
def test_confidence_bounds(self, base_kwargs):
|
||||
schema_low = AudioTranscriptSegmentSchema(**base_kwargs, confidence=0.0)
|
||||
assert schema_low.confidence == 0.0
|
||||
|
||||
schema_high = AudioTranscriptSegmentSchema(**base_kwargs, confidence=1.0)
|
||||
assert schema_high.confidence == 1.0
|
||||
|
||||
def test_confidence_out_of_bounds_low(self, base_kwargs):
|
||||
with pytest.raises(ValidationError):
|
||||
AudioTranscriptSegmentSchema(**base_kwargs, confidence=-0.1)
|
||||
|
||||
def test_confidence_out_of_bounds_high(self, base_kwargs):
|
||||
with pytest.raises(ValidationError):
|
||||
AudioTranscriptSegmentSchema(**base_kwargs, confidence=1.1)
|
||||
|
||||
def test_high_confidence(self, base_kwargs):
|
||||
segment = AudioTranscriptSegmentSchema(**base_kwargs, confidence=0.95)
|
||||
assert segment.confidence == 0.95
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# AudioClaimSchema
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestAudioClaimSchema:
|
||||
"""Tests für AudioClaimSchema — Claim mit Provenance und Timestamp."""
|
||||
|
||||
@pytest.fixture
|
||||
def base_kwargs(self):
|
||||
return {
|
||||
"claim_text": "Die Regierung hat die Ausgaben erhöht.",
|
||||
"timestamp_start": 120.0,
|
||||
"timestamp_end": 125.0,
|
||||
"speaker_id": "minister_1",
|
||||
"source_url": "https://example.com/interview.mp3",
|
||||
}
|
||||
|
||||
def test_create_valid_claim(self, base_kwargs):
|
||||
claim = AudioClaimSchema(**base_kwargs)
|
||||
assert claim.claim_text == "Die Regierung hat die Ausgaben erhöht."
|
||||
assert claim.timestamp_start == 120.0
|
||||
assert claim.timestamp_end == 125.0
|
||||
assert claim.speaker_id == "minister_1"
|
||||
assert claim.source_url == "https://example.com/interview.mp3"
|
||||
assert claim.confidence == 0.5
|
||||
assert claim.evidence_span is None
|
||||
assert claim.claim_type is None
|
||||
|
||||
def test_defaults(self, base_kwargs):
|
||||
claim = AudioClaimSchema(**base_kwargs)
|
||||
assert claim.confidence == 0.5
|
||||
assert claim.evidence_span is None
|
||||
assert claim.claim_type is None
|
||||
|
||||
def test_frozen(self, base_kwargs):
|
||||
claim = AudioClaimSchema(**base_kwargs)
|
||||
with pytest.raises(Exception):
|
||||
claim.claim_text = "modified"
|
||||
|
||||
def test_with_evidence_span(self, base_kwargs):
|
||||
claim = AudioClaimSchema(
|
||||
**base_kwargs,
|
||||
evidence_span="Laut dem Haushaltsgesetz 2024 wurden die Ausgaben um 15% erhöht.",
|
||||
)
|
||||
assert claim.evidence_span == "Laut dem Haushaltsgesetz 2024 wurden die Ausgaben um 15% erhöht."
|
||||
|
||||
def test_with_claim_type(self, base_kwargs):
|
||||
claim = AudioClaimSchema(**base_kwargs, claim_type="factual")
|
||||
assert claim.claim_type == "factual"
|
||||
|
||||
def test_empty_claim_text(self, base_kwargs):
|
||||
with pytest.raises(ValidationError, match="claim_text darf nicht nur aus Whitespaces bestehen"):
|
||||
AudioClaimSchema(
|
||||
claim_text=" ",
|
||||
timestamp_start=base_kwargs["timestamp_start"],
|
||||
timestamp_end=base_kwargs["timestamp_end"],
|
||||
speaker_id=base_kwargs["speaker_id"],
|
||||
source_url=base_kwargs["source_url"],
|
||||
)
|
||||
|
||||
def test_missing_claim_text(self, base_kwargs):
|
||||
with pytest.raises(ValidationError):
|
||||
AudioClaimSchema(
|
||||
timestamp_start=base_kwargs["timestamp_start"],
|
||||
timestamp_end=base_kwargs["timestamp_end"],
|
||||
speaker_id=base_kwargs["speaker_id"],
|
||||
source_url=base_kwargs["source_url"],
|
||||
)
|
||||
|
||||
def test_missing_speaker_id(self, base_kwargs):
|
||||
with pytest.raises(ValidationError):
|
||||
AudioClaimSchema(
|
||||
claim_text=base_kwargs["claim_text"],
|
||||
timestamp_start=base_kwargs["timestamp_start"],
|
||||
timestamp_end=base_kwargs["timestamp_end"],
|
||||
source_url=base_kwargs["source_url"],
|
||||
)
|
||||
|
||||
def test_empty_speaker_id(self, base_kwargs):
|
||||
with pytest.raises(ValidationError, match="speaker_id darf nicht leer sein"):
|
||||
AudioClaimSchema(
|
||||
claim_text=base_kwargs["claim_text"],
|
||||
timestamp_start=base_kwargs["timestamp_start"],
|
||||
timestamp_end=base_kwargs["timestamp_end"],
|
||||
speaker_id=" ",
|
||||
source_url=base_kwargs["source_url"],
|
||||
)
|
||||
|
||||
def test_missing_source_url(self, base_kwargs):
|
||||
with pytest.raises(ValidationError):
|
||||
AudioClaimSchema(
|
||||
claim_text=base_kwargs["claim_text"],
|
||||
timestamp_start=base_kwargs["timestamp_start"],
|
||||
timestamp_end=base_kwargs["timestamp_end"],
|
||||
speaker_id=base_kwargs["speaker_id"],
|
||||
)
|
||||
|
||||
def test_empty_source_url(self, base_kwargs):
|
||||
with pytest.raises(ValidationError, match="source_url darf nicht leer sein"):
|
||||
AudioClaimSchema(
|
||||
claim_text=base_kwargs["claim_text"],
|
||||
timestamp_start=base_kwargs["timestamp_start"],
|
||||
timestamp_end=base_kwargs["timestamp_end"],
|
||||
speaker_id=base_kwargs["speaker_id"],
|
||||
source_url=" ",
|
||||
)
|
||||
|
||||
def test_timestamp_end_before_start(self):
|
||||
with pytest.raises(ValidationError, match="timestamp_end muss nach timestamp_start liegen"):
|
||||
AudioClaimSchema(
|
||||
claim_text="test",
|
||||
timestamp_start=10.0,
|
||||
timestamp_end=5.0,
|
||||
speaker_id="speaker_1",
|
||||
source_url="https://example.com",
|
||||
)
|
||||
|
||||
def test_timestamp_bounds(self):
|
||||
claim = AudioClaimSchema(
|
||||
claim_text="test",
|
||||
timestamp_start=0.0,
|
||||
timestamp_end=0.0,
|
||||
speaker_id="speaker_1",
|
||||
source_url="https://example.com",
|
||||
)
|
||||
assert claim.timestamp_start == 0.0
|
||||
assert claim.timestamp_end == 0.0
|
||||
|
||||
def test_negative_timestamp_start(self):
|
||||
with pytest.raises(ValidationError):
|
||||
AudioClaimSchema(
|
||||
claim_text="test",
|
||||
timestamp_start=-1.0,
|
||||
timestamp_end=10.0,
|
||||
speaker_id="speaker_1",
|
||||
source_url="https://example.com",
|
||||
)
|
||||
|
||||
def test_confidence_bounds(self, base_kwargs):
|
||||
schema_low = AudioClaimSchema(**base_kwargs, confidence=0.0)
|
||||
assert schema_low.confidence == 0.0
|
||||
|
||||
schema_high = AudioClaimSchema(**base_kwargs, confidence=1.0)
|
||||
assert schema_high.confidence == 1.0
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# AudioReportSchema
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestAudioReportSchema:
|
||||
"""Tests für AudioReportSchema — Zusammenfassung der Audio-Analyse."""
|
||||
|
||||
@pytest.fixture
|
||||
def base_kwargs(self):
|
||||
return {
|
||||
"duration_seconds": 3600.0,
|
||||
"language": "de",
|
||||
}
|
||||
|
||||
def test_create_valid_report(self, base_kwargs):
|
||||
report = AudioReportSchema(**base_kwargs)
|
||||
assert report.duration_seconds == 3600.0
|
||||
assert report.language == "de"
|
||||
assert report.transcript_segments == []
|
||||
assert report.claims == []
|
||||
assert report.source_url is None
|
||||
assert report.research_run_id is None
|
||||
assert report.metadata == {}
|
||||
|
||||
def test_defaults(self, base_kwargs):
|
||||
report = AudioReportSchema(**base_kwargs)
|
||||
assert report.transcript_segments == []
|
||||
assert report.claims == []
|
||||
assert report.source_url is None
|
||||
assert report.research_run_id is None
|
||||
assert report.metadata == {}
|
||||
|
||||
def test_frozen(self, base_kwargs):
|
||||
report = AudioReportSchema(**base_kwargs)
|
||||
with pytest.raises(Exception):
|
||||
report.duration_seconds = 7200.0
|
||||
|
||||
def test_with_transcript_segments(self, base_kwargs):
|
||||
segment = AudioTranscriptSegmentSchema(
|
||||
text="Guten Tag, ich möchte Sie etwas fragen.",
|
||||
start_time=0.0,
|
||||
end_time=3.0,
|
||||
speaker_id="interviewer",
|
||||
)
|
||||
report = AudioReportSchema(
|
||||
**base_kwargs,
|
||||
transcript_segments=[segment],
|
||||
)
|
||||
assert len(report.transcript_segments) == 1
|
||||
assert report.transcript_segments[0].text == "Guten Tag, ich möchte Sie etwas fragen."
|
||||
|
||||
def test_with_claims(self, base_kwargs):
|
||||
claim = AudioClaimSchema(
|
||||
claim_text="Die Regierung hat die Ausgaben erhöht.",
|
||||
timestamp_start=120.0,
|
||||
timestamp_end=125.0,
|
||||
speaker_id="minister_1",
|
||||
source_url="https://example.com/interview.mp3",
|
||||
)
|
||||
report = AudioReportSchema(
|
||||
**base_kwargs,
|
||||
claims=[claim],
|
||||
)
|
||||
assert len(report.claims) == 1
|
||||
assert report.claims[0].claim_text == "Die Regierung hat die Ausgaben erhöht."
|
||||
|
||||
def test_with_source_url(self, base_kwargs):
|
||||
report = AudioReportSchema(
|
||||
**base_kwargs,
|
||||
source_url="https://example.com/podcast.mp3",
|
||||
)
|
||||
assert report.source_url == "https://example.com/podcast.mp3"
|
||||
|
||||
def test_with_research_run_id(self, base_kwargs):
|
||||
report = AudioReportSchema(
|
||||
**base_kwargs,
|
||||
research_run_id="run-uuid-001",
|
||||
)
|
||||
assert report.research_run_id == "run-uuid-001"
|
||||
|
||||
def test_empty_source_url(self, base_kwargs):
|
||||
with pytest.raises(ValidationError, match="source_url darf nicht leer sein"):
|
||||
AudioReportSchema(
|
||||
**base_kwargs,
|
||||
source_url=" ",
|
||||
)
|
||||
|
||||
def test_empty_language(self, base_kwargs):
|
||||
with pytest.raises(ValidationError, match="language darf nicht leer sein"):
|
||||
AudioReportSchema(
|
||||
**base_kwargs,
|
||||
language=" ",
|
||||
)
|
||||
|
||||
def test_language_normalized_to_lower(self, base_kwargs):
|
||||
report = AudioReportSchema(
|
||||
**base_kwargs,
|
||||
language="DE",
|
||||
)
|
||||
assert report.language == "de"
|
||||
|
||||
def test_negative_duration(self):
|
||||
with pytest.raises(ValidationError):
|
||||
AudioReportSchema(
|
||||
duration_seconds=-1.0,
|
||||
language="de",
|
||||
)
|
||||
|
||||
def test_zero_duration(self):
|
||||
report = AudioReportSchema(
|
||||
duration_seconds=0.0,
|
||||
language="de",
|
||||
)
|
||||
assert report.duration_seconds == 0.0
|
||||
|
||||
def test_metadata_dict(self, base_kwargs):
|
||||
report = AudioReportSchema(
|
||||
**base_kwargs,
|
||||
metadata={"model": "whisper-3", "processing_time": 12.5},
|
||||
)
|
||||
assert report.metadata["model"] == "whisper-3"
|
||||
assert report.metadata["processing_time"] == 12.5
|
||||
|
||||
def test_full_report(self, base_kwargs):
|
||||
segment = AudioTranscriptSegmentSchema(
|
||||
text="Interview: Was denken Sie über die Wirtschaftslage?",
|
||||
start_time=0.0,
|
||||
end_time=5.0,
|
||||
speaker_id="interviewer",
|
||||
)
|
||||
claim = AudioClaimSchema(
|
||||
claim_text="Die Wirtschaftslage ist stabil.",
|
||||
timestamp_start=5.0,
|
||||
timestamp_end=10.0,
|
||||
speaker_id="interviewee",
|
||||
source_url="https://example.com/interview.mp3",
|
||||
)
|
||||
report = AudioReportSchema(
|
||||
**base_kwargs,
|
||||
transcript_segments=[segment],
|
||||
claims=[claim],
|
||||
source_url="https://example.com/interview.mp3",
|
||||
research_run_id="run-uuid-001",
|
||||
metadata={"model": "whisper-3"},
|
||||
)
|
||||
assert len(report.transcript_segments) == 1
|
||||
assert len(report.claims) == 1
|
||||
assert report.source_url == "https://example.com/interview.mp3"
|
||||
assert report.research_run_id == "run-uuid-001"
|
||||
|
||||
def test_language_short_code(self, base_kwargs):
|
||||
"""Kurze ISO 639-1 Codes sind erlaubt (min_length=2)."""
|
||||
report = AudioReportSchema(**base_kwargs, language="en")
|
||||
assert report.language == "en"
|
||||
|
||||
def test_language_long_code(self, base_kwargs):
|
||||
"""Längere Codes bis max_length=5 sind erlaubt."""
|
||||
report = AudioReportSchema(**base_kwargs, language="deu")
|
||||
assert report.language == "deu"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# AudioRequestSchema
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestAudioRequestSchema:
|
||||
"""Tests für AudioRequestSchema — API-Request."""
|
||||
|
||||
@pytest.fixture
|
||||
def base_kwargs(self):
|
||||
return {
|
||||
"research_run_id": "run-uuid-001",
|
||||
"audio_file_url": "https://example.com/interview.mp3",
|
||||
"segment_type": AudioSegmentType.INTERVIEW,
|
||||
}
|
||||
|
||||
def test_create_valid_request(self, base_kwargs):
|
||||
request = AudioRequestSchema(**base_kwargs)
|
||||
assert request.research_run_id == "run-uuid-001"
|
||||
assert request.audio_file_url == "https://example.com/interview.mp3"
|
||||
assert request.audio_bytes_b64 is None
|
||||
assert request.segment_type == AudioSegmentType.INTERVIEW
|
||||
assert request.source_id is None
|
||||
|
||||
def test_defaults(self, base_kwargs):
|
||||
request = AudioRequestSchema(**base_kwargs)
|
||||
assert request.audio_bytes_b64 is None
|
||||
assert request.segment_type == AudioSegmentType.INTERVIEW
|
||||
assert request.source_id is None
|
||||
|
||||
def test_frozen(self, base_kwargs):
|
||||
request = AudioRequestSchema(**base_kwargs)
|
||||
with pytest.raises(Exception):
|
||||
request.research_run_id = "new-id"
|
||||
|
||||
def test_with_audio_bytes_b64(self, base_kwargs):
|
||||
request = AudioRequestSchema(
|
||||
**base_kwargs,
|
||||
audio_file_url=None,
|
||||
audio_bytes_b64="base64encodedaudiodata==",
|
||||
)
|
||||
assert request.audio_file_url is None
|
||||
assert request.audio_bytes_b64 == "base64encodedaudiodata=="
|
||||
|
||||
def test_with_source_id(self, base_kwargs):
|
||||
request = AudioRequestSchema(
|
||||
**base_kwargs,
|
||||
source_id="source-uuid-001",
|
||||
)
|
||||
assert request.source_id == "source-uuid-001"
|
||||
|
||||
def test_missing_research_run_id(self):
|
||||
with pytest.raises(ValidationError):
|
||||
AudioRequestSchema(
|
||||
audio_file_url="https://example.com/interview.mp3",
|
||||
segment_type=AudioSegmentType.INTERVIEW,
|
||||
)
|
||||
|
||||
def test_empty_research_run_id(self):
|
||||
with pytest.raises(ValidationError):
|
||||
AudioRequestSchema(
|
||||
research_run_id=" ",
|
||||
audio_file_url="https://example.com/interview.mp3",
|
||||
segment_type=AudioSegmentType.INTERVIEW,
|
||||
)
|
||||
|
||||
def test_empty_audio_file_url(self, base_kwargs):
|
||||
with pytest.raises(ValidationError, match="audio_file_url darf nicht leer sein"):
|
||||
AudioRequestSchema(
|
||||
**base_kwargs,
|
||||
audio_file_url=" ",
|
||||
)
|
||||
|
||||
def test_empty_audio_bytes_b64(self, base_kwargs):
|
||||
with pytest.raises(ValidationError, match="audio_bytes_b64 darf nicht leer sein"):
|
||||
AudioRequestSchema(
|
||||
**base_kwargs,
|
||||
audio_file_url=None,
|
||||
audio_bytes_b64=" ",
|
||||
)
|
||||
|
||||
def test_podcast_segment_type(self, base_kwargs):
|
||||
request = AudioRequestSchema(
|
||||
**base_kwargs,
|
||||
segment_type=AudioSegmentType.PODCAST,
|
||||
)
|
||||
assert request.segment_type == AudioSegmentType.PODCAST
|
||||
|
||||
def test_press_conference_segment_type(self, base_kwargs):
|
||||
request = AudioRequestSchema(
|
||||
**base_kwargs,
|
||||
segment_type=AudioSegmentType.PRESSEKONFERENZ,
|
||||
)
|
||||
assert request.segment_type == AudioSegmentType.PRESSEKONFERENZ
|
||||
|
||||
def test_speeches_segment_type(self, base_kwargs):
|
||||
request = AudioRequestSchema(
|
||||
**base_kwargs,
|
||||
segment_type=AudioSegmentType.REDEN,
|
||||
)
|
||||
assert request.segment_type == AudioSegmentType.REDEN
|
||||
|
||||
def test_other_segment_type(self, base_kwargs):
|
||||
request = AudioRequestSchema(
|
||||
**base_kwargs,
|
||||
segment_type=AudioSegmentType.SONSTIGE,
|
||||
)
|
||||
assert request.segment_type == AudioSegmentType.SONSTIGE
|
||||
|
||||
def test_segment_type_override(self):
|
||||
for st in AudioSegmentType:
|
||||
request = AudioRequestSchema(
|
||||
research_run_id="run-uuid-001",
|
||||
audio_file_url="https://example.com/audio.mp3",
|
||||
segment_type=st,
|
||||
)
|
||||
assert request.segment_type == st
|
||||
|
||||
def test_no_audio_url_or_bytes(self, base_kwargs):
|
||||
"""Erlaubt: kein audio_file_url UND kein audio_bytes_b64 (beide optional)."""
|
||||
request = AudioRequestSchema(
|
||||
**base_kwargs,
|
||||
audio_file_url=None,
|
||||
audio_bytes_b64=None,
|
||||
)
|
||||
assert request.audio_file_url is None
|
||||
assert request.audio_bytes_b64 is None
|
||||
Reference in New Issue
Block a user