import pytest from fastapi.testclient import TestClient from web.app import create_app @pytest.fixture() def client(): app = create_app() with TestClient(app) as c: yield c def test_healthz(client): assert client.get("/healthz").json()["status"] == "ok" def test_index_page(client): res = client.get("/") assert res.status_code == 200 assert "Anonimizzatore" in res.text def test_detect_and_render_flow(client): text = "Il RUP RSSMRA85T10A562S, PEC ufficio@pec.comune.it, CIG 7654321000." res = client.post("/api/detect", json={"text": text, "min_confidence": 0.7}) assert res.status_code == 200 data = res.json() assert data["detections"] >= 2 doc_id = data["doc_id"] types = {s["entity_type"] for s in data["render"]["json_export"]["by_severity"]["critica"]} assert "CODICE_FISCALE" in types or "CIG" in types # re-render con modalita' diversa, senza ri-rilevamento r2 = client.post("/api/render", json={ "doc_id": doc_id, "mode": "full_mask", "enabled_severities": ["critica", "alta", "media", "bassa"], }) assert r2.status_code == 200 assert "RSSMRA85T10A562S" not in r2.json()["anonymized_text"] def test_detection_methods_endpoint(client): data = client.get("/api/detection/methods").json() keys = {m["key"] for m in data["methods"]} # Niente più hybrid: l'utente compone la pipeline per layer (checkbox). assert {"rules", "ner", "ner_comuni", "llm", "embedding"} <= keys assert "hybrid" not in keys assert data["default"] == "rules" rules = next(m for m in data["methods"] if m["key"] == "rules") assert rules["requires_ml"] is False assert rules["technique"] == "deterministic" def test_detect_with_explicit_method(client): """La metodologia 'rules' (deterministica) rileva i codici a formato fisso.""" text = "CIG 7654321000 e CF RSSMRA85T10A562S nel documento." res = client.post( "/api/detect", json={"text": text, "min_confidence": 0.7, "method": "rules"} ) assert res.status_code == 200 assert res.json()["detections"] >= 1 def test_detect_method_changes_doc_id(client): """Metodologie diverse producono documenti (e cache) distinti.""" text = "Email test@example.com nel bando." a = client.post("/api/detect", json={"text": text, "method": "rules"}).json() b = client.post("/api/detect", json={"text": text, "method": "ner_comuni"}).json() assert a["doc_id"] != b["doc_id"] def test_detect_empty_text(client): assert client.post("/api/detect", json={"text": " "}).status_code == 400 def test_render_unknown_doc(client): res = client.post("/api/render", json={"doc_id": "nope", "mode": "placeholder"}) assert res.status_code == 404 def test_cache_returns_same_doc_id(client): text = "Email test@example.com ripetuta." a = client.post("/api/detect", json={"text": text}).json() b = client.post("/api/detect", json={"text": text}).json() assert a["doc_id"] == b["doc_id"] def test_manual_range_masks_text(client): text = "Segreto da nascondere completamente." doc_id = client.post("/api/detect", json={"text": text}).json()["doc_id"] res = client.post("/api/render", json={ "doc_id": doc_id, "mode": "full_mask", "manual_ranges": [[0, 7]], }) assert "Segreto" not in res.json()["anonymized_text"]