generated from john/python-template
108 lines
4.5 KiB
Python
108 lines
4.5 KiB
Python
"""Integration tests for end-to-end upload and worker pipeline behavior."""
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from sqlmodel import select
|
|
|
|
from transcription.config import Settings
|
|
from transcription.models import Job, JobStatus, Transcript, TranscriptRevision
|
|
from transcription.providers.base import TranscriptionResult
|
|
from transcription.services.store import create_upload_job
|
|
from transcription.worker import process_next_queued_job
|
|
|
|
|
|
@pytest.mark.integration
|
|
class TestPipelineSuccessFlow:
|
|
"""Verify end-to-end success lifecycle behavior."""
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_upload_then_worker_persists_transcribed_terminal_state(self, async_session, tmp_path: Path, monkeypatch):
|
|
"""Upload followed by worker processing persists transcript and transcribed status."""
|
|
settings = Settings(openrouter_api_key="test-key", upload_dir=tmp_path)
|
|
upload_result = await create_upload_job(
|
|
filename="pipeline.jpg",
|
|
file_bytes=b"pipeline-bytes",
|
|
session=async_session,
|
|
settings=settings,
|
|
)
|
|
|
|
async def _fake_transcribe(_path: str) -> TranscriptionResult:
|
|
return TranscriptionResult(
|
|
text="Pipeline transcript",
|
|
provider="openrouter",
|
|
prompt_name="transcribe_document.md",
|
|
model="test-model",
|
|
)
|
|
|
|
monkeypatch.setattr("transcription.services.workflows.transcribe_document_image", _fake_transcribe)
|
|
|
|
processed = await process_next_queued_job(session=async_session)
|
|
job = await async_session.get(Job, upload_result.job_id)
|
|
transcript = (await async_session.exec(select(Transcript).where(Transcript.job_id == upload_result.job_id))).first()
|
|
revisions = (
|
|
await async_session.exec(
|
|
select(TranscriptRevision)
|
|
.where(TranscriptRevision.job_id == upload_result.job_id)
|
|
.order_by(TranscriptRevision.version_number)
|
|
)
|
|
).all()
|
|
|
|
assert processed is True
|
|
assert job is not None
|
|
assert job.status == JobStatus.TRANSCRIBED
|
|
assert transcript is not None
|
|
assert transcript.text == "Pipeline transcript"
|
|
assert transcript.error_detail is None
|
|
assert transcript.model == "test-model"
|
|
assert len(revisions) == 1
|
|
assert revisions[0].version_number == 1
|
|
assert revisions[0].source == "ai"
|
|
assert revisions[0].text == "Pipeline transcript"
|
|
|
|
|
|
@pytest.mark.integration
|
|
class TestPipelineFailureFlow:
|
|
"""Verify end-to-end failure lifecycle behavior."""
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_upload_then_worker_persists_failed_terminal_state(self, async_session, tmp_path: Path, monkeypatch):
|
|
"""Upload followed by worker processing persists error detail and failed status."""
|
|
settings = Settings(openrouter_api_key="test-key", upload_dir=tmp_path)
|
|
upload_result = await create_upload_job(
|
|
filename="pipeline.jpg",
|
|
file_bytes=b"pipeline-bytes",
|
|
session=async_session,
|
|
settings=settings,
|
|
)
|
|
|
|
async def _fake_transcribe(_path: str) -> TranscriptionResult:
|
|
raise RuntimeError("pipeline provider failure")
|
|
|
|
monkeypatch.setattr("transcription.services.workflows.transcribe_document_image", _fake_transcribe)
|
|
|
|
processed = await process_next_queued_job(session=async_session)
|
|
job = await async_session.get(Job, upload_result.job_id)
|
|
transcript = (await async_session.exec(select(Transcript).where(Transcript.job_id == upload_result.job_id))).first()
|
|
revisions = (
|
|
await async_session.exec(
|
|
select(TranscriptRevision)
|
|
.where(TranscriptRevision.job_id == upload_result.job_id)
|
|
.order_by(TranscriptRevision.version_number)
|
|
)
|
|
).all()
|
|
|
|
assert processed is True
|
|
assert job is not None
|
|
assert job.status == JobStatus.FAILED
|
|
assert transcript is not None
|
|
assert transcript.text is None
|
|
assert "pipeline provider failure" in transcript.error_detail
|
|
assert "[internal_unexpected_error]" in transcript.error_detail
|
|
assert "error_id=" in transcript.error_detail
|
|
assert len(revisions) == 1
|
|
assert revisions[0].version_number == 1
|
|
assert revisions[0].source == "ai"
|
|
assert revisions[0].text is None
|
|
assert "pipeline provider failure" in (revisions[0].error_detail or "")
|