Files
transcription/tests/ui/test_documents_actions.py
T

179 lines
6.2 KiB
Python

"""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.",
}
response = client.post("/ui/documents/new", data=payload, follow_redirects=True)
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,
}
response = client.post("/ui/documents/new", data=payload, follow_redirects=True)
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,
}
response = client.post(f"/ui/documents/{doc_id}/edit", data=update_payload, follow_redirects=True)
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)
response = client.post(f"/ui/documents/{doc_id}/delete", follow_redirects=True)
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)
response = client.post(f"/ui/documents/{doc_id}/delete", follow_redirects=True)
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