mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	zerver/tests: Use python 3 syntax for typing.
This patch was extracted by tabbott for just the files with no open PRs modifying them.
This commit is contained in:
		@@ -28,8 +28,7 @@ from zerver.models import (
 | 
			
		||||
import datetime
 | 
			
		||||
 | 
			
		||||
class ActivityTest(ZulipTestCase):
 | 
			
		||||
    def test_activity(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_activity(self) -> None:
 | 
			
		||||
        self.login(self.example_email("hamlet"))
 | 
			
		||||
        client, _ = Client.objects.get_or_create(name='website')
 | 
			
		||||
        query = '/json/users/me/pointer'
 | 
			
		||||
@@ -50,8 +49,7 @@ class ActivityTest(ZulipTestCase):
 | 
			
		||||
        self.assert_length(queries, 4)
 | 
			
		||||
 | 
			
		||||
class TestClientModel(ZulipTestCase):
 | 
			
		||||
    def test_client_stringification(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_client_stringification(self) -> None:
 | 
			
		||||
        '''
 | 
			
		||||
        This test is designed to cover __str__ method for Client.
 | 
			
		||||
        '''
 | 
			
		||||
@@ -59,8 +57,7 @@ class TestClientModel(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(str(client), '<Client: some_client>')
 | 
			
		||||
 | 
			
		||||
class UserPresenceModelTests(ZulipTestCase):
 | 
			
		||||
    def test_date_logic(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_date_logic(self) -> None:
 | 
			
		||||
        UserPresence.objects.all().delete()
 | 
			
		||||
 | 
			
		||||
        user_profile = self.example_user('hamlet')
 | 
			
		||||
@@ -76,8 +73,7 @@ class UserPresenceModelTests(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(len(presence_dct), 1)
 | 
			
		||||
        self.assertEqual(presence_dct[email]['website']['status'], 'active')
 | 
			
		||||
 | 
			
		||||
        def back_date(num_weeks):
 | 
			
		||||
            # type: (int) -> None
 | 
			
		||||
        def back_date(num_weeks: int) -> None:
 | 
			
		||||
            user_presence = UserPresence.objects.filter(user_profile=user_profile)[0]
 | 
			
		||||
            user_presence.timestamp = timezone_now() - datetime.timedelta(weeks=num_weeks)
 | 
			
		||||
            user_presence.save()
 | 
			
		||||
@@ -92,8 +88,7 @@ class UserPresenceModelTests(ZulipTestCase):
 | 
			
		||||
        presence_dct = UserPresence.get_status_dict_by_realm(user_profile.realm_id)
 | 
			
		||||
        self.assertEqual(len(presence_dct), 0)
 | 
			
		||||
 | 
			
		||||
    def test_push_tokens(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_push_tokens(self) -> None:
 | 
			
		||||
        UserPresence.objects.all().delete()
 | 
			
		||||
 | 
			
		||||
        user_profile = self.example_user('hamlet')
 | 
			
		||||
@@ -103,8 +98,7 @@ class UserPresenceModelTests(ZulipTestCase):
 | 
			
		||||
        result = self.client_post("/json/users/me/presence", {'status': 'active'})
 | 
			
		||||
        self.assert_json_success(result)
 | 
			
		||||
 | 
			
		||||
        def pushable():
 | 
			
		||||
            # type: () -> bool
 | 
			
		||||
        def pushable() -> bool:
 | 
			
		||||
            presence_dct = UserPresence.get_status_dict_by_realm(user_profile.realm_id)
 | 
			
		||||
            self.assertEqual(len(presence_dct), 1)
 | 
			
		||||
            return presence_dct[email]['website']['pushable']
 | 
			
		||||
@@ -123,15 +117,13 @@ class UserPresenceModelTests(ZulipTestCase):
 | 
			
		||||
        self.assertTrue(pushable())
 | 
			
		||||
 | 
			
		||||
class UserPresenceTests(ZulipTestCase):
 | 
			
		||||
    def test_invalid_presence(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_invalid_presence(self) -> None:
 | 
			
		||||
        email = self.example_email("hamlet")
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        result = self.client_post("/json/users/me/presence", {'status': 'foo'})
 | 
			
		||||
        self.assert_json_error(result, 'Invalid status: foo')
 | 
			
		||||
 | 
			
		||||
    def test_set_idle(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_set_idle(self) -> None:
 | 
			
		||||
        email = self.example_email("hamlet")
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        client = 'website'
 | 
			
		||||
@@ -155,8 +147,7 @@ class UserPresenceTests(ZulipTestCase):
 | 
			
		||||
        newer_timestamp = json['presences'][email][client]['timestamp']
 | 
			
		||||
        self.assertGreaterEqual(newer_timestamp, timestamp)
 | 
			
		||||
 | 
			
		||||
    def test_set_active(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_set_active(self) -> None:
 | 
			
		||||
        self.login(self.example_email("hamlet"))
 | 
			
		||||
        client = 'website'
 | 
			
		||||
 | 
			
		||||
@@ -179,8 +170,7 @@ class UserPresenceTests(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(json['presences'][email][client]['status'], 'active')
 | 
			
		||||
        self.assertEqual(json['presences'][self.example_email("hamlet")][client]['status'], 'idle')
 | 
			
		||||
 | 
			
		||||
    def test_no_mit(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_no_mit(self) -> None:
 | 
			
		||||
        """Zephyr mirror realms such as MIT never get a list of users"""
 | 
			
		||||
        self.login(self.mit_email("espuser"))
 | 
			
		||||
        result = self.client_post("/json/users/me/presence", {'status': 'idle'},
 | 
			
		||||
@@ -188,15 +178,13 @@ class UserPresenceTests(ZulipTestCase):
 | 
			
		||||
        self.assert_json_success(result)
 | 
			
		||||
        self.assertEqual(result.json()['presences'], {})
 | 
			
		||||
 | 
			
		||||
    def test_mirror_presence(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_mirror_presence(self) -> None:
 | 
			
		||||
        """Zephyr mirror realms find out the status of their mirror bot"""
 | 
			
		||||
        user_profile = self.mit_user('espuser')
 | 
			
		||||
        email = user_profile.email
 | 
			
		||||
        self.login(email)
 | 
			
		||||
 | 
			
		||||
        def post_presence():
 | 
			
		||||
            # type: () -> Dict[str, Any]
 | 
			
		||||
        def post_presence() -> Dict[str, Any]:
 | 
			
		||||
            result = self.client_post("/json/users/me/presence", {'status': 'idle'},
 | 
			
		||||
                                      subdomain="zephyr")
 | 
			
		||||
            self.assert_json_success(result)
 | 
			
		||||
@@ -210,8 +198,7 @@ class UserPresenceTests(ZulipTestCase):
 | 
			
		||||
        json = post_presence()
 | 
			
		||||
        self.assertEqual(json['zephyr_mirror_active'], True)
 | 
			
		||||
 | 
			
		||||
    def _simulate_mirror_activity_for_user(self, user_profile):
 | 
			
		||||
        # type: (UserProfile) -> None
 | 
			
		||||
    def _simulate_mirror_activity_for_user(self, user_profile: UserProfile) -> None:
 | 
			
		||||
        last_visit = timezone_now()
 | 
			
		||||
        client = make_client('zephyr_mirror')
 | 
			
		||||
 | 
			
		||||
@@ -223,8 +210,7 @@ class UserPresenceTests(ZulipTestCase):
 | 
			
		||||
            last_visit=last_visit
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_same_realm(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_same_realm(self) -> None:
 | 
			
		||||
        self.login(self.mit_email("espuser"))
 | 
			
		||||
        self.client_post("/json/users/me/presence", {'status': 'idle'},
 | 
			
		||||
                         subdomain="zephyr")
 | 
			
		||||
@@ -241,8 +227,7 @@ class UserPresenceTests(ZulipTestCase):
 | 
			
		||||
            self.assertEqual(email_to_domain(email), 'zulip.com')
 | 
			
		||||
 | 
			
		||||
class SingleUserPresenceTests(ZulipTestCase):
 | 
			
		||||
    def test_single_user_get(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_single_user_get(self) -> None:
 | 
			
		||||
 | 
			
		||||
        # First, we setup the test with some data
 | 
			
		||||
        email = self.example_email("othello")
 | 
			
		||||
@@ -283,8 +268,7 @@ class SingleUserPresenceTests(ZulipTestCase):
 | 
			
		||||
            {"ZulipAndroid", "website", "aggregated"})
 | 
			
		||||
        self.assertEqual(set(result_dict['presence']['website'].keys()), {"status", "timestamp"})
 | 
			
		||||
 | 
			
		||||
    def test_ping_only(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_ping_only(self) -> None:
 | 
			
		||||
 | 
			
		||||
        self.login(self.example_email("othello"))
 | 
			
		||||
        req = dict(
 | 
			
		||||
@@ -295,8 +279,7 @@ class SingleUserPresenceTests(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(result.json()['msg'], '')
 | 
			
		||||
 | 
			
		||||
class UserPresenceAggregationTests(ZulipTestCase):
 | 
			
		||||
    def _send_presence_for_aggregated_tests(self, email, status, validate_time):
 | 
			
		||||
        # type: (str, str, datetime.datetime) -> Dict[str, Dict[str, Any]]
 | 
			
		||||
    def _send_presence_for_aggregated_tests(self, email: str, status: str, validate_time: datetime.datetime) -> Dict[str, Dict[str, Any]]:
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        timezone_util = 'zerver.views.presence.timezone_now'
 | 
			
		||||
        with mock.patch(timezone_util, return_value=validate_time - datetime.timedelta(seconds=5)):
 | 
			
		||||
@@ -321,8 +304,7 @@ class UserPresenceAggregationTests(ZulipTestCase):
 | 
			
		||||
        result = self.client_get("/json/users/%s/presence" % (email,))
 | 
			
		||||
        return result.json()
 | 
			
		||||
 | 
			
		||||
    def test_aggregated_info(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_aggregated_info(self) -> None:
 | 
			
		||||
        email = self.example_email("othello")
 | 
			
		||||
        validate_time = timezone_now()
 | 
			
		||||
        self._send_presence_for_aggregated_tests(str(self.example_email("othello")), 'active', validate_time)
 | 
			
		||||
@@ -341,8 +323,7 @@ class UserPresenceAggregationTests(ZulipTestCase):
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_aggregated_presense_active(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_aggregated_presense_active(self) -> None:
 | 
			
		||||
        validate_time = timezone_now()
 | 
			
		||||
        result_dict = self._send_presence_for_aggregated_tests(str(self.example_email("othello")), 'active',
 | 
			
		||||
                                                               validate_time)
 | 
			
		||||
@@ -354,8 +335,7 @@ class UserPresenceAggregationTests(ZulipTestCase):
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_aggregated_presense_idle(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_aggregated_presense_idle(self) -> None:
 | 
			
		||||
        validate_time = timezone_now()
 | 
			
		||||
        result_dict = self._send_presence_for_aggregated_tests(str(self.example_email("othello")), 'idle',
 | 
			
		||||
                                                               validate_time)
 | 
			
		||||
@@ -367,8 +347,7 @@ class UserPresenceAggregationTests(ZulipTestCase):
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_aggregated_presense_mixed(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_aggregated_presense_mixed(self) -> None:
 | 
			
		||||
        email = self.example_email("othello")
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        validate_time = timezone_now()
 | 
			
		||||
@@ -386,8 +365,7 @@ class UserPresenceAggregationTests(ZulipTestCase):
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_aggregated_presense_offline(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_aggregated_presense_offline(self) -> None:
 | 
			
		||||
        email = self.example_email("othello")
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        validate_time = timezone_now()
 | 
			
		||||
 
 | 
			
		||||
@@ -17,23 +17,21 @@ from zerver.worker import queue_processors
 | 
			
		||||
 | 
			
		||||
class WorkerTest(ZulipTestCase):
 | 
			
		||||
    class FakeClient:
 | 
			
		||||
        def __init__(self):
 | 
			
		||||
            # type: () -> None
 | 
			
		||||
        def __init__(self) -> None:
 | 
			
		||||
            self.consumers = {}  # type: Dict[str, Callable[[Dict[str, Any]], None]]
 | 
			
		||||
            self.queue = []  # type: List[Tuple[str, Dict[str, Any]]]
 | 
			
		||||
 | 
			
		||||
        def register_json_consumer(self, queue_name, callback):
 | 
			
		||||
            # type: (str, Callable[[Dict[str, Any]], None]) -> None
 | 
			
		||||
        def register_json_consumer(self,
 | 
			
		||||
                                   queue_name: str,
 | 
			
		||||
                                   callback: Callable[[Dict[str, Any]], None]) -> None:
 | 
			
		||||
            self.consumers[queue_name] = callback
 | 
			
		||||
 | 
			
		||||
        def start_consuming(self):
 | 
			
		||||
            # type: () -> None
 | 
			
		||||
        def start_consuming(self) -> None:
 | 
			
		||||
            for queue_name, data in self.queue:
 | 
			
		||||
                callback = self.consumers[queue_name]
 | 
			
		||||
                callback(data)
 | 
			
		||||
 | 
			
		||||
    def test_mirror_worker(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_mirror_worker(self) -> None:
 | 
			
		||||
        fake_client = self.FakeClient()
 | 
			
		||||
        data = [
 | 
			
		||||
            dict(
 | 
			
		||||
@@ -61,8 +59,7 @@ class WorkerTest(ZulipTestCase):
 | 
			
		||||
                worker.setup()
 | 
			
		||||
                worker.start()
 | 
			
		||||
 | 
			
		||||
    def test_email_sending_worker_retries(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_email_sending_worker_retries(self) -> None:
 | 
			
		||||
        """Tests the retry_send_email_failures decorator to make sure it
 | 
			
		||||
        retries sending the email 3 times and then gives up."""
 | 
			
		||||
        fake_client = self.FakeClient()
 | 
			
		||||
@@ -70,8 +67,9 @@ class WorkerTest(ZulipTestCase):
 | 
			
		||||
        data = {'test': 'test', 'id': 'test_missed'}
 | 
			
		||||
        fake_client.queue.append(('missedmessage_email_senders', data))
 | 
			
		||||
 | 
			
		||||
        def fake_publish(queue_name, event, processor):
 | 
			
		||||
            # type: (str, Dict[str, Any], Callable[[Any], None]) -> None
 | 
			
		||||
        def fake_publish(queue_name: str,
 | 
			
		||||
                         event: Dict[str, Any],
 | 
			
		||||
                         processor: Callable[[Any], None]) -> None:
 | 
			
		||||
            fake_client.queue.append((queue_name, event))
 | 
			
		||||
 | 
			
		||||
        with simulated_queue_client(lambda: fake_client):
 | 
			
		||||
@@ -86,8 +84,7 @@ class WorkerTest(ZulipTestCase):
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(data['failed_tries'], 4)
 | 
			
		||||
 | 
			
		||||
    def test_signups_worker_retries(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_signups_worker_retries(self) -> None:
 | 
			
		||||
        """Tests the retry logic of signups queue."""
 | 
			
		||||
        fake_client = self.FakeClient()
 | 
			
		||||
 | 
			
		||||
@@ -95,8 +92,7 @@ class WorkerTest(ZulipTestCase):
 | 
			
		||||
        data = {'user_id': user_id, 'id': 'test_missed'}
 | 
			
		||||
        fake_client.queue.append(('signups', data))
 | 
			
		||||
 | 
			
		||||
        def fake_publish(queue_name, event, processor):
 | 
			
		||||
            # type: (str, Dict[str, Any], Callable[[Any], None]) -> None
 | 
			
		||||
        def fake_publish(queue_name: str, event: Dict[str, Any], processor: Callable[[Any], None]) -> None:
 | 
			
		||||
            fake_client.queue.append((queue_name, event))
 | 
			
		||||
 | 
			
		||||
        fake_response = MagicMock()
 | 
			
		||||
@@ -117,8 +113,7 @@ class WorkerTest(ZulipTestCase):
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(data['failed_tries'], 4)
 | 
			
		||||
 | 
			
		||||
    def test_UserActivityWorker(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_UserActivityWorker(self) -> None:
 | 
			
		||||
        fake_client = self.FakeClient()
 | 
			
		||||
 | 
			
		||||
        user = self.example_user('hamlet')
 | 
			
		||||
@@ -146,20 +141,17 @@ class WorkerTest(ZulipTestCase):
 | 
			
		||||
            self.assertTrue(len(activity_records), 1)
 | 
			
		||||
            self.assertTrue(activity_records[0].count, 1)
 | 
			
		||||
 | 
			
		||||
    def test_error_handling(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_error_handling(self) -> None:
 | 
			
		||||
        processed = []
 | 
			
		||||
 | 
			
		||||
        @queue_processors.assign_queue('unreliable_worker')
 | 
			
		||||
        class UnreliableWorker(queue_processors.QueueProcessingWorker):
 | 
			
		||||
            def consume(self, data):
 | 
			
		||||
                # type: (Mapping[str, Any]) -> None
 | 
			
		||||
            def consume(self, data: Mapping[str, Any]) -> None:
 | 
			
		||||
                if data["type"] == 'unexpected behaviour':
 | 
			
		||||
                    raise Exception('Worker task not performing as expected!')
 | 
			
		||||
                processed.append(data["type"])
 | 
			
		||||
 | 
			
		||||
            def _log_problem(self):
 | 
			
		||||
                # type: () -> None
 | 
			
		||||
            def _log_problem(self) -> None:
 | 
			
		||||
 | 
			
		||||
                # keep the tests quiet
 | 
			
		||||
                pass
 | 
			
		||||
@@ -184,25 +176,20 @@ class WorkerTest(ZulipTestCase):
 | 
			
		||||
        event = ujson.loads(line.split('\t')[1])
 | 
			
		||||
        self.assertEqual(event["type"], 'unexpected behaviour')
 | 
			
		||||
 | 
			
		||||
    def test_worker_noname(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_worker_noname(self) -> None:
 | 
			
		||||
        class TestWorker(queue_processors.QueueProcessingWorker):
 | 
			
		||||
            def __init__(self):
 | 
			
		||||
                # type: () -> None
 | 
			
		||||
            def __init__(self) -> None:
 | 
			
		||||
                super().__init__()
 | 
			
		||||
 | 
			
		||||
            def consume(self, data):
 | 
			
		||||
                # type: (Mapping[str, Any]) -> None
 | 
			
		||||
            def consume(self, data: Mapping[str, Any]) -> None:
 | 
			
		||||
                pass  # nocoverage # this is intentionally not called
 | 
			
		||||
        with self.assertRaises(queue_processors.WorkerDeclarationException):
 | 
			
		||||
            TestWorker()
 | 
			
		||||
 | 
			
		||||
    def test_worker_noconsume(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_worker_noconsume(self) -> None:
 | 
			
		||||
        @queue_processors.assign_queue('test_worker')
 | 
			
		||||
        class TestWorker(queue_processors.QueueProcessingWorker):
 | 
			
		||||
            def __init__(self):
 | 
			
		||||
                # type: () -> None
 | 
			
		||||
            def __init__(self) -> None:
 | 
			
		||||
                super().__init__()
 | 
			
		||||
 | 
			
		||||
        with self.assertRaises(queue_processors.WorkerDeclarationException):
 | 
			
		||||
 
 | 
			
		||||
@@ -16,8 +16,7 @@ import ujson
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class RealmDomainTest(ZulipTestCase):
 | 
			
		||||
    def test_list_realm_domains(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_list_realm_domains(self) -> None:
 | 
			
		||||
        self.login(self.example_email("iago"))
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
        RealmDomain.objects.create(realm=realm, domain='acme.com', allow_subdomains=True)
 | 
			
		||||
@@ -29,8 +28,7 @@ class RealmDomainTest(ZulipTestCase):
 | 
			
		||||
                               sort_keys=True)
 | 
			
		||||
        self.assertEqual(received, expected)
 | 
			
		||||
 | 
			
		||||
    def test_not_realm_admin(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_not_realm_admin(self) -> None:
 | 
			
		||||
        self.login(self.example_email("hamlet"))
 | 
			
		||||
        result = self.client_post("/json/realm/domains")
 | 
			
		||||
        self.assert_json_error(result, 'Must be a realm administrator')
 | 
			
		||||
@@ -39,8 +37,7 @@ class RealmDomainTest(ZulipTestCase):
 | 
			
		||||
        result = self.client_delete("/json/realm/domains/15")
 | 
			
		||||
        self.assert_json_error(result, 'Must be a realm administrator')
 | 
			
		||||
 | 
			
		||||
    def test_create_realm_domain(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_create_realm_domain(self) -> None:
 | 
			
		||||
        self.login(self.example_email("iago"))
 | 
			
		||||
        data = {'domain': ujson.dumps(''),
 | 
			
		||||
                'allow_subdomains': ujson.dumps(True)}
 | 
			
		||||
@@ -66,8 +63,7 @@ class RealmDomainTest(ZulipTestCase):
 | 
			
		||||
                                  HTTP_HOST=mit_user_profile.realm.host)
 | 
			
		||||
        self.assert_json_success(result)
 | 
			
		||||
 | 
			
		||||
    def test_patch_realm_domain(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_patch_realm_domain(self) -> None:
 | 
			
		||||
        self.login(self.example_email("iago"))
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
        RealmDomain.objects.create(realm=realm, domain='acme.com',
 | 
			
		||||
@@ -86,8 +82,7 @@ class RealmDomainTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(result.status_code, 400)
 | 
			
		||||
        self.assert_json_error(result, 'No entry found for domain non-existent.com.')
 | 
			
		||||
 | 
			
		||||
    def test_delete_realm_domain(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_delete_realm_domain(self) -> None:
 | 
			
		||||
        self.login(self.example_email("iago"))
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
        RealmDomain.objects.create(realm=realm, domain='acme.com')
 | 
			
		||||
@@ -100,8 +95,7 @@ class RealmDomainTest(ZulipTestCase):
 | 
			
		||||
        self.assertFalse(RealmDomain.objects.filter(domain='acme.com').exists())
 | 
			
		||||
        self.assertTrue(realm.restricted_to_domain)
 | 
			
		||||
 | 
			
		||||
    def test_delete_all_realm_domains(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_delete_all_realm_domains(self) -> None:
 | 
			
		||||
        self.login(self.example_email("iago"))
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
        query = RealmDomain.objects.filter(realm=realm)
 | 
			
		||||
@@ -115,8 +109,7 @@ class RealmDomainTest(ZulipTestCase):
 | 
			
		||||
        # would not be updated.
 | 
			
		||||
        self.assertFalse(get_realm('zulip').restricted_to_domain)
 | 
			
		||||
 | 
			
		||||
    def test_email_allowed_for_realm(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_email_allowed_for_realm(self) -> None:
 | 
			
		||||
        realm1 = do_create_realm('testrealm1', 'Test Realm 1', restricted_to_domain=True)
 | 
			
		||||
        realm2 = do_create_realm('testrealm2', 'Test Realm 2', restricted_to_domain=True)
 | 
			
		||||
 | 
			
		||||
@@ -134,14 +127,12 @@ class RealmDomainTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(email_allowed_for_realm('user@test2.test1.com', realm1), True)
 | 
			
		||||
        self.assertEqual(email_allowed_for_realm('user@test2.com', realm1), False)
 | 
			
		||||
 | 
			
		||||
    def test_realm_realm_domains_uniqueness(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_realm_realm_domains_uniqueness(self) -> None:
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
        with self.assertRaises(IntegrityError):
 | 
			
		||||
            RealmDomain.objects.create(realm=realm, domain='zulip.com', allow_subdomains=True)
 | 
			
		||||
 | 
			
		||||
    def test_validate_domain(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_validate_domain(self) -> None:
 | 
			
		||||
        invalid_domains = ['', 'test', 't.', 'test.', '.com', '-test', 'test...com',
 | 
			
		||||
                           'test-', 'test_domain.com', 'test.-domain.com']
 | 
			
		||||
        for domain in invalid_domains:
 | 
			
		||||
 
 | 
			
		||||
@@ -7,8 +7,7 @@ from zerver.models import RealmEmoji
 | 
			
		||||
 | 
			
		||||
class RealmEmojiTest(ZulipTestCase):
 | 
			
		||||
 | 
			
		||||
    def test_list(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_list(self) -> None:
 | 
			
		||||
        email = self.example_email('iago')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
@@ -18,8 +17,7 @@ class RealmEmojiTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(200, result.status_code)
 | 
			
		||||
        self.assertEqual(len(result.json()["emoji"]), 2)
 | 
			
		||||
 | 
			
		||||
    def test_list_no_author(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_list_no_author(self) -> None:
 | 
			
		||||
        email = self.example_email('iago')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
@@ -30,8 +28,7 @@ class RealmEmojiTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(len(content["emoji"]), 2)
 | 
			
		||||
        self.assertIsNone(content["emoji"]['my_emoji']['author'])
 | 
			
		||||
 | 
			
		||||
    def test_list_admins_only(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_list_admins_only(self) -> None:
 | 
			
		||||
        email = self.example_email('othello')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
@@ -44,8 +41,7 @@ class RealmEmojiTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(len(content["emoji"]), 2)
 | 
			
		||||
        self.assertIsNone(content["emoji"]['my_emoji']['author'])
 | 
			
		||||
 | 
			
		||||
    def test_upload(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_upload(self) -> None:
 | 
			
		||||
        email = self.example_email('iago')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        with get_test_image_file('img.png') as fp1:
 | 
			
		||||
@@ -70,8 +66,7 @@ class RealmEmojiTest(ZulipTestCase):
 | 
			
		||||
            '<RealmEmoji(zulip): my_emoji my_emoji.png>'
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_upload_exception(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_upload_exception(self) -> None:
 | 
			
		||||
        email = self.example_email('iago')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        with get_test_image_file('img.png') as fp1:
 | 
			
		||||
@@ -79,8 +74,7 @@ class RealmEmojiTest(ZulipTestCase):
 | 
			
		||||
            result = self.client_post('/json/realm/emoji/my_em*oji', info=emoji_data)
 | 
			
		||||
        self.assert_json_error(result, 'Invalid characters in emoji name')
 | 
			
		||||
 | 
			
		||||
    def test_upload_uppercase_exception(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_upload_uppercase_exception(self) -> None:
 | 
			
		||||
        email = self.example_email('iago')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        with get_test_image_file('img.png') as fp1:
 | 
			
		||||
@@ -88,8 +82,7 @@ class RealmEmojiTest(ZulipTestCase):
 | 
			
		||||
            result = self.client_post('/json/realm/emoji/my_EMoji', info=emoji_data)
 | 
			
		||||
        self.assert_json_error(result, 'Invalid characters in emoji name')
 | 
			
		||||
 | 
			
		||||
    def test_upload_admins_only(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_upload_admins_only(self) -> None:
 | 
			
		||||
        email = self.example_email('othello')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
@@ -100,8 +93,7 @@ class RealmEmojiTest(ZulipTestCase):
 | 
			
		||||
            result = self.client_post('/json/realm/emoji/my_emoji', info=emoji_data)
 | 
			
		||||
        self.assert_json_error(result, 'Must be a realm administrator')
 | 
			
		||||
 | 
			
		||||
    def test_upload_anyone(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_upload_anyone(self) -> None:
 | 
			
		||||
        email = self.example_email('othello')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
@@ -112,8 +104,7 @@ class RealmEmojiTest(ZulipTestCase):
 | 
			
		||||
            result = self.client_post('/json/realm/emoji/my_emoji', info=emoji_data)
 | 
			
		||||
        self.assert_json_success(result)
 | 
			
		||||
 | 
			
		||||
    def test_delete(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_delete(self) -> None:
 | 
			
		||||
        email = self.example_email('iago')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
@@ -129,8 +120,7 @@ class RealmEmojiTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(len(emojis), 2)
 | 
			
		||||
        self.assertEqual(emojis["my_emoji"]["deactivated"], True)
 | 
			
		||||
 | 
			
		||||
    def test_delete_admins_only(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_delete_admins_only(self) -> None:
 | 
			
		||||
        email = self.example_email('othello')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
@@ -140,8 +130,7 @@ class RealmEmojiTest(ZulipTestCase):
 | 
			
		||||
        result = self.client_delete("/json/realm/emoji/my_emoji")
 | 
			
		||||
        self.assert_json_error(result, 'Must be a realm administrator')
 | 
			
		||||
 | 
			
		||||
    def test_delete_admin_or_author(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_delete_admin_or_author(self) -> None:
 | 
			
		||||
        # If any user in a realm can upload the emoji then the user who
 | 
			
		||||
        # uploaded it as well as the admin should be able to delete it.
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
@@ -165,23 +154,20 @@ class RealmEmojiTest(ZulipTestCase):
 | 
			
		||||
        result = self.client_delete("/json/realm/emoji/my_emoji_3")
 | 
			
		||||
        self.assert_json_error(result, 'Must be a realm administrator or emoji author')
 | 
			
		||||
 | 
			
		||||
    def test_delete_exception(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_delete_exception(self) -> None:
 | 
			
		||||
        email = self.example_email('iago')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        result = self.client_delete("/json/realm/emoji/invalid_emoji")
 | 
			
		||||
        self.assert_json_error(result, "Emoji 'invalid_emoji' does not exist")
 | 
			
		||||
 | 
			
		||||
    def test_multiple_upload(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_multiple_upload(self) -> None:
 | 
			
		||||
        email = self.example_email('iago')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        with get_test_image_file('img.png') as fp1, get_test_image_file('img.png') as fp2:
 | 
			
		||||
            result = self.client_post('/json/realm/emoji/my_emoji', {'f1': fp1, 'f2': fp2})
 | 
			
		||||
        self.assert_json_error(result, 'You must upload exactly one file.')
 | 
			
		||||
 | 
			
		||||
    def test_emoji_upload_file_size_error(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_emoji_upload_file_size_error(self) -> None:
 | 
			
		||||
        email = self.example_email('iago')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        with get_test_image_file('img.png') as fp:
 | 
			
		||||
@@ -189,8 +175,7 @@ class RealmEmojiTest(ZulipTestCase):
 | 
			
		||||
                result = self.client_post('/json/realm/emoji/my_emoji', {'file': fp})
 | 
			
		||||
        self.assert_json_error(result, 'Uploaded file is larger than the allowed limit of 0 MB')
 | 
			
		||||
 | 
			
		||||
    def test_upload_already_existed_emoji(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_upload_already_existed_emoji(self) -> None:
 | 
			
		||||
        email = self.example_email('iago')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        with get_test_image_file('img.png') as fp1:
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,7 @@ from zerver.models import RealmFilter
 | 
			
		||||
 | 
			
		||||
class RealmFilterTest(ZulipTestCase):
 | 
			
		||||
 | 
			
		||||
    def test_list(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_list(self) -> None:
 | 
			
		||||
        email = self.example_email('iago')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
@@ -20,8 +19,7 @@ class RealmFilterTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(200, result.status_code)
 | 
			
		||||
        self.assertEqual(len(result.json()["filters"]), 1)
 | 
			
		||||
 | 
			
		||||
    def test_create(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_create(self) -> None:
 | 
			
		||||
        email = self.example_email('iago')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        data = {"pattern": "", "url_format_string": "https://realm.com/my_realm_filter/%(id)s"}
 | 
			
		||||
@@ -55,8 +53,7 @@ class RealmFilterTest(ZulipTestCase):
 | 
			
		||||
        result = self.client_post("/json/realm/filters", info=data)
 | 
			
		||||
        self.assert_json_success(result)
 | 
			
		||||
 | 
			
		||||
    def test_not_realm_admin(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_not_realm_admin(self) -> None:
 | 
			
		||||
        email = self.example_email('hamlet')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        result = self.client_post("/json/realm/filters")
 | 
			
		||||
@@ -64,8 +61,7 @@ class RealmFilterTest(ZulipTestCase):
 | 
			
		||||
        result = self.client_delete("/json/realm/filters/15")
 | 
			
		||||
        self.assert_json_error(result, 'Must be a realm administrator')
 | 
			
		||||
 | 
			
		||||
    def test_delete(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_delete(self) -> None:
 | 
			
		||||
        email = self.example_email('iago')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
 
 | 
			
		||||
@@ -11,23 +11,19 @@ from zerver.lib.utils import statsd
 | 
			
		||||
import mock
 | 
			
		||||
import ujson
 | 
			
		||||
 | 
			
		||||
def fix_params(raw_params):
 | 
			
		||||
    # type: (Dict[str, Any]) -> Dict[str, str]
 | 
			
		||||
def fix_params(raw_params: Dict[str, Any]) -> Dict[str, str]:
 | 
			
		||||
    # A few of our few legacy endpoints need their
 | 
			
		||||
    # individual parameters serialized as JSON.
 | 
			
		||||
    return {k: ujson.dumps(v) for k, v in raw_params.items()}
 | 
			
		||||
 | 
			
		||||
class StatsMock:
 | 
			
		||||
    def __init__(self, settings):
 | 
			
		||||
        # type: (Callable[..., Any]) -> None
 | 
			
		||||
    def __init__(self, settings: Callable[..., Any]) -> None:
 | 
			
		||||
        self.settings = settings
 | 
			
		||||
        self.real_impl = statsd
 | 
			
		||||
        self.func_calls = []  # type: List[Tuple[str, Iterable[Any]]]
 | 
			
		||||
 | 
			
		||||
    def __getattr__(self, name):
 | 
			
		||||
        # type: (str) -> Callable[..., Any]
 | 
			
		||||
        def f(*args):
 | 
			
		||||
            # type: (*Any) -> None
 | 
			
		||||
    def __getattr__(self, name: str) -> Callable[..., Any]:
 | 
			
		||||
        def f(*args: Any) -> None:
 | 
			
		||||
            with self.settings(STATSD_HOST=''):
 | 
			
		||||
                getattr(self.real_impl, name)(*args)
 | 
			
		||||
            self.func_calls.append((name, args))
 | 
			
		||||
@@ -35,8 +31,7 @@ class StatsMock:
 | 
			
		||||
        return f
 | 
			
		||||
 | 
			
		||||
class TestReport(ZulipTestCase):
 | 
			
		||||
    def test_send_time(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_send_time(self) -> None:
 | 
			
		||||
        email = self.example_email('hamlet')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
 | 
			
		||||
@@ -62,8 +57,7 @@ class TestReport(ZulipTestCase):
 | 
			
		||||
        ]
 | 
			
		||||
        self.assertEqual(stats_mock.func_calls, expected_calls)
 | 
			
		||||
 | 
			
		||||
    def test_narrow_time(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_narrow_time(self) -> None:
 | 
			
		||||
        email = self.example_email('hamlet')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
 | 
			
		||||
@@ -85,8 +79,7 @@ class TestReport(ZulipTestCase):
 | 
			
		||||
        ]
 | 
			
		||||
        self.assertEqual(stats_mock.func_calls, expected_calls)
 | 
			
		||||
 | 
			
		||||
    def test_unnarrow_time(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_unnarrow_time(self) -> None:
 | 
			
		||||
        email = self.example_email('hamlet')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
 | 
			
		||||
@@ -107,8 +100,7 @@ class TestReport(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(stats_mock.func_calls, expected_calls)
 | 
			
		||||
 | 
			
		||||
    @override_settings(BROWSER_ERROR_REPORTING=True)
 | 
			
		||||
    def test_report_error(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_report_error(self) -> None:
 | 
			
		||||
        email = self.example_email('hamlet')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -18,8 +18,9 @@ from zerver.lib.test_classes import ZulipTestCase
 | 
			
		||||
 | 
			
		||||
class TestSessions(ZulipTestCase):
 | 
			
		||||
 | 
			
		||||
    def do_test_session(self, user, action, expected_result):
 | 
			
		||||
        # type: (Text, Callable[[], Any], bool) -> None
 | 
			
		||||
    def do_test_session(self, user: Text,
 | 
			
		||||
                        action: Callable[[], Any],
 | 
			
		||||
                        expected_result: bool) -> None:
 | 
			
		||||
        self.login(user)
 | 
			
		||||
        self.assertIn('_auth_user_id', self.client.session)
 | 
			
		||||
        action()
 | 
			
		||||
@@ -29,8 +30,7 @@ class TestSessions(ZulipTestCase):
 | 
			
		||||
        else:
 | 
			
		||||
            self.assertIn('_auth_user_id', self.client.session)
 | 
			
		||||
 | 
			
		||||
    def test_delete_session(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_delete_session(self) -> None:
 | 
			
		||||
        user_profile = self.example_user('hamlet')
 | 
			
		||||
        email = user_profile.email
 | 
			
		||||
        self.login(email)
 | 
			
		||||
@@ -40,26 +40,22 @@ class TestSessions(ZulipTestCase):
 | 
			
		||||
        result = self.client_get("/")
 | 
			
		||||
        self.assertEqual('/login', result.url)
 | 
			
		||||
 | 
			
		||||
    def test_delete_user_sessions(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_delete_user_sessions(self) -> None:
 | 
			
		||||
        user_profile = self.example_user('hamlet')
 | 
			
		||||
        email = user_profile.email
 | 
			
		||||
        self.do_test_session(str(email), lambda: delete_user_sessions(user_profile), True)
 | 
			
		||||
        self.do_test_session(str(self.example_email("othello")), lambda: delete_user_sessions(user_profile), False)
 | 
			
		||||
 | 
			
		||||
    def test_delete_realm_user_sessions(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_delete_realm_user_sessions(self) -> None:
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
        self.do_test_session(self.example_email("hamlet"), lambda: delete_realm_user_sessions(realm), True)
 | 
			
		||||
        self.do_test_session(self.mit_email("sipbtest"), lambda: delete_realm_user_sessions(realm), False)
 | 
			
		||||
 | 
			
		||||
    def test_delete_all_user_sessions(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_delete_all_user_sessions(self) -> None:
 | 
			
		||||
        self.do_test_session(self.example_email("hamlet"), lambda: delete_all_user_sessions(), True)
 | 
			
		||||
        self.do_test_session(self.mit_email("sipbtest"), lambda: delete_all_user_sessions(), True)
 | 
			
		||||
 | 
			
		||||
    def test_delete_all_deactivated_user_sessions(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_delete_all_deactivated_user_sessions(self) -> None:
 | 
			
		||||
 | 
			
		||||
        # Test that no exception is thrown with a logged-out session
 | 
			
		||||
        self.login(self.example_email("othello"))
 | 
			
		||||
 
 | 
			
		||||
@@ -12,14 +12,12 @@ from zerver.models import get_realm, get_user, UserProfile
 | 
			
		||||
 | 
			
		||||
class ChangeSettingsTest(ZulipTestCase):
 | 
			
		||||
 | 
			
		||||
    def check_well_formed_change_settings_response(self, result):
 | 
			
		||||
        # type: (Dict[str, Any]) -> None
 | 
			
		||||
    def check_well_formed_change_settings_response(self, result: Dict[str, Any]) -> None:
 | 
			
		||||
        self.assertIn("full_name", result)
 | 
			
		||||
 | 
			
		||||
    # DEPRECATED, to be deleted after all uses of check_for_toggle_param
 | 
			
		||||
    # are converted into check_for_toggle_param_patch.
 | 
			
		||||
    def check_for_toggle_param(self, pattern, param):
 | 
			
		||||
        # type: (str, str) -> None
 | 
			
		||||
    def check_for_toggle_param(self, pattern: str, param: str) -> None:
 | 
			
		||||
        self.login(self.example_email("hamlet"))
 | 
			
		||||
        user_profile = self.example_user('hamlet')
 | 
			
		||||
        json_result = self.client_post(pattern,
 | 
			
		||||
@@ -38,8 +36,7 @@ class ChangeSettingsTest(ZulipTestCase):
 | 
			
		||||
 | 
			
		||||
    # TODO: requires method consolidation, right now, there's no alternative
 | 
			
		||||
    # for check_for_toggle_param for PATCH.
 | 
			
		||||
    def check_for_toggle_param_patch(self, pattern, param):
 | 
			
		||||
        # type: (str, str) -> None
 | 
			
		||||
    def check_for_toggle_param_patch(self, pattern: str, param: str) -> None:
 | 
			
		||||
        self.login(self.example_email("hamlet"))
 | 
			
		||||
        user_profile = self.example_user('hamlet')
 | 
			
		||||
        json_result = self.client_patch(pattern,
 | 
			
		||||
@@ -56,8 +53,7 @@ class ChangeSettingsTest(ZulipTestCase):
 | 
			
		||||
        user_profile = self.example_user('hamlet')
 | 
			
		||||
        self.assertEqual(getattr(user_profile, param), False)
 | 
			
		||||
 | 
			
		||||
    def test_successful_change_settings(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_successful_change_settings(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        A call to /json/settings with valid parameters changes the user's
 | 
			
		||||
        settings correctly and returns correct values.
 | 
			
		||||
@@ -81,8 +77,7 @@ class ChangeSettingsTest(ZulipTestCase):
 | 
			
		||||
        user_profile = self.example_user('hamlet')
 | 
			
		||||
        self.assertEqual(get_session_dict_user(self.client.session), user_profile.id)
 | 
			
		||||
 | 
			
		||||
    def test_illegal_name_changes(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_illegal_name_changes(self) -> None:
 | 
			
		||||
        user = self.example_user('hamlet')
 | 
			
		||||
        email = user.email
 | 
			
		||||
        self.login(email)
 | 
			
		||||
@@ -110,8 +105,7 @@ class ChangeSettingsTest(ZulipTestCase):
 | 
			
		||||
                                        dict(full_name='x'))
 | 
			
		||||
        self.assert_json_error(json_result, 'Name too short!')
 | 
			
		||||
 | 
			
		||||
    def test_illegal_characters_in_name_changes(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_illegal_characters_in_name_changes(self) -> None:
 | 
			
		||||
        email = self.example_email("hamlet")
 | 
			
		||||
        self.login(email)
 | 
			
		||||
 | 
			
		||||
@@ -121,30 +115,25 @@ class ChangeSettingsTest(ZulipTestCase):
 | 
			
		||||
        self.assert_json_error(json_result, 'Invalid characters in name!')
 | 
			
		||||
 | 
			
		||||
    # This is basically a don't-explode test.
 | 
			
		||||
    def test_notify_settings(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_notify_settings(self) -> None:
 | 
			
		||||
        for notification_setting in UserProfile.notification_setting_types:
 | 
			
		||||
            self.check_for_toggle_param_patch("/json/settings/notifications",
 | 
			
		||||
                                              notification_setting)
 | 
			
		||||
 | 
			
		||||
    def test_ui_settings(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_ui_settings(self) -> None:
 | 
			
		||||
        self.check_for_toggle_param_patch("/json/settings/ui", "autoscroll_forever")
 | 
			
		||||
        self.check_for_toggle_param_patch("/json/settings/ui", "default_desktop_notifications")
 | 
			
		||||
 | 
			
		||||
    def test_toggling_boolean_user_display_settings(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_toggling_boolean_user_display_settings(self) -> None:
 | 
			
		||||
        """Test updating each boolean setting in UserProfile property_types"""
 | 
			
		||||
        boolean_settings = (s for s in UserProfile.property_types if UserProfile.property_types[s] is bool)
 | 
			
		||||
        for display_setting in boolean_settings:
 | 
			
		||||
            self.check_for_toggle_param_patch("/json/settings/display", display_setting)
 | 
			
		||||
 | 
			
		||||
    def test_enter_sends_setting(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_enter_sends_setting(self) -> None:
 | 
			
		||||
        self.check_for_toggle_param('/json/users/me/enter-sends', "enter_sends")
 | 
			
		||||
 | 
			
		||||
    def test_mismatching_passwords(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_mismatching_passwords(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        new_password and confirm_password must match
 | 
			
		||||
        """
 | 
			
		||||
@@ -158,8 +147,7 @@ class ChangeSettingsTest(ZulipTestCase):
 | 
			
		||||
        self.assert_json_error(result,
 | 
			
		||||
                               "New password must match confirmation password!")
 | 
			
		||||
 | 
			
		||||
    def test_wrong_old_password(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_wrong_old_password(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        new_password and confirm_password must match
 | 
			
		||||
        """
 | 
			
		||||
@@ -173,8 +161,7 @@ class ChangeSettingsTest(ZulipTestCase):
 | 
			
		||||
            ))
 | 
			
		||||
        self.assert_json_error(result, "Wrong password!")
 | 
			
		||||
 | 
			
		||||
    def test_changing_nothing_returns_error(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_changing_nothing_returns_error(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        We need to supply at least one non-empty parameter
 | 
			
		||||
        to this API, or it should fail.  (Eventually, we should
 | 
			
		||||
@@ -185,8 +172,7 @@ class ChangeSettingsTest(ZulipTestCase):
 | 
			
		||||
                                   dict(old_password='ignored',))
 | 
			
		||||
        self.assert_json_error(result, "No new data supplied")
 | 
			
		||||
 | 
			
		||||
    def do_test_change_user_display_setting(self, setting_name):
 | 
			
		||||
        # type: (str) -> None
 | 
			
		||||
    def do_test_change_user_display_setting(self, setting_name: str) -> None:
 | 
			
		||||
 | 
			
		||||
        test_changes = dict(
 | 
			
		||||
            default_language = 'de',
 | 
			
		||||
@@ -219,8 +205,7 @@ class ChangeSettingsTest(ZulipTestCase):
 | 
			
		||||
        user_profile = self.example_user('hamlet')
 | 
			
		||||
        self.assertNotEqual(getattr(user_profile, setting_name), invalid_value)
 | 
			
		||||
 | 
			
		||||
    def test_change_user_display_setting(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_change_user_display_setting(self) -> None:
 | 
			
		||||
        """Test updating each non-boolean setting in UserProfile property_types"""
 | 
			
		||||
        user_settings = (s for s in UserProfile.property_types if UserProfile.property_types[s] is not bool)
 | 
			
		||||
        for setting in user_settings:
 | 
			
		||||
@@ -228,8 +213,7 @@ class ChangeSettingsTest(ZulipTestCase):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserChangesTest(ZulipTestCase):
 | 
			
		||||
    def test_update_api_key(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_update_api_key(self) -> None:
 | 
			
		||||
        user = self.example_user('hamlet')
 | 
			
		||||
        email = user.email
 | 
			
		||||
        self.login(email)
 | 
			
		||||
 
 | 
			
		||||
@@ -15,8 +15,7 @@ from zerver.models import (
 | 
			
		||||
 | 
			
		||||
class UserSoftDeactivationTests(ZulipTestCase):
 | 
			
		||||
 | 
			
		||||
    def test_do_soft_deactivate_user(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_do_soft_deactivate_user(self) -> None:
 | 
			
		||||
        user = self.example_user('hamlet')
 | 
			
		||||
        self.assertFalse(user.long_term_idle)
 | 
			
		||||
 | 
			
		||||
@@ -25,8 +24,7 @@ class UserSoftDeactivationTests(ZulipTestCase):
 | 
			
		||||
        user.refresh_from_db()
 | 
			
		||||
        self.assertTrue(user.long_term_idle)
 | 
			
		||||
 | 
			
		||||
    def test_do_soft_deactivate_users(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_do_soft_deactivate_users(self) -> None:
 | 
			
		||||
        users = [
 | 
			
		||||
            self.example_user('hamlet'),
 | 
			
		||||
            self.example_user('iago'),
 | 
			
		||||
@@ -45,8 +43,7 @@ class UserSoftDeactivationTests(ZulipTestCase):
 | 
			
		||||
            user.refresh_from_db()
 | 
			
		||||
            self.assertTrue(user.long_term_idle)
 | 
			
		||||
 | 
			
		||||
    def test_get_users_for_soft_deactivation(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_get_users_for_soft_deactivation(self) -> None:
 | 
			
		||||
        users = [
 | 
			
		||||
            self.example_user('hamlet'),
 | 
			
		||||
            self.example_user('iago'),
 | 
			
		||||
@@ -75,8 +72,7 @@ class UserSoftDeactivationTests(ZulipTestCase):
 | 
			
		||||
        for user in users_to_deactivate:
 | 
			
		||||
            self.assertTrue(user in users)
 | 
			
		||||
 | 
			
		||||
    def test_do_soft_activate_users(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_do_soft_activate_users(self) -> None:
 | 
			
		||||
        users = [
 | 
			
		||||
            self.example_user('hamlet'),
 | 
			
		||||
            self.example_user('iago'),
 | 
			
		||||
 
 | 
			
		||||
@@ -8,11 +8,9 @@ from zerver.lib.subdomains import get_subdomain
 | 
			
		||||
from zerver.models import Realm
 | 
			
		||||
 | 
			
		||||
class SubdomainsTest(TestCase):
 | 
			
		||||
    def test_get_subdomain(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_get_subdomain(self) -> None:
 | 
			
		||||
 | 
			
		||||
        def request_mock(host):
 | 
			
		||||
            # type: (str) -> Any
 | 
			
		||||
        def request_mock(host: str) -> Any:
 | 
			
		||||
            request = mock.Mock(spec=['get_host'])
 | 
			
		||||
            request.attach_mock(mock.Mock(return_value=host), 'get_host')
 | 
			
		||||
            return request
 | 
			
		||||
 
 | 
			
		||||
@@ -11,8 +11,7 @@ from dateutil import parser
 | 
			
		||||
import pytz
 | 
			
		||||
 | 
			
		||||
class TestTimestamp(ZulipTestCase):
 | 
			
		||||
    def test_datetime_and_timestamp_conversions(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_datetime_and_timestamp_conversions(self) -> None:
 | 
			
		||||
        timestamp = 1483228800
 | 
			
		||||
        for dt in [
 | 
			
		||||
                parser.parse('2017-01-01 00:00:00.123 UTC'),
 | 
			
		||||
@@ -27,8 +26,7 @@ class TestTimestamp(ZulipTestCase):
 | 
			
		||||
            with self.assertRaises(TimezoneNotUTCException):
 | 
			
		||||
                datetime_to_timestamp(dt)
 | 
			
		||||
 | 
			
		||||
    def test_convert_to_UTC(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_convert_to_UTC(self) -> None:
 | 
			
		||||
        utc_datetime = parser.parse('2017-01-01 00:00:00.123 UTC')
 | 
			
		||||
        for dt in [
 | 
			
		||||
                parser.parse('2017-01-01 00:00:00.123').replace(tzinfo=timezone_utc),
 | 
			
		||||
@@ -36,8 +34,7 @@ class TestTimestamp(ZulipTestCase):
 | 
			
		||||
                parser.parse('2017-01-01 05:00:00.123+05')]:
 | 
			
		||||
            self.assertEqual(convert_to_UTC(dt), utc_datetime)
 | 
			
		||||
 | 
			
		||||
    def test_enforce_UTC(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_enforce_UTC(self) -> None:
 | 
			
		||||
        non_utc_datetime = parser.parse('2017-01-01 00:00:00.123')
 | 
			
		||||
        for function in [floor_to_hour, floor_to_day, ceiling_to_hour, ceiling_to_hour]:
 | 
			
		||||
            with self.assertRaises(TimezoneNotUTCException):
 | 
			
		||||
 
 | 
			
		||||
@@ -8,8 +8,7 @@ from typing import Any, Dict
 | 
			
		||||
import ujson
 | 
			
		||||
 | 
			
		||||
class TutorialTests(ZulipTestCase):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def setUp(self) -> None:
 | 
			
		||||
        # This emulates the welcome message sent by the welcome bot to hamlet@zulip.com
 | 
			
		||||
        # This is only a quick fix - ideally, we would have this message sent by the initialization
 | 
			
		||||
        # code in populate_db.py
 | 
			
		||||
@@ -18,8 +17,7 @@ class TutorialTests(ZulipTestCase):
 | 
			
		||||
        content = 'Shortened welcome message.'
 | 
			
		||||
        self.send_personal_message(bot_email, user_email, content)
 | 
			
		||||
 | 
			
		||||
    def test_tutorial_status(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_tutorial_status(self) -> None:
 | 
			
		||||
        email = self.example_email('hamlet')
 | 
			
		||||
        self.login(email)
 | 
			
		||||
 | 
			
		||||
@@ -34,8 +32,7 @@ class TutorialTests(ZulipTestCase):
 | 
			
		||||
            user = self.example_user('hamlet')
 | 
			
		||||
            self.assertEqual(user.tutorial_status, expected_db_status)
 | 
			
		||||
 | 
			
		||||
    def test_single_response_to_pm(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_single_response_to_pm(self) -> None:
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
        user_email = 'hamlet@zulip.com'
 | 
			
		||||
        bot_email = 'welcome-bot@zulip.com'
 | 
			
		||||
@@ -52,8 +49,7 @@ class TutorialTests(ZulipTestCase):
 | 
			
		||||
        self.send_personal_message(user_email, bot_email, content)
 | 
			
		||||
        self.assertEqual(message_stream_count(user), user_messages+1)
 | 
			
		||||
 | 
			
		||||
    def test_no_response_to_group_pm(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_no_response_to_group_pm(self) -> None:
 | 
			
		||||
        realm = get_realm('zulip')  # Assume realm is always 'zulip'
 | 
			
		||||
        user1_email = self.example_email('hamlet')
 | 
			
		||||
        user2_email = self.example_email('cordelia')
 | 
			
		||||
 
 | 
			
		||||
@@ -9,27 +9,22 @@ from typing import Any, Callable, Dict, Iterable, Tuple, TypeVar, List
 | 
			
		||||
 | 
			
		||||
T = TypeVar('T')
 | 
			
		||||
 | 
			
		||||
def add(x=0, y=0):
 | 
			
		||||
    # type: (Any, Any) -> Any
 | 
			
		||||
def add(x: Any=0, y: Any=0) -> Any:
 | 
			
		||||
    return x + y
 | 
			
		||||
 | 
			
		||||
def to_dict(v=[]):
 | 
			
		||||
    # type: (Iterable[Tuple[Any, Any]]) -> Dict[Any, Any]
 | 
			
		||||
def to_dict(v: Iterable[Tuple[Any, Any]]=[]) -> Dict[Any, Any]:
 | 
			
		||||
    return dict(v)
 | 
			
		||||
 | 
			
		||||
class TypesPrintTest(TestCase):
 | 
			
		||||
 | 
			
		||||
    # These 2 methods are needed to run tests with our custom test-runner
 | 
			
		||||
    def _pre_setup(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def _pre_setup(self) -> None:
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def _post_teardown(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def _post_teardown(self) -> None:
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def check_signature(self, signature, retval, func, *args, **kwargs):
 | 
			
		||||
        # type: (str, T, Callable[..., T], *Any, **Any) -> None
 | 
			
		||||
    def check_signature(self, signature: str, retval: T, func: Callable[..., T], *args: Any, **kwargs: Any) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Checks if print_types outputs `signature` when func is called with *args and **kwargs.
 | 
			
		||||
        Do not decorate func with print_types before passing into this function.
 | 
			
		||||
@@ -43,16 +38,13 @@ class TypesPrintTest(TestCase):
 | 
			
		||||
        finally:
 | 
			
		||||
            sys.stdout = original_stdout
 | 
			
		||||
 | 
			
		||||
    def test_empty(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
        def empty_func():
 | 
			
		||||
            # type: () -> None
 | 
			
		||||
    def test_empty(self) -> None:
 | 
			
		||||
        def empty_func() -> None:
 | 
			
		||||
            pass
 | 
			
		||||
        self.check_signature("empty_func() -> None", None, empty_func)
 | 
			
		||||
        self.check_signature("<lambda>() -> None", None, (lambda: None))  # type: ignore # https://github.com/python/mypy/issues/1932
 | 
			
		||||
 | 
			
		||||
    def test_basic(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_basic(self) -> None:
 | 
			
		||||
        self.check_signature("add(float, int) -> float",
 | 
			
		||||
                             5.0, add, 2.0, 3)
 | 
			
		||||
        self.check_signature("add(float, y=int) -> float",
 | 
			
		||||
@@ -60,8 +52,7 @@ class TypesPrintTest(TestCase):
 | 
			
		||||
        self.check_signature("add(x=int) -> int", 2, add, x=2)
 | 
			
		||||
        self.check_signature("add() -> int", 0, add)
 | 
			
		||||
 | 
			
		||||
    def test_list(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_list(self) -> None:
 | 
			
		||||
        self.check_signature("add([], [str]) -> [str]",
 | 
			
		||||
                             ['two'], add, [], ['two'])
 | 
			
		||||
        self.check_signature("add([int], [str]) -> [int, ...]",
 | 
			
		||||
@@ -69,8 +60,7 @@ class TypesPrintTest(TestCase):
 | 
			
		||||
        self.check_signature("add([int, ...], y=[]) -> [int, ...]",
 | 
			
		||||
                             [2, 'two'], add, [2, 'two'], y=[])
 | 
			
		||||
 | 
			
		||||
    def test_dict(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_dict(self) -> None:
 | 
			
		||||
        self.check_signature("to_dict() -> {}", {}, to_dict)
 | 
			
		||||
        self.check_signature("to_dict([(int, str)]) -> {int: str}",
 | 
			
		||||
                             {2: 'two'}, to_dict, [(2, 'two')])
 | 
			
		||||
@@ -79,8 +69,7 @@ class TypesPrintTest(TestCase):
 | 
			
		||||
        self.check_signature("to_dict([(int, str), ...]) -> {int: str, ...}",
 | 
			
		||||
                             {1: 'one', 2: 'two'}, to_dict, [(1, 'one'), (2, 'two')])
 | 
			
		||||
 | 
			
		||||
    def test_tuple(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_tuple(self) -> None:
 | 
			
		||||
        self.check_signature("add((), ()) -> ()",
 | 
			
		||||
                             (), add, (), ())
 | 
			
		||||
        self.check_signature("add((int,), (str,)) -> (int, str)",
 | 
			
		||||
@@ -88,8 +77,7 @@ class TypesPrintTest(TestCase):
 | 
			
		||||
        self.check_signature("add(((),), ((),)) -> ((), ())",
 | 
			
		||||
                             ((), ()), add, ((),), ((),))
 | 
			
		||||
 | 
			
		||||
    def test_class(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_class(self) -> None:
 | 
			
		||||
        class A:
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
@@ -99,8 +87,7 @@ class TypesPrintTest(TestCase):
 | 
			
		||||
        self.check_signature("<lambda>(A) -> str", 'A', (lambda x: x.__class__.__name__), A())
 | 
			
		||||
        self.check_signature("<lambda>(B) -> int", 5, (lambda x: len(x)), B("hello"))
 | 
			
		||||
 | 
			
		||||
    def test_sequence(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_sequence(self) -> None:
 | 
			
		||||
        class A(List[Any]):
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
@@ -114,13 +101,11 @@ class TypesPrintTest(TestCase):
 | 
			
		||||
        self.check_signature("add(A([int, ...]), y=B([])) -> [int, ...]",
 | 
			
		||||
                             [2, 'two'], add, A([2, 'two']), y=B([]))
 | 
			
		||||
 | 
			
		||||
    def test_mapping(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_mapping(self) -> None:
 | 
			
		||||
        class A(Dict[Any, Any]):
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
        def to_A(v=[]):
 | 
			
		||||
            # type: (Iterable[Tuple[Any, Any]]) -> A
 | 
			
		||||
        def to_A(v: Iterable[Tuple[Any, Any]]=[]) -> A:
 | 
			
		||||
            return A(v)
 | 
			
		||||
 | 
			
		||||
        self.check_signature("to_A() -> A([])", A(()), to_A)
 | 
			
		||||
 
 | 
			
		||||
@@ -11,8 +11,7 @@ from zerver.lib.test_classes import (
 | 
			
		||||
from zerver.models import get_realm, get_user
 | 
			
		||||
 | 
			
		||||
class TypingNotificationOperatorTest(ZulipTestCase):
 | 
			
		||||
    def test_missing_parameter(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_missing_parameter(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Sending typing notification without op parameter fails
 | 
			
		||||
        """
 | 
			
		||||
@@ -22,8 +21,7 @@ class TypingNotificationOperatorTest(ZulipTestCase):
 | 
			
		||||
                                  **self.api_auth(sender))
 | 
			
		||||
        self.assert_json_error(result, 'Missing \'op\' argument')
 | 
			
		||||
 | 
			
		||||
    def test_invalid_parameter(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_invalid_parameter(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Sending typing notification with invalid value for op parameter fails
 | 
			
		||||
        """
 | 
			
		||||
@@ -34,8 +32,7 @@ class TypingNotificationOperatorTest(ZulipTestCase):
 | 
			
		||||
        self.assert_json_error(result, 'Invalid \'op\' value (should be start or stop)')
 | 
			
		||||
 | 
			
		||||
class TypingNotificationRecipientsTest(ZulipTestCase):
 | 
			
		||||
    def test_missing_recipient(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_missing_recipient(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Sending typing notification without recipient fails
 | 
			
		||||
        """
 | 
			
		||||
@@ -44,8 +41,7 @@ class TypingNotificationRecipientsTest(ZulipTestCase):
 | 
			
		||||
                                  **self.api_auth(sender))
 | 
			
		||||
        self.assert_json_error(result, 'Missing parameter: \'to\' (recipient)')
 | 
			
		||||
 | 
			
		||||
    def test_invalid_recipient(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_invalid_recipient(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Sending typing notification to invalid recipient fails
 | 
			
		||||
        """
 | 
			
		||||
@@ -55,8 +51,7 @@ class TypingNotificationRecipientsTest(ZulipTestCase):
 | 
			
		||||
                                  **self.api_auth(sender))
 | 
			
		||||
        self.assert_json_error(result, 'Invalid email \'' + invalid + '\'')
 | 
			
		||||
 | 
			
		||||
    def test_single_recipient(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_single_recipient(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Sending typing notification to a single recipient is successful
 | 
			
		||||
        """
 | 
			
		||||
@@ -86,8 +81,7 @@ class TypingNotificationRecipientsTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(event['type'], 'typing')
 | 
			
		||||
        self.assertEqual(event['op'], 'start')
 | 
			
		||||
 | 
			
		||||
    def test_multiple_recipients(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_multiple_recipients(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Sending typing notification to a single recipient is successful
 | 
			
		||||
        """
 | 
			
		||||
@@ -117,8 +111,7 @@ class TypingNotificationRecipientsTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(event['op'], 'start')
 | 
			
		||||
 | 
			
		||||
class TypingStartedNotificationTest(ZulipTestCase):
 | 
			
		||||
    def test_send_notification_to_self_event(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_send_notification_to_self_event(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Sending typing notification to yourself
 | 
			
		||||
        is successful.
 | 
			
		||||
@@ -147,8 +140,7 @@ class TypingStartedNotificationTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(event['type'], 'typing')
 | 
			
		||||
        self.assertEqual(event['op'], 'start')
 | 
			
		||||
 | 
			
		||||
    def test_send_notification_to_another_user_event(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_send_notification_to_another_user_event(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Sending typing notification to another user
 | 
			
		||||
        is successful.
 | 
			
		||||
@@ -180,8 +172,7 @@ class TypingStartedNotificationTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(event['op'], 'start')
 | 
			
		||||
 | 
			
		||||
class StoppedTypingNotificationTest(ZulipTestCase):
 | 
			
		||||
    def test_send_notification_to_self_event(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_send_notification_to_self_event(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Sending stopped typing notification to yourself
 | 
			
		||||
        is successful.
 | 
			
		||||
@@ -211,8 +202,7 @@ class StoppedTypingNotificationTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(event['type'], 'typing')
 | 
			
		||||
        self.assertEqual(event['op'], 'stop')
 | 
			
		||||
 | 
			
		||||
    def test_send_notification_to_another_user_event(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_send_notification_to_another_user_event(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Sending stopped typing notification to another user
 | 
			
		||||
        is successful.
 | 
			
		||||
 
 | 
			
		||||
@@ -34,8 +34,7 @@ import ujson
 | 
			
		||||
 | 
			
		||||
class PointerTest(ZulipTestCase):
 | 
			
		||||
 | 
			
		||||
    def test_update_pointer(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_update_pointer(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Posting a pointer to /update (in the form {"pointer": pointer}) changes
 | 
			
		||||
        the pointer we store for your UserProfile.
 | 
			
		||||
@@ -47,8 +46,7 @@ class PointerTest(ZulipTestCase):
 | 
			
		||||
        self.assert_json_success(result)
 | 
			
		||||
        self.assertEqual(self.example_user('hamlet').pointer, msg_id)
 | 
			
		||||
 | 
			
		||||
    def test_api_update_pointer(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_api_update_pointer(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Same as above, but for the API view
 | 
			
		||||
        """
 | 
			
		||||
@@ -61,8 +59,7 @@ class PointerTest(ZulipTestCase):
 | 
			
		||||
        self.assert_json_success(result)
 | 
			
		||||
        self.assertEqual(get_user(email, user.realm).pointer, msg_id)
 | 
			
		||||
 | 
			
		||||
    def test_missing_pointer(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_missing_pointer(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Posting json to /json/users/me/pointer which does not contain a pointer key/value pair
 | 
			
		||||
        returns a 400 and error message.
 | 
			
		||||
@@ -73,8 +70,7 @@ class PointerTest(ZulipTestCase):
 | 
			
		||||
        self.assert_json_error(result, "Missing 'pointer' argument")
 | 
			
		||||
        self.assertEqual(self.example_user('hamlet').pointer, -1)
 | 
			
		||||
 | 
			
		||||
    def test_invalid_pointer(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_invalid_pointer(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Posting json to /json/users/me/pointer with an invalid pointer returns a 400 and error
 | 
			
		||||
        message.
 | 
			
		||||
@@ -85,8 +81,7 @@ class PointerTest(ZulipTestCase):
 | 
			
		||||
        self.assert_json_error(result, "Bad value for 'pointer': foo")
 | 
			
		||||
        self.assertEqual(self.example_user('hamlet').pointer, -1)
 | 
			
		||||
 | 
			
		||||
    def test_pointer_out_of_range(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_pointer_out_of_range(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Posting json to /json/users/me/pointer with an out of range (< 0) pointer returns a 400
 | 
			
		||||
        and error message.
 | 
			
		||||
@@ -97,8 +92,7 @@ class PointerTest(ZulipTestCase):
 | 
			
		||||
        self.assert_json_error(result, "Bad value for 'pointer': -2")
 | 
			
		||||
        self.assertEqual(self.example_user('hamlet').pointer, -1)
 | 
			
		||||
 | 
			
		||||
    def test_use_first_unread_anchor_interaction_with_pointer(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_use_first_unread_anchor_interaction_with_pointer(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Getting old messages (a get request to /json/messages) should never
 | 
			
		||||
        return an unread message older than the current pointer, when there's
 | 
			
		||||
@@ -177,8 +171,7 @@ class PointerTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(messages[0]['id'], new_message_id)
 | 
			
		||||
 | 
			
		||||
class UnreadCountTests(ZulipTestCase):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def setUp(self) -> None:
 | 
			
		||||
        self.unread_msg_ids = [
 | 
			
		||||
            self.send_personal_message(
 | 
			
		||||
                self.example_email("iago"), self.example_email("hamlet"), "hello"),
 | 
			
		||||
@@ -186,8 +179,7 @@ class UnreadCountTests(ZulipTestCase):
 | 
			
		||||
                self.example_email("iago"), self.example_email("hamlet"), "hello2")]
 | 
			
		||||
 | 
			
		||||
    # Sending a new message results in unread UserMessages being created
 | 
			
		||||
    def test_new_message(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_new_message(self) -> None:
 | 
			
		||||
        self.login(self.example_email("hamlet"))
 | 
			
		||||
        content = "Test message for unset read bit"
 | 
			
		||||
        last_msg = self.send_stream_message(self.example_email("hamlet"), "Verona", content)
 | 
			
		||||
@@ -198,8 +190,7 @@ class UnreadCountTests(ZulipTestCase):
 | 
			
		||||
            if um.user_profile.email != self.example_email("hamlet"):
 | 
			
		||||
                self.assertFalse(um.flags.read)
 | 
			
		||||
 | 
			
		||||
    def test_update_flags(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_update_flags(self) -> None:
 | 
			
		||||
        self.login(self.example_email("hamlet"))
 | 
			
		||||
 | 
			
		||||
        result = self.client_post("/json/messages/flags",
 | 
			
		||||
@@ -228,8 +219,7 @@ class UnreadCountTests(ZulipTestCase):
 | 
			
		||||
            elif msg['id'] == self.unread_msg_ids[1]:
 | 
			
		||||
                self.assertEqual(msg['flags'], [])
 | 
			
		||||
 | 
			
		||||
    def test_mark_all_in_stream_read(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_mark_all_in_stream_read(self) -> None:
 | 
			
		||||
        self.login(self.example_email("hamlet"))
 | 
			
		||||
        user_profile = self.example_user('hamlet')
 | 
			
		||||
        stream = self.subscribe(user_profile, "test_stream")
 | 
			
		||||
@@ -269,8 +259,7 @@ class UnreadCountTests(ZulipTestCase):
 | 
			
		||||
            if msg.user_profile.email == self.example_email("hamlet"):
 | 
			
		||||
                self.assertFalse(msg.flags.read)
 | 
			
		||||
 | 
			
		||||
    def test_mark_all_in_invalid_stream_read(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_mark_all_in_invalid_stream_read(self) -> None:
 | 
			
		||||
        self.login(self.example_email("hamlet"))
 | 
			
		||||
        invalid_stream_id = "12345678"
 | 
			
		||||
        result = self.client_post("/json/mark_stream_as_read", {
 | 
			
		||||
@@ -278,8 +267,7 @@ class UnreadCountTests(ZulipTestCase):
 | 
			
		||||
        })
 | 
			
		||||
        self.assert_json_error(result, 'Invalid stream id')
 | 
			
		||||
 | 
			
		||||
    def test_mark_all_topics_unread_with_invalid_stream_name(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_mark_all_topics_unread_with_invalid_stream_name(self) -> None:
 | 
			
		||||
        self.login(self.example_email("hamlet"))
 | 
			
		||||
        invalid_stream_id = "12345678"
 | 
			
		||||
        result = self.client_post("/json/mark_topic_as_read", {
 | 
			
		||||
@@ -288,8 +276,7 @@ class UnreadCountTests(ZulipTestCase):
 | 
			
		||||
        })
 | 
			
		||||
        self.assert_json_error(result, "Invalid stream id")
 | 
			
		||||
 | 
			
		||||
    def test_mark_all_in_stream_topic_read(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_mark_all_in_stream_topic_read(self) -> None:
 | 
			
		||||
        self.login(self.example_email("hamlet"))
 | 
			
		||||
        user_profile = self.example_user('hamlet')
 | 
			
		||||
        self.subscribe(user_profile, "test_stream")
 | 
			
		||||
@@ -326,8 +313,7 @@ class UnreadCountTests(ZulipTestCase):
 | 
			
		||||
            if msg.user_profile.email == self.example_email("hamlet"):
 | 
			
		||||
                self.assertFalse(msg.flags.read)
 | 
			
		||||
 | 
			
		||||
    def test_mark_all_in_invalid_topic_read(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_mark_all_in_invalid_topic_read(self) -> None:
 | 
			
		||||
        self.login(self.example_email("hamlet"))
 | 
			
		||||
        invalid_topic_name = "abc"
 | 
			
		||||
        result = self.client_post("/json/mark_topic_as_read", {
 | 
			
		||||
@@ -337,13 +323,11 @@ class UnreadCountTests(ZulipTestCase):
 | 
			
		||||
        self.assert_json_error(result, 'No such topic \'abc\'')
 | 
			
		||||
 | 
			
		||||
class FixUnreadTests(ZulipTestCase):
 | 
			
		||||
    def test_fix_unreads(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_fix_unreads(self) -> None:
 | 
			
		||||
        user = self.example_user('hamlet')
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
 | 
			
		||||
        def send_message(stream_name, topic_name):
 | 
			
		||||
            # type: (Text, Text) -> int
 | 
			
		||||
        def send_message(stream_name: Text, topic_name: Text) -> int:
 | 
			
		||||
            msg_id = self.send_stream_message(
 | 
			
		||||
                self.example_email("othello"),
 | 
			
		||||
                stream_name,
 | 
			
		||||
@@ -353,18 +337,15 @@ class FixUnreadTests(ZulipTestCase):
 | 
			
		||||
                message_id=msg_id)
 | 
			
		||||
            return um.id
 | 
			
		||||
 | 
			
		||||
        def assert_read(user_message_id):
 | 
			
		||||
            # type: (int) -> None
 | 
			
		||||
        def assert_read(user_message_id: int) -> None:
 | 
			
		||||
            um = UserMessage.objects.get(id=user_message_id)
 | 
			
		||||
            self.assertTrue(um.flags.read)
 | 
			
		||||
 | 
			
		||||
        def assert_unread(user_message_id):
 | 
			
		||||
            # type: (int) -> None
 | 
			
		||||
        def assert_unread(user_message_id: int) -> None:
 | 
			
		||||
            um = UserMessage.objects.get(id=user_message_id)
 | 
			
		||||
            self.assertFalse(um.flags.read)
 | 
			
		||||
 | 
			
		||||
        def mute_stream(stream_name):
 | 
			
		||||
            # type: (Text) -> None
 | 
			
		||||
        def mute_stream(stream_name: Text) -> None:
 | 
			
		||||
            stream = get_stream(stream_name, realm)
 | 
			
		||||
            recipient = get_stream_recipient(stream.id)
 | 
			
		||||
            subscription = Subscription.objects.get(
 | 
			
		||||
@@ -374,8 +355,7 @@ class FixUnreadTests(ZulipTestCase):
 | 
			
		||||
            subscription.in_home_view = False
 | 
			
		||||
            subscription.save()
 | 
			
		||||
 | 
			
		||||
        def mute_topic(stream_name, topic_name):
 | 
			
		||||
            # type: (Text, Text) -> None
 | 
			
		||||
        def mute_topic(stream_name: Text, topic_name: Text) -> None:
 | 
			
		||||
            stream = get_stream(stream_name, realm)
 | 
			
		||||
            recipient = get_stream_recipient(stream.id)
 | 
			
		||||
 | 
			
		||||
@@ -386,8 +366,7 @@ class FixUnreadTests(ZulipTestCase):
 | 
			
		||||
                topic_name=topic_name,
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        def force_unsubscribe(stream_name):
 | 
			
		||||
            # type: (Text) -> None
 | 
			
		||||
        def force_unsubscribe(stream_name: Text) -> None:
 | 
			
		||||
            '''
 | 
			
		||||
            We don't want side effects here, since the eventual
 | 
			
		||||
            unsubscribe path may mark messages as read, defeating
 | 
			
		||||
 
 | 
			
		||||
@@ -19,8 +19,7 @@ class PublicURLTest(ZulipTestCase):
 | 
			
		||||
    URLs redirect to a page.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def fetch(self, method, urls, expected_status):
 | 
			
		||||
        # type: (str, List[str], int) -> None
 | 
			
		||||
    def fetch(self, method: str, urls: List[str], expected_status: int) -> None:
 | 
			
		||||
        for url in urls:
 | 
			
		||||
            # e.g. self.client_post(url) if method is "post"
 | 
			
		||||
            response = getattr(self, method)(url)
 | 
			
		||||
@@ -29,8 +28,7 @@ class PublicURLTest(ZulipTestCase):
 | 
			
		||||
                                 expected_status, response.status_code, method, url))
 | 
			
		||||
 | 
			
		||||
    @slow("Tests dozens of endpoints, including all of our /help/ documents")
 | 
			
		||||
    def test_public_urls(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_public_urls(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Test which views are accessible when not logged in.
 | 
			
		||||
        """
 | 
			
		||||
@@ -89,8 +87,7 @@ class PublicURLTest(ZulipTestCase):
 | 
			
		||||
        for status_code, url_set in put_urls.items():
 | 
			
		||||
            self.fetch("client_put", url_set, status_code)
 | 
			
		||||
 | 
			
		||||
    def test_get_gcid_when_not_configured(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_get_gcid_when_not_configured(self) -> None:
 | 
			
		||||
        with self.settings(GOOGLE_CLIENT_ID=None):
 | 
			
		||||
            resp = self.client_get("/api/v1/fetch_google_client_id")
 | 
			
		||||
            self.assertEqual(400, resp.status_code,
 | 
			
		||||
@@ -98,8 +95,7 @@ class PublicURLTest(ZulipTestCase):
 | 
			
		||||
                                 resp.status_code,))
 | 
			
		||||
            self.assertEqual('error', resp.json()['result'])
 | 
			
		||||
 | 
			
		||||
    def test_get_gcid_when_configured(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_get_gcid_when_configured(self) -> None:
 | 
			
		||||
        with self.settings(GOOGLE_CLIENT_ID="ABCD"):
 | 
			
		||||
            resp = self.client_get("/api/v1/fetch_google_client_id")
 | 
			
		||||
            self.assertEqual(200, resp.status_code,
 | 
			
		||||
@@ -110,20 +106,17 @@ class PublicURLTest(ZulipTestCase):
 | 
			
		||||
            self.assertEqual('ABCD', data['google_client_id'])
 | 
			
		||||
 | 
			
		||||
class URLResolutionTest(TestCase):
 | 
			
		||||
    def get_callback_string(self, pattern):
 | 
			
		||||
        # type: (django.core.urlresolvers.RegexURLPattern) -> Optional[str]
 | 
			
		||||
    def get_callback_string(self, pattern: django.core.urlresolvers.RegexURLPattern) -> Optional[str]:
 | 
			
		||||
        callback_str = hasattr(pattern, 'lookup_str') and 'lookup_str'
 | 
			
		||||
        callback_str = callback_str or '_callback_str'
 | 
			
		||||
        return getattr(pattern, callback_str, None)
 | 
			
		||||
 | 
			
		||||
    def check_function_exists(self, module_name, view):
 | 
			
		||||
        # type: (str, str) -> None
 | 
			
		||||
    def check_function_exists(self, module_name: str, view: str) -> None:
 | 
			
		||||
        module = importlib.import_module(module_name)
 | 
			
		||||
        self.assertTrue(hasattr(module, view), "View %s.%s does not exist" % (module_name, view))
 | 
			
		||||
 | 
			
		||||
    # Tests that all views in urls.v1_api_and_json_patterns exist
 | 
			
		||||
    def test_rest_api_url_resolution(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_rest_api_url_resolution(self) -> None:
 | 
			
		||||
        for pattern in urls.v1_api_and_json_patterns:
 | 
			
		||||
            callback_str = self.get_callback_string(pattern)
 | 
			
		||||
            if callback_str and hasattr(pattern, "default_args"):
 | 
			
		||||
@@ -136,8 +129,7 @@ class URLResolutionTest(TestCase):
 | 
			
		||||
    # Tests function-based views declared in urls.urlpatterns for
 | 
			
		||||
    # whether the function exists.  We at present do not test the
 | 
			
		||||
    # class-based views.
 | 
			
		||||
    def test_non_api_url_resolution(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_non_api_url_resolution(self) -> None:
 | 
			
		||||
        for pattern in urls.urlpatterns:
 | 
			
		||||
            callback_str = self.get_callback_string(pattern)
 | 
			
		||||
            if callback_str:
 | 
			
		||||
@@ -145,8 +137,7 @@ class URLResolutionTest(TestCase):
 | 
			
		||||
                self.check_function_exists(module_name, base_view)
 | 
			
		||||
 | 
			
		||||
class ErrorPageTest(TestCase):
 | 
			
		||||
    def test_bogus_http_host(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_bogus_http_host(self) -> None:
 | 
			
		||||
        # This tests that we've successfully worked around a certain bug in
 | 
			
		||||
        # Django's exception handling.  The enforce_csrf_checks=True,
 | 
			
		||||
        # secure=True, and HTTP_REFERER with an `https:` scheme are all
 | 
			
		||||
 
 | 
			
		||||
@@ -47,16 +47,14 @@ import ujson
 | 
			
		||||
 | 
			
		||||
K = TypeVar('K')
 | 
			
		||||
V = TypeVar('V')
 | 
			
		||||
def find_dict(lst, k, v):
 | 
			
		||||
    # type: (Iterable[Dict[K, V]], K, V) -> Dict[K, V]
 | 
			
		||||
def find_dict(lst: Iterable[Dict[K, V]], k: K, v: V) -> Dict[K, V]:
 | 
			
		||||
    for dct in lst:
 | 
			
		||||
        if dct[k] == v:
 | 
			
		||||
            return dct
 | 
			
		||||
    raise AssertionError('Cannot find element in list where key %s == %s' % (k, v))
 | 
			
		||||
 | 
			
		||||
class PermissionTest(ZulipTestCase):
 | 
			
		||||
    def test_get_admin_users(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_get_admin_users(self) -> None:
 | 
			
		||||
        user_profile = self.example_user('hamlet')
 | 
			
		||||
        do_change_is_admin(user_profile, False)
 | 
			
		||||
        admin_users = user_profile.realm.get_admin_users()
 | 
			
		||||
@@ -65,8 +63,7 @@ class PermissionTest(ZulipTestCase):
 | 
			
		||||
        admin_users = user_profile.realm.get_admin_users()
 | 
			
		||||
        self.assertTrue(user_profile in admin_users)
 | 
			
		||||
 | 
			
		||||
    def test_updating_non_existent_user(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_updating_non_existent_user(self) -> None:
 | 
			
		||||
        self.login(self.example_email("hamlet"))
 | 
			
		||||
        admin = self.example_user('hamlet')
 | 
			
		||||
        do_change_is_admin(admin, True)
 | 
			
		||||
@@ -74,8 +71,7 @@ class PermissionTest(ZulipTestCase):
 | 
			
		||||
        result = self.client_patch('/json/users/nonexistentuser@zulip.com', {})
 | 
			
		||||
        self.assert_json_error(result, 'No such user')
 | 
			
		||||
 | 
			
		||||
    def test_admin_api(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_admin_api(self) -> None:
 | 
			
		||||
        self.login(self.example_email("hamlet"))
 | 
			
		||||
        admin = self.example_user('hamlet')
 | 
			
		||||
        user = self.example_user('othello')
 | 
			
		||||
@@ -137,8 +133,7 @@ class PermissionTest(ZulipTestCase):
 | 
			
		||||
        result = self.client_patch('/json/users/hamlet@zulip.com', req)
 | 
			
		||||
        self.assert_json_error(result, 'Insufficient permission')
 | 
			
		||||
 | 
			
		||||
    def test_admin_user_can_change_full_name(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_admin_user_can_change_full_name(self) -> None:
 | 
			
		||||
        new_name = 'new name'
 | 
			
		||||
        self.login(self.example_email("iago"))
 | 
			
		||||
        req = dict(full_name=ujson.dumps(new_name))
 | 
			
		||||
@@ -147,31 +142,27 @@ class PermissionTest(ZulipTestCase):
 | 
			
		||||
        hamlet = self.example_user('hamlet')
 | 
			
		||||
        self.assertEqual(hamlet.full_name, new_name)
 | 
			
		||||
 | 
			
		||||
    def test_non_admin_cannot_change_full_name(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_non_admin_cannot_change_full_name(self) -> None:
 | 
			
		||||
        self.login(self.example_email("hamlet"))
 | 
			
		||||
        req = dict(full_name=ujson.dumps('new name'))
 | 
			
		||||
        result = self.client_patch('/json/users/othello@zulip.com', req)
 | 
			
		||||
        self.assert_json_error(result, 'Insufficient permission')
 | 
			
		||||
 | 
			
		||||
    def test_admin_cannot_set_long_full_name(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_admin_cannot_set_long_full_name(self) -> None:
 | 
			
		||||
        new_name = 'a' * (UserProfile.MAX_NAME_LENGTH + 1)
 | 
			
		||||
        self.login(self.example_email("iago"))
 | 
			
		||||
        req = dict(full_name=ujson.dumps(new_name))
 | 
			
		||||
        result = self.client_patch('/json/users/hamlet@zulip.com', req)
 | 
			
		||||
        self.assert_json_error(result, 'Name too long!')
 | 
			
		||||
 | 
			
		||||
    def test_admin_cannot_set_short_full_name(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_admin_cannot_set_short_full_name(self) -> None:
 | 
			
		||||
        new_name = 'a'
 | 
			
		||||
        self.login(self.example_email("iago"))
 | 
			
		||||
        req = dict(full_name=ujson.dumps(new_name))
 | 
			
		||||
        result = self.client_patch('/json/users/hamlet@zulip.com', req)
 | 
			
		||||
        self.assert_json_error(result, 'Name too short!')
 | 
			
		||||
 | 
			
		||||
    def test_admin_cannot_set_full_name_with_invalid_characters(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_admin_cannot_set_full_name_with_invalid_characters(self) -> None:
 | 
			
		||||
        new_name = 'Opheli*'
 | 
			
		||||
        self.login(self.example_email("iago"))
 | 
			
		||||
        req = dict(full_name=ujson.dumps(new_name))
 | 
			
		||||
@@ -179,8 +170,7 @@ class PermissionTest(ZulipTestCase):
 | 
			
		||||
        self.assert_json_error(result, 'Invalid characters in name!')
 | 
			
		||||
 | 
			
		||||
class AdminCreateUserTest(ZulipTestCase):
 | 
			
		||||
    def test_create_user_backend(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_create_user_backend(self) -> None:
 | 
			
		||||
 | 
			
		||||
        # This test should give us complete coverage on
 | 
			
		||||
        # create_user_backend.  It mostly exercises error
 | 
			
		||||
@@ -254,16 +244,14 @@ class AdminCreateUserTest(ZulipTestCase):
 | 
			
		||||
                               "Email 'romeo@zulip.net' already in use")
 | 
			
		||||
 | 
			
		||||
class UserProfileTest(ZulipTestCase):
 | 
			
		||||
    def test_get_emails_from_user_ids(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_get_emails_from_user_ids(self) -> None:
 | 
			
		||||
        hamlet = self.example_user('hamlet')
 | 
			
		||||
        othello = self.example_user('othello')
 | 
			
		||||
        dct = get_emails_from_user_ids([hamlet.id, othello.id])
 | 
			
		||||
        self.assertEqual(dct[hamlet.id], self.example_email("hamlet"))
 | 
			
		||||
        self.assertEqual(dct[othello.id], self.example_email("othello"))
 | 
			
		||||
 | 
			
		||||
    def test_cache_invalidation(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_cache_invalidation(self) -> None:
 | 
			
		||||
        hamlet = self.example_user('hamlet')
 | 
			
		||||
        with mock.patch('zerver.lib.cache.delete_display_recipient_cache') as m:
 | 
			
		||||
            hamlet.full_name = 'Hamlet Junior'
 | 
			
		||||
@@ -278,16 +266,14 @@ class UserProfileTest(ZulipTestCase):
 | 
			
		||||
        self.assertFalse(m.called)
 | 
			
		||||
 | 
			
		||||
class ActivateTest(ZulipTestCase):
 | 
			
		||||
    def test_basics(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_basics(self) -> None:
 | 
			
		||||
        user = self.example_user('hamlet')
 | 
			
		||||
        do_deactivate_user(user)
 | 
			
		||||
        self.assertFalse(user.is_active)
 | 
			
		||||
        do_reactivate_user(user)
 | 
			
		||||
        self.assertTrue(user.is_active)
 | 
			
		||||
 | 
			
		||||
    def test_api(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_api(self) -> None:
 | 
			
		||||
        admin = self.example_user('othello')
 | 
			
		||||
        do_change_is_admin(admin, True)
 | 
			
		||||
        self.login(self.example_email("othello"))
 | 
			
		||||
@@ -305,8 +291,7 @@ class ActivateTest(ZulipTestCase):
 | 
			
		||||
        user = self.example_user('hamlet')
 | 
			
		||||
        self.assertTrue(user.is_active)
 | 
			
		||||
 | 
			
		||||
    def test_api_me_user(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_api_me_user(self) -> None:
 | 
			
		||||
        """This test helps ensure that our URL patterns for /users/me URLs
 | 
			
		||||
        handle email addresses starting with "me" correctly."""
 | 
			
		||||
        self.register(self.nonreg_email('me'), "testpassword")
 | 
			
		||||
@@ -322,8 +307,7 @@ class ActivateTest(ZulipTestCase):
 | 
			
		||||
        user = self.nonreg_user('me')
 | 
			
		||||
        self.assertTrue(user.is_active)
 | 
			
		||||
 | 
			
		||||
    def test_api_with_nonexistent_user(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_api_with_nonexistent_user(self) -> None:
 | 
			
		||||
        admin = self.example_user('othello')
 | 
			
		||||
        do_change_is_admin(admin, True)
 | 
			
		||||
        self.login(self.example_email("othello"))
 | 
			
		||||
@@ -346,8 +330,7 @@ class ActivateTest(ZulipTestCase):
 | 
			
		||||
        result = self.client_post('/json/users/nonexistent@zulip.com/reactivate')
 | 
			
		||||
        self.assert_json_error(result, 'No such user')
 | 
			
		||||
 | 
			
		||||
    def test_api_with_insufficient_permissions(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_api_with_insufficient_permissions(self) -> None:
 | 
			
		||||
        non_admin = self.example_user('othello')
 | 
			
		||||
        do_change_is_admin(non_admin, False)
 | 
			
		||||
        self.login(self.example_email("othello"))
 | 
			
		||||
@@ -360,8 +343,7 @@ class ActivateTest(ZulipTestCase):
 | 
			
		||||
        result = self.client_post('/json/users/hamlet@zulip.com/reactivate')
 | 
			
		||||
        self.assert_json_error(result, 'Insufficient permission')
 | 
			
		||||
 | 
			
		||||
    def test_clear_scheduled_jobs(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_clear_scheduled_jobs(self) -> None:
 | 
			
		||||
        user = self.example_user('hamlet')
 | 
			
		||||
        send_future_email('zerver/emails/followup_day1', to_user_id=user.id, delay=datetime.timedelta(hours=1))
 | 
			
		||||
        self.assertEqual(ScheduledEmail.objects.count(), 1)
 | 
			
		||||
@@ -369,8 +351,7 @@ class ActivateTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(ScheduledEmail.objects.count(), 0)
 | 
			
		||||
 | 
			
		||||
class RecipientInfoTest(ZulipTestCase):
 | 
			
		||||
    def test_stream_recipient_info(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_stream_recipient_info(self) -> None:
 | 
			
		||||
        hamlet = self.example_user('hamlet')
 | 
			
		||||
        cordelia = self.example_user('cordelia')
 | 
			
		||||
        othello = self.example_user('othello')
 | 
			
		||||
@@ -470,14 +451,12 @@ class RecipientInfoTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(info['default_bot_user_ids'], {normal_bot.id})
 | 
			
		||||
 | 
			
		||||
class BulkUsersTest(ZulipTestCase):
 | 
			
		||||
    def test_client_gravatar_option(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_client_gravatar_option(self) -> None:
 | 
			
		||||
        self.login(self.example_email('cordelia'))
 | 
			
		||||
 | 
			
		||||
        hamlet = self.example_user('hamlet')
 | 
			
		||||
 | 
			
		||||
        def get_hamlet_avatar(client_gravatar):
 | 
			
		||||
            # type: (bool) -> Optional[Text]
 | 
			
		||||
        def get_hamlet_avatar(client_gravatar: bool) -> Optional[Text]:
 | 
			
		||||
            data = dict(client_gravatar=ujson.dumps(client_gravatar))
 | 
			
		||||
            result = self.client_get('/json/users', data)
 | 
			
		||||
            self.assert_json_success(result)
 | 
			
		||||
@@ -507,14 +486,12 @@ class BulkUsersTest(ZulipTestCase):
 | 
			
		||||
 | 
			
		||||
class GetProfileTest(ZulipTestCase):
 | 
			
		||||
 | 
			
		||||
    def common_update_pointer(self, email, pointer):
 | 
			
		||||
        # type: (Text, int) -> None
 | 
			
		||||
    def common_update_pointer(self, email: Text, pointer: int) -> None:
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        result = self.client_post("/json/users/me/pointer", {"pointer": pointer})
 | 
			
		||||
        self.assert_json_success(result)
 | 
			
		||||
 | 
			
		||||
    def common_get_profile(self, user_id):
 | 
			
		||||
        # type: (str) -> Dict[Text, Any]
 | 
			
		||||
    def common_get_profile(self, user_id: str) -> Dict[Text, Any]:
 | 
			
		||||
        # Assumes all users are example users in realm 'zulip'
 | 
			
		||||
        user_profile = self.example_user(user_id)
 | 
			
		||||
        self.send_stream_message(user_profile.email, "Verona", "hello")
 | 
			
		||||
@@ -533,16 +510,14 @@ class GetProfileTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(json["max_message_id"], max_id)
 | 
			
		||||
        return json
 | 
			
		||||
 | 
			
		||||
    def test_get_pointer(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_get_pointer(self) -> None:
 | 
			
		||||
        email = self.example_email("hamlet")
 | 
			
		||||
        self.login(email)
 | 
			
		||||
        result = self.client_get("/json/users/me/pointer")
 | 
			
		||||
        self.assert_json_success(result)
 | 
			
		||||
        self.assertIn("pointer", result.json())
 | 
			
		||||
 | 
			
		||||
    def test_cache_behavior(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_cache_behavior(self) -> None:
 | 
			
		||||
        """Tests whether fetching a user object the normal way, with
 | 
			
		||||
        `get_user`, makes 1 cache query and 1 database query.
 | 
			
		||||
        """
 | 
			
		||||
@@ -556,8 +531,7 @@ class GetProfileTest(ZulipTestCase):
 | 
			
		||||
        self.assert_length(cache_queries, 1)
 | 
			
		||||
        self.assertEqual(user_profile.email, email)
 | 
			
		||||
 | 
			
		||||
    def test_get_user_profile(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_get_user_profile(self) -> None:
 | 
			
		||||
        self.login(self.example_email("hamlet"))
 | 
			
		||||
        result = ujson.loads(self.client_get('/json/users/me').content)
 | 
			
		||||
        self.assertEqual(result['short_name'], 'hamlet')
 | 
			
		||||
@@ -574,16 +548,14 @@ class GetProfileTest(ZulipTestCase):
 | 
			
		||||
        self.assertFalse(result['is_bot'])
 | 
			
		||||
        self.assertTrue(result['is_admin'])
 | 
			
		||||
 | 
			
		||||
    def test_api_get_empty_profile(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_api_get_empty_profile(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Ensure GET /users/me returns a max message id and returns successfully
 | 
			
		||||
        """
 | 
			
		||||
        json = self.common_get_profile("othello")
 | 
			
		||||
        self.assertEqual(json["pointer"], -1)
 | 
			
		||||
 | 
			
		||||
    def test_profile_with_pointer(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_profile_with_pointer(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Ensure GET /users/me returns a proper pointer id after the pointer is updated
 | 
			
		||||
        """
 | 
			
		||||
@@ -604,8 +576,7 @@ class GetProfileTest(ZulipTestCase):
 | 
			
		||||
        result = self.client_post("/json/users/me/pointer", {"pointer": 99999999})
 | 
			
		||||
        self.assert_json_error(result, "Invalid message ID")
 | 
			
		||||
 | 
			
		||||
    def test_get_all_profiles_avatar_urls(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
    def test_get_all_profiles_avatar_urls(self) -> None:
 | 
			
		||||
        user_profile = self.example_user('hamlet')
 | 
			
		||||
        result = self.client_get("/api/v1/users", **self.api_auth(self.example_email("hamlet")))
 | 
			
		||||
        self.assert_json_success(result)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user