[REF] *: rework webclient test helpers

This commit splits the 'getActionManagerTestConfig' helper into 2:
'setupWebClientServiceRegistry' and 'getActionManagerServerData'.

The first one is now automatically called by the 'createWebClient'
helper, as it properly setups the service registry with all services
required by the WebClient component.

The second one generates a few data (menus, actions, views...) that
can be used in tests. That helper is mainly useful for action tests
(formerly ActionManager tests) in web. With this refactoring, they
are no longer generated for each test in the whole codebase that
spawns a webclient, as before this commit.

closes odoo-dev/odoo#906

Related: odoo-dev/enterprise#161
Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
This commit is contained in:
Aaron Bohy
2021-06-18 21:31:30 +02:00
parent dd489c34e7
commit a5091fee99
38 changed files with 955 additions and 954 deletions
+14 -19
View File
@@ -9,16 +9,12 @@ var ListRenderer = require('web.ListRenderer');
var pyUtils = require('web.py_utils');
const cpHelpers = testUtils.controlPanel;
const {
createWebClient,
doAction,
getActionManagerTestConfig,
} = require("@web/../tests/webclient/actions/helpers");
const { createWebClient, doAction } = require("@web/../tests/webclient/helpers");
var createView = testUtils.createView;
const patchDate = testUtils.mock.patchDate;
let testConfig;
let serverData;
QUnit.module('Dashboard', {
beforeEach: function () {
this.data = {
@@ -53,9 +49,8 @@ QUnit.module('Dashboard', {
}],
},
};
testConfig = getActionManagerTestConfig();
// map legacy test data
Object.assign(testConfig.serverData, { models: this.data });
serverData = { models: this.data };
},
});
@@ -717,9 +712,9 @@ QUnit.test("save actions to dashboard", async function (assert) {
},
});
testConfig.serverData.models["partner"].fields.foo.sortable = true;
serverData.models.partner.fields.foo.sortable = true;
testConfig.serverData.views = {
serverData.views = {
"partner,false,list": '<list><field name="foo"/></list>',
"partner,false,search": "<search></search>",
};
@@ -752,7 +747,7 @@ QUnit.test("save actions to dashboard", async function (assert) {
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, {
id: 1,
@@ -785,7 +780,7 @@ QUnit.test("save two searches to dashboard", async function (assert) {
// the second search saved should not be influenced by the first
assert.expect(2);
testConfig.serverData.views = {
serverData.views = {
"partner,false,list": '<list><field name="foo"/></list>',
"partner,false,search": "<search></search>",
};
@@ -812,7 +807,7 @@ QUnit.test("save two searches to dashboard", async function (assert) {
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, {
id: 1,
@@ -863,7 +858,7 @@ QUnit.test("save a action domain to dashboard", async function (assert) {
// The filter domain already contains the view domain, but is always added by dashboard..,
var expected_domain = ["&", view_domain, "&", view_domain, filter_domain];
testConfig.serverData.views = {
serverData.views = {
"partner,false,list": '<list><field name="foo"/></list>',
"partner,false,search": "<search></search>",
};
@@ -875,7 +870,7 @@ QUnit.test("save a action domain to dashboard", async function (assert) {
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, {
id: 1,
@@ -1065,13 +1060,13 @@ QUnit.test(
const unpatchDate = patchDate(2020, 6, 1, 11, 0, 0);
testConfig.serverData.models.partner.fields.date = {
serverData.models.partner.fields.date = {
string: "Date",
type: "date",
sortable: true,
};
testConfig.serverData.views = {
serverData.views = {
"partner,false,pivot": '<pivot><field name="foo"/></pivot>',
"partner,false,search": '<search><filter name="Date" date="date"/></search>',
};
@@ -1095,7 +1090,7 @@ QUnit.test(
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, {
id: 1,
@@ -5,10 +5,7 @@ import * as BusService from "bus.BusService";
import * as RamStorage from "web.RamStorage";
import * as AbstractStorageService from "web.AbstractStorageService";
import {
createWebClient,
getActionManagerTestConfig,
} from "@web/../tests/webclient/actions/helpers";
import { createWebClient } from "@web/../tests/webclient/helpers";
import { assetsWatchdogService } from "@bus/js/services/assets_watchdog_service";
import { click, nextTick, patchWithCleanup } from "@web/../tests/helpers/utils";
import { NotificationContainer } from "@web/core/notifications/notification_container";
@@ -24,13 +21,11 @@ const serviceRegistry = registry.category("services");
QUnit.module("Bus Assets WatchDog", (hooks) => {
let legacyServicesRegistry;
let testConfig;
hooks.beforeEach((assert) => {
legacyServicesRegistry = new legacyRegistry();
legacyServicesRegistry.add("bus_service", BusService);
legacyServicesRegistry.add("local_storage", LocalStorageService);
testConfig = getActionManagerTestConfig();
serviceRegistry.add("assetsWatchdog", assetsWatchdogService);
clearRegistryWithCleanup(mainComponentRegistry);
@@ -68,7 +63,6 @@ QUnit.module("Bus Assets WatchDog", (hooks) => {
};
const webClient = await createWebClient({
testConfig,
legacyParams: { serviceRegistry: legacyServicesRegistry },
mockRPC,
});
@@ -5,10 +5,7 @@ import * as BusService from "bus.BusService";
import * as RamStorage from "web.RamStorage";
import * as AbstractStorageService from "web.AbstractStorageService";
import {
createWebClient,
getActionManagerTestConfig,
} from "@web/../tests/webclient/actions/helpers";
import { createWebClient } from "@web/../tests/webclient/helpers";
import { calendarNotificationService } from "@calendar/js/services/calendar_notification_service";
import { click, nextTick, patchWithCleanup } from "@web/../tests/helpers/utils";
import { NotificationContainer } from "@web/core/notifications/notification_container";
@@ -24,13 +21,11 @@ const serviceRegistry = registry.category("services");
QUnit.module("Calendar Notification", (hooks) => {
let legacyServicesRegistry;
let testConfig;
hooks.beforeEach(() => {
legacyServicesRegistry = new legacyRegistry();
legacyServicesRegistry.add("bus_service", BusService);
legacyServicesRegistry.add("local_storage", LocalStorageService);
testConfig = getActionManagerTestConfig();
serviceRegistry.add("calendarNotification", calendarNotificationService);
clearRegistryWithCleanup(mainComponentRegistry);
@@ -83,7 +78,6 @@ QUnit.module("Calendar Notification", (hooks) => {
};
const webClient = await createWebClient({
testConfig,
legacyParams: { serviceRegistry: legacyServicesRegistry },
mockRPC,
});
@@ -154,7 +148,6 @@ QUnit.module("Calendar Notification", (hooks) => {
serviceRegistry.add("action", fakeActionService, { force: true });
const webClient = await createWebClient({
testConfig,
legacyParams: { serviceRegistry: legacyServicesRegistry },
mockRPC,
});
@@ -213,7 +206,6 @@ QUnit.module("Calendar Notification", (hooks) => {
};
const webClient = await createWebClient({
testConfig,
legacyParams: { serviceRegistry: legacyServicesRegistry },
mockRPC,
});
+7 -17
View File
@@ -23,12 +23,7 @@ import {
mock,
} from 'web.test_utils';
import Widget from 'web.Widget';
import {
createWebClient,
getActionManagerTestConfig,
} from "@web/../tests/webclient/actions/helpers";
import { ComponentAdapter } from "web.OwlCompatibility";
import LegacyMockServer from "web.MockServer";
import { createWebClient } from "@web/../tests/webclient/helpers";
const {
addMockEnvironment,
@@ -551,27 +546,22 @@ async function start(param0 = {}) {
}
});
} else if (hasActionManager) {
let testConfig;
if (!kwargs.testConfig) {
testConfig = getActionManagerTestConfig();
} else {
testConfig = kwargs.testConfig;
delete kwargs.testConfig;
}
let serverData = kwargs.serverData || {};
delete kwargs.serverData;
if (kwargs.actions) {
const actions = {};
kwargs.actions.forEach((act) => {
actions[act.xml_id || act.id] = act;
});
Object.assign(testConfig.serverData.actions, actions);
Object.assign(serverData.actions, actions);
delete kwargs.actions;
}
Object.assign(testConfig.serverData.views, kwargs.archs);
Object.assign(serverData.views, kwargs.archs);
delete kwargs.archs;
Object.assign(testConfig.serverData.models, kwargs.data);
Object.assign(serverData.models, kwargs.data);
delete kwargs.data;
const mockRPC = kwargs.mockRPC;
@@ -579,7 +569,7 @@ async function start(param0 = {}) {
const legacyParams = kwargs;
legacyParams.withLegacyMockServer = true;
const widget = await createWebClient({ testConfig, mockRPC, legacyParams });
const widget = await createWebClient({ serverData, mockRPC, legacyParams });
legacyPatch(widget, {
destroy() {
+23 -21
View File
@@ -2,13 +2,12 @@
import ActivityView from '@mail/js/views/activity/activity_view';
import testUtils from 'web.test_utils';
import { createWebClient } from "@web/../tests/webclient/actions/helpers";
import { legacyExtraNextTick, patchWithCleanup } from "@web/../tests/helpers/utils";
import { doAction, getActionManagerTestConfig } from "@web/../tests/webclient/actions/helpers";
import { createWebClient, doAction } from "@web/../tests/webclient/helpers";
import { registry } from "@web/core/registry";
let testConfig;
let serverData;
var createView = testUtils.createView;
@@ -113,8 +112,7 @@ QUnit.module('activity view', {
],
},
};
testConfig = getActionManagerTestConfig();
Object.assign(testConfig.serverData.models, this.data);
serverData = { models: this.data };
}
});
@@ -361,15 +359,17 @@ QUnit.test('activity view: activity widget', async function (assert) {
QUnit.test("activity view: no group_by_menu and no comparison_menu", async function (assert) {
assert.expect(4);
testConfig.serverData.actions[1] = {
id: 1,
name: "Task Action",
res_model: "task",
type: "ir.actions.act_window",
views: [[false, "activity"]],
serverData.actions = {
1: {
id: 1,
name: "Task Action",
res_model: "task",
type: "ir.actions.act_window",
views: [[false, "activity"]],
},
};
testConfig.serverData.views = {
serverData.views = {
"task,false,activity":
'<activity string="Task">' +
"<templates>" +
@@ -393,7 +393,7 @@ QUnit.test("activity view: no group_by_menu and no comparison_menu", async funct
patchWithCleanup(odoo.session_info.user_context, { lang: "zz_ZZ" });
const webClient = await createWebClient({ testConfig, mockRPC , legacyParams: {withLegacyMockServer: true}});
const webClient = await createWebClient({ serverData, mockRPC , legacyParams: {withLegacyMockServer: true}});
await doAction(webClient, 1);
@@ -479,15 +479,17 @@ QUnit.test('activity view: search more to schedule an activity for a record of a
QUnit.test("Activity view: discard an activity creation dialog", async function (assert) {
assert.expect(2);
testConfig.serverData.actions[1] = {
id: 1,
name: "Task Action",
res_model: "task",
type: "ir.actions.act_window",
views: [[false, "activity"]],
serverData.actions = {
1: {
id: 1,
name: "Task Action",
res_model: "task",
type: "ir.actions.act_window",
views: [[false, "activity"]],
},
};
testConfig.serverData.views = {
serverData.views = {
"task,false,activity": `
<activity string="Task">
<templates>
@@ -512,7 +514,7 @@ QUnit.test("Activity view: discard an activity creation dialog", async function
}
};
const webClient = await createWebClient({ testConfig, mockRPC, legacyParams: {withLegacyMockServer: true} });
const webClient = await createWebClient({ serverData, mockRPC, legacyParams: {withLegacyMockServer: true} });
await doAction(webClient, 1);
await testUtils.dom.click(
@@ -2,11 +2,7 @@
import { manageMessages } from "@mail/js/tools/debug_manager";
import { click, legacyExtraNextTick, patchWithCleanup } from "@web/../tests/helpers/utils";
import {
createWebClient,
doAction,
getActionManagerTestConfig,
} from "@web/../tests/webclient/actions/helpers";
import { createWebClient, doAction, getActionManagerServerData } from "@web/../tests/webclient/helpers";
import { debugService } from "@web/core/debug/debug_service";
import { registry } from "@web/core/registry";
@@ -16,14 +12,14 @@ QUnit.test("Manage Messages", async function (assert) {
assert.expect(6);
patchWithCleanup(odoo, { debug: "1" });
const testConfig = getActionManagerTestConfig();
const serverData = getActionManagerServerData();
// Add fake "mail.message" model and arch
testConfig.serverData.models["mail.message"] = {
serverData.models["mail.message"] = {
fields: { name: { string: "Name", type: "char" } },
records: [],
};
Object.assign(testConfig.serverData.views, {
Object.assign(serverData.views, {
"mail.message,false,list": `<tree/>`,
"mail.message,false,form": `<form/>`,
"mail.message,false,search": `<search/>`,
@@ -44,7 +40,7 @@ QUnit.test("Manage Messages", async function (assert) {
}
}
const wc = await createWebClient({ testConfig, mockRPC });
const wc = await createWebClient({ serverData, mockRPC });
await doAction(wc, 3, { viewType: "form", resId: 5 });
await legacyExtraNextTick();
await click(wc.el, ".o_debug_manager .o_dropdown_toggler");
@@ -3,8 +3,9 @@ odoo.define('product.pricelist.report.tests', function (require) {
const GeneratePriceList = require('product.generate_pricelist').GeneratePriceList;
const testUtils = require('web.test_utils');
const { createWebClient, getActionManagerTestConfig, doAction } = require('@web/../tests/webclient/actions/helpers');
let testConfig;
const { createWebClient, doAction } = require('@web/../tests/webclient/helpers');
let serverData;
QUnit.module('Product Pricelist', {
beforeEach: function () {
@@ -31,8 +32,7 @@ QUnit.module('Product Pricelist', {
}]
}
};
testConfig = getActionManagerTestConfig();
Object.assign(testConfig.serverData, {models: this.data});
serverData = { models: this.data };
},
}, function () {
QUnit.test('Pricelist Client Action', async function (assert) {
@@ -57,7 +57,7 @@ QUnit.module('Product Pricelist', {
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, {
id: 1,
name: 'Generate Pricelist',
@@ -9,7 +9,7 @@ odoo.define('stock.stock_traceability_report_backend_tests', function (require)
const { dom: domUtils } = testUtils;
const { legacyExtraNextTick } = require("@web/../tests/helpers/utils");
const { createWebClient, getActionManagerTestConfig, doAction } = require('@web/../tests/webclient/actions/helpers');
const { createWebClient, doAction } = require('@web/../tests/webclient/helpers');
/**
* Helper function to instantiate a stock report action.
@@ -93,33 +93,35 @@ odoo.define('stock.stock_traceability_report_backend_tests', function (require)
this.__superMounted(...arguments);
},
});
const models = {
partner: {
fields: {
display_name: { string: "Displayed name", type: "char" },
const serverData = {
models: {
partner: {
fields: {
display_name: { string: "Displayed name", type: "char" },
},
records: [
{id: 1, display_name: "Genda Swami"},
],
},
},
views: {
'partner,false,form': '<form><field name="display_name"/></form>',
'partner,false,search': '<search></search>',
},
actions: {
42: {
id: 42,
name: "Stock report",
tag: 'stock_report_generic',
type: 'ir.actions.client',
context: {},
params: {},
},
records: [
{id: 1, display_name: "Genda Swami"},
],
},
};
let testConfig = getActionManagerTestConfig();
Object.assign(testConfig.serverData, { models });
testConfig.serverData.views = {
'partner,false,form': '<form><field name="display_name"/></form>',
'partner,false,search': '<search></search>',
};
testConfig.serverData.actions[42] = {
id: 42,
name: "Stock report",
tag: 'stock_report_generic',
type: 'ir.actions.client',
context: {},
params: {},
};
const webClient = await createWebClient({
testConfig,
serverData,
mockRPC: function (route) {
if (route === '/web/dataset/call_kw/stock.traceability.report/get_html') {
return Promise.resolve({
@@ -9,6 +9,19 @@ import { nextTick, patchWithCleanup } from "../helpers/utils";
async function createRouter(params = {}) {
const env = params.env || {};
env.bus = env.bus || new owl.core.EventBus();
if (params.onPushState) {
const originalPushState = browser.history.pushState;
const onPushState = params.onPushState;
delete params.onPushState;
patchWithCleanup(browser, {
history: Object.assign({}, browser.history, {
pushState() {
originalPushState(...arguments);
onPushState(...arguments);
},
}),
});
}
const router = await makeFakeRouterService(params).start(env);
return router;
}
@@ -126,61 +126,17 @@ export function makeMockFetch(mockRPC) {
};
}
function makeMockLocation() {
const locationLink = Object.assign(document.createElement("a"), {
href: window.location.origin + window.location.pathname,
assign(url) {
this.href = url;
},
reload() {},
});
return new Proxy(locationLink, {
get(target, p) {
return target[p];
},
set(target, p, value) {
target[p] = value;
if (p === "hash") {
window.dispatchEvent(new HashChangeEvent("hashchange"));
}
return true;
},
});
}
/**
* @param {Object} [params={}]
* @param {Object} [params.initialRoute] initial route object
* @param {Object} [params.onPushState] hook on the "pushState" method
* @param {Object} [params.onReplaceState] hook on the "onReplaceState" method
* @param {Object} [params.onRedirect] hook on the "redirect" method
* @returns {typeof routerService}
*/
export function makeFakeRouterService(params = {}) {
const mockLocation = makeMockLocation();
Object.assign(mockLocation, params.initialRoute);
patchWithCleanup(browser, {
location: mockLocation,
history: {
pushState(state, title, url) {
mockLocation.assign(url);
if (params.onPushState) {
params.onPushState(url);
}
},
replaceState(state, title, url) {
mockLocation.assign(url);
if (params.onReplaceState) {
params.onReplaceState(url);
}
},
},
});
return {
start({ bus }) {
const router = routerService.start(...arguments);
bus.on("test:hashchange", null, (hash) => {
mockLocation.hash = objectToUrlEncodedString(hash);
browser.location.hash = objectToUrlEncodedString(hash);
});
registerCleanup(router.cancelPushes);
patchWithCleanup(router, {
@@ -1,16 +1,12 @@
/** @odoo-module alias="web.search_bar_tests" **/
import testUtils from "web.test_utils";
import {
createWebClient,
doAction,
getActionManagerTestConfig,
} from "@web/../tests/webclient/actions/helpers";
import { createWebClient, doAction } from "@web/../tests/webclient/helpers";
import { Model } from "web.Model";
import Registry from "web.Registry";
import SearchBar from "web.SearchBar";
let testConfig;
let serverData;
// legacy stuff
let cpHelpers;
@@ -20,10 +16,7 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
cpHelpers = testUtils.controlPanel;
});
hooks.beforeEach(() => {
testConfig = getActionManagerTestConfig();
});
hooks.beforeEach(() => {
const serverData = {
serverData = {
models: {
partner: {
fields: {
@@ -67,13 +60,12 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
},
},
};
testConfig.serverData = serverData;
});
QUnit.test("basic rendering", async function (assert) {
assert.expect(1);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
assert.strictEqual(
@@ -86,7 +78,7 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
QUnit.test("navigation with facets", async function (assert) {
assert.expect(4);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
// add a facet
@@ -113,7 +105,7 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
let searchReadCount = 0;
const webClient = await createWebClient({
testConfig,
serverData,
legacyParams: {
getTZOffset() {
return 360;
@@ -171,7 +163,6 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
QUnit.test("autocomplete menu clickout interactions", async function (assert) {
assert.expect(9);
const { serverData } = testConfig;
const data = serverData.models;
const fields = serverData.models.partner.fields;
@@ -234,7 +225,7 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
let searchReadCount = 0;
const webClient = await createWebClient({
testConfig,
serverData,
mockRPC: (route, args) => {
if (route === '/web/dataset/search_read') {
switch (searchReadCount) {
@@ -267,7 +258,7 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
let searchReadCount = 0;
const firstLoading = testUtils.makeTestPromise();
const webClient = await createWebClient({
testConfig,
serverData,
mockRPC: (route, args) => {
if (route === '/web/dataset/search_read') {
switch (searchReadCount) {
@@ -323,8 +314,8 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
// Switch to pivot to ensure that the event comes from the control panel
// (pivot does not have a handler on "reload" event).
testConfig.serverData.actions[1].views = [[false, "pivot"]];
testConfig.serverData.views['partner,false,pivot'] = `
serverData.actions[1].views = [[false, "pivot"]];
serverData.views['partner,false,pivot'] = `
<pivot>
<field name="foo" type="row"/>
</pivot>
@@ -332,7 +323,7 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
let rpcs;
const webClient = await createWebClient({
testConfig,
serverData,
mockRPC: () => { rpcs++; },
});
await doAction(webClient, 1);
@@ -348,7 +339,7 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
QUnit.test('selecting (no result) triggers a re-render', async function (assert) {
assert.expect(3);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
const searchInput = webClient.el.querySelector('.o_searchview_input');
@@ -377,7 +368,7 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
// not handled but are triggered to ensure they do not interfere.
const TEST = "TEST";
const テスト = "テスト";
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
const searchInput = webClient.el.querySelector('.o_searchview_input');
@@ -450,7 +441,7 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
QUnit.test('open search view autocomplete on paste value using mouse', async function (assert) {
assert.expect(1);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
// Simulate paste text through the mouse.
@@ -467,7 +458,7 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
QUnit.test('select autocompleted many2one', async function (assert) {
assert.expect(5);
testConfig.serverData.views['partner,false,search'] = `
serverData.views['partner,false,search'] = `
<search>
<field name="foo"/>
<field name="birthday"/>
@@ -477,7 +468,7 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
`;
const webClient = await createWebClient({
testConfig,
serverData,
mockRPC: (route, { domain }) => {
if (route === '/web/dataset/search_read') {
assert.step(JSON.stringify(domain));
@@ -508,7 +499,7 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
assert.expect(4);
const webClient = await createWebClient({
testConfig,
serverData,
mockRPC: (route, { domain }) => {
if (route === '/web/dataset/search_read') {
assert.step(JSON.stringify(domain));
@@ -536,12 +527,12 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
QUnit.test('autocompletion with a boolean field', async function (assert) {
assert.expect(11);
testConfig.serverData.views['partner,false,search'] = `
serverData.views['partner,false,search'] = `
<search><field name="bool"/></search>
`;
const webClient = await createWebClient({
testConfig,
serverData,
mockRPC: (route, { domain }) => {
if (route === '/web/dataset/search_read') {
assert.step(JSON.stringify(domain));
@@ -581,11 +572,11 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
QUnit.test('autocompletion with a selection field', async function (assert) {
assert.expect(5);
testConfig.serverData.views['partner,false,search'] = `
serverData.views['partner,false,search'] = `
<search><field name="status"/></search>
`;
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
await cpHelpers.editSearch(webClient, "n");
@@ -600,20 +591,20 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
QUnit.test("reference fields are supported in search view", async function (assert) {
assert.expect(7);
const partnerModel = testConfig.serverData.models.partner;
const partnerModel = serverData.models.partner;
partnerModel.fields.ref = { type: 'reference', string: "Reference" };
partnerModel.records.forEach((record, i) => {
record.ref = `ref${String(i).padStart(3, "0")}`;
});
testConfig.serverData.views["partner,false,search"] = `
serverData.views["partner,false,search"] = `
<search>
<field name="ref"/>
</search>
`;
const webClient = await createWebClient({
testConfig,
serverData,
mockRPC: (route, { domain }) => {
if (route === '/web/dataset/search_read') {
assert.step(JSON.stringify(domain));
@@ -6,14 +6,12 @@ import core from "web.core";
import * as LegacyRegistry from "web.Registry";
import { registerCleanup } from "../../helpers/cleanup";
import { nextTick, patchWithCleanup } from "../../helpers/utils";
import { createWebClient, doAction, getActionManagerTestConfig } from "../../webclient/actions/helpers";
import { createWebClient, doAction } from "../../webclient/helpers";
let testConfig;
let legacyParams;
QUnit.module("Service Provider Adapter Notification", (hooks) => {
hooks.beforeEach(() => {
testConfig = getActionManagerTestConfig();
legacyParams = {
serviceRegistry: new LegacyRegistry(),
};
@@ -56,7 +54,7 @@ QUnit.module("Service Provider Adapter Notification", (hooks) => {
delete core.action_registry.map.NotifyTestLeg;
delete core.action_registry.map.CloseTestLeg;
});
const webClient = await createWebClient({ testConfig, legacyParams });
const webClient = await createWebClient({ legacyParams });
await doAction(webClient, "NotifyTestLeg");
await nextTick();
assert.containsOnce(document.body, ".o_notification");
@@ -5,7 +5,7 @@ var AbstractView = require('web.AbstractView');
var ajax = require('web.ajax');
var testUtils = require('web.test_utils');
const { createWebClient, doAction, getActionManagerTestConfig } = require('@web/../tests/webclient/actions/helpers');
const { createWebClient, doAction } = require('@web/../tests/webclient/helpers');
var createView = testUtils.createView;
QUnit.module('Views', {
@@ -113,10 +113,9 @@ QUnit.module('Views', {
QUnit.test('group_by from context can be a string, instead of a list of strings', async function (assert) {
assert.expect(1);
const testConfig = getActionManagerTestConfig();
Object.assign(testConfig.serverData, {
const serverData = {
actions: {
1:{
1: {
id: 1,
name: 'Foo',
res_model: 'foo',
@@ -132,14 +131,14 @@ QUnit.module('Views', {
'foo,false,search': '<search></search>',
},
models: this.data
});
};
const mockRPC = (route, args) => {
if (args.method === 'web_read_group') {
assert.deepEqual(args.kwargs.groupby, ['bar']);
}
};
const webClient = await createWebClient({testConfig, mockRPC});
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 1);
});
@@ -10,15 +10,14 @@ const fieldRegistry = require('web.field_registry');
var ViewDialogs = require('web.view_dialogs');
var fieldUtils = require('web.field_utils');
var mixins = require('web.mixins');
var RamStorage = require('web.RamStorage');
var testUtils = require('web.test_utils');
var session = require('web.session');
const Widget = require('web.Widget');
const { patchWithCleanup } = require("@web/../tests/helpers/utils");
const { createWebClient, getActionManagerTestConfig, doAction } = require('@web/../tests/webclient/actions/helpers');
let testConfig;
const { createWebClient, doAction } = require('@web/../tests/webclient/helpers');
let serverData;
CalendarRenderer.include({
getAvatars: function () {
@@ -130,11 +129,10 @@ QUnit.module('Views', {
]
},
};
testConfig = getActionManagerTestConfig();
serverData = { models: this.data };
this.data.event.methods = {
check_access_rights: this.data.event.check_access_rights,
}
Object.assign(testConfig.serverData, {models: this.data});
},
afterEach: function () {
window.removeEventListener('scroll', _preventScroll, true);
@@ -306,23 +304,25 @@ QUnit.module('Views', {
QUnit.test('breadcrumbs are updated with the displayed period', async function (assert) {
assert.expect(4);
testConfig.serverData.views = {
serverData.views = {
'event,1,calendar': '<calendar date_start="start" date_stop="stop" all_day="allday"/>',
'event,false,search': '<search></search>',
};
testConfig.serverData.actions[1] = {
id: 1,
flags: {
initialDate: initialDate,
serverData.actions = {
1: {
id: 1,
flags: {
initialDate: initialDate,
},
name: 'Meetings Test',
res_model: 'event',
type: 'ir.actions.act_window',
views: [[1, 'calendar']],
},
name: 'Meetings Test',
res_model: 'event',
type: 'ir.actions.act_window',
views: [[1, 'calendar']],
};
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
// displays month mode by default
@@ -2868,7 +2868,7 @@ QUnit.module('Views', {
QUnit.test('calendar is configured to have no groupBy menu', async function (assert) {
assert.expect(1);
testConfig.serverData.views = {
serverData.views = {
'event,1,calendar': '<calendar class="o_calendar_test" '+
'date_start="start" '+
'date_stop="stop" '+
@@ -2876,15 +2876,17 @@ QUnit.module('Views', {
'event,false,search': '<search></search>',
};
testConfig.serverData.actions[1] = {
id: 1,
name: 'some action',
res_model: 'event',
type: 'ir.actions.act_window',
views: [[1, 'calendar']]
serverData.actions = {
1: {
id: 1,
name: 'some action',
res_model: 'event',
type: 'ir.actions.act_window',
views: [[1, 'calendar']]
},
};
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
assert.containsNone($(webClient.el).find('.o_control_panel .o_search_options span.fa.fa-bars'),
@@ -3368,21 +3370,23 @@ QUnit.module('Views', {
QUnit.test('initial_date given in the context', async function (assert) {
assert.expect(1);
testConfig.serverData.views = {
serverData.views = {
'event,1,calendar': '<calendar date_start="start" date_stop="stop" mode="day"/>',
'event,false,search': '<search></search>',
};
testConfig.serverData.actions[1] = {
id: 1,
name: 'context initial date',
res_model: 'event',
type: 'ir.actions.act_window',
views: [[1, 'calendar']],
context: {initial_date: initialDate}
serverData.actions = {
1: {
id: 1,
name: 'context initial date',
res_model: 'event',
type: 'ir.actions.act_window',
views: [[1, 'calendar']],
context: {initial_date: initialDate}
},
};
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
await testUtils.nextTick();
assert.strictEqual($('.o_control_panel .breadcrumb-item').text(),
@@ -24,9 +24,9 @@ const cpHelpers = testUtils.controlPanel;
var createView = testUtils.createView;
const { legacyExtraNextTick, patchWithCleanup } = require("@web/../tests/helpers/utils");
const { createWebClient, doAction, getActionManagerTestConfig } = require('@web/../tests/webclient/actions/helpers');
const { createWebClient, doAction } = require('@web/../tests/webclient/helpers');
let testConfig;
let serverData;
QUnit.module('Views', {
beforeEach: function () {
this.data = {
@@ -155,14 +155,15 @@ QUnit.module('Views', {
views: [[false, 'kanban'], [false, 'form']],
}];
testConfig = getActionManagerTestConfig();
// map legacy test data
const actions = {};
this.actions.forEach((act) => {
actions[act.xmlId || act.id] = act;
});
Object.assign(testConfig.serverData, {actions, models: this.data});
serverData = {
actions,
models: this.data,
};
},
}, function () {
@@ -503,11 +504,11 @@ QUnit.module('Views', {
QUnit.test('Form and subview with _view_ref contexts', async function (assert) {
assert.expect(3);
testConfig.serverData.models.product.fields.partner_type_ids = {string: "one2many field", type: "one2many", relation: "partner_type"},
testConfig.serverData.models.product.records = [{id: 1, name: 'Tromblon', partner_type_ids: [12,14]}];
testConfig.serverData.models.partner.records[0].product_id = 1;
serverData.models.product.fields.partner_type_ids = {string: "one2many field", type: "one2many", relation: "partner_type"},
serverData.models.product.records = [{id: 1, name: 'Tromblon', partner_type_ids: [12,14]}];
serverData.models.partner.records[0].product_id = 1;
testConfig.serverData.views = {
serverData.views = {
'product,false,form': '<form>'+
'<field name="name"/>'+
'<field name="partner_type_ids" context="{\'tree_view_ref\': \'some_other_tree_view\'}"/>' +
@@ -551,7 +552,7 @@ QUnit.module('Views', {
}
};
const webClient = await createWebClient({testConfig, mockRPC});
const webClient = await createWebClient({serverData, mockRPC});
await doAction(webClient, {
res_id: 1,
type: 'ir.actions.act_window',
@@ -6816,7 +6817,7 @@ QUnit.module('Views', {
QUnit.test('translation alerts preserved on reverse breadcrumb', async function (assert) {
assert.expect(2);
testConfig.serverData.models['ir.translation'] = {
serverData.models['ir.translation'] = {
fields: {
name: { string: "name", type: "char" },
source: {string: "Source", type: "char"},
@@ -6825,9 +6826,9 @@ QUnit.module('Views', {
records: [],
};
testConfig.serverData.models.partner.fields.foo.translate = true;
serverData.models.partner.fields.foo.translate = true;
testConfig.serverData.views = {
serverData.views = {
'partner,false,form': '<form string="Partners">' +
'<sheet>' +
'<field name="foo"/>' +
@@ -6842,7 +6843,7 @@ QUnit.module('Views', {
'ir.translation,false,search': '<search></search>',
};
testConfig.serverData.actions = {
serverData.actions = {
1: {
id: 1,
name: 'Partner',
@@ -6861,7 +6862,7 @@ QUnit.module('Views', {
}
};
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
patchWithCleanup(_t.database, {
multi_lang: true,
});
@@ -8813,7 +8814,7 @@ QUnit.module('Views', {
QUnit.test('discard after a failed save', async function (assert) {
assert.expect(2);
testConfig.serverData.views = {
serverData.views = {
'partner,false,form': '<form>' +
'<field name="date" required="true"/>' +
'<field name="foo" required="true"/>' +
@@ -8823,7 +8824,7 @@ QUnit.module('Views', {
'partner,false,search': '<search></search>',
};
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
await testUtils.dom.click('.o_control_panel .o-kanban-button-new');
@@ -9716,7 +9717,7 @@ QUnit.module('Views', {
QUnit.test('Auto save: save when page changed', async function (assert) {
assert.expect(10);
testConfig.serverData.actions[1] = {
serverData.actions[1] = {
id: 1,
name: 'Partner',
res_model: 'partner',
@@ -9724,7 +9725,7 @@ QUnit.module('Views', {
views: [[false, 'list'], [false, 'form']],
};
testConfig.serverData.views = {
serverData.views = {
'partner,false,list': `
<tree>
<field name="name"/>
@@ -9749,7 +9750,7 @@ QUnit.module('Views', {
}
};
const webClient = await createWebClient({ testConfig , mockRPC });
const webClient = await createWebClient({ serverData , mockRPC });
await doAction(webClient, 1);
@@ -9780,7 +9781,7 @@ QUnit.module('Views', {
QUnit.test('Auto save: save when breadcrumb clicked', async function (assert) {
assert.expect(7);
testConfig.serverData.actions[1] = {
serverData.actions[1] = {
id: 1,
name: 'Partner',
res_model: 'partner',
@@ -9788,7 +9789,7 @@ QUnit.module('Views', {
views: [[false, 'list'], [false, 'form']],
};
testConfig.serverData.views = {
serverData.views = {
'partner,false,list': `
<tree>
<field name="name"/>
@@ -9813,7 +9814,7 @@ QUnit.module('Views', {
}
};
const webClient = await createWebClient({ testConfig , mockRPC });
const webClient = await createWebClient({ serverData , mockRPC });
await doAction(webClient, 1);
@@ -9840,7 +9841,7 @@ QUnit.module('Views', {
QUnit.test('Auto save: save when action changed', async function (assert) {
assert.expect(6);
testConfig.serverData.actions[1] = {
serverData.actions[1] = {
id: 1,
name: 'Partner',
res_model: 'partner',
@@ -9848,7 +9849,7 @@ QUnit.module('Views', {
views: [[false, 'list'], [false, 'form']],
};
testConfig.serverData.actions[2] = {
serverData.actions[2] = {
id: 2,
name: 'Other action',
res_model: 'partner',
@@ -9856,7 +9857,7 @@ QUnit.module('Views', {
views: [[false, 'kanban']],
};
testConfig.serverData.views = {
serverData.views = {
'partner,false,list': `
<tree>
<field name="name"/>
@@ -9891,7 +9892,7 @@ QUnit.module('Views', {
}
};
const webClient = await createWebClient({ testConfig , mockRPC });
const webClient = await createWebClient({ serverData , mockRPC });
await doAction(webClient, 1);
@@ -10017,7 +10018,7 @@ QUnit.module('Views', {
QUnit.test('Auto save: save on closing tab/browser (detached form)', async function (assert) {
assert.expect(3);
testConfig.serverData.actions[1] = {
serverData.actions[1] = {
id: 1,
name: 'Partner',
res_model: 'partner',
@@ -10025,7 +10026,7 @@ QUnit.module('Views', {
views: [[false, 'list'], [false, 'form']],
};
testConfig.serverData.views = {
serverData.views = {
'partner,false,list': `
<tree>
<field name="display_name"/>
@@ -10047,7 +10048,7 @@ QUnit.module('Views', {
}
};
const webClient = await createWebClient({ testConfig , mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 1);
@@ -7,7 +7,7 @@ const testUtils = require('web.test_utils');
const { sortBy } = require('web.utils');
const { legacyExtraNextTick } = require("@web/../tests/helpers/utils");
const { createWebClient, doAction, getActionManagerTestConfig } = require('@web/../tests/webclient/actions/helpers');
const { createWebClient, doAction } = require('@web/../tests/webclient/helpers');
const { createView } = testUtils;
const cpHelpers = testUtils.controlPanel;
@@ -75,7 +75,7 @@ function checkLegend(assert, graph, expectedLegendLabels) {
assert.deepEqual(actualLegendLabels, expectedLegendLabels);
}
let testConfig;
let serverData;
QUnit.module('Views', {
beforeEach: function () {
this.data = {
@@ -125,8 +125,7 @@ QUnit.module('Views', {
},
};
testConfig = getActionManagerTestConfig();
Object.assign(testConfig.serverData, {models: this.data});
serverData = { models: this.data };
}
}, function () {
@@ -793,7 +792,7 @@ QUnit.module('Views', {
QUnit.test('measure dropdown consistency', async function (assert) {
assert.expect(2);
testConfig.serverData.views = {
serverData.views = {
'foo,false,graph': `
<graph string="Partners" type="bar">
<field name="foo" type="measure"/>
@@ -809,7 +808,7 @@ QUnit.module('Views', {
</kanban>`,
};
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, {
res_model: 'foo',
@@ -27,9 +27,9 @@ const cpHelpers = testUtils.controlPanel;
var createView = testUtils.createView;
const { legacyExtraNextTick } = require("@web/../tests/helpers/utils");
const { createWebClient, doAction, getActionManagerTestConfig, loadState } = require('@web/../tests/webclient/actions/helpers');
const { createWebClient, doAction, loadState } = require('@web/../tests/webclient/helpers');
let testConfig;
let serverData;
QUnit.module('Views', {
beforeEach: function () {
@@ -133,8 +133,7 @@ QUnit.module('Views', {
},
};
testConfig = getActionManagerTestConfig();
Object.assign(testConfig.serverData, {models: this.data});
serverData = { models: this.data };
}
}, function () {
@@ -1772,17 +1771,19 @@ QUnit.module('Views', {
QUnit.test('editable list view: check that controlpanel buttons are updating when groupby applied', async function (assert) {
assert.expect(4);
testConfig.serverData.models.foo.fields.foo = {string: "Foo", type: "char", required:true};
serverData.models.foo.fields.foo = {string: "Foo", type: "char", required:true};
testConfig.serverData.actions[11] = {
id: 11,
name: 'Partners Action 11',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[3, 'list']],
search_view_id: [9, 'search'],
serverData.actions = {
11: {
id: 11,
name: 'Partners Action 11',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[3, 'list']],
search_view_id: [9, 'search'],
},
};
testConfig.serverData.views = {
serverData.views = {
'foo,3,list': '<tree editable="top"><field name="display_name"/><field name="foo"/></tree>',
'foo,9,search': '<search>'+
@@ -1790,7 +1791,7 @@ QUnit.module('Views', {
'</search>',
};
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 11);
await testUtils.dom.click($(webClient.el).find('.o_list_button_add'));
@@ -9484,19 +9485,21 @@ QUnit.module('Views', {
QUnit.test('add filter in a grouped list with a pager', async function (assert) {
assert.expect(11);
testConfig.serverData.actions[11] = {
id: 11,
name: 'Action 11',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[3, 'list']],
search_view_id: [9, 'search'],
flags: {
context: { group_by: ['int_field'] },
serverData.actions = {
11: {
id: 11,
name: 'Action 11',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[3, 'list']],
search_view_id: [9, 'search'],
flags: {
context: { group_by: ['int_field'] },
},
},
};
testConfig.serverData.views = {
serverData.views = {
'foo,3,list': '<tree groups_limit="3"><field name="foo"/></tree>',
'foo,9,search': `
<search>
@@ -9510,7 +9513,7 @@ QUnit.module('Views', {
}
};
const webClient = await createWebClient({testConfig, mockRPC});
const webClient = await createWebClient({serverData, mockRPC});
await doAction(webClient, 11);
assert.containsOnce(webClient, '.o_list_view');
@@ -11055,22 +11058,24 @@ QUnit.module('Views', {
QUnit.test('change the viewType of the current action', async function (assert) {
assert.expect(25);
testConfig.serverData.actions[1] = {
id: 1,
name: 'Partners Action 1',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[1, 'kanban']],
};
testConfig.serverData.actions[2] = {
id: 2,
name: 'Partners',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[false, 'list'], [1, 'kanban']],
serverData.actions = {
1: {
id: 1,
name: 'Partners Action 1',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[1, 'kanban']],
},
2: {
id: 2,
name: 'Partners',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[false, 'list'], [1, 'kanban']],
},
};
testConfig.serverData.views = {
serverData.views = {
'foo,1,kanban': '<kanban><templates><t t-name="kanban-box">' +
'<div class="oe_kanban_global_click"><field name="foo"/></div>' +
'</t></templates></kanban>',
@@ -11083,7 +11088,7 @@ QUnit.module('Views', {
'foo,false,search': '<search><field name="foo" string="Foo"/></search>',
};
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 2);
@@ -11630,28 +11635,30 @@ QUnit.module('Views', {
QUnit.test("Auto save: add a record and leave action", async function (assert) {
assert.expect(4);
testConfig.serverData.actions[1] = {
id: 1,
name: 'Action 1',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[2, 'list']],
search_view_id: [1, 'search'],
serverData.actions = {
1: {
id: 1,
name: 'Action 1',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[2, 'list']],
search_view_id: [1, 'search'],
},
2: {
id: 2,
name: 'Action 2',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[3, 'list']],
search_view_id: [1, 'search'],
},
};
testConfig.serverData.actions[2] = {
id: 2,
name: 'Action 2',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[3, 'list']],
search_view_id: [1, 'search'],
};
testConfig.serverData.views = {
serverData.views = {
'foo,1,search': '<search></search>',
'foo,2,list': '<tree editable="top"><field name="foo"/></tree>',
'foo,3,list': '<tree editable="top"><field name="foo"/></tree>',
};
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
@@ -11672,28 +11679,30 @@ QUnit.module('Views', {
QUnit.test("Auto save: modify a record and leave action", async function (assert) {
assert.expect(2);
testConfig.serverData.actions[1] = {
id: 1,
name: 'Action 1',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[2, 'list']],
search_view_id: [1, 'search'],
serverData.actions = {
1: {
id: 1,
name: 'Action 1',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[2, 'list']],
search_view_id: [1, 'search'],
},
2: {
id: 2,
name: 'Action 2',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[3, 'list']],
search_view_id: [1, 'search'],
},
};
testConfig.serverData.actions[2] = {
id: 2,
name: 'Action 2',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[3, 'list']],
search_view_id: [1, 'search'],
};
testConfig.serverData.views = {
serverData.views = {
'foo,1,search': '<search></search>',
'foo,2,list': '<tree editable="top"><field name="foo"/></tree>',
'foo,3,list': '<tree editable="top"><field name="foo"/></tree>',
};
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
@@ -11712,37 +11721,39 @@ QUnit.module('Views', {
QUnit.test("Auto save: modify a record and leave action (reject)", async function (assert) {
assert.expect(5);
testConfig.serverData.actions[1] = {
id: 1,
name: 'Action 1',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[2, 'list']],
search_view_id: [1, 'search'],
serverData.actions = {
1: {
id: 1,
name: 'Action 1',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[2, 'list']],
search_view_id: [1, 'search'],
},
2: {
id: 2,
name: 'Action 2',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[3, 'list']],
search_view_id: [1, 'search'],
},
};
testConfig.serverData.actions[2] = {
id: 2,
name: 'Action 2',
res_model: 'foo',
type: 'ir.actions.act_window',
views: [[3, 'list']],
search_view_id: [1, 'search'],
};
testConfig.serverData.views = {
serverData.views = {
'foo,1,search': '<search></search>',
'foo,2,list': '<tree editable="top"><field name="foo" required="1"/></tree>',
'foo,3,list': '<tree editable="top"><field name="foo"/></tree>',
};
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient,1);
await doAction(webClient, 1);
assert.strictEqual($(webClient.el).find('.o_field_cell[name="foo"]').text(), "yopblipgnapblip");
await testUtils.dom.click($(webClient.el).find('.o_field_cell[name="foo"]:first'));
await testUtils.fields.editInput($(webClient.el).find('.o_field_widget[name="foo"]'), "");
await assert.rejects(doAction(webClient,2));
await assert.rejects(doAction(webClient, 2));
assert.strictEqual($(webClient.el).find('.o_field_cell[name="foo"]').text(), "blipgnapblip");
assert.hasClass($(webClient.el).find('.o_field_widget[name="foo"]:first'), 'o_field_invalid');
@@ -11753,7 +11764,6 @@ QUnit.module('Views', {
assert.expect(3);
const list = await createView({
debug: true,
View: ListView,
model: 'foo',
data: this.data,
@@ -7,7 +7,7 @@ const PivotController = require("web.PivotController");
var testUtils = require('web.test_utils');
var testUtilsDom = require('web.test_utils_dom');
const { createWebClient, doAction, getActionManagerTestConfig } = require('@web/../tests/webclient/actions/helpers');
const { createWebClient, doAction } = require('@web/../tests/webclient/helpers');
var _t = core._t;
const cpHelpers = testUtils.controlPanel;
@@ -27,7 +27,7 @@ var getCurrentValues = function (pivot) {
};
let testConfig;
let serverData;
QUnit.module('Views', {
beforeEach: function () {
@@ -114,8 +114,7 @@ QUnit.module('Views', {
},
};
testConfig = getActionManagerTestConfig();
Object.assign(testConfig.serverData, {models: this.data});
serverData = { models: this.data };
},
}, function () {
QUnit.module('PivotView');
@@ -2723,8 +2722,8 @@ QUnit.module('Views', {
QUnit.test('Navigation list view for a group and back with breadcrumbs', async function (assert) {
assert.expect(16);
// create a webClient to test the interactions with the search view
testConfig.serverData.views = {
serverData.views = {
'partner,false,pivot': '<pivot>' +
'<field name="customer" type="row"/>' +
'</pivot>',
@@ -2754,7 +2753,7 @@ QUnit.module('Views', {
}
};
const webClient = await createWebClient({testConfig, mockRPC});
const webClient = await createWebClient({serverData, mockRPC});
await doAction(webClient, {
res_model: 'partner',
@@ -2,8 +2,7 @@ odoo.define('web.qweb_view_tests', function (require) {
"use strict";
const utils = require('web.test_utils');
const { legacyExtraNextTick } = require("@web/../tests/helpers/utils");
const { createWebClient, doAction, getActionManagerTestConfig } = require('@web/../tests/webclient/actions/helpers');
const { createWebClient, doAction } = require('@web/../tests/webclient/helpers');
QUnit.module("Views", {
@@ -11,17 +10,18 @@ QUnit.module("Views", {
QUnit.module("QWeb");
QUnit.test("basic", async function (assert) {
assert.expect(14);
const testConfig = getActionManagerTestConfig();
testConfig.serverData.models = {
test: {
fields: {},
records: [],
}
};
testConfig.serverData.views = {
'test,5,qweb': '<div id="xxx"><t t-esc="ok"/></div>',
'test,false,search': '<search/>'
const serverData = {
models: {
test: {
fields: {},
records: [],
}
},
views: {
'test,5,qweb': '<div id="xxx"><t t-esc="ok"/></div>',
'test,false,search': '<search/>'
},
};
const mockRPC = (route, args) => {
@@ -46,7 +46,7 @@ QUnit.module("Views", {
}
};
const webClient = await createWebClient({testConfig, mockRPC});
const webClient = await createWebClient({serverData, mockRPC});
let resolved = false;
const doActionProm = doAction(webClient, {
@@ -64,7 +64,7 @@ QUnit.module("Views", {
await utils.dom.click(content.querySelector('[type=toggle]'));
assert.equal(content.querySelector('div#sub').textContent, 'ok', 'should have unfolded the sub-item');
await utils.dom.click(content.querySelector('[type=toggle]'));
assert.containsNone(content, "div#sub")
assert.containsNone(content, "div#sub");
await utils.dom.click(content.querySelector('[type=toggle]'));
assert.verifySteps(['fetch', 'unfold', 'unfold']);
@@ -10,7 +10,7 @@ const SearchPanel = require("web.searchPanel");
const cpHelpers = testUtils.controlPanel;
const createView = testUtils.createView;
const { createWebClient, doAction, getActionManagerTestConfig, loadState } = require('@web/../tests/webclient/actions/helpers');
const { createWebClient, doAction } = require('@web/../tests/webclient/helpers');
const { legacyExtraNextTick } = require("@web/../tests/helpers/utils");
/**
@@ -38,7 +38,7 @@ function toggleFold(widget, text) {
return testUtils.dom.click(target);
}
let testConfig;
let serverData;
QUnit.module('Views', {
beforeEach: function () {
@@ -121,14 +121,16 @@ QUnit.module('Views', {
</search>`,
};
testConfig = getActionManagerTestConfig();
// map legacy test data
const actions = {};
this.actions.forEach((act) => {
actions[act.xmlId || act.id] = act;
});
Object.assign(testConfig.serverData, {actions, models: this.data, views: this.archs});
serverData = {
actions,
models: this.data,
views: this.archs,
};
},
}, function () {
@@ -2333,7 +2335,7 @@ QUnit.module('Views', {
QUnit.test('search panel is available on list and kanban by default', async function (assert) {
assert.expect(8);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
@@ -2359,7 +2361,7 @@ QUnit.module('Views', {
QUnit.test('search panel with view_types attribute', async function (assert) {
assert.expect(6);
testConfig.serverData.views['partner,false,search'] =
serverData.views['partner,false,search'] =
`<search>
<searchpanel view_types="kanban,pivot">
<field name="company_id" enable_counters="1"/>
@@ -2368,7 +2370,7 @@ QUnit.module('Views', {
</search>`;
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
assert.containsOnce(webClient, '.o_content.o_controller_with_searchpanel .o_kanban_view');
@@ -2394,7 +2396,7 @@ QUnit.module('Views', {
}
};
const webClient = await createWebClient({ testConfig , mockRPC });
const webClient = await createWebClient({ serverData , mockRPC });
await doAction(webClient, 1);
@@ -2441,7 +2443,7 @@ QUnit.module('Views', {
}
};
const webClient = await createWebClient({ testConfig , mockRPC });
const webClient = await createWebClient({ serverData , mockRPC });
await doAction(webClient, 1);
assert.containsNone(webClient, '.o_search_panel_filter_value input:checked');
@@ -2487,7 +2489,7 @@ QUnit.module('Views', {
QUnit.test('search panel filters are kept when switching to a view with no search panel', async function (assert) {
assert.expect(13);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
assert.containsOnce(webClient, '.o_content.o_controller_with_searchpanel .o_kanban_view');
@@ -2520,7 +2522,7 @@ QUnit.module('Views', {
QUnit.test('after onExecuteAction, selects "All" as default category value', async function (assert) {
assert.expect(4);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 2);
await testUtils.dom.click($(webClient.el).find('.o_form_view button:contains("multi view")'));
@@ -2536,8 +2538,8 @@ QUnit.module('Views', {
QUnit.test('search panel is not instantiated if stated in context', async function (assert) {
assert.expect(2);
testConfig.serverData.actions[2].context = {search_panel: false};
const webClient = await createWebClient({ testConfig });
serverData.actions[2].context = {search_panel: false};
const webClient = await createWebClient({ serverData });
await doAction(webClient, 2);
await testUtils.dom.click($(webClient.el).find('.o_form_view button:contains("multi view")'));
@@ -2556,7 +2558,7 @@ QUnit.module('Views', {
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 1);
await cpHelpers.switchView(webClient, 'list');
@@ -2577,10 +2579,10 @@ QUnit.module('Views', {
SearchPanel.scrollDebounce = 0;
for (var i = 10; i < 20; i++) {
testConfig.serverData.models.category.records.push({id: i, name: "Cat " + i});
serverData.models.category.records.push({id: i, name: "Cat " + i});
}
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
webClient.el.querySelector('.o_action_manager').style.maxHeight = "300px";
await doAction(webClient, 1);
@@ -3,7 +3,7 @@ odoo.define('web.domain_selector_tests', function (require) {
var DomainSelector = require("web.DomainSelector");
var testUtils = require("web.test_utils");
const { createWebClient, doAction, getActionManagerTestConfig } = require('@web/../tests/webclient/actions/helpers');
const { createWebClient, doAction } = require('@web/../tests/webclient/helpers');
QUnit.module('widgets', {}, function () {
@@ -248,26 +248,29 @@ QUnit.module('DomainSelector', {
QUnit.test("inline domain editor in modal", async function (assert) {
assert.expect(1);
const testConfig = getActionManagerTestConfig();
testConfig.serverData.actions[5] = {
id: 5,
name: "Partner Form",
res_model: "partner",
target: "new",
type: "ir.actions.act_window",
views: [["view_ref", "form"]],
const serverData = {
actions: {
5: {
id: 5,
name: "Partner Form",
res_model: "partner",
target: "new",
type: "ir.actions.act_window",
views: [["view_ref", "form"]],
},
},
models: this.data,
views: {
"partner,view_ref,form": `
<form>
<field name="foo" string="Domain" widget="domain" options="{'model': 'partner'}"/>
</form>
`,
},
};
testConfig.serverData.views = {
"partner,view_ref,form": `
<form>
<field name="foo" string="Domain" widget="domain" options="{'model': 'partner'}"/>
</form>
`,
};
const webClient = await createWebClient({testConfig});
const webClient = await createWebClient({ serverData });
await doAction(webClient, 5);
assert.strictEqual(document.querySelector('div[name="foo"]').closest('.modal-body').style.overflow,
'visible', "modal should have visible overflow if there is inline domain field widget");
+52 -12
View File
@@ -2,7 +2,7 @@
import core from "web.core";
import session from "web.session";
import { browser } from "@web/core/browser/browser";
import { browser, makeRAMLocalStorage } from "@web/core/browser/browser";
import { patchWithCleanup } from "@web/../tests/helpers/utils";
import { legacyProm } from "web.test_legacy";
import { registerCleanup } from "./helpers/cleanup";
@@ -24,21 +24,61 @@ function forceLocaleAndTimezoneWithCleanup() {
});
}
function patchBrowserWithCleanup() {
// patch addEventListner to automatically remove listeners bound (via browser.addEventListener)
// during a test (e.g. during the deployment of a service)
const originalAddEventListener = browser.addEventListener;
const originalRemoveEventListener = browser.removeEventListener;
patchWithCleanup(browser, {
addEventListener() {
originalAddEventListener(...arguments);
registerCleanup(() => {
originalRemoveEventListener(...arguments);
});
function makeMockLocation() {
const locationLink = Object.assign(document.createElement("a"), {
href: window.location.origin + window.location.pathname,
assign(url) {
this.href = url;
},
reload() {},
});
return new Proxy(locationLink, {
get(target, p) {
return target[p];
},
set(target, p, value) {
target[p] = value;
if (p === "hash") {
window.dispatchEvent(new HashChangeEvent("hashchange"));
}
return true;
},
});
}
function patchBrowserWithCleanup() {
const originalAddEventListener = browser.addEventListener;
const originalRemoveEventListener = browser.removeEventListener;
const mockLocation = makeMockLocation();
patchWithCleanup(
browser,
{
// patch addEventListner to automatically remove listeners bound (via
// browser.addEventListener) during a test (e.g. during the deployment of a service)
addEventListener() {
originalAddEventListener(...arguments);
registerCleanup(() => {
originalRemoveEventListener(...arguments);
});
},
// in tests, we never want to interact with the real url or reload the page
location: mockLocation,
history: {
pushState(state, title, url) {
mockLocation.assign(url);
},
replaceState(state, title, url) {
mockLocation.assign(url);
},
},
// in tests, we never want to interact with the real local/session storages.
localStorage: makeRAMLocalStorage(),
sessionStorage: makeRAMLocalStorage(),
},
{ pure: true }
);
}
function patchLegacyCoreBus() {
// patch core.bus.on to automatically remove listners bound on the legacy bus
// during a test (e.g. during the deployment of a service)
@@ -1,5 +1,6 @@
/** @odoo-module **/
import { browser } from "@web/core/browser/browser";
import { registry } from "@web/core/registry";
import { NotificationContainer } from "@web/core/notifications/notification_container";
import core from "web.core";
@@ -7,27 +8,25 @@ import AbstractAction from "web.AbstractAction";
import testUtils from "web.test_utils";
import { registerCleanup } from "../../helpers/cleanup";
import { clearRegistryWithCleanup } from "../../helpers/mock_env";
import { makeFakeRouterService } from "../../helpers/mock_services";
import { click, legacyExtraNextTick } from "../../helpers/utils";
import { createWebClient, doAction, getActionManagerTestConfig } from "./helpers";
import { click, legacyExtraNextTick, patchWithCleanup } from "../../helpers/utils";
import { createWebClient, doAction, getActionManagerServerData } from "./../helpers";
const { Component, tags } = owl;
let testConfig;
let serverData;
const mainComponentRegistry = registry.category("main_components");
const serviceRegistry = registry.category("services");
const actionRegistry = registry.category("actions");
QUnit.module("ActionManager", (hooks) => {
hooks.beforeEach(() => {
testConfig = getActionManagerTestConfig();
serverData = getActionManagerServerData();
});
QUnit.module("Client Actions");
QUnit.test("can display client actions in Dialog", async function (assert) {
assert.expect(2);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, {
name: "Dialog Test",
target: "new",
@@ -40,7 +39,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("can display client actions as main, then in Dialog", async function (assert) {
assert.expect(3);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, "__test__client__action__");
assert.containsOnce(webClient, ".o_action_manager .test_client_action");
await doAction(webClient, {
@@ -56,7 +55,7 @@ QUnit.module("ActionManager", (hooks) => {
"can display client actions in Dialog, then as main destroys Dialog",
async function (assert) {
assert.expect(4);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, {
target: "new",
tag: "__test__client__action__",
@@ -84,7 +83,7 @@ QUnit.module("ActionManager", (hooks) => {
};
core.action_registry.add("HelloWorldTestLeg", ClientAction);
registerCleanup(() => delete core.action_registry.map.HelloWorldTestLeg);
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, "HelloWorldTestLeg");
assert.containsNone(
document.body,
@@ -108,7 +107,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async function (route, args) {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, "HelloWorldTest");
assert.containsNone(
document.body,
@@ -137,7 +136,7 @@ QUnit.module("ActionManager", (hooks) => {
});
core.action_registry.add("HelloWorldTest", ClientAction);
registerCleanup(() => delete core.action_registry.map.HelloWorldTest);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, "HelloWorldTest");
assert.strictEqual(
$(".o_control_panel:visible").length,
@@ -172,19 +171,19 @@ QUnit.module("ActionManager", (hooks) => {
return { foo: "baz" };
},
});
serviceRegistry.add(
"router",
makeFakeRouterService({
onPushState() {
const pushState = browser.history.pushState;
patchWithCleanup(browser, {
history: Object.assign({}, browser.history, {
pushState() {
pushState(...arguments);
assert.step("push_state");
},
}),
{ force: true }
);
});
core.action_registry.add("HelloWorldTest", ClientAction);
registerCleanup(() => delete core.action_registry.map.HelloWorldTest);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
let currentTitle = webClient.env.services.title.current;
assert.strictEqual(currentTitle, '{"zopenerp":"Odoo"}');
let currentHash = webClient.env.services.router.current.hash;
@@ -214,7 +213,7 @@ QUnit.module("ActionManager", (hooks) => {
});
core.action_registry.add("HelloWorldTest", ClientAction);
registerCleanup(() => delete core.action_registry.map.HelloWorldTest);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, "HelloWorldTest");
assert.containsOnce(
webClient.el,
@@ -241,7 +240,7 @@ QUnit.module("ActionManager", (hooks) => {
});
core.action_registry.add("HelloWorldTest", ClientAction);
registerCleanup(() => delete core.action_registry.map.HelloWorldTest);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, "HelloWorldTest");
assert.strictEqual(
$("ol.breadcrumb").text(),
@@ -283,7 +282,7 @@ QUnit.module("ActionManager", (hooks) => {
});
core.action_registry.add("ClientAction", ClientAction);
core.action_registry.add("ClientAction2", ClientAction2);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, "ClientAction");
assert.containsOnce(webClient.el, ".breadcrumb-item");
assert.strictEqual(
@@ -319,7 +318,7 @@ QUnit.module("ActionManager", (hooks) => {
}
ClientAction.template = tags.xml`<div class="my_owl_action" t-on-click="onClick">owl client action</div>`;
actionRegistry.add("OwlClientAction", ClientAction);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 8);
await doAction(webClient, "OwlClientAction");
assert.containsOnce(webClient.el, ".my_owl_action");
@@ -337,7 +336,7 @@ QUnit.module("ActionManager", (hooks) => {
mainComponentRegistry.add("NotificationContainer", {
Component: NotificationContainer,
});
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
assert.containsOnce(webClient, ".o_kanban_view");
await doAction(webClient, {
@@ -380,9 +379,9 @@ QUnit.module("ActionManager", (hooks) => {
mainComponentRegistry.add("NotificationContainer", {
Component: NotificationContainer,
});
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
const options = {
onClose: function (infos) {
onClose: function () {
assert.step("onClose");
},
};
@@ -408,7 +407,6 @@ QUnit.module("ActionManager", (hooks) => {
notificationSelector,
"a notification should be present"
);
const notificationElement = document.body.querySelector(notificationSelector);
assert.verifySteps(["onClose"]);
});
});
@@ -2,20 +2,20 @@
import testUtils from "web.test_utils";
import { legacyExtraNextTick, nextTick } from "../../helpers/utils";
import { createWebClient, doAction, getActionManagerTestConfig } from "./helpers";
import { createWebClient, doAction, getActionManagerServerData } from "./../helpers";
let testConfig;
let serverData;
QUnit.module("ActionManager", (hooks) => {
hooks.beforeEach(() => {
testConfig = getActionManagerTestConfig();
serverData = getActionManagerServerData();
});
QUnit.module('"ir.actions.act_window_close" actions');
QUnit.test("close the currently opened dialog", async function (assert) {
assert.expect(2);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
// execute an action in target="new"
await doAction(webClient, 5);
assert.containsOnce(
@@ -32,7 +32,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test('execute "on_close" only if there is no dialog to close', async function (assert) {
assert.expect(3);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
// execute an action in target="new"
await doAction(webClient, 5);
function onClose() {
@@ -51,7 +51,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("close action with provided infos", async function (assert) {
assert.expect(1);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
const options = {
onClose: function (infos) {
assert.strictEqual(
@@ -73,7 +73,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("history back calls on_close handler of dialog action", async function (assert) {
assert.expect(4);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
function onClose() {
assert.step("on_close");
}
@@ -91,7 +91,7 @@ QUnit.module("ActionManager", (hooks) => {
"history back calls on_close handler of dialog action with 2 breadcrumbs",
async function (assert) {
assert.expect(7);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1); // kanban
await doAction(webClient, 3); // list
assert.containsOnce(webClient.el, ".o_list_view");
@@ -120,7 +120,7 @@ QUnit.module("ActionManager", (hooks) => {
return readOnFirstRecordDef;
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
// open first record in form view. this will crash and will not
// display a form view
@@ -3,12 +3,12 @@
import { registry } from "@web/core/registry";
import testUtils from "web.test_utils";
import { legacyExtraNextTick, nextTick } from "../../helpers/utils";
import { createWebClient, doAction, getActionManagerTestConfig } from "./helpers";
import { createWebClient, doAction, getActionManagerServerData } from "./../helpers";
const { Component, tags } = owl;
const actionRegistry = registry.category("actions");
let testConfig;
let serverData;
// legacy stuff
let cpHelpers;
@@ -18,7 +18,7 @@ QUnit.module("ActionManager", (hooks) => {
});
hooks.beforeEach(() => {
testConfig = getActionManagerTestConfig();
serverData = getActionManagerServerData();
});
QUnit.module("Concurrency management");
@@ -32,7 +32,7 @@ QUnit.module("ActionManager", (hooks) => {
await def;
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
doAction(webClient, 4);
doAction(webClient, 8);
def.resolve();
@@ -62,7 +62,7 @@ QUnit.module("ActionManager", (hooks) => {
await defs.shift();
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 4);
// kanban view is loaded, switch to list view
await cpHelpers.switchView(webClient.el, "list");
@@ -96,7 +96,7 @@ QUnit.module("ActionManager", (hooks) => {
return 1;
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
doAction(webClient, 2);
doAction(webClient, 4);
def.resolve();
@@ -117,7 +117,7 @@ QUnit.module("ActionManager", (hooks) => {
await def;
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
// create a situation with 3 breadcrumbs: kanban/form/list
await doAction(webClient, 4);
await testUtils.dom.click($(webClient.el).find(".o_kanban_record:first"));
@@ -155,7 +155,7 @@ QUnit.module("ActionManager", (hooks) => {
await def;
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
webClient.env.bus.trigger("test:hashchange", {
action: 4,
id: 2,
@@ -218,10 +218,10 @@ QUnit.module("ActionManager", (hooks) => {
assert.step((args && args.method) || route);
if (route === "/web/dataset/call_button") {
await def;
return testConfig.serverData.actions[1];
return serverData.actions[1];
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
// execute action 3 and open a record in form view
await doAction(webClient, 3);
await testUtils.dom.click($(webClient.el).find(".o_list_view .o_data_row:first"));
@@ -283,7 +283,7 @@ QUnit.module("ActionManager", (hooks) => {
await def;
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
assert.containsOnce(
webClient,
@@ -349,7 +349,7 @@ QUnit.module("ActionManager", (hooks) => {
await def;
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
// execute a first action (its 'load_views' RPC is blocked)
doAction(webClient, 3);
await testUtils.nextTick();
@@ -399,7 +399,7 @@ QUnit.module("ActionManager", (hooks) => {
await def;
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
// execute a first action (its 'search_read' RPC is blocked)
doAction(webClient, 3);
await testUtils.nextTick();
@@ -448,7 +448,7 @@ QUnit.module("ActionManager", (hooks) => {
await def;
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
assert.containsOnce(webClient, ".o_list_view");
assert.containsN(webClient, ".o_list_view .o_data_row", 5);
@@ -487,7 +487,7 @@ QUnit.module("ActionManager", (hooks) => {
}
ClientAction.template = tags.xml`<div class="client_action">ClientAction</div>`;
actionRegistry.add("slowAction", ClientAction);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
doAction(webClient, "slowAction");
await nextTick();
await legacyExtraNextTick();
@@ -516,7 +516,7 @@ QUnit.module("ActionManager", (hooks) => {
return Promise.resolve(def);
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
assert.containsOnce(webClient, ".o_list_view");
def = testUtils.makeTestPromise();
@@ -555,7 +555,7 @@ QUnit.module("ActionManager", (hooks) => {
await Promise.resolve(defs.shift());
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
assert.containsOnce(webClient, ".o_list_view");
doAction(webClient, 4, { clearBreadcrumbs: true });
@@ -6,15 +6,15 @@ import { EffectContainer } from "@web/webclient/effects/effect_container";
import testUtils from "web.test_utils";
import { clearRegistryWithCleanup } from "../../helpers/mock_env";
import { click, legacyExtraNextTick, nextTick, patchWithCleanup } from "../../helpers/utils";
import { createWebClient, doAction, getActionManagerTestConfig } from "./helpers";
import { createWebClient, doAction, getActionManagerServerData } from "./../helpers";
let testConfig;
let serverData;
const mainComponentRegistry = registry.category("main_components");
QUnit.module("ActionManager", (hooks) => {
hooks.beforeEach(() => {
testConfig = getActionManagerTestConfig();
serverData = getActionManagerServerData();
});
QUnit.module("Effects");
@@ -26,7 +26,7 @@ QUnit.module("ActionManager", (hooks) => {
mainComponentRegistry.add("EffectContainer", {
Component: EffectContainer,
});
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
assert.containsOnce(webClient.el, ".o_kanban_view");
assert.containsNone(webClient.el, ".o_reward");
@@ -58,7 +58,7 @@ QUnit.module("ActionManager", (hooks) => {
Component: NotificationContainer,
});
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
assert.containsOnce(webClient.el, ".o_kanban_view");
assert.containsNone(webClient.el, ".o_reward");
@@ -74,7 +74,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("on close with effect from server", async function (assert) {
assert.expect(1);
patchWithCleanup(odoo.session_info, { show_effect: true });
const mockRPC = async (route, args) => {
const mockRPC = async (route) => {
if (route === "/web/dataset/call_button") {
return Promise.resolve({
type: "ir.actions.act_window_close",
@@ -89,7 +89,7 @@ QUnit.module("ActionManager", (hooks) => {
mainComponentRegistry.add("EffectContainer", {
Component: EffectContainer,
});
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 6);
await click(webClient.el.querySelector('button[name="object"]'));
assert.containsOnce(webClient, ".o_reward");
@@ -97,7 +97,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("on close with effect in xml", async function (assert) {
assert.expect(2);
testConfig.serverData.views["partner,false,form"] = `
serverData.views["partner,false,form"] = `
<form>
<header>
<button string="Call method" name="object" type="object"
@@ -107,7 +107,7 @@ QUnit.module("ActionManager", (hooks) => {
<field name="display_name"/>
</form>`;
patchWithCleanup(odoo.session_info, { show_effect: true });
const mockRPC = async (route, args) => {
const mockRPC = async (route) => {
if (route === "/web/dataset/call_button") {
return Promise.resolve(false);
}
@@ -117,7 +117,7 @@ QUnit.module("ActionManager", (hooks) => {
Component: EffectContainer,
});
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 6);
await click(webClient.el.querySelector('button[name="object"]'));
await legacyExtraNextTick();
@@ -7,7 +7,7 @@ import testUtils from "web.test_utils";
import ListController from "web.ListController";
import { click, legacyExtraNextTick, patchWithCleanup } from "../../helpers/utils";
import { clearRegistryWithCleanup } from "../../helpers/mock_env";
import { createWebClient, doAction, getActionManagerTestConfig } from "./helpers";
import { createWebClient, doAction, getActionManagerServerData } from "./../helpers";
import { ClientActionAdapter } from "@web/legacy/action_adapters";
import { useDebugMenu } from "@web/core/debug/debug_menu";
@@ -17,13 +17,13 @@ import ControlPanel from "web.ControlPanel";
import core from "web.core";
import AbstractAction from "web.AbstractAction";
let testConfig;
let serverData;
const mainComponentRegistry = registry.category("main_components");
QUnit.module("ActionManager", (hooks) => {
hooks.beforeEach(() => {
testConfig = getActionManagerTestConfig();
serverData = getActionManagerServerData();
});
QUnit.module("Legacy tests (to eventually drop)");
@@ -43,7 +43,7 @@ QUnit.module("ActionManager", (hooks) => {
mainComponentRegistry.add("NotificationContainer", {
Component: NotificationContainer,
});
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 3);
assert.containsOnce(webClient, ".o_list_view");
list.trigger_up("warning", {
@@ -73,7 +73,7 @@ QUnit.module("ActionManager", (hooks) => {
Component: DialogContainer,
});
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 3);
assert.containsOnce(webClient, ".o_list_view");
list.trigger_up("warning", {
@@ -127,7 +127,7 @@ QUnit.module("ActionManager", (hooks) => {
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, "customLegacy");
assert.containsOnce(webClient, ".custom-action");
assert.verifySteps([]);
@@ -175,7 +175,7 @@ QUnit.module("ActionManager", (hooks) => {
});
core.action_registry.add("customLegacy", LegacyAction);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
await doAction(webClient, "customLegacy");
await click(webClient.el.querySelectorAll(".breadcrumb-item")[0]);
@@ -10,25 +10,31 @@ import { registerCleanup } from "../../helpers/cleanup";
import { makeTestEnv } from "../../helpers/mock_env";
import { makeFakeRouterService } from "../../helpers/mock_services";
import { getFixture, legacyExtraNextTick, patchWithCleanup } from "../../helpers/utils";
import { createWebClient, doAction, getActionManagerTestConfig, loadState } from "./helpers";
import {
createWebClient,
doAction,
getActionManagerServerData,
loadState,
setupWebClientServiceRegistry,
} from "./../helpers";
const { Component, mount, tags } = owl;
let testConfig;
let serverData;
const actionRegistry = registry.category("actions");
const serviceRegistry = registry.category("services");
QUnit.module("ActionManager", (hooks) => {
hooks.beforeEach(() => {
testConfig = getActionManagerTestConfig();
serverData = getActionManagerServerData();
});
QUnit.module("Load State");
QUnit.test("action loading", async (assert) => {
assert.expect(2);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await loadState(webClient, { action: 1001 });
assert.containsOnce(webClient, ".test_client_action");
assert.strictEqual(webClient.el.querySelector(".o_menu_brand").textContent, "App1");
@@ -36,7 +42,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("menu loading", async (assert) => {
assert.expect(2);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await loadState(webClient, { menu_id: 2 });
assert.strictEqual(
webClient.el.querySelector(".test_client_action").textContent.trim(),
@@ -47,7 +53,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("action and menu loading", async (assert) => {
assert.expect(3);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await loadState(webClient, {
action: 1001,
menu_id: 2,
@@ -66,11 +72,11 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("initial loading with action id", async (assert) => {
assert.expect(4);
const hash = "#action=1001";
serviceRegistry.add("router", makeFakeRouterService({ initialRoute: { hash } }), {
force: true,
});
Object.assign(browser.location, { hash });
setupWebClientServiceRegistry();
const mockRPC = (route) => assert.step(route);
const env = await makeTestEnv({ ...testConfig, mockRPC });
const env = await makeTestEnv({ serverData, mockRPC });
assert.verifySteps(["/web/action/load", "/web/webclient/load_menus"]);
@@ -83,11 +89,11 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("initial loading with action tag", async (assert) => {
assert.expect(3);
const hash = "#action=__test__client__action__";
serviceRegistry.add("router", makeFakeRouterService({ initialRoute: { hash } }), {
force: true,
});
Object.assign(browser.location, { hash });
setupWebClientServiceRegistry();
const mockRPC = (route) => assert.step(route);
const env = await makeTestEnv({ ...testConfig, mockRPC });
const env = await makeTestEnv({ serverData, mockRPC });
assert.verifySteps(["/web/webclient/load_menus"]);
@@ -101,7 +107,7 @@ QUnit.module("ActionManager", (hooks) => {
assert.expect(2);
patchWithCleanup(odoo.session_info, { home_action_id: 1001 });
const wc = await createWebClient({ testConfig });
const wc = await createWebClient({ serverData });
await testUtils.nextTick(); // wait for the navbar to be updated
assert.containsOnce(wc, ".test_client_action");
@@ -111,9 +117,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("correctly sends additional context", async (assert) => {
assert.expect(1);
const hash = "#action=1001&active_id=4&active_ids=4,8";
serviceRegistry.add("router", makeFakeRouterService({ initialRoute: { hash } }), {
force: true,
});
Object.assign(browser.location, { hash });
function mockRPC(route, params) {
if (route === "/web/action/load") {
assert.deepEqual(params, {
@@ -126,12 +130,12 @@ QUnit.module("ActionManager", (hooks) => {
});
}
}
await createWebClient({ testConfig, mockRPC });
await createWebClient({ serverData, mockRPC });
});
QUnit.test("supports action as xmlId", async (assert) => {
assert.expect(2);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await loadState(webClient, {
action: "wowl.client_action",
});
@@ -144,8 +148,8 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("supports opening action in dialog", async (assert) => {
assert.expect(3);
testConfig.serverData.actions["wowl.client_action"].target = "new";
const webClient = await createWebClient({ testConfig });
serverData.actions["wowl.client_action"].target = "new";
const webClient = await createWebClient({ serverData });
await loadState(webClient, {
action: "wowl.client_action",
});
@@ -159,7 +163,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async function (route, args) {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await loadState(webClient, {
res_model: "partner",
});
@@ -175,7 +179,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async function (route, args) {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
webClient.env.bus.trigger("test:hashchange", {
action: "HelloWorldTest",
});
@@ -193,7 +197,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async function (route, args) {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
webClient.env.bus.trigger("test:hashchange", {
action: 1,
});
@@ -214,7 +218,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async function (route, args) {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
webClient.env.bus.trigger("test:hashchange", {
id: 2,
model: "partner",
@@ -237,16 +241,14 @@ QUnit.module("ActionManager", (hooks) => {
};
// simulate a real scenario with a first app (e.g. Discuss), to ensure that we don't
// fallback on that first app when only a model and res_id are given in the url
testConfig.serverData.menus = {
serverData.menus = {
root: { id: "root", children: [1, 2], name: "root", appID: "root" },
1: { id: 1, children: [], name: "App1", appID: 1, actionID: 1001, xmlid: "menu_1" },
2: { id: 2, children: [], name: "App2", appID: 2, actionID: 1002, xmlid: "menu_2" },
};
const hash = "#id=2&model=partner";
serviceRegistry.add("router", makeFakeRouterService({ initialRoute: { hash } }), {
force: true,
});
const webClient = await createWebClient({ testConfig, mockRPC });
Object.assign(browser.location, { hash });
const webClient = await createWebClient({ serverData, mockRPC });
await testUtils.nextTick();
assert.containsOnce(webClient, ".o_form_view");
@@ -264,7 +266,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async function (route, args) {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
webClient.env.bus.trigger("test:hashchange", {
action: 3,
id: "",
@@ -287,7 +289,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async function (route, args) {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
webClient.env.bus.trigger("test:hashchange", {
action: 3,
view_type: "kanban",
@@ -311,7 +313,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async function (route, args) {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
webClient.env.bus.trigger("test:hashchange", {
action: 3,
id: 2,
@@ -344,7 +346,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("lazy load multi record view with previous action", async function (assert) {
assert.expect(6);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 4);
assert.containsOnce(
webClient.el,
@@ -396,7 +398,7 @@ QUnit.module("ActionManager", (hooks) => {
return Promise.reject();
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await loadState(webClient, {
action: 3,
id: 2,
@@ -414,7 +416,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async function (route, args) {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
assert.containsOnce(webClient, ".o_list_view");
// switch to kanban view
@@ -465,7 +467,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async function (route, args) {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
// execute action 3 and open the first record in a form view
await doAction(webClient, 3);
await testUtils.dom.click($(webClient.el).find(".o_list_view .o_data_row:first"));
@@ -512,16 +514,16 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("should push the correct state at the right time", async function (assert) {
// formerly "should not push a loaded state"
assert.expect(7);
serviceRegistry.add(
"router",
makeFakeRouterService({
onPushState() {
const pushState = browser.history.pushState;
patchWithCleanup(browser, {
history: Object.assign({}, browser.history, {
pushState() {
pushState(...arguments);
assert.step("push_state");
},
}),
{ force: true }
);
const webClient = await createWebClient({ testConfig });
});
const webClient = await createWebClient({ serverData });
let currentHash = webClient.env.services.router.current.hash;
assert.deepEqual(currentHash, {});
await loadState(webClient, { action: 3 });
@@ -563,17 +565,17 @@ QUnit.module("ActionManager", (hooks) => {
return this._super.apply(this, arguments);
},
});
serviceRegistry.add(
"router",
makeFakeRouterService({
onPushState() {
const pushState = browser.history.pushState;
patchWithCleanup(browser, {
history: Object.assign({}, browser.history, {
pushState() {
pushState(...arguments);
assert.step("push_state");
},
}),
{ force: true }
);
});
core.action_registry.add("ClientAction", ClientAction);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
let currentHash = webClient.env.services.router.current.hash;
assert.deepEqual(currentHash, {});
await loadState(webClient, { action: 9 });
@@ -613,17 +615,17 @@ QUnit.module("ActionManager", (hooks) => {
return this._super.apply(this, arguments);
},
});
serviceRegistry.add(
"router",
makeFakeRouterService({
onPushState() {
const pushState = browser.history.pushState;
patchWithCleanup(browser, {
history: Object.assign({}, browser.history, {
pushState() {
pushState(...arguments);
assert.step("push_state");
},
}),
{ force: true }
);
});
core.action_registry.add("ClientAction", ClientAction);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
let currentHash = webClient.env.services.router.current.hash;
assert.deepEqual(currentHash, {});
// execute the client action
@@ -685,7 +687,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async (route, args) => {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 4);
assert.containsOnce(webClient, ".o_kanban_view", "should display a kanban view");
assert.strictEqual(
@@ -718,7 +720,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("load state supports being given menu_id alone", async function (assert) {
assert.expect(7);
testConfig.serverData.menus[666] = {
serverData.menus[666] = {
id: 666,
children: [],
name: "App1",
@@ -728,7 +730,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async function (route) {
assert.step(route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await loadState(webClient, { menu_id: 666 });
assert.containsOnce(webClient, ".o_kanban_view", "should display a kanban view");
assert.strictEqual(
@@ -746,11 +748,11 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("load state supports #home", async function (assert) {
assert.expect(6);
testConfig.serverData.menus = {
serverData.menus = {
root: { id: "root", children: [1], name: "root", appID: "root" },
1: { id: 1, children: [], name: "App1", appID: 1, actionID: 1 },
};
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await legacyExtraNextTick();
assert.containsOnce(webClient, ".o_kanban_view"); // action 1 (default app)
assert.strictEqual(
@@ -773,18 +775,16 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("load state supports #home as initial state", async function (assert) {
assert.expect(7);
testConfig.serverData.menus = {
serverData.menus = {
root: { id: "root", children: [1], name: "root", appID: "root" },
1: { id: 1, children: [], name: "App1", appID: 1, actionID: 1 },
};
const hash = "#home=1";
serviceRegistry.add("router", makeFakeRouterService({ initialRoute: { hash } }), {
force: true,
});
Object.assign(browser.location, { hash });
const mockRPC = async function (route) {
assert.step(route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await legacyExtraNextTick();
assert.containsOnce(webClient, ".o_kanban_view", "should display a kanban view");
assert.strictEqual(
@@ -801,7 +801,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("load state: in a form view, remove the id from the state", async function (assert) {
assert.expect(13);
testConfig.serverData.actions[999] = {
serverData.actions[999] = {
id: 999,
name: "Partner",
res_model: "partner",
@@ -814,7 +814,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async (route) => {
assert.step(route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 999, { viewType: "form", resId: 2 });
assert.containsOnce(webClient, ".o_form_view");
assert.containsN(webClient, ".breadcrumb-item", 2);
@@ -864,14 +864,18 @@ QUnit.module("ActionManager", (hooks) => {
return this._super.apply(this, arguments);
},
});
serviceRegistry.add(
"router",
makeFakeRouterService({ onPushState: () => assert.step("hashSet") }),
{ force: true }
);
const pushState = browser.history.pushState;
patchWithCleanup(browser, {
history: Object.assign({}, browser.history, {
pushState() {
pushState(...arguments);
assert.step("hashSet");
},
}),
});
core.action_registry.add("ClientAction", ClientAction);
core.action_registry.add("ClientAction2", ClientAction2);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
assert.verifySteps([]);
await doAction(webClient, 9);
assert.verifySteps(["hashSet"]);
@@ -894,7 +898,7 @@ QUnit.module("ActionManager", (hooks) => {
return new Promise(() => {});
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await loadState(webClient, {
action: 2,
active_ids: 3,
@@ -6,10 +6,15 @@ import core from "web.core";
import testUtils from "web.test_utils";
import Widget from "web.Widget";
import { makeTestEnv } from "../../helpers/mock_env";
import { legacyExtraNextTick, nextTick, patchWithCleanup } from "../../helpers/utils";
import { createWebClient, doAction, getActionManagerTestConfig } from "./helpers";
import { legacyExtraNextTick, patchWithCleanup } from "../../helpers/utils";
import {
createWebClient,
doAction,
getActionManagerServerData,
setupWebClientServiceRegistry,
} from "./../helpers";
let testConfig;
let serverData;
// legacy stuff
let cpHelpers;
const actionRegistry = registry.category("actions");
@@ -21,19 +26,19 @@ QUnit.module("ActionManager", (hooks) => {
});
hooks.beforeEach(() => {
testConfig = getActionManagerTestConfig();
serverData = getActionManagerServerData();
});
QUnit.module("Misc");
QUnit.test("can execute actions from id, xmlid and tag", async (assert) => {
assert.expect(6);
testConfig.serverData.actions[1] = {
serverData.actions[1] = {
tag: "client_action_by_db_id",
target: "main",
type: "ir.actions.client",
};
testConfig.serverData.actions["wowl.some_action"] = {
serverData.actions["wowl.some_action"] = {
tag: "client_action_by_xml_id",
target: "main",
type: "ir.actions.client",
@@ -42,7 +47,8 @@ QUnit.module("ActionManager", (hooks) => {
.add("client_action_by_db_id", () => assert.step("client_action_db_id"))
.add("client_action_by_xml_id", () => assert.step("client_action_xml_id"))
.add("client_action_by_object", () => assert.step("client_action_object"));
const env = await makeTestEnv(testConfig);
setupWebClientServiceRegistry();
const env = await makeTestEnv({ serverData });
await doAction(env, 1);
assert.verifySteps(["client_action_db_id"]);
await doAction(env, "wowl.some_action");
@@ -57,7 +63,8 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("action doesn't exists", async (assert) => {
assert.expect(1);
const env = await makeTestEnv(testConfig);
setupWebClientServiceRegistry();
const env = await makeTestEnv({ serverData });
try {
await doAction(env, {
tag: "this_is_a_tag",
@@ -74,7 +81,8 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("action in handler registry", async (assert) => {
assert.expect(2);
const env = await makeTestEnv(testConfig);
setupWebClientServiceRegistry();
const env = await makeTestEnv({ serverData });
actionHandlersRegistry.add("ir.action_in_handler_registry", ({ action }) =>
assert.step(action.type)
);
@@ -88,7 +96,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("properly handle case when action id does not exist", async (assert) => {
assert.expect(2);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
patchWithCleanup(webClient.env.services.notification, {
create(message) {
assert.strictEqual(message, "No action with id '4448' could be found");
@@ -107,7 +115,8 @@ QUnit.module("ActionManager", (hooks) => {
}
};
const env = await makeTestEnv({ ...testConfig, mockRPC });
setupWebClientServiceRegistry();
const env = await makeTestEnv({ serverData, mockRPC });
const loadAction = env.services.action.loadAction;
@@ -163,7 +172,8 @@ QUnit.module("ActionManager", (hooks) => {
}
};
const env = await makeTestEnv({ ...testConfig, mockRPC });
setupWebClientServiceRegistry();
const env = await makeTestEnv({ serverData, mockRPC });
const { loadAction } = env.services.action;
const actionParams = {
additionalContext: {
@@ -203,7 +213,7 @@ QUnit.module("ActionManager", (hooks) => {
this._super.apply(this, arguments);
},
});
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 8);
const n = delta;
await doAction(webClient, 4);
@@ -235,7 +245,7 @@ QUnit.module("ActionManager", (hooks) => {
this._super.apply(this, arguments);
},
});
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
const n = delta;
await doAction(webClient, 5);
await doAction(webClient, { type: "ir.actions.act_window_close" });
@@ -264,7 +274,7 @@ QUnit.module("ActionManager", (hooks) => {
await Promise.resolve(def);
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 4);
const n = delta;
await doAction(webClient, 3, { clearBreadcrumbs: true });
@@ -302,7 +312,7 @@ QUnit.module("ActionManager", (hooks) => {
await Promise.resolve(def);
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
// execute action 4 to know the number of widgets it instantiates
await doAction(webClient, 4);
const n = delta;
@@ -342,7 +352,7 @@ QUnit.module("ActionManager", (hooks) => {
await Promise.resolve(def);
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
// execute action 4 to know the number of widgets it instantiates
await doAction(webClient, 4);
const n = delta;
@@ -363,9 +373,9 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test('action with "no_breadcrumbs" set to true', async function (assert) {
assert.expect(2);
testConfig.serverData.actions[4].context = { no_breadcrumbs: true };
serverData.actions[4].context = { no_breadcrumbs: true };
const webClient = await createWebClient({
testConfig,
serverData,
});
await doAction(webClient, 3);
assert.containsOnce(webClient, ".o_control_panel .breadcrumb-item");
@@ -377,7 +387,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("document's title is updated when an action is executed", async function (assert) {
assert.expect(8);
const defaultTitle = { zopenerp: "Odoo" };
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
let currentTitle = webClient.env.services.title.getParts();
assert.deepEqual(currentTitle, defaultTitle);
let currentHash = webClient.env.services.router.current.hash;
@@ -431,7 +441,7 @@ QUnit.module("ActionManager", (hooks) => {
},
});
core.action_registry.add("ClientAction", ClientAction);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, "ClientAction");
assert.containsOnce(webClient, ".my_button");
await testUtils.dom.click(webClient.el.querySelector(".my_button"));
@@ -447,7 +457,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test('handles "history_back" event', async function (assert) {
assert.expect(3);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 4);
await doAction(webClient, 3);
assert.containsN(webClient, ".o_control_panel .breadcrumb-item", 2);
@@ -467,9 +477,9 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("stores and restores scroll position", async function (assert) {
assert.expect(3);
for (let i = 0; i < 60; i++) {
testConfig.serverData.models.partner.records.push({ id: 100 + i, foo: `Record ${i}` });
serverData.models.partner.records.push({ id: 100 + i, foo: `Record ${i}` });
}
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
webClient.el.style.height = "250px";
// execute a first action
await doAction(webClient, 3);
@@ -489,14 +499,14 @@ QUnit.module("ActionManager", (hooks) => {
'executing an action with target != "new" closes all dialogs',
async function (assert) {
assert.expect(4);
testConfig.serverData.views["partner,false,form"] = `
serverData.views["partner,false,form"] = `
<form>
<field name="o2m">
<tree><field name="foo"/></tree>
<form><field name="foo"/></form>
</field>
</form>`;
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 3);
assert.containsOnce(webClient, ".o_list_view");
await testUtils.dom.click($(webClient.el).find(".o_list_view .o_data_row:first"));
@@ -514,14 +524,14 @@ QUnit.module("ActionManager", (hooks) => {
'executing an action with target "new" does not close dialogs',
async function (assert) {
assert.expect(4);
testConfig.serverData.views["partner,false,form"] = `
serverData.views["partner,false,form"] = `
<form>
<field name="o2m">
<tree><field name="foo"/></tree>
<form><field name="foo"/></form>
</field>
</form>`;
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 3);
assert.containsOnce(webClient, ".o_list_view");
await testUtils.dom.click($(webClient.el).find(".o_list_view .o_data_row:first"));
@@ -1,28 +1,27 @@
/** @odoo-module **/
import { browser } from "@web/core/browser/browser";
import { registry } from "@web/core/registry";
import { useService } from "@web/core/service_hook";
import testUtils from "web.test_utils";
import { makeFakeRouterService } from "../../helpers/mock_services";
import { click, legacyExtraNextTick, nextTick } from "../../helpers/utils";
import { createWebClient, doAction, getActionManagerTestConfig } from "./helpers";
import { click, legacyExtraNextTick, nextTick, patchWithCleanup } from "../../helpers/utils";
import { createWebClient, doAction, getActionManagerServerData } from "./../helpers";
const { Component, tags } = owl;
let testConfig;
let serverData;
const actionRegistry = registry.category("actions");
const serviceRegistry = registry.category("services");
QUnit.module("ActionManager", (hooks) => {
hooks.beforeEach(() => {
testConfig = getActionManagerTestConfig();
serverData = getActionManagerServerData();
});
QUnit.module("Push State");
QUnit.test("basic action as App", async (assert) => {
assert.expect(5);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
let urlState = webClient.env.services.router.current;
assert.deepEqual(urlState.hash, {});
await click(webClient.el, ".o_navbar_apps_menu button");
@@ -41,7 +40,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("do action keeps menu in url", async (assert) => {
assert.expect(9);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
let urlState = webClient.env.services.router.current;
assert.deepEqual(urlState.hash, {});
await click(webClient.el, ".o_navbar_apps_menu button");
@@ -83,7 +82,7 @@ QUnit.module("ActionManager", (hooks) => {
ClientAction_<t t-esc="props.params and props.params.description" />
</div>`;
actionRegistry.add("client_action_pushes", ClientActionPushes);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
let urlState = webClient.env.services.router.current;
assert.deepEqual(urlState.hash, {});
await doAction(webClient, "client_action_pushes");
@@ -112,7 +111,7 @@ QUnit.module("ActionManager", (hooks) => {
ClientAction_<t t-esc="props.params and props.params.description" />
</div>`;
actionRegistry.add("client_action_pushes", ClientActionPushes);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
let urlState = webClient.env.services.router.current;
assert.deepEqual(urlState.hash, {});
await doAction(webClient, "client_action_pushes");
@@ -142,7 +141,7 @@ QUnit.module("ActionManager", (hooks) => {
ClientAction_<t t-esc="props.params and props.params.description" />
</div>`;
actionRegistry.add("client_action_pushes", ClientActionPushes);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
let urlState = webClient.env.services.router.current;
assert.deepEqual(urlState.hash, {});
await doAction(webClient, "client_action_pushes");
@@ -158,24 +157,22 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("action in target new do not push state", async (assert) => {
assert.expect(1);
testConfig.serverData.actions[1001].target = "new";
serviceRegistry.add(
"router",
makeFakeRouterService({
onPushState() {
serverData.actions[1001].target = "new";
patchWithCleanup(browser, {
history: Object.assign({}, browser.history, {
pushState() {
throw new Error("should not push state");
},
}),
{ force: true }
);
const webClient = await createWebClient({ testConfig });
});
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1001);
assert.containsOnce(webClient, ".modal .test_client_action");
});
QUnit.test("properly push state", async function (assert) {
assert.expect(3);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 4);
assert.deepEqual(webClient.env.services.router.current.hash, {
action: 4,
@@ -206,7 +203,7 @@ QUnit.module("ActionManager", (hooks) => {
await def;
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
doAction(webClient, 4);
await testUtils.nextTick();
await legacyExtraNextTick();
@@ -228,7 +225,7 @@ QUnit.module("ActionManager", (hooks) => {
return Promise.reject();
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 8);
assert.deepEqual(webClient.env.services.router.current.hash, {
action: 8,
@@ -7,18 +7,18 @@ import ReportClientAction from "report.client_action";
import { clearRegistryWithCleanup } from "../../helpers/mock_env";
import { makeFakeNotificationService } from "../../helpers/mock_services";
import { patchWithCleanup } from "../../helpers/utils";
import { createWebClient, doAction, getActionManagerTestConfig } from "./helpers";
import { createWebClient, doAction, getActionManagerServerData } from "./../helpers";
import { mockDownload } from "@web/../tests/helpers/utils";
import { DialogContainer } from "@web/core/dialog/dialog_container";
let testConfig;
let serverData;
const mainComponentRegistry = registry.category("main_components");
const serviceRegistry = registry.category("services");
QUnit.module("ActionManager", (hooks) => {
hooks.beforeEach(() => {
testConfig = getActionManagerTestConfig();
serverData = getActionManagerServerData();
clearRegistryWithCleanup(mainComponentRegistry);
mainComponentRegistry.add("DialogContainer", {
Component: DialogContainer,
@@ -39,7 +39,7 @@ QUnit.module("ActionManager", (hooks) => {
return Promise.resolve("ok");
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 7, { onClose: () => assert.step("on_close") });
assert.verifySteps([
"/web/webclient/load_menus",
@@ -61,7 +61,7 @@ QUnit.module("ActionManager", (hooks) => {
return Promise.resolve("ok");
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 5, { onClose: () => assert.step("on_close") });
assert.containsOnce(
document.body,
@@ -94,7 +94,6 @@ QUnit.module("ActionManager", (hooks) => {
},
() => {}
),
{ force: true }
);
mockDownload((options) => {
assert.step(options.url);
@@ -106,7 +105,7 @@ QUnit.module("ActionManager", (hooks) => {
return Promise.resolve("upgrade");
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 7);
assert.verifySteps([
"/web/webclient/load_menus",
@@ -133,7 +132,6 @@ QUnit.module("ActionManager", (hooks) => {
},
() => {}
),
{ force: true }
);
const mockRPC = async (route, args) => {
assert.step(args.method || route);
@@ -156,7 +154,7 @@ QUnit.module("ActionManager", (hooks) => {
this.iframe.setAttribute("src", "about:blank");
},
});
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 7);
assert.containsOnce(
webClient,
@@ -189,8 +187,7 @@ QUnit.module("ActionManager", (hooks) => {
assert.step(options.type || "notification");
},
() => {}
),
{ force: true }
)
);
patchWithCleanup(odoo.session_info.user_context, { some_key: 2 });
const mockRPC = async (route, args) => {
@@ -211,7 +208,7 @@ QUnit.module("ActionManager", (hooks) => {
this.iframe.setAttribute("src", "about:blank");
},
});
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 12);
assert.containsOnce(webClient, ".o_report_iframe", "should have opened the client action");
assert.verifySteps([
@@ -239,13 +236,13 @@ QUnit.module("ActionManager", (hooks) => {
return Promise.reject();
}
});
serviceRegistry.add("ui", uiService, { force: true });
serviceRegistry.add("ui", uiService);
const mockRPC = async (route) => {
if (route === "/report/check_wkhtmltopdf") {
return Promise.resolve("ok");
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
const ui = webClient.env.services.ui;
ui.bus.on("BLOCK", webClient, () => {
assert.step("block");
@@ -285,7 +282,7 @@ QUnit.module("ActionManager", (hooks) => {
return "ok";
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
let customHandlerCalled = false;
registry.category("ir.actions.report handlers").add("custom_handler", async (action) => {
if (action.id === 7 && !customHandlerCalled) {
@@ -1,12 +1,12 @@
/** @odoo-module **/
import { createWebClient, doAction, getActionManagerTestConfig } from "./helpers";
import { createWebClient, doAction, getActionManagerServerData } from "./../helpers";
let testConfig;
let serverData;
QUnit.module("ActionManager", (hooks) => {
hooks.beforeEach(() => {
testConfig = getActionManagerTestConfig();
serverData = getActionManagerServerData();
});
QUnit.module("Server actions");
@@ -20,7 +20,7 @@ QUnit.module("ActionManager", (hooks) => {
return Promise.resolve(1); // execute action 1
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 2);
assert.containsOnce(webClient, ".o_control_panel", "should have rendered a control panel");
assert.containsOnce(webClient, ".o_kanban_view", "should have rendered a kanban view");
@@ -42,7 +42,7 @@ QUnit.module("ActionManager", (hooks) => {
return Promise.resolve(false);
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
// execute an action in target="new"
function onClose() {
assert.step("close handler");
@@ -4,13 +4,13 @@ import testUtils from "web.test_utils";
import core from "web.core";
import AbstractAction from "web.AbstractAction";
import { legacyExtraNextTick } from "../../helpers/utils";
import { createWebClient, doAction, getActionManagerTestConfig } from "./helpers";
import { createWebClient, doAction, getActionManagerServerData } from "./../helpers";
let testConfig;
let serverData;
QUnit.module("ActionManager", (hooks) => {
hooks.beforeEach(() => {
testConfig = getActionManagerTestConfig();
serverData = getActionManagerServerData();
});
QUnit.module('Actions in target="new"');
@@ -20,7 +20,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async (route, args) => {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 5);
assert.containsOnce(
document.body,
@@ -51,7 +51,7 @@ QUnit.module("ActionManager", (hooks) => {
assert.strictEqual(closeInfo, "smallCandle");
assert.step("Close Action");
}
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 5, { onClose });
// a target=new action shouldn't activate the on_close
await doAction(webClient, 5);
@@ -63,14 +63,14 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("footer buttons are moved to the dialog footer", async function (assert) {
assert.expect(3);
testConfig.serverData.views["partner,false,form"] = `
serverData.views["partner,false,form"] = `
<form>
<field name="display_name"/>
<footer>
<button string="Create" type="object" class="infooter"/>
</footer>
</form>`;
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 5);
assert.containsNone(
$(".o_technical_modal .modal-body")[0],
@@ -91,7 +91,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("Button with `close` attribute closes dialog", async function (assert) {
assert.expect(19);
testConfig.serverData.views = {
serverData.views = {
"partner,false,form": `
<form>
<header>
@@ -108,14 +108,14 @@ QUnit.module("ActionManager", (hooks) => {
`,
"partner,false,search": "<search></search>",
};
testConfig.serverData.actions[4] = {
serverData.actions[4] = {
id: 4,
name: "Partners Action 4",
res_model: "partner",
type: "ir.actions.act_window",
views: [[false, "form"]],
};
testConfig.serverData.actions[5] = {
serverData.actions[5] = {
id: 5,
name: "Create a Partner",
res_model: "partner",
@@ -132,7 +132,7 @@ QUnit.module("ActionManager", (hooks) => {
};
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
assert.verifySteps(["/web/webclient/load_menus"]);
await doAction(webClient, 4);
assert.verifySteps([
@@ -177,7 +177,7 @@ QUnit.module("ActionManager", (hooks) => {
},
});
core.action_registry.add("test", ClientAction);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, {
tag: "test",
target: "new",
@@ -191,14 +191,14 @@ QUnit.module("ActionManager", (hooks) => {
'footer buttons are updated when having another action in target "new"',
async function (assert) {
assert.expect(9);
testConfig.serverData.views["partner,false,form"] =
serverData.views["partner,false,form"] =
"<form>" +
'<field name="display_name"/>' +
"<footer>" +
'<button string="Create" type="object" class="infooter"/>' +
"</footer>" +
"</form>";
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 5);
assert.containsNone(
webClient.el,
@@ -234,7 +234,7 @@ QUnit.module("ActionManager", (hooks) => {
},
});
core.action_registry.add("test", ClientAction);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, {
tag: "test",
target: "new",
@@ -254,7 +254,7 @@ QUnit.module("ActionManager", (hooks) => {
async function (assert) {
assert.expect(5);
testConfig.serverData.actions[999] = {
serverData.actions[999] = {
id: 999,
name: "A window action",
res_model: "partner",
@@ -262,11 +262,11 @@ QUnit.module("ActionManager", (hooks) => {
type: "ir.actions.act_window",
views: [[999, "form"]],
};
testConfig.serverData.views["partner,999,form"] = `
serverData.views["partner,999,form"] = `
<form>
<button name="method" string="Call method" type="object" confirm="Are you sure?"/>
</form>`;
testConfig.serverData.views["partner,1000,form"] = `<form>Another action</form>`;
serverData.views["partner,1000,form"] = `<form>Another action</form>`;
const mockRPC = (route, args) => {
if (args.method === "method") {
@@ -280,7 +280,7 @@ QUnit.module("ActionManager", (hooks) => {
});
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 999);
@@ -305,7 +305,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async (route, args) => {
assert.step(args.method || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 6);
assert.containsOnce(
webClient,
@@ -323,9 +323,9 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("breadcrumbs and actions with target inline", async function (assert) {
assert.expect(4);
testConfig.serverData.actions[4].views = [[false, "form"]];
testConfig.serverData.actions[4].target = "inline";
const webClient = await createWebClient({ testConfig });
serverData.actions[4].views = [[false, "form"]];
serverData.actions[4].target = "inline";
const webClient = await createWebClient({ serverData });
await doAction(webClient, 4);
assert.containsNone(webClient, ".o_control_panel");
await doAction(webClient, 1, { clearBreadcrumbs: true });
@@ -343,8 +343,8 @@ QUnit.module("ActionManager", (hooks) => {
'correctly execute act_window actions in target="fullscreen"',
async function (assert) {
assert.expect(3);
testConfig.serverData.actions[1].target = "fullscreen";
const webClient = await createWebClient({ testConfig });
serverData.actions[1].target = "fullscreen";
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
assert.containsOnce(
webClient.el,
@@ -358,11 +358,11 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test('fullscreen on action change: back to a "current" action', async function (assert) {
assert.expect(3);
testConfig.serverData.actions[1].target = "fullscreen";
testConfig.serverData.views[
serverData.actions[1].target = "fullscreen";
serverData.views[
"partner,false,form"
] = `<form><button name="1" type="action" class="oe_stat_button" /></form>`;
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 6);
assert.isVisible(webClient.el.querySelector(".o_main_navbar"));
await testUtils.dom.click($(webClient.el).find("button[name=1]"));
@@ -375,11 +375,11 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test('fullscreen on action change: all "fullscreen" actions', async function (assert) {
assert.expect(3);
testConfig.serverData.actions[6].target = "fullscreen";
testConfig.serverData.views[
serverData.actions[6].target = "fullscreen";
serverData.views[
"partner,false,form"
] = `<form><button name="1" type="action" class="oe_stat_button" /></form>`;
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 6);
assert.isNotVisible(webClient.el.querySelector(".o_main_navbar"));
await testUtils.dom.click($(webClient.el).find("button[name=1]"));
@@ -394,14 +394,14 @@ QUnit.module("ActionManager", (hooks) => {
'fullscreen on action change: back to another "current" action',
async function (assert) {
assert.expect(8);
testConfig.serverData.menus = {
serverData.menus = {
root: { id: "root", children: [1], name: "root", appID: "root" },
1: { id: 1, children: [], name: "MAIN APP", appID: 1, actionID: 6 },
};
testConfig.serverData.actions[1].target = "fullscreen";
testConfig.serverData.views["partner,false,form"] =
serverData.actions[1].target = "fullscreen";
serverData.views["partner,false,form"] =
'<form><button name="24" type="action" class="oe_stat_button"/></form>';
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await testUtils.nextTick(); // wait for the load state (default app)
await legacyExtraNextTick();
assert.containsOnce(webClient, "nav .o_menu_brand");
@@ -3,14 +3,14 @@
import { registry } from "@web/core/registry";
import { makeTestEnv } from "../../helpers/mock_env";
import { makeFakeRouterService } from "../../helpers/mock_services";
import { doAction, getActionManagerTestConfig } from "./helpers";
import { setupWebClientServiceRegistry, doAction, getActionManagerServerData } from "./../helpers";
let testConfig;
let serverData;
const serviceRegistry = registry.category("services");
QUnit.module("ActionManager", (hooks) => {
hooks.beforeEach(() => {
testConfig = getActionManagerTestConfig();
serverData = getActionManagerServerData();
});
QUnit.module("URL actions");
@@ -22,10 +22,10 @@ QUnit.module("ActionManager", (hooks) => {
onRedirect(url) {
assert.step(url);
},
}),
{ force: true }
})
);
const env = await makeTestEnv(testConfig);
setupWebClientServiceRegistry();
const env = await makeTestEnv({ serverData });
await doAction(env, {
type: "ir.actions.act_url",
target: "self",
@@ -1,5 +1,6 @@
/** @odoo-module **/
import { browser } from "@web/core/browser/browser";
import { debugService } from "@web/core/debug/debug_service";
import { DialogContainer } from "@web/core/dialog/dialog_container";
import { registry } from "@web/core/registry";
@@ -12,9 +13,9 @@ import testUtils from "web.test_utils";
import legacyViewRegistry from "web.view_registry";
import { clearRegistryWithCleanup } from "../../helpers/mock_env";
import { click, legacyExtraNextTick, nextTick, patchWithCleanup } from "../../helpers/utils";
import { createWebClient, doAction, getActionManagerTestConfig, loadState } from "./helpers";
import { createWebClient, doAction, getActionManagerServerData, loadState } from "./../helpers";
let testConfig;
let serverData;
const serviceRegistry = registry.category("services");
// legacy stuff
@@ -25,7 +26,7 @@ QUnit.module("ActionManager", (hooks) => {
cpHelpers = testUtils.controlPanel;
});
hooks.beforeEach(() => {
testConfig = getActionManagerTestConfig();
serverData = getActionManagerServerData();
});
QUnit.module("Window Actions");
@@ -35,7 +36,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async (route, args) => {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 1);
assert.containsOnce(
document.body,
@@ -53,7 +54,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("sidebar is present in list view", async function (assert) {
assert.expect(4);
testConfig.serverData.models.partner.toolbar = {
serverData.models.partner.toolbar = {
print: [{ name: "Print that record" }],
};
const mockRPC = async (route, args) => {
@@ -65,7 +66,7 @@ QUnit.module("ActionManager", (hooks) => {
);
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
assert.containsNone(webClient, ".o_cp_action_menus");
await testUtils.dom.clickFirst($(webClient.el).find("input.custom-control-input"));
@@ -86,7 +87,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async (route, args) => {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
assert.containsOnce(webClient, ".o_list_view", "should display the list view");
// switch to kanban view
@@ -131,7 +132,7 @@ QUnit.module("ActionManager", (hooks) => {
});
QUnit.test("switching into a view with mode=edit lands in edit mode", async function (assert) {
testConfig.serverData.views["partner,1,kanban"] = `
serverData.views["partner,1,kanban"] = `
<kanban on_create="quick_create" default_group_by="m2o">
<templates>
<t t-name="kanban-box">
@@ -140,7 +141,7 @@ QUnit.module("ActionManager", (hooks) => {
</templates>
</kanban>
`;
testConfig.serverData.actions[1] = {
serverData.actions[1] = {
id: 1,
xml_id: "action_1",
name: "Partners Action 1 patched",
@@ -155,7 +156,7 @@ QUnit.module("ActionManager", (hooks) => {
assert.step((args && args.method) || route);
};
assert.expect(14);
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 1);
assert.containsOnce(webClient, ".o_kanban_view", "should display the kanban view");
// quick create record
@@ -191,14 +192,14 @@ QUnit.module("ActionManager", (hooks) => {
"orderedBy in context is not propagated when executing another action",
async function (assert) {
assert.expect(6);
testConfig.serverData.models.partner.fields.foo.sortable = true;
testConfig.serverData.views["partner,false,form"] = `
serverData.models.partner.fields.foo.sortable = true;
serverData.views["partner,false,form"] = `
<form>
<header>
<button name="8" string="Execute action" type="action"/>
</header>
</form>`;
testConfig.serverData.models.partner.filters = [
serverData.models.partner.filters = [
{
id: 1,
context: "{}",
@@ -227,7 +228,7 @@ QUnit.module("ActionManager", (hooks) => {
searchReadCount += 1;
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
// Sort records
await testUtils.dom.click($(webClient.el).find(".o_list_view th.o_column_sortable"));
@@ -243,7 +244,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("breadcrumbs are updated when switching between views", async function (assert) {
assert.expect(15);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 3);
assert.containsOnce(
webClient.el,
@@ -338,7 +339,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("switch buttons are updated when switching between views", async function (assert) {
assert.expect(13);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 3);
assert.containsN(
webClient.el,
@@ -424,7 +425,7 @@ QUnit.module("ActionManager", (hooks) => {
});
QUnit.test("pager is updated when switching between views", async function (assert) {
assert.expect(10);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 4);
assert.strictEqual(
$(webClient.el).find(".o_control_panel .o_pager_value").text(),
@@ -492,8 +493,8 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("domain is kept when switching between views", async function (assert) {
assert.expect(5);
testConfig.serverData.actions[3].search_view_id = [4, "a custom search view"];
const webClient = await createWebClient({ testConfig });
serverData.actions[3].search_view_id = [4, "a custom search view"];
const webClient = await createWebClient({ serverData });
await doAction(webClient, 3);
assert.containsN(webClient, ".o_data_row", 5);
// activate a domain
@@ -521,7 +522,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async (route, args) => {
await def;
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
// switch to kanban view
def = testUtils.makeTestPromise();
@@ -597,7 +598,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("breadcrumbs are updated when display_name changes", async function (assert) {
assert.expect(4);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 3);
// open a record in form view
await testUtils.dom.click(webClient.el.querySelector(".o_list_view .o_data_row"));
@@ -637,7 +638,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test('reverse breadcrumb works on accesskey "b"', async function (assert) {
assert.expect(4);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 3);
// open a record in form view
await testUtils.dom.click($(webClient.el).find(".o_list_view .o_data_row:first"));
@@ -673,7 +674,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async (route, args) => {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
// create a new record
await testUtils.dom.click($(webClient.el).find(".o_control_panel .o_list_button_add"));
@@ -724,14 +725,14 @@ QUnit.module("ActionManager", (hooks) => {
},
"should call route with correct arguments"
);
const record = testConfig.serverData.models.partner.records.find(
const record = serverData.models.partner.records.find(
(r) => r.id === args.args[0][0]
);
record.foo = "value changed";
return Promise.resolve(false);
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
// open a record in form view
await testUtils.dom.click($(webClient.el).find(".o_list_view .o_data_row:first"));
@@ -766,12 +767,12 @@ QUnit.module("ActionManager", (hooks) => {
"requests for execute_action of type object: disable buttons (2)",
async function (assert) {
assert.expect(6);
testConfig.serverData.views["pony,44,form"] = `
serverData.views["pony,44,form"] = `
<form>
<field name="name"/>
<button string="Cancel" class="cancel-btn" special="cancel"/>
</form>`;
testConfig.serverData.actions[4] = {
serverData.actions[4] = {
id: 4,
name: "Create a Partner",
res_model: "pony",
@@ -786,7 +787,7 @@ QUnit.module("ActionManager", (hooks) => {
await def;
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
assert.containsOnce(webClient.el, ".o_list_view");
// open first record in form view
@@ -826,7 +827,7 @@ QUnit.module("ActionManager", (hooks) => {
return Promise.reject();
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3, { viewType: "form" });
assert.containsOnce(webClient.el, ".o_form_view");
// click on 'Execute action', to execute action 4 in a dialog
@@ -842,7 +843,7 @@ QUnit.module("ActionManager", (hooks) => {
"requests for execute_action of type object raises error in modal: re-enables buttons",
async function (assert) {
assert.expect(5);
testConfig.serverData.views["partner,false,form"] = `
serverData.views["partner,false,form"] = `
<form>
<field name="display_name"/>
<footer>
@@ -855,7 +856,7 @@ QUnit.module("ActionManager", (hooks) => {
return Promise.reject();
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 5);
assert.containsOnce(webClient.el, ".modal .o_form_view");
testUtils.dom.click(webClient.el.querySelector('.modal footer button[name="object"]'));
@@ -873,7 +874,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async (route, args) => {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
// open a record in form view
await testUtils.dom.click($(webClient.el).find(".o_list_view .o_data_row:first"));
@@ -922,7 +923,7 @@ QUnit.module("ActionManager", (hooks) => {
assert.strictEqual(args.context.default_partner, 2);
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 24);
assert.containsOnce(webClient.el, ".o_form_view");
assert.containsN(webClient.el, ".o_form_buttons_view button:not([disabled])", 2);
@@ -943,7 +944,7 @@ QUnit.module("ActionManager", (hooks) => {
return Promise.reject();
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 24);
assert.containsOnce(webClient.el, ".o_form_view");
assert.containsN(webClient.el, ".o_form_buttons_view button:not([disabled])", 2);
@@ -974,7 +975,7 @@ QUnit.module("ActionManager", (hooks) => {
await def; // block the 'read' call
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
// open a record in form view
await testUtils.dom.click($(webClient.el).find(".o_list_view .o_data_row:first"));
@@ -1009,7 +1010,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async (route, args) => {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
// open the first record in form view
await testUtils.dom.click($(webClient.el).find(".o_list_view .o_data_row:first"));
@@ -1053,9 +1054,9 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("restore previous view state when switching back", async function (assert) {
assert.expect(5);
testConfig.serverData.actions[3].views.unshift([false, "graph"]);
testConfig.serverData.views["partner,false,graph"] = "<graph/>";
const webClient = await createWebClient({ testConfig });
serverData.actions[3].views.unshift([false, "graph"]);
serverData.views["partner,false,graph"] = "<graph/>";
const webClient = await createWebClient({ serverData });
await doAction(webClient, 3);
assert.hasClass(
$(webClient.el).find(".o_control_panel .fa-bar-chart-o")[0],
@@ -1094,9 +1095,9 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("view switcher is properly highlighted in graph view", async function (assert) {
assert.expect(4);
testConfig.serverData.actions[3].views.splice(1, 1, [false, "graph"]);
testConfig.serverData.views["partner,false,graph"] = "<graph/>";
const webClient = await createWebClient({ testConfig });
serverData.actions[3].views.splice(1, 1, [false, "graph"]);
serverData.views["partner,false,graph"] = "<graph/>";
const webClient = await createWebClient({ serverData });
await doAction(webClient, 3);
assert.hasClass(
$(webClient.el).find(".o_control_panel .o_switch_view.o_list")[0],
@@ -1125,13 +1126,13 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("can interact with search view", async function (assert) {
assert.expect(2);
testConfig.serverData.views["partner,false,search"] = `
serverData.views["partner,false,search"] = `
<search>
<group>
<filter name="foo" string="foo" context="{'group_by': 'foo'}"/>
</group>
</search>`;
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 3);
assert.doesNotHaveClass(
$(webClient.el).find(".o_list_table")[0],
@@ -1156,14 +1157,14 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("can open a many2one external window", async function (assert) {
assert.expect(9);
testConfig.serverData.models.partner.records[0].bar = 2;
testConfig.serverData.views["partner,false,search"] = `
serverData.models.partner.records[0].bar = 2;
serverData.views["partner,false,search"] = `
<search>
<group>
<filter name="foo" string="foo" context="{'group_by': 'foo'}"/>
</group>
</search>`;
testConfig.serverData.views["partner,false,form"] = `
serverData.views["partner,false,form"] = `
<form>
<field name="foo"/>
<field name="bar"/>
@@ -1174,7 +1175,7 @@ QUnit.module("ActionManager", (hooks) => {
return Promise.resolve(false);
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
// open first record in form view
await testUtils.dom.click($(webClient.el).find(".o_data_row:first"));
@@ -1204,7 +1205,7 @@ QUnit.module("ActionManager", (hooks) => {
assert.deepEqual(args, [[1], { foo: "pinkypie" }]);
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 4);
// open record in form view
await testUtils.dom.click($(webClient.el).find(".o_kanban_record:first")[0]);
@@ -1226,8 +1227,8 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("limit set in action is passed to each created controller", async function (assert) {
assert.expect(2);
testConfig.serverData.actions[3].limit = 2;
const webClient = await createWebClient({ testConfig });
serverData.actions[3].limit = 2;
const webClient = await createWebClient({ serverData });
await doAction(webClient, 3);
assert.containsN(webClient, ".o_data_row", 2);
// switch to kanban view
@@ -1238,7 +1239,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("go back to a previous action using the breadcrumbs", async function (assert) {
assert.expect(10);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 3);
// open a record in form view
await testUtils.dom.click($(webClient.el).find(".o_list_view .o_data_row:first"));
@@ -1314,7 +1315,7 @@ QUnit.module("ActionManager", (hooks) => {
"form views are restored in readonly when coming back in breadcrumbs",
async function (assert) {
assert.expect(2);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 3);
// open a record in form view
await testUtils.dom.click($(webClient.el).find(".o_list_view .o_data_row:first"));
@@ -1334,14 +1335,14 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("honor group_by specified in actions context", async function (assert) {
assert.expect(5);
testConfig.serverData.actions[3].context = "{'group_by': 'bar'}";
testConfig.serverData.views["partner,false,search"] = `
serverData.actions[3].context = "{'group_by': 'bar'}";
serverData.views["partner,false,search"] = `
<search>
<group>
<filter name="foo" string="foo" context="{'group_by': 'foo'}"/>
</group>
</search>`;
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 3);
assert.containsOnce(webClient, ".o_list_table_grouped", "should be grouped");
assert.containsN(
@@ -1380,7 +1381,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("switch request to unknown view type", async function (assert) {
assert.expect(8);
testConfig.serverData.actions[33] = {
serverData.actions[33] = {
id: 33,
name: "Partners",
res_model: "partner",
@@ -1393,7 +1394,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async (route, args) => {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 33);
assert.containsOnce(webClient, ".o_list_view", "should display the list view");
// try to open a record in a form view
@@ -1412,7 +1413,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("flags field of ir.actions.act_window is used", async function (assert) {
// more info about flags field : https://github.com/odoo/odoo/commit/c9b133813b250e89f1f61816b0eabfb9bee2009d
assert.expect(7);
testConfig.serverData.actions[44] = {
serverData.actions[44] = {
id: 33,
name: "Partners",
res_model: "partner",
@@ -1425,7 +1426,7 @@ QUnit.module("ActionManager", (hooks) => {
const mockRPC = async (route, args) => {
assert.step((args && args.method) || route);
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 44);
assert.containsOnce(webClient, ".o_form_view", "should display the form view");
assert.containsNone(
@@ -1453,7 +1454,7 @@ QUnit.module("ActionManager", (hooks) => {
};
},
});
testConfig.serverData.actions[33] = {
serverData.actions[33] = {
id: 33,
context: {
shouldNotBeInFilterContext: false,
@@ -1484,7 +1485,7 @@ QUnit.module("ActionManager", (hooks) => {
},
},
};
const webClient = await createWebClient({ testConfig, legacyParams });
const webClient = await createWebClient({ serverData, legacyParams });
await doAction(webClient, 33);
assert.containsN(webClient, ".o_data_row", 5, "should contain 5 records");
// filter on bar
@@ -1504,9 +1505,9 @@ QUnit.module("ActionManager", (hooks) => {
"list with default_order and favorite filter with no orderedBy",
async function (assert) {
assert.expect(5);
testConfig.serverData.views["partner,1,list"] =
serverData.views["partner,1,list"] =
'<tree default_order="foo desc"><field name="foo"/></tree>';
testConfig.serverData.actions[100] = {
serverData.actions[100] = {
id: 100,
name: "Partners",
res_model: "partner",
@@ -1516,7 +1517,7 @@ QUnit.module("ActionManager", (hooks) => {
[false, "form"],
],
};
testConfig.serverData.models.partner.filters = [
serverData.models.partner.filters = [
{
name: "favorite filter",
id: 5,
@@ -1526,7 +1527,7 @@ QUnit.module("ActionManager", (hooks) => {
is_default: false,
},
];
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 100);
assert.strictEqual(
$(webClient.el).find(".o_list_view tr.o_data_row .o_data_cell").text(),
@@ -1571,7 +1572,7 @@ QUnit.module("ActionManager", (hooks) => {
"search menus are still available when switching between actions",
async function (assert) {
assert.expect(3);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
assert.isVisible(
webClient.el.querySelector(".o_search_options .o_dropdown.o_filter_menu"),
@@ -1595,24 +1596,25 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("current act_window action is stored in session_storage", async function (assert) {
assert.expect(1);
const expectedAction = {
...testConfig.serverData.actions[3],
...serverData.actions[3],
context: {
lang: "en",
uid: 7,
tz: "taht",
},
};
const sessionStorage = testConfig.browser.sessionStorage;
testConfig.browser.sessionStorage = Object.assign(Object.create(sessionStorage), {
setItem(k, value) {
assert.deepEqual(
JSON.parse(value),
expectedAction,
"should store the executed action in the sessionStorage"
);
},
patchWithCleanup(browser, {
sessionStorage: Object.assign(Object.create(sessionStorage), {
setItem(k, value) {
assert.deepEqual(
JSON.parse(value),
expectedAction,
"should store the executed action in the sessionStorage"
);
},
}),
});
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 3);
});
@@ -1624,7 +1626,7 @@ QUnit.module("ActionManager", (hooks) => {
// once restored
assert.expect(1);
const expectedAction = {
...testConfig.serverData.actions[4],
...serverData.actions[4],
context: {
lang: "en",
uid: 7,
@@ -1635,19 +1637,20 @@ QUnit.module("ActionManager", (hooks) => {
},
};
let checkSessionStorage = false;
const sessionStorage = testConfig.browser.sessionStorage;
testConfig.browser.sessionStorage = Object.assign(Object.create(sessionStorage), {
setItem(k, value) {
if (checkSessionStorage) {
assert.strictEqual(
value,
JSON.stringify(expectedAction),
"should store the executed action in the sessionStorage"
);
}
},
patchWithCleanup(browser, {
sessionStorage: Object.assign(Object.create(sessionStorage), {
setItem(k, value) {
if (checkSessionStorage) {
assert.strictEqual(
value,
JSON.stringify(expectedAction),
"should store the executed action in the sessionStorage"
);
}
},
}),
});
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
// execute an action and open a record in form view
await doAction(webClient, 3);
await testUtils.dom.click($(webClient.el).find(".o_list_view .o_data_row:first"));
@@ -1663,7 +1666,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("destroy action with lazy loaded controller", async function (assert) {
assert.expect(6);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await loadState(webClient, {
action: 3,
id: 2,
@@ -1689,8 +1692,8 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("execute action from dirty, new record, and come back", async function (assert) {
assert.expect(18);
testConfig.serverData.models.partner.fields.bar.default = 1;
testConfig.serverData.views["partner,false,form"] = `
serverData.models.partner.fields.bar.default = 1;
serverData.views["partner,false,form"] = `
<form>
<field name="display_name"/>
<field name="foo"/>
@@ -1707,7 +1710,7 @@ QUnit.module("ActionManager", (hooks) => {
});
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
// execute an action and create a new record
await doAction(webClient, 3);
await testUtils.dom.click($(webClient.el).find(".o_list_button_add"));
@@ -1758,9 +1761,9 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("execute a contextual action from a form view", async function (assert) {
assert.expect(4);
const contextualAction = testConfig.serverData.actions[8];
const contextualAction = serverData.actions[8];
contextualAction.context = "{}"; // need a context to evaluate
testConfig.serverData.models.partner.toolbar = {
serverData.models.partner.toolbar = {
action: [contextualAction],
print: [],
};
@@ -1773,7 +1776,7 @@ QUnit.module("ActionManager", (hooks) => {
);
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
// execute an action and open a record
await doAction(webClient, 3);
assert.containsOnce(webClient, ".o_list_view");
@@ -1791,7 +1794,7 @@ QUnit.module("ActionManager", (hooks) => {
"go back to action with form view as main view, and res_id",
async function (assert) {
assert.expect(7);
testConfig.serverData.actions[999] = {
serverData.actions[999] = {
id: 999,
name: "Partner",
res_model: "partner",
@@ -1799,7 +1802,7 @@ QUnit.module("ActionManager", (hooks) => {
res_id: 2,
views: [[44, "form"]],
};
testConfig.serverData.views["partner,44,form"] = '<form><field name="m2o"/></form>';
serverData.views["partner,44,form"] = '<form><field name="m2o"/></form>';
const mockRPC = async (route, args) => {
if (args.method === "get_formview_action") {
return Promise.resolve({
@@ -1810,7 +1813,7 @@ QUnit.module("ActionManager", (hooks) => {
});
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 999);
assert.containsOnce(webClient.el, ".o_form_view");
assert.hasClass(webClient.el.querySelector(".o_form_view"), "o_form_readonly");
@@ -1839,7 +1842,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("open a record, come back, and create a new record", async function (assert) {
assert.expect(7);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
// execute an action and open a record
await doAction(webClient, 3);
assert.containsOnce(webClient.el, ".o_list_view");
@@ -1863,7 +1866,7 @@ QUnit.module("ActionManager", (hooks) => {
"open form view, use the pager, execute action, and come back",
async function (assert) {
assert.expect(8);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
// execute an action and open a record
await doAction(webClient, 3);
assert.containsOnce(webClient.el, ".o_list_view");
@@ -1902,7 +1905,7 @@ QUnit.module("ActionManager", (hooks) => {
"create a new record in a form view, execute action, and come back",
async function (assert) {
assert.expect(8);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
// execute an action and create a new record
await doAction(webClient, 3);
assert.containsOnce(webClient.el, ".o_list_view");
@@ -1945,10 +1948,10 @@ QUnit.module("ActionManager", (hooks) => {
assert.step("init js class");
},
});
testConfig.serverData.views["partner,false,test_view"] = `
serverData.views["partner,false,test_view"] = `
<div js_class="test_jsClass"></div>
`;
testConfig.serverData.actions[9999] = {
serverData.actions[9999] = {
id: 1,
name: "Partners Action 1",
res_model: "partner",
@@ -1957,7 +1960,7 @@ QUnit.module("ActionManager", (hooks) => {
};
legacyViewRegistry.add("test_view", TestView);
legacyViewRegistry.add("test_jsClass", TestJsClassView);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 9999);
assert.verifySteps(["init js class"]);
delete legacyViewRegistry.map.test_view;
@@ -1988,14 +1991,14 @@ QUnit.module("ActionManager", (hooks) => {
}),
});
legacyViewRegistry.add("test_view", TestCustoFormView);
testConfig.serverData.views["partner,3,form"] = `
serverData.views["partner,3,form"] = `
<form js_class="test_view">
<field name="foo" />
<footer>
<button string="Echoes" special="save" />
</footer>
</form>`;
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
await doAction(webClient, 24); // main form view
await doAction(webClient, 25, {
// Custom jsClass form view in target new
@@ -2019,7 +2022,7 @@ QUnit.module("ActionManager", (hooks) => {
"execute action without modal closes bootstrap tooltips anyway",
async function (assert) {
assert.expect(12);
Object.assign(testConfig.serverData.views, {
Object.assign(serverData.views, {
"partner,666,form": `<form>
<header>
<button name="object" string="Call method" type="object" help="need somebody"/>
@@ -2034,7 +2037,7 @@ QUnit.module("ActionManager", (hooks) => {
return Promise.resolve(false);
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 24);
assert.verifySteps([
"/web/webclient/load_menus",
@@ -2077,7 +2080,7 @@ QUnit.module("ActionManager", (hooks) => {
}
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
await cpHelpers.editSearch(webClient.el, "m");
await cpHelpers.validateSearch(webClient.el);
@@ -2102,7 +2105,7 @@ QUnit.module("ActionManager", (hooks) => {
writeCalls += 1;
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
// execute an action and edit existing record
await doAction(webClient, 3);
await testUtils.dom.click($(webClient.el).find(".o_list_view .o_data_row:first"));
@@ -2134,7 +2137,7 @@ QUnit.module("ActionManager", (hooks) => {
Component: DialogContainer,
});
testConfig.serverData.views["partner,false,form"] = `
serverData.views["partner,false,form"] = `
<form>
<field name="foo"/>
</form>`;
@@ -2150,7 +2153,7 @@ QUnit.module("ActionManager", (hooks) => {
});
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
@@ -2176,7 +2179,7 @@ QUnit.module("ActionManager", (hooks) => {
"do not call clearUncommittedChanges() when target=new and dialog is opened",
async function (assert) {
assert.expect(2);
const webClient = await createWebClient({ testConfig });
const webClient = await createWebClient({ serverData });
// Open Partner form view and enter some text
await doAction(webClient, 3, { viewType: "form" });
await legacyExtraNextTick();
@@ -2199,14 +2202,14 @@ QUnit.module("ActionManager", (hooks) => {
return true;
}
};
testConfig.serverData.views["partner,false,form"] = `
serverData.views["partner,false,form"] = `
<form>
<header><button name="do_something" string="Call button" type="object"/></header>
<sheet>
<field name="display_name"/>
</sheet>
</form>`;
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3, { viewType: "form", resId: 1 });
await legacyExtraNextTick();
assert.isVisible(webClient.el.querySelector(".o_form_buttons_view .o_form_button_edit"));
@@ -2235,7 +2238,7 @@ QUnit.module("ActionManager", (hooks) => {
return true;
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 1);
assert.containsNone(
webClient.el,
@@ -2250,14 +2253,14 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("reload a view via the view switcher keep state", async function (assert) {
assert.expect(6);
testConfig.serverData.actions[3].views.unshift([false, "pivot"]);
testConfig.serverData.views["partner,false,pivot"] = "<pivot/>";
serverData.actions[3].views.unshift([false, "pivot"]);
serverData.views["partner,false,pivot"] = "<pivot/>";
const mockRPC = async (route, args) => {
if (args.method === "read_group") {
assert.step(args.method);
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 3);
assert.doesNotHaveClass(
webClient.el.querySelector(".o_pivot_measure_row"),
@@ -1,6 +1,5 @@
/** @odoo-module **/
import { browser, makeRAMLocalStorage } from "@web/core/browser/browser";
import { dialogService } from "@web/core/dialog/dialog_service";
import { notificationService } from "@web/core/notifications/notification_service";
import { ormService } from "@web/core/orm_service";
@@ -19,7 +18,6 @@ import { effectService } from "@web/webclient/effects/effect_service";
import { hotkeyService } from "@web/webclient/hotkeys/hotkey_service";
import { menuService } from "@web/webclient/menu_service";
import { WebClient } from "@web/webclient/webclient";
import { DialogContainer } from "@web/core/dialog/dialog_container";
// This import is needed because of it's sideeffects, for exemple :
// web.test_utils easyload xml templates at line : 124:130.
// Also it set the autocomplete delay time for the field Many2One at 0 for the tests at line : 132:137
@@ -32,15 +30,15 @@ import basicFields from "web.basic_fields";
import Registry from "web.Registry";
import core from "web.core";
import makeTestEnvironment from "web.test_env";
import { registerCleanup } from "../../helpers/cleanup";
import { makeTestEnv } from "../../helpers/mock_env";
import { registerCleanup } from "../helpers/cleanup";
import { makeTestEnv } from "../helpers/mock_env";
import {
fakeTitleService,
makeFakeLocalizationService,
makeFakeRouterService,
makeFakeUIService,
} from "../../helpers/mock_services";
import { getFixture, legacyExtraNextTick, nextTick, patchWithCleanup } from "../../helpers/utils";
} from "../helpers/mock_services";
import { getFixture, legacyExtraNextTick, nextTick, patchWithCleanup } from "../helpers/utils";
import session from "web.session";
import { ComponentAdapter } from "web.OwlCompatibility";
import LegacyMockServer from "web.MockServer";
@@ -51,79 +49,42 @@ const { Component, mount, tags } = owl;
const actionRegistry = registry.category("actions");
const serviceRegistry = registry.category("services");
// -----------------------------------------------------------------------------
// Utils
// -----------------------------------------------------------------------------
/**
* This method create a web client instance properly configured.
*
* Note that the returned web client will be automatically cleaned up after the
* end of the test.
*
* @param {*} params
* Builds the service registry for tests using a WebClient with a default version
* of each required service. If the registry already contains one of those
* services, the existing one is kept (it means it has been added in the test
* directly, e.g. to have a custom version of the service).
*/
export async function createWebClient(params) {
// With the compatibility layer, the action manager keeps legacy alive if they
// are still acessible from the breacrumbs. They are manually destroyed as soon
// as they are no longer referenced in the stack. This works fine in production,
// because the webclient is never destroyed. However, at the end of each test,
// we destroy the webclient and expect every legacy that has been instantiated
// to be destroyed. We thus need to manually destroy them here.
const controllers = [];
patchWithCleanup(AbstractAction.prototype, {
init() {
this._super(...arguments);
controllers.push(this);
},
});
patchWithCleanup(AbstractController.prototype, {
init() {
this._super(...arguments);
controllers.push(this);
},
});
const legacyParams = params.legacyParams;
const models = params.testConfig.serverData.models;
if (legacyParams && legacyParams.withLegacyMockServer && models) {
legacyParams.models = Object.assign({}, models);
// In lagacy, data may not be sole models, but can contain some other variables
// So we filter them out for our WOWL mockServer
Object.entries(legacyParams.models).forEach(([k, v]) => {
if (!(v instanceof Object) || !("fields" in v)) {
delete models[k];
}
});
}
const mockRPC = params.mockRPC || undefined;
const env = await makeTestEnv({
...params.testConfig,
mockRPC,
});
addLegacyMockEnvironment(env, params.testConfig, legacyParams);
const WebClientClass = params.WebClientClass || WebClient;
const target = params && params.target ? params.target : getFixture();
const wc = await mount(WebClientClass, { env, target });
registerCleanup(() => {
for (const controller of controllers) {
if (!controller.isDestroyed()) {
controller.destroy();
}
export function setupWebClientServiceRegistry() {
const services = {
action: () => actionService,
dialog: () => dialogService,
effect: () => effectService,
hotkey: () => hotkeyService,
legacy_service_provider: () => legacyServiceProvider,
localization: () => makeFakeLocalizationService(),
menu: () => menuService,
notification: () => notificationService,
orm: () => ormService,
popover: () => popoverService,
router: () => makeFakeRouterService(),
title: () => fakeTitleService,
ui: () => makeFakeUIService(),
user: () => userService,
view: () => viewService,
};
for (let serviceName in services) {
if (!serviceRegistry.contains(serviceName)) {
serviceRegistry.add(serviceName, services[serviceName]());
}
wc.destroy();
});
// Wait for visual changes caused by a potential loadState
await nextTick();
return wc;
}
}
/**
* Remove this as soon as we drop the legacy support
*/
function addLegacyMockEnvironment(env, testConfig, legacyParams = {}) {
function addLegacyMockEnvironment(env, legacyParams = {}) {
// setup a legacy env
const dataManager = Object.assign(
{
@@ -227,6 +188,74 @@ function addLegacyMockEnvironment(env, testConfig, legacyParams = {}) {
}
}
/**
* This method create a web client instance properly configured.
*
* Note that the returned web client will be automatically cleaned up after the
* end of the test.
*
* @param {*} params
*/
export async function createWebClient(params) {
setupWebClientServiceRegistry();
// With the compatibility layer, the action manager keeps legacy alive if they
// are still acessible from the breacrumbs. They are manually destroyed as soon
// as they are no longer referenced in the stack. This works fine in production,
// because the webclient is never destroyed. However, at the end of each test,
// we destroy the webclient and expect every legacy that has been instantiated
// to be destroyed. We thus need to manually destroy them here.
const controllers = [];
patchWithCleanup(AbstractAction.prototype, {
init() {
this._super(...arguments);
controllers.push(this);
},
});
patchWithCleanup(AbstractController.prototype, {
init() {
this._super(...arguments);
controllers.push(this);
},
});
const legacyParams = params.legacyParams;
params.serverData = params.serverData || {};
const models = params.serverData.models;
if (legacyParams && legacyParams.withLegacyMockServer && models) {
legacyParams.models = Object.assign({}, models);
// In lagacy, data may not be sole models, but can contain some other variables
// So we filter them out for our WOWL mockServer
Object.entries(legacyParams.models).forEach(([k, v]) => {
if (!(v instanceof Object) || !("fields" in v)) {
delete models[k];
}
});
}
const mockRPC = params.mockRPC || undefined;
const env = await makeTestEnv({
serverData: params.serverData,
mockRPC,
});
addLegacyMockEnvironment(env, legacyParams);
const WebClientClass = params.WebClientClass || WebClient;
const target = params && params.target ? params.target : getFixture();
const wc = await mount(WebClientClass, { env, target });
registerCleanup(() => {
for (const controller of controllers) {
if (!controller.isDestroyed()) {
controller.destroy();
}
}
wc.destroy();
});
// Wait for visual changes caused by a potential loadState
await nextTick();
return wc;
}
export async function doAction(env, ...args) {
if (env instanceof Component) {
env = env.env;
@@ -247,41 +276,7 @@ export async function loadState(env, state) {
await legacyExtraNextTick();
}
export function getActionManagerTestConfig() {
patchWithCleanup(
browser,
{
setTimeout: window.setTimeout.bind(window),
clearTimeout: window.clearTimeout.bind(window),
localStorage: makeRAMLocalStorage(),
sessionStorage: makeRAMLocalStorage(),
},
{ pure: true }
);
// build the service registry
// need activateMockServer or something like that for odoo.browser.fetch !!! something is bad
const fakeLocalizationService = makeFakeLocalizationService();
const fakeUIService = makeFakeUIService();
const fakeRouterService = makeFakeRouterService();
serviceRegistry.add("action", actionService);
serviceRegistry.add("dialog", dialogService);
serviceRegistry.add("effect", effectService);
serviceRegistry.add("hotkey", hotkeyService);
serviceRegistry.add("legacy_service_provider", legacyServiceProvider);
serviceRegistry.add("localization", fakeLocalizationService);
serviceRegistry.add("menu", menuService);
serviceRegistry.add("notification", notificationService);
serviceRegistry.add("orm", ormService);
serviceRegistry.add("popover", popoverService);
serviceRegistry.add("router", fakeRouterService);
serviceRegistry.add("title", fakeTitleService);
serviceRegistry.add("ui", fakeUIService);
serviceRegistry.add("user", userService);
serviceRegistry.add("view", viewService);
export function getActionManagerServerData() {
// additional basic client action
class TestClientAction extends Component {}
TestClientAction.template = tags.xml`
@@ -290,7 +285,6 @@ export function getActionManagerTestConfig() {
</div>`;
actionRegistry.add("__test__client__action__", TestClientAction);
// build the mocked server data
const menus = {
root: { id: "root", children: [0, 1, 2], name: "root", appID: "root" },
// id:0 is a hack to not load anything at webClient mount
@@ -534,14 +528,10 @@ export function getActionManagerTestConfig() {
],
},
};
const serverData = {
return {
models,
views: archs,
actions,
menus,
};
return {
browser,
serverData,
};
}
@@ -1,12 +1,13 @@
/** @odoo-module **/
import { browser } from "@web/core/browser/browser";
import { registry } from "@web/core/registry";
import { hotkeyService } from "@web/webclient/hotkeys/hotkey_service";
import { SwitchCompanyMenu } from "@web/webclient/switch_company_menu/switch_company_menu";
import { registerCleanup } from "../helpers/cleanup";
import { makeTestEnv } from "../helpers/mock_env";
import { companyService } from "@web/webclient/company_service";
import { makeFakeRouterService, makeFakeUIService } from "../helpers/mock_services";
import { makeFakeUIService } from "../helpers/mock_services";
import { click, getFixture, makeDeferred, patchWithCleanup } from "../helpers/utils";
const { mount } = owl;
@@ -14,8 +15,18 @@ const serviceRegistry = registry.category("services");
async function createSwitchCompanyMenu(routerParams = {}, toggleDelay = 0) {
patchWithCleanup(SwitchCompanyMenu, { toggleDelay });
if (routerParams.onPushState || routerParams.initialRoute) {
serviceRegistry.add("router", makeFakeRouterService(routerParams));
if (routerParams.onPushState) {
const pushState = browser.history.pushState;
patchWithCleanup(browser, {
history: Object.assign({}, browser.history, {
pushState(state, title, url) {
pushState(...arguments);
if (routerParams.onPushState) {
routerParams.onPushState(url);
}
},
}),
});
}
const env = await makeTestEnv();
const target = getFixture();
@@ -212,8 +223,8 @@ QUnit.module("SwitchCompanyMenu", (hooks) => {
function onPushState(url) {
assert.step(url.split("#")[1]);
}
const initialRoute = { hash: "cids=3%2C1" };
const scMenu = await createSwitchCompanyMenu({ onPushState, initialRoute });
Object.assign(browser.location, { hash: "cids=3%2C1" });
const scMenu = await createSwitchCompanyMenu({ onPushState });
/**
* [x] Company 1
@@ -243,8 +254,8 @@ QUnit.module("SwitchCompanyMenu", (hooks) => {
function onPushState(url) {
assert.step(url.split("#")[1]);
}
const initialRoute = { hash: "cids=2%2C3" };
const scMenu = await createSwitchCompanyMenu({ onPushState, initialRoute });
Object.assign(browser.location, { hash: "cids=2%2C3" });
const scMenu = await createSwitchCompanyMenu({ onPushState });
/**
* [ ] Company 1
@@ -8,13 +8,9 @@ var createView = testUtils.createView;
var BaseSettingsView = view_registry.get('base_settings');
const { legacyExtraNextTick } = require("@web/../tests/helpers/utils");
const {
createWebClient,
doAction,
getActionManagerTestConfig,
} = require("@web/../tests/webclient/actions/helpers");
const { createWebClient, doAction } = require("@web/../tests/webclient/helpers");
let testConfig;
let serverData;
QUnit.module('base_settings_tests', {
beforeEach: function () {
this.data = {
@@ -29,9 +25,7 @@ QUnit.module('base_settings_tests', {
fields: {}
}
};
testConfig = getActionManagerTestConfig();
const models = Object.assign(testConfig.serverData.models, this.data);
Object.assign(testConfig.serverData, { models });
serverData = { models: this.data };
}
}, function () {
@@ -105,7 +99,7 @@ QUnit.module('base_settings_tests', {
async function (assert) {
assert.expect(8);
testConfig.serverData.actions = {
serverData.actions = {
1: {
id: 1,
name: "Settings view",
@@ -122,7 +116,7 @@ QUnit.module('base_settings_tests', {
},
};
testConfig.serverData.views = {
serverData.views = {
"res.config.settings,1,form":
`<form string="Settings" js_class="base_settings">
<div class="app_settings_block" string="CRM" data-key="crm">
@@ -140,7 +134,7 @@ QUnit.module('base_settings_tests', {
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 1);
await testUtils.dom.click($(webClient.el).find('button[name="4"]'));
@@ -165,7 +159,7 @@ QUnit.module('base_settings_tests', {
async function (assert) {
assert.expect(11);
testConfig.serverData.actions = {
serverData.actions = {
1: {
id: 1,
name: "Settings view",
@@ -182,7 +176,7 @@ QUnit.module('base_settings_tests', {
},
};
testConfig.serverData.views = {
serverData.views = {
"res.config.settings,1,form":
`<form string="Settings" js_class="base_settings">
<header>
@@ -224,7 +218,7 @@ QUnit.module('base_settings_tests', {
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 1);
assert.containsNone(
@@ -409,7 +403,7 @@ QUnit.module('base_settings_tests', {
// This commit fixes a race condition, that's why we artificially slow down a read rpc
assert.expect(4);
testConfig.serverData.actions = {
serverData.actions = {
1: {
id: 1,
name: "First action",
@@ -433,7 +427,7 @@ QUnit.module('base_settings_tests', {
},
};
testConfig.serverData.views = {
serverData.views = {
"task,1,list": '<tree><field name="display_name"/></tree>',
"res.config.settings,2,form": `
<form string="Settings" js_class="base_settings">
@@ -453,7 +447,7 @@ QUnit.module('base_settings_tests', {
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 1);
assert.strictEqual($(webClient.el).find(".breadcrumb").text(), "First action");
@@ -531,15 +525,24 @@ QUnit.module('base_settings_tests', {
async function (assert) {
assert.expect(7);
testConfig.serverData.actions[1] = {
id: 1,
name: "Settings view",
res_model: "res.config.settings",
type: "ir.actions.act_window",
views: [[1, "form"]],
serverData.actions = {
1: {
id: 1,
name: "Settings view",
res_model: "res.config.settings",
type: "ir.actions.act_window",
views: [[1, "form"]],
},
4: {
id: 4,
name: "Other Action",
res_model: "task",
type: "ir.actions.act_window",
views: [[false, "list"]],
}
};
testConfig.serverData.views = Object.assign(testConfig.serverData.views, {
serverData.views = {
"res.config.settings,1,form": `
<form string="Settings" js_class="base_settings">
<div class="app_settings_block" string="CRM" data-key="crm">
@@ -561,7 +564,9 @@ QUnit.module('base_settings_tests', {
</form>
`,
"res.config.settings,false,search": "<search></search>",
});
"task,false,list": "<tree></tree>",
"task,false,search": "<search></search>",
};
const mockRPC = (route, args) => {
if (route === "/web/dataset/call_button" && args.method === "execute") {
@@ -572,7 +577,7 @@ QUnit.module('base_settings_tests', {
}
};
const webClient = await createWebClient({ testConfig, mockRPC });
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 1);
assert.containsNone(