zulip/frontend_tests/node_tests/stream_edit.js

407 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 $ = require("../zjsunit/zjquery");
const {page_params, user_settings} = require("../zjsunit/zpage_params");
const noop = () => {};
const typeahead_helper = mock_esm("../../static/js/typeahead_helper");
const ui = mock_esm("../../static/js/ui", {
get_scroll_element: noop,
});
mock_esm("../../static/js/browser_history", {update: noop});
mock_esm("../../static/js/hash_util", {
stream_edit_uri: noop,
by_stream_uri: noop,
active_stream: noop,
});
mock_esm("../../static/js/list_widget", {
create: () => ({init: noop}),
});
mock_esm("../../static/js/stream_color", {
set_colorpicker_color: noop,
});
mock_esm("../../static/js/components", {
toggle: () => ({
get: () => [],
}),
});
const peer_data = zrequire("peer_data");
const people = zrequire("people");
const stream_data = zrequire("stream_data");
const stream_edit = zrequire("stream_edit");
const stream_pill = zrequire("stream_pill");
const user_groups = zrequire("user_groups");
const user_group_pill = zrequire("user_group_pill");
const user_pill = zrequire("user_pill");
const stream_subscribers_ui = zrequire("stream_subscribers_ui");
const stream_ui_updates = zrequire("stream_ui_updates");
const settings_config = zrequire("settings_config");
const jill = {
email: "jill@zulip.com",
user_id: 10,
full_name: "Jill Hill",
};
const mark = {
email: "mark@zulip.com",
user_id: 20,
full_name: "Marky Mark",
};
const fred = {
email: "fred@zulip.com",
user_id: 30,
full_name: "Fred Flintstone",
};
const me = {
email: "me@example.com",
user_id: 40,
full_name: "me",
};
const persons = [jill, mark, fred, me];
for (const person of persons) {
people.add_active_user(person);
}
const admins = {
name: "Admins",
description: "foo",
id: 1,
members: [jill.user_id, mark.user_id],
};
const testers = {
name: "Testers",
description: "bar",
id: 2,
members: [mark.user_id, fred.user_id, me.user_id],
};
const groups = [admins, testers];
for (const group of groups) {
user_groups.add(group);
}
const denmark = {
stream_id: 1,
name: "Denmark",
subscribed: true,
render_subscribers: true,
};
peer_data.set_subscribers(denmark.stream_id, [me.user_id, mark.user_id]);
const sweden = {
stream_id: 2,
name: "Sweden",
subscribed: false,
};
peer_data.set_subscribers(sweden.stream_id, [mark.user_id, jill.user_id]);
const subs = [denmark, sweden];
for (const sub of subs) {
stream_data.add_sub(sub);
}
function test_ui(label, f) {
run_test(label, ({override, mock_template}) => {
page_params.user_id = me.user_id;
stream_subscribers_ui.initialize();
stream_edit.initialize();
f({override, mock_template});
});
}
test_ui("subscriber_pills", ({override, mock_template}) => {
mock_template("input_pill.hbs", true, (data, html) => {
assert.equal(typeof data.display_value, "string");
return html;
});
mock_template("stream_settings/stream_settings.hbs", false, () => "stream_settings");
mock_template(
"stream_settings/stream_subscription_request_result.hbs",
false,
() => "stream_subscription_request_result",
);
override(people, "sort_but_pin_current_user_on_top", noop);
const subscriptions_table_selector = "#subscriptions_table";
const input_field_stub = $.create(".input");
input_field_stub.before = () => {};
const sub_settings_selector = `#subscription_overlay .subscription_settings[data-stream-id='${CSS.escape(
denmark.stream_id,
)}']`;
const pill_container_stub = $.create("pill-container-stub");
pill_container_stub.find = () => input_field_stub;
const $sub_settings_container = $.create(sub_settings_selector);
const $edit_subscribers_container = $.create("edit-subscribers-stub");
$sub_settings_container.find = (selector) => {
switch (selector) {
case ".colorpicker": {
return undefined;
}
case ".edit_subscribers_for_stream": {
return $edit_subscribers_container;
}
// No default
}
throw new Error(`unexpected selector ${selector}`);
};
$edit_subscribers_container.find = (selector) => {
switch (selector) {
case ".pill-container": {
return pill_container_stub;
}
case ".search": {
return undefined;
}
case ".subscriber_table": {
return $.create("subscriber-table-stub");
}
case ".subscriber_list_container": {
return undefined;
}
// No default
}
throw new Error(`unexpected selector ${selector}`);
};
const $subscription_settings = $.create(".subscription_settings");
$subscription_settings.addClass = noop;
$subscription_settings.closest = () => $subscription_settings;
$subscription_settings.attr("data-stream-id", denmark.stream_id);
$subscription_settings.length = 0;
const $add_subscribers_form = $.create(
".edit_subscribers_for_stream .subscriber_list_add form",
);
$add_subscribers_form.closest = () => $subscription_settings;
let template_rendered = false;
ui.get_content_element = () => {
template_rendered = true;
return {html: noop};
};
let expected_user_ids = [];
let input_typeahead_called = false;
let add_subscribers_request = false;
override(stream_subscribers_ui, "invite_user_to_stream", (user_ids, sub) => {
assert.equal(sub.stream_id, denmark.stream_id);
assert.deepEqual(user_ids.sort(), expected_user_ids.sort());
add_subscribers_request = true;
});
input_field_stub.typeahead = (config) => {
assert.equal(config.items, 5);
assert.ok(config.fixed);
assert.ok(config.dropup);
assert.ok(config.stopAdvance);
assert.equal(typeof config.source, "function");
assert.equal(typeof config.highlighter, "function");
assert.equal(typeof config.matcher, "function");
assert.equal(typeof config.sorter, "function");
assert.equal(typeof config.updater, "function");
const fake_stream_this = {
query: "#Denmark",
};
const fake_person_this = {
query: "me",
};
const fake_group_this = {
query: "test",
};
(function test_highlighter() {
const fake_html = $.create("fake-html");
typeahead_helper.render_stream = function () {
return fake_html;
};
assert.equal(config.highlighter.call(fake_stream_this, denmark), fake_html);
typeahead_helper.render_user_group = function () {
return fake_html;
};
typeahead_helper.render_person = function () {
return fake_html;
};
assert.equal(config.highlighter.call(fake_group_this, testers), fake_html);
assert.equal(config.highlighter.call(fake_person_this, me), fake_html);
})();
(function test_matcher() {
let result = config.matcher.call(fake_stream_this, denmark);
assert.ok(result);
result = config.matcher.call(fake_stream_this, sweden);
assert.ok(!result);
result = config.matcher.call(fake_group_this, testers);
assert.ok(result);
result = config.matcher.call(fake_group_this, admins);
assert.ok(!result);
result = config.matcher.call(fake_person_this, me);
assert.ok(result);
result = config.matcher.call(fake_person_this, jill);
assert.ok(!result);
})();
(function test_sorter() {
let sort_streams_called = false;
typeahead_helper.sort_streams = () => {
sort_streams_called = true;
};
config.sorter.call(fake_stream_this);
assert.ok(sort_streams_called);
let sort_recipients_called = false;
typeahead_helper.sort_recipients = function () {
sort_recipients_called = true;
};
config.sorter.call(fake_group_this, [testers]);
assert.ok(sort_recipients_called);
sort_recipients_called = false;
config.sorter.call(fake_person_this, [me]);
assert.ok(sort_recipients_called);
})();
(function test_updater() {
function number_of_pills() {
const pills = stream_subscribers_ui.pill_widget.items();
return pills.length;
}
assert.equal(number_of_pills(), 0);
config.updater.call(fake_stream_this, denmark);
assert.equal(number_of_pills(), 1);
config.updater.call(fake_person_this, me);
assert.equal(number_of_pills(), 2);
config.updater.call(fake_group_this, testers);
assert.equal(number_of_pills(), 3);
})();
(function test_source() {
let result = config.source.call(fake_stream_this);
const stream_ids = result.map((stream) => stream.stream_id);
const expected_stream_ids = [sweden.stream_id];
assert.deepEqual(stream_ids, expected_stream_ids);
result = config.source.call(fake_group_this);
const group_ids = result.map((group) => group.id).filter(Boolean);
const expected_group_ids = [admins.id];
assert.deepEqual(group_ids, expected_group_ids);
result = config.source.call(fake_person_this);
const user_ids = result.map((user) => user.user_id).filter(Boolean);
const expected_user_ids = [jill.user_id, fred.user_id];
assert.deepEqual(user_ids, expected_user_ids);
})();
input_typeahead_called = true;
};
// Initialize pill widget upon displaying subscription settings page.
const stream_row_handler = $(subscriptions_table_selector).get_on_handler(
"click",
".stream-row",
);
let fake_this = $subscription_settings;
let event = {target: fake_this};
override(stream_ui_updates, "update_toggler_for_sub", noop);
override(stream_ui_updates, "update_add_subscriptions_elements", noop);
const {stream_notification_settings, pm_mention_notification_settings} = settings_config;
for (const setting of [...stream_notification_settings, ...pm_mention_notification_settings]) {
user_settings[setting] = true;
}
stream_row_handler.call(fake_this, event);
assert.ok(template_rendered);
assert.ok(input_typeahead_called);
let add_subscribers_handler = $(subscriptions_table_selector).get_on_handler(
"submit",
".edit_subscribers_for_stream .subscriber_list_add form",
);
fake_this = $add_subscribers_form;
fake_this.closest = () => $subscription_settings;
event = {
target: fake_this,
preventDefault: () => {},
};
// We cannot subscribe ourselves (`me`) as
// we are already subscribed to denmark stream.
const potential_denmark_stream_subscribers = Array.from(
peer_data.get_subscribers(denmark.stream_id),
).filter((id) => id !== me.user_id);
// `denmark` stream pill, `me` user pill and
// `testers` user group pill are stubbed.
// Thus request is sent to add all the users.
expected_user_ids = [mark.user_id, fred.user_id];
add_subscribers_handler(event);
add_subscribers_handler = $(subscriptions_table_selector).get_on_handler(
"keyup",
".edit_subscribers_for_stream .subscriber_list_add form",
);
event.key = "Enter";
// Only Denmark stream pill is created and a
// request is sent to add all it's subscribers.
override(user_pill, "get_user_ids", () => []);
override(user_group_pill, "get_user_ids", () => []);
expected_user_ids = potential_denmark_stream_subscribers;
add_subscribers_handler(event);
// No request is sent when there are no users to subscribe.
stream_pill.get_user_ids = () => [];
add_subscribers_request = false;
add_subscribers_handler(event);
assert.ok(!add_subscribers_request);
// No request is sent if we try to subscribe ourselves
// only and are already subscribed to the stream.
override(user_pill, "get_user_ids", () => [me.user_id]);
add_subscribers_handler(event);
assert.ok(!add_subscribers_request);
// Denmark stream pill and fred and mark user pills are created.
// But only one request for mark is sent even though a mark user
// pill is created and mark is also a subscriber of Denmark stream.
override(user_pill, "get_user_ids", () => [mark.user_id, fred.user_id]);
stream_pill.get_user_ids = () => peer_data.get_subscribers(denmark.stream_id);
expected_user_ids = potential_denmark_stream_subscribers.concat(fred.user_id);
add_subscribers_handler(event);
function is_person_active(user_id) {
return user_id === mark.user_id;
}
// Deactivated user_id is not included in request.
override(user_pill, "get_user_ids", () => [mark.user_id, fred.user_id]);
override(people, "is_person_active", is_person_active);
expected_user_ids = [mark.user_id];
add_subscribers_handler(event);
});