From b8d979fdad946f540f01830621a80e576c185af8 Mon Sep 17 00:00:00 2001 From: panpann Date: Fri, 4 Jan 2019 00:05:25 +0100 Subject: [PATCH] handle NoContent response in operation validation --- connexion/apis/abstract.py | 3 +++ connexion/apis/flask_api.py | 10 +++------- connexion/operations/validation.py | 9 +++++++-- tests/api/test_abstract.py | 1 + tests/operations/test_op_validation.py | 10 ++++++++++ 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/connexion/apis/abstract.py b/connexion/apis/abstract.py index 1bcd9f54e..979c4a8bf 100644 --- a/connexion/apis/abstract.py +++ b/connexion/apis/abstract.py @@ -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") diff --git a/connexion/apis/flask_api.py b/connexion/apis/flask_api.py index ec9cbe5ac..2ca30c381 100644 --- a/connexion/apis/flask_api.py +++ b/connexion/apis/flask_api.py @@ -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 @@ -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 @@ -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, diff --git a/connexion/operations/validation.py b/connexion/operations/validation.py index c473d5fbf..c89133f32 100644 --- a/connexion/operations/validation.py +++ b/connexion/operations/validation.py @@ -1,5 +1,6 @@ import six +from connexion.decorators.produces import NoContent from connexion.utils import normalize_tuple BODY_TYPES = (six.text_type, six.binary_type, dict, list) @@ -7,10 +8,14 @@ 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) diff --git a/tests/api/test_abstract.py b/tests/api/test_abstract.py index 127925b6a..5eae2a1ae 100644 --- a/tests/api/test_abstract.py +++ b/tests/api/test_abstract.py @@ -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. diff --git a/tests/operations/test_op_validation.py b/tests/operations/test_op_validation.py index e2c2bee3e..bf2394c0b 100644 --- a/tests/operations/test_op_validation.py +++ b/tests/operations/test_op_validation.py @@ -1,4 +1,5 @@ import pytest +from connexion.decorators.produces import NoContent from connexion.operations.validation import (BODY_TYPES, validate_operation_output) @@ -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""