Skip to content

Commit

Permalink
FIX a typo causing an ERROR log (spec-first#523)
Browse files Browse the repository at this point in the history
* FIX a typo causing an ERROR log

A small bug was introduced in spec-first#500 when sanitizing the request query
parameters. Instead of fetching the arguments from `request.query`,
the parameters were sanitized from the `request.form`. This causes an
error log to be printed, as the parameters are not expected for the
query (for example in the case of a POST request).

Fixes spec-first#504

* adds a fixture for testing query param sanitazion

Adds a simple fixture to test form and query parameter sanitazion. This
is mostly related to spec-first#522, in which the `formData` parameters were
treated as query parameters.

* add a test to validate form data params

* introduce testfixtures library
  • Loading branch information
mvalkon authored and hjacobs committed Nov 16, 2017
1 parent 0918a9e commit f4bc6dc
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 1 deletion.
2 changes: 1 addition & 1 deletion connexion/decorators/parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def make_request_query(request):
else:
request_query[k] = v[0]
except AttributeError:
request_query = {sanitize_param(k): v for k, v in request.form.items()}
request_query = {sanitize_param(k): v for k, v in request.query.items()}
return request_query

body_parameters = [parameter for parameter in parameters if parameter['in'] == 'body'] or [{}]
Expand Down
1 change: 1 addition & 0 deletions requirements-devel.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
inflection
mock
pytest
testfixtures>=5.3.0
# This repo doesn't have the latest version released on PyPI
# -e hg+https://bitbucket.org/pitrou/pathlib#egg=pathlib
# PyYAML is not that easy to build manually, it may fail.
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def read_version(package):
'mock',
'pytest',
'pytest-cov',
'testfixtures',
flask_require
]

Expand Down
5 changes: 5 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,8 @@ def unordered_definition_app():
@pytest.fixture(scope="session")
def bad_operations_app():
return build_app_from_fixture('bad_operations', resolver_error=501)


@pytest.fixture(scope="session")
def query_sanitazion():
return build_app_from_fixture('query_sanitazion')
21 changes: 21 additions & 0 deletions tests/decorators/test_parameter.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

from connexion.decorators.parameter import parameter_to_arg
# we are using "mock" module here for Py 2.7 support
from mock import MagicMock
from testfixtures import LogCapture


def test_injection(monkeypatch):
Expand All @@ -17,3 +19,22 @@ def handler(**kwargs):
parameter_to_arg({}, [], handler)(request)

func.assert_called_with(p1='123')


def test_query_sanitazion(query_sanitazion):
app_client = query_sanitazion.app.test_client()
l = LogCapture()

url = '/v1.0/greeting'
response = app_client.post(url, data={'name': 'Jane Doe'})
# This is ugly. The reason for asserting the logging in this way
# is that in order to use LogCapture().check, we'd have to assert that
# a specific sequence of logging has occurred. This is too restricting
# for future development, and we are really only interested in the fact
# a single message is logged.
messages = [x.strip() for x in str(l).split("\n")]
assert "FormData parameter 'name' in function arguments" in messages
assert "Query Parameter 'name' in function arguments" not in messages
assert "Function argument 'name' not defined in specification" not in messages
assert response.status_code == 200
l.uninstall()
22 changes: 22 additions & 0 deletions tests/fixtures/query_sanitazion/swagger.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
swagger: "2.0"
info:
title: "{{title}}"
version: "1.0"
basePath: /v1.0
paths:
/greeting:
post:
summary: Generate greeting
description: Generates a greeting message.
operationId: fakeapi.hello.post_greeting
responses:
'200':
description: greeting response
schema:
type: object
parameters:
- name: name
in: formData
description: Name of the person to greet.
required: true
type: string

0 comments on commit f4bc6dc

Please sign in to comment.