mirror of
https://github.com/zulip/zulip.git
synced 2026-06-24 21:08:25 +08:00
The Event.which and Event.keyCode are deprecated as pointed out by TypeScript intellisense based on the jQuery types. We use Event.key instead which behaves similarly to Event.which & Event.keyCode for our use case. The only difference in functionality by this change is that the vim keys won't work when Caps Lock is on. This is because, in this case, the key property will be "J" instead of 'j'. We can fix this by adding a mapping for this, however, I think we don't want to handle this case so I left this change out. Tested by trying out the everywhere keydown_util is used. Finally, we also turn off the new-cap rule for tests since I think it fine to only enforce it on real code and exempting test code is fine.
648 lines
18 KiB
JavaScript
648 lines
18 KiB
JavaScript
"use strict";
|
|
|
|
const {strict: assert} = require("assert");
|
|
|
|
const {mock_cjs, mock_esm, set_global, with_field, zrequire} = require("../zjsunit/namespace");
|
|
const {run_test} = require("../zjsunit/test");
|
|
const blueslip = require("../zjsunit/zblueslip");
|
|
const $ = require("../zjsunit/zjquery");
|
|
const {page_params} = require("../zjsunit/zpage_params");
|
|
|
|
mock_cjs("jquery", $);
|
|
const window_stub = $.create("window-stub");
|
|
set_global("to_$", () => window_stub);
|
|
$(window).idle = () => {};
|
|
|
|
const _document = {
|
|
hasFocus() {
|
|
return true;
|
|
},
|
|
};
|
|
|
|
const channel = mock_esm("../../static/js/channel");
|
|
const compose_state = mock_esm("../../static/js/compose_state");
|
|
const padded_widget = mock_esm("../../static/js/padded_widget");
|
|
const pm_list = mock_esm("../../static/js/pm_list");
|
|
const popovers = mock_esm("../../static/js/popovers");
|
|
const resize = mock_esm("../../static/js/resize");
|
|
const scroll_util = mock_esm("../../static/js/scroll_util");
|
|
const watchdog = mock_esm("../../static/js/watchdog");
|
|
|
|
set_global("document", _document);
|
|
|
|
const huddle_data = zrequire("huddle_data");
|
|
const compose_fade = zrequire("compose_fade");
|
|
const keydown_util = zrequire("keydown_util");
|
|
const muting = zrequire("muting");
|
|
const narrow = zrequire("narrow");
|
|
const presence = zrequire("presence");
|
|
const people = zrequire("people");
|
|
const buddy_data = zrequire("buddy_data");
|
|
const {buddy_list} = zrequire("buddy_list");
|
|
const user_status = zrequire("user_status");
|
|
const activity = zrequire("activity");
|
|
|
|
const me = {
|
|
email: "[email protected]",
|
|
user_id: 999,
|
|
full_name: "Me Myself",
|
|
};
|
|
|
|
const alice = {
|
|
email: "[email protected]",
|
|
user_id: 1,
|
|
full_name: "Alice Smith",
|
|
};
|
|
const fred = {
|
|
email: "[email protected]",
|
|
user_id: 2,
|
|
full_name: "Fred Flintstone",
|
|
};
|
|
const jill = {
|
|
email: "[email protected]",
|
|
user_id: 3,
|
|
full_name: "Jill Hill",
|
|
};
|
|
const mark = {
|
|
email: "[email protected]",
|
|
user_id: 4,
|
|
full_name: "Marky Mark",
|
|
};
|
|
const norbert = {
|
|
email: "[email protected]",
|
|
user_id: 5,
|
|
full_name: "Norbert Oswald",
|
|
};
|
|
|
|
const zoe = {
|
|
email: "[email protected]",
|
|
user_id: 6,
|
|
full_name: "Zoe Yang",
|
|
};
|
|
|
|
people.add_active_user(alice);
|
|
people.add_active_user(fred);
|
|
people.add_active_user(jill);
|
|
people.add_active_user(mark);
|
|
people.add_active_user(norbert);
|
|
people.add_active_user(zoe);
|
|
people.add_active_user(me);
|
|
people.initialize_current_user(me.user_id);
|
|
|
|
function clear_buddy_list() {
|
|
buddy_list.populate({
|
|
keys: [],
|
|
});
|
|
}
|
|
|
|
let presence_info;
|
|
|
|
function test(label, f) {
|
|
run_test(label, (override) => {
|
|
// Simulate a small window by having the
|
|
// fill_screen_with_content render the entire
|
|
// list in one pass. We will do more refined
|
|
// testing in the buddy_list node tests.
|
|
override(buddy_list, "fill_screen_with_content", () => {
|
|
buddy_list.render_more({
|
|
chunk_size: 100,
|
|
});
|
|
});
|
|
|
|
presence_info = new Map();
|
|
presence.__Rewire__("presence_info", presence_info);
|
|
|
|
presence_info.set(alice.user_id, {status: "active"});
|
|
presence_info.set(fred.user_id, {status: "active"});
|
|
presence_info.set(jill.user_id, {status: "active"});
|
|
presence_info.set(mark.user_id, {status: "idle"});
|
|
presence_info.set(norbert.user_id, {status: "active"});
|
|
presence_info.set(zoe.user_id, {status: "active"});
|
|
presence_info.set(me.user_id, {status: "active"});
|
|
|
|
clear_buddy_list();
|
|
muting.set_muted_users([]);
|
|
|
|
activity.clear_for_testing();
|
|
activity.set_cursor_and_filter();
|
|
|
|
f(override);
|
|
});
|
|
}
|
|
|
|
run_test("reload_defaults", () => {
|
|
activity.clear_for_testing();
|
|
blueslip.expect("warn", "get_filter_text() is called before initialization");
|
|
assert.equal(activity.get_filter_text(), "");
|
|
});
|
|
|
|
test("get_status", () => {
|
|
page_params.realm_users = [];
|
|
page_params.user_id = 999;
|
|
|
|
assert.equal(presence.get_status(page_params.user_id), "active");
|
|
assert.equal(presence.get_status(alice.user_id), "active");
|
|
assert.equal(presence.get_status(mark.user_id), "idle");
|
|
assert.equal(presence.get_status(fred.user_id), "active");
|
|
|
|
presence_info.delete(zoe.user_id);
|
|
assert.equal(presence.get_status(zoe.user_id), "offline");
|
|
|
|
presence_info.set(alice.user_id, {status: "whatever"});
|
|
assert.equal(presence.get_status(alice.user_id), "whatever");
|
|
});
|
|
|
|
test("sort_users", () => {
|
|
const user_ids = [alice.user_id, fred.user_id, jill.user_id];
|
|
|
|
presence_info.delete(alice.user_id);
|
|
|
|
buddy_data.sort_users(user_ids);
|
|
|
|
assert.deepEqual(user_ids, [fred.user_id, jill.user_id, alice.user_id]);
|
|
});
|
|
|
|
test("huddle_data.process_loaded_messages", () => {
|
|
// TODO: move this to a module for just testing `huddle_data`
|
|
|
|
const huddle1 = "[email protected],[email protected]";
|
|
const timestamp1 = 1382479029; // older
|
|
|
|
const huddle2 = "[email protected],[email protected]";
|
|
const timestamp2 = 1382479033; // newer
|
|
|
|
const old_timestamp = 1382479000;
|
|
|
|
const messages = [
|
|
{
|
|
type: "private",
|
|
display_recipient: [{id: jill.user_id}, {id: norbert.user_id}],
|
|
timestamp: timestamp1,
|
|
},
|
|
{
|
|
type: "stream",
|
|
},
|
|
{
|
|
type: "private",
|
|
display_recipient: [{id: me.user_id}], // PM to myself
|
|
},
|
|
{
|
|
type: "private",
|
|
display_recipient: [{id: alice.user_id}, {id: fred.user_id}],
|
|
timestamp: timestamp2,
|
|
},
|
|
{
|
|
type: "private",
|
|
display_recipient: [{id: fred.user_id}, {id: alice.user_id}],
|
|
timestamp: old_timestamp,
|
|
},
|
|
];
|
|
|
|
huddle_data.process_loaded_messages(messages);
|
|
|
|
const user_ids_string1 = people.emails_strings_to_user_ids_string(huddle1);
|
|
const user_ids_string2 = people.emails_strings_to_user_ids_string(huddle2);
|
|
assert.deepEqual(huddle_data.get_huddles(), [user_ids_string2, user_ids_string1]);
|
|
});
|
|
|
|
test("presence_list_full_update", (override) => {
|
|
override(padded_widget, "update_padding", () => {});
|
|
|
|
$(".user-list-filter").trigger("focus");
|
|
compose_state.private_message_recipient = () => fred.email;
|
|
compose_fade.set_focused_recipient("private");
|
|
|
|
const user_ids = activity.build_user_sidebar();
|
|
|
|
assert.deepEqual(user_ids, [
|
|
me.user_id,
|
|
alice.user_id,
|
|
fred.user_id,
|
|
jill.user_id,
|
|
norbert.user_id,
|
|
zoe.user_id,
|
|
mark.user_id,
|
|
]);
|
|
});
|
|
|
|
function simulate_right_column_buddy_list() {
|
|
$(".user-list-filter").closest = (selector) => {
|
|
assert.equal(selector, ".app-main [class^='column-']");
|
|
return $.create("right-sidebar").addClass("column-right");
|
|
};
|
|
}
|
|
|
|
function buddy_list_add(user_id, stub) {
|
|
if (stub.attr) {
|
|
stub.attr("data-user-id", user_id);
|
|
}
|
|
stub.length = 1;
|
|
const sel = `li.user_sidebar_entry[data-user-id='${CSS.escape(user_id)}']`;
|
|
$("#user_presences").set_find_results(sel, stub);
|
|
}
|
|
|
|
test("PM_update_dom_counts", () => {
|
|
const count = $.create("alice-unread-count");
|
|
const pm_key = alice.user_id.toString();
|
|
const li = $.create("alice stub");
|
|
buddy_list_add(pm_key, li);
|
|
li.set_find_results(".unread_count", count);
|
|
count.set_parents_result("li", li);
|
|
|
|
const counts = new Map();
|
|
counts.set(pm_key, 5);
|
|
li.addClass("user_sidebar_entry");
|
|
|
|
activity.update_dom_with_unread_counts({pm_count: counts});
|
|
assert.equal(count.text(), "5");
|
|
|
|
counts.set(pm_key, 0);
|
|
|
|
activity.update_dom_with_unread_counts({pm_count: counts});
|
|
assert.equal(count.text(), "");
|
|
});
|
|
|
|
test("handlers", (override) => {
|
|
let filter_key_handlers;
|
|
|
|
override(keydown_util, "handle", (opts) => {
|
|
filter_key_handlers = opts.handlers;
|
|
});
|
|
override(scroll_util, "scroll_element_into_container", () => {});
|
|
override(padded_widget, "update_padding", () => {});
|
|
override(popovers, "hide_all", () => {});
|
|
override(popovers, "hide_all_except_sidebars", () => {});
|
|
override(popovers, "show_userlist_sidebar", () => {});
|
|
override(resize, "resize_sidebars", () => {});
|
|
|
|
// This is kind of weak coverage; we are mostly making sure that
|
|
// keys and clicks got mapped to functions that don't crash.
|
|
let me_li;
|
|
let alice_li;
|
|
let fred_li;
|
|
|
|
let narrowed;
|
|
|
|
override(narrow, "by", (method, email) => {
|
|
assert.equal(email, "[email protected]");
|
|
narrowed = true;
|
|
});
|
|
|
|
function init() {
|
|
$.clear_all_elements();
|
|
buddy_list.populate({
|
|
keys: [me.user_id, alice.user_id, fred.user_id],
|
|
});
|
|
activity.set_cursor_and_filter();
|
|
|
|
me_li = $.create("me stub");
|
|
alice_li = $.create("alice stub");
|
|
fred_li = $.create("fred stub");
|
|
|
|
buddy_list_add(me.user_id, me_li);
|
|
buddy_list_add(alice.user_id, alice_li);
|
|
buddy_list_add(fred.user_id, fred_li);
|
|
}
|
|
|
|
(function test_filter_keys() {
|
|
init();
|
|
activity.user_cursor.go_to(alice.user_id);
|
|
filter_key_handlers.ArrowDown();
|
|
filter_key_handlers.ArrowUp();
|
|
})();
|
|
|
|
(function test_click_filter() {
|
|
init();
|
|
const e = {
|
|
stopPropagation: () => {},
|
|
};
|
|
|
|
const handler = $(".user-list-filter").get_on_handler("focus");
|
|
handler(e);
|
|
})();
|
|
|
|
(function test_click_header_filter() {
|
|
init();
|
|
const e = {};
|
|
const handler = $("#userlist-header").get_on_handler("click");
|
|
|
|
simulate_right_column_buddy_list();
|
|
|
|
handler(e);
|
|
// and click again
|
|
handler(e);
|
|
})();
|
|
|
|
(function test_enter_key() {
|
|
init();
|
|
|
|
$(".user-list-filter").val("al");
|
|
narrowed = false;
|
|
activity.user_cursor.go_to(alice.user_id);
|
|
filter_key_handlers.Enter();
|
|
assert(narrowed);
|
|
|
|
// get line coverage for cleared case
|
|
activity.user_cursor.clear();
|
|
filter_key_handlers.Enter();
|
|
})();
|
|
|
|
(function test_click_handler() {
|
|
init();
|
|
// We wire up the click handler in click_handlers.js,
|
|
// so this just tests the called function.
|
|
narrowed = false;
|
|
activity.narrow_for_user({li: alice_li});
|
|
assert(narrowed);
|
|
})();
|
|
|
|
(function test_blur_filter() {
|
|
init();
|
|
const e = {};
|
|
const handler = $(".user-list-filter").get_on_handler("blur");
|
|
handler(e);
|
|
})();
|
|
});
|
|
|
|
test("first/prev/next", (override) => {
|
|
override(padded_widget, "update_padding", () => {});
|
|
|
|
assert.equal(buddy_list.first_key(), undefined);
|
|
assert.equal(buddy_list.prev_key(alice.user_id), undefined);
|
|
assert.equal(buddy_list.next_key(alice.user_id), undefined);
|
|
|
|
override(buddy_list.container, "append", () => {});
|
|
|
|
activity.redraw_user(alice.user_id);
|
|
activity.redraw_user(fred.user_id);
|
|
|
|
assert.equal(buddy_list.first_key(), alice.user_id);
|
|
assert.equal(buddy_list.prev_key(alice.user_id), undefined);
|
|
assert.equal(buddy_list.prev_key(fred.user_id), alice.user_id);
|
|
|
|
assert.equal(buddy_list.next_key(alice.user_id), fred.user_id);
|
|
assert.equal(buddy_list.next_key(fred.user_id), undefined);
|
|
});
|
|
|
|
test("insert_one_user_into_empty_list", (override) => {
|
|
override(padded_widget, "update_padding", () => {});
|
|
|
|
let appended_html;
|
|
override(buddy_list.container, "append", (html) => {
|
|
appended_html = html;
|
|
});
|
|
|
|
activity.redraw_user(alice.user_id);
|
|
assert(appended_html.indexOf('data-user-id="1"') > 0);
|
|
assert(appended_html.indexOf("user_circle_green") > 0);
|
|
});
|
|
|
|
test("insert_alice_then_fred", (override) => {
|
|
let appended_html;
|
|
override(buddy_list.container, "append", (html) => {
|
|
appended_html = html;
|
|
});
|
|
override(padded_widget, "update_padding", () => {});
|
|
|
|
activity.redraw_user(alice.user_id);
|
|
assert(appended_html.indexOf('data-user-id="1"') > 0);
|
|
assert(appended_html.indexOf("user_circle_green") > 0);
|
|
|
|
activity.redraw_user(fred.user_id);
|
|
assert(appended_html.indexOf('data-user-id="2"') > 0);
|
|
assert(appended_html.indexOf("user_circle_green") > 0);
|
|
});
|
|
|
|
test("insert_fred_then_alice_then_rename", (override) => {
|
|
let appended_html;
|
|
override(buddy_list.container, "append", (html) => {
|
|
appended_html = html;
|
|
});
|
|
override(padded_widget, "update_padding", () => {});
|
|
|
|
activity.redraw_user(fred.user_id);
|
|
assert(appended_html.indexOf('data-user-id="2"') > 0);
|
|
assert(appended_html.indexOf("user_circle_green") > 0);
|
|
|
|
const fred_stub = $.create("fred-first");
|
|
buddy_list_add(fred.user_id, fred_stub);
|
|
|
|
let inserted_html;
|
|
fred_stub.before = (html) => {
|
|
inserted_html = html;
|
|
};
|
|
|
|
let fred_removed;
|
|
fred_stub.remove = () => {
|
|
fred_removed = true;
|
|
};
|
|
|
|
activity.redraw_user(alice.user_id);
|
|
assert(inserted_html.indexOf('data-user-id="1"') > 0);
|
|
assert(inserted_html.indexOf("user_circle_green") > 0);
|
|
|
|
// Next rename fred to Aaron.
|
|
const fred_with_new_name = {
|
|
email: fred.email,
|
|
user_id: fred.user_id,
|
|
full_name: "Aaron",
|
|
};
|
|
people.add_active_user(fred_with_new_name);
|
|
|
|
const alice_stub = $.create("alice-first");
|
|
buddy_list_add(alice.user_id, alice_stub);
|
|
|
|
alice_stub.before = (html) => {
|
|
inserted_html = html;
|
|
};
|
|
|
|
activity.redraw_user(fred_with_new_name.user_id);
|
|
assert(fred_removed);
|
|
assert(appended_html.indexOf('data-user-id="2"') > 0);
|
|
|
|
// restore old Fred data
|
|
people.add_active_user(fred);
|
|
});
|
|
|
|
test("insert_unfiltered_user_with_filter", () => {
|
|
// This test only tests that we do not explode when
|
|
// try to insert Fred into a list where he does not
|
|
// match the search filter.
|
|
const user_filter = $(".user-list-filter");
|
|
user_filter.val("do-not-match-filter");
|
|
activity.redraw_user(fred.user_id);
|
|
});
|
|
|
|
test("realm_presence_disabled", () => {
|
|
page_params.realm_presence_disabled = true;
|
|
|
|
activity.redraw_user();
|
|
activity.build_user_sidebar();
|
|
});
|
|
|
|
test("redraw_muted_user", () => {
|
|
muting.add_muted_user(mark.user_id);
|
|
let appended_html;
|
|
$("#user_presences").append = function (html) {
|
|
appended_html = html;
|
|
};
|
|
|
|
activity.redraw_user(mark.user_id);
|
|
assert(appended_html === undefined);
|
|
});
|
|
|
|
test("update_presence_info", (override) => {
|
|
override(pm_list, "update_private_messages", () => {});
|
|
|
|
page_params.realm_presence_disabled = false;
|
|
|
|
const server_time = 500;
|
|
const info = {
|
|
website: {
|
|
status: "active",
|
|
timestamp: server_time,
|
|
},
|
|
};
|
|
|
|
override(buddy_data, "matches_filter", () => true);
|
|
|
|
const alice_li = $.create("alice stub");
|
|
buddy_list_add(alice.user_id, alice_li);
|
|
|
|
let inserted;
|
|
override(buddy_list, "insert_or_move", () => {
|
|
inserted = true;
|
|
});
|
|
|
|
presence.presence_info.delete(me.user_id);
|
|
activity.update_presence_info(me.user_id, info, server_time);
|
|
assert(inserted);
|
|
assert.deepEqual(presence.presence_info.get(me.user_id).status, "active");
|
|
|
|
presence.presence_info.delete(alice.user_id);
|
|
activity.update_presence_info(alice.user_id, info, server_time);
|
|
assert(inserted);
|
|
|
|
const expected = {status: "active", last_active: 500};
|
|
assert.deepEqual(presence.presence_info.get(alice.user_id), expected);
|
|
});
|
|
|
|
test("initialize", (override) => {
|
|
override(padded_widget, "update_padding", () => {});
|
|
override(pm_list, "update_private_messages", () => {});
|
|
override(watchdog, "check_for_unsuspend", () => {});
|
|
|
|
let payload;
|
|
override(channel, "post", (arg) => {
|
|
payload = arg;
|
|
});
|
|
|
|
function clear() {
|
|
$.clear_all_elements();
|
|
buddy_list.container = $("#user_presences");
|
|
buddy_list.container.append = () => {};
|
|
clear_buddy_list();
|
|
page_params.presences = {};
|
|
}
|
|
|
|
clear();
|
|
|
|
let scroll_handler_started;
|
|
buddy_list.start_scroll_handler = () => {
|
|
scroll_handler_started = true;
|
|
};
|
|
|
|
activity.mark_client_idle();
|
|
|
|
$(window).off("focus");
|
|
activity.initialize();
|
|
payload.success({
|
|
zephyr_mirror_active: true,
|
|
presences: {},
|
|
});
|
|
$(window).trigger("focus");
|
|
clear();
|
|
|
|
assert(scroll_handler_started);
|
|
assert(!activity.new_user_input);
|
|
assert(!$("#zephyr-mirror-error").hasClass("show"));
|
|
assert.equal(activity.compute_active_status(), "active");
|
|
|
|
$(window).idle = (params) => {
|
|
params.onIdle();
|
|
};
|
|
|
|
set_global("setInterval", (func) => func());
|
|
|
|
$(window).off("focus");
|
|
activity.initialize();
|
|
payload.success({
|
|
zephyr_mirror_active: false,
|
|
presences: {},
|
|
});
|
|
|
|
assert($("#zephyr-mirror-error").hasClass("show"));
|
|
assert(!activity.new_user_input);
|
|
assert.equal(activity.compute_active_status(), "idle");
|
|
|
|
// Exercise the mousemove handler, which just
|
|
// sets a flag.
|
|
$("html").get_on_handler("mousemove")();
|
|
|
|
clear();
|
|
});
|
|
|
|
test("away_status", (override) => {
|
|
override(pm_list, "update_private_messages", () => {});
|
|
override(buddy_list, "insert_or_move", () => {});
|
|
|
|
assert(!user_status.is_away(alice.user_id));
|
|
activity.on_set_away(alice.user_id);
|
|
assert(user_status.is_away(alice.user_id));
|
|
activity.on_revoke_away(alice.user_id);
|
|
assert(!user_status.is_away(alice.user_id));
|
|
});
|
|
|
|
test("electron_bridge", (override) => {
|
|
override(activity, "send_presence_to_server", () => {});
|
|
|
|
function with_bridge_idle(bridge_idle, f) {
|
|
with_field(
|
|
window,
|
|
"electron_bridge",
|
|
{
|
|
get_idle_on_system: () => bridge_idle,
|
|
},
|
|
() => {
|
|
f();
|
|
},
|
|
);
|
|
}
|
|
|
|
with_bridge_idle(true, () => {
|
|
activity.mark_client_idle();
|
|
assert.equal(activity.compute_active_status(), "idle");
|
|
activity.mark_client_active();
|
|
assert.equal(activity.compute_active_status(), "idle");
|
|
});
|
|
|
|
with_field(window, "electron_bridge", undefined, () => {
|
|
activity.mark_client_idle();
|
|
assert.equal(activity.compute_active_status(), "idle");
|
|
activity.mark_client_active();
|
|
assert.equal(activity.compute_active_status(), "active");
|
|
});
|
|
|
|
with_bridge_idle(false, () => {
|
|
activity.mark_client_idle();
|
|
assert.equal(activity.compute_active_status(), "active");
|
|
activity.mark_client_active();
|
|
assert.equal(activity.compute_active_status(), "active");
|
|
});
|
|
});
|
|
|
|
test("test_send_or_receive_no_presence_for_web_public_visitor", () => {
|
|
page_params.is_web_public_visitor = true;
|
|
activity.send_presence_to_server();
|
|
});
|