Skip to content

Commit c954275

Browse files
authored
Merge pull request #18 from p1c2u/fix/werkzeug-as-extra-requirement-fix
Werkzeug as extra requirement fix
2 parents e186e17 + 4a9cd2b commit c954275

File tree

3 files changed

+233
-9
lines changed

3 files changed

+233
-9
lines changed

openapi_core/shortcuts.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from openapi_core.exceptions import OpenAPIParameterError, OpenAPIBodyError
77
from openapi_core.specs import SpecFactory
88
from openapi_core.validators import RequestValidator, ResponseValidator
9-
from openapi_core.wrappers import FlaskOpenAPIRequest, FlaskOpenAPIResponse
109

1110

1211
def create_spec(spec_dict, spec_url=''):
@@ -17,12 +16,13 @@ def create_spec(spec_dict, spec_url=''):
1716
return spec_factory.create(spec_dict, spec_url=spec_url)
1817

1918

20-
def validate_parameters(spec, request, wrapper_class=FlaskOpenAPIRequest):
21-
if wrapper_class:
19+
def validate_parameters(spec, request, wrapper_class=None):
20+
if wrapper_class is not None:
2221
request = wrapper_class(request)
2322

2423
validator = RequestValidator(spec)
2524
result = validator.validate(request)
25+
2626
try:
2727
result.raise_for_errors()
2828
except OpenAPIBodyError:
@@ -31,12 +31,13 @@ def validate_parameters(spec, request, wrapper_class=FlaskOpenAPIRequest):
3131
return result.parameters
3232

3333

34-
def validate_body(spec, request, wrapper_class=FlaskOpenAPIRequest):
35-
if wrapper_class:
34+
def validate_body(spec, request, wrapper_class=None):
35+
if wrapper_class is not None:
3636
request = wrapper_class(request)
3737

3838
validator = RequestValidator(spec)
3939
result = validator.validate(request)
40+
4041
try:
4142
result.raise_for_errors()
4243
except OpenAPIParameterError:
@@ -47,11 +48,12 @@ def validate_body(spec, request, wrapper_class=FlaskOpenAPIRequest):
4748

4849
def validate_data(
4950
spec, request, response,
50-
request_wrapper_class=FlaskOpenAPIRequest,
51-
response_wrapper_class=FlaskOpenAPIResponse):
52-
if request_wrapper_class:
51+
request_wrapper_class=None,
52+
response_wrapper_class=None):
53+
if request_wrapper_class is not None:
5354
request = request_wrapper_class(request)
54-
if response_wrapper_class:
55+
56+
if response_wrapper_class is not None:
5557
response = response_wrapper_class(response)
5658

5759
validator = ResponseValidator(spec)

setup.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ def run_tests(self):
7575
],
7676
install_requires=read_requirements('requirements.txt'),
7777
tests_require=read_requirements('requirements_dev.txt'),
78+
extras_require={
79+
'flask': ["werkzeug"],
80+
},
7881
cmdclass={'test': PyTest},
7982
zip_safe=False,
8083
)

