2017-03-17 10:07:22 +01:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
2018-05-11 01:39:38 +02:00
|
|
|
from typing import Union, List, Dict, Any
|
2017-03-17 10:07:22 +01:00
|
|
|
|
2019-05-04 04:47:44 +02:00
|
|
|
from zerver.lib.actions import try_add_realm_custom_profile_field, \
|
2018-04-08 18:13:37 +02:00
|
|
|
do_update_user_custom_profile_data, do_remove_realm_custom_profile_field, \
|
|
|
|
try_reorder_realm_custom_profile_fields
|
2017-03-17 10:07:22 +01:00
|
|
|
from zerver.lib.test_classes import ZulipTestCase
|
2018-11-06 10:05:31 +01:00
|
|
|
from zerver.lib.bugdown import convert as bugdown_convert
|
2017-05-23 20:57:59 +02:00
|
|
|
from zerver.models import CustomProfileField, \
|
2019-05-04 04:47:44 +02:00
|
|
|
custom_profile_fields_for_realm, CustomProfileFieldValue, get_realm
|
2017-03-17 10:07:22 +01:00
|
|
|
import ujson
|
|
|
|
|
|
|
|
class CustomProfileFieldTest(ZulipTestCase):
|
2018-04-30 19:51:16 +02:00
|
|
|
def setUp(self) -> None:
|
2018-05-06 11:35:34 +02:00
|
|
|
self.realm = get_realm("zulip")
|
|
|
|
self.original_count = len(custom_profile_fields_for_realm(self.realm.id))
|
|
|
|
|
|
|
|
def custom_field_exists_in_realm(self, field_id: int) -> bool:
|
|
|
|
fields = custom_profile_fields_for_realm(self.realm.id)
|
|
|
|
field_ids = [field.id for field in fields]
|
|
|
|
return (field_id in field_ids)
|
2018-04-30 19:51:16 +02:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_list(self) -> None:
|
2017-05-23 20:57:59 +02:00
|
|
|
self.login(self.example_email("iago"))
|
2017-03-17 10:07:22 +01:00
|
|
|
result = self.client_get("/json/realm/profile_fields")
|
|
|
|
self.assert_json_success(result)
|
|
|
|
self.assertEqual(200, result.status_code)
|
|
|
|
content = result.json()
|
2018-04-30 19:51:16 +02:00
|
|
|
self.assertEqual(len(content["custom_fields"]), self.original_count)
|
2017-03-17 10:07:22 +01:00
|
|
|
|
2018-04-08 18:13:37 +02:00
|
|
|
def test_list_order(self) -> None:
|
|
|
|
self.login(self.example_email("iago"))
|
|
|
|
realm = get_realm('zulip')
|
|
|
|
order = (
|
|
|
|
CustomProfileField.objects.filter(realm=realm)
|
|
|
|
.order_by('-order')
|
|
|
|
.values_list('order', flat=True)
|
|
|
|
)
|
|
|
|
try_reorder_realm_custom_profile_fields(realm, order)
|
|
|
|
result = self.client_get("/json/realm/profile_fields")
|
|
|
|
content = result.json()
|
|
|
|
self.assertListEqual(content["custom_fields"],
|
|
|
|
sorted(content["custom_fields"], key=lambda x: -x["id"]))
|
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_create(self) -> None:
|
2017-05-23 20:57:59 +02:00
|
|
|
self.login(self.example_email("iago"))
|
2018-04-08 18:13:37 +02:00
|
|
|
realm = get_realm('zulip')
|
2017-03-17 10:07:22 +01:00
|
|
|
data = {"name": u"Phone", "field_type": "text id"} # type: Dict[str, Any]
|
|
|
|
result = self.client_post("/json/realm/profile_fields", info=data)
|
2017-06-26 13:12:20 +02:00
|
|
|
self.assert_json_error(result, u'Argument "field_type" is not valid JSON.')
|
2017-03-17 10:07:22 +01:00
|
|
|
|
|
|
|
data["name"] = ""
|
|
|
|
data["field_type"] = 100
|
|
|
|
result = self.client_post("/json/realm/profile_fields", info=data)
|
|
|
|
self.assert_json_error(result, u'Name cannot be blank.')
|
|
|
|
|
2018-08-16 20:12:49 +02:00
|
|
|
data["name"] = "*" * 41
|
|
|
|
data["field_type"] = 100
|
|
|
|
result = self.client_post("/json/realm/profile_fields", info=data)
|
|
|
|
self.assert_json_error(result, 'name is too long (limit: 40 characters)')
|
|
|
|
|
2017-03-17 10:07:22 +01:00
|
|
|
data["name"] = "Phone"
|
|
|
|
result = self.client_post("/json/realm/profile_fields", info=data)
|
|
|
|
self.assert_json_error(result, u'Invalid field type.')
|
|
|
|
|
|
|
|
data["name"] = "Phone"
|
2018-03-31 07:30:24 +02:00
|
|
|
data["hint"] = "*" * 81
|
|
|
|
data["field_type"] = CustomProfileField.SHORT_TEXT
|
|
|
|
result = self.client_post("/json/realm/profile_fields", info=data)
|
2018-05-03 23:21:16 +02:00
|
|
|
msg = "hint is too long (limit: 80 characters)"
|
2018-03-31 07:30:24 +02:00
|
|
|
self.assert_json_error(result, msg)
|
|
|
|
|
|
|
|
data["name"] = "Phone"
|
|
|
|
data["hint"] = "Contact number"
|
2017-03-17 10:07:22 +01:00
|
|
|
data["field_type"] = CustomProfileField.SHORT_TEXT
|
|
|
|
result = self.client_post("/json/realm/profile_fields", info=data)
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
2018-04-08 18:13:37 +02:00
|
|
|
field = CustomProfileField.objects.get(name="Phone", realm=realm)
|
|
|
|
self.assertEqual(field.id, field.order)
|
|
|
|
|
2017-03-17 10:07:22 +01:00
|
|
|
result = self.client_post("/json/realm/profile_fields", info=data)
|
|
|
|
self.assert_json_error(result,
|
|
|
|
u'A field with that name already exists.')
|
|
|
|
|
2018-04-08 09:50:05 +02:00
|
|
|
def test_create_choice_field(self) -> None:
|
|
|
|
self.login(self.example_email("iago"))
|
|
|
|
data = {} # type: Dict[str, Union[str, int]]
|
|
|
|
data["name"] = "Favorite programming language"
|
|
|
|
data["field_type"] = CustomProfileField.CHOICE
|
|
|
|
|
|
|
|
data['field_data'] = 'invalid'
|
|
|
|
result = self.client_post("/json/realm/profile_fields", info=data)
|
|
|
|
error_msg = "Bad value for 'field_data': invalid"
|
|
|
|
self.assert_json_error(result, error_msg)
|
|
|
|
|
|
|
|
data["field_data"] = ujson.dumps({
|
|
|
|
'python': ['1'],
|
|
|
|
'java': ['2'],
|
|
|
|
})
|
|
|
|
result = self.client_post("/json/realm/profile_fields", info=data)
|
|
|
|
self.assert_json_error(result, 'field_data is not a dict')
|
|
|
|
|
|
|
|
data["field_data"] = ujson.dumps({
|
|
|
|
'python': {'text': 'Python'},
|
|
|
|
'java': {'text': 'Java'},
|
|
|
|
})
|
|
|
|
result = self.client_post("/json/realm/profile_fields", info=data)
|
|
|
|
self.assert_json_error(result, "order key is missing from field_data")
|
|
|
|
|
|
|
|
data["field_data"] = ujson.dumps({
|
|
|
|
'python': {'text': 'Python', 'order': ''},
|
|
|
|
'java': {'text': 'Java', 'order': '2'},
|
|
|
|
})
|
|
|
|
result = self.client_post("/json/realm/profile_fields", info=data)
|
|
|
|
self.assert_json_error(result, 'field_data["order"] cannot be blank.')
|
|
|
|
|
|
|
|
data["field_data"] = ujson.dumps({
|
|
|
|
'': {'text': 'Python', 'order': '1'},
|
|
|
|
'java': {'text': 'Java', 'order': '2'},
|
|
|
|
})
|
|
|
|
result = self.client_post("/json/realm/profile_fields", info=data)
|
|
|
|
self.assert_json_error(result, "'value' cannot be blank.")
|
|
|
|
|
|
|
|
data["field_data"] = ujson.dumps({
|
|
|
|
'python': {'text': 'Python', 'order': 1},
|
|
|
|
'java': {'text': 'Java', 'order': '2'},
|
|
|
|
})
|
|
|
|
result = self.client_post("/json/realm/profile_fields", info=data)
|
|
|
|
self.assert_json_error(result, 'field_data["order"] is not a string')
|
|
|
|
|
2018-08-10 20:39:13 +02:00
|
|
|
data["field_data"] = ujson.dumps({})
|
|
|
|
result = self.client_post("/json/realm/profile_fields", info=data)
|
|
|
|
self.assert_json_error(result, 'Field must have at least one choice.')
|
|
|
|
|
2018-04-08 09:50:05 +02:00
|
|
|
data["field_data"] = ujson.dumps({
|
|
|
|
'python': {'text': 'Python', 'order': '1'},
|
|
|
|
'java': {'text': 'Java', 'order': '2'},
|
|
|
|
})
|
|
|
|
result = self.client_post("/json/realm/profile_fields", info=data)
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_not_realm_admin(self) -> None:
|
2017-05-23 20:57:59 +02:00
|
|
|
self.login(self.example_email("hamlet"))
|
2017-03-17 10:07:22 +01:00
|
|
|
result = self.client_post("/json/realm/profile_fields")
|
2018-03-08 01:47:17 +01:00
|
|
|
self.assert_json_error(result, u'Must be an organization administrator')
|
2017-03-17 10:07:22 +01:00
|
|
|
result = self.client_delete("/json/realm/profile_fields/1")
|
2018-03-08 01:47:17 +01:00
|
|
|
self.assert_json_error(result, 'Must be an organization administrator')
|
2017-03-17 10:07:22 +01:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_delete(self) -> None:
|
2017-05-23 20:57:59 +02:00
|
|
|
self.login(self.example_email("iago"))
|
2017-03-17 10:07:22 +01:00
|
|
|
realm = get_realm('zulip')
|
2018-03-19 20:17:52 +01:00
|
|
|
field = CustomProfileField.objects.get(name="Phone number", realm=realm)
|
2017-03-17 10:07:22 +01:00
|
|
|
result = self.client_delete("/json/realm/profile_fields/100")
|
|
|
|
self.assert_json_error(result, 'Field id 100 not found.')
|
|
|
|
|
2018-05-06 11:35:34 +02:00
|
|
|
self.assertTrue(self.custom_field_exists_in_realm(field.id))
|
2017-03-17 10:07:22 +01:00
|
|
|
result = self.client_delete(
|
|
|
|
"/json/realm/profile_fields/{}".format(field.id))
|
|
|
|
self.assert_json_success(result)
|
2018-05-06 11:35:34 +02:00
|
|
|
self.assertFalse(self.custom_field_exists_in_realm(field.id))
|
2017-03-17 10:07:22 +01:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_update(self) -> None:
|
2017-05-23 20:57:59 +02:00
|
|
|
self.login(self.example_email("iago"))
|
2017-03-17 10:07:22 +01:00
|
|
|
realm = get_realm('zulip')
|
|
|
|
result = self.client_patch(
|
|
|
|
"/json/realm/profile_fields/100",
|
|
|
|
info={'name': '',
|
|
|
|
'field_type': CustomProfileField.SHORT_TEXT}
|
|
|
|
)
|
|
|
|
self.assert_json_error(result, u'Name cannot be blank.')
|
|
|
|
|
|
|
|
result = self.client_patch(
|
|
|
|
"/json/realm/profile_fields/100",
|
|
|
|
info={'name': 'Phone Number',
|
|
|
|
'field_type': CustomProfileField.SHORT_TEXT}
|
|
|
|
)
|
|
|
|
self.assert_json_error(result, u'Field id 100 not found.')
|
|
|
|
|
2018-03-19 20:17:52 +01:00
|
|
|
field = CustomProfileField.objects.get(name="Phone number", realm=realm)
|
2017-03-17 10:07:22 +01:00
|
|
|
|
2018-04-30 19:51:16 +02:00
|
|
|
self.assertEqual(CustomProfileField.objects.count(), self.original_count)
|
2017-03-17 10:07:22 +01:00
|
|
|
result = self.client_patch(
|
|
|
|
"/json/realm/profile_fields/{}".format(field.id),
|
2018-03-19 20:17:52 +01:00
|
|
|
info={'name': 'New phone number',
|
2017-03-17 10:07:22 +01:00
|
|
|
'field_type': CustomProfileField.SHORT_TEXT})
|
|
|
|
self.assert_json_success(result)
|
2018-03-31 07:30:24 +02:00
|
|
|
field = CustomProfileField.objects.get(id=field.id, realm=realm)
|
2018-04-30 19:51:16 +02:00
|
|
|
self.assertEqual(CustomProfileField.objects.count(), self.original_count)
|
2018-03-31 07:30:24 +02:00
|
|
|
self.assertEqual(field.name, 'New phone number')
|
|
|
|
self.assertIs(field.hint, '')
|
|
|
|
self.assertEqual(field.field_type, CustomProfileField.SHORT_TEXT)
|
|
|
|
|
2018-08-16 20:12:49 +02:00
|
|
|
result = self.client_patch(
|
|
|
|
"/json/realm/profile_fields/{}".format(field.id),
|
|
|
|
info={'name': '*' * 41,
|
|
|
|
'field_type': CustomProfileField.SHORT_TEXT})
|
|
|
|
msg = "name is too long (limit: 40 characters)"
|
|
|
|
self.assert_json_error(result, msg)
|
|
|
|
|
2018-03-31 07:30:24 +02:00
|
|
|
result = self.client_patch(
|
|
|
|
"/json/realm/profile_fields/{}".format(field.id),
|
|
|
|
info={'name': 'New phone number',
|
|
|
|
'hint': '*' * 81,
|
|
|
|
'field_type': CustomProfileField.SHORT_TEXT})
|
2018-05-03 23:21:16 +02:00
|
|
|
msg = "hint is too long (limit: 80 characters)"
|
2018-03-31 07:30:24 +02:00
|
|
|
self.assert_json_error(result, msg)
|
|
|
|
|
|
|
|
result = self.client_patch(
|
|
|
|
"/json/realm/profile_fields/{}".format(field.id),
|
|
|
|
info={'name': 'New phone number',
|
|
|
|
'hint': 'New contact number',
|
|
|
|
'field_type': CustomProfileField.SHORT_TEXT})
|
|
|
|
self.assert_json_success(result)
|
2018-03-19 20:17:52 +01:00
|
|
|
|
|
|
|
field = CustomProfileField.objects.get(id=field.id, realm=realm)
|
2018-04-30 19:51:16 +02:00
|
|
|
self.assertEqual(CustomProfileField.objects.count(), self.original_count)
|
2018-03-19 20:17:52 +01:00
|
|
|
self.assertEqual(field.name, 'New phone number')
|
2018-03-31 07:30:24 +02:00
|
|
|
self.assertEqual(field.hint, 'New contact number')
|
2017-03-17 10:07:22 +01:00
|
|
|
self.assertEqual(field.field_type, CustomProfileField.SHORT_TEXT)
|
|
|
|
|
2018-04-08 09:50:05 +02:00
|
|
|
field = CustomProfileField.objects.get(name="Favorite editor", realm=realm)
|
|
|
|
result = self.client_patch(
|
|
|
|
"/json/realm/profile_fields/{}".format(field.id),
|
|
|
|
info={'name': 'Favorite editor',
|
|
|
|
'field_data': 'invalid'})
|
|
|
|
self.assert_json_error(result, "Bad value for 'field_data': invalid")
|
|
|
|
|
|
|
|
field_data = ujson.dumps({
|
|
|
|
'vim': 'Vim',
|
|
|
|
'emacs': {'order': '2', 'text': 'Emacs'},
|
|
|
|
})
|
|
|
|
result = self.client_patch(
|
|
|
|
"/json/realm/profile_fields/{}".format(field.id),
|
|
|
|
info={'name': 'Favorite editor',
|
|
|
|
'field_data': field_data})
|
|
|
|
self.assert_json_error(result, "field_data is not a dict")
|
|
|
|
|
|
|
|
field_data = ujson.dumps({
|
|
|
|
'vim': {'order': '1', 'text': 'Vim'},
|
|
|
|
'emacs': {'order': '2', 'text': 'Emacs'},
|
|
|
|
'notepad': {'order': '3', 'text': 'Notepad'},
|
|
|
|
})
|
|
|
|
result = self.client_patch(
|
|
|
|
"/json/realm/profile_fields/{}".format(field.id),
|
|
|
|
info={'name': 'Favorite editor',
|
|
|
|
'field_data': field_data})
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_update_is_aware_of_uniqueness(self) -> None:
|
2017-05-23 20:57:59 +02:00
|
|
|
self.login(self.example_email("iago"))
|
2017-03-17 10:07:22 +01:00
|
|
|
realm = get_realm('zulip')
|
2018-05-06 11:35:34 +02:00
|
|
|
field_1 = try_add_realm_custom_profile_field(realm, u"Phone",
|
|
|
|
CustomProfileField.SHORT_TEXT)
|
2017-03-17 10:07:22 +01:00
|
|
|
|
2018-05-06 11:35:34 +02:00
|
|
|
field_2 = try_add_realm_custom_profile_field(realm, u"Phone 1",
|
|
|
|
CustomProfileField.SHORT_TEXT)
|
2017-03-17 10:07:22 +01:00
|
|
|
|
2018-05-06 11:35:34 +02:00
|
|
|
self.assertTrue(self.custom_field_exists_in_realm(field_1.id))
|
|
|
|
self.assertTrue(self.custom_field_exists_in_realm(field_2.id))
|
2017-03-17 10:07:22 +01:00
|
|
|
result = self.client_patch(
|
2018-05-06 11:35:34 +02:00
|
|
|
"/json/realm/profile_fields/{}".format(field_2.id),
|
2017-03-17 10:07:22 +01:00
|
|
|
info={'name': 'Phone', 'field_type': CustomProfileField.SHORT_TEXT})
|
|
|
|
self.assert_json_error(
|
|
|
|
result, u'A field with that name already exists.')
|
|
|
|
|
2018-04-29 11:55:16 +02:00
|
|
|
def assert_error_update_invalid_value(self, field_name: str, new_value: object, error_msg: str) -> None:
|
|
|
|
self.login(self.example_email("iago"))
|
|
|
|
realm = get_realm('zulip')
|
|
|
|
field = CustomProfileField.objects.get(name=field_name, realm=realm)
|
|
|
|
|
|
|
|
# Update value of field
|
|
|
|
result = self.client_patch("/json/users/me/profile_data",
|
|
|
|
{'data': ujson.dumps([{"id": field.id, "value": new_value}])})
|
|
|
|
self.assert_json_error(result, error_msg)
|
2017-03-17 10:07:22 +01:00
|
|
|
|
2018-04-08 18:13:37 +02:00
|
|
|
def test_reorder(self) -> None:
|
|
|
|
self.login(self.example_email("iago"))
|
|
|
|
realm = get_realm('zulip')
|
|
|
|
order = (
|
|
|
|
CustomProfileField.objects.filter(realm=realm)
|
|
|
|
.order_by('-order')
|
|
|
|
.values_list('order', flat=True)
|
|
|
|
)
|
|
|
|
result = self.client_patch("/json/realm/profile_fields",
|
|
|
|
info={'order': ujson.dumps(order)})
|
|
|
|
self.assert_json_success(result)
|
|
|
|
fields = CustomProfileField.objects.filter(realm=realm).order_by('order')
|
|
|
|
for field in fields:
|
|
|
|
self.assertEqual(field.id, order[field.order])
|
|
|
|
|
|
|
|
def test_reorder_duplicates(self) -> None:
|
|
|
|
self.login(self.example_email("iago"))
|
|
|
|
realm = get_realm('zulip')
|
|
|
|
order = (
|
|
|
|
CustomProfileField.objects.filter(realm=realm)
|
|
|
|
.order_by('-order')
|
|
|
|
.values_list('order', flat=True)
|
|
|
|
)
|
|
|
|
order = list(order)
|
|
|
|
order.append(4)
|
|
|
|
result = self.client_patch("/json/realm/profile_fields",
|
|
|
|
info={'order': ujson.dumps(order)})
|
|
|
|
self.assert_json_success(result)
|
|
|
|
fields = CustomProfileField.objects.filter(realm=realm).order_by('order')
|
|
|
|
for field in fields:
|
|
|
|
self.assertEqual(field.id, order[field.order])
|
|
|
|
|
|
|
|
def test_reorder_unauthorized(self) -> None:
|
|
|
|
self.login(self.example_email("hamlet"))
|
|
|
|
realm = get_realm('zulip')
|
|
|
|
order = (
|
|
|
|
CustomProfileField.objects.filter(realm=realm)
|
|
|
|
.order_by('-order')
|
|
|
|
.values_list('order', flat=True)
|
|
|
|
)
|
|
|
|
result = self.client_patch("/json/realm/profile_fields",
|
|
|
|
info={'order': ujson.dumps(order)})
|
|
|
|
self.assert_json_error(result, "Must be an organization administrator")
|
|
|
|
|
|
|
|
def test_reorder_invalid(self) -> None:
|
|
|
|
self.login(self.example_email("iago"))
|
|
|
|
order = [100, 200, 300]
|
|
|
|
result = self.client_patch("/json/realm/profile_fields",
|
|
|
|
info={'order': ujson.dumps(order)})
|
|
|
|
self.assert_json_error(
|
|
|
|
result, u'Invalid order mapping.')
|
|
|
|
order = [1, 2]
|
|
|
|
result = self.client_patch("/json/realm/profile_fields",
|
|
|
|
info={'order': ujson.dumps(order)})
|
|
|
|
self.assert_json_error(
|
|
|
|
result, u'Invalid order mapping.')
|
|
|
|
|
2018-04-29 11:55:16 +02:00
|
|
|
def test_update_invalid_field(self) -> None:
|
2017-05-23 20:57:59 +02:00
|
|
|
self.login(self.example_email("iago"))
|
2017-03-17 10:07:22 +01:00
|
|
|
data = [{'id': 1234, 'value': '12'}]
|
|
|
|
result = self.client_patch("/json/users/me/profile_data", {
|
|
|
|
'data': ujson.dumps(data)
|
|
|
|
})
|
|
|
|
self.assert_json_error(result,
|
|
|
|
u"Field id 1234 not found.")
|
|
|
|
|
2018-06-05 12:57:02 +02:00
|
|
|
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,
|
2019-04-20 01:00:46 +02:00
|
|
|
u'Field id %d not found.' % (invalid_field_id,))
|
2018-06-05 12:57:02 +02:00
|
|
|
|
|
|
|
field = CustomProfileField.objects.get(name="Mentor", realm=realm)
|
|
|
|
data = [{'id': field.id,
|
2018-06-07 20:01:31 +02:00
|
|
|
'value': [self.example_user("aaron").id]}] # type: List[Dict[str, Union[int, str, List[int]]]]
|
2018-06-05 12:57:02 +02:00
|
|
|
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]
|
2018-06-07 20:01:31 +02:00
|
|
|
self.assertEqual([self.example_user("aaron").id], converter(iago_value.value))
|
2018-06-05 12:57:02 +02:00
|
|
|
|
|
|
|
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)
|
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_update_invalid_short_text(self) -> None:
|
2018-04-29 11:55:16 +02:00
|
|
|
field_name = "Phone number"
|
|
|
|
self.assert_error_update_invalid_value(field_name, 't' * 201,
|
2018-05-03 23:21:16 +02:00
|
|
|
u"{} is too long (limit: 50 characters)".format(field_name))
|
2017-03-17 10:07:22 +01:00
|
|
|
|
2018-04-03 18:06:13 +02:00
|
|
|
def test_update_invalid_date(self) -> None:
|
2018-04-29 11:55:16 +02:00
|
|
|
field_name = "Birthday"
|
|
|
|
self.assert_error_update_invalid_value(field_name, u"a-b-c",
|
|
|
|
u"{} is not a date".format(field_name))
|
|
|
|
self.assert_error_update_invalid_value(field_name, 123,
|
|
|
|
u"{} is not a string".format(field_name))
|
2018-04-03 18:06:13 +02:00
|
|
|
|
2018-04-25 19:20:58 +02:00
|
|
|
def test_update_invalid_url(self) -> None:
|
2018-04-29 11:55:16 +02:00
|
|
|
field_name = "GitHub profile"
|
|
|
|
self.assert_error_update_invalid_value(field_name, u"not URL",
|
|
|
|
u"{} is not a URL".format(field_name))
|
2018-04-25 19:20:58 +02:00
|
|
|
|
2018-05-06 09:43:38 +02:00
|
|
|
def test_update_invalid_user_field(self) -> None:
|
|
|
|
field_name = "Mentor"
|
|
|
|
invalid_user_id = 1000
|
2018-06-07 20:01:31 +02:00
|
|
|
self.assert_error_update_invalid_value(field_name, [invalid_user_id],
|
2018-05-06 09:43:38 +02:00
|
|
|
u"Invalid user ID: %d"
|
2019-04-20 01:00:46 +02:00
|
|
|
% (invalid_user_id,))
|
2018-05-06 09:43:38 +02:00
|
|
|
|
|
|
|
def test_create_field_of_type_user(self) -> None:
|
|
|
|
self.login(self.example_email("iago"))
|
|
|
|
data = {"name": "Your mentor",
|
|
|
|
"field_type": CustomProfileField.USER,
|
|
|
|
}
|
|
|
|
result = self.client_post("/json/realm/profile_fields", info=data)
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
2018-04-29 11:55:16 +02:00
|
|
|
def test_update_profile_data_successfully(self) -> None:
|
2017-05-23 20:57:59 +02:00
|
|
|
self.login(self.example_email("iago"))
|
2017-03-17 10:07:22 +01:00
|
|
|
realm = get_realm('zulip')
|
|
|
|
fields = [
|
2018-11-06 10:05:31 +01:00
|
|
|
('Phone number', '*short* text data'),
|
|
|
|
('Biography', '~~short~~ **long** text data'),
|
|
|
|
('Favorite food', 'long short text data'),
|
2018-04-08 09:50:05 +02:00
|
|
|
('Favorite editor', 'vim'),
|
2018-04-03 18:06:13 +02:00
|
|
|
('Birthday', '1909-3-5'),
|
2018-04-25 19:20:58 +02:00
|
|
|
('GitHub profile', 'https://github.com/ABC'),
|
2018-06-07 20:01:31 +02:00
|
|
|
('Mentor', [self.example_user("cordelia").id]),
|
2017-03-17 10:07:22 +01:00
|
|
|
]
|
|
|
|
|
|
|
|
data = []
|
|
|
|
for i, field_value in enumerate(fields):
|
2018-03-19 20:17:52 +01:00
|
|
|
name, value = field_value
|
|
|
|
field = CustomProfileField.objects.get(name=name, realm=realm)
|
2017-03-17 10:07:22 +01:00
|
|
|
data.append({
|
|
|
|
'id': field.id,
|
|
|
|
'value': value,
|
2018-11-06 10:05:31 +01:00
|
|
|
'field': field,
|
2017-03-17 10:07:22 +01:00
|
|
|
})
|
|
|
|
|
2018-03-19 20:17:52 +01:00
|
|
|
# Update value of field
|
2017-03-17 10:07:22 +01:00
|
|
|
result = self.client_patch("/json/users/me/profile_data",
|
|
|
|
{'data': ujson.dumps(data)})
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
2017-05-23 20:57:59 +02:00
|
|
|
iago = self.example_user('iago')
|
2017-03-17 10:07:22 +01:00
|
|
|
expected_value = {f['id']: f['value'] for f in data}
|
2018-11-06 10:05:31 +01:00
|
|
|
expected_rendered_value = {} # type: Dict[Union[int, float, str, None], Union[str, None]]
|
|
|
|
for f in data:
|
|
|
|
if f['field'].is_renderable():
|
|
|
|
expected_rendered_value[f['id']] = bugdown_convert(f['value'])
|
|
|
|
else:
|
|
|
|
expected_rendered_value[f['id']] = None
|
2017-03-17 10:07:22 +01:00
|
|
|
|
2017-05-10 23:37:20 +02:00
|
|
|
for field_dict in iago.profile_data:
|
|
|
|
self.assertEqual(field_dict['value'], expected_value[field_dict['id']])
|
2018-11-06 10:05:31 +01:00
|
|
|
self.assertEqual(field_dict['rendered_value'], expected_rendered_value[field_dict['id']])
|
2018-04-08 09:50:05 +02:00
|
|
|
for k in ['id', 'type', 'name', 'field_data']:
|
2017-05-10 23:37:20 +02:00
|
|
|
self.assertIn(k, field_dict)
|
2017-03-17 10:07:22 +01:00
|
|
|
|
2018-03-19 20:17:52 +01:00
|
|
|
# Update value of one field.
|
|
|
|
field = CustomProfileField.objects.get(name='Biography', realm=realm)
|
2017-03-17 10:07:22 +01:00
|
|
|
data = [{
|
|
|
|
'id': field.id,
|
|
|
|
'value': 'foobar',
|
|
|
|
}]
|
|
|
|
|
|
|
|
result = self.client_patch("/json/users/me/profile_data",
|
|
|
|
{'data': ujson.dumps(data)})
|
|
|
|
self.assert_json_success(result)
|
|
|
|
for f in iago.profile_data:
|
|
|
|
if f['id'] == field.id:
|
|
|
|
self.assertEqual(f['value'], 'foobar')
|
|
|
|
|
2018-04-29 11:55:16 +02:00
|
|
|
def test_update_invalid_choice_field(self) -> None:
|
|
|
|
field_name = "Favorite editor"
|
|
|
|
self.assert_error_update_invalid_value(field_name, "foobar",
|
|
|
|
"'foobar' is not a valid choice for '{}'.".format(field_name))
|
|
|
|
|
|
|
|
def test_update_choice_field_successfully(self) -> None:
|
2018-04-08 09:50:05 +02:00
|
|
|
self.login(self.example_email("iago"))
|
|
|
|
realm = get_realm('zulip')
|
2018-04-29 11:55:16 +02:00
|
|
|
field = CustomProfileField.objects.get(name='Favorite editor', realm=realm)
|
2018-04-08 09:50:05 +02:00
|
|
|
data = [{
|
|
|
|
'id': field.id,
|
|
|
|
'value': 'emacs',
|
|
|
|
}]
|
|
|
|
|
|
|
|
result = self.client_patch("/json/users/me/profile_data",
|
|
|
|
{'data': ujson.dumps(data)})
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
2018-04-30 19:51:16 +02:00
|
|
|
def test_delete_internals(self) -> None:
|
2017-05-07 17:21:26 +02:00
|
|
|
user_profile = self.example_user('iago')
|
2017-03-17 10:07:22 +01:00
|
|
|
realm = user_profile.realm
|
2018-03-19 20:17:52 +01:00
|
|
|
field = CustomProfileField.objects.get(name="Phone number", realm=realm)
|
2018-06-07 20:01:31 +02:00
|
|
|
data = [{'id': field.id, 'value': u'123456'}] # type: List[Dict[str, Union[int, str, List[int]]]]
|
2017-03-17 10:07:22 +01:00
|
|
|
do_update_user_custom_profile_data(user_profile, data)
|
|
|
|
|
2018-05-06 11:35:34 +02:00
|
|
|
self.assertTrue(self.custom_field_exists_in_realm(field.id))
|
2018-04-30 19:51:16 +02:00
|
|
|
self.assertEqual(user_profile.customprofilefieldvalue_set.count(), self.original_count)
|
2017-03-17 10:07:22 +01:00
|
|
|
|
|
|
|
do_remove_realm_custom_profile_field(realm, field)
|
|
|
|
|
2018-05-06 11:35:34 +02:00
|
|
|
self.assertFalse(self.custom_field_exists_in_realm(field.id))
|
2018-04-30 19:51:16 +02:00
|
|
|
self.assertEqual(user_profile.customprofilefieldvalue_set.count(), self.original_count - 1)
|
2018-11-06 10:05:31 +01:00
|
|
|
|
|
|
|
def test_null_value_and_rendered_value(self) -> None:
|
|
|
|
self.login(self.example_email("iago"))
|
|
|
|
realm = get_realm("zulip")
|
|
|
|
|
|
|
|
quote = try_add_realm_custom_profile_field(
|
|
|
|
realm=realm,
|
|
|
|
name="Quote",
|
|
|
|
hint="Saying or phrase which you known for.",
|
|
|
|
field_type=CustomProfileField.SHORT_TEXT
|
|
|
|
)
|
|
|
|
|
|
|
|
iago = self.example_user("iago")
|
|
|
|
iago_profile_quote = iago.profile_data[-1]
|
|
|
|
value = iago_profile_quote["value"]
|
|
|
|
rendered_value = iago_profile_quote["rendered_value"]
|
|
|
|
self.assertIsNone(value)
|
|
|
|
self.assertIsNone(rendered_value)
|
|
|
|
|
|
|
|
update_dict = {
|
|
|
|
"id": quote.id,
|
|
|
|
"value": "***beware*** of jealousy..."
|
|
|
|
}
|
|
|
|
do_update_user_custom_profile_data(iago, [update_dict])
|
|
|
|
|
|
|
|
iago_profile_quote = self.example_user("iago").profile_data[-1]
|
|
|
|
value = iago_profile_quote["value"]
|
|
|
|
rendered_value = iago_profile_quote["rendered_value"]
|
|
|
|
self.assertIsNotNone(value)
|
|
|
|
self.assertIsNotNone(rendered_value)
|
|
|
|
self.assertEqual("<p><strong><em>beware</em></strong> of jealousy...</p>", rendered_value)
|