@@ -240,15 +240,20 @@ def test_oneof_required(self):
240
240
assert result is None
241
241
242
242
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 ):
244
247
# We define a few components schemas
245
248
components = {
246
249
"MountainHiking" : {
247
250
"type" : "object" ,
248
251
"properties" : {
249
252
"discipline" : {
250
253
"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" ]
252
257
},
253
258
"length" : {
254
259
"type" : "integer" ,
@@ -270,12 +275,13 @@ def test_oneof_discriminator(self):
270
275
"required" : ["discipline" , "height" ]
271
276
},
272
277
"Route" : {
273
- "oneOf" : [
274
- {"$ref" : "#/components/schemas/MountainHiking" },
275
- {"$ref" : "#/components/schemas/AlpineClimbing" },
276
- ]
278
+ # defined later
277
279
}
278
280
}
281
+ components ['Route' ][schema_type ] = [
282
+ {"$ref" : "#/components/schemas/MountainHiking" },
283
+ {"$ref" : "#/components/schemas/AlpineClimbing" },
284
+ ]
279
285
280
286
# Add the compoments in a minimalis schema
281
287
schema = {
@@ -285,13 +291,23 @@ def test_oneof_discriminator(self):
285
291
}
286
292
}
287
293
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
295
311
296
312
discriminator = {
297
313
"propertyName" : "discipline" ,
@@ -301,31 +317,43 @@ def test_oneof_discriminator(self):
301
317
}
302
318
}
303
319
schema ['components' ]['schemas' ]['Route' ]['discriminator' ] = discriminator
320
+
321
+ # Optional: check we return useful result when the schema is wrong
304
322
validator = OAS30Validator (schema , format_checker = oas30_format_checker )
305
323
with pytest .raises (ValidationError , match = "does not contain discriminating property" ):
306
324
validator .validate ({
307
325
"something" : "missing"
308
326
})
309
327
assert False
310
328
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
317
330
with pytest .raises (ValidationError , match = "'bad_string' is not of type integer" ):
318
331
validator .validate ({
319
332
"discipline" : "mountain_hiking" ,
320
333
"length" : "bad_string"
321
334
})
322
335
assert False
323
336
337
+ # Check explicit MountainHiking resolution
324
338
validator .validate ({
325
339
"discipline" : "mountain_hiking" ,
326
340
"length" : 10
327
341
})
328
342
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
+
329
357
330
358
class TestOAS31ValidatorValidate (object ):
331
359
@pytest .mark .parametrize ('schema_type' , [
0 commit comments