settings: Migrate main settings-change code to API.

This was one of the few major remaining endpoints that were still on
the old-style legacy API.
This commit is contained in:
Tim Abbott
2017-07-31 11:44:52 -07:00
parent 9bf02fb913
commit 1e5aee054b
11 changed files with 41 additions and 35 deletions

View File

@@ -5,7 +5,7 @@ var OUTGOING_WEBHOOK_BOT_TYPE = '3';
common.start_and_log_in(); common.start_and_log_in();
var form_sel = 'form[action^="/json/settings/change"]'; var form_sel = 'form[action^="/json/settings"]';
var regex_zuliprc = /^data:application\/octet-stream;charset=utf-8,\[api\]\nemail=.+\nkey=.+\nsite=.+\n$/; var regex_zuliprc = /^data:application\/octet-stream;charset=utf-8,\[api\]\nemail=.+\nkey=.+\nsite=.+\n$/;
var regex_flaskbotrc = /^data:application\/octet-stream;charset=utf-8,\[.\]\nemail=.+\nkey=.+\nsite=.+\n$/; var regex_flaskbotrc = /^data:application\/octet-stream;charset=utf-8,\[.\]\nemail=.+\nkey=.+\nsite=.+\n$/;

View File

@@ -155,7 +155,7 @@ exports.set_up = function () {
data.email = $('.email_change_container').find("input[name='email']").val(); data.email = $('.email_change_container').find("input[name='email']").val();
channel.patch({ channel.patch({
url: '/json/settings/change', url: '/json/settings',
data: data, data: data,
success: function (data) { success: function (data) {
if ('account_email' in data) { if ('account_email' in data) {

View File

@@ -37,7 +37,7 @@
</div> </div>
</form> </form>
<form action="/json/settings/change" method="post" <form action="/json/settings" method="patch"
class="form-horizontal your-account-settings"> class="form-horizontal your-account-settings">
<div class="m-10 inline-block grid user-name-parent"> <div class="m-10 inline-block grid user-name-parent">

View File

@@ -1023,6 +1023,7 @@ class TestHumanUsersOnlyDecorator(ZulipTestCase):
self.assert_json_error(result, "This endpoint does not accept bot requests.") self.assert_json_error(result, "This endpoint does not accept bot requests.")
patch_endpoints = [ patch_endpoints = [
"/api/v1/settings",
"/api/v1/settings/display", "/api/v1/settings/display",
"/api/v1/settings/notifications", "/api/v1/settings/notifications",
"/api/v1/settings/ui", "/api/v1/settings/ui",

View File

@@ -103,9 +103,9 @@ class EmailChangeTestCase(ZulipTestCase):
data = {'email': 'hamlet-new@zulip.com'} data = {'email': 'hamlet-new@zulip.com'}
email = self.example_email("hamlet") email = self.example_email("hamlet")
self.login(email) self.login(email)
url = '/json/settings/change' url = '/json/settings'
self.assertEqual(len(mail.outbox), 0) self.assertEqual(len(mail.outbox), 0)
result = self.client_post(url, data) result = self.client_patch(url, data)
self.assertEqual(len(mail.outbox), 1) self.assertEqual(len(mail.outbox), 1)
self.assert_in_success_response(['Check your email for a confirmation link.'], result) self.assert_in_success_response(['Check your email for a confirmation link.'], result)
email_message = mail.outbox[0] email_message = mail.outbox[0]
@@ -132,8 +132,8 @@ class EmailChangeTestCase(ZulipTestCase):
email = user_profile.email email = user_profile.email
self.login(email) self.login(email)
do_set_realm_property(user_profile.realm, 'email_changes_disabled', True) do_set_realm_property(user_profile.realm, 'email_changes_disabled', True)
url = '/json/settings/change' url = '/json/settings'
result = self.client_post(url, data) result = self.client_patch(url, data)
self.assertEqual(len(mail.outbox), 0) self.assertEqual(len(mail.outbox), 0)
self.assertEqual(result.status_code, 400) self.assertEqual(result.status_code, 400)
self.assert_in_response("Email address changes are disabled in this organization.", self.assert_in_response("Email address changes are disabled in this organization.",
@@ -145,9 +145,9 @@ class EmailChangeTestCase(ZulipTestCase):
user_profile = self.example_user('hamlet') user_profile = self.example_user('hamlet')
email = user_profile.email email = user_profile.email
self.login(email) self.login(email)
url = '/json/settings/change' url = '/json/settings'
self.assertEqual(len(mail.outbox), 0) self.assertEqual(len(mail.outbox), 0)
result = self.client_post(url, data) result = self.client_patch(url, data)
self.assertEqual(len(mail.outbox), 1) self.assertEqual(len(mail.outbox), 1)
self.assert_in_success_response(['Check your email for a confirmation link.'], result) self.assert_in_success_response(['Check your email for a confirmation link.'], result)
email_message = mail.outbox[0] email_message = mail.outbox[0]
@@ -172,8 +172,8 @@ class EmailChangeTestCase(ZulipTestCase):
data = {'email': 'hamlet-new'} data = {'email': 'hamlet-new'}
email = self.example_email("hamlet") email = self.example_email("hamlet")
self.login(email) self.login(email)
url = '/json/settings/change' url = '/json/settings'
result = self.client_post(url, data) result = self.client_patch(url, data)
self.assert_in_response('Invalid address', result) self.assert_in_response('Invalid address', result)
def test_post_same_email(self): def test_post_same_email(self):
@@ -181,7 +181,7 @@ class EmailChangeTestCase(ZulipTestCase):
data = {'email': self.example_email("hamlet")} data = {'email': self.example_email("hamlet")}
email = self.example_email("hamlet") email = self.example_email("hamlet")
self.login(email) self.login(email)
url = '/json/settings/change' url = '/json/settings'
result = self.client_post(url, data) result = self.client_patch(url, data)
self.assertEqual('success', result.json()['result']) self.assertEqual('success', result.json()['result'])
self.assertEqual('', result.json()['msg']) self.assertEqual('', result.json()['msg'])

View File

@@ -122,8 +122,8 @@ class RealmTest(ZulipTestCase):
email = user_profile.email email = user_profile.email
self.login(email) self.login(email)
do_set_realm_property(user_profile.realm, 'name_changes_disabled', True) do_set_realm_property(user_profile.realm, 'name_changes_disabled', True)
url = '/json/settings/change' url = '/json/settings'
result = self.client_post(url, data) result = self.client_patch(url, data)
self.assertEqual(result.status_code, 200) self.assertEqual(result.status_code, 200)
# Since the setting fails silently, no message is returned # Since the setting fails silently, no message is returned
self.assert_in_response("", result) self.assert_in_response("", result)

View File

@@ -61,12 +61,12 @@ class ChangeSettingsTest(ZulipTestCase):
def test_successful_change_settings(self): def test_successful_change_settings(self):
# type: () -> None # type: () -> None
""" """
A call to /json/settings/change with valid parameters changes the user's A call to /json/settings with valid parameters changes the user's
settings correctly and returns correct values. settings correctly and returns correct values.
""" """
self.login(self.example_email("hamlet")) self.login(self.example_email("hamlet"))
json_result = self.client_post( json_result = self.client_patch(
"/json/settings/change", "/json/settings",
dict( dict(
full_name='Foo Bar', full_name='Foo Bar',
old_password=initial_password(self.example_email("hamlet")), old_password=initial_password(self.example_email("hamlet")),
@@ -91,8 +91,8 @@ class ChangeSettingsTest(ZulipTestCase):
full_name = user.full_name full_name = user.full_name
with self.settings(NAME_CHANGES_DISABLED=True): with self.settings(NAME_CHANGES_DISABLED=True):
json_result = self.client_post("/json/settings/change", json_result = self.client_patch("/json/settings",
dict(full_name='Foo Bar')) dict(full_name='Foo Bar'))
# We actually fail silently here, since this only happens if # We actually fail silently here, since this only happens if
# somebody is trying to game our API, and there's no reason to # somebody is trying to game our API, and there's no reason to
@@ -103,13 +103,13 @@ class ChangeSettingsTest(ZulipTestCase):
self.assertEqual(user.full_name, full_name) self.assertEqual(user.full_name, full_name)
# Now try a too-long name # Now try a too-long name
json_result = self.client_post("/json/settings/change", json_result = self.client_patch("/json/settings",
dict(full_name='x' * 1000)) dict(full_name='x' * 1000))
self.assert_json_error(json_result, 'Name too long!') self.assert_json_error(json_result, 'Name too long!')
# Now try a too-short name # Now try a too-short name
json_result = self.client_post("/json/settings/change", json_result = self.client_patch("/json/settings",
dict(full_name='x')) dict(full_name='x'))
self.assert_json_error(json_result, 'Name too short!') self.assert_json_error(json_result, 'Name too short!')
def test_illegal_characters_in_name_changes(self): def test_illegal_characters_in_name_changes(self):
@@ -118,8 +118,8 @@ class ChangeSettingsTest(ZulipTestCase):
self.login(email) self.login(email)
# Now try a name with invalid characters # Now try a name with invalid characters
json_result = self.client_post("/json/settings/change", json_result = self.client_patch("/json/settings",
dict(full_name='Opheli*')) dict(full_name='Opheli*'))
self.assert_json_error(json_result, 'Invalid characters in name!') self.assert_json_error(json_result, 'Invalid characters in name!')
# This is basically a don't-explode test. # This is basically a don't-explode test.
@@ -151,8 +151,8 @@ class ChangeSettingsTest(ZulipTestCase):
new_password and confirm_password must match new_password and confirm_password must match
""" """
self.login(self.example_email("hamlet")) self.login(self.example_email("hamlet"))
result = self.client_post( result = self.client_patch(
"/json/settings/change", "/json/settings",
dict( dict(
new_password="mismatched_password", new_password="mismatched_password",
confirm_password="not_the_same", confirm_password="not_the_same",
@@ -166,8 +166,8 @@ class ChangeSettingsTest(ZulipTestCase):
new_password and confirm_password must match new_password and confirm_password must match
""" """
self.login(self.example_email("hamlet")) self.login(self.example_email("hamlet"))
result = self.client_post( result = self.client_patch(
"/json/settings/change", "/json/settings",
dict( dict(
old_password='bad_password', old_password='bad_password',
new_password="ignored", new_password="ignored",
@@ -183,8 +183,8 @@ class ChangeSettingsTest(ZulipTestCase):
probably use a patch interface for these changes.) probably use a patch interface for these changes.)
""" """
self.login(self.example_email("hamlet")) self.login(self.example_email("hamlet"))
result = self.client_post("/json/settings/change", result = self.client_patch("/json/settings",
dict(old_password='ignored',)) dict(old_password='ignored',))
self.assert_json_error(result, "No new data supplied") self.assert_json_error(result, "No new data supplied")
def do_test_change_user_display_setting(self, setting_name): def do_test_change_user_display_setting(self, setting_name):

View File

@@ -65,7 +65,6 @@ class PublicURLTest(ZulipTestCase):
302: ["/accounts/logout/"], 302: ["/accounts/logout/"],
401: ["/json/messages", 401: ["/json/messages",
"/json/invite_users", "/json/invite_users",
"/json/settings/change",
"/json/subscriptions/exists", "/json/subscriptions/exists",
"/api/v1/users/me/subscriptions/properties", "/api/v1/users/me/subscriptions/properties",
"/json/fetch_api_key", "/json/fetch_api_key",
@@ -77,12 +76,17 @@ class PublicURLTest(ZulipTestCase):
"/api/v1/fetch_api_key", "/api/v1/fetch_api_key",
], ],
} }
patch_urls = {
401: ["/json/settings"],
}
put_urls = {401: ["/json/users/me/pointer"], put_urls = {401: ["/json/users/me/pointer"],
} }
for status_code, url_set in six.iteritems(get_urls): for status_code, url_set in six.iteritems(get_urls):
self.fetch("client_get", url_set, status_code) self.fetch("client_get", url_set, status_code)
for status_code, url_set in six.iteritems(post_urls): for status_code, url_set in six.iteritems(post_urls):
self.fetch("client_post", url_set, status_code) self.fetch("client_post", url_set, status_code)
for status_code, url_set in six.iteritems(patch_urls):
self.fetch("client_patch", url_set, status_code)
for status_code, url_set in six.iteritems(put_urls): for status_code, url_set in six.iteritems(put_urls):
self.fetch("client_put", url_set, status_code) self.fetch("client_put", url_set, status_code)

View File

@@ -82,7 +82,7 @@ def json_change_ui_settings(request, user_profile,
return json_success(result) return json_success(result)
@authenticated_json_post_view @human_users_only
@has_request_variables @has_request_variables
def json_change_settings(request, user_profile, def json_change_settings(request, user_profile,
full_name=REQ(default=""), full_name=REQ(default=""),

View File

@@ -15,7 +15,6 @@ import zerver.views.muting
legacy_urls = [ legacy_urls = [
# These are json format views used by the web client. They require a logged in browser. # These are json format views used by the web client. They require a logged in browser.
url(r'^json/invite_users$', zerver.views.invite.json_invite_users), url(r'^json/invite_users$', zerver.views.invite.json_invite_users),
url(r'^json/settings/change$', zerver.views.user_settings.json_change_settings),
# We should remove this endpoint and all code related to it. # We should remove this endpoint and all code related to it.
# It returns a 404 if the stream doesn't exist, which is confusing # It returns a 404 if the stream doesn't exist, which is confusing

View File

@@ -324,6 +324,8 @@ v1_api_and_json_patterns = [
{'POST': 'zerver.views.hotspots.mark_hotspot_as_read'}), {'POST': 'zerver.views.hotspots.mark_hotspot_as_read'}),
# settings -> zerver.views.user_settings # settings -> zerver.views.user_settings
url(r'^settings$', rest_dispatch,
{'PATCH': 'zerver.views.user_settings.json_change_settings'}),
url(r'^settings/display$', rest_dispatch, url(r'^settings/display$', rest_dispatch,
{'PATCH': 'zerver.views.user_settings.update_display_settings_backend'}), {'PATCH': 'zerver.views.user_settings.update_display_settings_backend'}),
url(r'^settings/notifications$', rest_dispatch, url(r'^settings/notifications$', rest_dispatch,