1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/web_enterprise/static/tests/webclient/home_menu_tests.js
2024-12-10 09:04:09 +07:00

459 lines
17 KiB
JavaScript

/** @odoo-module **/
import { registerCleanup } from "@web/../tests/helpers/cleanup";
import { makeTestEnv } from "@web/../tests/helpers/mock_env";
import { makeFakeLocalizationService } from "@web/../tests/helpers/mock_services";
import {
drag,
getFixture,
nextTick,
patchWithCleanup,
triggerHotkey,
} from "@web/../tests/helpers/utils";
import testUtils from "@web/../tests/legacy/helpers/test_utils";
import { templates } from "@web/core/assets";
import { browser } from "@web/core/browser/browser";
import { commandService } from "@web/core/commands/command_service";
import { hotkeyService } from "@web/core/hotkeys/hotkey_service";
import { ormService } from "@web/core/orm_service";
import { registry } from "@web/core/registry";
import { uiService } from "@web/core/ui/ui_service";
import { session } from "@web/session";
import { reorderApps } from "@web/webclient/menus/menu_helpers";
import { enterpriseSubscriptionService } from "@web_enterprise/webclient/home_menu/enterprise_subscription_service";
import { HomeMenu } from "@web_enterprise/webclient/home_menu/home_menu";
import { App, Component, EventBus, useState, xml } from "@odoo/owl";
const patchDate = testUtils.mock.patchDate;
const serviceRegistry = registry.category("services");
let target;
let appItems;
// -----------------------------------------------------------------------------
// Helpers
// -----------------------------------------------------------------------------
async function createHomeMenu(config = {}) {
const env = await makeTestEnv(config);
class HomeMenuContainer extends Component {
static props = ["*"];
static components = { HomeMenu };
static template = xml`<HomeMenu t-props="homeMenuProps"/>`;
setup() {
const apps = useState(appItems);
this.homeMenuProps = {
apps: apps,
reorderApps: (order) => {
reorderApps(apps, order);
},
};
}
}
const app = new App(HomeMenuContainer, {
env,
templates,
test: true,
});
const homeMenu = await app.mount(target);
registerCleanup(() => app.destroy());
return homeMenu;
}
async function walkOn(assert, path) {
for (const step of path) {
triggerHotkey(`${step.shiftKey ? "shift+" : ""}${step.key}`);
await nextTick();
assert.hasClass(
target.querySelectorAll(".o_menuitem")[step.index],
"o_focused",
`step ${step.number}`
);
}
}
// -----------------------------------------------------------------------------
// Tests
// -----------------------------------------------------------------------------
let bus;
QUnit.module(
"web_enterprise",
{
beforeEach: function () {
appItems = [
{
actionID: 121,
appID: 1,
id: 1,
label: "Discuss",
parents: "",
webIcon: false,
xmlid: "app.1",
},
{
actionID: 122,
appID: 2,
id: 2,
label: "Calendar",
parents: "",
webIcon: false,
xmlid: "app.2",
},
{
actionID: 123,
appID: 3,
id: 3,
label: "Contacts",
parents: "",
webIcon: false,
xmlid: "app.3",
},
];
bus = new EventBus();
const fakeHomeMenuService = {
name: "home_menu",
start() {
return {
toggle(show) {
bus.trigger("toggle", show);
},
};
},
};
const fakeMenuService = {
name: "menu",
start() {
return {
selectMenu(menu) {
bus.trigger("selectMenu", menu.id);
},
getMenu() {
return {};
},
};
},
};
serviceRegistry.add("ui", uiService);
serviceRegistry.add("hotkey", hotkeyService);
serviceRegistry.add("command", commandService);
serviceRegistry.add("localization", makeFakeLocalizationService());
serviceRegistry.add("orm", ormService);
serviceRegistry.add(enterpriseSubscriptionService.name, enterpriseSubscriptionService);
serviceRegistry.add(fakeHomeMenuService.name, fakeHomeMenuService);
serviceRegistry.add(fakeMenuService.name, fakeMenuService);
target = getFixture();
},
},
function () {
QUnit.module("HomeMenu");
QUnit.test("ESC Support", async function (assert) {
bus.addEventListener("toggle", (ev) => {
assert.step(`toggle ${ev.detail}`);
});
await createHomeMenu();
await testUtils.dom.triggerEvent(window, "keydown", { key: "Escape" });
assert.verifySteps(["toggle false"]);
});
QUnit.test("Click on an app", async function (assert) {
bus.addEventListener("selectMenu", (ev) => {
assert.step(`selectMenu ${ev.detail}`);
});
await createHomeMenu();
await testUtils.dom.click(target.querySelectorAll(".o_menuitem")[0]);
assert.verifySteps(["selectMenu 1"]);
});
QUnit.test("Display Expiration Panel (no module installed)", async function (assert) {
const unpatchDate = patchDate(2019, 9, 10, 0, 0, 0);
registerCleanup(unpatchDate);
patchWithCleanup(session, {
expiration_date: "2019-11-01 12:00:00",
expiration_reason: "",
isMailInstalled: false,
warning: "admin",
});
await createHomeMenu();
assert.containsOnce(target, ".database_expiration_panel");
assert.strictEqual(
target.querySelector(".database_expiration_panel .oe_instance_register").innerText,
"You will be able to register your database once you have installed your first app.",
"There should be an expiration panel displayed"
);
// Close the expiration panel
await testUtils.dom.click(
target.querySelector(".database_expiration_panel .oe_instance_hide_panel")
);
assert.containsNone(target, ".database_expiration_panel");
});
QUnit.test("Navigation (only apps, only one line)", async function (assert) {
assert.expect(8);
appItems = new Array(3).fill().map((x, i) => {
return {
actionID: 120 + i,
appID: i + 1,
id: i + 1,
label: `0${i}`,
parents: "",
webIcon: false,
xmlid: `app.${i}`,
};
});
await createHomeMenu();
const path = [
{ number: 0, key: "ArrowDown", index: 0 },
{ number: 1, key: "ArrowRight", index: 1 },
{ number: 2, key: "Tab", index: 2 },
{ number: 3, key: "ArrowRight", index: 0 },
{ number: 4, key: "Tab", shiftKey: true, index: 2 },
{ number: 5, key: "ArrowLeft", index: 1 },
{ number: 6, key: "ArrowDown", index: 1 },
{ number: 7, key: "ArrowUp", index: 1 },
];
await walkOn(assert, path);
});
QUnit.test("Navigation (only apps, two lines, one incomplete)", async function (assert) {
assert.expect(19);
appItems = new Array(8).fill().map((x, i) => {
return {
actionID: 121,
appID: i + 1,
id: i + 1,
label: `0${i}`,
parents: "",
webIcon: false,
xmlid: `app.${i}`,
};
});
await createHomeMenu();
const path = [
{ number: 1, key: "ArrowRight", index: 0 },
{ number: 2, key: "ArrowUp", index: 6 },
{ number: 3, key: "ArrowUp", index: 0 },
{ number: 4, key: "ArrowDown", index: 6 },
{ number: 5, key: "ArrowDown", index: 0 },
{ number: 6, key: "ArrowRight", index: 1 },
{ number: 7, key: "ArrowRight", index: 2 },
{ number: 8, key: "ArrowUp", index: 7 },
{ number: 9, key: "ArrowUp", index: 1 },
{ number: 10, key: "ArrowRight", index: 2 },
{ number: 11, key: "ArrowDown", index: 7 },
{ number: 12, key: "ArrowDown", index: 1 },
{ number: 13, key: "ArrowUp", index: 7 },
{ number: 14, key: "ArrowRight", index: 6 },
{ number: 15, key: "ArrowLeft", index: 7 },
{ number: 16, key: "ArrowUp", index: 1 },
{ number: 17, key: "ArrowLeft", index: 0 },
{ number: 18, key: "ArrowLeft", index: 5 },
{ number: 19, key: "ArrowRight", index: 0 },
];
await walkOn(assert, path);
});
QUnit.test("Navigation and open an app in the home menu", async function (assert) {
assert.expect(7);
bus.addEventListener("selectMenu", (ev) => {
assert.step(`selectMenu ${ev.detail}`);
});
await createHomeMenu();
// No app selected so nothing to open
await testUtils.dom.triggerEvent(window, "keydown", { key: "Enter" });
assert.verifySteps([]);
const path = [
{ number: 0, key: "ArrowDown", index: 0 },
{ number: 1, key: "ArrowRight", index: 1 },
{ number: 2, key: "Tab", index: 2 },
{ number: 3, key: "shift+Tab", index: 1 },
];
await walkOn(assert, path);
// open first app (Calendar)
await testUtils.dom.triggerEvent(window, "keydown", { key: "Enter" });
assert.verifySteps(["selectMenu 2"]);
});
QUnit.test("Reorder apps in home menu using drag and drop", async function (assert) {
appItems = new Array(8).fill().map((x, i) => {
return {
actionID: 121,
appID: i + 1,
id: i + 1,
label: `0${i}`,
parents: "",
webIcon: false,
xmlid: `app.${i}`,
};
});
patchWithCleanup(browser, {
setTimeout: (callback, delay) => {
assert.step(`setTimeout of ${delay}ms`);
callback();
},
});
patchWithCleanup(session, { user_settings: { id: 1, homemenu_config: "" } });
const mockRPC = (route, args) => {
if (args.method === "set_res_users_settings") {
assert.step(`set_res_users_settings`);
return {
id: 1,
homemenu_config:
'["app.1","app.2","app.3","app.0","app.4","app.5","app.6","app.7"]',
};
}
};
const serverData = {
models: {
"res.users.settings": {
fields: {
id: {
type: "number",
},
homemenu_config: {
type: "string",
},
},
records: [
{
id: 1,
homemenu_config: "",
},
],
},
},
};
await createHomeMenu({ serverData, mockRPC });
const { drop } = await drag(".o_draggable:first-child");
await drop(".o_draggable:nth-child(4)");
assert.verifySteps(["setTimeout of 500ms", "set_res_users_settings"]);
const apps = document.querySelectorAll(".o_app");
assert.strictEqual(
apps[0].getAttribute("data-menu-xmlid"),
"app.1",
"first displayed app has app.1 xmlid"
);
assert.strictEqual(
apps[3].getAttribute("data-menu-xmlid"),
"app.0",
"app 0 is now at 4th position"
);
});
QUnit.test(
"The HomeMenu input takes the focus when you press a key only if no other element is the activeElement",
async function (assert) {
const target = getFixture();
const homeMenu = await createHomeMenu();
const input = target.querySelector(".o_search_hidden");
assert.strictEqual(document.activeElement, input);
const activeElement = document.createElement("div");
homeMenu.env.services.ui.activateElement(activeElement);
// remove the focus from the input
const otherInput = document.createElement("input");
target.querySelector(".o_home_menu").appendChild(otherInput);
otherInput.focus();
otherInput.blur();
assert.notEqual(document.activeElement, input);
await testUtils.dom.triggerEvent(window, "keydown", { key: "a" });
await nextTick();
assert.notEqual(document.activeElement, input);
homeMenu.env.services.ui.deactivateElement(activeElement);
await testUtils.dom.triggerEvent(window, "keydown", { key: "a" });
await nextTick();
assert.strictEqual(document.activeElement, input);
}
);
QUnit.test(
"The HomeMenu input does not take the focus if it is already on another input",
async function (assert) {
const target = getFixture();
await createHomeMenu();
const homeMenuInput = target.querySelector(".o_search_hidden");
assert.strictEqual(document.activeElement, homeMenuInput);
const otherInput = document.createElement("input");
target.querySelector(".o_home_menu").appendChild(otherInput);
otherInput.focus();
await testUtils.dom.triggerEvent(window, "keydown", { key: "a" });
await nextTick();
assert.notEqual(document.activeElement, homeMenuInput);
otherInput.remove();
await testUtils.dom.triggerEvent(window, "keydown", { key: "a" });
await nextTick();
assert.strictEqual(document.activeElement, homeMenuInput);
}
);
QUnit.test(
"The HomeMenu input does not take the focus if it is already on a textarea",
async function (assert) {
const target = getFixture();
await createHomeMenu();
const homeMenuInput = target.querySelector(".o_search_hidden");
assert.strictEqual(document.activeElement, homeMenuInput);
const textarea = document.createElement("textarea");
target.querySelector(".o_home_menu").appendChild(textarea);
textarea.focus();
await testUtils.dom.triggerEvent(window, "keydown", { key: "a" });
await nextTick();
assert.notEqual(document.activeElement, homeMenuInput);
textarea.remove();
await testUtils.dom.triggerEvent(window, "keydown", { key: "a" });
await nextTick();
assert.strictEqual(document.activeElement, homeMenuInput);
}
);
QUnit.test(
"home search input shouldn't be focused on touch devices [REQUIRE FOCUS]",
async function (assert) {
// patch matchMedia to alter hasTouch value
patchWithCleanup(browser, {
setTimeout: (fn) => fn(),
matchMedia: (media) => {
if (media === "(pointer:coarse)") {
return { matches: true };
}
this._super();
},
});
const target = getFixture();
await createHomeMenu();
const homeMenuInput = target.querySelector(".o_search_hidden");
assert.notOk(
homeMenuInput.matches(":focus"),
"home menu search input shouldn't have the focus"
);
}
);
}
);