Files
transcription/tests/services/test_library.py
T
2026-06-26 18:19:09 -05:00

99 lines
4.0 KiB
Python

"""Tests for Step 3 library services (revisions, search, export)."""
import pytest
from sqlmodel import select
from transcription.models import Document
from transcription.models import Job
from transcription.models import JobStatus
from transcription.models import Transcript
from transcription.models import TranscriptRevision
from transcription.services.library import accept_revision
from transcription.services.library import add_revision
from transcription.services.library import export_transcripts
from transcription.services.library import list_revisions
from transcription.services.library import search_accepted_transcripts
def _create_job(session) -> Job:
document = Document(filename="letter.jpg", file_path="uploads/letter.jpg")
session.add(document)
session.commit()
session.refresh(document)
job = Job(document_id=document.id, status=JobStatus.TRANSCRIBED)
session.add(job)
session.commit()
session.refresh(job)
return job
@pytest.mark.integration
class TestRevisionHistoryBehavior:
"""Verify revision append/accept behavior."""
def test_add_revision_appends_incrementing_revision_numbers(self, session):
"""add_revision creates immutable incrementing revisions per job."""
job = _create_job(session)
r1 = add_revision(job_id=job.id, text="first", session=session)
r2 = add_revision(job_id=job.id, text="second", session=session)
revisions = list_revisions(job_id=job.id, session=session)
assert r1.revision_number == 1
assert r2.revision_number == 2
assert [revision.revision_number for revision in revisions] == [1, 2]
def test_accept_revision_marks_selected_revision_and_sets_job_completed(self, session):
"""accept_revision marks one revision accepted and transitions job to completed."""
job = _create_job(session)
r1 = add_revision(job_id=job.id, text="v1", session=session)
r2 = add_revision(job_id=job.id, text="v2", session=session)
accepted = accept_revision(revision_id=r2.id, session=session)
session.refresh(job)
all_revisions = list(session.exec(select(TranscriptRevision).where(TranscriptRevision.job_id == job.id)).all())
accepted_flags = {revision.id: revision.accepted for revision in all_revisions}
transcript = session.exec(select(Transcript).where(Transcript.job_id == job.id)).first()
assert accepted.id == r2.id
assert accepted_flags[r1.id] is False
assert accepted_flags[r2.id] is True
assert job.status == JobStatus.COMPLETED
assert transcript is not None
assert transcript.text == "v2"
@pytest.mark.integration
class TestSearchAndExportBehavior:
"""Verify accepted-only search and export semantics."""
def test_search_returns_only_accepted_revisions(self, session):
"""search_accepted_transcripts filters out non-accepted revisions."""
job = _create_job(session)
draft = add_revision(job_id=job.id, text="family archive draft", session=session)
accepted = add_revision(job_id=job.id, text="family archive final", accepted=True, session=session)
results = search_accepted_transcripts(query="archive", session=session)
assert results
result_ids = {result.id for result in results}
assert accepted.id in result_ids
assert draft.id not in result_ids
def test_export_returns_serializable_records_for_accepted_revisions(self, session):
"""export_transcripts returns expected fields for accepted-only export."""
job = _create_job(session)
accepted = add_revision(job_id=job.id, text="export me", accepted=True, session=session)
records = export_transcripts(accepted_only=True, session=session)
assert len(records) == 1
record = records[0]
assert record["job_id"] == str(job.id)
assert record["revision_id"] == str(accepted.id)
assert record["accepted"] is True
assert record["text"] == "export me"