mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	Add organization description field to realm settings.
This adds an organization description field to the Realm model, as well as an input field to the organization settings template. Added three tests. Set the max length of the field to 100 characters. Fixes #3962.
This commit is contained in:
		
				
					committed by
					
						
						Tim Abbott
					
				
			
			
				
	
			
			
			
						parent
						
							81f9de7cc8
						
					
				
				
					commit
					aa880b0419
				
			@@ -176,6 +176,10 @@ exports.toggle_email_change_display = function () {
 | 
			
		||||
    $(".change_email_tooltip").toggle();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
exports.update_realm_description = function (description) {
 | 
			
		||||
    $('#id_realm_description').val(description);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
exports.build_default_stream_table = function (streams_data) {
 | 
			
		||||
    var self = {};
 | 
			
		||||
 | 
			
		||||
@@ -373,6 +377,7 @@ exports.populate_auth_methods = function (auth_methods) {
 | 
			
		||||
function _setup_page() {
 | 
			
		||||
    var options = {
 | 
			
		||||
        realm_name: page_params.realm_name,
 | 
			
		||||
        realm_description: page_params.realm_description,
 | 
			
		||||
        realm_restricted_to_domain: page_params.realm_restricted_to_domain,
 | 
			
		||||
        realm_invite_required: page_params.realm_invite_required,
 | 
			
		||||
        realm_invite_by_admins_only: page_params.realm_invite_by_admins_only,
 | 
			
		||||
@@ -614,6 +619,7 @@ function _setup_page() {
 | 
			
		||||
 | 
			
		||||
    $(".administration").on("submit", "form.admin-realm-form", function (e) {
 | 
			
		||||
        var name_status = $("#admin-realm-name-status").expectOne();
 | 
			
		||||
        var description_status = $("#admin-realm-description-status").expectOne();
 | 
			
		||||
        var restricted_to_domain_status = $("#admin-realm-restricted-to-domain-status").expectOne();
 | 
			
		||||
        var invite_required_status = $("#admin-realm-invite-required-status").expectOne();
 | 
			
		||||
        var invite_by_admins_only_status = $("#admin-realm-invite-by-admins-only-status").expectOne();
 | 
			
		||||
@@ -626,6 +632,7 @@ function _setup_page() {
 | 
			
		||||
        var default_language_status = $("#admin-realm-default-language-status").expectOne();
 | 
			
		||||
        var waiting_period_threshold_status = $("#admin-realm-waiting_period_threshold_status").expectOne();
 | 
			
		||||
        name_status.hide();
 | 
			
		||||
        description_status.hide();
 | 
			
		||||
        restricted_to_domain_status.hide();
 | 
			
		||||
        invite_required_status.hide();
 | 
			
		||||
        invite_by_admins_only_status.hide();
 | 
			
		||||
@@ -642,6 +649,7 @@ function _setup_page() {
 | 
			
		||||
        e.stopPropagation();
 | 
			
		||||
 | 
			
		||||
        var new_name = $("#id_realm_name").val();
 | 
			
		||||
        var new_description = $("#id_realm_description").val();
 | 
			
		||||
        var new_restricted = $("#id_realm_restricted_to_domain").prop("checked");
 | 
			
		||||
        var new_invite = $("#id_realm_invite_required").prop("checked");
 | 
			
		||||
        var new_invite_by_admins_only = $("#id_realm_invite_by_admins_only").prop("checked");
 | 
			
		||||
@@ -673,6 +681,7 @@ function _setup_page() {
 | 
			
		||||
        var url = "/json/realm";
 | 
			
		||||
        var data = {
 | 
			
		||||
            name: JSON.stringify(new_name),
 | 
			
		||||
            description: JSON.stringify(new_description),
 | 
			
		||||
            restricted_to_domain: JSON.stringify(new_restricted),
 | 
			
		||||
            invite_required: JSON.stringify(new_invite),
 | 
			
		||||
            invite_by_admins_only: JSON.stringify(new_invite_by_admins_only),
 | 
			
		||||
@@ -695,6 +704,9 @@ function _setup_page() {
 | 
			
		||||
                if (response_data.name !== undefined) {
 | 
			
		||||
                    ui_report.success(i18n.t("Name changed!"), name_status);
 | 
			
		||||
                }
 | 
			
		||||
                if (response_data.description !== undefined) {
 | 
			
		||||
                    ui.report_success(i18n.t("Description changed!"), description_status);
 | 
			
		||||
                }
 | 
			
		||||
                if (response_data.restricted_to_domain !== undefined) {
 | 
			
		||||
                    if (response_data.restricted_to_domain) {
 | 
			
		||||
                        ui_report.success(i18n.t("New user e-mails now restricted to certain domains!"), restricted_to_domain_status);
 | 
			
		||||
 
 | 
			
		||||
@@ -55,6 +55,9 @@ function dispatch_normal_event(event) {
 | 
			
		||||
        if (event.op === 'update' && event.property === 'name') {
 | 
			
		||||
            page_params.realm_name = event.value;
 | 
			
		||||
            notifications.redraw_title();
 | 
			
		||||
        } else if (event.op === 'update' && event.property === 'description') {
 | 
			
		||||
            page_params.realm_description = event.value;
 | 
			
		||||
            admin.update_realm_description(event.value);
 | 
			
		||||
        } else if (event.op === 'update' && event.property === 'invite_required') {
 | 
			
		||||
            page_params.realm_invite_required = event.value;
 | 
			
		||||
        } else if (event.op === 'update' && event.property === 'invite_by_admins_only') {
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
{{t "Organization settings" }}</div>
 | 
			
		||||
  <form class="form-horizontal admin-realm-form">
 | 
			
		||||
    <div class="alert" id="admin-realm-name-status"></div>
 | 
			
		||||
    <div class="alert" id="admin-realm-description-status"></div>
 | 
			
		||||
    <div class="alert" id="admin-realm-restricted-to-domain-status"></div>
 | 
			
		||||
    <div class="alert" id="admin-realm-invite-required-status"></div>
 | 
			
		||||
    <div class="alert" id="admin-realm-invite-by-admins-only-status"></div>
 | 
			
		||||
@@ -20,6 +21,11 @@
 | 
			
		||||
      <input type="text" id="id_realm_name" name="realm_name" class="admin-realm-name"
 | 
			
		||||
             value="{{ realm_name }}" />
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="input-group admin-realm">
 | 
			
		||||
      <label for="realm_description">{{t "Your organization's description" }}</label>
 | 
			
		||||
      <input type="text" id="id_realm_description" name="realm_description" class="admin-realm-description"
 | 
			
		||||
        maxlength="100" value="{{ realm_description }}" />
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="input-group admin-restricted-to-domain">
 | 
			
		||||
      <input type="checkbox" class="inline-block" id="id_realm_restricted_to_domain" name="realm_restricted_to_domain"
 | 
			
		||||
         {{#if realm_restricted_to_domain}}checked="checked"{{/if}} />
 | 
			
		||||
 
 | 
			
		||||
@@ -431,6 +431,18 @@ def do_set_realm_name(realm, name):
 | 
			
		||||
    )
 | 
			
		||||
    send_event(event, active_user_ids(realm))
 | 
			
		||||
 | 
			
		||||
def do_set_realm_description(realm, description):
 | 
			
		||||
    # type: (Realm, Text) -> None
 | 
			
		||||
    realm.description = description
 | 
			
		||||
    realm.save(update_fields=['description'])
 | 
			
		||||
    event = dict(
 | 
			
		||||
        type='realm',
 | 
			
		||||
        op='update',
 | 
			
		||||
        property='description',
 | 
			
		||||
        value=description,
 | 
			
		||||
    )
 | 
			
		||||
    send_event(event, active_user_ids(realm))
 | 
			
		||||
 | 
			
		||||
def do_set_realm_restricted_to_domain(realm, restricted):
 | 
			
		||||
    # type: (Realm, bool) -> None
 | 
			
		||||
    realm.restricted_to_domain = restricted
 | 
			
		||||
 
 | 
			
		||||
@@ -93,6 +93,7 @@ def fetch_initial_state_data(user_profile, event_types, queue_id,
 | 
			
		||||
 | 
			
		||||
    if want('realm'):
 | 
			
		||||
        state['realm_name'] = user_profile.realm.name
 | 
			
		||||
        state['realm_description'] = user_profile.realm.description
 | 
			
		||||
        state['realm_restricted_to_domain'] = user_profile.realm.restricted_to_domain
 | 
			
		||||
        state['realm_invite_required'] = user_profile.realm.invite_required
 | 
			
		||||
        state['realm_invite_by_admins_only'] = user_profile.realm.invite_by_admins_only
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								zerver/migrations/0063_realm_description.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								zerver/migrations/0063_realm_description.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
# -*- coding: utf-8 -*-
 | 
			
		||||
# Generated by Django 1.10.5 on 2017-03-19 19:06
 | 
			
		||||
from __future__ import unicode_literals
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('zerver', '0062_default_timezone'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='realm',
 | 
			
		||||
            name='description',
 | 
			
		||||
            field=models.TextField(max_length=100, null=True),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@@ -122,6 +122,7 @@ class Realm(ModelReprMixin, models.Model):
 | 
			
		||||
    show_digest_email = models.BooleanField(default=True) # type: bool
 | 
			
		||||
    name_changes_disabled = models.BooleanField(default=False) # type: bool
 | 
			
		||||
    email_changes_disabled = models.BooleanField(default=False) # type: bool
 | 
			
		||||
    description = models.TextField(max_length=100, null=True) # type: Optional[Text]
 | 
			
		||||
 | 
			
		||||
    allow_message_editing = models.BooleanField(default=True) # type: bool
 | 
			
		||||
    DEFAULT_MESSAGE_CONTENT_EDIT_LIMIT_SECONDS = 600 # if changed, also change in admin.js
 | 
			
		||||
 
 | 
			
		||||
@@ -43,6 +43,7 @@ from zerver.lib.actions import (
 | 
			
		||||
    do_set_muted_topics,
 | 
			
		||||
    do_set_realm_create_stream_by_admins_only,
 | 
			
		||||
    do_set_realm_name,
 | 
			
		||||
    do_set_realm_description,
 | 
			
		||||
    do_set_realm_restricted_to_domain,
 | 
			
		||||
    do_set_realm_invite_required,
 | 
			
		||||
    do_set_realm_invite_by_admins_only,
 | 
			
		||||
@@ -564,6 +565,18 @@ class EventsRegisterTest(ZulipTestCase):
 | 
			
		||||
        error = schema_checker('events[0]', events[0])
 | 
			
		||||
        self.assert_on_error(error)
 | 
			
		||||
 | 
			
		||||
    def test_change_realm_description(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
        schema_checker = check_dict([
 | 
			
		||||
            ('type', equals('realm')),
 | 
			
		||||
            ('op', equals('update')),
 | 
			
		||||
            ('property', equals('description')),
 | 
			
		||||
            ('value', check_string),
 | 
			
		||||
        ])
 | 
			
		||||
        events = self.do_test(lambda: do_set_realm_description(self.user_profile.realm, 'New Realm Description'))
 | 
			
		||||
        error = schema_checker('events[0]', events[0])
 | 
			
		||||
        self.assert_on_error(error)
 | 
			
		||||
 | 
			
		||||
    def test_change_realm_restricted_to_domain(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
        schema_checker = check_dict([
 | 
			
		||||
 
 | 
			
		||||
@@ -99,6 +99,7 @@ class HomeTest(ZulipTestCase):
 | 
			
		||||
            "realm_create_stream_by_admins_only",
 | 
			
		||||
            "realm_default_language",
 | 
			
		||||
            "realm_default_streams",
 | 
			
		||||
            "realm_description",
 | 
			
		||||
            "realm_email_changes_disabled",
 | 
			
		||||
            "realm_emoji",
 | 
			
		||||
            "realm_filters",
 | 
			
		||||
 
 | 
			
		||||
@@ -7,8 +7,13 @@ from django.http import HttpResponse
 | 
			
		||||
from mock import patch
 | 
			
		||||
from typing import Any, Dict, List, Text
 | 
			
		||||
 | 
			
		||||
from zerver.lib.actions import \
 | 
			
		||||
    do_change_is_admin, do_set_realm_name, do_deactivate_realm, do_set_name_changes_disabled
 | 
			
		||||
from zerver.lib.actions import (
 | 
			
		||||
    do_change_is_admin,
 | 
			
		||||
    do_set_realm_name,
 | 
			
		||||
    do_set_realm_description,
 | 
			
		||||
    do_deactivate_realm,
 | 
			
		||||
    do_set_name_changes_disabled,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
from zerver.lib.test_classes import ZulipTestCase
 | 
			
		||||
from zerver.lib.test_helpers import tornado_redirected_to_list
 | 
			
		||||
@@ -48,6 +53,35 @@ class RealmTest(ZulipTestCase):
 | 
			
		||||
            value = new_name,
 | 
			
		||||
        ))
 | 
			
		||||
 | 
			
		||||
    def test_do_set_realm_description(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
        new_description = 'zulip dev group'
 | 
			
		||||
        events = [] # type: List[Dict[str, Any]]
 | 
			
		||||
        with tornado_redirected_to_list(events):
 | 
			
		||||
            do_set_realm_description(realm, new_description)
 | 
			
		||||
        event = events[0]['event']
 | 
			
		||||
        self.assertEqual(event, dict(
 | 
			
		||||
            type='realm',
 | 
			
		||||
            op='update',
 | 
			
		||||
            property='description',
 | 
			
		||||
            value=new_description,
 | 
			
		||||
        ))
 | 
			
		||||
 | 
			
		||||
    def test_realm_description_length(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
        new_description = 'A' * 101
 | 
			
		||||
        data = dict(description=ujson.dumps(new_description))
 | 
			
		||||
 | 
			
		||||
        # create an admin user
 | 
			
		||||
        email = 'iago@zulip.com'
 | 
			
		||||
        self.login(email)
 | 
			
		||||
 | 
			
		||||
        result = self.client_patch('/json/realm', data)
 | 
			
		||||
        self.assert_json_error(result, 'Realm description cannot exceed 100 characters.')
 | 
			
		||||
        realm = get_realm('zulip')
 | 
			
		||||
        self.assertNotEqual(realm.description, new_description)
 | 
			
		||||
 | 
			
		||||
    def test_update_realm_api(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
        new_name = 'Zulip: Worldwide Exporter of APIs'
 | 
			
		||||
 
 | 
			
		||||
@@ -302,6 +302,7 @@ def home_real(request):
 | 
			
		||||
        'realm_invite_required',
 | 
			
		||||
        'realm_message_content_edit_limit_seconds',
 | 
			
		||||
        'realm_name',
 | 
			
		||||
        'realm_description',
 | 
			
		||||
        'realm_name_changes_disabled',
 | 
			
		||||
        'realm_restricted_to_domain',
 | 
			
		||||
        'realm_waiting_period_threshold',
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ from zerver.decorator import require_realm_admin, to_non_negative_int
 | 
			
		||||
from zerver.lib.actions import (
 | 
			
		||||
    do_set_realm_create_stream_by_admins_only,
 | 
			
		||||
    do_set_realm_name,
 | 
			
		||||
    do_set_realm_description,
 | 
			
		||||
    do_set_realm_invite_by_admins_only,
 | 
			
		||||
    do_set_name_changes_disabled,
 | 
			
		||||
    do_set_email_changes_disabled,
 | 
			
		||||
@@ -28,6 +29,7 @@ from zerver.models import UserProfile
 | 
			
		||||
@require_realm_admin
 | 
			
		||||
@has_request_variables
 | 
			
		||||
def update_realm(request, user_profile, name=REQ(validator=check_string, default=None),
 | 
			
		||||
                 description=REQ(validator=check_string, default=None),
 | 
			
		||||
                 restricted_to_domain=REQ(validator=check_bool, default=None),
 | 
			
		||||
                 invite_required=REQ(validator=check_bool, default=None),
 | 
			
		||||
                 invite_by_admins_only=REQ(validator=check_bool, default=None),
 | 
			
		||||
@@ -40,7 +42,7 @@ def update_realm(request, user_profile, name=REQ(validator=check_string, default
 | 
			
		||||
                 default_language=REQ(validator=check_string, default=None),
 | 
			
		||||
                 waiting_period_threshold=REQ(converter=to_non_negative_int, default=None),
 | 
			
		||||
                 authentication_methods=REQ(validator=check_dict([]), default=None)):
 | 
			
		||||
    # type: (HttpRequest, UserProfile, Optional[str], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[int], Optional[str], Optional[int], Optional[dict]) -> HttpResponse
 | 
			
		||||
    # type: (HttpRequest, UserProfile, Optional[str], Optional[str], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[int], Optional[str], Optional[int], Optional[dict]) -> HttpResponse
 | 
			
		||||
    # Validation for default_language
 | 
			
		||||
    if default_language is not None and default_language not in get_available_language_codes():
 | 
			
		||||
        raise JsonableError(_("Invalid language '%s'" % (default_language,)))
 | 
			
		||||
@@ -49,6 +51,11 @@ def update_realm(request, user_profile, name=REQ(validator=check_string, default
 | 
			
		||||
    if name is not None and realm.name != name:
 | 
			
		||||
        do_set_realm_name(realm, name)
 | 
			
		||||
        data['name'] = 'updated'
 | 
			
		||||
    if description is not None and realm.description != description:
 | 
			
		||||
        if len(description) > 100:
 | 
			
		||||
            return json_error(_("Realm description cannot exceed 100 characters."))
 | 
			
		||||
        do_set_realm_description(realm, description)
 | 
			
		||||
        data['description'] = 'updated'
 | 
			
		||||
    if restricted_to_domain is not None and realm.restricted_to_domain != restricted_to_domain:
 | 
			
		||||
        do_set_realm_restricted_to_domain(realm, restricted_to_domain)
 | 
			
		||||
        data['restricted_to_domain'] = restricted_to_domain
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user