From 4c28786d2dd0e58d599efc5cf32f4c2ae76ad2e3 Mon Sep 17 00:00:00 2001 From: Steve Howell Date: Mon, 29 Jun 2020 11:19:17 +0000 Subject: [PATCH] tests: Move GetUnreadMsgsTest. The tests in this suite are 90% about handling unread messages, and the only event-related logic is apply_unread_message_event. --- zerver/tests/test_events.py | 428 +---------------------------------- zerver/tests/test_unread.py | 436 +++++++++++++++++++++++++++++++++++- 2 files changed, 435 insertions(+), 429 deletions(-) diff --git a/zerver/tests/test_events.py b/zerver/tests/test_events.py index de4670ca44..27bfa74ca4 100644 --- a/zerver/tests/test_events.py +++ b/zerver/tests/test_events.py @@ -93,14 +93,7 @@ from zerver.lib.actions import ( ) from zerver.lib.events import apply_events, fetch_initial_state_data, post_process_state from zerver.lib.markdown import MentionData -from zerver.lib.message import ( - MessageDict, - UnreadMessagesResult, - aggregate_unread_data, - apply_unread_message_event, - get_raw_unread_data, - render_markdown, -) +from zerver.lib.message import render_markdown from zerver.lib.test_classes import ZulipTestCase from zerver.lib.test_helpers import ( create_dummy_file, @@ -111,7 +104,6 @@ from zerver.lib.test_helpers import ( ) from zerver.lib.test_runner import slow from zerver.lib.topic import ORIG_TOPIC, TOPIC_LINKS, TOPIC_NAME -from zerver.lib.topic_mutes import add_topic_mute from zerver.lib.validator import ( Validator, check_bool, @@ -134,10 +126,8 @@ from zerver.models import ( Realm, RealmAuditLog, RealmDomain, - Recipient, Service, Stream, - Subscription, UserGroup, UserMessage, UserPresence, @@ -2620,419 +2610,3 @@ class EventsRegisterTest(ZulipTestCase): ]) events = self.do_test(lambda: do_set_zoom_token(self.user_profile, None)) schema_checker('events[0]', events[0]) - -class GetUnreadMsgsTest(ZulipTestCase): - def mute_stream(self, user_profile: UserProfile, stream: Stream) -> None: - recipient = Recipient.objects.get(type_id=stream.id, type=Recipient.STREAM) - subscription = Subscription.objects.get( - user_profile=user_profile, - recipient=recipient, - ) - subscription.is_muted = True - subscription.save() - - def mute_topic(self, user_profile: UserProfile, stream_name: str, - topic_name: str) -> None: - realm = user_profile.realm - stream = get_stream(stream_name, realm) - recipient = stream.recipient - - add_topic_mute( - user_profile=user_profile, - stream_id=stream.id, - recipient_id=recipient.id, - topic_name=topic_name, - ) - - def test_raw_unread_stream(self) -> None: - cordelia = self.example_user('cordelia') - hamlet = self.example_user('hamlet') - realm = hamlet.realm - - for stream_name in ['social', 'devel', 'test here']: - self.subscribe(hamlet, stream_name) - self.subscribe(cordelia, stream_name) - - all_message_ids: Set[int] = set() - message_ids = dict() - - tups = [ - ('social', 'lunch'), - ('test here', 'bla'), - ('devel', 'python'), - ('devel', 'ruby'), - ] - - for stream_name, topic_name in tups: - message_ids[topic_name] = [ - self.send_stream_message( - sender=cordelia, - stream_name=stream_name, - topic_name=topic_name, - ) for i in range(3) - ] - all_message_ids |= set(message_ids[topic_name]) - - self.assertEqual(len(all_message_ids), 12) # sanity check on test setup - - self.mute_stream( - user_profile=hamlet, - stream=get_stream('test here', realm), - ) - - self.mute_topic( - user_profile=hamlet, - stream_name='devel', - topic_name='ruby', - ) - - raw_unread_data = get_raw_unread_data( - user_profile=hamlet, - ) - - stream_dict = raw_unread_data['stream_dict'] - - self.assertEqual( - set(stream_dict.keys()), - all_message_ids, - ) - - self.assertEqual( - raw_unread_data['unmuted_stream_msgs'], - set(message_ids['python']) | set(message_ids['lunch']), - ) - - self.assertEqual( - stream_dict[message_ids['lunch'][0]], - dict( - sender_id=cordelia.id, - stream_id=get_stream('social', realm).id, - topic='lunch', - ), - ) - - def test_raw_unread_huddle(self) -> None: - cordelia = self.example_user('cordelia') - othello = self.example_user('othello') - hamlet = self.example_user('hamlet') - prospero = self.example_user('prospero') - - huddle1_message_ids = [ - self.send_huddle_message( - cordelia, - [hamlet, othello], - ) - for i in range(3) - ] - - huddle2_message_ids = [ - self.send_huddle_message( - cordelia, - [hamlet, prospero], - ) - for i in range(3) - ] - - raw_unread_data = get_raw_unread_data( - user_profile=hamlet, - ) - - huddle_dict = raw_unread_data['huddle_dict'] - - self.assertEqual( - set(huddle_dict.keys()), - set(huddle1_message_ids) | set(huddle2_message_ids), - ) - - huddle_string = ','.join( - str(uid) - for uid in sorted([cordelia.id, hamlet.id, othello.id]) - ) - - self.assertEqual( - huddle_dict[huddle1_message_ids[0]], - dict(user_ids_string=huddle_string), - ) - - def test_raw_unread_personal(self) -> None: - cordelia = self.example_user('cordelia') - othello = self.example_user('othello') - hamlet = self.example_user('hamlet') - - cordelia_pm_message_ids = [ - self.send_personal_message(cordelia, hamlet) - for i in range(3) - ] - - othello_pm_message_ids = [ - self.send_personal_message(othello, hamlet) - for i in range(3) - ] - - raw_unread_data = get_raw_unread_data( - user_profile=hamlet, - ) - - pm_dict = raw_unread_data['pm_dict'] - - self.assertEqual( - set(pm_dict.keys()), - set(cordelia_pm_message_ids) | set(othello_pm_message_ids), - ) - - self.assertEqual( - pm_dict[cordelia_pm_message_ids[0]], - dict(sender_id=cordelia.id), - ) - - def test_raw_unread_personal_from_self(self) -> None: - hamlet = self.example_user('hamlet') - - def send_unread_pm(other_user: UserProfile) -> Message: - # It is rare to send a message from Hamlet to Othello - # (or any other user) and have it be unread for - # Hamlet himself, but that is actually normal - # behavior for most API clients. - message_id = self.send_personal_message( - from_user=hamlet, - to_user=other_user, - sending_client_name='some_api_program', - ) - - # Check our test setup is correct--the message should - # not have looked like it was sent by a human. - message = Message.objects.get(id=message_id) - self.assertFalse(message.sent_by_human()) - - # And since it was not sent by a human, it should not - # be read, not even by the sender (Hamlet). - um = UserMessage.objects.get( - user_profile_id=hamlet.id, - message_id=message_id, - ) - self.assertFalse(um.flags.read) - - return message - - othello = self.example_user('othello') - othello_msg = send_unread_pm(other_user=othello) - - # And now check the unread data structure... - raw_unread_data = get_raw_unread_data( - user_profile=hamlet, - ) - - pm_dict = raw_unread_data['pm_dict'] - - self.assertEqual(set(pm_dict.keys()), {othello_msg.id}) - - # For legacy reason we call the field `sender_id` here, - # but it really refers to the other user id in the conversation, - # which is Othello. - self.assertEqual( - pm_dict[othello_msg.id], - dict(sender_id=othello.id), - ) - - cordelia = self.example_user('cordelia') - cordelia_msg = send_unread_pm(other_user=cordelia) - - apply_unread_message_event( - user_profile=hamlet, - state=raw_unread_data, - message=MessageDict.wide_dict(cordelia_msg), - flags=[], - ) - self.assertEqual( - set(pm_dict.keys()), - {othello_msg.id, cordelia_msg.id}, - ) - - # Again, `sender_id` is misnamed here. - self.assertEqual( - pm_dict[cordelia_msg.id], - dict(sender_id=cordelia.id), - ) - - # Send a message to ourself. - hamlet_msg = send_unread_pm(other_user=hamlet) - apply_unread_message_event( - user_profile=hamlet, - state=raw_unread_data, - message=MessageDict.wide_dict(hamlet_msg), - flags=[], - ) - self.assertEqual( - set(pm_dict.keys()), - {othello_msg.id, cordelia_msg.id, hamlet_msg.id}, - ) - - # Again, `sender_id` is misnamed here. - self.assertEqual( - pm_dict[hamlet_msg.id], - dict(sender_id=hamlet.id), - ) - - # Call get_raw_unread_data again. - raw_unread_data = get_raw_unread_data( - user_profile=hamlet, - ) - pm_dict = raw_unread_data['pm_dict'] - - self.assertEqual( - set(pm_dict.keys()), - {othello_msg.id, cordelia_msg.id, hamlet_msg.id}, - ) - - # Again, `sender_id` is misnamed here. - self.assertEqual( - pm_dict[hamlet_msg.id], - dict(sender_id=hamlet.id), - ) - - def test_unread_msgs(self) -> None: - sender = self.example_user('cordelia') - sender_id = sender.id - user_profile = self.example_user('hamlet') - othello = self.example_user('othello') - - pm1_message_id = self.send_personal_message(sender, user_profile, "hello1") - pm2_message_id = self.send_personal_message(sender, user_profile, "hello2") - - muted_stream = self.subscribe(user_profile, 'Muted Stream') - self.mute_stream(user_profile, muted_stream) - self.mute_topic(user_profile, 'Denmark', 'muted-topic') - - stream_message_id = self.send_stream_message(sender, "Denmark", "hello") - muted_stream_message_id = self.send_stream_message(sender, "Muted Stream", "hello") - muted_topic_message_id = self.send_stream_message( - sender, - "Denmark", - topic_name="muted-topic", - content="hello", - ) - - huddle_message_id = self.send_huddle_message( - sender, - [user_profile, othello], - 'hello3', - ) - - def get_unread_data() -> UnreadMessagesResult: - raw_unread_data = get_raw_unread_data(user_profile) - aggregated_data = aggregate_unread_data(raw_unread_data) - return aggregated_data - - result = get_unread_data() - - # The count here reflects the count of unread messages that we will - # report to users in the bankruptcy dialog, and for now it excludes unread messages - # from muted treams, but it doesn't exclude unread messages from muted topics yet. - self.assertEqual(result['count'], 4) - - unread_pm = result['pms'][0] - self.assertEqual(unread_pm['sender_id'], sender_id) - self.assertEqual(unread_pm['unread_message_ids'], [pm1_message_id, pm2_message_id]) - self.assertTrue('sender_ids' not in unread_pm) - - unread_stream = result['streams'][0] - self.assertEqual(unread_stream['stream_id'], get_stream('Denmark', user_profile.realm).id) - self.assertEqual(unread_stream['topic'], 'muted-topic') - self.assertEqual(unread_stream['unread_message_ids'], [muted_topic_message_id]) - self.assertEqual(unread_stream['sender_ids'], [sender_id]) - - unread_stream = result['streams'][1] - self.assertEqual(unread_stream['stream_id'], get_stream('Denmark', user_profile.realm).id) - self.assertEqual(unread_stream['topic'], 'test') - self.assertEqual(unread_stream['unread_message_ids'], [stream_message_id]) - self.assertEqual(unread_stream['sender_ids'], [sender_id]) - - unread_stream = result['streams'][2] - self.assertEqual(unread_stream['stream_id'], get_stream('Muted Stream', user_profile.realm).id) - self.assertEqual(unread_stream['topic'], 'test') - self.assertEqual(unread_stream['unread_message_ids'], [muted_stream_message_id]) - self.assertEqual(unread_stream['sender_ids'], [sender_id]) - - huddle_string = ','.join(str(uid) for uid in sorted([sender_id, user_profile.id, othello.id])) - - unread_huddle = result['huddles'][0] - self.assertEqual(unread_huddle['user_ids_string'], huddle_string) - self.assertEqual(unread_huddle['unread_message_ids'], [huddle_message_id]) - self.assertTrue('sender_ids' not in unread_huddle) - - self.assertEqual(result['mentions'], []) - - um = UserMessage.objects.get( - user_profile_id=user_profile.id, - message_id=stream_message_id, - ) - um.flags |= UserMessage.flags.mentioned - um.save() - result = get_unread_data() - self.assertEqual(result['mentions'], [stream_message_id]) - - um.flags = UserMessage.flags.has_alert_word - um.save() - result = get_unread_data() - # TODO: This should change when we make alert words work better. - self.assertEqual(result['mentions'], []) - - um.flags = UserMessage.flags.wildcard_mentioned - um.save() - result = get_unread_data() - self.assertEqual(result['mentions'], [stream_message_id]) - - um.flags = 0 - um.save() - result = get_unread_data() - self.assertEqual(result['mentions'], []) - - # Test with a muted stream - um = UserMessage.objects.get( - user_profile_id=user_profile.id, - message_id=muted_stream_message_id, - ) - um.flags = UserMessage.flags.mentioned - um.save() - result = get_unread_data() - self.assertEqual(result['mentions'], [muted_stream_message_id]) - - um.flags = UserMessage.flags.has_alert_word - um.save() - result = get_unread_data() - self.assertEqual(result['mentions'], []) - - um.flags = UserMessage.flags.wildcard_mentioned - um.save() - result = get_unread_data() - self.assertEqual(result['mentions'], []) - - um.flags = 0 - um.save() - result = get_unread_data() - self.assertEqual(result['mentions'], []) - - # Test with a muted topic - um = UserMessage.objects.get( - user_profile_id=user_profile.id, - message_id=muted_topic_message_id, - ) - um.flags = UserMessage.flags.mentioned - um.save() - result = get_unread_data() - self.assertEqual(result['mentions'], [muted_topic_message_id]) - - um.flags = UserMessage.flags.has_alert_word - um.save() - result = get_unread_data() - self.assertEqual(result['mentions'], []) - - um.flags = UserMessage.flags.wildcard_mentioned - um.save() - result = get_unread_data() - self.assertEqual(result['mentions'], []) - - um.flags = 0 - um.save() - result = get_unread_data() - self.assertEqual(result['mentions'], []) diff --git a/zerver/tests/test_unread.py b/zerver/tests/test_unread.py index afb9d9f1fd..f4b5dbb5ab 100644 --- a/zerver/tests/test_unread.py +++ b/zerver/tests/test_unread.py @@ -1,14 +1,30 @@ -from typing import Any, List, Mapping +from typing import Any, List, Mapping, Set from unittest import mock import ujson from django.db import connection from zerver.lib.fix_unreads import fix, fix_unsubscribed +from zerver.lib.message import ( + MessageDict, + UnreadMessagesResult, + aggregate_unread_data, + apply_unread_message_event, + get_raw_unread_data, +) from zerver.lib.test_classes import ZulipTestCase from zerver.lib.test_helpers import get_subscription, tornado_redirected_to_list from zerver.lib.topic_mutes import add_topic_mute -from zerver.models import Subscription, UserMessage, UserProfile, get_realm, get_stream +from zerver.models import ( + Message, + Recipient, + Stream, + Subscription, + UserMessage, + UserProfile, + get_realm, + get_stream, +) class FirstUnreadAnchorTests(ZulipTestCase): @@ -422,3 +438,419 @@ class PushNotificationMarkReadFlowsTest(ZulipTestCase): self.assertEqual(self.get_mobile_push_notification_ids(user_profile), []) mock_push_notifications.assert_called() + +class GetUnreadMsgsTest(ZulipTestCase): + def mute_stream(self, user_profile: UserProfile, stream: Stream) -> None: + recipient = Recipient.objects.get(type_id=stream.id, type=Recipient.STREAM) + subscription = Subscription.objects.get( + user_profile=user_profile, + recipient=recipient, + ) + subscription.is_muted = True + subscription.save() + + def mute_topic(self, user_profile: UserProfile, stream_name: str, + topic_name: str) -> None: + realm = user_profile.realm + stream = get_stream(stream_name, realm) + recipient = stream.recipient + + add_topic_mute( + user_profile=user_profile, + stream_id=stream.id, + recipient_id=recipient.id, + topic_name=topic_name, + ) + + def test_raw_unread_stream(self) -> None: + cordelia = self.example_user('cordelia') + hamlet = self.example_user('hamlet') + realm = hamlet.realm + + for stream_name in ['social', 'devel', 'test here']: + self.subscribe(hamlet, stream_name) + self.subscribe(cordelia, stream_name) + + all_message_ids: Set[int] = set() + message_ids = dict() + + tups = [ + ('social', 'lunch'), + ('test here', 'bla'), + ('devel', 'python'), + ('devel', 'ruby'), + ] + + for stream_name, topic_name in tups: + message_ids[topic_name] = [ + self.send_stream_message( + sender=cordelia, + stream_name=stream_name, + topic_name=topic_name, + ) for i in range(3) + ] + all_message_ids |= set(message_ids[topic_name]) + + self.assertEqual(len(all_message_ids), 12) # sanity check on test setup + + self.mute_stream( + user_profile=hamlet, + stream=get_stream('test here', realm), + ) + + self.mute_topic( + user_profile=hamlet, + stream_name='devel', + topic_name='ruby', + ) + + raw_unread_data = get_raw_unread_data( + user_profile=hamlet, + ) + + stream_dict = raw_unread_data['stream_dict'] + + self.assertEqual( + set(stream_dict.keys()), + all_message_ids, + ) + + self.assertEqual( + raw_unread_data['unmuted_stream_msgs'], + set(message_ids['python']) | set(message_ids['lunch']), + ) + + self.assertEqual( + stream_dict[message_ids['lunch'][0]], + dict( + sender_id=cordelia.id, + stream_id=get_stream('social', realm).id, + topic='lunch', + ), + ) + + def test_raw_unread_huddle(self) -> None: + cordelia = self.example_user('cordelia') + othello = self.example_user('othello') + hamlet = self.example_user('hamlet') + prospero = self.example_user('prospero') + + huddle1_message_ids = [ + self.send_huddle_message( + cordelia, + [hamlet, othello], + ) + for i in range(3) + ] + + huddle2_message_ids = [ + self.send_huddle_message( + cordelia, + [hamlet, prospero], + ) + for i in range(3) + ] + + raw_unread_data = get_raw_unread_data( + user_profile=hamlet, + ) + + huddle_dict = raw_unread_data['huddle_dict'] + + self.assertEqual( + set(huddle_dict.keys()), + set(huddle1_message_ids) | set(huddle2_message_ids), + ) + + huddle_string = ','.join( + str(uid) + for uid in sorted([cordelia.id, hamlet.id, othello.id]) + ) + + self.assertEqual( + huddle_dict[huddle1_message_ids[0]], + dict(user_ids_string=huddle_string), + ) + + def test_raw_unread_personal(self) -> None: + cordelia = self.example_user('cordelia') + othello = self.example_user('othello') + hamlet = self.example_user('hamlet') + + cordelia_pm_message_ids = [ + self.send_personal_message(cordelia, hamlet) + for i in range(3) + ] + + othello_pm_message_ids = [ + self.send_personal_message(othello, hamlet) + for i in range(3) + ] + + raw_unread_data = get_raw_unread_data( + user_profile=hamlet, + ) + + pm_dict = raw_unread_data['pm_dict'] + + self.assertEqual( + set(pm_dict.keys()), + set(cordelia_pm_message_ids) | set(othello_pm_message_ids), + ) + + self.assertEqual( + pm_dict[cordelia_pm_message_ids[0]], + dict(sender_id=cordelia.id), + ) + + def test_raw_unread_personal_from_self(self) -> None: + hamlet = self.example_user('hamlet') + + def send_unread_pm(other_user: UserProfile) -> Message: + # It is rare to send a message from Hamlet to Othello + # (or any other user) and have it be unread for + # Hamlet himself, but that is actually normal + # behavior for most API clients. + message_id = self.send_personal_message( + from_user=hamlet, + to_user=other_user, + sending_client_name='some_api_program', + ) + + # Check our test setup is correct--the message should + # not have looked like it was sent by a human. + message = Message.objects.get(id=message_id) + self.assertFalse(message.sent_by_human()) + + # And since it was not sent by a human, it should not + # be read, not even by the sender (Hamlet). + um = UserMessage.objects.get( + user_profile_id=hamlet.id, + message_id=message_id, + ) + self.assertFalse(um.flags.read) + + return message + + othello = self.example_user('othello') + othello_msg = send_unread_pm(other_user=othello) + + # And now check the unread data structure... + raw_unread_data = get_raw_unread_data( + user_profile=hamlet, + ) + + pm_dict = raw_unread_data['pm_dict'] + + self.assertEqual(set(pm_dict.keys()), {othello_msg.id}) + + # For legacy reason we call the field `sender_id` here, + # but it really refers to the other user id in the conversation, + # which is Othello. + self.assertEqual( + pm_dict[othello_msg.id], + dict(sender_id=othello.id), + ) + + cordelia = self.example_user('cordelia') + cordelia_msg = send_unread_pm(other_user=cordelia) + + apply_unread_message_event( + user_profile=hamlet, + state=raw_unread_data, + message=MessageDict.wide_dict(cordelia_msg), + flags=[], + ) + self.assertEqual( + set(pm_dict.keys()), + {othello_msg.id, cordelia_msg.id}, + ) + + # Again, `sender_id` is misnamed here. + self.assertEqual( + pm_dict[cordelia_msg.id], + dict(sender_id=cordelia.id), + ) + + # Send a message to ourself. + hamlet_msg = send_unread_pm(other_user=hamlet) + apply_unread_message_event( + user_profile=hamlet, + state=raw_unread_data, + message=MessageDict.wide_dict(hamlet_msg), + flags=[], + ) + self.assertEqual( + set(pm_dict.keys()), + {othello_msg.id, cordelia_msg.id, hamlet_msg.id}, + ) + + # Again, `sender_id` is misnamed here. + self.assertEqual( + pm_dict[hamlet_msg.id], + dict(sender_id=hamlet.id), + ) + + # Call get_raw_unread_data again. + raw_unread_data = get_raw_unread_data( + user_profile=hamlet, + ) + pm_dict = raw_unread_data['pm_dict'] + + self.assertEqual( + set(pm_dict.keys()), + {othello_msg.id, cordelia_msg.id, hamlet_msg.id}, + ) + + # Again, `sender_id` is misnamed here. + self.assertEqual( + pm_dict[hamlet_msg.id], + dict(sender_id=hamlet.id), + ) + + def test_unread_msgs(self) -> None: + sender = self.example_user('cordelia') + sender_id = sender.id + user_profile = self.example_user('hamlet') + othello = self.example_user('othello') + + pm1_message_id = self.send_personal_message(sender, user_profile, "hello1") + pm2_message_id = self.send_personal_message(sender, user_profile, "hello2") + + muted_stream = self.subscribe(user_profile, 'Muted Stream') + self.mute_stream(user_profile, muted_stream) + self.mute_topic(user_profile, 'Denmark', 'muted-topic') + + stream_message_id = self.send_stream_message(sender, "Denmark", "hello") + muted_stream_message_id = self.send_stream_message(sender, "Muted Stream", "hello") + muted_topic_message_id = self.send_stream_message( + sender, + "Denmark", + topic_name="muted-topic", + content="hello", + ) + + huddle_message_id = self.send_huddle_message( + sender, + [user_profile, othello], + 'hello3', + ) + + def get_unread_data() -> UnreadMessagesResult: + raw_unread_data = get_raw_unread_data(user_profile) + aggregated_data = aggregate_unread_data(raw_unread_data) + return aggregated_data + + result = get_unread_data() + + # The count here reflects the count of unread messages that we will + # report to users in the bankruptcy dialog, and for now it excludes unread messages + # from muted treams, but it doesn't exclude unread messages from muted topics yet. + self.assertEqual(result['count'], 4) + + unread_pm = result['pms'][0] + self.assertEqual(unread_pm['sender_id'], sender_id) + self.assertEqual(unread_pm['unread_message_ids'], [pm1_message_id, pm2_message_id]) + self.assertTrue('sender_ids' not in unread_pm) + + unread_stream = result['streams'][0] + self.assertEqual(unread_stream['stream_id'], get_stream('Denmark', user_profile.realm).id) + self.assertEqual(unread_stream['topic'], 'muted-topic') + self.assertEqual(unread_stream['unread_message_ids'], [muted_topic_message_id]) + self.assertEqual(unread_stream['sender_ids'], [sender_id]) + + unread_stream = result['streams'][1] + self.assertEqual(unread_stream['stream_id'], get_stream('Denmark', user_profile.realm).id) + self.assertEqual(unread_stream['topic'], 'test') + self.assertEqual(unread_stream['unread_message_ids'], [stream_message_id]) + self.assertEqual(unread_stream['sender_ids'], [sender_id]) + + unread_stream = result['streams'][2] + self.assertEqual(unread_stream['stream_id'], get_stream('Muted Stream', user_profile.realm).id) + self.assertEqual(unread_stream['topic'], 'test') + self.assertEqual(unread_stream['unread_message_ids'], [muted_stream_message_id]) + self.assertEqual(unread_stream['sender_ids'], [sender_id]) + + huddle_string = ','.join(str(uid) for uid in sorted([sender_id, user_profile.id, othello.id])) + + unread_huddle = result['huddles'][0] + self.assertEqual(unread_huddle['user_ids_string'], huddle_string) + self.assertEqual(unread_huddle['unread_message_ids'], [huddle_message_id]) + self.assertTrue('sender_ids' not in unread_huddle) + + self.assertEqual(result['mentions'], []) + + um = UserMessage.objects.get( + user_profile_id=user_profile.id, + message_id=stream_message_id, + ) + um.flags |= UserMessage.flags.mentioned + um.save() + result = get_unread_data() + self.assertEqual(result['mentions'], [stream_message_id]) + + um.flags = UserMessage.flags.has_alert_word + um.save() + result = get_unread_data() + # TODO: This should change when we make alert words work better. + self.assertEqual(result['mentions'], []) + + um.flags = UserMessage.flags.wildcard_mentioned + um.save() + result = get_unread_data() + self.assertEqual(result['mentions'], [stream_message_id]) + + um.flags = 0 + um.save() + result = get_unread_data() + self.assertEqual(result['mentions'], []) + + # Test with a muted stream + um = UserMessage.objects.get( + user_profile_id=user_profile.id, + message_id=muted_stream_message_id, + ) + um.flags = UserMessage.flags.mentioned + um.save() + result = get_unread_data() + self.assertEqual(result['mentions'], [muted_stream_message_id]) + + um.flags = UserMessage.flags.has_alert_word + um.save() + result = get_unread_data() + self.assertEqual(result['mentions'], []) + + um.flags = UserMessage.flags.wildcard_mentioned + um.save() + result = get_unread_data() + self.assertEqual(result['mentions'], []) + + um.flags = 0 + um.save() + result = get_unread_data() + self.assertEqual(result['mentions'], []) + + # Test with a muted topic + um = UserMessage.objects.get( + user_profile_id=user_profile.id, + message_id=muted_topic_message_id, + ) + um.flags = UserMessage.flags.mentioned + um.save() + result = get_unread_data() + self.assertEqual(result['mentions'], [muted_topic_message_id]) + + um.flags = UserMessage.flags.has_alert_word + um.save() + result = get_unread_data() + self.assertEqual(result['mentions'], []) + + um.flags = UserMessage.flags.wildcard_mentioned + um.save() + result = get_unread_data() + self.assertEqual(result['mentions'], []) + + um.flags = 0 + um.save() + result = get_unread_data() + self.assertEqual(result['mentions'], [])