From a15ee3ad0667193fa358cfd8293d6e758413bb5e Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Thu, 2 Feb 2017 18:51:33 +0900 Subject: [PATCH] Fix sanic_endpoint_test working with redirects Before fix, it raises error like: ``` tests/test_utils.py F ================================= FAILURES ================================= ______________________________ test_redirect _______________________________ app = , method = 'get', uri = '/1', gather_request = True, debug = False server_kwargs = {}, request_args = (), request_kwargs = {} _collect_request = ._collect_request at 0x1045ec950> _collect_response = ._collect_response at 0x1045ec7b8> def sanic_endpoint_test(app, method='get', uri='/', gather_request=True, debug=False, server_kwargs={}, *request_args, **request_kwargs): results = [] exceptions = [] if gather_request: def _collect_request(request): results.append(request) app.request_middleware.appendleft(_collect_request) async def _collect_response(sanic, loop): try: response = await local_request(method, uri, *request_args, **request_kwargs) results.append(response) except Exception as e: exceptions.append(e) app.stop() app.run(host=HOST, debug=debug, port=PORT, after_start=_collect_response, **server_kwargs) if exceptions: raise ValueError("Exception during request: {}".format(exceptions)) if gather_request: try: > request, response = results E ValueError: too many values to unpack (expected 2) sanic/utils.py:47: ValueError During handling of the above exception, another exception occurred: utils_app = def test_redirect(utils_app): """Test sanic_endpoint_test is working for redirection""" > request, response = sanic_endpoint_test(utils_app, uri='/1') tests/test_utils.py:33: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ app = , method = 'get', uri = '/1', gather_request = True, debug = False server_kwargs = {}, request_args = (), request_kwargs = {} _collect_request = ._collect_request at 0x1045ec950> _collect_response = ._collect_response at 0x1045ec7b8> def sanic_endpoint_test(app, method='get', uri='/', gather_request=True, debug=False, server_kwargs={}, *request_args, **request_kwargs): results = [] exceptions = [] if gather_request: def _collect_request(request): results.append(request) app.request_middleware.appendleft(_collect_request) async def _collect_response(sanic, loop): try: response = await local_request(method, uri, *request_args, **request_kwargs) results.append(response) except Exception as e: exceptions.append(e) app.stop() app.run(host=HOST, debug=debug, port=PORT, after_start=_collect_response, **server_kwargs) if exceptions: raise ValueError("Exception during request: {}".format(exceptions)) if gather_request: try: request, response = results return request, response except: raise ValueError( "Request and response object expected, got ({})".format( > results)) E ValueError: Request and response object expected, got ([{}, {}, {}, E E ]) sanic/utils.py:52: ValueError ``` --- sanic/utils.py | 9 ++-- tests/test_redirect.py | 96 ++++++++++++++++++++++++++++++++++++++++++ tests/test_requests.py | 76 ++------------------------------- 3 files changed, 104 insertions(+), 77 deletions(-) create mode 100644 tests/test_redirect.py diff --git a/sanic/utils.py b/sanic/utils.py index 644a2a22..8e8f8124 100644 --- a/sanic/utils.py +++ b/sanic/utils.py @@ -19,19 +19,20 @@ async def local_request(method, uri, cookies=None, *args, **kwargs): def sanic_endpoint_test(app, method='get', uri='/', gather_request=True, debug=False, server_kwargs={}, *request_args, **request_kwargs): - results = [] + results = [None, None] exceptions = [] if gather_request: def _collect_request(request): - results.append(request) + if results[0] is None: + results[0] = request app.request_middleware.appendleft(_collect_request) async def _collect_response(sanic, loop): try: response = await local_request(method, uri, *request_args, **request_kwargs) - results.append(response) + results[-1] = response except Exception as e: exceptions.append(e) app.stop() @@ -52,7 +53,7 @@ def sanic_endpoint_test(app, method='get', uri='/', gather_request=True, results)) else: try: - return results[0] + return results[-1] except: raise ValueError( "Request object expected, got ({})".format(results)) diff --git a/tests/test_redirect.py b/tests/test_redirect.py new file mode 100644 index 00000000..b2b72c35 --- /dev/null +++ b/tests/test_redirect.py @@ -0,0 +1,96 @@ +import pytest + +from sanic import Sanic +from sanic.response import text, redirect +from sanic.utils import sanic_endpoint_test + + +@pytest.fixture +def redirect_app(): + app = Sanic('test_redirection') + + @app.route('/redirect_init') + async def redirect_init(request): + return redirect("/redirect_target") + + @app.route('/redirect_init_with_301') + async def redirect_init_with_301(request): + return redirect("/redirect_target", status=301) + + @app.route('/redirect_target') + async def redirect_target(request): + return text('OK') + + @app.route('/1') + def handler(request): + return redirect('/2') + + @app.route('/2') + def handler(request): + return redirect('/3') + + @app.route('/3') + def handler(request): + return text('OK') + + return app + + +def test_redirect_default_302(redirect_app): + """ + We expect a 302 default status code and the headers to be set. + """ + request, response = sanic_endpoint_test( + redirect_app, method="get", + uri="/redirect_init", + allow_redirects=False) + + assert response.status == 302 + assert response.headers["Location"] == "/redirect_target" + assert response.headers["Content-Type"] == 'text/html; charset=utf-8' + + +def test_redirect_headers_none(redirect_app): + request, response = sanic_endpoint_test( + redirect_app, method="get", + uri="/redirect_init", + headers=None, + allow_redirects=False) + + assert response.status == 302 + assert response.headers["Location"] == "/redirect_target" + + +def test_redirect_with_301(redirect_app): + """ + Test redirection with a different status code. + """ + request, response = sanic_endpoint_test( + redirect_app, method="get", + uri="/redirect_init_with_301", + allow_redirects=False) + + assert response.status == 301 + assert response.headers["Location"] == "/redirect_target" + + +def test_get_then_redirect_follow_redirect(redirect_app): + """ + With `allow_redirects` we expect a 200. + """ + response = sanic_endpoint_test( + redirect_app, method="get", + uri="/redirect_init", gather_request=False, + allow_redirects=True) + + assert response.status == 200 + assert response.text == 'OK' + + +def test_chained_redirect(redirect_app): + """Test sanic_endpoint_test is working for redirection""" + request, response = sanic_endpoint_test(redirect_app, uri='/1') + assert request.url.endswith('/1') + assert response.status == 200 + assert response.text == 'OK' + assert response.url.endswith('/3') diff --git a/tests/test_requests.py b/tests/test_requests.py index b2ee8e78..985f5b00 100644 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -58,7 +58,7 @@ def test_non_str_headers(): request, response = sanic_endpoint_test(app) assert response.headers.get('answer') == '42' - + def test_invalid_response(): app = Sanic('test_invalid_response') @@ -73,8 +73,8 @@ def test_invalid_response(): request, response = sanic_endpoint_test(app) assert response.status == 500 assert response.text == "Internal Server Error." - - + + def test_json(): app = Sanic('test_json') @@ -189,73 +189,3 @@ def test_post_form_multipart_form_data(): request, response = sanic_endpoint_test(app, data=payload, headers=headers) assert request.form.get('test') == 'OK' - - -@pytest.fixture -def redirect_app(): - app = Sanic('test_redirection') - - @app.route('/redirect_init') - async def redirect_init(request): - return redirect("/redirect_target") - - @app.route('/redirect_init_with_301') - async def redirect_init_with_301(request): - return redirect("/redirect_target", status=301) - - @app.route('/redirect_target') - async def redirect_target(request): - return text('OK') - - return app - - -def test_redirect_default_302(redirect_app): - """ - We expect a 302 default status code and the headers to be set. - """ - request, response = sanic_endpoint_test( - redirect_app, method="get", - uri="/redirect_init", - allow_redirects=False) - - assert response.status == 302 - assert response.headers["Location"] == "/redirect_target" - assert response.headers["Content-Type"] == 'text/html; charset=utf-8' - - -def test_redirect_headers_none(redirect_app): - request, response = sanic_endpoint_test( - redirect_app, method="get", - uri="/redirect_init", - headers=None, - allow_redirects=False) - - assert response.status == 302 - assert response.headers["Location"] == "/redirect_target" - - -def test_redirect_with_301(redirect_app): - """ - Test redirection with a different status code. - """ - request, response = sanic_endpoint_test( - redirect_app, method="get", - uri="/redirect_init_with_301", - allow_redirects=False) - - assert response.status == 301 - assert response.headers["Location"] == "/redirect_target" - - -def test_get_then_redirect_follow_redirect(redirect_app): - """ - With `allow_redirects` we expect a 200. - """ - response = sanic_endpoint_test( - redirect_app, method="get", - uri="/redirect_init", gather_request=False, - allow_redirects=True) - - assert response.status == 200 - assert response.text == 'OK'