2020-08-01 03:43:15 +02:00
|
|
|
"use strict";
|
|
|
|
|
2020-11-30 23:46:45 +01:00
|
|
|
const {strict: assert} = require("assert");
|
|
|
|
|
2024-04-04 00:53:08 +02:00
|
|
|
const {$t} = require("./lib/i18n");
|
2023-02-22 23:04:10 +01:00
|
|
|
const {mock_cjs, mock_esm, zrequire} = require("./lib/namespace");
|
2023-12-14 23:51:33 +01:00
|
|
|
const {run_test, noop} = require("./lib/test");
|
2023-02-22 23:04:10 +01:00
|
|
|
const blueslip = require("./lib/zblueslip");
|
|
|
|
const $ = require("./lib/zjquery");
|
2024-02-13 02:08:24 +01:00
|
|
|
const {realm, user_settings} = require("./lib/zpage_params");
|
2020-12-01 00:02:16 +01:00
|
|
|
|
2021-05-25 20:47:17 +02:00
|
|
|
let clipboard_args;
|
|
|
|
class Clipboard {
|
|
|
|
constructor(...args) {
|
|
|
|
clipboard_args = args;
|
|
|
|
}
|
2023-06-29 21:59:08 +02:00
|
|
|
on(_success, show_copied_confirmation) {
|
2023-02-21 16:45:12 +01:00
|
|
|
show_copied_confirmation();
|
|
|
|
}
|
2021-05-25 20:47:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
mock_cjs("clipboard", Clipboard);
|
|
|
|
|
2023-02-22 23:04:10 +01:00
|
|
|
const realm_playground = mock_esm("../src/realm_playground");
|
2023-09-23 10:07:32 +02:00
|
|
|
const copied_tooltip = mock_esm("../src/copied_tooltip");
|
2021-07-28 16:00:58 +02:00
|
|
|
user_settings.emojiset = "apple";
|
2020-12-01 23:21:38 +01:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
const rm = zrequire("rendered_markdown");
|
2020-08-20 21:24:06 +02:00
|
|
|
const people = zrequire("people");
|
2021-02-10 04:53:22 +01:00
|
|
|
const user_groups = zrequire("user_groups");
|
|
|
|
const stream_data = zrequire("stream_data");
|
2024-02-20 01:25:16 +01:00
|
|
|
const rows = mock_esm("../src/rows");
|
|
|
|
const message_store = mock_esm("../src/message_store");
|
2024-06-12 12:04:08 +02:00
|
|
|
mock_esm("../src/settings_data", {
|
|
|
|
user_can_access_all_other_users: () => false,
|
|
|
|
});
|
2020-07-15 01:29:15 +02:00
|
|
|
|
2020-05-21 05:39:58 +02:00
|
|
|
const iago = {
|
2020-07-15 01:29:15 +02:00
|
|
|
email: "iago@zulip.com",
|
2020-05-21 05:39:58 +02:00
|
|
|
user_id: 30,
|
2020-07-15 01:29:15 +02:00
|
|
|
full_name: "Iago",
|
2020-05-21 05:39:58 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
const cordelia = {
|
2021-05-25 22:22:09 +02:00
|
|
|
email: "cordelia@zulip.com",
|
2020-05-21 05:39:58 +02:00
|
|
|
user_id: 31,
|
2021-05-25 22:22:09 +02:00
|
|
|
full_name: "Cordelia Lear",
|
2020-05-21 05:39:58 +02:00
|
|
|
};
|
2023-09-14 17:09:41 +02:00
|
|
|
|
|
|
|
const polonius = {
|
|
|
|
email: "polonius@zulip.com",
|
|
|
|
user_id: 32,
|
|
|
|
full_name: "Polonius",
|
|
|
|
is_guest: true,
|
|
|
|
};
|
2023-12-01 12:18:25 +01:00
|
|
|
const inaccessible_user_id = 33;
|
|
|
|
const inaccessible_user = people.add_inaccessible_user(inaccessible_user_id);
|
2020-05-21 05:39:58 +02:00
|
|
|
people.init();
|
2020-05-26 22:34:15 +02:00
|
|
|
people.add_active_user(iago);
|
|
|
|
people.add_active_user(cordelia);
|
2023-09-14 17:09:41 +02:00
|
|
|
people.add_active_user(polonius);
|
2020-05-21 05:39:58 +02:00
|
|
|
people.initialize_current_user(iago.user_id);
|
|
|
|
|
|
|
|
const group_me = {
|
2020-07-15 01:29:15 +02:00
|
|
|
name: "my user group",
|
2020-05-21 05:39:58 +02:00
|
|
|
id: 1,
|
|
|
|
members: [iago.user_id, cordelia.user_id],
|
|
|
|
};
|
|
|
|
const group_other = {
|
2020-07-15 01:29:15 +02:00
|
|
|
name: "other user group",
|
2020-05-21 05:39:58 +02:00
|
|
|
id: 2,
|
|
|
|
members: [cordelia.user_id],
|
|
|
|
};
|
|
|
|
user_groups.initialize({
|
|
|
|
realm_user_groups: [group_me, group_other],
|
|
|
|
});
|
|
|
|
|
2020-05-21 05:57:15 +02:00
|
|
|
const stream = {
|
|
|
|
subscribed: true,
|
2020-07-15 01:29:15 +02:00
|
|
|
color: "yellow",
|
|
|
|
name: "test",
|
2020-05-21 05:57:15 +02:00
|
|
|
stream_id: 3,
|
|
|
|
is_muted: true,
|
|
|
|
invite_only: false,
|
|
|
|
};
|
|
|
|
stream_data.add_sub(stream);
|
|
|
|
|
2020-05-21 05:27:04 +02:00
|
|
|
const $array = (array) => {
|
|
|
|
const each = (func) => {
|
2021-01-22 22:29:08 +01:00
|
|
|
for (const e of array) {
|
2020-05-21 05:27:04 +02:00
|
|
|
func.call(e);
|
2021-01-22 22:29:08 +01:00
|
|
|
}
|
2020-05-21 05:27:04 +02:00
|
|
|
};
|
|
|
|
return {each};
|
|
|
|
};
|
|
|
|
|
2023-11-23 17:17:37 +01:00
|
|
|
function set_message_for_message_content($content, value) {
|
|
|
|
// no message row found
|
|
|
|
if (value === undefined) {
|
|
|
|
$content.closest = (closest_opts) => {
|
|
|
|
assert.equal(closest_opts, ".message_row");
|
|
|
|
return [];
|
2023-06-15 07:15:50 +02:00
|
|
|
};
|
2023-11-23 17:17:37 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
// message row found
|
|
|
|
const $message_row = $.create(".message-row");
|
|
|
|
$content.closest = (closest_opts) => {
|
|
|
|
assert.equal(closest_opts, ".message_row");
|
|
|
|
return $message_row;
|
|
|
|
};
|
|
|
|
$message_row.length = 1;
|
|
|
|
$message_row.closest = (closest_opts) => {
|
|
|
|
assert.equal(closest_opts, ".overlay-message-row");
|
|
|
|
return [];
|
|
|
|
};
|
|
|
|
const message_id = 100;
|
|
|
|
rows.id = (message_row) => {
|
|
|
|
assert.equal(message_row, $message_row);
|
|
|
|
return message_id;
|
|
|
|
};
|
|
|
|
message_store.get = (message_id_opt) => {
|
|
|
|
assert.equal(message_id_opt, message_id);
|
|
|
|
return value;
|
2023-06-15 07:15:50 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-05-21 05:27:04 +02:00
|
|
|
const get_content_element = () => {
|
2021-05-25 22:33:32 +02:00
|
|
|
const $content = $.create("content-stub");
|
2020-07-15 01:29:15 +02:00
|
|
|
$content.set_find_results(".user-mention", $array([]));
|
2023-11-03 15:46:14 +01:00
|
|
|
$content.set_find_results(".topic-mention", $array([]));
|
2020-07-15 01:29:15 +02:00
|
|
|
$content.set_find_results(".user-group-mention", $array([]));
|
|
|
|
$content.set_find_results("a.stream", $array([]));
|
|
|
|
$content.set_find_results("a.stream-topic", $array([]));
|
|
|
|
$content.set_find_results("time", $array([]));
|
|
|
|
$content.set_find_results("span.timestamp-error", $array([]));
|
|
|
|
$content.set_find_results(".emoji", $array([]));
|
|
|
|
$content.set_find_results("div.spoiler-header", $array([]));
|
2020-08-20 16:11:08 +02:00
|
|
|
$content.set_find_results("div.codehilite", $array([]));
|
2023-09-14 05:20:31 +02:00
|
|
|
$content.set_find_results(".message_inline_video video", $array([]));
|
2024-07-13 07:03:16 +02:00
|
|
|
|
2023-11-23 17:17:37 +01:00
|
|
|
set_message_for_message_content($content, undefined);
|
2021-05-26 13:42:16 +02:00
|
|
|
|
|
|
|
// Fend off dumb security bugs by forcing devs to be
|
|
|
|
// intentional about HTML manipulation.
|
2022-04-09 23:44:38 +02:00
|
|
|
/* istanbul ignore next */
|
2021-05-26 13:42:16 +02:00
|
|
|
function security_violation() {
|
|
|
|
throw new Error(`
|
|
|
|
Be super careful about HTML manipulation.
|
|
|
|
|
|
|
|
Make sure your test objects set up their own
|
|
|
|
functions to validate that calls to html/prepend/append
|
|
|
|
use trusted values.
|
|
|
|
`);
|
|
|
|
}
|
|
|
|
$content.html = security_violation;
|
|
|
|
$content.prepend = security_violation;
|
|
|
|
$content.append = security_violation;
|
2020-05-21 05:27:04 +02:00
|
|
|
return $content;
|
|
|
|
};
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("misc_helpers", () => {
|
2022-01-25 11:36:19 +01:00
|
|
|
const $elem = $.create("user-mention");
|
|
|
|
rm.set_name_in_mention_element($elem, "Aaron");
|
|
|
|
assert.equal($elem.text(), "@Aaron");
|
|
|
|
$elem.addClass("silent");
|
|
|
|
rm.set_name_in_mention_element($elem, "Aaron, but silent");
|
|
|
|
assert.equal($elem.text(), "Aaron, but silent");
|
2023-09-14 17:09:41 +02:00
|
|
|
|
2024-02-13 02:08:24 +01:00
|
|
|
realm.realm_enable_guest_user_indicator = true;
|
2023-09-14 17:09:41 +02:00
|
|
|
rm.set_name_in_mention_element($elem, "Polonius", polonius.user_id);
|
|
|
|
assert.equal($elem.text(), "translated: Polonius (guest)");
|
|
|
|
|
2024-02-13 02:08:24 +01:00
|
|
|
realm.realm_enable_guest_user_indicator = false;
|
2023-09-14 17:09:41 +02:00
|
|
|
rm.set_name_in_mention_element($elem, "Polonius", polonius.user_id);
|
|
|
|
assert.equal($elem.text(), "Polonius");
|
2020-05-21 04:15:27 +02:00
|
|
|
});
|
2020-05-21 05:27:04 +02:00
|
|
|
|
2023-09-14 05:20:31 +02:00
|
|
|
run_test("message_inline_video", () => {
|
|
|
|
const $content = get_content_element();
|
|
|
|
const $elem = $.create("message_inline_video");
|
|
|
|
|
|
|
|
let load_called = false;
|
|
|
|
$elem.load = () => {
|
|
|
|
load_called = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
$content.set_find_results(".message_inline_video video", $array([$elem]));
|
|
|
|
window.GestureEvent = true;
|
|
|
|
rm.update_elements($content);
|
|
|
|
assert.equal(load_called, true);
|
|
|
|
window.GestureEvent = false;
|
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("user-mention", () => {
|
2020-05-21 05:27:04 +02:00
|
|
|
// Setup
|
|
|
|
const $content = get_content_element();
|
2021-05-25 22:33:32 +02:00
|
|
|
const $iago = $.create("user-mention(iago)");
|
2020-07-15 01:29:15 +02:00
|
|
|
$iago.set_find_results(".highlight", false);
|
|
|
|
$iago.attr("data-user-id", iago.user_id);
|
2021-05-25 22:33:32 +02:00
|
|
|
const $cordelia = $.create("user-mention(cordelia)");
|
2020-07-15 01:29:15 +02:00
|
|
|
$cordelia.set_find_results(".highlight", false);
|
|
|
|
$cordelia.attr("data-user-id", cordelia.user_id);
|
2023-09-14 17:09:41 +02:00
|
|
|
const $polonius = $.create("user-mention(polonius)");
|
|
|
|
$polonius.set_find_results(".highlight", false);
|
|
|
|
$polonius.attr("data-user-id", polonius.user_id);
|
|
|
|
$content.set_find_results(".user-mention", $array([$iago, $cordelia, $polonius]));
|
2024-02-13 02:08:24 +01:00
|
|
|
realm.realm_enable_guest_user_indicator = true;
|
2020-05-21 05:27:04 +02:00
|
|
|
// Initial asserts
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(!$iago.hasClass("user-mention-me"));
|
2020-07-15 01:29:15 +02:00
|
|
|
assert.equal($iago.text(), "never-been-set");
|
|
|
|
assert.equal($cordelia.text(), "never-been-set");
|
2023-09-14 17:09:41 +02:00
|
|
|
assert.equal($polonius.text(), "never-been-set");
|
2020-05-21 05:27:04 +02:00
|
|
|
|
|
|
|
rm.update_elements($content);
|
2023-11-23 17:17:37 +01:00
|
|
|
assert.ok(!$iago.hasClass("user-mention-me"));
|
2020-05-21 05:27:04 +02:00
|
|
|
assert.equal($iago.text(), `@${iago.full_name}`);
|
|
|
|
assert.equal($cordelia.text(), `@${cordelia.full_name}`);
|
2023-09-14 17:09:41 +02:00
|
|
|
assert.equal($polonius.text(), `translated: @${polonius.full_name} (guest)`);
|
2023-11-23 17:17:37 +01:00
|
|
|
|
|
|
|
// message row found
|
|
|
|
const message = {mentioned_me_directly: true};
|
|
|
|
set_message_for_message_content($content, message);
|
|
|
|
rm.update_elements($content);
|
|
|
|
assert.ok($iago.hasClass("user-mention-me"));
|
2023-09-14 17:09:41 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
run_test("user-mention without guest indicator", () => {
|
|
|
|
const $content = get_content_element();
|
|
|
|
const $polonius = $.create("user-mention(polonius-again)");
|
|
|
|
$polonius.set_find_results(".highlight", false);
|
|
|
|
$polonius.attr("data-user-id", polonius.user_id);
|
|
|
|
$content.set_find_results(".user-mention", $array([$polonius]));
|
|
|
|
|
2024-02-13 02:08:24 +01:00
|
|
|
realm.realm_enable_guest_user_indicator = false;
|
2023-09-14 17:09:41 +02:00
|
|
|
rm.update_elements($content);
|
|
|
|
assert.equal($polonius.text(), `@${polonius.full_name}`);
|
2020-05-21 05:27:04 +02:00
|
|
|
});
|
2020-05-21 05:39:58 +02:00
|
|
|
|
2023-12-01 12:18:25 +01:00
|
|
|
run_test("user-mention of inaccessible users", () => {
|
|
|
|
const $content = get_content_element();
|
|
|
|
const $othello = $.create("user-mention(othello)");
|
|
|
|
$othello.set_find_results(".highlight", false);
|
|
|
|
$othello.attr("data-user-id", inaccessible_user_id);
|
|
|
|
$othello.text("@Othello");
|
|
|
|
$content.set_find_results(".user-mention", $array([$othello]));
|
|
|
|
|
|
|
|
rm.update_elements($content);
|
|
|
|
assert.equal($othello.text(), "@Othello");
|
|
|
|
assert.notEqual($othello.text(), `@${inaccessible_user.full_name}`);
|
|
|
|
|
|
|
|
// Test inaccessible user id with no user object.
|
|
|
|
const $cordelia = $.create("user-mention(cordelia)");
|
|
|
|
$cordelia.set_find_results(".highlight", false);
|
|
|
|
$cordelia.attr("data-user-id", 40);
|
|
|
|
$cordelia.text("@Cordelia");
|
|
|
|
$content.set_find_results(".user-mention", $array([$cordelia]));
|
|
|
|
|
|
|
|
rm.update_elements($content);
|
|
|
|
assert.equal($cordelia.text(), "@Cordelia");
|
|
|
|
});
|
|
|
|
|
2023-11-23 17:17:37 +01:00
|
|
|
run_test("user-mention (stream wildcard)", () => {
|
2021-05-25 22:16:25 +02:00
|
|
|
// Setup
|
|
|
|
const $content = get_content_element();
|
|
|
|
const $mention = $.create("mention");
|
|
|
|
$mention.attr("data-user-id", "*");
|
|
|
|
$content.set_find_results(".user-mention", $array([$mention]));
|
2023-11-23 17:17:37 +01:00
|
|
|
const message = {stream_wildcard_mentioned: true};
|
|
|
|
set_message_for_message_content($content, message);
|
2021-05-25 22:16:25 +02:00
|
|
|
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(!$mention.hasClass("user-mention-me"));
|
2021-05-25 22:16:25 +02:00
|
|
|
rm.update_elements($content);
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok($mention.hasClass("user-mention-me"));
|
2021-05-25 22:16:25 +02:00
|
|
|
});
|
|
|
|
|
2021-05-25 22:22:09 +02:00
|
|
|
run_test("user-mention (email)", () => {
|
|
|
|
// Setup
|
|
|
|
const $content = get_content_element();
|
|
|
|
const $mention = $.create("mention");
|
|
|
|
$mention.attr("data-user-email", cordelia.email);
|
|
|
|
$mention.set_find_results(".highlight", false);
|
|
|
|
$content.set_find_results(".user-mention", $array([$mention]));
|
|
|
|
|
|
|
|
rm.update_elements($content);
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(!$mention.hasClass("user-mention-me"));
|
2021-05-25 22:22:09 +02:00
|
|
|
assert.equal($mention.text(), "@Cordelia Lear");
|
|
|
|
});
|
|
|
|
|
2021-05-25 22:29:33 +02:00
|
|
|
run_test("user-mention (missing)", () => {
|
|
|
|
const $content = get_content_element();
|
|
|
|
const $mention = $.create("mention");
|
|
|
|
$content.set_find_results(".user-mention", $array([$mention]));
|
|
|
|
|
|
|
|
rm.update_elements($content);
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(!$mention.hasClass("user-mention-me"));
|
2021-05-25 22:29:33 +02:00
|
|
|
});
|
|
|
|
|
2023-11-03 15:46:14 +01:00
|
|
|
run_test("topic-mention", () => {
|
|
|
|
// Setup
|
|
|
|
const $content = get_content_element();
|
|
|
|
const $mention = $.create("mention");
|
|
|
|
$content.set_find_results(".topic-mention", $array([$mention]));
|
|
|
|
|
2023-11-23 17:17:37 +01:00
|
|
|
// when no message row found
|
2023-11-03 15:46:14 +01:00
|
|
|
assert.ok(!$mention.hasClass("user-mention-me"));
|
|
|
|
rm.update_elements($content);
|
|
|
|
assert.ok(!$mention.hasClass("user-mention-me"));
|
|
|
|
|
|
|
|
// message row found
|
|
|
|
const message = {
|
|
|
|
topic_wildcard_mentioned: true,
|
|
|
|
};
|
2023-11-23 17:17:37 +01:00
|
|
|
set_message_for_message_content($content, message);
|
2023-11-03 15:46:14 +01:00
|
|
|
|
|
|
|
assert.ok(!$mention.hasClass("user-mention-me"));
|
|
|
|
rm.update_elements($content);
|
|
|
|
assert.ok($mention.hasClass("user-mention-me"));
|
|
|
|
});
|
|
|
|
|
|
|
|
run_test("topic-mention not topic participant", () => {
|
|
|
|
// Setup
|
|
|
|
const $content = get_content_element();
|
|
|
|
const $mention = $.create("mention");
|
|
|
|
$content.set_find_results(".topic-mention", $array([$mention]));
|
2023-11-23 17:17:37 +01:00
|
|
|
|
2023-11-03 15:46:14 +01:00
|
|
|
const message = {
|
|
|
|
topic_wildcard_mentioned: false,
|
|
|
|
};
|
2023-11-23 17:17:37 +01:00
|
|
|
set_message_for_message_content($content, message);
|
2023-11-03 15:46:14 +01:00
|
|
|
|
|
|
|
assert.ok(!$mention.hasClass("user-mention-me"));
|
|
|
|
rm.update_elements($content);
|
|
|
|
assert.ok(!$mention.hasClass("user-mention-me"));
|
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("user-group-mention", () => {
|
2020-05-21 05:39:58 +02:00
|
|
|
// Setup
|
|
|
|
const $content = get_content_element();
|
2021-05-25 22:33:32 +02:00
|
|
|
const $group_me = $.create("user-group-mention(me)");
|
2020-07-15 01:29:15 +02:00
|
|
|
$group_me.set_find_results(".highlight", false);
|
|
|
|
$group_me.attr("data-user-group-id", group_me.id);
|
2021-05-25 22:33:32 +02:00
|
|
|
const $group_other = $.create("user-group-mention(other)");
|
2020-07-15 01:29:15 +02:00
|
|
|
$group_other.set_find_results(".highlight", false);
|
|
|
|
$group_other.attr("data-user-group-id", group_other.id);
|
|
|
|
$content.set_find_results(".user-group-mention", $array([$group_me, $group_other]));
|
2020-05-21 05:39:58 +02:00
|
|
|
|
|
|
|
// Initial asserts
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(!$group_me.hasClass("user-mention-me"));
|
2020-07-15 01:29:15 +02:00
|
|
|
assert.equal($group_me.text(), "never-been-set");
|
|
|
|
assert.equal($group_other.text(), "never-been-set");
|
2020-05-21 05:39:58 +02:00
|
|
|
|
|
|
|
rm.update_elements($content);
|
|
|
|
|
|
|
|
// Final asserts
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok($group_me.hasClass("user-mention-me"));
|
2020-05-21 05:39:58 +02:00
|
|
|
assert.equal($group_me.text(), `@${group_me.name}`);
|
|
|
|
assert.equal($group_other.text(), `@${group_other.name}`);
|
|
|
|
});
|
2020-05-21 05:57:15 +02:00
|
|
|
|
2021-05-25 21:45:11 +02:00
|
|
|
run_test("user-group-mention (error)", () => {
|
|
|
|
const $content = get_content_element();
|
2021-05-25 22:33:32 +02:00
|
|
|
const $group = $.create("user-group-mention(bogus)");
|
2021-05-25 21:45:11 +02:00
|
|
|
$group.attr("data-user-group-id", "not-even-a-number");
|
2021-05-25 22:29:33 +02:00
|
|
|
$content.set_find_results(".user-group-mention", $array([$group]));
|
|
|
|
|
|
|
|
rm.update_elements($content);
|
|
|
|
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(!$group.hasClass("user-mention-me"));
|
2021-05-25 22:29:33 +02:00
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("stream-links", () => {
|
2020-05-21 05:57:15 +02:00
|
|
|
// Setup
|
|
|
|
const $content = get_content_element();
|
2020-07-15 01:29:15 +02:00
|
|
|
const $stream = $.create("a.stream");
|
|
|
|
$stream.set_find_results(".highlight", false);
|
|
|
|
$stream.attr("data-stream-id", stream.stream_id);
|
|
|
|
const $stream_topic = $.create("a.stream-topic");
|
|
|
|
$stream_topic.set_find_results(".highlight", false);
|
|
|
|
$stream_topic.attr("data-stream-id", stream.stream_id);
|
2021-04-29 20:11:03 +02:00
|
|
|
$stream_topic.text("#random > topic name > still the topic name");
|
2020-07-15 01:29:15 +02:00
|
|
|
$content.set_find_results("a.stream", $array([$stream]));
|
|
|
|
$content.set_find_results("a.stream-topic", $array([$stream_topic]));
|
2020-05-21 05:57:15 +02:00
|
|
|
|
|
|
|
// Initial asserts
|
2020-07-15 01:29:15 +02:00
|
|
|
assert.equal($stream.text(), "never-been-set");
|
2021-04-29 20:11:03 +02:00
|
|
|
assert.equal($stream_topic.text(), "#random > topic name > still the topic name");
|
2020-05-21 05:57:15 +02:00
|
|
|
|
|
|
|
rm.update_elements($content);
|
|
|
|
|
|
|
|
// Final asserts
|
|
|
|
assert.equal($stream.text(), `#${stream.name}`);
|
2021-04-29 20:11:03 +02:00
|
|
|
assert.equal($stream_topic.text(), `#${stream.name} > topic name > still the topic name`);
|
2020-05-21 05:57:15 +02:00
|
|
|
});
|
2020-05-21 06:10:49 +02:00
|
|
|
|
2021-05-25 21:39:50 +02:00
|
|
|
run_test("timestamp without time", () => {
|
|
|
|
const $content = get_content_element();
|
2022-02-08 00:13:33 +01:00
|
|
|
const $timestamp = $.create("timestamp without actual time");
|
2021-05-25 21:39:50 +02:00
|
|
|
$content.set_find_results("time", $array([$timestamp]));
|
|
|
|
|
|
|
|
rm.update_elements($content);
|
|
|
|
assert.equal($timestamp.text(), "never-been-set");
|
|
|
|
});
|
|
|
|
|
2021-06-28 00:41:05 +02:00
|
|
|
run_test("timestamp", ({mock_template}) => {
|
|
|
|
mock_template("markdown_timestamp.hbs", true, (data, html) => {
|
2023-03-16 19:40:55 +01:00
|
|
|
assert.deepEqual(data, {text: "Thu, Jan 1, 1970, 12:00 AM"});
|
2021-06-27 19:31:29 +02:00
|
|
|
return html;
|
|
|
|
});
|
|
|
|
|
2018-02-13 00:33:36 +01:00
|
|
|
// Setup
|
|
|
|
const $content = get_content_element();
|
2020-07-15 01:29:15 +02:00
|
|
|
const $timestamp = $.create("timestamp(valid)");
|
|
|
|
$timestamp.attr("datetime", "1970-01-01T00:00:01Z");
|
|
|
|
const $timestamp_invalid = $.create("timestamp(invalid)");
|
|
|
|
$timestamp_invalid.attr("datetime", "invalid");
|
|
|
|
$content.set_find_results("time", $array([$timestamp, $timestamp_invalid]));
|
2023-04-24 15:57:45 +02:00
|
|
|
blueslip.expect("error", "Could not parse datetime supplied by backend");
|
2018-02-13 00:33:36 +01:00
|
|
|
|
|
|
|
// Initial asserts
|
2020-07-15 01:29:15 +02:00
|
|
|
assert.equal($timestamp.text(), "never-been-set");
|
|
|
|
assert.equal($timestamp_invalid.text(), "never-been-set");
|
2018-02-13 00:33:36 +01:00
|
|
|
|
|
|
|
rm.update_elements($content);
|
|
|
|
|
|
|
|
// Final asserts
|
2024-08-01 22:24:13 +02:00
|
|
|
assert.equal(
|
|
|
|
$timestamp.html(),
|
2024-08-21 21:08:03 +02:00
|
|
|
'<span class="timestamp-content-wrapper">\n <i class="zulip-icon zulip-icon-clock markdown-timestamp-icon"></i>Thu, Jan 1, 1970, 12:00 AM</span>',
|
2024-08-01 22:24:13 +02:00
|
|
|
);
|
2020-07-15 01:29:15 +02:00
|
|
|
assert.equal($timestamp_invalid.text(), "never-been-set");
|
2018-02-13 00:33:36 +01:00
|
|
|
});
|
|
|
|
|
2022-07-09 23:25:05 +02:00
|
|
|
run_test("timestamp-twenty-four-hour-time", ({mock_template, override}) => {
|
2021-06-28 00:41:05 +02:00
|
|
|
mock_template("markdown_timestamp.hbs", true, (data, html) => {
|
2021-06-27 19:31:29 +02:00
|
|
|
// sanity check incoming data
|
2023-01-08 18:08:49 +01:00
|
|
|
assert.ok(data.text.startsWith("Wed, Jul 15, 2020, "));
|
2021-06-27 19:31:29 +02:00
|
|
|
return html;
|
|
|
|
});
|
|
|
|
|
2020-07-15 23:54:22 +02:00
|
|
|
const $content = get_content_element();
|
2020-07-15 01:29:15 +02:00
|
|
|
const $timestamp = $.create("timestamp");
|
|
|
|
$timestamp.attr("datetime", "2020-07-15T20:40:00Z");
|
|
|
|
$content.set_find_results("time", $array([$timestamp]));
|
2020-07-15 23:54:22 +02:00
|
|
|
|
|
|
|
// We will temporarily change the 24h setting for this test.
|
2022-07-09 23:25:05 +02:00
|
|
|
override(user_settings, "twenty_four_hour_time", true);
|
|
|
|
rm.update_elements($content);
|
2024-08-01 22:24:13 +02:00
|
|
|
assert.equal(
|
|
|
|
$timestamp.html(),
|
2024-08-21 21:08:03 +02:00
|
|
|
'<span class="timestamp-content-wrapper">\n <i class="zulip-icon zulip-icon-clock markdown-timestamp-icon"></i>Wed, Jul 15, 2020, 20:40</span>',
|
2024-08-01 22:24:13 +02:00
|
|
|
);
|
2020-12-01 23:21:38 +01:00
|
|
|
|
2022-07-09 23:25:05 +02:00
|
|
|
override(user_settings, "twenty_four_hour_time", false);
|
|
|
|
rm.update_elements($content);
|
2024-08-01 22:24:13 +02:00
|
|
|
assert.equal(
|
|
|
|
$timestamp.html(),
|
2024-08-21 21:08:03 +02:00
|
|
|
'<span class="timestamp-content-wrapper">\n <i class="zulip-icon zulip-icon-clock markdown-timestamp-icon"></i>Wed, Jul 15, 2020, 8:40 PM</span>',
|
2024-08-01 22:24:13 +02:00
|
|
|
);
|
2020-07-15 23:54:22 +02:00
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("timestamp-error", () => {
|
2020-07-06 17:07:44 +02:00
|
|
|
// Setup
|
|
|
|
const $content = get_content_element();
|
2020-07-15 01:29:15 +02:00
|
|
|
const $timestamp_error = $.create("timestamp-error");
|
|
|
|
$timestamp_error.text("Invalid time format: the-time-format");
|
|
|
|
$content.set_find_results("span.timestamp-error", $array([$timestamp_error]));
|
2020-07-06 17:07:44 +02:00
|
|
|
|
|
|
|
// Initial assert
|
2020-07-15 01:29:15 +02:00
|
|
|
assert.equal($timestamp_error.text(), "Invalid time format: the-time-format");
|
2020-07-06 17:07:44 +02:00
|
|
|
|
|
|
|
rm.update_elements($content);
|
|
|
|
|
|
|
|
// Final assert
|
2020-07-15 01:29:15 +02:00
|
|
|
assert.equal($timestamp_error.text(), "translated: Invalid time format: the-time-format");
|
2020-07-06 17:07:44 +02:00
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("emoji", () => {
|
2020-05-21 06:10:49 +02:00
|
|
|
// Setup
|
|
|
|
const $content = get_content_element();
|
2021-05-25 22:33:32 +02:00
|
|
|
const $emoji = $.create("emoji-stub");
|
2020-07-15 01:29:15 +02:00
|
|
|
$emoji.attr("title", "tada");
|
2020-05-21 06:10:49 +02:00
|
|
|
let called = false;
|
2024-04-03 02:50:42 +02:00
|
|
|
$emoji.text = (f) => {
|
2020-05-21 06:10:49 +02:00
|
|
|
const text = f.call($emoji);
|
2020-07-15 01:29:15 +02:00
|
|
|
assert.equal(":tada:", text);
|
2020-05-21 06:10:49 +02:00
|
|
|
called = true;
|
2024-04-03 02:50:42 +02:00
|
|
|
return {contents: () => ({unwrap() {}})};
|
2020-05-21 06:10:49 +02:00
|
|
|
};
|
2020-07-15 01:29:15 +02:00
|
|
|
$content.set_find_results(".emoji", $emoji);
|
2021-07-28 16:00:58 +02:00
|
|
|
user_settings.emojiset = "text";
|
2020-05-21 06:10:49 +02:00
|
|
|
|
|
|
|
rm.update_elements($content);
|
|
|
|
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(called);
|
2020-04-04 22:14:34 +02:00
|
|
|
|
2020-08-11 01:47:44 +02:00
|
|
|
// Set page parameters back so that test run order is independent
|
2021-07-28 16:00:58 +02:00
|
|
|
user_settings.emojiset = "apple";
|
2020-04-04 22:14:34 +02:00
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("spoiler-header", () => {
|
2020-04-04 22:14:34 +02:00
|
|
|
// Setup
|
|
|
|
const $content = get_content_element();
|
2020-07-15 01:29:15 +02:00
|
|
|
const $header = $.create("div.spoiler-header");
|
|
|
|
$content.set_find_results("div.spoiler-header", $array([$header]));
|
2024-04-12 21:53:48 +02:00
|
|
|
let $appended;
|
|
|
|
$header.append = ($element) => {
|
|
|
|
$appended = $element;
|
2024-04-04 00:53:08 +02:00
|
|
|
};
|
2020-04-04 22:14:34 +02:00
|
|
|
|
2020-07-06 17:11:58 +02:00
|
|
|
// Test that the show/hide button gets added to a spoiler header.
|
2021-05-10 07:02:14 +02:00
|
|
|
const label = "My spoiler header";
|
2020-07-15 00:34:28 +02:00
|
|
|
const toggle_button_html =
|
|
|
|
'<span class="spoiler-button" aria-expanded="false"><span class="spoiler-arrow"></span></span>';
|
2020-04-04 22:14:34 +02:00
|
|
|
$header.html(label);
|
2024-09-02 09:52:14 +02:00
|
|
|
$header.set_find_results("p", $.create("p"));
|
2020-04-04 22:14:34 +02:00
|
|
|
rm.update_elements($content);
|
2024-04-04 00:53:08 +02:00
|
|
|
assert.equal(label, $header.html());
|
2024-04-12 21:53:48 +02:00
|
|
|
assert.equal($appended.selector, toggle_button_html);
|
2020-04-04 22:14:34 +02:00
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("spoiler-header-empty-fill", () => {
|
2020-04-04 22:14:34 +02:00
|
|
|
// Setup
|
|
|
|
const $content = get_content_element();
|
2020-07-15 01:29:15 +02:00
|
|
|
const $header = $.create("div.spoiler-header");
|
|
|
|
$content.set_find_results("div.spoiler-header", $array([$header]));
|
2024-04-12 21:53:48 +02:00
|
|
|
const $appended = [];
|
2024-04-04 00:53:08 +02:00
|
|
|
$header.append = ($element) => {
|
2024-04-12 21:53:48 +02:00
|
|
|
$appended.push($element);
|
2024-04-04 00:53:08 +02:00
|
|
|
};
|
2020-04-04 22:14:34 +02:00
|
|
|
|
2020-07-06 17:11:58 +02:00
|
|
|
// Test that an empty header gets the default text applied (through i18n filter).
|
2020-07-15 00:34:28 +02:00
|
|
|
const toggle_button_html =
|
|
|
|
'<span class="spoiler-button" aria-expanded="false"><span class="spoiler-arrow"></span></span>';
|
2022-08-18 00:30:47 +02:00
|
|
|
$header.empty();
|
2024-09-02 09:52:14 +02:00
|
|
|
$header.set_find_results("p", $.create("p"));
|
2020-04-04 22:14:34 +02:00
|
|
|
rm.update_elements($content);
|
2024-04-12 21:53:48 +02:00
|
|
|
assert.equal($appended[0].selector, "<p>");
|
|
|
|
assert.equal($appended[0].text(), $t({defaultMessage: "Spoiler"}));
|
|
|
|
assert.equal($appended[1].selector, toggle_button_html);
|
2020-05-21 06:10:49 +02:00
|
|
|
});
|
2021-05-25 20:47:17 +02:00
|
|
|
|
|
|
|
function assert_clipboard_setup() {
|
|
|
|
assert.equal(clipboard_args[0], "copy-code-stub");
|
|
|
|
const text = clipboard_args[1].text({
|
|
|
|
to_$: () => ({
|
2024-04-26 20:57:30 +02:00
|
|
|
parent: () => ({
|
|
|
|
siblings(arg) {
|
|
|
|
assert.equal(arg, "code");
|
|
|
|
return {
|
|
|
|
text: () => "text",
|
|
|
|
};
|
|
|
|
},
|
|
|
|
}),
|
2021-05-25 20:47:17 +02:00
|
|
|
}),
|
|
|
|
});
|
|
|
|
assert.equal(text, "text");
|
|
|
|
}
|
|
|
|
|
2021-06-28 00:41:05 +02:00
|
|
|
function test_code_playground(mock_template, viewing_code) {
|
2021-05-25 20:47:17 +02:00
|
|
|
const $content = get_content_element();
|
|
|
|
const $hilite = $.create("div.codehilite");
|
|
|
|
const $pre = $.create("hilite-pre");
|
|
|
|
$content.set_find_results("div.codehilite", $array([$hilite]));
|
|
|
|
$hilite.set_find_results("pre", $pre);
|
|
|
|
|
2024-05-03 02:12:38 +02:00
|
|
|
$hilite.attr("data-code-language", "javascript");
|
2021-05-25 20:47:17 +02:00
|
|
|
|
2024-03-07 20:58:37 +01:00
|
|
|
const $code_buttons_container = $.create("code_buttons_container", {
|
|
|
|
children: ["copy-code-stub", "view-code-stub"],
|
|
|
|
});
|
2021-05-25 20:47:17 +02:00
|
|
|
const $copy_code_button = $.create("copy_code_button", {children: ["copy-code-stub"]});
|
|
|
|
const $view_code_in_playground = $.create("view_code_in_playground");
|
|
|
|
|
2024-03-07 20:58:37 +01:00
|
|
|
$code_buttons_container.set_find_results(".copy_codeblock", $copy_code_button);
|
|
|
|
$code_buttons_container.set_find_results(".code_external_link", $view_code_in_playground);
|
|
|
|
|
|
|
|
// The code playground code prepends a button container
|
2021-05-26 13:42:16 +02:00
|
|
|
// to the <pre> section of a highlighted piece of code.
|
|
|
|
// The args to prepend should be jQuery objects (or in
|
|
|
|
// our case "fake" zjquery objects).
|
2021-05-25 20:47:17 +02:00
|
|
|
const prepends = [];
|
|
|
|
$pre.prepend = (arg) => {
|
2022-04-09 23:44:38 +02:00
|
|
|
assert.ok(arg.__zjquery, "We should only prepend jQuery objects.");
|
2021-05-25 20:47:17 +02:00
|
|
|
prepends.push(arg);
|
|
|
|
};
|
|
|
|
|
2021-06-14 16:54:46 +02:00
|
|
|
if (viewing_code) {
|
2024-03-07 20:58:37 +01:00
|
|
|
mock_template("code_buttons_container.hbs", true, (data) => {
|
|
|
|
assert.equal(data.show_playground_button, true);
|
|
|
|
return {to_$: () => $code_buttons_container};
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
mock_template("code_buttons_container.hbs", true, (data) => {
|
|
|
|
assert.equal(data.show_playground_button, false);
|
|
|
|
return {to_$: () => $code_buttons_container};
|
2021-06-14 16:54:46 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-05-25 20:47:17 +02:00
|
|
|
rm.update_elements($content);
|
|
|
|
|
|
|
|
return {
|
|
|
|
prepends,
|
2024-03-07 20:58:37 +01:00
|
|
|
$button_container: $code_buttons_container,
|
2022-01-25 11:36:19 +01:00
|
|
|
$copy_code: $copy_code_button,
|
|
|
|
$view_code: $view_code_in_playground,
|
2021-05-25 20:47:17 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-06-28 00:41:05 +02:00
|
|
|
run_test("code playground none", ({override, mock_template}) => {
|
2021-05-25 20:47:17 +02:00
|
|
|
override(realm_playground, "get_playground_info_for_languages", (language) => {
|
|
|
|
assert.equal(language, "javascript");
|
|
|
|
return undefined;
|
|
|
|
});
|
|
|
|
|
2023-12-14 23:51:33 +01:00
|
|
|
override(copied_tooltip, "show_copied_confirmation", noop);
|
2023-02-21 16:45:12 +01:00
|
|
|
|
2024-03-07 20:58:37 +01:00
|
|
|
const {prepends, $button_container, $view_code} = test_code_playground(mock_template, false);
|
|
|
|
assert.deepEqual(prepends, [$button_container]);
|
2021-05-25 20:47:17 +02:00
|
|
|
assert_clipboard_setup();
|
|
|
|
|
2022-01-25 11:36:19 +01:00
|
|
|
assert.equal($view_code.attr("data-tippy-content"), undefined);
|
|
|
|
assert.equal($view_code.attr("aria-label"), undefined);
|
2021-05-25 20:47:17 +02:00
|
|
|
});
|
|
|
|
|
2021-06-28 00:41:05 +02:00
|
|
|
run_test("code playground single", ({override, mock_template}) => {
|
2021-05-25 20:47:17 +02:00
|
|
|
override(realm_playground, "get_playground_info_for_languages", (language) => {
|
|
|
|
assert.equal(language, "javascript");
|
|
|
|
return [{name: "Some Javascript Playground"}];
|
|
|
|
});
|
|
|
|
|
2023-12-14 23:51:33 +01:00
|
|
|
override(copied_tooltip, "show_copied_confirmation", noop);
|
2023-02-21 16:45:12 +01:00
|
|
|
|
2024-03-07 20:58:37 +01:00
|
|
|
const {prepends, $button_container, $view_code} = test_code_playground(mock_template, true);
|
|
|
|
assert.deepEqual(prepends, [$button_container]);
|
2021-05-25 20:47:17 +02:00
|
|
|
assert_clipboard_setup();
|
|
|
|
|
|
|
|
assert.equal(
|
2022-01-25 11:36:19 +01:00
|
|
|
$view_code.attr("data-tippy-content"),
|
2021-05-25 20:47:17 +02:00
|
|
|
"translated: View in Some Javascript Playground",
|
|
|
|
);
|
2022-01-25 11:36:19 +01:00
|
|
|
assert.equal($view_code.attr("aria-label"), "translated: View in Some Javascript Playground");
|
|
|
|
assert.equal($view_code.attr("aria-haspopup"), undefined);
|
2021-05-25 20:47:17 +02:00
|
|
|
});
|
|
|
|
|
2021-06-28 00:41:05 +02:00
|
|
|
run_test("code playground multiple", ({override, mock_template}) => {
|
2021-05-25 20:47:17 +02:00
|
|
|
override(realm_playground, "get_playground_info_for_languages", (language) => {
|
|
|
|
assert.equal(language, "javascript");
|
|
|
|
return ["whatever", "whatever"];
|
|
|
|
});
|
|
|
|
|
2023-12-14 23:51:33 +01:00
|
|
|
override(copied_tooltip, "show_copied_confirmation", noop);
|
2023-02-21 16:45:12 +01:00
|
|
|
|
2024-03-07 20:58:37 +01:00
|
|
|
const {prepends, $button_container, $view_code} = test_code_playground(mock_template, true);
|
|
|
|
assert.deepEqual(prepends, [$button_container]);
|
2021-05-25 20:47:17 +02:00
|
|
|
assert_clipboard_setup();
|
|
|
|
|
2022-01-25 11:36:19 +01:00
|
|
|
assert.equal($view_code.attr("data-tippy-content"), "translated: View in playground");
|
|
|
|
assert.equal($view_code.attr("aria-label"), "translated: View in playground");
|
|
|
|
assert.equal($view_code.attr("aria-haspopup"), "true");
|
2021-05-25 20:47:17 +02:00
|
|
|
});
|
2021-05-25 22:04:49 +02:00
|
|
|
|
|
|
|
run_test("rtl", () => {
|
|
|
|
const $content = get_content_element();
|
|
|
|
|
|
|
|
$content.text("مرحبا");
|
|
|
|
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(!$content.hasClass("rtl"));
|
2021-05-25 22:04:49 +02:00
|
|
|
rm.update_elements($content);
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok($content.hasClass("rtl"));
|
2021-05-25 22:04:49 +02:00
|
|
|
});
|