def test_remove_muted_topic(self) -> None: user = self.example_user('hamlet') email = user.email realm = user.realm self.login(email) stream = get_stream(u'Verona', realm) recipient = get_stream_recipient(stream.id) url = '/api/v1/users/me/subscriptions/muted_topics' payloads = [ {'stream': stream.name, 'topic': 'vERONA3', 'op': 'remove'}, {'stream_id': stream.id, 'topic': 'vEroNA3', 'op': 'remove'}, ] for data in payloads: add_topic_mute( user_profile=user, stream_id=stream.id, recipient_id=recipient.id, topic_name='Verona3', ) self.assertIn([stream.name, 'Verona3'], get_topic_mutes(user)) result = self.api_patch(email, url, data) self.assert_json_success(result) self.assertNotIn([stream.name, 'Verona3'], get_topic_mutes(user)) self.assertFalse(topic_is_muted(user, stream.id, 'verona3'))
def test_muted_topic_add_invalid(self) -> None: user = self.example_user('hamlet') email = user.email realm = user.realm self.login(email) stream = get_stream('Verona', realm) recipient = get_stream_recipient(stream.id) add_topic_mute( user_profile=user, stream_id=stream.id, recipient_id=recipient.id, topic_name=u'Verona3', ) url = '/api/v1/users/me/subscriptions/muted_topics' data = {'stream': stream.name, 'topic': 'Verona3', 'op': 'add'} # type: Dict[str, Any] result = self.api_patch(email, url, data) self.assert_json_error(result, "Topic already muted") data = {'stream_id': 999999999, 'topic': 'Verona3', 'op': 'add'} result = self.api_patch(email, url, data) self.assert_json_error(result, "Invalid stream id") data = {'topic': 'Verona3', 'op': 'add'} result = self.api_patch(email, url, data) self.assert_json_error(result, "Please supply 'stream'.") data = {'stream': stream.name, 'stream_id': stream.id, 'topic': 'Verona3', 'op': 'add'} result = self.api_patch(email, url, data) self.assert_json_error(result, "Please choose one: 'stream' or 'stream_id'.")
def mute_user(user: UserProfile) -> None: add_topic_mute( user_profile=user, stream_id=stream.id, recipient_id=recipient.id, topic_name='test TOPIC', )
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 mute_topic(stream_name, topic_name): # type: (Text, Text) -> 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 mute_topic(stream_name, topic_name): # type: (Text, Text) -> 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 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 assert recipient is not None add_topic_mute( user_profile=user_profile, stream_id=stream.id, recipient_id=recipient.id, topic_name=topic_name, )
def test_add_muted_topic(self) -> None: user = self.example_user("hamlet") self.login_user(user) stream = get_stream("Verona", user.realm) url = "/api/v1/users/me/subscriptions/muted_topics" payloads: List[Dict[str, object]] = [ {"stream": stream.name, "topic": "Verona3", "op": "add"}, {"stream_id": stream.id, "topic": "Verona3", "op": "add"}, ] mock_date_muted = datetime(2020, 1, 1, tzinfo=timezone.utc).timestamp() for data in payloads: with mock.patch( "zerver.views.muting.timezone_now", return_value=datetime(2020, 1, 1, tzinfo=timezone.utc), ): result = self.api_patch(user, url, data) self.assert_json_success(result) self.assertIn((stream.name, "Verona3", mock_date_muted), get_topic_mutes(user)) self.assertTrue(topic_is_muted(user, stream.id, "verona3")) remove_topic_mute( user_profile=user, stream_id=stream.id, topic_name="Verona3", ) # Verify the error handling for the database level # IntegrityError we'll get with a race between two processes # trying to mute the topic. To do this, we patch the # topic_is_muted function to always return False when trying # to mute a topic that is already muted. add_topic_mute( user_profile=user, stream_id=stream.id, recipient_id=stream.recipient.id, topic_name="Verona3", date_muted=datetime(2020, 1, 1, tzinfo=timezone.utc), ) with mock.patch("zerver.views.muting.topic_is_muted", return_value=False): result = self.api_patch(user, url, data) self.assert_json_error(result, "Topic already muted")
def test_muted_topic_add_invalid(self) -> None: user = self.example_user("hamlet") realm = user.realm self.login_user(user) stream = get_stream("Verona", 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="Verona3", date_muted=timezone_now(), ) url = "/api/v1/users/me/subscriptions/muted_topics" data: Dict[str, Any] = { "stream": stream.name, "topic": "Verona3", "op": "add" } result = self.api_patch(user, url, data) self.assert_json_error(result, "Topic already muted") data = {"stream_id": 999999999, "topic": "Verona3", "op": "add"} result = self.api_patch(user, url, data) self.assert_json_error(result, "Invalid stream id") data = {"topic": "Verona3", "op": "add"} result = self.api_patch(user, url, data) self.assert_json_error(result, "Please supply 'stream'.") data = { "stream": stream.name, "stream_id": stream.id, "topic": "Verona3", "op": "add" } result = self.api_patch(user, url, data) self.assert_json_error(result, "Please choose one: 'stream' or 'stream_id'.")
def test_muted_topic_add_invalid(self) -> None: user = self.example_user('hamlet') email = user.email realm = user.realm self.login(email) stream = get_stream('Verona', realm) recipient = get_stream_recipient(stream.id) add_topic_mute( user_profile=user, stream_id=stream.id, recipient_id=recipient.id, topic_name=u'Verona3', date_muted=timezone_now(), ) url = '/api/v1/users/me/subscriptions/muted_topics' data = { 'stream': stream.name, 'topic': 'Verona3', 'op': 'add' } # type: Dict[str, Any] result = self.api_patch(email, url, data) self.assert_json_error(result, "Topic already muted") data = {'stream_id': 999999999, 'topic': 'Verona3', 'op': 'add'} result = self.api_patch(email, url, data) self.assert_json_error(result, "Invalid stream id") data = {'topic': 'Verona3', 'op': 'add'} result = self.api_patch(email, url, data) self.assert_json_error(result, "Please supply 'stream'.") data = { 'stream': stream.name, 'stream_id': stream.id, 'topic': 'Verona3', 'op': 'add' } result = self.api_patch(email, url, data) self.assert_json_error(result, "Please choose one: 'stream' or 'stream_id'.")
def test_muted_topic_add_invalid(self) -> None: self.user_profile = self.example_user('hamlet') email = self.user_profile.email self.login(email) realm = self.user_profile.realm stream = get_stream(u'Verona', realm) recipient = get_stream_recipient(stream.id) add_topic_mute( user_profile=self.user_profile, stream_id=stream.id, recipient_id=recipient.id, topic_name=u'Verona3', ) url = '/api/v1/users/me/subscriptions/muted_topics' data = {'stream': 'Verona', 'topic': 'Verona3', 'op': 'add'} result = self.api_patch(email, url, data) self.assert_json_error(result, "Topic already muted")
def test_remove_muted_topic(self) -> None: user = self.example_user("hamlet") realm = user.realm self.login_user(user) stream = get_stream("Verona", realm) recipient = stream.recipient url = "/api/v1/users/me/subscriptions/muted_topics" payloads = [ { "stream": stream.name, "topic": "vERONA3", "op": "remove" }, { "stream_id": stream.id, "topic": "vEroNA3", "op": "remove" }, ] mock_date_muted = datetime(2020, 1, 1, tzinfo=timezone.utc).timestamp() assert recipient is not None for data in payloads: add_topic_mute( user_profile=user, stream_id=stream.id, recipient_id=recipient.id, topic_name="Verona3", date_muted=datetime(2020, 1, 1, tzinfo=timezone.utc), ) self.assertIn((stream.name, "Verona3", mock_date_muted), get_topic_mutes(user)) result = self.api_patch(user, url, data) self.assert_json_success(result) self.assertNotIn((stream.name, "Verona3", mock_date_muted), get_topic_mutes(user)) self.assertFalse(topic_is_muted(user, stream.id, "verona3"))
def test_remove_muted_topic(self) -> None: user = self.example_user('hamlet') realm = user.realm self.login_user(user) stream = get_stream('Verona', realm) recipient = stream.recipient url = '/api/v1/users/me/subscriptions/muted_topics' payloads = [ { 'stream': stream.name, 'topic': 'vERONA3', 'op': 'remove' }, { 'stream_id': stream.id, 'topic': 'vEroNA3', 'op': 'remove' }, ] mock_date_muted = datetime.timestamp(datetime(2020, 1, 1)) for data in payloads: add_topic_mute( user_profile=user, stream_id=stream.id, recipient_id=recipient.id, topic_name='Verona3', date_muted=datetime(2020, 1, 1), ) self.assertIn([stream.name, 'Verona3', mock_date_muted], get_topic_mutes(user)) result = self.api_patch(user, url, data) self.assert_json_success(result) self.assertNotIn([stream.name, 'Verona3', mock_date_muted], get_topic_mutes(user)) self.assertFalse(topic_is_muted(user, stream.id, 'verona3'))
def test_remove_muted_topic(self) -> None: self.user_profile = self.example_user('hamlet') email = self.user_profile.email self.login(email) realm = self.user_profile.realm stream = get_stream(u'Verona', realm) recipient = get_stream_recipient(stream.id) add_topic_mute( user_profile=self.user_profile, stream_id=stream.id, recipient_id=recipient.id, topic_name=u'Verona3', ) url = '/api/v1/users/me/subscriptions/muted_topics' data = {'stream': 'Verona', 'topic': 'vERONA3', 'op': 'remove'} result = self.api_patch(email, url, data) self.assert_json_success(result) user = self.example_user('hamlet') self.assertNotIn([[u'Verona', u'Verona3']], get_topic_mutes(user))
def test_remove_muted_topic(self) -> None: user = self.example_user('hamlet') email = user.email realm = user.realm self.login(email) stream = get_stream(u'Verona', realm) recipient = get_stream_recipient(stream.id) url = '/api/v1/users/me/subscriptions/muted_topics' payloads = [ { 'stream': stream.name, 'topic': 'vERONA3', 'op': 'remove' }, { 'stream_id': stream.id, 'topic': 'vEroNA3', 'op': 'remove' }, ] for data in payloads: add_topic_mute( user_profile=user, stream_id=stream.id, recipient_id=recipient.id, topic_name='Verona3', date_muted=timezone_now(), ) self.assertIn([stream.name, 'Verona3'], get_topic_mutes(user)) result = self.api_patch(email, url, data) self.assert_json_success(result) self.assertNotIn([stream.name, 'Verona3'], get_topic_mutes(user)) self.assertFalse(topic_is_muted(user, stream.id, 'verona3'))
def test_get_deactivated_muted_topic(self) -> None: user = self.example_user("hamlet") self.login_user(user) stream = get_stream("Verona", user.realm) recipient = stream.recipient mock_date_muted = datetime(2020, 1, 1, tzinfo=timezone.utc).timestamp() assert recipient is not None add_topic_mute( user_profile=user, stream_id=stream.id, recipient_id=recipient.id, topic_name="Verona3", date_muted=datetime(2020, 1, 1, tzinfo=timezone.utc), ) stream.deactivated = True stream.save() self.assertNotIn((stream.name, "Verona3", mock_date_muted), get_topic_mutes(user)) self.assertIn((stream.name, "Verona3", mock_date_muted), get_topic_mutes(user, True))
def test_stream_recipient_info(self) -> None: hamlet = self.example_user('hamlet') cordelia = self.example_user('cordelia') othello = self.example_user('othello') realm = hamlet.realm stream_name = 'Test Stream' topic_name = 'test topic' for user in [hamlet, cordelia, othello]: self.subscribe(user, stream_name) stream = get_stream(stream_name, realm) recipient = get_stream_recipient(stream.id) stream_topic = StreamTopicTarget( stream_id=stream.id, topic_name=topic_name, ) sub = get_subscription(stream_name, hamlet) sub.push_notifications = True sub.save() info = get_recipient_info( recipient=recipient, sender_id=hamlet.id, stream_topic=stream_topic, ) all_user_ids = {hamlet.id, cordelia.id, othello.id} expected_info = dict( active_user_ids=all_user_ids, push_notify_user_ids=set(), stream_push_user_ids={hamlet.id}, stream_email_user_ids=set(), um_eligible_user_ids=all_user_ids, long_term_idle_user_ids=set(), default_bot_user_ids=set(), service_bot_tuples=[], ) self.assertEqual(info, expected_info) # Now mute Hamlet to omit him from stream_push_user_ids. add_topic_mute( user_profile=hamlet, stream_id=stream.id, recipient_id=recipient.id, topic_name=topic_name, ) info = get_recipient_info( recipient=recipient, sender_id=hamlet.id, stream_topic=stream_topic, ) self.assertEqual(info['stream_push_user_ids'], set()) # Add a service bot. service_bot = do_create_user( email='*****@*****.**', password='', realm=realm, full_name='', short_name='', bot_type=UserProfile.EMBEDDED_BOT, ) info = get_recipient_info( recipient=recipient, sender_id=hamlet.id, stream_topic=stream_topic, possibly_mentioned_user_ids={service_bot.id} ) self.assertEqual(info['service_bot_tuples'], [ (service_bot.id, UserProfile.EMBEDDED_BOT), ]) # Add a normal bot. normal_bot = do_create_user( email='*****@*****.**', password='', realm=realm, full_name='', short_name='', bot_type=UserProfile.DEFAULT_BOT, ) info = get_recipient_info( recipient=recipient, sender_id=hamlet.id, stream_topic=stream_topic, possibly_mentioned_user_ids={service_bot.id, normal_bot.id} ) self.assertEqual(info['default_bot_user_ids'], {normal_bot.id})
def test_stream_recipient_info(self) -> None: hamlet = self.example_user('hamlet') cordelia = self.example_user('cordelia') othello = self.example_user('othello') realm = hamlet.realm stream_name = 'Test Stream' topic_name = 'test topic' for user in [hamlet, cordelia, othello]: self.subscribe(user, stream_name) stream = get_stream(stream_name, realm) recipient = get_stream_recipient(stream.id) stream_topic = StreamTopicTarget( stream_id=stream.id, topic_name=topic_name, ) sub = get_subscription(stream_name, hamlet) sub.push_notifications = True sub.save() info = get_recipient_info( recipient=recipient, sender_id=hamlet.id, stream_topic=stream_topic, ) all_user_ids = {hamlet.id, cordelia.id, othello.id} expected_info = dict( active_user_ids=all_user_ids, push_notify_user_ids=set(), stream_push_user_ids={hamlet.id}, stream_email_user_ids=set(), um_eligible_user_ids=all_user_ids, long_term_idle_user_ids=set(), default_bot_user_ids=set(), service_bot_tuples=[], ) self.assertEqual(info, expected_info) # Now mute Hamlet to omit him from stream_push_user_ids. add_topic_mute( user_profile=hamlet, stream_id=stream.id, recipient_id=recipient.id, topic_name=topic_name, ) info = get_recipient_info( recipient=recipient, sender_id=hamlet.id, stream_topic=stream_topic, ) self.assertEqual(info['stream_push_user_ids'], set()) # Add a service bot. service_bot = do_create_user( email='*****@*****.**', password='', realm=realm, full_name='', short_name='', bot_type=UserProfile.EMBEDDED_BOT, ) info = get_recipient_info(recipient=recipient, sender_id=hamlet.id, stream_topic=stream_topic, possibly_mentioned_user_ids={service_bot.id}) self.assertEqual(info['service_bot_tuples'], [ (service_bot.id, UserProfile.EMBEDDED_BOT), ]) # Add a normal bot. normal_bot = do_create_user( email='*****@*****.**', password='', realm=realm, full_name='', short_name='', bot_type=UserProfile.DEFAULT_BOT, ) info = get_recipient_info( recipient=recipient, sender_id=hamlet.id, stream_topic=stream_topic, possibly_mentioned_user_ids={service_bot.id, normal_bot.id}) self.assertEqual(info['default_bot_user_ids'], {normal_bot.id})
def test_import_realm(self) -> None: original_realm = Realm.objects.get(string_id='zulip') RealmEmoji.objects.get(realm=original_realm).delete() # data to test import of huddles huddle = [self.example_email('hamlet'), self.example_email('othello')] self.send_huddle_message(self.example_email('cordelia'), huddle, 'test huddle message') # data to test import of hotspots sample_user = self.example_user('hamlet') UserHotspot.objects.create(user=sample_user, hotspot='intro_streams') # data to test import of muted topic stream = get_stream(u'Verona', original_realm) add_topic_mute(user_profile=sample_user, stream_id=stream.id, recipient_id=get_stream_recipient(stream.id).id, topic_name=u'Verona2') # data to test import of botstoragedata and botconfigdata bot_profile = do_create_user(email="*****@*****.**", password="******", realm=original_realm, full_name="bot", short_name="bot", bot_type=UserProfile.EMBEDDED_BOT, bot_owner=sample_user) storage = StateHandler(bot_profile) storage.put('some key', 'some value') set_bot_config(bot_profile, 'entry 1', 'value 1') self._export_realm(original_realm) with patch('logging.info'): with self.settings(BILLING_ENABLED=False): do_import_realm('var/test-export', 'test-zulip') # sanity checks # test realm self.assertTrue(Realm.objects.filter(string_id='test-zulip').exists()) imported_realm = Realm.objects.get(string_id='test-zulip') self.assertNotEqual(imported_realm.id, original_realm.id) def assert_realm_values(f: Callable[[Realm], Any], equal: bool = True) -> None: orig_realm_result = f(original_realm) imported_realm_result = f(imported_realm) # orig_realm_result should be truthy and have some values, otherwise # the test is kind of meaningless assert (orig_realm_result) if equal: self.assertEqual(orig_realm_result, imported_realm_result) else: self.assertNotEqual(orig_realm_result, imported_realm_result) # test users assert_realm_values( lambda r: {user.email for user in r.get_admin_users()}) assert_realm_values( lambda r: {user.email for user in r.get_active_users()}) # test stream assert_realm_values( lambda r: {stream.name for stream in get_active_streams(r)}) # test recipients def get_recipient_stream(r: Realm) -> Stream: return get_stream_recipient( Stream.objects.get(name='Verona', realm=r).id) def get_recipient_user(r: Realm) -> UserProfile: return get_personal_recipient( UserProfile.objects.get(full_name='Iago', realm=r).id) assert_realm_values(lambda r: get_recipient_stream(r).type) assert_realm_values(lambda r: get_recipient_user(r).type) # test subscription def get_subscribers(recipient: Recipient) -> Set[str]: subscriptions = Subscription.objects.filter(recipient=recipient) users = {sub.user_profile.email for sub in subscriptions} return users assert_realm_values(lambda r: get_subscribers(get_recipient_stream(r))) assert_realm_values(lambda r: get_subscribers(get_recipient_user(r))) # test custom profile fields def get_custom_profile_field_names(r: Realm) -> Set[str]: custom_profile_fields = CustomProfileField.objects.filter(realm=r) custom_profile_field_names = { field.name for field in custom_profile_fields } return custom_profile_field_names assert_realm_values(get_custom_profile_field_names) def get_custom_profile_with_field_type_user( r: Realm) -> Tuple[Set[Any], Set[Any], Set[FrozenSet[str]]]: fields = CustomProfileField.objects.filter( field_type=CustomProfileField.USER, realm=r) def get_email(user_id: int) -> str: return UserProfile.objects.get(id=user_id).email def get_email_from_value( field_value: CustomProfileFieldValue) -> Set[str]: user_id_list = ujson.loads(field_value.value) return {get_email(user_id) for user_id in user_id_list} def custom_profile_field_values_for( fields: List[CustomProfileField]) -> Set[FrozenSet[str]]: user_emails = set() # type: Set[FrozenSet[str]] for field in fields: values = CustomProfileFieldValue.objects.filter( field=field) for value in values: user_emails.add(frozenset(get_email_from_value(value))) return user_emails field_names, field_hints = (set() for i in range(2)) for field in fields: field_names.add(field.name) field_hints.add(field.hint) return (field_hints, field_names, custom_profile_field_values_for(fields)) assert_realm_values(get_custom_profile_with_field_type_user) # test realmauditlog def get_realm_audit_log_event_type(r: Realm) -> Set[str]: realmauditlogs = RealmAuditLog.objects.filter(realm=r).exclude( event_type=RealmAuditLog.REALM_PLAN_TYPE_CHANGED) realmauditlog_event_type = { log.event_type for log in realmauditlogs } return realmauditlog_event_type assert_realm_values(get_realm_audit_log_event_type) # test huddles def get_huddle_hashes(r: str) -> str: short_names = ['cordelia', 'hamlet', 'othello'] user_id_list = [ UserProfile.objects.get(realm=r, short_name=name).id for name in short_names ] huddle_hash = get_huddle_hash(user_id_list) return huddle_hash assert_realm_values(get_huddle_hashes, equal=False) def get_huddle_message(r: str) -> str: huddle_hash = get_huddle_hashes(r) huddle_id = Huddle.objects.get(huddle_hash=huddle_hash).id huddle_recipient = Recipient.objects.get(type_id=huddle_id, type=3) huddle_message = Message.objects.get(recipient=huddle_recipient) return huddle_message.content assert_realm_values(get_huddle_message) self.assertEqual(get_huddle_message(imported_realm), 'test huddle message') # test userhotspot def get_user_hotspots(r: str) -> Set[str]: user_profile = UserProfile.objects.get(realm=r, short_name='hamlet') hotspots = UserHotspot.objects.filter(user=user_profile) user_hotspots = {hotspot.hotspot for hotspot in hotspots} return user_hotspots assert_realm_values(get_user_hotspots) # test muted topics def get_muted_topics(r: Realm) -> Set[str]: user_profile = UserProfile.objects.get(realm=r, short_name='hamlet') muted_topics = MutedTopic.objects.filter(user_profile=user_profile) topic_names = { muted_topic.topic_name for muted_topic in muted_topics } return topic_names assert_realm_values(get_muted_topics) # test usergroups assert_realm_values( lambda r: {group.name for group in UserGroup.objects.filter(realm=r)}) def get_user_membership(r: str) -> Set[str]: usergroup = UserGroup.objects.get(realm=r, name='hamletcharacters') usergroup_membership = UserGroupMembership.objects.filter( user_group=usergroup) users = { membership.user_profile.email for membership in usergroup_membership } return users assert_realm_values(get_user_membership) # test botstoragedata and botconfigdata def get_botstoragedata(r: Realm) -> Dict[str, Any]: bot_profile = UserProfile.objects.get(full_name="bot", realm=r) bot_storage_data = BotStorageData.objects.get( bot_profile=bot_profile) return { 'key': bot_storage_data.key, 'data': bot_storage_data.value } assert_realm_values(get_botstoragedata) def get_botconfigdata(r: Realm) -> Dict[str, Any]: bot_profile = UserProfile.objects.get(full_name="bot", realm=r) bot_config_data = BotConfigData.objects.get( bot_profile=bot_profile) return {'key': bot_config_data.key, 'data': bot_config_data.value} assert_realm_values(get_botconfigdata) # test messages def get_stream_messages(r: Realm) -> Message: recipient = get_recipient_stream(r) messages = Message.objects.filter(recipient=recipient) return messages def get_stream_topics(r: Realm) -> Set[str]: messages = get_stream_messages(r) topics = {m.topic_name() for m in messages} return topics assert_realm_values(get_stream_topics) # test usermessages def get_usermessages_user(r: Realm) -> Set[Any]: messages = get_stream_messages(r).order_by('content') usermessage = UserMessage.objects.filter(message=messages[0]) usermessage_user = {um.user_profile.email for um in usermessage} return usermessage_user assert_realm_values(get_usermessages_user)
def test_import_realm(self) -> None: original_realm = Realm.objects.get(string_id='zulip') RealmEmoji.objects.get(realm=original_realm).delete() # data to test import of huddles huddle = [self.example_email('hamlet'), self.example_email('othello')] self.send_huddle_message(self.example_email('cordelia'), huddle, 'test huddle message') user_mention_message = '@**King Hamlet** Hello' self.send_stream_message(self.example_email("iago"), "Verona", user_mention_message) stream_mention_message = 'Subscribe to #**Denmark**' self.send_stream_message(self.example_email("hamlet"), "Verona", stream_mention_message) user_group_mention_message = 'Hello @*hamletcharacters*' self.send_stream_message(self.example_email("othello"), "Verona", user_group_mention_message) special_characters_message = "```\n'\n```\n@**Polonius**" self.send_stream_message(self.example_email("iago"), "Denmark", special_characters_message) # data to test import of hotspots sample_user = self.example_user('hamlet') UserHotspot.objects.create(user=sample_user, hotspot='intro_streams') # data to test import of muted topic stream = get_stream(u'Verona', original_realm) add_topic_mute(user_profile=sample_user, stream_id=stream.id, recipient_id=get_stream_recipient(stream.id).id, topic_name=u'Verona2') # data to test import of botstoragedata and botconfigdata bot_profile = do_create_user(email="*****@*****.**", password="******", realm=original_realm, full_name="bot", short_name="bot", bot_type=UserProfile.EMBEDDED_BOT, bot_owner=sample_user) storage = StateHandler(bot_profile) storage.put('some key', 'some value') set_bot_config(bot_profile, 'entry 1', 'value 1') self._export_realm(original_realm) with patch('logging.info'): with self.settings(BILLING_ENABLED=False): do_import_realm( os.path.join(settings.TEST_WORKER_DIR, 'test-export'), 'test-zulip') # sanity checks # test realm self.assertTrue(Realm.objects.filter(string_id='test-zulip').exists()) imported_realm = Realm.objects.get(string_id='test-zulip') self.assertNotEqual(imported_realm.id, original_realm.id) def assert_realm_values(f: Callable[[Realm], Any], equal: bool = True) -> None: orig_realm_result = f(original_realm) imported_realm_result = f(imported_realm) # orig_realm_result should be truthy and have some values, otherwise # the test is kind of meaningless assert (orig_realm_result) if equal: self.assertEqual(orig_realm_result, imported_realm_result) else: self.assertNotEqual(orig_realm_result, imported_realm_result) # test users assert_realm_values( lambda r: {user.email for user in r.get_admin_users_and_bots()}) assert_realm_values( lambda r: {user.email for user in r.get_active_users()}) # test stream assert_realm_values( lambda r: {stream.name for stream in get_active_streams(r)}) # test recipients def get_recipient_stream(r: Realm) -> Stream: return get_stream_recipient( Stream.objects.get(name='Verona', realm=r).id) def get_recipient_user(r: Realm) -> UserProfile: return get_personal_recipient( UserProfile.objects.get(full_name='Iago', realm=r).id) assert_realm_values(lambda r: get_recipient_stream(r).type) assert_realm_values(lambda r: get_recipient_user(r).type) # test subscription def get_subscribers(recipient: Recipient) -> Set[str]: subscriptions = Subscription.objects.filter(recipient=recipient) users = {sub.user_profile.email for sub in subscriptions} return users assert_realm_values(lambda r: get_subscribers(get_recipient_stream(r))) assert_realm_values(lambda r: get_subscribers(get_recipient_user(r))) # test custom profile fields def get_custom_profile_field_names(r: Realm) -> Set[str]: custom_profile_fields = CustomProfileField.objects.filter(realm=r) custom_profile_field_names = { field.name for field in custom_profile_fields } return custom_profile_field_names assert_realm_values(get_custom_profile_field_names) def get_custom_profile_with_field_type_user( r: Realm) -> Tuple[Set[Any], Set[Any], Set[FrozenSet[str]]]: fields = CustomProfileField.objects.filter( field_type=CustomProfileField.USER, realm=r) def get_email(user_id: int) -> str: return UserProfile.objects.get(id=user_id).email def get_email_from_value( field_value: CustomProfileFieldValue) -> Set[str]: user_id_list = ujson.loads(field_value.value) return {get_email(user_id) for user_id in user_id_list} def custom_profile_field_values_for( fields: List[CustomProfileField]) -> Set[FrozenSet[str]]: user_emails = set() # type: Set[FrozenSet[str]] for field in fields: values = CustomProfileFieldValue.objects.filter( field=field) for value in values: user_emails.add(frozenset(get_email_from_value(value))) return user_emails field_names, field_hints = (set() for i in range(2)) for field in fields: field_names.add(field.name) field_hints.add(field.hint) return (field_hints, field_names, custom_profile_field_values_for(fields)) assert_realm_values(get_custom_profile_with_field_type_user) # test realmauditlog def get_realm_audit_log_event_type(r: Realm) -> Set[str]: realmauditlogs = RealmAuditLog.objects.filter(realm=r).exclude( event_type=RealmAuditLog.REALM_PLAN_TYPE_CHANGED) realmauditlog_event_type = { log.event_type for log in realmauditlogs } return realmauditlog_event_type assert_realm_values(get_realm_audit_log_event_type) # test huddles def get_huddle_hashes(r: str) -> str: short_names = ['cordelia', 'hamlet', 'othello'] user_id_list = [ UserProfile.objects.get(realm=r, short_name=name).id for name in short_names ] huddle_hash = get_huddle_hash(user_id_list) return huddle_hash assert_realm_values(get_huddle_hashes, equal=False) def get_huddle_message(r: str) -> str: huddle_hash = get_huddle_hashes(r) huddle_id = Huddle.objects.get(huddle_hash=huddle_hash).id huddle_recipient = Recipient.objects.get(type_id=huddle_id, type=3) huddle_message = Message.objects.get(recipient=huddle_recipient) return huddle_message.content assert_realm_values(get_huddle_message) self.assertEqual(get_huddle_message(imported_realm), 'test huddle message') # test userhotspot def get_user_hotspots(r: str) -> Set[str]: user_profile = UserProfile.objects.get(realm=r, short_name='hamlet') hotspots = UserHotspot.objects.filter(user=user_profile) user_hotspots = {hotspot.hotspot for hotspot in hotspots} return user_hotspots assert_realm_values(get_user_hotspots) # test muted topics def get_muted_topics(r: Realm) -> Set[str]: user_profile = UserProfile.objects.get(realm=r, short_name='hamlet') muted_topics = MutedTopic.objects.filter(user_profile=user_profile) topic_names = { muted_topic.topic_name for muted_topic in muted_topics } return topic_names assert_realm_values(get_muted_topics) # test usergroups assert_realm_values( lambda r: {group.name for group in UserGroup.objects.filter(realm=r)}) def get_user_membership(r: str) -> Set[str]: usergroup = UserGroup.objects.get(realm=r, name='hamletcharacters') usergroup_membership = UserGroupMembership.objects.filter( user_group=usergroup) users = { membership.user_profile.email for membership in usergroup_membership } return users assert_realm_values(get_user_membership) # test botstoragedata and botconfigdata def get_botstoragedata(r: Realm) -> Dict[str, Any]: bot_profile = UserProfile.objects.get(full_name="bot", realm=r) bot_storage_data = BotStorageData.objects.get( bot_profile=bot_profile) return { 'key': bot_storage_data.key, 'data': bot_storage_data.value } assert_realm_values(get_botstoragedata) def get_botconfigdata(r: Realm) -> Dict[str, Any]: bot_profile = UserProfile.objects.get(full_name="bot", realm=r) bot_config_data = BotConfigData.objects.get( bot_profile=bot_profile) return {'key': bot_config_data.key, 'data': bot_config_data.value} assert_realm_values(get_botconfigdata) # test messages def get_stream_messages(r: Realm) -> Message: recipient = get_recipient_stream(r) messages = Message.objects.filter(recipient=recipient) return messages def get_stream_topics(r: Realm) -> Set[str]: messages = get_stream_messages(r) topics = {m.topic_name() for m in messages} return topics assert_realm_values(get_stream_topics) # test usermessages def get_usermessages_user(r: Realm) -> Set[Any]: messages = get_stream_messages(r).order_by('content') usermessage = UserMessage.objects.filter(message=messages[0]) usermessage_user = {um.user_profile.email for um in usermessage} return usermessage_user assert_realm_values(get_usermessages_user) # tests to make sure that various data-*-ids in rendered_content # are replaced correctly with the values of newer realm. def get_user_mention(r: Realm) -> Set[Any]: mentioned_user = UserProfile.objects.get( delivery_email=self.example_email("hamlet"), realm=r) data_user_id = 'data-user-id="{}"'.format(mentioned_user.id) mention_message = get_stream_messages(r).get( rendered_content__contains=data_user_id) return mention_message.content assert_realm_values(get_user_mention) def get_stream_mention(r: Realm) -> Set[Any]: mentioned_stream = get_stream(u'Denmark', r) data_stream_id = 'data-stream-id="{}"'.format(mentioned_stream.id) mention_message = get_stream_messages(r).get( rendered_content__contains=data_stream_id) return mention_message.content assert_realm_values(get_stream_mention) def get_user_group_mention(r: Realm) -> Set[Any]: user_group = UserGroup.objects.get(realm=r, name='hamletcharacters') data_usergroup_id = 'data-user-group-id="{}"'.format(user_group.id) mention_message = get_stream_messages(r).get( rendered_content__contains=data_usergroup_id) return mention_message.content assert_realm_values(get_user_group_mention) # test to highlight that bs4 which we use to do data-**id # replacements modifies the HTML sometimes. eg replacing <br> # with </br>, ' with \' etc. The modifications doesn't # affect how the browser displays the rendered_content so we # are okay with using bs4 for this. lxml package also has # similar behavior. orig_polonius_user = UserProfile.objects.get( email=self.example_email("polonius"), realm=original_realm) original_msg = Message.objects.get(content=special_characters_message, sender__realm=original_realm) self.assertEqual(original_msg.rendered_content, ( '<div class="codehilite"><pre><span></span>'\n</pre></div>\n\n\n' '<p><span class="user-mention" data-user-id="%s">@Polonius</span></p>' % (orig_polonius_user.id, ))) imported_polonius_user = UserProfile.objects.get( email=self.example_email("polonius"), realm=imported_realm) imported_msg = Message.objects.get(content=special_characters_message, sender__realm=imported_realm) self.assertEqual(imported_msg.rendered_content, ( '<div class="codehilite"><pre><span></span>\'\n</pre></div>\n' '<p><span class="user-mention" data-user-id="%s">@Polonius</span></p>' % (imported_polonius_user.id, ))) # Check recipient_id was generated correctly for the imported users and streams. for user_profile in UserProfile.objects.filter(realm=imported_realm): self.assertEqual(user_profile.recipient_id, get_personal_recipient(user_profile.id).id) for stream in Stream.objects.filter(realm=imported_realm): self.assertEqual(stream.recipient_id, get_stream_recipient(stream.id).id)
def test_import_realm(self) -> None: original_realm = Realm.objects.get(string_id='zulip') RealmEmoji.objects.get(realm=original_realm).delete() # data to test import of huddles huddle = [ self.example_email('hamlet'), self.example_email('othello') ] self.send_huddle_message( self.example_email('cordelia'), huddle, 'test huddle message' ) # data to test import of hotspots sample_user = self.example_user('hamlet') UserHotspot.objects.create( user=sample_user, hotspot='intro_streams' ) # data to test import of muted topic stream = get_stream(u'Verona', original_realm) add_topic_mute( user_profile=sample_user, stream_id=stream.id, recipient_id=get_stream_recipient(stream.id).id, topic_name=u'Verona2') # data to test import of botstoragedata and botconfigdata bot_profile = do_create_user( email="*****@*****.**", password="******", realm=original_realm, full_name="bot", short_name="bot", bot_type=UserProfile.EMBEDDED_BOT, bot_owner=sample_user) storage = StateHandler(bot_profile) storage.put('some key', 'some value') set_bot_config(bot_profile, 'entry 1', 'value 1') self._export_realm(original_realm) with patch('logging.info'): do_import_realm('var/test-export', 'test-zulip') # sanity checks # test realm self.assertTrue(Realm.objects.filter(string_id='test-zulip').exists()) imported_realm = Realm.objects.get(string_id='test-zulip') self.assertNotEqual(imported_realm.id, original_realm.id) def assert_realm_values(f: Callable[[Realm], Any], equal: bool=True) -> None: orig_realm_result = f(original_realm) imported_realm_result = f(imported_realm) # orig_realm_result should be truthy and have some values, otherwise # the test is kind of meaningless assert(orig_realm_result) if equal: self.assertEqual(orig_realm_result, imported_realm_result) else: self.assertNotEqual(orig_realm_result, imported_realm_result) # test users assert_realm_values( lambda r: {user.email for user in r.get_admin_users()} ) assert_realm_values( lambda r: {user.email for user in r.get_active_users()} ) # test stream assert_realm_values( lambda r: {stream.name for stream in get_active_streams(r)} ) # test recipients def get_recipient_stream(r: Realm) -> Stream: return get_stream_recipient( Stream.objects.get(name='Verona', realm=r).id ) def get_recipient_user(r: Realm) -> UserProfile: return get_personal_recipient( UserProfile.objects.get(full_name='Iago', realm=r).id ) assert_realm_values(lambda r: get_recipient_stream(r).type) assert_realm_values(lambda r: get_recipient_user(r).type) # test subscription def get_subscribers(recipient: Recipient) -> Set[str]: subscriptions = Subscription.objects.filter(recipient=recipient) users = {sub.user_profile.email for sub in subscriptions} return users assert_realm_values( lambda r: get_subscribers(get_recipient_stream(r)) ) assert_realm_values( lambda r: get_subscribers(get_recipient_user(r)) ) # test custom profile fields def get_custom_profile_field_names(r: Realm) -> Set[str]: custom_profile_fields = CustomProfileField.objects.filter(realm=r) custom_profile_field_names = {field.name for field in custom_profile_fields} return custom_profile_field_names assert_realm_values(get_custom_profile_field_names) def get_custom_profile_with_field_type_user(r: Realm) -> Tuple[Set[Any], Set[Any], Set[FrozenSet[str]]]: fields = CustomProfileField.objects.filter( field_type=CustomProfileField.USER, realm=r) def get_email(user_id: int) -> str: return UserProfile.objects.get(id=user_id).email def get_email_from_value(field_value: CustomProfileFieldValue) -> Set[str]: user_id_list = ujson.loads(field_value.value) return {get_email(user_id) for user_id in user_id_list} def custom_profile_field_values_for(fields: List[CustomProfileField]) -> Set[FrozenSet[str]]: user_emails = set() # type: Set[FrozenSet[str]] for field in fields: values = CustomProfileFieldValue.objects.filter(field=field) for value in values: user_emails.add(frozenset(get_email_from_value(value))) return user_emails field_names, field_hints = (set() for i in range(2)) for field in fields: field_names.add(field.name) field_hints.add(field.hint) return (field_hints, field_names, custom_profile_field_values_for(fields)) assert_realm_values(get_custom_profile_with_field_type_user) # test realmauditlog def get_realm_audit_log_event_type(r: Realm) -> Set[str]: realmauditlogs = RealmAuditLog.objects.filter(realm=r) realmauditlog_event_type = {log.event_type for log in realmauditlogs} return realmauditlog_event_type assert_realm_values(get_realm_audit_log_event_type) # test huddles def get_huddle_hashes(r: str) -> str: short_names = ['cordelia', 'hamlet', 'othello'] user_id_list = [UserProfile.objects.get(realm=r, short_name=name).id for name in short_names] huddle_hash = get_huddle_hash(user_id_list) return huddle_hash assert_realm_values(get_huddle_hashes, equal=False) def get_huddle_message(r: str) -> str: huddle_hash = get_huddle_hashes(r) huddle_id = Huddle.objects.get(huddle_hash=huddle_hash).id huddle_recipient = Recipient.objects.get(type_id=huddle_id, type=3) huddle_message = Message.objects.get(recipient=huddle_recipient) return huddle_message.content assert_realm_values(get_huddle_message) self.assertEqual(get_huddle_message(imported_realm), 'test huddle message') # test userhotspot def get_user_hotspots(r: str) -> Set[str]: user_profile = UserProfile.objects.get(realm=r, short_name='hamlet') hotspots = UserHotspot.objects.filter(user=user_profile) user_hotspots = {hotspot.hotspot for hotspot in hotspots} return user_hotspots assert_realm_values(get_user_hotspots) # test muted topics def get_muted_topics(r: Realm) -> Set[str]: user_profile = UserProfile.objects.get(realm=r, short_name='hamlet') muted_topics = MutedTopic.objects.filter(user_profile=user_profile) topic_names = {muted_topic.topic_name for muted_topic in muted_topics} return topic_names assert_realm_values(get_muted_topics) # test usergroups assert_realm_values( lambda r: {group.name for group in UserGroup.objects.filter(realm=r)} ) def get_user_membership(r: str) -> Set[str]: usergroup = UserGroup.objects.get(realm=r, name='hamletcharacters') usergroup_membership = UserGroupMembership.objects.filter(user_group=usergroup) users = {membership.user_profile.email for membership in usergroup_membership} return users assert_realm_values(get_user_membership) # test botstoragedata and botconfigdata def get_botstoragedata(r: Realm) -> Dict[str, Any]: bot_profile = UserProfile.objects.get(full_name="bot", realm=r) bot_storage_data = BotStorageData.objects.get(bot_profile=bot_profile) return {'key': bot_storage_data.key, 'data': bot_storage_data.value} assert_realm_values(get_botstoragedata) def get_botconfigdata(r: Realm) -> Dict[str, Any]: bot_profile = UserProfile.objects.get(full_name="bot", realm=r) bot_config_data = BotConfigData.objects.get(bot_profile=bot_profile) return {'key': bot_config_data.key, 'data': bot_config_data.value} assert_realm_values(get_botconfigdata) # test messages def get_stream_messages(r: Realm) -> Message: recipient = get_recipient_stream(r) messages = Message.objects.filter(recipient=recipient) return messages def get_stream_topics(r: Realm) -> Set[str]: messages = get_stream_messages(r) topics = {m.topic_name() for m in messages} return topics assert_realm_values(get_stream_topics) # test usermessages def get_usermessages_user(r: Realm) -> Set[Any]: messages = get_stream_messages(r).order_by('content') usermessage = UserMessage.objects.filter(message=messages[0]) usermessage_user = {um.user_profile.email for um in usermessage} return usermessage_user assert_realm_values(get_usermessages_user)