Exemplo n.º 1
0
    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())),
        )
Exemplo n.º 2
0
    def test_room_join_with_wrong_room_id(self):
        client = WSClient()
        client.login(username='******', password='******')
        client.send_and_consume('websocket.connect', path='/api/websocket/')
        client.receive()

        data = {
            'room_id': 'room3',
        }

        req = request('room-join', data, nonce='test')

        client.send_and_consume('websocket.receive',
                                req,
                                path='/api/websocket/')

        room_join_consumer(self.get_next_message('room-join'))

        response = client.receive()

        player_room_cache = cache.get('player-room:skystar1')

        self.assertFalse(response['success'])
        self.assertEqual(response['error']['reason'], 'Room does not exist')
        self.assertIsNone(player_room_cache)
Exemplo n.º 3
0
    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())),
        )
Exemplo n.º 4
0
    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())
Exemplo n.º 5
0
    def test_receives_messages(self):
        client = WSClient()
        user = UserFactory()
        author = UserFactory()

        # join a conversation
        conversation = ConversationFactory()
        conversation.join(user)
        conversation.join(author)

        # login and connect
        client.force_login(user)
        client.send_and_consume('websocket.connect', path='/')

        # add a message to the conversation
        message = ConversationMessage.objects.create(conversation=conversation, content='yay', author=author)

        # hopefully they receive it!
        response = client.receive(json=True)
        response['payload']['created_at'] = parse(response['payload']['created_at'])
        self.assertEqual(response, {
            'topic': 'conversations:message',
            'payload': {
                'id': message.id,
                'content': message.content,
                'author': message.author.id,
                'conversation': conversation.id,
                'created_at': message.created_at
            }
        })
Exemplo n.º 6
0
    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())),
        )
Exemplo n.º 7
0
    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())),
        )
Exemplo n.º 8
0
    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())
Exemplo n.º 9
0
    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())),
        )
Exemplo n.º 10
0
    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())),
        )
Exemplo n.º 11
0
    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())),
        )
Exemplo n.º 12
0
class FinishedPickupReceiverTest(ChannelTestCase):
    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_feedback_possible_and_history(self):
        self.pickup.date = timezone.now() - relativedelta(days=1)
        self.pickup.save()

        self.client.force_login(self.member)
        self.client.send_and_consume('websocket.connect', path='/')
        call_command('process_finished_pickup_dates')

        response = self.client.receive(json=True)
        self.assertEqual(response['topic'], 'history:history')
        self.assertEqual(response['payload']['typus'], 'PICKUP_DONE')

        response = self.client.receive(json=True)
        self.assertEqual(response['topic'], 'pickups:feedback_possible')
        self.assertEqual(response['payload']['id'], self.pickup.id)

        self.assertIsNone(self.client.receive(json=True))
Exemplo n.º 13
0
 def test_receive_no_content(self):
     ws_client = WSClient()
     ws_client.send_and_consume(
         'websocket.receive',
         path='/commands',
     )
     self.assertIsNone(ws_client.receive())
Exemplo n.º 14
0
    def test_connection_session_duplication(self):
        first_client = WSClient()
        second_client = WSClient()

        first_client.login(username='******', password='******')
        second_client.login(username='******', password='******')

        first_client.send_and_consume('websocket.connect',
                                      path='/api/websocket/')
        session_cache = cache.get('session:skystar')
        self.assertIsNotNone(session_cache)

        second_client.send_and_consume('websocket.connect',
                                       path='/api/websocket/')

        response = second_client.receive()

        self.assertIn('event', response)
        self.assertEqual(response['data']['reason'],
                         'Session duplication detected')
        self.assertEqual(response['data']['type'], 'connection-dup')

        response = second_client.receive()
        self.assertEqual(response['close'], 4001)

        self.assertEqual(cache.get('session:skystar'), session_cache)
Exemplo n.º 15
0
    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())),
        )
Exemplo n.º 16
0
    def test_simple_as_route_method(self):
        class WebsocketConsumer(websockets.WebsocketConsumer):
            def connect(self, message, **kwargs):
                self.message.reply_channel.send({'accept': True})
                self.send(text=message.get('order'))

        routes = [
            WebsocketConsumer.as_route(attrs={"strict_ordering": True},
                                       path='^/path$'),
            WebsocketConsumer.as_route(path='^/path/2$'),
        ]

        self.assertIsNot(routes[0].consumer, WebsocketConsumer)
        self.assertIs(routes[1].consumer, WebsocketConsumer)

        with apply_routes(routes):
            client = WSClient()

            client.send('websocket.connect', {'path': '/path', 'order': 1})
            client.send('websocket.connect', {'path': '/path', 'order': 0})
            client.consume('websocket.connect', check_accept=False)
            client.consume('websocket.connect')
            self.assertEqual(client.receive(json=False), 0)
            client.consume('websocket.connect')
            self.assertEqual(client.receive(json=False), 1)

            client.send_and_consume('websocket.connect', {
                'path': '/path/2',
                'order': 'next'
            })
            self.assertEqual(client.receive(json=False), 'next')
