Files
transcription/tests/services/test_settings_services.py
T

169 lines
6.9 KiB
Python

from __future__ import annotations
from uuid import uuid4
import pytest
from transcription.db.models import Document
from transcription.db.models import DocumentPerson
from transcription.db.models import DocumentPersonRole
from transcription.db.models import Person
from transcription.errors import ErrorCategory
from transcription.services.documents import DocumentService
from transcription.services.documents import DocumentTypeError
from transcription.services.people import PeopleService
from transcription.services.people import PersonRoleError
@pytest.mark.asyncio
async def test_document_type_maintenance_uses_alphabetical_labels(default_session_factory):
service = DocumentService(session_factory=default_session_factory)
second = await service.create_document_type(label="Court Record")
first = await service.create_document_type(label="Letter")
updated = await service.update_document_type(
second.id,
label="Archive",
is_active=False,
)
assert updated.label == "Archive"
assert updated.is_active is False
assert [item.id for item in await service.list_document_types(active_only=False)] == [second.id, first.id]
assert [item.id for item in await service.list_document_types()] == [first.id]
summaries = await service.list_document_type_summaries()
assert [item.label for item in summaries] == ["Archive", "Letter"]
assert [item.document_count for item in summaries] == [0, 0]
@pytest.mark.asyncio
async def test_document_type_duplicate_normalized_label_is_conflict(default_session_factory):
service = DocumentService(session_factory=default_session_factory)
await service.create_document_type(label="Letter")
with pytest.raises(DocumentTypeError) as caught:
await service.create_document_type(label=" letter ")
assert caught.value.category == ErrorCategory.CONFLICT
@pytest.mark.asyncio
async def test_document_type_delete_allows_unreferenced_and_blocks_referenced(default_session_factory):
service = DocumentService(session_factory=default_session_factory)
unused = await service.create_document_type(label="Unused")
referenced = await service.create_document_type(label="Record")
await service.create_document(Document(id=uuid4(), name="Typed document", document_type_id=referenced.id))
summaries = {item.id: item for item in await service.list_document_type_summaries()}
assert summaries[referenced.id].document_count == 1
await service.delete_document_type(unused.id)
with pytest.raises(DocumentTypeError) as caught:
await service.delete_document_type(referenced.id)
assert caught.value.category == ErrorCategory.CONFLICT
relabeled = await service.update_document_type(
referenced.id,
label="Referenced Record",
is_active=False,
)
assert relabeled.label == "Referenced Record"
assert relabeled.is_active is False
@pytest.mark.asyncio
async def test_person_role_maintenance_orders_by_label_then_code(default_session_factory):
service = PeopleService(session_factory=default_session_factory)
second = await service.create_person_role(code="witness", label="Witness")
first = await service.create_person_role(code="author", label="Author")
updated = await service.update_person_role(second.id, label="Attestor", is_active=False)
assert updated.code == "witness"
assert [item.id for item in await service.list_person_roles(active_only=False)] == [second.id, first.id]
assert [item.id for item in await service.list_person_roles()] == [first.id]
@pytest.mark.asyncio
async def test_person_role_delete_allows_unreferenced_and_blocks_referenced(default_session_factory):
documents = DocumentService(session_factory=default_session_factory)
people = PeopleService(session_factory=default_session_factory)
unused = await people.create_person_role(code="witness", label="Witness")
referenced = await people.create_person_role(code="author", label="Author")
document = await documents.create_document(Document(name="Role document"))
person = await people.create_person(Person(full_name="Role Person"))
await people.create_document_person(
DocumentPerson(
document_id=document.id,
person_id=person.id,
role_id=referenced.id,
role=DocumentPersonRole.AUTHOR,
)
)
await people.delete_person_role(unused.id)
with pytest.raises(PersonRoleError) as caught:
await people.delete_person_role(referenced.id)
assert caught.value.category == ErrorCategory.CONFLICT
relabeled = await people.update_person_role(referenced.id, label="Creator", is_active=False)
assert relabeled.label == "Creator"
assert relabeled.is_active is False
@pytest.mark.asyncio
async def test_person_role_duplicate_code_is_conflict(default_session_factory):
service = PeopleService(session_factory=default_session_factory)
await service.create_person_role(code="author", label="Author")
with pytest.raises(PersonRoleError) as caught:
await service.create_person_role(code=" AUTHOR ", label="Duplicate")
assert caught.value.category == ErrorCategory.CONFLICT
@pytest.mark.asyncio
async def test_custom_person_role_can_be_used_for_document_link(default_session_factory):
documents = DocumentService(session_factory=default_session_factory)
people = PeopleService(session_factory=default_session_factory)
role = await people.create_person_role(code="witness", label="Witness")
document = await documents.create_document(Document(name="Witnessed document"))
person = await people.create_person(Person(full_name="Archive Witness"))
link = await people.add_document_person_link(
document_id=document.id,
person_id=person.id,
role_id=role.id,
)
loaded = await people.list_document_people(document_id=document.id)
assert link.role == "witness"
assert loaded[0].role_ref is not None
assert loaded[0].role_ref.code == "witness"
@pytest.mark.asyncio
async def test_custom_person_role_delete_blocks_legacy_only_reference(default_session_factory):
documents = DocumentService(session_factory=default_session_factory)
people = PeopleService(session_factory=default_session_factory)
role = await people.create_person_role(code="witness", label="Witness")
document = await documents.create_document(Document(name="Legacy role document"))
person = await people.create_person(Person(full_name="Legacy Witness"))
async with people._session_scope() as session:
session.add(
DocumentPerson(
document_id=document.id,
person_id=person.id,
role="witness",
role_id=None,
)
)
await session.commit()
assert await people.is_person_role_referenced(role.id) is True
with pytest.raises(PersonRoleError) as caught:
await people.delete_person_role(role.id)
assert caught.value.category == ErrorCategory.CONFLICT