def fix_all_users(self, realm): # type: (Realm) -> None user_profiles = list( UserProfile.objects.filter(realm=realm, is_bot=False)) for user_profile in user_profiles: fix(user_profile) connection.commit()
def fix_all_users(self, realm: Realm) -> None: user_profiles = list(UserProfile.objects.filter( realm=realm, is_bot=False )) for user_profile in user_profiles: fix(user_profile) connection.commit()
def fix_emails(self, realm: Optional[Realm], emails: List[str]) -> None: for email in emails: try: user_profile = self.get_user(email, realm) except CommandError: print(f"e-mail {email} doesn't exist in the realm {realm}, skipping") return fix(user_profile) connection.commit()
def fix_emails(self, realm: Optional[Realm], emails: List[Text]) -> None: for email in emails: try: user_profile = self.get_user(email, realm) except CommandError: print("e-mail %s doesn't exist in the realm %s, skipping" % (email, realm)) return fix(user_profile) connection.commit()
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_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 assert recipient is not None 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") self.subscribe(user, "temporary") um_unsubscribed_id = send_message("temporary", "whatever") force_unsubscribe("temporary") # Verify the setup assert_unread(um_normal_id) assert_unread(um_muted_topic_id) assert_unread(um_muted_stream_id) assert_unread(um_unsubscribed_id) # fix unsubscribed with connection.cursor() as cursor, self.assertLogs( "zulip.fix_unreads", "INFO" ) as info_logs: fix_unsubscribed(cursor, user) self.assertEqual(info_logs.output[0], "INFO:zulip.fix_unreads:get recipients") self.assertTrue("INFO:zulip.fix_unreads:[" in info_logs.output[1]) self.assertTrue("INFO:zulip.fix_unreads:elapsed time:" in info_logs.output[2]) self.assertEqual( info_logs.output[3], "INFO:zulip.fix_unreads:finding unread messages for non-active streams", ) self.assertEqual(info_logs.output[4], "INFO:zulip.fix_unreads:rows found: 1") self.assertTrue("INFO:zulip.fix_unreads:elapsed time:" in info_logs.output[5]) self.assertEqual( info_logs.output[6], "INFO:zulip.fix_unreads:fixing unread messages for non-active streams", ) self.assertTrue("INFO:zulip.fix_unreads:elapsed time:" in info_logs.output[7]) # Muted messages don't change. assert_unread(um_muted_topic_id) assert_unread(um_muted_stream_id) assert_unread(um_normal_id) # The unsubscribed entry should change. assert_read(um_unsubscribed_id) with self.assertLogs("zulip.fix_unreads", "INFO") as info_logs: # test idempotency fix(user) self.assertEqual(info_logs.output[0], f"INFO:zulip.fix_unreads:\n---\nFixing {user.id}:") self.assertEqual(info_logs.output[1], "INFO:zulip.fix_unreads:get recipients") self.assertTrue("INFO:zulip.fix_unreads:[" in info_logs.output[2]) self.assertTrue("INFO:zulip.fix_unreads:elapsed time:" in info_logs.output[3]) self.assertEqual( info_logs.output[4], "INFO:zulip.fix_unreads:finding unread messages for non-active streams", ) self.assertEqual(info_logs.output[5], "INFO:zulip.fix_unreads:rows found: 0") self.assertTrue("INFO:zulip.fix_unreads:elapsed time:" in info_logs.output[6]) assert_unread(um_normal_id) assert_unread(um_muted_topic_id) assert_unread(um_muted_stream_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)
def fix_unreads(apps: StateApps, schema_editor: DatabaseSchemaEditor) -> None: UserProfile = apps.get_model("zerver", "UserProfile") user_profiles = list(UserProfile.objects.filter(is_bot=False)) for user_profile in user_profiles: fix(user_profile)
def fix_unreads(apps, schema_editor): # type: (StateApps, DatabaseSchemaEditor) -> None UserProfile = apps.get_model("zerver", "UserProfile") user_profiles = list(UserProfile.objects.filter(is_bot=False)) for user_profile in user_profiles: fix(user_profile)