def test_fix_unreads(self) -> None: user = self.example_user('hamlet') realm = get_realm('zulip') def send_message(stream_name: str, topic_name: str) -> int: msg_id = self.send_stream_message(self.example_user("othello"), stream_name, topic_name=topic_name) um = UserMessage.objects.get(user_profile=user, message_id=msg_id) return um.id def assert_read(user_message_id: int) -> None: um = UserMessage.objects.get(id=user_message_id) self.assertTrue(um.flags.read) def assert_unread(user_message_id: int) -> None: um = UserMessage.objects.get(id=user_message_id) self.assertFalse(um.flags.read) def mute_stream(stream_name: str) -> None: stream = get_stream(stream_name, realm) recipient = stream.recipient subscription = Subscription.objects.get(user_profile=user, recipient=recipient) subscription.is_muted = True subscription.save() def mute_topic(stream_name: str, topic_name: str) -> None: stream = get_stream(stream_name, realm) recipient = stream.recipient add_topic_mute( user_profile=user, stream_id=stream.id, recipient_id=recipient.id, topic_name=topic_name, ) def force_unsubscribe(stream_name: str) -> None: ''' We don't want side effects here, since the eventual unsubscribe path may mark messages as read, defeating the test setup here. ''' sub = get_subscription(stream_name, user) sub.active = False sub.save() # The data setup here is kind of funny, because some of these # conditions should not actually happen in practice going forward, # but we may have had bad data from the past. mute_stream('Denmark') mute_topic('Verona', 'muted_topic') um_normal_id = send_message('Verona', 'normal') um_muted_topic_id = send_message('Verona', 'muted_topic') um_muted_stream_id = send_message('Denmark', 'whatever') user.pointer = self.get_last_message().id user.save() um_post_pointer_id = send_message('Verona', 'muted_topic') self.subscribe(user, 'temporary') um_unsubscribed_id = send_message('temporary', 'whatever') force_unsubscribe('temporary') # verify data setup assert_unread(um_normal_id) assert_unread(um_muted_topic_id) assert_unread(um_muted_stream_id) assert_unread(um_post_pointer_id) assert_unread(um_unsubscribed_id) with connection.cursor() as cursor: fix_pre_pointer(cursor, user) # The only message that should have been fixed is the "normal" # unumuted message before the pointer. assert_read(um_normal_id) # We don't "fix" any messages that are either muted or after the # pointer, because they can be legitimately unread. assert_unread(um_muted_topic_id) assert_unread(um_muted_stream_id) assert_unread(um_post_pointer_id) assert_unread(um_unsubscribed_id) # fix unsubscribed with connection.cursor() as cursor: fix_unsubscribed(cursor, user) # Most messages don't change. assert_unread(um_muted_topic_id) assert_unread(um_muted_stream_id) assert_unread(um_post_pointer_id) # The unsubscribed entry should change. assert_read(um_unsubscribed_id) # test idempotency fix(user) assert_read(um_normal_id) assert_unread(um_muted_topic_id) assert_unread(um_muted_stream_id) assert_unread(um_post_pointer_id) assert_read(um_unsubscribed_id)
def test_fix_unreads(self) -> None: user = self.example_user('hamlet') realm = get_realm('zulip') def send_message(stream_name: str, topic_name: str) -> int: msg_id = self.send_stream_message( self.example_email("othello"), stream_name, topic_name=topic_name) um = UserMessage.objects.get( user_profile=user, message_id=msg_id) return um.id def assert_read(user_message_id: int) -> None: um = UserMessage.objects.get(id=user_message_id) self.assertTrue(um.flags.read) def assert_unread(user_message_id: int) -> None: um = UserMessage.objects.get(id=user_message_id) self.assertFalse(um.flags.read) def mute_stream(stream_name: str) -> None: stream = get_stream(stream_name, realm) recipient = get_stream_recipient(stream.id) subscription = Subscription.objects.get( user_profile=user, recipient=recipient ) subscription.in_home_view = False subscription.save() def mute_topic(stream_name: str, topic_name: str) -> None: stream = get_stream(stream_name, realm) recipient = get_stream_recipient(stream.id) add_topic_mute( user_profile=user, stream_id=stream.id, recipient_id=recipient.id, topic_name=topic_name, ) def force_unsubscribe(stream_name: str) -> None: ''' We don't want side effects here, since the eventual unsubscribe path may mark messages as read, defeating the test setup here. ''' sub = get_subscription(stream_name, user) sub.active = False sub.save() # The data setup here is kind of funny, because some of these # conditions should not actually happen in practice going forward, # but we may have had bad data from the past. mute_stream('Denmark') mute_topic('Verona', 'muted_topic') um_normal_id = send_message('Verona', 'normal') um_muted_topic_id = send_message('Verona', 'muted_topic') um_muted_stream_id = send_message('Denmark', 'whatever') user.pointer = self.get_last_message().id user.save() um_post_pointer_id = send_message('Verona', 'muted_topic') self.subscribe(user, 'temporary') um_unsubscribed_id = send_message('temporary', 'whatever') force_unsubscribe('temporary') # verify data setup assert_unread(um_normal_id) assert_unread(um_muted_topic_id) assert_unread(um_muted_stream_id) assert_unread(um_post_pointer_id) assert_unread(um_unsubscribed_id) with connection.cursor() as cursor: fix_pre_pointer(cursor, user) # The only message that should have been fixed is the "normal" # unumuted message before the pointer. assert_read(um_normal_id) # We don't "fix" any messages that are either muted or after the # pointer, because they can be legitimately unread. assert_unread(um_muted_topic_id) assert_unread(um_muted_stream_id) assert_unread(um_post_pointer_id) assert_unread(um_unsubscribed_id) # fix unsubscribed with connection.cursor() as cursor: fix_unsubscribed(cursor, user) # Most messages don't change. assert_unread(um_muted_topic_id) assert_unread(um_muted_stream_id) assert_unread(um_post_pointer_id) # The unsubscribed entry should change. assert_read(um_unsubscribed_id) # test idempotency fix(user) assert_read(um_normal_id) assert_unread(um_muted_topic_id) assert_unread(um_muted_stream_id) assert_unread(um_post_pointer_id) assert_read(um_unsubscribed_id)