From 3c03b44af716099443ddf745c9f02725112aa2b8 Mon Sep 17 00:00:00 2001 From: Krukov Dima Date: Sun, 24 Jul 2016 13:08:31 +0000 Subject: [PATCH 1/4] Added method join_group to the test Client --- channels/tests/base.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/channels/tests/base.py b/channels/tests/base.py index b42914e..248a837 100644 --- a/channels/tests/base.py +++ b/channels/tests/base.py @@ -7,6 +7,7 @@ from functools import wraps from django.test.testcases import TestCase from .. import DEFAULT_CHANNEL_LAYER +from ..channel import Group from ..routing import Router, include from ..asgi import channel_layers, ChannelLayerWrapper from ..message import Message @@ -133,6 +134,9 @@ class Client(object): if message: return message.content + def join_group(self, group_name): + Group(group_name).add(self.reply_channel) + class apply_routes(object): """ From a3e779fe9c2c7a71c1708d327c5a9435078f87c5 Mon Sep 17 00:00:00 2001 From: Krukov Dima Date: Sun, 24 Jul 2016 13:10:57 +0000 Subject: [PATCH 2/4] Json encoding/decoding for send/receive content at the HttpClient --- channels/tests/http.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/channels/tests/http.py b/channels/tests/http.py index fa4526c..ecb0ed3 100644 --- a/channels/tests/http.py +++ b/channels/tests/http.py @@ -1,4 +1,4 @@ - +import json import copy from django.apps import apps @@ -56,7 +56,12 @@ class HttpClient(Client): self._session = session_for_reply_channel(self.reply_channel) return self._session - def send(self, to, content={}, path='/'): + def receive(self): + content = super(HttpClient, self).receive() + if content: + return json.loads(content['text']) + + def send(self, to, text=None, content={}, path='/'): """ Send a message to a channel. Adds reply_channel name and channel_session to the message. @@ -65,6 +70,9 @@ class HttpClient(Client): content.setdefault('reply_channel', self.reply_channel) content.setdefault('path', path) content.setdefault('headers', self.headers) + text = text or content.get('text', None) + if text: + content['text'] = json.dumps(text) self.channel_layer.send(to, content) def login(self, **credentials): From 05b0073d8e878246c96a68592c36abb4bcf8b8f1 Mon Sep 17 00:00:00 2001 From: Krukov Dima Date: Sun, 24 Jul 2016 13:11:58 +0000 Subject: [PATCH 3/4] Fix calling class registration --- channels/binding/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/channels/binding/base.py b/channels/binding/base.py index dd35b03..2af9969 100644 --- a/channels/binding/base.py +++ b/channels/binding/base.py @@ -21,7 +21,7 @@ class BindingMetaclass(type): if bases != (object, ): cls.binding_classes.append(klass) if cls.register_immediately: - cls.register() + klass.register() return klass @classmethod From 72039cd3e9495ac9df45d231fe57a6902850ed7f Mon Sep 17 00:00:00 2001 From: Krukov Dima Date: Sun, 24 Jul 2016 13:13:21 +0000 Subject: [PATCH 4/4] A few tests for binding (outbound) --- channels/tests/test_binding.py | 133 +++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 channels/tests/test_binding.py diff --git a/channels/tests/test_binding.py b/channels/tests/test_binding.py new file mode 100644 index 0000000..dd85208 --- /dev/null +++ b/channels/tests/test_binding.py @@ -0,0 +1,133 @@ +from __future__ import unicode_literals + +from django.contrib.auth import get_user_model +from channels.binding.websockets import WebsocketBinding +from channels.tests import ChannelTestCase, apply_routes, HttpClient +from channels import route + +User = get_user_model() + + +class TestsBinding(ChannelTestCase): + + def test_trigger_outbound_create(self): + + class TestBinding(WebsocketBinding): + model = User + stream = 'test' + fields = ['username', 'email', 'password', 'last_name'] + + def group_names(self, instance, action): + return ["users"] + + def has_permission(self, user, action, pk): + return True + + with apply_routes([route('test', TestBinding.consumer)]): + client = HttpClient() + client.join_group('users') + + user = User.objects.create(username='test', email='test@test.com') + + received = client.receive() + self.assertTrue('payload' in received) + self.assertTrue('action' in received['payload']) + self.assertTrue('data' in received['payload']) + self.assertTrue('username' in received['payload']['data']) + self.assertTrue('email' in received['payload']['data']) + self.assertTrue('password' in received['payload']['data']) + self.assertTrue('last_name' in received['payload']['data']) + self.assertTrue('model' in received['payload']) + self.assertTrue('pk' in received['payload']) + + self.assertEqual(received['payload']['action'], 'create') + self.assertEqual(received['payload']['model'], 'auth.user') + self.assertEqual(received['payload']['pk'], user.pk) + + self.assertEqual(received['payload']['data']['email'], 'test@test.com') + self.assertEqual(received['payload']['data']['username'], 'test') + self.assertEqual(received['payload']['data']['password'], '') + self.assertEqual(received['payload']['data']['last_name'], '') + + received = client.receive() + self.assertIsNone(received) + + def test_trigger_outbound_update(self): + class TestBinding(WebsocketBinding): + model = User + stream = 'test' + fields = ['__all__'] + + def group_names(self, instance, action): + return ["users2"] + + def has_permission(self, user, action, pk): + return True + + user = User.objects.create(username='test', email='test@test.com') + + with apply_routes([route('test', TestBinding.consumer)]): + client = HttpClient() + client.join_group('users2') + + user.username = 'test_new' + user.save() + + received = client.receive() + self.assertTrue('payload' in received) + self.assertTrue('action' in received['payload']) + self.assertTrue('data' in received['payload']) + self.assertTrue('username' in received['payload']['data']) + self.assertTrue('email' in received['payload']['data']) + self.assertTrue('password' in received['payload']['data']) + self.assertTrue('last_name' in received['payload']['data']) + self.assertTrue('model' in received['payload']) + self.assertTrue('pk' in received['payload']) + + self.assertEqual(received['payload']['action'], 'update') + self.assertEqual(received['payload']['model'], 'auth.user') + self.assertEqual(received['payload']['pk'], user.pk) + + self.assertEqual(received['payload']['data']['email'], 'test@test.com') + self.assertEqual(received['payload']['data']['username'], 'test_new') + self.assertEqual(received['payload']['data']['password'], '') + self.assertEqual(received['payload']['data']['last_name'], '') + + received = client.receive() + self.assertIsNone(received) + + def test_trigger_outbound_delete(self): + class TestBinding(WebsocketBinding): + model = User + stream = 'test' + fields = ['username'] + + def group_names(self, instance, action): + return ["users3"] + + def has_permission(self, user, action, pk): + return True + + user = User.objects.create(username='test', email='test@test.com') + + with apply_routes([route('test', TestBinding.consumer)]): + client = HttpClient() + client.join_group('users3') + + user.delete() + + received = client.receive() + self.assertTrue('payload' in received) + self.assertTrue('action' in received['payload']) + self.assertTrue('data' in received['payload']) + self.assertTrue('username' in received['payload']['data']) + self.assertTrue('model' in received['payload']) + self.assertTrue('pk' in received['payload']) + + self.assertEqual(received['payload']['action'], 'delete') + self.assertEqual(received['payload']['model'], 'auth.user') + self.assertEqual(received['payload']['pk'], 1) + self.assertEqual(received['payload']['data']['username'], 'test') + + received = client.receive() + self.assertIsNone(received)