V1 mostly complete except for some testing. Linting in the last step changed nearly every file which is why this commit is so larger.

This commit is contained in:
Jim Lancaster
2026-07-29 17:27:21 -05:00
parent bc21a97019
commit a3b3bab571
37 changed files with 1383 additions and 410 deletions
+5 -1
View File
@@ -25,7 +25,11 @@ class TestJobService:
assert fetched.document.id == document.id
@pytest.mark.asyncio
async def test_update_job_state_updates_status_and_retry(self, job_service: JobService, document_service: DocumentService):
async def test_update_job_state_updates_status_and_retry(
self,
job_service: JobService,
document_service: DocumentService,
):
document = Document(id=uuid4(), name="test-bundle")
await document_service.create_document(document=document)
@@ -7,7 +7,6 @@ import pytest
from transcription.services.transcription import transcribe_document_image
HAS_OPENROUTER_KEY = bool(os.getenv("OPENROUTER_API_KEY"))
REAL_IMAGES_DIR = Path(__file__).resolve().parents[1] / "fixtures" / "images" / "real"
@@ -68,4 +67,4 @@ class TestRealImageExternalTranscription:
f"{result.text}\n"
)
artifact_path.write_text(artifact_text, encoding="utf-8")
assert artifact_path.exists()
assert artifact_path.exists()
@@ -0,0 +1,85 @@
"""Tests for revision behavior in TranscriptionService."""
from uuid import uuid4
import pytest
from transcription.models import Document
from transcription.models import Job
from transcription.models import JobStatus
from transcription.models import Source
from transcription.services.documents import DocumentService
from transcription.services.jobs import JobService
from transcription.services.transcription import TranscriptionService
@pytest.mark.integration
class TestTranscriptionServiceRevisionUpsert:
"""Verify optional single-revision create/update semantics."""
@pytest.mark.asyncio
async def test_upsert_revision_creates_new_revision(self, default_session_factory):
documents = DocumentService(session_factory=default_session_factory)
jobs = JobService(session_factory=default_session_factory)
transcriptions = TranscriptionService(session_factory=default_session_factory)
document = Document(id=uuid4(), name="revision-create")
await documents.create_document(document=document)
job = Job(document_id=document.id, status=JobStatus.TRANSCRIBED, text="Original text")
await jobs.create_job(job=job)
source = Source(
document_id=document.id,
job_id=job.id,
upload_name="source.jpg",
filename="source.jpg",
file_path="uploads/source.jpg",
)
async with transcriptions._session_scope() as session:
session.add(source)
await session.commit()
await session.refresh(source)
revision = await transcriptions.upsert_revision_for_source(source_id=source.id, text="User revision")
fetched = await transcriptions.read_revision_by_source(source.id)
assert revision.source_id == source.id
assert revision.text == "User revision"
assert fetched is not None
assert fetched.id == revision.id
assert fetched.text == "User revision"
@pytest.mark.asyncio
async def test_upsert_revision_updates_existing_single_revision(self, default_session_factory):
documents = DocumentService(session_factory=default_session_factory)
jobs = JobService(session_factory=default_session_factory)
transcriptions = TranscriptionService(session_factory=default_session_factory)
document = Document(id=uuid4(), name="revision-update")
await documents.create_document(document=document)
job = Job(document_id=document.id, status=JobStatus.TRANSCRIBED, text="Original text")
await jobs.create_job(job=job)
source = Source(
document_id=document.id,
job_id=job.id,
upload_name="source.jpg",
filename="source.jpg",
file_path="uploads/source.jpg",
)
async with transcriptions._session_scope() as session:
session.add(source)
await session.commit()
await session.refresh(source)
first = await transcriptions.upsert_revision_for_source(source_id=source.id, text="Revision v1")
second = await transcriptions.upsert_revision_for_source(source_id=source.id, text="Revision v2")
revisions = await transcriptions.list_revisions_by_job(job.id)
assert first.id == second.id
assert second.text == "Revision v2"
assert len(revisions) == 1
assert revisions[0].id == first.id
assert revisions[0].text == "Revision v2"
+15 -3
View File
@@ -22,9 +22,21 @@ class TestWorkflowReliability:
async def test_process_queued_job_timeout_marks_job_failed(self, default_session_factory, monkeypatch):
"""Provider timeout transitions a queued job to failed with error detail."""
services = ServiceBundle()
object.__setattr__(services, "documents", services.documents.__class__(session_factory=default_session_factory))
object.__setattr__(services, "jobs", services.jobs.__class__(session_factory=default_session_factory))
object.__setattr__(services, "transcriptions", services.transcriptions.__class__(session_factory=default_session_factory))
object.__setattr__(
services,
"documents",
services.documents.__class__(session_factory=default_session_factory),
)
object.__setattr__(
services,
"jobs",
services.jobs.__class__(session_factory=default_session_factory),
)
object.__setattr__(
services,
"transcriptions",
services.transcriptions.__class__(session_factory=default_session_factory),
)
async with services.jobs._session_scope() as session:
document = Document(id=uuid4(), name="timeout-doc")