Spaces:
Runtime error
Runtime error
- Added support for RICS survey levels (1, 2, 3) in document uploads and reports, allowing for better tier management and retrieval filtering.
b76f199 | """HTTP tests for canonical paragraph rollout (scan + apply guards).""" | |
| import pytest | |
| from app.db.models import Document, IngestStatus | |
| from app.models.schemas import SearchResult | |
| class _FakeVS: | |
| def __init__(self, rows: list[SearchResult]) -> None: | |
| self._rows = rows | |
| def search(self, query: str, tenant_id: str, k: int = 10, **kwargs: object) -> list[SearchResult]: | |
| return self._rows | |
| def delete_document(self, doc_id: str) -> None: | |
| return None | |
| def count_for_doc(self, doc_id: str) -> int: | |
| return 0 | |
| async def test_canonical_scan_returns_matches( | |
| async_client: object, | |
| test_db: object, | |
| monkeypatch: pytest.MonkeyPatch, | |
| ) -> None: | |
| doc_id = "cccccccc-cccc-cccc-cccc-cccccccccccc" | |
| tenant = "tenant_test" | |
| doc = Document( | |
| id=doc_id, | |
| tenant_id=tenant, | |
| filename="guidance.docx", | |
| file_path="/tmp/guidance.docx", | |
| status=IngestStatus.complete, | |
| ) | |
| test_db.add(doc) | |
| await test_db.commit() | |
| hits = [ | |
| SearchResult( | |
| chunk_id=f"{doc_id}_00003", | |
| doc_id=doc_id, | |
| tenant_id=tenant, | |
| text=( | |
| "The damp proof course should be at least 150 mm above external ground level " | |
| "in accordance with approved guidance for moisture protection." | |
| ), | |
| score=0.41, | |
| section_type="paragraph", | |
| ), | |
| ] | |
| monkeypatch.setattr( | |
| "app.services.canonical_rollout.get_vectorstore", | |
| lambda: _FakeVS(hits), | |
| ) | |
| res = await async_client.post( | |
| "/content/canonical-scan", | |
| json={ | |
| "canonical_text": ( | |
| "Damp proof courses must provide adequate clearance above external ground " | |
| "to limit moisture ingress per current building standards." | |
| ), | |
| "limit": 10, | |
| "min_relevance_percent": 20.0, | |
| "min_jaccard_vs_canonical": 0.05, | |
| }, | |
| headers={"X-Tenant-ID": tenant}, | |
| ) | |
| assert res.status_code == 200 | |
| data = res.json() | |
| assert len(data["matches"]) == 1 | |
| assert data["matches"][0]["document_id"] == doc_id | |
| assert data["matches"][0]["chunk_id"] == f"{doc_id}_00003" | |
| assert data["matches"][0]["compatibility"] in ("high", "review", "low") | |
| assert "damp" in data["matches"][0]["proposed_replacement"].lower() | |
| async def test_canonical_apply_requires_confirm( | |
| async_client: object, | |
| ) -> None: | |
| res = await async_client.post( | |
| "/content/canonical-apply", | |
| json={ | |
| "document_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", | |
| "chunk_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa_00000", | |
| "replacement_text": "Updated text.", | |
| "confirm_destructive_docx": False, | |
| }, | |
| headers={"X-Tenant-ID": "tenant_test"}, | |
| ) | |
| assert res.status_code == 400 | |
| async def test_canonical_apply_rejects_pdf( | |
| async_client: object, | |
| test_db: object, | |
| ) -> None: | |
| doc_id = "dddddddd-dddd-dddd-dddd-dddddddddddd" | |
| tenant = "tenant_test" | |
| doc = Document( | |
| id=doc_id, | |
| tenant_id=tenant, | |
| filename="ref.pdf", | |
| file_path="/tmp/ref.pdf", | |
| status=IngestStatus.complete, | |
| ) | |
| test_db.add(doc) | |
| await test_db.commit() | |
| res = await async_client.post( | |
| "/content/canonical-apply", | |
| json={ | |
| "document_id": doc_id, | |
| "chunk_id": f"{doc_id}_00000", | |
| "replacement_text": "x", | |
| "confirm_destructive_docx": True, | |
| }, | |
| headers={"X-Tenant-ID": tenant}, | |
| ) | |
| assert res.status_code == 422 | |