Exemplo n.º 17
0
    def test_room_join_with_password(self):
        client = WSClient()
        client.login(username='******', password='******')
        client.send_and_consume('websocket.connect', path='/api/websocket/')
        client.receive()

        data = {'room_id': 'room2', 'password': '******'}

        req = request('room-join', data, nonce='test')

        client.send_and_consume('websocket.receive',
                                req,
                                path='/api/websocket/')

        room_join_consumer(self.get_next_message('room-join'))

        response = client.receive()

        room_cache = cache.get('room:room2')
        player_room_cache = cache.get('player-room:skystar1')

        self.assertTrue(response['success'])

        result = response['result']

        self.assertEqual(result['room_id'], 'room2')
        self.assertEqual(result['room_id'], player_room_cache)
        self.assertEqual(len(room_cache['players']), 1)
        self.assertEqual(room_cache['players'][0]['username'], 'skystar1')
Exemplo n.º 18
0
    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"
                    },
                })
Exemplo n.º 19
0
    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()
Exemplo n.º 20
0
    def test_game_server(self):
        client = WSClient()

        with apply_routes([
                GameConsumer.as_route(
                    path=r"^/minesweeper/stream/(?P<game_id>[^/]+)")
        ]):
            client.send_and_consume('websocket.connect',
                                    path='/minesweeper/stream/1')
            user_map = np.array(client.receive()['data'])
            self.assertEqual(client.receive()['type'], 'game_change')
            self.assertTrue(
                np.array_equal(user_map, np.full(user_map.shape, -2)))

            client.send_and_consume('websocket.receive',
                                    text=json.dumps({
                                        'type': 'reveal',
                                        'data': {
                                            'x': 0,
                                            'y': 0,
                                        }
                                    }),
                                    path='/minesweeper/stream/1')
            self.assertEqual(client.receive()['type'], 'game_change')

            client.send_and_consume('websocket.receive',
                                    text=json.dumps({
                                        'type': 'mark',
                                        'data': {
                                            'x': 0,
                                            'y': 0,
                                        }
                                    }),
                                    path='/minesweeper/stream/1')
            self.assertEqual(client.receive()['type'], 'game_change')

            client.send_and_consume('websocket.receive',
                                    text=json.dumps({
                                        'type': 'restart',
                                        'data': {
                                            'x': 0,
                                            'y': 0,
                                        }
                                    }),
                                    path='/minesweeper/stream/1')
            self.assertEqual(client.receive()['type'], 'game_change')

            client.send_and_consume('websocket.receive',
                                    text=json.dumps({
                                        'type': 'reveal_multiple',
                                        'data': {
                                            'points': [{
                                                'x': 0,
                                                'y': 0,
                                            }],
                                        }
                                    }),
                                    path='/minesweeper/stream/1')
            self.assertEqual(client.receive()['type'], 'game_change')
Exemplo n.º 21
0
    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})
Exemplo n.º 22
0
    def test_receives_messages(self):
        self.maxDiff = None
        client = WSClient()
        user = UserFactory()
        author_client = WSClient()
        author = UserFactory()

        # join a conversation
        conversation = ConversationFactory()
        conversation.join(user)
        conversation.join(author)

        # login and connect
        client.force_login(user)
        client.send_and_consume('websocket.connect', path='/')
        author_client.force_login(author)
        author_client.send_and_consume('websocket.connect', path='/')

        # add a message to the conversation
        message = ConversationMessage.objects.create(conversation=conversation, content='yay', author=author)

        # hopefully they receive it!
        response = client.receive(json=True)
        parse_dates(response)
        self.assertEqual(
            response,
            make_conversation_message_broadcast(message)
        )

        # and they should get an updated conversation object
        response = client.receive(json=True)
        parse_dates(response)
        del response['payload']['participants']
        self.assertEqual(
            response,
            make_conversation_broadcast(conversation, unread_message_count=1)
        )

        # author should get message & updated conversations object too
        response = author_client.receive(json=True)
        parse_dates(response)
        self.assertEqual(
            response,
            make_conversation_message_broadcast(message, is_editable=True)
        )

        # Author receives more recent `update_at` time,
        # because their `seen_up_to` status is set after sending the message.
        author_participant = conversation.conversationparticipant_set.get(user=author)
        response = author_client.receive(json=True)
        parse_dates(response)
        del response['payload']['participants']
        self.assertEqual(
            response,
            make_conversation_broadcast(conversation, seen_up_to=message.id, updated_at=author_participant.updated_at)
        )
