<commit_before># -*- coding: utf-8 -*-
from __future__ import absolute_import
from django.db.models import Q
from django.conf import settings
from django.http import HttpResponse
from django.test import TestCase, override_settings
from zerver.lib import bugdown
from zerver.decorator import JsonableError
from zerver.lib.test_runner import slow
from zilencer.models import Deployment

from zerver.lib.message import (
    MessageDict,
    message_to_dict,
)

from zerver.lib.test_helpers import (
    ZulipTestCase,
    get_user_messages,
    make_client,
    message_ids, message_stream_count,
    most_recent_message,
    most_recent_usermessage,
    queries_captured,
)

from zerver.models import (
    MAX_MESSAGE_LENGTH, MAX_SUBJECT_LENGTH,
    Message, Realm, Recipient, Stream, UserMessage, UserProfile, Attachment, RealmAlias,
    get_realm, get_stream, get_user_profile_by_email,
)

from zerver.lib.actions import (
    check_message, check_send_message,
    do_create_user,
    get_client,
)

from zerver.lib.upload import create_attachment

from zerver.views.messages import create_mirrored_message_users

import datetime
import DNS
import mock
import time
import ujson
from six import text_type
from six.moves import range
from typing import Any, Optional

class TestCrossRealmPMs(ZulipTestCase):
    def make_realm(self, domain):
        # type: (text_type) -> Realm
        realm = Realm.objects.create(string_id=domain, domain=domain, invite_required=False)
        RealmAlias.objects.create(realm=realm, domain=domain)
        return realm

    def setUp(self):
        # type: () -> None
        dep = Deployment()
        dep.base_api_url = "https://zulip.com/api/"
        dep.base_site_url = "https://zulip.com/"
        # We need to save the object before we can access
        # the many-to-many relationship 'realms'
        dep.save()
        dep.realms = [get_realm("zulip.com")]
        dep.save()


    def create_user(self, email):
        # type: (text_type) -> UserProfile
        username, domain = email.split('@')
        self.register(username, 'test', domain=domain)
        return get_user_profile_by_email(email)

    @override_settings(CROSS_REALM_BOT_EMAILS=['<EMAIL>',
                                               '<EMAIL>'])
    def test_realm_scenarios(self):
        # type: () -> None
        r1 = self.make_realm('1.example.com')
        r2 = self.make_realm('2.example.com')
        r3 = self.make_realm('3.example.com')
        deployment = Deployment.objects.filter()[0]
        deployment.realms.add(r1)
        deployment.realms.add(r2)
        deployment.realms.add(r3)

        def assert_message_received(to_user, from_user):
            # type: (UserProfile, UserProfile) -> None
            messages = get_user_messages(to_user)
            self.assertEquals(messages[-1].sender.pk, from_user.pk)

        def assert_disallowed():
            # type: () -> Any
            return self.assertRaisesRegexp(
                JsonableError,
                'You can\'t send private messages outside of your organization.')

        random_zulip_email = '<EMAIL>'
        user1_email = '<EMAIL>'
        user1a_email = '<EMAIL>'
        user2_email = '<EMAIL>'
        user3_email = '<EMAIL>'
        feedback_email = '<EMAIL>'
        support_email = '<EMAIL>' # note: not zulip.com

        self.create_user(random_zulip_email)
        user1 = self.create_user(user1_email)
        user1a = self.create_user(user1a_email)
        user2 = self.create_user(user2_email)
        self.create_user(user3_email)
        feedback_bot = get_user_profile_by_email(feedback_email)
        support_bot = self.create_user(support_email)

        # Users can PM themselves
        self.send_message(user1_email, user1_email, Recipient.PERSONAL)
        assert_message_received(user1, user1)

        # Users on the same realm can PM each other
        self.send_message(user1_email, user1a_email, Recipient.PERSONAL)
        assert_message_received(user1a, user1)

        # Cross-realm bots in the zulip.com realm can PM any realm
        self.send_message(feedback_email, user2_email, Recipient.PERSONAL)
        assert_message_received(user2, feedback_bot)

        # All users can PM cross-realm bots in the zulip.com realm
        self.send_message(user1_email, feedback_email, Recipient.PERSONAL)
        assert_message_received(feedback_bot, user1)

        # Users can PM cross-realm bots on non-zulip realms.
        # (The support bot represents some theoretical bot that we may
        # create in the future that does not have zulip.com as its realm.)
        self.send_message(user1_email, [support_email], Recipient.PERSONAL)
        assert_message_received(support_bot, user1)

        # Allow sending PMs to two different cross-realm bots simultaneously.
        # (We don't particularly need this feature, but since users can
        # already individually send PMs to cross-realm bots, we shouldn't
        # prevent them from sending multiple bots at once.  We may revisit
        # this if it's a nuisance for huddles.)
        self.send_message(user1_email, [feedback_email, support_email],
                          Recipient.PERSONAL)
        assert_message_received(feedback_bot, user1)
        assert_message_received(support_bot, user1)

        # Prevent old loophole where I could send PMs to other users as long
        # as I copied a cross-realm bot from the same realm.
        with assert_disallowed():
            self.send_message(user1_email, [user3_email, support_email], Recipient.PERSONAL)

        # Users on three different realms can't PM each other,
        # even if one of the users is a cross-realm bot.
        with assert_disallowed():
            self.send_message(user1_email, [user2_email, feedback_email],
                              Recipient.PERSONAL)

        # Users on the different realms can not PM each other
        with assert_disallowed():
            self.send_message(user1_email, user2_email, Recipient.PERSONAL)

        # Users on non-zulip realms can't PM "ordinary" Zulip users
        with assert_disallowed():
            self.send_message(user1_email, random_zulip_email, Recipient.PERSONAL)

        # Users on three different realms can not PM each other
        with assert_disallowed():
            self.send_message(user1_email, [user2_email, user3_email], Recipient.PERSONAL)

