mirror of
https://github.com/correl/openapi-core.git
synced 2024-11-28 19:19:52 +00:00
Merge pull request #43 from p1c2u/feature/schema-additional-properties-support
Schema additional properties support
This commit is contained in:
commit
469c558edd
4 changed files with 52 additions and 2 deletions
|
@ -28,6 +28,7 @@ class SchemaFactory(object):
|
||||||
deprecated = schema_deref.get('deprecated', False)
|
deprecated = schema_deref.get('deprecated', False)
|
||||||
all_of_spec = schema_deref.get('allOf', None)
|
all_of_spec = schema_deref.get('allOf', None)
|
||||||
one_of_spec = schema_deref.get('oneOf', None)
|
one_of_spec = schema_deref.get('oneOf', None)
|
||||||
|
additional_properties_spec = schema_deref.get('additionalProperties')
|
||||||
|
|
||||||
properties = None
|
properties = None
|
||||||
if properties_spec:
|
if properties_spec:
|
||||||
|
@ -45,11 +46,16 @@ class SchemaFactory(object):
|
||||||
if items_spec:
|
if items_spec:
|
||||||
items = self._create_items(items_spec)
|
items = self._create_items(items_spec)
|
||||||
|
|
||||||
|
additional_properties = None
|
||||||
|
if additional_properties_spec:
|
||||||
|
additional_properties = self.create(additional_properties_spec)
|
||||||
|
|
||||||
return Schema(
|
return Schema(
|
||||||
schema_type=schema_type, model=model, properties=properties,
|
schema_type=schema_type, model=model, properties=properties,
|
||||||
items=items, schema_format=schema_format, required=required,
|
items=items, schema_format=schema_format, required=required,
|
||||||
default=default, nullable=nullable, enum=enum,
|
default=default, nullable=nullable, enum=enum,
|
||||||
deprecated=deprecated, all_of=all_of, one_of=one_of,
|
deprecated=deprecated, all_of=all_of, one_of=one_of,
|
||||||
|
additional_properties=additional_properties,
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -28,7 +28,8 @@ class Schema(object):
|
||||||
def __init__(
|
def __init__(
|
||||||
self, schema_type=None, model=None, properties=None, items=None,
|
self, schema_type=None, model=None, properties=None, items=None,
|
||||||
schema_format=None, required=None, default=None, nullable=False,
|
schema_format=None, required=None, default=None, nullable=False,
|
||||||
enum=None, deprecated=False, all_of=None, one_of=None):
|
enum=None, deprecated=False, all_of=None, one_of=None,
|
||||||
|
additional_properties=None):
|
||||||
self.type = schema_type and SchemaType(schema_type)
|
self.type = schema_type and SchemaType(schema_type)
|
||||||
self.model = model
|
self.model = model
|
||||||
self.properties = properties and dict(properties) or {}
|
self.properties = properties and dict(properties) or {}
|
||||||
|
@ -41,6 +42,7 @@ class Schema(object):
|
||||||
self.deprecated = deprecated
|
self.deprecated = deprecated
|
||||||
self.all_of = all_of and list(all_of) or []
|
self.all_of = all_of and list(all_of) or []
|
||||||
self.one_of = one_of and list(one_of) or []
|
self.one_of = one_of and list(one_of) or []
|
||||||
|
self.additional_properties = additional_properties
|
||||||
|
|
||||||
self._all_required_properties_cache = None
|
self._all_required_properties_cache = None
|
||||||
self._all_optional_properties_cache = None
|
self._all_optional_properties_cache = None
|
||||||
|
@ -183,11 +185,16 @@ 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:
|
if extra_props and self.additional_properties is None:
|
||||||
raise UndefinedSchemaProperty(
|
raise UndefinedSchemaProperty(
|
||||||
"Undefined properties in schema: {0}".format(extra_props))
|
"Undefined properties in schema: {0}".format(extra_props))
|
||||||
|
|
||||||
properties = {}
|
properties = {}
|
||||||
|
for prop_name in extra_props:
|
||||||
|
prop_value = value[prop_name]
|
||||||
|
properties[prop_name] = self.additional_properties.unmarshal(
|
||||||
|
prop_value)
|
||||||
|
|
||||||
for prop_name, prop in iteritems(all_props):
|
for prop_name, prop in iteritems(all_props):
|
||||||
try:
|
try:
|
||||||
prop_value = value[prop_name]
|
prop_value = value[prop_name]
|
||||||
|
|
|
@ -284,6 +284,8 @@ components:
|
||||||
properties:
|
properties:
|
||||||
rootCause:
|
rootCause:
|
||||||
type: string
|
type: string
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
responses:
|
responses:
|
||||||
ErrorResponse:
|
ErrorResponse:
|
||||||
description: unexpected error
|
description: unexpected error
|
||||||
|
|
|
@ -757,3 +757,38 @@ class TestPetstore(object):
|
||||||
|
|
||||||
with pytest.raises(InvalidMediaTypeValue):
|
with pytest.raises(InvalidMediaTypeValue):
|
||||||
request.get_body(spec)
|
request.get_body(spec)
|
||||||
|
|
||||||
|
def test_post_tags_additional_properties(
|
||||||
|
self, spec, response_validator):
|
||||||
|
host_url = 'http://petstore.swagger.io/v1'
|
||||||
|
path_pattern = '/v1/tags'
|
||||||
|
pet_name = 'Dog'
|
||||||
|
data_json = {
|
||||||
|
'name': pet_name,
|
||||||
|
}
|
||||||
|
data = json.dumps(data_json)
|
||||||
|
|
||||||
|
request = MockRequest(
|
||||||
|
host_url, 'POST', '/tags',
|
||||||
|
path_pattern=path_pattern, data=data,
|
||||||
|
)
|
||||||
|
|
||||||
|
parameters = request.get_parameters(spec)
|
||||||
|
body = request.get_body(spec)
|
||||||
|
|
||||||
|
assert parameters == {}
|
||||||
|
assert body == data_json
|
||||||
|
|
||||||
|
data_json = {
|
||||||
|
'code': 400,
|
||||||
|
'message': 'Bad request',
|
||||||
|
'rootCause': 'Tag already exist',
|
||||||
|
'additionalinfo': 'Tag Dog already exist',
|
||||||
|
}
|
||||||
|
data = json.dumps(data_json)
|
||||||
|
response = MockResponse(data, status_code=404)
|
||||||
|
|
||||||
|
response_result = response_validator.validate(request, response)
|
||||||
|
|
||||||
|
assert response_result.errors == []
|
||||||
|
assert response_result.data == data_json
|
||||||
|
|
Loading…
Reference in a new issue