Exemplo n.º 23
0
class PickupDateReceiverTests(ChannelTestCase):
    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)

    def test_receive_pickup_changes(self):
        self.client.force_login(self.member)
        self.client.send_and_consume('websocket.connect', path='/')

        # change property
        date = faker.future_datetime(end_date='+30d', tzinfo=timezone.utc)
        self.pickup.date = date
        self.pickup.save()

        response = self.client.receive(json=True)
        self.assertEqual(response['topic'], 'pickups:pickupdate')
        self.assertEqual(parse(response['payload']['date']), date)

        # join
        self.pickup.collectors.add(self.member)

        response = self.client.receive(json=True)
        self.assertEqual(response['topic'], 'pickups:pickupdate')
        self.assertEqual(response['payload']['collector_ids'], [self.member.id])

        response = self.client.receive(json=True)
        self.assertEqual(response['topic'], 'conversations:conversation')
        self.assertEqual(response['payload']['participants'], [self.member.id])

        # leave
        self.pickup.collectors.remove(self.member)

        response = self.client.receive(json=True)
        self.assertEqual(response['topic'], 'pickups:pickupdate')
        self.assertEqual(response['payload']['collector_ids'], [])

        response = self.client.receive(json=True)
        self.assertEqual(response['topic'], 'conversations:leave')

        self.assertIsNone(self.client.receive(json=True))

    def test_receive_pickup_delete(self):
        self.client.force_login(self.member)
        self.client.send_and_consume('websocket.connect', path='/')

        self.pickup.deleted = True
        self.pickup.save()

        response = self.client.receive(json=True)
        self.assertEqual(response['topic'], 'pickups:pickupdate_deleted')
        self.assertEqual(response['payload']['id'], self.pickup.id)

        self.assertIsNone(self.client.receive(json=True))
Exemplo n.º 24
0
    def test_websocket(self):
        client = WSClient()

        client.send_and_consume('websocket.connect', path='/test/')
        self.assertIsNone(client.receive())

        client.send_and_consume('websocket.receive',
                                text={'message': 'echo'},
                                path='/test/')
        self.assertEqual(client.receive(), {'message': 'echo'})
Exemplo n.º 25
0
    def test_connection_not_authenticated(self):
        client = WSClient()
        client.send_and_consume('websocket.connect', path='/api/websocket/')
        response = client.receive()
        self.assertIn('event', response)
        self.assertEqual(response['data']['reason'], 'Not authenticated')
        self.assertEqual(response['data']['type'], 'connection-auth')

        response = client.receive()
        self.assertEqual(response['close'], 4000)
Exemplo n.º 26
0
 def test_adds_subscription(self):
     client = WSClient()
     user = UserFactory()
     client.force_login(user)
     self.assertEqual(
         ChannelSubscription.objects.filter(user=user).count(), 0)
     client.send_and_consume('websocket.connect', path='/')
     self.assertEqual(
         ChannelSubscription.objects.filter(user=user).count(), 1,
         'Did not add subscription')
Exemplo n.º 27
0
    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())
Exemplo n.º 28
0
    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})
Exemplo n.º 29
0
    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})
Exemplo n.º 30
0
    def test_saves_reply_channel(self):
        client = WSClient()
        user = UserFactory()
        client.force_login(user)
        client.send_and_consume('websocket.connect', path='/')
        subscription = ChannelSubscription.objects.filter(user=user).first()
        self.assertIsNotNone(subscription.reply_channel)

        # send a message on it
        Channel(subscription.reply_channel).send({'message': 'hey! whaatsup?'})
        self.assertEqual(client.receive(json=True),
                         {'message': 'hey! whaatsup?'})
Exemplo n.º 31
0
    def test_connection_authenticated(self):
        self.assertIsNone(cache.get('session:skystar'))

        client = WSClient()
        client.login(username='******', password='******')
        client.send_and_consume('websocket.connect', path='/api/websocket/')

        self.assertIsNotNone(cache.get('session:skystar'))

        response = client.receive()

        self.assertEqual(response['event'], 'connected')
Exemplo n.º 32
0
    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(), {})
Exemplo n.º 33
0
    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')
Exemplo n.º 34
0
    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')
Exemplo n.º 35
0
    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)
Exemplo n.º 36
0
    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())
Exemplo n.º 37
0
    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())
Exemplo n.º 38
0
    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)
Exemplo n.º 39
0
    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())
Exemplo n.º 40
0
 def test_ws_connect(self):
     client = WSClient()
     client.send_and_consume('websocket.connect')
     self.assertIsNone(client.receive())
Exemplo n.º 41
0
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)
Exemplo n.º 42
0
    def test_connect(self):
        client = WSClient()

        client.send_and_consume('websocket.connect', path='/knocker/en/')
        self.assertIsNone(client.receive())