Files
zulip/web/tests/typing_events.test.js
Anders Kaseorg e96ede0ef6 page_params: Split out state data for current user.
For spectators, the chunk of page_params that originates from
do_events_register isn’t assigned until ui_init.js.  That means the
TypeScript type of page_params is mostly a lie during module load
time: reading a parameter too early silently results in undefined
rather than the declared type, with unpredictable results later on.

We want to make such an early read into an immediate runtime error,
for both users and spectators consistently, and pave the way for
runtime validation of the page_params type.  As a first step, split
out the subset of fields that pertain to the current user.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-02-15 10:22:52 -08:00

104 lines
4.5 KiB
JavaScript

"use strict";
const {strict: assert} = require("assert");
const {mock_esm, zrequire} = require("./lib/namespace");
const {run_test} = require("./lib/test");
const $ = require("./lib/zjquery");
const {current_user} = require("./lib/zpage_params");
const settings_data = mock_esm("../src/settings_data");
const {Filter} = zrequire("filter");
const narrow_state = zrequire("narrow_state");
const people = zrequire("people");
const typing_data = zrequire("typing_data");
const typing_events = zrequire("typing_events");
const anna = {
email: "anna@example.com",
full_name: "Anna Karenina",
user_id: 8,
};
const vronsky = {
email: "vronsky@example.com",
full_name: "Alexei Vronsky",
user_id: 9,
};
const levin = {
email: "levin@example.com",
full_name: "Konstantin Levin",
user_id: 10,
};
const kitty = {
email: "kitty@example.com",
full_name: "Kitty S",
user_id: 11,
};
people.add_active_user(anna);
people.add_active_user(vronsky);
people.add_active_user(levin);
people.add_active_user(kitty);
run_test("render_notifications_for_narrow", ({override, mock_template}) => {
override(current_user, "user_id", anna.user_id);
override(settings_data, "user_can_access_all_other_users", () => true);
const group = [anna.user_id, vronsky.user_id, levin.user_id, kitty.user_id];
const conversation_key = typing_data.get_direct_message_conversation_key(group);
const group_emails = `${anna.email},${vronsky.email},${levin.email},${kitty.email}`;
narrow_state.set_current_filter(new Filter([{operator: "dm", operand: group_emails}]));
const $typing_notifications = $("#typing_notifications");
mock_template("typing_notifications.hbs", true, (_args, rendered_html) => rendered_html);
// Having only two(<MAX_USERS_TO_DISPLAY_NAME) typists, both of them
// should be rendered but not 'Several people are typing…'
typing_data.add_typist(conversation_key, anna.user_id);
typing_data.add_typist(conversation_key, vronsky.user_id);
typing_events.render_notifications_for_narrow();
assert.ok($typing_notifications.visible());
assert.ok($typing_notifications.html().includes(`${anna.full_name} is typing…`));
assert.ok($typing_notifications.html().includes(`${vronsky.full_name} is typing…`));
assert.ok(!$typing_notifications.html().includes("Several people are typing…"));
// Having 3(=MAX_USERS_TO_DISPLAY_NAME) typists should also display only names
typing_data.add_typist(conversation_key, levin.user_id);
typing_events.render_notifications_for_narrow();
assert.ok($typing_notifications.visible());
assert.ok($typing_notifications.html().includes(`${anna.full_name} is typing…`));
assert.ok($typing_notifications.html().includes(`${vronsky.full_name} is typing…`));
assert.ok($typing_notifications.html().includes(`${levin.full_name} is typing…`));
assert.ok(!$typing_notifications.html().includes("Several people are typing…"));
// Having 4(>MAX_USERS_TO_DISPLAY_NAME) typists should display "Several people are typing…"
typing_data.add_typist(conversation_key, kitty.user_id);
typing_events.render_notifications_for_narrow();
assert.ok($typing_notifications.visible());
assert.ok($typing_notifications.html().includes("Several people are typing…"));
assert.ok(!$typing_notifications.html().includes(`${anna.full_name} is typing…`));
assert.ok(!$typing_notifications.html().includes(`${vronsky.full_name} is typing…`));
assert.ok(!$typing_notifications.html().includes(`${levin.full_name} is typing…`));
assert.ok(!$typing_notifications.html().includes(`${kitty.full_name} is typing…`));
// #typing_notifications should be hidden when there are no typists.
typing_data.remove_typist(conversation_key, anna.user_id);
typing_data.remove_typist(conversation_key, vronsky.user_id);
typing_data.remove_typist(conversation_key, levin.user_id);
typing_data.remove_typist(conversation_key, kitty.user_id);
typing_events.render_notifications_for_narrow();
assert.ok(!$typing_notifications.visible());
// #typing_notifications should be hidden for inaccessible users.
override(settings_data, "user_can_access_all_other_users", () => false);
const inaccessible_user = people.add_inaccessible_user(20);
typing_data.add_typist(conversation_key, inaccessible_user.user_id);
typing_data.add_typist(conversation_key, 21);
typing_events.render_notifications_for_narrow();
assert.ok(!$typing_notifications.visible());
});