generated from john/python-template
V5.1 Modify Person table: split full name into first & last, added tags support
Quality Gate / gate (push) Failing after 11s
Quality Gate / gate (push) Failing after 11s
This commit is contained in:
@@ -13,6 +13,7 @@ from transcription.db.models import DocumentPerson
|
||||
from transcription.db.models import DocumentTag
|
||||
from transcription.db.models import Job
|
||||
from transcription.db.models import Person
|
||||
from transcription.db.models import PersonTag
|
||||
from transcription.db.models import Source
|
||||
from transcription.db.models import Tag
|
||||
from transcription.db.models import Photo
|
||||
@@ -132,7 +133,7 @@ async def test_delete_document_removes_person_links(default_session_factory, tmp
|
||||
name="person-linked-delete",
|
||||
)
|
||||
)
|
||||
person = await people_service.create_person(Person(full_name="Linked Person"))
|
||||
person = await people_service.create_person(Person(given_names="Linked", last_name="Person"))
|
||||
author_role = await people_service.create_person_role(label="Author")
|
||||
await people_service.create_document_person(
|
||||
DocumentPerson(
|
||||
@@ -197,7 +198,7 @@ async def test_read_person_detail_loads_document_links(default_session_factory):
|
||||
name="linked-doc",
|
||||
)
|
||||
)
|
||||
person = await people_service.create_person(Person(full_name="Linked Person"))
|
||||
person = await people_service.create_person(Person(given_names="Linked", last_name="Person"))
|
||||
author_role = await people_service.create_person_role(label="Author")
|
||||
await people_service.create_document_person(
|
||||
DocumentPerson(
|
||||
@@ -221,16 +222,17 @@ async def test_update_person_refreshes_updated_timestamp(default_session_factory
|
||||
|
||||
created = await service.create_person(
|
||||
Person(
|
||||
full_name="timestamp-person",
|
||||
given_names="timestamp",
|
||||
last_name="person",
|
||||
updated_at=datetime(2000, 1, 1, tzinfo=UTC),
|
||||
)
|
||||
)
|
||||
original_updated_at = created.updated_at
|
||||
created.display_name = "updated"
|
||||
created.given_names = "updated"
|
||||
|
||||
updated = await service.update_person(created)
|
||||
|
||||
assert updated.display_name == "updated"
|
||||
assert updated.given_names == "updated"
|
||||
assert updated.updated_at >= original_updated_at
|
||||
|
||||
|
||||
@@ -245,7 +247,7 @@ async def test_delete_person_removes_links_when_linked_documents_exist(default_s
|
||||
name="block-person-delete-doc",
|
||||
)
|
||||
)
|
||||
person = await service.create_person(Person(full_name="Blocked Person"))
|
||||
person = await service.create_person(Person(given_names="Blocked", last_name="Person"))
|
||||
author_role = await service.create_person_role(label="Author")
|
||||
await service.create_document_person(
|
||||
DocumentPerson(
|
||||
@@ -268,7 +270,7 @@ async def test_delete_person_removes_links_when_linked_documents_exist(default_s
|
||||
async def test_delete_person_succeeds_when_unlinked(default_session_factory):
|
||||
service = PeopleService(session_factory=default_session_factory)
|
||||
|
||||
person = await service.create_person(Person(full_name="Free Person"))
|
||||
person = await service.create_person(Person(given_names="Free", last_name="Person"))
|
||||
|
||||
await service.delete_person(person)
|
||||
|
||||
@@ -280,7 +282,7 @@ async def test_delete_person_succeeds_when_unlinked(default_session_factory):
|
||||
async def test_delete_person_blocks_when_photos_exist(default_session_factory):
|
||||
service = PeopleService(session_factory=default_session_factory)
|
||||
|
||||
person = await service.create_person(Person(full_name="Photo Protected Person"))
|
||||
person = await service.create_person(Person(given_names="Photo Protected", last_name="Person"))
|
||||
async with service._session_scope() as session:
|
||||
session.add(
|
||||
Photo(
|
||||
@@ -313,7 +315,7 @@ async def test_update_document_person_changes_role_id(default_session_factory):
|
||||
service = PeopleService(session_factory=default_session_factory)
|
||||
|
||||
document = await documents_service.create_document(Document(id=uuid4(), name="role-sync-doc"))
|
||||
person = await service.create_person(Person(full_name="Role Sync Person"))
|
||||
person = await service.create_person(Person(given_names="Role Sync", last_name="Person"))
|
||||
author_role = await service.create_person_role(label="Author")
|
||||
recipient_role = await service.create_person_role(label="Recipient")
|
||||
link = await service.create_document_person(
|
||||
@@ -357,3 +359,25 @@ async def test_sync_document_tags_by_labels_creates_and_replaces_tags(default_se
|
||||
assert len(listed) == 1
|
||||
listed_labels = {link.tag_ref.label for link in listed[0].document_tags if link.tag_ref is not None}
|
||||
assert listed_labels == {"Census", "Research"}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_sync_person_tags_by_labels_creates_and_replaces_tags(default_session_factory):
|
||||
people = PeopleService(session_factory=default_session_factory)
|
||||
person = await people.create_person(Person(given_names="Tagged", last_name="Person"))
|
||||
|
||||
await people.sync_person_tags_by_labels(person_id=person.id, labels=["Family", "Census"])
|
||||
await people.sync_person_tags_by_labels(person_id=person.id, labels=["Census", "Research"])
|
||||
|
||||
async with people._session_scope() as session:
|
||||
links = (await session.exec(select(PersonTag).where(PersonTag.person_id == person.id))).all()
|
||||
tags = (await session.exec(select(Tag))).all()
|
||||
|
||||
assert len(links) == 2
|
||||
linked_ids = {link.tag_id for link in links}
|
||||
linked_labels = {tag.label for tag in tags if tag.id in linked_ids}
|
||||
assert linked_labels == {"Census", "Research"}
|
||||
|
||||
detail = await people.read_person_detail(person.id)
|
||||
listed_labels = {link.tag_ref.label for link in detail.person_tags if link.tag_ref is not None}
|
||||
assert listed_labels == {"Census", "Research"}
|
||||
|
||||
@@ -18,7 +18,7 @@ async def test_create_photo_persists_media_and_primary_state(default_session_fac
|
||||
settings = Settings(openrouter_api_key="test-key", upload_dir=tmp_path / "uploads")
|
||||
people = PeopleService(session_factory=default_session_factory)
|
||||
photos = PhotosService(session_factory=default_session_factory, settings=settings)
|
||||
person = await people.create_person(Person(full_name="Photo Person"))
|
||||
person = await people.create_person(Person(given_names="Photo", last_name="Person"))
|
||||
|
||||
first = await photos.create_photo(person_id=person.id, filename="one.png", file_bytes=PNG_BYTES)
|
||||
second = await photos.create_photo(person_id=person.id, filename="two.png", file_bytes=PNG_BYTES)
|
||||
@@ -36,7 +36,7 @@ async def test_set_primary_and_delete_promotes_next_photo(default_session_factor
|
||||
settings = Settings(openrouter_api_key="test-key", upload_dir=tmp_path / "uploads")
|
||||
people = PeopleService(session_factory=default_session_factory)
|
||||
photos = PhotosService(session_factory=default_session_factory, settings=settings)
|
||||
person = await people.create_person(Person(full_name="Primary Person"))
|
||||
person = await people.create_person(Person(given_names="Primary", last_name="Person"))
|
||||
|
||||
first = await photos.create_photo(person_id=person.id, filename="one.png", file_bytes=PNG_BYTES)
|
||||
second = await photos.create_photo(person_id=person.id, filename="two.png", file_bytes=PNG_BYTES)
|
||||
|
||||
@@ -95,7 +95,7 @@ async def test_person_role_delete_allows_unreferenced_and_blocks_referenced(defa
|
||||
unused = await people.create_person_role(label="Witness")
|
||||
referenced = await people.create_person_role(label="Creator")
|
||||
document = await documents.create_document(Document(name="Role document"))
|
||||
person = await people.create_person(Person(full_name="Role Person"))
|
||||
person = await people.create_person(Person(given_names="Role", last_name="Person"))
|
||||
await people.create_document_person(
|
||||
DocumentPerson(
|
||||
document_id=document.id,
|
||||
@@ -131,7 +131,7 @@ async def test_custom_person_role_can_be_used_for_document_link(default_session_
|
||||
people = PeopleService(session_factory=default_session_factory)
|
||||
role = await people.create_person_role(label="Witness")
|
||||
document = await documents.create_document(Document(name="Witnessed document"))
|
||||
person = await people.create_person(Person(full_name="Archive Witness"))
|
||||
person = await people.create_person(Person(given_names="Archive", last_name="Witness"))
|
||||
|
||||
link = await people.add_document_person_link(
|
||||
document_id=document.id,
|
||||
|
||||
@@ -34,10 +34,11 @@ async def test_document_update_advances_updated_at(default_session_factory):
|
||||
@pytest.mark.asyncio
|
||||
async def test_person_update_advances_updated_at(default_session_factory):
|
||||
people = PeopleService(session_factory=default_session_factory)
|
||||
person = await people.create_person(Person(full_name="Grace Hopper"))
|
||||
person = await people.create_person(Person(given_names="Grace", last_name="Hopper"))
|
||||
original = person.updated_at
|
||||
|
||||
person.full_name = "Rear Adm. Grace Hopper"
|
||||
person.given_names = "Rear Adm. Grace"
|
||||
person.last_name = "Hopper"
|
||||
updated = await people.update_person(person)
|
||||
|
||||
assert updated.updated_at > original
|
||||
|
||||
@@ -28,7 +28,7 @@ async def test_people_service_handles_person_and_document_person_crud(default_se
|
||||
people_service = PeopleService(session_factory=default_session_factory)
|
||||
|
||||
document = await documents.create_document(Document(id=uuid4(), name="person-doc"))
|
||||
person = await people_service.create_person(Person(full_name="Ada Lovelace"))
|
||||
person = await people_service.create_person(Person(given_names="Ada", last_name="Lovelace"))
|
||||
author_role = await people_service.create_person_role(label="Author")
|
||||
recipient_role = await people_service.create_person_role(label="Recipient")
|
||||
|
||||
@@ -61,15 +61,15 @@ async def test_people_service_handles_person_and_document_person_crud(default_se
|
||||
async def test_people_service_normalizes_and_rejects_duplicate_family_search_ids(default_session_factory):
|
||||
people_service = PeopleService(session_factory=default_session_factory)
|
||||
|
||||
created = await people_service.create_person(Person(full_name="Hig Higgins", family_search_id=" g8t4-mdq "))
|
||||
created = await people_service.create_person(Person(given_names="Hig", last_name="Higgins", family_search_id=" g8t4-mdq "))
|
||||
assert created.family_search_id == "G8T4-MDQ"
|
||||
|
||||
with pytest.raises(PeopleError) as duplicate:
|
||||
await people_service.create_person(Person(full_name="Duplicate Hig", family_search_id="G8T4-MDQ"))
|
||||
await people_service.create_person(Person(given_names="Duplicate", last_name="Hig", family_search_id="G8T4-MDQ"))
|
||||
assert duplicate.value.category == ErrorCategory.CONFLICT
|
||||
|
||||
with pytest.raises(PeopleError) as malformed:
|
||||
await people_service.create_person(Person(full_name="Malformed", family_search_id="not-an-id"))
|
||||
await people_service.create_person(Person(given_names="Malformed", last_name="Person", family_search_id="not-an-id"))
|
||||
assert malformed.value.category == ErrorCategory.VALIDATION
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ async def test_document_detail_loads_linked_person_relationship(default_session_
|
||||
people_service = PeopleService(session_factory=default_session_factory)
|
||||
|
||||
document = await documents.create_document(Document(id=uuid4(), name="detail-person-doc"))
|
||||
person = await people_service.create_person(Person(full_name="Grace Hopper"))
|
||||
person = await people_service.create_person(Person(given_names="Grace", last_name="Hopper"))
|
||||
author_role = await people_service.create_person_role(label="Author")
|
||||
await people_service.create_document_person(
|
||||
DocumentPerson(
|
||||
|
||||
@@ -45,7 +45,7 @@ async def test_update_document_with_people_rolls_back_document_and_links(default
|
||||
people = PeopleService(session_factory=default_session_factory)
|
||||
role = await people.create_person_role(label="Witness")
|
||||
inactive = await people.create_person_role(label="Former Witness", is_active=False)
|
||||
person = await people.create_person(Person(full_name="Archive Witness"))
|
||||
person = await people.create_person(Person(given_names="Archive", last_name="Witness"))
|
||||
document = await create_document_with_people(
|
||||
document=Document(name="Original name"),
|
||||
links=[DocumentPersonInput(person_id=person.id, role_id=role.id)],
|
||||
@@ -83,7 +83,7 @@ async def test_direct_link_writes_reject_new_inactive_role_assignments(default_s
|
||||
people = PeopleService(session_factory=default_session_factory)
|
||||
active = await people.create_person_role(label="Witness")
|
||||
inactive = await people.create_person_role(label="Former Witness", is_active=False)
|
||||
person = await people.create_person(Person(full_name="Archive Witness"))
|
||||
person = await people.create_person(Person(given_names="Archive", last_name="Witness"))
|
||||
document = await documents.create_document(Document(name="Role rules"))
|
||||
link = await people.add_document_person_link(
|
||||
document_id=document.id,
|
||||
@@ -114,7 +114,7 @@ async def test_document_print_projection_uses_semantic_author_and_current_text(d
|
||||
document = await documents.create_document(
|
||||
Document(name="Print Me", notes="Archive note", document_type_id=document_type.id)
|
||||
)
|
||||
person = await people.create_person(Person(full_name="Historic Author"))
|
||||
person = await people.create_person(Person(given_names="Historic", last_name="Author"))
|
||||
|
||||
async with people._session_scope() as session:
|
||||
author = PersonRole(
|
||||
|
||||
Reference in New Issue
Block a user