Skip to content

Commit b029066

Browse files
author
Diogo Baeder de Paula Pinto
committed
Fix #124: Checking "additionalProperties" in "oneOf" items.
This is important because it does the correct validation over items that are restricted in "oneOf", so that it's possible to use schemas that are superset of one another as items of "oneOf".
1 parent 5f7c6ba commit b029066

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

openapi_core/schema/schemas/models.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,12 @@ def _unmarshal_properties(self, value, one_of_schema=None,
311311

312312
value_props_names = value.keys()
313313
extra_props = set(value_props_names) - set(all_props_names)
314-
if extra_props and self.additional_properties is False:
314+
no_more_properties_allowed = (
315+
(self.additional_properties is False) or
316+
(one_of_schema is not None and
317+
one_of_schema.additional_properties is False)
318+
)
319+
if extra_props and no_more_properties_allowed:
315320
raise UndefinedSchemaProperty(extra_props)
316321

317322
properties = {}
@@ -543,7 +548,12 @@ def _validate_properties(self, value, one_of_schema=None,
543548

544549
value_props_names = value.keys()
545550
extra_props = set(value_props_names) - set(all_props_names)
546-
if extra_props and self.additional_properties is False:
551+
no_more_properties_allowed = (
552+
(self.additional_properties is False) or
553+
(one_of_schema is not None and
554+
one_of_schema.additional_properties is False)
555+
)
556+
if extra_props and no_more_properties_allowed:
547557
raise UndefinedSchemaProperty(extra_props)
548558

549559
if self.additional_properties is not True:

tests/unit/schema/test_schemas.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,37 @@ def test_object_no_one_of(self, value):
711711
with pytest.raises(NoOneOfSchema):
712712
schema.validate(value)
713713

714+
@pytest.mark.parametrize('value', [
715+
Model({
716+
'foo': 'FOO',
717+
}),
718+
Model({
719+
'foo': 'FOO',
720+
'bar': 'BAR',
721+
}),
722+
])
723+
def test_unambiguous_one_of(self, value):
724+
one_of = [
725+
Schema(
726+
'object',
727+
properties={
728+
'bar': Schema('string'),
729+
},
730+
additional_properties=False,
731+
),
732+
Schema(
733+
'object',
734+
properties={
735+
'foo': Schema('string'),
736+
'bar': Schema('string'),
737+
},
738+
additional_properties=False,
739+
),
740+
]
741+
schema = Schema('object', one_of=one_of)
742+
743+
schema.validate(value)
744+
714745
@pytest.mark.parametrize('value', [Model(), ])
715746
def test_object_default_property(self, value):
716747
schema = Schema('object', default='value1')

0 commit comments

Comments
 (0)