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:
151
web/tests/example8.test.cjs
Normal file
151
web/tests/example8.test.cjs
Normal file
@@ -0,0 +1,151 @@
|
||||
"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…`));
|
||||
});
|
||||
Reference in New Issue
Block a user