def test_leave(self): user = UserFactory() conversation = ConversationFactory(participants=[ user, ]) self.assertIn(user, conversation.participants.all()) conversation.leave(user) self.assertNotIn(user, conversation.participants.all())
def setUp(self): self.conversation = ConversationFactory() self.user = UserFactory() self.user2 = UserFactory() self.conversation.join(self.user) self.conversation.join(self.user2) self.participant = ConversationParticipant.objects.get( conversation=self.conversation, user=self.user)
def test_reaction_create(self): user = UserFactory() conversation = ConversationFactory() conversation.sync_users([user]) message = conversation.messages.create(author=user, content='hello') message.reactions.create(message=message, user=user, name='tada') self.assertEqual( ConversationMessageReaction.objects.filter(message=message, user=user).count(), 1)
def test_create_message(self): conversation = ConversationFactory() conversation.join(self.participant1) self.client.force_login(user=self.participant1) data = {'conversation': conversation.id, 'content': 'a nice message'} response = self.client.post('/api/messages/', data, format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED, response.data) self.assertEqual(response.data['content'], data['content']) self.assertEqual(conversation.messages.first().content, data['content'])
def test_mark_seen_up_to_fails_for_message_in_other_conversation(self): conversation = ConversationFactory() conversation.join(self.user) message = conversation.messages.create(author=self.user, content='yay') self.client.force_login(user=self.user) data = {'seen_up_to': message.id} response = self.client.post('/api/conversations/{}/mark/'.format(self.conversation.id), data, format='json') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data['seen_up_to'][0], 'Must refer to a message in the conversation')
class ReceiverPushTests(ChannelTestCase): def setUp(self): self.user = UserFactory() self.author = UserFactory() self.token = faker.uuid4() self.content = faker.text() # join a conversation self.conversation = ConversationFactory() self.conversation.join(self.user) self.conversation.join(self.author) # add a push subscriber PushSubscription.objects.create(user=self.user, token=self.token, platform=PushSubscriptionPlatform.ANDROID) def test_sends_to_push_subscribers(self, m): def check_json_data(request): data = json.loads(request.body.decode('utf-8')) self.assertEqual(data['notification']['title'], self.author.display_name) self.assertEqual(data['notification']['body'], self.content) self.assertEqual(data['to'], self.token) return True m.post(FCMApi.FCM_END_POINT, json={}, additional_matcher=check_json_data) # add a message to the conversation ConversationMessage.objects.create(conversation=self.conversation, content=self.content, author=self.author) # TODO: add back in once https://github.com/yunity/karrot-frontend/issues/770 is implemented # def test_does_not_send_push_notification_if_active_channel_subscription(self, m): # # add a channel subscription to prevent the push being sent # ChannelSubscription.objects.create(user=self.user, reply_channel='foo') # # # add a message to the conversation # ConversationMessage.objects.create(conversation=self.conversation, content=self.content, author=self.author) # # # if it sent a push message, the requests mock would complain there is no matching request... def test_send_push_notification_if_channel_subscription_is_away(self, m): def check_json_data(request): data = json.loads(request.body.decode('utf-8')) self.assertEqual(data['notification']['title'], self.author.display_name) self.assertEqual(data['notification']['body'], self.content) self.assertEqual(data['to'], self.token) return True m.post(FCMApi.FCM_END_POINT, json={}, additional_matcher=check_json_data) # add a channel subscription to prevent the push being sent ChannelSubscription.objects.create(user=self.user, reply_channel='foo', away_at=timezone.now()) # add a message to the conversation ConversationMessage.objects.create(conversation=self.conversation, content=self.content, author=self.author)
def test_reaction_remove(self): # setup user = UserFactory() conversation = ConversationFactory() conversation.sync_users([user]) message = conversation.messages.create(author=user, content='hello') # creating reaction message.reactions.create(message=message, user=user, name='tada') instance = ConversationMessageReaction.objects.get(message=message, user=user, name='tada') # remove reaction instance.delete() self.assertEqual(ConversationMessageReaction.objects.filter(message=message, user=user).count(), 0)
def setUp(self): self.user = UserFactory() self.author = UserFactory() self.token = faker.uuid4() self.content = faker.text() # join a conversation self.conversation = ConversationFactory() self.conversation.join(self.user) self.conversation.join(self.author) # add a push subscriber PushSubscription.objects.create(user=self.user, token=self.token, platform=PushSubscriptionPlatform.ANDROID)
def tests_receive_message_on_leave(self): user = UserFactory() # join a conversation conversation = ConversationFactory(participants=[ user, ]) # login and connect client = self.connect_as(user) conversation.leave(user) self.assertEqual(client.messages[0], {'topic': 'conversations:leave', 'payload': {'id': conversation.id}})
def test_other_participants_receive_update_on_leave(self): user = UserFactory() leaving_user = UserFactory() # join a conversation conversation = ConversationFactory(participants=[user, leaving_user]) # login and connect client = self.connect_as(user) conversation.leave(leaving_user) response = client.messages[0] self.assertEqual(response['topic'], 'conversations:conversation') self.assertEqual(response['payload']['participants'], [user.id])
def test_edit_message(self): conversation = ConversationFactory() conversation.join(self.participant1) self.client.force_login(user=self.participant1) data = {'conversation': conversation.id, 'content': 'a nice message'} response = self.client.post('/api/messages/', data, format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED, response.data) self.assertEqual(response.data['content'], data['content']) data['content'] = 'a nicer message' response = self.client.post('/api/messages/edit', data, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(response.data['content'], data['content']) self.assertEqual(conversation.messages.first().content, data['content']) self.assertEqual(conversation.messages.first().modified_at, parse(response.data['modified_at']), response.data) self.assertEqual(conversation.messages.first().id, response.data['id']) self.assertEqual(conversation.messages.first().author.id, response.data['author'])
def test_receive_reaction_update(self): self.maxDiff = None author, user, reaction_user = [UserFactory() for _ in range(3)] conversation = ConversationFactory(participants=[author, user, reaction_user]) message = ConversationMessage.objects.create(conversation=conversation, content='yay', author=author) # login and connect client = self.connect_as(user) # create reaction ConversationMessageReaction.objects.create( message=message, user=reaction_user, name='carrot', ) # check if conversation update was received response = client.messages[0] parse_dates(response) self.assertEqual( response, make_conversation_message_broadcast(message, reactions=[{ 'name': 'carrot', 'user': reaction_user.id }]) )
def test_message_create(self): user = UserFactory() conversation = ConversationFactory(participants=[ user, ]) conversation.messages.create(author=user, content='yay') self.assertEqual(ConversationMessage.objects.filter(author=user).count(), 1)
def test_filter_by_conversation(self): more_users = [UserFactory() for _ in range(3)] + [self.user] another_conversation = ConversationFactory(participants=more_users) self.client.force_login(user=self.user) response = self.get_results('/api/users-info/?conversation={}'.format( another_conversation.id)) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), len(more_users))
def setUp(self): self.participant1 = UserFactory() self.participant2 = UserFactory() self.participant3 = UserFactory() self.not_participant1 = UserFactory() self.not_participant2 = UserFactory() self.not_participant3 = UserFactory() self.conversation1 = ConversationFactory() self.conversation1.sync_users( [self.participant1, self.participant2, self.participant3]) self.conversation1.messages.create(author=self.participant1, content='hello') self.conversation2 = ConversationFactory() self.conversation2.sync_users([self.participant1]) self.conversation2.messages.create(author=self.participant1, content='hello2') self.conversation3 = ConversationFactory() # conversation noone is in
def test_keeps_latest_message_updated(self): user = UserFactory() conversation = ConversationFactory(participants=[user]) message = conversation.messages.create(author=user, content='yay') self.assertEqual(conversation.latest_message, message) message = conversation.messages.create(author=user, content='yay2') self.assertEqual(conversation.latest_message, message)
def test_receives_messages(self): self.maxDiff = None user = UserFactory() author = UserFactory() # join a conversation conversation = ConversationFactory(participants=[user, author]) # login and connect client = self.connect_as(user) author_client = self.connect_as(author) # add a message to the conversation message = ConversationMessage.objects.create(conversation=conversation, content='yay', author=author) # hopefully they receive it! self.assertEqual(len(client.messages), 2, client.messages) response = client.messages[0] parse_dates(response) self.assertEqual(response, make_conversation_message_broadcast(message)) # and they should get an updated conversation object response = client.messages[1] parse_dates(response) del response['payload']['participants'] self.assertEqual( response, make_conversation_broadcast( conversation, unread_message_count=1, updated_at=response['payload']['updated_at'], # TODO fix test )) # author should get message & updated conversations object too response = author_client.messages[0] 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.messages[1] 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))
def setUpClass(cls): super().setUpClass() cls.participant1 = UserFactory() cls.participant2 = UserFactory() cls.participant3 = UserFactory() cls.not_participant1 = UserFactory() cls.not_participant2 = UserFactory() cls.not_participant3 = UserFactory() cls.conversation1 = ConversationFactory() cls.conversation1.sync_users([ cls.participant1, cls.participant2, cls.participant3 ]) cls.conversation1.messages.create(author=cls.participant1, content='hello') cls.conversation2 = ConversationFactory() cls.conversation2.sync_users([ cls.participant1 ]) cls.conversation2.messages.create(author=cls.participant1, content='hello2') cls.conversation3 = ConversationFactory() # conversation noone is in
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 } })
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) )
def setUp(self): self.user = UserFactory() self.author = UserFactory() self.token = faker.uuid4() self.content = faker.text() # join a conversation self.conversation = ConversationFactory(participants=[self.user, self.author]) # add a push subscriber self.subscription = PushSubscription.objects.create( user=self.user, token=self.token, platform=PushSubscriptionPlatform.ANDROID.value, )
def test_conversations_list(self): self.conversation1.messages.create(author=self.participant1, content='yay') self.conversation1.messages.create(author=self.participant1, content='second!') conversation2 = ConversationFactory( participants=[self.participant1, self.participant2]) conversation2.messages.create(author=self.participant1, content='yay') self.client.force_login(user=self.participant1) response = self.client.get('/api/conversations/', format='json') response_conversations = response.data['results']['conversations'] self.assertEqual(response.status_code, status.HTTP_200_OK) # is ordered by latest message first self.assertEqual( [conversation['id'] for conversation in response_conversations], [conversation2.id, self.conversation1.id, self.conversation2.id], )
def test_other_participants_receive_update_on_leave(self): client = WSClient() user = UserFactory() leaving_user = UserFactory() # join a conversation conversation = ConversationFactory() conversation.join(user) conversation.join(leaving_user) # login and connect client.force_login(user) client.send_and_consume('websocket.connect', path='/') conversation.leave(leaving_user) response = client.receive(json=True) self.assertEqual(response['topic'], 'conversations:conversation') self.assertEqual(response['payload']['participants'], [user.id])
def test_sync_users(self): user1 = UserFactory() user2 = UserFactory() user3 = UserFactory() user4 = UserFactory() users = [user1, user2, user3] conversation = ConversationFactory() conversation.join(user1) # should not be added again conversation.join(user4) # should be removed conversation.sync_users(users) self.assertEqual(conversation.participants.count(), 3) self.assertIn(user1, conversation.participants.all()) self.assertIn(user2, conversation.participants.all()) self.assertIn(user3, conversation.participants.all()) self.assertNotIn(user4, conversation.participants.all())
def tests_receive_message_on_leave(self): client = WSClient() user = UserFactory() # join a conversation conversation = ConversationFactory() conversation.join(user) # login and connect client.force_login(user) client.send_and_consume('websocket.connect', path='/') conversation.leave(user) self.assertEqual(client.receive(json=True), { 'topic': 'conversations:leave', 'payload': { 'id': conversation.id } })
class TestConversationsSeenUpToAPI(APITestCase): def setUp(self): self.conversation = ConversationFactory() self.user = UserFactory() self.conversation.join(self.user) self.participant = ConversationParticipant.objects.get( conversation=self.conversation, user=self.user) def test_conversation_get(self): message = self.conversation.messages.create(author=self.user, content='yay') self.client.force_login(user=self.user) response = self.client.get('/api/conversations/{}/'.format( self.conversation.id), format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['seen_up_to'], None) self.assertEqual(response.data['unread_message_count'], 1) self.participant.seen_up_to = message self.participant.save() response = self.client.get('/api/conversations/{}/'.format( self.conversation.id), format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['seen_up_to'], message.id) self.assertEqual(response.data['unread_message_count'], 0) def test_conversation_list(self): message = self.conversation.messages.create(author=self.user, content='yay') self.client.force_login(user=self.user) self.participant.seen_up_to = message self.participant.save() response = self.client.get('/api/conversations/'.format( self.conversation.id), format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data[0]['seen_up_to'], message.id) def test_mark_seen_up_to(self): message = self.conversation.messages.create(author=self.user, content='yay') self.client.force_login(user=self.user) response = self.client.get('/api/conversations/{}/'.format( self.conversation.id), format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['seen_up_to'], None) data = {'seen_up_to': message.id} response = self.client.post('/api/conversations/{}/mark/'.format( self.conversation.id), data, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['seen_up_to'], message.id) self.participant.refresh_from_db() self.assertEqual(self.participant.seen_up_to, message) def test_mark_seen_up_to_fails_for_invalid_id(self): self.client.force_login(user=self.user) data = {'seen_up_to': 9817298172} response = self.client.post('/api/conversations/{}/mark/'.format( self.conversation.id), data, format='json') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual( response.data['seen_up_to'][0], 'Invalid pk "{}" - object does not exist.'.format( data['seen_up_to'])) def test_mark_seen_up_to_fails_for_message_in_other_conversation(self): conversation = ConversationFactory() message = conversation.messages.create(author=self.user, content='yay') self.client.force_login(user=self.user) data = {'seen_up_to': message.id} response = self.client.post('/api/conversations/{}/mark/'.format( self.conversation.id), data, format='json') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data['seen_up_to'][0], 'Must refer to a message in the conversation')
class TestConversationsAPI(APITestCase): def setUp(self): self.participant1 = UserFactory() self.participant2 = UserFactory() self.participant3 = UserFactory() self.not_participant1 = UserFactory() self.not_participant2 = UserFactory() self.not_participant3 = UserFactory() self.conversation1 = ConversationFactory() self.conversation1.sync_users( [self.participant1, self.participant2, self.participant3]) self.conversation1.messages.create(author=self.participant1, content='hello') self.conversation2 = ConversationFactory() self.conversation2.sync_users([self.participant1]) self.conversation2.messages.create(author=self.participant1, content='hello2') self.conversation3 = ConversationFactory() # conversation noone is in def test_get_messages(self): self.client.force_login(user=self.participant1) response = self.client.get('/api/messages/?conversation={}'.format( self.conversation1.id), format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data['results']), 1) self.assertEqual(response.data['results'][0]['content'], 'hello') def test_can_get_messages_for_all_conversations(self): self.client.force_login(user=self.participant1) response = self.client.get('/api/messages/', format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data['results']), 2) self.assertEqual(response.data['results'][0]['content'], 'hello2') self.assertEqual(response.data['results'][1]['content'], 'hello') def test_cannot_get_messages_if_not_in_conversation(self): self.client.force_login(user=self.participant1) response = self.client.get('/api/messages/?conversation={}'.format( self.conversation3.id), format='json') self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_same_error_if_conversation_does_not_exist_as_if_you_are_just_not_in_it( self): self.client.force_login(user=self.participant1) response = self.client.get( '/api/messages/?conversation={}'.format(982398723), format='json') self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_create_message(self): conversation = ConversationFactory() conversation.join(self.participant1) self.client.force_login(user=self.participant1) data = {'conversation': conversation.id, 'content': 'a nice message'} response = self.client.post('/api/messages/', data, format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED, response.data) self.assertEqual(response.data['content'], data['content']) self.assertEqual(conversation.messages.first().content, data['content']) self.assertEqual(conversation.messages.first().created_at, parse(response.data['created_at']), response.data) self.assertEqual(conversation.messages.first().id, response.data['id']) self.assertEqual(conversation.messages.first().author.id, response.data['author']) def test_cannot_create_message_without_specifying_conversation(self): self.client.force_login(user=self.participant1) data = {'content': 'a nice message'} response = self.client.post('/api/messages/', data, format='json') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) def test_cannot_create_message_if_not_in_conversation(self): self.client.force_login(user=self.participant1) data = { 'conversation': self.conversation3.id, 'content': 'a nice message' } response = self.client.post('/api/messages/', data, format='json') self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
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) 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, 'received_via': '' } }) # and they should get an updated conversation object response = client.receive(json=True) response['payload']['created_at'] = parse( response['payload']['created_at']) response['payload']['updated_at'] = parse( response['payload']['updated_at']) del response['payload']['participants'] self.assertEqual( response, { 'topic': 'conversations:conversation', 'payload': { 'id': conversation.id, 'created_at': conversation.created_at, 'updated_at': conversation.updated_at, 'seen_up_to': None, 'unread_message_count': 1, 'email_notifications': True, } }) # author should get message & updated conversations object too response = author_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, 'received_via': '' } }) # 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) response['payload']['created_at'] = parse( response['payload']['created_at']) response['payload']['updated_at'] = parse( response['payload']['updated_at']) del response['payload']['participants'] self.assertEqual( response, { 'topic': 'conversations:conversation', 'payload': { 'id': conversation.id, 'created_at': conversation.created_at, 'updated_at': author_participant.updated_at, 'seen_up_to': message.id, 'unread_message_count': 0, 'email_notifications': True, } })
def test_message_create_requires_author(self): conversation = ConversationFactory() with self.assertRaises(IntegrityError): conversation.messages.create(content='ohno')
def test_join(self): user = UserFactory() conversation = ConversationFactory() conversation.join(user) self.assertIn(user, conversation.participants.all())