"""Action handler tests for Document CRUD mutations.""" from datetime import date from uuid import uuid4 import pytest from sqlmodel import select from transcription.db import session_scope from transcription.db.models import Document, DocumentPerson, DocumentPersonRole, Job, Person, Source @pytest.mark.integration class TestDocumentActionHandlers: """Verify POST/mutation routes for Document creation, updates, and deletions.""" @pytest.mark.asyncio async def test_create_document_success(self, app_client): _, client = app_client payload = { "name": "New Historical Journal", "document_type": "journal", "document_date": "1924-05-15", "document_date_raw": "May 1924", "location_created": "San Francisco, CA", "archive_identifier": "HJ-1924-01", "notes": "Belonged to Hig.", } assert response.status_code == 200 assert "New Historical Journal" in response.text async with session_scope() as session: doc = ( await session.exec(select(Document).where(Document.name == "New Historical Journal")) ).first() assert doc is not None assert doc.document_type == "journal" assert doc.document_date == date(1924, 5, 15) assert doc.archive_identifier == "HJ-1924-01" @pytest.mark.asyncio async def test_create_document_with_author_link(self, app_client): _, client = app_client async with session_scope() as session: person = Person(full_name="John Isbill") session.add(person) await session.commit() person_id = str(person.id) payload = { "name": "Isbill Letter", "document_type": "letter", "author_id": person_id, } assert response.status_code == 200 assert "Isbill Letter" in response.text async with session_scope() as session: doc = ( await session.exec(select(Document).where(Document.name == "Isbill Letter")) ).first() assert doc is not None link = ( await session.exec( select(DocumentPerson).where( DocumentPerson.document_id == doc.id, DocumentPerson.role == DocumentPersonRole.AUTHOR, ) ) ).first() assert link is not None assert str(link.person_id) == person_id @pytest.mark.asyncio async def test_update_document_details_and_author(self, app_client): _, client = app_client async with session_scope() as session: author1 = Person(full_name="Original Author") author2 = Person(full_name="New Author") doc = Document(name="Original Title", document_type="letter") session.add_all([author1, author2, doc]) await session.flush() session.add( DocumentPerson( document_id=doc.id, person_id=author1.id, role=DocumentPersonRole.AUTHOR, ) ) await session.commit() doc_id = str(doc.id) new_author_id = str(author2.id) update_payload = { "name": "Updated Title", "document_type": "journal_entry", "author_id": new_author_id, } assert response.status_code == 200 assert "Updated Title" in response.text async with session_scope() as session: updated_doc = await session.get(Document, doc_id) assert updated_doc is not None assert updated_doc.name == "Updated Title" assert updated_doc.document_type == "journal_entry" link = ( await session.exec( select(DocumentPerson).where( DocumentPerson.document_id == updated_doc.id, DocumentPerson.role == DocumentPersonRole.AUTHOR, ) ) ).first() assert link is not None assert str(link.person_id) == new_author_id @pytest.mark.asyncio async def test_delete_unlinked_document_success(self, app_client): _, client = app_client async with session_scope() as session: doc = Document(name="Temporary Doc", document_type="note") session.add(doc) await session.commit() doc_id = str(doc.id) assert response.status_code == 200 assert "Document deleted" in response.text or "Archival Documents" in response.text async with session_scope() as session: deleted_doc = await session.get(Document, doc_id) assert deleted_doc is None @pytest.mark.asyncio async def test_delete_document_blocked_when_dependencies_exist(self, app_client): _, client = app_client async with session_scope() as session: doc = Document(name="Protected Doc", document_type="letter") session.add(doc) await session.flush() source = Source( document_id=doc.id, page_number=1, upload_name="page_001.png", filename="page_001.png", file_path="/tmp/page_001.png", ) session.add(source) await session.commit() doc_id = str(doc.id) assert response.status_code == 200 assert "Delete is blocked because related records exist." in response.text async with session_scope() as session: doc_still_exists = await session.get(Document, doc_id) assert doc_still_exists is not None