import pytest from sanic import Sanic from sanic.response import empty, text from sanic_ext.bootstrap import Extend def test_trace_and_connect_available(app: Sanic): @app.route("/", methods=["trace", "connect"]) async def handler(_): return empty() _, response = app.test_client.request("", http_method="trace") assert response.status == 204 _, response = app.test_client.request("", http_method="connect") assert response.status == 204 _, response = app.test_client.request("", http_method="get") assert response.status == 405 def test_auto_head(app: Sanic, get_docs): app.config.TOUCHUP = False @app.get("/foo") async def foo_handler(_): return text("...") assert app.config.HTTP_AUTO_HEAD _, response = app.test_client.head("/foo") assert response.status == 200 assert len(response.body) == 0 assert int(response.headers["content-length"]) == 3 schema = get_docs() assert "get" in schema["paths"]["/foo"] def test_auto_options(app: Sanic, get_docs): @app.post("/foo") async def foo_handler(_): return text("...") _, response = app.test_client.options("/foo") assert response.status == 204 assert len(response.body) == 0 assert "POST" in response.headers["allow"] assert "OPTIONS" in response.headers["allow"] schema = get_docs() assert "post" in schema["paths"]["/foo"] def test_auto_trace(bare_app: Sanic): Extend(bare_app, config={"http_auto_trace": True}) @bare_app.get("/foo") async def foo_handler(_): return text("...") request, response = bare_app.test_client.request( "/foo", http_method="trace" ) assert response.status == 200 assert response.body.startswith(request.head) def test_auto_head_with_vhosts(app: Sanic, get_docs): @app.get("/foo", host="one.com", name="one") async def foo_handler_one(_): return text(".") @app.get("/foo", host="two.com", name="two") async def foo_handler_two(_): return text("..") assert app.config.HTTP_AUTO_HEAD _, response = app.test_client.head("/foo", headers={"host": "one.com"}) assert response.status == 200 assert len(response.body) == 0 assert int(response.headers["content-length"]) == 1 _, response = app.test_client.head("/foo", headers={"host": "two.com"}) assert response.status == 200 assert len(response.body) == 0 assert int(response.headers["content-length"]) == 2 schema = get_docs() assert "get" in schema["paths"]["/foo"] def test_auto_options_with_vhosts(app: Sanic, get_docs): @app.post("/foo", host="one.com", name="one") async def foo_handler_one(_): return text(".") @app.post("/foo", host="two.com", name="two") async def foo_handler_two(_): return text("..") assert app.config.HTTP_AUTO_OPTIONS _, response = app.test_client.options("/foo", headers={"host": "one.com"}) assert response.status == 204 assert len(response.body) == 0 assert "POST" in response.headers["allow"] assert "OPTIONS" in response.headers["allow"] _, response = app.test_client.options("/foo", headers={"host": "two.com"}) assert response.status == 204 assert len(response.body) == 0 assert "POST" in response.headers["allow"] assert "OPTIONS" in response.headers["allow"] # This test also appears in Core Sanic tests but is added here as well # because of: https://github.com/sanic-org/sanic-ext/issues/148 @pytest.mark.parametrize("unquote", [True, False, None]) def test_unquote_add_route(app, unquote): async def handler1(_, foo): return text(foo) app.add_route(handler1, "/", unquote=unquote) value = "啊" if unquote else r"%E5%95%8A" _, response = app.test_client.get("/啊") assert response.text == value _, response = app.test_client.get(r"/%E5%95%8A") assert response.text == value