[REF] mail: move ChannelSelector to discuss folder

Part of task-3265211

closes odoo/odoo#124891

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
This commit is contained in:
Sébastien Theys
2023-06-14 22:40:02 +02:00
parent 44aa89d0ec
commit 77fa212a43
27 changed files with 518 additions and 420 deletions
@@ -1,13 +1,10 @@
/* @odoo-module */
import { ChannelSelector } from "@mail/core/common/channel_selector";
import { ChatWindow } from "@mail/core/common/chat_window";
import { useService } from "@web/core/utils/hooks";
import { patch } from "@web/core/utils/patch";
Object.assign(ChatWindow.components, { ChannelSelector });
patch(ChatWindow.prototype, "mail/core/web", {
setup() {
this._super(...arguments);
@@ -4,11 +4,5 @@
<xpath expr="//*[hasclass('o-mail-ChatWindow')]" position="attributes">
<attribute name="class" add="border border-bottom-0" separator=" "/>
</xpath>
<xpath expr="//t[@name='thread content']" position="after">
<div t-if="!thread" class="d-flex align-items-center m-3">
<span class="flex-shrink-0 me-2">To :</span>
<ChannelSelector category="store.discuss.chats" onValidate="() => chatWindowService.closeNewMessage()" multiple="false" autofocus="true"/>
</div>
</xpath>
</t>
</templates>
@@ -1,6 +1,5 @@
/* @odoo-module */
import { ChannelSelector } from "@mail/core/common/channel_selector";
import { ImStatus } from "@mail/core/common/im_status";
import { useMessaging, useStore } from "@mail/core/common/messaging_hook";
import { NotificationItem } from "@mail/core/web/notification_item";
@@ -17,7 +16,7 @@ import { useService } from "@web/core/utils/hooks";
import { sprintf } from "@web/core/utils/strings";
export class MessagingMenu extends Component {
static components = { Dropdown, NotificationItem, ImStatus, ChannelSelector };
static components = { Dropdown, NotificationItem, ImStatus };
static props = [];
static template = "mail.MessagingMenu";
@@ -17,33 +17,12 @@
<t t-name="mail.MessagingMenu.content" owl="1">
<t t-set="failures" t-value="store.notificationGroups"/>
<div class="o-mail-MessagingMenu d-flex flex-column flex-grow-1" t-att-class="{ 'overflow-auto w-100 mh-100': ui.isSmall }">
<div t-att-class="{'flex-row-reverse text-uppercase': ui.isSmall,
'o-mail-MessagingMenu-header border-bottom d-flex flex-shrink-0 p-2': !env.inDiscussApp,
}">
<div class="o-mail-MessagingMenu-header" t-att-class="{'flex-row-reverse text-uppercase': ui.isSmall, 'border-bottom d-flex flex-shrink-0 p-2': !env.inDiscussApp }">
<t t-if="!ui.isSmall">
<button class="btn btn-link" t-att-class="store.discuss.activeTab === 'all' ? 'fw-bolder' : 'text-muted'" type="button" role="tab" t-on-click="() => store.discuss.activeTab = 'all'">All</button>
<button class="btn btn-link" t-att-class="store.discuss.activeTab === 'chat' ? 'fw-bolder' : 'text-muted'" type="button" role="tab" t-on-click="() => store.discuss.activeTab = 'chat'">Chats</button>
<button class="btn btn-link" t-att-class="store.discuss.activeTab === 'channel' ? 'fw-bolder' : 'text-muted'" type="button" role="tab" t-on-click="() => store.discuss.activeTab = 'channel'">Channels</button>
</t>
<div class="flex-grow-1"></div>
<t t-if="!store.discuss.isActive or ui.isSmall and store.discuss.activeTab !== 'mailbox'">
<t t-if="env.inDiscussApp and ['chat', 'channel'].includes(store.discuss.activeTab)">
<div t-if="state.addingChat or state.addingChannel" class="p-4 border-bottom bg-light" t-ref="selector">
<t t-if="state.addingChat" t-set="category" t-value="store.discuss.chats"/>
<t t-if="state.addingChannel" t-set="category" t-value="store.discuss.channels"/>
<ChannelSelector category="category" autofocus="true"/>
</div>
</t>
<button t-if="!env.inDiscussApp or (env.inDiscussApp and store.discuss.activeTab === 'chat' and !state.addingChat)" t-att-class="env.inDiscussApp ? 'w-100 p-2 btn btn-secondary border-bottom bg-light' : 'btn btn-link'" t-on-click.stop="onClickNewMessage">
<t t-if="env.inDiscussApp">Start a conversation</t>
<t t-else="">New Message</t>
</button>
<div t-if="env.inDiscussApp and store.discuss.activeTab === 'channel' and !state.addingChannel">
<button class="w-100 p-2 btn btn-secondary border-bottom bg-light" t-on-click.stop="() => this.state.addingChannel = true">
New Channel
</button>
</div>
</t>
</div>
<div t-if="!env.inDiscussApp or ['chat', 'channel'].includes(store.discuss.activeTab)" class="d-flex flex-column overflow-auto flex-grow-1">
<div class="d-flex justify-content-center py-4 px-2 text-muted" t-if="!hasPreviews">
+1 -2
View File
@@ -1,6 +1,5 @@
/* @odoo-module */
import { ChannelSelector } from "@mail/core/common/channel_selector";
import { ImStatus } from "@mail/core/common/im_status";
import { useMessaging, useStore } from "@mail/core/common/messaging_hook";
import { ThreadIcon } from "@mail/core/common/thread_icon";
@@ -19,7 +18,7 @@ import { useService } from "@web/core/utils/hooks";
*/
export class Sidebar extends Component {
static template = "mail.DiscussSidebar";
static components = { ChannelSelector, ThreadIcon, ImStatus };
static components = { ThreadIcon, ImStatus };
static props = [];
setup() {
@@ -61,9 +61,6 @@
</div>
</div>
<t t-if="category.isOpen">
<div t-if="state.editing === category.id" class="p-2" t-ref="selector">
<ChannelSelector category="category" onValidate.bind="stopEditing" autofocus="true"/>
</div>
<t t-foreach="filteredThreads(category)" t-as="threadLocalId" t-key="threadLocalId" t-call="mail.DiscussCategoryItem">
<t t-set="thread" t-value="store.threads[threadLocalId]"/>
</t>
@@ -52,13 +52,13 @@ export class ChannelSelector extends Component {
const choices = results.map((channel) => {
return {
channelId: channel.id,
classList: "o-mail-ChannelSelector-suggestion",
classList: "o-discuss-ChannelSelector-suggestion",
label: channel.name,
};
});
choices.push({
channelId: "__create__",
classList: "o-mail-ChannelSelector-suggestion",
classList: "o-discuss-ChannelSelector-suggestion",
label: cleanedTerm,
});
return choices;
@@ -74,21 +74,21 @@ export class ChannelSelector extends Component {
.map((data) => {
this.personaService.insert({ ...data, type: "partner" });
return {
classList: "o-mail-ChannelSelector-suggestion",
classList: "o-discuss-ChannelSelector-suggestion",
label: data.name,
partner: data,
};
});
if (this.store.self.name.includes(cleanedTerm)) {
suggestions.push({
classList: "o-mail-ChannelSelector-suggestion",
classList: "o-discuss-ChannelSelector-suggestion",
label: this.store.self.name,
partner: this.store.self,
});
}
if (suggestions.length === 0) {
suggestions.push({
classList: "o-mail-ChannelSelector-suggestion",
classList: "o-discuss-ChannelSelector-suggestion",
label: _t("No results found"),
unselectable: true,
});
@@ -1,4 +1,4 @@
.o-mail-ChannelSelector {
.o-discuss-ChannelSelector {
input {
width: unset !important;
}
@@ -2,7 +2,7 @@
<templates xml:space="preserve">
<t t-name="discuss.ChannelSelector" owl="1">
<div class="o-mail-ChannelSelector d-flex flex-wrap form-control rounded bg-white p-1" t-att-class="props.class" t-ref="root">
<div class="o-discuss-ChannelSelector d-flex flex-wrap form-control rounded bg-white p-1" t-att-class="props.class" t-ref="root">
<TagsList t-if="props.multiple" tags="tagsList"/>
<input
class="text-truncate form-control flex-grow-1 border-0 px-2 py-0"
@@ -14,7 +14,7 @@
type="text"
/>
</div>
<NavigableList class="'o-mail-ChannelSelector-list z-index-1'" t-props="navigableListProps"/>
<NavigableList class="'o-discuss-ChannelSelector-list z-index-1'" t-props="navigableListProps"/>
</t>
<t t-name="discuss.ChannelSelector.channel" owl="1">
@@ -0,0 +1,6 @@
/* @odoo-module */
import { ChannelSelector } from "@mail/discuss/core/web/channel_selector";
import { ChatWindow } from "@mail/core/common/chat_window";
Object.assign(ChatWindow.components, { ChannelSelector });
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-inherit="mail.ChatWindow" t-inherit-mode="extension" owl="1">
<xpath expr="//t[@name='thread content']" position="after">
<div t-if="!thread" class="d-flex align-items-center m-3">
<span class="flex-shrink-0 me-2">To :</span>
<ChannelSelector category="store.discuss.chats" onValidate="() => chatWindowService.closeNewMessage()" multiple="false" autofocus="true"/>
</div>
</xpath>
</t>
</templates>
@@ -18,7 +18,7 @@ registry.category("web_tour.tours").add("mail_tour", {
position: "bottom",
},
{
trigger: ".o-mail-ChannelSelector input",
trigger: ".o-discuss-ChannelSelector input",
content: Markup(_t("<p>Create a channel here.</p>")),
position: "bottom",
auto: true,
@@ -28,12 +28,12 @@ registry.category("web_tour.tours").add("mail_tour", {
},
},
{
trigger: ".o-mail-ChannelSelector-list",
extra_trigger: ".o-mail-ChannelSelector-suggestion",
trigger: ".o-discuss-ChannelSelector-list",
extra_trigger: ".o-discuss-ChannelSelector-suggestion",
content: Markup(_t("<p>Create a public or private channel.</p>")),
position: "right",
run() {
document.querySelector(".o-mail-ChannelSelector-suggestion").click();
document.querySelector(".o-discuss-ChannelSelector-suggestion").click();
},
},
{
@@ -0,0 +1,6 @@
/* @odoo-module */
import { MessagingMenu } from "@mail/core/web/messaging_menu";
import { ChannelSelector } from "@mail/discuss/core/web/channel_selector";
Object.assign(MessagingMenu.components, { ChannelSelector });
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-inherit="mail.MessagingMenu.content" t-inherit-mode="extension" owl="1">
<xpath expr="//div[hasclass('o-mail-MessagingMenu-header')]" position="inside">
<div class="flex-grow-1"/>
<t t-if="!store.discuss.isActive or ui.isSmall and store.discuss.activeTab !== 'mailbox'">
<t t-if="env.inDiscussApp and ['chat', 'channel'].includes(store.discuss.activeTab)">
<div t-if="state.addingChat or state.addingChannel" class="p-4 border-bottom bg-light" t-ref="selector">
<t t-if="state.addingChat" t-set="category" t-value="store.discuss.chats"/>
<t t-if="state.addingChannel" t-set="category" t-value="store.discuss.channels"/>
<ChannelSelector category="category" autofocus="true"/>
</div>
</t>
<button t-if="!env.inDiscussApp or (env.inDiscussApp and store.discuss.activeTab === 'chat' and !state.addingChat)" t-att-class="env.inDiscussApp ? 'w-100 p-2 btn btn-secondary border-bottom bg-light' : 'btn btn-link'" t-on-click.stop="onClickNewMessage">
<t t-if="env.inDiscussApp">Start a conversation</t>
<t t-else="">New Message</t>
</button>
<div t-if="env.inDiscussApp and store.discuss.activeTab === 'channel' and !state.addingChannel">
<button class="w-100 p-2 btn btn-secondary border-bottom bg-light" t-on-click.stop="() => this.state.addingChannel = true">
New Channel
</button>
</div>
</t>
</xpath>
</t>
</templates>
@@ -0,0 +1,6 @@
/* @odoo-module */
import { Sidebar } from "@mail/core/web/sidebar";
import { ChannelSelector } from "@mail/discuss/core/web/channel_selector";
Object.assign(Sidebar.components, { ChannelSelector });
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-inherit="mail.DiscussCategory" t-inherit-mode="extension" owl="1">
<xpath expr="//t[@t-call='mail.DiscussCategoryItem']" position="before">
<div t-if="state.editing === category.id" class="p-2" t-ref="selector">
<ChannelSelector category="category" onValidate.bind="stopEditing" autofocus="true"/>
</div>
</xpath>
</t>
</templates>
@@ -3,7 +3,6 @@
import {
afterNextRender,
click,
insertText,
start,
startServer,
waitUntil,
@@ -90,22 +89,6 @@ QUnit.test("Thread description update", async (assert) => {
);
});
QUnit.test("Channel subscription is renewed when channel is manually added", async (assert) => {
const pyEnv = await startServer();
pyEnv["discuss.channel"].create({ name: "General", channel_member_ids: [] });
const { env, openDiscuss } = await start();
patchWithCleanup(env.services["bus_service"], {
forceUpdateChannels() {
assert.step("update-channels");
},
});
await openDiscuss();
await click("[title='Add or join a channel']");
await insertText(".o-mail-ChannelSelector", "General");
await afterNextRender(() => triggerHotkey("Enter"));
assert.verifySteps(["update-channels"]);
});
QUnit.test("Channel subscription is renewed when channel is added from invite", async (assert) => {
const pyEnv = await startServer();
const channelId = pyEnv["discuss.channel"].create({ name: "Sales", channel_member_ids: [] });
@@ -11,7 +11,7 @@ import {
} from "@mail/../tests/helpers/test_utils";
import { browser } from "@web/core/browser/browser";
import { editInput, nextTick, patchWithCleanup, triggerEvent } from "@web/../tests/helpers/utils";
import { nextTick, patchWithCleanup } from "@web/../tests/helpers/utils";
QUnit.module("call");
@@ -114,48 +114,6 @@ QUnit.test("should disconnect when closing page while in call", async (assert) =
assert.verifySteps(["sendBeacon_leave_call"]);
});
QUnit.test("no default rtc after joining a chat conversation", async (assert) => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Mario" });
pyEnv["res.users"].create({ partner_id: partnerId });
const { openDiscuss } = await start();
await openDiscuss();
assert.containsNone($, ".o-mail-DiscussCategoryItem");
await click(".o-mail-DiscussSidebar i[title='Start a conversation']");
await afterNextRender(() => editInput(document.body, ".o-mail-ChannelSelector input", "mario"));
await click(".o-mail-ChannelSelector-suggestion");
await triggerEvent(document.body, ".o-mail-ChannelSelector input", "keydown", {
key: "Enter",
});
assert.containsOnce($, ".o-mail-DiscussCategoryItem");
assert.containsNone($, ".o-mail-Discuss-content .o-mail-Message");
assert.containsNone($, ".o-discuss-Call");
});
QUnit.test("no default rtc after joining a group conversation", async (assert) => {
const pyEnv = await startServer();
const [partnerId_1, partnerId_2] = pyEnv["res.partner"].create([
{ name: "Mario" },
{ name: "Luigi" },
]);
pyEnv["res.users"].create([{ partner_id: partnerId_1 }, { partner_id: partnerId_2 }]);
const { openDiscuss } = await start();
await openDiscuss();
assert.containsNone($, ".o-mail-DiscussCategoryItem");
await click(".o-mail-DiscussSidebar i[title='Start a conversation']");
await afterNextRender(() => editInput(document.body, ".o-mail-ChannelSelector input", "mario"));
await click(".o-mail-ChannelSelector-suggestion");
await afterNextRender(() => editInput(document.body, ".o-mail-ChannelSelector input", "luigi"));
await click(".o-mail-ChannelSelector-suggestion");
await triggerEvent(document.body, ".o-mail-ChannelSelector input", "keydown", {
key: "Enter",
});
assert.containsOnce($, ".o-mail-DiscussCategoryItem");
assert.containsNone($, ".o-mail-Discuss-content .o-mail-Message");
assert.containsNone($, ".o-discuss-Call");
});
QUnit.test("should display invitations", async (assert) => {
patchWithCleanup(
browser,
@@ -0,0 +1,55 @@
/* @odoo-module */
import { afterNextRender, click, start, startServer } from "@mail/../tests/helpers/test_utils";
import { editInput, triggerEvent } from "@web/../tests/helpers/utils";
QUnit.module("call");
QUnit.test("no default rtc after joining a chat conversation", async (assert) => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Mario" });
pyEnv["res.users"].create({ partner_id: partnerId });
const { openDiscuss } = await start();
await openDiscuss();
assert.containsNone($, ".o-mail-DiscussCategoryItem");
await click(".o-mail-DiscussSidebar i[title='Start a conversation']");
await afterNextRender(() =>
editInput(document.body, ".o-discuss-ChannelSelector input", "mario")
);
await click(".o-discuss-ChannelSelector-suggestion");
await triggerEvent(document.body, ".o-discuss-ChannelSelector input", "keydown", {
key: "Enter",
});
assert.containsOnce($, ".o-mail-DiscussCategoryItem");
assert.containsNone($, ".o-mail-Discuss-content .o-mail-Message");
assert.containsNone($, ".o-discuss-Call");
});
QUnit.test("no default rtc after joining a group conversation", async (assert) => {
const pyEnv = await startServer();
const [partnerId_1, partnerId_2] = pyEnv["res.partner"].create([
{ name: "Mario" },
{ name: "Luigi" },
]);
pyEnv["res.users"].create([{ partner_id: partnerId_1 }, { partner_id: partnerId_2 }]);
const { openDiscuss } = await start();
await openDiscuss();
assert.containsNone($, ".o-mail-DiscussCategoryItem");
await click(".o-mail-DiscussSidebar i[title='Start a conversation']");
await afterNextRender(() =>
editInput(document.body, ".o-discuss-ChannelSelector input", "mario")
);
await click(".o-discuss-ChannelSelector-suggestion");
await afterNextRender(() =>
editInput(document.body, ".o-discuss-ChannelSelector input", "luigi")
);
await click(".o-discuss-ChannelSelector-suggestion");
await triggerEvent(document.body, ".o-discuss-ChannelSelector input", "keydown", {
key: "Enter",
});
assert.containsOnce($, ".o-mail-DiscussCategoryItem");
assert.containsNone($, ".o-mail-Discuss-content .o-mail-Message");
assert.containsNone($, ".o-discuss-Call");
});
@@ -36,7 +36,7 @@ QUnit.test("basic rendering", async (assert) => {
".o-mail-ChatWindow-header .o-mail-ChatWindow-command[title='Close Chat Window']"
);
assert.containsOnce($, "span:contains('To :')");
assert.containsOnce($, ".o-mail-ChannelSelector");
assert.containsOnce($, ".o-discuss-ChannelSelector");
});
QUnit.test("focused on open [REQUIRE FOCUS]", async (assert) => {
@@ -45,7 +45,7 @@ QUnit.test("focused on open [REQUIRE FOCUS]", async (assert) => {
await click("button:contains(New Message)");
assert.strictEqual(
document.activeElement,
$(".o-mail-ChatWindow .o-mail-ChannelSelector input")[0]
$(".o-mail-ChatWindow .o-discuss-ChannelSelector input")[0]
);
});
@@ -62,15 +62,15 @@ QUnit.test("fold", async (assert) => {
await click(".o_menu_systray i[aria-label='Messages']");
await click("button:contains(New Message)");
assert.containsOnce($, ".o-mail-ChatWindow-content");
assert.containsOnce($, ".o-mail-ChannelSelector");
assert.containsOnce($, ".o-discuss-ChannelSelector");
await click(".o-mail-ChatWindow-header");
assert.containsNone($, ".o-mail-ChatWindow .o-mail-ChatWindow-content");
assert.containsNone($, ".o-mail-ChatWindow .o-mail-ChannelSelector");
assert.containsNone($, ".o-mail-ChatWindow .o-discuss-ChannelSelector");
await click(".o-mail-ChatWindow-header");
assert.containsOnce($, ".o-mail-ChatWindow .o-mail-ChatWindow-content");
assert.containsOnce($, ".o-mail-ChannelSelector");
assert.containsOnce($, ".o-discuss-ChannelSelector");
});
QUnit.test(
@@ -116,7 +116,7 @@ QUnit.test(
await click("button:contains(New Message)");
assert.containsOnce($, ".o-mail-ChatWindow-header:contains(New message)");
assert.containsN($, ".o-mail-ChatWindow", 2);
assert.containsOnce($, ".o-mail-ChatWindow .o-mail-ChannelSelector");
assert.containsOnce($, ".o-mail-ChatWindow .o-discuss-ChannelSelector");
assert.ok(
Array.from(document.querySelectorAll(".o-mail-ChatWindow"))
.pop()
@@ -135,11 +135,11 @@ QUnit.test(
// search for a user in "new message" autocomplete
await afterNextRender(async () => {
await insertText(".o-mail-ChannelSelector input", "131");
await insertText(".o-discuss-ChannelSelector input", "131");
await imSearchDef;
});
assert.containsOnce($, ".o-mail-ChannelSelector-suggestion a");
const $link = $(".o-mail-ChannelSelector-suggestion a");
assert.containsOnce($, ".o-discuss-ChannelSelector-suggestion a");
const $link = $(".o-discuss-ChannelSelector-suggestion a");
assert.strictEqual($link.text(), "Partner 131");
await click($link);
@@ -173,8 +173,8 @@ QUnit.test(
await start();
await click(".o_menu_systray i[aria-label='Messages']");
await click("button:contains(New Message)");
await insertText(".o-mail-ChannelSelector", "131");
await click(".o-mail-ChannelSelector-suggestion a");
await insertText(".o-discuss-ChannelSelector", "131");
await click(".o-discuss-ChannelSelector-suggestion a");
assert.containsNone($, ".o-mail-ChatWindow-header:contains(New message)");
assert.containsOnce($, ".o-mail-ChatWindow");
}
@@ -197,8 +197,8 @@ QUnit.test("new message autocomplete should automatically select first result",
await click("button:contains(New Message)");
// search for a user in "new message" autocomplete
await afterNextRender(async () => {
await insertText(".o-mail-ChannelSelector", "131");
await insertText(".o-discuss-ChannelSelector", "131");
await imSearchDef;
});
assert.hasClass($(".o-mail-ChannelSelector-suggestion a"), "o-mail-NavigableList-active");
assert.hasClass($(".o-discuss-ChannelSelector-suggestion a"), "o-mail-NavigableList-active");
});
@@ -0,0 +1,29 @@
/* @odoo-module */
import {
afterNextRender,
click,
insertText,
start,
startServer,
} from "@mail/../tests/helpers/test_utils";
import { triggerHotkey, patchWithCleanup } from "@web/../tests/helpers/utils";
QUnit.module("crosstab");
QUnit.test("Channel subscription is renewed when channel is manually added", async (assert) => {
const pyEnv = await startServer();
pyEnv["discuss.channel"].create({ name: "General", channel_member_ids: [] });
const { env, openDiscuss } = await start();
patchWithCleanup(env.services["bus_service"], {
forceUpdateChannels() {
assert.step("update-channels");
},
});
await openDiscuss();
await click("[title='Add or join a channel']");
await insertText(".o-discuss-ChannelSelector", "General");
await afterNextRender(() => triggerHotkey("Enter"));
assert.verifySteps(["update-channels"]);
});
@@ -0,0 +1,200 @@
/* @odoo-module */
import {
afterNextRender,
click,
insertText,
start,
startServer,
} from "@mail/../tests/helpers/test_utils";
import { editInput, triggerEvent, triggerHotkey } from "@web/../tests/helpers/utils";
QUnit.module("discuss");
QUnit.test("can create a new channel [REQUIRE FOCUS]", async (assert) => {
await startServer();
const { openDiscuss } = await start({
mockRPC(route, params) {
if (
route.startsWith("/mail") ||
route.startsWith("/discuss") ||
[
"/web/dataset/call_kw/discuss.channel/search_read",
"/web/dataset/call_kw/discuss.channel/channel_create",
].includes(route)
) {
assert.step(route);
}
},
});
await openDiscuss();
assert.containsNone($, ".o-mail-DiscussCategoryItem");
await click(".o-mail-DiscussSidebar i[title='Add or join a channel']");
await afterNextRender(() =>
editInput(document.body, ".o-discuss-ChannelSelector input", "abc")
);
await click(".o-discuss-ChannelSelector-suggestion");
assert.containsOnce($, ".o-mail-DiscussCategoryItem");
assert.containsNone($, ".o-mail-Discuss-content .o-mail-Message");
assert.verifySteps([
"/mail/init_messaging",
"/mail/load_message_failures",
"/mail/inbox/messages",
"/web/dataset/call_kw/discuss.channel/search_read",
"/web/dataset/call_kw/discuss.channel/channel_create",
"/discuss/channel/messages",
]);
});
QUnit.test(
"do not close channel selector when creating chat conversation after selection",
async (assert) => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Mario" });
pyEnv["res.users"].create({ partner_id: partnerId });
const { openDiscuss } = await start();
await openDiscuss();
assert.containsNone($, ".o-mail-DiscussCategoryItem");
await click("i[title='Start a conversation']");
await afterNextRender(() =>
editInput(document.body, ".o-discuss-ChannelSelector input", "mario")
);
await click(".o-discuss-ChannelSelector-suggestion");
assert.containsOnce($, ".o-discuss-ChannelSelector span[title='Mario']");
assert.containsNone($, ".o-mail-DiscussCategoryItem");
await triggerEvent(document.body, ".o-discuss-ChannelSelector input", "keydown", {
key: "Backspace",
});
assert.containsNone($, ".o-discuss-ChannelSelector span[title='Mario']");
await afterNextRender(() =>
editInput(document.body, ".o-discuss-ChannelSelector input", "mario")
);
await triggerEvent(document.body, ".o-discuss-ChannelSelector input", "keydown", {
key: "Enter",
});
assert.containsOnce($, ".o-discuss-ChannelSelector span[title='Mario']");
assert.containsNone($, ".o-mail-DiscussCategoryItem");
}
);
QUnit.test("can join a chat conversation", async (assert) => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Mario" });
pyEnv["res.users"].create({ partner_id: partnerId });
const { openDiscuss } = await start({
mockRPC(route, params) {
if (
route.startsWith("/mail") ||
route.startsWith("/discuss") ||
["/web/dataset/call_kw/discuss.channel/channel_get"].includes(route)
) {
assert.step(route);
}
if (route === "/web/dataset/call_kw/discuss.channel/channel_get") {
assert.equal(params.kwargs.partners_to[0], partnerId);
}
},
});
await openDiscuss();
assert.containsNone($, ".o-mail-DiscussCategoryItem");
await click(".o-mail-DiscussSidebar i[title='Start a conversation']");
await afterNextRender(() =>
editInput(document.body, ".o-discuss-ChannelSelector input", "mario")
);
await click(".o-discuss-ChannelSelector-suggestion");
await triggerEvent(document.body, ".o-discuss-ChannelSelector input", "keydown", {
key: "Enter",
});
assert.containsOnce($, ".o-mail-DiscussCategoryItem");
assert.containsNone($, ".o-mail-Message");
assert.verifySteps([
"/mail/init_messaging",
"/mail/load_message_failures",
"/mail/inbox/messages",
"/web/dataset/call_kw/discuss.channel/channel_get",
"/discuss/channel/messages",
]);
});
QUnit.test("can create a group chat conversation", async (assert) => {
const pyEnv = await startServer();
const [partnerId_1, partnerId_2] = pyEnv["res.partner"].create([
{ name: "Mario" },
{ name: "Luigi" },
]);
pyEnv["res.users"].create([{ partner_id: partnerId_1 }, { partner_id: partnerId_2 }]);
const { openDiscuss } = await start();
await openDiscuss();
assert.containsNone($, ".o-mail-DiscussCategoryItem");
await click(".o-mail-DiscussSidebar i[title='Start a conversation']");
await insertText(".o-discuss-ChannelSelector input", "Mario");
await click(".o-discuss-ChannelSelector-suggestion");
await insertText(".o-discuss-ChannelSelector input", "Luigi");
await click(".o-discuss-ChannelSelector-suggestion");
await triggerEvent(document.body, ".o-discuss-ChannelSelector input", "keydown", {
key: "Enter",
});
assert.containsN($, ".o-mail-DiscussCategoryItem", 1);
assert.containsNone($, ".o-mail-Message");
});
QUnit.test("chat search should display no result when no matches found", async (assert) => {
const { openDiscuss } = await start();
await openDiscuss();
await click(".o-mail-DiscussSidebar i[title='Start a conversation']");
await insertText(".o-discuss-ChannelSelector", "Rainbow Panda");
assert.containsOnce($, ".o-discuss-ChannelSelector-suggestion:contains(No results found)");
});
QUnit.test(
"chat search should not be visible when clicking outside of the field",
async (assert) => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Panda" });
pyEnv["res.users"].create({ partner_id: partnerId });
const { openDiscuss } = await start();
await openDiscuss();
assert.containsNone($, ".o-mail-DiscussCategoryItem");
await click(".o-mail-DiscussSidebar i[title='Start a conversation']");
await insertText(".o-discuss-ChannelSelector", "Panda");
assert.containsOnce($, ".o-discuss-ChannelSelector-suggestion");
await click(".o-mail-DiscussSidebar");
assert.containsNone($, ".o-discuss-ChannelSelector-suggestion");
}
);
QUnit.test("sidebar: add channel", async (assert) => {
const { openDiscuss } = await start();
await openDiscuss();
assert.containsOnce($, ".o-mail-DiscussCategory-channel .o-mail-DiscussCategory-add");
assert.hasAttrValue(
$(".o-mail-DiscussCategory-channel .o-mail-DiscussCategory-add")[0],
"title",
"Add or join a channel"
);
await click(".o-mail-DiscussCategory-channel .o-mail-DiscussCategory-add");
assert.containsOnce($, ".o-discuss-ChannelSelector");
assert.containsOnce($, ".o-discuss-ChannelSelector input[placeholder='Add or join a channel']");
});
QUnit.test("Chat is added to discuss on other tab that the one that joined", async (assert) => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Jerry Golay" });
pyEnv["res.users"].create({ partner_id: partnerId });
const tab1 = await start({ asTab: true });
const tab2 = await start({ asTab: true });
await tab1.openDiscuss();
await tab2.openDiscuss();
await tab1.click(".o-mail-DiscussCategory-chat .o-mail-DiscussCategory-add");
await tab1.insertText(".o-discuss-ChannelSelector input", "Jer");
await tab1.click(".o-discuss-ChannelSelector-suggestion");
await afterNextRender(() => triggerHotkey("Enter"));
assert.containsOnce(tab1.target, ".o-mail-DiscussCategoryItem:contains(Jerry Golay)");
assert.containsOnce(tab2.target, ".o-mail-DiscussCategoryItem:contains(Jerry Golay)");
});
@@ -0,0 +1,62 @@
/* @odoo-module */
import {
afterNextRender,
click,
insertText,
start,
startServer,
} from "@mail/../tests/helpers/test_utils";
import { patchUiSize } from "@mail/../tests/helpers/patch_ui_size";
import { triggerHotkey } from "@web/../tests/helpers/utils";
QUnit.module("messaging menu");
QUnit.test('"Start a conversation" item selection opens chat', async (assert) => {
patchUiSize({ height: 360, width: 640 });
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Gandalf" });
pyEnv["res.users"].create({ partner_id: partnerId });
const { openDiscuss } = await start();
await openDiscuss();
await click("button:contains(Chat)");
await click("button:contains(Start a conversation)");
await insertText("input[placeholder='Start a conversation']", "Gandalf");
await click(".o-discuss-ChannelSelector-suggestion");
await afterNextRender(() => triggerHotkey("Enter"));
assert.containsOnce($, ".o-mail-ChatWindow-name[title='Gandalf']");
});
QUnit.test('"New channel" item selection opens channel (existing)', async (assert) => {
patchUiSize({ height: 360, width: 640 });
const pyEnv = await startServer();
pyEnv["discuss.channel"].create({ name: "Gryffindors" });
const { openDiscuss } = await start();
await openDiscuss();
await click("button:contains(Channel)");
await click("button:contains(New Channel)");
await insertText("input[placeholder='Add or join a channel']", "Gryff");
await click(".o-discuss-ChannelSelector-suggestion");
assert.containsOnce($, ".o-mail-ChatWindow-name[title='Gryffindors']");
});
QUnit.test('"New channel" item selection opens channel (new)', async (assert) => {
patchUiSize({ height: 360, width: 640 });
const { openDiscuss } = await start();
await openDiscuss();
await click("button:contains(Channel)");
await click("button:contains(New Channel)");
await insertText("input[placeholder='Add or join a channel']", "slytherins");
await click(".o-discuss-ChannelSelector-suggestion");
assert.containsOnce($, ".o-mail-ChatWindow-name[title='slytherins']");
});
QUnit.test("new message [REQUIRE FOCUS]", async (assert) => {
await start();
await click(".o_menu_systray .dropdown-toggle:has(i[aria-label='Messages'])");
await click('.o-mail-MessagingMenu button:contains("New Message")');
assert.containsOnce($, ".o-mail-ChatWindow");
assert.containsOnce($, ".o-mail-ChatWindow .o-discuss-ChannelSelector");
assert.containsOnce($, ".o-discuss-ChannelSelector input:focus");
});
@@ -0,0 +1,73 @@
/* @odoo-module */
import { Command } from "@mail/../tests/helpers/command";
import {
click,
insertText,
nextAnimationFrame,
start,
startServer,
} from "@mail/../tests/helpers/test_utils";
import { makeDeferred } from "@web/../tests/helpers/utils";
QUnit.module("discuss sidebar");
QUnit.test("sidebar find shows channels matching search term", async (assert) => {
const pyEnv = await startServer();
pyEnv["discuss.channel"].create({
channel_member_ids: [],
channel_type: "channel",
group_public_id: false,
name: "test",
});
const def = makeDeferred();
const { openDiscuss } = await start({
async mockRPC(route, args) {
if (args.method === "search_read") {
def.resolve();
}
},
});
await openDiscuss();
await click(".o-mail-DiscussCategory-add");
await insertText(".o-discuss-ChannelSelector input", "test");
await def;
await nextAnimationFrame(); // ensures search_read rpc is rendered.
// When searching for a single existing channel, the results list will have at least 2 lines:
// One for the existing channel itself
// One for creating a channel with the search term
assert.containsN($, ".o-mail-NavigableList-item", 2);
assert.containsN($, ".o-mail-NavigableList-item:contains(test)", 2);
});
QUnit.test(
"sidebar find shows channels matching search term even when user is member",
async (assert) => {
const pyEnv = await startServer();
pyEnv["discuss.channel"].create({
channel_member_ids: [Command.create({ partner_id: pyEnv.currentPartnerId })],
channel_type: "channel",
group_public_id: false,
name: "test",
});
const def = makeDeferred();
const { openDiscuss } = await start({
async mockRPC(route, args) {
if (args.method === "search_read") {
def.resolve();
}
},
});
await openDiscuss();
await click(".o-mail-DiscussCategory-add");
await insertText(".o-discuss-ChannelSelector input", "test");
await def;
await nextAnimationFrame(); // ensures search_read rpc is rendered.
// When searching for a single existing channel, the results list will have at least 2 lines:
// One for the existing channel itself
// One for creating a channel with the search term
assert.containsN($, ".o-mail-NavigableList-item", 2);
assert.containsN($, ".o-mail-NavigableList-item:contains(test)", 2);
}
);
@@ -99,159 +99,6 @@ QUnit.test("can change the thread description of #general", async (assert) => {
assert.verifySteps(["/web/dataset/call_kw/discuss.channel/channel_change_description"]);
});
QUnit.test("can create a new channel [REQUIRE FOCUS]", async (assert) => {
await startServer();
const { openDiscuss } = await start({
mockRPC(route, params) {
if (
route.startsWith("/mail") ||
route.startsWith("/discuss") ||
[
"/web/dataset/call_kw/discuss.channel/search_read",
"/web/dataset/call_kw/discuss.channel/channel_create",
].includes(route)
) {
assert.step(route);
}
},
});
await openDiscuss();
assert.containsNone($, ".o-mail-DiscussCategoryItem");
await click(".o-mail-DiscussSidebar i[title='Add or join a channel']");
await afterNextRender(() => editInput(document.body, ".o-mail-ChannelSelector input", "abc"));
await click(".o-mail-ChannelSelector-suggestion");
assert.containsOnce($, ".o-mail-DiscussCategoryItem");
assert.containsNone($, ".o-mail-Discuss-content .o-mail-Message");
assert.verifySteps([
"/mail/init_messaging",
"/mail/load_message_failures",
"/mail/inbox/messages",
"/web/dataset/call_kw/discuss.channel/search_read",
"/web/dataset/call_kw/discuss.channel/channel_create",
"/discuss/channel/messages",
]);
});
QUnit.test(
"do not close channel selector when creating chat conversation after selection",
async (assert) => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Mario" });
pyEnv["res.users"].create({ partner_id: partnerId });
const { openDiscuss } = await start();
await openDiscuss();
assert.containsNone($, ".o-mail-DiscussCategoryItem");
await click("i[title='Start a conversation']");
await afterNextRender(() =>
editInput(document.body, ".o-mail-ChannelSelector input", "mario")
);
await click(".o-mail-ChannelSelector-suggestion");
assert.containsOnce($, ".o-mail-ChannelSelector span[title='Mario']");
assert.containsNone($, ".o-mail-DiscussCategoryItem");
await triggerEvent(document.body, ".o-mail-ChannelSelector input", "keydown", {
key: "Backspace",
});
assert.containsNone($, ".o-mail-ChannelSelector span[title='Mario']");
await afterNextRender(() =>
editInput(document.body, ".o-mail-ChannelSelector input", "mario")
);
await triggerEvent(document.body, ".o-mail-ChannelSelector input", "keydown", {
key: "Enter",
});
assert.containsOnce($, ".o-mail-ChannelSelector span[title='Mario']");
assert.containsNone($, ".o-mail-DiscussCategoryItem");
}
);
QUnit.test("can join a chat conversation", async (assert) => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Mario" });
pyEnv["res.users"].create({ partner_id: partnerId });
const { openDiscuss } = await start({
mockRPC(route, params) {
if (
route.startsWith("/mail") ||
route.startsWith("/discuss") ||
["/web/dataset/call_kw/discuss.channel/channel_get"].includes(route)
) {
assert.step(route);
}
if (route === "/web/dataset/call_kw/discuss.channel/channel_get") {
assert.equal(params.kwargs.partners_to[0], partnerId);
}
},
});
await openDiscuss();
assert.containsNone($, ".o-mail-DiscussCategoryItem");
await click(".o-mail-DiscussSidebar i[title='Start a conversation']");
await afterNextRender(() => editInput(document.body, ".o-mail-ChannelSelector input", "mario"));
await click(".o-mail-ChannelSelector-suggestion");
await triggerEvent(document.body, ".o-mail-ChannelSelector input", "keydown", {
key: "Enter",
});
assert.containsOnce($, ".o-mail-DiscussCategoryItem");
assert.containsNone($, ".o-mail-Message");
assert.verifySteps([
"/mail/init_messaging",
"/mail/load_message_failures",
"/mail/inbox/messages",
"/web/dataset/call_kw/discuss.channel/channel_get",
"/discuss/channel/messages",
]);
});
QUnit.test("can create a group chat conversation", async (assert) => {
const pyEnv = await startServer();
const [partnerId_1, partnerId_2] = pyEnv["res.partner"].create([
{ name: "Mario" },
{ name: "Luigi" },
]);
pyEnv["res.users"].create([{ partner_id: partnerId_1 }, { partner_id: partnerId_2 }]);
const { openDiscuss } = await start();
await openDiscuss();
assert.containsNone($, ".o-mail-DiscussCategoryItem");
await click(".o-mail-DiscussSidebar i[title='Start a conversation']");
await insertText(".o-mail-ChannelSelector input", "Mario");
await click(".o-mail-ChannelSelector-suggestion");
await insertText(".o-mail-ChannelSelector input", "Luigi");
await click(".o-mail-ChannelSelector-suggestion");
await triggerEvent(document.body, ".o-mail-ChannelSelector input", "keydown", {
key: "Enter",
});
assert.containsN($, ".o-mail-DiscussCategoryItem", 1);
assert.containsNone($, ".o-mail-Message");
});
QUnit.test("chat search should display no result when no matches found", async (assert) => {
const { openDiscuss } = await start();
await openDiscuss();
await click(".o-mail-DiscussSidebar i[title='Start a conversation']");
await insertText(".o-mail-ChannelSelector", "Rainbow Panda");
assert.containsOnce($, ".o-mail-ChannelSelector-suggestion:contains(No results found)");
});
QUnit.test(
"chat search should not be visible when clicking outside of the field",
async (assert) => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Panda" });
pyEnv["res.users"].create({ partner_id: partnerId });
const { openDiscuss } = await start();
await openDiscuss();
assert.containsNone($, ".o-mail-DiscussCategoryItem");
await click(".o-mail-DiscussSidebar i[title='Start a conversation']");
await insertText(".o-mail-ChannelSelector", "Panda");
assert.containsOnce($, ".o-mail-ChannelSelector-suggestion");
await click(".o-mail-DiscussSidebar");
assert.containsNone($, ".o-mail-ChannelSelector-suggestion");
}
);
QUnit.test("Message following a notification should not be squashed", async (assert) => {
const pyEnv = await startServer();
const channelId = pyEnv["discuss.channel"].create({
@@ -659,20 +506,6 @@ QUnit.test("sidebar: change active", async (assert) => {
assert.hasClass($("button:contains(Starred)"), "o-active");
});
QUnit.test("sidebar: add channel", async (assert) => {
const { openDiscuss } = await start();
await openDiscuss();
assert.containsOnce($, ".o-mail-DiscussCategory-channel .o-mail-DiscussCategory-add");
assert.hasAttrValue(
$(".o-mail-DiscussCategory-channel .o-mail-DiscussCategory-add")[0],
"title",
"Add or join a channel"
);
await click(".o-mail-DiscussCategory-channel .o-mail-DiscussCategory-add");
assert.containsOnce($, ".o-mail-ChannelSelector");
assert.containsOnce($, ".o-mail-ChannelSelector input[placeholder='Add or join a channel']");
});
QUnit.test("sidebar: basic channel rendering", async (assert) => {
const pyEnv = await startServer();
pyEnv["discuss.channel"].create({ name: "General" });
@@ -1490,22 +1323,6 @@ QUnit.test("Channel is added to discuss after invitation", async (assert) => {
assert.verifySteps(["You have been invited to #General"]);
});
QUnit.test("Chat is added to discuss on other tab that the one that joined", async (assert) => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Jerry Golay" });
pyEnv["res.users"].create({ partner_id: partnerId });
const tab1 = await start({ asTab: true });
const tab2 = await start({ asTab: true });
await tab1.openDiscuss();
await tab2.openDiscuss();
await tab1.click(".o-mail-DiscussCategory-chat .o-mail-DiscussCategory-add");
await tab1.insertText(".o-mail-ChannelSelector input", "Jer");
await tab1.click(".o-mail-ChannelSelector-suggestion");
await afterNextRender(() => triggerHotkey("Enter"));
assert.containsOnce(tab1.target, ".o-mail-DiscussCategoryItem:contains(Jerry Golay)");
assert.containsOnce(tab2.target, ".o-mail-DiscussCategoryItem:contains(Jerry Golay)");
});
QUnit.test("select another mailbox", async (assert) => {
patchUiSize({ height: 360, width: 640 });
const { openDiscuss } = await start();
@@ -5,7 +5,6 @@ import {
afterNextRender,
click,
insertText,
nextAnimationFrame,
start,
startServer,
waitUntil,
@@ -13,7 +12,7 @@ import {
import { getOrigin } from "@web/core/utils/urls";
import { makeFakeNotificationService } from "@web/../tests/helpers/mock_services";
import { editInput, makeDeferred, nextTick } from "@web/../tests/helpers/utils";
import { editInput, nextTick } from "@web/../tests/helpers/utils";
QUnit.module("discuss sidebar");
@@ -632,65 +631,6 @@ QUnit.test("chat - states: close manually by clicking the title", async (assert)
assert.containsNone($, ".o-mail-DiscussCategoryItem");
});
QUnit.test("sidebar find shows channels matching search term", async (assert) => {
const pyEnv = await startServer();
pyEnv["discuss.channel"].create({
channel_member_ids: [],
channel_type: "channel",
group_public_id: false,
name: "test",
});
const def = makeDeferred();
const { openDiscuss } = await start({
async mockRPC(route, args) {
if (args.method === "search_read") {
def.resolve();
}
},
});
await openDiscuss();
await click(".o-mail-DiscussCategory-add");
await insertText(".o-mail-ChannelSelector input", "test");
await def;
await nextAnimationFrame(); // ensures search_read rpc is rendered.
// When searching for a single existing channel, the results list will have at least 2 lines:
// One for the existing channel itself
// One for creating a channel with the search term
assert.containsN($, ".o-mail-NavigableList-item", 2);
assert.containsN($, ".o-mail-NavigableList-item:contains(test)", 2);
});
QUnit.test(
"sidebar find shows channels matching search term even when user is member",
async (assert) => {
const pyEnv = await startServer();
pyEnv["discuss.channel"].create({
channel_member_ids: [Command.create({ partner_id: pyEnv.currentPartnerId })],
channel_type: "channel",
group_public_id: false,
name: "test",
});
const def = makeDeferred();
const { openDiscuss } = await start({
async mockRPC(route, args) {
if (args.method === "search_read") {
def.resolve();
}
},
});
await openDiscuss();
await click(".o-mail-DiscussCategory-add");
await insertText(".o-mail-ChannelSelector input", "test");
await def;
await nextAnimationFrame(); // ensures search_read rpc is rendered.
// When searching for a single existing channel, the results list will have at least 2 lines:
// One for the existing channel itself
// One for creating a channel with the search term
assert.containsN($, ".o-mail-NavigableList-item", 2);
assert.containsN($, ".o-mail-NavigableList-item:contains(test)", 2);
}
);
QUnit.test("sidebar channels should be ordered case insensitive alphabetically", async (assert) => {
const pyEnv = await startServer();
pyEnv["discuss.channel"].create([
@@ -1,20 +1,19 @@
/* @odoo-module */
import { Command } from "@mail/../tests/helpers/command";
import { patchBrowserNotification } from "@mail/../tests/helpers/patch_notifications";
import { patchUiSize, SIZES } from "@mail/../tests/helpers/patch_ui_size";
import {
afterNextRender,
click,
insertText,
start,
startServer,
waitUntil,
} from "@mail/../tests/helpers/test_utils";
import { makeFakeNotificationService } from "@web/../tests/helpers/mock_services";
import { patchWithCleanup, triggerEvent, triggerHotkey } from "@web/../tests/helpers/utils";
import { patchBrowserNotification } from "@mail/../tests/helpers/patch_notifications";
import { patchUiSize, SIZES } from "@mail/../tests/helpers/patch_ui_size";
import { browser } from "@web/core/browser/browser";
import { makeFakeNotificationService } from "@web/../tests/helpers/mock_services";
import { patchWithCleanup, triggerEvent } from "@web/../tests/helpers/utils";
QUnit.module("messaging menu");
@@ -489,45 +488,6 @@ QUnit.test('"New Channel" in mobile shows channel selector (+ click away)', asyn
assert.containsNone($, "input[placeholder='Add or join a channel']");
});
QUnit.test('"Start a conversation" item selection opens chat', async (assert) => {
patchUiSize({ height: 360, width: 640 });
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Gandalf" });
pyEnv["res.users"].create({ partner_id: partnerId });
const { openDiscuss } = await start();
await openDiscuss();
await click("button:contains(Chat)");
await click("button:contains(Start a conversation)");
await insertText("input[placeholder='Start a conversation']", "Gandalf");
await click(".o-mail-ChannelSelector-suggestion");
await afterNextRender(() => triggerHotkey("Enter"));
assert.containsOnce($, ".o-mail-ChatWindow-name[title='Gandalf']");
});
QUnit.test('"New channel" item selection opens channel (existing)', async (assert) => {
patchUiSize({ height: 360, width: 640 });
const pyEnv = await startServer();
pyEnv["discuss.channel"].create({ name: "Gryffindors" });
const { openDiscuss } = await start();
await openDiscuss();
await click("button:contains(Channel)");
await click("button:contains(New Channel)");
await insertText("input[placeholder='Add or join a channel']", "Gryff");
await click(".o-mail-ChannelSelector-suggestion");
assert.containsOnce($, ".o-mail-ChatWindow-name[title='Gryffindors']");
});
QUnit.test('"New channel" item selection opens channel (new)', async (assert) => {
patchUiSize({ height: 360, width: 640 });
const { openDiscuss } = await start();
await openDiscuss();
await click("button:contains(Channel)");
await click("button:contains(New Channel)");
await insertText("input[placeholder='Add or join a channel']", "slytherins");
await click(".o-mail-ChannelSelector-suggestion");
assert.containsOnce($, ".o-mail-ChatWindow-name[title='slytherins']");
});
QUnit.test("'New Message' button should open a chat window in mobile", async (assert) => {
patchUiSize({ height: 360, width: 640 });
await start();
@@ -619,15 +579,6 @@ QUnit.test("switch tab", async (assert) => {
assert.doesNotHaveClass($('.o-mail-MessagingMenu button:contains("Channels")'), "fw-bolder");
});
QUnit.test("new message [REQUIRE FOCUS]", async (assert) => {
await start();
await click(".o_menu_systray .dropdown-toggle:has(i[aria-label='Messages'])");
await click('.o-mail-MessagingMenu button:contains("New Message")');
assert.containsOnce($, ".o-mail-ChatWindow");
assert.containsOnce($, ".o-mail-ChatWindow .o-mail-ChannelSelector");
assert.containsOnce($, ".o-mail-ChannelSelector input:focus");
});
QUnit.test("channel preview: basic rendering", async (assert) => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Demo" });