generated from john/python-template
179 lines
6.2 KiB
Python
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 |