tests/unit/test_shortcuts.py

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
import mock
2+
3+
import pytest
4+
5+
from openapi_core.shortcuts import (
6+
validate_parameters, validate_body, validate_data,
7+
)
8+
9+
10+
class ResultMock(object):
11+
12+
def __init__(
13+
self, body=None, parameters=None, data=None, error_to_raise=None):
14+
self.body = body
15+
self.parameters = parameters
16+
self.data = data
17+
self.error_to_raise = error_to_raise
18+
19+
def raise_for_errors(self):
20+
if self.error_to_raise is not None:
21+
raise self.error_to_raise
22+
23+
if self.parameters is not None:
24+
return self.parameters
25+
26+
if self.data is not None:
27+
return self.data
28+
29+
30+
class WrapperClassMock(object):
31+
32+
_instances = {}
33+
34+
def __new__(cls, obj):
35+
if obj not in cls._instances:
36+
cls._instances[obj] = object.__new__(cls)
37+
return cls._instances[obj]
38+
39+
def __init__(self, obj):
40+
self.obj = obj
41+
42+
43+
class TestValidateParameters(object):
44+
45+
@mock.patch('openapi_core.shortcuts.RequestValidator.validate')
46+
def test_no_wrapper(self, mock_validate):
47+
spec = mock.sentinel.spec
48+
request = mock.sentinel.request
49+
parameters = mock.sentinel.parameters
50+
mock_validate.return_value = ResultMock(parameters=parameters)
51+
52+
result = validate_parameters(spec, request)
53+
54+
assert result == parameters
55+
mock_validate.aasert_called_once_with(request)
56+
57+
@mock.patch('openapi_core.shortcuts.RequestValidator.validate')
58+
def test_no_wrapper_error(self, mock_validate):
59+
spec = mock.sentinel.spec
60+
request = mock.sentinel.request
61+
mock_validate.return_value = ResultMock(error_to_raise=ValueError)
62+
63+
with pytest.raises(ValueError):
64+
validate_parameters(spec, request)
65+
66+
mock_validate.aasert_called_once_with(request)
67+
68+
@mock.patch('openapi_core.shortcuts.RequestValidator.validate')
69+
def test_wrapper(self, mock_validate):
70+
spec = mock.sentinel.spec
71+
request = mock.sentinel.request
72+
parameters = mock.sentinel.parameters
73+
mock_validate.return_value = ResultMock(parameters=parameters)
74+
request_wrapper_class = WrapperClassMock
75+
76+
result = validate_parameters(spec, request, request_wrapper_class)
77+
78+
assert result == parameters
79+
mock_validate.assert_called_once_with(
80+
WrapperClassMock(request),
81+
)
82+
83+
@mock.patch('openapi_core.shortcuts.RequestValidator.validate')
84+
def test_wrapper_error(self, mock_validate):
85+
spec = mock.sentinel.spec
86+
request = mock.sentinel.request
87+
mock_validate.return_value = ResultMock(error_to_raise=ValueError)
88+
request_wrapper_class = WrapperClassMock
89+
90+
with pytest.raises(ValueError):
91+
validate_parameters(spec, request, request_wrapper_class)
92+
93+
mock_validate.assert_called_once_with(
94+
WrapperClassMock(request),
95+
)
96+
97+
98+
class TestValidateBody(object):
99+
100+
@mock.patch('openapi_core.shortcuts.RequestValidator.validate')
101+
def test_no_wrapper(self, mock_validate):
102+
spec = mock.sentinel.spec
103+
request = mock.sentinel.request
104+
body = mock.sentinel.body
105+
mock_validate.return_value = ResultMock(body=body)
106+
107+
result = validate_body(spec, request)
108+
109+
assert result == body
110+
mock_validate.aasert_called_once_with(request)
111+
112+
@mock.patch('openapi_core.shortcuts.RequestValidator.validate')
113+
def test_no_wrapper_error(self, mock_validate):
114+
spec = mock.sentinel.spec
115+
request = mock.sentinel.request
116+
mock_validate.return_value = ResultMock(error_to_raise=ValueError)
117+
118+
with pytest.raises(ValueError):
119+
validate_body(spec, request)
120+
121+
mock_validate.aasert_called_once_with(request)
122+
123+
@mock.patch('openapi_core.shortcuts.RequestValidator.validate')
124+
def test_wrapper(self, mock_validate):
125+
spec = mock.sentinel.spec
126+
request = mock.sentinel.request
127+
body = mock.sentinel.body
128+
mock_validate.return_value = ResultMock(body=body)
129+
request_wrapper_class = WrapperClassMock
130+
131+
result = validate_body(spec, request, request_wrapper_class)
132+
133+
assert result == body
134+
mock_validate.assert_called_once_with(
135+
WrapperClassMock(request),
136+
)
137+
138+
@mock.patch('openapi_core.shortcuts.RequestValidator.validate')
139+
def test_wrapper_error(self, mock_validate):
140+
spec = mock.sentinel.spec
141+
request = mock.sentinel.request
142+
mock_validate.return_value = ResultMock(error_to_raise=ValueError)
143+
request_wrapper_class = WrapperClassMock
144+
145+
with pytest.raises(ValueError):
146+
validate_body(spec, request, request_wrapper_class)
147+
148+
mock_validate.assert_called_once_with(
149+
WrapperClassMock(request),
150+
)
151+
152+
153+
class TestvalidateData(object):
154+
155+
@mock.patch('openapi_core.shortcuts.ResponseValidator.validate')
156+
def test_no_wrappers(self, mock_validate):
157+
spec = mock.sentinel.spec
158+
request = mock.sentinel.request
159+
response = mock.sentinel.response
160+
data = mock.sentinel.data
161+
mock_validate.return_value = ResultMock(data=data)
162+
163+
result = validate_data(spec, request, response)
164+
165+
assert result == data
166+
mock_validate.aasert_called_once_with(request, response)
167+
168+
@mock.patch('openapi_core.shortcuts.ResponseValidator.validate')
169+
def test_no_wrappers_error(self, mock_validate):
170+
spec = mock.sentinel.spec
171+
request = mock.sentinel.request
172+
response = mock.sentinel.response
173+
mock_validate.return_value = ResultMock(error_to_raise=ValueError)
174+
175+
with pytest.raises(ValueError):
176+
validate_data(spec, request, response)
177+
178+
mock_validate.aasert_called_once_with(request, response)
179+
180+
@mock.patch('openapi_core.shortcuts.ResponseValidator.validate')
181+
def test_wrappers(self, mock_validate):
182+
spec = mock.sentinel.spec
183+
request = mock.sentinel.request
184+
response = mock.sentinel.response
185+
data = mock.sentinel.data
186+
mock_validate.return_value = ResultMock(data=data)
187+
request_wrapper_class = WrapperClassMock
188+
response_wrapper_class = WrapperClassMock
189+
190+
result = validate_data(
191+
spec, request, response,
192+
request_wrapper_class, response_wrapper_class,
193+
)
194+
195+
assert result == data
196+
mock_validate.assert_called_once_with(
197+
WrapperClassMock(request),
198+
WrapperClassMock(response),
199+
)
200+
201+
@mock.patch('openapi_core.shortcuts.ResponseValidator.validate')
202+
def test_wrappers_error(self, mock_validate):
203+
spec = mock.sentinel.spec
204+
request = mock.sentinel.request
205+
response = mock.sentinel.response
206+
mock_validate.return_value = ResultMock(error_to_raise=ValueError)
207+
request_wrapper_class = WrapperClassMock
208+
response_wrapper_class = WrapperClassMock
209+
210+
with pytest.raises(ValueError):
211+
validate_data(
212+
spec, request, response,
213+
request_wrapper_class, response_wrapper_class,
214+
)
215+
216+
mock_validate.assert_called_once_with(
217+
WrapperClassMock(request),
218+
WrapperClassMock(response),
219+
)

0 commit comments

Comments
 (0)