snapshot of https://github.com/zulip/zulip.git @ 48c69911c7dd4e03b20552eb3bd77ad8151c1357 (2026-09-15)
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
This commit is contained in:
435
web/tests/user_events.test.cjs
Normal file
435
web/tests/user_events.test.cjs
Normal file
@@ -0,0 +1,435 @@
|
||||
"use strict";
|
||||
|
||||
const assert = require("node:assert/strict");
|
||||
|
||||
const {make_realm} = require("./lib/example_realm.cjs");
|
||||
const {make_bot, make_user} = require("./lib/example_user.cjs");
|
||||
const {make_message_list} = require("./lib/message_list.cjs");
|
||||
const {mock_esm, zrequire} = require("./lib/namespace.cjs");
|
||||
const {run_test, noop} = require("./lib/test.cjs");
|
||||
const blueslip = require("./lib/zblueslip.cjs");
|
||||
const {$} = require("./lib/zjquery.cjs");
|
||||
|
||||
const message_live_update = mock_esm("../src/message_live_update");
|
||||
const navbar_alerts = mock_esm("../src/navbar_alerts");
|
||||
const settings_account = mock_esm("../src/settings_account", {
|
||||
maybe_update_deactivate_account_button() {},
|
||||
update_email() {},
|
||||
update_full_name() {},
|
||||
update_account_settings_display() {},
|
||||
update_role_text() {},
|
||||
set_user_own_role_dropdown_value() {},
|
||||
add_or_remove_owner_from_role_dropdown() {},
|
||||
update_user_own_role_dropdown_state() {},
|
||||
});
|
||||
const settings_preferences = mock_esm("../src/settings_preferences", {
|
||||
update_user_list_style_preview_name() {},
|
||||
update_user_list_style_preview_avatar() {},
|
||||
});
|
||||
const settings_bots = mock_esm("../src/settings_bots", {
|
||||
redraw_your_bots_list() {},
|
||||
toggle_bot_config_download_container() {},
|
||||
});
|
||||
mock_esm("../src/settings_panel_menu", {
|
||||
hide_default_streams_list_for_guest() {},
|
||||
update_imported_users_tab() {},
|
||||
});
|
||||
mock_esm("../src/settings_users", {
|
||||
update_user_data() {},
|
||||
update_view_on_deactivate() {},
|
||||
update_view_on_reactivate() {},
|
||||
});
|
||||
mock_esm("../src/user_profile", {
|
||||
update_profile_modal_ui() {},
|
||||
update_user_custom_profile_fields() {},
|
||||
});
|
||||
|
||||
const buddy_list = mock_esm("../src/buddy_list", {
|
||||
BuddyList: class {
|
||||
insert_or_move = noop;
|
||||
},
|
||||
});
|
||||
|
||||
const compose_pm_pill = mock_esm("../src/compose_pm_pill", {
|
||||
update_user_pill_active_status() {},
|
||||
});
|
||||
mock_esm("../src/compose_recipient", {
|
||||
update_user_name_in_compose() {},
|
||||
});
|
||||
const pm_list = mock_esm("../src/pm_list", {
|
||||
update_private_messages() {},
|
||||
});
|
||||
|
||||
const buddy_data = new buddy_list.BuddyList();
|
||||
buddy_list.buddy_list = buddy_data;
|
||||
|
||||
mock_esm("../src/activity_ui", {
|
||||
redraw() {},
|
||||
});
|
||||
mock_esm("../src/settings", {
|
||||
update_lock_icon_in_sidebar() {},
|
||||
});
|
||||
mock_esm("../src/settings_linkifiers", {
|
||||
maybe_disable_widgets() {},
|
||||
});
|
||||
mock_esm("../src/settings_org", {
|
||||
maybe_disable_widgets() {},
|
||||
enable_or_disable_group_permission_settings() {},
|
||||
});
|
||||
mock_esm("../src/settings_profile_fields", {
|
||||
maybe_disable_widgets() {},
|
||||
});
|
||||
mock_esm("../src/settings_realm_user_settings_defaults", {
|
||||
maybe_disable_widgets() {},
|
||||
});
|
||||
mock_esm("../src/settings_streams", {
|
||||
rerender_default_streams_for_role_change() {},
|
||||
});
|
||||
|
||||
const bot_data = zrequire("bot_data");
|
||||
const message_lists = zrequire("message_lists");
|
||||
const people = zrequire("people");
|
||||
const settings_config = zrequire("settings_config");
|
||||
const {set_current_user, set_realm} = zrequire("state_data");
|
||||
const {initialize_user_settings} = zrequire("user_settings");
|
||||
const user_events = zrequire("user_events");
|
||||
|
||||
const current_user = {};
|
||||
set_current_user(current_user);
|
||||
set_realm(make_realm());
|
||||
initialize_user_settings({user_settings: {default_language: "en"}});
|
||||
|
||||
const me = make_user({
|
||||
email: "me@example.com",
|
||||
user_id: 30,
|
||||
full_name: "Me Myself",
|
||||
role: settings_config.user_role_values.member.code,
|
||||
});
|
||||
|
||||
function initialize() {
|
||||
people.init();
|
||||
people.add_active_user(me);
|
||||
people.initialize_current_user(me.user_id);
|
||||
}
|
||||
|
||||
initialize();
|
||||
|
||||
run_test("updates", ({override}) => {
|
||||
let person;
|
||||
|
||||
const isaac = make_user({
|
||||
email: "isaac@example.com",
|
||||
delivery_email: null,
|
||||
user_id: 32,
|
||||
full_name: "Isaac Newton",
|
||||
});
|
||||
people.add_active_user(isaac);
|
||||
|
||||
override(navbar_alerts, "maybe_toggle_empty_required_profile_fields_banner", noop);
|
||||
user_events.update_person({
|
||||
user_id: isaac.user_id,
|
||||
role: settings_config.user_role_values.guest.code,
|
||||
});
|
||||
person = people.get_by_email(isaac.email);
|
||||
assert.ok(person.is_guest);
|
||||
assert.equal(person.role, settings_config.user_role_values.guest.code);
|
||||
user_events.update_person({
|
||||
user_id: isaac.user_id,
|
||||
role: settings_config.user_role_values.member.code,
|
||||
});
|
||||
person = people.get_by_email(isaac.email);
|
||||
assert.ok(!person.is_guest);
|
||||
assert.equal(person.role, settings_config.user_role_values.member.code);
|
||||
|
||||
user_events.update_person({
|
||||
user_id: isaac.user_id,
|
||||
role: settings_config.user_role_values.moderator.code,
|
||||
});
|
||||
person = people.get_by_email(isaac.email);
|
||||
assert.equal(person.is_moderator, true);
|
||||
assert.equal(person.role, settings_config.user_role_values.moderator.code);
|
||||
|
||||
user_events.update_person({
|
||||
user_id: isaac.user_id,
|
||||
role: settings_config.user_role_values.admin.code,
|
||||
});
|
||||
person = people.get_by_email(isaac.email);
|
||||
assert.equal(person.full_name, "Isaac Newton");
|
||||
assert.equal(person.is_moderator, true);
|
||||
assert.equal(person.is_admin, true);
|
||||
assert.equal(person.role, settings_config.user_role_values.admin.code);
|
||||
|
||||
user_events.update_person({
|
||||
user_id: isaac.user_id,
|
||||
role: settings_config.user_role_values.owner.code,
|
||||
});
|
||||
assert.equal(person.is_admin, true);
|
||||
assert.equal(person.is_owner, true);
|
||||
assert.equal(person.role, settings_config.user_role_values.owner.code);
|
||||
|
||||
person = people.get_by_email(me.email);
|
||||
assert.equal(person.role, settings_config.user_role_values.member.code);
|
||||
|
||||
person = people.get_by_email(me.email);
|
||||
assert.equal(person.user_id, me.user_id);
|
||||
assert.equal(person.role, settings_config.user_role_values.member.code);
|
||||
|
||||
person = people.get_by_email(isaac.email);
|
||||
assert.equal(person.user_id, isaac.user_id);
|
||||
assert.equal(person.role, settings_config.user_role_values.owner.code);
|
||||
|
||||
let user_id;
|
||||
let full_name;
|
||||
message_live_update.update_user_full_name = (user_id_arg, full_name_arg) => {
|
||||
user_id = user_id_arg;
|
||||
full_name = full_name_arg;
|
||||
};
|
||||
|
||||
const $navbar_title = $("#message_view_header .message-header-navbar-title");
|
||||
|
||||
// The navbar title lists the participants of the current DM narrow,
|
||||
// so renaming one of them refreshes its text in place.
|
||||
people.add_valid_user_id(isaac.user_id);
|
||||
message_lists.set_current(make_message_list([{operator: "dm", operand: [isaac.user_id]}]));
|
||||
$navbar_title.text("Isaac Newton");
|
||||
|
||||
user_events.update_person({user_id: isaac.user_id, full_name: "Sir Isaac"});
|
||||
person = people.get_by_email(isaac.email);
|
||||
assert.equal(person.full_name, "Sir Isaac");
|
||||
assert.equal(person.is_admin, true);
|
||||
assert.equal(user_id, isaac.user_id);
|
||||
assert.equal(full_name, "Sir Isaac");
|
||||
assert.equal($navbar_title.text(), "Sir Isaac");
|
||||
|
||||
// Renaming someone the title does not mention leaves it untouched.
|
||||
user_events.update_person({user_id: me.user_id, full_name: "Me Interim"});
|
||||
assert.equal($navbar_title.text(), "Sir Isaac");
|
||||
|
||||
message_lists.set_current(undefined);
|
||||
|
||||
user_events.update_person({
|
||||
user_id: me.user_id,
|
||||
role: settings_config.user_role_values.guest.code,
|
||||
});
|
||||
assert.ok(current_user.is_guest);
|
||||
|
||||
user_events.update_person({
|
||||
user_id: me.user_id,
|
||||
role: settings_config.user_role_values.member.code,
|
||||
});
|
||||
assert.ok(!current_user.is_guest);
|
||||
assert.ok(!current_user.is_admin);
|
||||
|
||||
let user_list_style_preview_name;
|
||||
settings_preferences.update_user_list_style_preview_name = (full_name_arg) => {
|
||||
user_list_style_preview_name = full_name_arg;
|
||||
};
|
||||
|
||||
user_events.update_person({user_id: me.user_id, full_name: "Me V2"});
|
||||
assert.equal(people.my_full_name(), "Me V2");
|
||||
assert.equal(user_id, me.user_id);
|
||||
assert.equal(full_name, "Me V2");
|
||||
assert.equal(user_list_style_preview_name, "Me V2");
|
||||
|
||||
user_events.update_person({user_id: isaac.user_id, new_email: "newton@example.com"});
|
||||
person = people.get_by_user_id(isaac.user_id);
|
||||
assert.equal(person.email, "newton@example.com");
|
||||
assert.equal(person.full_name, "Sir Isaac");
|
||||
|
||||
user_events.update_person({user_id: me.user_id, new_email: "meforu@example.com"});
|
||||
person = people.get_by_user_id(me.user_id);
|
||||
assert.equal(person.email, "meforu@example.com");
|
||||
assert.equal(person.full_name, "Me V2");
|
||||
|
||||
let avatar_url;
|
||||
let inserted_or_moved_user_ids;
|
||||
message_live_update.update_avatar = (user_id_arg, avatar_url_arg) => {
|
||||
user_id = user_id_arg;
|
||||
avatar_url = avatar_url_arg;
|
||||
};
|
||||
buddy_data.insert_or_move = (user_ids_arg) => {
|
||||
inserted_or_moved_user_ids = user_ids_arg;
|
||||
};
|
||||
let user_list_style_preview_avatar_url;
|
||||
settings_preferences.update_user_list_style_preview_avatar = (avatar_url_arg) => {
|
||||
user_list_style_preview_avatar_url = avatar_url_arg;
|
||||
};
|
||||
|
||||
user_events.update_person({user_id: isaac.user_id, full_name: "Sir Isaac"});
|
||||
person = people.get_by_email(isaac.email);
|
||||
assert.equal(person.full_name, "Sir Isaac");
|
||||
assert.equal(person.is_admin, true);
|
||||
assert.equal(user_id, isaac.user_id);
|
||||
assert.equal(full_name, "Sir Isaac");
|
||||
// The user list style preview shows the current user's name, so
|
||||
// renaming someone else must not update it.
|
||||
assert.equal(user_list_style_preview_name, "Me V2");
|
||||
|
||||
person = people.get_by_email(isaac.email);
|
||||
assert.equal(person.delivery_email, null);
|
||||
user_events.update_person({
|
||||
user_id: isaac.user_id,
|
||||
delivery_email: "isaac-delivery@example.com",
|
||||
});
|
||||
person = people.get_by_email(isaac.email);
|
||||
assert.equal(person.delivery_email, "isaac-delivery@example.com");
|
||||
|
||||
user_events.update_person({user_id: isaac.user_id, delivery_email: null});
|
||||
person = people.get_by_email(isaac.email);
|
||||
assert.equal(person.delivery_email, null);
|
||||
|
||||
user_events.update_person({user_id: isaac.user_id, avatar_url: "http://gravatar.com/123456"});
|
||||
person = people.get_by_email(isaac.email);
|
||||
assert.equal(person.full_name, "Sir Isaac");
|
||||
assert.equal(user_id, isaac.user_id);
|
||||
assert.equal(person.avatar_url, avatar_url);
|
||||
assert.deepEqual(inserted_or_moved_user_ids, [isaac.user_id]);
|
||||
// The user list style preview shows the current user's avatar, so
|
||||
// another user's avatar change must not update it.
|
||||
assert.equal(user_list_style_preview_avatar_url, undefined);
|
||||
|
||||
user_events.update_person({user_id: me.user_id, avatar_url: "http://gravatar.com/789456"});
|
||||
person = people.get_by_email(me.email);
|
||||
assert.equal(person.full_name, "Me V2");
|
||||
assert.equal(user_id, me.user_id);
|
||||
assert.equal(person.avatar_url, avatar_url);
|
||||
assert.deepEqual(inserted_or_moved_user_ids, [me.user_id]);
|
||||
assert.equal(user_list_style_preview_avatar_url, "http://gravatar.com/789456");
|
||||
|
||||
user_events.update_person({user_id: me.user_id, timezone: "UTC"});
|
||||
person = people.get_by_email(me.email);
|
||||
assert.ok(person.timezone);
|
||||
|
||||
blueslip.expect("error", "Got update_person event for unexpected user");
|
||||
blueslip.expect("error", "Unknown user_id in maybe_get_user_by_id");
|
||||
assert.ok(!user_events.update_person({user_id: 29, full_name: "Sir Isaac Newton"}));
|
||||
|
||||
me.profile_data = {};
|
||||
user_events.update_person({
|
||||
user_id: me.user_id,
|
||||
custom_profile_field: {id: 3, value: "Value", rendered_value: "<p>Value</p>"},
|
||||
});
|
||||
person = people.get_by_email(me.email);
|
||||
assert.equal(person.profile_data[3].value, "Value");
|
||||
assert.equal(person.profile_data[3].rendered_value, "<p>Value</p>");
|
||||
|
||||
let updated = false;
|
||||
settings_account.update_email = (email) => {
|
||||
assert.equal(email, "you@example.org");
|
||||
updated = true;
|
||||
};
|
||||
|
||||
let confirm_banner_hidden = false;
|
||||
settings_account.hide_confirm_email_banner = () => {
|
||||
confirm_banner_hidden = true;
|
||||
};
|
||||
|
||||
user_events.update_person({user_id: me.user_id, delivery_email: "you@example.org"});
|
||||
assert.ok(updated);
|
||||
assert.ok(confirm_banner_hidden);
|
||||
|
||||
const test_bot = make_bot({
|
||||
email: "test-bot@example.com",
|
||||
user_id: 35,
|
||||
full_name: "Test Bot",
|
||||
bot_owner_id: isaac.id,
|
||||
});
|
||||
people.add_active_user(test_bot);
|
||||
bot_data.add({
|
||||
default_all_public_streams: true,
|
||||
default_events_register_stream: "register stream test",
|
||||
default_sending_stream: "sending stream test",
|
||||
user_id: 35,
|
||||
services: [],
|
||||
});
|
||||
|
||||
user_events.update_person({user_id: test_bot.user_id, bot_owner_id: me.user_id});
|
||||
person = people.get_by_email(test_bot.email);
|
||||
assert.equal(person.bot_owner_id, me.user_id);
|
||||
|
||||
buddy_list.BuddyList.insert_or_move = noop;
|
||||
|
||||
// Test that UI elements are updated when a user is deactivated/reactivated
|
||||
let pm_list_updated = false;
|
||||
let compose_pill_updated = false;
|
||||
let expected_user_id = isaac.user_id;
|
||||
let expected_is_active;
|
||||
|
||||
pm_list.update_private_messages = () => {
|
||||
pm_list_updated = true;
|
||||
};
|
||||
compose_pm_pill.update_user_pill_active_status = (user, is_active) => {
|
||||
compose_pill_updated = true;
|
||||
assert.equal(user.user_id, expected_user_id);
|
||||
assert.equal(is_active, expected_is_active);
|
||||
};
|
||||
|
||||
// Deactivate a user and verify UI updates are triggered
|
||||
expected_is_active = false;
|
||||
user_events.update_person({user_id: isaac.user_id, is_active: false});
|
||||
assert.ok(!people.is_person_active(isaac.user_id));
|
||||
assert.ok(pm_list_updated);
|
||||
assert.ok(compose_pill_updated);
|
||||
|
||||
// Reset flags and test reactivation
|
||||
pm_list_updated = false;
|
||||
compose_pill_updated = false;
|
||||
|
||||
// Reactivate the user and verify UI updates are triggered again
|
||||
expected_is_active = true;
|
||||
user_events.update_person({user_id: isaac.user_id, is_active: true});
|
||||
assert.ok(people.is_person_active(isaac.user_id));
|
||||
assert.ok(pm_list_updated);
|
||||
assert.ok(compose_pill_updated);
|
||||
|
||||
let bot_data_updated = false;
|
||||
settings_bots.update_bot_data = (user_id) => {
|
||||
assert.equal(user_id, test_bot.user_id);
|
||||
bot_data_updated = true;
|
||||
};
|
||||
|
||||
// Reset flags and test bot deactivation
|
||||
pm_list_updated = false;
|
||||
compose_pill_updated = false;
|
||||
|
||||
expected_is_active = false;
|
||||
expected_user_id = test_bot.user_id;
|
||||
user_events.update_person({user_id: test_bot.user_id, is_active: false});
|
||||
assert.equal(bot_data_updated, true);
|
||||
assert.ok(pm_list_updated);
|
||||
assert.ok(compose_pill_updated);
|
||||
|
||||
// Reset flags and test bot reactivation
|
||||
bot_data_updated = false;
|
||||
pm_list_updated = false;
|
||||
compose_pill_updated = false;
|
||||
|
||||
expected_is_active = true;
|
||||
user_events.update_person({user_id: test_bot.user_id, is_active: true});
|
||||
assert.ok(bot_data_updated);
|
||||
assert.ok(pm_list_updated);
|
||||
assert.ok(compose_pill_updated);
|
||||
|
||||
const imported_user = {
|
||||
email: "imoreted-user@example.com",
|
||||
delivery_email: null,
|
||||
user_id: 33,
|
||||
full_name: "Imported user",
|
||||
is_imported_stub: true,
|
||||
};
|
||||
people.add_active_user(imported_user);
|
||||
user_events.update_person({user_id: imported_user.user_id, is_imported_stub: false});
|
||||
|
||||
// A non-common narrow (here sender: combined with is:) shows a search
|
||||
// bar, not a name, so renaming the user must leave the title alone.
|
||||
message_lists.set_current(
|
||||
make_message_list([
|
||||
{operator: "is", operand: "starred"},
|
||||
{operator: "sender", operand: isaac.user_id},
|
||||
]),
|
||||
);
|
||||
$navbar_title.text("placeholder");
|
||||
user_events.update_person({user_id: isaac.user_id, full_name: "Sir Isaac Newton"});
|
||||
assert.equal($navbar_title.text(), "placeholder");
|
||||
message_lists.set_current(undefined);
|
||||
});
|
||||
Reference in New Issue
Block a user