1- import base64
2- import random
3- import uuid
4- from enum import Enum
5- from inspect import isclass
6- from typing import Annotated
7- from typing import Any
8- from typing import get_args
9- from typing import get_origin
10-
11- from scim2_models import ComplexAttribute
12- from scim2_models import Extension
13- from scim2_models import ExternalReference
14- from scim2_models import Meta
151from scim2_models import Mutability
16- from scim2_models import Reference
17- from scim2_models import Required
182from scim2_models import Resource
193from scim2_models import ResourceType
20- from scim2_models import URIReference
21- from scim2_models .utils import UNION_TYPES
224
5+ from scim2_tester .filling import fill_with_random_values
236from scim2_tester .utils import CheckConfig
247from scim2_tester .utils import CheckResult
258from scim2_tester .utils import Status
@@ -36,107 +19,6 @@ def model_from_resource_type(
3619 return None
3720
3821
39- def create_minimal_object (
40- conf : CheckConfig , model : type [Resource ]
41- ) -> tuple [Resource , list [Resource ]]:
42- """Create an object filling with the minimum required field set."""
43- field_names = [
44- field_name
45- for field_name in model .model_fields .keys ()
46- if model .get_field_annotation (field_name , Required ) == Required .true
47- ]
48- obj , garbages = fill_with_random_values (conf , model (), field_names )
49- obj = conf .client .create (obj )
50- return obj , garbages
51-
52-
53- def model_from_ref_type (
54- conf : CheckConfig , ref_type : type , different_than : Resource
55- ) -> type [Resource ]:
56- def model_from_ref_type_ (ref_type ):
57- if get_origin (ref_type ) in UNION_TYPES :
58- return [
59- model_from_ref_type_ (sub_ref_type )
60- for sub_ref_type in get_args (ref_type )
61- ]
62-
63- model_name = get_args (ref_type )[0 ]
64- model = conf .client .get_resource_model (model_name )
65- return model
66-
67- models = model_from_ref_type_ (ref_type )
68- models = models if isinstance (models , list ) else [models ]
69- acceptable_models = [model for model in models if model != different_than ]
70- return acceptable_models [0 ]
71-
72-
73- def fill_with_random_values (
74- conf : CheckConfig , obj : Resource , field_names : list [str ] | None = None
75- ) -> Resource :
76- garbages = []
77- for field_name in field_names or obj .model_fields .keys ():
78- field = obj .model_fields [field_name ]
79- if field .default :
80- continue
81-
82- is_multiple = obj .get_field_multiplicity (field_name )
83- field_type = obj .get_field_root_type (field_name )
84- if get_origin (field_type ) == Annotated :
85- field_type = get_args (field_type )[0 ]
86-
87- value : Any
88- if field_type is Meta :
89- value = None
90-
91- elif field .examples :
92- value = random .choice (field .examples )
93-
94- elif field_type is int :
95- value = uuid .uuid4 ().int
96-
97- elif field_type is bool :
98- value = random .choice ([True , False ])
99-
100- elif field_type is bytes :
101- value = base64 .b64encode (str (uuid .uuid4 ()).encode ("utf-8" ))
102-
103- elif get_origin (field_type ) is Reference :
104- ref_type = get_args (field_type )[0 ]
105- if ref_type not in (ExternalReference , URIReference ):
106- model = model_from_ref_type (
107- conf , ref_type , different_than = obj .__class__
108- )
109- ref_obj , sub_garbages = create_minimal_object (conf , model )
110- value = ref_obj .meta .location
111- garbages += sub_garbages
112-
113- else :
114- value = f"https://{ str (uuid .uuid4 ())} .test"
115-
116- elif isclass (field_type ) and issubclass (field_type , Enum ):
117- value = random .choice (list (field_type ))
118-
119- elif isclass (field_type ) and issubclass (field_type , ComplexAttribute ):
120- value , sub_garbages = fill_with_random_values (conf , field_type ())
121- garbages += sub_garbages
122-
123- elif isclass (field_type ) and issubclass (field_type , Extension ):
124- value , sub_garbages = fill_with_random_values (conf , field_type ())
125- garbages += sub_garbages
126-
127- else :
128- # Put emails so this will be accepted by EmailStr too
129- value = f"{ uuid .uuid4 ()} @{ uuid .uuid4 ()} .com"
130-
131- if is_multiple :
132- setattr (obj , field_name , [value ])
133-
134- else :
135- setattr (obj , field_name , value )
136-
137- return obj , garbages
138-
139-
14022@checker
14123def check_object_creation (conf : CheckConfig , obj : type [Resource ]) -> CheckResult :
14224 """Perform an object creation.
0 commit comments