55import re
66from contextlib import nullcontext as does_not_raise
77
8+ from typing import Any
89import pytest
910
1011from 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