mirror of
https://github.com/zulip/zulip.git
synced 2025-11-05 22:43:42 +00:00
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 commit173c9cee42we 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. Commits64abdc199eande17ba5260a(#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>
976 lines
30 KiB
JavaScript
976 lines
30 KiB
JavaScript
"use strict";
|
|
|
|
const {strict: assert} = require("assert");
|
|
|
|
const {mock_esm, set_global, zrequire} = require("../zjsunit/namespace");
|
|
const {make_stub} = require("../zjsunit/stub");
|
|
const {run_test} = require("../zjsunit/test");
|
|
const blueslip = require("../zjsunit/zblueslip");
|
|
const $ = require("../zjsunit/zjquery");
|
|
const {page_params} = require("../zjsunit/zpage_params");
|
|
|
|
const alice_user_id = 5;
|
|
|
|
const sample_message = {
|
|
id: 1001,
|
|
reactions: [
|
|
{emoji_name: "smile", user_id: 5, reaction_type: "unicode_emoji", emoji_code: "1f642"},
|
|
{emoji_name: "smile", user_id: 6, reaction_type: "unicode_emoji", emoji_code: "1f642"},
|
|
{emoji_name: "frown", user_id: 7, reaction_type: "unicode_emoji", emoji_code: "1f641"},
|
|
|
|
{emoji_name: "tada", user_id: 7, reaction_type: "unicode_emoji", emoji_code: "1f389"},
|
|
{emoji_name: "tada", user_id: 8, reaction_type: "unicode_emoji", emoji_code: "1f389"},
|
|
|
|
{emoji_name: "rocket", user_id: 5, reaction_type: "unicode_emoji", emoji_code: "1f680"},
|
|
{emoji_name: "rocket", user_id: 6, reaction_type: "unicode_emoji", emoji_code: "1f680"},
|
|
{emoji_name: "rocket", user_id: 7, reaction_type: "unicode_emoji", emoji_code: "1f680"},
|
|
|
|
{emoji_name: "wave", user_id: 6, reaction_type: "unicode_emoji", emoji_code: "1f44b"},
|
|
{emoji_name: "wave", user_id: 7, reaction_type: "unicode_emoji", emoji_code: "1f44b"},
|
|
{emoji_name: "wave", user_id: 8, reaction_type: "unicode_emoji", emoji_code: "1f44b"},
|
|
|
|
{
|
|
emoji_name: "inactive_realm_emoji",
|
|
user_id: 5,
|
|
reaction_type: "realm_emoji",
|
|
emoji_code: "992",
|
|
},
|
|
],
|
|
};
|
|
|
|
const channel = mock_esm("../../static/js/channel");
|
|
const emoji_picker = mock_esm("../../static/js/emoji_picker", {
|
|
hide_emoji_popover() {},
|
|
});
|
|
const message_lists = mock_esm("../../static/js/message_lists");
|
|
const message_store = mock_esm("../../static/js/message_store");
|
|
const spectators = mock_esm("../../static/js/spectators", {
|
|
login_to_access() {},
|
|
});
|
|
|
|
message_lists.current = {
|
|
selected_row() {
|
|
return $(".selected-row");
|
|
},
|
|
selected_id() {
|
|
return 42;
|
|
},
|
|
};
|
|
set_global("document", "document-stub");
|
|
|
|
const emoji = zrequire("emoji");
|
|
const emoji_codes = zrequire("../generated/emoji/emoji_codes.json");
|
|
const people = zrequire("people");
|
|
const reactions = zrequire("reactions");
|
|
|
|
const emoji_params = {
|
|
realm_emoji: {
|
|
991: {
|
|
id: "991",
|
|
name: "realm_emoji",
|
|
source_url: "/url/for/991",
|
|
deactivated: false,
|
|
},
|
|
992: {
|
|
id: "992",
|
|
name: "inactive_realm_emoji",
|
|
source_url: "/url/for/992",
|
|
still_url: "/still/url/for/992",
|
|
deactivated: true,
|
|
},
|
|
},
|
|
emoji_codes,
|
|
};
|
|
|
|
emoji.initialize(emoji_params);
|
|
|
|
const alice = {
|
|
email: "alice@example.com",
|
|
user_id: alice_user_id,
|
|
full_name: "Alice",
|
|
};
|
|
const bob = {
|
|
email: "bob@example.com",
|
|
user_id: 6,
|
|
full_name: "Bob van Roberts",
|
|
};
|
|
const cali = {
|
|
email: "cali@example.com",
|
|
user_id: 7,
|
|
full_name: "Cali",
|
|
};
|
|
const alexus = {
|
|
email: "alexus@example.com",
|
|
user_id: 8,
|
|
full_name: "Alexus",
|
|
};
|
|
people.add_active_user(alice);
|
|
people.add_active_user(bob);
|
|
people.add_active_user(cali);
|
|
people.add_active_user(alexus);
|
|
|
|
function test(label, f) {
|
|
run_test(label, (helpers) => {
|
|
page_params.user_id = alice_user_id;
|
|
f(helpers);
|
|
});
|
|
}
|
|
|
|
test("open_reactions_popover (sent by me)", () => {
|
|
message_lists.current.selected_message = () => ({sent_by_me: true});
|
|
$(".selected-row").set_find_results(".actions_hover", ["action-stub"]);
|
|
|
|
let called = false;
|
|
emoji_picker.toggle_emoji_popover = (target, id) => {
|
|
called = true;
|
|
assert.equal(id, 42);
|
|
assert.equal(target, "action-stub");
|
|
};
|
|
|
|
assert.ok(reactions.open_reactions_popover());
|
|
assert.ok(called);
|
|
});
|
|
|
|
test("open_reactions_popover (not sent by me)", () => {
|
|
message_lists.current.selected_message = () => ({sent_by_me: false});
|
|
$(".selected-row").set_find_results(".reaction_button", ["reaction-stub"]);
|
|
|
|
let called = false;
|
|
emoji_picker.toggle_emoji_popover = (target, id) => {
|
|
called = true;
|
|
assert.equal(id, 42);
|
|
assert.equal(target, "reaction-stub");
|
|
};
|
|
|
|
assert.ok(reactions.open_reactions_popover());
|
|
assert.ok(called);
|
|
});
|
|
|
|
test("basics", () => {
|
|
const message = {...sample_message};
|
|
|
|
const result = reactions.get_message_reactions(message);
|
|
assert.ok(reactions.current_user_has_reacted_to_emoji(message, "unicode_emoji,1f642"));
|
|
assert.ok(!reactions.current_user_has_reacted_to_emoji(message, "bogus"));
|
|
|
|
result.sort((a, b) => a.count - b.count);
|
|
|
|
const expected_result = [
|
|
{
|
|
emoji_name: "frown",
|
|
reaction_type: "unicode_emoji",
|
|
emoji_code: "1f641",
|
|
local_id: "unicode_emoji,1f641",
|
|
count: 1,
|
|
user_ids: [7],
|
|
label: "translated: Cali reacted with :frown:",
|
|
emoji_alt_code: false,
|
|
class: "message_reaction",
|
|
is_realm_emoji: false,
|
|
},
|
|
{
|
|
emoji_name: "inactive_realm_emoji",
|
|
reaction_type: "realm_emoji",
|
|
emoji_code: "992",
|
|
local_id: "realm_emoji,992",
|
|
count: 1,
|
|
user_ids: [5],
|
|
label: "translated: You (click to remove) reacted with :inactive_realm_emoji:",
|
|
emoji_alt_code: false,
|
|
is_realm_emoji: true,
|
|
url: "/url/for/992",
|
|
still_url: "/still/url/for/992",
|
|
class: "message_reaction reacted",
|
|
},
|
|
{
|
|
emoji_name: "smile",
|
|
reaction_type: "unicode_emoji",
|
|
emoji_code: "1f642",
|
|
local_id: "unicode_emoji,1f642",
|
|
count: 2,
|
|
user_ids: [5, 6],
|
|
label: "translated: You (click to remove) and Bob van Roberts reacted with :smile:",
|
|
emoji_alt_code: false,
|
|
class: "message_reaction reacted",
|
|
is_realm_emoji: false,
|
|
},
|
|
{
|
|
emoji_name: "tada",
|
|
reaction_type: "unicode_emoji",
|
|
emoji_code: "1f389",
|
|
local_id: "unicode_emoji,1f389",
|
|
count: 2,
|
|
user_ids: [7, 8],
|
|
label: "translated: Cali and Alexus reacted with :tada:",
|
|
emoji_alt_code: false,
|
|
class: "message_reaction",
|
|
is_realm_emoji: false,
|
|
},
|
|
{
|
|
emoji_name: "rocket",
|
|
reaction_type: "unicode_emoji",
|
|
emoji_code: "1f680",
|
|
local_id: "unicode_emoji,1f680",
|
|
count: 3,
|
|
user_ids: [5, 6, 7],
|
|
label: "translated: You (click to remove), Bob van Roberts and Cali reacted with :rocket:",
|
|
emoji_alt_code: false,
|
|
class: "message_reaction reacted",
|
|
is_realm_emoji: false,
|
|
},
|
|
{
|
|
emoji_name: "wave",
|
|
reaction_type: "unicode_emoji",
|
|
emoji_code: "1f44b",
|
|
local_id: "unicode_emoji,1f44b",
|
|
count: 3,
|
|
user_ids: [6, 7, 8],
|
|
label: "translated: Bob van Roberts, Cali and Alexus reacted with :wave:",
|
|
emoji_alt_code: false,
|
|
class: "message_reaction",
|
|
is_realm_emoji: false,
|
|
},
|
|
];
|
|
assert.deepEqual(result, expected_result);
|
|
});
|
|
|
|
test("unknown realm emojis (add)", () => {
|
|
assert.throws(
|
|
() =>
|
|
reactions.view.insert_new_reaction({
|
|
reaction_type: "realm_emoji",
|
|
emoji_name: "false_emoji",
|
|
emoji_code: "broken",
|
|
user_ids: [alice.user_id],
|
|
}),
|
|
{
|
|
name: "Error",
|
|
message: "Cannot find realm emoji for code 'broken'.",
|
|
},
|
|
);
|
|
});
|
|
|
|
test("unknown realm emojis (insert)", () => {
|
|
assert.throws(
|
|
() =>
|
|
reactions.view.insert_new_reaction({
|
|
reaction_type: "realm_emoji",
|
|
emoji_name: "fake_emoji",
|
|
emoji_code: "bogus",
|
|
user_id: bob.user_id,
|
|
}),
|
|
{
|
|
name: "Error",
|
|
message: "Cannot find realm emoji for code 'bogus'.",
|
|
},
|
|
);
|
|
});
|
|
|
|
test("sending", ({override, override_rewire}) => {
|
|
const message = {...sample_message};
|
|
assert.equal(message.id, 1001);
|
|
override(message_store, "get", (message_id) => {
|
|
assert.equal(message_id, message.id);
|
|
return message;
|
|
});
|
|
|
|
let emoji_name = "smile"; // should be a current reaction
|
|
|
|
override_rewire(reactions, "add_reaction", () => {});
|
|
override_rewire(reactions, "remove_reaction", () => {});
|
|
|
|
{
|
|
const stub = make_stub();
|
|
channel.del = stub.f;
|
|
reactions.toggle_emoji_reaction(message.id, emoji_name);
|
|
assert.equal(stub.num_calls, 1);
|
|
const args = stub.get_args("args").args;
|
|
assert.equal(args.url, "/json/messages/1001/reactions");
|
|
assert.deepEqual(args.data, {
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "smile",
|
|
emoji_code: "1f642",
|
|
});
|
|
// args.success() does nothing; just make sure it doesn't crash
|
|
args.success();
|
|
|
|
// similarly, we only exercise the failure codepath
|
|
// Since this path calls blueslip.warn, we need to handle it.
|
|
blueslip.expect("warn", "XHR error message.");
|
|
channel.xhr_error_message = () => "XHR error message.";
|
|
args.error();
|
|
}
|
|
emoji_name = "alien"; // not set yet
|
|
{
|
|
const stub = make_stub();
|
|
channel.post = stub.f;
|
|
reactions.toggle_emoji_reaction(message.id, emoji_name);
|
|
assert.equal(stub.num_calls, 1);
|
|
const args = stub.get_args("args").args;
|
|
assert.equal(args.url, "/json/messages/1001/reactions");
|
|
assert.deepEqual(args.data, {
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "alien",
|
|
emoji_code: "1f47d",
|
|
});
|
|
}
|
|
|
|
emoji_name = "inactive_realm_emoji";
|
|
{
|
|
// Test removing a deactivated realm emoji. A user can interact with a
|
|
// deactivated realm emoji only by clicking on a reaction, hence, only
|
|
// `process_reaction_click()` codepath supports deleting/adding a deactivated
|
|
// realm emoji.
|
|
const stub = make_stub();
|
|
channel.del = stub.f;
|
|
reactions.process_reaction_click(message.id, "realm_emoji,992");
|
|
assert.equal(stub.num_calls, 1);
|
|
const args = stub.get_args("args").args;
|
|
assert.equal(args.url, "/json/messages/1001/reactions");
|
|
assert.deepEqual(args.data, {
|
|
reaction_type: "realm_emoji",
|
|
emoji_name: "inactive_realm_emoji",
|
|
emoji_code: "992",
|
|
});
|
|
}
|
|
|
|
emoji_name = "zulip"; // Test adding zulip emoji.
|
|
{
|
|
const stub = make_stub();
|
|
channel.post = stub.f;
|
|
reactions.toggle_emoji_reaction(message.id, emoji_name);
|
|
assert.equal(stub.num_calls, 1);
|
|
const args = stub.get_args("args").args;
|
|
assert.equal(args.url, "/json/messages/1001/reactions");
|
|
assert.deepEqual(args.data, {
|
|
reaction_type: "zulip_extra_emoji",
|
|
emoji_name: "zulip",
|
|
emoji_code: "zulip",
|
|
url: "/static/generated/emoji/images/emoji/unicode/zulip.png",
|
|
});
|
|
}
|
|
|
|
emoji_name = "unknown-emoji"; // Test sending an emoji unknown to frontend.
|
|
assert.throws(() => reactions.toggle_emoji_reaction(message.id, emoji_name), {
|
|
name: "Error",
|
|
message: "Bad emoji name: unknown-emoji",
|
|
});
|
|
});
|
|
|
|
function stub_reactions(message_id) {
|
|
const $message_row = $.create("message-row-stub");
|
|
const $message_reactions = $.create("reactions-stub");
|
|
$(".message_table").set_find_results(`[zid='${CSS.escape(message_id)}']`, $message_row);
|
|
$message_row.set_find_results(".message_reactions", $message_reactions);
|
|
return $message_reactions;
|
|
}
|
|
|
|
function stub_reaction(message_id, local_id) {
|
|
const $reaction = $.create("reaction-stub");
|
|
stub_reactions(message_id).set_find_results(
|
|
`[data-reaction-id='${CSS.escape(local_id)}']`,
|
|
$reaction,
|
|
);
|
|
return $reaction;
|
|
}
|
|
|
|
test("set_reaction_count", () => {
|
|
const $count_element = $.create("count-stub");
|
|
const $reaction_element = $.create("reaction-stub");
|
|
|
|
$reaction_element.set_find_results(".message_reaction_count", $count_element);
|
|
|
|
reactions.set_reaction_count($reaction_element, 5);
|
|
|
|
assert.equal($count_element.text(), "5");
|
|
});
|
|
|
|
test("find_reaction", () => {
|
|
const message_id = 99;
|
|
const local_id = "unicode_emoji,1f44b";
|
|
const $reaction = stub_reaction(message_id, local_id);
|
|
|
|
assert.equal(reactions.find_reaction(message_id, local_id), $reaction);
|
|
});
|
|
|
|
test("get_reaction_section", () => {
|
|
const $message_reactions = stub_reactions(555);
|
|
|
|
const $section = reactions.get_reaction_section(555);
|
|
|
|
assert.equal($section, $message_reactions);
|
|
});
|
|
|
|
test("emoji_reaction_title", ({override}) => {
|
|
const message = {...sample_message};
|
|
override(message_store, "get", () => message);
|
|
const local_id = "unicode_emoji,1f642";
|
|
|
|
assert.equal(
|
|
reactions.get_reaction_title_data(message.id, local_id),
|
|
"translated: You (click to remove) and Bob van Roberts reacted with :smile:",
|
|
);
|
|
});
|
|
|
|
test("add_reaction/remove_reaction", ({override}) => {
|
|
// This function tests reaction events by mocking out calls to
|
|
// the view.
|
|
|
|
const message = {
|
|
id: 2001,
|
|
reactions: [],
|
|
};
|
|
|
|
override(message_store, "get", () => message);
|
|
|
|
let view_calls = [];
|
|
|
|
override(reactions.view, "insert_new_reaction", (opts) => {
|
|
view_calls.push({name: "insert_new_reaction", opts});
|
|
});
|
|
override(reactions.view, "update_existing_reaction", (opts) => {
|
|
view_calls.push({name: "update_existing_reaction", opts});
|
|
});
|
|
override(reactions.view, "remove_reaction", (opts) => {
|
|
view_calls.push({name: "remove_reaction", opts});
|
|
});
|
|
|
|
function test_view_calls(test_params) {
|
|
view_calls = [];
|
|
|
|
test_params.run_code();
|
|
|
|
assert.deepEqual(view_calls, test_params.expected_view_calls);
|
|
assert.deepEqual(
|
|
new Set(reactions.get_emojis_used_by_user_for_message_id(message.message_id)),
|
|
new Set(test_params.alice_emojis),
|
|
);
|
|
}
|
|
|
|
const alice_8ball_event = {
|
|
message_id: 2001,
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "8ball",
|
|
emoji_code: "1f3b1",
|
|
user_id: alice.user_id,
|
|
};
|
|
|
|
const bob_8ball_event = {
|
|
message_id: 2001,
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "8ball",
|
|
emoji_code: "1f3b1",
|
|
user_id: bob.user_id,
|
|
};
|
|
|
|
const cali_airplane_event = {
|
|
message_id: 2001,
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "airplane",
|
|
emoji_code: "2708",
|
|
user_id: cali.user_id,
|
|
};
|
|
|
|
test_view_calls({
|
|
run_code() {
|
|
reactions.add_reaction(alice_8ball_event);
|
|
},
|
|
expected_view_calls: [
|
|
{
|
|
name: "insert_new_reaction",
|
|
opts: {
|
|
message_id: 2001,
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "8ball",
|
|
emoji_code: "1f3b1",
|
|
user_id: alice.user_id,
|
|
},
|
|
},
|
|
],
|
|
alice_emojis: ["8ball"],
|
|
});
|
|
|
|
// Add redundant reaction.
|
|
test_view_calls({
|
|
run_code() {
|
|
reactions.add_reaction(alice_8ball_event);
|
|
},
|
|
expected_view_calls: [],
|
|
alice_emojis: ["8ball"],
|
|
});
|
|
|
|
test_view_calls({
|
|
run_code() {
|
|
reactions.add_reaction(bob_8ball_event);
|
|
},
|
|
expected_view_calls: [
|
|
{
|
|
name: "update_existing_reaction",
|
|
opts: {
|
|
message_id: 2001,
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "8ball",
|
|
emoji_code: "1f3b1",
|
|
user_id: bob.user_id,
|
|
user_list: [alice.user_id, bob.user_id],
|
|
},
|
|
},
|
|
],
|
|
alice_emojis: ["8ball"],
|
|
});
|
|
|
|
test_view_calls({
|
|
run_code() {
|
|
reactions.add_reaction(cali_airplane_event);
|
|
},
|
|
expected_view_calls: [
|
|
{
|
|
name: "insert_new_reaction",
|
|
opts: {
|
|
message_id: 2001,
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "airplane",
|
|
emoji_code: "2708",
|
|
user_id: cali.user_id,
|
|
},
|
|
},
|
|
],
|
|
alice_emojis: ["8ball"],
|
|
});
|
|
|
|
test_view_calls({
|
|
run_code() {
|
|
reactions.remove_reaction(bob_8ball_event);
|
|
},
|
|
expected_view_calls: [
|
|
{
|
|
name: "remove_reaction",
|
|
opts: {
|
|
message_id: 2001,
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "8ball",
|
|
emoji_code: "1f3b1",
|
|
user_id: bob.user_id,
|
|
user_list: [alice.user_id],
|
|
},
|
|
},
|
|
],
|
|
alice_emojis: ["8ball"],
|
|
});
|
|
|
|
test_view_calls({
|
|
run_code() {
|
|
reactions.remove_reaction(alice_8ball_event);
|
|
},
|
|
expected_view_calls: [
|
|
{
|
|
name: "remove_reaction",
|
|
opts: {
|
|
message_id: 2001,
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "8ball",
|
|
emoji_code: "1f3b1",
|
|
user_id: alice.user_id,
|
|
user_list: [],
|
|
},
|
|
},
|
|
],
|
|
alice_emojis: [],
|
|
});
|
|
|
|
// Test redundant remove.
|
|
test_view_calls({
|
|
run_code() {
|
|
reactions.remove_reaction(alice_8ball_event);
|
|
},
|
|
expected_view_calls: [],
|
|
alice_emojis: [],
|
|
});
|
|
});
|
|
|
|
test("view.insert_new_reaction (me w/unicode emoji)", ({mock_template}) => {
|
|
const opts = {
|
|
message_id: 501,
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "8ball",
|
|
emoji_code: "1f3b1",
|
|
user_id: alice.user_id,
|
|
};
|
|
|
|
const $message_reactions = stub_reactions(opts.message_id);
|
|
$message_reactions.find = (selector) => {
|
|
assert.equal(selector, ".reaction_button");
|
|
return "reaction-button-stub";
|
|
};
|
|
|
|
mock_template("message_reaction.hbs", false, (data) => {
|
|
assert.deepEqual(data, {
|
|
count: 1,
|
|
emoji_alt_code: false,
|
|
emoji_name: "8ball",
|
|
emoji_code: "1f3b1",
|
|
local_id: "unicode_emoji,1f3b1",
|
|
class: "message_reaction reacted",
|
|
message_id: opts.message_id,
|
|
label: "translated: You (click to remove) reacted with :8ball:",
|
|
reaction_type: opts.reaction_type,
|
|
is_realm_emoji: false,
|
|
});
|
|
return "<new-reaction-stub>";
|
|
});
|
|
|
|
let insert_called;
|
|
$("<new-reaction-stub>").insertBefore = (element) => {
|
|
assert.equal(element, "reaction-button-stub");
|
|
insert_called = true;
|
|
};
|
|
|
|
reactions.view.insert_new_reaction(opts);
|
|
assert.ok(insert_called);
|
|
});
|
|
|
|
test("view.insert_new_reaction (them w/zulip emoji)", ({mock_template}) => {
|
|
const opts = {
|
|
message_id: 502,
|
|
reaction_type: "realm_emoji",
|
|
emoji_name: "zulip",
|
|
emoji_code: "zulip",
|
|
user_id: bob.user_id,
|
|
};
|
|
|
|
const $message_reactions = stub_reactions(opts.message_id);
|
|
$message_reactions.find = (selector) => {
|
|
assert.equal(selector, ".reaction_button");
|
|
return "reaction-button-stub";
|
|
};
|
|
|
|
mock_template("message_reaction.hbs", false, (data) => {
|
|
assert.deepEqual(data, {
|
|
count: 1,
|
|
url: "/static/generated/emoji/images/emoji/unicode/zulip.png",
|
|
is_realm_emoji: true,
|
|
emoji_alt_code: false,
|
|
emoji_name: "zulip",
|
|
emoji_code: "zulip",
|
|
local_id: "realm_emoji,zulip",
|
|
class: "message_reaction",
|
|
message_id: opts.message_id,
|
|
label: "translated: Bob van Roberts reacted with :zulip:",
|
|
still_url: undefined,
|
|
reaction_type: opts.reaction_type,
|
|
});
|
|
return "<new-reaction-stub>";
|
|
});
|
|
|
|
let insert_called;
|
|
$("<new-reaction-stub>").insertBefore = (element) => {
|
|
assert.equal(element, "reaction-button-stub");
|
|
insert_called = true;
|
|
};
|
|
|
|
reactions.view.insert_new_reaction(opts);
|
|
assert.ok(insert_called);
|
|
});
|
|
|
|
test("view.update_existing_reaction (me)", () => {
|
|
const opts = {
|
|
message_id: 503,
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "8ball",
|
|
emoji_code: "1f3b1",
|
|
user_id: alice.user_id,
|
|
user_list: [alice.user_id, bob.user_id],
|
|
};
|
|
|
|
const $our_reaction = stub_reaction(opts.message_id, "unicode_emoji,1f3b1");
|
|
const $reaction_count = $.create("reaction-count-stub");
|
|
$our_reaction.set_find_results(".message_reaction_count", $reaction_count);
|
|
|
|
reactions.view.update_existing_reaction(opts);
|
|
|
|
assert.equal($reaction_count.text(), "2");
|
|
assert.ok($our_reaction.hasClass("reacted"));
|
|
assert.equal(
|
|
$our_reaction.attr("aria-label"),
|
|
"translated: You (click to remove) and Bob van Roberts reacted with :8ball:",
|
|
);
|
|
});
|
|
|
|
test("view.update_existing_reaction (them)", () => {
|
|
const opts = {
|
|
message_id: 504,
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "8ball",
|
|
emoji_code: "1f3b1",
|
|
user_id: bob.user_id,
|
|
user_list: [alice.user_id, bob.user_id, cali.user_id, alexus.user_id],
|
|
};
|
|
|
|
const $our_reaction = stub_reaction(opts.message_id, "unicode_emoji,1f3b1");
|
|
const $reaction_count = $.create("reaction-count-stub");
|
|
$our_reaction.set_find_results(".message_reaction_count", $reaction_count);
|
|
|
|
reactions.view.update_existing_reaction(opts);
|
|
|
|
assert.equal($reaction_count.text(), "4");
|
|
assert.ok(!$our_reaction.hasClass("reacted"));
|
|
assert.equal(
|
|
$our_reaction.attr("aria-label"),
|
|
"translated: You (click to remove), Bob van Roberts, Cali and Alexus reacted with :8ball:",
|
|
);
|
|
});
|
|
|
|
test("view.remove_reaction (me)", () => {
|
|
const opts = {
|
|
message_id: 505,
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "8ball",
|
|
emoji_code: "1f3b1",
|
|
user_id: alice.user_id,
|
|
user_list: [bob.user_id, cali.user_id],
|
|
};
|
|
|
|
const $our_reaction = stub_reaction(opts.message_id, "unicode_emoji,1f3b1");
|
|
const $reaction_count = $.create("reaction-count-stub");
|
|
$our_reaction.addClass("reacted");
|
|
$our_reaction.set_find_results(".message_reaction_count", $reaction_count);
|
|
|
|
reactions.view.remove_reaction(opts);
|
|
|
|
assert.equal($reaction_count.text(), "2");
|
|
assert.ok(!$our_reaction.hasClass("reacted"));
|
|
assert.equal(
|
|
$our_reaction.attr("aria-label"),
|
|
"translated: Bob van Roberts and Cali reacted with :8ball:",
|
|
);
|
|
});
|
|
|
|
test("view.remove_reaction (them)", () => {
|
|
const opts = {
|
|
message_id: 506,
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "8ball",
|
|
emoji_code: "1f3b1",
|
|
user_id: bob.user_id,
|
|
user_list: [alice.user_id],
|
|
};
|
|
|
|
const $our_reaction = stub_reaction(opts.message_id, "unicode_emoji,1f3b1");
|
|
const $reaction_count = $.create("reaction-count-stub");
|
|
$our_reaction.addClass("reacted");
|
|
$our_reaction.set_find_results(".message_reaction_count", $reaction_count);
|
|
|
|
$our_reaction.addClass("reacted");
|
|
reactions.view.remove_reaction(opts);
|
|
|
|
assert.equal($reaction_count.text(), "1");
|
|
assert.ok($our_reaction.hasClass("reacted"));
|
|
assert.equal(
|
|
$our_reaction.attr("aria-label"),
|
|
"translated: You (click to remove) reacted with :8ball:",
|
|
);
|
|
});
|
|
|
|
test("view.remove_reaction (last person)", () => {
|
|
const opts = {
|
|
message_id: 507,
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "8ball",
|
|
emoji_code: "1f3b1",
|
|
user_id: bob.user_id,
|
|
user_list: [],
|
|
};
|
|
|
|
const $our_reaction = stub_reaction(opts.message_id, "unicode_emoji,1f3b1");
|
|
|
|
let removed;
|
|
$our_reaction.remove = () => {
|
|
removed = true;
|
|
};
|
|
reactions.view.remove_reaction(opts);
|
|
assert.ok(removed);
|
|
});
|
|
|
|
test("error_handling", ({override, override_rewire}) => {
|
|
override(message_store, "get", () => {});
|
|
|
|
blueslip.expect("error", "reactions: Bad message id: 55");
|
|
|
|
const bogus_event = {
|
|
message_id: 55,
|
|
reaction_type: "realm_emoji",
|
|
emoji_name: "realm_emoji",
|
|
emoji_code: "991",
|
|
user_id: 99,
|
|
};
|
|
override_rewire(reactions, "current_user_has_reacted_to_emoji", () => true);
|
|
reactions.toggle_emoji_reaction(55, bogus_event.emoji_name);
|
|
|
|
reactions.add_reaction(bogus_event);
|
|
reactions.remove_reaction(bogus_event);
|
|
});
|
|
|
|
test("remove spurious user", ({override}) => {
|
|
// get coverage for removing non-user (it should just
|
|
// silently fail)
|
|
|
|
const message = {...sample_message};
|
|
override(message_store, "get", () => message);
|
|
|
|
const event = {
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "frown",
|
|
emoji_code: "1f641",
|
|
message_id: message.id,
|
|
user_id: alice.user_id,
|
|
};
|
|
|
|
reactions.remove_reaction(event);
|
|
});
|
|
|
|
test("remove last user", ({override}) => {
|
|
const message = {...sample_message};
|
|
|
|
override(message_store, "get", () => message);
|
|
override(reactions.view, "remove_reaction", () => {});
|
|
|
|
function assert_names(names) {
|
|
assert.deepEqual(
|
|
reactions.get_message_reactions(message).map((r) => r.emoji_name),
|
|
names,
|
|
);
|
|
}
|
|
|
|
assert_names(["smile", "frown", "tada", "rocket", "wave", "inactive_realm_emoji"]);
|
|
|
|
const event = {
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "frown",
|
|
emoji_code: "1f641",
|
|
message_id: message.id,
|
|
user_id: cali.user_id,
|
|
};
|
|
reactions.remove_reaction(event);
|
|
|
|
assert_names(["smile", "tada", "rocket", "wave", "inactive_realm_emoji"]);
|
|
});
|
|
|
|
test("local_reaction_id", () => {
|
|
const reaction_info = {
|
|
reaction_type: "unicode_emoji",
|
|
emoji_code: "1f44d",
|
|
};
|
|
const local_id = reactions.get_local_reaction_id(reaction_info);
|
|
assert.equal(local_id, "unicode_emoji,1f44d");
|
|
});
|
|
|
|
test("process_reaction_click", ({override}) => {
|
|
override(reactions.view, "remove_reaction", () => {});
|
|
|
|
const message = {...sample_message};
|
|
override(message_store, "get", () => message);
|
|
|
|
const expected_reaction_info = {
|
|
reaction_type: "unicode_emoji",
|
|
emoji_name: "smile",
|
|
emoji_code: "1f642",
|
|
};
|
|
|
|
// Test spectator cannot react.
|
|
page_params.is_spectator = true;
|
|
let stub = make_stub();
|
|
spectators.login_to_access = stub.f;
|
|
reactions.process_reaction_click(message.id, "unicode_emoji,1f642");
|
|
let args = stub.get_args("args").args;
|
|
assert.equal(args, undefined);
|
|
|
|
page_params.is_spectator = false;
|
|
stub = make_stub();
|
|
channel.del = stub.f;
|
|
reactions.process_reaction_click(message.id, "unicode_emoji,1f642");
|
|
assert.equal(stub.num_calls, 1);
|
|
args = stub.get_args("args").args;
|
|
assert.equal(args.url, "/json/messages/1001/reactions");
|
|
assert.deepEqual(args.data, expected_reaction_info);
|
|
});
|
|
|
|
test("warnings", () => {
|
|
const message = {
|
|
id: 3001,
|
|
reactions: [
|
|
{emoji_name: "smile", user_id: 5, reaction_type: "unicode_emoji", emoji_code: "1f642"},
|
|
// add some bogus user_ids
|
|
{
|
|
emoji_name: "octopus",
|
|
user_id: 8888,
|
|
reaction_type: "unicode_emoji",
|
|
emoji_code: "1f419",
|
|
},
|
|
{
|
|
emoji_name: "frown",
|
|
user_id: 9999,
|
|
reaction_type: "unicode_emoji",
|
|
emoji_code: "1f641",
|
|
},
|
|
],
|
|
};
|
|
blueslip.expect("warn", "Unknown user_id 8888 in reaction for message 3001");
|
|
blueslip.expect("warn", "Unknown user_id 9999 in reaction for message 3001");
|
|
reactions.get_message_reactions(message);
|
|
});
|
|
|
|
test("code coverage", ({override}) => {
|
|
/*
|
|
We just silently fail in a few places in the reaction
|
|
code, since events may come for messages that we don't
|
|
have yet, or reactions may be for deactivated users, etc.
|
|
|
|
Here we just cheaply ensure 100% line coverage to make
|
|
it easy to enforce 100% coverage for more significant
|
|
code additions.
|
|
*/
|
|
override(message_store, "get", (id) => {
|
|
assert.equal(id, 42);
|
|
return {
|
|
reactions: [],
|
|
};
|
|
});
|
|
|
|
reactions.remove_reaction({
|
|
message_id: 42, // TODO: REACTIONS API
|
|
});
|
|
});
|
|
|
|
test("duplicates", () => {
|
|
const dup_reaction_message = {
|
|
id: 1001,
|
|
reactions: [
|
|
{emoji_name: "smile", user_id: 5, reaction_type: "unicode_emoji", emoji_code: "1f642"},
|
|
{emoji_name: "smile", user_id: 5, reaction_type: "unicode_emoji", emoji_code: "1f642"},
|
|
],
|
|
};
|
|
|
|
blueslip.expect(
|
|
"error",
|
|
"server sent duplicate reactions for user 5 (key=unicode_emoji,1f642)",
|
|
);
|
|
reactions.set_clean_reactions(dup_reaction_message);
|
|
});
|
|
|
|
test("process_reaction_click undefined", ({override}) => {
|
|
override(message_store, "get", () => undefined);
|
|
blueslip.expect("error", "reactions: Bad message id: 55");
|
|
blueslip.expect("error", "message_id for reaction click is unknown: 55");
|
|
reactions.process_reaction_click(55, "whatever");
|
|
});
|
|
|
|
test("process_reaction_click bad local id", ({override}) => {
|
|
const stub_message = {id: 4001, reactions: []};
|
|
override(message_store, "get", () => stub_message);
|
|
blueslip.expect(
|
|
"error",
|
|
"Data integrity problem for reaction bad-local-id (message some-msg-id)",
|
|
);
|
|
reactions.process_reaction_click("some-msg-id", "bad-local-id");
|
|
});
|