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:
177
web/tests/example4.test.cjs
Normal file
177
web/tests/example4.test.cjs
Normal file
@@ -0,0 +1,177 @@
|
||||
"use strict";
|
||||
|
||||
const assert = require("node:assert/strict");
|
||||
|
||||
const {make_bot} = require("./lib/example_user.cjs");
|
||||
const {mock_esm, zrequire} = require("./lib/namespace.cjs");
|
||||
const {run_test, noop} = require("./lib/test.cjs");
|
||||
const {$} = require("./lib/zjquery.cjs");
|
||||
|
||||
/*
|
||||
|
||||
Let's step back and review what we've done so far.
|
||||
|
||||
We've used fairly straightforward testing techniques
|
||||
to explore the following modules:
|
||||
|
||||
filter
|
||||
message_store
|
||||
narrow_state
|
||||
people
|
||||
stream_data
|
||||
util
|
||||
|
||||
We haven't gone deep on any of these objects, but if
|
||||
you are interested, all of these objects have test
|
||||
suites that have 100% line coverage on the modules
|
||||
that implement those objects. For example, you can look
|
||||
at people.test.cjs in this directory for more tests on the
|
||||
people object.
|
||||
|
||||
We can quickly review some testing concepts:
|
||||
|
||||
zrequire - bring in real code
|
||||
mock_esm - mock es6 modules
|
||||
assert.equal - verify results
|
||||
|
||||
------
|
||||
|
||||
Let's talk about our next steps.
|
||||
|
||||
An app is pretty useless without an actual data source.
|
||||
One of the primary ways that a Zulip client gets data
|
||||
is through events. (We also get data at page load, and
|
||||
we can also ask the server for data, but that's not in
|
||||
the scope of this conversation yet.)
|
||||
|
||||
Chat systems are dynamic. If an admin adds a user, or
|
||||
if a user sends a messages, the server immediately sends
|
||||
events to all clients so that they can reflect appropriate
|
||||
changes in their UI. We're not going to discuss the entire
|
||||
"full stack" mechanism here. Instead, we'll focus on
|
||||
the client code, starting at the boundary where we
|
||||
process events.
|
||||
|
||||
Let's just get started...
|
||||
|
||||
*/
|
||||
|
||||
// We are going to use mock versions of some of our libraries.
|
||||
const activity_ui = mock_esm("../src/activity_ui");
|
||||
const message_live_update = mock_esm("../src/message_live_update");
|
||||
const pm_list = mock_esm("../src/pm_list");
|
||||
const settings_bots = mock_esm("../src/settings_bots");
|
||||
const settings_users = mock_esm("../src/settings_users");
|
||||
const user_profile = mock_esm("../src/user_profile");
|
||||
mock_esm("../src/compose_recipient", {
|
||||
update_user_name_in_compose() {},
|
||||
});
|
||||
mock_esm("../src/message_view_header", {
|
||||
maybe_update_navbar_title_for_user() {},
|
||||
});
|
||||
|
||||
// Use real versions of these modules.
|
||||
const bot_data = zrequire("bot_data");
|
||||
const people = zrequire("people");
|
||||
const server_events_dispatch = zrequire("server_events_dispatch");
|
||||
const {set_current_user} = zrequire("state_data");
|
||||
|
||||
set_current_user({});
|
||||
|
||||
const bob = make_bot({
|
||||
email: "bob@example.com",
|
||||
user_id: 33,
|
||||
full_name: "Bob Roberts",
|
||||
});
|
||||
|
||||
run_test("add users with event", ({override}) => {
|
||||
people.init();
|
||||
|
||||
const event = {
|
||||
type: "realm_user",
|
||||
op: "add",
|
||||
person: bob,
|
||||
};
|
||||
|
||||
assert.ok(!people.is_known_user_id(bob.user_id));
|
||||
|
||||
// We need to override a stub here before dispatching the event.
|
||||
// Keep reading to see how overriding works!
|
||||
override(settings_bots, "redraw_all_bots_list", noop);
|
||||
override(activity_ui, "check_should_redraw_new_user", noop);
|
||||
override(pm_list, "update_private_messages", noop);
|
||||
// Let's simulate dispatching our event!
|
||||
server_events_dispatch.dispatch_normal_event(event);
|
||||
|
||||
// And it works!
|
||||
assert.ok(people.is_known_user_id(bob.user_id));
|
||||
});
|
||||
|
||||
/*
|
||||
|
||||
It's actually a little surprising that adding a user does
|
||||
not have side effects beyond the people object, the bots list,
|
||||
and the direct messages list. I guess we don't immediately
|
||||
update the buddy list, but that's because the buddy list gets
|
||||
updated on the next server fetch.
|
||||
|
||||
Let's try an update next. To make this work, we will want
|
||||
to override some more of our stubs.
|
||||
|
||||
This is where we see a little extra benefit from the
|
||||
run_test wrapper. It passes us in an object that we
|
||||
can use to override data, and that works within the
|
||||
scope of the function.
|
||||
|
||||
*/
|
||||
|
||||
run_test("update user with event", ({override}) => {
|
||||
people.init();
|
||||
people.add_active_user(bob);
|
||||
bot_data.add({
|
||||
default_all_public_streams: true,
|
||||
default_events_register_stream: "register stream test",
|
||||
default_sending_stream: "sending stream test",
|
||||
user_id: bob.user_id,
|
||||
services: [],
|
||||
});
|
||||
|
||||
set_current_user({user_id: bob.user_id});
|
||||
|
||||
const $select = $.create("#user-self-role-select");
|
||||
const $option = $.create('option[value="100"]');
|
||||
$select.set_find_results('option[value="100"]', $option);
|
||||
|
||||
const new_bob = {
|
||||
user_id: bob.user_id,
|
||||
full_name: "The Artist Formerly Known as Bob",
|
||||
};
|
||||
|
||||
const event = {
|
||||
type: "realm_user",
|
||||
op: "update",
|
||||
person: new_bob,
|
||||
};
|
||||
|
||||
// We have to stub a few things. We don't want to test
|
||||
// the details of these functions, but we do want to
|
||||
// verify that they run. Fortunately, the run_test()
|
||||
// wrapper will tell us if we override a method that
|
||||
// doesn't get called!
|
||||
override(activity_ui, "redraw", noop);
|
||||
override(message_live_update, "update_user_full_name", noop);
|
||||
override(pm_list, "update_private_messages", noop);
|
||||
override(settings_users, "update_user_data", noop);
|
||||
override(settings_bots, "update_bot_data", noop);
|
||||
override(user_profile, "update_profile_modal_ui", noop);
|
||||
|
||||
// Dispatch the realm_user/update event, which will update
|
||||
// data structures and have other side effects that are
|
||||
// stubbed out above.
|
||||
server_events_dispatch.dispatch_normal_event(event);
|
||||
|
||||
const user = people.get_by_user_id(bob.user_id);
|
||||
|
||||
// Verify that the code actually did its main job:
|
||||
assert.equal(user.full_name, "The Artist Formerly Known as Bob");
|
||||
});
|
||||
Reference in New Issue
Block a user