79 lines
2.6 KiB
Python
79 lines
2.6 KiB
Python
"""Tests d'intégration API ↔ store (unlock, labels patients, audit)."""
|
|
|
|
import nacl.pwhash
|
|
from fastapi.testclient import TestClient
|
|
|
|
from kazeia_central.adb import Adb
|
|
from kazeia_central.adb.client import AdbDevice
|
|
from kazeia_central.api.app import create_app
|
|
from kazeia_central.store import Store
|
|
|
|
_OPS = nacl.pwhash.argon2id.OPSLIMIT_MIN
|
|
_MEM = nacl.pwhash.argon2id.MEMLIMIT_MIN
|
|
|
|
|
|
class _FakeAdb(Adb):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def devices(self):
|
|
return [AdbDevice(serial="ABC123", state="device", props={"model": "Pad3"})]
|
|
|
|
|
|
def _client(tmp_path):
|
|
store = Store(tmp_path / "central.db", kdf_ops=_OPS, kdf_mem=_MEM)
|
|
return TestClient(create_app(adb=_FakeAdb(), store=store))
|
|
|
|
|
|
def test_lock_unlock_flow(tmp_path):
|
|
c = _client(tmp_path)
|
|
st = c.get("/api/lock-status").json()
|
|
assert st == {"initialized": False, "unlocked": False}
|
|
|
|
r = c.post("/api/unlock", json={"password": "oppass"}).json()
|
|
assert r["unlocked"] and r["initialized_now"]
|
|
assert c.get("/api/lock-status").json()["unlocked"] is True
|
|
|
|
|
|
def test_label_requires_unlock_then_persists(tmp_path):
|
|
c = _client(tmp_path)
|
|
# verrouillé → 423
|
|
assert c.put("/api/devices/ABC123/label", json={"label": "X"}).status_code == 423
|
|
|
|
c.post("/api/unlock", json={"password": "pw"})
|
|
# device listé sans label au départ
|
|
devs = c.get("/api/devices").json()
|
|
assert devs[0]["serial"] == "ABC123" and devs[0]["label"] is None
|
|
# on nomme
|
|
c.put("/api/devices/ABC123/label", json={"label": "Mme D."})
|
|
devs = c.get("/api/devices").json()
|
|
assert devs[0]["label"] == "Mme D."
|
|
|
|
|
|
def test_wrong_password_401(tmp_path):
|
|
c = _client(tmp_path)
|
|
c.post("/api/unlock", json={"password": "right"})
|
|
# re-lock puis mauvais mdp
|
|
c.post("/api/lock")
|
|
assert c.post("/api/unlock", json={"password": "wrong"}).status_code == 401
|
|
|
|
|
|
def test_audit_trace(tmp_path):
|
|
c = _client(tmp_path)
|
|
c.post("/api/unlock", json={"password": "pw"})
|
|
c.put("/api/devices/ABC123/label", json={"label": "Mme D."})
|
|
actions = [a["action"] for a in c.get("/api/audit").json()]
|
|
assert "store_init" in actions and "set_label" in actions
|
|
# le label (PII) ne doit PAS apparaître en clair dans l'audit
|
|
raw = c.get("/api/audit").text
|
|
assert "Mme D." not in raw
|
|
|
|
|
|
def test_locked_hides_labels(tmp_path):
|
|
c = _client(tmp_path)
|
|
c.post("/api/unlock", json={"password": "pw"})
|
|
c.put("/api/devices/ABC123/label", json={"label": "Secret"})
|
|
c.post("/api/lock")
|
|
devs = c.get("/api/devices").json()
|
|
assert "label" not in devs[0] # verrouillé → pas d'enrichissement
|