Skip to content

Commit 0e30b71

Browse files
authored
Merge pull request #145 from gweis/path-parameter-override
very simple and hacky path item parameter override test
2 parents 4ac4baf + 3d23f17 commit 0e30b71

File tree

2 files changed

+63
-14
lines changed

2 files changed

+63
-14
lines changed

openapi_core/validation/request/validators.py

+18-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""OpenAPI core validation request validators module"""
2+
from itertools import chain
23
from six import iteritems
34

45
from openapi_core.schema.exceptions import OpenAPIMappingError
@@ -28,30 +29,34 @@ def validate(self, request):
2829

2930
try:
3031
path = self.spec[operation_pattern]
31-
# don't process if operation errors
32-
except OpenAPIMappingError as exc:
33-
return RequestValidationResult([exc, ], None, None)
34-
35-
path_params, path_params_errors = self._get_parameters(request, path)
36-
37-
try:
3832
operation = self.spec.get_operation(
3933
operation_pattern, request.method)
4034
# don't process if operation errors
4135
except OpenAPIMappingError as exc:
4236
return RequestValidationResult([exc, ], None, None)
4337

44-
op_params, op_params_errors = self._get_parameters(request, operation)
38+
params, params_errors = self._get_parameters(
39+
request, chain(
40+
iteritems(operation.parameters),
41+
iteritems(path.parameters)
42+
)
43+
)
44+
4545
body, body_errors = self._get_body(request, operation)
4646

47-
errors = path_params_errors + op_params_errors + body_errors
48-
return RequestValidationResult(errors, body, path_params + op_params)
47+
errors = params_errors + body_errors
48+
return RequestValidationResult(errors, body, params)
4949

50-
def _get_parameters(self, request, operation):
50+
def _get_parameters(self, request, params):
5151
errors = []
52-
52+
seen = set()
5353
parameters = RequestParameters()
54-
for param_name, param in iteritems(operation.parameters):
54+
for param_name, param in params:
55+
if (param_name, param.location.value) in seen:
56+
# skip parameter already seen
57+
# e.g. overriden path item paremeter on operation
58+
continue
59+
seen.add((param_name, param.location.value))
5560
try:
5661
raw_value = param.get_value(request)
5762
except MissingParameter:

tests/integration/test_validators.py

+45-1
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ def test_get_pet(self, validator):
235235
class TestPathItemParamsValidator(object):
236236

237237
@pytest.fixture
238-
def spec_dict(self, factory):
238+
def spec_dict(self):
239239
return {
240240
"openapi": "3.0.0",
241241
"info": {
@@ -305,6 +305,50 @@ def test_request_valid_param(self, validator):
305305
assert result.body is None
306306
assert result.parameters == {'query': {'resId': 10}}
307307

308+
def test_request_override_param(self, spec_dict):
309+
# override path parameter on operation
310+
spec_dict["paths"]["/resource"]["get"]["parameters"] = [
311+
{
312+
# full valid parameter object required
313+
"name": "resId",
314+
"in": "query",
315+
"required": False,
316+
"schema": {
317+
"type": "integer",
318+
},
319+
}
320+
]
321+
validator = RequestValidator(create_spec(spec_dict))
322+
request = MockRequest('http://example.com', 'get', '/resource')
323+
result = validator.validate(request)
324+
325+
assert len(result.errors) == 0
326+
assert result.body is None
327+
assert result.parameters == {}
328+
329+
def test_request_override_param_uniqueness(self, spec_dict):
330+
# add parameter on operation with same name as on path but
331+
# different location
332+
spec_dict["paths"]["/resource"]["get"]["parameters"] = [
333+
{
334+
# full valid parameter object required
335+
"name": "resId",
336+
"in": "header",
337+
"required": False,
338+
"schema": {
339+
"type": "integer",
340+
},
341+
}
342+
]
343+
validator = RequestValidator(create_spec(spec_dict))
344+
request = MockRequest('http://example.com', 'get', '/resource')
345+
result = validator.validate(request)
346+
347+
assert len(result.errors) == 1
348+
assert type(result.errors[0]) == MissingRequiredParameter
349+
assert result.body is None
350+
assert result.parameters == {}
351+
308352

309353
class TestResponseValidator(object):
310354

0 commit comments

Comments
 (0)