# import asyncio # import pytest # from sanic_testing.testing import SanicTestClient # from sanic import Sanic # from sanic.constants import HTTP_METHODS # from sanic.response import json, text # from sanic.router import ParameterNameConflicts, RouteDoesNotExist, RouteExists # # ------------------------------------------------------------ # # # UTF-8 # # ------------------------------------------------------------ # # @pytest.mark.parametrize("method", HTTP_METHODS) # def test_versioned_routes_get(app, method): # method = method.lower() # func = getattr(app, method) # if callable(func): # @func(f"/{method}", version=1) # def handler(request): # return text("OK") # else: # print(func) # raise Exception(f"Method: {method} is not callable") # client_method = getattr(app.test_client, method) # request, response = client_method(f"/v1/{method}") # assert response.status == 200 # def test_shorthand_routes_get(app): # @app.get("/get") # def handler(request): # return text("OK") # request, response = app.test_client.get("/get") # assert response.text == "OK" # request, response = app.test_client.post("/get") # assert response.status == 405 # def test_shorthand_routes_multiple(app): # @app.get("/get") # def get_handler(request): # return text("OK") # @app.options("/get") # def options_handler(request): # return text("") # request, response = app.test_client.get("/get/") # assert response.status == 200 # assert response.text == "OK" # request, response = app.test_client.options("/get/") # assert response.status == 200 # def test_route_strict_slash(app): # @app.get("/get", strict_slashes=True) # def handler1(request): # return text("OK") # @app.post("/post/", strict_slashes=True) # def handler2(request): # return text("OK") # request, response = app.test_client.get("/get") # assert response.text == "OK" # request, response = app.test_client.get("/get/") # assert response.status == 404 # request, response = app.test_client.post("/post/") # assert response.text == "OK" # request, response = app.test_client.post("/post") # assert response.status == 404 # def test_route_invalid_parameter_syntax(app): # with pytest.raises(ValueError): # @app.get("/get/<:string>", strict_slashes=True) # def handler(request): # return text("OK") # request, response = app.test_client.get("/get") # def test_route_strict_slash_default_value(): # app = Sanic("test_route_strict_slash", strict_slashes=True) # @app.get("/get") # def handler(request): # return text("OK") # request, response = app.test_client.get("/get/") # assert response.status == 404 # def test_route_strict_slash_without_passing_default_value(app): # @app.get("/get") # def handler(request): # return text("OK") # request, response = app.test_client.get("/get/") # assert response.text == "OK" # def test_route_strict_slash_default_value_can_be_overwritten(): # app = Sanic("test_route_strict_slash", strict_slashes=True) # @app.get("/get", strict_slashes=False) # def handler(request): # return text("OK") # request, response = app.test_client.get("/get/") # assert response.text == "OK" # def test_route_slashes_overload(app): # @app.get("/hello/") # def handler_get(request): # return text("OK") # @app.post("/hello/") # def handler_post(request): # return text("OK") # request, response = app.test_client.get("/hello") # assert response.text == "OK" # request, response = app.test_client.get("/hello/") # assert response.text == "OK" # request, response = app.test_client.post("/hello") # assert response.text == "OK" # request, response = app.test_client.post("/hello/") # assert response.text == "OK" # def test_route_optional_slash(app): # @app.get("/get") # def handler(request): # return text("OK") # request, response = app.test_client.get("/get") # assert response.text == "OK" # request, response = app.test_client.get("/get/") # assert response.text == "OK" # def test_route_strict_slashes_set_to_false_and_host_is_a_list(app): # # Part of regression test for issue #1120 # test_client = SanicTestClient(app, port=42101) # site1 = f"127.0.0.1:{test_client.port}" # # before fix, this raises a RouteExists error # @app.get("/get", host=[site1, "site2.com"], strict_slashes=False) # def get_handler(request): # return text("OK") # request, response = test_client.get("http://" + site1 + "/get") # assert response.text == "OK" # @app.post("/post", host=[site1, "site2.com"], strict_slashes=False) # def post_handler(request): # return text("OK") # request, response = test_client.post("http://" + site1 + "/post") # assert response.text == "OK" # @app.put("/put", host=[site1, "site2.com"], strict_slashes=False) # def put_handler(request): # return text("OK") # request, response = test_client.put("http://" + site1 + "/put") # assert response.text == "OK" # @app.delete("/delete", host=[site1, "site2.com"], strict_slashes=False) # def delete_handler(request): # return text("OK") # request, response = test_client.delete("http://" + site1 + "/delete") # assert response.text == "OK" # def test_shorthand_routes_post(app): # @app.post("/post") # def handler(request): # return text("OK") # request, response = app.test_client.post("/post") # assert response.text == "OK" # request, response = app.test_client.get("/post") # assert response.status == 405 # def test_shorthand_routes_put(app): # @app.put("/put") # def handler(request): # return text("OK") # request, response = app.test_client.put("/put") # assert response.text == "OK" # request, response = app.test_client.get("/put") # assert response.status == 405 # def test_shorthand_routes_delete(app): # @app.delete("/delete") # def handler(request): # return text("OK") # request, response = app.test_client.delete("/delete") # assert response.text == "OK" # request, response = app.test_client.get("/delete") # assert response.status == 405 # def test_shorthand_routes_patch(app): # @app.patch("/patch") # def handler(request): # return text("OK") # request, response = app.test_client.patch("/patch") # assert response.text == "OK" # request, response = app.test_client.get("/patch") # assert response.status == 405 # def test_shorthand_routes_head(app): # @app.head("/head") # def handler(request): # return text("OK") # request, response = app.test_client.head("/head") # assert response.status == 200 # request, response = app.test_client.get("/head") # assert response.status == 405 # def test_shorthand_routes_options(app): # @app.options("/options") # def handler(request): # return text("OK") # request, response = app.test_client.options("/options") # assert response.status == 200 # request, response = app.test_client.get("/options") # assert response.status == 405 # def test_static_routes(app): # @app.route("/test") # async def handler1(request): # return text("OK1") # @app.route("/pizazz") # async def handler2(request): # return text("OK2") # request, response = app.test_client.get("/test") # assert response.text == "OK1" # request, response = app.test_client.get("/pizazz") # assert response.text == "OK2" # def test_dynamic_route(app): # results = [] # @app.route("/folder/") # async def handler(request, name): # results.append(name) # return text("OK") # request, response = app.test_client.get("/folder/test123") # assert response.text == "OK" # assert results[0] == "test123" # def test_dynamic_route_string(app): # results = [] # @app.route("/folder/") # async def handler(request, name): # results.append(name) # return text("OK") # request, response = app.test_client.get("/folder/test123") # assert response.text == "OK" # assert results[0] == "test123" # request, response = app.test_client.get("/folder/favicon.ico") # assert response.text == "OK" # assert results[1] == "favicon.ico" # def test_dynamic_route_int(app): # results = [] # @app.route("/folder/") # async def handler(request, folder_id): # results.append(folder_id) # return text("OK") # request, response = app.test_client.get("/folder/12345") # assert response.text == "OK" # assert type(results[0]) is int # request, response = app.test_client.get("/folder/asdf") # assert response.status == 404 # def test_dynamic_route_number(app): # results = [] # @app.route("/weight/") # async def handler(request, weight): # results.append(weight) # return text("OK") # request, response = app.test_client.get("/weight/12345") # assert response.text == "OK" # assert type(results[0]) is float # request, response = app.test_client.get("/weight/1234.56") # assert response.status == 200 # request, response = app.test_client.get("/weight/.12") # assert response.status == 200 # request, response = app.test_client.get("/weight/12.") # assert response.status == 200 # request, response = app.test_client.get("/weight/1234-56") # assert response.status == 404 # request, response = app.test_client.get("/weight/12.34.56") # assert response.status == 404 # def test_dynamic_route_regex(app): # @app.route("/folder/") # async def handler(request, folder_id): # return text("OK") # request, response = app.test_client.get("/folder/test") # assert response.status == 200 # request, response = app.test_client.get("/folder/test1") # assert response.status == 404 # request, response = app.test_client.get("/folder/test-123") # assert response.status == 404 # request, response = app.test_client.get("/folder/") # assert response.status == 200 # def test_dynamic_route_uuid(app): # import uuid # results = [] # @app.route("/quirky/") # async def handler(request, unique_id): # results.append(unique_id) # return text("OK") # url = "/quirky/123e4567-e89b-12d3-a456-426655440000" # request, response = app.test_client.get(url) # assert response.text == "OK" # assert type(results[0]) is uuid.UUID # generated_uuid = uuid.uuid4() # request, response = app.test_client.get(f"/quirky/{generated_uuid}") # assert response.status == 200 # request, response = app.test_client.get("/quirky/non-existing") # assert response.status == 404 # def test_dynamic_route_path(app): # @app.route("//info") # async def handler(request, path): # return text("OK") # request, response = app.test_client.get("/path/1/info") # assert response.status == 200 # request, response = app.test_client.get("/info") # assert response.status == 404 # @app.route("/") # async def handler1(request, path): # return text("OK") # request, response = app.test_client.get("/info") # assert response.status == 200 # request, response = app.test_client.get("/whatever/you/set") # assert response.status == 200 # def test_dynamic_route_unhashable(app): # @app.route("/folder//end/") # async def handler(request, unhashable): # return text("OK") # request, response = app.test_client.get("/folder/test/asdf/end/") # assert response.status == 200 # request, response = app.test_client.get("/folder/test///////end/") # assert response.status == 200 # request, response = app.test_client.get("/folder/test/end/") # assert response.status == 200 # request, response = app.test_client.get("/folder/test/nope/") # assert response.status == 404 # @pytest.mark.parametrize("url", ["/ws", "ws"]) # def test_websocket_route(app, url): # ev = asyncio.Event() # @app.websocket(url) # async def handler(request, ws): # assert request.scheme == "ws" # assert ws.subprotocol is None # ev.set() # request, response = app.test_client.websocket(url) # assert response.opened is True # assert ev.is_set() # @pytest.mark.asyncio # @pytest.mark.parametrize("url", ["/ws", "ws"]) # async def test_websocket_route_asgi(app, url): # ev = asyncio.Event() # @app.websocket(url) # async def handler(request, ws): # ev.set() # request, response = await app.asgi_client.websocket(url) # assert ev.is_set() # def test_websocket_route_with_subprotocols(app): # results = [] # @app.websocket("/ws", subprotocols=["foo", "bar"]) # async def handler(request, ws): # results.append(ws.subprotocol) # assert ws.subprotocol is not None # _, response = SanicTestClient(app).websocket("/ws", subprotocols=["bar"]) # assert response.opened is True # assert results == ["bar"] # _, response = SanicTestClient(app).websocket( # "/ws", subprotocols=["bar", "foo"] # ) # assert response.opened is True # assert results == ["bar", "bar"] # _, response = SanicTestClient(app).websocket("/ws", subprotocols=["baz"]) # assert response.opened is True # assert results == ["bar", "bar", None] # _, response = SanicTestClient(app).websocket("/ws") # assert response.opened is True # assert results == ["bar", "bar", None, None] # @pytest.mark.parametrize("strict_slashes", [True, False, None]) # def test_add_webscoket_route(app, strict_slashes): # ev = asyncio.Event() # async def handler(request, ws): # assert ws.subprotocol is None # ev.set() # app.add_websocket_route(handler, "/ws", strict_slashes=strict_slashes) # request, response = app.test_client.websocket("/ws") # assert response.opened is True # assert ev.is_set() # def test_add_webscoket_route_with_version(app): # ev = asyncio.Event() # async def handler(request, ws): # assert ws.subprotocol is None # ev.set() # app.add_websocket_route(handler, "/ws", version=1) # request, response = app.test_client.websocket("/v1/ws") # assert response.opened is True # assert ev.is_set() # def test_route_duplicate(app): # with pytest.raises(RouteExists): # @app.route("/test") # async def handler1(request): # pass # @app.route("/test") # async def handler2(request): # pass # with pytest.raises(RouteExists): # @app.route("/test//") # async def handler3(request, dynamic): # pass # @app.route("/test//") # async def handler4(request, dynamic): # pass # def test_double_stack_route(app): # @app.route("/test/1") # @app.route("/test/2") # async def handler1(request): # return text("OK") # request, response = app.test_client.get("/test/1") # assert response.status == 200 # request, response = app.test_client.get("/test/2") # assert response.status == 200 # @pytest.mark.asyncio # async def test_websocket_route_asgi(app): # ev = asyncio.Event() # @app.websocket("/test/1") # @app.websocket("/test/2") # async def handler(request, ws): # ev.set() # request, response = await app.asgi_client.websocket("/test/1") # first_set = ev.is_set() # ev.clear() # request, response = await app.asgi_client.websocket("/test/1") # second_set = ev.is_set() # assert first_set and second_set # def test_method_not_allowed(app): # @app.route("/test", methods=["GET"]) # async def handler(request): # return text("OK") # request, response = app.test_client.get("/test") # assert response.status == 200 # request, response = app.test_client.post("/test") # assert response.status == 405 # @pytest.mark.parametrize("strict_slashes", [True, False, None]) # def test_static_add_route(app, strict_slashes): # async def handler1(request): # return text("OK1") # async def handler2(request): # return text("OK2") # app.add_route(handler1, "/test", strict_slashes=strict_slashes) # app.add_route(handler2, "/test2", strict_slashes=strict_slashes) # request, response = app.test_client.get("/test") # assert response.text == "OK1" # request, response = app.test_client.get("/test2") # assert response.text == "OK2" # def test_dynamic_add_route(app): # results = [] # async def handler(request, name): # results.append(name) # return text("OK") # app.add_route(handler, "/folder/") # request, response = app.test_client.get("/folder/test123") # assert response.text == "OK" # assert results[0] == "test123" # def test_dynamic_add_route_string(app): # results = [] # async def handler(request, name): # results.append(name) # return text("OK") # app.add_route(handler, "/folder/") # request, response = app.test_client.get("/folder/test123") # assert response.text == "OK" # assert results[0] == "test123" # request, response = app.test_client.get("/folder/favicon.ico") # assert response.text == "OK" # assert results[1] == "favicon.ico" # def test_dynamic_add_route_int(app): # results = [] # async def handler(request, folder_id): # results.append(folder_id) # return text("OK") # app.add_route(handler, "/folder/") # request, response = app.test_client.get("/folder/12345") # assert response.text == "OK" # assert type(results[0]) is int # request, response = app.test_client.get("/folder/asdf") # assert response.status == 404 # def test_dynamic_add_route_number(app): # results = [] # async def handler(request, weight): # results.append(weight) # return text("OK") # app.add_route(handler, "/weight/") # request, response = app.test_client.get("/weight/12345") # assert response.text == "OK" # assert type(results[0]) is float # request, response = app.test_client.get("/weight/1234.56") # assert response.status == 200 # request, response = app.test_client.get("/weight/.12") # assert response.status == 200 # request, response = app.test_client.get("/weight/12.") # assert response.status == 200 # request, response = app.test_client.get("/weight/1234-56") # assert response.status == 404 # request, response = app.test_client.get("/weight/12.34.56") # assert response.status == 404 # def test_dynamic_add_route_regex(app): # async def handler(request, folder_id): # return text("OK") # app.add_route(handler, "/folder/") # request, response = app.test_client.get("/folder/test") # assert response.status == 200 # request, response = app.test_client.get("/folder/test1") # assert response.status == 404 # request, response = app.test_client.get("/folder/test-123") # assert response.status == 404 # request, response = app.test_client.get("/folder/") # assert response.status == 200 # def test_dynamic_add_route_unhashable(app): # async def handler(request, unhashable): # return text("OK") # app.add_route(handler, "/folder//end/") # request, response = app.test_client.get("/folder/test/asdf/end/") # assert response.status == 200 # request, response = app.test_client.get("/folder/test///////end/") # assert response.status == 200 # request, response = app.test_client.get("/folder/test/end/") # assert response.status == 200 # request, response = app.test_client.get("/folder/test/nope/") # assert response.status == 404 # def test_add_route_duplicate(app): # with pytest.raises(RouteExists): # async def handler1(request): # pass # async def handler2(request): # pass # app.add_route(handler1, "/test") # app.add_route(handler2, "/test") # with pytest.raises(RouteExists): # async def handler1(request, dynamic): # pass # async def handler2(request, dynamic): # pass # app.add_route(handler1, "/test//") # app.add_route(handler2, "/test//") # def test_add_route_method_not_allowed(app): # async def handler(request): # return text("OK") # app.add_route(handler, "/test", methods=["GET"]) # request, response = app.test_client.get("/test") # assert response.status == 200 # request, response = app.test_client.post("/test") # assert response.status == 405 # def test_removing_slash(app): # @app.get("/rest/") # def get(_): # pass # @app.post("/rest/") # def post(_): # pass # assert len(app.router.routes_all.keys()) == 2 # def test_overload_routes(app): # @app.route("/overload", methods=["GET"]) # async def handler1(request): # return text("OK1") # @app.route("/overload", methods=["POST", "PUT"]) # async def handler2(request): # return text("OK2") # request, response = app.test_client.get("/overload") # assert response.text == "OK1" # request, response = app.test_client.post("/overload") # assert response.text == "OK2" # request, response = app.test_client.put("/overload") # assert response.text == "OK2" # request, response = app.test_client.delete("/overload") # assert response.status == 405 # with pytest.raises(RouteExists): # @app.route("/overload", methods=["PUT", "DELETE"]) # async def handler3(request): # return text("Duplicated") # def test_unmergeable_overload_routes(app): # @app.route("/overload_whole", methods=None) # async def handler1(request): # return text("OK1") # with pytest.raises(RouteExists): # @app.route("/overload_whole", methods=["POST", "PUT"]) # async def handler2(request): # return text("Duplicated") # request, response = app.test_client.get("/overload_whole") # assert response.text == "OK1" # request, response = app.test_client.post("/overload_whole") # assert response.text == "OK1" # @app.route("/overload_part", methods=["GET"]) # async def handler3(request): # return text("OK1") # with pytest.raises(RouteExists): # @app.route("/overload_part") # async def handler4(request): # return text("Duplicated") # request, response = app.test_client.get("/overload_part") # assert response.text == "OK1" # request, response = app.test_client.post("/overload_part") # assert response.status == 405 # def test_unicode_routes(app): # @app.get("/你好") # def handler1(request): # return text("OK1") # request, response = app.test_client.get("/你好") # assert response.text == "OK1" # @app.route("/overload/", methods=["GET"]) # async def handler2(request, param): # return text("OK2 " + param) # request, response = app.test_client.get("/overload/你好") # assert response.text == "OK2 你好" # def test_uri_with_different_method_and_different_params(app): # @app.route("/ads/", methods=["GET"]) # async def ad_get(request, ad_id): # return json({"ad_id": ad_id}) # @app.route("/ads/", methods=["POST"]) # async def ad_post(request, action): # return json({"action": action}) # request, response = app.test_client.get("/ads/1234") # assert response.status == 200 # assert response.json == {"ad_id": "1234"} # request, response = app.test_client.post("/ads/post") # assert response.status == 200 # assert response.json == {"action": "post"} # def test_route_raise_ParameterNameConflicts(app): # with pytest.raises(ParameterNameConflicts): # @app.get("/api/v1///") # def handler(request, user): # return text("OK") # def test_route_invalid_host(app): # host = 321 # with pytest.raises(ValueError) as excinfo: # @app.get("/test", host=host) # def handler(request): # return text("pass") # assert str(excinfo.value) == ( # "Expected either string or Iterable of " "host strings, not {!r}" # ).format(host)