RandomZ / app /tests /test_report_tier_guard.py
StormShadow308's picture
- Added support for RICS survey levels (1, 2, 3) in document uploads and reports, allowing for better tier management and retrieval filtering.
b76f199
Raw
History Blame Contribute Delete
2.05 kB
"""API guardrail: block report tier mismatches with primary document."""
from pathlib import Path
import pytest
from docx import Document as DocxDocument
from app.db.models import Document, IngestStatus
@pytest.mark.asyncio
async def test_create_report_rejects_confident_tier_mismatch(
async_client: object,
test_db: object,
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
from app.services import survey_level_classifier as slc
tenant = "tenant_test"
doc_id = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
fp = tmp_path / "primary.docx"
d = DocxDocument()
d.add_paragraph("RICS Home Survey Level 3 building survey. Further investigations. " * 20)
d.save(fp)
test_db.add(
Document(
id=doc_id,
tenant_id=tenant,
filename="primary.docx",
file_path=str(fp.resolve()),
status=IngestStatus.complete,
survey_level=2, # even if user-labelled wrong, classifier should stop silent mismatch
)
)
await test_db.commit()
# Force a confident classifier mismatch regardless of corpus contents.
fake = slc.SurveyLevelClassification(
document_id=doc_id,
filename="primary.docx",
predicted_survey_level=3,
confidence=0.9,
candidates=[slc.SurveyLevelCandidate(survey_level=3, score=1.0)],
rationale="FIXTURE: looks like a building survey.",
)
monkeypatch.setattr(slc, "classify_file_path", lambda *args, **kwargs: fake)
res = await async_client.post(
f"/reports?document_id={doc_id}&survey_level=2",
headers={"X-Tenant-ID": tenant},
)
assert res.status_code == 422
body = res.json()
assert "detail" in body
assert body["detail"]["error"] == "Tier mismatch"
ok = await async_client.post(
f"/reports?document_id={doc_id}&survey_level=2&confirm_tier_mismatch=true",
headers={"X-Tenant-ID": tenant},
)
assert ok.status_code == 201
data = ok.json()
assert data["report_id"]