diff --git a/openapi_core/__init__.py b/openapi_core/__init__.py index 8d7ddfe..8f63118 100644 --- a/openapi_core/__init__.py +++ b/openapi_core/__init__.py @@ -6,7 +6,7 @@ from openapi_core.shortcuts import ( __author__ = 'Artur Maciag' __email__ = 'maciag.artur@gmail.com' -__version__ = '0.8.0' +__version__ = '0.8.1' __url__ = 'https://github.com/p1c2u/openapi-core' __license__ = 'BSD 3-Clause License' diff --git a/openapi_core/schema/schemas/factories.py b/openapi_core/schema/schemas/factories.py index 50f04ba..136fbd0 100644 --- a/openapi_core/schema/schemas/factories.py +++ b/openapi_core/schema/schemas/factories.py @@ -28,7 +28,8 @@ class SchemaFactory(object): deprecated = schema_deref.get('deprecated', False) all_of_spec = schema_deref.get('allOf', None) one_of_spec = schema_deref.get('oneOf', None) - additional_properties_spec = schema_deref.get('additionalProperties') + additional_properties_spec = schema_deref.get('additionalProperties', + True) min_items = schema_deref.get('minItems', None) max_items = schema_deref.get('maxItems', None) min_length = schema_deref.get('minLength', None) @@ -59,8 +60,8 @@ class SchemaFactory(object): if items_spec: items = self._create_items(items_spec) - additional_properties = None - if additional_properties_spec: + additional_properties = additional_properties_spec + if isinstance(additional_properties_spec, dict): additional_properties = self.create(additional_properties_spec) return Schema( diff --git a/openapi_core/schema/schemas/models.py b/openapi_core/schema/schemas/models.py index 6ae4dc9..65c8bc8 100644 --- a/openapi_core/schema/schemas/models.py +++ b/openapi_core/schema/schemas/models.py @@ -68,7 +68,7 @@ class Schema(object): self, schema_type=None, model=None, properties=None, items=None, schema_format=None, required=None, default=None, nullable=False, enum=None, deprecated=False, all_of=None, one_of=None, - additional_properties=None, min_items=None, max_items=None, + additional_properties=True, min_items=None, max_items=None, min_length=None, max_length=None, pattern=None, unique_items=False, minimum=None, maximum=None, multiple_of=None, exclusive_minimum=False, exclusive_maximum=False, @@ -284,14 +284,15 @@ class Schema(object): value_props_names = value.keys() extra_props = set(value_props_names) - set(all_props_names) - if extra_props and self.additional_properties is None: + if extra_props and self.additional_properties is False: raise UndefinedSchemaProperty(extra_props) properties = {} - for prop_name in extra_props: - prop_value = value[prop_name] - properties[prop_name] = self.additional_properties.unmarshal( - prop_value, custom_formatters=custom_formatters) + if self.additional_properties is not True: + for prop_name in extra_props: + prop_value = value[prop_name] + properties[prop_name] = self.additional_properties.unmarshal( + prop_value, custom_formatters=custom_formatters) for prop_name, prop in iteritems(all_props): try: @@ -515,13 +516,14 @@ class Schema(object): value_props_names = value.keys() extra_props = set(value_props_names) - set(all_props_names) - if extra_props and self.additional_properties is None: + if extra_props and self.additional_properties is False: raise UndefinedSchemaProperty(extra_props) - for prop_name in extra_props: - prop_value = value[prop_name] - self.additional_properties.validate( - prop_value, custom_formatters=custom_formatters) + if self.additional_properties is not True: + for prop_name in extra_props: + prop_value = value[prop_name] + self.additional_properties.validate( + prop_value, custom_formatters=custom_formatters) for prop_name, prop in iteritems(all_props): try: diff --git a/tests/integration/data/v3.0/petstore.yaml b/tests/integration/data/v3.0/petstore.yaml index 3f132c3..ed623a3 100644 --- a/tests/integration/data/v3.0/petstore.yaml +++ b/tests/integration/data/v3.0/petstore.yaml @@ -295,6 +295,7 @@ components: $ref: "#/components/schemas/Utctime" name: type: string + additionalProperties: false TagList: type: array items: diff --git a/tests/unit/schema/test_schemas.py b/tests/unit/schema/test_schemas.py index 302719f..cab5fdf 100644 --- a/tests/unit/schema/test_schemas.py +++ b/tests/unit/schema/test_schemas.py @@ -7,6 +7,7 @@ import pytest from openapi_core.extensions.models.models import Model from openapi_core.schema.schemas.exceptions import ( InvalidSchemaValue, MultipleOneOfSchema, NoOneOfSchema, OpenAPISchemaError, + UndefinedSchemaProperty ) from openapi_core.schema.schemas.models import Schema @@ -697,6 +698,26 @@ class TestSchemaValidate(object): assert result == value + @pytest.mark.parametrize('value', [Model({'additional': 1}), ]) + def test_object_additional_propetries(self, value): + schema = Schema('object') + + schema.validate(value) + + @pytest.mark.parametrize('value', [Model({'additional': 1}), ]) + def test_object_additional_propetries_false(self, value): + schema = Schema('object', additional_properties=False) + + with pytest.raises(UndefinedSchemaProperty): + schema.validate(value) + + @pytest.mark.parametrize('value', [Model({'additional': 1}), ]) + def test_object_additional_propetries_object(self, value): + additional_properties = Schema('integer') + schema = Schema('object', additional_properties=additional_properties) + + schema.validate(value) + @pytest.mark.parametrize('value', [[], ]) def test_list_min_items_invalid_schema(self, value): schema = Schema(