Files
transcription/tests/ui/test_people_actions.py
T
2026-08-05 13:27:30 -05:00

138 lines
4.8 KiB
Python

"""Action handler tests for Person 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, Person
@pytest.mark.integration
class TestPeopleActionHandlers:
"""Verify POST/mutation routes for Person creation, updates, and deletions."""
@pytest.mark.asyncio
async def test_create_person_success(self, app_client):
_, client = app_client
payload = {
"full_name": "Mary-Jo Kline",
"display_name": "Mary-Jo",
"maiden_name": "",
"birth_date": "1945-03-12",
"birth_date_raw": "ca. 1945",
"birth_place": "Boston, MA",
"biography": "Editor and scholar in documentary editing.",
}
assert response.status_code == 200
assert "Mary-Jo Kline" in response.text
async with session_scope() as session:
person = (
await session.exec(select(Person).where(Person.full_name == "Mary-Jo Kline"))
).first()
assert person is not None
assert person.display_name == "Mary-Jo"
assert person.birth_date == date(1945, 3, 12)
assert person.biography == "Editor and scholar in documentary editing."
@pytest.mark.asyncio
async def test_create_person_validation_missing_full_name(self, app_client):
_, client = app_client
payload = {
"full_name": "",
"display_name": "Anonymous",
}
assert response.status_code == 200
assert "Full name is required." in response.text
@pytest.mark.asyncio
async def test_update_person_details_success(self, app_client):
_, client = app_client
async with session_scope() as session:
person = Person(full_name="Original Name", display_name="Orig")
session.add(person)
await session.commit()
person_id = str(person.id)
update_payload = {
"full_name": "Updated Person Name",
"display_name": "Updated Display",
"maiden_name": "Cochran",
"birth_date": "1902-08-20",
"biography": "Updated archival biographical information.",
}
assert response.status_code == 200
assert "Updated Person Name" in response.text
async with session_scope() as session:
updated_person = await session.get(Person, person_id)
assert updated_person is not None
assert updated_person.full_name == "Updated Person Name"
assert updated_person.display_name == "Updated Display"
assert updated_person.maiden_name == "Cochran"
assert updated_person.birth_date == date(1902, 8, 20)
@pytest.mark.asyncio
async def test_delete_unlinked_person_success(self, app_client):
_, client = app_client
async with session_scope() as session:
person = Person(full_name="Transient Record")
session.add(person)
await session.commit()
person_id = str(person.id)
assert response.status_code == 200
assert "Person deleted" in response.text or "Archival Entities: People" in response.text
async with session_scope() as session:
deleted_person = await session.get(Person, person_id)
assert deleted_person is None
@pytest.mark.asyncio
async def test_delete_person_removes_linked_document_relationship(self, app_client):
_, client = app_client
async with session_scope() as session:
person = Person(full_name="Linked Person to Delete")
doc = Document(name="Historical Letter", document_type="letter")
session.add_all([person, doc])
await session.flush()
link = DocumentPerson(
document_id=doc.id,
person_id=person.id,
role=DocumentPersonRole.AUTHOR,
)
session.add(link)
await session.commit()
person_id = str(person.id)
doc_id = str(doc.id)
assert response.status_code == 200
async with session_scope() as session:
# Person should be deleted
deleted_person = await session.get(Person, person_id)
assert deleted_person is None
# Associated relationship link should also be removed
remaining_links = (
await session.exec(
select(DocumentPerson).where(DocumentPerson.person_id == person_id)
)
).all()
assert len(remaining_links) == 0
# Document itself should remain intact
document = await session.get(Document, doc_id)
assert document is not None