mirror of
https://github.com/django/daphne.git
synced 2025-05-07 09:03:50 +03:00
349 lines
10 KiB
Python
349 lines
10 KiB
Python
from __future__ import unicode_literals
|
|
|
|
from django.test import SimpleTestCase
|
|
|
|
from channels.generic import BaseConsumer
|
|
from channels.message import Message
|
|
from channels.routing import Router, include, route, route_class
|
|
from channels.utils import name_that_thing
|
|
|
|
|
|
# Fake consumers and routing sets that can be imported by string
|
|
def consumer_1():
|
|
pass
|
|
|
|
|
|
def consumer_2():
|
|
pass
|
|
|
|
|
|
def consumer_3():
|
|
pass
|
|
|
|
|
|
class TestClassConsumer(BaseConsumer):
|
|
|
|
method_mapping = {
|
|
"test.channel": "some_method",
|
|
}
|
|
|
|
def some_method(self, message, **kwargs):
|
|
pass
|
|
|
|
|
|
chatroom_routing = [
|
|
route("websocket.connect", consumer_2, path=r"^/chat/(?P<room>[^/]+)/$"),
|
|
route("websocket.connect", consumer_3, path=r"^/mentions/$"),
|
|
]
|
|
|
|
chatroom_routing_nolinestart = [
|
|
route("websocket.connect", consumer_2, path=r"/chat/(?P<room>[^/]+)/$"),
|
|
route("websocket.connect", consumer_3, path=r"/mentions/$"),
|
|
]
|
|
|
|
class_routing = [
|
|
route_class(TestClassConsumer, path=r"^/foobar/$"),
|
|
]
|
|
|
|
|
|
class RoutingTests(SimpleTestCase):
|
|
"""
|
|
Tests that the router's routing code works correctly.
|
|
"""
|
|
|
|
def assertRoute(self, router, channel, content, consumer, kwargs=None):
|
|
"""
|
|
Asserts that asking the `router` to route the `content` as a message
|
|
from `channel` means it returns consumer `consumer`, optionally
|
|
testing it also returns `kwargs` to be passed in
|
|
|
|
Use `consumer` = None to assert that no route is found.
|
|
"""
|
|
message = Message(content, channel, channel_layer="fake channel layer")
|
|
match = router.match(message)
|
|
if match is None:
|
|
if consumer is None:
|
|
return
|
|
else:
|
|
self.fail("No route found for %s on %s; expecting %s" % (
|
|
content,
|
|
channel,
|
|
name_that_thing(consumer),
|
|
))
|
|
else:
|
|
mconsumer, mkwargs = match
|
|
if consumer is None:
|
|
self.fail("Route found for %s on %s; expecting no route." % (
|
|
content,
|
|
channel,
|
|
))
|
|
self.assertEqual(consumer, mconsumer, "Route found for %s on %s; but wrong consumer (%s not %s)." % (
|
|
content,
|
|
channel,
|
|
name_that_thing(mconsumer),
|
|
name_that_thing(consumer),
|
|
))
|
|
if kwargs is not None:
|
|
self.assertEqual(kwargs, mkwargs, "Route found for %s on %s; but wrong kwargs (%s not %s)." % (
|
|
content,
|
|
channel,
|
|
mkwargs,
|
|
kwargs,
|
|
))
|
|
|
|
def test_assumption(self):
|
|
"""
|
|
Ensures the test consumers don't compare equal, as if this ever happens
|
|
this test file will pass and miss most bugs.
|
|
"""
|
|
self.assertEqual(consumer_1, consumer_1)
|
|
self.assertNotEqual(consumer_1, consumer_2)
|
|
self.assertNotEqual(consumer_1, consumer_3)
|
|
|
|
def test_dict(self):
|
|
"""
|
|
Tests dict expansion
|
|
"""
|
|
router = Router({
|
|
"http.request": consumer_1,
|
|
"http.disconnect": consumer_2,
|
|
})
|
|
self.assertRoute(
|
|
router,
|
|
channel="http.request",
|
|
content={},
|
|
consumer=consumer_1,
|
|
kwargs={},
|
|
)
|
|
self.assertRoute(
|
|
router,
|
|
channel="http.request",
|
|
content={"path": "/chat/"},
|
|
consumer=consumer_1,
|
|
kwargs={},
|
|
)
|
|
self.assertRoute(
|
|
router,
|
|
channel="http.disconnect",
|
|
content={},
|
|
consumer=consumer_2,
|
|
kwargs={},
|
|
)
|
|
|
|
def test_filters(self):
|
|
"""
|
|
Tests that filters catch things correctly.
|
|
"""
|
|
router = Router([
|
|
route("http.request", consumer_1, path=r"^/chat/$"),
|
|
route("http.disconnect", consumer_2),
|
|
route("http.request", consumer_3),
|
|
])
|
|
# Filter hit
|
|
self.assertRoute(
|
|
router,
|
|
channel="http.request",
|
|
content={"path": "/chat/"},
|
|
consumer=consumer_1,
|
|
kwargs={},
|
|
)
|
|
# Fall-through
|
|
self.assertRoute(
|
|
router,
|
|
channel="http.request",
|
|
content={},
|
|
consumer=consumer_3,
|
|
kwargs={},
|
|
)
|
|
self.assertRoute(
|
|
router,
|
|
channel="http.request",
|
|
content={"path": "/liveblog/"},
|
|
consumer=consumer_3,
|
|
kwargs={},
|
|
)
|
|
|
|
def test_include(self):
|
|
"""
|
|
Tests inclusion without a prefix
|
|
"""
|
|
router = Router([
|
|
include("channels.tests.test_routing.chatroom_routing"),
|
|
])
|
|
self.assertRoute(
|
|
router,
|
|
channel="websocket.connect",
|
|
content={"path": "/boom/"},
|
|
consumer=None,
|
|
)
|
|
self.assertRoute(
|
|
router,
|
|
channel="websocket.connect",
|
|
content={"path": "/chat/django/"},
|
|
consumer=consumer_2,
|
|
kwargs={"room": "django"},
|
|
)
|
|
self.assertRoute(
|
|
router,
|
|
channel="websocket.connect",
|
|
content={"path": "/mentions/"},
|
|
consumer=consumer_3,
|
|
kwargs={},
|
|
)
|
|
|
|
def test_route_class(self):
|
|
"""
|
|
Tests route_class with/without prefix
|
|
"""
|
|
router = Router([
|
|
include("channels.tests.test_routing.class_routing"),
|
|
])
|
|
self.assertRoute(
|
|
router,
|
|
channel="websocket.connect",
|
|
content={"path": "/foobar/"},
|
|
consumer=None,
|
|
)
|
|
self.assertRoute(
|
|
router,
|
|
channel="test.channel",
|
|
content={"path": "/foobar/"},
|
|
consumer=TestClassConsumer,
|
|
)
|
|
self.assertRoute(
|
|
router,
|
|
channel="test.channel",
|
|
content={"path": "/"},
|
|
consumer=None,
|
|
)
|
|
|
|
def test_include_prefix(self):
|
|
"""
|
|
Tests inclusion with a prefix
|
|
"""
|
|
router = Router([
|
|
include("channels.tests.test_routing.chatroom_routing", path="^/ws/v(?P<version>[0-9]+)"),
|
|
])
|
|
self.assertRoute(
|
|
router,
|
|
channel="websocket.connect",
|
|
content={"path": "/boom/"},
|
|
consumer=None,
|
|
)
|
|
self.assertRoute(
|
|
router,
|
|
channel="websocket.connect",
|
|
content={"path": "/chat/django/"},
|
|
consumer=None,
|
|
)
|
|
self.assertRoute(
|
|
router,
|
|
channel="websocket.connect",
|
|
content={"path": "/ws/v2/chat/django/"},
|
|
consumer=consumer_2,
|
|
kwargs={"version": "2", "room": "django"},
|
|
)
|
|
self.assertRoute(
|
|
router,
|
|
channel="websocket.connect",
|
|
content={"path": "/ws/v1/mentions/"},
|
|
consumer=consumer_3,
|
|
kwargs={"version": "1"},
|
|
)
|
|
# Check it works without the ^s too.
|
|
router = Router([
|
|
include("channels.tests.test_routing.chatroom_routing_nolinestart", path="/ws/v(?P<version>[0-9]+)"),
|
|
])
|
|
self.assertRoute(
|
|
router,
|
|
channel="websocket.connect",
|
|
content={"path": "/ws/v2/chat/django/"},
|
|
consumer=consumer_2,
|
|
kwargs={"version": "2", "room": "django"},
|
|
)
|
|
|
|
def test_positional_pattern(self):
|
|
"""
|
|
Tests that regexes with positional groups are rejected.
|
|
"""
|
|
with self.assertRaises(ValueError):
|
|
Router([
|
|
route("http.request", consumer_1, path=r"^/chat/([^/]+)/$"),
|
|
])
|
|
|
|
def test_mixed_unicode_bytes(self):
|
|
"""
|
|
Tests that having the message key be bytes and pattern unicode (or vice-versa)
|
|
still works.
|
|
"""
|
|
# Unicode patterns, byte message
|
|
router = Router([
|
|
route("websocket.connect", consumer_1, path="^/foo/"),
|
|
include("channels.tests.test_routing.chatroom_routing", path="^/ws/v(?P<version>[0-9]+)"),
|
|
])
|
|
self.assertRoute(
|
|
router,
|
|
channel="websocket.connect",
|
|
content={"path": b"/boom/"},
|
|
consumer=None,
|
|
)
|
|
self.assertRoute(
|
|
router,
|
|
channel="websocket.connect",
|
|
content={"path": b"/foo/"},
|
|
consumer=consumer_1,
|
|
)
|
|
self.assertRoute(
|
|
router,
|
|
channel="websocket.connect",
|
|
content={"path": b"/ws/v2/chat/django/"},
|
|
consumer=consumer_2,
|
|
kwargs={"version": "2", "room": "django"},
|
|
)
|
|
# Byte patterns, unicode message
|
|
router = Router([
|
|
route("websocket.connect", consumer_1, path=b"^/foo/"),
|
|
include("channels.tests.test_routing.chatroom_routing", path=b"^/ws/v(?P<version>[0-9]+)"),
|
|
])
|
|
self.assertRoute(
|
|
router,
|
|
channel="websocket.connect",
|
|
content={"path": "/boom/"},
|
|
consumer=None,
|
|
)
|
|
self.assertRoute(
|
|
router,
|
|
channel="websocket.connect",
|
|
content={"path": "/foo/"},
|
|
consumer=consumer_1,
|
|
)
|
|
self.assertRoute(
|
|
router,
|
|
channel="websocket.connect",
|
|
content={"path": "/ws/v2/chat/django/"},
|
|
consumer=consumer_2,
|
|
kwargs={"version": "2", "room": "django"},
|
|
)
|
|
|
|
def test_channels(self):
|
|
"""
|
|
Tests that the router reports channels to listen on correctly
|
|
"""
|
|
router = Router([
|
|
route("http.request", consumer_1, path=r"^/chat/$"),
|
|
route("http.disconnect", consumer_2),
|
|
route("http.request", consumer_3),
|
|
route_class(TestClassConsumer),
|
|
])
|
|
# Initial check
|
|
self.assertEqual(
|
|
router.channels,
|
|
{"http.request", "http.disconnect", "test.channel"},
|
|
)
|
|
# Dynamically add route, recheck
|
|
router.add_route(route("websocket.receive", consumer_1))
|
|
self.assertEqual(
|
|
router.channels,
|
|
{"http.request", "http.disconnect", "websocket.receive", "test.channel"},
|
|
)
|