322 lines
9.9 KiB
JavaScript
322 lines
9.9 KiB
JavaScript
import showModal from "discourse/lib/show-modal";
|
||
import {
|
||
acceptance,
|
||
exists,
|
||
loggedInUser,
|
||
query,
|
||
queryAll,
|
||
visible,
|
||
} from "discourse/tests/helpers/qunit-helpers";
|
||
import {
|
||
click,
|
||
currentURL,
|
||
fillIn,
|
||
focus,
|
||
settled,
|
||
triggerKeyEvent,
|
||
visit,
|
||
} from "@ember/test-helpers";
|
||
import {
|
||
chatChannels,
|
||
generateChatView,
|
||
} from "discourse/plugins/chat/chat-fixtures";
|
||
import ChatChannel from "discourse/plugins/chat/discourse/models/chat-channel";
|
||
import { KEY_MODIFIER } from "discourse/plugins/chat/discourse/initializers/chat-keyboard-shortcuts";
|
||
import { test } from "qunit";
|
||
|
||
const MODIFIER_OPTIONS =
|
||
KEY_MODIFIER === "meta" ? { metaKey: true } : { ctrlKey: true };
|
||
|
||
acceptance("Discourse Chat - Keyboard shortcuts", function (needs) {
|
||
needs.user({
|
||
admin: false,
|
||
moderator: false,
|
||
username: "eviltrout",
|
||
id: 1,
|
||
can_chat: true,
|
||
has_chat_enabled: true,
|
||
});
|
||
|
||
needs.pretender((server, helper) => {
|
||
// allows to create a staged message
|
||
server.post("/chat/:id.json", () =>
|
||
helper.response({
|
||
errors: [""],
|
||
})
|
||
);
|
||
server.get("/chat/chat_channels.json", () => helper.response(chatChannels));
|
||
server.get("/chat/:chatChannelId/messages.json", () =>
|
||
helper.response(generateChatView(loggedInUser()))
|
||
);
|
||
server.post("/uploads/lookup-urls", () => {
|
||
return helper.response([]);
|
||
});
|
||
server.post("/chat/drafts", () => {
|
||
return helper.response([]);
|
||
});
|
||
|
||
server.get("/chat/chat_channels/search", () => {
|
||
return helper.response({
|
||
public_channels: [ChatChannel.create({ id: 3, title: "seventeen" })],
|
||
direct_message_channels: [
|
||
ChatChannel.create({
|
||
id: 4,
|
||
users: [{ id: 10, username: "someone" }],
|
||
}),
|
||
],
|
||
users: [
|
||
{ id: 11, username: "smoothies" },
|
||
{ id: 12, username: "server" },
|
||
],
|
||
});
|
||
});
|
||
});
|
||
|
||
needs.settings({
|
||
chat_enabled: true,
|
||
});
|
||
|
||
needs.hooks.beforeEach(function () {
|
||
Object.defineProperty(this, "chatService", {
|
||
get: () => this.container.lookup("service:chat"),
|
||
});
|
||
});
|
||
|
||
test("channel selector opens channel in float", async function (assert) {
|
||
await visit("/latest");
|
||
|
||
await showModal("chat-channel-selector-modal");
|
||
await settled();
|
||
assert.ok(exists("#chat-channel-selector-modal-inner"));
|
||
|
||
// All channels should show because the input is blank
|
||
assert.equal(
|
||
queryAll("#chat-channel-selector-modal-inner .chat-channel-selection-row")
|
||
.length,
|
||
9
|
||
);
|
||
|
||
// Freaking keyup event isn't triggered by fillIn...
|
||
// Next line manually keyup's "r" to make the keyup event run.
|
||
// fillIn is needed for `this.filter` but triggerKeyEvent is needed to fire the JS event.
|
||
await fillIn("#chat-channel-selector-input", "s");
|
||
await triggerKeyEvent("#chat-channel-selector-input", "keyup", "R");
|
||
|
||
// Only 4 channels match this filter now!
|
||
assert.equal(
|
||
queryAll("#chat-channel-selector-modal-inner .chat-channel-selection-row")
|
||
.length,
|
||
4
|
||
);
|
||
|
||
await triggerKeyEvent(document.body, "keyup", "Enter");
|
||
assert.ok(exists(".topic-chat-container.visible"));
|
||
assert.notOk(exists("#chat-channel-selector-modal-inner"));
|
||
assert.equal(currentURL(), "/latest");
|
||
});
|
||
|
||
test("the current chat channel does not show in the channel selector list", async function (assert) {
|
||
await visit("/chat/channel/75/@hawk");
|
||
await showModal("chat-channel-selector-modal");
|
||
await settled();
|
||
|
||
// All channels minus 1
|
||
assert.equal(
|
||
queryAll("#chat-channel-selector-modal-inner .chat-channel-selection-row")
|
||
.length,
|
||
8
|
||
);
|
||
assert.notOk(
|
||
exists(
|
||
"#chat-channel-selector-modal-inner .chat-channel-selection-row.chat-channel-9"
|
||
)
|
||
);
|
||
});
|
||
|
||
test("switching channel with alt+arrow keys in full page chat", async function (assert) {
|
||
this.container.lookup("service:chat").set("chatWindowFullPage", true);
|
||
await visit("/chat/channel/75/@hawk");
|
||
await triggerKeyEvent(document.body, "keydown", "ArrowDown", {
|
||
altKey: true,
|
||
});
|
||
assert.equal(currentURL(), "/chat/channel/76/eviltrout-markvanlan");
|
||
await triggerKeyEvent(document.body, "keydown", "ArrowDown", {
|
||
altKey: true,
|
||
});
|
||
assert.equal(currentURL(), "/chat/channel/11/another-category");
|
||
await triggerKeyEvent(document.body, "keydown", "ArrowDown", {
|
||
altKey: true,
|
||
});
|
||
assert.equal(currentURL(), "/chat/channel/7/bug");
|
||
await triggerKeyEvent(document.body, "keydown", "ArrowUp", {
|
||
altKey: true,
|
||
});
|
||
assert.equal(currentURL(), "/chat/channel/11/another-category");
|
||
await triggerKeyEvent(document.body, "keydown", "ArrowUp", {
|
||
altKey: true,
|
||
});
|
||
assert.equal(currentURL(), "/chat/channel/76/eviltrout-markvanlan");
|
||
await triggerKeyEvent(document.body, "keydown", "ArrowUp", {
|
||
altKey: true,
|
||
});
|
||
assert.equal(currentURL(), "/chat/channel/75/hawk");
|
||
});
|
||
|
||
test("switching channel with alt+arrow keys in float", async function (assert) {
|
||
await visit("/latest");
|
||
this.chatService.set("sidebarActive", false);
|
||
|
||
await click(".header-dropdown-toggle.open-chat");
|
||
await click("#chat-channel-row-4");
|
||
|
||
assert.ok(visible(".topic-chat-float-container"), "chat float is open");
|
||
assert.ok(query(".topic-chat-container").classList.contains("channel-4"));
|
||
|
||
await triggerKeyEvent(document.body, "keydown", "ArrowDown", {
|
||
altKey: true,
|
||
});
|
||
|
||
assert.ok(query(".topic-chat-container").classList.contains("channel-10"));
|
||
|
||
await triggerKeyEvent(document.body, "keydown", "ArrowUp", {
|
||
altKey: true,
|
||
});
|
||
assert.ok(query(".topic-chat-container").classList.contains("channel-4"));
|
||
});
|
||
|
||
test("simple composer formatting shortcuts", async function (assert) {
|
||
this.chatService.set("sidebarActive", false);
|
||
await visit("/latest");
|
||
await click(".header-dropdown-toggle.open-chat");
|
||
await click(".chat-channel-row");
|
||
|
||
const composerInput = query(".chat-composer-input");
|
||
await fillIn(composerInput, "test text");
|
||
await focus(composerInput);
|
||
composerInput.selectionStart = 0;
|
||
composerInput.selectionEnd = 9;
|
||
await triggerKeyEvent(composerInput, "keydown", "B", MODIFIER_OPTIONS);
|
||
|
||
assert.strictEqual(
|
||
composerInput.value,
|
||
"**test text**",
|
||
"selection should get the bold markdown"
|
||
);
|
||
await fillIn(composerInput, "test text");
|
||
await focus(composerInput);
|
||
composerInput.selectionStart = 0;
|
||
composerInput.selectionEnd = 9;
|
||
await triggerKeyEvent(composerInput, "keydown", "I", MODIFIER_OPTIONS);
|
||
|
||
assert.strictEqual(
|
||
composerInput.value,
|
||
"_test text_",
|
||
"selection should get the italic markdown"
|
||
);
|
||
await fillIn(composerInput, "test text");
|
||
await focus(composerInput);
|
||
composerInput.selectionStart = 0;
|
||
composerInput.selectionEnd = 9;
|
||
await triggerKeyEvent(composerInput, "keydown", "E", MODIFIER_OPTIONS);
|
||
|
||
assert.strictEqual(
|
||
composerInput.value,
|
||
"`test text`",
|
||
"selection should get the code markdown"
|
||
);
|
||
});
|
||
|
||
test("editing last non staged message", async function (assert) {
|
||
const stagedMessageText = "This is a test";
|
||
await visit("/latest");
|
||
|
||
this.chatService.set("sidebarActive", false);
|
||
await click(".header-dropdown-toggle.open-chat");
|
||
await click(".chat-channel-row");
|
||
await fillIn(".chat-composer-input", stagedMessageText);
|
||
await click(".chat-composer-inline-button");
|
||
await triggerKeyEvent(".chat-composer-input", "keydown", "ArrowUp");
|
||
|
||
assert.notEqual(
|
||
query(".chat-composer-input").value.trim(),
|
||
stagedMessageText
|
||
);
|
||
});
|
||
|
||
test("insert link shortcut", async function (assert) {
|
||
await visit("/latest");
|
||
|
||
this.chatService.set("sidebarActive", false);
|
||
await click(".header-dropdown-toggle.open-chat");
|
||
await click(".chat-channel-row");
|
||
|
||
await focus(".chat-composer-input");
|
||
await fillIn(".chat-composer-input", "This is a link to ");
|
||
await triggerKeyEvent(
|
||
".chat-composer-input",
|
||
"keydown",
|
||
"L",
|
||
MODIFIER_OPTIONS
|
||
);
|
||
assert.ok(exists(".insert-link.modal-body"), "hyperlink modal visible");
|
||
|
||
await fillIn(".modal-body .link-url", "google.com");
|
||
await fillIn(".modal-body .link-text", "Google");
|
||
await click(".modal-footer button.btn-primary");
|
||
|
||
assert.strictEqual(
|
||
query(".chat-composer-input").value,
|
||
"This is a link to [Google](https://google.com)",
|
||
"adds link with url and text, prepends 'https://'"
|
||
);
|
||
|
||
assert.ok(
|
||
!exists(".insert-link.modal-body"),
|
||
"modal dismissed after submitting link"
|
||
);
|
||
});
|
||
|
||
test("Dash key (-) opens chat float", async function (assert) {
|
||
await visit("/latest");
|
||
this.chatService.set("sidebarActive", false);
|
||
|
||
await triggerKeyEvent(document.body, "keydown", "-");
|
||
assert.ok(exists(".topic-chat-drawer-content"), "chat float is open");
|
||
});
|
||
|
||
test("Pressing Escape when drawer is opened", async function (assert) {
|
||
this.chatService.set("sidebarActive", false);
|
||
await visit("/latest");
|
||
await click(".header-dropdown-toggle.open-chat");
|
||
await click(".chat-channel-row");
|
||
|
||
const composerInput = query(".chat-composer-input");
|
||
await focus(composerInput);
|
||
await triggerKeyEvent(composerInput, "keydown", "Escape");
|
||
|
||
assert.ok(
|
||
exists(".topic-chat-float-container.hidden"),
|
||
"it closes the drawer"
|
||
);
|
||
});
|
||
|
||
test("Pressing Escape when full page is opened", async function (assert) {
|
||
this.chatService.set("sidebarActive", false);
|
||
await visit("/chat/channel/75/@hawk");
|
||
const composerInput = query(".chat-composer-input");
|
||
await focus(composerInput);
|
||
await triggerKeyEvent(composerInput, "keydown", "Escape");
|
||
|
||
assert.equal(
|
||
currentURL(),
|
||
"/chat/channel/75/hawk",
|
||
"it doesn’t close full page chat"
|
||
);
|
||
|
||
assert.ok(
|
||
exists(".chat-message-container[data-id='177']"),
|
||
"it doesn’t remove channel content"
|
||
);
|
||
});
|
||
});
|