Skip to content

Commit

Permalink
handle NoContent response in operation validation
Browse files Browse the repository at this point in the history
  • Loading branch information
ainquel committed Jan 3, 2019
1 parent 67e7dac commit b8d979f
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 9 deletions.
3 changes: 3 additions & 0 deletions connexion/apis/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,9 @@ def encode_body(cls, body, mimetype=None):
if json_encode or not is_string(body):
if isinstance(body, six.binary_type):
body = decode(body)
"""if body is empty transform it to object."""
if body == "":
body = {}
body = cls.jsonifier.dumps(body)
if isinstance(body, six.text_type):
body = body.encode("UTF-8")
Expand Down
10 changes: 3 additions & 7 deletions connexion/apis/flask_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

from connexion.apis import flask_utils
from connexion.apis.abstract import AbstractAPI
from connexion.decorators.produces import NoContent
from connexion.handlers import AuthErrorHandler
from connexion.lifecycle import ConnexionRequest, ConnexionResponse
from connexion.operations.validation import validate_operation_output
Expand Down Expand Up @@ -159,12 +158,8 @@ def _build_flask_response(cls, mimetype=None, content_type=None,

flask_response.status_code = status_code

if data is not None and data is not NoContent:
data = cls.encode_body(data, mimetype)
flask_response.set_data(data)

elif data is NoContent:
flask_response.set_data('')
data = cls.encode_body(data, mimetype)
flask_response.set_data(data)

return flask_response

Expand All @@ -180,6 +175,7 @@ def _response_from_handler(cls, response, mimetype):
return flask.current_app.make_response(response)

body, status_code, headers = validate_operation_output(response)

return cls._build_flask_response(
mimetype=mimetype,
headers=headers,
Expand Down
9 changes: 7 additions & 2 deletions connexion/operations/validation.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import six

from connexion.decorators.produces import NoContent
from connexion.utils import normalize_tuple

BODY_TYPES = (six.text_type, six.binary_type, dict, list)


def validate_operation_output(response):
"""Will validate the format returned by a handler."""
if isinstance(response, BODY_TYPES):
if isinstance(response, BODY_TYPES) or response == NoContent:
response = (response, )

body, status, headers = normalize_tuple(response, 3)
if not isinstance(body, BODY_TYPES):

if body == NoContent:
body = b""
elif not isinstance(body, BODY_TYPES):
raise ValueError(
"first returned value has to be {}, got {}".format(
BODY_TYPES, type(body)
Expand Down
1 change: 1 addition & 0 deletions tests/api/test_abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
(b"test", "text/plain", b"test"),
("test", "application/json", b'"test"\n'),
(b"test", "application/json", b'"test"\n'),
("", "application/json", b"{}\n")
])
def test_encode_body(body, mimetype, expected):
"""Test the body encoding.
Expand Down
10 changes: 10 additions & 0 deletions tests/operations/test_op_validation.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest
from connexion.decorators.produces import NoContent
from connexion.operations.validation import (BODY_TYPES,
validate_operation_output)

Expand All @@ -16,3 +17,12 @@ def test_validate_operation_output(output):
assert isinstance(body, BODY_TYPES)
assert isinstance(status, int) or status is None
assert isinstance(headers, dict) or headers is None


@pytest.mark.parametrize("output", [
NoContent,
(NoContent,)
])
def test_validate_operation_no_content(output):
body, _, _ = validate_operation_output(output)
assert body == b""

0 comments on commit b8d979f

Please sign in to comment.