AiAnonymize_v3 / tests /test_api.py
Alessandro Tomassini
deploy(hf): overlay README/Dockerfile da huggingface/, senza docs/binari/model
c42a5a1
Raw
History Blame Contribute Delete
3.38 kB
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"]