From 938c49b899595b1b2f980109508311d9631cd465 Mon Sep 17 00:00:00 2001 From: Adam Hopkins Date: Sun, 28 Jun 2020 14:45:52 +0300 Subject: [PATCH] Add handler names for websockets for url_for usage (#1880) --- sanic/blueprints.py | 7 +++++ tests/test_blueprints.py | 18 ++++++++++--- tests/test_multiprocessing.py | 3 ++- tests/test_reloader.py | 36 +++++++++++++++++++------- tests/test_response.py | 2 +- tests/test_url_for.py | 48 +++++++++++++++++++++++++++++++++++ 6 files changed, 100 insertions(+), 14 deletions(-) diff --git a/sanic/blueprints.py b/sanic/blueprints.py index 42599342e9..cf5eee5ece 100644 --- a/sanic/blueprints.py +++ b/sanic/blueprints.py @@ -283,6 +283,13 @@ def websocket( strict_slashes = self.strict_slashes def decorator(handler): + nonlocal uri + nonlocal host + nonlocal strict_slashes + nonlocal version + nonlocal name + + name = f"{self.name}.{name or handler.__name__}" route = FutureRoute( handler, uri, [], host, strict_slashes, False, version, name ) diff --git a/tests/test_blueprints.py b/tests/test_blueprints.py index 00bee04346..4978b51e8f 100644 --- a/tests/test_blueprints.py +++ b/tests/test_blueprints.py @@ -253,7 +253,11 @@ def handler2(request): def test_bp_with_host_list(app): - bp = Blueprint("test_bp_host", url_prefix="/test1", host=["example.com", "sub.example.com"]) + bp = Blueprint( + "test_bp_host", + url_prefix="/test1", + host=["example.com", "sub.example.com"], + ) @bp.route("/") def handler1(request): @@ -279,8 +283,16 @@ def handler2(request): def test_several_bp_with_host_list(app): - bp = Blueprint("test_text", url_prefix="/test", host=["example.com", "sub.example.com"]) - bp2 = Blueprint("test_text2", url_prefix="/test", host=["sub1.example.com", "sub2.example.com"]) + bp = Blueprint( + "test_text", + url_prefix="/test", + host=["example.com", "sub.example.com"], + ) + bp2 = Blueprint( + "test_text2", + url_prefix="/test", + host=["sub1.example.com", "sub2.example.com"], + ) @bp.route("/") def handler(request): diff --git a/tests/test_multiprocessing.py b/tests/test_multiprocessing.py index ef1db52f40..59be2df77d 100644 --- a/tests/test_multiprocessing.py +++ b/tests/test_multiprocessing.py @@ -88,10 +88,11 @@ def test_pickle_app_with_bp(app, protocol): assert up_p_app.is_request_stream is False assert response.text == "Hello" + @pytest.mark.parametrize("protocol", [3, 4]) def test_pickle_app_with_static(app, protocol): app.route("/")(handler) - app.static('/static', "/tmp/static") + app.static("/static", "/tmp/static") p_app = pickle.dumps(app, protocol=protocol) del app up_p_app = pickle.loads(p_app) diff --git a/tests/test_reloader.py b/tests/test_reloader.py index 5eccb8011b..5079883399 100644 --- a/tests/test_reloader.py +++ b/tests/test_reloader.py @@ -1,8 +1,8 @@ import os import secrets import sys -from contextlib import suppress +from contextlib import suppress from subprocess import PIPE, Popen, TimeoutExpired from tempfile import TemporaryDirectory from textwrap import dedent @@ -23,16 +23,20 @@ except ImportError: flags = 0 + def terminate(proc): if flags: proc.send_signal(CTRL_BREAK_EVENT) else: proc.terminate() + def write_app(filename, **runargs): text = secrets.token_urlsafe() with open(filename, "w") as f: - f.write(dedent(f"""\ + f.write( + dedent( + f"""\ import os from sanic import Sanic @@ -45,9 +49,11 @@ def complete(*args): if __name__ == "__main__": app.run(**{runargs!r}) """ - )) + ) + ) return text + def scanner(proc): for line in proc.stdout: line = line.decode().strip() @@ -59,14 +65,26 @@ def scanner(proc): argv = dict( script=[sys.executable, "reloader.py"], module=[sys.executable, "-m", "reloader"], - sanic=[sys.executable, "-m", "sanic", "--port", "42104", "--debug", "reloader.app"], + sanic=[ + sys.executable, + "-m", + "sanic", + "--port", + "42104", + "--debug", + "reloader.app", + ], ) -@pytest.mark.parametrize("runargs, mode", [ - (dict(port=42102, auto_reload=True), "script"), - (dict(port=42103, debug=True), "module"), - (dict(), "sanic"), -]) + +@pytest.mark.parametrize( + "runargs, mode", + [ + (dict(port=42102, auto_reload=True), "script"), + (dict(port=42103, debug=True), "module"), + (dict(), "sanic"), + ], +) async def test_reloader_live(runargs, mode): with TemporaryDirectory() as tmpdir: filename = os.path.join(tmpdir, "reloader.py") diff --git a/tests/test_response.py b/tests/test_response.py index d3ed294b0d..625317d592 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -614,7 +614,7 @@ def test_response_body_bytes_deprecated(app): with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") - HTTPResponse(body_bytes=b'bytes') + HTTPResponse(body_bytes=b"bytes") assert len(w) == 1 assert issubclass(w[0].category, DeprecationWarning) diff --git a/tests/test_url_for.py b/tests/test_url_for.py index e77d6d825a..2d692f2ef1 100644 --- a/tests/test_url_for.py +++ b/tests/test_url_for.py @@ -1,3 +1,8 @@ +import asyncio + +from sanic.blueprints import Blueprint + + def test_routes_with_host(app): @app.route("/") @app.route("/", name="hostindex", host="example.com") @@ -13,3 +18,46 @@ def index(request): app.url_for("hostpath", _external=True) == "http://path.example.com/path" ) + + +def test_websocket_bp_route_name(app): + """Tests that blueprint websocket route is named.""" + event = asyncio.Event() + bp = Blueprint("test_bp", url_prefix="/bp") + + @bp.get("/main") + async def main(request): + ... + + @bp.websocket("/route") + async def test_route(request, ws): + event.set() + + @bp.websocket("/route2") + async def test_route2(request, ws): + event.set() + + @bp.websocket("/route3", name="foobar_3") + async def test_route3(request, ws): + event.set() + + app.blueprint(bp) + + uri = app.url_for("test_bp.main") + assert uri == "/bp/main" + + uri = app.url_for("test_bp.test_route") + assert uri == "/bp/route" + request, response = app.test_client.websocket(uri) + assert response.opened is True + assert event.is_set() + + event.clear() + uri = app.url_for("test_bp.test_route2") + assert uri == "/bp/route2" + request, response = app.test_client.websocket(uri) + assert response.opened is True + assert event.is_set() + + uri = app.url_for("test_bp.foobar_3") + assert uri == "/bp/route3"