class PersonalMessagesTest(ZulipTestCase):

    def test_auto_subbed_to_personals(self):
        # type: () -> None
        """
        Newly created users are auto-subbed to the ability to receive
        personals.
        """
        self.register("test", "test")
        user_profile = get_user_profile_by_email('<EMAIL>')
        old_messages_count = message_stream_count(user_profile)
        self.send_message("<EMAIL>", "<EMAIL>", Recipient.PERSONAL)
        new_messages_count = message_stream_count(user_profile)
        self.assertEqual(new_messages_count, old_messages_count + 1)<commit_msg>tests: Improve coverage of cross-realm bot limitations.<commit_after># -*- coding: utf-8 -*-
from __future__ import absolute_import
from django.db.models import Q
from django.conf import settings
from django.http import HttpResponse
from django.test import TestCase, override_settings
from zerver.lib import bugdown
from zerver.decorator import JsonableError
from zerver.lib.test_runner import slow
from zilencer.models import Deployment

from zerver.lib.message import (
    MessageDict,
    message_to_dict,
)

from zerver.lib.test_helpers import (
    ZulipTestCase,
    get_user_messages,
    make_client,
    message_ids, message_stream_count,
    most_recent_message,
    most_recent_usermessage,
    queries_captured,
)

from zerver.models import (
    MAX_MESSAGE_LENGTH, MAX_SUBJECT_LENGTH,
    Message, Realm, Recipient, Stream, UserMessage, UserProfile, Attachment, RealmAlias,
    get_realm, get_stream, get_user_profile_by_email,
)

from zerver.lib.actions import (
    check_message, check_send_message,
    do_create_user,
    get_client,
)

from zerver.lib.upload import create_attachment

from zerver.views.messages import create_mirrored_message_users

import datetime
import DNS
import mock
import time
import ujson
from six import text_type
from six.moves import range
from typing import Any, Optional

