def test_encode_decode_nonlatin_alphabet_stream_name(self) -> None: realm = get_realm('zulip') stream_name = 'Тестовы some ascii letters' stream = ensure_stream(realm, stream_name) email_address = encode_email_address(stream) msg_string = get_email_gateway_message_string_from_address( email_address) assert msg_string is not None parts = msg_string.split('+') # Stream name should be completely stripped to '', so msg_string # should only have the email_token in it. self.assertEqual(len(parts), 1) # Correctly decode the resulting address that doesn't have the stream name: tup = decode_email_address(email_address) assert tup is not None token, show_sender = tup self.assertFalse(show_sender) self.assertEqual(token, stream.email_token) asciiable_stream_name = "ąężć" stream = ensure_stream(realm, asciiable_stream_name) email_address = encode_email_address(stream) self.assertTrue(email_address.startswith("aezc+"))
def test_mentions(self) -> None: cordelia = self.example_user('cordelia') hamlet = self.example_user('hamlet') othello = self.example_user('othello') zoe = self.example_user('ZOE') realm = cordelia.realm group_name = 'support' stream_name = 'Dev Help' content_with_group_mention = 'hey @*support* can you help us with this?' ensure_stream(realm, stream_name) all_users = {cordelia, hamlet, othello, zoe} support_team = {hamlet, zoe} sender = cordelia other_users = all_users - support_team for user in all_users: self.subscribe(user, stream_name) create_user_group( name=group_name, members=list(support_team), realm=realm, ) payload = dict( type="stream", to=stream_name, sender=sender.email, client='test suite', subject='whatever', content=content_with_group_mention, ) with mock.patch('logging.info'): result = self.api_post(sender.email, "/json/messages", payload) self.assert_json_success(result) for user in support_team: um = most_recent_usermessage(user) self.assertTrue(um.flags.mentioned) for user in other_users: um = most_recent_usermessage(user) self.assertFalse(um.flags.mentioned)
def test_mentions(self) -> None: cordelia = self.example_user('cordelia') hamlet = self.example_user('hamlet') othello = self.example_user('othello') zoe = self.example_user('ZOE') realm = cordelia.realm group_name = 'support' stream_name = 'Dev Help' content_with_group_mention = 'hey @*support* can you help us with this?' ensure_stream(realm, stream_name) all_users = {cordelia, hamlet, othello, zoe} support_team = {hamlet, zoe} sender = cordelia other_users = all_users - support_team for user in all_users: self.subscribe(user, stream_name) create_user_group( name=group_name, members=list(support_team), realm=realm, ) payload = dict( type="stream", to=stream_name, sender=sender.email, client='test suite', topic='whatever', content=content_with_group_mention, ) with mock.patch('logging.info'): result = self.api_post(sender.email, "/json/messages", payload) self.assert_json_success(result) for user in support_team: um = most_recent_usermessage(user) self.assertTrue(um.flags.mentioned) for user in other_users: um = most_recent_usermessage(user) self.assertFalse(um.flags.mentioned)
def test_mentions(self) -> None: cordelia = self.example_user("cordelia") hamlet = self.example_user("hamlet") othello = self.example_user("othello") zoe = self.example_user("ZOE") realm = cordelia.realm group_name = "support" stream_name = "Dev Help" content_with_group_mention = "hey @*support* can you help us with this?" ensure_stream(realm, stream_name) all_users = {cordelia, hamlet, othello, zoe} support_team = {hamlet, zoe} sender = cordelia other_users = all_users - support_team for user in all_users: self.subscribe(user, stream_name) create_user_group( name=group_name, members=list(support_team), realm=realm, ) payload = dict( type="stream", to=stream_name, client="test suite", topic="whatever", content=content_with_group_mention, ) result = self.api_post(sender, "/json/messages", payload) self.assert_json_success(result) for user in support_team: um = most_recent_usermessage(user) self.assertTrue(um.flags.mentioned) for user in other_users: um = most_recent_usermessage(user) self.assertFalse(um.flags.mentioned)
def handle(self, *args: Any, **options: Any) -> None: realm = self.get_realm(options) assert realm is not None # Should be ensured by parser streams = [] stream_names = { stream.strip() for stream in options["streams"].split(",") } for stream_name in set(stream_names): stream = ensure_stream(realm, stream_name, acting_user=None) streams.append(stream) try: default_stream_group = DefaultStreamGroup.objects.get( name=options["name"], realm=realm, description=options["description"]) except DefaultStreamGroup.DoesNotExist: default_stream_group = DefaultStreamGroup.objects.create( name=options["name"], realm=realm, description=options["description"]) default_stream_group.streams.set(streams) default_stream_groups = DefaultStreamGroup.objects.all() for default_stream_group in default_stream_groups: print(default_stream_group.name) print(default_stream_group.description) for stream in default_stream_group.streams.all(): print(stream.name) print("")
def test_encode_decode(self) -> None: realm = get_realm('zulip') stream_name = 'dev. help' stream = ensure_stream(realm, stream_name) email_address = encode_email_address(stream) self.assertTrue(email_address.startswith('dev%0046%0032help')) self.assertTrue(email_address.endswith('@testserver')) tup = decode_email_address(email_address) assert tup is not None (decoded_stream_name, token) = tup self.assertEqual(decoded_stream_name, stream_name) self.assertEqual(token, stream.email_token) email_address = email_address.replace('+', '.') tup = decode_email_address(email_address) assert tup is not None (decoded_stream_name, token) = tup self.assertEqual(decoded_stream_name, stream_name) self.assertEqual(token, stream.email_token) email_address = email_address.replace('@testserver', '@zulip.org') self.assertEqual(decode_email_address(email_address), None) with self.settings(EMAIL_GATEWAY_EXTRA_PATTERN_HACK='@zulip.org'): tup = decode_email_address(email_address) assert tup is not None (decoded_stream_name, token) = tup self.assertEqual(decoded_stream_name, stream_name) self.assertEqual(token, stream.email_token) self.assertEqual(decode_email_address('bogus'), None)
def handle(self, *args: Any, **options: Any) -> None: realm = self.get_realm(options) assert realm is not None # Should be ensured by parser streams = [] stream_names = set([stream.strip() for stream in options["streams"].split(",")]) for stream_name in set(stream_names): stream = ensure_stream(realm, stream_name) streams.append(stream) try: default_stream_group = DefaultStreamGroup.objects.get( name=options["name"], realm=realm, description=options["description"]) except DefaultStreamGroup.DoesNotExist: default_stream_group = DefaultStreamGroup.objects.create( name=options["name"], realm=realm, description=options["description"]) default_stream_group.streams.set(streams) default_stream_groups = DefaultStreamGroup.objects.all() for default_stream_group in default_stream_groups: print(default_stream_group.name) print(default_stream_group.description) for stream in default_stream_group.streams.all(): print(stream.name) print("")
def test_encode_decode(self) -> None: realm = get_realm('zulip') stream_name = 'dev. help' stream = ensure_stream(realm, stream_name) email_address = encode_email_address(stream) self.assertTrue(email_address.startswith('dev-help')) self.assertTrue(email_address.endswith('@testserver')) tup = decode_email_address(email_address) assert tup is not None token, show_sender = tup self.assertFalse(show_sender) self.assertEqual(token, stream.email_token) parts = email_address.split('@') parts[0] += "+show-sender" email_address_show = '@'.join(parts) tup = decode_email_address(email_address_show) assert tup is not None token, show_sender = tup self.assertTrue(show_sender) self.assertEqual(token, stream.email_token) email_address_dots = email_address.replace('+', '.') tup = decode_email_address(email_address_dots) assert tup is not None token, show_sender = tup self.assertFalse(show_sender) self.assertEqual(token, stream.email_token) email_address_dots_show = email_address_show.replace('+', '.') tup = decode_email_address(email_address_dots_show) assert tup is not None token, show_sender = tup self.assertTrue(show_sender) self.assertEqual(token, stream.email_token) email_address = email_address.replace('@testserver', '@zulip.org') email_address_show = email_address_show.replace( '@testserver', '@zulip.org') self.assertEqual(decode_email_address(email_address), None) self.assertEqual(decode_email_address(email_address_show), None) with self.settings(EMAIL_GATEWAY_EXTRA_PATTERN_HACK='@zulip.org'): tup = decode_email_address(email_address) assert tup is not None token, show_sender = tup self.assertFalse(show_sender) self.assertEqual(token, stream.email_token) tup = decode_email_address(email_address_show) assert tup is not None token, show_sender = tup self.assertTrue(show_sender) self.assertEqual(token, stream.email_token) self.assertEqual(decode_email_address('bogus'), None)
def handle(self, *args: Any, **options: Any) -> None: realm = self.get_realm(options) assert realm is not None # Should be ensured by parser streams = [] # type: List[Stream] if options["streams"]: stream_names = set([stream.strip() for stream in options["streams"].split(",")]) for stream_name in set(stream_names): stream = ensure_stream(realm, stream_name) streams.append(stream) referred_by = self.get_user(options['referred_by'], realm) invite_link = do_create_multiuse_invite_link(referred_by, streams) print("You can use %s to invite as many number of people to the organization." % (invite_link,))
def handle(self, *args: Any, **options: Any) -> None: realm = self.get_realm(options) assert realm is not None # Should be ensured by parser streams: List[Stream] = [] if options["streams"]: stream_names = {stream.strip() for stream in options["streams"].split(",")} for stream_name in set(stream_names): stream = ensure_stream(realm, stream_name, acting_user=None) streams.append(stream) referred_by = self.get_user(options["referred_by"], realm) invite_as = PreregistrationUser.INVITE_AS["MEMBER"] invite_link = do_create_multiuse_invite_link(referred_by, invite_as, streams) print(f"You can use {invite_link} to invite as many number of people to the organization.")
def handle(self, **options: Any) -> None: realm = self.get_realm(options) assert realm is not None # Should be ensured by parser user_profiles = self.get_users(options, realm) stream_names = {stream.strip() for stream in options["streams"].split(",")} for stream_name in set(stream_names): for user_profile in user_profiles: stream = ensure_stream(realm, stream_name, acting_user=None) _ignore, already_subscribed = bulk_add_subscriptions([stream], [user_profile]) was_there_already = user_profile.id in (tup[0].id for tup in already_subscribed) print("{} {} to {}".format( "Already subscribed" if was_there_already else "Subscribed", user_profile.delivery_email, stream_name))
def handle(self, *args: Any, **options: Any) -> None: realm = self.get_realm(options) assert realm is not None # Should be ensured by parser streams = [] # type: List[Stream] if options["streams"]: stream_names = set([stream.strip() for stream in options["streams"].split(",")]) for stream_name in set(stream_names): stream = ensure_stream(realm, stream_name) streams.append(stream) referred_by = self.get_user(options['referred_by'], realm) invite_as = PreregistrationUser.INVITE_AS['MEMBER'] invite_link = do_create_multiuse_invite_link(referred_by, invite_as, streams) print("You can use %s to invite as many number of people to the organization." % (invite_link,))
def handle(self, **options: Any) -> None: realm = self.get_realm(options) assert realm is not None # Should be ensured by parser user_profiles = self.get_users(options, realm) stream_names = set([stream.strip() for stream in options["streams"].split(",")]) for stream_name in set(stream_names): for user_profile in user_profiles: stream = ensure_stream(realm, stream_name) _ignore, already_subscribed = bulk_add_subscriptions([stream], [user_profile]) was_there_already = user_profile.id in {tup[0].id for tup in already_subscribed} print("%s %s to %s" % ( "Already subscribed" if was_there_already else "Subscribed", user_profile.email, stream_name))
def add_message_formatting_conversation(self) -> None: realm = get_realm('zulip') stream = ensure_stream(realm, 'zulip features') UserProfile.objects.filter(email__contains='stage').delete() starr = do_create_user('*****@*****.**', 'password', realm, 'Ada Starr', '') self.set_avatar(starr, 'static/images/characters/starr.png') fisher = do_create_user('*****@*****.**', 'password', realm, 'Bel Fisher', '') self.set_avatar(fisher, 'static/images/characters/fisher.png') twitter_bot = do_create_user('*****@*****.**', 'password', realm, 'Twitter Bot', '', bot_type=UserProfile.DEFAULT_BOT) self.set_avatar(twitter_bot, 'static/images/features/twitter.png') bulk_add_subscriptions([stream], list(UserProfile.objects.filter(realm=realm))) staged_messages = [ { 'sender': starr, 'content': "Hey @**Bel Fisher**, check out Zulip's Markdown formatting! " "You can have:\n* bulleted lists\n * with sub-bullets too\n" "* **bold**, *italic*, and ~~strikethrough~~ text\n" "* LaTeX for mathematical formulas, both inline -- $$O(n^2)$$ -- and displayed:\n" "```math\n\\int_a^b f(t)\\, dt=F(b)-F(a)\n```" }, { 'sender': fisher, 'content': "My favorite is the syntax highlighting for code blocks\n" "```python\ndef fib(n: int) -> int:\n # returns the n-th Fibonacci number\n" " return fib(n-1) + fib(n-2)\n```" }, { 'sender': starr, 'content': "I think you forgot your base case there, Bel :laughing:\n" "```quote\n```python\ndef fib(n: int) -> int:\n # returns the n-th Fibonacci number\n" " return fib(n-1) + fib(n-2)\n```\n```" }, { 'sender': fisher, 'content': "I'm also a big fan of inline link, tweet, video, and image previews. " "Check out this picture of Çet Whalin[](/static/images/features/whale.png)!" }, { 'sender': starr, 'content': "I just set up a custom linkifier, " "so `#1234` becomes [#1234](github.com/zulip/zulip/1234), " "a link to the corresponding GitHub issue." }, { 'sender': twitter_bot, 'content': 'https://twitter.com/gvanrossum/status/786661035637772288' }, { 'sender': fisher, 'content': "Oops, the Twitter bot I set up shouldn't be posting here. Let me go fix that." }, ] # type: List[Dict[str, Any]] messages = [ internal_prep_stream_message(realm, message['sender'], 'message formatting', message['content'], stream=stream) for message in staged_messages ] message_ids = do_send_messages(messages) preview_message = Message.objects.get( id__in=message_ids, content__icontains='image previews') do_add_reaction_legacy(starr, preview_message, 'whale') twitter_message = Message.objects.get(id__in=message_ids, content__icontains='gvanrossum') # Setting up a twitter integration in dev is a decent amount of work. If you need # to update this tweet, either copy the format below, or send the link to the tweet # to chat.zulip.org and ask an admin of that server to get you the rendered_content. twitter_message.rendered_content = ( '<p><a>https://twitter.com/gvanrossum/status/786661035637772288</a></p>\n' '<div class="inline-preview-twitter"><div class="twitter-tweet">' '<a><img class="twitter-avatar" ' 'src="https://pbs.twimg.com/profile_images/424495004/GuidoAvatar_bigger.jpg"></a>' '<p>Great blog post about Zulip\'s use of mypy: ' '<a>http://blog.zulip.org/2016/10/13/static-types-in-python-oh-mypy/</a></p>' '<span>- Guido van Rossum (@gvanrossum)</span></div></div>') twitter_message.save(update_fields=['rendered_content']) # Put a short pause between the whale reaction and this, so that the # thumbs_up shows up second do_add_reaction_legacy(starr, preview_message, 'thumbs_up')
def add_message_formatting_conversation(self) -> None: realm = get_realm('zulip') stream = ensure_stream(realm, 'zulip features') UserProfile.objects.filter(email__contains='stage').delete() starr = do_create_user('*****@*****.**', 'password', realm, 'Ada Starr', '') self.set_avatar(starr, 'static/images/characters/starr.png') fisher = do_create_user('*****@*****.**', 'password', realm, 'Bel Fisher', '') self.set_avatar(fisher, 'static/images/characters/fisher.png') twitter_bot = do_create_user('*****@*****.**', 'password', realm, 'Twitter Bot', '', bot_type=UserProfile.DEFAULT_BOT) self.set_avatar(twitter_bot, 'static/images/features/twitter.png') bulk_add_subscriptions([stream], list(UserProfile.objects.filter(realm=realm))) staged_messages = [ {'sender': starr, 'content': "Hey @**Bel Fisher**, check out Zulip's Markdown formatting! " "You can have:\n* bulleted lists\n * with sub-bullets too\n" "* **bold**, *italic*, and ~~strikethrough~~ text\n" "* LaTeX for mathematical formulas, both inline -- $$O(n^2)$$ -- and displayed:\n" "```math\n\\int_a^b f(t)\\, dt=F(b)-F(a)\n```"}, {'sender': fisher, 'content': "My favorite is the syntax highlighting for code blocks\n" "```python\ndef fib(n: int) -> int:\n # returns the n-th Fibonacci number\n" " return fib(n-1) + fib(n-2)\n```"}, {'sender': starr, 'content': "I think you forgot your base case there, Bel :laughing:\n" "```quote\n```python\ndef fib(n: int) -> int:\n # returns the n-th Fibonacci number\n" " return fib(n-1) + fib(n-2)\n```\n```"}, {'sender': fisher, 'content': "I'm also a big fan of inline link, tweet, video, and image previews. " "Check out this picture of Çet Whalin[](/static/images/features/whale.png)!"}, {'sender': starr, 'content': "I just set up a custom linkifier, " "so `#1234` becomes [#1234](github.com/zulip/zulip/1234), " "a link to the corresponding GitHub issue."}, {'sender': twitter_bot, 'content': 'https://twitter.com/gvanrossum/status/786661035637772288'}, {'sender': fisher, 'content': "Oops, the Twitter bot I set up shouldn't be posting here. Let me go fix that."}, ] # type: List[Dict[str, Any]] messages = [internal_prep_stream_message( realm, message['sender'], stream, 'message formatting', message['content'] ) for message in staged_messages] message_ids = do_send_messages(messages) preview_message = Message.objects.get(id__in=message_ids, content__icontains='image previews') do_add_reaction_legacy(starr, preview_message, 'whale') twitter_message = Message.objects.get(id__in=message_ids, content__icontains='gvanrossum') # Setting up a twitter integration in dev is a decent amount of work. If you need # to update this tweet, either copy the format below, or send the link to the tweet # to chat.zulip.org and ask an admin of that server to get you the rendered_content. twitter_message.rendered_content = ( '<p><a>https://twitter.com/gvanrossum/status/786661035637772288</a></p>\n' '<div class="inline-preview-twitter"><div class="twitter-tweet">' '<a><img class="twitter-avatar" ' 'src="https://pbs.twimg.com/profile_images/424495004/GuidoAvatar_bigger.jpg"></a>' '<p>Great blog post about Zulip\'s use of mypy: ' '<a>http://blog.zulip.org/2016/10/13/static-types-in-python-oh-mypy/</a></p>' '<span>- Guido van Rossum (@gvanrossum)</span></div></div>') twitter_message.save(update_fields=['rendered_content']) # Put a short pause between the whale reaction and this, so that the # thumbs_up shows up second do_add_reaction_legacy(starr, preview_message, 'thumbs_up')