Skip to content

Commit cd709b8

Browse files
Peibing GuPeibing Gu
authored andcommitted
Updated tests for this story
1 parent 4ae3a2f commit cd709b8

4 files changed

Lines changed: 122 additions & 0 deletions

File tree

backend-api/tests/conftest.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ def admin_user() -> User:
4242
return make_user(role=Role.ADMIN.value, user_id=2)
4343

4444

45+
@pytest.fixture
46+
def auditor_user() -> User:
47+
return make_user(role=Role.AUDITOR.value, user_id=3)
48+
49+
4550
def _make_execute_result(items: list | None = None, single=None):
4651
result = MagicMock()
4752
scalars = MagicMock()
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
"""Unit tests for RBAC permission dependencies."""
2+
3+
import pytest
4+
from fastapi import HTTPException
5+
6+
from app.core.permissions import (
7+
RoleChecker,
8+
require_admin,
9+
require_auditor_or_above,
10+
require_viewer_or_above,
11+
)
12+
from app.models.user import Role
13+
from tests.conftest import make_user
14+
15+
16+
def test_require_auditor_or_above_allows_admin():
17+
user = make_user(role=Role.ADMIN.value)
18+
19+
result = require_auditor_or_above(user=user)
20+
21+
assert result is user
22+
23+
24+
def test_require_auditor_or_above_allows_auditor():
25+
user = make_user(role=Role.AUDITOR.value)
26+
27+
result = require_auditor_or_above(user=user)
28+
29+
assert result is user
30+
31+
32+
def test_require_auditor_or_above_rejects_viewer():
33+
user = make_user(role=Role.VIEWER.value)
34+
35+
with pytest.raises(HTTPException) as exc_info:
36+
require_auditor_or_above(user=user)
37+
38+
assert exc_info.value.status_code == 403
39+
assert exc_info.value.detail == "Auditor or Admin access required"
40+
41+
42+
def test_require_admin_allows_admin():
43+
user = make_user(role=Role.ADMIN.value)
44+
45+
result = require_admin(user=user)
46+
47+
assert result is user
48+
49+
50+
def test_require_admin_rejects_auditor():
51+
user = make_user(role=Role.AUDITOR.value)
52+
53+
with pytest.raises(HTTPException) as exc_info:
54+
require_admin(user=user)
55+
56+
assert exc_info.value.status_code == 403
57+
assert exc_info.value.detail == "Admin access required"
58+
59+
60+
def test_require_viewer_or_above_allows_viewer():
61+
user = make_user(role=Role.VIEWER.value)
62+
63+
result = require_viewer_or_above(user=user)
64+
65+
assert result is user
66+
67+
68+
def test_role_checker_allows_listed_roles():
69+
checker = RoleChecker([Role.ADMIN, Role.AUDITOR])
70+
auditor = make_user(role=Role.AUDITOR.value)
71+
72+
result = checker(user=auditor)
73+
74+
assert result is auditor
75+
76+
77+
def test_role_checker_rejects_unlisted_role():
78+
checker = RoleChecker([Role.ADMIN])
79+
viewer = make_user(role=Role.VIEWER.value)
80+
81+
with pytest.raises(HTTPException) as exc_info:
82+
checker(user=viewer)
83+
84+
assert exc_info.value.status_code == 403
85+
assert "Insufficient permissions" in exc_info.value.detail

backend-api/tests/test_rbac_m365_connections.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,19 @@ async def test_admin_passes_rbac_on_update_connection(client_factory, admin_user
8080
)
8181

8282
assert response.status_code != 403
83+
84+
85+
@pytest.mark.asyncio
86+
async def test_auditor_passes_rbac_on_create_connection(client_factory, auditor_user):
87+
async with client_factory(auditor_user) as client:
88+
response = await client.post("/v1/m365-connections/", json=CONNECTION_CREATE_BODY)
89+
90+
assert response.status_code != 403
91+
92+
93+
@pytest.mark.asyncio
94+
async def test_auditor_passes_rbac_on_delete_connection(client_factory, auditor_user):
95+
async with client_factory(auditor_user) as client:
96+
response = await client.delete("/v1/m365-connections/1")
97+
98+
assert response.status_code != 403

backend-api/tests/test_rbac_scans.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,19 @@ async def test_admin_passes_rbac_on_create_scan(client_factory, admin_user):
5454
response = await client.post("/v1/scans/", json=SCAN_CREATE_BODY)
5555

5656
assert response.status_code != 403
57+
58+
59+
@pytest.mark.asyncio
60+
async def test_auditor_passes_rbac_on_create_scan(client_factory, auditor_user):
61+
async with client_factory(auditor_user) as client:
62+
response = await client.post("/v1/scans/", json=SCAN_CREATE_BODY)
63+
64+
assert response.status_code != 403
65+
66+
67+
@pytest.mark.asyncio
68+
async def test_auditor_passes_rbac_on_delete_scan(client_factory, auditor_user):
69+
async with client_factory(auditor_user) as client:
70+
response = await client.delete("/v1/scans/1")
71+
72+
assert response.status_code != 403

0 commit comments

Comments
 (0)