88from scim2_models import InvalidPathException
99from scim2_models import PatchOp
1010from scim2_models import PatchOperation
11- from scim2_models import PathNotFoundException
1211from scim2_models import User
1312from scim2_models .resources .enterprise_user import EnterpriseUser
1413from scim2_models .resources .resource import Resource
@@ -26,9 +25,9 @@ def test_patch_operation_extension_simple_attribute():
2625 }
2726 )
2827
29- patch1 = PatchOp [User ](
28+ patch1 = PatchOp [User [ EnterpriseUser ] ](
3029 operations = [
31- PatchOperation [User ](
30+ PatchOperation [User [ EnterpriseUser ] ](
3231 op = PatchOperation .Op .replace_ ,
3332 path = "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:employeeNumber" ,
3433 value = "54321" ,
@@ -39,9 +38,9 @@ def test_patch_operation_extension_simple_attribute():
3938 assert result is True
4039 assert user [EnterpriseUser ].employee_number == "54321"
4140
42- patch2 = PatchOp [User ](
41+ patch2 = PatchOp [User [ EnterpriseUser ] ](
4342 operations = [
44- PatchOperation [User ](
43+ PatchOperation [User [ EnterpriseUser ] ](
4544 op = PatchOperation .Op .add ,
4645 path = "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:organization" ,
4746 value = "ACME Corp" ,
@@ -52,9 +51,9 @@ def test_patch_operation_extension_simple_attribute():
5251 assert result is True
5352 assert user [EnterpriseUser ].organization == "ACME Corp"
5453
55- patch3 = PatchOp [User ](
54+ patch3 = PatchOp [User [ EnterpriseUser ] ](
5655 operations = [
57- PatchOperation [User ](
56+ PatchOperation [User [ EnterpriseUser ] ](
5857 op = PatchOperation .Op .remove ,
5958 path = "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:costCenter" ,
6059 )
@@ -77,9 +76,9 @@ def test_patch_operation_extension_complex_attribute():
7776 }
7877 )
7978
80- patch1 = PatchOp [User ](
79+ patch1 = PatchOp [User [ EnterpriseUser ] ](
8180 operations = [
82- PatchOperation [User ](
81+ PatchOperation [User [ EnterpriseUser ] ](
8382 op = PatchOperation .Op .replace_ ,
8483 path = "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:manager.value" ,
8584 value = "new-manager-456" ,
@@ -91,9 +90,9 @@ def test_patch_operation_extension_complex_attribute():
9190 assert user [EnterpriseUser ].manager .value == "new-manager-456"
9291 assert user [EnterpriseUser ].manager .display_name == "John Smith"
9392
94- patch2 = PatchOp [User ](
93+ patch2 = PatchOp [User [ EnterpriseUser ] ](
9594 operations = [
96- PatchOperation [User ](
95+ PatchOperation [User [ EnterpriseUser ] ](
9796 op = PatchOperation .Op .replace_ ,
9897 path = "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:manager" ,
9998 value = {
@@ -109,9 +108,9 @@ def test_patch_operation_extension_complex_attribute():
109108 assert user [EnterpriseUser ].manager .value == "super-manager-789"
110109 assert user [EnterpriseUser ].manager .display_name == "Alice Johnson"
111110
112- patch3 = PatchOp [User ](
111+ patch3 = PatchOp [User [ EnterpriseUser ] ](
113112 operations = [
114- PatchOperation [User ](
113+ PatchOperation [User [ EnterpriseUser ] ](
115114 op = PatchOperation .Op .remove ,
116115 path = "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:manager" ,
117116 )
@@ -139,9 +138,9 @@ def test_patch_operation_extension_mutability_handled_by_model():
139138
140139 # This operation would fail during model validation for mutability,
141140 # but patch method assumes operations are already validated
142- patch = PatchOp [User ](
141+ patch = PatchOp [User [ EnterpriseUser ] ](
143142 operations = [
144- PatchOperation [User ](
143+ PatchOperation [User [ EnterpriseUser ] ](
145144 op = PatchOperation .Op .replace_ ,
146145 path = "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:employeeNumber" ,
147146 value = "12345" ,
@@ -154,38 +153,30 @@ def test_patch_operation_extension_mutability_handled_by_model():
154153
155154
156155def test_patch_operation_extension_invalid_path_error ():
157- """Test invalidPath error for non-existent extension attributes.
158-
159- :rfc:`RFC7644 §3.5.2 <7644#section-3.5.2>`: invalidPath errors occur when
160- the path references an attribute that doesn't exist in the schema.
161- """
162- user = User [EnterpriseUser ].model_validate ({"userName" : "test.user" })
163-
164- patch1 = PatchOp [User ](
165- operations = [
166- PatchOperation [User ](
167- op = PatchOperation .Op .add ,
168- path = "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:invalidAttribute" ,
169- value = "test" ,
170- )
171- ]
172- )
173- with pytest .raises (InvalidPathException ):
174- patch1 .patch (user )
175- assert user [EnterpriseUser ] is None
156+ """An attribute the extension does not declare is refused, and so is its sub-attribute."""
157+ with pytest .raises (ValidationError ) as raised :
158+ PatchOp [User [EnterpriseUser ]](
159+ operations = [
160+ PatchOperation [User [EnterpriseUser ]](
161+ op = PatchOperation .Op .add ,
162+ path = "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:invalidAttribute" ,
163+ value = "test" ,
164+ )
165+ ]
166+ )
167+ assert raised .value .errors ()[0 ]["type" ] == "scim_invalidPath"
176168
177- patch2 = PatchOp [User ](
178- operations = [
179- PatchOperation [User ](
180- op = PatchOperation .Op .add ,
181- path = "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:manager.invalidField" ,
182- value = "test" ,
183- )
184- ]
185- )
186- with pytest .raises (InvalidPathException ):
187- patch2 .patch (user )
188- assert user [EnterpriseUser ] is None
169+ with pytest .raises (ValidationError ) as raised :
170+ PatchOp [User [EnterpriseUser ]](
171+ operations = [
172+ PatchOperation [User [EnterpriseUser ]](
173+ op = PatchOperation .Op .add ,
174+ path = "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:manager.invalidField" ,
175+ value = "test" ,
176+ )
177+ ]
178+ )
179+ assert raised .value .errors ()[0 ]["type" ] == "scim_invalidPath"
189180
190181
191182def test_urn_parsing_errors ():
@@ -230,17 +221,16 @@ class TestResourceTypeVar(Resource):
230221
231222 typevar_field : T = None
232223
233- user = TestResourceTypeVar ()
234- patch = PatchOp [TestResourceTypeVar ](
235- operations = [
236- PatchOperation [TestResourceTypeVar ](
237- op = PatchOperation .Op .add , path = "typevarField.subfield" , value = "test"
238- )
239- ]
240- )
224+ with pytest . raises ( ValidationError ) as raised :
225+ PatchOp [TestResourceTypeVar ](
226+ operations = [
227+ PatchOperation [TestResourceTypeVar ](
228+ op = PatchOperation .Op .add , path = "typevarField.subfield" , value = "test"
229+ )
230+ ]
231+ )
241232
242- with pytest .raises (PathNotFoundException ):
243- patch .patch (user )
233+ assert raised .value .errors ()[0 ]["type" ] == "scim_invalidPath"
244234
245235
246236def test_add_creates_the_parent_of_a_complex_attribute ():
@@ -270,9 +260,9 @@ def test_patch_extension_schema_path_without_attribute():
270260 )
271261 user [EnterpriseUser ] = EnterpriseUser ()
272262
273- patch = PatchOp [User ](
263+ patch = PatchOp [User [ EnterpriseUser ] ](
274264 operations = [
275- PatchOperation [User ](
265+ PatchOperation [User [ EnterpriseUser ] ](
276266 op = PatchOperation .Op .add ,
277267 path = "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User" ,
278268 value = {
@@ -350,9 +340,9 @@ def test_patch_delete_extension_root():
350340 assert user [EnterpriseUser ].employee_number == "12345"
351341 assert user [EnterpriseUser ].cost_center == "Engineering"
352342
353- patch = PatchOp [User ](
343+ patch = PatchOp [User [ EnterpriseUser ] ](
354344 operations = [
355- PatchOperation [User ](
345+ PatchOperation [User [ EnterpriseUser ] ](
356346 op = PatchOperation .Op .remove ,
357347 path = "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User" ,
358348 )
0 commit comments