2017-03-08 12:12:02 +01:00
|
|
|
from __future__ import absolute_import
|
|
|
|
from __future__ import print_function
|
|
|
|
|
|
|
|
import ujson
|
|
|
|
|
|
|
|
from django.http import HttpResponse
|
|
|
|
from mock import patch
|
|
|
|
from typing import Any, Dict
|
|
|
|
|
|
|
|
from zerver.lib.initial_password import initial_password
|
|
|
|
from zerver.lib.sessions import get_session_dict_user
|
|
|
|
from zerver.lib.test_classes import ZulipTestCase
|
2017-05-24 02:42:31 +02:00
|
|
|
from zerver.models import get_realm, get_user
|
2017-03-08 12:12:02 +01:00
|
|
|
|
|
|
|
class ChangeSettingsTest(ZulipTestCase):
|
|
|
|
|
|
|
|
def check_well_formed_change_settings_response(self, result):
|
|
|
|
# type: (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
|
2017-05-25 01:40:26 +02:00
|
|
|
self.login(self.example_email("hamlet"))
|
2017-05-07 17:21:26 +02:00
|
|
|
user_profile = self.example_user('hamlet')
|
2017-03-08 12:12:02 +01:00
|
|
|
json_result = self.client_post(pattern,
|
|
|
|
{param: ujson.dumps(True)})
|
|
|
|
self.assert_json_success(json_result)
|
|
|
|
# refetch user_profile object to correctly handle caching
|
2017-05-07 17:21:26 +02:00
|
|
|
user_profile = self.example_user('hamlet')
|
2017-03-08 12:12:02 +01:00
|
|
|
self.assertEqual(getattr(user_profile, param), True)
|
|
|
|
|
|
|
|
json_result = self.client_post(pattern,
|
|
|
|
{param: ujson.dumps(False)})
|
|
|
|
self.assert_json_success(json_result)
|
|
|
|
# refetch user_profile object to correctly handle caching
|
2017-05-07 17:21:26 +02:00
|
|
|
user_profile = self.example_user('hamlet')
|
2017-03-08 12:12:02 +01:00
|
|
|
self.assertEqual(getattr(user_profile, param), False)
|
|
|
|
|
|
|
|
# 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
|
2017-05-25 01:40:26 +02:00
|
|
|
self.login(self.example_email("hamlet"))
|
2017-05-07 17:21:26 +02:00
|
|
|
user_profile = self.example_user('hamlet')
|
2017-03-08 12:12:02 +01:00
|
|
|
json_result = self.client_patch(pattern,
|
|
|
|
{param: ujson.dumps(True)})
|
|
|
|
self.assert_json_success(json_result)
|
|
|
|
# refetch user_profile object to correctly handle caching
|
2017-05-07 17:21:26 +02:00
|
|
|
user_profile = self.example_user('hamlet')
|
2017-03-08 12:12:02 +01:00
|
|
|
self.assertEqual(getattr(user_profile, param), True)
|
|
|
|
|
|
|
|
json_result = self.client_patch(pattern,
|
|
|
|
{param: ujson.dumps(False)})
|
|
|
|
self.assert_json_success(json_result)
|
|
|
|
# refetch user_profile object to correctly handle caching
|
2017-05-07 17:21:26 +02:00
|
|
|
user_profile = self.example_user('hamlet')
|
2017-03-08 12:12:02 +01:00
|
|
|
self.assertEqual(getattr(user_profile, param), False)
|
|
|
|
|
|
|
|
def test_successful_change_settings(self):
|
|
|
|
# type: () -> None
|
|
|
|
"""
|
|
|
|
A call to /json/settings/change with valid parameters changes the user's
|
|
|
|
settings correctly and returns correct values.
|
|
|
|
"""
|
2017-05-25 01:40:26 +02:00
|
|
|
self.login(self.example_email("hamlet"))
|
2017-03-08 12:12:02 +01:00
|
|
|
json_result = self.client_post(
|
|
|
|
"/json/settings/change",
|
|
|
|
dict(
|
|
|
|
full_name='Foo Bar',
|
2017-05-25 01:40:26 +02:00
|
|
|
old_password=initial_password(self.example_email("hamlet")),
|
2017-03-08 12:12:02 +01:00
|
|
|
new_password='foobar1',
|
|
|
|
confirm_password='foobar1',
|
|
|
|
))
|
|
|
|
self.assert_json_success(json_result)
|
|
|
|
result = ujson.loads(json_result.content)
|
|
|
|
self.check_well_formed_change_settings_response(result)
|
2017-05-07 17:21:26 +02:00
|
|
|
self.assertEqual(self.example_user('hamlet').
|
2017-03-08 12:12:02 +01:00
|
|
|
full_name, "Foo Bar")
|
2017-04-18 03:23:32 +02:00
|
|
|
self.logout()
|
2017-05-25 01:40:26 +02:00
|
|
|
self.login(self.example_email("hamlet"), "foobar1")
|
2017-05-07 17:21:26 +02:00
|
|
|
user_profile = self.example_user('hamlet')
|
2017-03-08 12:12:02 +01:00
|
|
|
self.assertEqual(get_session_dict_user(self.client.session), user_profile.id)
|
|
|
|
|
|
|
|
def test_illegal_name_changes(self):
|
|
|
|
# type: () -> None
|
2017-05-07 21:25:59 +02:00
|
|
|
user = self.example_user('hamlet')
|
|
|
|
email = user.email
|
2017-03-08 12:12:02 +01:00
|
|
|
self.login(email)
|
|
|
|
full_name = user.full_name
|
|
|
|
|
|
|
|
with self.settings(NAME_CHANGES_DISABLED=True):
|
|
|
|
json_result = self.client_post("/json/settings/change",
|
|
|
|
dict(full_name='Foo Bar'))
|
|
|
|
|
|
|
|
# We actually fail silently here, since this only happens if
|
|
|
|
# somebody is trying to game our API, and there's no reason to
|
|
|
|
# give them the courtesy of an error reason.
|
|
|
|
self.assert_json_success(json_result)
|
|
|
|
|
2017-05-24 02:42:31 +02:00
|
|
|
user = self.example_user('hamlet')
|
2017-03-08 12:12:02 +01:00
|
|
|
self.assertEqual(user.full_name, full_name)
|
|
|
|
|
|
|
|
# Now try a too-long name
|
|
|
|
json_result = self.client_post("/json/settings/change",
|
|
|
|
dict(full_name='x' * 1000))
|
|
|
|
self.assert_json_error(json_result, 'Name too long!')
|
|
|
|
|
2017-05-12 04:21:49 +02:00
|
|
|
# Now try a too-short name
|
|
|
|
json_result = self.client_post("/json/settings/change",
|
|
|
|
dict(full_name='x'))
|
|
|
|
self.assert_json_error(json_result, 'Name too short!')
|
|
|
|
|
2017-03-08 12:12:02 +01:00
|
|
|
def test_illegal_characters_in_name_changes(self):
|
|
|
|
# type: () -> None
|
2017-05-25 01:40:26 +02:00
|
|
|
email = self.example_email("hamlet")
|
2017-03-08 12:12:02 +01:00
|
|
|
self.login(email)
|
|
|
|
|
|
|
|
# Now try a name with invalid characters
|
|
|
|
json_result = self.client_post("/json/settings/change",
|
|
|
|
dict(full_name='Opheli*'))
|
|
|
|
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
|
|
|
|
self.check_for_toggle_param_patch("/json/settings/notifications", "enable_desktop_notifications")
|
|
|
|
self.check_for_toggle_param_patch("/json/settings/notifications", "enable_stream_desktop_notifications")
|
|
|
|
self.check_for_toggle_param_patch("/json/settings/notifications", "enable_stream_sounds")
|
|
|
|
self.check_for_toggle_param_patch("/json/settings/notifications", "enable_sounds")
|
|
|
|
self.check_for_toggle_param_patch("/json/settings/notifications", "enable_offline_email_notifications")
|
|
|
|
self.check_for_toggle_param_patch("/json/settings/notifications", "enable_offline_push_notifications")
|
|
|
|
self.check_for_toggle_param_patch("/json/settings/notifications", "enable_online_push_notifications")
|
|
|
|
self.check_for_toggle_param_patch("/json/settings/notifications", "enable_digest_emails")
|
|
|
|
self.check_for_toggle_param_patch("/json/settings/notifications", "pm_content_in_desktop_notifications")
|
|
|
|
|
|
|
|
def test_ui_settings(self):
|
|
|
|
# type: () -> 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_left_side_userlist(self):
|
|
|
|
# type: () -> None
|
|
|
|
self.check_for_toggle_param_patch("/json/settings/display", "left_side_userlist")
|
|
|
|
|
|
|
|
def test_toggling_emoji_alt_code(self):
|
|
|
|
# type: () -> None
|
|
|
|
self.check_for_toggle_param_patch("/json/settings/display", "emoji_alt_code")
|
|
|
|
|
|
|
|
def test_time_setting(self):
|
|
|
|
# type: () -> None
|
|
|
|
self.check_for_toggle_param_patch("/json/settings/display", "twenty_four_hour_time")
|
|
|
|
|
|
|
|
def test_enter_sends_setting(self):
|
|
|
|
# type: () -> None
|
|
|
|
self.check_for_toggle_param('/json/users/me/enter-sends', "enter_sends")
|
|
|
|
|
|
|
|
def test_mismatching_passwords(self):
|
|
|
|
# type: () -> None
|
|
|
|
"""
|
|
|
|
new_password and confirm_password must match
|
|
|
|
"""
|
2017-05-25 01:40:26 +02:00
|
|
|
self.login(self.example_email("hamlet"))
|
2017-03-08 12:12:02 +01:00
|
|
|
result = self.client_post(
|
|
|
|
"/json/settings/change",
|
|
|
|
dict(
|
|
|
|
new_password="mismatched_password",
|
|
|
|
confirm_password="not_the_same",
|
|
|
|
))
|
|
|
|
self.assert_json_error(result,
|
|
|
|
"New password must match confirmation password!")
|
|
|
|
|
|
|
|
def test_wrong_old_password(self):
|
|
|
|
# type: () -> None
|
|
|
|
"""
|
|
|
|
new_password and confirm_password must match
|
|
|
|
"""
|
2017-05-25 01:40:26 +02:00
|
|
|
self.login(self.example_email("hamlet"))
|
2017-03-08 12:12:02 +01:00
|
|
|
result = self.client_post(
|
|
|
|
"/json/settings/change",
|
|
|
|
dict(
|
|
|
|
old_password='bad_password',
|
|
|
|
new_password="ignored",
|
|
|
|
confirm_password="ignored",
|
|
|
|
))
|
|
|
|
self.assert_json_error(result, "Wrong password!")
|
|
|
|
|
|
|
|
def test_changing_nothing_returns_error(self):
|
|
|
|
# type: () -> None
|
|
|
|
"""
|
|
|
|
We need to supply at least one non-empty parameter
|
|
|
|
to this API, or it should fail. (Eventually, we should
|
|
|
|
probably use a patch interface for these changes.)
|
|
|
|
"""
|
2017-05-25 01:40:26 +02:00
|
|
|
self.login(self.example_email("hamlet"))
|
2017-03-08 12:12:02 +01:00
|
|
|
result = self.client_post("/json/settings/change",
|
|
|
|
dict(old_password='ignored',))
|
|
|
|
self.assert_json_error(result, "No new data supplied")
|
|
|
|
|
|
|
|
def test_change_default_language(self):
|
|
|
|
# type: () -> None
|
|
|
|
"""
|
|
|
|
Test changing the default language of the user.
|
|
|
|
"""
|
2017-05-24 02:42:31 +02:00
|
|
|
email = self.example_email('hamlet')
|
2017-03-08 12:12:02 +01:00
|
|
|
self.login(email)
|
|
|
|
german = "de"
|
|
|
|
data = dict(default_language=ujson.dumps(german))
|
|
|
|
result = self.client_patch("/json/settings/display", data)
|
|
|
|
self.assert_json_success(result)
|
2017-05-24 02:42:31 +02:00
|
|
|
user_profile = self.example_user('hamlet')
|
2017-03-08 12:12:02 +01:00
|
|
|
self.assertEqual(user_profile.default_language, german)
|
|
|
|
|
|
|
|
# Test to make sure invalid languages are not accepted
|
|
|
|
# and saved in the db.
|
|
|
|
invalid_lang = "invalid_lang"
|
|
|
|
data = dict(default_language=ujson.dumps(invalid_lang))
|
|
|
|
result = self.client_patch("/json/settings/display", data)
|
|
|
|
self.assert_json_error(result, "Invalid language '%s'" % (invalid_lang,))
|
2017-05-24 02:42:31 +02:00
|
|
|
user_profile = self.example_user('hamlet')
|
2017-03-08 12:12:02 +01:00
|
|
|
self.assertNotEqual(user_profile.default_language, invalid_lang)
|
2017-03-08 12:20:56 +01:00
|
|
|
|
2017-03-14 10:53:09 +01:00
|
|
|
def test_change_timezone(self):
|
|
|
|
# type: () -> None
|
|
|
|
"""
|
|
|
|
Test changing the timezone of the user.
|
|
|
|
"""
|
2017-05-24 02:42:31 +02:00
|
|
|
email = self.example_email('hamlet')
|
2017-03-14 10:53:09 +01:00
|
|
|
self.login(email)
|
|
|
|
usa_pacific = 'US/Pacific'
|
|
|
|
data = dict(timezone=ujson.dumps(usa_pacific))
|
|
|
|
result = self.client_patch("/json/settings/display", data)
|
|
|
|
self.assert_json_success(result)
|
2017-05-24 02:42:31 +02:00
|
|
|
user_profile = self.example_user('hamlet')
|
2017-03-14 10:53:09 +01:00
|
|
|
self.assertEqual(user_profile.timezone, usa_pacific)
|
|
|
|
|
|
|
|
# Test to make sure invalid timezones are not accepted
|
|
|
|
# and saved in the db.
|
|
|
|
invalid_timezone = "invalid_timezone"
|
|
|
|
data = dict(timezone=ujson.dumps(invalid_timezone))
|
|
|
|
result = self.client_patch("/json/settings/display", data)
|
|
|
|
self.assert_json_error(result, "Invalid timezone '%s'" % (invalid_timezone,))
|
2017-05-24 02:42:31 +02:00
|
|
|
user_profile = self.example_user('hamlet')
|
2017-03-14 10:53:09 +01:00
|
|
|
self.assertNotEqual(user_profile.timezone, invalid_timezone)
|
|
|
|
|
2017-04-02 21:05:33 +02:00
|
|
|
def test_change_emojiset(self):
|
|
|
|
# type: () -> None
|
|
|
|
"""
|
|
|
|
Test changing the emojiset.
|
|
|
|
"""
|
2017-05-24 02:42:31 +02:00
|
|
|
email = self.example_email('hamlet')
|
2017-04-02 21:05:33 +02:00
|
|
|
self.login(email)
|
|
|
|
emojiset = 'apple'
|
|
|
|
data = dict(emojiset=ujson.dumps(emojiset))
|
|
|
|
result = self.client_patch("/json/settings/display", data)
|
|
|
|
self.assert_json_success(result)
|
2017-05-24 02:42:31 +02:00
|
|
|
user_profile = self.example_user('hamlet')
|
2017-04-02 21:05:33 +02:00
|
|
|
self.assertEqual(user_profile.emojiset, emojiset)
|
|
|
|
|
|
|
|
# Test to make sure invalid emojisets are not accepted
|
|
|
|
# and saved in the db.
|
|
|
|
invalid_emojiset = "invalid_emojiset"
|
|
|
|
data = dict(emojiset=ujson.dumps(invalid_emojiset))
|
|
|
|
result = self.client_patch("/json/settings/display", data)
|
|
|
|
self.assert_json_error(result, "Invalid emojiset '%s'" % (invalid_emojiset,))
|
2017-05-24 02:42:31 +02:00
|
|
|
user_profile = self.example_user('hamlet')
|
2017-04-02 21:05:33 +02:00
|
|
|
self.assertNotEqual(user_profile.emojiset, invalid_emojiset)
|
|
|
|
|
2017-03-08 12:20:56 +01:00
|
|
|
class UserChangesTest(ZulipTestCase):
|
|
|
|
def test_update_api_key(self):
|
|
|
|
# type: () -> None
|
2017-05-07 21:25:59 +02:00
|
|
|
user = self.example_user('hamlet')
|
|
|
|
email = user.email
|
2017-03-08 12:20:56 +01:00
|
|
|
self.login(email)
|
|
|
|
old_api_key = user.api_key
|
|
|
|
result = self.client_post('/json/users/me/api_key/regenerate')
|
|
|
|
self.assert_json_success(result)
|
|
|
|
new_api_key = ujson.loads(result.content)['api_key']
|
|
|
|
self.assertNotEqual(old_api_key, new_api_key)
|
2017-05-24 02:42:31 +02:00
|
|
|
user = self.example_user('hamlet')
|
2017-03-08 12:20:56 +01:00
|
|
|
self.assertEqual(new_api_key, user.api_key)
|