Skip to content

Commit 4cfa26d

Browse files
authored
Merge pull request #1120 from python-openapi/fix/parameters-validator-unmarshaller-order
Fix swapped operation/path order in request-parameters flows
2 parents c651498 + 97c5b6d commit 4cfa26d

File tree

3 files changed

+75
-2
lines changed

3 files changed

+75
-2
lines changed

openapi_core/unmarshalling/request/unmarshallers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ def _unmarshal_parameters(
198198
self, request: BaseRequest, operation: SchemaPath, path: SchemaPath
199199
) -> RequestUnmarshalResult:
200200
try:
201-
params = self._get_parameters(request.parameters, path, operation)
201+
params = self._get_parameters(request.parameters, operation, path)
202202
except ParametersError as exc:
203203
params = exc.parameters
204204
params_errors = exc.errors

openapi_core/validation/request/validators.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def _iter_parameters_errors(
135135
self, request: BaseRequest, operation: SchemaPath, path: SchemaPath
136136
) -> Iterator[Exception]:
137137
try:
138-
self._get_parameters(request.parameters, path, operation)
138+
self._get_parameters(request.parameters, operation, path)
139139
except ParametersError as exc:
140140
yield from exc.errors
141141

tests/unit/unmarshalling/test_path_item_params_validator.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@
99
from openapi_core.casting.schemas.exceptions import CastError
1010
from openapi_core.datatypes import Parameters
1111
from openapi_core.testing import MockRequest
12+
from openapi_core.unmarshalling.request.unmarshallers import (
13+
V30RequestParametersUnmarshaller,
14+
)
1215
from openapi_core.validation.request.exceptions import MissingRequiredParameter
1316
from openapi_core.validation.request.exceptions import ParameterValidationError
17+
from openapi_core.validation.request.validators import (
18+
V30RequestParametersValidator,
19+
)
1420

1521

1622
class TestPathItemParamsValidator:
@@ -169,3 +175,70 @@ def test_request_object_deep_object_params(self, spec, spec_dict):
169175
assert is_dataclass(result.parameters.query["paramObj"])
170176
assert result.parameters.query["paramObj"].count == 2
171177
assert result.parameters.query["paramObj"].name == "John"
178+
179+
def test_request_override_param_uniqueness_parameters_validator(
180+
self, spec, spec_dict
181+
):
182+
# add parameter on operation with same name as on path but
183+
# different location
184+
spec_dict["paths"]["/resource"]["get"]["parameters"] = [
185+
{
186+
# full valid parameter object required
187+
"name": "resId",
188+
"in": "header",
189+
"required": False,
190+
"schema": {
191+
"type": "integer",
192+
},
193+
}
194+
]
195+
request = MockRequest("http://example.com", "get", "/resource")
196+
with pytest.raises(MissingRequiredParameter):
197+
validate_request(
198+
request,
199+
spec,
200+
base_url="http://example.com",
201+
cls=V30RequestParametersValidator,
202+
)
203+
204+
def test_request_object_deep_object_params_parameters_unmarshaller(
205+
self, spec, spec_dict
206+
):
207+
# override path parameter on operation
208+
spec_dict["paths"]["/resource"]["parameters"] = [
209+
{
210+
# full valid parameter object required
211+
"name": "paramObj",
212+
"in": "query",
213+
"required": True,
214+
"schema": {
215+
"x-model": "paramObj",
216+
"type": "object",
217+
"properties": {
218+
"count": {"type": "integer"},
219+
"name": {"type": "string"},
220+
},
221+
},
222+
"explode": True,
223+
"style": "deepObject",
224+
}
225+
]
226+
227+
request = MockRequest(
228+
"http://example.com",
229+
"get",
230+
"/resource",
231+
args={"paramObj[count]": 2, "paramObj[name]": "John"},
232+
)
233+
result = unmarshal_request(
234+
request,
235+
spec,
236+
base_url="http://example.com",
237+
cls=V30RequestParametersUnmarshaller,
238+
)
239+
240+
assert len(result.errors) == 0
241+
assert len(result.parameters.query) == 1
242+
assert is_dataclass(result.parameters.query["paramObj"])
243+
assert result.parameters.query["paramObj"].count == 2
244+
assert result.parameters.query["paramObj"].name == "John"

0 commit comments

Comments
 (0)