"""Integration tests for end-to-end upload and worker pipeline behavior.""" from pathlib import Path import pytest from transcription.config import Settings from transcription.models import Job from transcription.models import JobStatus 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 job transcription 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(*, prompt_text: str, image_bytes: bytes, mime_type: str) -> TranscriptionResult: _ = (prompt_text, image_bytes, mime_type) return TranscriptionResult(text="Pipeline transcript", provider="openrouter", model="test-model", prompt_name="transcribe_document.md") async def _fake_transcribe_document_image( image_path, *, prompt_name="transcribe_document.md", settings=None, provider=None, ) -> TranscriptionResult: _ = (image_path, prompt_name, settings, provider) return TranscriptionResult( text="Pipeline transcript", provider="openrouter", model="test-model", prompt_name="transcribe_document.md", ) monkeypatch.setattr( "transcription.services.workflows.transcribe_document_image", _fake_transcribe_document_image, ) processed = await process_next_queued_job(session=async_session) job = await async_session.get(Job, upload_result.job_id) assert processed is True assert job is not None assert job.status == JobStatus.TRANSCRIBED assert job.text == "Pipeline transcript" assert job.error_detail is None @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 on the job.""" 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_document_image( image_path, *, prompt_name="transcribe_document.md", settings=None, provider=None, ) -> TranscriptionResult: _ = (image_path, prompt_name, settings, provider) raise RuntimeError("pipeline provider failure") monkeypatch.setattr( "transcription.services.workflows.transcribe_document_image", _fake_transcribe_document_image, ) processed = await process_next_queued_job(session=async_session) job = await async_session.get(Job, upload_result.job_id) assert processed is True assert job is not None assert job.status == JobStatus.FAILED assert job.text is None assert job.error_detail is not None assert "pipeline provider failure" in job.error_detail assert "[internal_unexpected_error]" in job.error_detail assert "error_id=" in job.error_detail