44
55import base64
66import json
7- from typing import Optional
7+ from typing import Any , Optional
88
99import pytest
1010from fastapi import HTTPException , Request
1616
1717
1818@pytest .fixture
19- def user_identity_data () -> dict :
19+ def user_identity_data () -> dict [ str , Any ] :
2020 """Fixture providing valid User identity data.
2121
2222 Provide a valid Red Hat identity payload for a User, suitable for unit tests.
@@ -55,7 +55,7 @@ def user_identity_data() -> dict:
5555
5656
5757@pytest .fixture
58- def system_identity_data () -> dict :
58+ def system_identity_data () -> dict [ str , Any ] :
5959 """Fixture providing valid System identity data.
6060
6161 Provide a sample System identity payload used by tests.
@@ -85,7 +85,7 @@ def system_identity_data() -> dict:
8585
8686
8787@pytest .fixture
88- def service_account_identity_data () -> dict :
88+ def service_account_identity_data () -> dict [ str , Any ] :
8989 """Fixture providing valid ServiceAccount identity data.
9090
9191 Mirrors the canonical ServiceAccount payload from the identity-schemas repo.
@@ -113,7 +113,7 @@ def service_account_identity_data() -> dict:
113113 }
114114
115115
116- def create_auth_header (identity_data : dict ) -> str :
116+ def create_auth_header (identity_data : dict [ str , Any ] ) -> str :
117117 """Helper to create base64-encoded x-rh-identity header value.
118118
119119 Create a base64-encoded string suitable for use as an x-rh-identity header from identity data.
@@ -160,22 +160,22 @@ def create_request_with_header(
160160class TestRHIdentityData :
161161 """Test suite for RHIdentityData class."""
162162
163- def test_user_type_extraction (self , user_identity_data : dict ) -> None :
163+ def test_user_type_extraction (self , user_identity_data : dict [ str , Any ] ) -> None :
164164 """Test extraction of User identity fields."""
165165 rh_identity = RHIdentityData (user_identity_data )
166166
167167 assert rh_identity .get_user_id () == "abc123"
168168 assert rh_identity .get_username () == "user@redhat.com"
169169
170- def test_system_type_extraction (self , system_identity_data : dict ) -> None :
170+ def test_system_type_extraction (self , system_identity_data : dict [ str , Any ] ) -> None :
171171 """Test extraction of System identity fields."""
172172 rh_identity = RHIdentityData (system_identity_data )
173173
174174 assert rh_identity .get_user_id () == "c87dcb4c-8af1-40dd-878e-60c744edddd0"
175175 assert rh_identity .get_username () == "123"
176176
177177 def test_service_account_type_extraction (
178- self , service_account_identity_data : dict
178+ self , service_account_identity_data : dict [ str , Any ]
179179 ) -> None :
180180 """Test extraction of ServiceAccount identity fields."""
181181 rh_identity = RHIdentityData (service_account_identity_data )
@@ -187,7 +187,7 @@ def test_service_account_type_extraction(
187187 )
188188
189189 def test_service_account_system_id_empty (
190- self , service_account_identity_data : dict
190+ self , service_account_identity_data : dict [ str , Any ]
191191 ) -> None :
192192 """Test that get_system_id returns empty string for ServiceAccount type."""
193193 rh_identity = RHIdentityData (service_account_identity_data )
@@ -205,7 +205,7 @@ def test_get_org_id(
205205 rh_identity = RHIdentityData (identity_data )
206206 assert rh_identity .get_org_id () == "321"
207207
208- def test_get_org_id_missing (self , user_identity_data : dict ) -> None :
208+ def test_get_org_id_missing (self , user_identity_data : dict [ str , Any ] ) -> None :
209209 """Test org_id returns empty string when not present."""
210210 identity_data = {
211211 ** user_identity_data ,
@@ -225,7 +225,7 @@ def test_get_org_id_missing(self, user_identity_data: dict) -> None:
225225 ],
226226 )
227227 def test_has_entitlement (
228- self , user_identity_data : dict , service : str , expected : bool
228+ self , user_identity_data : dict [ str , Any ] , service : str , expected : bool
229229 ) -> None :
230230 """Test has_entitlement returns correct result for various services."""
231231 rh_identity = RHIdentityData (user_identity_data )
@@ -240,7 +240,7 @@ def test_has_entitlement(
240240 ],
241241 )
242242 def test_has_entitlements (
243- self , user_identity_data : dict , services : list [str ], expected : bool
243+ self , user_identity_data : dict [ str , Any ] , services : list [str ], expected : bool
244244 ) -> None :
245245 """Test has_entitlements returns correct result for service lists."""
246246 rh_identity = RHIdentityData (user_identity_data )
@@ -267,7 +267,7 @@ def test_has_entitlements(
267267 )
268268 def test_validate_entitlements (
269269 self ,
270- user_identity_data : dict ,
270+ user_identity_data : dict [ str , Any ] ,
271271 required_entitlements : Optional [list [str ]],
272272 should_raise : bool ,
273273 expected_error : Optional [str ],
@@ -388,7 +388,7 @@ def test_validate_entitlements(
388388 )
389389 def test_validation_failures (
390390 self ,
391- missing_field : dict ,
391+ missing_field : dict [ str , Any ] ,
392392 expected_error : str ,
393393 mocker : MockerFixture ,
394394 ) -> None :
@@ -422,7 +422,7 @@ class TestRHIdentityAuthDependency:
422422
423423 @pytest .mark .asyncio
424424 async def test_user_authentication_success (
425- self , mocker : MockerFixture , user_identity_data : dict
425+ self , mocker : MockerFixture , user_identity_data : dict [ str , Any ]
426426 ) -> None :
427427 """Test successful User authentication."""
428428 auth_dep = RHIdentityAuthDependency ()
@@ -436,7 +436,7 @@ async def test_user_authentication_success(
436436
437437 @pytest .mark .asyncio
438438 async def test_system_authentication_success (
439- self , mocker : MockerFixture , system_identity_data : dict
439+ self , mocker : MockerFixture , system_identity_data : dict [ str , Any ]
440440 ) -> None :
441441 """Test successful System authentication."""
442442 auth_dep = RHIdentityAuthDependency ()
@@ -452,7 +452,7 @@ async def test_system_authentication_success(
452452
453453 @pytest .mark .asyncio
454454 async def test_service_account_authentication_success (
455- self , mocker : MockerFixture , service_account_identity_data : dict
455+ self , mocker : MockerFixture , service_account_identity_data : dict [ str , Any ]
456456 ) -> None :
457457 """Test successful ServiceAccount authentication."""
458458 auth_dep = RHIdentityAuthDependency ()
@@ -558,7 +558,7 @@ async def test_invalid_json(self, mocker: MockerFixture) -> None:
558558 async def test_entitlement_validation ( # pylint: disable=too-many-arguments,too-many-positional-arguments
559559 self ,
560560 mocker : MockerFixture ,
561- user_identity_data : dict ,
561+ user_identity_data : dict [ str , Any ] ,
562562 required_entitlements : Optional [list [str ]],
563563 should_raise : bool ,
564564 expected_error : Optional [str ],
@@ -581,7 +581,7 @@ async def test_entitlement_validation( # pylint: disable=too-many-arguments,too
581581
582582 @pytest .mark .asyncio
583583 async def test_no_entitlement_data (
584- self , mocker : MockerFixture , user_identity_data : dict
584+ self , mocker : MockerFixture , user_identity_data : dict [ str , Any ]
585585 ) -> None :
586586 """Test authentication succeeds when no entitlements are present in identity data."""
587587 user_identity_data_no_entitlements = user_identity_data .copy ()
@@ -756,7 +756,7 @@ class TestRHIdentityHeaderSizeLimit:
756756
757757 @pytest .mark .asyncio
758758 async def test_header_at_exact_limit_accepted (
759- self , mocker : MockerFixture , user_identity_data : dict
759+ self , mocker : MockerFixture , user_identity_data : dict [ str , Any ]
760760 ) -> None :
761761 """Test that a header at exactly the size limit is accepted."""
762762 header_value = create_auth_header (user_identity_data )
@@ -815,7 +815,10 @@ class TestRHIdentityFieldValidation: # pylint: disable=too-many-public-methods
815815 ],
816816 )
817817 def test_user_non_string_types_rejected (
818- self , user_identity_data : dict , field_path : tuple [str , str ], bad_value : object
818+ self ,
819+ user_identity_data : dict [str , Any ],
820+ field_path : tuple [str , str ],
821+ bad_value : object ,
819822 ) -> None :
820823 """Reject non-string values in User identity string fields."""
821824 user_identity_data ["identity" ][field_path [0 ]][field_path [1 ]] = bad_value
@@ -840,7 +843,7 @@ def test_user_non_string_types_rejected(
840843 )
841844 def test_system_non_string_types_rejected (
842845 self ,
843- system_identity_data : dict ,
846+ system_identity_data : dict [ str , Any ] ,
844847 field_path : tuple [str , ...],
845848 bad_value : object ,
846849 ) -> None :
@@ -868,7 +871,7 @@ def test_system_non_string_types_rejected(
868871 )
869872 def test_service_account_non_string_types_rejected (
870873 self ,
871- service_account_identity_data : dict ,
874+ service_account_identity_data : dict [ str , Any ] ,
872875 field_path : tuple [str , str ],
873876 bad_value : object ,
874877 ) -> None :
@@ -882,7 +885,7 @@ def test_service_account_non_string_types_rejected(
882885
883886 @pytest .mark .parametrize ("bad_value" , ["" , " " , "\t " , "\n " ])
884887 def test_empty_whitespace_rejected (
885- self , user_identity_data : dict , bad_value : str
888+ self , user_identity_data : dict [ str , Any ] , bad_value : str
886889 ) -> None :
887890 """Reject empty and whitespace-only strings."""
888891 user_identity_data ["identity" ]["user" ]["user_id" ] = bad_value
@@ -895,49 +898,55 @@ def test_empty_whitespace_rejected(
895898 ["user\x00 id" , "user\n id" , "user\r id" , "a\x1f b" , "a\x7f b" ],
896899 )
897900 def test_control_characters_rejected (
898- self , user_identity_data : dict , bad_value : str
901+ self , user_identity_data : dict [ str , Any ] , bad_value : str
899902 ) -> None :
900903 """Reject strings containing control characters."""
901904 user_identity_data ["identity" ]["user" ]["user_id" ] = bad_value
902905 with pytest .raises (HTTPException ) as exc_info :
903906 RHIdentityData (user_identity_data )
904907 assert exc_info .value .status_code == 400
905908
906- def test_oversized_value_rejected (self , user_identity_data : dict ) -> None :
909+ def test_oversized_value_rejected (self , user_identity_data : dict [ str , Any ] ) -> None :
907910 """Reject values longer than 256 characters."""
908911 user_identity_data ["identity" ]["user" ]["user_id" ] = "a" * 257
909912 with pytest .raises (HTTPException ) as exc_info :
910913 RHIdentityData (user_identity_data )
911914 assert exc_info .value .status_code == 400
912915
913- def test_max_length_boundary_accepted (self , user_identity_data : dict ) -> None :
916+ def test_max_length_boundary_accepted (
917+ self , user_identity_data : dict [str , Any ]
918+ ) -> None :
914919 """Accept values exactly 256 characters long."""
915920 user_identity_data ["identity" ]["user" ]["user_id" ] = "a" * 256
916921 RHIdentityData (user_identity_data )
917922
918- def test_org_id_missing_accepted (self , user_identity_data : dict ) -> None :
923+ def test_org_id_missing_accepted (self , user_identity_data : dict [ str , Any ] ) -> None :
919924 """Allow missing org_id."""
920925 user_identity_data ["identity" ].pop ("org_id" , None )
921926 RHIdentityData (user_identity_data )
922927
923- def test_org_id_empty_accepted (self , user_identity_data : dict ) -> None :
928+ def test_org_id_empty_accepted (self , user_identity_data : dict [ str , Any ] ) -> None :
924929 """Allow empty org_id."""
925930 user_identity_data ["identity" ]["org_id" ] = ""
926931 RHIdentityData (user_identity_data )
927932
928- def test_org_id_non_string_rejected (self , user_identity_data : dict ) -> None :
933+ def test_org_id_non_string_rejected (
934+ self , user_identity_data : dict [str , Any ]
935+ ) -> None :
929936 """Reject non-string org_id when provided and non-empty."""
930937 user_identity_data ["identity" ]["org_id" ] = 12345
931938 with pytest .raises (HTTPException ) as exc_info :
932939 RHIdentityData (user_identity_data )
933940 assert exc_info .value .status_code == 400
934941
935- def test_org_id_valid_accepted (self , user_identity_data : dict ) -> None :
942+ def test_org_id_valid_accepted (self , user_identity_data : dict [ str , Any ] ) -> None :
936943 """Accept valid string org_id."""
937944 user_identity_data ["identity" ]["org_id" ] = "valid-org-id"
938945 RHIdentityData (user_identity_data )
939946
940- def test_org_id_oversized_rejected (self , user_identity_data : dict ) -> None :
947+ def test_org_id_oversized_rejected (
948+ self , user_identity_data : dict [str , Any ]
949+ ) -> None :
941950 """Reject oversized org_id.
942951
943952 Verifies that an identity with an org_id longer than 256 characters is rejected.
@@ -950,30 +959,36 @@ def test_org_id_oversized_rejected(self, user_identity_data: dict) -> None:
950959 RHIdentityData (user_identity_data )
951960 assert exc_info .value .status_code == 400
952961
953- def test_org_id_control_chars_rejected (self , user_identity_data : dict ) -> None :
962+ def test_org_id_control_chars_rejected (
963+ self , user_identity_data : dict [str , Any ]
964+ ) -> None :
954965 """Reject org_id containing control characters."""
955966 user_identity_data ["identity" ]["org_id" ] = "org\x00 id"
956967 with pytest .raises (HTTPException ) as exc_info :
957968 RHIdentityData (user_identity_data )
958969 assert exc_info .value .status_code == 400
959970
960- def test_valid_user_data_still_passes (self , user_identity_data : dict ) -> None :
971+ def test_valid_user_data_still_passes (
972+ self , user_identity_data : dict [str , Any ]
973+ ) -> None :
961974 """Regression: valid User identity data passes validation."""
962975 RHIdentityData (user_identity_data )
963976
964- def test_valid_system_data_still_passes (self , system_identity_data : dict ) -> None :
977+ def test_valid_system_data_still_passes (
978+ self , system_identity_data : dict [str , Any ]
979+ ) -> None :
965980 """Regression: valid System identity data passes validation."""
966981 RHIdentityData (system_identity_data )
967982
968983 def test_valid_service_account_data_still_passes (
969- self , service_account_identity_data : dict
984+ self , service_account_identity_data : dict [ str , Any ]
970985 ) -> None :
971986 """Regression: valid ServiceAccount identity data passes validation."""
972987 RHIdentityData (service_account_identity_data )
973988
974989 @pytest .mark .parametrize ("account_number" , ["" , None ])
975990 def test_system_empty_or_absent_account_number_accepted (
976- self , system_identity_data : dict , account_number : Optional [str ]
991+ self , system_identity_data : dict [ str , Any ] , account_number : Optional [str ]
977992 ) -> None :
978993 """Accept System identity with empty or absent account_number.
979994
@@ -1022,7 +1037,7 @@ def test_system_developer_subscription_identity_accepted(self) -> None:
10221037 assert rh_identity .get_org_id () == "18939564"
10231038
10241039 def test_system_present_account_number_unchanged (
1025- self , system_identity_data : dict
1040+ self , system_identity_data : dict [ str , Any ]
10261041 ) -> None :
10271042 """Regression: System with a present, non-empty account_number is unchanged.
10281043
@@ -1034,7 +1049,7 @@ def test_system_present_account_number_unchanged(
10341049
10351050 @pytest .mark .parametrize ("org_id" , ["" , None ])
10361051 def test_system_missing_org_id_rejected (
1037- self , system_identity_data : dict , org_id : Optional [str ]
1052+ self , system_identity_data : dict [ str , Any ] , org_id : Optional [str ]
10381053 ) -> None :
10391054 """Reject System identity when org_id is empty or absent.
10401055
@@ -1050,7 +1065,9 @@ def test_system_missing_org_id_rejected(
10501065 RHIdentityData (system_identity_data )
10511066 assert exc_info .value .status_code == 400
10521067
1053- def test_system_empty_cn_rejected (self , system_identity_data : dict ) -> None :
1068+ def test_system_empty_cn_rejected (
1069+ self , system_identity_data : dict [str , Any ]
1070+ ) -> None :
10541071 """Reject System identity when system cn is empty."""
10551072 system_identity_data ["identity" ]["system" ]["cn" ] = ""
10561073 with pytest .raises (HTTPException ) as exc_info :
0 commit comments