44from enum import Enum
55from inspect import isclass
66from typing import TYPE_CHECKING
7- from typing import Annotated
87from typing import Any
98from typing import get_args
109from typing import get_origin
@@ -46,6 +45,72 @@ def model_from_ref_type_(ref_type):
4645 return acceptable_models [0 ]
4746
4847
48+ def generate_random_value (
49+ conf : CheckConfig ,
50+ obj : Resource ,
51+ resource_manager : "ResourceManager" ,
52+ field_name : str ,
53+ ):
54+ field = obj .__class__ .model_fields [field_name ]
55+ field_type = obj .get_field_root_type (field_name )
56+
57+ value : Any
58+ if field_type is Meta :
59+ value = None
60+
61+ elif field .examples :
62+ value = random .choice (field .examples )
63+
64+ # RFC7643 §4.1.2 provides the following indications, however
65+ # there is no way to guess the existence of such requirements
66+ # just by looking at the object schema.
67+ # The value SHOULD be specified according to [RFC5321].
68+ elif field_name == "value" and "email" in obj .__class__ .__name__ .lower ():
69+ value = f"{ uuid .uuid4 ()} @{ uuid .uuid4 ()} .com"
70+
71+ # RFC7643 §4.1.2 provides the following indications, however
72+ # there is no way to guess the existence of such requirements
73+ # just by looking at the object schema.
74+ # The value SHOULD be specified
75+ # according to the format defined in [RFC3966], e.g.,
76+ # 'tel:+1-201-555-0123'.
77+ elif field_name == "value" and "phone" in obj .__class__ .__name__ .lower ():
78+ value = "" .join (str (random .choice (range (10 ))) for _ in range (10 ))
79+
80+ elif field_type is int :
81+ value = uuid .uuid4 ().int
82+
83+ elif field_type is bool :
84+ value = random .choice ([True , False ])
85+
86+ elif field_type is bytes :
87+ value = base64 .b64encode (str (uuid .uuid4 ()).encode ("utf-8" ))
88+
89+ elif get_origin (field_type ) is Reference :
90+ ref_type = get_args (field_type )[0 ]
91+ if ref_type not in (ExternalReference , URIReference ):
92+ model = model_from_ref_type (conf , ref_type , different_than = obj .__class__ )
93+ ref_obj = resource_manager .create_and_register (model )
94+ value = ref_obj .meta .location
95+
96+ else :
97+ value = f"https://{ str (uuid .uuid4 ())} .test"
98+
99+ elif isclass (field_type ) and issubclass (field_type , Enum ):
100+ value = random .choice (list (field_type ))
101+
102+ elif isclass (field_type ) and issubclass (field_type , ComplexAttribute ):
103+ value = fill_with_random_values (conf , field_type (), resource_manager )
104+
105+ elif isclass (field_type ) and issubclass (field_type , Extension ):
106+ value = fill_with_random_values (conf , field_type (), resource_manager )
107+
108+ else :
109+ # Put emails so this will be accepted by EmailStr too
110+ value = str (uuid .uuid4 ())
111+ return value
112+
113+
49114def fill_with_random_values (
50115 conf : CheckConfig ,
51116 obj : Resource ,
@@ -65,68 +130,9 @@ def fill_with_random_values(
65130 if field .default :
66131 continue
67132
68- is_multiple = obj .get_field_multiplicity (field_name )
69- field_type = obj .get_field_root_type (field_name )
70- if get_origin (field_type ) == Annotated :
71- field_type = get_args (field_type )[0 ]
72-
73- value : Any
74- if field_type is Meta :
75- value = None
76-
77- elif field .examples :
78- value = random .choice (field .examples )
79-
80- # RFC7643 §4.1.2 provides the following indications, however
81- # there is no way to guess the existence of such requirements
82- # just by looking at the object schema.
83- # The value SHOULD be specified according to [RFC5321].
84- elif field_name == "value" and "email" in obj .__class__ .__name__ .lower ():
85- value = f"{ uuid .uuid4 ()} @{ uuid .uuid4 ()} .com"
86-
87- # RFC7643 §4.1.2 provides the following indications, however
88- # there is no way to guess the existence of such requirements
89- # just by looking at the object schema.
90- # The value SHOULD be specified
91- # according to the format defined in [RFC3966], e.g.,
92- # 'tel:+1-201-555-0123'.
93- elif field_name == "value" and "phone" in obj .__class__ .__name__ .lower ():
94- value = "" .join (str (random .choice (range (10 ))) for _ in range (10 ))
95-
96- elif field_type is int :
97- value = uuid .uuid4 ().int
98-
99- elif field_type is bool :
100- value = random .choice ([True , False ])
101-
102- elif field_type is bytes :
103- value = base64 .b64encode (str (uuid .uuid4 ()).encode ("utf-8" ))
104-
105- elif get_origin (field_type ) is Reference :
106- ref_type = get_args (field_type )[0 ]
107- if ref_type not in (ExternalReference , URIReference ):
108- model = model_from_ref_type (
109- conf , ref_type , different_than = obj .__class__
110- )
111- ref_obj = resource_manager .create_and_register (model )
112- value = ref_obj .meta .location
113-
114- else :
115- value = f"https://{ str (uuid .uuid4 ())} .test"
116-
117- elif isclass (field_type ) and issubclass (field_type , Enum ):
118- value = random .choice (list (field_type ))
119-
120- elif isclass (field_type ) and issubclass (field_type , ComplexAttribute ):
121- value = fill_with_random_values (conf , field_type (), resource_manager )
122-
123- elif isclass (field_type ) and issubclass (field_type , Extension ):
124- value = fill_with_random_values (conf , field_type (), resource_manager )
125-
126- else :
127- # Put emails so this will be accepted by EmailStr too
128- value = str (uuid .uuid4 ())
133+ value = generate_random_value (conf , obj , resource_manager , field_name )
129134
135+ is_multiple = obj .get_field_multiplicity (field_name )
130136 if is_multiple :
131137 setattr (obj , field_name , [value ])
132138 else :
0 commit comments