2013-03-20 22:08:48 +01:00
|
|
|
# -*- coding: utf-8 -*-
|
2013-04-23 18:51:17 +02:00
|
|
|
from __future__ import absolute_import
|
2015-11-01 17:11:06 +01:00
|
|
|
from __future__ import print_function
|
2013-03-20 22:08:48 +01:00
|
|
|
|
2017-03-08 12:18:27 +01:00
|
|
|
from typing import (Any, Dict, Iterable, List,
|
|
|
|
Optional, TypeVar, Text, Union)
|
2016-06-22 10:36:22 +02:00
|
|
|
from mock import patch, MagicMock
|
2016-06-15 23:47:22 +02:00
|
|
|
|
2016-09-14 02:08:08 +02:00
|
|
|
from django.http import HttpResponse
|
2016-08-24 07:53:05 +02:00
|
|
|
from django.test import TestCase, override_settings
|
2012-08-28 18:44:51 +02:00
|
|
|
|
2014-01-27 22:53:36 +01:00
|
|
|
from zerver.lib.test_helpers import (
|
2016-07-15 10:14:51 +02:00
|
|
|
queries_captured, simulated_empty_cache,
|
2017-03-08 12:18:27 +01:00
|
|
|
tornado_redirected_to_list,
|
2016-12-19 08:48:03 +01:00
|
|
|
most_recent_message, make_client, avatar_disk_path,
|
|
|
|
get_test_image_file
|
2014-01-27 22:53:36 +01:00
|
|
|
)
|
2016-11-10 19:30:09 +01:00
|
|
|
from zerver.lib.test_classes import (
|
|
|
|
ZulipTestCase,
|
|
|
|
)
|
2016-07-16 03:56:45 +02:00
|
|
|
from zerver.lib.test_runner import slow
|
2016-10-10 12:51:59 +02:00
|
|
|
from zerver.forms import WRONG_SUBDOMAIN_ERROR
|
2014-01-27 22:53:36 +01:00
|
|
|
|
2014-01-31 23:13:58 +01:00
|
|
|
from zerver.models import UserProfile, Recipient, \
|
2016-09-19 23:13:13 +02:00
|
|
|
Realm, RealmAlias, UserActivity, \
|
2016-12-26 19:19:02 +01:00
|
|
|
get_user_profile_by_email, get_realm, get_client, get_stream, \
|
2017-03-06 08:45:59 +01:00
|
|
|
Message, get_unique_open_realm, completely_open, get_context_for_message
|
2014-02-07 22:47:30 +01:00
|
|
|
|
2017-02-16 22:35:57 +01:00
|
|
|
from zerver.lib.avatar import avatar_url
|
2016-06-22 10:36:22 +02:00
|
|
|
from zerver.lib.email_mirror import create_missed_message_address
|
2014-01-31 16:44:45 +01:00
|
|
|
from zerver.lib.actions import \
|
2014-01-29 22:07:09 +01:00
|
|
|
get_emails_from_user_ids, do_deactivate_user, do_reactivate_user, \
|
2014-02-14 19:29:42 +01:00
|
|
|
do_change_is_admin, extract_recipients, \
|
2017-03-08 12:07:51 +01:00
|
|
|
do_set_realm_name, do_deactivate_realm
|
2017-03-06 08:45:59 +01:00
|
|
|
from zerver.lib.notifications import handle_missedmessage_emails, \
|
|
|
|
send_missedmessage_email
|
2013-12-26 15:01:46 +01:00
|
|
|
from zerver.middleware import is_slow_query
|
2017-01-06 18:56:36 +01:00
|
|
|
from zerver.lib.utils import split_by
|
2012-08-28 18:44:51 +02:00
|
|
|
|
2012-09-27 19:58:42 +02:00
|
|
|
from django.conf import settings
|
2014-07-15 21:03:51 +02:00
|
|
|
from django.core import mail
|
2017-03-08 11:57:55 +01:00
|
|
|
from six.moves import range
|
2013-06-19 20:08:48 +02:00
|
|
|
import os
|
2014-07-15 21:03:51 +02:00
|
|
|
import re
|
2013-01-10 19:41:49 +01:00
|
|
|
import sys
|
2013-06-20 18:47:19 +02:00
|
|
|
import time
|
2013-06-18 23:55:55 +02:00
|
|
|
import ujson
|
2016-07-13 19:05:41 +02:00
|
|
|
import random
|
2017-01-06 18:56:36 +01:00
|
|
|
import subprocess
|
2013-03-14 22:12:25 +01:00
|
|
|
|
2016-06-15 23:47:22 +02:00
|
|
|
K = TypeVar('K')
|
|
|
|
V = TypeVar('V')
|
2014-01-14 20:38:45 +01:00
|
|
|
def find_dict(lst, k, v):
|
2016-06-15 23:47:22 +02:00
|
|
|
# type: (Iterable[Dict[K, V]], K, V) -> Dict[K, V]
|
2014-01-14 20:38:45 +01:00
|
|
|
for dct in lst:
|
|
|
|
if dct[k] == v:
|
|
|
|
return dct
|
2017-03-05 08:17:36 +01:00
|
|
|
raise AssertionError('Cannot find element in list where key %s == %s' % (k, v))
|
2014-01-14 20:38:45 +01:00
|
|
|
|
2013-12-26 15:01:46 +01:00
|
|
|
class SlowQueryTest(TestCase):
|
|
|
|
def test_is_slow_query(self):
|
2016-06-15 23:47:22 +02:00
|
|
|
# type: () -> None
|
2013-12-26 15:16:49 +01:00
|
|
|
self.assertFalse(is_slow_query(1.1, '/some/random/url'))
|
2013-12-26 15:01:46 +01:00
|
|
|
self.assertTrue(is_slow_query(2, '/some/random/url'))
|
2013-12-26 15:23:18 +01:00
|
|
|
self.assertTrue(is_slow_query(5.1, '/activity'))
|
2013-12-26 15:01:46 +01:00
|
|
|
self.assertFalse(is_slow_query(2, '/activity'))
|
|
|
|
self.assertFalse(is_slow_query(2, '/json/report_error'))
|
|
|
|
self.assertFalse(is_slow_query(2, '/api/v1/deployments/report_error'))
|
|
|
|
self.assertFalse(is_slow_query(2, '/realm_activity/whatever'))
|
|
|
|
self.assertFalse(is_slow_query(2, '/user_activity/whatever'))
|
2013-12-26 15:20:59 +01:00
|
|
|
self.assertFalse(is_slow_query(9, '/accounts/webathena_kerberos_login/'))
|
|
|
|
self.assertTrue(is_slow_query(11, '/accounts/webathena_kerberos_login/'))
|
2013-12-26 15:01:46 +01:00
|
|
|
|
2016-09-20 03:00:27 +02:00
|
|
|
class ModelTest(TestCase):
|
|
|
|
def test_miscellaneous_things(self):
|
|
|
|
# type: () -> None
|
|
|
|
'''
|
|
|
|
This is a kitchen sink test that is designed simply to get
|
|
|
|
test coverage up to 100% for models.py.
|
|
|
|
'''
|
|
|
|
client = make_client('some_client')
|
|
|
|
self.assertEqual(str(client), u'<Client: some_client>')
|
|
|
|
|
2016-08-23 02:08:42 +02:00
|
|
|
class PermissionTest(ZulipTestCase):
|
2013-11-02 15:36:17 +01:00
|
|
|
def test_get_admin_users(self):
|
2016-06-15 23:47:22 +02:00
|
|
|
# type: () -> None
|
2013-11-02 15:36:17 +01:00
|
|
|
user_profile = get_user_profile_by_email('hamlet@zulip.com')
|
2014-01-22 20:12:29 +01:00
|
|
|
do_change_is_admin(user_profile, False)
|
2013-11-02 15:36:17 +01:00
|
|
|
admin_users = user_profile.realm.get_admin_users()
|
|
|
|
self.assertFalse(user_profile in admin_users)
|
2014-01-22 20:12:29 +01:00
|
|
|
do_change_is_admin(user_profile, True)
|
2013-11-02 15:36:17 +01:00
|
|
|
admin_users = user_profile.realm.get_admin_users()
|
|
|
|
self.assertTrue(user_profile in admin_users)
|
2013-09-30 22:52:04 +02:00
|
|
|
|
2016-07-13 05:05:55 +02:00
|
|
|
def test_updating_non_existent_user(self):
|
|
|
|
# type: () -> None
|
|
|
|
self.login('hamlet@zulip.com')
|
|
|
|
admin = get_user_profile_by_email('hamlet@zulip.com')
|
|
|
|
do_change_is_admin(admin, True)
|
|
|
|
|
|
|
|
result = self.client_patch('/json/users/nonexistentuser@zulip.com', {})
|
|
|
|
self.assert_json_error(result, 'No such user')
|
|
|
|
|
2014-01-14 16:19:26 +01:00
|
|
|
def test_admin_api(self):
|
2016-06-15 23:47:22 +02:00
|
|
|
# type: () -> None
|
2014-01-14 16:19:26 +01:00
|
|
|
self.login('hamlet@zulip.com')
|
|
|
|
admin = get_user_profile_by_email('hamlet@zulip.com')
|
|
|
|
user = get_user_profile_by_email('othello@zulip.com')
|
|
|
|
realm = admin.realm
|
2014-01-22 20:12:29 +01:00
|
|
|
do_change_is_admin(admin, True)
|
2014-01-14 20:38:45 +01:00
|
|
|
|
|
|
|
# Make sure we see is_admin flag in /json/users
|
2016-07-28 00:38:45 +02:00
|
|
|
result = self.client_get('/json/users')
|
2014-01-14 20:38:45 +01:00
|
|
|
self.assert_json_success(result)
|
|
|
|
members = ujson.loads(result.content)['members']
|
|
|
|
hamlet = find_dict(members, 'email', 'hamlet@zulip.com')
|
|
|
|
self.assertTrue(hamlet['is_admin'])
|
|
|
|
othello = find_dict(members, 'email', 'othello@zulip.com')
|
|
|
|
self.assertFalse(othello['is_admin'])
|
2014-01-14 16:19:26 +01:00
|
|
|
|
|
|
|
# Giveth
|
|
|
|
req = dict(is_admin=ujson.dumps(True))
|
2014-01-21 19:27:22 +01:00
|
|
|
|
2016-06-15 23:47:22 +02:00
|
|
|
events = [] # type: List[Dict[str, Any]]
|
2014-01-21 19:27:22 +01:00
|
|
|
with tornado_redirected_to_list(events):
|
|
|
|
result = self.client_patch('/json/users/othello@zulip.com', req)
|
2014-01-14 16:19:26 +01:00
|
|
|
self.assert_json_success(result)
|
|
|
|
admin_users = realm.get_admin_users()
|
|
|
|
self.assertTrue(user in admin_users)
|
2014-01-21 19:27:22 +01:00
|
|
|
person = events[0]['event']['person']
|
|
|
|
self.assertEqual(person['email'], 'othello@zulip.com')
|
|
|
|
self.assertEqual(person['is_admin'], True)
|
2014-01-14 16:19:26 +01:00
|
|
|
|
|
|
|
# Taketh away
|
|
|
|
req = dict(is_admin=ujson.dumps(False))
|
2014-01-21 19:27:22 +01:00
|
|
|
events = []
|
|
|
|
with tornado_redirected_to_list(events):
|
|
|
|
result = self.client_patch('/json/users/othello@zulip.com', req)
|
2014-01-14 16:19:26 +01:00
|
|
|
self.assert_json_success(result)
|
|
|
|
admin_users = realm.get_admin_users()
|
|
|
|
self.assertFalse(user in admin_users)
|
2014-01-21 19:27:22 +01:00
|
|
|
person = events[0]['event']['person']
|
|
|
|
self.assertEqual(person['email'], 'othello@zulip.com')
|
|
|
|
self.assertEqual(person['is_admin'], False)
|
2014-01-14 16:19:26 +01:00
|
|
|
|
2016-12-05 06:40:00 +01:00
|
|
|
# Cannot take away from last admin
|
|
|
|
self.login('iago@zulip.com')
|
|
|
|
req = dict(is_admin=ujson.dumps(False))
|
|
|
|
events = []
|
|
|
|
with tornado_redirected_to_list(events):
|
|
|
|
result = self.client_patch('/json/users/hamlet@zulip.com', req)
|
|
|
|
self.assert_json_success(result)
|
|
|
|
admin_users = realm.get_admin_users()
|
|
|
|
self.assertFalse(admin in admin_users)
|
|
|
|
person = events[0]['event']['person']
|
|
|
|
self.assertEqual(person['email'], 'hamlet@zulip.com')
|
|
|
|
self.assertEqual(person['is_admin'], False)
|
|
|
|
with tornado_redirected_to_list([]):
|
|
|
|
result = self.client_patch('/json/users/iago@zulip.com', req)
|
|
|
|
self.assert_json_error(result, 'Cannot remove the only organization administrator')
|
|
|
|
|
2014-01-14 16:19:26 +01:00
|
|
|
# Make sure only admins can patch other user's info.
|
|
|
|
self.login('othello@zulip.com')
|
|
|
|
result = self.client_patch('/json/users/hamlet@zulip.com', req)
|
|
|
|
self.assert_json_error(result, 'Insufficient permission')
|
|
|
|
|
2016-09-27 14:25:52 +02:00
|
|
|
def test_admin_user_can_change_full_name(self):
|
|
|
|
# type: () -> None
|
|
|
|
new_name = 'new name'
|
|
|
|
self.login('iago@zulip.com')
|
|
|
|
req = dict(full_name=ujson.dumps(new_name))
|
|
|
|
result = self.client_patch('/json/users/hamlet@zulip.com', req)
|
|
|
|
self.assertTrue(result.status_code == 200)
|
|
|
|
hamlet = get_user_profile_by_email('hamlet@zulip.com')
|
|
|
|
self.assertEqual(hamlet.full_name, new_name)
|
|
|
|
|
|
|
|
def test_non_admin_cannot_change_full_name(self):
|
|
|
|
# type: () -> None
|
|
|
|
self.login('hamlet@zulip.com')
|
|
|
|
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
|
|
|
|
new_name = 'a' * (UserProfile.MAX_NAME_LENGTH + 1)
|
|
|
|
self.login('iago@zulip.com')
|
|
|
|
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!')
|
|
|
|
|
2017-01-16 04:18:42 +01:00
|
|
|
def test_admin_cannot_set_full_name_with_invalid_characters(self):
|
|
|
|
# type: () -> None
|
|
|
|
new_name = 'Opheli*'
|
|
|
|
self.login('iago@zulip.com')
|
|
|
|
req = dict(full_name=ujson.dumps(new_name))
|
|
|
|
result = self.client_patch('/json/users/hamlet@zulip.com', req)
|
|
|
|
self.assert_json_error(result, 'Invalid characters in name!')
|
|
|
|
|
2016-08-23 02:08:42 +02:00
|
|
|
class AdminCreateUserTest(ZulipTestCase):
|
2016-07-12 20:46:55 +02:00
|
|
|
def test_create_user_backend(self):
|
|
|
|
# type: () -> None
|
|
|
|
|
|
|
|
# This test should give us complete coverage on
|
|
|
|
# create_user_backend. It mostly exercises error
|
|
|
|
# conditions, and it also does a basic test of the success
|
|
|
|
# path.
|
|
|
|
|
|
|
|
admin_email = 'hamlet@zulip.com'
|
|
|
|
self.login(admin_email)
|
|
|
|
admin = get_user_profile_by_email(admin_email)
|
|
|
|
do_change_is_admin(admin, True)
|
|
|
|
|
2016-12-31 08:07:22 +01:00
|
|
|
result = self.client_post("/json/users", dict())
|
2016-07-12 20:46:55 +02:00
|
|
|
self.assert_json_error(result, "Missing 'email' argument")
|
|
|
|
|
2016-12-31 08:07:22 +01:00
|
|
|
result = self.client_post("/json/users", dict(
|
2016-07-12 20:46:55 +02:00
|
|
|
email='romeo@not-zulip.com',
|
2017-01-24 06:34:26 +01:00
|
|
|
))
|
2016-07-12 20:46:55 +02:00
|
|
|
self.assert_json_error(result, "Missing 'password' argument")
|
|
|
|
|
2016-12-31 08:07:22 +01:00
|
|
|
result = self.client_post("/json/users", dict(
|
2016-07-12 20:46:55 +02:00
|
|
|
email='romeo@not-zulip.com',
|
|
|
|
password='xxxx',
|
2017-01-24 06:34:26 +01:00
|
|
|
))
|
2016-07-12 20:46:55 +02:00
|
|
|
self.assert_json_error(result, "Missing 'full_name' argument")
|
|
|
|
|
2016-12-31 08:07:22 +01:00
|
|
|
result = self.client_post("/json/users", dict(
|
2016-07-12 20:46:55 +02:00
|
|
|
email='romeo@not-zulip.com',
|
|
|
|
password='xxxx',
|
|
|
|
full_name='Romeo Montague',
|
2017-01-24 06:34:26 +01:00
|
|
|
))
|
2016-07-12 20:46:55 +02:00
|
|
|
self.assert_json_error(result, "Missing 'short_name' argument")
|
|
|
|
|
2016-12-31 08:07:22 +01:00
|
|
|
result = self.client_post("/json/users", dict(
|
2016-07-12 20:46:55 +02:00
|
|
|
email='broken',
|
|
|
|
password='xxxx',
|
|
|
|
full_name='Romeo Montague',
|
|
|
|
short_name='Romeo',
|
2017-01-24 06:34:26 +01:00
|
|
|
))
|
2016-07-12 20:46:55 +02:00
|
|
|
self.assert_json_error(result, "Bad name or username")
|
|
|
|
|
2016-12-31 08:07:22 +01:00
|
|
|
result = self.client_post("/json/users", dict(
|
2016-07-12 20:46:55 +02:00
|
|
|
email='romeo@not-zulip.com',
|
|
|
|
password='xxxx',
|
|
|
|
full_name='Romeo Montague',
|
|
|
|
short_name='Romeo',
|
2017-01-24 06:34:26 +01:00
|
|
|
))
|
2016-07-12 20:46:55 +02:00
|
|
|
self.assert_json_error(result,
|
2016-12-03 00:04:17 +01:00
|
|
|
"Email 'romeo@not-zulip.com' does not belong to domain 'zulip.com'")
|
2016-07-12 20:46:55 +02:00
|
|
|
|
2017-01-04 05:30:48 +01:00
|
|
|
RealmAlias.objects.create(realm=get_realm('zulip'), domain='zulip.net')
|
2016-09-19 23:13:13 +02:00
|
|
|
|
2016-07-12 20:46:55 +02:00
|
|
|
# HAPPY PATH STARTS HERE
|
|
|
|
valid_params = dict(
|
2016-09-19 23:13:13 +02:00
|
|
|
email='romeo@zulip.net',
|
2016-07-12 20:46:55 +02:00
|
|
|
password='xxxx',
|
|
|
|
full_name='Romeo Montague',
|
|
|
|
short_name='Romeo',
|
|
|
|
)
|
2016-12-31 08:07:22 +01:00
|
|
|
result = self.client_post("/json/users", valid_params)
|
2016-07-12 20:46:55 +02:00
|
|
|
self.assert_json_success(result)
|
|
|
|
|
2016-09-19 23:13:13 +02:00
|
|
|
new_user = get_user_profile_by_email('romeo@zulip.net')
|
2016-07-12 20:46:55 +02:00
|
|
|
self.assertEqual(new_user.full_name, 'Romeo Montague')
|
|
|
|
self.assertEqual(new_user.short_name, 'Romeo')
|
|
|
|
|
|
|
|
# One more error condition to test--we can't create
|
|
|
|
# the same user twice.
|
2016-12-31 08:07:22 +01:00
|
|
|
result = self.client_post("/json/users", valid_params)
|
2016-07-12 20:46:55 +02:00
|
|
|
self.assert_json_error(result,
|
2016-12-03 00:04:17 +01:00
|
|
|
"Email 'romeo@zulip.net' already in use")
|
2016-07-12 20:46:55 +02:00
|
|
|
|
2016-08-23 02:08:42 +02:00
|
|
|
class DocPageTest(ZulipTestCase):
|
2016-08-18 18:09:47 +02:00
|
|
|
def _test(self, url, expected_content):
|
|
|
|
# type: (str, str) -> None
|
|
|
|
result = self.client_get(url)
|
|
|
|
self.assertEqual(result.status_code, 200)
|
|
|
|
self.assertIn(expected_content, str(result.content))
|
|
|
|
|
|
|
|
def test_doc_endpoints(self):
|
|
|
|
# type: () -> None
|
|
|
|
self._test('/api/', 'We hear you like APIs')
|
2017-02-28 23:44:58 +01:00
|
|
|
self._test('/api/endpoints/', 'pre-built API bindings for')
|
2016-10-16 20:19:27 +02:00
|
|
|
self._test('/about/', 'Cambridge, Massachusetts')
|
2016-10-16 20:26:01 +02:00
|
|
|
# Test the i18n version of one of these pages.
|
|
|
|
self._test('/en/about/', 'Cambridge, Massachusetts')
|
2016-08-18 18:09:47 +02:00
|
|
|
self._test('/apps/', 'Appsolutely')
|
|
|
|
self._test('/features/', 'Talk about multiple topics at once')
|
|
|
|
self._test('/hello/', 'workplace chat that actually improves your productivity')
|
|
|
|
self._test('/integrations/', 'require creating a Zulip bot')
|
|
|
|
self._test('/login/', '(Normal users)')
|
|
|
|
self._test('/register/', 'get started')
|
|
|
|
|
|
|
|
result = self.client_get('/new-user/')
|
|
|
|
self.assertEqual(result.status_code, 301)
|
|
|
|
self.assertIn('hello', result['Location'])
|
|
|
|
|
|
|
|
result = self.client_get('/robots.txt')
|
|
|
|
self.assertEqual(result.status_code, 301)
|
|
|
|
self.assertIn('static/robots.txt', result['Location'])
|
|
|
|
|
|
|
|
result = self.client_get('/static/robots.txt')
|
|
|
|
self.assertEqual(result.status_code, 200)
|
|
|
|
self.assertIn(
|
|
|
|
'Disallow: /',
|
|
|
|
''.join(str(x) for x in list(result.streaming_content))
|
|
|
|
)
|
|
|
|
|
2013-10-20 21:10:03 +02:00
|
|
|
class UserProfileTest(TestCase):
|
|
|
|
def test_get_emails_from_user_ids(self):
|
2016-06-15 23:47:22 +02:00
|
|
|
# type: () -> None
|
2013-10-20 21:10:03 +02:00
|
|
|
hamlet = get_user_profile_by_email('hamlet@zulip.com')
|
|
|
|
othello = get_user_profile_by_email('othello@zulip.com')
|
|
|
|
dct = get_emails_from_user_ids([hamlet.id, othello.id])
|
|
|
|
self.assertEqual(dct[hamlet.id], 'hamlet@zulip.com')
|
|
|
|
self.assertEqual(dct[othello.id], 'othello@zulip.com')
|
|
|
|
|
2016-08-23 02:08:42 +02:00
|
|
|
class ActivateTest(ZulipTestCase):
|
2013-11-15 18:57:44 +01:00
|
|
|
def test_basics(self):
|
2016-06-15 23:47:22 +02:00
|
|
|
# type: () -> None
|
2013-11-15 18:57:44 +01:00
|
|
|
user = get_user_profile_by_email('hamlet@zulip.com')
|
2013-11-16 17:11:15 +01:00
|
|
|
do_deactivate_user(user)
|
2013-11-15 18:57:44 +01:00
|
|
|
self.assertFalse(user.is_active)
|
2013-11-16 17:11:15 +01:00
|
|
|
do_reactivate_user(user)
|
2013-11-15 18:57:44 +01:00
|
|
|
self.assertTrue(user.is_active)
|
|
|
|
|
2013-11-15 19:39:03 +01:00
|
|
|
def test_api(self):
|
2016-06-15 23:47:22 +02:00
|
|
|
# type: () -> None
|
2013-11-15 19:39:03 +01:00
|
|
|
admin = get_user_profile_by_email('othello@zulip.com')
|
2014-01-22 20:12:29 +01:00
|
|
|
do_change_is_admin(admin, True)
|
2013-11-15 19:39:03 +01:00
|
|
|
self.login('othello@zulip.com')
|
|
|
|
|
|
|
|
user = get_user_profile_by_email('hamlet@zulip.com')
|
|
|
|
self.assertTrue(user.is_active)
|
|
|
|
|
2013-12-11 20:02:32 +01:00
|
|
|
result = self.client_delete('/json/users/hamlet@zulip.com')
|
2013-11-15 19:39:03 +01:00
|
|
|
self.assert_json_success(result)
|
|
|
|
user = get_user_profile_by_email('hamlet@zulip.com')
|
|
|
|
self.assertFalse(user.is_active)
|
|
|
|
|
2016-07-28 00:30:22 +02:00
|
|
|
result = self.client_post('/json/users/hamlet@zulip.com/reactivate')
|
2013-11-15 19:39:03 +01:00
|
|
|
self.assert_json_success(result)
|
|
|
|
user = get_user_profile_by_email('hamlet@zulip.com')
|
|
|
|
self.assertTrue(user.is_active)
|
|
|
|
|
2017-02-19 00:18:19 +01:00
|
|
|
def test_api_me_user(self):
|
|
|
|
# type: () -> None
|
|
|
|
"""This test helps ensure that our URL patterns for /users/me URLs
|
|
|
|
handle email addresses starting with "me" correctly."""
|
|
|
|
self.register("me@zulip.com", "testpassword")
|
|
|
|
self.login('iago@zulip.com')
|
|
|
|
|
|
|
|
result = self.client_delete('/json/users/me@zulip.com')
|
|
|
|
self.assert_json_success(result)
|
|
|
|
user = get_user_profile_by_email('me@zulip.com')
|
|
|
|
self.assertFalse(user.is_active)
|
|
|
|
|
|
|
|
result = self.client_post('/json/users/me@zulip.com/reactivate')
|
|
|
|
self.assert_json_success(result)
|
|
|
|
user = get_user_profile_by_email('me@zulip.com')
|
|
|
|
self.assertTrue(user.is_active)
|
|
|
|
|
2016-07-13 05:24:11 +02:00
|
|
|
def test_api_with_nonexistent_user(self):
|
|
|
|
# type: () -> None
|
|
|
|
admin = get_user_profile_by_email('othello@zulip.com')
|
|
|
|
do_change_is_admin(admin, True)
|
|
|
|
self.login('othello@zulip.com')
|
|
|
|
|
|
|
|
# Can not deactivate a user with the bot api
|
2014-02-11 17:14:33 +01:00
|
|
|
result = self.client_delete('/json/bots/hamlet@zulip.com')
|
|
|
|
self.assert_json_error(result, 'No such bot')
|
|
|
|
|
2016-07-13 05:24:11 +02:00
|
|
|
# Can not deactivate a nonexistent user.
|
|
|
|
result = self.client_delete('/json/users/nonexistent@zulip.com')
|
|
|
|
self.assert_json_error(result, 'No such user')
|
|
|
|
|
2016-12-05 06:40:00 +01:00
|
|
|
result = self.client_delete('/json/users/iago@zulip.com')
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
result = self.client_delete('/json/users/othello@zulip.com')
|
|
|
|
self.assert_json_error(result, 'Cannot deactivate the only organization administrator')
|
|
|
|
|
2016-07-13 05:24:11 +02:00
|
|
|
# Can not reactivate a nonexistent user.
|
2016-07-28 00:30:22 +02:00
|
|
|
result = self.client_post('/json/users/nonexistent@zulip.com/reactivate')
|
2016-07-13 05:24:11 +02:00
|
|
|
self.assert_json_error(result, 'No such user')
|
|
|
|
|
2016-07-13 05:42:29 +02:00
|
|
|
def test_api_with_insufficient_permissions(self):
|
|
|
|
# type: () -> None
|
|
|
|
non_admin = get_user_profile_by_email('othello@zulip.com')
|
|
|
|
do_change_is_admin(non_admin, False)
|
|
|
|
self.login('othello@zulip.com')
|
|
|
|
|
|
|
|
# Can not deactivate a user with the users api
|
|
|
|
result = self.client_delete('/json/users/hamlet@zulip.com')
|
|
|
|
self.assert_json_error(result, 'Insufficient permission')
|
|
|
|
|
|
|
|
# Can not reactivate a user
|
2016-07-28 00:30:22 +02:00
|
|
|
result = self.client_post('/json/users/hamlet@zulip.com/reactivate')
|
2016-07-13 05:42:29 +02:00
|
|
|
self.assert_json_error(result, 'Insufficient permission')
|
|
|
|
|
2016-08-23 02:08:42 +02:00
|
|
|
class GetProfileTest(ZulipTestCase):
|
2013-01-22 20:07:51 +01:00
|
|
|
|
|
|
|
def common_update_pointer(self, email, pointer):
|
2016-12-04 18:38:56 +01:00
|
|
|
# type: (Text, int) -> None
|
2013-01-22 20:07:51 +01:00
|
|
|
self.login(email)
|
2016-12-31 08:54:00 +01:00
|
|
|
result = self.client_post("/json/users/me/pointer", {"pointer": pointer})
|
2013-01-22 20:07:51 +01:00
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
def common_get_profile(self, email):
|
2016-12-04 18:38:56 +01:00
|
|
|
# type: (str) -> Dict[Text, Any]
|
2013-07-02 21:50:05 +02:00
|
|
|
user_profile = get_user_profile_by_email(email)
|
2013-07-02 18:13:26 +02:00
|
|
|
self.send_message(email, "Verona", Recipient.STREAM, "hello")
|
2013-01-22 20:07:51 +01:00
|
|
|
|
2016-07-28 00:38:45 +02:00
|
|
|
result = self.client_get("/api/v1/users/me", **self.api_auth(email))
|
2013-01-22 20:07:51 +01:00
|
|
|
|
2013-07-02 16:15:10 +02:00
|
|
|
max_id = most_recent_message(user_profile).id
|
2013-01-22 20:07:51 +01:00
|
|
|
|
|
|
|
self.assert_json_success(result)
|
2013-06-18 23:55:55 +02:00
|
|
|
json = ujson.loads(result.content)
|
2013-01-22 20:07:51 +01:00
|
|
|
|
|
|
|
self.assertIn("client_id", json)
|
|
|
|
self.assertIn("max_message_id", json)
|
|
|
|
self.assertIn("pointer", json)
|
|
|
|
|
2013-01-17 18:12:02 +01:00
|
|
|
self.assertEqual(json["max_message_id"], max_id)
|
2013-01-22 20:07:51 +01:00
|
|
|
return json
|
|
|
|
|
2016-09-14 02:14:45 +02:00
|
|
|
def test_get_pointer(self):
|
|
|
|
# type: () -> None
|
|
|
|
email = "hamlet@zulip.com"
|
|
|
|
self.login(email)
|
|
|
|
result = self.client_get("/json/users/me/pointer")
|
|
|
|
self.assert_json_success(result)
|
|
|
|
json = ujson.loads(result.content)
|
|
|
|
self.assertIn("pointer", json)
|
|
|
|
|
2013-09-28 01:05:08 +02:00
|
|
|
def test_cache_behavior(self):
|
2016-06-15 23:47:22 +02:00
|
|
|
# type: () -> None
|
2013-09-28 01:05:08 +02:00
|
|
|
with queries_captured() as queries:
|
|
|
|
with simulated_empty_cache() as cache_queries:
|
|
|
|
user_profile = get_user_profile_by_email('hamlet@zulip.com')
|
|
|
|
|
2016-09-25 21:30:10 +02:00
|
|
|
self.assert_max_length(queries, 1)
|
|
|
|
self.assert_length(cache_queries, 1)
|
2013-09-28 01:05:08 +02:00
|
|
|
self.assertEqual(user_profile.email, 'hamlet@zulip.com')
|
|
|
|
|
2016-12-13 19:17:49 +01:00
|
|
|
def test_get_user_profile(self):
|
|
|
|
# type: () -> None
|
|
|
|
self.login('hamlet@zulip.com')
|
|
|
|
result = ujson.loads(self.client_get('/json/users/me').content)
|
|
|
|
self.assertEqual(result['short_name'], 'hamlet')
|
|
|
|
self.assertEqual(result['email'], 'hamlet@zulip.com')
|
|
|
|
self.assertEqual(result['full_name'], 'King Hamlet')
|
|
|
|
self.assertIn("user_id", result)
|
|
|
|
self.assertFalse(result['is_bot'])
|
|
|
|
self.assertFalse(result['is_admin'])
|
|
|
|
self.login('iago@zulip.com')
|
|
|
|
result = ujson.loads(self.client_get('/json/users/me').content)
|
|
|
|
self.assertEqual(result['short_name'], 'iago')
|
|
|
|
self.assertEqual(result['email'], 'iago@zulip.com')
|
|
|
|
self.assertEqual(result['full_name'], 'Iago')
|
|
|
|
self.assertFalse(result['is_bot'])
|
|
|
|
self.assertTrue(result['is_admin'])
|
|
|
|
|
2013-01-22 20:07:51 +01:00
|
|
|
def test_api_get_empty_profile(self):
|
2016-06-15 23:47:22 +02:00
|
|
|
# type: () -> None
|
2013-01-22 20:07:51 +01:00
|
|
|
"""
|
2016-04-02 20:07:28 +02:00
|
|
|
Ensure GET /users/me returns a max message id and returns successfully
|
2013-01-22 20:07:51 +01:00
|
|
|
"""
|
2013-07-24 20:41:09 +02:00
|
|
|
json = self.common_get_profile("othello@zulip.com")
|
2013-01-17 18:12:02 +01:00
|
|
|
self.assertEqual(json["pointer"], -1)
|
2013-01-22 20:07:51 +01:00
|
|
|
|
|
|
|
def test_profile_with_pointer(self):
|
2016-06-15 23:47:22 +02:00
|
|
|
# type: () -> None
|
2013-01-22 20:07:51 +01:00
|
|
|
"""
|
2016-04-02 20:07:28 +02:00
|
|
|
Ensure GET /users/me returns a proper pointer id after the pointer is updated
|
2013-01-22 20:07:51 +01:00
|
|
|
"""
|
2013-08-19 21:05:23 +02:00
|
|
|
|
2013-08-28 21:29:55 +02:00
|
|
|
id1 = self.send_message("othello@zulip.com", "Verona", Recipient.STREAM)
|
|
|
|
id2 = self.send_message("othello@zulip.com", "Verona", Recipient.STREAM)
|
2013-08-19 21:05:23 +02:00
|
|
|
|
2013-07-24 20:41:09 +02:00
|
|
|
json = self.common_get_profile("hamlet@zulip.com")
|
2013-01-22 20:07:51 +01:00
|
|
|
|
2013-08-19 21:05:23 +02:00
|
|
|
self.common_update_pointer("hamlet@zulip.com", id2)
|
2013-07-24 20:41:09 +02:00
|
|
|
json = self.common_get_profile("hamlet@zulip.com")
|
2013-08-19 21:05:23 +02:00
|
|
|
self.assertEqual(json["pointer"], id2)
|
2013-01-22 20:07:51 +01:00
|
|
|
|
2013-08-19 21:05:23 +02:00
|
|
|
self.common_update_pointer("hamlet@zulip.com", id1)
|
2013-07-24 20:41:09 +02:00
|
|
|
json = self.common_get_profile("hamlet@zulip.com")
|
2013-08-19 21:05:23 +02:00
|
|
|
self.assertEqual(json["pointer"], id2) # pointer does not move backwards
|
|
|
|
|
2016-12-31 08:54:00 +01:00
|
|
|
result = self.client_post("/json/users/me/pointer", {"pointer": 99999999})
|
2013-08-19 21:05:23 +02:00
|
|
|
self.assert_json_error(result, "Invalid message ID")
|
2012-12-19 20:19:46 +01:00
|
|
|
|
2014-07-18 06:16:14 +02:00
|
|
|
def test_get_all_profiles_avatar_urls(self):
|
2016-06-15 23:47:22 +02:00
|
|
|
# type: () -> None
|
2014-07-18 06:16:14 +02:00
|
|
|
user_profile = get_user_profile_by_email('hamlet@zulip.com')
|
2016-07-28 00:38:45 +02:00
|
|
|
result = self.client_get("/api/v1/users", **self.api_auth('hamlet@zulip.com'))
|
2014-07-18 06:16:14 +02:00
|
|
|
self.assert_json_success(result)
|
|
|
|
json = ujson.loads(result.content)
|
|
|
|
|
|
|
|
for user in json['members']:
|
|
|
|
if user['email'] == 'hamlet@zulip.com':
|
|
|
|
self.assertEqual(
|
|
|
|
user['avatar_url'],
|
2017-02-16 22:35:57 +01:00
|
|
|
avatar_url(user_profile),
|
2014-07-18 06:16:14 +02:00
|
|
|
)
|
|
|
|
|
2017-01-06 18:56:36 +01:00
|
|
|
class AuthorsPageTest(ZulipTestCase):
|
|
|
|
def setUp(self):
|
|
|
|
# type: () -> None
|
2017-01-14 11:19:26 +01:00
|
|
|
""" Manual installation which did not execute `tools/provision`
|
2017-01-06 18:56:36 +01:00
|
|
|
would not have the `static/generated/github-contributors.json` fixture
|
|
|
|
file.
|
|
|
|
"""
|
2017-03-05 08:17:36 +01:00
|
|
|
# This block has unreliable test coverage due to the implicit
|
|
|
|
# caching here, so we exclude it from coverage.
|
2017-01-06 18:56:36 +01:00
|
|
|
if not os.path.exists(settings.CONTRIBUTORS_DATA):
|
|
|
|
# Copy the fixture file in `zerver/fixtures` to `static/generated`
|
|
|
|
update_script = os.path.join(os.path.dirname(__file__),
|
2017-03-05 08:17:36 +01:00
|
|
|
'../../tools/update-authors-json') # nocoverage
|
|
|
|
subprocess.check_call([update_script, '--use-fixture']) # nocoverage
|
2017-01-06 18:56:36 +01:00
|
|
|
|
|
|
|
def test_endpoint(self):
|
|
|
|
# type: () -> None
|
|
|
|
result = self.client_get('/authors/')
|
|
|
|
self.assert_in_success_response(
|
|
|
|
['Contributors', 'Statistic last Updated:', 'commits',
|
|
|
|
'@timabbott'],
|
|
|
|
result
|
|
|
|
)
|
|
|
|
|
2016-08-23 02:08:42 +02:00
|
|
|
class MutedTopicsTests(ZulipTestCase):
|
2013-09-10 00:06:24 +02:00
|
|
|
def test_json_set(self):
|
2016-06-15 23:47:22 +02:00
|
|
|
# type: () -> None
|
2013-09-10 00:06:24 +02:00
|
|
|
email = 'hamlet@zulip.com'
|
|
|
|
self.login(email)
|
|
|
|
|
|
|
|
url = '/json/set_muted_topics'
|
|
|
|
data = {'muted_topics': '[["stream", "topic"]]'}
|
2016-07-28 00:30:22 +02:00
|
|
|
result = self.client_post(url, data)
|
2013-09-10 00:06:24 +02:00
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
user = get_user_profile_by_email(email)
|
|
|
|
self.assertEqual(ujson.loads(user.muted_topics), [["stream", "topic"]])
|
|
|
|
|
|
|
|
url = '/json/set_muted_topics'
|
|
|
|
data = {'muted_topics': '[["stream2", "topic2"]]'}
|
2016-07-28 00:30:22 +02:00
|
|
|
result = self.client_post(url, data)
|
2013-09-10 00:06:24 +02:00
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
user = get_user_profile_by_email(email)
|
|
|
|
self.assertEqual(ujson.loads(user.muted_topics), [["stream2", "topic2"]])
|
|
|
|
|
2014-02-14 19:29:42 +01:00
|
|
|
class ExtractedRecipientsTest(TestCase):
|
|
|
|
def test_extract_recipients(self):
|
2016-06-15 23:47:22 +02:00
|
|
|
# type: () -> None
|
|
|
|
|
2014-02-14 19:39:11 +01:00
|
|
|
# JSON list w/dups, empties, and trailing whitespace
|
2014-02-14 19:29:42 +01:00
|
|
|
s = ujson.dumps([' alice@zulip.com ', ' bob@zulip.com ', ' ', 'bob@zulip.com'])
|
2016-07-10 00:24:19 +02:00
|
|
|
self.assertEqual(sorted(extract_recipients(s)), ['alice@zulip.com', 'bob@zulip.com'])
|
2014-02-14 19:39:11 +01:00
|
|
|
|
|
|
|
# simple string with one name
|
2014-02-14 19:29:42 +01:00
|
|
|
s = 'alice@zulip.com '
|
2016-07-10 00:24:19 +02:00
|
|
|
self.assertEqual(extract_recipients(s), ['alice@zulip.com'])
|
2014-02-14 19:29:42 +01:00
|
|
|
|
2014-02-14 19:39:11 +01:00
|
|
|
# JSON-encoded string
|
|
|
|
s = '"alice@zulip.com"'
|
2016-07-10 00:24:19 +02:00
|
|
|
self.assertEqual(extract_recipients(s), ['alice@zulip.com'])
|
2014-02-14 19:39:11 +01:00
|
|
|
|
2014-02-14 19:56:55 +01:00
|
|
|
# bare comma-delimited string
|
|
|
|
s = 'bob@zulip.com, alice@zulip.com'
|
2016-07-10 00:24:19 +02:00
|
|
|
self.assertEqual(sorted(extract_recipients(s)), ['alice@zulip.com', 'bob@zulip.com'])
|
2014-02-14 19:56:55 +01:00
|
|
|
|
2014-02-14 19:39:11 +01:00
|
|
|
# JSON-encoded, comma-delimited string
|
|
|
|
s = '"bob@zulip.com,alice@zulip.com"'
|
2016-07-10 00:24:19 +02:00
|
|
|
self.assertEqual(sorted(extract_recipients(s)), ['alice@zulip.com', 'bob@zulip.com'])
|
2014-02-14 19:39:11 +01:00
|
|
|
|
2014-02-14 19:29:42 +01:00
|
|
|
|
2016-08-23 02:08:42 +02:00
|
|
|
class TestMissedMessages(ZulipTestCase):
|
2016-06-22 10:36:22 +02:00
|
|
|
def normalize_string(self, s):
|
2016-12-04 18:38:56 +01:00
|
|
|
# type: (Text) -> Text
|
2016-06-22 10:36:22 +02:00
|
|
|
s = s.strip()
|
|
|
|
return re.sub(r'\s+', ' ', s)
|
|
|
|
|
2016-10-18 11:14:12 +02:00
|
|
|
def _get_tokens(self):
|
|
|
|
# type: () -> List[str]
|
|
|
|
return [str(random.getrandbits(32)) for _ in range(30)]
|
2014-07-15 21:03:51 +02:00
|
|
|
|
2016-10-18 11:14:12 +02:00
|
|
|
def _test_cases(self, tokens, msg_id, body, send_as_user):
|
|
|
|
# type: (List[str], int, str, bool) -> None
|
2016-06-22 10:36:22 +02:00
|
|
|
othello = get_user_profile_by_email('othello@zulip.com')
|
2014-07-15 21:03:51 +02:00
|
|
|
hamlet = get_user_profile_by_email('hamlet@zulip.com')
|
|
|
|
handle_missedmessage_emails(hamlet.id, [{'message_id': msg_id}])
|
2016-10-18 11:14:12 +02:00
|
|
|
reply_to_addresses = [settings.EMAIL_GATEWAY_PATTERN % (u'mm' + t) for t in tokens]
|
2017-03-06 08:45:59 +01:00
|
|
|
msg = mail.outbox[0]
|
2016-06-22 10:36:22 +02:00
|
|
|
sender = 'Zulip <{}>'.format(settings.NOREPLY_EMAIL_ADDRESS)
|
2016-10-18 11:14:12 +02:00
|
|
|
from_email = sender
|
2016-12-16 02:01:34 +01:00
|
|
|
self.assertEqual(len(mail.outbox), 1)
|
2016-10-18 11:14:12 +02:00
|
|
|
if send_as_user:
|
|
|
|
from_email = '"%s" <%s>' % (othello.full_name, othello.email)
|
|
|
|
self.assertEqual(msg.extra_headers['Sender'], sender)
|
|
|
|
else:
|
|
|
|
self.assertNotIn("Sender", msg.extra_headers)
|
|
|
|
self.assertEqual(msg.from_email, from_email)
|
2016-06-22 10:36:22 +02:00
|
|
|
self.assertIn(msg.extra_headers['Reply-To'], reply_to_addresses)
|
2016-10-18 11:14:12 +02:00
|
|
|
self.assertIn(body, self.normalize_string(msg.body))
|
|
|
|
|
|
|
|
@patch('zerver.lib.email_mirror.generate_random_token')
|
|
|
|
def _extra_context_in_missed_stream_messages(self, send_as_user, mock_random_token):
|
|
|
|
# type: (bool, MagicMock) -> None
|
|
|
|
tokens = self._get_tokens()
|
|
|
|
mock_random_token.side_effect = tokens
|
|
|
|
|
|
|
|
for i in range(0, 11):
|
|
|
|
self.send_message("othello@zulip.com", "Denmark", Recipient.STREAM, str(i))
|
|
|
|
self.send_message("othello@zulip.com", "Denmark", Recipient.STREAM, '11', subject='test2')
|
|
|
|
msg_id = self.send_message("othello@zulip.com", "denmark", Recipient.STREAM, '@**hamlet**')
|
|
|
|
body = 'Denmark > test Othello, the Moor of Venice 1 2 3 4 5 6 7 8 9 10 @**hamlet**'
|
|
|
|
self._test_cases(tokens, msg_id, body, send_as_user)
|
2015-10-15 16:13:52 +02:00
|
|
|
|
2016-06-22 10:36:22 +02:00
|
|
|
@patch('zerver.lib.email_mirror.generate_random_token')
|
2016-10-18 11:14:12 +02:00
|
|
|
def _extra_context_in_personal_missed_stream_messages(self, send_as_user, mock_random_token):
|
|
|
|
# type: (bool, MagicMock) -> None
|
|
|
|
tokens = self._get_tokens()
|
2016-06-22 10:36:22 +02:00
|
|
|
mock_random_token.side_effect = tokens
|
|
|
|
|
|
|
|
msg_id = self.send_message("othello@zulip.com", "hamlet@zulip.com",
|
|
|
|
Recipient.PERSONAL,
|
|
|
|
'Extremely personal message!')
|
2016-10-18 11:14:12 +02:00
|
|
|
body = 'You and Othello, the Moor of Venice Extremely personal message!'
|
|
|
|
self._test_cases(tokens, msg_id, body, send_as_user)
|
2016-06-22 10:36:22 +02:00
|
|
|
|
|
|
|
@patch('zerver.lib.email_mirror.generate_random_token')
|
2016-10-18 11:14:12 +02:00
|
|
|
def _extra_context_in_huddle_missed_stream_messages(self, send_as_user, mock_random_token):
|
|
|
|
# type: (bool, MagicMock) -> None
|
|
|
|
tokens = self._get_tokens()
|
2016-06-22 10:36:22 +02:00
|
|
|
mock_random_token.side_effect = tokens
|
|
|
|
|
|
|
|
msg_id = self.send_message("othello@zulip.com",
|
|
|
|
["hamlet@zulip.com", "iago@zulip.com"],
|
|
|
|
Recipient.PERSONAL,
|
|
|
|
'Group personal message!')
|
|
|
|
|
|
|
|
body = ('You and Iago, Othello, the Moor of Venice Othello,'
|
|
|
|
' the Moor of Venice Group personal message')
|
2016-10-18 11:14:12 +02:00
|
|
|
self._test_cases(tokens, msg_id, body, send_as_user)
|
|
|
|
|
|
|
|
@override_settings(SEND_MISSED_MESSAGE_EMAILS_AS_USER=True)
|
|
|
|
def test_extra_context_in_missed_stream_messages_as_user(self):
|
|
|
|
# type: () -> None
|
|
|
|
self._extra_context_in_missed_stream_messages(True)
|
|
|
|
|
|
|
|
def test_extra_context_in_missed_stream_messages(self):
|
|
|
|
# type: () -> None
|
|
|
|
self._extra_context_in_missed_stream_messages(False)
|
|
|
|
|
|
|
|
@override_settings(SEND_MISSED_MESSAGE_EMAILS_AS_USER=True)
|
|
|
|
def test_extra_context_in_personal_missed_stream_messages_as_user(self):
|
|
|
|
# type: () -> None
|
|
|
|
self._extra_context_in_personal_missed_stream_messages(True)
|
|
|
|
|
|
|
|
def test_extra_context_in_personal_missed_stream_messages(self):
|
|
|
|
# type: () -> None
|
|
|
|
self._extra_context_in_personal_missed_stream_messages(False)
|
|
|
|
|
|
|
|
@override_settings(SEND_MISSED_MESSAGE_EMAILS_AS_USER=True)
|
|
|
|
def test_extra_context_in_huddle_missed_stream_messages_as_user(self):
|
|
|
|
# type: () -> None
|
|
|
|
self._extra_context_in_huddle_missed_stream_messages(True)
|
|
|
|
|
|
|
|
def test_extra_context_in_huddle_missed_stream_messages(self):
|
|
|
|
# type: () -> None
|
|
|
|
self._extra_context_in_huddle_missed_stream_messages(False)
|
2016-06-22 10:36:22 +02:00
|
|
|
|
|
|
|
|
2016-08-23 02:08:42 +02:00
|
|
|
class TestOpenRealms(ZulipTestCase):
|
2015-10-15 16:13:52 +02:00
|
|
|
def test_open_realm_logic(self):
|
2016-06-15 23:47:22 +02:00
|
|
|
# type: () -> None
|
2017-01-27 00:06:55 +01:00
|
|
|
realm = get_realm('simple')
|
|
|
|
do_deactivate_realm(realm)
|
|
|
|
|
2017-03-04 09:19:37 +01:00
|
|
|
mit_realm = get_realm("zephyr")
|
2016-12-16 02:01:34 +01:00
|
|
|
self.assertEqual(get_unique_open_realm(), None)
|
2015-10-15 16:13:52 +02:00
|
|
|
mit_realm.restricted_to_domain = False
|
|
|
|
mit_realm.save()
|
2016-12-24 02:10:26 +01:00
|
|
|
self.assertTrue(completely_open(mit_realm))
|
2016-12-16 02:01:34 +01:00
|
|
|
self.assertEqual(get_unique_open_realm(), None)
|
2017-01-04 09:20:23 +01:00
|
|
|
with self.settings(SYSTEM_ONLY_REALMS={"zulip"}):
|
2016-12-16 02:01:34 +01:00
|
|
|
self.assertEqual(get_unique_open_realm(), mit_realm)
|
2015-10-15 16:13:52 +02:00
|
|
|
mit_realm.restricted_to_domain = True
|
|
|
|
mit_realm.save()
|
2016-10-10 12:51:59 +02:00
|
|
|
|
|
|
|
class TestLoginPage(ZulipTestCase):
|
2017-01-13 07:52:15 +01:00
|
|
|
def test_login_page_wrong_subdomain_error(self):
|
2016-10-10 12:51:59 +02:00
|
|
|
# type: () -> None
|
|
|
|
result = self.client_get("/login/?subdomain=1")
|
|
|
|
self.assertIn(WRONG_SUBDOMAIN_ERROR, result.content.decode('utf8'))
|
2016-12-20 10:41:46 +01:00
|
|
|
|
2017-01-10 10:44:56 +01:00
|
|
|
@patch('django.http.HttpRequest.get_host')
|
|
|
|
def test_login_page_redirects_for_root_alias(self, mock_get_host):
|
|
|
|
# type: (MagicMock) -> None
|
|
|
|
mock_get_host.return_value = 'www.testserver'
|
|
|
|
with self.settings(REALMS_HAVE_SUBDOMAINS=True,
|
|
|
|
ROOT_SUBDOMAIN_ALIASES=['www']):
|
|
|
|
result = self.client_get("/en/login/")
|
|
|
|
self.assertEqual(result.status_code, 302)
|
|
|
|
self.assertEqual(result.url, '/find_my_team/')
|
|
|
|
|
|
|
|
@patch('django.http.HttpRequest.get_host')
|
|
|
|
def test_login_page_redirects_for_root_domain(self, mock_get_host):
|
|
|
|
# type: (MagicMock) -> None
|
|
|
|
mock_get_host.return_value = 'testserver'
|
|
|
|
with self.settings(REALMS_HAVE_SUBDOMAINS=True,
|
|
|
|
ROOT_SUBDOMAIN_ALIASES=['www']):
|
|
|
|
result = self.client_get("/en/login/")
|
|
|
|
self.assertEqual(result.status_code, 302)
|
|
|
|
self.assertEqual(result.url, '/find_my_team/')
|
|
|
|
|
|
|
|
mock_get_host.return_value = 'www.testserver.com'
|
|
|
|
with self.settings(REALMS_HAVE_SUBDOMAINS=True,
|
|
|
|
EXTERNAL_HOST='www.testserver.com',
|
|
|
|
ROOT_SUBDOMAIN_ALIASES=['test']):
|
|
|
|
result = self.client_get("/en/login/")
|
|
|
|
self.assertEqual(result.status_code, 302)
|
|
|
|
self.assertEqual(result.url, '/find_my_team/')
|
|
|
|
|
|
|
|
@patch('django.http.HttpRequest.get_host')
|
|
|
|
def test_login_page_works_without_subdomains(self, mock_get_host):
|
|
|
|
# type: (MagicMock) -> None
|
|
|
|
mock_get_host.return_value = 'www.testserver'
|
|
|
|
with self.settings(ROOT_SUBDOMAIN_ALIASES=['www']):
|
|
|
|
result = self.client_get("/en/login/")
|
|
|
|
self.assertEqual(result.status_code, 200)
|
|
|
|
|
|
|
|
mock_get_host.return_value = 'testserver'
|
|
|
|
with self.settings(ROOT_SUBDOMAIN_ALIASES=['www']):
|
|
|
|
result = self.client_get("/en/login/")
|
|
|
|
self.assertEqual(result.status_code, 200)
|
|
|
|
|
2017-01-06 04:48:12 +01:00
|
|
|
class TestFindMyTeam(ZulipTestCase):
|
2016-12-20 10:41:46 +01:00
|
|
|
def test_template(self):
|
|
|
|
# type: () -> None
|
2017-01-06 03:31:48 +01:00
|
|
|
result = self.client_get('/find_my_team/')
|
2016-12-20 10:41:46 +01:00
|
|
|
self.assertIn("Find your team", result.content.decode('utf8'))
|
|
|
|
|
|
|
|
def test_result(self):
|
|
|
|
# type: () -> None
|
2017-01-06 03:31:48 +01:00
|
|
|
url = '/find_my_team/?emails=iago@zulip.com,cordelia@zulip.com'
|
2016-12-20 10:41:46 +01:00
|
|
|
result = self.client_get(url)
|
|
|
|
content = result.content.decode('utf8')
|
2017-01-05 03:42:53 +01:00
|
|
|
self.assertIn("Emails sent! You will only receive emails", content)
|
2016-12-20 10:41:46 +01:00
|
|
|
self.assertIn("iago@zulip.com", content)
|
|
|
|
self.assertIn("cordelia@zulip.com", content)
|
|
|
|
|
|
|
|
def test_find_team_zero_emails(self):
|
|
|
|
# type: () -> None
|
|
|
|
data = {'emails': ''}
|
2017-01-06 03:31:48 +01:00
|
|
|
result = self.client_post('/find_my_team/', data)
|
2016-12-20 10:41:46 +01:00
|
|
|
self.assertIn('This field is required', result.content.decode('utf8'))
|
|
|
|
self.assertEqual(result.status_code, 200)
|
|
|
|
|
|
|
|
def test_find_team_one_email(self):
|
|
|
|
# type: () -> None
|
|
|
|
data = {'emails': 'hamlet@zulip.com'}
|
2017-01-06 03:31:48 +01:00
|
|
|
result = self.client_post('/find_my_team/', data)
|
2016-12-20 10:41:46 +01:00
|
|
|
self.assertEqual(result.status_code, 302)
|
2017-01-06 03:31:48 +01:00
|
|
|
self.assertEqual(result.url, '/find_my_team/?emails=hamlet%40zulip.com')
|
2016-12-20 10:41:46 +01:00
|
|
|
|
|
|
|
def test_find_team_multiple_emails(self):
|
|
|
|
# type: () -> None
|
|
|
|
data = {'emails': 'hamlet@zulip.com,iago@zulip.com'}
|
2017-01-06 03:31:48 +01:00
|
|
|
result = self.client_post('/find_my_team/', data)
|
2016-12-20 10:41:46 +01:00
|
|
|
self.assertEqual(result.status_code, 302)
|
2017-01-06 03:31:48 +01:00
|
|
|
expected = '/find_my_team/?emails=hamlet%40zulip.com%2Ciago%40zulip.com'
|
2016-12-20 10:41:46 +01:00
|
|
|
self.assertEqual(result.url, expected)
|
|
|
|
|
|
|
|
def test_find_team_more_than_ten_emails(self):
|
|
|
|
# type: () -> None
|
|
|
|
data = {'emails': ','.join(['hamlet-{}@zulip.com'.format(i) for i in range(11)])}
|
2017-01-06 03:31:48 +01:00
|
|
|
result = self.client_post('/find_my_team/', data)
|
2016-12-20 10:41:46 +01:00
|
|
|
self.assertEqual(result.status_code, 200)
|
|
|
|
self.assertIn("Please enter at most 10", result.content.decode('utf8'))
|
2017-01-06 18:56:36 +01:00
|
|
|
|
|
|
|
class UtilsUnitTest(TestCase):
|
|
|
|
def test_split_by(self):
|
|
|
|
# type: () -> None
|
|
|
|
flat_list = [1, 2, 3, 4, 5, 6, 7]
|
|
|
|
expected_result = [[1, 2], [3, 4], [5, 6], [7, None]]
|
|
|
|
self.assertEqual(split_by(flat_list, 2, None), expected_result)
|