diff --git a/openapi_core/shortcuts.py b/openapi_core/shortcuts.py index 2b0bedc..5bdd4c2 100644 --- a/openapi_core/shortcuts.py +++ b/openapi_core/shortcuts.py @@ -6,7 +6,6 @@ from openapi_spec_validator import default_handlers from openapi_core.exceptions import OpenAPIParameterError, OpenAPIBodyError from openapi_core.specs import SpecFactory from openapi_core.validators import RequestValidator, ResponseValidator -from openapi_core.wrappers import FlaskOpenAPIRequest, FlaskOpenAPIResponse def create_spec(spec_dict, spec_url=''): @@ -17,12 +16,13 @@ def create_spec(spec_dict, spec_url=''): return spec_factory.create(spec_dict, spec_url=spec_url) -def validate_parameters(spec, request, wrapper_class=FlaskOpenAPIRequest): - if wrapper_class: +def validate_parameters(spec, request, wrapper_class=None): + if wrapper_class is not None: request = wrapper_class(request) validator = RequestValidator(spec) result = validator.validate(request) + try: result.raise_for_errors() except OpenAPIBodyError: @@ -31,12 +31,13 @@ def validate_parameters(spec, request, wrapper_class=FlaskOpenAPIRequest): return result.parameters -def validate_body(spec, request, wrapper_class=FlaskOpenAPIRequest): - if wrapper_class: +def validate_body(spec, request, wrapper_class=None): + if wrapper_class is not None: request = wrapper_class(request) validator = RequestValidator(spec) result = validator.validate(request) + try: result.raise_for_errors() except OpenAPIParameterError: @@ -47,11 +48,12 @@ def validate_body(spec, request, wrapper_class=FlaskOpenAPIRequest): def validate_data( spec, request, response, - request_wrapper_class=FlaskOpenAPIRequest, - response_wrapper_class=FlaskOpenAPIResponse): - if request_wrapper_class: + request_wrapper_class=None, + response_wrapper_class=None): + if request_wrapper_class is not None: request = request_wrapper_class(request) - if response_wrapper_class: + + if response_wrapper_class is not None: response = response_wrapper_class(response) validator = ResponseValidator(spec) diff --git a/setup.py b/setup.py index ccba137..839ceae 100644 --- a/setup.py +++ b/setup.py @@ -75,6 +75,9 @@ setup( ], install_requires=read_requirements('requirements.txt'), tests_require=read_requirements('requirements_dev.txt'), + extras_require={ + 'flask': ["werkzeug"], + }, cmdclass={'test': PyTest}, zip_safe=False, ) diff --git a/tests/unit/test_shortcuts.py b/tests/unit/test_shortcuts.py new file mode 100644 index 0000000..dc2caca --- /dev/null +++ b/tests/unit/test_shortcuts.py @@ -0,0 +1,219 @@ +import mock + +import pytest + +from openapi_core.shortcuts import ( + validate_parameters, validate_body, validate_data, +) + + +class ResultMock(object): + + def __init__( + self, body=None, parameters=None, data=None, error_to_raise=None): + self.body = body + self.parameters = parameters + self.data = data + self.error_to_raise = error_to_raise + + def raise_for_errors(self): + if self.error_to_raise is not None: + raise self.error_to_raise + + if self.parameters is not None: + return self.parameters + + if self.data is not None: + return self.data + + +class WrapperClassMock(object): + + _instances = {} + + def __new__(cls, obj): + if obj not in cls._instances: + cls._instances[obj] = object.__new__(cls) + return cls._instances[obj] + + def __init__(self, obj): + self.obj = obj + + +class TestValidateParameters(object): + + @mock.patch('openapi_core.shortcuts.RequestValidator.validate') + def test_no_wrapper(self, mock_validate): + spec = mock.sentinel.spec + request = mock.sentinel.request + parameters = mock.sentinel.parameters + mock_validate.return_value = ResultMock(parameters=parameters) + + result = validate_parameters(spec, request) + + assert result == parameters + mock_validate.aasert_called_once_with(request) + + @mock.patch('openapi_core.shortcuts.RequestValidator.validate') + def test_no_wrapper_error(self, mock_validate): + spec = mock.sentinel.spec + request = mock.sentinel.request + mock_validate.return_value = ResultMock(error_to_raise=ValueError) + + with pytest.raises(ValueError): + validate_parameters(spec, request) + + mock_validate.aasert_called_once_with(request) + + @mock.patch('openapi_core.shortcuts.RequestValidator.validate') + def test_wrapper(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 + + result = validate_parameters(spec, request, request_wrapper_class) + + assert result == parameters + mock_validate.assert_called_once_with( + WrapperClassMock(request), + ) + + @mock.patch('openapi_core.shortcuts.RequestValidator.validate') + def test_wrapper_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 + + with pytest.raises(ValueError): + validate_parameters(spec, request, request_wrapper_class) + + mock_validate.assert_called_once_with( + WrapperClassMock(request), + ) + + +class TestValidateBody(object): + + @mock.patch('openapi_core.shortcuts.RequestValidator.validate') + def test_no_wrapper(self, mock_validate): + spec = mock.sentinel.spec + request = mock.sentinel.request + body = mock.sentinel.body + mock_validate.return_value = ResultMock(body=body) + + result = validate_body(spec, request) + + assert result == body + mock_validate.aasert_called_once_with(request) + + @mock.patch('openapi_core.shortcuts.RequestValidator.validate') + def test_no_wrapper_error(self, mock_validate): + spec = mock.sentinel.spec + request = mock.sentinel.request + mock_validate.return_value = ResultMock(error_to_raise=ValueError) + + with pytest.raises(ValueError): + validate_body(spec, request) + + mock_validate.aasert_called_once_with(request) + + @mock.patch('openapi_core.shortcuts.RequestValidator.validate') + def test_wrapper(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 + + result = validate_body(spec, request, request_wrapper_class) + + assert result == body + mock_validate.assert_called_once_with( + WrapperClassMock(request), + ) + + @mock.patch('openapi_core.shortcuts.RequestValidator.validate') + def test_wrapper_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 + + with pytest.raises(ValueError): + validate_body(spec, request, request_wrapper_class) + + mock_validate.assert_called_once_with( + WrapperClassMock(request), + ) + + +class TestvalidateData(object): + + @mock.patch('openapi_core.shortcuts.ResponseValidator.validate') + def test_no_wrappers(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) + + result = validate_data(spec, request, response) + + assert result == data + mock_validate.aasert_called_once_with(request, response) + + @mock.patch('openapi_core.shortcuts.ResponseValidator.validate') + def test_no_wrappers_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) + + with pytest.raises(ValueError): + validate_data(spec, request, response) + + mock_validate.aasert_called_once_with(request, response) + + @mock.patch('openapi_core.shortcuts.ResponseValidator.validate') + def test_wrappers(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 + + result = validate_data( + spec, request, response, + request_wrapper_class, response_wrapper_class, + ) + + assert result == data + mock_validate.assert_called_once_with( + WrapperClassMock(request), + WrapperClassMock(response), + ) + + @mock.patch('openapi_core.shortcuts.ResponseValidator.validate') + def test_wrappers_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 + + with pytest.raises(ValueError): + validate_data( + spec, request, response, + request_wrapper_class, response_wrapper_class, + ) + + mock_validate.assert_called_once_with( + WrapperClassMock(request), + WrapperClassMock(response), + )