def test_do_soft_activate_users(self) -> None: users = [ self.example_user("hamlet"), self.example_user("iago"), self.example_user("cordelia"), ] self.send_huddle_message(users[0], users) with self.assertLogs(logger_string, level="INFO") as m: do_soft_deactivate_users(users) log_output = [] for user in users: log_output.append(f"INFO:{logger_string}:Soft deactivated user {user.id}") log_output.append( f"INFO:{logger_string}:Soft-deactivated batch of {len(users[:100])} users; {len(users[100:])} remain to process" ) self.assertEqual(m.output, log_output) for user in users: self.assertTrue(user.long_term_idle) with self.assertLogs(logger_string, level="INFO") as m: do_soft_activate_users(users) log_output = [] for user in users: log_output.append(f"INFO:{logger_string}:Soft reactivated user {user.id}") self.assertEqual(m.output, log_output) for user in users: user.refresh_from_db() self.assertFalse(user.long_term_idle)
def handle(self, *args: Any, **options: str) -> None: if settings.STAGING: print('This is a Staging server. Suppressing management command.') sys.exit(0) realm = self.get_realm(options) user_emails = options['users'] activate = options['activate'] deactivate = options['deactivate'] filter_kwargs = {} # type: Dict[str, Realm] if realm is not None: filter_kwargs = dict(realm=realm) if activate: if not user_emails: print('You need to specify at least one user to use the activate option.') self.print_help("./manage.py", "soft_deactivate_users") sys.exit(1) users_to_activate = UserProfile.objects.filter( email__in=user_emails, **filter_kwargs ) users_to_activate = list(users_to_activate) if len(users_to_activate) != len(user_emails): user_emails_found = [user.email for user in users_to_activate] for user in user_emails: if user not in user_emails_found: raise Exception('User with email %s was not found. Check if the email is correct.' % (user)) users_activated = do_soft_activate_users(users_to_activate) logger.info('Soft Reactivated %d user(s)' % (len(users_activated))) elif deactivate: if user_emails: users_to_deactivate = UserProfile.objects.filter( email__in=user_emails, **filter_kwargs ) users_to_deactivate = list(users_to_deactivate) if len(users_to_deactivate) != len(user_emails): user_emails_found = [user.email for user in users_to_deactivate] for user in user_emails: if user not in user_emails_found: raise Exception('User with email %s was not found. ' 'Check if the email is correct.' % (user,)) print('Soft deactivating forcefully...') else: if realm is not None: filter_kwargs = dict(user_profile__realm=realm) users_to_deactivate = get_users_for_soft_deactivation(int(options['inactive_for']), filter_kwargs) if users_to_deactivate: users_deactivated = do_soft_deactivate_users(users_to_deactivate) logger.info('Soft Deactivated %d user(s)' % (len(users_deactivated))) else: self.print_help("./manage.py", "soft_deactivate_users") sys.exit(1)
def test_do_soft_activate_users(self) -> None: users = [ self.example_user('hamlet'), self.example_user('iago'), self.example_user('cordelia'), ] self.send_huddle_message(users[0].email, [user.email for user in users]) do_soft_deactivate_users(users) for user in users: self.assertTrue(user.long_term_idle) do_soft_activate_users(users) for user in users: user.refresh_from_db() self.assertFalse(user.long_term_idle)
def test_do_soft_activate_users(self) -> None: users = [ self.example_user('hamlet'), self.example_user('iago'), self.example_user('cordelia'), ] self.send_huddle_message(users[0], users) with mock.patch('logging.info'): do_soft_deactivate_users(users) for user in users: self.assertTrue(user.long_term_idle) with mock.patch('logging.info'): do_soft_activate_users(users) for user in users: user.refresh_from_db() self.assertFalse(user.long_term_idle)
def handle(self, *args: Any, **options: str) -> None: if settings.STAGING: print('This is a Staging server. Suppressing management command.') sys.exit(0) realm = self.get_realm(options) user_emails = options[ 'users'] # type: ignore # mypy thinks this is a str, not List[str] # activate = options['activate'] deactivate = options['deactivate'] filter_kwargs = {} # type: Dict[str, Realm] if realm is not None: filter_kwargs = dict(realm=realm) if activate: if not user_emails: print( 'You need to specify at least one user to use the activate option.' ) self.print_help("./manage.py", "soft_deactivate_users") raise CommandError users_to_activate = get_users_from_emails(user_emails, filter_kwargs) users_activated = do_soft_activate_users(users_to_activate) logger.info('Soft Reactivated %d user(s)' % (len(users_activated), )) elif deactivate: if user_emails: users_to_deactivate = get_users_from_emails( user_emails, filter_kwargs) print('Soft deactivating forcefully...') users_deactivated = do_soft_deactivate_users( users_to_deactivate) else: users_deactivated = do_auto_soft_deactivate_users( int(options['inactive_for']), realm) logger.info('Soft Deactivated %d user(s)' % (len(users_deactivated), )) else: self.print_help("./manage.py", "soft_deactivate_users") raise CommandError
def handle(self, *args: Any, **options: Any) -> None: if settings.STAGING: print("This is a Staging server. Suppressing management command.") sys.exit(0) realm = self.get_realm(options) user_emails = options["users"] activate = options["activate"] deactivate = options["deactivate"] filter_kwargs: Dict[str, Realm] = {} if realm is not None: filter_kwargs = dict(realm=realm) if activate: if not user_emails: print( "You need to specify at least one user to use the activate option." ) self.print_help("./manage.py", "soft_deactivate_users") raise CommandError users_to_activate = get_users_from_emails(user_emails, filter_kwargs) users_activated = do_soft_activate_users(users_to_activate) logger.info("Soft Reactivated %d user(s)", len(users_activated)) elif deactivate: if user_emails: users_to_deactivate = get_users_from_emails( user_emails, filter_kwargs) print("Soft deactivating forcefully...") users_deactivated = do_soft_deactivate_users( users_to_deactivate) else: users_deactivated = do_auto_soft_deactivate_users( int(options["inactive_for"]), realm) logger.info("Soft deactivated %d user(s)", len(users_deactivated)) else: self.print_help("./manage.py", "soft_deactivate_users") raise CommandError
def handle(self, *args, **options): # type: (*Any, **str) -> None realm = self.get_realm(options) user_emails = options['users'] activate = options['activate'] deactivate = options['deactivate'] if activate: if not user_emails: print('You need to specify at least one user to use the activate option.') self.print_help("./manage.py", "soft_activate_deactivate_users") sys.exit(1) users_to_activate = list(UserProfile.objects.filter( realm=realm, email__in=user_emails)) if len(users_to_activate) != len(user_emails): user_emails_found = [user.email for user in users_to_activate] for user in user_emails: if user not in user_emails_found: raise Exception('User with email %s was not found. Check if the email is correct.' % (user)) users_activated = do_soft_activate_users(users_to_activate) logger.info('Soft Reactivated %d user(s)' % (len(users_activated))) elif deactivate: if user_emails: users_to_deactivate = list(UserProfile.objects.filter( realm=realm, email__in=user_emails)) if len(users_to_deactivate) != len(user_emails): user_emails_found = [user.email for user in users_to_deactivate] for user in user_emails: if user not in user_emails_found: raise Exception('User with email %s was not found. Check if the email is correct.' % (user)) print('Soft deactivating forcefully...') else: users_to_deactivate = get_users_for_soft_deactivation(realm, int(options['inactive_for'])) if users_to_deactivate: users_deactivated = do_soft_deactivate_users(users_to_deactivate) logger.info('Soft Deactivated %d user(s)' % (len(users_deactivated))) else: self.print_help("./manage.py", "soft_activate_deactivate_users") sys.exit(1)
def handle(self, *args: Any, **options: str) -> None: if settings.STAGING: print('This is a Staging server. Suppressing management command.') sys.exit(0) realm = self.get_realm(options) user_emails = options['users'] activate = options['activate'] deactivate = options['deactivate'] filter_kwargs = {} # type: Dict[str, Realm] if realm is not None: filter_kwargs = dict(realm=realm) if activate: if not user_emails: print('You need to specify at least one user to use the activate option.') self.print_help("./manage.py", "soft_deactivate_users") sys.exit(1) users_to_activate = UserProfile.objects.filter( email__in=user_emails, **filter_kwargs ) users_to_activate = list(users_to_activate) if len(users_to_activate) != len(user_emails): user_emails_found = [user.email for user in users_to_activate] for user in user_emails: if user not in user_emails_found: raise Exception('User with email %s was not found. ' 'Check if the email is correct.' % (user)) users_activated = do_soft_activate_users(users_to_activate) logger.info('Soft Reactivated %d user(s)' % (len(users_activated))) elif deactivate: if user_emails: users_to_deactivate = UserProfile.objects.filter( email__in=user_emails, **filter_kwargs ) users_to_deactivate = list(users_to_deactivate) if len(users_to_deactivate) != len(user_emails): user_emails_found = [user.email for user in users_to_deactivate] for user in user_emails: if user not in user_emails_found: raise Exception('User with email %s was not found. ' 'Check if the email is correct.' % (user,)) print('Soft deactivating forcefully...') else: if realm is not None: filter_kwargs = dict(user_profile__realm=realm) users_to_deactivate = get_users_for_soft_deactivation(int(options['inactive_for']), filter_kwargs) if users_to_deactivate: users_deactivated = do_soft_deactivate_users(users_to_deactivate) logger.info('Soft Deactivated %d user(s)' % (len(users_deactivated))) else: self.print_help("./manage.py", "soft_deactivate_users") sys.exit(1)
def test_add_missing_messages(self) -> None: recipient_list = [ self.example_user("hamlet"), self.example_user("iago") ] for user_profile in recipient_list: self.subscribe(user_profile, "Denmark") sender = self.example_user('iago') realm = sender.realm sending_client = make_client(name="test suite") stream_name = 'Denmark' stream = get_stream(stream_name, realm) topic_name = 'foo' def send_fake_message(message_content: str, stream: Stream) -> Message: recipient = stream.recipient message = Message(sender=sender, recipient=recipient, content=message_content, date_sent=timezone_now(), sending_client=sending_client) message.set_topic_name(topic_name) message.save() return message long_term_idle_user = self.example_user('hamlet') self.send_stream_message(long_term_idle_user, stream_name) with self.assertLogs(level='INFO') as info_logs: do_soft_deactivate_users([long_term_idle_user]) self.assertEqual(info_logs.output, [ 'INFO:root:Soft-deactivated batch of 1 users; 0 remain to process' ]) # Test that add_missing_messages() in simplest case of adding a # message for which UserMessage row doesn't exist for this user. sent_message = send_fake_message('Test Message 1', stream) idle_user_msg_list = get_user_messages(long_term_idle_user) idle_user_msg_count = len(idle_user_msg_list) self.assertNotEqual(idle_user_msg_list[-1], sent_message) with queries_captured() as queries: add_missing_messages(long_term_idle_user) self.assert_length(queries, 6) idle_user_msg_list = get_user_messages(long_term_idle_user) self.assertEqual(len(idle_user_msg_list), idle_user_msg_count + 1) self.assertEqual(idle_user_msg_list[-1], sent_message) long_term_idle_user.refresh_from_db() self.assertEqual(long_term_idle_user.last_active_message_id, sent_message.id) # Test that add_missing_messages() only adds messages that aren't # already present in the UserMessage table. This test works on the # fact that previous test just above this added a message but didn't # updated the last_active_message_id field for the user. sent_message = send_fake_message('Test Message 2', stream) idle_user_msg_list = get_user_messages(long_term_idle_user) idle_user_msg_count = len(idle_user_msg_list) self.assertNotEqual(idle_user_msg_list[-1], sent_message) with queries_captured() as queries: add_missing_messages(long_term_idle_user) self.assert_length(queries, 7) idle_user_msg_list = get_user_messages(long_term_idle_user) self.assertEqual(len(idle_user_msg_list), idle_user_msg_count + 1) self.assertEqual(idle_user_msg_list[-1], sent_message) long_term_idle_user.refresh_from_db() self.assertEqual(long_term_idle_user.last_active_message_id, sent_message.id) # Test UserMessage rows are created correctly in case of stream # Subscription was altered by admin while user was away. # Test for a public stream. sent_message_list = [] sent_message_list.append(send_fake_message('Test Message 3', stream)) # Alter subscription to stream. self.unsubscribe(long_term_idle_user, stream_name) send_fake_message('Test Message 4', stream) self.subscribe(long_term_idle_user, stream_name) sent_message_list.append(send_fake_message('Test Message 5', stream)) sent_message_list.reverse() idle_user_msg_list = get_user_messages(long_term_idle_user) idle_user_msg_count = len(idle_user_msg_list) for sent_message in sent_message_list: self.assertNotEqual(idle_user_msg_list.pop(), sent_message) with queries_captured() as queries: add_missing_messages(long_term_idle_user) self.assert_length(queries, 6) idle_user_msg_list = get_user_messages(long_term_idle_user) self.assertEqual(len(idle_user_msg_list), idle_user_msg_count + 2) for sent_message in sent_message_list: self.assertEqual(idle_user_msg_list.pop(), sent_message) long_term_idle_user.refresh_from_db() self.assertEqual(long_term_idle_user.last_active_message_id, sent_message_list[0].id) # Test consecutive subscribe/unsubscribe in a public stream sent_message_list = [] sent_message_list.append(send_fake_message('Test Message 6', stream)) # Unsubscribe from stream and then immediately subscribe back again. self.unsubscribe(long_term_idle_user, stream_name) self.subscribe(long_term_idle_user, stream_name) sent_message_list.append(send_fake_message('Test Message 7', stream)) # Again unsubscribe from stream and send a message. # This will make sure that if initially in a unsubscribed state # a consecutive subscribe/unsubscribe doesn't misbehave. self.unsubscribe(long_term_idle_user, stream_name) send_fake_message('Test Message 8', stream) # Do a subscribe and unsubscribe immediately. self.subscribe(long_term_idle_user, stream_name) self.unsubscribe(long_term_idle_user, stream_name) sent_message_list.reverse() idle_user_msg_list = get_user_messages(long_term_idle_user) idle_user_msg_count = len(idle_user_msg_list) for sent_message in sent_message_list: self.assertNotEqual(idle_user_msg_list.pop(), sent_message) with queries_captured() as queries: add_missing_messages(long_term_idle_user) self.assert_length(queries, 6) idle_user_msg_list = get_user_messages(long_term_idle_user) self.assertEqual(len(idle_user_msg_list), idle_user_msg_count + 2) for sent_message in sent_message_list: self.assertEqual(idle_user_msg_list.pop(), sent_message) long_term_idle_user.refresh_from_db() self.assertEqual(long_term_idle_user.last_active_message_id, sent_message_list[0].id) # Test for when user unsubscribes before soft deactivation # (must reactivate them in order to do this). do_soft_activate_users([long_term_idle_user]) self.subscribe(long_term_idle_user, stream_name) # Send a real message to update last_active_message_id sent_message_id = self.send_stream_message(sender, stream_name, 'Test Message 9') self.unsubscribe(long_term_idle_user, stream_name) # Soft deactivate and send another message to the unsubscribed stream. with self.assertLogs(level='INFO') as info_logs: do_soft_deactivate_users([long_term_idle_user]) self.assertEqual(info_logs.output, [ 'INFO:root:Soft-deactivated batch of 1 users; 0 remain to process' ]) send_fake_message('Test Message 10', stream) idle_user_msg_list = get_user_messages(long_term_idle_user) idle_user_msg_count = len(idle_user_msg_list) self.assertEqual(idle_user_msg_list[-1].id, sent_message_id) with queries_captured() as queries: add_missing_messages(long_term_idle_user) # There are no streams to fetch missing messages from, so # the Message.objects query will be avoided. self.assert_length(queries, 4) idle_user_msg_list = get_user_messages(long_term_idle_user) # No new UserMessage rows should have been created. self.assertEqual(len(idle_user_msg_list), idle_user_msg_count) # Note: At this point in this test we have long_term_idle_user # unsubscribed from the 'Denmark' stream. # Test for a Private Stream. stream_name = "Core" private_stream = self.make_stream('Core', invite_only=True) self.subscribe(self.example_user("iago"), stream_name) sent_message_list = [] send_fake_message('Test Message 11', private_stream) self.subscribe(self.example_user("hamlet"), stream_name) sent_message_list.append( send_fake_message('Test Message 12', private_stream)) self.unsubscribe(long_term_idle_user, stream_name) send_fake_message('Test Message 13', private_stream) self.subscribe(long_term_idle_user, stream_name) sent_message_list.append( send_fake_message('Test Message 14', private_stream)) sent_message_list.reverse() idle_user_msg_list = get_user_messages(long_term_idle_user) idle_user_msg_count = len(idle_user_msg_list) for sent_message in sent_message_list: self.assertNotEqual(idle_user_msg_list.pop(), sent_message) with queries_captured() as queries: add_missing_messages(long_term_idle_user) self.assert_length(queries, 6) idle_user_msg_list = get_user_messages(long_term_idle_user) self.assertEqual(len(idle_user_msg_list), idle_user_msg_count + 2) for sent_message in sent_message_list: self.assertEqual(idle_user_msg_list.pop(), sent_message) long_term_idle_user.refresh_from_db() self.assertEqual(long_term_idle_user.last_active_message_id, sent_message_list[0].id)