def setUp(self): self.client = WSClient() self.member = UserFactory() self.group = GroupFactory(members=[self.member]) self.store = StoreFactory(group=self.group) self.pickup = PickupDateFactory(store=self.store, collectors=[self.member])
def test_receive_no_content(self): ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', ) self.assertIsNone(ws_client.receive())
def test_websockets_demultiplexer_custom_multiplexer(self): class MyWebsocketConsumer(websockets.JsonWebsocketConsumer): def connect(self, message, multiplexer=None, **kwargs): multiplexer.send({"THIS_SHOULD_BE_LOWERCASED": "1"}) class MyMultiplexer(websockets.WebsocketMultiplexer): @classmethod def encode_json(cls, content): lowered = { "stream": content["stream"], "payload": dict((key.lower(), content["payload"][key]) for key in content["payload"]) } return json.dumps(lowered) class Demultiplexer(websockets.WebsocketDemultiplexer): multiplexer_class = MyMultiplexer consumers = {"mystream": MyWebsocketConsumer} with apply_routes( [route_class(Demultiplexer, path='/path/(?P<ID>\d+)')]): client = WSClient() client.send_and_consume('websocket.connect', path='/path/1') self.assertEqual( client.receive(), { "stream": "mystream", "payload": { "this_should_be_lowercased": "1" }, })
def test_trigger_outbound_create_non_auto_pk(self): class TestBinding(WebsocketBinding): model = models.TestUUIDModel stream = 'test' fields = ['name'] @classmethod def group_names(cls, instance): return ["testuuidmodels"] def has_permission(self, user, action, pk): return True client = WSClient() client.join_group('testuuidmodels') instance = models.TestUUIDModel.objects.create(name='testname') received = client.receive() self.assertTrue('payload' in received) self.assertTrue('action' in received['payload']) self.assertTrue('data' in received['payload']) self.assertTrue('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'], 'tests.testuuidmodel') self.assertEqual(received['payload']['pk'], str(instance.pk)) self.assertEqual(received['payload']['data']['name'], 'testname') received = client.receive() self.assertIsNone(received)
def test_timer_slave_timeout(self): from threading import Timer webinterface = WSClient() webinterface.join_group('notifications') self.sched._Scheduler__event = asyncio.Event(loop=self.sched.loop) self.sched._Scheduler__script = self.script.id self.sched._Scheduler__state = SchedulerStatus.WAITING_FOR_SLAVES timer = Timer( 1, self.sched.slave_timeout_callback, ) timer.start() timer.join() self.assertEqual( self.sched._Scheduler__state, SchedulerStatus.ERROR, ) self.assertEqual( self.sched._Scheduler__error_code, "Not all slaves connected within 5 minutes.", )
def test_get_params(self): client = WSClient() content = client._get_content(path='/my/path?test=1&token=2') self.assertTrue('path' in content) self.assertTrue('query_string' in content) self.assertEqual(content['path'], '/my/path') self.assertEqual(content['query_string'], 'test=1&token=2')
def test_route_params_saved_in_kwargs(self): class UserBinding(WebsocketBinding): model = User stream = 'users' fields = ['username', 'email', 'password', 'last_name'] @classmethod def group_names(cls, instance): return ['users_outbound'] def has_permission(self, user, action, pk): return True class Demultiplexer(WebsocketDemultiplexer): consumers = { 'users': UserBinding.consumer, } groups = ['inbound'] with apply_routes([Demultiplexer.as_route(path='/path/(?P<id>\d+)')]): client = WSClient() consumer = client.send_and_consume('websocket.connect', path='/path/789') self.assertEqual(consumer.kwargs['id'], '789')
def test_simple_content(self): client = WSClient() content = client._get_content(text={'key': 'value'}, path='/my/path') self.assertEqual(content['text'], '{"key": "value"}') self.assertEqual(content['path'], '/my/path') self.assertTrue('reply_channel' in content) self.assertTrue('headers' in content)
def test_path_in_content(self): client = WSClient() content = client._get_content(content={'path': '/my_path'}, text={'path': 'hi'}, path='/my/path') self.assertEqual(content['text'], '{"path": "hi"}') self.assertEqual(content['path'], '/my_path') self.assertTrue('reply_channel' in content) self.assertTrue('headers' in content)
def test_session_in_headers(self): client = WSClient() content = client._get_content() self.assertTrue('path' in content) self.assertEqual(content['path'], '/') self.assertTrue('headers' in content) self.assertTrue('cookie' in content['headers']) self.assertTrue(b'sessionid' in content['headers']['cookie'])
def test_ordering_in_content(self): client = WSClient(ordered=True) content = client._get_content() self.assertTrue('order' in content) self.assertEqual(content['order'], 0) client.order = 2 content = client._get_content() self.assertTrue('order' in content) self.assertEqual(content['order'], 2)
def test_session_in_headers(self): client = WSClient() content = client._get_content() self.assertTrue('path' in content) self.assertEqual(content['path'], '/') self.assertTrue('headers' in content) self.assertIn(b'cookie', [x[0] for x in content['headers']]) self.assertIn(b'sessionid', [x[1] for x in content['headers'] if x[0] == b'cookie'][0])
def setUp(self): self.client = WSClient() self.member = UserFactory() self.group = GroupFactory(members=[self.member]) self.store = StoreFactory(group=self.group) # Create far in the future to generate no pickup dates # They would lead to interfering websocket messages self.series = PickupDateSeriesFactory(store=self.store, start_date=timezone.now() + relativedelta(months=2))
def test_authentication_with_wrong_token_failed(self): client = WSClient() client.send_and_consume('websocket.connect', path='/accounts/user/wrong/', check_accept=False) received = client.receive(json=False) self.assertEqual(received, {"close": True})
def test_create_contestant_valid_room(self): """ Attempt to create a contestant in a valid room """ room = Room.objects.last() client = WSClient() client.send_and_consume('websocket.connect') client.send_and_consume( 'quiz.receive', { 'command': 'new_contestant', 'room_code': room.code, 'contestant_name': 'Joe Bloggs' }) response = client.receive() # Verify server responded with correct status code self.assertEqual(response['status_code'], StatusCode.OK) # Verify room contestant count is one self.assertEquals(room.contestant_set.count(), 1) # Verify it is indeed Joe Bloggs in the room self.assertEquals(room.contestant_set.last().handle, 'Joe Bloggs') client.send_and_consume('websocket.disconnect')
def test_receive_filesystem_restore_with_error_code(self): filesystem = MovedFileFactory() error_code = 'any kind of string' error_status = Status.err({ 'method': 'filesystem_restore', 'result': error_code, }) error_status.uuid = filesystem.command_uuid # connect webinterface webinterface = WSClient() webinterface.join_group('notifications') ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': error_status.to_json()}, ) query = FilesystemModel.objects.get(id=filesystem.id) self.assertEqual(query.error_code, error_code) self.assertEqual( Status.ok({ 'filesystem_status': 'error', 'fid': str(filesystem.id), 'error_code': error_code, }), Status.from_json(json.dumps(webinterface.receive())), )
def test_receive_online_with_error_status(self): slave = SlaveOnlineFactory(online=False) error_status = Status.err({ 'method': 'online', 'result': str(Exception('foobar')) }) error_status.uuid = slave.command_uuid # connect webinterface on /notifications webinterface = WSClient() webinterface.join_group('notifications') # send online answer ws_client = WSClient() ws_client.send_and_consume('websocket.receive', path='/commands', content={'text': error_status.to_json()}) self.assertFalse(SlaveModel.objects.get(id=slave.id).is_online) # test if a connected message was send on /notifications self.assertEqual( Status.err( 'An error occurred while connecting to client {}!'.format( slave.name)), Status.from_json(json.dumps(webinterface.receive())), )
def test_receive_online_success(self): slave = SlaveOnlineFactory(online=False) expected_status = Status.ok({'method': 'online'}) expected_status.uuid = slave.command_uuid # connect webinterface on /notifications webinterface = WSClient() webinterface.join_group('notifications') # send online answer ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': expected_status.to_json()}, ) self.assertTrue(SlaveModel.objects.get(id=slave.id).is_online) # test if a connected message was send on /notifications self.assertEqual( Status.ok({ 'slave_status': 'connected', 'sid': str(slave.id), }), Status.from_json(json.dumps(webinterface.receive())), )
def test_receive_execute_slave_not_exists(self): program_status = ProgramStatusFactory(running=True) program = program_status.program expected_status = Status.ok({'method': 'execute', 'result': 0}) expected_status.uuid = program_status.command_uuid # connect webinterface webinterface = WSClient() webinterface.send_and_consume( 'websocket.connect', path='/notifications', ) program.delete() ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': expected_status.to_json()}, ) self.assertFalse( ProgramStatusModel.objects.filter(program=program).exists()) # test if the webinterface gets the "finished" message self.assertIsNone(webinterface.receive())
def test_receive_execute_success(self): program_status = ProgramStatusFactory(running=True) program = program_status.program expected_status = Status.ok({'method': 'execute', 'result': 0}) expected_status.uuid = program_status.command_uuid # connect webinterface webinterface = WSClient() webinterface.send_and_consume( 'websocket.connect', path='/notifications', ) ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': expected_status.to_json()}, ) query = ProgramStatusModel.objects.filter(program=program, code=0) self.assertTrue(query.count() == 1) self.assertFalse(query.first().running) # test if the webinterface gets the "finished" message self.assertEqual( Status.ok({ 'program_status': 'finished', 'pid': str(program.id), 'code': 0, }), Status.from_json(json.dumps(webinterface.receive())), )
def test_receive_get_log_success(self): program_status = ProgramStatusFactory(running=True) program = program_status.program error_status = Status.ok({ 'method': 'get_log', 'result': { 'log': 'this is the content of a logfile', 'uuid': program_status.command_uuid, }, }) # connect webinterface webinterface = WSClient() webinterface.join_group('notifications') ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': error_status.to_json()}, ) # test if the webinterface gets the error message self.assertEqual( Status.ok({ 'log': 'this is the content of a logfile', 'pid': str(program.id), }), Status.from_json(json.dumps(webinterface.receive())), )
def test_receive_execute_with_error_status(self): program_status = ProgramStatusFactory(running=True) program = program_status.program error_status = Status.err({ 'method': 'execute', 'result': str(Exception('foobar')), }) error_status.uuid = program_status.command_uuid # connect webinterface webinterface = WSClient() webinterface.join_group('notifications') ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': error_status.to_json()}, ) query = ProgramStatusModel.objects.get(program=program) self.assertFalse(query.running) self.assertEqual(query.code, 'foobar') # test if the webinterface gets the error message self.assertEqual( Status.ok({ 'program_status': 'finished', 'pid': str(program.id), 'code': 'foobar', }), Status.from_json(json.dumps(webinterface.receive())), )
def test_submit_card(self): client = WSClient() client.send_and_consume( 'websocket.connect', path='/game/' ) # Connect is forwarded to ALL multiplexed consumers under this demultiplexer while client.receive(): pass # Grab connection success message from each consumer # Invalid Test client.send_and_consume( 'websocket.receive', path='/game/', text={ 'stream': 'submit_card', 'payload': { 'game_code': '1234' } }) # Text arg is JSON as if it came from browser receive_reply = client.receive( ) # receive() grabs the content of the next message off of the client's reply_channel self.assertEqual(receive_reply.get('stream'), 'submit_card') self.assertFalse(receive_reply.get('payload').get('data').get('valid')) disconnect_consumer = client.send_and_consume('websocket.disconnect', path='/game/') disconnect_consumer.close()
def test_receive_get_log_program_not_exists(self): error_status = Status.ok({ 'method': 'get_log', 'result': { 'log': '', 'uuid': '0' }, }) # connect webinterface webinterface = WSClient() webinterface.join_group('notifications') ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': error_status.to_json()}, ) # test if the webinterface gets the error message self.assertEqual( Status.err('Received log from unknown program!'), Status.from_json(json.dumps(webinterface.receive())), )
def test_receive_filesystem_moved_success(self): filesystem = FileFactory() moved = MovedFileFactory.build() error_status = Status.ok({ 'method': 'filesystem_move', 'result': moved.hash_value, }) error_status.uuid = filesystem.command_uuid # connect webinterface webinterface = WSClient() webinterface.join_group('notifications') ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': error_status.to_json()}, ) query = FilesystemModel.objects.get(id=filesystem.id) self.assertEqual(query.hash_value, moved.hash_value) self.assertEqual(query.error_code, "") self.assertEqual( Status.ok({ 'filesystem_status': 'moved', 'fid': str(filesystem.id), }), Status.from_json(json.dumps(webinterface.receive())), )
def test_receive_unknown_message_type(self): ws_client = WSClient() ws_client.send_and_consume( 'websocket.receive', path='/commands', content={'text': Status.ok({ 'method': '' }).to_json()}, ) self.assertIsNone(ws_client.receive())
def test_ws_message(self): client = WSClient() client.send_and_consume('websocket.receive', text={'event': 'ConnectionEstablished', 'socketId': '54'}) self.assertIsNone(client.receive()) client.send_and_consume('websocket.receive', text={'event': 'fetchCurrentPort'}) receive = client.receive()["data"] self.assertEqual(receive, settings.PORT) client.send_and_consume('websocket.receive', text={'event': 'getPublicIPaddress'}) receive = client.receive()["data"] self.assertEqual(receive, settings.HOST_NAME)
def test_authentication_with_token_success(self): client = WSClient() resident = ResidentFactory.create() token = TokenFactory.create(user=resident) client.send_and_consume('websocket.connect', path='/accounts/user/{0}/'.format(token.key), check_accept=False) received = client.receive(json=False) self.assertEqual(received, {"accept": True})
def test_websocket_close_exception_close_code(self): def consumer(message): raise WebsocketCloseException(3001) client = WSClient(reply_channel='daphne.response.1') with apply_routes(route('websocket.receive', consumer)): client.send_and_consume('websocket.receive') self.assertEqual( client.get_next_message(client.reply_channel).content, {'close': 3001})
def setUp(self): self.client = WSClient() self.member = UserFactory() self.other_member = UserFactory() self.unrelated_user = UserFactory() self.group = GroupFactory(members=[self.member, self.other_member]) pathlib.Path(settings.MEDIA_ROOT).mkdir(exist_ok=True) copyfile(os.path.join(os.path.dirname(__file__), './photo.jpg'), os.path.join(settings.MEDIA_ROOT, 'photo.jpg')) self.member.photo = 'photo.jpg' self.member.save() self.other_member.photo = 'photo.jpg' self.other_member.save()
def test_channel_socket_exception(self): class MyChannelSocketException(ChannelSocketException): def run(self, message): message.reply_channel.send({'text': 'error'}) def consumer(message): raise MyChannelSocketException client = WSClient() with apply_routes(route('websocket.receive', consumer)): client.send_and_consume('websocket.receive') self.assertEqual(client.receive(json=False), 'error')
def test_receive_for_authenticated_success(self): client = WSClient() resident = ResidentFactory.create() token = TokenFactory.create(user=resident) client.send_and_consume( 'websocket.connect', path='/accounts/user/{0}/'.format(token.key), ) Group('user-{0}'.format(resident.pk)).send({'text': 'ok'}, immediately=True) self.assertEqual(client.receive(json=False), 'ok')
def test_trigger_outbound_update(self): class TestBinding(WebsocketBinding): model = User stream = 'test' fields = ['__all__'] @classmethod def group_names(cls, instance): return ["users2"] def has_permission(self, user, action, pk): return True # Make model and clear out pending sends user = User.objects.create(username='******', email='*****@*****.**') client = WSClient() client.join_group('users2') user.username = '******' 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'], '*****@*****.**') 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_notification(self): client = WSClient() client.send_and_consume('websocket.connect', path='/knocker/en/') post = Post.objects.create( title='first post', slug='first-post', ) notification = client.receive() self.assertEqual(notification['title'], 'new {0}'.format(post._meta.verbose_name)) self.assertEqual(notification['message'], post.title) self.assertEqual(notification['url'], post.get_absolute_url()) # This model does not send notifications NoKnockPost.objects.create( title='first post', slug='first-post', ) self.assertIsNone(client.receive())
def test_cookies(self): client = WSClient() client.set_cookie('foo', 'not-bar') client.set_cookie('foo', 'bar') client.set_cookie('qux', 'qu;x') # Django's interpretation of the serialized cookie. cookie_dict = parse_cookie(client.headers['cookie'].decode('ascii')) self.assertEqual(client.get_cookies(), cookie_dict) self.assertEqual({'foo': 'bar', 'qux': 'qu;x', 'sessionid': client.get_cookies()['sessionid']}, cookie_dict)
def test_trigger_outbound_create_exclude(self): class TestBinding(WebsocketBinding): model = User stream = 'test' exclude = ['first_name', 'last_name'] @classmethod def group_names(cls, instance): return ["users_exclude"] def has_permission(self, user, action, pk): return True with apply_routes([route('test', TestBinding.consumer)]): client = WSClient() client.join_group('users_exclude') user = User.objects.create(username='******', email='*****@*****.**') 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('model' in received['payload']) self.assertTrue('pk' in received['payload']) self.assertFalse('last_name' in received['payload']['data']) self.assertFalse('first_name' in received['payload']['data']) 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'], '*****@*****.**') self.assertEqual(received['payload']['data']['username'], 'test') self.assertEqual(received['payload']['data']['password'], '') received = client.receive() self.assertIsNone(received)
def test_inbound_delete(self): user = User.objects.create(username='******', email='*****@*****.**') class UserBinding(WebsocketBinding): model = User stream = 'users' fields = ['username', ] @classmethod def group_names(cls, instance): return ['users_outbound'] def has_permission(self, user, action, pk): return True class Demultiplexer(WebsocketDemultiplexer): consumers = { 'users': UserBinding.consumer, } groups = ['inbound'] with apply_routes([Demultiplexer.as_route(path='/')]): client = WSClient() client.send_and_consume('websocket.connect', path='/') client.send_and_consume('websocket.receive', path='/', text={ 'stream': 'users', 'payload': {'action': DELETE, 'pk': user.pk} }) self.assertIsNone(User.objects.filter(pk=user.pk).first()) self.assertIsNone(client.receive())
def test_inbound_update(self): user = User.objects.create(username='******', email='*****@*****.**') class UserBinding(WebsocketBinding): model = User stream = 'users' fields = ['username', ] @classmethod def group_names(cls, instance): return ['users_outbound'] def has_permission(self, user, action, pk): return True class Demultiplexer(WebsocketDemultiplexer): consumers = { 'users': UserBinding.consumer, } groups = ['inbound'] with apply_routes([Demultiplexer.as_route(path='/')]): client = WSClient() client.send_and_consume('websocket.connect', path='/') client.send_and_consume('websocket.receive', path='/', text={ 'stream': 'users', 'payload': {'action': UPDATE, 'pk': user.pk, 'data': {'username': '******'}} }) user = User.objects.get(pk=user.pk) self.assertEqual(user.username, 'test_inbound') self.assertEqual(user.email, '*****@*****.**') # trying change field that not in binding fields client.send_and_consume('websocket.receive', path='/', text={ 'stream': 'users', 'payload': {'action': UPDATE, 'pk': user.pk, 'data': {'email': '*****@*****.**'}} }) user = User.objects.get(pk=user.pk) self.assertEqual(user.username, 'test_inbound') self.assertEqual(user.email, '*****@*****.**') self.assertIsNone(client.receive())
def test_get_params_with_consumer(self): client = WSClient(ordered=True) def consumer(message): message.content['method'] = 'FAKE' message.reply_channel.send({'text': dict(AsgiRequest(message).GET)}) with apply_routes([route('websocket.receive', consumer, path=r'^/test'), route('websocket.connect', consumer, path=r'^/test')]): path = '/test?key1=val1&key2=val2&key1=val3' client.send_and_consume('websocket.connect', path=path, check_accept=False) self.assertDictEqual(client.receive(), {'key2': ['val2'], 'key1': ['val1', 'val3']}) client.send_and_consume('websocket.receive', path=path) self.assertDictEqual(client.receive(), {})
def test_ordering(self): client = WSClient(ordered=True) @enforce_ordering def consumer(message): message.reply_channel.send({'text': message['text']}) with apply_routes(route('websocket.receive', consumer)): client.send_and_consume('websocket.receive', text='1') # order = 0 client.send_and_consume('websocket.receive', text='2') # order = 1 client.send_and_consume('websocket.receive', text='3') # order = 2 self.assertEqual(client.receive(), 1) self.assertEqual(client.receive(), 2) self.assertEqual(client.receive(), 3)
def test_inbound_create(self): self.assertEqual(User.objects.all().count(), 0) class UserBinding(WebsocketBinding): model = User stream = 'users' fields = ['username', 'email', 'password', 'last_name'] @classmethod def group_names(cls, instance): return ['users_outbound'] def has_permission(self, user, action, pk): return True class Demultiplexer(WebsocketDemultiplexer): consumers = { 'users': UserBinding.consumer, } groups = ['inbound'] with apply_routes([Demultiplexer.as_route(path='/')]): client = WSClient() client.send_and_consume('websocket.connect', path='/') client.send_and_consume('websocket.receive', path='/', text={ 'stream': 'users', 'payload': { 'action': CREATE, 'data': {'username': '******', 'email': 'test@user_steam.com'}, }, }) self.assertEqual(User.objects.all().count(), 1) user = User.objects.all().first() self.assertEqual(user.username, 'test_inbound') self.assertEqual(user.email, 'test@user_steam.com') self.assertIsNone(client.receive())
def test_ws_connect(self): client = WSClient() client.send_and_consume('websocket.connect') self.assertIsNone(client.receive())
def setUp(self): super(ResourceBindingTestCase, self).setUp() self.client = WSClient()
def test_connect(self): client = WSClient() client.send_and_consume('websocket.connect', path='/knocker/en/') self.assertIsNone(client.receive())
class ResourceBindingTestCase(ChannelTestCase): def setUp(self): super(ResourceBindingTestCase, self).setUp() self.client = WSClient() def _send_and_consume(self, channel, data): """Helper that sends and consumes message and returns the next message.""" self.client.send_and_consume(force_text(channel), data) return self._get_next_message() def _get_next_message(self): msg = self.client.get_next_message(self.client.reply_channel) return json.loads(msg['text']) def _build_message(self, stream, payload): return {"text": json.dumps({"stream": stream, "payload": payload}), "path": "/"} def test_create(self): """Integration that asserts routing a message to the create channel. Asserts response is correct and an object is created. """ json_content = self._send_and_consume("websocket.receive", self._build_message("testmodel", { 'action': 'create', 'pk': None, 'request_id': 'client-request-id', 'data': {'name': 'some-thing'} })) # it should create an object self.assertEqual(TestModel.objects.count(), 1) expected = { 'action': 'create', 'data': TestModelSerializer(TestModel.objects.first()).data, 'errors': [], 'request_id': 'client-request-id', 'response_status': 201 } # it should respond with the serializer.data self.assertEqual(json_content['payload'], expected) def test_create_failure(self): """Integration that asserts error handling of a message to the create channel.""" json_content = self._send_and_consume('websocket.receive', self._build_message("testmodel", { 'action': 'create', 'pk': None, 'request_id': 'client-request-id', 'data': {}, })) # it should not create an object self.assertEqual(TestModel.objects.count(), 0) expected = { 'action': 'create', 'data': None, 'request_id': 'client-request-id', 'errors': [{'name': ['This field is required.']}], 'response_status': 400 } # it should respond with an error self.assertEqual(json_content['payload'], expected) def test_delete(self): instance = TestModel.objects.create(name='test-name') json_content = self._send_and_consume('websocket.receive', self._build_message('testmodel', { 'action': 'delete', 'pk': instance.id, 'request_id': 'client-request-id', })) expected = { 'action': 'delete', 'errors': [], 'data': {}, 'request_id': 'client-request-id', 'response_status': 200 } self.assertEqual(json_content['payload'], expected) self.assertEqual(TestModel.objects.count(), 0) def test_delete_failure(self): json_content = self._send_and_consume('websocket.receive', self._build_message('testmodel', { 'action': 'delete', 'pk': -1, 'request_id': 'client-request-id' })) expected = { 'action': 'delete', 'errors': ['Not found.'], 'data': None, 'request_id': 'client-request-id', 'response_status': 404 } self.assertEqual(json_content['payload'], expected) def test_list(self): for n in range(api_settings.DEFAULT_PAGE_SIZE + 1): TestModel.objects.create(name='Name-{}'.format(str(n))) json_content = self._send_and_consume('websocket.receive', self._build_message('testmodel', { 'action': 'list', 'request_id': 'client-request-id', 'data': None, })) self.assertEqual(len(json_content['payload']['data']), api_settings.DEFAULT_PAGE_SIZE) json_content = self._send_and_consume('websocket.receive', self._build_message('testmodel', { 'action': 'list', 'request_id': 'client-request-id', 'data': { 'page': 2 } })) self.assertEqual(len(json_content['payload']['data']), 1) self.assertEqual('client-request-id', json_content['payload']['request_id']) def test_retrieve(self): instance = TestModel.objects.create(name="Test") json_content = self._send_and_consume('websocket.receive', self._build_message('testmodel', { 'action': 'retrieve', 'pk': instance.id, 'request_id': 'client-request-id' })) expected = { 'action': 'retrieve', 'data': TestModelSerializer(instance).data, 'errors': [], 'response_status': 200, 'request_id': 'client-request-id' } self.assertTrue(json_content['payload'] == expected) def test_retrieve_404(self): json_content = self._send_and_consume('websocket.receive', self._build_message('testmodel', { 'action': 'retrieve', 'pk': 1, 'request_id': 'client-request-id' })) expected = { 'action': 'retrieve', 'data': None, 'errors': ['Not found.'], 'response_status': 404, 'request_id': 'client-request-id' } self.assertEqual(json_content['payload'], expected) def test_retrieve_invalid_pk_404(self): json_content = self._send_and_consume('websocket.receive', self._build_message('testmodel', { 'action': 'retrieve', 'pk': 'invalid-pk-value', 'request_id': 'client-request-id' })) expected = { 'action': 'retrieve', 'data': None, 'errors': ['Not found.'], 'response_status': 404, 'request_id': 'client-request-id' } self.assertEqual(json_content['payload'], expected) def test_subscribe(self): json_content = self._send_and_consume('websocket.receive', self._build_message("testmodel",{ 'action': 'subscribe', 'data': { 'action': 'create' }, 'request_id': 'client-request-id' })) expected_response = { 'action': 'subscribe', 'request_id': 'client-request-id', 'data': { 'action': 'create' }, 'errors': [], 'response_status': 200 } self.assertEqual(json_content['payload'], expected_response) # it should be on the create group instance = TestModel.objects.create(name='test-name') expected = { 'action': 'create', 'data': TestModelSerializer(instance).data, 'model': 'tests.testmodel', 'pk': instance.id } actual = self._get_next_message() self.assertEqual(expected, actual['payload']) def test_subscribe_failure(self): json_content = self._send_and_consume('websocket.receive', self._build_message('testmodel', { 'action': 'subscribe', 'data': { }, 'request_id': 'client-request-id' })) expected = { 'action': 'subscribe', 'data': None, 'errors': ['action required'], 'request_id': 'client-request-id', 'response_status': 400 } self.assertEqual(expected, json_content['payload']) def test_update(self): instance = TestModel.objects.create(name='some-test') json_content = self._send_and_consume('websocket.receive', self._build_message('testmodel',{ 'action': 'update', 'pk': instance.id, 'data': {'name': 'some-value'}, 'request_id': 'client-request-id' })) instance.refresh_from_db() expected = { 'action': 'update', 'errors': [], 'data': TestModelSerializer(instance).data, 'response_status': 200, 'request_id': 'client-request-id' } self.assertEqual(json_content['payload'], expected) def test_update_failure(self): instance = TestModel.objects.create(name='some-test') json_content = self._send_and_consume('websocket.receive', self._build_message('testmodel', { 'action': 'update', 'pk': -1, 'data': {'name': 'some-value'}, 'request_id': 'client-request-id' })) expected = { 'data': None, 'action': 'update', 'errors': ['Not found.'], 'response_status': 404, 'request_id': 'client-request-id' } self.assertEqual(json_content['payload'], expected) def test_list_action(self): json_content = self._send_and_consume('websocket.receive', self._build_message('testmodel',{ 'action': 'test_list', 'pk': None, 'data': {}, 'request_id': 'client-request-id', })) expected = { 'action': 'test_list', 'errors': [], 'data': 'some data', 'response_status': 200, 'request_id': 'client-request-id' } self.assertEqual(json_content['payload'], expected) def test_detail_action(self): instance = TestModel.objects.create(name='some-test') json_content = self._send_and_consume('websocket.receive', self._build_message('testmodel',{ 'action': 'test_detail', 'pk': instance.id, 'data': {}, 'request_id': 'client-request-id' })) expected = { 'action': 'test_detail', 'errors': [], 'data': instance.name, 'response_status': 200, 'request_id': 'client-request-id' } self.assertEqual(json_content['payload'], expected) def test_named_list_action(self): json_content = self._send_and_consume('websocket.receive', self._build_message('testmodel',{ 'action': 'named_list', 'pk': None, 'data': {}, 'request_id': 'client-request-id', })) expected = { 'action': 'named_list', 'errors': [], 'data': 'some data', 'response_status': 200, 'request_id': 'client-request-id' } self.assertEqual(json_content['payload'], expected) def test_named_detail_action(self): instance = TestModel.objects.create(name='some-test') json_content = self._send_and_consume('websocket.receive', self._build_message('testmodel',{ 'action': 'named_detail', 'pk': instance.id, 'data': {}, 'request_id': 'client-request-id' })) expected = { 'action': 'named_detail', 'errors': [], 'data': instance.name, 'response_status': 200, 'request_id': 'client-request-id' } self.assertEqual(json_content['payload'], expected) def test_bad_permission_reply(self): mock_has_perm = Mock() mock_has_perm.return_value = False with patch.object(TestModelResourceBinding, 'has_permission', mock_has_perm): json_content = self._send_and_consume('websocket.receive', self._build_message('testmodel',{ 'action': 'named_detail', 'pk': 546, 'data': {}, 'request_id': 'client-request-id' })) expected = { 'action': 'named_detail', 'errors': ['Permission Denied'], 'data': None, 'response_status': 401, 'request_id': 'client-request-id' } self.assertEqual(json_content['payload'], expected) self.assertEqual(mock_has_perm.called, True) def test_bad_action_reply(self): json_content = self._send_and_consume('websocket.receive', self._build_message('testmodel',{ 'action': 'named_detail_not_set', 'pk': 123, 'data': {}, 'request_id': 'client-request-id' })) expected = { 'action': 'named_detail_not_set', 'errors': ['Invalid Action'], 'data': None, 'response_status': 400, 'request_id': 'client-request-id' } self.assertEqual(json_content['payload'], expected) def test_is_authenticated_permission(self): with patch.object(TestModelResourceBinding, 'permission_classes', (IsAuthenticated,)): content = { 'action': 'test_list', 'pk': None, 'data': {}, 'request_id': 'client-request-id', } json_content = self._send_and_consume('websocket.receive', self._build_message('testmodel', content)) # It should block the request self.assertEqual(json_content['payload']['response_status'], 401) user = User.objects.create(username="******", password="******") self.client.force_login(user) self.client._session_cookie = True json_content = self._send_and_consume('websocket.receive', self._build_message('testmodel', content)) self.assertEqual(json_content['payload']['response_status'], 200)