Kazeia-central/tests/test_api_store.py

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