Skip to content

Commit d0f1a25

Browse files
committed
feat: create temporary objects to test references
1 parent 3ff1c4c commit d0f1a25

3 files changed

Lines changed: 67 additions & 20 deletions

File tree

doc/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Changelog
77
Added
88
^^^^^
99
- Slightly improved error messages.
10+
- Create temporary resources to test references.
1011

1112
[0.1.10] - 2024-12-02
1213
---------------------

scim2_tester/resource.py

Lines changed: 65 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from scim2_models import Resource
1818
from scim2_models import ResourceType
1919
from scim2_models import URIReference
20+
from scim2_models.utils import UNION_TYPES
2021

2122
from scim2_tester.utils import CheckConfig
2223
from scim2_tester.utils import CheckResult
@@ -34,8 +35,46 @@ def model_from_resource_type(
3435
return None
3536

3637

37-
def fill_with_random_values(obj: Resource) -> Resource:
38-
for field_name, field in obj.model_fields.items():
38+
def create_minimal_object(
39+
conf: CheckConfig, model: type[Resource]
40+
) -> tuple[Resource, list[Resource]]:
41+
"""Create an object filling with the minimum required field set."""
42+
field_names = [
43+
field_name
44+
for field_name in model.model_fields.keys()
45+
if model.get_field_annotation(field_name, Required) == Required.true
46+
]
47+
obj, garbages = fill_with_random_values(conf, model(), field_names)
48+
obj = conf.client.create(obj)
49+
return obj, garbages
50+
51+
52+
def model_from_ref_type(
53+
conf: CheckConfig, ref_type: type, different_than: Resource
54+
) -> type[Resource]:
55+
def model_from_ref_type_(ref_type):
56+
if get_origin(ref_type) in UNION_TYPES:
57+
return [
58+
model_from_ref_type_(sub_ref_type)
59+
for sub_ref_type in get_args(ref_type)
60+
]
61+
62+
model_name = get_args(ref_type)[0]
63+
model = conf.client.get_resource_model(model_name)
64+
return model
65+
66+
models = model_from_ref_type_(ref_type)
67+
models = models if isinstance(models, list) else [models]
68+
acceptable_models = [model for model in models if model != different_than]
69+
return acceptable_models[0]
70+
71+
72+
def fill_with_random_values(
73+
conf: CheckConfig, obj: Resource, field_names: list[str] | None = None
74+
) -> Resource:
75+
garbages = []
76+
for field_name in field_names or obj.model_fields.keys():
77+
field = obj.model_fields[field_name]
3978
if field.default:
4079
continue
4180

@@ -61,27 +100,28 @@ def fill_with_random_values(obj: Resource) -> Resource:
61100
value = base64.b64encode(str(uuid.uuid4()).encode("utf-8"))
62101

63102
elif get_origin(field_type) is Reference:
64-
if get_args(field_type)[0] not in (
65-
ExternalReference,
66-
URIReference,
67-
):
68-
if (
69-
obj.__class__.get_field_annotation(field_name, Required)
70-
== Required.true
71-
):
72-
return None
73-
continue
74-
75-
value = f"https://{str(uuid.uuid4())}.test"
103+
ref_type = get_args(field_type)[0]
104+
if ref_type not in (ExternalReference, URIReference):
105+
model = model_from_ref_type(
106+
conf, ref_type, different_than=obj.__class__
107+
)
108+
ref_obj, sub_garbages = create_minimal_object(conf, model)
109+
value = ref_obj.meta.location
110+
garbages += sub_garbages
111+
112+
else:
113+
value = f"https://{str(uuid.uuid4())}.test"
76114

77115
elif isclass(field_type) and issubclass(field_type, Enum):
78116
value = random.choice(list(field_type))
79117

80118
elif isclass(field_type) and issubclass(field_type, ComplexAttribute):
81-
value = fill_with_random_values(field_type())
119+
value, sub_garbages = fill_with_random_values(conf, field_type())
120+
garbages += sub_garbages
82121

83122
elif isclass(field_type) and issubclass(field_type, Extension):
84-
value = fill_with_random_values(field_type())
123+
value, sub_garbages = fill_with_random_values(conf, field_type())
124+
garbages += sub_garbages
85125

86126
else:
87127
# Put emails so this will be accepted by EmailStr too
@@ -93,7 +133,7 @@ def fill_with_random_values(obj: Resource) -> Resource:
93133
else:
94134
setattr(obj, field_name, value)
95135

96-
return obj
136+
return obj, garbages
97137

98138

99139
@checker
@@ -217,7 +257,9 @@ def check_resource_type(
217257
]
218258

219259
results = []
220-
obj = fill_with_random_values(model())
260+
garbages = []
261+
obj, obj_garbages = fill_with_random_values(conf, model())
262+
garbages += obj_garbages
221263

222264
result = check_object_creation(conf, obj)
223265
results.append(result)
@@ -231,11 +273,15 @@ def check_resource_type(
231273
result = check_object_query_without_id(conf, created_obj)
232274
results.append(result)
233275

234-
fill_with_random_values(queried_obj)
276+
_, obj_garbages = fill_with_random_values(conf, queried_obj)
277+
garbages += obj_garbages
235278
result = check_object_replacement(conf, created_obj)
236279
results.append(result)
237280

238281
result = check_object_deletion(conf, created_obj)
239282
results.append(result)
240283

284+
for garbage in reversed(garbages):
285+
conf.client.delete(garbage)
286+
241287
return results

tests/test_resource.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class Type(str, Enum):
4848
def test_random_values():
4949
"""Check that 'fill_with_random_values' produce valid objects."""
5050
obj = CustomModel()
51-
fill_with_random_values(obj)
51+
fill_with_random_values(None, obj)
5252
for field_name in obj.model_fields:
5353
if field_name == "meta":
5454
continue

0 commit comments

Comments
 (0)