From c733f9434a3517ff9b181069518fcc0ea717cd54 Mon Sep 17 00:00:00 2001 From: Artur Maciag Date: Wed, 4 Apr 2018 11:26:21 +0100 Subject: [PATCH] Allow undefined schema type --- openapi_core/schemas.py | 21 ++++++------- tests/integration/data/v3.0/petstore.yaml | 17 +++++++---- tests/integration/test_petstore.py | 36 +++++++++++++++++++++++ 3 files changed, 58 insertions(+), 16 deletions(-) diff --git a/openapi_core/schemas.py b/openapi_core/schemas.py index f66a5bac..31aaca64 100644 --- a/openapi_core/schemas.py +++ b/openapi_core/schemas.py @@ -36,10 +36,10 @@ class Schema(object): """Represents an OpenAPI Schema.""" def __init__( - self, schema_type, 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, enum=None, deprecated=False, all_of=None): - self.type = SchemaType(schema_type) + self.type = schema_type and SchemaType(schema_type) self.model = model self.properties = properties and dict(properties) or {} self.items = items @@ -76,12 +76,12 @@ def cast(self, value): """Cast value to schema type""" if value is None: if not self.nullable: - raise InvalidValueType( - "Failed to cast value of {0} to {1}".format( - value, self.type) - ) + raise InvalidValueType("Null value for non-nullable schema") return self.default + if self.type is None: + return value + cast_mapping = self.get_cast_mapping() if self.type in cast_mapping and value == '': @@ -167,7 +167,7 @@ def __init__(self, dereferencer): def create(self, schema_spec): schema_deref = self.dereferencer.dereference(schema_spec) - schema_type = schema_deref['type'] + schema_type = schema_deref.get('type') schema_format = schema_deref.get('format') model = schema_deref.get('x-model', None) required = schema_deref.get('required', False) @@ -192,9 +192,10 @@ def create(self, schema_spec): items = self._create_items(items_spec) return Schema( - schema_type, model=model, properties=properties, items=items, - schema_format=schema_format, required=required, default=default, - nullable=nullable, enum=enum, deprecated=deprecated, all_of=all_of, + schema_type=schema_type, model=model, properties=properties, + items=items, schema_format=schema_format, required=required, + default=default, nullable=nullable, enum=enum, + deprecated=deprecated, all_of=all_of, ) @property diff --git a/tests/integration/data/v3.0/petstore.yaml b/tests/integration/data/v3.0/petstore.yaml index 9b210113..405bdeac 100644 --- a/tests/integration/data/v3.0/petstore.yaml +++ b/tests/integration/data/v3.0/petstore.yaml @@ -84,11 +84,7 @@ paths: '201': description: Null response default: - description: unexpected error - content: - application/json: - schema: - $ref: "#/components/schemas/Error" + $ref: "#/components/responses/ErrorResponse" /pets/{petId}: get: summary: Info for a specific pet @@ -192,10 +188,19 @@ components: format: int32 message: type: string + ExtendedError: + allOf: + - $ref: "#/components/schemas/Error" + - type: object + required: + - rootCause + properties: + rootCause: + type: string responses: ErrorResponse: description: unexpected error content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: "#/components/schemas/ExtendedError" diff --git a/tests/integration/test_petstore.py b/tests/integration/test_petstore.py index f8248ca7..d1fd9f9e 100644 --- a/tests/integration/test_petstore.py +++ b/tests/integration/test_petstore.py @@ -619,3 +619,39 @@ def test_get_pet(self, spec, response_validator): assert response_result.errors == [] assert response_result.data == data_json + + def test_get_pet_not_found(self, spec, response_validator): + host_url = 'http://petstore.swagger.io/v1' + path_pattern = '/v1/pets/{petId}' + view_args = { + 'petId': '1', + } + request = MockRequest( + host_url, 'GET', '/pets/1', + path_pattern=path_pattern, view_args=view_args, + ) + + parameters = request.get_parameters(spec) + + assert parameters == { + 'path': { + 'petId': 1, + } + } + + body = request.get_body(spec) + + assert body is None + + data_json = { + 'code': 404, + 'message': 'Not found', + 'rootCause': 'Pet not found', + } + 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