Skip to content

Commit 10809b4

Browse files
committed
Correctly set values for Reference objects in parent object
1 parent 3d29aa7 commit 10809b4

File tree

2 files changed

+70
-5
lines changed

2 files changed

+70
-5
lines changed

scim2_tester/filling.py

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def generate_random_value(
4848
context: CheckContext,
4949
obj: Resource[Any],
5050
field_name: str,
51+
ref_objs: dict[str, Resource[Any]],
5152
) -> Any:
5253
field_type = obj.get_field_root_type(field_name)
5354

@@ -71,6 +72,17 @@ def generate_random_value(
7172
elif field_name == "value" and "phone" in obj.__class__.__name__.lower():
7273
value = "".join(str(random.choice(range(10))) for _ in range(10))
7374

75+
elif field_name == "value" and obj.__class__.__name__.lower() in ref_objs:
76+
value = ref_objs[obj.__class__.__name__.lower()].id
77+
78+
elif field_name == "type" and obj.__class__.__name__.lower() in ref_objs:
79+
value = ref_objs[obj.__class__.__name__.lower()].meta.resource_type
80+
81+
elif (
82+
field_name == "display" or field_name == "display_name"
83+
) and obj.__class__.__name__.lower() in ref_objs:
84+
value = ref_objs[obj.__class__.__name__.lower()].display_name
85+
7486
elif field_type is int:
7587
value = uuid.uuid4().int
7688

@@ -80,9 +92,8 @@ def generate_random_value(
8092
elif get_origin(field_type) is Reference and get_args(field_type)[0] != Any:
8193
ref_type = get_args(field_type)[0]
8294
if ref_type not in (ExternalReference, URIReference):
83-
model = model_from_ref_type(context, ref_type, different_than=obj.__class__)
84-
ref_obj = context.resource_manager.create_and_register(model)
85-
value = ref_obj.meta.location
95+
if obj.__class__.__name__.lower() in ref_objs:
96+
value = ref_objs[obj.__class__.__name__.lower()].meta.location
8697

8798
else:
8899
value = f"https://{str(uuid.uuid4())}.test"
@@ -102,6 +113,21 @@ def generate_random_value(
102113
return value
103114

104115

116+
def create_ref_object(
117+
context: CheckContext,
118+
obj: Resource[Any],
119+
field_name: str,
120+
) -> dict[str, Resource[Any]] | None:
121+
field_type = obj.get_field_root_type(field_name)
122+
if get_origin(field_type) is Reference and get_args(field_type)[0] != Any:
123+
ref_type = get_args(field_type)[0]
124+
if ref_type not in (ExternalReference, URIReference):
125+
model = model_from_ref_type(context, ref_type, different_than=obj.__class__)
126+
return context.resource_manager.create_and_register(model)
127+
128+
return None
129+
130+
105131
def fill_with_random_values(
106132
context: CheckContext,
107133
obj: Resource[Any],
@@ -114,6 +140,21 @@ def fill_with_random_values(
114140
:param field_names: Optional list of field names to fill (defaults to all)
115141
:returns: The filled object or None if the object ends up empty
116142
"""
143+
ref_objs = {}
144+
for field_name in (
145+
field_names if field_names is not None else obj.__class__.model_fields.keys()
146+
):
147+
if field_name not in obj.__class__.model_fields:
148+
continue
149+
150+
field = obj.__class__.model_fields[field_name]
151+
if field.default:
152+
continue
153+
154+
ref_obj = create_ref_object(context, obj, field_name)
155+
if ref_obj is not None:
156+
ref_objs[obj.__class__.__name__.lower()] = ref_obj
157+
117158
for field_name in (
118159
field_names if field_names is not None else obj.__class__.model_fields.keys()
119160
):
@@ -124,7 +165,7 @@ def fill_with_random_values(
124165
if field.default:
125166
continue
126167

127-
value = generate_random_value(context, obj, field_name)
168+
value = generate_random_value(context, obj, field_name, ref_objs)
128169

129170
is_multiple = obj.get_field_multiplicity(field_name)
130171
if is_multiple:

tests/test_filling.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
"""Test automatic field filling functionality."""
22

33
import base64
4+
import uuid
45
from typing import Literal
56
from unittest.mock import patch
67

78
from scim2_models import Group
9+
from scim2_models import Meta
810
from scim2_models import User
11+
from scim2_models.resources.resource_type import ResourceType
912
from scim2_models.resources.user import X509Certificate
1013

1114
from scim2_tester.filling import fill_with_random_values
@@ -23,6 +26,14 @@ def get_resource_model(self, model_name):
2326
model_map = {"User": User, "Group": Group}
2427
return model_map.get(model_name)
2528

29+
def create(self, obj):
30+
obj.id = str(uuid.uuid4())
31+
obj.meta = Meta(
32+
location=f"http://scim-tester.test/{obj.id}",
33+
resource_type=ResourceType.from_resource(obj).name,
34+
)
35+
return obj
36+
2637

2738
def test_generate_random_value_bytes_field():
2839
"""Validates random value generation for bytes fields."""
@@ -31,7 +42,7 @@ def test_generate_random_value_bytes_field():
3142

3243
cert = X509Certificate(value=base64.b64encode(b"placeholder"))
3344

34-
value = generate_random_value(context, cert, "value")
45+
value = generate_random_value(context, cert, "value", {})
3546

3647
assert isinstance(value, str)
3748
assert len(value) == 36 # UUID string length
@@ -50,6 +61,19 @@ def test_model_resolution_from_reference_type():
5061
assert result == User
5162

5263

64+
def test_generate_random_value_for_reference():
65+
"""Validates random value generation for reference fields."""
66+
config = CheckConfig()
67+
context = CheckContext(MockClient(), config)
68+
69+
group = Group()
70+
71+
result = fill_with_random_values(context, group)
72+
73+
assert len(result.members) == 1
74+
assert result.members[0].value == result.members[0].ref.rsplit("/", 1)[-1]
75+
76+
5377
def test_fill_with_empty_field_list():
5478
"""Confirms no fields are modified when empty field list provided."""
5579
conf = CheckConfig()

0 commit comments

Comments
 (0)