Skip to content

Commit dd5196d

Browse files
committed
Added type hints into tests/unit/authorization/test_resolvers.py
1 parent 1596bb7 commit dd5196d

1 file changed

Lines changed: 49 additions & 32 deletions

File tree

tests/unit/authorization/test_resolvers.py

Lines changed: 49 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import re
66
from contextlib import nullcontext as does_not_raise
77

8+
from typing import Any
89
import pytest
910

1011
from authentication.interface import AuthTuple
@@ -33,7 +34,7 @@ class TestJwtRolesResolver:
3334
"""Test cases for JwtRolesResolver."""
3435

3536
@pytest.fixture
36-
async def employee_role_rule(self) -> None:
37+
async def employee_role_rule(self) -> JwtRoleRule:
3738
"""Role rule for RedHat employees."""
3839
return JwtRoleRule(
3940
jsonpath="$.realm_access.roles[*]",
@@ -43,12 +44,14 @@ async def employee_role_rule(self) -> None:
4344
)
4445

4546
@pytest.fixture
46-
async def employee_resolver(self, employee_role_rule):
47+
async def employee_resolver(
48+
self, employee_role_rule: JwtRoleRule
49+
) -> JwtRolesResolver:
4750
"""JwtRolesResolver with a rule for RedHat employees."""
4851
return JwtRolesResolver([employee_role_rule])
4952

5053
@pytest.fixture
51-
async def employee_claims(self):
54+
async def employee_claims(self) -> dict[str, Any]:
5255
"""JWT claims for a RedHat employee."""
5356
return {
5457
"foo": "bar",
@@ -66,7 +69,7 @@ async def employee_claims(self):
6669
}
6770

6871
@pytest.fixture
69-
async def non_employee_claims(self):
72+
async def non_employee_claims(self) -> dict[str, Any]:
7073
"""JWT claims for a non-RedHat employee."""
7174
return {
7275
"exp": 1754489339,
@@ -76,14 +79,16 @@ async def non_employee_claims(self):
7679
}
7780

7881
async def test_resolve_roles_redhat_employee(
79-
self, employee_resolver, employee_claims
80-
):
82+
self, employee_resolver: JwtRolesResolver, employee_claims: dict[str, Any]
83+
) -> None:
8184
"""Test role extraction for RedHat employee JWT."""
8285
assert "employee" in await employee_resolver.resolve_roles(
8386
claims_to_auth_tuple(employee_claims)
8487
)
8588

