[FIX] mail: debounce suggestion (and channel selector) searches
Before this commit, fetching suggestions (e.g. channel selector in discuss sidebar "Find or create a channel", or `@`-mentions) were performing RPCs on each user input, resulting in wasted network and server load. This commit fixes the issue by debouncing the fetching of suggestions to 0.5 sec. closes odoo/odoo#126952 X-original-commit: 6770ac3 Related: odoo/enterprise#43502 Signed-off-by: Matthieu Stockbauer (tsm) <tsm@odoo.com> Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
insertText,
|
||||
start,
|
||||
} from "@mail/../tests/helpers/test_utils";
|
||||
import { DEBOUNCE_FETCH_SUGGESTION_TIME } from "@mail/core/common/suggestion_service";
|
||||
|
||||
import { editInput, nextTick, triggerHotkey } from "@web/../tests/helpers/utils";
|
||||
|
||||
@@ -111,10 +112,13 @@ QUnit.test('display canned response suggestions on typing ":"', async (assert) =
|
||||
source: "hello",
|
||||
substitution: "Hello! How are you?",
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
assert.containsNone($, ".o-mail-Composer-suggestionList .o-open");
|
||||
await insertText(".o-mail-Composer-input", ":");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
assert.containsOnce($, ".o-mail-Composer-suggestionList .o-open");
|
||||
});
|
||||
|
||||
@@ -133,11 +137,14 @@ QUnit.test("use a canned response", async (assert) => {
|
||||
source: "hello",
|
||||
substitution: "Hello! How are you?",
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
assert.containsNone($, ".o-mail-Composer-suggestionList .o-open");
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "");
|
||||
await insertText(".o-mail-Composer-input", ":");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
assert.containsOnce($, ".o-mail-Composer-suggestion");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
assert.strictEqual(
|
||||
@@ -162,13 +169,16 @@ QUnit.test("use a canned response some text", async (assert) => {
|
||||
source: "hello",
|
||||
substitution: "Hello! How are you?",
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
assert.containsNone($, ".o-mail-Composer-suggestion");
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "");
|
||||
await insertText(".o-mail-Composer-input", "bluhbluh ");
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "bluhbluh ");
|
||||
await insertText(".o-mail-Composer-input", ":");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
assert.containsOnce($, ".o-mail-Composer-suggestion");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
assert.strictEqual(
|
||||
@@ -193,11 +203,14 @@ QUnit.test("add an emoji after a canned response", async (assert) => {
|
||||
source: "hello",
|
||||
substitution: "Hello! How are you?",
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
assert.containsNone($, ".o-mail-Composer-suggestion");
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "");
|
||||
await insertText(".o-mail-Composer-input", ":");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
assert.containsOnce($, ".o-mail-Composer-suggestion");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
assert.strictEqual(
|
||||
|
||||
@@ -65,9 +65,6 @@ export class NavigableList extends Component {
|
||||
}
|
||||
|
||||
open() {
|
||||
if (this.state.isLoading) {
|
||||
return;
|
||||
}
|
||||
this.load().then(() => {
|
||||
this.state.open = true;
|
||||
this.navigate("first");
|
||||
@@ -80,6 +77,7 @@ export class NavigableList extends Component {
|
||||
}
|
||||
|
||||
async load() {
|
||||
this.state.isLoading = true;
|
||||
this.state.options = [];
|
||||
const makeOption = (opt) => {
|
||||
return Object.assign(Object.create(opt), {
|
||||
@@ -87,12 +85,12 @@ export class NavigableList extends Component {
|
||||
});
|
||||
};
|
||||
if (this.props.options instanceof Promise) {
|
||||
this.state.isLoading = true;
|
||||
return this.props.options.then((opts) => {
|
||||
opts.forEach((opt) => this.state.options.push(makeOption(opt)));
|
||||
this.state.isLoading = false;
|
||||
});
|
||||
}
|
||||
this.state.isLoading = false;
|
||||
if (this.props.options instanceof Array) {
|
||||
if (this.props.options.length === 0) {
|
||||
return;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
/* @odoo-module */
|
||||
|
||||
import { DEBOUNCE_FETCH_SUGGESTION_TIME } from "@mail/core/common/suggestion_service";
|
||||
import { useComponent, useEffect, useState } from "@odoo/owl";
|
||||
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { useDebounced } from "@web/core/utils/timing";
|
||||
|
||||
export function useSuggestion() {
|
||||
const comp = useComponent();
|
||||
@@ -124,9 +126,10 @@ export function useSuggestion() {
|
||||
state: useState({
|
||||
count: 0,
|
||||
items: undefined,
|
||||
loading: false,
|
||||
}),
|
||||
update() {
|
||||
if (!self.search.delimiter) {
|
||||
if (!self.search.delimiter || self.state.loading) {
|
||||
return;
|
||||
}
|
||||
const suggestions = suggestionService.searchSuggestions(
|
||||
@@ -150,6 +153,10 @@ export function useSuggestion() {
|
||||
self.state.items = { type, mainSuggestions, extraSuggestions };
|
||||
},
|
||||
};
|
||||
const debouncedFetchSuggestions = useDebounced(
|
||||
(...args) => suggestionService.fetchSuggestions(...args),
|
||||
DEBOUNCE_FETCH_SUGGESTION_TIME
|
||||
);
|
||||
useEffect(
|
||||
() => {
|
||||
self.update();
|
||||
@@ -157,12 +164,14 @@ export function useSuggestion() {
|
||||
if (self.search.position === undefined || !self.search.delimiter) {
|
||||
return; // ignore obsolete call
|
||||
}
|
||||
await suggestionService.fetchSuggestions(self.search, {
|
||||
self.state.loading = true;
|
||||
await debouncedFetchSuggestions(self.search, {
|
||||
thread: self.thread,
|
||||
onFetched() {
|
||||
if (owl.status(comp) === "destroyed") {
|
||||
return;
|
||||
}
|
||||
self.state.loading = false;
|
||||
self.update();
|
||||
},
|
||||
});
|
||||
|
||||
@@ -4,6 +4,8 @@ import { cleanTerm } from "@mail/utils/common/format";
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
|
||||
export const DEBOUNCE_FETCH_SUGGESTION_TIME = 500;
|
||||
|
||||
export class SuggestionService {
|
||||
constructor(env, services) {
|
||||
this.orm = services.orm;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useStore } from "@mail/core/common/messaging_hook";
|
||||
import { NavigableList } from "@mail/core/common/navigable_list";
|
||||
import { DEBOUNCE_FETCH_SUGGESTION_TIME } from "@mail/core/common/suggestion_service";
|
||||
import { cleanTerm } from "@mail/utils/common/format";
|
||||
import { createLocalId, isEventHandled, markEventHandled } from "@mail/utils/common/misc";
|
||||
|
||||
@@ -11,6 +12,7 @@ import { getActiveHotkey } from "@web/core/hotkeys/hotkey_service";
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
import { TagsList } from "@web/core/tags_list/tags_list";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { useDebounced } from "@web/core/utils/timing";
|
||||
|
||||
export class ChannelSelector extends Component {
|
||||
static components = { TagsList, NavigableList };
|
||||
@@ -35,6 +37,10 @@ export class ChannelSelector extends Component {
|
||||
onMounted(() => this.inputRef.el.focus());
|
||||
}
|
||||
this.markEventHandled = markEventHandled;
|
||||
this.debouncedFetchSuggestions = useDebounced(
|
||||
this.fetchSuggestions.bind(this),
|
||||
DEBOUNCE_FETCH_SUGGESTION_TIME
|
||||
);
|
||||
}
|
||||
|
||||
async fetchSuggestions() {
|
||||
@@ -198,7 +204,7 @@ export class ChannelSelector extends Component {
|
||||
this.props.category.id === "channels"
|
||||
? "discuss.ChannelSelector.channel"
|
||||
: "discuss.ChannelSelector.chat",
|
||||
options: this.fetchSuggestions(),
|
||||
options: this.debouncedFetchSuggestions(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
import { file } from "web.test_utils";
|
||||
|
||||
const { inputFiles } = file;
|
||||
import { DEBOUNCE_FETCH_SUGGESTION_TIME } from "@mail/core/common/suggestion_service";
|
||||
|
||||
QUnit.module("composer", {
|
||||
async beforeEach() {
|
||||
@@ -359,13 +360,16 @@ QUnit.test("add an emoji after a partner mention", async (assert) => {
|
||||
Command.create({ partner_id: partnerId }),
|
||||
],
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
assert.containsNone($, ".o-mail-Composer-suggestion");
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "");
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await insertText(".o-mail-Composer-input", "T");
|
||||
await insertText(".o-mail-Composer-input", "e");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
assert.strictEqual($(".o-mail-Composer-input").val().replace(/\s/, " "), "@TestPartner ");
|
||||
|
||||
@@ -380,7 +384,7 @@ QUnit.test("mention a channel after some text", async (assert) => {
|
||||
name: "General",
|
||||
channel_type: "channel",
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
assert.containsNone($, ".o-mail-Composer-suggestion");
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "");
|
||||
@@ -391,6 +395,9 @@ QUnit.test("mention a channel after some text", async (assert) => {
|
||||
"text content of composer should have content"
|
||||
);
|
||||
await insertText(".o-mail-Composer-input", "#");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
assert.containsOnce($, ".o-mail-Composer-suggestion");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
assert.strictEqual(
|
||||
@@ -406,11 +413,14 @@ QUnit.test("add an emoji after a channel mention", async (assert) => {
|
||||
name: "General",
|
||||
channel_type: "channel",
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
assert.containsNone($, ".o-mail-Composer-suggestion");
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "");
|
||||
await insertText(".o-mail-Composer-input", "#");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
assert.containsOnce($, ".o-mail-Composer-suggestion");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
assert.strictEqual(
|
||||
@@ -427,10 +437,13 @@ QUnit.test("add an emoji after a channel mention", async (assert) => {
|
||||
|
||||
QUnit.test("pending mentions are kept when toggling composer", async (assert) => {
|
||||
const pyEnv = await startServer();
|
||||
const { openFormView } = await start();
|
||||
const { advanceTime, openFormView } = await start({ hasTimeControl: true });
|
||||
await openFormView("res.partner", pyEnv.currentPartnerId);
|
||||
await click("button:contains(Send message)");
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
await click(".o-mail-Composer-suggestion:contains(Mitchell Admin)");
|
||||
await click("button:contains(Send message)");
|
||||
await click("button:contains(Send message)");
|
||||
@@ -611,7 +624,8 @@ QUnit.test("Select composer suggestion via Enter does not send the message", asy
|
||||
Command.create({ partner_id: partnerId }),
|
||||
],
|
||||
});
|
||||
const { openDiscuss } = await start({
|
||||
const { advanceTime, openDiscuss } = await start({
|
||||
hasTimeControl: true,
|
||||
async mockRPC(route, args) {
|
||||
if (route === "/mail/message/post") {
|
||||
assert.step("message_post");
|
||||
@@ -621,6 +635,9 @@ QUnit.test("Select composer suggestion via Enter does not send the message", asy
|
||||
await openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await insertText(".o-mail-Composer-input", "Shrek");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
await afterNextRender(() => triggerHotkey("Enter"));
|
||||
assert.equal($(".o-mail-Composer-input").val().trim(), "@Shrek");
|
||||
assert.verifySteps([]);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
/* @odoo-module */
|
||||
|
||||
import { afterNextRender, click, start, startServer } from "@mail/../tests/helpers/test_utils";
|
||||
import { DEBOUNCE_FETCH_SUGGESTION_TIME } from "@mail/core/common/suggestion_service";
|
||||
|
||||
import { editInput, triggerEvent } from "@web/../tests/helpers/utils";
|
||||
import { editInput, nextTick, triggerEvent } from "@web/../tests/helpers/utils";
|
||||
|
||||
QUnit.module("call");
|
||||
|
||||
@@ -10,7 +11,7 @@ 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();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss();
|
||||
assert.containsNone($, ".o-mail-DiscussCategoryItem");
|
||||
|
||||
@@ -18,6 +19,8 @@ QUnit.test("no default rtc after joining a chat conversation", async (assert) =>
|
||||
await afterNextRender(() =>
|
||||
editInput(document.body, ".o-discuss-ChannelSelector input", "mario")
|
||||
);
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await click(".o-discuss-ChannelSelector-suggestion");
|
||||
await triggerEvent(document.body, ".o-discuss-ChannelSelector input", "keydown", {
|
||||
key: "Enter",
|
||||
@@ -34,17 +37,21 @@ QUnit.test("no default rtc after joining a group conversation", async (assert) =
|
||||
{ name: "Luigi" },
|
||||
]);
|
||||
pyEnv["res.users"].create([{ partner_id: partnerId_1 }, { partner_id: partnerId_2 }]);
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
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 advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await click(".o-discuss-ChannelSelector-suggestion");
|
||||
await afterNextRender(() =>
|
||||
editInput(document.body, ".o-discuss-ChannelSelector input", "luigi")
|
||||
);
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await click(".o-discuss-ChannelSelector-suggestion");
|
||||
await triggerEvent(document.body, ".o-discuss-ChannelSelector input", "keydown", {
|
||||
key: "Enter",
|
||||
|
||||
@@ -4,7 +4,8 @@ import { Composer } from "@mail/core/common/composer";
|
||||
import { Command } from "@mail/../tests/helpers/command";
|
||||
import { click, insertText, start, startServer } from "@mail/../tests/helpers/test_utils";
|
||||
|
||||
import { patchWithCleanup } from "@web/../tests/helpers/utils";
|
||||
import { nextTick, patchWithCleanup } from "@web/../tests/helpers/utils";
|
||||
import { DEBOUNCE_FETCH_SUGGESTION_TIME } from "@mail/core/common/suggestion_service";
|
||||
|
||||
QUnit.module("suggestion", {
|
||||
async beforeEach() {
|
||||
@@ -110,7 +111,7 @@ QUnit.test("Sort partner suggestions by recent chats", async (assert) => {
|
||||
channel_type: "chat",
|
||||
},
|
||||
]);
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss();
|
||||
await click(".o-mail-DiscussCategoryItem:contains('User 2')");
|
||||
await insertText(".o-mail-Composer-input", "This is a test");
|
||||
@@ -119,6 +120,9 @@ QUnit.test("Sort partner suggestions by recent chats", async (assert) => {
|
||||
await click(".o-mail-DiscussCategoryItem:contains('General')");
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await insertText(".o-mail-Composer-input", "User");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
assert.containsN($, ".o-mail-Composer-suggestion", 3);
|
||||
assert.strictEqual($(".o-mail-Composer-suggestion").eq(0).text(), "User 2");
|
||||
assert.strictEqual($(".o-mail-Composer-suggestion").eq(1).text(), "User 1");
|
||||
|
||||
@@ -15,7 +15,8 @@ import {
|
||||
startServer,
|
||||
} from "@mail/../tests/helpers/test_utils";
|
||||
|
||||
import { makeDeferred } from "@web/../tests/helpers/utils";
|
||||
import { makeDeferred, nextTick } from "@web/../tests/helpers/utils";
|
||||
import { DEBOUNCE_FETCH_SUGGESTION_TIME } from "@mail/core/common/suggestion_service";
|
||||
|
||||
QUnit.module("chat window: new message");
|
||||
|
||||
@@ -103,7 +104,8 @@ QUnit.test(
|
||||
1920,
|
||||
"should have enough space to open 3 chat windows simultaneously"
|
||||
);
|
||||
await start({
|
||||
const { advanceTime } = await start({
|
||||
hasTimeControl: true,
|
||||
mockRPC(route, args) {
|
||||
if (args.method === "im_search") {
|
||||
imSearchDef.resolve();
|
||||
@@ -137,6 +139,8 @@ QUnit.test(
|
||||
// search for a user in "new message" autocomplete
|
||||
await afterNextRender(async () => {
|
||||
await insertText(".o-discuss-ChannelSelector input", "131");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await imSearchDef;
|
||||
});
|
||||
assert.containsOnce($, ".o-discuss-ChannelSelector-suggestion a");
|
||||
@@ -171,10 +175,12 @@ QUnit.test(
|
||||
channel_type: "chat",
|
||||
name: "Partner 131",
|
||||
});
|
||||
await start();
|
||||
const { advanceTime } = await start({ hasTimeControl: true });
|
||||
await click(".o_menu_systray i[aria-label='Messages']");
|
||||
await click("button:contains(New Message)");
|
||||
await insertText(".o-discuss-ChannelSelector", "131");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await click(".o-discuss-ChannelSelector-suggestion a");
|
||||
assert.containsNone($, ".o-mail-ChatWindow-header:contains(New message)");
|
||||
assert.containsOnce($, ".o-mail-ChatWindow");
|
||||
@@ -186,7 +192,8 @@ QUnit.test("new message autocomplete should automatically select first result",
|
||||
const partnerId = pyEnv["res.partner"].create({ name: "Partner 131" });
|
||||
pyEnv["res.users"].create({ partner_id: partnerId });
|
||||
const imSearchDef = makeDeferred();
|
||||
await start({
|
||||
const { advanceTime } = await start({
|
||||
hasTimeControl: true,
|
||||
mockRPC(route, args) {
|
||||
if (args.method === "im_search") {
|
||||
imSearchDef.resolve();
|
||||
@@ -199,6 +206,8 @@ QUnit.test("new message autocomplete should automatically select first result",
|
||||
// search for a user in "new message" autocomplete
|
||||
await afterNextRender(async () => {
|
||||
await insertText(".o-discuss-ChannelSelector", "131");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await imSearchDef;
|
||||
});
|
||||
assert.hasClass($(".o-discuss-ChannelSelector-suggestion a"), "o-mail-NavigableList-active");
|
||||
|
||||
@@ -7,15 +7,16 @@ import {
|
||||
start,
|
||||
startServer,
|
||||
} from "@mail/../tests/helpers/test_utils";
|
||||
import { DEBOUNCE_FETCH_SUGGESTION_TIME } from "@mail/core/common/suggestion_service";
|
||||
|
||||
import { triggerHotkey, patchWithCleanup } from "@web/../tests/helpers/utils";
|
||||
import { triggerHotkey, patchWithCleanup, nextTick } 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();
|
||||
const { advanceTime, env, openDiscuss } = await start({ hasTimeControl: true });
|
||||
patchWithCleanup(env.services["bus_service"], {
|
||||
forceUpdateChannels() {
|
||||
assert.step("update-channels");
|
||||
@@ -24,6 +25,8 @@ QUnit.test("Channel subscription is renewed when channel is manually added", asy
|
||||
await openDiscuss();
|
||||
await click("[title='Add or join a channel']");
|
||||
await insertText(".o-discuss-ChannelSelector", "General");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await afterNextRender(() => triggerHotkey("Enter"));
|
||||
assert.verifySteps(["update-channels"]);
|
||||
});
|
||||
|
||||
@@ -7,14 +7,16 @@ import {
|
||||
start,
|
||||
startServer,
|
||||
} from "@mail/../tests/helpers/test_utils";
|
||||
import { DEBOUNCE_FETCH_SUGGESTION_TIME } from "@mail/core/common/suggestion_service";
|
||||
|
||||
import { editInput, triggerEvent, triggerHotkey } from "@web/../tests/helpers/utils";
|
||||
import { editInput, nextTick, 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({
|
||||
const { advanceTime, openDiscuss } = await start({
|
||||
hasTimeControl: true,
|
||||
mockRPC(route, params) {
|
||||
if (
|
||||
route.startsWith("/mail") ||
|
||||
@@ -35,6 +37,8 @@ QUnit.test("can create a new channel [REQUIRE FOCUS]", async (assert) => {
|
||||
await afterNextRender(() =>
|
||||
editInput(document.body, ".o-discuss-ChannelSelector input", "abc")
|
||||
);
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await click(".o-discuss-ChannelSelector-suggestion");
|
||||
assert.containsOnce($, ".o-mail-DiscussCategoryItem");
|
||||
assert.containsNone($, ".o-mail-Discuss-content .o-mail-Message");
|
||||
@@ -54,14 +58,15 @@ QUnit.test(
|
||||
const pyEnv = await startServer();
|
||||
const partnerId = pyEnv["res.partner"].create({ name: "Mario" });
|
||||
pyEnv["res.users"].create({ partner_id: partnerId });
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
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 afterNextRender(async () => {
|
||||
editInput(document.body, ".o-discuss-ChannelSelector input", "mario");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
});
|
||||
await click(".o-discuss-ChannelSelector-suggestion");
|
||||
assert.containsOnce($, ".o-discuss-ChannelSelector span[title='Mario']");
|
||||
assert.containsNone($, ".o-mail-DiscussCategoryItem");
|
||||
@@ -71,9 +76,10 @@ QUnit.test(
|
||||
});
|
||||
assert.containsNone($, ".o-discuss-ChannelSelector span[title='Mario']");
|
||||
|
||||
await afterNextRender(() =>
|
||||
editInput(document.body, ".o-discuss-ChannelSelector input", "mario")
|
||||
);
|
||||
await afterNextRender(async () => {
|
||||
editInput(document.body, ".o-discuss-ChannelSelector input", "mario");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
});
|
||||
await triggerEvent(document.body, ".o-discuss-ChannelSelector input", "keydown", {
|
||||
key: "Enter",
|
||||
});
|
||||
@@ -86,7 +92,8 @@ 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({
|
||||
const { advanceTime, openDiscuss } = await start({
|
||||
hasTimeControl: true,
|
||||
mockRPC(route, params) {
|
||||
if (
|
||||
route.startsWith("/mail") ||
|
||||
@@ -107,6 +114,8 @@ QUnit.test("can join a chat conversation", async (assert) => {
|
||||
await afterNextRender(() =>
|
||||
editInput(document.body, ".o-discuss-ChannelSelector input", "mario")
|
||||
);
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await click(".o-discuss-ChannelSelector-suggestion");
|
||||
await triggerEvent(document.body, ".o-discuss-ChannelSelector input", "keydown", {
|
||||
key: "Enter",
|
||||
@@ -129,13 +138,17 @@ QUnit.test("can create a group chat conversation", async (assert) => {
|
||||
{ name: "Luigi" },
|
||||
]);
|
||||
pyEnv["res.users"].create([{ partner_id: partnerId_1 }, { partner_id: partnerId_2 }]);
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
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 advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await click(".o-discuss-ChannelSelector-suggestion");
|
||||
await insertText(".o-discuss-ChannelSelector input", "Luigi");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await click(".o-discuss-ChannelSelector-suggestion");
|
||||
await triggerEvent(document.body, ".o-discuss-ChannelSelector input", "keydown", {
|
||||
key: "Enter",
|
||||
@@ -145,10 +158,12 @@ QUnit.test("can create a group chat conversation", async (assert) => {
|
||||
});
|
||||
|
||||
QUnit.test("chat search should display no result when no matches found", async (assert) => {
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss();
|
||||
await click(".o-mail-DiscussSidebar i[title='Start a conversation']");
|
||||
await insertText(".o-discuss-ChannelSelector", "Rainbow Panda");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
assert.containsOnce($, ".o-discuss-ChannelSelector-suggestion:contains(No results found)");
|
||||
});
|
||||
|
||||
@@ -158,11 +173,13 @@ QUnit.test(
|
||||
const pyEnv = await startServer();
|
||||
const partnerId = pyEnv["res.partner"].create({ name: "Panda" });
|
||||
pyEnv["res.users"].create({ partner_id: partnerId });
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss();
|
||||
assert.containsNone($, ".o-mail-DiscussCategoryItem");
|
||||
await click(".o-mail-DiscussSidebar i[title='Start a conversation']");
|
||||
await insertText(".o-discuss-ChannelSelector", "Panda");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
assert.containsOnce($, ".o-discuss-ChannelSelector-suggestion");
|
||||
await click(".o-mail-DiscussSidebar");
|
||||
assert.containsNone($, ".o-discuss-ChannelSelector-suggestion");
|
||||
@@ -187,12 +204,14 @@ QUnit.test("Chat is added to discuss on other tab that the one that joined", asy
|
||||
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 tab1 = await start({ asTab: true, hasTimeControl: 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.advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await tab1.click(".o-discuss-ChannelSelector-suggestion");
|
||||
await afterNextRender(() => triggerHotkey("Enter"));
|
||||
assert.containsOnce(tab1.target, ".o-mail-DiscussCategoryItem:contains(Jerry Golay)");
|
||||
|
||||
@@ -9,7 +9,8 @@ import {
|
||||
} from "@mail/../tests/helpers/test_utils";
|
||||
|
||||
import { patchUiSize } from "@mail/../tests/helpers/patch_ui_size";
|
||||
import { triggerHotkey } from "@web/../tests/helpers/utils";
|
||||
import { nextTick, triggerHotkey } from "@web/../tests/helpers/utils";
|
||||
import { DEBOUNCE_FETCH_SUGGESTION_TIME } from "@mail/core/common/suggestion_service";
|
||||
|
||||
QUnit.module("messaging menu");
|
||||
|
||||
@@ -18,11 +19,13 @@ QUnit.test('"Start a conversation" item selection opens chat', async (assert) =>
|
||||
const pyEnv = await startServer();
|
||||
const partnerId = pyEnv["res.partner"].create({ name: "Gandalf" });
|
||||
pyEnv["res.users"].create({ partner_id: partnerId });
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss();
|
||||
await click("button:contains(Chat)");
|
||||
await click("button:contains(Start a conversation)");
|
||||
await insertText("input[placeholder='Start a conversation']", "Gandalf");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await click(".o-discuss-ChannelSelector-suggestion");
|
||||
await afterNextRender(() => triggerHotkey("Enter"));
|
||||
assert.containsOnce($, ".o-mail-ChatWindow-name[title='Gandalf']");
|
||||
@@ -32,22 +35,26 @@ QUnit.test('"New channel" item selection opens channel (existing)', async (asser
|
||||
patchUiSize({ height: 360, width: 640 });
|
||||
const pyEnv = await startServer();
|
||||
pyEnv["discuss.channel"].create({ name: "Gryffindors" });
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss();
|
||||
await click("button:contains(Channel)");
|
||||
await click("button:contains(New Channel)");
|
||||
await insertText("input[placeholder='Add or join a channel']", "Gryff");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
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();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss();
|
||||
await click("button:contains(Channel)");
|
||||
await click("button:contains(New Channel)");
|
||||
await insertText("input[placeholder='Add or join a channel']", "slytherins");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await click(".o-discuss-ChannelSelector-suggestion");
|
||||
assert.containsOnce($, ".o-mail-ChatWindow-name[title='slytherins']");
|
||||
});
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
start,
|
||||
startServer,
|
||||
} from "@mail/../tests/helpers/test_utils";
|
||||
import { DEBOUNCE_FETCH_SUGGESTION_TIME } from "@mail/core/common/suggestion_service";
|
||||
|
||||
import { makeDeferred } from "@web/../tests/helpers/utils";
|
||||
|
||||
@@ -22,7 +23,8 @@ QUnit.test("sidebar find shows channels matching search term", async (assert) =>
|
||||
name: "test",
|
||||
});
|
||||
const def = makeDeferred();
|
||||
const { openDiscuss } = await start({
|
||||
const { advanceTime, openDiscuss } = await start({
|
||||
hasTimeControl: true,
|
||||
async mockRPC(route, args) {
|
||||
if (args.method === "search_read") {
|
||||
def.resolve();
|
||||
@@ -32,6 +34,7 @@ QUnit.test("sidebar find shows channels matching search term", async (assert) =>
|
||||
await openDiscuss();
|
||||
await click(".o-mail-DiscussCategory-add");
|
||||
await insertText(".o-discuss-ChannelSelector input", "test");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
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:
|
||||
@@ -52,7 +55,8 @@ QUnit.test(
|
||||
name: "test",
|
||||
});
|
||||
const def = makeDeferred();
|
||||
const { openDiscuss } = await start({
|
||||
const { advanceTime, openDiscuss } = await start({
|
||||
hasTimeControl: true,
|
||||
async mockRPC(route, args) {
|
||||
if (args.method === "search_read") {
|
||||
def.resolve();
|
||||
@@ -62,6 +66,7 @@ QUnit.test(
|
||||
await openDiscuss();
|
||||
await click(".o-mail-DiscussCategory-add");
|
||||
await insertText(".o-discuss-ChannelSelector input", "test");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
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:
|
||||
|
||||
@@ -7,8 +7,14 @@ import {
|
||||
start,
|
||||
startServer,
|
||||
} from "@mail/../tests/helpers/test_utils";
|
||||
import { DEBOUNCE_FETCH_SUGGESTION_TIME } from "@mail/core/common/suggestion_service";
|
||||
|
||||
import { patchWithCleanup, triggerHotkey, mockTimeout } from "@web/../tests/helpers/utils";
|
||||
import {
|
||||
patchWithCleanup,
|
||||
triggerHotkey,
|
||||
mockTimeout,
|
||||
nextTick,
|
||||
} from "@web/../tests/helpers/utils";
|
||||
|
||||
QUnit.module("discuss inbox");
|
||||
|
||||
@@ -57,7 +63,7 @@ QUnit.test("reply: discard on pressing escape", async (assert) => {
|
||||
notification_type: "inbox",
|
||||
res_partner_id: pyEnv.currentPartnerId,
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss();
|
||||
assert.containsOnce($, ".o-mail-Message");
|
||||
|
||||
@@ -73,6 +79,9 @@ QUnit.test("reply: discard on pressing escape", async (assert) => {
|
||||
|
||||
// Escape on suggestion prompt does not stop replying
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
assert.containsOnce($, ".o-mail-Composer-suggestionList .o-open");
|
||||
await afterNextRender(() => triggerHotkey("Escape"));
|
||||
assert.containsNone($, ".o-mail-Composer-suggestionList .o-open");
|
||||
|
||||
@@ -16,12 +16,14 @@ import { url } from "@web/core/utils/urls";
|
||||
import {
|
||||
editInput,
|
||||
makeDeferred,
|
||||
nextTick,
|
||||
patchWithCleanup,
|
||||
triggerEvent,
|
||||
triggerHotkey,
|
||||
} from "@web/../tests/helpers/utils";
|
||||
|
||||
const { DateTime } = luxon;
|
||||
import { DEBOUNCE_FETCH_SUGGESTION_TIME } from "@mail/core/common/suggestion_service";
|
||||
|
||||
QUnit.module("message");
|
||||
|
||||
@@ -319,11 +321,14 @@ QUnit.test("can add new mentions when editing message", async (assert) => {
|
||||
res_id: channelId,
|
||||
message_type: "comment",
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
await click(".o-mail-Message [title='Expand']");
|
||||
await click(".o-mail-Message [title='Edit']");
|
||||
await insertText(".o-mail-Composer-input", " @");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
await click(".o-mail-Composer-suggestion:contains(TestPartner)");
|
||||
await click(".o-mail-Message a:contains('save')");
|
||||
assert.strictEqual($(".o-mail-Message-body")[0].innerText, "Hello @TestPartner");
|
||||
@@ -1236,12 +1241,15 @@ QUnit.test("Chat with partner should be opened after clicking on their mention",
|
||||
email: "testpartner@odoo.com",
|
||||
});
|
||||
pyEnv["res.users"].create({ partner_id: partnerId });
|
||||
const { openFormView } = await start();
|
||||
const { advanceTime, openFormView } = await start({ hasTimeControl: true });
|
||||
await openFormView("res.partner", partnerId);
|
||||
await click("button:contains(Send message)");
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await insertText(".o-mail-Composer-input", "T");
|
||||
await insertText(".o-mail-Composer-input", "e");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
await click(".o-mail-Composer-suggestion:contains(Test Partner)");
|
||||
await click(".o-mail-Composer-send");
|
||||
await click(".o_mail_redirect");
|
||||
@@ -1284,10 +1292,13 @@ QUnit.test("Channel should be opened after clicking on its mention", async (asse
|
||||
const pyEnv = await startServer();
|
||||
const partnerId = pyEnv["res.partner"].create({});
|
||||
pyEnv["discuss.channel"].create({ name: "my-channel" });
|
||||
const { openFormView } = await start();
|
||||
const { advanceTime, openFormView } = await start({ hasTimeControl: true });
|
||||
await openFormView("res.partner", partnerId);
|
||||
await click("button:contains(Send message)");
|
||||
await insertText(".o-mail-Composer-input", "#");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
await click(".o-mail-Composer-suggestion:contains(my-channel)");
|
||||
await click(".o-mail-Composer-send");
|
||||
await click(".o_channel_redirect");
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
patchWithCleanup,
|
||||
triggerHotkey,
|
||||
} from "@web/../tests/helpers/utils";
|
||||
import { DEBOUNCE_FETCH_SUGGESTION_TIME } from "@mail/core/common/suggestion_service";
|
||||
|
||||
QUnit.module("suggestion", {
|
||||
async beforeEach() {
|
||||
@@ -41,11 +42,14 @@ QUnit.test('display partner mention suggestions on typing "@"', async (assert) =
|
||||
Command.create({ partner_id: partnerId_2 }),
|
||||
],
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
assert.containsNone($, ".o-mail-Composer-suggestion");
|
||||
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
assert.containsN($, ".o-mail-Composer-suggestion", 3);
|
||||
});
|
||||
|
||||
@@ -70,7 +74,7 @@ QUnit.test(
|
||||
Command.create({ partner_id: partnerId_2 }),
|
||||
],
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
assert.containsNone($, ".o-mail-Composer-suggestion");
|
||||
await insertText(".o-mail-Composer-input", "first message");
|
||||
@@ -78,17 +82,23 @@ QUnit.test(
|
||||
await nextTick();
|
||||
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
assert.containsN($, ".o-mail-Composer-suggestion", 3);
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test('display partner mention suggestions on typing "@" in chatter', async (assert) => {
|
||||
const pyEnv = await startServer();
|
||||
const { openFormView } = await start();
|
||||
const { advanceTime, openFormView } = await start({ hasTimeControl: true });
|
||||
await openFormView("res.partner", pyEnv.currentPartnerId);
|
||||
await click("button:contains(Send message)");
|
||||
assert.containsNone($, ".o-mail-Composer-suggestion");
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
assert.containsOnce($, ".o-mail-Composer-suggestion:contains(Mitchell Admin)");
|
||||
});
|
||||
|
||||
@@ -105,9 +115,12 @@ QUnit.test("show other channel member in @ mention", async (assert) => {
|
||||
Command.create({ partner_id: partnerId }),
|
||||
],
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
assert.containsOnce($, ".o-mail-Composer-suggestion:contains(TestPartner)");
|
||||
});
|
||||
|
||||
@@ -124,9 +137,12 @@ QUnit.test("select @ mention insert mention text in composer", async (assert) =>
|
||||
Command.create({ partner_id: partnerId }),
|
||||
],
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
await click(".o-mail-Composer-suggestion:contains(TestPartner)");
|
||||
assert.strictEqual($(".o-mail-Composer-input").val().trim(), "@TestPartner");
|
||||
});
|
||||
@@ -137,10 +153,13 @@ QUnit.test('display channel mention suggestions on typing "#"', async (assert) =
|
||||
name: "General",
|
||||
channel_type: "channel",
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
assert.containsNone($, ".o-mail-Composer-suggestionList .o-open");
|
||||
await insertText(".o-mail-Composer-input", "#");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
assert.containsOnce($, ".o-mail-Composer-suggestionList .o-open");
|
||||
});
|
||||
|
||||
@@ -150,11 +169,14 @@ QUnit.test("mention a channel", async (assert) => {
|
||||
name: "General",
|
||||
channel_type: "channel",
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
assert.containsNone($, ".o-mail-Composer-suggestionList .o-open");
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "");
|
||||
await insertText(".o-mail-Composer-input", "#");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
assert.containsOnce($, ".o-mail-Composer-suggestion");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
assert.strictEqual(
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
patchWithCleanup,
|
||||
triggerEvents,
|
||||
} from "@web/../tests/helpers/utils";
|
||||
import { DEBOUNCE_FETCH_SUGGESTION_TIME } from "@mail/core/common/suggestion_service";
|
||||
|
||||
QUnit.module("thread");
|
||||
|
||||
@@ -208,9 +209,12 @@ QUnit.test("thread is still scrolling after scrolling up then to bottom", async
|
||||
QUnit.test("mention a channel with space in the name", async (assert) => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "General good boy" });
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "#");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
await click(".o-mail-Composer-send");
|
||||
assert.containsOnce($(".o-mail-Message-body"), ".o_channel_redirect");
|
||||
@@ -220,9 +224,12 @@ QUnit.test("mention a channel with space in the name", async (assert) => {
|
||||
QUnit.test('mention a channel with "&" in the name', async (assert) => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "General & good" });
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "#");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
await click(".o-mail-Composer-send");
|
||||
assert.containsOnce($(".o-mail-Message-body"), ".o_channel_redirect");
|
||||
@@ -543,10 +550,13 @@ QUnit.test("Mention a partner with special character (e.g. apostrophe ')", async
|
||||
Command.create({ partner_id: partnerId }),
|
||||
],
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await insertText(".o-mail-Composer-input", "Pyn");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
await click(".o-mail-Composer-send");
|
||||
assert.containsOnce(
|
||||
@@ -575,13 +585,19 @@ QUnit.test("mention 2 different partners that have the same name", async (assert
|
||||
Command.create({ partner_id: partnerId_2 }),
|
||||
],
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await insertText(".o-mail-Composer-input", "Te");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
await click(".o-mail-Composer-suggestion:eq(0)");
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await insertText(".o-mail-Composer-input", "Te");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
await click(".o-mail-Composer-suggestion:eq(1)");
|
||||
await click(".o-mail-Composer-send");
|
||||
assert.containsOnce($, ".o-mail-Message-body");
|
||||
@@ -598,10 +614,13 @@ QUnit.test("mention 2 different partners that have the same name", async (assert
|
||||
QUnit.test("mention a channel on a second line when the first line contains #", async (assert) => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "General good" });
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "#blabla\n");
|
||||
await insertText(".o-mail-Composer-input", "#");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
await click(".o-mail-Composer-send");
|
||||
assert.containsOnce($(".o-mail-Message-body"), ".o_channel_redirect");
|
||||
@@ -613,9 +632,12 @@ QUnit.test(
|
||||
async (assert) => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "General good" });
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "#");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
const text = $(".o-mail-Composer-input").val();
|
||||
$(".o-mail-Composer-input").val(text.slice(0, -1));
|
||||
@@ -639,13 +661,19 @@ QUnit.test("mention 2 different channels that have the same name", async (assert
|
||||
name: "my channel",
|
||||
},
|
||||
]);
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId_1);
|
||||
await insertText(".o-mail-Composer-input", "#");
|
||||
await insertText(".o-mail-Composer-input", "m");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
await click(".o-mail-Composer-suggestion:eq(0)");
|
||||
await insertText(".o-mail-Composer-input", "#");
|
||||
await insertText(".o-mail-Composer-input", "m");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
await click(".o-mail-Composer-suggestion:eq(1)");
|
||||
await click(".o-mail-Composer-send");
|
||||
assert.containsOnce($, ".o-mail-Message-body");
|
||||
@@ -674,11 +702,14 @@ QUnit.test(
|
||||
Command.create({ partner_id: partnerId }),
|
||||
],
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
const { advanceTime, openDiscuss } = await start({ hasTimeControl: true });
|
||||
await openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "email@odoo.com\n");
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await insertText(".o-mail-Composer-input", "Te");
|
||||
await advanceTime(DEBOUNCE_FETCH_SUGGESTION_TIME);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
await click(".o-mail-Composer-send");
|
||||
assert.containsOnce(
|
||||
|
||||
Reference in New Issue
Block a user