mirror of
https://github.com/zulip/zulip.git
synced 2025-11-06 06:53:25 +00:00
For spectators, the chunk of page_params that originates from do_events_register isn’t assigned until ui_init.js. That means the TypeScript type of page_params is mostly a lie during module load time: reading a parameter too early silently results in undefined rather than the declared type, with unpredictable results later on. We want to make such an early read into an immediate runtime error, for both users and spectators consistently, and pave the way for runtime validation of the page_params type. As a second step, split out the subset of fields that pertain to the entire realm. Signed-off-by: Anders Kaseorg <anders@zulip.com>
635 lines
22 KiB
JavaScript
635 lines
22 KiB
JavaScript
"use strict";
|
|
|
|
const {strict: assert} = require("assert");
|
|
|
|
const {mock_cjs, mock_esm, zrequire} = require("./lib/namespace");
|
|
const {run_test, noop} = require("./lib/test");
|
|
const blueslip = require("./lib/zblueslip");
|
|
const $ = require("./lib/zjquery");
|
|
const {realm, user_settings} = require("./lib/zpage_params");
|
|
|
|
let clipboard_args;
|
|
class Clipboard {
|
|
constructor(...args) {
|
|
clipboard_args = args;
|
|
}
|
|
on(_success, show_copied_confirmation) {
|
|
show_copied_confirmation();
|
|
}
|
|
}
|
|
|
|
mock_cjs("clipboard", Clipboard);
|
|
|
|
const realm_playground = mock_esm("../src/realm_playground");
|
|
const copied_tooltip = mock_esm("../src/copied_tooltip");
|
|
user_settings.emojiset = "apple";
|
|
|
|
const rm = zrequire("rendered_markdown");
|
|
const people = zrequire("people");
|
|
const user_groups = zrequire("user_groups");
|
|
const stream_data = zrequire("stream_data");
|
|
const rows = zrequire("rows");
|
|
const message_store = zrequire("message_store");
|
|
|
|
const iago = {
|
|
email: "iago@zulip.com",
|
|
user_id: 30,
|
|
full_name: "Iago",
|
|
};
|
|
|
|
const cordelia = {
|
|
email: "cordelia@zulip.com",
|
|
user_id: 31,
|
|
full_name: "Cordelia Lear",
|
|
};
|
|
|
|
const polonius = {
|
|
email: "polonius@zulip.com",
|
|
user_id: 32,
|
|
full_name: "Polonius",
|
|
is_guest: true,
|
|
};
|
|
const inaccessible_user_id = 33;
|
|
const inaccessible_user = people.add_inaccessible_user(inaccessible_user_id);
|
|
people.init();
|
|
people.add_active_user(iago);
|
|
people.add_active_user(cordelia);
|
|
people.add_active_user(polonius);
|
|
people.initialize_current_user(iago.user_id);
|
|
|
|
const group_me = {
|
|
name: "my user group",
|
|
id: 1,
|
|
members: [iago.user_id, cordelia.user_id],
|
|
};
|
|
const group_other = {
|
|
name: "other user group",
|
|
id: 2,
|
|
members: [cordelia.user_id],
|
|
};
|
|
user_groups.initialize({
|
|
realm_user_groups: [group_me, group_other],
|
|
});
|
|
|
|
const stream = {
|
|
subscribed: true,
|
|
color: "yellow",
|
|
name: "test",
|
|
stream_id: 3,
|
|
is_muted: true,
|
|
invite_only: false,
|
|
};
|
|
stream_data.add_sub(stream);
|
|
|
|
const $array = (array) => {
|
|
const each = (func) => {
|
|
for (const e of array) {
|
|
func.call(e);
|
|
}
|
|
};
|
|
return {each};
|
|
};
|
|
|
|
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 [];
|
|
};
|
|
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;
|
|
};
|
|
}
|
|
|
|
const get_content_element = () => {
|
|
const $content = $.create("content-stub");
|
|
$content.set_find_results(".user-mention", $array([]));
|
|
$content.set_find_results(".topic-mention", $array([]));
|
|
$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([]));
|
|
$content.set_find_results("div.codehilite", $array([]));
|
|
$content.set_find_results(".message_inline_video video", $array([]));
|
|
set_message_for_message_content($content, undefined);
|
|
|
|
// Fend off dumb security bugs by forcing devs to be
|
|
// intentional about HTML manipulation.
|
|
/* istanbul ignore next */
|
|
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;
|
|
return $content;
|
|
};
|
|
|
|
run_test("misc_helpers", () => {
|
|
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");
|
|
|
|
realm.realm_enable_guest_user_indicator = true;
|
|
rm.set_name_in_mention_element($elem, "Polonius", polonius.user_id);
|
|
assert.equal($elem.text(), "translated: Polonius (guest)");
|
|
|
|
realm.realm_enable_guest_user_indicator = false;
|
|
rm.set_name_in_mention_element($elem, "Polonius", polonius.user_id);
|
|
assert.equal($elem.text(), "Polonius");
|
|
});
|
|
|
|
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;
|
|
});
|
|
|
|
run_test("user-mention", () => {
|
|
// Setup
|
|
const $content = get_content_element();
|
|
const $iago = $.create("user-mention(iago)");
|
|
$iago.set_find_results(".highlight", false);
|
|
$iago.attr("data-user-id", iago.user_id);
|
|
const $cordelia = $.create("user-mention(cordelia)");
|
|
$cordelia.set_find_results(".highlight", false);
|
|
$cordelia.attr("data-user-id", cordelia.user_id);
|
|
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]));
|
|
realm.realm_enable_guest_user_indicator = true;
|
|
// Initial asserts
|
|
assert.ok(!$iago.hasClass("user-mention-me"));
|
|
assert.equal($iago.text(), "never-been-set");
|
|
assert.equal($cordelia.text(), "never-been-set");
|
|
assert.equal($polonius.text(), "never-been-set");
|
|
|
|
rm.update_elements($content);
|
|
assert.ok(!$iago.hasClass("user-mention-me"));
|
|
assert.equal($iago.text(), `@${iago.full_name}`);
|
|
assert.equal($cordelia.text(), `@${cordelia.full_name}`);
|
|
assert.equal($polonius.text(), `translated: @${polonius.full_name} (guest)`);
|
|
|
|
// 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"));
|
|
});
|
|
|
|
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]));
|
|
|
|
realm.realm_enable_guest_user_indicator = false;
|
|
rm.update_elements($content);
|
|
assert.equal($polonius.text(), `@${polonius.full_name}`);
|
|
});
|
|
|
|
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");
|
|
});
|
|
|
|
run_test("user-mention (stream wildcard)", () => {
|
|
// Setup
|
|
const $content = get_content_element();
|
|
const $mention = $.create("mention");
|
|
$mention.attr("data-user-id", "*");
|
|
$content.set_find_results(".user-mention", $array([$mention]));
|
|
const message = {stream_wildcard_mentioned: true};
|
|
set_message_for_message_content($content, message);
|
|
|
|
assert.ok(!$mention.hasClass("user-mention-me"));
|
|
rm.update_elements($content);
|
|
assert.ok($mention.hasClass("user-mention-me"));
|
|
});
|
|
|
|
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);
|
|
assert.ok(!$mention.hasClass("user-mention-me"));
|
|
assert.equal($mention.text(), "@Cordelia Lear");
|
|
});
|
|
|
|
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);
|
|
assert.ok(!$mention.hasClass("user-mention-me"));
|
|
});
|
|
|
|
run_test("topic-mention", () => {
|
|
// Setup
|
|
const $content = get_content_element();
|
|
const $mention = $.create("mention");
|
|
$content.set_find_results(".topic-mention", $array([$mention]));
|
|
|
|
// when no message row found
|
|
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,
|
|
};
|
|
set_message_for_message_content($content, message);
|
|
|
|
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]));
|
|
|
|
const message = {
|
|
topic_wildcard_mentioned: false,
|
|
};
|
|
set_message_for_message_content($content, message);
|
|
|
|
assert.ok(!$mention.hasClass("user-mention-me"));
|
|
rm.update_elements($content);
|
|
assert.ok(!$mention.hasClass("user-mention-me"));
|
|
});
|
|
|
|
run_test("user-group-mention", () => {
|
|
// Setup
|
|
const $content = get_content_element();
|
|
const $group_me = $.create("user-group-mention(me)");
|
|
$group_me.set_find_results(".highlight", false);
|
|
$group_me.attr("data-user-group-id", group_me.id);
|
|
const $group_other = $.create("user-group-mention(other)");
|
|
$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]));
|
|
|
|
// Initial asserts
|
|
assert.ok(!$group_me.hasClass("user-mention-me"));
|
|
assert.equal($group_me.text(), "never-been-set");
|
|
assert.equal($group_other.text(), "never-been-set");
|
|
|
|
rm.update_elements($content);
|
|
|
|
// Final asserts
|
|
assert.ok($group_me.hasClass("user-mention-me"));
|
|
assert.equal($group_me.text(), `@${group_me.name}`);
|
|
assert.equal($group_other.text(), `@${group_other.name}`);
|
|
});
|
|
|
|
run_test("user-group-mention (error)", () => {
|
|
const $content = get_content_element();
|
|
const $group = $.create("user-group-mention(bogus)");
|
|
$group.attr("data-user-group-id", "not-even-a-number");
|
|
$content.set_find_results(".user-group-mention", $array([$group]));
|
|
|
|
rm.update_elements($content);
|
|
|
|
assert.ok(!$group.hasClass("user-mention-me"));
|
|
});
|
|
|
|
run_test("stream-links", () => {
|
|
// Setup
|
|
const $content = get_content_element();
|
|
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);
|
|
$stream_topic.text("#random > topic name > still the topic name");
|
|
$content.set_find_results("a.stream", $array([$stream]));
|
|
$content.set_find_results("a.stream-topic", $array([$stream_topic]));
|
|
|
|
// Initial asserts
|
|
assert.equal($stream.text(), "never-been-set");
|
|
assert.equal($stream_topic.text(), "#random > topic name > still the topic name");
|
|
|
|
rm.update_elements($content);
|
|
|
|
// Final asserts
|
|
assert.equal($stream.text(), `#${stream.name}`);
|
|
assert.equal($stream_topic.text(), `#${stream.name} > topic name > still the topic name`);
|
|
});
|
|
|
|
run_test("timestamp without time", () => {
|
|
const $content = get_content_element();
|
|
const $timestamp = $.create("timestamp without actual time");
|
|
$content.set_find_results("time", $array([$timestamp]));
|
|
|
|
rm.update_elements($content);
|
|
assert.equal($timestamp.text(), "never-been-set");
|
|
});
|
|
|
|
run_test("timestamp", ({mock_template}) => {
|
|
mock_template("markdown_timestamp.hbs", true, (data, html) => {
|
|
assert.deepEqual(data, {text: "Thu, Jan 1, 1970, 12:00 AM"});
|
|
return html;
|
|
});
|
|
|
|
// Setup
|
|
const $content = get_content_element();
|
|
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]));
|
|
blueslip.expect("error", "Could not parse datetime supplied by backend");
|
|
|
|
// Initial asserts
|
|
assert.equal($timestamp.text(), "never-been-set");
|
|
assert.equal($timestamp_invalid.text(), "never-been-set");
|
|
|
|
rm.update_elements($content);
|
|
|
|
// Final asserts
|
|
assert.equal($timestamp.html(), '<i class="fa fa-clock-o"></i>\nThu, Jan 1, 1970, 12:00 AM\n');
|
|
assert.equal($timestamp_invalid.text(), "never-been-set");
|
|
});
|
|
|
|
run_test("timestamp-twenty-four-hour-time", ({mock_template, override}) => {
|
|
mock_template("markdown_timestamp.hbs", true, (data, html) => {
|
|
// sanity check incoming data
|
|
assert.ok(data.text.startsWith("Wed, Jul 15, 2020, "));
|
|
return html;
|
|
});
|
|
|
|
const $content = get_content_element();
|
|
const $timestamp = $.create("timestamp");
|
|
$timestamp.attr("datetime", "2020-07-15T20:40:00Z");
|
|
$content.set_find_results("time", $array([$timestamp]));
|
|
|
|
// We will temporarily change the 24h setting for this test.
|
|
override(user_settings, "twenty_four_hour_time", true);
|
|
rm.update_elements($content);
|
|
assert.equal($timestamp.html(), '<i class="fa fa-clock-o"></i>\nWed, Jul 15, 2020, 20:40\n');
|
|
|
|
override(user_settings, "twenty_four_hour_time", false);
|
|
rm.update_elements($content);
|
|
assert.equal($timestamp.html(), '<i class="fa fa-clock-o"></i>\nWed, Jul 15, 2020, 8:40 PM\n');
|
|
});
|
|
|
|
run_test("timestamp-error", () => {
|
|
// Setup
|
|
const $content = get_content_element();
|
|
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]));
|
|
|
|
// Initial assert
|
|
assert.equal($timestamp_error.text(), "Invalid time format: the-time-format");
|
|
|
|
rm.update_elements($content);
|
|
|
|
// Final assert
|
|
assert.equal($timestamp_error.text(), "translated: Invalid time format: the-time-format");
|
|
});
|
|
|
|
run_test("emoji", () => {
|
|
// Setup
|
|
const $content = get_content_element();
|
|
const $emoji = $.create("emoji-stub");
|
|
$emoji.attr("title", "tada");
|
|
let called = false;
|
|
$emoji.replaceWith = (f) => {
|
|
const text = f.call($emoji);
|
|
assert.equal(":tada:", text);
|
|
called = true;
|
|
};
|
|
$content.set_find_results(".emoji", $emoji);
|
|
user_settings.emojiset = "text";
|
|
|
|
rm.update_elements($content);
|
|
|
|
assert.ok(called);
|
|
|
|
// Set page parameters back so that test run order is independent
|
|
user_settings.emojiset = "apple";
|
|
});
|
|
|
|
run_test("spoiler-header", () => {
|
|
// Setup
|
|
const $content = get_content_element();
|
|
const $header = $.create("div.spoiler-header");
|
|
$content.set_find_results("div.spoiler-header", $array([$header]));
|
|
|
|
// Test that the show/hide button gets added to a spoiler header.
|
|
const label = "My spoiler header";
|
|
const toggle_button_html =
|
|
'<span class="spoiler-button" aria-expanded="false"><span class="spoiler-arrow"></span></span>';
|
|
$header.html(label);
|
|
rm.update_elements($content);
|
|
assert.equal(toggle_button_html + label, $header.html());
|
|
});
|
|
|
|
run_test("spoiler-header-empty-fill", () => {
|
|
// Setup
|
|
const $content = get_content_element();
|
|
const $header = $.create("div.spoiler-header");
|
|
$content.set_find_results("div.spoiler-header", $array([$header]));
|
|
|
|
// Test that an empty header gets the default text applied (through i18n filter).
|
|
const toggle_button_html =
|
|
'<span class="spoiler-button" aria-expanded="false"><span class="spoiler-arrow"></span></span>';
|
|
$header.empty();
|
|
rm.update_elements($content);
|
|
assert.equal(toggle_button_html + "<p>translated HTML: Spoiler</p>", $header.html());
|
|
});
|
|
|
|
function assert_clipboard_setup() {
|
|
assert.equal(clipboard_args[0], "copy-code-stub");
|
|
const text = clipboard_args[1].text({
|
|
to_$: () => ({
|
|
siblings(arg) {
|
|
assert.equal(arg, "code");
|
|
return {
|
|
text: () => "text",
|
|
};
|
|
},
|
|
}),
|
|
});
|
|
assert.equal(text, "text");
|
|
}
|
|
|
|
function test_code_playground(mock_template, viewing_code) {
|
|
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);
|
|
|
|
$hilite.data("code-language", "javascript");
|
|
|
|
const $copy_code_button = $.create("copy_code_button", {children: ["copy-code-stub"]});
|
|
const $view_code_in_playground = $.create("view_code_in_playground");
|
|
|
|
// The code playground code prepends a few buttons
|
|
// 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).
|
|
const prepends = [];
|
|
$pre.prepend = (arg) => {
|
|
assert.ok(arg.__zjquery, "We should only prepend jQuery objects.");
|
|
prepends.push(arg);
|
|
};
|
|
|
|
mock_template("copy_code_button.hbs", false, (data) => {
|
|
assert.equal(data, undefined);
|
|
return {to_$: () => $copy_code_button};
|
|
});
|
|
|
|
if (viewing_code) {
|
|
mock_template("view_code_in_playground.hbs", false, (data) => {
|
|
assert.equal(data, undefined);
|
|
return {to_$: () => $view_code_in_playground};
|
|
});
|
|
}
|
|
|
|
rm.update_elements($content);
|
|
|
|
return {
|
|
prepends,
|
|
$copy_code: $copy_code_button,
|
|
$view_code: $view_code_in_playground,
|
|
};
|
|
}
|
|
|
|
run_test("code playground none", ({override, mock_template}) => {
|
|
override(realm_playground, "get_playground_info_for_languages", (language) => {
|
|
assert.equal(language, "javascript");
|
|
return undefined;
|
|
});
|
|
|
|
override(copied_tooltip, "show_copied_confirmation", noop);
|
|
|
|
const {prepends, $copy_code, $view_code} = test_code_playground(mock_template, false);
|
|
assert.deepEqual(prepends, [$copy_code]);
|
|
assert_clipboard_setup();
|
|
|
|
assert.equal($view_code.attr("data-tippy-content"), undefined);
|
|
assert.equal($view_code.attr("aria-label"), undefined);
|
|
});
|
|
|
|
run_test("code playground single", ({override, mock_template}) => {
|
|
override(realm_playground, "get_playground_info_for_languages", (language) => {
|
|
assert.equal(language, "javascript");
|
|
return [{name: "Some Javascript Playground"}];
|
|
});
|
|
|
|
override(copied_tooltip, "show_copied_confirmation", noop);
|
|
|
|
const {prepends, $copy_code, $view_code} = test_code_playground(mock_template, true);
|
|
assert.deepEqual(prepends, [$view_code, $copy_code]);
|
|
assert_clipboard_setup();
|
|
|
|
assert.equal(
|
|
$view_code.attr("data-tippy-content"),
|
|
"translated: View in Some Javascript Playground",
|
|
);
|
|
assert.equal($view_code.attr("aria-label"), "translated: View in Some Javascript Playground");
|
|
assert.equal($view_code.attr("aria-haspopup"), undefined);
|
|
});
|
|
|
|
run_test("code playground multiple", ({override, mock_template}) => {
|
|
override(realm_playground, "get_playground_info_for_languages", (language) => {
|
|
assert.equal(language, "javascript");
|
|
return ["whatever", "whatever"];
|
|
});
|
|
|
|
override(copied_tooltip, "show_copied_confirmation", noop);
|
|
|
|
const {prepends, $copy_code, $view_code} = test_code_playground(mock_template, true);
|
|
assert.deepEqual(prepends, [$view_code, $copy_code]);
|
|
assert_clipboard_setup();
|
|
|
|
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");
|
|
});
|
|
|
|
run_test("rtl", () => {
|
|
const $content = get_content_element();
|
|
|
|
$content.text("مرحبا");
|
|
|
|
assert.ok(!$content.hasClass("rtl"));
|
|
rm.update_elements($content);
|
|
assert.ok($content.hasClass("rtl"));
|
|
});
|