2021-03-15 13:03:00 +01:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
const {strict: assert} = require("assert");
|
|
|
|
|
2021-03-30 02:21:21 +02:00
|
|
|
const {mock_esm, zrequire} = require("../zjsunit/namespace");
|
2021-03-15 13:03:00 +01:00
|
|
|
const {run_test} = require("../zjsunit/test");
|
|
|
|
|
|
|
|
/*
|
|
|
|
Our test from an earlier example verifies that the update events
|
|
|
|
leads to a name change inside the people object, but it obviously
|
|
|
|
kind of glosses over the other interactions.
|
|
|
|
|
|
|
|
We can go a step further and verify the sequence of operations that
|
|
|
|
happen during an event. This concept is called "stubbing", and you
|
|
|
|
can find libraries to help do stubbing. Here we will just build our
|
|
|
|
own lightweight stubbing system, which is almost trivially easy to
|
|
|
|
do in a language like JavaScript.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
// First we tell the compiler to skip certain modules and just
|
|
|
|
// replace them with {}.
|
|
|
|
const huddle_data = mock_esm("../../static/js/huddle_data");
|
2021-03-30 02:21:21 +02:00
|
|
|
const message_lists = mock_esm("../../static/js/message_lists");
|
2021-03-15 13:03:00 +01:00
|
|
|
const message_util = mock_esm("../../static/js/message_util");
|
|
|
|
const notifications = mock_esm("../../static/js/notifications");
|
|
|
|
const pm_list = mock_esm("../../static/js/pm_list");
|
2022-04-24 06:13:19 +02:00
|
|
|
const recent_topics_data = mock_esm("../../static/js/recent_topics_data");
|
2021-03-15 13:03:00 +01:00
|
|
|
const resize = mock_esm("../../static/js/resize");
|
|
|
|
const stream_list = mock_esm("../../static/js/stream_list");
|
|
|
|
const unread_ops = mock_esm("../../static/js/unread_ops");
|
|
|
|
const unread_ui = mock_esm("../../static/js/unread_ui");
|
|
|
|
|
2021-03-30 02:21:21 +02:00
|
|
|
message_lists.home = {};
|
2021-03-15 13:03:00 +01:00
|
|
|
|
|
|
|
// And we will also test some real code, of course.
|
|
|
|
const message_events = zrequire("message_events");
|
|
|
|
const message_store = zrequire("message_store");
|
|
|
|
const narrow_state = zrequire("narrow_state");
|
|
|
|
const people = zrequire("people");
|
|
|
|
|
|
|
|
const isaac = {
|
|
|
|
email: "isaac@example.com",
|
|
|
|
user_id: 30,
|
|
|
|
full_name: "Isaac Newton",
|
|
|
|
};
|
|
|
|
people.add_active_user(isaac);
|
|
|
|
|
|
|
|
/*
|
|
|
|
Next we create a test_helper that will allow us to redirect methods to an
|
|
|
|
events array, and we can then later verify that the sequence of side effect
|
|
|
|
is as predicted.
|
|
|
|
|
|
|
|
(Note that for now we don't simulate return values nor do we inspect the
|
|
|
|
arguments to these functions. We could easily extend our helper to do more.)
|
|
|
|
|
|
|
|
The forthcoming example is a pretty extreme example, where we are calling a
|
|
|
|
pretty high level method that dispatches a lot of its work out to other
|
|
|
|
objects.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2021-06-16 14:38:37 +02:00
|
|
|
function test_helper({override}) {
|
2021-03-15 13:03:00 +01:00
|
|
|
const events = [];
|
|
|
|
|
|
|
|
return {
|
|
|
|
redirect: (module, func_name) => {
|
|
|
|
override(module, func_name, () => {
|
|
|
|
events.push([module, func_name]);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
events,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-06-16 14:38:37 +02:00
|
|
|
run_test("insert_message", ({override}) => {
|
2021-03-15 13:03:00 +01:00
|
|
|
message_store.clear_for_testing();
|
|
|
|
|
|
|
|
override(pm_list, "update_private_messages", () => {});
|
|
|
|
|
2021-06-16 14:38:37 +02:00
|
|
|
const helper = test_helper({override});
|
2021-03-15 13:03:00 +01:00
|
|
|
|
|
|
|
const new_message = {
|
|
|
|
sender_id: isaac.user_id,
|
|
|
|
id: 1001,
|
|
|
|
content: "example content",
|
|
|
|
};
|
|
|
|
|
|
|
|
assert.equal(message_store.get(new_message.id), undefined);
|
|
|
|
|
|
|
|
helper.redirect(huddle_data, "process_loaded_messages");
|
2021-03-30 06:23:09 +02:00
|
|
|
helper.redirect(message_util, "add_new_messages_data");
|
2021-03-15 13:03:00 +01:00
|
|
|
helper.redirect(message_util, "add_new_messages");
|
|
|
|
helper.redirect(notifications, "received_messages");
|
2022-04-24 06:13:19 +02:00
|
|
|
helper.redirect(recent_topics_data, "process_message");
|
2021-03-15 13:03:00 +01:00
|
|
|
helper.redirect(resize, "resize_page_components");
|
|
|
|
helper.redirect(stream_list, "update_streams_sidebar");
|
|
|
|
helper.redirect(unread_ops, "process_visible");
|
|
|
|
helper.redirect(unread_ui, "update_unread_counts");
|
|
|
|
|
|
|
|
narrow_state.reset_current_filter();
|
|
|
|
|
|
|
|
message_events.insert_new_messages([new_message]);
|
|
|
|
|
|
|
|
// Even though we have stubbed a *lot* of code, our
|
|
|
|
// tests can still verify the main "narrative" of how
|
|
|
|
// the code invokes various objects when a new message
|
|
|
|
// comes in:
|
|
|
|
assert.deepEqual(helper.events, [
|
|
|
|
[huddle_data, "process_loaded_messages"],
|
2021-03-30 06:23:09 +02:00
|
|
|
[message_util, "add_new_messages_data"],
|
2021-03-15 13:03:00 +01:00
|
|
|
[message_util, "add_new_messages"],
|
|
|
|
[unread_ui, "update_unread_counts"],
|
|
|
|
[resize, "resize_page_components"],
|
|
|
|
[unread_ops, "process_visible"],
|
|
|
|
[notifications, "received_messages"],
|
|
|
|
[stream_list, "update_streams_sidebar"],
|
2022-04-24 06:13:19 +02:00
|
|
|
[recent_topics_data, "process_message"],
|
2021-03-15 13:03:00 +01:00
|
|
|
]);
|
|
|
|
|
|
|
|
// Despite all of our stubbing/mocking, the call to
|
|
|
|
// insert_new_messages will have created a very important
|
|
|
|
// side effect that we can verify:
|
|
|
|
const inserted_message = message_store.get(new_message.id);
|
|
|
|
assert.equal(inserted_message.id, new_message.id);
|
|
|
|
assert.equal(inserted_message.content, "example content");
|
|
|
|
});
|