Files
transcription/tests/api/test_routes.py
T
2026-06-26 14:23:12 -05:00

119 lines
4.0 KiB
Python

"""Tests for Step 3 functional API routes."""
from datetime import datetime, timezone
from types import SimpleNamespace
from uuid import uuid4
from fastapi import FastAPI
from fastapi.testclient import TestClient
import pytest
from transcription.api.errors import register_error_handlers
from transcription.api.routes import router
def _build_app() -> FastAPI:
app = FastAPI()
register_error_handlers(app)
app.include_router(router)
return app
@pytest.mark.integration
class TestFunctionalRoutes:
"""Verify jobs/revisions/search/export route behavior."""
def test_get_jobs_returns_serialized_rows(self, monkeypatch):
"""GET /api/jobs returns normalized job rows."""
now = datetime.now(timezone.utc)
job = SimpleNamespace(
id=uuid4(),
document_id=uuid4(),
status=SimpleNamespace(value="queued"),
created_at=now,
updated_at=now,
)
monkeypatch.setattr("transcription.api.routes.list_jobs", lambda: [job])
client = TestClient(_build_app())
response = client.get("/api/jobs")
assert response.status_code == 200
payload = response.json()
assert len(payload) == 1
assert payload[0]["id"] == str(job.id)
assert payload[0]["status"] == "queued"
def test_create_revision_returns_revision_payload(self, monkeypatch):
"""POST /api/jobs/{job_id}/revisions returns created revision fields."""
revision = SimpleNamespace(
id=uuid4(),
job_id=uuid4(),
revision_number=2,
text="edited text",
source="user",
accepted=False,
created_at=datetime.now(timezone.utc),
)
monkeypatch.setattr("transcription.api.routes.add_revision", lambda **_kwargs: revision)
client = TestClient(_build_app())
response = client.post(
f"/api/jobs/{revision.job_id}/revisions",
json={"text": "edited text", "source": "user", "accepted": False},
)
assert response.status_code == 200
payload = response.json()
assert payload["id"] == str(revision.id)
assert payload["revision_number"] == 2
assert payload["text"] == "edited text"
def test_search_returns_results(self, monkeypatch):
"""GET /api/search returns accepted transcript matches."""
result = SimpleNamespace(
id=uuid4(),
job_id=uuid4(),
revision_number=1,
text="family archive",
source="user",
accepted=True,
created_at=datetime.now(timezone.utc),
)
monkeypatch.setattr("transcription.api.routes.search_accepted_transcripts", lambda query: [result])
client = TestClient(_build_app())
response = client.get("/api/search", params={"query": "archive"})
assert response.status_code == 200
payload = response.json()
assert len(payload) == 1
assert payload[0]["revision_id"] == str(result.id)
assert payload[0]["accepted"] is True
def test_export_returns_count_and_records(self, monkeypatch):
"""GET /api/export returns record count and payload list."""
records = [
{
"job_id": str(uuid4()),
"document_id": str(uuid4()),
"filename": "letter.jpg",
"revision_id": str(uuid4()),
"revision_number": 1,
"accepted": True,
"source": "user",
"text": "exported",
"created_at": datetime.now(timezone.utc).isoformat(),
}
]
monkeypatch.setattr("transcription.api.routes.export_transcripts", lambda accepted_only=True: records)
client = TestClient(_build_app())
response = client.get("/api/export")
assert response.status_code == 200
payload = response.json()
assert payload["count"] == 1
assert payload["accepted_only"] is True
assert payload["records"] == records