V4.3 revision to Document Types

This commit is contained in:
Jim Lancaster
2026-08-15 13:29:53 -05:00
parent aed827babe
commit a78b58ff40
30 changed files with 1481 additions and 291 deletions
+19 -11
View File
@@ -10,6 +10,7 @@ from uuid import UUID
from fastapi import FastAPI
from fastapi.testclient import TestClient
from sqlmodel import select
from transcription.api.errors import register_error_handlers
from transcription.api.v4_documents import get_document_service
@@ -21,6 +22,7 @@ from transcription.db import create_all
from transcription.db.engine import get_database_url
from transcription.db.engine import get_engine
from transcription.db.models import Document
from transcription.db.models import DocumentType
from transcription.db.models import Person
from transcription.db.session import dispose_session_factory
from transcription.db.session import session_scope
@@ -45,6 +47,12 @@ def _seed_document_and_person(
return asyncio.run(_seed())
async def _document_type_id(*, db_url: str, label: str) -> UUID:
async with session_scope(database_url=db_url) as session:
document_type = (await session.exec(select(DocumentType).where(DocumentType.label == label))).one()
return document_type.id
@contextmanager
def _v4_api_client(tmp_path: Path, *, db_filename: str) -> Generator[tuple[TestClient, str]]:
settings = Settings(
@@ -88,8 +96,8 @@ def test_list_document_types_returns_seeded_registry(tmp_path):
assert response.status_code == 200
payload = response.json()
codes = {item["code"] for item in payload}
assert {"letter", "record", "memo"}.issubset(codes)
labels = {item["label"] for item in payload}
assert {"Letter", "Record", "Memo"}.issubset(labels)
def test_list_person_roles_returns_seeded_registry(tmp_path):
@@ -102,37 +110,37 @@ def test_list_person_roles_returns_seeded_registry(tmp_path):
assert {"author", "recipient", "mentioned"}.issubset(codes)
def test_set_document_type_by_code_updates_canonical_fields(tmp_path):
def test_set_document_type_by_id_updates_canonical_field(tmp_path):
with _v4_api_client(tmp_path, db_filename="api-doc-type.db") as (client, db_url):
document_id, _ = _seed_document_and_person(db_url=db_url)
type_id = asyncio.run(_document_type_id(db_url=db_url, label="Record"))
response = client.put(
f"/api/v4/documents/{document_id}/type",
json={"document_type_code": "record"},
json={"document_type_id": str(type_id)},
)
assert response.status_code == 200
payload = response.json()
assert payload["document_id"] == str(document_id)
assert payload["document_type_id"] is not None
assert payload["document_type_code"] == "record"
assert payload["document_type_id"] == str(type_id)
def test_document_type_payload_requires_exactly_one_selector(tmp_path):
def test_document_type_payload_requires_uuid_only(tmp_path):
with _v4_api_client(tmp_path, db_filename="api-doc-type-validation.db") as (client, db_url):
document_id, _ = _seed_document_and_person(db_url=db_url)
missing = client.put(f"/api/v4/documents/{document_id}/type", json={})
conflicting = client.put(
invalid = client.put(
f"/api/v4/documents/{document_id}/type",
json={"document_type_id": str(UUID(int=1)), "document_type_code": "record"},
json={"document_type_id": "record"},
)
unexpected = client.put(
f"/api/v4/documents/{document_id}/type",
json={"document_type_code": "record", "ignored": True},
json={"document_type_id": str(UUID(int=1)), "ignored": True},
)
assert missing.status_code == 422
assert conflicting.status_code == 422
assert invalid.status_code == 422
assert unexpected.status_code == 422