mirror of
https://github.com/correl/openapi-core.git
synced 2025-04-09 17:00:10 -09:00
Merge pull request #40 from p1c2u/feature/one-of-schema-support
OneOf schema support
This commit is contained in:
commit
4669c4763a
6 changed files with 263 additions and 60 deletions
openapi_core/schema/schemas
tests/integration
|
@ -15,3 +15,11 @@ class UndefinedSchemaProperty(OpenAPISchemaError):
|
||||||
|
|
||||||
class MissingSchemaProperty(OpenAPISchemaError):
|
class MissingSchemaProperty(OpenAPISchemaError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class NoOneOfSchema(OpenAPISchemaError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MultipleOneOfSchema(OpenAPISchemaError):
|
||||||
|
pass
|
||||||
|
|
|
@ -27,6 +27,7 @@ class SchemaFactory(object):
|
||||||
enum = schema_deref.get('enum', None)
|
enum = schema_deref.get('enum', None)
|
||||||
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)
|
||||||
|
|
||||||
properties = None
|
properties = None
|
||||||
if properties_spec:
|
if properties_spec:
|
||||||
|
@ -36,6 +37,10 @@ class SchemaFactory(object):
|
||||||
if all_of_spec:
|
if all_of_spec:
|
||||||
all_of = map(self.create, all_of_spec)
|
all_of = map(self.create, all_of_spec)
|
||||||
|
|
||||||
|
one_of = []
|
||||||
|
if one_of_spec:
|
||||||
|
one_of = map(self.create, one_of_spec)
|
||||||
|
|
||||||
items = None
|
items = None
|
||||||
if items_spec:
|
if items_spec:
|
||||||
items = self._create_items(items_spec)
|
items = self._create_items(items_spec)
|
||||||
|
@ -44,7 +49,7 @@ class SchemaFactory(object):
|
||||||
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,
|
deprecated=deprecated, all_of=all_of, one_of=one_of,
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -9,6 +9,7 @@ from openapi_core.extensions.models.factories import ModelFactory
|
||||||
from openapi_core.schema.schemas.enums import SchemaType, SchemaFormat
|
from openapi_core.schema.schemas.enums import SchemaType, SchemaFormat
|
||||||
from openapi_core.schema.schemas.exceptions import (
|
from openapi_core.schema.schemas.exceptions import (
|
||||||
InvalidSchemaValue, UndefinedSchemaProperty, MissingSchemaProperty,
|
InvalidSchemaValue, UndefinedSchemaProperty, MissingSchemaProperty,
|
||||||
|
OpenAPISchemaError, NoOneOfSchema, MultipleOneOfSchema,
|
||||||
)
|
)
|
||||||
from openapi_core.schema.schemas.util import forcebool
|
from openapi_core.schema.schemas.util import forcebool
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ 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):
|
enum=None, deprecated=False, all_of=None, one_of=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 {}
|
||||||
|
@ -39,6 +40,10 @@ class Schema(object):
|
||||||
self.enum = enum
|
self.enum = enum
|
||||||
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._all_required_properties_cache = None
|
||||||
|
self._all_optional_properties_cache = None
|
||||||
|
|
||||||
def __getitem__(self, name):
|
def __getitem__(self, name):
|
||||||
return self.properties[name]
|
return self.properties[name]
|
||||||
|
@ -52,14 +57,35 @@ class Schema(object):
|
||||||
|
|
||||||
return properties
|
return properties
|
||||||
|
|
||||||
|
def get_all_properties_names(self):
|
||||||
|
all_properties = self.get_all_properties()
|
||||||
|
return set(all_properties.keys())
|
||||||
|
|
||||||
def get_all_required_properties(self):
|
def get_all_required_properties(self):
|
||||||
|
if self._all_required_properties_cache is None:
|
||||||
|
self._all_required_properties_cache =\
|
||||||
|
self._get_all_required_properties()
|
||||||
|
|
||||||
|
return self._all_required_properties_cache
|
||||||
|
|
||||||
|
def _get_all_required_properties(self):
|
||||||
|
all_properties = self.get_all_properties()
|
||||||
|
required = self.get_all_required_properties_names()
|
||||||
|
|
||||||
|
return dict(
|
||||||
|
(prop_name, val)
|
||||||
|
for prop_name, val in all_properties.items()
|
||||||
|
if prop_name in required
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_all_required_properties_names(self):
|
||||||
required = self.required.copy()
|
required = self.required.copy()
|
||||||
|
|
||||||
for subschema in self.all_of:
|
for subschema in self.all_of:
|
||||||
subschema_req = subschema.get_all_required_properties()
|
subschema_req = subschema.get_all_required_properties()
|
||||||
required += subschema_req
|
required += subschema_req
|
||||||
|
|
||||||
return required
|
return set(required)
|
||||||
|
|
||||||
def get_cast_mapping(self):
|
def get_cast_mapping(self):
|
||||||
mapping = self.DEFAULT_CAST_CALLABLE_GETTER.copy()
|
mapping = self.DEFAULT_CAST_CALLABLE_GETTER.copy()
|
||||||
|
@ -119,27 +145,58 @@ class Schema(object):
|
||||||
raise InvalidSchemaValue(
|
raise InvalidSchemaValue(
|
||||||
"Value of {0} not an object".format(value))
|
"Value of {0} not an object".format(value))
|
||||||
|
|
||||||
all_properties = self.get_all_properties()
|
if self.one_of:
|
||||||
all_required_properties = self.get_all_required_properties()
|
properties = None
|
||||||
all_properties_keys = all_properties.keys()
|
for one_of_schema in self.one_of:
|
||||||
value_keys = value.keys()
|
try:
|
||||||
|
found_props = self._unmarshal_properties(
|
||||||
|
value, one_of_schema)
|
||||||
|
except OpenAPISchemaError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if properties is not None:
|
||||||
|
raise MultipleOneOfSchema(
|
||||||
|
"Exactly one schema should be valid,"
|
||||||
|
"multiple found")
|
||||||
|
properties = found_props
|
||||||
|
|
||||||
extra_props = set(value_keys) - set(all_properties_keys)
|
if properties is None:
|
||||||
|
raise NoOneOfSchema(
|
||||||
|
"Exactly one valid schema should be valid, None found.")
|
||||||
|
|
||||||
|
else:
|
||||||
|
properties = self._unmarshal_properties(value)
|
||||||
|
|
||||||
|
return ModelFactory().create(properties, name=self.model)
|
||||||
|
|
||||||
|
def _unmarshal_properties(self, value, one_of_schema=None):
|
||||||
|
all_props = self.get_all_properties()
|
||||||
|
all_props_names = self.get_all_properties_names()
|
||||||
|
all_req_props_names = self.get_all_required_properties_names()
|
||||||
|
|
||||||
|
if one_of_schema is not None:
|
||||||
|
all_props.update(one_of_schema.get_all_properties())
|
||||||
|
all_props_names |= one_of_schema.\
|
||||||
|
get_all_properties_names()
|
||||||
|
all_req_props_names |= one_of_schema.\
|
||||||
|
get_all_required_properties_names()
|
||||||
|
|
||||||
|
value_props_names = value.keys()
|
||||||
|
extra_props = set(value_props_names) - set(all_props_names)
|
||||||
if extra_props:
|
if extra_props:
|
||||||
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, prop in iteritems(all_properties):
|
for prop_name, prop in iteritems(all_props):
|
||||||
try:
|
try:
|
||||||
prop_value = value[prop_name]
|
prop_value = value[prop_name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
if prop_name in all_required_properties:
|
if prop_name in all_req_props_names:
|
||||||
raise MissingSchemaProperty(
|
raise MissingSchemaProperty(
|
||||||
"Missing schema property {0}".format(prop_name))
|
"Missing schema property {0}".format(prop_name))
|
||||||
if not prop.nullable and not prop.default:
|
if not prop.nullable and not prop.default:
|
||||||
continue
|
continue
|
||||||
prop_value = prop.default
|
prop_value = prop.default
|
||||||
properties[prop_name] = prop.unmarshal(prop_value)
|
properties[prop_name] = prop.unmarshal(prop_value)
|
||||||
return ModelFactory().create(properties, name=self.model)
|
return properties
|
||||||
|
|
|
@ -123,6 +123,22 @@ paths:
|
||||||
$ref: "#/components/schemas/TagList"
|
$ref: "#/components/schemas/TagList"
|
||||||
default:
|
default:
|
||||||
$ref: "#/components/responses/ErrorResponse"
|
$ref: "#/components/responses/ErrorResponse"
|
||||||
|
post:
|
||||||
|
summary: Create new tag
|
||||||
|
operationId: createTag
|
||||||
|
tags:
|
||||||
|
- tags
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/TagCreate'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Null response
|
||||||
|
default:
|
||||||
|
$ref: "#/components/responses/ErrorResponse"
|
||||||
components:
|
components:
|
||||||
schemas:
|
schemas:
|
||||||
Address:
|
Address:
|
||||||
|
@ -163,6 +179,9 @@ components:
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: "#/components/schemas/PetCreatePartOne"
|
- $ref: "#/components/schemas/PetCreatePartOne"
|
||||||
- $ref: "#/components/schemas/PetCreatePartTwo"
|
- $ref: "#/components/schemas/PetCreatePartTwo"
|
||||||
|
oneOf:
|
||||||
|
- $ref: "#/components/schemas/Cat"
|
||||||
|
- $ref: "#/components/schemas/Bird"
|
||||||
PetCreatePartOne:
|
PetCreatePartOne:
|
||||||
type: object
|
type: object
|
||||||
x-model: PetCreatePartOne
|
x-model: PetCreatePartOne
|
||||||
|
@ -183,6 +202,38 @@ components:
|
||||||
$ref: "#/components/schemas/Position"
|
$ref: "#/components/schemas/Position"
|
||||||
healthy:
|
healthy:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
Bird:
|
||||||
|
type: object
|
||||||
|
x-model: Bird
|
||||||
|
required:
|
||||||
|
- wings
|
||||||
|
properties:
|
||||||
|
wings:
|
||||||
|
$ref: "#/components/schemas/Wings"
|
||||||
|
Wings:
|
||||||
|
type: object
|
||||||
|
x-model: Wings
|
||||||
|
required:
|
||||||
|
- healthy
|
||||||
|
properties:
|
||||||
|
healthy:
|
||||||
|
type: boolean
|
||||||
|
Cat:
|
||||||
|
type: object
|
||||||
|
x-model: Cat
|
||||||
|
required:
|
||||||
|
- ears
|
||||||
|
properties:
|
||||||
|
ears:
|
||||||
|
$ref: "#/components/schemas/Ears"
|
||||||
|
Ears:
|
||||||
|
type: object
|
||||||
|
x-model: Ears
|
||||||
|
required:
|
||||||
|
- healthy
|
||||||
|
properties:
|
||||||
|
healthy:
|
||||||
|
type: boolean
|
||||||
Pets:
|
Pets:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
|
@ -201,6 +252,13 @@ components:
|
||||||
properties:
|
properties:
|
||||||
data:
|
data:
|
||||||
$ref: "#/components/schemas/Pet"
|
$ref: "#/components/schemas/Pet"
|
||||||
|
TagCreate:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
TagList:
|
TagList:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
|
|
|
@ -15,7 +15,7 @@ from openapi_core.schema.paths.models import Path
|
||||||
from openapi_core.schema.request_bodies.models import RequestBody
|
from openapi_core.schema.request_bodies.models import RequestBody
|
||||||
from openapi_core.schema.responses.models import Response
|
from openapi_core.schema.responses.models import Response
|
||||||
from openapi_core.schema.schemas.exceptions import (
|
from openapi_core.schema.schemas.exceptions import (
|
||||||
UndefinedSchemaProperty, MissingSchemaProperty,
|
UndefinedSchemaProperty, MissingSchemaProperty, NoOneOfSchema,
|
||||||
)
|
)
|
||||||
from openapi_core.schema.schemas.models import Schema
|
from openapi_core.schema.schemas.models import Schema
|
||||||
from openapi_core.schema.servers.exceptions import InvalidServer
|
from openapi_core.schema.servers.exceptions import InvalidServer
|
||||||
|
@ -369,7 +369,7 @@ class TestPetstore(object):
|
||||||
|
|
||||||
assert body is None
|
assert body is None
|
||||||
|
|
||||||
def test_post_pets(self, spec, spec_dict):
|
def test_post_birds(self, spec, spec_dict):
|
||||||
host_url = 'http://petstore.swagger.io/v1'
|
host_url = 'http://petstore.swagger.io/v1'
|
||||||
path_pattern = '/v1/pets'
|
path_pattern = '/v1/pets'
|
||||||
pet_name = 'Cat'
|
pet_name = 'Cat'
|
||||||
|
@ -386,6 +386,9 @@ class TestPetstore(object):
|
||||||
'city': pet_city,
|
'city': pet_city,
|
||||||
},
|
},
|
||||||
'healthy': pet_healthy,
|
'healthy': pet_healthy,
|
||||||
|
'wings': {
|
||||||
|
'healthy': pet_healthy,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
data = json.dumps(data_json)
|
data = json.dumps(data_json)
|
||||||
|
|
||||||
|
@ -412,7 +415,53 @@ class TestPetstore(object):
|
||||||
assert body.address.city == pet_city
|
assert body.address.city == pet_city
|
||||||
assert body.healthy == pet_healthy
|
assert body.healthy == pet_healthy
|
||||||
|
|
||||||
def test_post_pets_boolean_string(self, spec, spec_dict):
|
def test_post_cats(self, spec, spec_dict):
|
||||||
|
host_url = 'http://petstore.swagger.io/v1'
|
||||||
|
path_pattern = '/v1/pets'
|
||||||
|
pet_name = 'Cat'
|
||||||
|
pet_tag = 'cats'
|
||||||
|
pet_street = 'Piekna'
|
||||||
|
pet_city = 'Warsaw'
|
||||||
|
pet_healthy = False
|
||||||
|
data_json = {
|
||||||
|
'name': pet_name,
|
||||||
|
'tag': pet_tag,
|
||||||
|
'position': '2',
|
||||||
|
'address': {
|
||||||
|
'street': pet_street,
|
||||||
|
'city': pet_city,
|
||||||
|
},
|
||||||
|
'healthy': pet_healthy,
|
||||||
|
'ears': {
|
||||||
|
'healthy': pet_healthy,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data = json.dumps(data_json)
|
||||||
|
|
||||||
|
request = MockRequest(
|
||||||
|
host_url, 'POST', '/pets',
|
||||||
|
path_pattern=path_pattern, data=data,
|
||||||
|
)
|
||||||
|
|
||||||
|
parameters = request.get_parameters(spec)
|
||||||
|
|
||||||
|
assert parameters == {}
|
||||||
|
|
||||||
|
body = request.get_body(spec)
|
||||||
|
|
||||||
|
schemas = spec_dict['components']['schemas']
|
||||||
|
pet_model = schemas['PetCreate']['x-model']
|
||||||
|
address_model = schemas['Address']['x-model']
|
||||||
|
assert body.__class__.__name__ == pet_model
|
||||||
|
assert body.name == pet_name
|
||||||
|
assert body.tag == pet_tag
|
||||||
|
assert body.position == 2
|
||||||
|
assert body.address.__class__.__name__ == address_model
|
||||||
|
assert body.address.street == pet_street
|
||||||
|
assert body.address.city == pet_city
|
||||||
|
assert body.healthy == pet_healthy
|
||||||
|
|
||||||
|
def test_post_cats_boolean_string(self, spec, spec_dict):
|
||||||
host_url = 'http://petstore.swagger.io/v1'
|
host_url = 'http://petstore.swagger.io/v1'
|
||||||
path_pattern = '/v1/pets'
|
path_pattern = '/v1/pets'
|
||||||
pet_name = 'Cat'
|
pet_name = 'Cat'
|
||||||
|
@ -429,6 +478,9 @@ class TestPetstore(object):
|
||||||
'city': pet_city,
|
'city': pet_city,
|
||||||
},
|
},
|
||||||
'healthy': pet_healthy,
|
'healthy': pet_healthy,
|
||||||
|
'ears': {
|
||||||
|
'healthy': pet_healthy,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
data = json.dumps(data_json)
|
data = json.dumps(data_json)
|
||||||
|
|
||||||
|
@ -455,25 +507,7 @@ class TestPetstore(object):
|
||||||
assert body.address.city == pet_city
|
assert body.address.city == pet_city
|
||||||
assert body.healthy is False
|
assert body.healthy is False
|
||||||
|
|
||||||
def test_post_pets_empty_body(self, spec, spec_dict):
|
def test_post_no_one_of_schema(self, spec, spec_dict):
|
||||||
host_url = 'http://petstore.swagger.io/v1'
|
|
||||||
path_pattern = '/v1/pets'
|
|
||||||
data_json = {}
|
|
||||||
data = json.dumps(data_json)
|
|
||||||
|
|
||||||
request = MockRequest(
|
|
||||||
host_url, 'POST', '/pets',
|
|
||||||
path_pattern=path_pattern, data=data,
|
|
||||||
)
|
|
||||||
|
|
||||||
parameters = request.get_parameters(spec)
|
|
||||||
|
|
||||||
assert parameters == {}
|
|
||||||
|
|
||||||
with pytest.raises(MissingSchemaProperty):
|
|
||||||
request.get_body(spec)
|
|
||||||
|
|
||||||
def test_post_pets_extra_body_properties(self, spec, spec_dict):
|
|
||||||
host_url = 'http://petstore.swagger.io/v1'
|
host_url = 'http://petstore.swagger.io/v1'
|
||||||
path_pattern = '/v1/pets'
|
path_pattern = '/v1/pets'
|
||||||
pet_name = 'Cat'
|
pet_name = 'Cat'
|
||||||
|
@ -493,15 +527,19 @@ class TestPetstore(object):
|
||||||
|
|
||||||
assert parameters == {}
|
assert parameters == {}
|
||||||
|
|
||||||
with pytest.raises(UndefinedSchemaProperty):
|
with pytest.raises(NoOneOfSchema):
|
||||||
request.get_body(spec)
|
request.get_body(spec)
|
||||||
|
|
||||||
def test_post_pets_only_required_body(self, spec, spec_dict):
|
def test_post_cats_only_required_body(self, spec, spec_dict):
|
||||||
host_url = 'http://petstore.swagger.io/v1'
|
host_url = 'http://petstore.swagger.io/v1'
|
||||||
path_pattern = '/v1/pets'
|
path_pattern = '/v1/pets'
|
||||||
pet_name = 'Cat'
|
pet_name = 'Cat'
|
||||||
|
pet_healthy = True
|
||||||
data_json = {
|
data_json = {
|
||||||
'name': pet_name,
|
'name': pet_name,
|
||||||
|
'ears': {
|
||||||
|
'healthy': pet_healthy,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
data = json.dumps(data_json)
|
data = json.dumps(data_json)
|
||||||
|
|
||||||
|
@ -523,31 +561,6 @@ class TestPetstore(object):
|
||||||
assert not hasattr(body, 'tag')
|
assert not hasattr(body, 'tag')
|
||||||
assert not hasattr(body, 'address')
|
assert not hasattr(body, 'address')
|
||||||
|
|
||||||
def test_get_pets_wrong_body_type(self, spec):
|
|
||||||
host_url = 'http://petstore.swagger.io/v1'
|
|
||||||
path_pattern = '/v1/pets'
|
|
||||||
pet_name = 'Cat'
|
|
||||||
pet_tag = 'cats'
|
|
||||||
pet_address = 'address text'
|
|
||||||
data_json = {
|
|
||||||
'name': pet_name,
|
|
||||||
'tag': pet_tag,
|
|
||||||
'address': pet_address,
|
|
||||||
}
|
|
||||||
data = json.dumps(data_json)
|
|
||||||
|
|
||||||
request = MockRequest(
|
|
||||||
host_url, 'POST', '/pets',
|
|
||||||
path_pattern=path_pattern, data=data,
|
|
||||||
)
|
|
||||||
|
|
||||||
parameters = request.get_parameters(spec)
|
|
||||||
|
|
||||||
assert parameters == {}
|
|
||||||
|
|
||||||
with pytest.raises(InvalidMediaTypeValue):
|
|
||||||
request.get_body(spec)
|
|
||||||
|
|
||||||
def test_post_pets_raises_invalid_mimetype(self, spec):
|
def test_post_pets_raises_invalid_mimetype(self, spec):
|
||||||
host_url = 'http://petstore.swagger.io/v1'
|
host_url = 'http://petstore.swagger.io/v1'
|
||||||
path_pattern = '/v1/pets'
|
path_pattern = '/v1/pets'
|
||||||
|
@ -685,3 +698,62 @@ class TestPetstore(object):
|
||||||
|
|
||||||
assert response_result.errors == []
|
assert response_result.errors == []
|
||||||
assert response_result.data == data_json
|
assert response_result.data == data_json
|
||||||
|
|
||||||
|
def test_post_tags_extra_body_properties(self, spec, spec_dict):
|
||||||
|
host_url = 'http://petstore.swagger.io/v1'
|
||||||
|
path_pattern = '/v1/tags'
|
||||||
|
pet_name = 'Dog'
|
||||||
|
alias = 'kitty'
|
||||||
|
data_json = {
|
||||||
|
'name': pet_name,
|
||||||
|
'alias': alias,
|
||||||
|
}
|
||||||
|
data = json.dumps(data_json)
|
||||||
|
|
||||||
|
request = MockRequest(
|
||||||
|
host_url, 'POST', '/tags',
|
||||||
|
path_pattern=path_pattern, data=data,
|
||||||
|
)
|
||||||
|
|
||||||
|
parameters = request.get_parameters(spec)
|
||||||
|
|
||||||
|
assert parameters == {}
|
||||||
|
|
||||||
|
with pytest.raises(UndefinedSchemaProperty):
|
||||||
|
request.get_body(spec)
|
||||||
|
|
||||||
|
def test_post_tags_empty_body(self, spec, spec_dict):
|
||||||
|
host_url = 'http://petstore.swagger.io/v1'
|
||||||
|
path_pattern = '/v1/tags'
|
||||||
|
data_json = {}
|
||||||
|
data = json.dumps(data_json)
|
||||||
|
|
||||||
|
request = MockRequest(
|
||||||
|
host_url, 'POST', '/tags',
|
||||||
|
path_pattern=path_pattern, data=data,
|
||||||
|
)
|
||||||
|
|
||||||
|
parameters = request.get_parameters(spec)
|
||||||
|
|
||||||
|
assert parameters == {}
|
||||||
|
|
||||||
|
with pytest.raises(MissingSchemaProperty):
|
||||||
|
request.get_body(spec)
|
||||||
|
|
||||||
|
def test_post_tags_wrong_property_type(self, spec):
|
||||||
|
host_url = 'http://petstore.swagger.io/v1'
|
||||||
|
path_pattern = '/v1/tags'
|
||||||
|
tag_name = 123
|
||||||
|
data = json.dumps(tag_name)
|
||||||
|
|
||||||
|
request = MockRequest(
|
||||||
|
host_url, 'POST', '/tags',
|
||||||
|
path_pattern=path_pattern, data=data,
|
||||||
|
)
|
||||||
|
|
||||||
|
parameters = request.get_parameters(spec)
|
||||||
|
|
||||||
|
assert parameters == {}
|
||||||
|
|
||||||
|
with pytest.raises(InvalidMediaTypeValue):
|
||||||
|
request.get_body(spec)
|
||||||
|
|
|
@ -123,6 +123,9 @@ class TestRequestValidator(object):
|
||||||
'address': {
|
'address': {
|
||||||
'street': pet_street,
|
'street': pet_street,
|
||||||
'city': pet_city,
|
'city': pet_city,
|
||||||
|
},
|
||||||
|
'ears': {
|
||||||
|
'healthy': True,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data = json.dumps(data_json)
|
data = json.dumps(data_json)
|
||||||
|
|
Loading…
Add table
Reference in a new issue