@@ -240,15 +240,20 @@ def test_oneof_required(self):
240240 assert result is None
241241
242242
243- def test_oneof_discriminator (self ):
243+ @pytest .mark .parametrize ('schema_type' , [
244+ 'oneOf' , 'anyOf' , 'allOf' ,
245+ ])
246+ def test_oneof_discriminator (self , schema_type ):
244247 # We define a few components schemas
245248 components = {
246249 "MountainHiking" : {
247250 "type" : "object" ,
248251 "properties" : {
249252 "discipline" : {
250253 "type" : "string" ,
251- "enum" : ["mountain_hiking" ]
254+ # we allow both the explicitely matched mountain_hiking discipline
255+ # and the implicitely matched MoutainHiking discipline
256+ "enum" : ["mountain_hiking" , "MountainHiking" ]
252257 },
253258 "length" : {
254259 "type" : "integer" ,
@@ -270,12 +275,13 @@ def test_oneof_discriminator(self):
270275 "required" : ["discipline" , "height" ]
271276 },
272277 "Route" : {
273- "oneOf" : [
274- {"$ref" : "#/components/schemas/MountainHiking" },
275- {"$ref" : "#/components/schemas/AlpineClimbing" },
276- ]
278+ # defined later
277279 }
278280 }
281+ components ['Route' ][schema_type ] = [
282+ {"$ref" : "#/components/schemas/MountainHiking" },
283+ {"$ref" : "#/components/schemas/AlpineClimbing" },
284+ ]
279285
280286 # Add the compoments in a minimalis schema
281287 schema = {
@@ -285,13 +291,23 @@ def test_oneof_discriminator(self):
285291 }
286292 }
287293
288- # use jsonschema validator when no discriminator is defined
289- validator = OAS30Validator (schema , format_checker = oas30_format_checker )
290- with pytest .raises (ValidationError , match = "is not valid under any of the given schemas" ):
291- validator .validate ({
292- "something" : "matching_none_of_the_schemas"
293- })
294- assert False
294+ if schema_type != 'allOf' :
295+ # use jsonschema validator when no discriminator is defined
296+ validator = OAS30Validator (schema , format_checker = oas30_format_checker )
297+ with pytest .raises (ValidationError , match = "is not valid under any of the given schemas" ):
298+ validator .validate ({
299+ "something" : "matching_none_of_the_schemas"
300+ })
301+ assert False
302+
303+ if schema_type == 'anyOf' :
304+ # use jsonschema validator when no discriminator is defined
305+ validator = OAS30Validator (schema , format_checker = oas30_format_checker )
306+ with pytest .raises (ValidationError , match = "is not valid under any of the given schemas" ):
307+ validator .validate ({
308+ "something" : "matching_none_of_the_schemas"
309+ })
310+ assert False
295311
296312 discriminator = {
297313 "propertyName" : "discipline" ,
@@ -301,31 +317,43 @@ def test_oneof_discriminator(self):
301317 }
302318 }
303319 schema ['components' ]['schemas' ]['Route' ]['discriminator' ] = discriminator
320+
321+ # Optional: check we return useful result when the schema is wrong
304322 validator = OAS30Validator (schema , format_checker = oas30_format_checker )
305323 with pytest .raises (ValidationError , match = "does not contain discriminating property" ):
306324 validator .validate ({
307325 "something" : "missing"
308326 })
309327 assert False
310328
311- with pytest .raises (ValidationError , match = "is not a valid discriminator value, expected one of" ):
312- result = validator .validate ({
313- "discipline" : "other"
314- })
315- assert False
316-
329+ # Check we get a non-generic, somehow usable, error message when a discriminated schema is failing
317330 with pytest .raises (ValidationError , match = "'bad_string' is not of type integer" ):
318331 validator .validate ({
319332 "discipline" : "mountain_hiking" ,
320333 "length" : "bad_string"
321334 })
322335 assert False
323336
337+ # Check explicit MountainHiking resolution
324338 validator .validate ({
325339 "discipline" : "mountain_hiking" ,
326340 "length" : 10
327341 })
328342
343+ # Check implicit MountainHiking resolution
344+ validator .validate ({
345+ "discipline" : "MountainHiking" ,
346+ "length" : 10
347+ })
348+
349+ # Check non resolvable implicit schema
350+ with pytest .raises (ValidationError , match = "reference '#/components/schemas/other' could not be resolved" ):
351+ result = validator .validate ({
352+ "discipline" : "other"
353+ })
354+ assert False
355+
356+
329357
330358class TestOAS31ValidatorValidate (object ):
331359 @pytest .mark .parametrize ('schema_type' , [
0 commit comments