86-
async def test_resolve_roles_no_match(self, employee_resolver, non_employee_claims):
89+
async def test_resolve_roles_no_match(
90+
self, employee_resolver: JwtRolesResolver, non_employee_claims: dict[str, Any]
91+
) -> None:
8792
"""Test no roles extracted for non-RedHat employee JWT."""
8893
assert (
8994
len(
@@ -94,7 +99,9 @@ async def test_resolve_roles_no_match(self, employee_resolver, non_employee_clai
9499
== 0
95100
)
96101

97-
async def test_negate_operator(self, employee_role_rule, non_employee_claims):
102+
async def test_negate_operator(
103+
self, employee_role_rule: JwtRoleRule, non_employee_claims: dict[str, Any]
104+
) -> None:
98105
"""Test role extraction with negated operator."""
99106
negated_rule = employee_role_rule
100107
negated_rule.negate = True
@@ -106,7 +113,7 @@ async def test_negate_operator(self, employee_role_rule, non_employee_claims):
106113
)
107114

108115
@pytest.fixture
109-
async def email_rule_resolver(self):
116+
async def email_rule_resolver(self) -> JwtRolesResolver:
110117
"""JwtRolesResolver with a rule for email domain."""
111118
return JwtRolesResolver(
112119
[
@@ -120,7 +127,7 @@ async def email_rule_resolver(self):
120127
)
121128

122129
@pytest.fixture
123-
async def equals_rule_resolver(self):
130+
async def equals_rule_resolver(self) -> JwtRolesResolver:
124131
"""JwtRolesResolver with a rule for exact email match."""
125132
return JwtRolesResolver(
126133
[
@@ -134,15 +141,15 @@ async def equals_rule_resolver(self):
134141
)
135142

136143
async def test_resolve_roles_equals_operator(
137-
self, equals_rule_resolver, employee_claims
138-
):
144+
self, equals_rule_resolver: JwtRolesResolver, employee_claims: dict[str, Any]
145+
) -> None:
139146
"""Test role extraction using EQUALS operator."""
140147
assert "foobar" in await equals_rule_resolver.resolve_roles(
141148
claims_to_auth_tuple(employee_claims)
142149
)
143150

144151
@pytest.fixture
145-
async def in_rule_resolver(self):
152+
async def in_rule_resolver(self) -> JwtRolesResolver:
146153
"""JwtRolesResolver with a rule for IN operator."""
147154
return JwtRolesResolver(
148155
[
@@ -155,23 +162,25 @@ async def in_rule_resolver(self):
155162
]
156163
)
157164

158-
async def test_resolve_roles_in_operator(self, in_rule_resolver, employee_claims):
165+
async def test_resolve_roles_in_operator(
166+
self, in_rule_resolver: JwtRolesResolver, employee_claims: dict[str, Any]
167+
) -> None:
159168
"""Test role extraction using IN operator."""
160169
assert "in_role" in await in_rule_resolver.resolve_roles(
161170
claims_to_auth_tuple(employee_claims)
162171
)
163172

164173
async def test_resolve_roles_match_operator_email_domain(
165-
self, email_rule_resolver, employee_claims
166-
):
174+
self, email_rule_resolver: JwtRolesResolver, employee_claims: dict[str, Any]
175+
) -> None:
167176
"""Test role extraction using MATCH operator with email domain regex."""
168177
assert "redhat_employee" in await email_rule_resolver.resolve_roles(
169178
claims_to_auth_tuple(employee_claims)
170179
)
171180

172181
async def test_resolve_roles_match_operator_no_match(
173-
self, email_rule_resolver, non_employee_claims
174-
):
182+
self, email_rule_resolver: JwtRolesResolver, non_employee_claims: dict[str, Any]
183+
) -> None:
175184
"""Test role extraction using MATCH operator with no match."""
176185
assert (
177186
len(
@@ -182,7 +191,7 @@ async def test_resolve_roles_match_operator_no_match(
182191
== 0
183192
)
184193

185-
async def test_resolve_roles_match_operator_invalid_regex(self):
194+
async def test_resolve_roles_match_operator_invalid_regex(self) -> None:
186195
"""Test that invalid regex patterns are rejected at rule creation time."""
187196
with pytest.raises(
188197
ValueError, match="Invalid regex pattern for MATCH operator"
@@ -194,7 +203,7 @@ async def test_resolve_roles_match_operator_invalid_regex(self):
194203
roles=["test_role"],
195204
)
196205

197-
async def test_resolve_roles_match_operator_non_string_pattern(self):
206+
async def test_resolve_roles_match_operator_non_string_pattern(self) -> None:
198207
"""Test that non-string regex patterns are rejected at rule creation time."""
199208
with pytest.raises(
200209
ValueError, match="MATCH operator requires a string pattern"
@@ -206,7 +215,7 @@ async def test_resolve_roles_match_operator_non_string_pattern(self):
206215
roles=["test_role"],
207216
)
208217

209-
async def test_resolve_roles_match_operator_non_string_value(self):
218+
async def test_resolve_roles_match_operator_non_string_value(self) -> None:
210219
"""Test role extraction using MATCH operator with non-string match value."""
211220
role_rules = [
212221
JwtRoleRule(
@@ -228,7 +237,7 @@ async def test_resolve_roles_match_operator_non_string_value(self):
228237
roles = await jwt_resolver.resolve_roles(auth)
229238
assert len(roles) == 0 # Non-string values don't match regex
230239

231-
async def test_compiled_regex_property(self):
240+
async def test_compiled_regex_property(self) -> None:
232241
"""Test that compiled regex pattern is properly created for MATCH operator."""
233242
# Test MATCH operator creates compiled regex
234243
match_rule = JwtRoleRule(
@@ -250,7 +259,9 @@ async def test_compiled_regex_property(self):
250259
)
251260
assert equals_rule.compiled_regex is None
252261

253-
async def test_resolve_roles_with_no_user_token(self, employee_resolver):
262+
async def test_resolve_roles_with_no_user_token(
263+
self, employee_resolver: JwtRolesResolver
264+
) -> None:
254265
"""Test NO_USER_TOKEN returns empty claims."""
255266
guest_tuple = (
256267
"user",
@@ -269,19 +280,19 @@ class TestGenericAccessResolver:
269280
"""Test cases for GenericAccessResolver."""
270281

271282
@pytest.fixture
272-
def admin_access_rules(self):
283+
def admin_access_rules(self) -> list[AccessRule]:
273284
"""Access rules with admin role for testing."""
274285
return [AccessRule(role="superuser", actions=[Action.ADMIN])]
275286

276287
@pytest.fixture
277-
def multi_role_access_rules(self):
288+
def multi_role_access_rules(self) -> list[AccessRule]:
278289
"""Access rules with multiple roles for testing."""
279290
return [
280291
AccessRule(role="user", actions=[Action.QUERY, Action.GET_MODELS]),
281292
AccessRule(role="moderator", actions=[Action.FEEDBACK]),
282293
]
283294

284-
async def test_check_access_with_valid_role(self):
295+
async def test_check_access_with_valid_role(self) -> None:
285296
"""Test access check with valid role."""
286297
access_rules = [
287298
AccessRule(role="employee", actions=[Action.QUERY, Action.GET_MODELS])
@@ -296,7 +307,7 @@ async def test_check_access_with_valid_role(self):
296307
has_access = resolver.check_access(Action.FEEDBACK, frozenset(["employee"]))
297308
assert has_access is False
298309

299-
async def test_check_access_with_invalid_role(self):
310+
async def test_check_access_with_invalid_role(self) -> None:
300311
"""Test access check with invalid role."""
301312
access_rules = [
302313
AccessRule(role="employee", actions=[Action.QUERY, Action.GET_MODELS])
@@ -306,7 +317,7 @@ async def test_check_access_with_invalid_role(self):
306317
has_access = resolver.check_access(Action.QUERY, {"visitor"})
307318
assert has_access is False
308319

309-
async def test_check_access_with_no_roles(self):
320+
async def test_check_access_with_no_roles(self) -> None:
310321
"""Test access check with no roles."""
311322
access_rules = [
312323
AccessRule(role="employee", actions=[Action.QUERY, Action.GET_MODELS])
@@ -316,27 +327,33 @@ async def test_check_access_with_no_roles(self):
316327
has_access = resolver.check_access(Action.QUERY, set())
317328
assert has_access is False
318329

319-
def test_admin_action_with_other_actions_raises_error(self):
330+
def test_admin_action_with_other_actions_raises_error(self) -> None:
320331
"""Test admin action with others raises ValueError."""
321332
with pytest.raises(ValueError):
322333
GenericAccessResolver(
323334
[AccessRule(role="superuser", actions=[Action.ADMIN, Action.QUERY])]
324335
)
325336

326-
def test_admin_role_allows_all_actions(self, admin_access_rules):
337+
def test_admin_role_allows_all_actions(
338+
self, admin_access_rules: list[AccessRule]
339+
) -> None:
327340
"""Test admin action allows all actions via recursive check."""
328341
resolver = GenericAccessResolver(admin_access_rules)
329342
assert resolver.check_access(Action.QUERY, {"superuser"}) is True
330343

331-
def test_admin_get_actions_excludes_admin_action(self, admin_access_rules):
344+
def test_admin_get_actions_excludes_admin_action(
345+
self, admin_access_rules: list[AccessRule]
346+
) -> None:
332347
"""Test get actions on a role with admin returns everything except ADMIN."""
333348
resolver = GenericAccessResolver(admin_access_rules)
334349
actions = resolver.get_actions({"superuser"})
335350
assert Action.ADMIN not in actions
336351
assert Action.QUERY in actions
337352
assert len(actions) == len(set(Action)) - 1
338353

339-
def test_get_actions_for_regular_users(self, multi_role_access_rules):
354+
def test_get_actions_for_regular_users(
355+
self, multi_role_access_rules: list[AccessRule]
356+
) -> None:
340357
"""Test non-admin user gets only their specific actions."""
341358
resolver = GenericAccessResolver(multi_role_access_rules)
342359
actions = resolver.get_actions({"user", "moderator"})

0 commit comments

Comments
 (0)