omnidiag / tests /test_rbac.py
yahyoha's picture
test: add comprehensive test suite for Features 2.1–2.6 (81 tests)
5b98477
Raw
History Blame Contribute Delete
4.37 kB
"""
Tests — Feature 2.3: RBAC
Verifies that clinical endpoints enforce role requirements.
"""
import pytest
HEART_PAYLOAD = {
"Age": 55,
"Sex": "M",
"ChestPainType": "ATA",
"RestingBP": 130,
"Cholesterol": 250,
"FastingBS": 0,
"RestingECG": "Normal",
"MaxHR": 150,
"ExerciseAngina": "N",
"Oldpeak": 1.5,
"ST_Slope": "Up",
}
class TestUnauthenticated:
async def test_predict_requires_auth(self, client, db_tables):
resp = await client.post("/api/v4/heart_disease/predict", json=HEART_PAYLOAD)
assert resp.status_code in (401, 403)
async def test_explain_requires_auth(self, client, db_tables):
resp = await client.post("/api/v4/heart_disease/explain", json=HEART_PAYLOAD)
assert resp.status_code in (401, 403)
async def test_counterfactuals_requires_auth(self, client, db_tables):
resp = await client.post("/api/v4/heart_disease/counterfactuals", json=HEART_PAYLOAD)
assert resp.status_code in (401, 403)
async def test_admin_audit_logs_requires_auth(self, client, db_tables):
resp = await client.get("/admin/audit-logs")
assert resp.status_code in (401, 403)
async def test_patients_requires_auth(self, client, db_tables):
resp = await client.get("/api/v4/patients/")
assert resp.status_code in (401, 403)
class TestViewerRole:
"""Viewer role must NOT access clinical or admin routes."""
async def test_viewer_cannot_predict(self, client, viewer_token):
resp = await client.post(
"/api/v4/heart_disease/predict",
json=HEART_PAYLOAD,
headers={"Authorization": f"Bearer {viewer_token}"},
)
assert resp.status_code == 403
async def test_viewer_cannot_explain(self, client, viewer_token):
resp = await client.post(
"/api/v4/heart_disease/explain",
json=HEART_PAYLOAD,
headers={"Authorization": f"Bearer {viewer_token}"},
)
assert resp.status_code == 403
async def test_viewer_cannot_access_admin(self, client, viewer_token):
resp = await client.get(
"/admin/audit-logs",
headers={"Authorization": f"Bearer {viewer_token}"},
)
assert resp.status_code == 403
class TestDoctorRole:
"""Doctor role should have clinical access but NOT admin access."""
async def test_doctor_can_predict(self, client, doctor_token):
resp = await client.post(
"/api/v4/heart_disease/predict",
json=HEART_PAYLOAD,
headers={"Authorization": f"Bearer {doctor_token}"},
)
assert resp.status_code == 200
async def test_doctor_can_explain(self, client, doctor_token):
resp = await client.post(
"/api/v4/heart_disease/explain",
json=HEART_PAYLOAD,
headers={"Authorization": f"Bearer {doctor_token}"},
)
assert resp.status_code == 200
async def test_doctor_cannot_access_admin(self, client, doctor_token):
resp = await client.get(
"/admin/audit-logs",
headers={"Authorization": f"Bearer {doctor_token}"},
)
assert resp.status_code == 403
async def test_doctor_cannot_flush_cache(self, client, doctor_token):
resp = await client.post(
"/admin/cache/flush",
headers={"Authorization": f"Bearer {doctor_token}"},
)
assert resp.status_code == 403
class TestAdminRole:
"""super_admin should have access to everything."""
async def test_admin_can_predict(self, client, admin_token):
resp = await client.post(
"/api/v4/heart_disease/predict",
json=HEART_PAYLOAD,
headers={"Authorization": f"Bearer {admin_token}"},
)
assert resp.status_code == 200
async def test_admin_can_access_audit_logs(self, client, admin_token):
resp = await client.get(
"/admin/audit-logs",
headers={"Authorization": f"Bearer {admin_token}"},
)
assert resp.status_code == 200
async def test_admin_can_flush_cache(self, client, admin_token):
resp = await client.post(
"/admin/cache/flush",
headers={"Authorization": f"Bearer {admin_token}"},
)
assert resp.status_code == 200