Files
zulip/frontend_tests/node_tests/pm_list_data.js
Anders Kaseorg c520890f54 node_tests: Remove low-hanging uses of __Rewire__.
When we were preparing the conversion to ES modules in 2019, the
primary obstacle was that the Node tests extensively relied on the
ability to reach into modules and mutate their CommonJS exports in
order to mock things.  ES module bindings are not mutable, so in
commit 173c9cee42 we added
babel-plugin-rewire-ts as a kludgy transpilation-based workaround for
this to unblock the conversion.

However, babel-plugin-rewire-ts is slow, buggy, nonstandard,
confusing, and unmaintained.  It’s incompatible with running our ES
modules as native ES modules, and prevents us from taking advantage of
modern tools for ES modules.  So we want to excise all use of
__Rewire__ (and the disallow_rewire, override_rewire helper functions
that rely on it) from the tests and remove babel-plugin-rewire-ts.

Commits 64abdc199e and
e17ba5260a (#20730) prepared for this by
letting us see where __Rewire__ is being used.  Now we go through and
remove most of the uses that are easy to remove without modifying the
production code at all.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-07-13 16:27:30 -07:00

442 lines
13 KiB
JavaScript

"use strict";
const {strict: assert} = require("assert");
const {mock_esm, zrequire} = require("../zjsunit/namespace");
const {run_test} = require("../zjsunit/test");
const unread = mock_esm("../../static/js/unread");
mock_esm("../../static/js/user_status", {
is_away: () => false,
get_status_emoji: () => ({
emoji_code: 20,
}),
});
const narrow_state = zrequire("narrow_state");
const people = zrequire("people");
const pm_conversations = zrequire("pm_conversations");
const pm_list_data = zrequire("pm_list_data");
const alice = {
email: "alice@zulip.com",
user_id: 101,
full_name: "Alice",
};
const bob = {
email: "bob@zulip.com",
user_id: 102,
full_name: "Bob",
};
const me = {
email: "me@zulip.com",
user_id: 103,
full_name: "Me Myself",
};
const zoe = {
email: "zoe@zulip.com",
user_id: 104,
full_name: "Zoe",
};
const cardelio = {
email: "cardelio@zulip.com",
user_id: 105,
full_name: "Cardelio",
};
const shiv = {
email: "shiv@zulip.com",
user_id: 106,
full_name: "Shiv",
};
const desdemona = {
email: "desdemona@zulip.com",
user_id: 107,
full_name: "Desdemona",
};
const lago = {
email: "lago@zulip.com",
user_id: 108,
full_name: "Lago",
};
const aaron = {
email: "aaron@zulip.com",
user_id: 109,
full_name: "Aaron",
};
const jai = {
email: "jai@zulip.com",
user_id: 110,
full_name: "Jai",
};
const shivam = {
email: "shivam@zulip.com",
user_id: 111,
full_name: "Shivam",
};
const bot_test = {
email: "outgoingwebhook@zulip.com",
user_id: 314,
full_name: "Outgoing webhook",
is_admin: false,
is_bot: true,
};
people.add_active_user(alice);
people.add_active_user(bob);
people.add_active_user(me);
people.add_active_user(zoe);
people.add_active_user(cardelio);
people.add_active_user(shiv);
people.add_active_user(desdemona);
people.add_active_user(lago);
people.add_active_user(aaron);
people.add_active_user(jai);
people.add_active_user(shivam);
people.add_active_user(bot_test);
people.initialize_current_user(me.user_id);
function test(label, f) {
run_test(label, (helpers) => {
narrow_state.reset_current_filter();
pm_conversations.clear_for_testing();
f(helpers);
});
}
function get_list_info(zoomed) {
return pm_list_data.get_list_info(zoomed);
}
test("get_conversations", ({override}) => {
pm_conversations.recent.insert([alice.user_id, bob.user_id], 1);
pm_conversations.recent.insert([me.user_id], 2);
let num_unread_for_person = 1;
override(unread, "num_unread_for_person", () => num_unread_for_person);
assert.equal(narrow_state.filter(), undefined);
const expected_data = [
{
is_active: false,
is_group: false,
is_zero: false,
recipients: "Me Myself",
unread: 1,
url: "#narrow/pm-with/103-me",
user_circle_class: "user_circle_empty",
user_ids_string: "103",
status_emoji_info: {
emoji_code: 20,
},
},
{
recipients: "Alice, Bob",
user_ids_string: "101,102",
unread: 1,
is_zero: false,
is_active: false,
url: "#narrow/pm-with/101,102-group",
user_circle_class: undefined,
is_group: true,
status_emoji_info: undefined,
},
];
let pm_data = pm_list_data.get_conversations();
assert.deepEqual(pm_data, expected_data);
num_unread_for_person = 0;
pm_data = pm_list_data.get_conversations();
expected_data[0].unread = 0;
expected_data[0].is_zero = true;
expected_data[1].unread = 0;
expected_data[1].is_zero = true;
assert.deepEqual(pm_data, expected_data);
pm_data = pm_list_data.get_conversations();
assert.deepEqual(pm_data, expected_data);
});
test("get_conversations bot", ({override}) => {
pm_conversations.recent.insert([alice.user_id, bob.user_id], 1);
pm_conversations.recent.insert([bot_test.user_id], 2);
override(unread, "num_unread_for_person", () => 1);
assert.equal(narrow_state.filter(), undefined);
const expected_data = [
{
recipients: "Outgoing webhook",
user_ids_string: "314",
unread: 1,
is_zero: false,
is_active: false,
url: "#narrow/pm-with/314-outgoingwebhook",
status_emoji_info: undefined,
user_circle_class: "user_circle_green",
is_group: false,
},
{
recipients: "Alice, Bob",
user_ids_string: "101,102",
unread: 1,
is_zero: false,
is_active: false,
url: "#narrow/pm-with/101,102-group",
user_circle_class: undefined,
status_emoji_info: undefined,
is_group: true,
},
];
const pm_data = pm_list_data.get_conversations();
assert.deepEqual(pm_data, expected_data);
});
test("get_active_user_ids_string", () => {
assert.equal(pm_list_data.get_active_user_ids_string(), undefined);
function set_filter_result(emails) {
const active_filter = {
operands: (operand) => {
assert.equal(operand, "pm-with");
return emails;
},
};
narrow_state.set_current_filter(active_filter);
}
set_filter_result([]);
assert.equal(pm_list_data.get_active_user_ids_string(), undefined);
set_filter_result(["bob@zulip.com,alice@zulip.com"]);
assert.equal(pm_list_data.get_active_user_ids_string(), "101,102");
});
function private_filter() {
return {
operands: (operand) => {
assert.equal(operand, "is");
return ["private", "starred"];
},
};
}
test("is_all_privates", () => {
assert.equal(narrow_state.filter(), undefined);
assert.equal(pm_list_data.is_all_privates(), false);
narrow_state.set_current_filter(private_filter());
assert.equal(pm_list_data.is_all_privates(), true);
});
test("get_list_info", ({override}) => {
let list_info;
assert.equal(narrow_state.filter(), undefined);
// Initialize an empty list to start.
const empty_list_info = get_list_info();
assert.deepEqual(empty_list_info, {
conversations_to_be_shown: [],
more_conversations_unread_count: 0,
});
// TODO: We should just initialize a Filter object with `new
// Filter` rather than creating a mock.
function set_filter_result(emails) {
const active_filter = {
operands: (operand) => {
assert.equal(operand, "pm-with");
return emails;
},
};
narrow_state.set_current_filter(active_filter);
}
set_filter_result([]);
assert.equal(pm_list_data.get_active_user_ids_string(), undefined);
// Mock to arrange that each user has exactly 1 unread.
const num_unread_for_person = 1;
override(unread, "num_unread_for_person", () => num_unread_for_person);
// Initially, we append 2 conversations and check for the
// `conversations_to_be_shown` returned in list_info.
pm_conversations.recent.insert([alice.user_id, bob.user_id], 1);
pm_conversations.recent.insert([me.user_id], 2);
list_info = get_list_info(false);
const expected_list_info = [
{
is_active: false,
is_group: false,
is_zero: false,
recipients: "Me Myself",
status_emoji_info: {
emoji_code: 20,
},
unread: 1,
url: "#narrow/pm-with/103-me",
user_circle_class: "user_circle_empty",
user_ids_string: "103",
},
{
recipients: "Alice, Bob",
user_ids_string: "101,102",
unread: 1,
is_active: false,
url: "#narrow/pm-with/101,102-group",
user_circle_class: undefined,
status_emoji_info: undefined,
is_group: true,
is_zero: false,
},
];
assert.deepEqual(list_info, {
conversations_to_be_shown: expected_list_info,
more_conversations_unread_count: 0,
});
// Now, add additional converstaions until we exceed
// `max_conversations_to_show_with_unreads`.
pm_conversations.recent.insert([zoe.user_id], 3);
pm_conversations.recent.insert([cardelio.user_id], 4);
pm_conversations.recent.insert([zoe.user_id, cardelio.user_id], 5);
pm_conversations.recent.insert([shiv.user_id], 6);
pm_conversations.recent.insert([cardelio.user_id, shiv.user_id], 7);
pm_conversations.recent.insert([desdemona.user_id], 8);
// We've now added a total of 8 conversations, which is the value
// of `max_conversations_to_show_with_unreads` so even now, the
// number of unreads in `more conversations` li-item should be 0.
list_info = get_list_info(false);
assert.deepEqual(list_info.conversations_to_be_shown.length, 8);
assert.deepEqual(list_info.more_conversations_unread_count, 0);
// Verify just the ordering of the conversations with unreads.
assert.deepEqual(
list_info.conversations_to_be_shown.map((conversation) => conversation.recipients),
[
"Desdemona",
"Cardelio, Shiv",
"Shiv",
"Cardelio, Zoe",
"Cardelio",
"Zoe",
"Me Myself",
"Alice, Bob",
],
);
// After adding one more conversation, there will be 10
// conversations, which exceeds
// `max_conversations_to_show_with_unreads`. Verify that the
// oldest conversations are not shown and their unreads counted in
// more_conversations_unread_count.
pm_conversations.recent.insert([lago.user_id], 9);
pm_conversations.recent.insert([zoe.user_id, lago.user_id], 10);
list_info = get_list_info(false);
assert.deepEqual(list_info.conversations_to_be_shown.length, 8);
assert.deepEqual(list_info.more_conversations_unread_count, 2);
assert.deepEqual(
list_info.conversations_to_be_shown.map((conversation) => conversation.recipients),
[
"Lago, Zoe",
"Lago",
"Desdemona",
"Cardelio, Shiv",
"Shiv",
"Cardelio, Zoe",
"Cardelio",
"Zoe",
],
);
// If we are narrowed to an older topic, then that one gets
// included despite not being among the 8 most recent.
set_filter_result(["alice@zulip.com,bob@zulip.com"]);
list_info = get_list_info(false);
assert.deepEqual(list_info.conversations_to_be_shown.length, 9);
assert.deepEqual(list_info.more_conversations_unread_count, 1);
assert.deepEqual(
list_info.conversations_to_be_shown.map((conversation) => conversation.recipients),
[
"Lago, Zoe",
"Lago",
"Desdemona",
"Cardelio, Shiv",
"Shiv",
"Cardelio, Zoe",
"Cardelio",
"Zoe",
"Alice, Bob",
],
);
// Verify that if the list is zoomed, we'll include all 9
// conversations in the correct order.
list_info = get_list_info(true);
assert.deepEqual(list_info.conversations_to_be_shown.length, 10);
assert.deepEqual(
list_info.conversations_to_be_shown.map((conversation) => conversation.recipients),
[
"Lago, Zoe",
"Lago",
"Desdemona",
"Cardelio, Shiv",
"Shiv",
"Cardelio, Zoe",
"Cardelio",
"Zoe",
"Me Myself",
"Alice, Bob",
],
);
// We now test some no unreads cases.
override(unread, "num_unread_for_person", () => 0);
pm_conversations.clear_for_testing();
pm_conversations.recent.insert([alice.user_id], 1);
pm_conversations.recent.insert([bob.user_id], 2);
pm_conversations.recent.insert([me.user_id], 3);
pm_conversations.recent.insert([zoe.user_id], 4);
pm_conversations.recent.insert([cardelio.user_id], 5);
pm_conversations.recent.insert([shiv.user_id], 6);
pm_conversations.recent.insert([alice.user_id, bob.user_id], 7);
// We have 7 conversations in total, but only most recent 5 are visible.
list_info = get_list_info(false);
assert.deepEqual(list_info.conversations_to_be_shown.length, 5);
// If we set the oldest conversation as active, it will be
// included as well as the 5 most recent.
set_filter_result(["alice@zulip.com"]);
assert.equal(pm_list_data.get_active_user_ids_string(), "101");
list_info = get_list_info(false);
assert.deepEqual(list_info.conversations_to_be_shown.length, 6);
assert.deepEqual(list_info.conversations_to_be_shown[5], {
recipients: "Alice",
user_ids_string: "101",
unread: 0,
is_zero: true,
is_active: true,
url: "#narrow/pm-with/101-alice",
status_emoji_info: {emoji_code: 20},
user_circle_class: "user_circle_empty",
is_group: false,
});
assert.deepEqual(
list_info.conversations_to_be_shown.map((conversation) => conversation.recipients),
["Alice, Bob", "Shiv", "Cardelio", "Zoe", "Me Myself", "Alice"],
);
});