def test_message_create(self): user = UserFactory() conversation = ConversationFactory() conversation.join(user) conversation.messages.create(author=user, content='yay') self.assertEqual( ConversationMessage.objects.filter(author=user).count(), 1)
def test_leave(self): user = UserFactory() conversation = ConversationFactory() conversation.join(user) self.assertIn(user, conversation.participants.all()) conversation.leave(user) self.assertNotIn(user, conversation.participants.all())
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 } })
class TestEmailReplyAPI(APITestCase): def setUp(self): self.user = UserFactory() self.conversation = ConversationFactory() self.conversation.join(self.user) @override_settings(SPARKPOST_RELAY_SECRET='test_key') def test_receive_incoming_email(self): reply_token = make_local_part(self.conversation, self.user) relay_message = { 'rcpt_to': '{}@example.com'.format(reply_token), 'content': { 'text': 'message body' }, } response = self.client.post( '/api/webhooks/incoming_email/', data=[{ 'msys': { 'relay_message': relay_message } }], HTTP_X_MESSAGESYSTEMS_WEBHOOK_TOKEN='test_key', format='json') self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(self.conversation.messages.count(), 1) message = ConversationMessage.objects.first() self.assertEqual(message.received_via, 'email') incoming_email = IncomingEmail.objects.first() self.assertEqual(incoming_email.user, self.user) self.assertEqual(incoming_email.payload, relay_message) self.assertEqual(incoming_email.message, message)
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_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 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_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 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_other_participants_receive_update_on_join(self): user = UserFactory() joining_user = UserFactory() # join a conversation conversation = ConversationFactory(participants=[ user, ]) # login and connect client = self.connect_as(user) conversation.join(joining_user) response = client.messages[0] self.assertEqual(response['topic'], 'conversations:conversation') self.assertEqual(set(response['payload']['participants']), {user.id, joining_user.id})
def test_other_participants_receive_update_on_join(self): client = WSClient() user = UserFactory() joining_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.join(joining_user) response = client.receive(json=True) self.assertEqual(response['topic'], 'conversations:conversation') self.assertEqual(set(response['payload']['participants']), {user.id, joining_user.id})
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')
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, } })