mirror of
https://github.com/bringout/oca-ocb-core.git
synced 2026-04-20 17:31:59 +02:00
19.0 vanilla
This commit is contained in:
parent
d1963a3c3a
commit
2d3ee4855a
7430 changed files with 2687981 additions and 2965473 deletions
|
|
@ -0,0 +1,35 @@
|
|||
import {
|
||||
click,
|
||||
contains,
|
||||
defineMailModels,
|
||||
openFormView,
|
||||
start,
|
||||
startServer,
|
||||
} from "@mail/../tests/mail_test_helpers";
|
||||
import { describe, expect, test } from "@odoo/hoot";
|
||||
import { asyncStep, onRpc, serverState, waitForSteps } from "@web/../tests/web_test_helpers";
|
||||
|
||||
defineMailModels();
|
||||
describe.current.tags("desktop");
|
||||
|
||||
test("Manage messages", async () => {
|
||||
serverState.debug = "1";
|
||||
const pyEnv = await startServer();
|
||||
onRpc("mail.message", "web_search_read", (params) => {
|
||||
expect(params.kwargs.context.default_res_id).toBe(partnerId);
|
||||
expect(params.kwargs.context.default_res_model).toBe("res.partner");
|
||||
expect(params.kwargs.domain).toEqual([
|
||||
"&",
|
||||
["res_id", "=", partnerId],
|
||||
["model", "=", "res.partner"],
|
||||
]);
|
||||
asyncStep("message_read");
|
||||
});
|
||||
await start();
|
||||
const partnerId = pyEnv["res.partner"].create({ name: "Bob" });
|
||||
await openFormView("res.partner", partnerId);
|
||||
await click(".o_debug_manager .dropdown-toggle");
|
||||
await click(".dropdown-item", { text: "Messages" });
|
||||
await waitForSteps(["message_read"]);
|
||||
await contains(".o_breadcrumb .active > span", { text: "Messages" });
|
||||
});
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import { click, contains, defineMailModels, start } from "@mail/../tests/mail_test_helpers";
|
||||
import { describe, test } from "@odoo/hoot";
|
||||
import { mountWithCleanup, serverState } from "@web/../tests/web_test_helpers";
|
||||
|
||||
import { Avatar } from "@mail/views/web/fields/avatar/avatar";
|
||||
|
||||
describe.current.tags("desktop");
|
||||
defineMailModels();
|
||||
|
||||
test("basic rendering", async () => {
|
||||
await start();
|
||||
await mountWithCleanup(Avatar, {
|
||||
props: {
|
||||
resId: serverState.userId,
|
||||
resModel: "res.users",
|
||||
displayName: "User display name",
|
||||
},
|
||||
});
|
||||
await contains(".o-mail-Avatar");
|
||||
await contains(".o-mail-Avatar img");
|
||||
await contains(".o-mail-Avatar img[data-src='/web/image/res.users/7/avatar_128']");
|
||||
await contains(".o-mail-Avatar span");
|
||||
await contains(".o-mail-Avatar span", { text: "User display name" });
|
||||
await contains(".o_avatar_card", { count: 0 });
|
||||
await click(".o-mail-Avatar img");
|
||||
await contains(".o_avatar_card");
|
||||
});
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
import {
|
||||
click,
|
||||
contains,
|
||||
defineMailModels,
|
||||
insertText,
|
||||
openFormView,
|
||||
start,
|
||||
} from "@mail/../tests/mail_test_helpers";
|
||||
import { describe, test } from "@odoo/hoot";
|
||||
import { serverState } from "@web/../tests/web_test_helpers";
|
||||
|
||||
defineMailModels();
|
||||
describe.current.tags("desktop");
|
||||
|
||||
test("insert emoji at end of word", async () => {
|
||||
await start();
|
||||
await openFormView("res.partner", serverState.partnerId, {
|
||||
arch: `<form><field name="name" widget="text_emojis"/></form>`,
|
||||
});
|
||||
await insertText("textarea#name_0", "Hello", { replace: true });
|
||||
await click(".o_field_text_emojis button");
|
||||
await click('.o-Emoji[data-codepoints="😀"]');
|
||||
await contains("textarea#name_0", { value: "Hello😀" });
|
||||
});
|
||||
|
||||
test("insert emoji as new word", async () => {
|
||||
await start();
|
||||
await openFormView("res.partner", serverState.partnerId, {
|
||||
arch: `<form><field name="name" widget="text_emojis"/></form>`,
|
||||
});
|
||||
await insertText("textarea#name_0", "Hello ", { replace: true });
|
||||
await click(".o_field_text_emojis button");
|
||||
await click('.o-Emoji[data-codepoints="😀"]');
|
||||
await contains("textarea#name_0", { value: "Hello 😀" });
|
||||
});
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
import {
|
||||
click,
|
||||
contains,
|
||||
defineMailModels,
|
||||
insertText,
|
||||
openFormView,
|
||||
start,
|
||||
} from "@mail/../tests/mail_test_helpers";
|
||||
import { describe, test } from "@odoo/hoot";
|
||||
import { serverState } from "@web/../tests/web_test_helpers";
|
||||
|
||||
defineMailModels();
|
||||
describe.current.tags("desktop");
|
||||
|
||||
test("insert emoji at end of word", async () => {
|
||||
await start();
|
||||
await openFormView("res.partner", serverState.partnerId, {
|
||||
arch: `<form><field name="name" widget="char_emojis"/></form>`,
|
||||
});
|
||||
await insertText("input#name_0", "Hello", { replace: true });
|
||||
await click(".o_field_char_emojis button");
|
||||
await click('.o-Emoji[data-codepoints="😀"]');
|
||||
await contains("input#name_0", { value: "Hello😀" });
|
||||
});
|
||||
|
||||
test("insert emoji as new word", async () => {
|
||||
await start();
|
||||
await openFormView("res.partner", serverState.partnerId, {
|
||||
arch: `<form><field name="name" widget="char_emojis"/></form>`,
|
||||
});
|
||||
await insertText("input#name_0", "Hello ", { replace: true });
|
||||
await click(".o_field_char_emojis button");
|
||||
await click('.o-Emoji[data-codepoints="😀"]');
|
||||
await contains("input#name_0", { value: "Hello 😀" });
|
||||
});
|
||||
|
|
@ -0,0 +1,431 @@
|
|||
import {
|
||||
click,
|
||||
contains,
|
||||
defineMailModels,
|
||||
openFormView,
|
||||
openKanbanView,
|
||||
openListView,
|
||||
start,
|
||||
startServer,
|
||||
triggerHotkey,
|
||||
} from "@mail/../tests/mail_test_helpers";
|
||||
import { describe, expect, test } from "@odoo/hoot";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { getOrigin } from "@web/core/utils/urls";
|
||||
|
||||
defineMailModels();
|
||||
describe.current.tags("desktop");
|
||||
|
||||
test("many2many_avatar_user in kanban view", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const userIds = pyEnv["res.users"].create([
|
||||
{ partner_id: pyEnv["res.partner"].create({ name: "Mario" }) },
|
||||
{ partner_id: pyEnv["res.partner"].create({ name: "Yoshi" }) },
|
||||
{ partner_id: pyEnv["res.partner"].create({ name: "Luigi" }) },
|
||||
{ partner_id: pyEnv["res.partner"].create({ name: "Tapu" }) },
|
||||
]);
|
||||
pyEnv["m2x.avatar.user"].create({ user_ids: userIds });
|
||||
await start();
|
||||
await openKanbanView("m2x.avatar.user", {
|
||||
arch: `
|
||||
<kanban>
|
||||
<templates>
|
||||
<t t-name="card">
|
||||
<field name="user_id"/>
|
||||
<field name="user_ids" widget="many2many_avatar_user"/>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
`,
|
||||
});
|
||||
expect(".o_kanban_record .o_field_many2many_avatar_user .o_m2m_avatar_empty").toHaveText("+2");
|
||||
await click(".o_kanban_record .o_field_many2many_avatar_user .o_quick_assign");
|
||||
await contains(".o_popover > .o_field_tags > .o_tag", { count: 4 });
|
||||
await contains(".o_popover > .o_field_tags > :nth-child(1 of .o_tag)", { text: "Tapu" });
|
||||
await contains(".o_popover > .o_field_tags > :nth-child(2 of .o_tag)", { text: "Luigi" });
|
||||
await contains(".o_popover > .o_field_tags > :nth-child(3 of .o_tag)", { text: "Yoshi" });
|
||||
await contains(".o_popover > .o_field_tags > :nth-child(4 of .o_tag)", { text: "Mario" });
|
||||
});
|
||||
|
||||
test('many2one_avatar_user widget edited by the smart action "Assign to..."', async () => {
|
||||
const pyEnv = await startServer();
|
||||
const [userId_1] = pyEnv["res.users"].create([
|
||||
{ partner_id: pyEnv["res.partner"].create({ name: "Mario" }) },
|
||||
{ partner_id: pyEnv["res.partner"].create({ name: "Luigi" }) },
|
||||
{ partner_id: pyEnv["res.partner"].create({ name: "Yoshi" }) },
|
||||
]);
|
||||
const avatarUserId_1 = pyEnv["m2x.avatar.user"].create({ user_id: userId_1 });
|
||||
await start();
|
||||
await openFormView("m2x.avatar.user", avatarUserId_1, {
|
||||
arch: "<form><field name='user_id' widget='many2one_avatar_user'/></form>",
|
||||
});
|
||||
await contains(".o_field_many2one_avatar_user .o_external_button");
|
||||
await contains(".o_field_many2one_avatar_user input", { value: "Mario" });
|
||||
triggerHotkey("control+k");
|
||||
await click(".o_command", { text: "Assign to ...ALT + I" });
|
||||
await contains(".o_command", { count: 6 });
|
||||
await contains(":nth-child(1 of .o_command)", { text: "Mitchell Admin" });
|
||||
await contains(":nth-child(2 of .o_command)", { text: "Public user" });
|
||||
await contains(":nth-child(3 of .o_command)", { text: "OdooBot" });
|
||||
await contains(":nth-child(4 of .o_command)", { text: "Mario" });
|
||||
await contains(":nth-child(5 of .o_command)", { text: "Luigi" });
|
||||
await contains(":nth-child(6 of .o_command)", { text: "Yoshi" });
|
||||
await click(".o_command", { text: "Luigi" });
|
||||
await contains(".o_field_many2one_avatar_user input", { value: "Luigi" });
|
||||
});
|
||||
|
||||
test('many2many_avatar_user widget edited by the smart action "Assign to..."', async () => {
|
||||
const pyEnv = await startServer();
|
||||
const [userId_1, userId_2] = pyEnv["res.users"].create([
|
||||
{ partner_id: pyEnv["res.partner"].create({ name: "Mario" }) },
|
||||
{ partner_id: pyEnv["res.partner"].create({ name: "Yoshi" }) },
|
||||
{ partner_id: pyEnv["res.partner"].create({ name: "Luigi" }) },
|
||||
]);
|
||||
const m2xAvatarUserId1 = pyEnv["m2x.avatar.user"].create({ user_ids: [userId_1, userId_2] });
|
||||
await start();
|
||||
await openFormView("m2x.avatar.user", m2xAvatarUserId1, {
|
||||
arch: "<form><field name='user_ids' widget='many2many_avatar_user'/></form>",
|
||||
});
|
||||
await contains(".o_tag_badge_text", { count: 2 });
|
||||
await contains(":nth-child(1 of .o_tag) .o_tag_badge_text", { text: "Mario" });
|
||||
await contains(":nth-child(2 of .o_tag) .o_tag_badge_text", { text: "Yoshi" });
|
||||
triggerHotkey("control+k");
|
||||
await contains(".o_command", { text: "Assign to ...ALT + I" });
|
||||
// Assign Luigi
|
||||
triggerHotkey("alt+i");
|
||||
await contains(".o_command", { count: 4 });
|
||||
await contains(":nth-child(1 of .o_command)", { text: "Mitchell Admin" });
|
||||
await contains(":nth-child(2 of .o_command)", { text: "Public user" });
|
||||
await contains(":nth-child(3 of .o_command)", { text: "OdooBot" });
|
||||
await contains(":nth-child(4 of .o_command)", { text: "Luigi" });
|
||||
await click(".o_command", { text: "Luigi" });
|
||||
await contains(".o_tag_badge_text", { count: 3 });
|
||||
await contains(":nth-child(1 of .o_tag) .o_tag_badge_text", { text: "Mario" });
|
||||
await contains(":nth-child(2 of .o_tag) .o_tag_badge_text", { text: "Yoshi" });
|
||||
await contains(":nth-child(3 of .o_tag) .o_tag_badge_text", { text: "Luigi" });
|
||||
});
|
||||
|
||||
test('many2one_avatar_user widget edited by the smart action "Assign to me" in form view', async () => {
|
||||
const pyEnv = await startServer();
|
||||
const userId = pyEnv["res.users"].create({
|
||||
partner_id: pyEnv["res.partner"].create({ name: "Mario" }),
|
||||
});
|
||||
const avatarUserId_1 = pyEnv["m2x.avatar.user"].create({ user_id: userId });
|
||||
await start();
|
||||
await openFormView("m2x.avatar.user", avatarUserId_1, {
|
||||
arch: "<form><field name='user_id' widget='many2one_avatar_user'/></form>",
|
||||
});
|
||||
await contains(".o_field_many2one_avatar_user input", { value: "Mario" });
|
||||
await triggerHotkey("control+k");
|
||||
await contains(".o_command", { text: "Assign to meALT + SHIFT + I" });
|
||||
await triggerHotkey("alt+shift+i");
|
||||
await contains(".o_field_many2one_avatar_user input", { value: "Mitchell Admin" });
|
||||
// Unassign me
|
||||
await triggerHotkey("control+k");
|
||||
await click(".o_command", { text: "Unassign from meALT + SHIFT + I" });
|
||||
await contains(".o_field_many2one_avatar_user input", { value: "" });
|
||||
});
|
||||
|
||||
test('many2one_avatar_user widget edited by the smart action "Assign to me"', async () => {
|
||||
const pyEnv = await startServer();
|
||||
const userId_1 = pyEnv["res.users"].create({
|
||||
partner_id: pyEnv["res.partner"].create({ name: "Mario" }),
|
||||
});
|
||||
const avatarUserId_1 = pyEnv["m2x.avatar.user"].create({ user_id: userId_1 });
|
||||
await start();
|
||||
await openFormView("m2x.avatar.user", avatarUserId_1, {
|
||||
arch: "<form><field name='user_id' widget='many2one_avatar_user'/></form>",
|
||||
});
|
||||
await contains(".o_field_many2one_avatar_user input", { value: "Mario" });
|
||||
triggerHotkey("control+k");
|
||||
await contains(".o_command", { text: "Assign to meALT + SHIFT + I" });
|
||||
// Assign to me
|
||||
triggerHotkey("alt+shift+i");
|
||||
await contains(".o_field_many2one_avatar_user input", { value: "Mitchell Admin" });
|
||||
// Unassign from me
|
||||
triggerHotkey("control+k");
|
||||
await click(".o_command", { text: "Unassign from meALT + SHIFT + I" });
|
||||
await contains(".o_field_many2one_avatar_user input", { value: "" });
|
||||
});
|
||||
|
||||
test('many2one_avatar_user widget edited by the smart action "Assign to me" in list view', async () => {
|
||||
const pyEnv = await startServer();
|
||||
const [userId_1, userId_2] = pyEnv["res.users"].create([
|
||||
{ partner_id: pyEnv["res.partner"].create({ name: "Mario" }) },
|
||||
{ partner_id: pyEnv["res.partner"].create({ name: "Luigi" }) },
|
||||
]);
|
||||
|
||||
pyEnv["m2x.avatar.user"].create([{ user_id: userId_2 }, { user_id: userId_1 }]);
|
||||
await start();
|
||||
await openListView("m2x.avatar.user", {
|
||||
arch: "<list multi_edit='1'><field name='user_id' widget='many2one_avatar_user'/></list>",
|
||||
});
|
||||
await contains(":nth-child(1 of .o_data_row) .o_field_many2one_avatar_user .o_many2one", {
|
||||
text: "Luigi",
|
||||
});
|
||||
await contains(":nth-child(2 of .o_data_row) .o_field_many2one_avatar_user .o_many2one", {
|
||||
text: "Mario",
|
||||
});
|
||||
// Select all
|
||||
await click(".o_list_table > thead .o_list_controller input");
|
||||
await triggerHotkey("control+k");
|
||||
await contains(".o_command", { text: "Assign to meALT + SHIFT + I" });
|
||||
// Assign me
|
||||
await triggerHotkey("alt+shift+i");
|
||||
// Multi-edit confirmation dialog
|
||||
await contains(".o_dialog");
|
||||
// Cancel
|
||||
await click(".o_dialog .modal-footer button:nth-child(2)");
|
||||
await contains(":nth-child(1 of .o_data_row) .o_field_many2one_avatar_user .o_many2one", {
|
||||
text: "Luigi",
|
||||
});
|
||||
await contains(":nth-child(2 of .o_data_row) .o_field_many2one_avatar_user .o_many2one", {
|
||||
text: "Mario",
|
||||
});
|
||||
// Assign me
|
||||
await triggerHotkey("alt+shift+i");
|
||||
// Multi-edit confirmation dialog
|
||||
await contains(".o_dialog");
|
||||
// Confirm
|
||||
await click(".o_dialog .modal-footer button:nth-child(1)");
|
||||
await contains(".o_dialog", { count: 0 });
|
||||
await contains(":nth-child(1 of .o_data_row) .o_field_many2one_avatar_user .o_many2one", {
|
||||
text: "Mitchell Admin",
|
||||
});
|
||||
await contains(":nth-child(2 of .o_data_row) .o_field_many2one_avatar_user .o_many2one", {
|
||||
text: "Mitchell Admin",
|
||||
});
|
||||
// Unassign me
|
||||
await triggerHotkey("alt+shift+u");
|
||||
// Multi-edit confirmation dialog
|
||||
await contains(".o_dialog");
|
||||
// Confirm
|
||||
await click(".o_dialog .modal-footer button:nth-child(1)");
|
||||
await contains(".o_field_many2one_avatar_user .o_form_uri", { count: 0 });
|
||||
});
|
||||
|
||||
test('many2many_avatar_user widget edited by the smart action "Assign to me"', async () => {
|
||||
const pyEnv = await startServer();
|
||||
const [userId_1, userId_2] = pyEnv["res.users"].create([
|
||||
{ partner_id: pyEnv["res.partner"].create({ name: "Mario" }) },
|
||||
{ partner_id: pyEnv["res.partner"].create({ name: "Yoshi" }) },
|
||||
]);
|
||||
const m2xAvatarUserId1 = pyEnv["m2x.avatar.user"].create({
|
||||
user_ids: [userId_1, userId_2],
|
||||
});
|
||||
await start();
|
||||
await openFormView("m2x.avatar.user", m2xAvatarUserId1, {
|
||||
arch: "<form><field name='user_ids' widget='many2many_avatar_user'/></form>",
|
||||
});
|
||||
await contains(".o_tag_badge_text", { count: 2 });
|
||||
await contains(":nth-child(1 of .o_tag) .o_tag_badge_text", { text: "Mario" });
|
||||
await contains(":nth-child(2 of .o_tag) .o_tag_badge_text", { text: "Yoshi" });
|
||||
triggerHotkey("control+k");
|
||||
await contains(".o_command", { text: "Assign to meALT + SHIFT + I" });
|
||||
// Assign me
|
||||
triggerHotkey("alt+shift+i");
|
||||
await contains(".o_tag_badge_text", { count: 3 });
|
||||
await contains(":nth-child(1 of .o_tag) .o_tag_badge_text", { text: "Mario" });
|
||||
await contains(":nth-child(2 of .o_tag) .o_tag_badge_text", { text: "Yoshi" });
|
||||
await contains(":nth-child(3 of .o_tag) .o_tag_badge_text", { text: "Mitchell Admin" });
|
||||
// Unassign me
|
||||
triggerHotkey("control+k");
|
||||
await contains(".o_command", { text: "Unassign from meALT + SHIFT + I" });
|
||||
triggerHotkey("alt+shift+i");
|
||||
await contains(".o_tag_badge_text", { count: 2 });
|
||||
await contains(":nth-child(1 of .o_tag) .o_tag_badge_text", { text: "Mario" });
|
||||
await contains(":nth-child(2 of .o_tag) .o_tag_badge_text", { text: "Yoshi" });
|
||||
});
|
||||
|
||||
test("avatar_user widget displays the appropriate user image in list view", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const userId = pyEnv["res.users"].create({
|
||||
partner_id: pyEnv["res.partner"].create({ name: "Mario" }),
|
||||
});
|
||||
const avatarUserId = pyEnv["m2x.avatar.user"].create({ user_id: userId });
|
||||
await start();
|
||||
await openListView("m2x.avatar.user", {
|
||||
res_id: avatarUserId,
|
||||
arch: "<list><field name='user_id' widget='many2one_avatar_user'/></list>",
|
||||
});
|
||||
|
||||
await contains(`.o_m2o_avatar > img[data-src="/web/image/res.users/${userId}/avatar_128"]`);
|
||||
});
|
||||
|
||||
test("avatar_user widget displays the appropriate user image in kanban view", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const userId = pyEnv["res.users"].create({ name: "Mario" });
|
||||
const avatarUserId = pyEnv["m2x.avatar.user"].create({ user_id: userId });
|
||||
await start();
|
||||
await openKanbanView("m2x.avatar.user", {
|
||||
res_id: avatarUserId,
|
||||
arch: `
|
||||
<kanban>
|
||||
<templates>
|
||||
<t t-name="card">
|
||||
<field name="user_id" widget="many2one_avatar_user"/>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
`,
|
||||
});
|
||||
await start();
|
||||
await contains(`.o_m2o_avatar > img[data-src="/web/image/res.users/${userId}/avatar_128"]`);
|
||||
});
|
||||
|
||||
test("avatar card preview", async () => {
|
||||
registry.category("services").add(
|
||||
"im_status",
|
||||
{
|
||||
start() {
|
||||
return {
|
||||
registerToImStatus() {},
|
||||
unregisterFromImStatus() {},
|
||||
updateBusPresence() {},
|
||||
};
|
||||
},
|
||||
},
|
||||
{ force: true }
|
||||
);
|
||||
const pyEnv = await startServer();
|
||||
const userId = pyEnv["res.users"].create({
|
||||
partner_id: pyEnv["res.partner"].create({
|
||||
email: "Mario@odoo.test",
|
||||
name: "Mario",
|
||||
phone: "+78786987",
|
||||
}),
|
||||
im_status: "online",
|
||||
});
|
||||
const avatarUserId = pyEnv["m2x.avatar.user"].create({ user_id: userId });
|
||||
await start();
|
||||
await openKanbanView("m2x.avatar.user", {
|
||||
res_id: avatarUserId,
|
||||
arch: `
|
||||
<kanban>
|
||||
<templates>
|
||||
<t t-name="card">
|
||||
<field name="user_id" widget="many2one_avatar_user"/>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
`,
|
||||
});
|
||||
// Open card
|
||||
await click(".o_m2o_avatar > img");
|
||||
await contains(".o_avatar_card");
|
||||
await contains(".o_card_user_infos > span", { text: "Mario" });
|
||||
await contains(".o_card_user_infos > a", { text: "Mario@odoo.test" });
|
||||
await contains(".o_card_user_infos > a", { text: "+78786987" });
|
||||
// Close card
|
||||
await click(".o_action_manager");
|
||||
await contains(".o_avatar_card", { count: 0 });
|
||||
});
|
||||
|
||||
test("avatar card preview (partner_id field)", async () => {
|
||||
registry.category("services").add(
|
||||
"im_status",
|
||||
{
|
||||
start() {
|
||||
return {
|
||||
registerToImStatus() {},
|
||||
unregisterFromImStatus() {},
|
||||
updateBusPresence() {},
|
||||
};
|
||||
},
|
||||
},
|
||||
{ force: true }
|
||||
);
|
||||
const pyEnv = await startServer();
|
||||
const userId = pyEnv["res.users"].create({
|
||||
im_status: "online",
|
||||
});
|
||||
const partnerId = pyEnv["res.partner"].create({
|
||||
email: "Mario@odoo.test",
|
||||
name: "Mario",
|
||||
phone: "+78786987",
|
||||
user_ids: [userId],
|
||||
});
|
||||
const avatarUserId = pyEnv["m2x.avatar.user"].create({ partner_id: partnerId });
|
||||
await start();
|
||||
await openKanbanView("m2x.avatar.user", {
|
||||
res_id: avatarUserId,
|
||||
arch: `
|
||||
<kanban>
|
||||
<templates>
|
||||
<t t-name="card">
|
||||
<field name="partner_id" widget="many2one_avatar_user"/>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
`,
|
||||
});
|
||||
// Open card
|
||||
await click(".o_m2o_avatar > img");
|
||||
await contains(".o_avatar_card");
|
||||
await contains(".o_card_user_infos > span", { text: "Mario" });
|
||||
await contains(".o_card_user_infos > a", { text: "Mario@odoo.test" });
|
||||
await contains(".o_card_user_infos > a", { text: "+78786987" });
|
||||
// Close card
|
||||
await click(".o_action_manager");
|
||||
await contains(".o_avatar_card", { count: 0 });
|
||||
});
|
||||
|
||||
test("avatar_user widget displays the appropriate user image in form view", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const userId = pyEnv["res.users"].create({
|
||||
partner_id: pyEnv["res.partner"].create({ name: "Mario" }),
|
||||
});
|
||||
const avatarUserId = pyEnv["m2x.avatar.user"].create({ user_ids: [userId] });
|
||||
await start();
|
||||
await openFormView("m2x.avatar.user", avatarUserId, {
|
||||
arch: "<form><field name='user_ids' widget='many2many_avatar_user'/></form>",
|
||||
});
|
||||
await contains(
|
||||
`.o_field_many2many_avatar_user.o_field_widget .o_avatar img[data-src="${getOrigin()}/web/image/res.users/${userId}/avatar_128"]`
|
||||
);
|
||||
});
|
||||
|
||||
test("many2one_avatar_user widget in list view", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const userId = pyEnv["res.users"].create({
|
||||
partner_id: pyEnv["res.partner"].create({
|
||||
email: "Mario@partner.com",
|
||||
name: "Mario",
|
||||
phone: "+45687468",
|
||||
}),
|
||||
});
|
||||
pyEnv["m2x.avatar.user"].create({ user_id: userId });
|
||||
await start();
|
||||
await openListView("m2x.avatar.user", {
|
||||
arch: "<list><field name='user_id' widget='many2one_avatar_user'/></list>",
|
||||
});
|
||||
await contains(".o_data_cell .o_many2one span");
|
||||
await contains(".o_data_cell .o_many2one a", { count: 0 });
|
||||
await click(".o_data_cell .o_m2o_avatar > img");
|
||||
await contains(".o_avatar_card");
|
||||
await contains(".o_card_user_infos > span", { text: "Mario" });
|
||||
await contains(".o_card_user_infos > a", { text: "Mario@partner.com" });
|
||||
await contains(".o_card_user_infos > a", { text: "+45687468" });
|
||||
});
|
||||
|
||||
test("many2many_avatar_user widget in form view", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const userId = pyEnv["res.users"].create({
|
||||
name: "Mario",
|
||||
partner_id: pyEnv["res.partner"].create({
|
||||
email: "Mario@partner.com",
|
||||
name: "Mario",
|
||||
phone: "+45687468",
|
||||
}),
|
||||
});
|
||||
const avatarUserId = pyEnv["m2x.avatar.user"].create({ user_ids: [userId] });
|
||||
await start();
|
||||
await openFormView("m2x.avatar.user", avatarUserId, {
|
||||
arch: "<form><field name='user_ids' widget='many2many_avatar_user'/></form>",
|
||||
});
|
||||
await click(".o_field_many2many_avatar_user .o_avatar img");
|
||||
await contains(".o_avatar_card");
|
||||
await contains(".o_card_user_infos > span", { text: "Mario" });
|
||||
await contains(".o_card_user_infos > a", { text: "Mario@partner.com" });
|
||||
await contains(".o_card_user_infos > a", { text: "+45687468" });
|
||||
});
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
import { beforeEach, describe, expect, test } from "@odoo/hoot";
|
||||
import {
|
||||
click,
|
||||
contains,
|
||||
defineMailModels,
|
||||
insertText,
|
||||
openFormView,
|
||||
start,
|
||||
startServer,
|
||||
} from "@mail/../tests/mail_test_helpers";
|
||||
import {
|
||||
asyncStep,
|
||||
clickFieldDropdown,
|
||||
clickFieldDropdownItem,
|
||||
onRpc,
|
||||
waitForSteps,
|
||||
} from "@web/../tests/web_test_helpers";
|
||||
import { queryAll } from "@odoo/hoot-dom";
|
||||
import { ResPartner } from "../../mock_server/mock_models/res_partner";
|
||||
|
||||
defineMailModels();
|
||||
describe.current.tags("desktop");
|
||||
|
||||
beforeEach(() => {
|
||||
ResPartner._views.form = /* xml */ `
|
||||
<form>
|
||||
<field name="name"/>
|
||||
<field name="email"/>
|
||||
</form>
|
||||
`;
|
||||
});
|
||||
|
||||
test("fieldmany2many tags email (edition)", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const [partnerId_1, partnerId_2] = pyEnv["res.partner"].create([
|
||||
{ name: "gold", email: "coucou@petite.perruche" },
|
||||
{ name: "", email: "", type: "invoice" },
|
||||
]);
|
||||
pyEnv["res.partner"].write([partnerId_2], { parent_id: partnerId_1 });
|
||||
const messageId = pyEnv["mail.message"].create({ partner_ids: [partnerId_1] });
|
||||
onRpc("res.partner", "web_read", (params) => {
|
||||
expect(params.kwargs.specification).toInclude("email");
|
||||
asyncStep(`web_read ${JSON.stringify(params.args[0])}`);
|
||||
});
|
||||
onRpc("res.partner", "web_save", (params) => {
|
||||
expect(params.kwargs.specification).toInclude("email");
|
||||
asyncStep(`web_save ${JSON.stringify(params.args[0])}`);
|
||||
});
|
||||
onRpc("res.partner", "get_formview_id", () => false);
|
||||
await start();
|
||||
await openFormView("mail.message", messageId, {
|
||||
arch: `
|
||||
<form>
|
||||
<field name="body"/>
|
||||
<field name="partner_ids" widget="many2many_tags_email"/>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
await waitForSteps([]);
|
||||
await contains('.o_field_many2many_tags_email[name="partner_ids"] .badge.o_tag_color_0');
|
||||
await clickFieldDropdown("partner_ids");
|
||||
await clickFieldDropdownItem("partner_ids", "gold, Invoice");
|
||||
const tags = queryAll('.o_field_many2many_tags_email[name="partner_ids"] .badge.o_tag_color_0');
|
||||
expect(tags[1].innerText).toBe("gold, Invoice");
|
||||
await contains(".o-mail-RecipientsInputTagsListPopover");
|
||||
// set the email
|
||||
await insertText(".o-mail-RecipientsInputTagsListPopover input", "coucou@petite.perruche");
|
||||
await click(".o-mail-RecipientsInputTagsListPopover .btn-primary");
|
||||
await contains('.o_field_many2many_tags_email[name="partner_ids"] .badge.o_tag_color_0', {
|
||||
count: 2,
|
||||
});
|
||||
expect(tags[0].innerText).toBe("gold");
|
||||
expect(tags[0].querySelector(".o_badge_text")).toHaveAttribute(
|
||||
"title",
|
||||
"coucou@petite.perruche"
|
||||
);
|
||||
// should have read Partner_2 2 times: when opening the dropdown and when saving the new email.
|
||||
await waitForSteps([`web_read [${partnerId_2}]`, `web_save [${partnerId_2}]`]);
|
||||
});
|
||||
|
||||
test("fieldmany2many tags email popup close without filling", async () => {
|
||||
const pyEnv = await startServer();
|
||||
pyEnv["res.partner"].create([
|
||||
{ name: "Valid Valeria", email: "normal_valid_email@test.com" },
|
||||
{ name: "Deficient Denise", email: "" },
|
||||
]);
|
||||
onRpc("res.partner", "get_formview_id", () => false);
|
||||
await start();
|
||||
await openFormView("mail.message", undefined, {
|
||||
arch: `
|
||||
<form>
|
||||
<field name="body"/>
|
||||
<field name="partner_ids" widget="many2many_tags_email"/>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
// add an other existing tag
|
||||
await clickFieldDropdown("partner_ids");
|
||||
await clickFieldDropdownItem("partner_ids", "Deficient Denise");
|
||||
await contains(".o-mail-RecipientsInputTagsListPopover");
|
||||
// set the email
|
||||
await insertText(".o-mail-RecipientsInputTagsListPopover input", "coucou@petite.perruche");
|
||||
// Close the modal dialog without saving (should remove partner from invalid records)
|
||||
await click(".o-mail-RecipientsInputTagsListPopover .btn-secondary");
|
||||
// Selecting a partner with a valid email shouldn't open the modal dialog for the previous partner
|
||||
await contains(".o_field_widget[name='partner_ids'] .badge", { count: 0 });
|
||||
await clickFieldDropdown("partner_ids");
|
||||
await clickFieldDropdownItem("partner_ids", "Valid Valeria");
|
||||
await contains(".o-mail-RecipientsInputTagsListPopover", { count: 0 });
|
||||
});
|
||||
|
||||
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++) {
|
||||
partnerIds.push(pyEnv["res.partner"].create({ display_name: `partner${i}` }));
|
||||
}
|
||||
const messageId = pyEnv["mail.message"].create({ partner_ids: partnerIds });
|
||||
await start();
|
||||
await openFormView("mail.message", messageId, {
|
||||
arch: "<form><field name='partner_ids' widget='many2many_tags'/></form>",
|
||||
});
|
||||
await contains('.o_field_widget[name="partner_ids"] .badge', { count: 100 });
|
||||
await contains(".o_form_editable");
|
||||
await clickFieldDropdown("partner_ids");
|
||||
await clickFieldDropdownItem("partner_ids", "Public user");
|
||||
await contains('.o_field_widget[name="partner_ids"] .badge', { count: 101 });
|
||||
});
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
import {
|
||||
click,
|
||||
contains,
|
||||
defineMailModels,
|
||||
insertText,
|
||||
openFormView,
|
||||
start,
|
||||
startServer,
|
||||
} from "@mail/../tests/mail_test_helpers";
|
||||
import { DiscussChannel } from "@mail/../tests/mock_server/mock_models/discuss_channel";
|
||||
import { describe, expect, test } from "@odoo/hoot";
|
||||
import { keyDown, runAllTimers } from "@odoo/hoot-dom";
|
||||
import { asyncStep, onRpc, waitForSteps } from "@web/../tests/web_test_helpers";
|
||||
|
||||
defineMailModels();
|
||||
describe.current.tags("desktop");
|
||||
|
||||
test("onchange_on_keydown option triggers onchange properly", async () => {
|
||||
DiscussChannel._onChanges.description = () => {};
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "General" });
|
||||
await start();
|
||||
onRpc("discuss.channel", "onchange", (params) => {
|
||||
expect(params.args[1].description).toBe("testing the keydown event");
|
||||
asyncStep("onchange");
|
||||
});
|
||||
await openFormView("discuss.channel", channelId, {
|
||||
arch: "<form><field name='description' onchange_on_keydown='True'/></form>",
|
||||
});
|
||||
await insertText("textarea#description_0", "testing the keydown event");
|
||||
await waitForSteps(["onchange"]);
|
||||
});
|
||||
|
||||
test("editing a text field with the onchange_on_keydown option disappearing shouldn't trigger a crash", async () => {
|
||||
DiscussChannel._onChanges.description = () => {};
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "General" });
|
||||
onRpc("discuss.channel", "onchange", () => asyncStep("onchange"));
|
||||
await start();
|
||||
await openFormView("discuss.channel", channelId, {
|
||||
arch: `
|
||||
<form>
|
||||
<field name="description" onchange_on_keydown="True" invisible="name == 'yop'"/>
|
||||
<field name="name"/>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
await click("textarea#description_0");
|
||||
await keyDown("a");
|
||||
await insertText("[name=name] input", "yop", { replace: true });
|
||||
await contains("textarea#description_0", { count: 0 });
|
||||
await runAllTimers();
|
||||
await waitForSteps([]);
|
||||
});
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
import {
|
||||
click,
|
||||
contains,
|
||||
defineMailModels,
|
||||
openView,
|
||||
registerArchs,
|
||||
start,
|
||||
startServer,
|
||||
} from "@mail/../tests/mail_test_helpers";
|
||||
|
||||
import { beforeEach, test } from "@odoo/hoot";
|
||||
import { mockDate } from "@odoo/hoot-mock";
|
||||
|
||||
defineMailModels();
|
||||
beforeEach(() => mockDate("2024-10-20 10:00:00", +1));
|
||||
|
||||
test("Text scheduled date field", async () => {
|
||||
const pyEnv = await startServer();
|
||||
registerArchs({
|
||||
"mail.compose.message,false,form": `<form><field name="scheduled_date" widget="text_scheduled_date"/></form>`,
|
||||
});
|
||||
const composerId = pyEnv["mail.compose.message"].create({
|
||||
subject: "Greetings",
|
||||
body: "<p>Hello There</p>",
|
||||
model: "res.partner",
|
||||
});
|
||||
await start();
|
||||
await openView({
|
||||
res_model: "mail.compose.message",
|
||||
res_id: composerId,
|
||||
views: [["mail.compose.message,false,form", "form"]],
|
||||
});
|
||||
// should not contain text as scheduled date is empty
|
||||
await contains(".o_field_text_scheduled_date button", { text: "" });
|
||||
await click(".o_field_text_scheduled_date button");
|
||||
// should open the dialog to select the schedule date
|
||||
await contains(".modal");
|
||||
// clear button should not be shown as no selected date is set on the record
|
||||
await contains(".modal-footer button", { text: "Clear Time", count: 0 });
|
||||
await click(".modal input[value='afternoon']");
|
||||
await contains(".modal input[value='afternoon']:checked");
|
||||
await click(".modal-footer .btn-primary");
|
||||
// button should show the scheduled date
|
||||
await contains(".o_field_text_scheduled_date button", {
|
||||
text: "Sending Oct 21, 1:00 PM",
|
||||
});
|
||||
await click(".o_field_text_scheduled_date button");
|
||||
// previously selected datetime should be selected in the dialog
|
||||
await contains(".modal input[value='afternoon']:checked");
|
||||
// should be able to clear the selected datetime
|
||||
await click(".modal-footer button:contains('Clear Time')");
|
||||
// button should be empty again
|
||||
await contains(".o_field_text_scheduled_date button", { text: "" });
|
||||
});
|
||||
|
||||
test("Datetime scheduled date field", async () => {
|
||||
const pyEnv = await startServer();
|
||||
registerArchs({
|
||||
"mail.scheduled.message,false,form": `<form><field name="scheduled_date" widget="datetime_scheduled_date"/></form>`,
|
||||
});
|
||||
const composerId = pyEnv["mail.scheduled.message"].create({
|
||||
subject: "Greetings",
|
||||
body: "<p>Hello There</p>",
|
||||
model: "res.partner",
|
||||
scheduled_date: "2024-10-21 12:00:00",
|
||||
});
|
||||
await start();
|
||||
await openView({
|
||||
res_model: "mail.scheduled.message",
|
||||
res_id: composerId,
|
||||
views: [["mail.scheduled.message,false,form", "form"]],
|
||||
});
|
||||
// button should show the scheduled date
|
||||
await contains(".o_field_datetime_scheduled_date button", {
|
||||
text: "Sending Oct 21, 1:00 PM",
|
||||
});
|
||||
await click(".o_field_datetime_scheduled_date button");
|
||||
// should open the dialog to select the schedule date
|
||||
await contains(".modal");
|
||||
// current scheduled datetime should be selected in the dialog
|
||||
await contains(".modal input[value='afternoon']:checked");
|
||||
// clear button should not be shown (can't clear scheduled date of scheduled message)
|
||||
await contains(".modal-footer button", { text: "Clear Time", count: 0 });
|
||||
await click(".modal input[value='morning']");
|
||||
await contains(".modal input[value='morning']:checked");
|
||||
|
||||
await click(".modal-footer .btn-primary");
|
||||
|
||||
// button should show the new scheduled date
|
||||
await contains(".o_field_datetime_scheduled_date button", {
|
||||
text: "Sending Oct 21, 8:00 AM",
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
import {
|
||||
click,
|
||||
contains,
|
||||
defineMailModels,
|
||||
start,
|
||||
startServer,
|
||||
} from "@mail/../tests/mail_test_helpers";
|
||||
import { describe, test } from "@odoo/hoot";
|
||||
import { getService, switchView } from "@web/../tests/web_test_helpers";
|
||||
|
||||
defineMailModels();
|
||||
describe.current.tags("desktop");
|
||||
|
||||
test('shortcut widget displays the appropriate "::" icon across views', async () => {
|
||||
const pyEnv = await startServer();
|
||||
pyEnv["mail.canned.response"].create([{ source: "hello" }]);
|
||||
await start();
|
||||
await getService("action").doAction({
|
||||
res_model: "mail.canned.response",
|
||||
type: "ir.actions.act_window",
|
||||
views: [
|
||||
[false, "list"],
|
||||
[false, "form"],
|
||||
[false, "kanban"],
|
||||
],
|
||||
});
|
||||
const selector = `div[name='source']`;
|
||||
|
||||
await contains(`.o_control_panel_navigation .o_cp_switch_buttons`);
|
||||
await contains(`.o_switch_view`, { count: 2 });
|
||||
|
||||
await contains(".o_list_view .o_content");
|
||||
await contains(selector, { text: "::hello" });
|
||||
|
||||
await switchView("kanban");
|
||||
await contains(".o_kanban_view .o_content");
|
||||
await contains(selector, { text: "::hello" });
|
||||
|
||||
await click(".o_control_panel_main_buttons .o-kanban-button-new");
|
||||
await contains(`.o_form_view .o_content`);
|
||||
await contains(`${selector} input[type='text']`);
|
||||
await contains(selector, { text: "::" });
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue