Skip to content

Commit

Permalink
fix-square bracket : V1 (spec-first#1408)
Browse files Browse the repository at this point in the history
* fix-square bracket : V1

Envoyé depuis mon iPhone.
P.S. : Ce commit est certifié sans gluten

* Fix syntax

Envoyé depuis mon iPhone.
P.S. : Ce commit est certifié sans gluten

* Add OpenAPI test with square brackets

Envoyé depuis mon iPhone.
P.S. : Ce commit est certifié sans gluten

* Fix test

Fix alphabetic order in import
Fix test parametrization

Envoyé depuis mon iPhone.
P.S. : Ce commit est certifié sans gluten

* square bracket : Set collection format to None for OpenAPIURIParser

Envoyé depuis mon iPhone.
P.S. : Ce commit est certifié sans gluten

Co-authored-by: Géry THRASIBULE <g.thrasibule@lecomptoirdespharmacies.fr>
  • Loading branch information
2 people authored and vbxx3 committed Feb 21, 2022
1 parent 5532f98 commit 5742ea3
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 8 deletions.
2 changes: 1 addition & 1 deletion connexion/decorators/parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def parameter_to_arg(operation, function, pythonic_params=False,
consumes = operation.consumes

def sanitized(name):
return name and re.sub('^[^a-zA-Z_]+', '', re.sub('[^0-9a-zA-Z_]', '', name))
return name and re.sub('^[^a-zA-Z_]+', '', re.sub('[^0-9a-zA-Z[_]', '', re.sub(r'[\[]', '_', name)))

def pythonic(name):
name = name and snake_and_shadow(name)
Expand Down
24 changes: 17 additions & 7 deletions connexion/decorators/uri_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def resolve_params(self, params, _in):
# multiple values in a path is impossible
values = [values]

if (param_schema is not None and param_schema['type'] == 'array'):
if param_schema and param_schema['type'] == 'array':
# resolve variable re-assignment, handle explode
values = self._resolve_param_duplicates(values, param_defn, _in)
# handle array styles
Expand Down Expand Up @@ -184,22 +184,32 @@ def resolve_form(self, form_data):
form_data[k] = json.loads(form_data[k])
return form_data

@staticmethod
def _make_deep_object(k, v):
def _make_deep_object(self, k, v):
""" consumes keys, value pairs like (a[foo][bar], "baz")
returns (a, {"foo": {"bar": "baz"}}}, is_deep_object)
"""
root_key = k.split("[", 1)[0]
if k == root_key:
return (k, v, False)
root_key = None
if k in self.param_schemas.keys():
return k, v, False
else:
for keys in self.param_schemas.keys():
if k.startswith(keys):
rest = keys.replace(k, '')
root_key = rest

if not root_key:
root_key = k.split("[", 1)[0]
if k == root_key:
return k, v, False

key_path = re.findall(r'\[([^\[\]]*)\]', k)
root = prev = node = {}
for k in key_path:
node[k] = {}
prev = node
node = node[k]
prev[k] = v[0]
return (root_key, [root], True)
return root_key, [root], True

def _preprocess_deep_objects(self, query_data):
""" deep objects provide a way of rendering nested objects using query
Expand Down
35 changes: 35 additions & 0 deletions tests/decorators/test_uri_parsing.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import pytest
from connexion.decorators.uri_parsing import (AlwaysMultiURIParser,
FirstValueURIParser,
OpenAPIURIParser,
Swagger2URIParser)
from werkzeug.datastructures import MultiDict

QUERY1 = MultiDict([("letters", "a"), ("letters", "b,c"),
("letters", "d,e,f")])
QUERY2 = MultiDict([("letters", "a"), ("letters", "b|c"),
("letters", "d|e|f")])
QUERY3 = MultiDict([("letters[eq]", ["a"]), ("letters[eq]", ["b", "c"]),
("letters[eq]", ["d", "e", "f"])])
QUERY4 = MultiDict([("letters[eq]", "a"), ("letters[eq]", "b|c"),
("letters[eq]", "d|e|f")])
QUERY5 = MultiDict([("letters[eq]", "a"), ("letters[eq]", "b,c"),
("letters[eq]", "d,e,f")])
PATH1 = {"letters": "d,e,f"}
PATH2 = {"letters": "d|e|f"}
CSV = "csv"
Expand Down Expand Up @@ -100,3 +107,31 @@ class Request:
p = parser_class(parameters, body_defn)
res = p(lambda x: x)(request)
assert res.path_params["letters"] == expected


@pytest.mark.parametrize("parser_class, expected, query_in, collection_format", [
(OpenAPIURIParser, ['d', 'e', 'f'], QUERY3, None),
(Swagger2URIParser, ['d', 'e', 'f'], QUERY5, CSV),
(FirstValueURIParser, ['a'], QUERY5, CSV),
(AlwaysMultiURIParser, ['a', 'b', 'c', 'd', 'e', 'f'], QUERY5, CSV),
(Swagger2URIParser, ['d', 'e', 'f'], QUERY4, PIPES),
(FirstValueURIParser, ['a'], QUERY4, PIPES),
(AlwaysMultiURIParser, ['a', 'b', 'c', 'd', 'e', 'f'], QUERY4, PIPES)])
def test_uri_parser_query_params_with_square_brackets(parser_class, expected, query_in, collection_format):
class Request:
query = query_in
path_params = {}
form = {}

request = Request()
parameters = [
{"name": "letters[eq]",
"in": "query",
"type": "array",
"items": {"type": "string"},
"collectionFormat": collection_format}
]
body_defn = {}
p = parser_class(parameters, body_defn)
res = p(lambda x: x)(request)
assert res.query["letters[eq]"] == expected

0 comments on commit 5742ea3

Please sign in to comment.