Beispiel #1
0
    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+"))
Beispiel #2
0
    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)
Beispiel #3
0
    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)
Beispiel #4
0
    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("")
Beispiel #6
0
    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("")
Beispiel #8
0
    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)
Beispiel #9
0
    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,))
Beispiel #11
0
    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))
Beispiel #13
0
    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,))
Beispiel #14
0
    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))
Beispiel #15
0
    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')