Files
upstream-zulip/web/tests/example8.test.cjs
upstream-mirror 64898b2c79
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
snapshot of https://github.com/zulip/zulip.git @ 48c69911c7dd4e03b20552eb3bd77ad8151c1357 (2026-09-15)
2026-09-15 15:05:30 +05:00

152 lines
6.4 KiB
JavaScript

"use strict";
const assert = require("node:assert/strict");
const {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} = require("./lib/test.cjs");
const {$} = require("./lib/zjquery.cjs");
mock_esm("../src/settings_data", {
user_can_access_all_other_users: () => true,
});
/*
Until now, we had seen various testing techniques, learned
how to use helper functions like `mock_esm`, `override` of
`run_test` etc., but we didn't see how to deal with
render calls to Handlebars templates. We'll learn that
in this test.
The below code tests the rendering of typing notifications which
is handled by the function `typing_events.render_notifications_for_narrow`.
The function relies on the `typing_notifications.hbs` template for
rendering html.
It is worthwhile to read those (they're short and simple) before proceeding
as that would help better understand the below test.
*/
const message_lists = zrequire("message_lists");
const people = zrequire("people");
const {set_current_user} = zrequire("state_data");
const typing_data = zrequire("typing_data");
const typing_events = zrequire("typing_events");
const current_user = {};
set_current_user(current_user);
// Let us add a few users to use as typists.
const anna = make_user({
email: "anna@example.com",
full_name: "Anna Karenina",
user_id: 8,
});
const vronsky = make_user({
email: "vronsky@example.com",
full_name: "Alexei Vronsky",
user_id: 9,
});
const levin = make_user({
email: "levin@example.com",
full_name: "Konstantin Levin",
user_id: 10,
});
const kitty = make_user({
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);
/*
Notice the `mock_template` in the object passed to `run_test` wrapper below.
It is pretty similar to `override` we've seen in previous examples but
mocks a template instead of a js function.
Just like `override`, `mock_template` lets us run a function taking in
the arguments passed to the template. Additionally, we can also have
the rendered html passed as an argument.
It's usage below will make it more clear to you.
*/
run_test("typing_events.render_notifications_for_narrow", ({override, mock_template}) => {
// All typists are rendered in `#typing_notifications`.
const $typing_notifications = $("#typing_notifications");
// Narrow to a group direct message with four users.
override(current_user, "user_id", anna.user_id);
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);
message_lists.set_current(make_message_list([{operator: "dm", operand: group}]));
// Based on typing_events.MAX_USERS_TO_DISPLAY_NAME (which is currently 3),
// we display either the list of all users typing (if they do not exceed
// MAX_USERS_TO_DISPLAY_NAME) or 'Several people are typing…'
// For now, set two of the users as being typists.
typing_data.add_typist(conversation_key, anna.user_id);
typing_data.add_typist(conversation_key, vronsky.user_id);
const two_typing_users_rendered_html = "Two typing users rendered html stub";
// As you can see below, the first argument of mock_template takes
// the relative path of the template we want to mock w.r.t web/templates/
//
// The second argument takes a boolean determining whether to render html.
// We mostly set this to `false` and recommend you avoid setting this to `true`
// unless necessary in situations where you want to test conditionals
// or something similar. The latter examples below would make that more clear.
//
// The third takes a function to run on calling this template. The function
// gets passed an object(`args` below) containing arguments passed to the template.
// Additionally, it can also have rendered html passed to it if second argument of
// mock_template was set to `true`. Any render calls to this template
// will run the function and return the function's return value.
//
// We often use the function in third argument, like below, to make sure
// the arguments passed to the template are what we expect.
mock_template("typing_notifications.hbs", false, (args) => {
assert.deepEqual(args.users, [anna, vronsky]);
assert.ok(!args.several_users); // Whether to show 'Several people are typing…'
return two_typing_users_rendered_html;
});
typing_events.render_notifications_for_narrow();
// Make sure #typing_notifications's html content is set to the rendered template
// which we mocked and gave a custom return value.
assert.equal($typing_notifications.html(), two_typing_users_rendered_html);
// Now we'll see how setting the second argument to `true`
// can be helpful in testing conditionals inside the template.
// Let's set the mock to just return the rendered html.
mock_template("typing_notifications.hbs", true, (_args, rendered_html) => rendered_html);
// Since we only have two(<MAX_USERS_TO_DISPLAY_NAME) typists, both of them
// should be rendered but not 'Several people are typing…'
typing_events.render_notifications_for_narrow();
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…"));
// Change to having four typists and verify the rendered html has
// 'Several people are typing…' but not the list of users.
typing_data.add_typist(conversation_key, levin.user_id);
typing_data.add_typist(conversation_key, kitty.user_id);
typing_events.render_notifications_for_narrow();
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…`));
});