discourse/plugins/chat/test/javascripts/acceptance/chat-keyboard-shortcuts-test.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

320 lines
9.9 KiB
JavaScript
Raw Normal View History

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);
this.chatService.set("chatWindowFullPage", false);
await click(".header-dropdown-toggle.open-chat");
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) {
await visit("/latest");
this.chatService.set("sidebarActive", false);
await click(".header-dropdown-toggle.open-chat");
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 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 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);
this.chatService.set("chatWindowFullPage", 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) {
await visit("/latest");
this.chatService.set("sidebarActive", false);
this.chatService.set("chatWindowFullPage", false);
await click(".header-dropdown-toggle.open-chat");
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);
this.chatService.set("chatWindowFullPage", true);
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 doesnt close full page chat"
);
assert.ok(
exists(".chat-message-container[data-id='177']"),
"it doesnt remove channel content"
);
});
});