From 10cc011dae6ea03ac31b1aea277c755e996837d8 Mon Sep 17 00:00:00 2001 From: panpann Date: Tue, 18 Dec 2018 20:58:01 +0100 Subject: [PATCH] use the connexion test_client in tests --- connexion/lifecycle.py | 12 ++++- connexion/tests.py | 56 ++++++++++++++++++++++ tests/api/test_bootstrap.py | 30 ++++++------ tests/api/test_errors.py | 2 +- tests/api/test_headers.py | 10 ++-- tests/api/test_parameters.py | 64 ++++++++++++------------- tests/api/test_responses.py | 65 ++++++++++++++------------ tests/api/test_schema.py | 20 ++++---- tests/api/test_secure_api.py | 9 ++-- tests/api/test_unordered_definition.py | 2 +- tests/test_json_validation.py | 6 +-- tests/test_lifecycle.py | 15 ++++++ 12 files changed, 188 insertions(+), 103 deletions(-) create mode 100644 connexion/tests.py diff --git a/connexion/lifecycle.py b/connexion/lifecycle.py index f7adc003c..3c262ec0d 100644 --- a/connexion/lifecycle.py +++ b/connexion/lifecycle.py @@ -42,9 +42,9 @@ def __init__(self, raise ValueError("{} is not a valid status code".format(status_code)) self.status_code = status_code self.mimetype = mimetype - self.content_type = content_type self.body = body self.headers = headers or {} + self.content_type = content_type or self.headers.get("Content-Type") @property def text(self): @@ -57,6 +57,7 @@ def json(self): This method is naive, it will try to load JSON even if the content_type is not JSON. + It will raise in case of a non JSON string """ return json.loads(self.text) @@ -64,3 +65,12 @@ def json(self): def data(self): """return the encoded body.""" return encode(self.body) + + @property + def content_length(self): + """return the content length. + + If Content-Length is not present in headers, + get the size of encoded body. + """ + return int(self.headers.get("Content-Length", len(self.data))) diff --git a/connexion/tests.py b/connexion/tests.py new file mode 100644 index 000000000..11cc03652 --- /dev/null +++ b/connexion/tests.py @@ -0,0 +1,56 @@ +import abc +import functools + +import six + + +class AbstractClientMeta(abc.ABCMeta): + pass + + +@six.add_metaclass(AbstractClientMeta) +class AbstractClient(object): + """A test client to run tests on top of different web frameworks.""" + http_verbs = [ + "head", + "get", + "delete", + "options", + "patch", + "post", + "put", + "trace", + ] + + def __init__(self, app): + self.app = app + + @classmethod + def from_app(cls, app): + return cls(app) + + @abc.abstractmethod + def _request( + self, + method, + url, + headers=None, + data=None, + json=None, + content_type=None, + ): + # type: (...) -> connexion.lifecycle.ConnexionResponse + """Make request and return a ConnexionResponse instance. + + For now, the expected client has to be compatible with flask's test_client. + TODO: use the arguments from ConnexionRequest if one day Apis have a method + to translate ConnexionRequest to web framework request. + see https://github.com/pallets/werkzeug/blob/master/werkzeug/test.py#L222 + for the request client. + """ + + def __getattr__(self, key): + """Call _request with method bound if key is an HTTP method.""" + if key in self.http_verbs: + return functools.partial(self._request, key) + raise AttributeError(key) diff --git a/tests/api/test_bootstrap.py b/tests/api/test_bootstrap.py index 8b6c41f31..3334d0f2a 100644 --- a/tests/api/test_bootstrap.py +++ b/tests/api/test_bootstrap.py @@ -21,7 +21,7 @@ def test_app_with_relative_path(simple_api_spec_dir, spec): debug=True) app.add_api(spec) - app_client = app.app.test_client() + app_client = app.test_client() get_bye = app_client.get('/v1.0/bye/jsantos') # type: flask.Response assert get_bye.status_code == 200 assert get_bye.data == b'Goodbye jsantos' @@ -47,7 +47,7 @@ def test_app_with_different_server_option(simple_api_spec_dir, spec): debug=True) app.add_api(spec) - app_client = app.app.test_client() + app_client = app.test_client() get_bye = app_client.get('/v1.0/bye/jsantos') # type: flask.Response assert get_bye.status_code == 200 assert get_bye.data == b'Goodbye jsantos' @@ -61,12 +61,12 @@ def test_app_with_different_uri_parser(simple_api_spec_dir): debug=True) app.add_api('swagger.yaml') - app_client = app.app.test_client() + app_client = app.test_client() resp = app_client.get( '/v1.0/test_array_csv_query_param?items=a,b,c&items=d,e,f' ) # type: flask.Response assert resp.status_code == 200 - j = json.loads(resp.get_data(as_text=True)) + j = resp.json assert j == ['a', 'b', 'c'] @@ -77,13 +77,13 @@ def test_no_swagger_ui(simple_api_spec_dir, spec): options=options, debug=True) app.add_api(spec) - app_client = app.app.test_client() + app_client = app.test_client() swagger_ui = app_client.get('/v1.0/ui/') # type: flask.Response assert swagger_ui.status_code == 404 app2 = App(__name__, port=5001, specification_dir=simple_api_spec_dir, debug=True) app2.add_api(spec, options={"swagger_ui": False}) - app2_client = app2.app.test_client() + app2_client = app2.test_client() swagger_ui2 = app2_client.get('/v1.0/ui/') # type: flask.Response assert swagger_ui2.status_code == 404 @@ -93,7 +93,7 @@ def test_swagger_json_app(simple_api_spec_dir, spec): """ Verify the spec json file is returned for default setting passed to app. """ app = App(__name__, port=5001, specification_dir=simple_api_spec_dir, debug=True) app.add_api(spec) - app_client = app.app.test_client() + app_client = app.test_client() url = '/v1.0/{spec}' url = url.format(spec=spec.replace("yaml", "json")) spec_json = app_client.get(url) # type: flask.Response @@ -108,7 +108,7 @@ def test_no_swagger_json_app(simple_api_spec_dir, spec): options=options, debug=True) app.add_api(spec) - app_client = app.app.test_client() + app_client = app.test_client() url = '/v1.0/{spec}' url = url.format(spec=spec.replace("yaml", "json")) spec_json = app_client.get(url) # type: flask.Response @@ -132,7 +132,7 @@ def test_dict_as_yaml_path(simple_api_spec_dir, spec): app = App(__name__, port=5001, specification_dir=simple_api_spec_dir, debug=True) app.add_api(specification) - app_client = app.app.test_client() + app_client = app.test_client() url = '/v1.0/{spec}'.format(spec=spec.replace("yaml", "json")) swagger_json = app_client.get(url) # type: flask.Response assert swagger_json.status_code == 200 @@ -144,7 +144,7 @@ def test_swagger_json_api(simple_api_spec_dir, spec): app = App(__name__, port=5001, specification_dir=simple_api_spec_dir, debug=True) app.add_api(spec) - app_client = app.app.test_client() + app_client = app.test_client() url = '/v1.0/{spec}'.format(spec=spec.replace("yaml", "json")) swagger_json = app_client.get(url) # type: flask.Response assert swagger_json.status_code == 200 @@ -156,14 +156,14 @@ def test_no_swagger_json_api(simple_api_spec_dir, spec): app = App(__name__, port=5001, specification_dir=simple_api_spec_dir, debug=True) app.add_api(spec, options={"serve_spec": False}) - app_client = app.app.test_client() + app_client = app.test_client() url = '/v1.0/{spec}'.format(spec=spec.replace("yaml", "json")) swagger_json = app_client.get(url) # type: flask.Response assert swagger_json.status_code == 404 def test_swagger_json_content_type(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() spec = simple_app._spec_file url = '/v1.0/{spec}'.format(spec=spec.replace("yaml", "json")) response = app_client.get(url) # type: flask.Response @@ -179,7 +179,7 @@ def route1(): def route2(): return 'single 2' - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() simple_app.add_url_rule('/single1', 'single1', route1, methods=['GET']) @@ -197,13 +197,13 @@ def route2(): def test_resolve_method(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/resolver-test/method') # type: flask.Response assert resp.data == b'"DummyClass"\n' def test_resolve_classmethod(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/resolver-test/classmethod') # type: flask.Response assert resp.data.decode('utf-8', 'replace') == '"DummyClass"\n' diff --git a/tests/api/test_errors.py b/tests/api/test_errors.py index d635c2da3..a9f32cc71 100644 --- a/tests/api/test_errors.py +++ b/tests/api/test_errors.py @@ -8,7 +8,7 @@ def fix_data(data): def test_errors(problem_app): - app_client = problem_app.app.test_client() + app_client = problem_app.test_client() greeting404 = app_client.get('/v1.0/greeting') # type: flask.Response assert greeting404.content_type == 'application/problem+json' diff --git a/tests/api/test_headers.py b/tests/api/test_headers.py index 0b6c88c75..c66e24d37 100644 --- a/tests/api/test_headers.py +++ b/tests/api/test_headers.py @@ -2,7 +2,7 @@ def test_headers_jsonifier(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() response = app_client.post('/v1.0/goodday/dan', data={}) # type: flask.Response assert response.status_code == 201 @@ -10,7 +10,7 @@ def test_headers_jsonifier(simple_app): def test_headers_produces(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() response = app_client.post('/v1.0/goodevening/dan', data={}) # type: flask.Response assert response.status_code == 201 @@ -18,7 +18,7 @@ def test_headers_produces(simple_app): def test_header_not_returned(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() response = app_client.post('/v1.0/goodday/noheader', data={}) # type: flask.Response assert response.status_code == 500 # view_func has not returned what was promised in spec @@ -31,14 +31,14 @@ def test_header_not_returned(simple_app): def test_no_content_response_have_headers(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/test-204-with-headers') assert resp.status_code == 204 assert 'X-Something' in resp.headers def test_no_content_object_and_have_headers(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/test-204-with-headers-nocontent-obj') assert resp.status_code == 204 assert 'X-Something' in resp.headers diff --git a/tests/api/test_parameters.py b/tests/api/test_parameters.py index acbc157a8..d88f2def6 100644 --- a/tests/api/test_parameters.py +++ b/tests/api/test_parameters.py @@ -6,7 +6,7 @@ def test_parameter_validation(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() url = '/v1.0/test_parameter_validation' @@ -29,7 +29,7 @@ def test_parameter_validation(simple_app): def test_required_query_param(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() url = '/v1.0/test_required_query_param' response = app_client.get(url) @@ -40,7 +40,7 @@ def test_required_query_param(simple_app): def test_array_query_param(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() headers = {'Content-type': 'application/json'} url = '/v1.0/test_array_csv_query_param' response = app_client.get(url, headers=headers) @@ -73,7 +73,7 @@ def test_array_query_param(simple_app): def test_array_form_param(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() headers = {'Content-type': 'application/x-www-form-urlencoded'} url = '/v1.0/test_array_csv_form_param' response = app_client.post(url, headers=headers) @@ -100,7 +100,7 @@ def test_array_form_param(simple_app): def test_extra_query_param(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() headers = {'Content-type': 'application/json'} url = '/v1.0/test_parameter_validation?extra_parameter=true' resp = app_client.get(url, headers=headers) @@ -108,7 +108,7 @@ def test_extra_query_param(simple_app): def test_strict_extra_query_param(strict_app): - app_client = strict_app.app.test_client() + app_client = strict_app.test_client() headers = {'Content-type': 'application/json'} url = '/v1.0/test_parameter_validation?extra_parameter=true' resp = app_client.get(url, headers=headers) @@ -118,7 +118,7 @@ def test_strict_extra_query_param(strict_app): def test_path_parameter_someint(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/test-int-path/123') # type: flask.Response assert resp.data.decode('utf-8', 'replace') == '"int"\n' @@ -128,7 +128,7 @@ def test_path_parameter_someint(simple_app): def test_path_parameter_somefloat(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/test-float-path/123.45') # type: flask.Response assert resp.data.decode('utf-8' , 'replace') == '"float"\n' @@ -138,7 +138,7 @@ def test_path_parameter_somefloat(simple_app): def test_default_param(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/test-default-query-parameter') assert resp.status_code == 200 response = json.loads(resp.data.decode('utf-8', 'replace')) @@ -146,7 +146,7 @@ def test_default_param(simple_app): def test_falsy_param(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/test-falsy-param', query_string={'falsy': 0}) assert resp.status_code == 200 response = json.loads(resp.data.decode('utf-8', 'replace')) @@ -159,7 +159,7 @@ def test_falsy_param(simple_app): def test_formdata_param(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.post('/v1.0/test-formData-param', data={'formData': 'test'}) assert resp.status_code == 200 @@ -168,7 +168,7 @@ def test_formdata_param(simple_app): def test_formdata_bad_request(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.post('/v1.0/test-formData-param') assert resp.status_code == 400 response = json.loads(resp.data.decode('utf-8', 'replace')) @@ -179,14 +179,14 @@ def test_formdata_bad_request(simple_app): def test_formdata_missing_param(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.post('/v1.0/test-formData-missing-param', data={'missing_formData': 'test'}) assert resp.status_code == 200 def test_formdata_extra_param(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.post('/v1.0/test-formData-param', data={'formData': 'test', 'extra_formData': 'test'}) @@ -194,7 +194,7 @@ def test_formdata_extra_param(simple_app): def test_strict_formdata_extra_param(strict_app): - app_client = strict_app.app.test_client() + app_client = strict_app.test_client() resp = app_client.post('/v1.0/test-formData-param', data={'formData': 'test', 'extra_formData': 'test'}) @@ -204,7 +204,7 @@ def test_strict_formdata_extra_param(strict_app): def test_formdata_file_upload(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.post('/v1.0/test-formData-file-upload', data={'formData': (BytesIO(b'file contents'), 'filename.txt')}) assert resp.status_code == 200 @@ -213,7 +213,7 @@ def test_formdata_file_upload(simple_app): def test_formdata_file_upload_bad_request(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.post('/v1.0/test-formData-file-upload') assert resp.status_code == 400 response = json.loads(resp.data.decode('utf-8', 'replace')) @@ -224,14 +224,14 @@ def test_formdata_file_upload_bad_request(simple_app): def test_formdata_file_upload_missing_param(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.post('/v1.0/test-formData-file-upload-missing-param', data={'missing_formData': (BytesIO(b'file contents'), 'example.txt')}) assert resp.status_code == 200 def test_body_not_allowed_additional_properties(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() body = { 'body1': 'bodyString', 'additional_property': 'test1'} resp = app_client.post( '/v1.0/body-not-allowed-additional-properties', @@ -243,7 +243,7 @@ def test_body_not_allowed_additional_properties(simple_app): assert 'Additional properties are not allowed' in response['detail'] def test_bool_as_default_param(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/test-bool-param') assert resp.status_code == 200 @@ -254,7 +254,7 @@ def test_bool_as_default_param(simple_app): def test_bool_param(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/test-bool-param', query_string={'thruthiness': True}) assert resp.status_code == 200 response = json.loads(resp.data.decode('utf-8', 'replace')) @@ -267,25 +267,25 @@ def test_bool_param(simple_app): def test_bool_array_param(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/test-bool-array-param?thruthiness=true,true,true') assert resp.status_code == 200 response = json.loads(resp.data.decode('utf-8', 'replace')) assert response is True - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/test-bool-array-param?thruthiness=true,true,false') assert resp.status_code == 200 response = json.loads(resp.data.decode('utf-8', 'replace')) assert response is False - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/test-bool-array-param') assert resp.status_code == 200 def test_required_param_miss_config(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/test-required-param') assert resp.status_code == 400 @@ -298,7 +298,7 @@ def test_required_param_miss_config(simple_app): def test_parameters_defined_in_path_level(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/parameters-in-root-path?title=nice-get') assert resp.status_code == 200 assert json.loads(resp.data.decode('utf-8', 'replace')) == ["nice-get"] @@ -308,7 +308,7 @@ def test_parameters_defined_in_path_level(simple_app): def test_array_in_path(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/test-array-in-path/one_item') assert json.loads(resp.data.decode('utf-8', 'replace')) == ["one_item"] @@ -317,7 +317,7 @@ def test_array_in_path(simple_app): def test_nullable_parameter(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/nullable-parameters?time_start=null') assert json.loads(resp.data.decode('utf-8', 'replace')) == 'it was None' @@ -344,7 +344,7 @@ def test_nullable_parameter(simple_app): def test_args_kwargs(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/query-params-as-kwargs') assert resp.status_code == 200 assert json.loads(resp.data.decode('utf-8', 'replace')) == {} @@ -355,7 +355,7 @@ def test_args_kwargs(simple_app): def test_param_sanitization(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.post('/v1.0/param-sanitization') assert resp.status_code == 200 assert json.loads(resp.data.decode('utf-8', 'replace')) == {} @@ -393,7 +393,7 @@ def test_param_sanitization(simple_app): assert json.loads(resp.data.decode('utf-8', 'replace')) == body def test_parameters_snake_case(snake_case_app): - app_client = snake_case_app.app.test_client() + app_client = snake_case_app.test_client() headers = {'Content-type': 'application/json'} resp = app_client.post('/v1.0/test-post-path-snake/123', headers=headers, data=json.dumps({"a": "test"})) assert resp.status_code == 200 @@ -415,7 +415,7 @@ def test_parameters_snake_case(snake_case_app): def test_get_unicode_request(simple_app): """Regression test for Python 2 UnicodeEncodeError bug during parameter parsing.""" - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/get_unicode_request?price=%C2%A319.99') # £19.99 assert resp.status_code == 200 assert json.loads(resp.data.decode('utf-8'))['price'] == '£19.99' diff --git a/tests/api/test_responses.py b/tests/api/test_responses.py index 093e0d3af..5d4faa9d0 100644 --- a/tests/api/test_responses.py +++ b/tests/api/test_responses.py @@ -9,7 +9,7 @@ def test_app(simple_app): assert simple_app.port == 5001 - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() # by default the Swagger UI is enabled swagger_ui = app_client.get('/v1.0/ui/') # type: flask.Response @@ -44,14 +44,14 @@ def test_app(simple_app): def test_produce_decorator(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() get_bye = app_client.get('/v1.0/bye/jsantos') # type: flask.Response assert get_bye.content_type == 'text/plain; charset=utf-8' def test_returning_flask_response_tuple(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() result = app_client.get('/v1.0/flask_response_tuple') # type: flask.Response assert result.status_code == 201 @@ -61,7 +61,7 @@ def test_returning_flask_response_tuple(simple_app): def test_jsonifier(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() post_greeting = app_client.post('/v1.0/greeting/jsantos', data={}) # type: flask.Response assert post_greeting.status_code == 200 @@ -86,22 +86,23 @@ def test_jsonifier(simple_app): def test_not_content_response(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() get_no_content_response = app_client.get('/v1.0/test_no_content_response') assert get_no_content_response.status_code == 204 + print("popo", get_no_content_response.headers) assert get_no_content_response.content_length == 0 def test_pass_through(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() response = app_client.get('/v1.0/multimime', data={}) # type: flask.Response assert response.status_code == 200 def test_empty(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() response = app_client.get('/v1.0/empty') # type: flask.Response assert response.status_code == 204 @@ -109,19 +110,19 @@ def test_empty(simple_app): def test_redirect_endpoint(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/test-redirect-endpoint') assert resp.status_code == 302 def test_redirect_response_endpoint(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/test-redirect-response-endpoint') assert resp.status_code == 302 def test_default_object_body(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.post('/v1.0/test-default-object-body') assert resp.status_code == 200 response = json.loads(resp.data.decode('utf-8', 'replace')) @@ -152,7 +153,7 @@ def default(self, o): def test_content_type_not_json(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/blob-response') assert resp.status_code == 200 @@ -164,7 +165,7 @@ def test_content_type_not_json(simple_app): def test_maybe_blob_or_json(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/binary-response') assert resp.status_code == 200 @@ -177,7 +178,7 @@ def test_maybe_blob_or_json(simple_app): def test_bad_operations(bad_operations_app): # Bad operationIds in bad_operations_app should result in 501 - app_client = bad_operations_app.app.test_client() + app_client = bad_operations_app.test_client() resp = app_client.get('/v1.0/welcome') assert resp.status_code == 501 @@ -190,20 +191,20 @@ def test_bad_operations(bad_operations_app): def test_text_request(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.post('/v1.0/text-request', data='text') assert resp.status_code == 200 def test_operation_handler_returns_flask_object(invalid_resp_allowed_app): - app_client = invalid_resp_allowed_app.app.test_client() + app_client = invalid_resp_allowed_app.test_client() resp = app_client.get('/v1.0/get_non_conforming_response') assert resp.status_code == 200 def test_post_wrong_content_type(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.post('/v1.0/post_wrong_content_type', content_type="application/xml", data=json.dumps({"some": "data"}) @@ -227,19 +228,22 @@ def test_post_wrong_content_type(simple_app): # (https://github.com/pallets/werkzeug/issues/1159) # so that content-type is added to every request, we remove it here manually for our test # this test can be removed once the werkzeug issue is addressed - builder = EnvironBuilder(path='/v1.0/post_wrong_content_type', method='POST', - data=json.dumps({"some": "data"})) - try: - environ = builder.get_environ() - finally: - builder.close() - environ.pop('CONTENT_TYPE') + # builder = EnvironBuilder(path='/v1.0/post_wrong_content_type', method='POST', + # data=json.dumps({"some": "data"})) + # try: + # environ = builder.get_environ() + # finally: + # builder.close() + # environ.pop('CONTENT_TYPE') # we cannot just call app_client.open() since app_client is a flask.testing.FlaskClient # which overrides werkzeug.test.Client.open() but does not allow passing an environment # directly - resp = Client.open(app_client, environ) - assert resp.status_code == 415 + # resp = Client.open(app_client, environ) + + # building then environ is not necessary anymore, seems to work without it. + resp = app_client.post('/v1.0/post_wrong_content_type', data=json.dumps({"some": "data"})) + assert resp.status_code == 415 resp = app_client.post('/v1.0/post_wrong_content_type', content_type="application/json", @@ -250,25 +254,26 @@ def test_post_wrong_content_type(simple_app): def test_get_unicode_response(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/get_unicode_response') actualJson = {u'currency': u'\xa3', u'key': u'leena'} - assert json.loads(resp.data.decode('utf-8','replace')) == actualJson + assert json.loads(resp.data.decode('utf-8', 'replace')) == actualJson def test_get_enum_response(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/get_enum_response') assert resp.status_code == 200 + def test_get_httpstatus_response(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/get_httpstatus_response') assert resp.status_code == 200 def test_get_bad_default_response(simple_app): - app_client = simple_app.app.test_client() + app_client = simple_app.test_client() resp = app_client.get('/v1.0/get_bad_default_response/200') assert resp.status_code == 200 diff --git a/tests/api/test_schema.py b/tests/api/test_schema.py index 272ad0b1a..b1d3a4ea5 100644 --- a/tests/api/test_schema.py +++ b/tests/api/test_schema.py @@ -2,7 +2,7 @@ def test_schema(schema_app): - app_client = schema_app.app.test_client() + app_client = schema_app.test_client() headers = {'Content-type': 'application/json'} empty_request = app_client.post('/v1.0/test_schema', headers=headers, data=json.dumps({})) # type: flask.Response @@ -42,7 +42,7 @@ def test_schema(schema_app): def test_schema_response(schema_app): - app_client = schema_app.app.test_client() + app_client = schema_app.test_client() request = app_client.get('/v1.0/test_schema/response/object/valid', headers={}, data=None) # type: flask.Response assert request.status_code == 200 @@ -81,7 +81,7 @@ def test_schema_response(schema_app): def test_schema_in_query(schema_app): - app_client = schema_app.app.test_client() + app_client = schema_app.test_client() headers = {'Content-type': 'application/json'} good_request = app_client.post('/v1.0/test_schema_in_query', headers=headers, @@ -93,7 +93,7 @@ def test_schema_in_query(schema_app): def test_schema_list(schema_app): - app_client = schema_app.app.test_client() + app_client = schema_app.test_client() headers = {'Content-type': 'application/json'} wrong_type = app_client.post('/v1.0/test_schema_list', headers=headers, data=json.dumps(42)) # type: flask.Response @@ -113,7 +113,7 @@ def test_schema_list(schema_app): def test_schema_map(schema_app): - app_client = schema_app.app.test_client() + app_client = schema_app.test_client() headers = {'Content-type': 'application/json'} valid_object = { @@ -150,7 +150,7 @@ def test_schema_map(schema_app): def test_schema_recursive(schema_app): - app_client = schema_app.app.test_client() + app_client = schema_app.test_client() headers = {'Content-type': 'application/json'} valid_object = { @@ -189,7 +189,7 @@ def test_schema_recursive(schema_app): def test_schema_format(schema_app): - app_client = schema_app.app.test_client() + app_client = schema_app.test_client() headers = {'Content-type': 'application/json'} wrong_type = app_client.post('/v1.0/test_schema_format', headers=headers, @@ -202,7 +202,7 @@ def test_schema_format(schema_app): def test_schema_array(schema_app): - app_client = schema_app.app.test_client() + app_client = schema_app.test_client() headers = {'Content-type': 'application/json'} array_request = app_client.post('/v1.0/schema_array', headers=headers, @@ -214,7 +214,7 @@ def test_schema_array(schema_app): def test_schema_int(schema_app): - app_client = schema_app.app.test_client() + app_client = schema_app.test_client() headers = {'Content-type': 'application/json'} array_request = app_client.post('/v1.0/schema_int', headers=headers, @@ -226,6 +226,6 @@ def test_schema_int(schema_app): def test_global_response_definitions(schema_app): - app_client = schema_app.app.test_client() + app_client = schema_app.test_client() resp = app_client.get('/v1.0/define_global_response') assert json.loads(resp.data.decode('utf-8', 'replace')) == ['general', 'list'] diff --git a/tests/api/test_secure_api.py b/tests/api/test_secure_api.py index e21501cfc..408a4e5db 100644 --- a/tests/api/test_secure_api.py +++ b/tests/api/test_secure_api.py @@ -1,10 +1,8 @@ import json -from connexion import FlaskApp - def test_security_over_nonexistent_endpoints(oauth_requests, secure_api_app): - app_client = secure_api_app.app.test_client() + app_client = secure_api_app.test_client() headers = {"Authorization": "Bearer 300"} get_inexistent_endpoint = app_client.get('/v1.0/does-not-exist-invalid-token', headers=headers) # type: flask.Response @@ -32,7 +30,7 @@ def test_security_over_nonexistent_endpoints(oauth_requests, secure_api_app): def test_security(oauth_requests, secure_endpoint_app): - app_client = secure_endpoint_app.app.test_client() + app_client = secure_endpoint_app.test_client() get_bye_no_auth = app_client.get('/v1.0/byesecure/jsantos') # type: flask.Response assert get_bye_no_auth.status_code == 401 @@ -88,9 +86,10 @@ def test_security(oauth_requests, secure_endpoint_app): get_bye_from_connexion = app_client.get('/v1.0/byesecure-jwt/test-user', headers=headers) # type: flask.Response assert get_bye_from_connexion.data == b'Goodbye test-user (Secure: 100)' + def test_checking_that_client_token_has_all_necessary_scopes( oauth_requests, secure_endpoint_app): - app_client = secure_endpoint_app.app.test_client() + app_client = secure_endpoint_app.test_client() # has only one of the required scopes headers = {"Authorization": "Bearer has_myscope"} diff --git a/tests/api/test_unordered_definition.py b/tests/api/test_unordered_definition.py index fbe93eab9..4b35ede4f 100644 --- a/tests/api/test_unordered_definition.py +++ b/tests/api/test_unordered_definition.py @@ -2,7 +2,7 @@ def test_app(unordered_definition_app): - app_client = unordered_definition_app.app.test_client() + app_client = unordered_definition_app.test_client() response = app_client.get('/v1.0/unordered-params/1?first=first&second=2') # type: flask.Response assert response.status_code == 400 response_data = json.loads(response.data.decode('utf-8', 'replace')) diff --git a/tests/test_json_validation.py b/tests/test_json_validation.py index 5b25aec43..16f56d61f 100644 --- a/tests/test_json_validation.py +++ b/tests/test_json_validation.py @@ -32,7 +32,7 @@ def __init__(self, *args, **kwargs): app = App(__name__, specification_dir=json_validation_spec_dir) app.add_api(spec, validate_responses=True, validator_map=validator_map) - app_client = app.app.test_client() + app_client = app.test_client() # type: flask.Response res = app_client.post('/v1.0/minlength', data=json.dumps({'foo': 'bar'}), content_type='application/json') @@ -46,7 +46,7 @@ def __init__(self, *args, **kwargs): @pytest.mark.parametrize("spec", SPECS) def test_readonly(json_validation_spec_dir, spec): app = build_app_from_fixture(json_validation_spec_dir, spec, validate_responses=True) - app_client = app.app.test_client() + app_client = app.test_client() res = app_client.get('/v1.0/user') # type: flask.Response assert res.status_code == 200 @@ -66,7 +66,7 @@ def test_readonly(json_validation_spec_dir, spec): @pytest.mark.parametrize("spec", SPECS) def test_writeonly(json_validation_spec_dir, spec): app = build_app_from_fixture(json_validation_spec_dir, spec, validate_responses=True) - app_client = app.app.test_client() + app_client = app.test_client() # type: flask.Response res = app_client.post( diff --git a/tests/test_lifecycle.py b/tests/test_lifecycle.py index 808a9aa92..80d327099 100644 --- a/tests/test_lifecycle.py +++ b/tests/test_lifecycle.py @@ -36,3 +36,18 @@ def test_text_and_data(self, body): ]) def test_json(self, body): assert ConnexionResponse(body=body).json == json.loads(body) + + @pytest.mark.parametrize("body,expected", [ + ("test", 4), + ("", 0), + # Always count body as bytes, some unicode characters representation + # is composed of multiple bytes + ("€", 3) + ]) + def test_content_length(self, body, expected): + assert ConnexionResponse(body=body).content_length == expected + response_with_headers = ConnexionResponse( + body=body, + headers={"Content-Length": str(len(body.encode("UTF-8")))}, + ) + assert response_with_headers.content_length == expected