@@ -240,6 +240,87 @@ def test_oneof_required(self):
240240 assert result is None
241241
242242
243+ def test_oneof_discriminator (self ):
244+ schema = {
245+ "$ref" : "#/$defs/Route" ,
246+ "$defs" : {
247+ "MountainHiking" : {
248+ "type" : "object" ,
249+ "properties" : {
250+ "discipline" : {
251+ "type" : "string" ,
252+ "enum" : ["mountain_hiking" ]
253+ },
254+ "length" : {
255+ "type" : "integer" ,
256+ }
257+ },
258+ "required" : ["discipline" , "length" ]
259+ },
260+ "AlpineClimbing" : {
261+ "type" : "object" ,
262+ "properties" : {
263+ "discipline" : {
264+ "type" : "string" ,
265+ "enum" : ["alpine_climbing" ]
266+ },
267+ "height" : {
268+ "type" : "integer" ,
269+ },
270+ },
271+ "required" : ["discipline" , "height" ]
272+ },
273+ "Route" : {
274+ "oneOf" : [
275+ {"$ref" : "#/$defs/MountainHiking" },
276+ {"$ref" : "#/$defs/AlpineClimbing" },
277+ ]
278+ }
279+ }
280+ }
281+
282+ # use jsonschema validator when no discriminator is defined
283+ validator = OAS30Validator (schema , format_checker = oas30_format_checker )
284+ with pytest .raises (ValidationError , match = "is not valid under any of the given schemas" ):
285+ validator .validate ({
286+ "something" : "matching_none_of_the_schemas"
287+ })
288+ assert False
289+
290+ discriminator = {
291+ "propertyName" : "discipline" ,
292+ "mapping" : {
293+ "mountain_hiking" : "#/$defs/MountainHiking" ,
294+ "alpine_climbing" : "#/$defs/AlpineClimbing" ,
295+ }
296+ }
297+ schema ['$defs' ]['Route' ]['discriminator' ] = discriminator
298+ validator = OAS30Validator (schema , format_checker = oas30_format_checker )
299+ with pytest .raises (ValidationError , match = "does not contain discriminating property" ):
300+ validator .validate ({
301+ "something" : "missing"
302+ })
303+ assert False
304+
305+ with pytest .raises (ValidationError , match = "is not a valid discriminator value, expected one of" ):
306+ result = validator .validate ({
307+ "discipline" : "other"
308+ })
309+ assert False
310+
311+ with pytest .raises (ValidationError , match = "'bad_string' is not of type integer" ):
312+ validator .validate ({
313+ "discipline" : "mountain_hiking" ,
314+ "length" : "bad_string"
315+ })
316+ assert False
317+
318+ validator .validate ({
319+ "discipline" : "mountain_hiking" ,
320+ "length" : 10
321+ })
322+
323+
243324class TestOAS31ValidatorValidate (object ):
244325 @pytest .mark .parametrize ('schema_type' , [
245326 'boolean' , 'array' , 'integer' , 'number' , 'string' ,
0 commit comments