[REF] mail: tests: keep using contains whenever possible

In preparation to further remove `afterNextRender` and other slow
waiting operations.

closes odoo/odoo#133022

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
This commit is contained in:
Sébastien Theys
2023-08-25 10:59:28 +02:00
parent 63102bc841
commit 994ca05047
18 changed files with 264 additions and 382 deletions
@@ -75,7 +75,7 @@ QUnit.test(
}
);
QUnit.test("Message post in chat window of chatter should log a note", async (assert) => {
QUnit.test("Message post in chat window of chatter should log a note", async () => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "TestPartner" });
const messageId = pyEnv["mail.message"].create({
@@ -135,7 +135,7 @@ QUnit.test("chat window: basic rendering", async (assert) => {
await click(".o-mail-NotificationItem");
await contains(".o-mail-ChatWindow");
await contains(".o-mail-ChatWindow-header");
assert.containsOnce($(".o-mail-ChatWindow-header"), ".o-mail-ChatWindow-threadAvatar");
await contains(".o-mail-ChatWindow-header .o-mail-ChatWindow-threadAvatar");
await contains(".o-mail-ChatWindow-name:contains(General)");
await contains(".o-mail-ChatWindow-command", 4);
await contains("[title='Start a Call']");
@@ -841,7 +841,7 @@ QUnit.test(
}
);
QUnit.test("chat window: composer state conservation on toggle discuss", async (assert) => {
QUnit.test("chat window: composer state conservation on toggle discuss", async () => {
const pyEnv = await startServer();
const channelId = pyEnv["discuss.channel"].create({});
const { openDiscuss, openView } = await start();
@@ -20,21 +20,16 @@ import { makeDeferred } from "@web/../tests/helpers/utils";
QUnit.module("chat window: new message");
QUnit.test("basic rendering", async (assert) => {
QUnit.test("basic rendering", async () => {
await start();
await click(".o_menu_systray i[aria-label='Messages']");
await click("button:contains(New Message)");
await contains(".o-mail-ChatWindow");
await contains(".o-mail-ChatWindow-header");
await contains(".o-mail-ChatWindow-header .o-mail-ChatWindow-name");
assert.strictEqual(
$(".o-mail-ChatWindow-header .o-mail-ChatWindow-name").text(),
"New message"
);
await contains(".o-mail-ChatWindow-header .o-mail-ChatWindow-name:contains(New message)");
await contains(".o-mail-ChatWindow-header .o-mail-ChatWindow-command", 2);
await contains(".o-mail-ChatWindow-header .o-mail-ChatWindow-command[title='Fold']");
assert.containsOnce(
$,
await contains(
".o-mail-ChatWindow-header .o-mail-ChatWindow-command[title='Close Chat Window']"
);
await contains("span:contains('To :')");
@@ -3,20 +3,13 @@
import { LONG_TYPING, SHORT_TYPING } from "@mail/discuss/typing/common/composer_patch";
import { OTHER_LONG_TYPING } from "@mail/discuss/typing/common/typing_service";
import { Command } from "@mail/../tests/helpers/command";
import {
afterNextRender,
click,
insertText,
nextAnimationFrame,
start,
startServer,
} from "@mail/../tests/helpers/test_utils";
import { click, contains, insertText, start, startServer } from "@mail/../tests/helpers/test_utils";
import { nextTick } from "@web/../tests/helpers/utils";
QUnit.module("typing");
QUnit.test('receive other member typing status "is typing"', async (assert) => {
QUnit.test('receive other member typing status "is typing"', async () => {
const pyEnv = await startServer();
const userId = pyEnv["res.users"].create({ name: "Demo" });
const partnerId = pyEnv["res.partner"].create({ name: "Demo", user_ids: [userId] });
@@ -29,23 +22,20 @@ QUnit.test('receive other member typing status "is typing"', async (assert) => {
});
const { env, openDiscuss } = await start();
await openDiscuss(channelId);
assert.strictEqual($(".o-discuss-Typing").text(), "");
await contains(".o-discuss-Typing:not(:contains(Demo is typing...))");
// simulate receive typing notification from demo
await afterNextRender(() =>
pyEnv.withUser(userId, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
)
pyEnv.withUser(userId, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
);
assert.strictEqual($(".o-discuss-Typing").text(), "Demo is typing...");
await contains(".o-discuss-Typing:contains(Demo is typing...)");
});
QUnit.test(
'receive other member typing status "is typing" then "no longer is typing"',
async (assert) => {
async () => {
const pyEnv = await startServer();
const userId = pyEnv["res.users"].create({ name: "Demo" });
const partnerId = pyEnv["res.partner"].create({ name: "Demo", user_ids: [userId] });
@@ -58,35 +48,30 @@ QUnit.test(
});
const { env, openDiscuss } = await start();
await openDiscuss(channelId);
assert.strictEqual($(".o-discuss-Typing").text(), "");
await contains(".o-discuss-Typing:not(:contains(Demo is typing...))");
// simulate receive typing notification from demo "is typing"
await afterNextRender(() =>
pyEnv.withUser(userId, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
)
pyEnv.withUser(userId, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
);
assert.strictEqual($(".o-discuss-Typing").text(), "Demo is typing...");
await contains(".o-discuss-Typing:contains(Demo is typing...)");
// simulate receive typing notification from demo "is no longer typing"
await afterNextRender(() =>
pyEnv.withUser(userId, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: false,
})
)
pyEnv.withUser(userId, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: false,
})
);
assert.strictEqual($(".o-discuss-Typing").text(), "");
await contains(".o-discuss-Typing:not(:contains(Demo is typing...))");
}
);
QUnit.test(
'assume other member typing status becomes "no longer is typing" after long without any updated typing status',
async (assert) => {
async () => {
const pyEnv = await startServer();
const userId = pyEnv["res.users"].create({ name: "Demo" });
const partnerId = pyEnv["res.partner"].create({ name: "Demo", user_ids: [userId] });
@@ -100,27 +85,24 @@ QUnit.test(
const { advanceTime, env, openDiscuss } = await start({ hasTimeControl: true });
await openDiscuss(channelId);
assert.strictEqual($(".o-discuss-Typing").text(), "");
await contains(".o-discuss-Typing:not(:contains(Demo is typing...))");
// simulate receive typing notification from demo "is typing"
await afterNextRender(() =>
pyEnv.withUser(userId, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
)
pyEnv.withUser(userId, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
);
assert.strictEqual($(".o-discuss-Typing").text(), "Demo is typing...");
await afterNextRender(() => advanceTime(OTHER_LONG_TYPING));
assert.strictEqual($(".o-discuss-Typing").text(), "");
await contains(".o-discuss-Typing:contains(Demo is typing...)");
advanceTime(OTHER_LONG_TYPING);
await contains(".o-discuss-Typing:not(:contains(Demo is typing...))");
}
);
QUnit.test(
'other member typing status "is typing" refreshes of assuming no longer typing',
async (assert) => {
async () => {
const pyEnv = await startServer();
const userId = pyEnv["res.users"].create({ name: "Demo" });
const partnerId = pyEnv["res.partner"].create({ name: "Demo", user_ids: [userId] });
@@ -133,18 +115,16 @@ QUnit.test(
});
const { advanceTime, env, openDiscuss } = await start({ hasTimeControl: true });
await openDiscuss(channelId);
assert.strictEqual($(".o-discuss-Typing").text(), "");
await contains(".o-discuss-Typing:not(:contains(Demo is typing...))");
// simulate receive typing notification from demo "is typing"
await afterNextRender(() =>
pyEnv.withUser(userId, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
)
pyEnv.withUser(userId, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
);
assert.strictEqual($(".o-discuss-Typing").text(), "Demo is typing...");
await contains(".o-discuss-Typing:contains(Demo is typing...)");
// simulate receive typing notification from demo "is typing" again after long time.
await advanceTime(LONG_TYPING);
@@ -156,14 +136,13 @@ QUnit.test(
);
await nextTick();
await advanceTime(LONG_TYPING);
await nextAnimationFrame();
assert.strictEqual($(".o-discuss-Typing").text(), "Demo is typing...");
await afterNextRender(() => advanceTime(OTHER_LONG_TYPING - LONG_TYPING));
assert.strictEqual($(".o-discuss-Typing").text(), "");
await contains(".o-discuss-Typing:contains(Demo is typing...)");
advanceTime(OTHER_LONG_TYPING - LONG_TYPING);
await contains(".o-discuss-Typing:not(:contains(Demo is typing...))");
}
);
QUnit.test('receive several other members typing status "is typing"', async (assert) => {
QUnit.test('receive several other members typing status "is typing"', async () => {
const pyEnv = await startServer();
const [userId_1, userId_2, userId_3] = pyEnv["res.users"].create([
{ name: "Other 10" },
@@ -186,70 +165,48 @@ QUnit.test('receive several other members typing status "is typing"', async (ass
});
const { env, openDiscuss } = await start();
await openDiscuss(channelId);
assert.strictEqual($(".o-discuss-Typing").text(), "");
await contains(".o-discuss-Typing:not(:contains(Demo is typing...))");
// simulate receive typing notification from other 10 (is typing)
await afterNextRender(() =>
pyEnv.withUser(userId_1, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
)
pyEnv.withUser(userId_1, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
);
assert.strictEqual($(".o-discuss-Typing").text(), "Other 10 is typing...");
await contains(".o-discuss-Typing:contains(Other 10 is typing...)");
// simulate receive typing notification from other 11 (is typing)
await afterNextRender(() =>
pyEnv.withUser(userId_2, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
)
pyEnv.withUser(userId_2, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
);
assert.strictEqual(
$(".o-discuss-Typing").text(),
"Other 10 and Other 11 are typing...",
"Should display longer typer named first"
);
await contains(".o-discuss-Typing:contains(Other 10 and Other 11 are typing...)");
// simulate receive typing notification from other 12 (is typing)
await afterNextRender(() =>
pyEnv.withUser(userId_3, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
)
pyEnv.withUser(userId_3, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
);
assert.strictEqual($(".o-discuss-Typing").text(), "Other 10, Other 11 and more are typing...");
await contains(".o-discuss-Typing:contains(Other 10, Other 11 and more are typing...)");
// simulate receive typing notification from other 10 (no longer is typing)
await afterNextRender(() =>
pyEnv.withUser(userId_1, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: false,
})
)
pyEnv.withUser(userId_1, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: false,
})
);
assert.strictEqual($(".o-discuss-Typing").text(), "Other 11 and Other 12 are typing...");
await contains(".o-discuss-Typing:contains(Other 11 and Other 12 are typing...)");
// simulate receive typing notification from other 10 (is typing again)
await afterNextRender(() =>
pyEnv.withUser(userId_1, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
)
);
assert.strictEqual(
$(".o-discuss-Typing").text(),
"Other 11, Other 12 and more are typing...",
"Should order by longer typer ('Other 10' just recently restarted typing)"
pyEnv.withUser(userId_1, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
);
await contains(".o-discuss-Typing:contains(Other 11, Other 12 and more are typing...)");
});
QUnit.test("current partner notify is typing to other thread members", async (assert) => {
@@ -334,13 +291,11 @@ QUnit.test(
await openDiscuss(channelId);
await insertText(".o-mail-Composer-input", "a");
assert.verifySteps(["notify_typing:true"]);
await nextAnimationFrame();
assert.strictEqual($(".o-discuss-Typing").text(), "");
await contains(".o-discuss-Typing:not(:contains(Demo is typing...))");
}
);
QUnit.test("chat: correspondent is typing", async (assert) => {
QUnit.test("chat: correspondent is typing", async () => {
const pyEnv = await startServer();
const userId = pyEnv["res.users"].create({ name: "Demo" });
const partnerId = pyEnv["res.partner"].create({
@@ -357,37 +312,27 @@ QUnit.test("chat: correspondent is typing", async (assert) => {
});
const { env, openDiscuss } = await start();
await openDiscuss();
assert.containsOnce(
$(".o-mail-DiscussSidebarChannel"),
".o-mail-DiscussSidebarChannel-threadIcon"
);
assert.containsOnce($, ".fa-circle.text-success");
await contains(".o-mail-DiscussSidebarChannel .o-mail-DiscussSidebarChannel-threadIcon");
await contains(".fa-circle.text-success");
// simulate receive typing notification from demo "is typing"
await afterNextRender(() =>
pyEnv.withUser(userId, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
)
pyEnv.withUser(userId, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
);
assert.containsOnce($, ".o-discuss-Typing-icon");
assert.strictEqual($(".o-discuss-Typing-icon")[0].title, "Demo is typing...");
await contains(".o-discuss-Typing-icon[title='Demo is typing...']");
// simulate receive typing notification from demo "no longer is typing"
await afterNextRender(() =>
pyEnv.withUser(userId, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: false,
})
)
pyEnv.withUser(userId, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: false,
})
);
assert.containsOnce($, ".fa-circle.text-success");
await contains(".fa-circle.text-success");
});
QUnit.test("chat: correspondent is typing in chat window", async (assert) => {
QUnit.test("chat: correspondent is typing in chat window", async () => {
const pyEnv = await startServer();
const userId = pyEnv["res.users"].create({ name: "Demo" });
const partnerId = pyEnv["res.partner"].create({
@@ -405,25 +350,21 @@ QUnit.test("chat: correspondent is typing in chat window", async (assert) => {
const { env } = await start();
await click(".o_menu_systray i[aria-label='Messages']");
await click(".o-mail-NotificationItem");
assert.containsNone($, "[title='Demo is typing...']");
await contains("[title='Demo is typing...']", 0);
// simulate receive typing notification from demo "is typing"
await afterNextRender(() =>
pyEnv.withUser(userId, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
)
pyEnv.withUser(userId, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: true,
})
);
assert.containsOnce($, "[title='Demo is typing...']");
await contains("[title='Demo is typing...']");
// simulate receive typing notification from demo "no longer is typing"
await afterNextRender(() =>
pyEnv.withUser(userId, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: false,
})
)
pyEnv.withUser(userId, () =>
env.services.rpc("/discuss/channel/notify_typing", {
channel_id: channelId,
is_typing: false,
})
);
assert.containsNone($, "[title='Demo is typing...']");
await contains("[title='Demo is typing...']", 0);
});
@@ -451,7 +451,6 @@ QUnit.test("sidebar: Inbox should have icon", async () => {
QUnit.test("sidebar: default active inbox", async () => {
const { openDiscuss } = await start();
openDiscuss();
await contains("button:contains(Inbox)");
await contains("button:contains(Inbox).o-active");
});
@@ -217,7 +217,7 @@ QUnit.test("sidebar quick search at 20 or more pinned channels", async () => {
await contains(".o-mail-DiscussSidebarChannel", 0);
});
QUnit.test("sidebar: basic chat rendering", async (assert) => {
QUnit.test("sidebar: basic chat rendering", async () => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Demo" });
pyEnv["discuss.channel"].create({
@@ -229,16 +229,13 @@ QUnit.test("sidebar: basic chat rendering", async (assert) => {
});
const { openDiscuss } = await start();
openDiscuss();
await contains(".o-mail-DiscussSidebarChannel:contains(Demo)");
const $chat = $(".o-mail-DiscussSidebarChannel:contains(Demo)");
assert.containsOnce($chat, "img[data-alt='Thread Image']");
assert.containsOnce($chat, "span:contains(Demo)");
assert.containsOnce($chat, ".o-mail-DiscussSidebarChannel-commands");
assert.containsOnce(
$chat,
".o-mail-DiscussSidebarChannel-commands div[title='Unpin Conversation']"
await contains(".o-mail-DiscussSidebarChannel");
await contains(".o-mail-DiscussSidebarChannel span:contains(Demo)");
await contains(".o-mail-DiscussSidebarChannel img[data-alt='Thread Image']");
await contains(
".o-mail-DiscussSidebarChannel .o-mail-DiscussSidebarChannel-commands div[title='Unpin Conversation']"
);
assert.containsNone($chat, ".badge");
await contains(".o-mail-DiscussSidebarChannel .badge", 0);
});
QUnit.test("sidebar: show pinned channel", async () => {
@@ -249,7 +246,7 @@ QUnit.test("sidebar: show pinned channel", async () => {
await contains(".o-mail-DiscussSidebarChannel:contains(General)");
});
QUnit.test("sidebar: open pinned channel", async (assert) => {
QUnit.test("sidebar: open pinned channel", async () => {
const pyEnv = await startServer();
pyEnv["discuss.channel"].create({ name: "General" });
const { openDiscuss } = await start();
@@ -937,7 +934,7 @@ QUnit.test("chat - avatar: should have correct avatar", async () => {
await contains(`img[data-src='/web/image/res.partner/${partnerId}/avatar_128']`);
});
QUnit.test("chat should be sorted by last activity time [REQUIRE FOCUS]", async (assert) => {
QUnit.test("chat should be sorted by last activity time [REQUIRE FOCUS]", async () => {
const pyEnv = await startServer();
const [demo_id, yoshi_id] = pyEnv["res.partner"].create([{ name: "Demo" }, { name: "Yoshi" }]);
pyEnv["res.users"].create([{ partner_id: demo_id }, { partner_id: yoshi_id }]);
+2 -2
View File
@@ -62,7 +62,7 @@ QUnit.test("addLink: utility function and special entities", function (assert) {
}
});
QUnit.test("addLink: linkify inside text node (1 occurrence)", function (assert) {
QUnit.test("addLink: linkify inside text node (1 occurrence)", async (assert) => {
const content = "<p>some text https://somelink.com</p>";
const linkified = parseAndTransform(content, addLink);
assert.ok(linkified.startsWith("<p>some text <a"));
@@ -76,7 +76,7 @@ QUnit.test("addLink: linkify inside text node (1 occurrence)", function (assert)
fragment.appendChild(div);
div.innerHTML = linkified;
assert.strictEqual(div.textContent, "some text https://somelink.com");
assert.containsOnce(div, "a");
await contains("a", 1, { target: div });
assert.strictEqual(div.querySelector(":scope a").textContent, "https://somelink.com");
});
@@ -1,7 +1,7 @@
/* @odoo-module */
import { Command } from "@mail/../tests/helpers/command";
import { startServer, start, afterNextRender } from "@mail/../tests/helpers/test_utils";
import { contains, startServer, start, afterNextRender } from "@mail/../tests/helpers/test_utils";
QUnit.module("message_seen_indicator");
@@ -34,9 +34,9 @@ QUnit.test("rendering when just one has received the message", async (assert) =>
});
const { openDiscuss } = await start();
await openDiscuss(channelId);
assert.containsOnce($, ".o-mail-MessageSeenIndicator");
await contains(".o-mail-MessageSeenIndicator");
assert.doesNotHaveClass($(".o-mail-MessageSeenIndicator"), "o-all-seen");
assert.containsOnce($, ".o-mail-MessageSeenIndicator i");
await contains(".o-mail-MessageSeenIndicator i");
});
QUnit.test("rendering when everyone have received the message", async (assert) => {
@@ -65,9 +65,9 @@ QUnit.test("rendering when everyone have received the message", async (assert) =
});
const { openDiscuss } = await start();
await openDiscuss(channelId);
assert.containsOnce($, ".o-mail-MessageSeenIndicator");
await contains(".o-mail-MessageSeenIndicator");
assert.doesNotHaveClass($(".o-mail-MessageSeenIndicator"), "o-all-seen");
assert.containsOnce($, ".o-mail-MessageSeenIndicator i");
await contains(".o-mail-MessageSeenIndicator i");
});
QUnit.test("rendering when just one has seen the message", async (assert) => {
@@ -103,9 +103,9 @@ QUnit.test("rendering when just one has seen the message", async (assert) => {
});
const { openDiscuss } = await start();
await openDiscuss(channelId);
assert.containsOnce($, ".o-mail-MessageSeenIndicator");
await contains(".o-mail-MessageSeenIndicator");
assert.doesNotHaveClass($(".o-mail-MessageSeenIndicator"), "o-all-seen");
assert.containsN($, ".o-mail-MessageSeenIndicator i", 2);
await contains(".o-mail-MessageSeenIndicator i", 2);
});
QUnit.test("rendering when just one has seen & received the message", async (assert) => {
@@ -137,9 +137,9 @@ QUnit.test("rendering when just one has seen & received the message", async (ass
});
const { openDiscuss } = await start();
await openDiscuss(channelId);
assert.containsOnce($, ".o-mail-MessageSeenIndicator");
await contains(".o-mail-MessageSeenIndicator");
assert.doesNotHaveClass($(".o-mail-MessageSeenIndicator"), "o-all-seen");
assert.containsN($, ".o-mail-MessageSeenIndicator i", 2);
await contains(".o-mail-MessageSeenIndicator i", 2);
});
QUnit.test("rendering when just everyone has seen the message", async (assert) => {
@@ -168,12 +168,12 @@ QUnit.test("rendering when just everyone has seen the message", async (assert) =
});
const { openDiscuss } = await start();
await openDiscuss(channelId);
assert.containsOnce($, ".o-mail-MessageSeenIndicator");
await contains(".o-mail-MessageSeenIndicator");
assert.hasClass($(".o-mail-MessageSeenIndicator"), "o-all-seen");
assert.containsN($, ".o-mail-MessageSeenIndicator i", 2);
await contains(".o-mail-MessageSeenIndicator i", 2);
});
QUnit.test("'channel_fetch' notification received is correctly handled", async (assert) => {
QUnit.test("'channel_fetch' notification received is correctly handled", async () => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "test" });
const channelId = pyEnv["discuss.channel"].create({
@@ -192,8 +192,8 @@ QUnit.test("'channel_fetch' notification received is correctly handled", async (
});
const { openDiscuss } = await start();
await openDiscuss(channelId);
assert.containsOnce($, ".o-mail-Message");
assert.containsNone($, ".o-mail-MessageSeenIndicator i");
await contains(".o-mail-Message");
await contains(".o-mail-MessageSeenIndicator i", 0);
const channel = pyEnv["discuss.channel"].searchRead([["id", "=", channelId]])[0];
// Simulate received channel fetched notification
@@ -204,10 +204,10 @@ QUnit.test("'channel_fetch' notification received is correctly handled", async (
partner_id: partnerId,
});
});
assert.containsOnce($, ".o-mail-MessageSeenIndicator i");
await contains(".o-mail-MessageSeenIndicator i");
});
QUnit.test("'channel_seen' notification received is correctly handled", async (assert) => {
QUnit.test("'channel_seen' notification received is correctly handled", async () => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "test" });
const channelId = pyEnv["discuss.channel"].create({
@@ -226,8 +226,8 @@ QUnit.test("'channel_seen' notification received is correctly handled", async (a
});
const { openDiscuss } = await start();
await openDiscuss(channelId);
assert.containsOnce($, ".o-mail-Message");
assert.containsNone($, ".o-mail-MessageSeenIndicator i");
await contains(".o-mail-Message");
await contains(".o-mail-MessageSeenIndicator i", 0);
const channel = pyEnv["discuss.channel"].searchRead([["id", "=", channelId]])[0];
// Simulate received channel seen notification
@@ -238,12 +238,12 @@ QUnit.test("'channel_seen' notification received is correctly handled", async (a
partner_id: partnerId,
});
});
assert.containsN($, ".o-mail-MessageSeenIndicator i", 2);
await contains(".o-mail-MessageSeenIndicator i", 2);
});
QUnit.test(
"'channel_fetch' notification then 'channel_seen' received are correctly handled",
async (assert) => {
async () => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Recipient" });
const channelId = pyEnv["discuss.channel"].create({
@@ -262,8 +262,8 @@ QUnit.test(
});
const { openDiscuss } = await start();
await openDiscuss(channelId);
assert.containsOnce($, ".o-mail-Message");
assert.containsNone($, ".o-mail-MessageSeenIndicator i");
await contains(".o-mail-Message");
await contains(".o-mail-MessageSeenIndicator i", 0);
const channel = pyEnv["discuss.channel"].searchRead([["id", "=", channelId]])[0];
// Simulate received channel fetched notification
@@ -274,7 +274,7 @@ QUnit.test(
partner_id: partnerId,
});
});
assert.containsOnce($, ".o-mail-MessageSeenIndicator i");
await contains(".o-mail-MessageSeenIndicator i");
// Simulate received channel seen notification
await afterNextRender(() => {
@@ -284,13 +284,13 @@ QUnit.test(
partner_id: partnerId,
});
});
assert.containsN($, ".o-mail-MessageSeenIndicator i", 2);
await contains(".o-mail-MessageSeenIndicator i", 2);
}
);
QUnit.test(
"do not show message seen indicator on the last message seen by everyone when the current user is not author of the message",
async (assert) => {
async () => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Demo User" });
const channelId = pyEnv["discuss.channel"].create({
@@ -311,14 +311,14 @@ QUnit.test(
pyEnv["discuss.channel.member"].write(memberIds, { seen_message_id: messageId });
const { openDiscuss } = await start();
await openDiscuss(channelId);
assert.containsOnce($, ".o-mail-Message");
assert.containsNone($, ".o-mail-MessageSeenIndicator");
await contains(".o-mail-Message");
await contains(".o-mail-MessageSeenIndicator", 0);
}
);
QUnit.test(
"do not show message seen indicator on all the messages of the current user that are older than the last message seen by everyone",
async (assert) => {
async () => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Demo User" });
const channelId = pyEnv["discuss.channel"].create({
@@ -347,21 +347,20 @@ QUnit.test(
pyEnv["discuss.channel.member"].write(memberIds, { seen_message_id: messageId_2 });
const { openDiscuss } = await start();
await openDiscuss(channelId);
assert.containsOnce($, ".o-mail-Message:contains(Message before last seen)");
assert.containsOnce(
$,
await contains(".o-mail-Message:contains(Message before last seen)");
await contains(
".o-mail-Message:contains(Message before last seen) .o-mail-MessageSeenIndicator"
);
assert.containsNone(
$,
".o-mail-Message:contains(Message before last seen) .o-mail-MessageSeenIndicator i"
await contains(
".o-mail-Message:contains(Message before last seen) .o-mail-MessageSeenIndicator i",
0
);
}
);
QUnit.test(
"only show messaging seen indicator if authored by me, after last seen by all message",
async (assert) => {
async () => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Demo User" });
const channelId = pyEnv["discuss.channel"].create({
@@ -385,8 +384,8 @@ QUnit.test(
});
const { openDiscuss } = await start();
await openDiscuss(channelId);
assert.containsOnce($, ".o-mail-Message");
assert.containsOnce($, ".o-mail-MessageSeenIndicator");
assert.containsN($, ".o-mail-MessageSeenIndicator i", 1);
await contains(".o-mail-Message");
await contains(".o-mail-MessageSeenIndicator");
await contains(".o-mail-MessageSeenIndicator i");
}
);
@@ -11,7 +11,7 @@ import {
} from "@mail/../tests/helpers/test_utils";
import { deserializeDateTime } from "@web/core/l10n/dates";
import { url } from "@web/core/utils/urls";
import { getOrigin } from "@web/core/utils/urls";
import {
editInput,
makeDeferred,
@@ -591,7 +591,7 @@ QUnit.test("Add the same reaction twice from the emoji picker", async () => {
await contains(".o-mail-MessageReaction:contains('😅')");
});
QUnit.test("basic rendering of message", async (assert) => {
QUnit.test("basic rendering of message", async () => {
const pyEnv = await startServer();
const channelId = pyEnv["discuss.channel"].create({ name: "general" });
const partnerId = pyEnv["res.partner"].create({ name: "Demo" });
@@ -604,27 +604,17 @@ QUnit.test("basic rendering of message", async (assert) => {
});
const { openDiscuss } = await start();
openDiscuss(channelId);
await contains(".o-mail-Message:contains(body)");
const $message = $(".o-mail-Message:contains(body)");
assert.containsOnce($message, ".o-mail-Message-sidebar");
assert.containsOnce($message, ".o-mail-Message-sidebar .o-mail-Message-avatarContainer img");
assert.hasAttrValue(
$message.find(".o-mail-Message-sidebar .o-mail-Message-avatarContainer img"),
"data-src",
url(`/discuss/channel/${channelId}/partner/${partnerId}/avatar_128`)
await contains(".o-mail-Message");
await contains(".o-mail-Message .o-mail-Message-content:contains(body)");
await contains(
`.o-mail-Message .o-mail-Message-sidebar .o-mail-Message-avatarContainer img[data-src='${getOrigin()}/discuss/channel/${channelId}/partner/${partnerId}/avatar_128']`
);
assert.containsOnce($message, ".o-mail-Message-header");
assert.containsOnce($message, ".o-mail-Message-header .o-mail-Message-author:contains(Demo)");
assert.containsOnce($message, ".o-mail-Message-header .o-mail-Message-date");
assert.hasAttrValue(
$message.find(".o-mail-Message-header .o-mail-Message-date"),
"title",
deserializeDateTime("2019-04-20 10:00:00").toLocaleString(
DateTime.DATETIME_SHORT_WITH_SECONDS
)
await contains(".o-mail-Message .o-mail-Message-header .o-mail-Message-author:contains(Demo)");
await contains(
`.o-mail-Message .o-mail-Message-header .o-mail-Message-date[title='${deserializeDateTime(
"2019-04-20 10:00:00"
).toLocaleString(DateTime.DATETIME_SHORT_WITH_SECONDS)}']`
);
assert.containsOnce($message, ".o-mail-Message-content");
assert.strictEqual($message.find(".o-mail-Message-content").text(), "body");
});
QUnit.test("should not be able to reply to temporary/transient messages", async () => {
@@ -638,7 +628,7 @@ QUnit.test("should not be able to reply to temporary/transient messages", async
await contains(".o-mail-Message [title='Reply']", 0);
});
QUnit.test("message comment of same author within 1min. should be squashed", async (assert) => {
QUnit.test("message comment of same author within 1min. should be squashed", async () => {
// messages are squashed when "close", e.g. less than 1 minute has elapsed
// from messages of same author and same thread. Note that this should
// be working in non-mailboxes
@@ -800,7 +790,7 @@ QUnit.test(
QUnit.test(
"Name of message author is not displayed in chat window for channel of type chat",
async (assert) => {
async () => {
const pyEnv = await startServer();
const channelId = pyEnv["discuss.channel"].create({ channel_type: "chat" });
const partnerId = pyEnv["res.partner"].create({ name: "A" });
@@ -1503,7 +1493,7 @@ QUnit.test("Mark as unread", async () => {
await contains(".o-mail-DiscussSidebarChannel .badge:contains(1)");
});
QUnit.test("Avatar of unknown author", async (assert) => {
QUnit.test("Avatar of unknown author", async () => {
const pyEnv = await startServer();
pyEnv["mail.message"].create({
body: "<p>Want to know features and benefits of using the new software.</p>",
@@ -1,47 +1,36 @@
/* @odoo-module */
import { Command } from "@mail/../tests/helpers/command";
import {
afterNextRender,
click,
insertText,
start,
startServer,
} from "@mail/../tests/helpers/test_utils";
import { click, contains, insertText, start, startServer } from "@mail/../tests/helpers/test_utils";
QUnit.module("messaging");
QUnit.test(
"Receiving a new message out of discuss app should open a chat window",
async (assert) => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Dumbledore" });
const userId = pyEnv["res.users"].create({ partner_id: partnerId });
const channelId = pyEnv["discuss.channel"].create({
channel_member_ids: [
Command.create({ partner_id: pyEnv.currentPartnerId }),
Command.create({ partner_id: partnerId }),
],
channel_type: "chat",
});
const { env } = await start();
// simulate receving new message
await afterNextRender(() =>
pyEnv.withUser(userId, () =>
env.services.rpc("/mail/message/post", {
post_data: { body: "new message", message_type: "comment" },
thread_id: channelId,
thread_model: "discuss.channel",
})
)
);
assert.containsOnce($, ".o-mail-ChatWindow-header:contains(Dumbledore)");
}
);
QUnit.test("Receiving a new message out of discuss app should open a chat window", async () => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Dumbledore" });
const userId = pyEnv["res.users"].create({ partner_id: partnerId });
const channelId = pyEnv["discuss.channel"].create({
channel_member_ids: [
Command.create({ partner_id: pyEnv.currentPartnerId }),
Command.create({ partner_id: partnerId }),
],
channel_type: "chat",
});
const { env } = await start();
// simulate receving new message
pyEnv.withUser(userId, () =>
env.services.rpc("/mail/message/post", {
post_data: { body: "new message", message_type: "comment" },
thread_id: channelId,
thread_model: "discuss.channel",
})
);
await contains(".o-mail-ChatWindow-header:contains(Dumbledore)");
});
QUnit.test(
"Receiving a new message in discuss app should open a chat window after leaving discuss app",
async (assert) => {
async () => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Dumbledore" });
const userId = pyEnv["res.users"].create({ partner_id: partnerId });
@@ -64,13 +53,13 @@ QUnit.test(
);
// leaving discuss.
await openFormView("res.partner", partnerId);
assert.containsOnce($, ".o-mail-ChatWindow-header:contains(Dumbledore)");
await contains(".o-mail-ChatWindow-header:contains(Dumbledore)");
}
);
QUnit.test(
"Posting a message in discuss app should not open a chat window after leaving discuss app",
async (assert) => {
async () => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Dumbledore" });
const channelId = pyEnv["discuss.channel"].create({
@@ -86,6 +75,7 @@ QUnit.test(
await click(".o-mail-Composer-send:not(:disabled)");
// leaving discuss.
await openFormView("res.partner", partnerId);
assert.containsNone($, ".o-mail-ChatWindow-header:contains(Dumbledore)");
// weak test, no guarantee that we waited long enough for the potential chat window to open
await contains(".o-mail-ChatWindow-header:contains(Dumbledore)", 0);
}
);
@@ -352,7 +352,7 @@ QUnit.test("mark unread channel as read", async (assert) => {
await contains(".o-mail-ChatWindow", 0);
});
QUnit.test("mark failure as read", async (assert) => {
QUnit.test("mark failure as read", async () => {
const pyEnv = await startServer();
const messageId = pyEnv["mail.message"].create({
message_type: "email",
@@ -378,10 +378,7 @@ QUnit.test("mark failure as read", async (assert) => {
await click(".o-mail-NotificationItem [title='Mark As Read']");
await contains(".o-mail-NotificationItem:contains(Channel)", 0);
assert.containsNone(
$,
".o-mail-NotificationItem:contains(An error occurred when sending an email)"
);
await contains(".o-mail-NotificationItem:contains(An error occurred when sending an email)", 0);
});
QUnit.test("different discuss.channel are not grouped", async () => {
@@ -633,7 +630,7 @@ QUnit.test("filtered previews", async () => {
await contains('.o-mail-NotificationItem:contains("channel1")');
});
QUnit.test("no code injection in message body preview", async (assert) => {
QUnit.test("no code injection in message body preview", async () => {
const pyEnv = await startServer();
const channelId = pyEnv["discuss.channel"].create({});
pyEnv["mail.message"].create({
@@ -643,15 +640,13 @@ QUnit.test("no code injection in message body preview", async (assert) => {
});
await start();
await click(".o_menu_systray .dropdown-toggle:has(i[aria-label='Messages'])");
await contains(".o-mail-NotificationItem");
assert.strictEqual(
$(".o-mail-NotificationItem-text").text().replace(/\s/g, ""),
"You:&shoulnotberaisedthrownewError('CodeInjectionError');"
await contains(
".o-mail-NotificationItem-text:contains(You: &shoulnotberaisedthrow new Error('CodeInjectionError');)"
);
assert.containsNone($(".o-mail-NotificationItem-text"), "script");
await contains(".o-mail-NotificationItem-text script", 0);
});
QUnit.test("no code injection in message body preview from sanitized message", async (assert) => {
QUnit.test("no code injection in message body preview from sanitized message", async () => {
const pyEnv = await startServer();
const channelId = pyEnv["discuss.channel"].create({});
pyEnv["mail.message"].create({
@@ -661,13 +656,10 @@ QUnit.test("no code injection in message body preview from sanitized message", a
});
await start();
await click(".o_menu_systray .dropdown-toggle:has(i[aria-label='Messages'])");
await contains(".o-mail-NotificationItem");
await contains(".o-mail-NotificationItem-text");
assert.strictEqual(
$(".o-mail-NotificationItem-text").text().replace(/\s/g, ""),
"You:<em>&shoulnotberaised</em><script>thrownewError('CodeInjectionError');</script>"
await contains(
".o-mail-NotificationItem-text:contains(You: <em>&shoulnotberaised</em><script>throw new Error('CodeInjectionError');</script>)"
);
assert.containsNone($(".o-mail-NotificationItem-text"), "script");
await contains(".o-mail-NotificationItem-text script", 0);
});
QUnit.test("<br/> tags in message body preview are transformed in spaces", async (assert) => {
@@ -31,7 +31,7 @@ QUnit.test("simplest layout", async (assert) => {
await contains(".o-mail-AttachmentCard-image");
assert.hasClass($(".o-mail-AttachmentCard-image"), "o_image"); // required for mimetype.scss style
assert.hasAttrValue($(".o-mail-AttachmentCard-image"), "data-mimetype", "text/plain"); // required for mimetype.scss style
assert.containsN($, ".o-mail-AttachmentCard-aside button", 2);
await contains(".o-mail-AttachmentCard-aside button", 2);
await contains(".o-mail-AttachmentCard-unlink");
await contains(".o-mail-AttachmentCard-aside button[title='Download']");
});
@@ -40,7 +40,7 @@ QUnit.test("list activity widget with no activity", async (assert) => {
res_model: "res.users",
views: [[false, "list"]],
});
assert.containsOnce($, ".o-mail-ActivityButton i.text-muted");
await contains(".o-mail-ActivityButton i.text-muted");
await contains(".o-mail-ListActivity-summary:eq(0):contains()");
assert.verifySteps(["/web/dataset/call_kw/res.users/unity_web_search_read"]);
});
@@ -92,12 +92,12 @@ QUnit.test("list activity widget with activities", async (assert) => {
res_model: "res.users",
views: [[false, "list"]],
});
assert.containsOnce($(".o_data_row:eq(0)"), ".o-mail-ActivityButton i.text-warning.fa-phone");
await contains(".o_data_row:eq(0) .o-mail-ActivityButton i.text-warning.fa-phone");
assert.strictEqual(
$(".o_data_row:eq(0) .o-mail-ListActivity-summary")[0].innerText,
"Call with Al"
);
assert.containsOnce($(".o_data_row:eq(1)"), ".o-mail-ActivityButton i.text-success.fa-clock-o");
await contains(".o_data_row:eq(1) .o-mail-ActivityButton i.text-success.fa-clock-o");
assert.strictEqual($(".o_data_row:eq(1) .o-mail-ListActivity-summary")[0].innerText, "Type 2");
assert.verifySteps(["/web/dataset/call_kw/res.users/unity_web_search_read"]);
});
@@ -140,7 +140,7 @@ QUnit.test("list activity widget with exception", async (assert) => {
res_model: "res.users",
views: [[false, "list"]],
});
assert.containsOnce($, ".o-mail-ActivityButton i.text-warning.fa-warning");
await contains(".o-mail-ActivityButton i.text-warning.fa-warning");
await contains(".o-mail-ListActivity-summary:eq(0):contains(Warning)");
assert.verifySteps(["/web/dataset/call_kw/res.users/unity_web_search_read"]);
});
@@ -229,7 +229,7 @@ QUnit.test("list activity widget: open dropdown", async (assert) => {
assert.verifySteps(["unity_web_search_read", "activity_format", "action_feedback", "web_read"]);
});
QUnit.test("list activity exception widget with activity", async (assert) => {
QUnit.test("list activity exception widget with activity", async () => {
const pyEnv = await startServer();
const [activityTypeId_1, activityTypeId_2] = pyEnv["mail.activity.type"].create([{}, {}]);
const [activityId_1, activityId_2] = pyEnv["mail.activity"].create([
@@ -275,13 +275,7 @@ QUnit.test("list activity exception widget with activity", async (assert) => {
res_model: "res.users",
views: [[false, "list"]],
});
assert.containsN($, ".o_data_row", 2);
assert.containsNone(
$(".o_data_row .o_activity_exception_cell")[0],
".o-mail-ActivityException"
);
assert.containsOnce(
$(".o_data_row .o_activity_exception_cell")[1],
".o-mail-ActivityException"
);
await contains(".o_data_row", 2);
await contains(".o_data_row .o_activity_exception_cell:eq(0) .o-mail-ActivityException", 0);
await contains(".o_data_row .o_activity_exception_cell:eq(1) .o-mail-ActivityException");
});
+11 -17
View File
@@ -221,7 +221,7 @@ QUnit.test("chatter: drop attachments", async (assert) => {
await contains(".o-mail-AttachmentCard", 0);
await afterNextRender(() => dropFiles($(".o-mail-Dropzone")[0], files));
assert.containsN($, ".o-mail-AttachmentCard", 2);
await contains(".o-mail-AttachmentCard", 2);
await afterNextRender(() => dragenterFiles($(".o-mail-Chatter")[0]));
files = [
@@ -232,7 +232,7 @@ QUnit.test("chatter: drop attachments", async (assert) => {
}),
];
await afterNextRender(() => dropFiles($(".o-mail-Dropzone")[0], files));
assert.containsN($, ".o-mail-AttachmentCard", 3);
await contains(".o-mail-AttachmentCard", 3);
});
QUnit.test("should display subject when subject isn't infered from the record", async () => {
@@ -307,7 +307,7 @@ QUnit.test("base rendering when chatter has no attachment", async (assert) => {
await contains(".o-mail-Chatter-topbar");
await contains(".o-mail-AttachmentBox", 0);
await contains(".o-mail-Thread");
assert.containsN($, ".o-mail-Message", 30);
await contains(".o-mail-Message", 30);
});
QUnit.test("base rendering when chatter has no record", async (assert) => {
@@ -620,7 +620,7 @@ QUnit.test(
}
);
QUnit.test("basic chatter rendering without followers", async (assert) => {
QUnit.test("basic chatter rendering without followers", async () => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ display_name: "second partner" });
const views = {
@@ -632,6 +632,7 @@ QUnit.test("basic chatter rendering without followers", async (assert) => {
<div class="oe_chatter">
<field name="activity_ids"/>
<field name="message_ids"/>
<!-- no message_follower_ids field -->
</div>
</form>`,
};
@@ -645,15 +646,11 @@ QUnit.test("basic chatter rendering without followers", async (assert) => {
await contains(".o-mail-Chatter-topbar");
await contains("button[aria-label='Attach files']");
await contains("button:contains(Activities)");
assert.containsNone(
$,
".o-mail-Followers",
"there should be no followers menu because the 'message_follower_ids' field is not present in 'oe_chatter'"
);
await contains(".o-mail-Chatter .o-mail-Thread");
await contains(".o-mail-Followers", 0);
});
QUnit.test("basic chatter rendering without messages", async (assert) => {
QUnit.test("basic chatter rendering without messages", async () => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ display_name: "second partner" });
const views = {
@@ -665,6 +662,7 @@ QUnit.test("basic chatter rendering without messages", async (assert) => {
<div class="oe_chatter">
<field name="message_follower_ids"/>
<field name="activity_ids"/>
<!-- no message_ids field -->
</div>
</form>`,
};
@@ -679,14 +677,10 @@ QUnit.test("basic chatter rendering without messages", async (assert) => {
await contains("button[aria-label='Attach files']");
await contains("button:contains(Activities)");
await contains(".o-mail-Followers");
assert.containsNone(
$,
".o-mail-Chatter .o-mail-Thread",
"there should be no thread because the 'message_ids' field is not present in 'oe_chatter'"
);
await contains(".o-mail-Chatter .o-mail-Thread", 0);
});
QUnit.test("chatter updating", async (assert) => {
QUnit.test("chatter updating", async () => {
const pyEnv = await startServer();
const [partnerId_1, partnerId_2] = pyEnv["res.partner"].create([
{ display_name: "first partner" },
@@ -795,5 +789,5 @@ QUnit.test("upload attachment on draft record", async () => {
QUnit.test("Follower count of draft record is set to 0", async (assert) => {
const { openView } = await start();
await openView({ res_model: "res.partner", views: [[false, "form"]] });
assert.containsOnce($, ".o-mail-Followers:contains(0)");
await contains(".o-mail-Followers:contains(0)");
});
@@ -7,7 +7,7 @@ import { getFixture, mount } from "@web/../tests/helpers/utils";
QUnit.module("avatar field");
QUnit.test("basic rendering", async (assert) => {
QUnit.test("basic rendering", async () => {
const { env } = await start();
await mount(Avatar, getFixture(), {
env,
@@ -19,11 +19,10 @@ QUnit.test("basic rendering", async (assert) => {
});
await contains(".o-mail-Avatar");
await contains(".o-mail-Avatar img");
assert.strictEqual($(".o-mail-Avatar img")[0].dataset.src, "/web/image/res.users/2/avatar_128");
await contains(".o-mail-Avatar img[data-src='/web/image/res.users/2/avatar_128']");
await contains(".o-mail-Avatar span");
assert.strictEqual($(".o-mail-Avatar span")[0].innerText, "User display name");
assert.containsNone($, ".o-mail-ChatWindow");
await contains(".o-mail-Avatar span:contains(User display name)");
await contains(".o-mail-ChatWindow", 0);
await click(".o-mail-Avatar img");
await contains(".o-mail-ChatWindow");
});
@@ -2,7 +2,7 @@
import { addFakeModel } from "@bus/../tests/helpers/model_definitions_helpers";
import { start, startServer } from "@mail/../tests/helpers/test_utils";
import { contains, start, startServer } from "@mail/../tests/helpers/test_utils";
import { click } from "@web/../tests/helpers/utils";
@@ -12,11 +12,11 @@ import { click } from "@web/../tests/helpers/utils";
* @param {object} assert the assert object passed by QUnit
* @param {string} emojiComponentSelector unique selector to get the component template root (e.g. "o_field_text_emojis")
*/
export async function testEmojiButtonVisible(assert, selector) {
assert.containsOnce($, ".o_form_editable");
assert.containsOnce($, selector);
assert.containsOnce($, `${selector} button`);
assert.containsOnce($, `${selector} button .fa-smile-o`);
export async function testEmojiButtonVisible(selector) {
await contains(".o_form_editable");
await contains(selector);
await contains(`${selector} button`);
await contains(`${selector} button .fa-smile-o`);
}
/**
@@ -29,7 +29,7 @@ export async function testEmojiButtonVisible(assert, selector) {
export async function testEmojiButton(assert, input, button) {
// emoji picker opens
await click(button);
assert.containsOnce($, ".o-EmojiPicker");
await contains(".o-EmojiPicker");
// clicking an emoji adds it to the input field
const emoji_1 = $(".o-EmojiPicker-content .o-Emoji")[0];
const emojiChar_1 = emoji_1.textContent;
@@ -79,9 +79,9 @@ async function openTestView(model) {
QUnit.module("Field char emojis");
QUnit.test("emojis button is shown", async (assert) => {
QUnit.test("emojis button is shown", async () => {
await openTestView("fields.char.emojis.user");
await testEmojiButtonVisible(assert, ".o_field_char_emojis");
await testEmojiButtonVisible(".o_field_char_emojis");
});
QUnit.test("emojis button works", async (assert) => {
@@ -93,9 +93,9 @@ QUnit.test("emojis button works", async (assert) => {
QUnit.module("Field text emojis");
QUnit.test("emojis button is shown", async (assert) => {
QUnit.test("emojis button is shown", async () => {
await openTestView("fields.text.emojis.user");
await testEmojiButtonVisible(assert, ".o_field_text_emojis");
await testEmojiButtonVisible(".o_field_text_emojis");
});
QUnit.test("emojis button works", async (assert) => {
@@ -82,7 +82,7 @@ QUnit.test("many2many_avatar_user in kanban view", async (assert) => {
res_model: "m2x.avatar.user",
views: [[false, "kanban"]],
});
assert.containsOnce($, ".o_kanban_record .o_field_many2many_avatar_user .o_m2m_avatar_empty");
await contains(".o_kanban_record .o_field_many2many_avatar_user .o_m2m_avatar_empty");
assert.strictEqual(
$(
".o_kanban_record .o_field_many2many_avatar_user .o_m2m_avatar_empty"
@@ -393,7 +393,7 @@ QUnit.test("avatar card preview", async (assert) => {
// Open card
await triggerEvent(document, ".o_m2o_avatar > img", "mouseover");
assert.verifySteps(["setTimeout of 350ms", "setTimeout of 250ms", "user read"]);
assert.containsOnce(document.body, ".o_avatar_card");
await contains(".o_avatar_card");
assert.deepEqual(getNodesTextContent(document.querySelectorAll(".o_card_user_infos > *")), [
"Mario",
" Mario@odoo.test",
@@ -402,7 +402,7 @@ QUnit.test("avatar card preview", async (assert) => {
// Close card
await triggerEvent(document, ".o_control_panel", "mouseover");
assert.verifySteps(["setTimeout of 400ms"]);
assert.containsNone(document.body, ".o_avatar_card");
await contains(".o_avatar_card", 0);
});
QUnit.test(
@@ -447,7 +447,7 @@ QUnit.test("many2one_avatar_user widget in list view", async (assert) => {
views: [[false, "list"]],
});
await click(document.body, ".o_data_cell .o_m2o_avatar > img");
assert.containsOnce($, ".o-mail-ChatWindow");
await contains(".o-mail-ChatWindow");
assert.strictEqual($(".o-mail-ChatWindow-name").text(), "Partner 1");
});
@@ -469,6 +469,6 @@ QUnit.test("many2many_avatar_user widget in form view", async (assert) => {
views: [[false, "form"]],
});
await click(document.body, ".o_field_many2many_avatar_user .o_avatar img");
assert.containsOnce($, ".o-mail-ChatWindow");
await contains(".o-mail-ChatWindow");
assert.strictEqual($(".o-mail-ChatWindow-name").text(), "Partner 1");
});
@@ -48,20 +48,13 @@ QUnit.test("fieldmany2many tags email (edition)", async (assert) => {
);
assert.verifySteps([]);
assert.containsOnce(
$,
'.o_field_many2many_tags_email[name="partner_ids"] .badge.o_tag_color_0'
);
await contains('.o_field_many2many_tags_email[name="partner_ids"] .badge.o_tag_color_0');
// add an other existing tag
await selectDropdownItem(document.body, "partner_ids", "silver");
assert.containsOnce(
$,
".modal-content .o_form_view",
"there should be one modal opened to edit the empty email"
);
await contains(".modal-content .o_form_view");
await contains(".modal-content .o_form_view .o_input#name_0", 1, { value: "silver" });
assert.containsOnce($, ".modal-content .o_form_view .o_input#email_0");
await contains(".modal-content .o_form_view .o_input#email_0");
// set the email and save the modal (will rerender the form view)
await insertText(".modal-content .o_form_view .o_input#email_0", "coucou@petite.perruche");
@@ -79,7 +72,7 @@ QUnit.test("fieldmany2many tags email (edition)", async (assert) => {
assert.verifySteps([`[${partnerId_2}]`, `[${partnerId_2}]`, `[${partnerId_1},${partnerId_2}]`]);
});
QUnit.test("many2many_tags_email widget can load more than 40 records", async (assert) => {
QUnit.test("many2many_tags_email widget can load more than 40 records", async () => {
const pyEnv = await startServer();
const partnerIds = [];
for (let i = 100; i < 200; i++) {
@@ -97,10 +90,10 @@ QUnit.test("many2many_tags_email widget can load more than 40 records", async (a
views: [[false, "form"]],
});
assert.containsN($, '.o_field_widget[name="partner_ids"] .badge', 100);
assert.containsOnce($, ".o_form_editable");
await contains('.o_field_widget[name="partner_ids"] .badge', 100);
await contains(".o_form_editable");
// add a record to the relation
await selectDropdownItem(document.body, "partner_ids", "Public user");
assert.containsN($, '.o_field_widget[name="partner_ids"] .badge', 101);
await contains('.o_field_widget[name="partner_ids"] .badge', 101);
});
@@ -279,7 +279,7 @@ QUnit.test("Load 100 recipients at once", async (assert) => {
QUnit.test(
'Show "Add follower" and subtypes edition/removal buttons on all followers if user has write access',
async (assert) => {
async () => {
const pyEnv = await startServer();
const [partnerId_1, partnerId_2] = pyEnv["res.partner"].create([
{ name: "Partner1" },
@@ -317,11 +317,10 @@ QUnit.test(
await click(".o-mail-Followers-button");
await contains("a:contains(Add Followers)");
const $followers = $(".o-mail-Follower");
assert.containsOnce($followers[0], "button[title='Edit subscription']");
assert.containsOnce($followers[0], "button[title='Remove this follower']");
assert.containsOnce($followers[1], "button[title='Edit subscription']");
assert.containsOnce($followers[1], "button[title='Remove this follower']");
await contains(".o-mail-Follower:eq(0) button[title='Edit subscription']");
await contains(".o-mail-Follower:eq(0) button[title='Remove this follower']");
await contains(".o-mail-Follower:eq(1) button[title='Edit subscription']");
await contains(".o-mail-Follower:eq(1) button[title='Remove this follower']");
}
);