71 lines
3.0 KiB
Python
71 lines
3.0 KiB
Python
"""Tests feature Questionnaires : PHQ-9 fourni, authoring QCM, scoring, assignation,
|
|
résultats chiffrés dans le dossier patient."""
|
|
|
|
import nacl.pwhash
|
|
|
|
from kazeia_central.core.store import Store
|
|
from kazeia_central.features.medical.questionnaires import service as svc
|
|
|
|
_OPS = nacl.pwhash.argon2id.OPSLIMIT_MIN
|
|
_MEM = nacl.pwhash.argon2id.MEMLIMIT_MIN
|
|
NOW = 1_700_000_000_000
|
|
|
|
|
|
def _store(tmp_path):
|
|
s = Store(tmp_path / "c.db", kdf_ops=_OPS, kdf_mem=_MEM)
|
|
s.unlock("pw")
|
|
return s
|
|
|
|
|
|
def test_phq9_seeded_and_undeletable(tmp_path):
|
|
s = _store(tmp_path)
|
|
ids = {q["id"] for q in svc.list_questionnaires(s)}
|
|
assert "phq9" in ids
|
|
q = svc.get_questionnaire(s, "phq9")
|
|
assert q["builtin"] is True and len(q["definition"]["questions"]) == 9
|
|
assert svc.delete_questionnaire(s, "phq9", now=NOW)["deleted"] is False # fourni → protégé
|
|
|
|
|
|
def test_phq9_scoring_bands(tmp_path):
|
|
s = _store(tmp_path)
|
|
defn = svc.get_questionnaire(s, "phq9")["definition"]
|
|
assert svc.score(defn, [0] * 9) == {"total_score": 0, "interpretation": defn["scoring"]["ranges"][0]["label"]}
|
|
top = svc.score(defn, [3] * 9)
|
|
assert top["total_score"] == 27 and "sévère" in top["interpretation"].lower()
|
|
|
|
|
|
def test_authoring_custom_qcm(tmp_path):
|
|
s = _store(tmp_path)
|
|
defn = {
|
|
"type": "qcm",
|
|
"questions": [{"text": "Sommeil ?", "choices": [{"label": "Bon", "score": 0},
|
|
{"label": "Mauvais", "score": 2}]}],
|
|
"scoring": {"method": "sum", "ranges": [{"min": 0, "max": 1, "label": "ok"},
|
|
{"min": 2, "max": 2, "label": "alerte"}]},
|
|
}
|
|
svc.save_questionnaire(s, "sommeil", "Suivi sommeil", defn, now=NOW, actor="dr")
|
|
assert svc.score(defn, [1])["interpretation"] == "alerte"
|
|
assert svc.delete_questionnaire(s, "sommeil", now=NOW)["deleted"] is True
|
|
|
|
|
|
def test_assign_list_deactivate(tmp_path):
|
|
s = _store(tmp_path)
|
|
r = svc.assign(s, "phq9", "SER1", "p_1", {"mode": "recurring", "every_days": 7}, now=NOW, actor="dr")
|
|
aid = r["assignment_id"]
|
|
ags = svc.assignments(s, serial="SER1")
|
|
assert len(ags) == 1 and ags[0]["frequency"]["every_days"] == 7 and ags[0]["active"] == 1
|
|
svc.deactivate(s, aid, now=NOW, actor="dr")
|
|
assert svc.assignments(s, serial="SER1") == [] # active_only → filtré
|
|
|
|
|
|
def test_result_into_patient_dossier_encrypted(tmp_path):
|
|
s = _store(tmp_path)
|
|
out = svc.record_result(s, "phq9", "SER1", "p_1", [2, 2, 1, 1, 0, 0, 0, 0, 0], now=NOW, actor="dr")
|
|
assert out["total_score"] == 6 and out["interpretation"]
|
|
res = svc.patient_results(s, "SER1", "p_1")
|
|
assert len(res) == 1 and res[0]["result"]["total_score"] == 6
|
|
assert res[0]["result"]["answers"][0] == 2
|
|
# PII chiffrée au repos : le blob brut ne contient pas l'interprétation en clair
|
|
raw = s._db.execute("SELECT result_enc FROM questionnaire_results").fetchone()["result_enc"]
|
|
assert isinstance(raw, (bytes, memoryview)) and b"interpretation" not in bytes(raw)
|