Skip to content

Commit 6241f44

Browse files
committed
more discriminator tests
1 parent 36866eb commit 6241f44

File tree

2 files changed

+181
-3
lines changed

2 files changed

+181
-3
lines changed

end_to_end_tests/functional_tests/generated_code_execution/test_unions.py

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,20 @@ def test_type_hints(self, ModelWithUnion, ModelWithRequiredUnion, ModelWithUnion
167167
modelType: {"type": "string"}
168168
name: {"type": "string"}
169169
required: ["modelType"]
170+
Corgi:
171+
type: object
172+
properties:
173+
modelType: {"type": "string"}
174+
dogType: {"type": "string"}
175+
name: {"type": "string"}
176+
required: ["modelType"]
177+
Schnauzer:
178+
type: object
179+
properties:
180+
modelType: {"type": "string"}
181+
dogType: {"type": "string"}
182+
name: {"type": "string"}
183+
required: ["modelType"]
170184
WithDiscriminatedUnion:
171185
type: object
172186
properties:
@@ -178,8 +192,8 @@ def test_type_hints(self, ModelWithUnion, ModelWithRequiredUnion, ModelWithUnion
178192
propertyName: modelType
179193
mapping:
180194
"type1": "#/components/schemas/ModelType1"
181-
"type2": "#/components/schemas/ModelType2"
182-
"another-value": "#/components/schemas/ModelType2"
195+
"type2": "ModelType2" # exactly equivalent to "#/components/schemas/ModelType2"
196+
"another-value": "#/components/schemas/ModelType2" # deliberately mapped to same type as previous line
183197
WithDiscriminatedUnionImplicitMapping:
184198
type: object
185199
properties:
@@ -189,12 +203,46 @@ def test_type_hints(self, ModelWithUnion, ModelWithRequiredUnion, ModelWithUnion
189203
- $ref: "#/components/schemas/ModelType2"
190204
discriminator:
191205
propertyName: modelType
206+
WithNestedDiscriminatorsSameProperty:
207+
type: object
208+
properties:
209+
unionProp:
210+
oneOf:
211+
- oneOf:
212+
- $ref: "#/components/schemas/ModelType1"
213+
- $ref: "#/components/schemas/ModelType2"
214+
discriminator:
215+
propertyName: modelType
216+
- oneOf:
217+
- $ref: "#/components/schemas/Corgi"
218+
- $ref: "#/components/schemas/Schnauzer"
219+
discriminator:
220+
propertyName: modelType
221+
WithNestedDiscriminatorsDifferentProperty:
222+
type: object
223+
properties:
224+
unionProp:
225+
oneOf:
226+
- oneOf:
227+
- $ref: "#/components/schemas/ModelType1"
228+
- $ref: "#/components/schemas/ModelType2"
229+
discriminator:
230+
propertyName: modelType
231+
- oneOf:
232+
- $ref: "#/components/schemas/Corgi"
233+
- $ref: "#/components/schemas/Schnauzer"
234+
discriminator:
235+
propertyName: dogType
192236
""")
193237
@with_generated_code_imports(
194238
".models.ModelType1",
195239
".models.ModelType2",
240+
".models.Corgi",
241+
".models.Schnauzer",
196242
".models.WithDiscriminatedUnion",
197243
".models.WithDiscriminatedUnionImplicitMapping",
244+
".models.WithNestedDiscriminatorsSameProperty",
245+
".models.WithNestedDiscriminatorsDifferentProperty",
198246
)
199247
class TestDiscriminators:
200248
def test_with_explicit_mapping(self, ModelType1, ModelType2, WithDiscriminatedUnion):
@@ -231,3 +279,27 @@ def test_with_implicit_mapping(self, ModelType1, ModelType2, WithDiscriminatedUn
231279
)
232280
with pytest.raises(TypeError):
233281
WithDiscriminatedUnionImplicitMapping.from_dict({"unionProp": {"modelType": "unknown-value"}})
282+
283+
def test_nested_with_same_property(self, ModelType1, Schnauzer, WithNestedDiscriminatorsSameProperty):
284+
assert_model_decode_encode(
285+
WithNestedDiscriminatorsSameProperty,
286+
{"unionProp": {"modelType": "ModelType1", "name": "a"}},
287+
WithNestedDiscriminatorsSameProperty(union_prop=ModelType1(model_type="ModelType1", name="a")),
288+
)
289+
assert_model_decode_encode(
290+
WithNestedDiscriminatorsSameProperty,
291+
{"unionProp": {"modelType": "Schnauzer", "name": "a"}},
292+
WithNestedDiscriminatorsSameProperty(union_prop=Schnauzer(model_type="Schnauzer", name="a")),
293+
)
294+
295+
def test_nested_with_different_property(self, ModelType1, Schnauzer, WithNestedDiscriminatorsDifferentProperty):
296+
assert_model_decode_encode(
297+
WithNestedDiscriminatorsDifferentProperty,
298+
{"unionProp": {"modelType": "ModelType1", "name": "a"}},
299+
WithNestedDiscriminatorsDifferentProperty(union_prop=ModelType1(model_type="ModelType1", name="a")),
300+
)
301+
assert_model_decode_encode(
302+
WithNestedDiscriminatorsDifferentProperty,
303+
{"unionProp": {"modelType": "irrelevant", "dogType": "Schnauzer", "name": "a"}},
304+
WithNestedDiscriminatorsDifferentProperty(union_prop=Schnauzer(model_type="irrelevant", dog_type="Schnauzer", name="a")),
305+
)

end_to_end_tests/functional_tests/generator_failure_cases/test_invalid_unions.py

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,110 @@ def test_invalid_default(self, warnings):
3232
assert_bad_schema_warning(warnings, "UnionWithInvalidDefault", "Invalid int value: aaa")
3333

3434
def test_invalid_property(self, warnings):
35-
assert_bad_schema_warning(warnings, "UnionWithMalformedVariant", "Invalid property in union")
35+
assert_bad_schema_warning(warnings, "UnionWithMalformedVariant", "Invalid property in union")
36+
37+
38+
class TestInvalidDiscriminators:
39+
@pytest.fixture(scope="class")
40+
def warnings(self):
41+
return inline_spec_should_cause_warnings(
42+
"""
43+
components:
44+
schemas:
45+
ModelType1:
46+
type: object
47+
properties:
48+
modelType: {"type": "string"}
49+
name: {"type": "string"}
50+
required: ["modelType"]
51+
ModelType2:
52+
type: object
53+
properties:
54+
modelType: {"type": "string"}
55+
name: {"type": "string"}
56+
required: ["modelType"]
57+
ModelType3:
58+
type: object
59+
properties:
60+
modelType: {"type": "string"}
61+
name: {"type": "string"}
62+
required: ["modelType"]
63+
StringType:
64+
type: string
65+
WithUnknownSchemaInMapping:
66+
type: object
67+
properties:
68+
unionProp:
69+
oneOf:
70+
- $ref: "#/components/schemas/ModelType1"
71+
- $ref: "#/components/schemas/ModelType2"
72+
discriminator:
73+
propertyName: modelType
74+
mapping:
75+
"type1": "#/components/schemas/ModelType1"
76+
"type2": "#/components/schemas/DoesntExist"
77+
WithReferenceToSchemaNotInUnion:
78+
type: object
79+
properties:
80+
unionProp:
81+
oneOf:
82+
- $ref: "#/components/schemas/ModelType1"
83+
- $ref: "#/components/schemas/ModelType2"
84+
discriminator:
85+
propertyName: modelType
86+
mapping:
87+
"type1": "#/components/schemas/ModelType1"
88+
"type2": "#/components/schemas/ModelType2"
89+
"type3": "#/components/schemas/ModelType3"
90+
WithNonObjectVariant:
91+
type: object
92+
properties:
93+
unionProp:
94+
oneOf:
95+
- $ref: "#/components/schemas/ModelType1"
96+
- $ref: "#/components/schemas/StringType"
97+
discriminator:
98+
propertyName: modelType
99+
WithInlineSchema:
100+
type: object
101+
properties:
102+
unionProp:
103+
oneOf:
104+
- $ref: "#/components/schemas/ModelType1"
105+
- type: object
106+
properties:
107+
modelType: {"type": "string"}
108+
name: {"type": "string"}
109+
discriminator:
110+
propertyName: modelType
111+
112+
"""
113+
)
114+
115+
def test_invalid_reference(self, warnings):
116+
assert_bad_schema_warning(
117+
warnings,
118+
"WithUnknownSchemaInMapping",
119+
'Invalid reference "#/components/schemas/DoesntExist" in discriminator mapping',
120+
)
121+
122+
def test_reference_to_schema_not_in_union(self, warnings):
123+
assert_bad_schema_warning(
124+
warnings,
125+
"WithReferenceToSchemaNotInUnion",
126+
'Discriminator mapping referred to "ModelType3" which is not one of the schema variants',
127+
)
128+
129+
def test_non_object_variant(self, warnings):
130+
assert_bad_schema_warning(
131+
warnings,
132+
"WithNonObjectVariant",
133+
"All schema variants must be objects when using a discriminator",
134+
)
135+
136+
def test_inline_schema(self, warnings):
137+
assert_bad_schema_warning(
138+
warnings,
139+
"WithInlineSchema",
140+
"Inline schema declarations are not allowed when using a discriminator",
141+
)

0 commit comments

Comments
 (0)