Files
upstream-zulip/web/tests/example7.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

161 lines
5.4 KiB
JavaScript

"use strict";
const assert = require("node:assert/strict");
const {make_stream} = require("./lib/example_stream.cjs");
const {mock_esm, set_global, zrequire} = require("./lib/namespace.cjs");
const {run_test, noop} = require("./lib/test.cjs");
const {$} = require("./lib/zjquery.cjs");
/*
Let's continue to explore how we can test complex
interactions in the real code.
When a new message comes in, we update the three major
panes of the app:
* left sidebar - stream list
* middle pane - message view
* right sidebar - buddy list (aka "activity" list)
These are reflected by the following calls:
stream_list.update_streams_sidebar
message_util.add_new_messages
activity.process_loaded_messages
For now, though, let's focus on another side effect
of processing incoming messages:
unread_ops.process_visible
When new messages come in, they are often immediately
visible to users, so the app will communicate this
back to the server by calling unread_ops.process_visible.
In order to unit test this, we don't want to require
an actual server to be running. Instead, this example
will stub many of the "boundaries" to focus on the
core behavior.
The two key pieces here are as follows:
* Use mock_esm to avoid compiling the "real"
modules that are immaterial to our current
testing concerns.
* Use override(...) to simulate how we want
methods to behave. (Often we want them to
do nothing at all or return a simple
value.)
*/
set_global("document", {hasFocus: () => true});
const channel = mock_esm("../src/channel");
const desktop_notifications = mock_esm("../src/desktop_notifications");
const message_lists = mock_esm("../src/message_lists");
const message_viewport = mock_esm("../src/message_viewport");
const unread_ui = mock_esm("../src/unread_ui");
message_lists.current = {view: {}};
message_lists.all_rendered_message_lists = () => [message_lists.current];
const message_store = zrequire("message_store");
const stream_data = zrequire("stream_data");
const unread = zrequire("unread");
const unread_ops = zrequire("unread_ops");
const denmark_stream = make_stream({
color: "blue",
name: "Denmark",
stream_id: 101,
subscribed: false,
});
run_test("unread_ops", ({override}) => {
stream_data.clear_subscriptions();
stream_data.add_sub_for_tests(denmark_stream);
message_store.clear_for_testing();
unread.declare_bankruptcy();
const message_id = 50;
const test_messages = [
{
id: message_id,
type: "stream",
stream_id: denmark_stream.stream_id,
topic: "copenhagen",
unread: true,
},
];
// Make our test message appear to be unread, so that
// we then need to subsequently process them as read.
message_store.update_message_cache({
type: "server_message",
message: test_messages[0],
});
unread.process_loaded_messages(test_messages);
// Make our message_viewport appear visible.
$("#message_feed_container").show();
// Make our "test" message appear visible.
override(message_viewport, "bottom_rendered_message_visible", () => true);
// Set message_lists.current containing messages that can be marked read
override(message_lists.current, "all_messages", () => test_messages);
// Ignore these interactions for now:
override(message_lists.current.view, "show_message_as_read", noop);
override(desktop_notifications, "close_notification", noop);
override(unread_ui, "update_unread_counts", noop);
override(unread_ui, "notify_messages_remain_unread", noop);
// Set up a way to capture the options passed in to channel.post.
let channel_post_opts;
override(channel, "post", (opts) => {
channel_post_opts = opts;
});
let can_mark_messages_read;
// Set up an override to point to the above var, so we can
// toggle it easily from within the test (and avoid complicated
// data setup).
override(message_lists.current, "can_mark_messages_read", () => can_mark_messages_read);
override(message_lists.current, "has_unread_messages", () => true);
override(message_lists.current.view, "is_fetched_end_rendered", () => true);
// First, test for a message list that cannot read messages.
can_mark_messages_read = false;
unread_ops.process_visible();
assert.deepEqual(channel_post_opts, undefined);
// Now flip the boolean, and get to the main thing we are testing.
can_mark_messages_read = true;
// Don't mark messages as read until all messages in the narrow are fetched and rendered.
override(message_lists.current.view, "is_fetched_end_rendered", () => false);
unread_ops.process_visible();
assert.deepEqual(channel_post_opts, undefined);
override(message_lists.current.view, "is_fetched_end_rendered", () => true);
unread_ops.process_visible();
// The most important side effect of the above call is that
// we post info to the server. We can verify that the correct
// url and parameters are specified:
assert.deepEqual(channel_post_opts, {
url: "/json/messages/flags",
data: {messages: "[50]", op: "add", flag: "read"},
success: channel_post_opts.success,
});
// Simulate a successful post (which also clears the queue
// in our message_flag code).
channel_post_opts.success({messages: [message_id]});
});