class TestCrossRealmPMs(ZulipTestCase):
    def make_realm(self, domain):
        # type: (text_type) -> Realm
        realm = Realm.objects.create(string_id=domain, domain=domain, invite_required=False)
        RealmAlias.objects.create(realm=realm, domain=domain)
        return realm

    def setUp(self):
        # type: () -> None
        dep = Deployment()
        dep.base_api_url = "https://zulip.com/api/"
        dep.base_site_url = "https://zulip.com/"
        # We need to save the object before we can access
        # the many-to-many relationship 'realms'
        dep.save()
        dep.realms = [get_realm("zulip.com")]
        dep.save()


    def create_user(self, email):
        # type: (text_type) -> UserProfile
        username, domain = email.split('@')
        self.register(username, 'test', domain=domain)
        return get_user_profile_by_email(email)

    @override_settings(CROSS_REALM_BOT_EMAILS=['<EMAIL>',
                                               '<EMAIL>'])
    def test_realm_scenarios(self):
        # type: () -> None
        r1 = self.make_realm('1.example.com')
        r2 = self.make_realm('2.example.com')
        r3 = self.make_realm('3.example.com')
        deployment = Deployment.objects.filter()[0]
        deployment.realms.add(r1)
        deployment.realms.add(r2)
        deployment.realms.add(r3)

        def assert_message_received(to_user, from_user):
            # type: (UserProfile, UserProfile) -> None
            messages = get_user_messages(to_user)
            self.assertEquals(messages[-1].sender.pk, from_user.pk)

        def assert_disallowed():
            # type: () -> Any
            return self.assertRaisesRegexp(
                JsonableError,
                'You can\'t send private messages outside of your organization.')

        random_zulip_email = '<EMAIL>'
        user1_email = '<EMAIL>'
        user1a_email = '<EMAIL>'
        user2_email = '<EMAIL>'
        user3_email = '<EMAIL>'
        feedback_email = '<EMAIL>'
        support_email = '<EMAIL>' # note: not zulip.com

        self.create_user(random_zulip_email)
        user1 = self.create_user(user1_email)
        user1a = self.create_user(user1a_email)
        user2 = self.create_user(user2_email)
        self.create_user(user3_email)
        feedback_bot = get_user_profile_by_email(feedback_email)
        support_bot = self.create_user(support_email)

        # Users can PM themselves
        self.send_message(user1_email, user1_email, Recipient.PERSONAL)
        assert_message_received(user1, user1)

        # Users on the same realm can PM each other
        self.send_message(user1_email, user1a_email, Recipient.PERSONAL)
        assert_message_received(user1a, user1)

        # Cross-realm bots in the zulip.com realm can PM any realm
        self.send_message(feedback_email, user2_email, Recipient.PERSONAL)
        assert_message_received(user2, feedback_bot)

        # All users can PM cross-realm bots in the zulip.com realm
        self.send_message(user1_email, feedback_email, Recipient.PERSONAL)
        assert_message_received(feedback_bot, user1)

        # Users can PM cross-realm bots on non-zulip realms.
        # (The support bot represents some theoretical bot that we may
        # create in the future that does not have zulip.com as its realm.)
        self.send_message(user1_email, [support_email], Recipient.PERSONAL)
        assert_message_received(support_bot, user1)

        # Allow sending PMs to two different cross-realm bots simultaneously.
        # (We don't particularly need this feature, but since users can
        # already individually send PMs to cross-realm bots, we shouldn't
        # prevent them from sending multiple bots at once.  We may revisit
        # this if it's a nuisance for huddles.)
        self.send_message(user1_email, [feedback_email, support_email],
                          Recipient.PERSONAL)
        assert_message_received(feedback_bot, user1)
        assert_message_received(support_bot, user1)

        # Prevent old loophole where I could send PMs to other users as long
        # as I copied a cross-realm bot from the same realm.
        with assert_disallowed():
            self.send_message(user1_email, [user3_email, support_email], Recipient.PERSONAL)

        # Users on three different realms can't PM each other,
        # even if one of the users is a cross-realm bot.
        with assert_disallowed():
            self.send_message(user1_email, [user2_email, feedback_email],
                              Recipient.PERSONAL)

        with assert_disallowed():
            self.send_message(feedback_email, [user1_email, user2_email],
                              Recipient.PERSONAL)

        # Users on the different realms can not PM each other
        with assert_disallowed():
            self.send_message(user1_email, user2_email, Recipient.PERSONAL)

        # Users on non-zulip realms can't PM "ordinary" Zulip users
        with assert_disallowed():
            self.send_message(user1_email, random_zulip_email, Recipient.PERSONAL)

        # Users on three different realms can not PM each other
        with assert_disallowed():
            self.send_message(user1_email, [user2_email, user3_email], Recipient.PERSONAL)

class PersonalMessagesTest(ZulipTestCase):

    def test_auto_subbed_to_personals(self):
        # type: () -> None
        """
        Newly created users are auto-subbed to the ability to receive
        personals.
        """
        self.register("test", "test")
        user_profile = get_user_profile_by_email('<EMAIL>')
        old_messages_count = message_stream_count(user_profile)
        self.send_message("<EMAIL>", "<EMAIL>", Recipient.PERSONAL)
        new_messages_count = message_stream_count(user_profile)
        self.assertEqual(new_messages_count, old_messages_count + 1)
{'fraction_non_alphanumeric': 0.08286981623600648, 'fraction_numerical': 0.0073223966767584315, 'mean_word_length': 2.8555917480998914, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 41, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '792008', 'n_tokens_mistral': 4350, 'n_tokens_neox': 4234, 'n_words': 1037}