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".
This commit is contained in:
Diogo Baeder de Paula Pinto 2019-03-26 02:30:07 -03:00
parent 5f7c6ba6ee
commit b029066add
2 changed files with 43 additions and 2 deletions

View file

@ -311,7 +311,12 @@ class Schema(object):
value_props_names = value.keys() value_props_names = value.keys()
extra_props = set(value_props_names) - set(all_props_names) extra_props = set(value_props_names) - set(all_props_names)
if extra_props and self.additional_properties is False: no_more_properties_allowed = (
(self.additional_properties is False) or
(one_of_schema is not None and
one_of_schema.additional_properties is False)
)
if extra_props and no_more_properties_allowed:
raise UndefinedSchemaProperty(extra_props) raise UndefinedSchemaProperty(extra_props)
properties = {} properties = {}
@ -543,7 +548,12 @@ class Schema(object):
value_props_names = value.keys() value_props_names = value.keys()
extra_props = set(value_props_names) - set(all_props_names) extra_props = set(value_props_names) - set(all_props_names)
if extra_props and self.additional_properties is False: no_more_properties_allowed = (
(self.additional_properties is False) or
(one_of_schema is not None and
one_of_schema.additional_properties is False)
)
if extra_props and no_more_properties_allowed:
raise UndefinedSchemaProperty(extra_props) raise UndefinedSchemaProperty(extra_props)
if self.additional_properties is not True: if self.additional_properties is not True:

View file

@ -711,6 +711,37 @@ class TestSchemaValidate(object):
with pytest.raises(NoOneOfSchema): with pytest.raises(NoOneOfSchema):
schema.validate(value) schema.validate(value)
@pytest.mark.parametrize('value', [
Model({
'foo': 'FOO',
}),
Model({
'foo': 'FOO',
'bar': 'BAR',
}),
])
def test_unambiguous_one_of(self, value):
one_of = [
Schema(
'object',
properties={
'bar': Schema('string'),
},
additional_properties=False,
),
Schema(
'object',
properties={
'foo': Schema('string'),
'bar': Schema('string'),
},
additional_properties=False,
),
]
schema = Schema('object', one_of=one_of)
schema.validate(value)
@pytest.mark.parametrize('value', [Model(), ]) @pytest.mark.parametrize('value', [Model(), ])
def test_object_default_property(self, value): def test_object_default_property(self, value):
schema = Schema('object', default='value1') schema = Schema('object', default='value1')