mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	support: Add functionality to copy admin emails.
Also renamed a bunch of functions in test_views for better readability.
This commit is contained in:
		@@ -330,12 +330,14 @@ class TestGetChartData(ZulipTestCase):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class TestSupportEndpoint(ZulipTestCase):
 | 
					class TestSupportEndpoint(ZulipTestCase):
 | 
				
			||||||
    def test_search(self) -> None:
 | 
					    def test_search(self) -> None:
 | 
				
			||||||
        def check_hamlet_user_result(result: HttpResponse) -> None:
 | 
					        def check_hamlet_user_query_result(result: HttpResponse) -> None:
 | 
				
			||||||
            self.assert_in_success_response(['<span class="label">user</span>\n', '<h3>King Hamlet</h3>',
 | 
					            self.assert_in_success_response(['<span class="label">user</span>\n', '<h3>King Hamlet</h3>',
 | 
				
			||||||
                                             '<b>Email</b>: hamlet@zulip.com', '<b>Is active</b>: True<br>',
 | 
					                                             '<b>Email</b>: hamlet@zulip.com', '<b>Is active</b>: True<br>',
 | 
				
			||||||
                                             '<b>Admins</b>: iago@zulip.com <br>'], result)
 | 
					                                             '<b>Admins</b>: iago@zulip.com\n',
 | 
				
			||||||
 | 
					                                             'class="copy-button" data-admin-emails="iago@zulip.com"'
 | 
				
			||||||
 | 
					                                             ], result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def check_zulip_realm_result(result: HttpResponse) -> None:
 | 
					        def check_zulip_realm_query_result(result: HttpResponse) -> None:
 | 
				
			||||||
            self.assert_in_success_response(['<input type="hidden" name="realm_id" value="1"', 'Zulip Dev</h3>',
 | 
					            self.assert_in_success_response(['<input type="hidden" name="realm_id" value="1"', 'Zulip Dev</h3>',
 | 
				
			||||||
                                             '<option value="1" selected>Self Hosted</option>',
 | 
					                                             '<option value="1" selected>Self Hosted</option>',
 | 
				
			||||||
                                             '<option value="2" >Limited</option>',
 | 
					                                             '<option value="2" >Limited</option>',
 | 
				
			||||||
@@ -345,7 +347,7 @@ class TestSupportEndpoint(ZulipTestCase):
 | 
				
			|||||||
                                             'scrub-realm-button">',
 | 
					                                             'scrub-realm-button">',
 | 
				
			||||||
                                             'data-string-id="zulip"'], result)
 | 
					                                             'data-string-id="zulip"'], result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def check_lear_realm_result(result: HttpResponse) -> None:
 | 
					        def check_lear_realm_query_result(result: HttpResponse) -> None:
 | 
				
			||||||
            self.assert_in_success_response(['<input type="hidden" name="realm_id" value="3"', 'Lear & Co.</h3>',
 | 
					            self.assert_in_success_response(['<input type="hidden" name="realm_id" value="3"', 'Lear & Co.</h3>',
 | 
				
			||||||
                                             '<option value="1" selected>Self Hosted</option>',
 | 
					                                             '<option value="1" selected>Self Hosted</option>',
 | 
				
			||||||
                                             '<option value="2" >Limited</option>',
 | 
					                                             '<option value="2" >Limited</option>',
 | 
				
			||||||
@@ -369,28 +371,28 @@ class TestSupportEndpoint(ZulipTestCase):
 | 
				
			|||||||
        self.assert_in_success_response(['<input type="text" name="q" class="input-xxlarge search-query"'], result)
 | 
					        self.assert_in_success_response(['<input type="text" name="q" class="input-xxlarge search-query"'], result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        result = self.client_get("/activity/support", {"q": "hamlet@zulip.com"})
 | 
					        result = self.client_get("/activity/support", {"q": "hamlet@zulip.com"})
 | 
				
			||||||
        check_hamlet_user_result(result)
 | 
					        check_hamlet_user_query_result(result)
 | 
				
			||||||
        check_zulip_realm_result(result)
 | 
					        check_zulip_realm_query_result(result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        result = self.client_get("/activity/support", {"q": "lear"})
 | 
					        result = self.client_get("/activity/support", {"q": "lear"})
 | 
				
			||||||
        check_lear_realm_result(result)
 | 
					        check_lear_realm_query_result(result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        result = self.client_get("/activity/support", {"q": "http://lear.testserver"})
 | 
					        result = self.client_get("/activity/support", {"q": "http://lear.testserver"})
 | 
				
			||||||
        check_lear_realm_result(result)
 | 
					        check_lear_realm_query_result(result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        with self.settings(REALM_HOSTS={'zulip': 'localhost'}):
 | 
					        with self.settings(REALM_HOSTS={'zulip': 'localhost'}):
 | 
				
			||||||
            result = self.client_get("/activity/support", {"q": "http://localhost"})
 | 
					            result = self.client_get("/activity/support", {"q": "http://localhost"})
 | 
				
			||||||
            check_zulip_realm_result(result)
 | 
					            check_zulip_realm_query_result(result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        result = self.client_get("/activity/support", {"q": "hamlet@zulip.com, lear"})
 | 
					        result = self.client_get("/activity/support", {"q": "hamlet@zulip.com, lear"})
 | 
				
			||||||
        check_hamlet_user_result(result)
 | 
					        check_hamlet_user_query_result(result)
 | 
				
			||||||
        check_zulip_realm_result(result)
 | 
					        check_zulip_realm_query_result(result)
 | 
				
			||||||
        check_lear_realm_result(result)
 | 
					        check_lear_realm_query_result(result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        result = self.client_get("/activity/support", {"q": "lear, Hamlet <hamlet@zulip.com>"})
 | 
					        result = self.client_get("/activity/support", {"q": "lear, Hamlet <hamlet@zulip.com>"})
 | 
				
			||||||
        check_hamlet_user_result(result)
 | 
					        check_hamlet_user_query_result(result)
 | 
				
			||||||
        check_zulip_realm_result(result)
 | 
					        check_zulip_realm_query_result(result)
 | 
				
			||||||
        check_lear_realm_result(result)
 | 
					        check_lear_realm_query_result(result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_change_plan_type(self) -> None:
 | 
					    def test_change_plan_type(self) -> None:
 | 
				
			||||||
        cordelia_email = self.example_email("cordelia")
 | 
					        cordelia_email = self.example_email("cordelia")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1077,7 +1077,8 @@ def support(request: HttpRequest) -> HttpResponse:
 | 
				
			|||||||
        if users:
 | 
					        if users:
 | 
				
			||||||
            for user in users:
 | 
					            for user in users:
 | 
				
			||||||
                user.realm.realm_icon_url = realm_icon_url(user.realm)
 | 
					                user.realm.realm_icon_url = realm_icon_url(user.realm)
 | 
				
			||||||
                user.realm.admins = UserProfile.objects.filter(realm=user.realm, is_realm_admin=True)
 | 
					                user.realm.admin_emails = ", ".join(user.realm.get_admin_users().values_list("email",
 | 
				
			||||||
 | 
					                                                                                             flat=True))
 | 
				
			||||||
                user.realm.default_discount = get_discount_for_realm(user.realm)
 | 
					                user.realm.default_discount = get_discount_for_realm(user.realm)
 | 
				
			||||||
            context["users"] = users
 | 
					            context["users"] = users
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1101,7 +1102,7 @@ def support(request: HttpRequest) -> HttpResponse:
 | 
				
			|||||||
        if realms:
 | 
					        if realms:
 | 
				
			||||||
            for realm in realms:
 | 
					            for realm in realms:
 | 
				
			||||||
                realm.realm_icon_url = realm_icon_url(realm)
 | 
					                realm.realm_icon_url = realm_icon_url(realm)
 | 
				
			||||||
                realm.admins = UserProfile.objects.filter(realm=realm, is_realm_admin=True)
 | 
					                realm.admin_emails = ", ".join(realm.get_admin_users().values_list("email", flat=True))
 | 
				
			||||||
                realm.default_discount = get_discount_for_realm(realm)
 | 
					                realm.default_discount = get_discount_for_realm(realm)
 | 
				
			||||||
            context["realms"] = realms
 | 
					            context["realms"] = realms
 | 
				
			||||||
    return render(request, 'analytics/support.html', context=context)
 | 
					    return render(request, 'analytics/support.html', context=context)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,19 @@
 | 
				
			|||||||
 | 
					const noop = () => {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set_global('$', global.make_zjquery());
 | 
					set_global('$', global.make_zjquery());
 | 
				
			||||||
 | 
					const input = $.create('input');
 | 
				
			||||||
 | 
					set_global('document', {
 | 
				
			||||||
 | 
					    createElement: () => input,
 | 
				
			||||||
 | 
					    execCommand: noop,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$("body").append = noop;
 | 
				
			||||||
 | 
					$(input).val = (arg) => {
 | 
				
			||||||
 | 
					    assert.equal(arg, "iago@zulip.com");
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					        select: noop,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
zrequire('common');
 | 
					zrequire('common');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -16,3 +31,20 @@ run_test('phrase_match', () => {
 | 
				
			|||||||
    assert(!common.phrase_match('tests', 'test'));
 | 
					    assert(!common.phrase_match('tests', 'test'));
 | 
				
			||||||
    assert(!common.phrase_match('tes', 'hostess'));
 | 
					    assert(!common.phrase_match('tes', 'hostess'));
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					run_test('copy_data_attribute_value', () => {
 | 
				
			||||||
 | 
					    var elem = $.create('.envelope-link');
 | 
				
			||||||
 | 
					    elem.data = (key) => {
 | 
				
			||||||
 | 
					        if (key === "admin-emails") {
 | 
				
			||||||
 | 
					            return "iago@zulip.com";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return "";
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    elem.fadeOut = (val) => {
 | 
				
			||||||
 | 
					        assert.equal(val, 250);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    elem.fadeIn = (val) => {
 | 
				
			||||||
 | 
					        assert.equal(val, 1000);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    common.copy_data_attribute_value(elem, 'admin-emails');
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,4 +7,8 @@ $(function () {
 | 
				
			|||||||
            this.form.submit();
 | 
					            this.form.submit();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $('a.copy-button').click(function () {
 | 
				
			||||||
 | 
					        common.copy_data_attribute_value($(this), "admin-emails");
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -88,6 +88,18 @@ exports.phrase_match = function (query, phrase) {
 | 
				
			|||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					exports.copy_data_attribute_value = function (elem, key) {
 | 
				
			||||||
 | 
					    // function to copy the value of data-key
 | 
				
			||||||
 | 
					    // attribute of the element to clipboard
 | 
				
			||||||
 | 
					    var temp = $(document.createElement('input'));
 | 
				
			||||||
 | 
					    $("body").append(temp);
 | 
				
			||||||
 | 
					    temp.val(elem.data(key)).select();
 | 
				
			||||||
 | 
					    document.execCommand("copy");
 | 
				
			||||||
 | 
					    temp.remove();
 | 
				
			||||||
 | 
					    elem.fadeOut(250);
 | 
				
			||||||
 | 
					    elem.fadeIn(1000);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
return exports;
 | 
					return exports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}());
 | 
					}());
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,7 +46,10 @@
 | 
				
			|||||||
                <h3><img src="{{ user.realm.realm_icon_url }}" class="support-realm-icon"> {{ user.realm.name }}</h3>
 | 
					                <h3><img src="{{ user.realm.realm_icon_url }}" class="support-realm-icon"> {{ user.realm.name }}</h3>
 | 
				
			||||||
                <b>URL</b>: <a target="_blank" href="{{ user.realm.uri }}">{{ user.realm.uri }}</a><br>
 | 
					                <b>URL</b>: <a target="_blank" href="{{ user.realm.uri }}">{{ user.realm.uri }}</a><br>
 | 
				
			||||||
                <b>Date created</b>: {{ user.realm.date_created|timesince }} ago<br>
 | 
					                <b>Date created</b>: {{ user.realm.date_created|timesince }} ago<br>
 | 
				
			||||||
                <b>Admins</b>: {% for admin in user.realm.admins %}{{ admin.email }} {% endfor %}<br>
 | 
					                <b>Admins</b>: {{ user.realm.admin_emails }}
 | 
				
			||||||
 | 
					                <a title="Copy emails" class="copy-button" data-admin-emails="{{ user.realm.admin_emails }}">
 | 
				
			||||||
 | 
					                    <i class="fa fa-copy"></i>
 | 
				
			||||||
 | 
					                </a>
 | 
				
			||||||
                <form method="POST">
 | 
					                <form method="POST">
 | 
				
			||||||
                    <b>Status</b>:<br>
 | 
					                    <b>Status</b>:<br>
 | 
				
			||||||
                    {{ csrf_input }}
 | 
					                    {{ csrf_input }}
 | 
				
			||||||
@@ -93,7 +96,10 @@
 | 
				
			|||||||
            <h3><img src="{{ realm.realm_icon_url }}" class="support-realm-icon"> {{ realm.name }}</h3>
 | 
					            <h3><img src="{{ realm.realm_icon_url }}" class="support-realm-icon"> {{ realm.name }}</h3>
 | 
				
			||||||
            <b>URL</b>: <a target="_blank" href="{{ realm.uri }}">{{ realm.uri }}</a><br>
 | 
					            <b>URL</b>: <a target="_blank" href="{{ realm.uri }}">{{ realm.uri }}</a><br>
 | 
				
			||||||
            <b>Date created</b>: {{ realm.date_created|timesince }} ago<br>
 | 
					            <b>Date created</b>: {{ realm.date_created|timesince }} ago<br>
 | 
				
			||||||
            <b>Admins</b>: {% for admin in realm.admins %}{{ admin.email }} {% endfor %}<br>
 | 
					            <b>Admins</b>: {{ realm.admin_emails }}
 | 
				
			||||||
 | 
					            <a title="Copy emails" class="copy-button" data-admin-emails="{{ realm.admin_emails }}">
 | 
				
			||||||
 | 
					                <i class="fa fa-copy"></i>
 | 
				
			||||||
 | 
					            </a>
 | 
				
			||||||
            <form method="POST">
 | 
					            <form method="POST">
 | 
				
			||||||
                <b>Status</b>:<br>
 | 
					                <b>Status</b>:<br>
 | 
				
			||||||
                {{ csrf_input }}
 | 
					                {{ csrf_input }}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -603,13 +603,14 @@ def build_custom_checkers(by_lang):
 | 
				
			|||||||
        {'pattern': "title='[^{]",
 | 
					        {'pattern': "title='[^{]",
 | 
				
			||||||
         'description': "`title` value should be translatable.",
 | 
					         'description': "`title` value should be translatable.",
 | 
				
			||||||
         'good_lines': ['<link rel="author" title="{{ _(\'About these documents\') }}" />'],
 | 
					         'good_lines': ['<link rel="author" title="{{ _(\'About these documents\') }}" />'],
 | 
				
			||||||
         'bad_lines': ["<p title='foo'></p>"]},
 | 
					         'bad_lines': ["<p title='foo'></p>"],
 | 
				
			||||||
 | 
					         },
 | 
				
			||||||
        {'pattern': r'title="[^{\:]',
 | 
					        {'pattern': r'title="[^{\:]',
 | 
				
			||||||
         'exclude_line': set([
 | 
					         'exclude_line': set([
 | 
				
			||||||
             ('templates/zerver/app/markdown_help.html',
 | 
					             ('templates/zerver/app/markdown_help.html',
 | 
				
			||||||
              '<td class="rendered_markdown"><img alt=":heart:" class="emoji" src="/static/generated/emoji/images/emoji/heart.png" title=":heart:" /></td>')
 | 
					              '<td class="rendered_markdown"><img alt=":heart:" class="emoji" src="/static/generated/emoji/images/emoji/heart.png" title=":heart:" /></td>')
 | 
				
			||||||
         ]),
 | 
					         ]),
 | 
				
			||||||
         'exclude': set(["templates/zerver/emails"]),
 | 
					         'exclude': set(["templates/zerver/emails", "templates/analytics/support.html"]),
 | 
				
			||||||
         'description': "`title` value should be translatable."},
 | 
					         'description': "`title` value should be translatable."},
 | 
				
			||||||
        {'pattern': r'''\Walt=["'][^{"']''',
 | 
					        {'pattern': r'''\Walt=["'][^{"']''',
 | 
				
			||||||
         'description': "alt argument should be enclosed by _() or it should be an empty string.",
 | 
					         'description': "alt argument should be enclosed by _() or it should be an empty string.",
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user