mirror of
https://github.com/zulip/zulip.git
synced 2025-11-10 00:46:03 +00:00
committed by
Tim Abbott
parent
1e948ab405
commit
e82c879b85
@@ -89,6 +89,8 @@ exports.add_custom_profile_fields_to_settings = function () {
|
||||
type = "date";
|
||||
} else if (field_type === "URL") {
|
||||
type = "url";
|
||||
} else if (field_type === "User") {
|
||||
type = "user";
|
||||
} else {
|
||||
blueslip.error("Undefined field type.");
|
||||
}
|
||||
|
||||
@@ -7,13 +7,15 @@ ViewFuncT = TypeVar('ViewFuncT', bound=Callable[..., HttpResponse])
|
||||
# including many examples
|
||||
Validator = Callable[[str, object], Optional[str]]
|
||||
ExtendedValidator = Callable[[str, str, object], Optional[str]]
|
||||
RealmUserValidator = Callable[[int, object, bool], Optional[str]]
|
||||
|
||||
ProfileDataElement = Dict[str, Union[int, float, Optional[str]]]
|
||||
ProfileData = List[ProfileDataElement]
|
||||
|
||||
FieldElement = Tuple[int, str, Validator, Callable[[Any], Any]]
|
||||
ExtendedFieldElement = Tuple[int, str, ExtendedValidator, Callable[[Any], Any]]
|
||||
UserFieldElement = Tuple[int, str, RealmUserValidator, Callable[[Any], Any]]
|
||||
|
||||
FieldTypeData = List[Union[FieldElement, ExtendedFieldElement]]
|
||||
FieldTypeData = List[Union[FieldElement, ExtendedFieldElement, UserFieldElement]]
|
||||
|
||||
ProfileFieldData = Dict[str, Dict[str, str]]
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.11 on 2018-05-08 17:24
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('zerver', '0171_userprofile_dense_mode'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='customprofilefield',
|
||||
name='field_type',
|
||||
field=models.PositiveSmallIntegerField(choices=[(1, 'Short text'), (2, 'Long text'), (4, 'Date'), (5, 'URL'), (3, 'Choice'), (6, 'User')], default=1),
|
||||
),
|
||||
]
|
||||
@@ -36,7 +36,8 @@ from zerver.lib.validator import check_int, check_float, \
|
||||
check_url
|
||||
from zerver.lib.name_restrictions import is_disposable_domain
|
||||
from zerver.lib.types import Validator, ExtendedValidator, \
|
||||
ProfileDataElement, ProfileData, FieldTypeData
|
||||
ProfileDataElement, ProfileData, FieldTypeData, FieldElement, \
|
||||
RealmUserValidator
|
||||
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
@@ -1971,16 +1972,24 @@ class CustomProfileField(models.Model):
|
||||
CHOICE = 3
|
||||
DATE = 4
|
||||
URL = 5
|
||||
USER = 6
|
||||
|
||||
# These are the fields whose validators require field_data
|
||||
# argument as well.
|
||||
EXTENDED_FIELD_TYPE_DATA = [
|
||||
# These are the fields whose validators require more than var_name
|
||||
# and value argument. i.e. CHOICE require field_data, USER require
|
||||
# realm as argument.
|
||||
CHOICE_FIELD_TYPE_DATA = [
|
||||
(CHOICE, str(_('Choice')), validate_choice_field, str),
|
||||
] # type: FieldTypeData
|
||||
USER_FIELD_TYPE_DATA = [
|
||||
(USER, str(_('User')), check_valid_user_id, int),
|
||||
] # type: FieldTypeData
|
||||
|
||||
EXTENDED_FIELD_VALIDATORS = {
|
||||
item[0]: item[2] for item in EXTENDED_FIELD_TYPE_DATA
|
||||
CHOICE_FIELD_VALIDATORS = {
|
||||
item[0]: item[2] for item in CHOICE_FIELD_TYPE_DATA
|
||||
} # type: Dict[int, ExtendedValidator]
|
||||
USER_FIELD_VALIDATORS = {
|
||||
item[0]: item[2] for item in USER_FIELD_TYPE_DATA
|
||||
} # type: Dict[int, RealmUserValidator]
|
||||
|
||||
FIELD_TYPE_DATA = [
|
||||
# Type, Name, Validator, Converter
|
||||
@@ -1990,7 +1999,7 @@ class CustomProfileField(models.Model):
|
||||
(URL, str(_('URL')), check_url, str),
|
||||
] # type: FieldTypeData
|
||||
|
||||
ALL_FIELD_TYPES = FIELD_TYPE_DATA + EXTENDED_FIELD_TYPE_DATA
|
||||
ALL_FIELD_TYPES = FIELD_TYPE_DATA + CHOICE_FIELD_TYPE_DATA + USER_FIELD_TYPE_DATA
|
||||
|
||||
FIELD_VALIDATORS = {item[0]: item[2] for item in FIELD_TYPE_DATA} # type: Dict[int, Validator]
|
||||
FIELD_CONVERTERS = {item[0]: item[3] for item in ALL_FIELD_TYPES} # type: Dict[int, Callable[[Any], Any]]
|
||||
|
||||
@@ -342,6 +342,21 @@ class CustomProfileFieldTest(ZulipTestCase):
|
||||
self.assert_error_update_invalid_value(field_name, u"not URL",
|
||||
u"{} is not a URL".format(field_name))
|
||||
|
||||
def test_update_invalid_user_field(self) -> None:
|
||||
field_name = "Mentor"
|
||||
invalid_user_id = 1000
|
||||
self.assert_error_update_invalid_value(field_name, invalid_user_id,
|
||||
u"Invalid user ID: %d"
|
||||
% (invalid_user_id))
|
||||
|
||||
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)
|
||||
|
||||
def test_update_profile_data_successfully(self) -> None:
|
||||
self.login(self.example_email("iago"))
|
||||
realm = get_realm('zulip')
|
||||
@@ -352,6 +367,7 @@ class CustomProfileFieldTest(ZulipTestCase):
|
||||
('Favorite editor', 'vim'),
|
||||
('Birthday', '1909-3-5'),
|
||||
('GitHub profile', 'https://github.com/ABC'),
|
||||
('Mentor', self.example_user("cordelia").id),
|
||||
]
|
||||
|
||||
data = []
|
||||
|
||||
@@ -131,18 +131,21 @@ def update_user_custom_profile_data(
|
||||
return json_error(_('Field id {id} not found.').format(id=field_id))
|
||||
|
||||
validators = CustomProfileField.FIELD_VALIDATORS
|
||||
extended_validators = CustomProfileField.EXTENDED_FIELD_VALIDATORS
|
||||
field_type = field.field_type
|
||||
value = item['value']
|
||||
var_name = '{}'.format(field.name)
|
||||
if field_type in validators:
|
||||
validator = validators[field_type]
|
||||
result = validator(var_name, value)
|
||||
else:
|
||||
# Check extended validators.
|
||||
extended_validator = extended_validators[field_type]
|
||||
elif field_type == CustomProfileField.CHOICE:
|
||||
choice_field_validator = CustomProfileField.CHOICE_FIELD_VALIDATORS[field_type]
|
||||
field_data = field.field_data
|
||||
result = extended_validator(var_name, field_data, value)
|
||||
result = choice_field_validator(var_name, field_data, value)
|
||||
elif field_type == CustomProfileField.USER:
|
||||
user_field_validator = CustomProfileField.USER_FIELD_VALIDATORS[field_type]
|
||||
result = user_field_validator(user_profile.realm.id, value, False)
|
||||
else:
|
||||
raise AssertionError("Invalid field type")
|
||||
|
||||
if result is not None:
|
||||
return json_error(result)
|
||||
|
||||
@@ -327,6 +327,8 @@ class Command(BaseCommand):
|
||||
favorite_website = try_add_realm_custom_profile_field(zulip_realm, "GitHub profile",
|
||||
CustomProfileField.URL,
|
||||
hint="Or your personal blog's URL")
|
||||
mentor = try_add_realm_custom_profile_field(zulip_realm, "Mentor",
|
||||
CustomProfileField.USER)
|
||||
|
||||
# Fill in values for Iago and Hamlet
|
||||
hamlet = get_user("hamlet@zulip.com", zulip_realm)
|
||||
@@ -337,6 +339,7 @@ class Command(BaseCommand):
|
||||
{"id": favorite_editor.id, "value": "emacs"},
|
||||
{"id": birthday.id, "value": "2000-1-1"},
|
||||
{"id": favorite_website.id, "value": "https://github.com/zulip/zulip"},
|
||||
{"id": mentor.id, "value": hamlet.id},
|
||||
])
|
||||
do_update_user_custom_profile_data(hamlet, [
|
||||
{"id": phone_number.id, "value": "+0-11-23-456-7890"},
|
||||
@@ -345,6 +348,7 @@ class Command(BaseCommand):
|
||||
{"id": favorite_editor.id, "value": "vim"},
|
||||
{"id": birthday.id, "value": "1900-1-1"},
|
||||
{"id": favorite_website.id, "value": "https://blog.zulig.org"},
|
||||
{"id": mentor.id, "value": iago.id},
|
||||
])
|
||||
else:
|
||||
zulip_realm = get_realm("zulip")
|
||||
|
||||
Reference in New Issue
Block a user