sanic/tests/test_redirect.py
Adam Hopkins ccd4c9615c Create requests-async based TestClient, remove aiohttp dependency, drop Python 3.5
Update all tests to be compatible with requests-async
Cleanup testing client changes with black and isort
Remove Python 3.5 and other meta doc cleanup
rename pyproject and fix pep517 error
Add black config to tox.ini
Cleanup tests and remove aiohttp
tox.ini change for easier development commands
Remove aiohttp from changelog and requirements
Cleanup imports and Makefile
2019-04-30 15:26:06 +03:00

131 lines
3.6 KiB
Python

from urllib.parse import quote
import pytest
from sanic.response import redirect, text
@pytest.fixture
def redirect_app(app):
@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 handler1(request):
return redirect("/2")
@app.route("/2")
def handler2(request):
return redirect("/3")
@app.route("/3")
def handler3(request):
return text("OK")
@app.route("/redirect_with_header_injection")
async def redirect_with_header_injection(request):
return redirect("/unsafe\ntest-header: test-value\n\ntest-body")
return app
def test_redirect_default_302(redirect_app):
"""
We expect a 302 default status code and the headers to be set.
"""
request, response = redirect_app.test_client.get(
"/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 = redirect_app.test_client.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 = redirect_app.test_client.get(
"/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.
"""
request, response = redirect_app.test_client.get(
"/redirect_init", allow_redirects=True
)
assert response.status == 200
assert response.text == "OK"
def test_chained_redirect(redirect_app):
"""Test test_client is working for redirection"""
request, response = redirect_app.test_client.get("/1")
assert request.url.endswith("/1")
assert response.status == 200
assert response.text == "OK"
try:
assert response.url.endswith("/3")
except AttributeError:
assert response.url.path.endswith("/3")
def test_redirect_with_header_injection(redirect_app):
"""
Test redirection to a URL with header and body injections.
"""
request, response = redirect_app.test_client.get(
"/redirect_with_header_injection", allow_redirects=False
)
assert response.status == 302
assert "test-header" not in response.headers
assert not response.text.startswith("test-body")
@pytest.mark.parametrize("test_str", ["sanic-test", "sanictest", "sanic test"])
async def test_redirect_with_params(app, test_client, test_str):
@app.route("/api/v1/test/<test>/")
async def init_handler(request, test):
assert test == test_str
return redirect("/api/v2/test/{}/".format(quote(test)))
@app.route("/api/v2/test/<test>/")
async def target_handler(request, test):
assert test == test_str
return text("OK")
test_cli = await test_client(app)
response = await test_cli.get("/api/v1/test/{}/".format(quote(test_str)))
assert response.status == 200
txt = await response.text()
assert txt == "OK"