fund-flow-backend / tests /test_case_access.py
Aniket2006's picture
feat: Story Mode v2 — cluster boundaries toggle, Path Finder, fraud pattern highlighting, and UI toolbar fixes
bb050ce
Raw
History Blame Contribute Delete
2.64 kB
"""
Automated unit/integration tests to verify Case Access Control.
Ensures that an investigator can only access and edit their own cases (or guest sessions).
"""
from fastapi.testclient import TestClient
from server import app
# We use headers with "Bearer guest:<user_id>" to simulate active investigator sessions
ALICE_HEADERS = {"Authorization": "Bearer guest:user_alice"}
BOB_HEADERS = {"Authorization": "Bearer guest:user_bob"}
def test_row_level_access_control():
client = TestClient(app)
# 1. Create a case as Alice
create_resp = client.post(
"/api/v1/cases",
json={
"title": "Alice's Investigation",
"description": "Cyclic round tripping suspected.",
"priority": "HIGH",
"primary_subject_account_id": "ACC_11111",
"subject_account_ids": ["ACC_11111"],
"tags": ["suspicious", "ml_flagged"]
},
headers=ALICE_HEADERS
)
assert create_resp.status_code == 201, create_resp.text
case = create_resp.json()
case_id = case["id"]
assert case["investigator_id"] == "user_alice"
# 2. Alice can read her own case details
get_resp = client.get(f"/api/v1/cases/{case_id}", headers=ALICE_HEADERS)
assert get_resp.status_code == 200
assert get_resp.json()["id"] == case_id
# 3. Bob attempts to read Alice's case -> 403 Forbidden
get_resp_bob = client.get(f"/api/v1/cases/{case_id}", headers=BOB_HEADERS)
assert get_resp_bob.status_code == 403, get_resp_bob.text
assert "access" in get_resp_bob.json()["detail"].lower()
# 4. Bob attempts to update Alice's case -> 403 Forbidden
patch_resp_bob = client.patch(
f"/api/v1/cases/{case_id}",
json={"title": "Bob's Malicious Edit"},
headers=BOB_HEADERS
)
assert patch_resp_bob.status_code == 403
# 5. Bob attempts to list cases -> Alice's case is NOT returned in Bob's list
list_resp_bob = client.get("/api/v1/cases", headers=BOB_HEADERS)
assert list_resp_bob.status_code == 200
items = list_resp_bob.json()["items"]
for item in items:
assert item["id"] != case_id
# 6. Alice can successfully update her case
patch_resp_alice = client.patch(
f"/api/v1/cases/{case_id}",
json={"title": "Alice's Authorized Edit"},
headers=ALICE_HEADERS
)
assert patch_resp_alice.status_code == 200
assert patch_resp_alice.json()["title"] == "Alice's Authorized Edit"
# 7. Alice can delete/soft-delete her case
del_resp = client.delete(f"/api/v1/cases/{case_id}", headers=ALICE_HEADERS)
assert del_resp.status_code == 204