mirror of
https://github.com/zulip/zulip.git
synced 2025-11-07 15:33:30 +00:00
custom fields: Add endpoint to delete value of custom profile data.
Add delete endpoint at `users/me/profile_data` to delete value of custom profile data. Fixes #9669
This commit is contained in:
committed by
Tim Abbott
parent
f725fa591d
commit
f7f039e772
@@ -53,10 +53,13 @@ function settings_change_success(message) {
|
|||||||
ui_report.success(message, $('#account-settings-status').expectOne());
|
ui_report.success(message, $('#account-settings-status').expectOne());
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_user_custom_profile_fields(fields) {
|
function update_user_custom_profile_fields(fields, method) {
|
||||||
|
if (method === undefined) {
|
||||||
|
blueslip.error("Undefined method in update_user_custom_profile_fields");
|
||||||
|
}
|
||||||
var spinner = $("#custom-field-status").expectOne();
|
var spinner = $("#custom-field-status").expectOne();
|
||||||
loading.make_indicator(spinner, {text: 'Saving ...'});
|
loading.make_indicator(spinner, {text: 'Saving ...'});
|
||||||
settings_ui.do_settings_change(channel.patch, "/json/users/me/profile_data",
|
settings_ui.do_settings_change(method, "/json/users/me/profile_data",
|
||||||
{data: JSON.stringify(fields)}, spinner);
|
{data: JSON.stringify(fields)}, spinner);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,12 +123,17 @@ exports.add_custom_profile_fields_to_settings = function () {
|
|||||||
function update_custom_user_field() {
|
function update_custom_user_field() {
|
||||||
var fields = [];
|
var fields = [];
|
||||||
var user_id = user_pill.get_user_ids(pills);
|
var user_id = user_pill.get_user_ids(pills);
|
||||||
if (user_id.length !== 1) {
|
if (user_id.length > 1) {
|
||||||
ui_report.message(i18n.t("Only one user allowed"), $("#custom-field-status"), 'alert-error');
|
ui_report.message(i18n.t("Only one user allowed"), $("#custom-field-status"), 'alert-error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (user_id.length < 1) {
|
||||||
|
fields.push(field.id);
|
||||||
|
update_user_custom_profile_fields(fields, channel.del);
|
||||||
|
} else {
|
||||||
fields.push({id: field.id, value: user_id[0]});
|
fields.push({id: field.id, value: user_id[0]});
|
||||||
update_user_custom_profile_fields(fields);
|
update_user_custom_profile_fields(fields, channel.patch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
@@ -383,9 +391,14 @@ exports.set_up = function () {
|
|||||||
$('#settings_page').on('change', '.custom_user_field_value', function (e) {
|
$('#settings_page').on('change', '.custom_user_field_value', function (e) {
|
||||||
var fields = [];
|
var fields = [];
|
||||||
var value = $(this).val();
|
var value = $(this).val();
|
||||||
fields.push({id: parseInt($(e.target).closest('.custom_user_field').attr("data-field-id"), 10),
|
var field_id = parseInt($(e.target).closest('.custom_user_field').attr("data-field-id"), 10);
|
||||||
value: value});
|
if (value) {
|
||||||
update_user_custom_profile_fields(fields);
|
fields.push({id: field_id, value: value});
|
||||||
|
update_user_custom_profile_fields(fields, channel.patch);
|
||||||
|
} else {
|
||||||
|
fields.push(field_id);
|
||||||
|
update_user_custom_profile_fields(fields, channel.del);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#do_deactivate_self_button").on('click',function () {
|
$("#do_deactivate_self_button").on('click',function () {
|
||||||
|
|||||||
@@ -4741,6 +4741,13 @@ def try_reorder_realm_custom_profile_fields(realm: Realm, order: List[int]) -> N
|
|||||||
field.save(update_fields=['order'])
|
field.save(update_fields=['order'])
|
||||||
notify_realm_custom_profile_fields(realm, 'update')
|
notify_realm_custom_profile_fields(realm, 'update')
|
||||||
|
|
||||||
|
def notify_user_update_custom_profile_data(user_profile: UserProfile,
|
||||||
|
field: Dict[str, Union[int, str, None]]) -> None:
|
||||||
|
payload = dict(user_id=user_profile.id, custom_profile_field=dict(id=field['id'],
|
||||||
|
value=field['value']))
|
||||||
|
event = dict(type="realm_user", op="update", person=payload)
|
||||||
|
send_event(event, active_user_ids(user_profile.realm.id))
|
||||||
|
|
||||||
def do_update_user_custom_profile_data(user_profile: UserProfile,
|
def do_update_user_custom_profile_data(user_profile: UserProfile,
|
||||||
data: List[Dict[str, Union[int, str]]]) -> None:
|
data: List[Dict[str, Union[int, str]]]) -> None:
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
@@ -4749,10 +4756,7 @@ def do_update_user_custom_profile_data(user_profile: UserProfile,
|
|||||||
update_or_create(user_profile=user_profile,
|
update_or_create(user_profile=user_profile,
|
||||||
field_id=field['id'],
|
field_id=field['id'],
|
||||||
defaults={'value': field['value']})
|
defaults={'value': field['value']})
|
||||||
payload = dict(user_id=user_profile.id, custom_profile_field=dict(id=field['id'],
|
notify_user_update_custom_profile_data(user_profile, field)
|
||||||
value=field['value']))
|
|
||||||
event = dict(type="realm_user", op="update", person=payload)
|
|
||||||
send_event(event, active_user_ids(user_profile.realm.id))
|
|
||||||
|
|
||||||
def do_send_create_user_group_event(user_group: UserGroup, members: List[UserProfile]) -> None:
|
def do_send_create_user_group_event(user_group: UserGroup, members: List[UserProfile]) -> None:
|
||||||
event = dict(type="user_group",
|
event = dict(type="user_group",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from zerver.lib.actions import get_realm, try_add_realm_custom_profile_field, \
|
|||||||
try_reorder_realm_custom_profile_fields
|
try_reorder_realm_custom_profile_fields
|
||||||
from zerver.lib.test_classes import ZulipTestCase
|
from zerver.lib.test_classes import ZulipTestCase
|
||||||
from zerver.models import CustomProfileField, \
|
from zerver.models import CustomProfileField, \
|
||||||
custom_profile_fields_for_realm, get_realm
|
custom_profile_fields_for_realm, get_realm, CustomProfileFieldValue
|
||||||
import ujson
|
import ujson
|
||||||
|
|
||||||
class CustomProfileFieldTest(ZulipTestCase):
|
class CustomProfileFieldTest(ZulipTestCase):
|
||||||
@@ -325,6 +325,38 @@ class CustomProfileFieldTest(ZulipTestCase):
|
|||||||
self.assert_json_error(result,
|
self.assert_json_error(result,
|
||||||
u"Field id 1234 not found.")
|
u"Field id 1234 not found.")
|
||||||
|
|
||||||
|
def test_delete_field_value(self) -> None:
|
||||||
|
iago = self.example_user("iago")
|
||||||
|
self.login(iago.email)
|
||||||
|
realm = get_realm("zulip")
|
||||||
|
|
||||||
|
invalid_field_id = 1234
|
||||||
|
result = self.client_delete("/json/users/me/profile_data", {
|
||||||
|
'data': ujson.dumps([invalid_field_id])
|
||||||
|
})
|
||||||
|
self.assert_json_error(result,
|
||||||
|
u'Field id %d not found.' % (invalid_field_id))
|
||||||
|
|
||||||
|
field = CustomProfileField.objects.get(name="Mentor", realm=realm)
|
||||||
|
data = [{'id': field.id,
|
||||||
|
'value': self.example_user("aaron").id}] # type: List[Dict[str, Union[int, str]]]
|
||||||
|
do_update_user_custom_profile_data(iago, data)
|
||||||
|
|
||||||
|
iago_value = CustomProfileFieldValue.objects.get(user_profile=iago, field=field)
|
||||||
|
converter = field.FIELD_CONVERTERS[field.field_type]
|
||||||
|
self.assertEqual(self.example_user("aaron").id, converter(iago_value.value))
|
||||||
|
|
||||||
|
result = self.client_delete("/json/users/me/profile_data", {
|
||||||
|
'data': ujson.dumps([field.id])
|
||||||
|
})
|
||||||
|
self.assert_json_success(result)
|
||||||
|
|
||||||
|
# Don't throw an exception here
|
||||||
|
result = self.client_delete("/json/users/me/profile_data", {
|
||||||
|
'data': ujson.dumps([field.id])
|
||||||
|
})
|
||||||
|
self.assert_json_success(result)
|
||||||
|
|
||||||
def test_update_invalid_short_text(self) -> None:
|
def test_update_invalid_short_text(self) -> None:
|
||||||
field_name = "Phone number"
|
field_name = "Phone number"
|
||||||
self.assert_error_update_invalid_value(field_name, 't' * 201,
|
self.assert_error_update_invalid_value(field_name, 't' * 201,
|
||||||
|
|||||||
@@ -14,13 +14,14 @@ from zerver.lib.actions import (try_add_realm_custom_profile_field,
|
|||||||
do_remove_realm_custom_profile_field,
|
do_remove_realm_custom_profile_field,
|
||||||
try_update_realm_custom_profile_field,
|
try_update_realm_custom_profile_field,
|
||||||
do_update_user_custom_profile_data,
|
do_update_user_custom_profile_data,
|
||||||
try_reorder_realm_custom_profile_fields)
|
try_reorder_realm_custom_profile_fields,
|
||||||
|
notify_user_update_custom_profile_data)
|
||||||
from zerver.lib.response import json_success, json_error
|
from zerver.lib.response import json_success, json_error
|
||||||
from zerver.lib.types import ProfileFieldData
|
from zerver.lib.types import ProfileFieldData
|
||||||
from zerver.lib.validator import (check_dict, check_list, check_int,
|
from zerver.lib.validator import (check_dict, check_list, check_int,
|
||||||
validate_field_data, check_capped_string)
|
validate_field_data, check_capped_string)
|
||||||
|
|
||||||
from zerver.models import (custom_profile_fields_for_realm, UserProfile,
|
from zerver.models import (custom_profile_fields_for_realm, UserProfile, CustomProfileFieldValue,
|
||||||
CustomProfileField, custom_profile_fields_for_realm)
|
CustomProfileField, custom_profile_fields_for_realm)
|
||||||
|
|
||||||
def list_realm_custom_profile_fields(request: HttpRequest, user_profile: UserProfile) -> HttpResponse:
|
def list_realm_custom_profile_fields(request: HttpRequest, user_profile: UserProfile) -> HttpResponse:
|
||||||
@@ -116,6 +117,26 @@ def reorder_realm_custom_profile_fields(request: HttpRequest, user_profile: User
|
|||||||
try_reorder_realm_custom_profile_fields(user_profile.realm, order)
|
try_reorder_realm_custom_profile_fields(user_profile.realm, order)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
|
@human_users_only
|
||||||
|
@has_request_variables
|
||||||
|
def remove_user_custom_profile_data(request: HttpRequest, user_profile: UserProfile,
|
||||||
|
data: List[int]=REQ(validator=check_list(
|
||||||
|
check_int))) -> HttpResponse:
|
||||||
|
for field_id in data:
|
||||||
|
try:
|
||||||
|
field = CustomProfileField.objects.get(realm=user_profile.realm, id=field_id)
|
||||||
|
except CustomProfileField.DoesNotExist:
|
||||||
|
return json_error(_('Field id {id} not found.').format(id=field_id))
|
||||||
|
|
||||||
|
try:
|
||||||
|
field_value = CustomProfileFieldValue.objects.get(field=field, user_profile=user_profile)
|
||||||
|
except CustomProfileFieldValue.DoesNotExist:
|
||||||
|
continue
|
||||||
|
field_value.delete()
|
||||||
|
notify_user_update_custom_profile_data(user_profile, {'id': field_id, 'value': None})
|
||||||
|
|
||||||
|
return json_success()
|
||||||
|
|
||||||
@human_users_only
|
@human_users_only
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def update_user_custom_profile_data(
|
def update_user_custom_profile_data(
|
||||||
|
|||||||
@@ -292,7 +292,8 @@ v1_api_and_json_patterns = [
|
|||||||
|
|
||||||
# users/me/custom_profile_data -> zerver.views.custom_profile_data
|
# users/me/custom_profile_data -> zerver.views.custom_profile_data
|
||||||
url(r'^users/me/profile_data$', rest_dispatch,
|
url(r'^users/me/profile_data$', rest_dispatch,
|
||||||
{'PATCH': 'zerver.views.custom_profile_fields.update_user_custom_profile_data'}),
|
{'PATCH': 'zerver.views.custom_profile_fields.update_user_custom_profile_data',
|
||||||
|
'DELETE': 'zerver.views.custom_profile_fields.remove_user_custom_profile_data'}),
|
||||||
|
|
||||||
url(r'^users/me/(?P<stream_id>\d+)/topics$', rest_dispatch,
|
url(r'^users/me/(?P<stream_id>\d+)/topics$', rest_dispatch,
|
||||||
{'GET': 'zerver.views.streams.get_topics_backend'}),
|
{'GET': 'zerver.views.streams.get_topics_backend'}),
|
||||||
|
|||||||
Reference in New Issue
Block a user