diff --git a/README.rst b/README.rst index 7cd3101..9a414f4 100644 --- a/README.rst +++ b/README.rst @@ -66,8 +66,10 @@ and unmarshal request data from validation result .. code-block:: python - # get parameters dictionary with path, query, cookies and headers parameters + # get parameters object with path, query, cookies and headers parameters validated_params = result.parameters + # or specific parameters + validated_path_params = result.parameters.path # get body validated_body = result.body @@ -81,27 +83,27 @@ or use shortcuts for simple validation validated_params = validate_parameters(spec, request) validated_body = validate_body(spec, request) -Request object should implement BaseOpenAPIRequest interface. You can use FlaskOpenAPIRequest a Flask/Werkzeug request wrapper implementation: +Request object should be instance of OpenAPIRequest class. You can use FlaskOpenAPIRequest a Flask/Werkzeug request factory: .. code-block:: python from openapi_core.shortcuts import RequestValidator - from openapi_core.wrappers.flask import FlaskOpenAPIRequest + from openapi_core.contrib.flask import FlaskOpenAPIRequest openapi_request = FlaskOpenAPIRequest(flask_request) validator = RequestValidator(spec) result = validator.validate(openapi_request) -or specify request wrapper class for shortcuts +or simply specify request factory for shortcuts .. code-block:: python from openapi_core import validate_parameters, validate_body validated_params = validate_parameters( - spec, request, wrapper_class=FlaskOpenAPIRequest) + spec, request, request_factory=FlaskOpenAPIRequest) validated_body = validate_body( - spec, request, wrapper_class=FlaskOpenAPIRequest) + spec, request, request_factory=FlaskOpenAPIRequest) You can also validate responses @@ -136,25 +138,27 @@ or use shortcuts for simple validation validated_data = validate_data(spec, request, response) -Response object should implement BaseOpenAPIResponse interface. You can use FlaskOpenAPIResponse a Flask/Werkzeug response wrapper implementation: +Response object should be instance of OpenAPIResponse class. You can use FlaskOpenAPIResponse a Flask/Werkzeug response factory: .. code-block:: python from openapi_core.shortcuts import ResponseValidator - from openapi_core.wrappers.flask import FlaskOpenAPIResponse + from openapi_core.contrib.flask import FlaskOpenAPIResponse openapi_response = FlaskOpenAPIResponse(flask_response) validator = ResponseValidator(spec) result = validator.validate(openapi_request, openapi_response) -or specify response wrapper class for shortcuts +or simply specify response factory for shortcuts .. code-block:: python from openapi_core import validate_parameters, validate_body validated_data = validate_data( - spec, request, response, response_wrapper_class=FlaskOpenAPIResponse) + spec, request, response, + request_factory=FlaskOpenAPIRequest, + response_factory=FlaskOpenAPIResponse) Related projects ================ diff --git a/openapi_core/wrappers/__init__.py b/openapi_core/contrib/__init__.py similarity index 100% rename from openapi_core/wrappers/__init__.py rename to openapi_core/contrib/__init__.py diff --git a/openapi_core/contrib/flask/__init__.py b/openapi_core/contrib/flask/__init__.py new file mode 100644 index 0000000..415b74c --- /dev/null +++ b/openapi_core/contrib/flask/__init__.py @@ -0,0 +1,11 @@ +from openapi_core.contrib.flask.requests import FlaskOpenAPIRequestFactory +from openapi_core.contrib.flask.responses import FlaskOpenAPIResponseFactory + +# backward compatibility +FlaskOpenAPIRequest = FlaskOpenAPIRequestFactory.create +FlaskOpenAPIResponse = FlaskOpenAPIResponseFactory.create + +__all__ = [ + 'FlaskOpenAPIRequestFactory', 'FlaskOpenAPIResponseFactory', + 'FlaskOpenAPIRequest', 'FlaskOpenAPIResponse', +] diff --git a/openapi_core/contrib/flask/requests.py b/openapi_core/contrib/flask/requests.py new file mode 100644 index 0000000..93e6538 --- /dev/null +++ b/openapi_core/contrib/flask/requests.py @@ -0,0 +1,39 @@ +"""OpenAPI core contrib flask requests module""" +import re + +from openapi_core.validation.request.datatypes import ( + RequestParameters, OpenAPIRequest, +) + +# http://flask.pocoo.org/docs/1.0/quickstart/#variable-rules +PATH_PARAMETER_PATTERN = r'<(?:(?:string|int|float|path|uuid):)?(\w+)>' + + +class FlaskOpenAPIRequestFactory(object): + + path_regex = re.compile(PATH_PARAMETER_PATTERN) + + @classmethod + def create(cls, request): + method = request.method.lower() + + if request.url_rule is None: + path_pattern = request.path + else: + path_pattern = cls.path_regex.sub(r'{\1}', request.url_rule.rule) + + parameters = RequestParameters( + path=request.view_args, + query=request.args, + header=request.headers, + cookie=request.cookies, + ) + return OpenAPIRequest( + host_url=request.host_url, + path=request.path, + path_pattern=path_pattern, + method=method, + parameters=parameters, + body=request.data, + mimetype=request.mimetype, + ) diff --git a/openapi_core/contrib/flask/responses.py b/openapi_core/contrib/flask/responses.py new file mode 100644 index 0000000..6e1f3e2 --- /dev/null +++ b/openapi_core/contrib/flask/responses.py @@ -0,0 +1,15 @@ +"""OpenAPI core contrib flask responses module""" +import re + +from openapi_core.validation.response.datatypes import OpenAPIResponse + + +class FlaskOpenAPIResponseFactory(object): + + @classmethod + def create(cls, response): + return OpenAPIResponse( + data=response.data, + status_code=response._status_code, + mimetype=response.mimetype, + ) diff --git a/openapi_core/shortcuts.py b/openapi_core/shortcuts.py index 02df1c1..e55006d 100644 --- a/openapi_core/shortcuts.py +++ b/openapi_core/shortcuts.py @@ -20,9 +20,9 @@ def create_spec(spec_dict, spec_url=''): return spec_factory.create(spec_dict, spec_url=spec_url) -def validate_parameters(spec, request, wrapper_class=None): - if wrapper_class is not None: - request = wrapper_class(request) +def validate_parameters(spec, request, request_factory=None): + if request_factory is not None: + request = request_factory(request) validator = RequestValidator(spec) result = validator.validate(request) @@ -38,9 +38,9 @@ def validate_parameters(spec, request, wrapper_class=None): return result.parameters -def validate_body(spec, request, wrapper_class=None): - if wrapper_class is not None: - request = wrapper_class(request) +def validate_body(spec, request, request_factory=None): + if request_factory is not None: + request = request_factory(request) validator = RequestValidator(spec) result = validator.validate(request) @@ -55,13 +55,13 @@ def validate_body(spec, request, wrapper_class=None): def validate_data( spec, request, response, - request_wrapper_class=None, - response_wrapper_class=None): - if request_wrapper_class is not None: - request = request_wrapper_class(request) + request_factory=None, + response_factory=None): + if request_factory is not None: + request = request_factory(request) - if response_wrapper_class is not None: - response = response_wrapper_class(response) + if response_factory is not None: + response = response_factory(response) validator = ResponseValidator(spec) result = validator.validate(request, response) diff --git a/openapi_core/testing/__init__.py b/openapi_core/testing/__init__.py new file mode 100644 index 0000000..28b50ca --- /dev/null +++ b/openapi_core/testing/__init__.py @@ -0,0 +1,10 @@ +"""OpenAPI core testing module""" +from openapi_core.testing.mock import MockRequestFactory, MockResponseFactory + +# backward compatibility +MockRequest = MockRequestFactory.create +MockResponse = MockResponseFactory.create + +__all__ = [ + 'MockRequestFactory', 'MockResponseFactory', 'MockRequest', 'MockResponse', +] diff --git a/openapi_core/testing/mock.py b/openapi_core/testing/mock.py new file mode 100644 index 0000000..4ff0533 --- /dev/null +++ b/openapi_core/testing/mock.py @@ -0,0 +1,45 @@ +"""OpenAPI core testing mock module""" +from werkzeug.datastructures import ImmutableMultiDict + +from openapi_core.validation.request.datatypes import ( + RequestParameters, OpenAPIRequest, +) +from openapi_core.validation.response.datatypes import OpenAPIResponse + + +class MockRequestFactory(object): + + @classmethod + def create( + cls, host_url, method, path, path_pattern=None, args=None, + view_args=None, headers=None, cookies=None, data=None, + mimetype='application/json'): + parameters = RequestParameters( + path=view_args or {}, + query=ImmutableMultiDict(args or []), + header=headers or {}, + cookie=cookies or {}, + ) + path_pattern = path_pattern or path + method = method.lower() + body = data or '' + return OpenAPIRequest( + host_url=host_url, + path=path, + path_pattern=path_pattern, + method=method, + parameters=parameters, + body=body, + mimetype=mimetype, + ) + + +class MockResponseFactory(object): + + @classmethod + def create(cls, data, status_code=200, mimetype='application/json'): + return OpenAPIResponse( + data=data, + status_code=status_code, + mimetype=mimetype, + ) diff --git a/openapi_core/validation/request/datatypes.py b/openapi_core/validation/request/datatypes.py index 2e5b8ea..4158798 100644 --- a/openapi_core/validation/request/datatypes.py +++ b/openapi_core/validation/request/datatypes.py @@ -1,13 +1,17 @@ """OpenAPI core validation request datatypes module""" import attr +from werkzeug.datastructures import ImmutableMultiDict from openapi_core.validation.datatypes import BaseValidationResult +from six.moves.urllib.parse import urljoin + + @attr.s class RequestParameters(object): path = attr.ib(factory=dict) - query = attr.ib(factory=dict) + query = attr.ib(factory=ImmutableMultiDict) header = attr.ib(factory=dict) cookie = attr.ib(factory=dict) @@ -15,6 +19,25 @@ class RequestParameters(object): return getattr(self, location) +@attr.s +class OpenAPIRequest(object): + + host_url = attr.ib() + path = attr.ib() + path_pattern = attr.ib() + method = attr.ib() + + body = attr.ib() + + mimetype = attr.ib() + + parameters = attr.ib(factory=RequestParameters) + + @property + def full_url_pattern(self): + return urljoin(self.host_url, self.path_pattern) + + @attr.s class RequestValidationResult(BaseValidationResult): body = attr.ib(default=None) diff --git a/openapi_core/validation/request/validators.py b/openapi_core/validation/request/validators.py index a6d8e78..dd726d9 100644 --- a/openapi_core/validation/request/validators.py +++ b/openapi_core/validation/request/validators.py @@ -50,7 +50,7 @@ class RequestValidator(object): def _get_parameters(self, request, params): errors = [] seen = set() - parameters = RequestParameters() + locations = {} for param_name, param in params: if (param_name, param.location.value) in seen: # skip parameter already seen @@ -79,9 +79,10 @@ class RequestValidator(object): except OpenAPIMappingError as exc: errors.append(exc) else: - parameters[param.location.value][param_name] = unmarshalled + locations.setdefault(param.location.value, {}) + locations[param.location.value][param_name] = unmarshalled - return parameters, errors + return RequestParameters(**locations), errors def _get_body(self, request, operation): errors = [] diff --git a/openapi_core/validation/response/datatypes.py b/openapi_core/validation/response/datatypes.py index 38cfb07..c41f5a2 100644 --- a/openapi_core/validation/response/datatypes.py +++ b/openapi_core/validation/response/datatypes.py @@ -4,6 +4,15 @@ import attr from openapi_core.validation.datatypes import BaseValidationResult +@attr.s +class OpenAPIResponse(object): + + data = attr.ib() + status_code = attr.ib() + + mimetype = attr.ib() + + @attr.s class ResponseValidationResult(BaseValidationResult): data = attr.ib(default=None) diff --git a/openapi_core/wrappers/base.py b/openapi_core/wrappers/base.py deleted file mode 100644 index 395d16e..0000000 --- a/openapi_core/wrappers/base.py +++ /dev/null @@ -1,49 +0,0 @@ -"""OpenAPI core wrappers module""" -import warnings - -from six.moves.urllib.parse import urljoin - - -class BaseOpenAPIRequest(object): - - host_url = NotImplemented - path = NotImplemented - path_pattern = NotImplemented - method = NotImplemented - - parameters = NotImplemented - body = NotImplemented - - mimetype = NotImplemented - - @property - def full_url_pattern(self): - return urljoin(self.host_url, self.path_pattern) - - def get_body(self, spec): - warnings.warn( - "`get_body` method is deprecated. " - "Use RequestValidator instead.", - DeprecationWarning, - ) - # backward compatibility - from openapi_core.shortcuts import validate_body - return validate_body(spec, self, wrapper_class=None) - - def get_parameters(self, spec): - warnings.warn( - "`get_parameters` method is deprecated. " - "Use RequestValidator instead.", - DeprecationWarning, - ) - # backward compatibility - from openapi_core.shortcuts import validate_parameters - return validate_parameters(spec, self, wrapper_class=None) - - -class BaseOpenAPIResponse(object): - - body = NotImplemented - status_code = NotImplemented - - mimetype = NotImplemented diff --git a/openapi_core/wrappers/flask.py b/openapi_core/wrappers/flask.py deleted file mode 100644 index 14c330b..0000000 --- a/openapi_core/wrappers/flask.py +++ /dev/null @@ -1,69 +0,0 @@ -"""OpenAPI core wrappers module""" -import re - -from openapi_core.wrappers.base import BaseOpenAPIRequest, BaseOpenAPIResponse - -# http://flask.pocoo.org/docs/1.0/quickstart/#variable-rules -PATH_PARAMETER_PATTERN = r'<(?:(?:string|int|float|path|uuid):)?(\w+)>' - - -class FlaskOpenAPIRequest(BaseOpenAPIRequest): - - path_regex = re.compile(PATH_PARAMETER_PATTERN) - - def __init__(self, request): - self.request = request - - @property - def host_url(self): - return self.request.host_url - - @property - def path(self): - return self.request.path - - @property - def method(self): - return self.request.method.lower() - - @property - def path_pattern(self): - if self.request.url_rule is None: - return self.path - - return self.path_regex.sub(r'{\1}', self.request.url_rule.rule) - - @property - def parameters(self): - return { - 'path': self.request.view_args, - 'query': self.request.args, - 'header': self.request.headers, - 'cookie': self.request.cookies, - } - - @property - def body(self): - return self.request.data - - @property - def mimetype(self): - return self.request.mimetype - - -class FlaskOpenAPIResponse(BaseOpenAPIResponse): - - def __init__(self, response): - self.response = response - - @property - def data(self): - return self.response.data - - @property - def status_code(self): - return self.response._status_code - - @property - def mimetype(self): - return self.response.mimetype diff --git a/openapi_core/wrappers/mock.py b/openapi_core/wrappers/mock.py deleted file mode 100644 index 9b03429..0000000 --- a/openapi_core/wrappers/mock.py +++ /dev/null @@ -1,36 +0,0 @@ -"""OpenAPI core wrappers module""" -from werkzeug.datastructures import ImmutableMultiDict - -from openapi_core.wrappers.base import BaseOpenAPIRequest, BaseOpenAPIResponse - - -class MockRequest(BaseOpenAPIRequest): - - def __init__( - self, host_url, method, path, path_pattern=None, args=None, - view_args=None, headers=None, cookies=None, data=None, - mimetype='application/json'): - self.host_url = host_url - self.path = path - self.path_pattern = path_pattern or path - self.method = method.lower() - - self.parameters = { - 'path': view_args or {}, - 'query': ImmutableMultiDict(args or []), - 'header': headers or {}, - 'cookie': cookies or {}, - } - - self.body = data or '' - - self.mimetype = mimetype - - -class MockResponse(BaseOpenAPIResponse): - - def __init__(self, data, status_code=200, mimetype='application/json'): - self.data = data - - self.status_code = status_code - self.mimetype = mimetype diff --git a/tests/integration/test_wrappers.py b/tests/integration/contrib/test_flask.py similarity index 87% rename from tests/integration/test_wrappers.py rename to tests/integration/contrib/test_flask.py index 6c4b7d1..c058543 100644 --- a/tests/integration/test_wrappers.py +++ b/tests/integration/contrib/test_flask.py @@ -1,14 +1,16 @@ from flask.wrappers import Request, Response +import pytest from werkzeug.datastructures import EnvironHeaders, ImmutableMultiDict from werkzeug.routing import Map, Rule, Subdomain from werkzeug.test import create_environ -import pytest +from openapi_core.contrib.flask import ( + FlaskOpenAPIRequest, FlaskOpenAPIResponse, +) from openapi_core.shortcuts import create_spec -from openapi_core.validation.response.validators import ResponseValidator +from openapi_core.validation.request.datatypes import RequestParameters from openapi_core.validation.request.validators import RequestValidator -from openapi_core.wrappers.flask import (FlaskOpenAPIRequest, - FlaskOpenAPIResponse) +from openapi_core.validation.response.validators import ResponseValidator @pytest.fixture @@ -66,12 +68,12 @@ class TestFlaskOpenAPIRequest(object): query = ImmutableMultiDict([]) headers = EnvironHeaders(request.environ) cookies = {} - assert openapi_request.parameters == { - 'path': path, - 'query': query, - 'header': headers, - 'cookie': cookies, - } + assert openapi_request.parameters == RequestParameters( + path=path, + query=query, + header=headers, + cookie=cookies, + ) assert openapi_request.host_url == request.host_url assert openapi_request.path == request.path assert openapi_request.method == request.method.lower() @@ -91,12 +93,12 @@ class TestFlaskOpenAPIRequest(object): ]) headers = EnvironHeaders(request.environ) cookies = {} - assert openapi_request.parameters == { - 'path': path, - 'query': query, - 'header': headers, - 'cookie': cookies, - } + assert openapi_request.parameters == RequestParameters( + path=path, + query=query, + header=headers, + cookie=cookies, + ) assert openapi_request.host_url == request.host_url assert openapi_request.path == request.path assert openapi_request.method == request.method.lower() @@ -113,12 +115,12 @@ class TestFlaskOpenAPIRequest(object): query = ImmutableMultiDict([]) headers = EnvironHeaders(request.environ) cookies = {} - assert openapi_request.parameters == { - 'path': path, - 'query': query, - 'header': headers, - 'cookie': cookies, - } + assert openapi_request.parameters == RequestParameters( + path=path, + query=query, + header=headers, + cookie=cookies, + ) assert openapi_request.host_url == request.host_url assert openapi_request.path == request.path assert openapi_request.method == request.method.lower() @@ -134,7 +136,6 @@ class TestFlaskOpenAPIResponse(object): openapi_response = FlaskOpenAPIResponse(response) - assert openapi_response.response == response assert openapi_response.data == response.data assert openapi_response.status_code == response._status_code assert openapi_response.mimetype == response.mimetype @@ -144,7 +145,7 @@ class TestFlaskOpenAPIValidation(object): @pytest.fixture def flask_spec(self, factory): - specfile = 'data/v3.0/flask_wrapper.yaml' + specfile = 'data/v3.0/flask_factory.yaml' return create_spec(factory.spec_from_file(specfile)) def test_response_validator_path_pattern(self, diff --git a/tests/integration/data/v3.0/flask_wrapper.yaml b/tests/integration/data/v3.0/flask_factory.yaml similarity index 80% rename from tests/integration/data/v3.0/flask_wrapper.yaml rename to tests/integration/data/v3.0/flask_factory.yaml index 0dcfdd3..6b01b8b 100644 --- a/tests/integration/data/v3.0/flask_wrapper.yaml +++ b/tests/integration/data/v3.0/flask_factory.yaml @@ -1,6 +1,6 @@ openapi: "3.0.0" info: - title: Basic OpenAPI specification used with test_wrappers.TestFlaskOpenAPIIValidation + title: Basic OpenAPI specification used with test_flask.TestFlaskOpenAPIIValidation version: "0.1" servers: - url: 'http://localhost' diff --git a/tests/integration/validation/test_minimal.py b/tests/integration/validation/test_minimal.py index 936c27b..00390aa 100644 --- a/tests/integration/validation/test_minimal.py +++ b/tests/integration/validation/test_minimal.py @@ -3,8 +3,8 @@ import pytest from openapi_core.schema.operations.exceptions import InvalidOperation from openapi_core.schema.paths.exceptions import InvalidPath from openapi_core.shortcuts import create_spec +from openapi_core.testing import MockRequest from openapi_core.validation.request.validators import RequestValidator -from openapi_core.wrappers.mock import MockRequest class TestMinimal(object): diff --git a/tests/integration/validation/test_petstore.py b/tests/integration/validation/test_petstore.py index b07f7f0..0e06022 100644 --- a/tests/integration/validation/test_petstore.py +++ b/tests/integration/validation/test_petstore.py @@ -15,11 +15,13 @@ from openapi_core.schema.parameters.exceptions import ( from openapi_core.schema.schemas.enums import SchemaType from openapi_core.schema.schemas.exceptions import InvalidSchemaValue from openapi_core.schema.servers.exceptions import InvalidServer -from openapi_core.shortcuts import create_spec +from openapi_core.shortcuts import ( + create_spec, validate_parameters, validate_body, +) +from openapi_core.testing import MockRequest, MockResponse from openapi_core.validation.request.datatypes import RequestParameters from openapi_core.validation.request.validators import RequestValidator from openapi_core.validation.response.validators import ResponseValidator -from openapi_core.wrappers.mock import MockRequest, MockResponse class TestPetstore(object): @@ -64,8 +66,8 @@ class TestPetstore(object): path_pattern=path_pattern, args=query_params, ) - parameters = request.get_parameters(spec) - body = request.get_body(spec) + parameters = validate_parameters(spec, request) + body = validate_body(spec, request) assert parameters == RequestParameters( query={ @@ -100,8 +102,8 @@ class TestPetstore(object): path_pattern=path_pattern, args=query_params, ) - parameters = request.get_parameters(spec) - body = request.get_body(spec) + parameters = validate_parameters(spec, request) + body = validate_body(spec, request) assert parameters == RequestParameters( query={ @@ -146,8 +148,8 @@ class TestPetstore(object): path_pattern=path_pattern, args=query_params, ) - parameters = request.get_parameters(spec) - body = request.get_body(spec) + parameters = validate_parameters(spec, request) + body = validate_body(spec, request) assert parameters == RequestParameters( query={ @@ -197,8 +199,8 @@ class TestPetstore(object): path_pattern=path_pattern, args=query_params, ) - parameters = request.get_parameters(spec) - body = request.get_body(spec) + parameters = validate_parameters(spec, request) + body = validate_body(spec, request) assert parameters == RequestParameters( query={ @@ -235,8 +237,8 @@ class TestPetstore(object): path_pattern=path_pattern, args=query_params, ) - parameters = request.get_parameters(spec) - body = request.get_body(spec) + parameters = validate_parameters(spec, request) + body = validate_body(spec, request) assert parameters == RequestParameters( query={ @@ -274,9 +276,9 @@ class TestPetstore(object): ) with pytest.raises(InvalidParameterValue): - request.get_parameters(spec) + validate_parameters(spec, request) - body = request.get_body(spec) + body = validate_body(spec, request) assert body is None @@ -293,9 +295,9 @@ class TestPetstore(object): ) with pytest.raises(InvalidParameterValue): - request.get_parameters(spec) + validate_parameters(spec, request) - body = request.get_body(spec) + body = validate_body(spec, request) assert body is None @@ -308,9 +310,9 @@ class TestPetstore(object): ) with pytest.raises(MissingRequiredParameter): - request.get_parameters(spec) + validate_parameters(spec, request) - body = request.get_body(spec) + body = validate_body(spec, request) assert body is None @@ -327,8 +329,8 @@ class TestPetstore(object): ) with pytest.raises(EmptyParameterValue): - request.get_parameters(spec) - body = request.get_body(spec) + validate_parameters(spec, request) + body = validate_body(spec, request) assert body is None @@ -344,7 +346,7 @@ class TestPetstore(object): path_pattern=path_pattern, args=query_params, ) - parameters = request.get_parameters(spec) + parameters = validate_parameters(spec, request) assert parameters == RequestParameters( query={ @@ -354,7 +356,7 @@ class TestPetstore(object): } ) - body = request.get_body(spec) + body = validate_body(spec, request) assert body is None @@ -393,7 +395,7 @@ class TestPetstore(object): headers=headers, cookies=cookies, ) - parameters = request.get_parameters(spec) + parameters = validate_parameters(spec, request) assert parameters == RequestParameters( header={ @@ -404,7 +406,7 @@ class TestPetstore(object): }, ) - body = request.get_body(spec) + body = validate_body(spec, request) schemas = spec_dict['components']['schemas'] pet_model = schemas['PetCreate']['x-model'] @@ -453,7 +455,7 @@ class TestPetstore(object): headers=headers, cookies=cookies, ) - parameters = request.get_parameters(spec) + parameters = validate_parameters(spec, request) assert parameters == RequestParameters( header={ @@ -464,7 +466,7 @@ class TestPetstore(object): }, ) - body = request.get_body(spec) + body = validate_body(spec, request) schemas = spec_dict['components']['schemas'] pet_model = schemas['PetCreate']['x-model'] @@ -513,7 +515,7 @@ class TestPetstore(object): headers=headers, cookies=cookies, ) - parameters = request.get_parameters(spec) + parameters = validate_parameters(spec, request) assert parameters == RequestParameters( header={ @@ -524,7 +526,7 @@ class TestPetstore(object): }, ) - body = request.get_body(spec) + body = validate_body(spec, request) schemas = spec_dict['components']['schemas'] pet_model = schemas['PetCreate']['x-model'] @@ -561,7 +563,7 @@ class TestPetstore(object): headers=headers, cookies=cookies, ) - parameters = request.get_parameters(spec) + parameters = validate_parameters(spec, request) assert parameters == RequestParameters( header={ @@ -573,7 +575,7 @@ class TestPetstore(object): ) with pytest.raises(InvalidMediaTypeValue): - request.get_body(spec) + validate_body(spec, request) def test_post_cats_only_required_body(self, spec, spec_dict): host_url = 'http://petstore.swagger.io/v1' @@ -600,7 +602,7 @@ class TestPetstore(object): headers=headers, cookies=cookies, ) - parameters = request.get_parameters(spec) + parameters = validate_parameters(spec, request) assert parameters == RequestParameters( header={ @@ -611,7 +613,7 @@ class TestPetstore(object): }, ) - body = request.get_body(spec) + body = validate_body(spec, request) schemas = spec_dict['components']['schemas'] pet_model = schemas['PetCreate']['x-model'] @@ -641,7 +643,7 @@ class TestPetstore(object): headers=headers, cookies=cookies, ) - parameters = request.get_parameters(spec) + parameters = validate_parameters(spec, request) assert parameters == RequestParameters( header={ @@ -653,7 +655,7 @@ class TestPetstore(object): ) with pytest.raises(InvalidContentType): - request.get_body(spec) + validate_body(spec, request) def test_post_pets_missing_cookie(self, spec, spec_dict): host_url = 'http://petstore.swagger.io/v1' @@ -678,9 +680,9 @@ class TestPetstore(object): ) with pytest.raises(MissingRequiredParameter): - request.get_parameters(spec) + validate_parameters(spec, request) - body = request.get_body(spec) + body = validate_body(spec, request) schemas = spec_dict['components']['schemas'] pet_model = schemas['PetCreate']['x-model'] @@ -712,9 +714,9 @@ class TestPetstore(object): ) with pytest.raises(MissingRequiredParameter): - request.get_parameters(spec) + validate_parameters(spec, request) - body = request.get_body(spec) + body = validate_body(spec, request) schemas = spec_dict['components']['schemas'] pet_model = schemas['PetCreate']['x-model'] @@ -745,10 +747,10 @@ class TestPetstore(object): ) with pytest.raises(InvalidServer): - request.get_parameters(spec) + validate_parameters(spec, request) with pytest.raises(InvalidServer): - request.get_body(spec) + validate_body(spec, request) def test_get_pet(self, spec, response_validator): host_url = 'http://petstore.swagger.io/v1' @@ -761,7 +763,7 @@ class TestPetstore(object): path_pattern=path_pattern, view_args=view_args, ) - parameters = request.get_parameters(spec) + parameters = validate_parameters(spec, request) assert parameters == RequestParameters( path={ @@ -769,7 +771,7 @@ class TestPetstore(object): } ) - body = request.get_body(spec) + body = validate_body(spec, request) assert body is None @@ -806,7 +808,7 @@ class TestPetstore(object): path_pattern=path_pattern, view_args=view_args, ) - parameters = request.get_parameters(spec) + parameters = validate_parameters(spec, request) assert parameters == RequestParameters( path={ @@ -814,7 +816,7 @@ class TestPetstore(object): } ) - body = request.get_body(spec) + body = validate_body(spec, request) assert body is None @@ -848,7 +850,7 @@ class TestPetstore(object): path_pattern=path_pattern, view_args=view_args, ) - parameters = request.get_parameters(spec) + parameters = validate_parameters(spec, request) assert parameters == RequestParameters( path={ @@ -856,7 +858,7 @@ class TestPetstore(object): } ) - body = request.get_body(spec) + body = validate_body(spec, request) assert body is None @@ -877,8 +879,8 @@ class TestPetstore(object): path_pattern=path_pattern, ) - parameters = request.get_parameters(spec) - body = request.get_body(spec) + parameters = validate_parameters(spec, request) + body = validate_body(spec, request) assert parameters == RequestParameters() assert body is None @@ -908,12 +910,12 @@ class TestPetstore(object): path_pattern=path_pattern, data=data, ) - parameters = request.get_parameters(spec) + parameters = validate_parameters(spec, request) assert parameters == RequestParameters() with pytest.raises(InvalidMediaTypeValue): - request.get_body(spec) + validate_body(spec, request) def test_post_tags_empty_body(self, spec, spec_dict): host_url = 'http://petstore.swagger.io/v1' @@ -926,12 +928,12 @@ class TestPetstore(object): path_pattern=path_pattern, data=data, ) - parameters = request.get_parameters(spec) + parameters = validate_parameters(spec, request) assert parameters == RequestParameters() with pytest.raises(InvalidMediaTypeValue): - request.get_body(spec) + validate_body(spec, request) def test_post_tags_wrong_property_type(self, spec): host_url = 'http://petstore.swagger.io/v1' @@ -944,12 +946,12 @@ class TestPetstore(object): path_pattern=path_pattern, data=data, ) - parameters = request.get_parameters(spec) + parameters = validate_parameters(spec, request) assert parameters == RequestParameters() with pytest.raises(InvalidMediaTypeValue): - request.get_body(spec) + validate_body(spec, request) def test_post_tags_additional_properties( self, spec, response_validator): @@ -966,8 +968,8 @@ class TestPetstore(object): path_pattern=path_pattern, data=data, ) - parameters = request.get_parameters(spec) - body = request.get_body(spec) + parameters = validate_parameters(spec, request) + body = validate_body(spec, request) assert parameters == RequestParameters() assert isinstance(body, BaseModel) @@ -1012,8 +1014,8 @@ class TestPetstore(object): path_pattern=path_pattern, data=data, ) - parameters = request.get_parameters(spec) - body = request.get_body(spec) + parameters = validate_parameters(spec, request) + body = validate_body(spec, request) assert parameters == RequestParameters() assert isinstance(body, BaseModel) @@ -1059,8 +1061,8 @@ class TestPetstore(object): path_pattern=path_pattern, data=data, ) - parameters = request.get_parameters(spec) - body = request.get_body(spec) + parameters = validate_parameters(spec, request) + body = validate_body(spec, request) assert parameters == RequestParameters() assert isinstance(body, BaseModel) @@ -1106,9 +1108,9 @@ class TestPetstore(object): path_pattern=path_pattern, data=data, ) - parameters = request.get_parameters(spec) + parameters = validate_parameters(spec, request) with pytest.raises(InvalidMediaTypeValue): - request.get_body(spec) + validate_body(spec, request) assert parameters == RequestParameters() diff --git a/tests/integration/validation/test_validators.py b/tests/integration/validation/test_validators.py index c696cf1..449fdf4 100644 --- a/tests/integration/validation/test_validators.py +++ b/tests/integration/validation/test_validators.py @@ -17,10 +17,10 @@ from openapi_core.schema.responses.exceptions import ( ) from openapi_core.schema.servers.exceptions import InvalidServer from openapi_core.shortcuts import create_spec +from openapi_core.testing import MockRequest, MockResponse from openapi_core.validation.request.datatypes import RequestParameters from openapi_core.validation.request.validators import RequestValidator from openapi_core.validation.response.validators import ResponseValidator -from openapi_core.wrappers.mock import MockRequest, MockResponse class TestRequestValidator(object): diff --git a/tests/unit/test_shortcuts.py b/tests/unit/test_shortcuts.py index dc2caca..c5f1a7d 100644 --- a/tests/unit/test_shortcuts.py +++ b/tests/unit/test_shortcuts.py @@ -27,7 +27,7 @@ class ResultMock(object): return self.data -class WrapperClassMock(object): +class FactoryClassMock(object): _instances = {} @@ -43,7 +43,7 @@ class WrapperClassMock(object): class TestValidateParameters(object): @mock.patch('openapi_core.shortcuts.RequestValidator.validate') - def test_no_wrapper(self, mock_validate): + def test_no_request_factory(self, mock_validate): spec = mock.sentinel.spec request = mock.sentinel.request parameters = mock.sentinel.parameters @@ -55,7 +55,7 @@ class TestValidateParameters(object): mock_validate.aasert_called_once_with(request) @mock.patch('openapi_core.shortcuts.RequestValidator.validate') - def test_no_wrapper_error(self, mock_validate): + def test_no_request_factory_error(self, mock_validate): spec = mock.sentinel.spec request = mock.sentinel.request mock_validate.return_value = ResultMock(error_to_raise=ValueError) @@ -66,39 +66,39 @@ class TestValidateParameters(object): mock_validate.aasert_called_once_with(request) @mock.patch('openapi_core.shortcuts.RequestValidator.validate') - def test_wrapper(self, mock_validate): + def test_request_factory(self, mock_validate): spec = mock.sentinel.spec request = mock.sentinel.request parameters = mock.sentinel.parameters mock_validate.return_value = ResultMock(parameters=parameters) - request_wrapper_class = WrapperClassMock + request_factory = FactoryClassMock - result = validate_parameters(spec, request, request_wrapper_class) + result = validate_parameters(spec, request, request_factory) assert result == parameters mock_validate.assert_called_once_with( - WrapperClassMock(request), + FactoryClassMock(request), ) @mock.patch('openapi_core.shortcuts.RequestValidator.validate') - def test_wrapper_error(self, mock_validate): + def test_request_factory_error(self, mock_validate): spec = mock.sentinel.spec request = mock.sentinel.request mock_validate.return_value = ResultMock(error_to_raise=ValueError) - request_wrapper_class = WrapperClassMock + request_factory = FactoryClassMock with pytest.raises(ValueError): - validate_parameters(spec, request, request_wrapper_class) + validate_parameters(spec, request, request_factory) mock_validate.assert_called_once_with( - WrapperClassMock(request), + FactoryClassMock(request), ) class TestValidateBody(object): @mock.patch('openapi_core.shortcuts.RequestValidator.validate') - def test_no_wrapper(self, mock_validate): + def test_no_request_factory(self, mock_validate): spec = mock.sentinel.spec request = mock.sentinel.request body = mock.sentinel.body @@ -110,7 +110,7 @@ class TestValidateBody(object): mock_validate.aasert_called_once_with(request) @mock.patch('openapi_core.shortcuts.RequestValidator.validate') - def test_no_wrapper_error(self, mock_validate): + def test_no_request_factory_error(self, mock_validate): spec = mock.sentinel.spec request = mock.sentinel.request mock_validate.return_value = ResultMock(error_to_raise=ValueError) @@ -121,39 +121,39 @@ class TestValidateBody(object): mock_validate.aasert_called_once_with(request) @mock.patch('openapi_core.shortcuts.RequestValidator.validate') - def test_wrapper(self, mock_validate): + def test_request_factory(self, mock_validate): spec = mock.sentinel.spec request = mock.sentinel.request body = mock.sentinel.body mock_validate.return_value = ResultMock(body=body) - request_wrapper_class = WrapperClassMock + request_factory = FactoryClassMock - result = validate_body(spec, request, request_wrapper_class) + result = validate_body(spec, request, request_factory) assert result == body mock_validate.assert_called_once_with( - WrapperClassMock(request), + FactoryClassMock(request), ) @mock.patch('openapi_core.shortcuts.RequestValidator.validate') - def test_wrapper_error(self, mock_validate): + def test_request_factory_error(self, mock_validate): spec = mock.sentinel.spec request = mock.sentinel.request mock_validate.return_value = ResultMock(error_to_raise=ValueError) - request_wrapper_class = WrapperClassMock + request_factory = FactoryClassMock with pytest.raises(ValueError): - validate_body(spec, request, request_wrapper_class) + validate_body(spec, request, request_factory) mock_validate.assert_called_once_with( - WrapperClassMock(request), + FactoryClassMock(request), ) class TestvalidateData(object): @mock.patch('openapi_core.shortcuts.ResponseValidator.validate') - def test_no_wrappers(self, mock_validate): + def test_no_factories(self, mock_validate): spec = mock.sentinel.spec request = mock.sentinel.request response = mock.sentinel.response @@ -166,7 +166,7 @@ class TestvalidateData(object): mock_validate.aasert_called_once_with(request, response) @mock.patch('openapi_core.shortcuts.ResponseValidator.validate') - def test_no_wrappers_error(self, mock_validate): + def test_no_factories_error(self, mock_validate): spec = mock.sentinel.spec request = mock.sentinel.request response = mock.sentinel.response @@ -178,42 +178,42 @@ class TestvalidateData(object): mock_validate.aasert_called_once_with(request, response) @mock.patch('openapi_core.shortcuts.ResponseValidator.validate') - def test_wrappers(self, mock_validate): + def test_factories(self, mock_validate): spec = mock.sentinel.spec request = mock.sentinel.request response = mock.sentinel.response data = mock.sentinel.data mock_validate.return_value = ResultMock(data=data) - request_wrapper_class = WrapperClassMock - response_wrapper_class = WrapperClassMock + request_factory = FactoryClassMock + response_factory = FactoryClassMock result = validate_data( spec, request, response, - request_wrapper_class, response_wrapper_class, + request_factory, response_factory, ) assert result == data mock_validate.assert_called_once_with( - WrapperClassMock(request), - WrapperClassMock(response), + FactoryClassMock(request), + FactoryClassMock(response), ) @mock.patch('openapi_core.shortcuts.ResponseValidator.validate') - def test_wrappers_error(self, mock_validate): + def test_factories_error(self, mock_validate): spec = mock.sentinel.spec request = mock.sentinel.request response = mock.sentinel.response mock_validate.return_value = ResultMock(error_to_raise=ValueError) - request_wrapper_class = WrapperClassMock - response_wrapper_class = WrapperClassMock + request_factory = FactoryClassMock + response_factory = FactoryClassMock with pytest.raises(ValueError): validate_data( spec, request, response, - request_wrapper_class, response_wrapper_class, + request_factory, response_factory, ) mock_validate.assert_called_once_with( - WrapperClassMock(request), - WrapperClassMock(response), + FactoryClassMock(request), + FactoryClassMock(response), )