"""Tests for transcription.services.upload.""" from pathlib import Path import pytest from transcription.config import Settings from transcription.models import Document, Job, JobStatus from transcription.services.upload import UploadError, create_upload_job @pytest.mark.unit class TestUploadValidation: """Verify upload validation behavior.""" def test_rejects_empty_bytes(self, session, tmp_path: Path): """create_upload_job rejects an empty upload payload.""" settings = Settings(openrouter_api_key="test-key", upload_dir=tmp_path) with pytest.raises(UploadError) as exc_info: create_upload_job( filename="letter.jpg", file_bytes=b"", session=session, settings=settings, ) assert exc_info.value.category.value == "validation_error" assert "non-empty" in exc_info.value.suggestion.lower() def test_rejects_unsupported_extension(self, session, tmp_path: Path): """create_upload_job rejects unsupported filename extensions.""" settings = Settings(openrouter_api_key="test-key", upload_dir=tmp_path) with pytest.raises(UploadError) as exc_info: create_upload_job( filename="notes.txt", file_bytes=b"content", session=session, settings=settings, ) assert exc_info.value.category.value == "user_input_error" assert "jpg" in exc_info.value.suggestion.lower() def test_rejects_payload_exceeding_max_upload_bytes(self, session, tmp_path: Path): """create_upload_job rejects payloads above configured size limit.""" settings = Settings( openrouter_api_key="test-key", upload_dir=tmp_path, max_upload_bytes=3, ) with pytest.raises(UploadError) as exc_info: create_upload_job( filename="scan.jpg", file_bytes=b"1234", session=session, settings=settings, ) assert exc_info.value.category.value == "user_input_error" assert "smaller file" in exc_info.value.suggestion.lower() @pytest.mark.integration class TestUploadPersistence: """Verify upload file and record persistence behavior.""" def test_writes_file_and_creates_records(self, session, tmp_path: Path): """create_upload_job writes file and creates document/job records.""" settings = Settings(openrouter_api_key="test-key", upload_dir=tmp_path) result = create_upload_job( filename="letter.jpg", file_bytes=b"image-bytes", session=session, settings=settings, ) assert result.stored_path.exists() assert result.stored_path.read_bytes() == b"image-bytes" document = session.get(Document, result.document_id) job = session.get(Job, result.job_id) assert document is not None assert job is not None assert document.filename == "letter.jpg" assert document.file_path == str(result.stored_path) def test_uses_unique_stored_filename(self, session, tmp_path: Path): """create_upload_job stores uploads with unique filenames.""" settings = Settings(openrouter_api_key="test-key", upload_dir=tmp_path) first = create_upload_job( filename="duplicate.jpg", file_bytes=b"first", session=session, settings=settings, ) second = create_upload_job( filename="duplicate.jpg", file_bytes=b"second", session=session, settings=settings, ) assert first.stored_path != second.stored_path assert first.stored_path.exists() assert second.stored_path.exists() def test_sets_job_status_queued(self, session, tmp_path: Path): """create_upload_job persists a job with queued status.""" settings = Settings(openrouter_api_key="test-key", upload_dir=tmp_path) result = create_upload_job( filename="queued.pdf", file_bytes=b"%PDF-1.4", session=session, settings=settings, ) job = session.get(Job, result.job_id) assert job is not None assert job.status == JobStatus.QUEUED