From 705675f837fcbc0751fd9a3241ce5a2eb4d4271e Mon Sep 17 00:00:00 2001 From: p1c2u Date: Thu, 11 Apr 2024 08:10:45 +0000 Subject: [PATCH] Falcon multi-value query parameters fix --- openapi_core/contrib/falcon/requests.py | 3 ++- openapi_core/contrib/falcon/util.py | 15 +++++++++++ .../data/v3.0/falconproject/pets/resources.py | 18 +++++++++---- .../contrib/falcon/test_falcon_project.py | 27 +++++++++++++++++++ 4 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 openapi_core/contrib/falcon/util.py diff --git a/openapi_core/contrib/falcon/requests.py b/openapi_core/contrib/falcon/requests.py index 6ef5033e..7e1fe1cf 100644 --- a/openapi_core/contrib/falcon/requests.py +++ b/openapi_core/contrib/falcon/requests.py @@ -11,6 +11,7 @@ from werkzeug.datastructures import Headers from werkzeug.datastructures import ImmutableMultiDict +from openapi_core.contrib.falcon.util import unpack_params from openapi_core.datatypes import RequestParameters @@ -29,7 +30,7 @@ def __init__( # Path gets deduced by path finder against spec self.parameters = RequestParameters( - query=ImmutableMultiDict(list(self.request.params.items())), + query=ImmutableMultiDict(unpack_params(self.request.params)), header=Headers(self.request.headers), cookie=self.request.cookies, ) diff --git a/openapi_core/contrib/falcon/util.py b/openapi_core/contrib/falcon/util.py new file mode 100644 index 00000000..0f651e42 --- /dev/null +++ b/openapi_core/contrib/falcon/util.py @@ -0,0 +1,15 @@ +from typing import Any +from typing import Dict +from typing import Generator +from typing import Tuple + + +def unpack_params( + params: Dict[str, Any] +) -> Generator[Tuple[str, Any], None, None]: + for k, v in params.items(): + if isinstance(v, list): + for v2 in v: + yield (k, v2) + else: + yield (k, v) diff --git a/tests/integration/contrib/falcon/data/v3.0/falconproject/pets/resources.py b/tests/integration/contrib/falcon/data/v3.0/falconproject/pets/resources.py index 5d0a83f4..d6e903da 100644 --- a/tests/integration/contrib/falcon/data/v3.0/falconproject/pets/resources.py +++ b/tests/integration/contrib/falcon/data/v3.0/falconproject/pets/resources.py @@ -11,11 +11,19 @@ class PetListResource: def on_get(self, request, response): assert request.context.openapi assert not request.context.openapi.errors - assert request.context.openapi.parameters.query == { - "page": 1, - "limit": 12, - "search": "", - } + if "ids" in request.params: + assert request.context.openapi.parameters.query == { + "page": 1, + "limit": 2, + "search": "", + "ids": [1, 2], + } + else: + assert request.context.openapi.parameters.query == { + "page": 1, + "limit": 12, + "search": "", + } data = [ { "id": 12, diff --git a/tests/integration/contrib/falcon/test_falcon_project.py b/tests/integration/contrib/falcon/test_falcon_project.py index 7ed3a19c..69e11974 100644 --- a/tests/integration/contrib/falcon/test_falcon_project.py +++ b/tests/integration/contrib/falcon/test_falcon_project.py @@ -67,6 +67,33 @@ def test_get_valid(self, client): ], } + def test_get_valid_multiple_ids(self, client): + headers = { + "Content-Type": "application/json", + } + query_string = "limit=2&ids=1&ids=2" + + with pytest.warns(DeprecationWarning): + response = client.simulate_get( + "/v1/pets", + host="petstore.swagger.io", + headers=headers, + query_string=query_string, + ) + + assert response.status_code == 200 + assert response.json == { + "data": [ + { + "id": 12, + "name": "Cat", + "ears": { + "healthy": True, + }, + }, + ], + } + def test_post_server_invalid(self, client): response = client.simulate_post( "/v1/pets", pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy