2525from scim2_tester .urns import iter_all_urns
2626from scim2_tester .urns import set_value_by_urn
2727
28+
29+ def filter_sub_urns (parent_urn : str , allowed_urns : list [str ]) -> list [str ]:
30+ """Extract and normalize sub-URNs for a parent complex attribute.
31+
32+ Converts "parent.child" URNs to "child" URNs for use in the complex attribute context.
33+ """
34+ prefix = f"{ parent_urn } ."
35+ sub_urns = []
36+ for urn in allowed_urns :
37+ if urn .startswith (prefix ):
38+ sub_urn = urn .removeprefix (prefix )
39+ sub_urns .append (sub_urn )
40+ return sub_urns
41+
42+
2843if TYPE_CHECKING :
2944 from scim2_tester .utils import CheckContext
3045
@@ -69,6 +84,7 @@ def generate_random_value(
6984 context : "CheckContext" ,
7085 urn : str ,
7186 model : type [Resource ],
87+ allowed_urns : list [str ] | None = None ,
7288) -> Any :
7389 field_name = _find_field_name (model , urn )
7490 field_type = get_attribute_type_by_urn (model , urn )
@@ -124,10 +140,14 @@ def generate_random_value(
124140 value = random .choice (list (field_type ))
125141
126142 elif isclass (field_type ) and issubclass (field_type , ComplexAttribute ):
127- value = fill_complex_attribute_with_random_values (context , field_type ()) # type: ignore[arg-type]
143+ sub_urns = filter_sub_urns (urn , allowed_urns ) if allowed_urns else None
144+ value = fill_complex_attribute_with_random_values (
145+ context , field_type (), sub_urns
146+ ) # type: ignore[arg-type]
128147
129148 elif isclass (field_type ) and issubclass (field_type , Extension ):
130- value = fill_with_random_values (context , field_type ()) # type: ignore[arg-type]
149+ sub_urns = filter_sub_urns (urn , allowed_urns ) if allowed_urns else None
150+ value = fill_with_random_values (context , field_type (), sub_urns ) # type: ignore[arg-type]
131151
132152 elif field_type is Base64Bytes :
133153 value = base64 .b64encode (uuid .uuid4 ().bytes ).decode ("ascii" )
@@ -168,7 +188,9 @@ def fill_with_random_values(
168188 ]
169189
170190 for urn in urns :
171- value = generate_random_value (context , urn = urn , model = type (obj ))
191+ value = generate_random_value (
192+ context , urn = urn , model = type (obj ), allowed_urns = urns
193+ )
172194 set_value_by_urn (obj , urn , value )
173195
174196 fix_primary_attributes (obj )
@@ -179,13 +201,14 @@ def fill_with_random_values(
179201def fill_complex_attribute_with_random_values (
180202 context : "CheckContext" ,
181203 obj : ComplexAttribute ,
204+ urns : list [str ] | None = None ,
182205) -> Resource [Any ] | None :
183206 """Fill a ComplexAttribute with random values.
184207
185208 For SCIM reference fields, correctly sets the value field to match
186209 the ID extracted from the reference URL.
187210 """
188- fill_with_random_values (context , obj )
211+ fill_with_random_values (context , obj , urns )
189212 if "ref" in type (obj ).model_fields and "value" in type (obj ).model_fields :
190213 ref_type = type (obj ).get_field_root_type ("ref" )
191214 if (
0 commit comments