/** @odoo-module **/
import { getFixture, legacyExtraNextTick, patchWithCleanup } from "@web/../tests/helpers/utils";
import {
getFacetTexts,
removeFacet,
saveFavorite,
setupControlPanelFavoriteMenuRegistry,
setupControlPanelServiceRegistry,
switchView,
toggleFavoriteMenu,
toggleMenu,
toggleMenuItem,
toggleSaveFavorite,
} from "@web/../tests/search/helpers";
import { createWebClient, doAction } from "@web/../tests/webclient/helpers";
import { _lt } from "@web/core/l10n/translation";
import { registry } from "@web/core/registry";
import { ControlPanel } from "@web/search/control_panel/control_panel";
import { SearchModel } from "@web/search/search_model";
import AbstractView from "web.AbstractView";
import ActionModel from "web.ActionModel";
import { mock } from "web.test_utils";
import legacyViewRegistry from "web.view_registry";
import { browser } from "@web/core/browser/browser";
import { LegacyComponent } from "@web/legacy/legacy_component";
import { xml } from "@odoo/owl";
const viewRegistry = registry.category("views");
let serverData;
let target;
QUnit.module("LegacyViews", (hooks) => {
hooks.beforeEach(async () => {
target = getFixture();
serverData = {
models: {
foo: {
fields: {
display_name: { string: "Displayed name", type: "char" },
foo: {
string: "Foo",
type: "char",
default: "My little Foo Value",
store: true,
sortable: true,
},
date_field: { string: "Date", type: "date", store: true, sortable: true },
float_field: { string: "Float", type: "float" },
bar: {
string: "Bar",
type: "many2one",
relation: "partner",
store: true,
sortable: true,
},
},
records: [],
},
},
views: {
"foo,false,legacy_toy": ``,
"foo,false,toy": ``,
"foo,false,search": `
`,
},
};
setupControlPanelFavoriteMenuRegistry();
setupControlPanelServiceRegistry();
class ToyController extends LegacyComponent {}
ToyController.template = xml`
`;
ToyController.components = { ControlPanel};
viewRegistry.add("toy", {
type: "toy",
display_name: _lt("Toy view"),
multiRecord: true,
searchMenuTypes: ["filter", "groupBy", "comparison", "favorite"],
Controller: ToyController,
});
const LegacyToyView = AbstractView.extend({
display_name: _lt("Legacy toy view"),
icon: "fa fa-bars",
multiRecord: true,
viewType: "legacy_toy",
searchMenuTypes: ["filter", "groupBy", "comparison", "favorite"],
});
legacyViewRegistry.add("legacy_toy", LegacyToyView);
});
QUnit.module("State Mappings");
QUnit.test(
"legacy and new views can share search model state (no favorite)",
async function (assert) {
assert.expect(10);
const unpatchDate = mock.patchDate(2021, 6, 1, 10, 0, 0);
const webClient = await createWebClient({ serverData });
await doAction(webClient, {
name: "Action name",
res_model: "foo",
type: "ir.actions.act_window",
views: [
[false, "toy"],
[false, "legacy_toy"],
],
context: {
search_default_foo: "ABC",
search_default_true_domain: 1,
search_default_date_domain: 1,
search_default_group_by_bar: 50,
search_default_group_by_date_field: 1,
},
});
assert.containsOnce(target, ".o_switch_view.o_toy.active");
assert.deepEqual(
getFacetTexts(target).map((s) => s.replace(/\s/, "")),
[
"FooABC",
"TrueDomainorDate Filter: July 2021",
"DateGroupBy: Month>Bar",
]
);
await toggleMenu(target, "Comparison");
await toggleMenuItem(target, "Date Filter: Previous Period");
assert.deepEqual(
getFacetTexts(target).map((s) => s.replace(/\s/, "")),
[
"FooABC",
"TrueDomainorDate Filter: July 2021",
"DateGroupBy: Month>Bar",
"DateFilter: Previous Period",
]
);
await switchView(target, "legacy_toy");
await legacyExtraNextTick();
assert.containsOnce(target, ".o_switch_view.o_legacy_toy.active");
assert.deepEqual(
getFacetTexts(target).map((s) => s.replace(/\s/, "")),
[
"FooABC",
"TrueDomainorDate Filter: July 2021",
"DateGroupBy: Month>Bar",
"DateFilter: Previous Period",
]
);
await removeFacet(target, 1);
assert.deepEqual(
getFacetTexts(target).map((s) => s.replace(/\s/, "")),
[
"FooABC",
"DateGroupBy: Month>Bar",
]
);
await switchView(target, "toy");
assert.containsOnce(target, ".o_switch_view.o_toy.active");
assert.deepEqual(
getFacetTexts(target).map((s) => s.replace(/\s/, "")),
[
"FooABC",
"DateGroupBy: Month>Bar",
]
);
// Check if update works
await removeFacet(target, 1);
assert.deepEqual(
getFacetTexts(target).map((s) => s.replace(/\s/, "")),
[
"FooABC",
]
);
await switchView(target, "legacy_toy");
assert.deepEqual(
getFacetTexts(target).map((s) => s.replace(/\s/, "")),
[
"FooABC",
]
);
unpatchDate();
}
);
QUnit.test(
"legacy and new views can share search model state (favorite)",
async function (assert) {
assert.expect(6);
serverData.models.foo.filters = [
{
context: "{}",
domain: "[['foo', '=', 'qsdf']]",
id: 7,
is_default: true,
name: "My favorite",
sort: "[]",
user_id: [2, "Mitchell Admin"],
},
];
const webClient = await createWebClient({ serverData });
await doAction(webClient, {
name: "Action name",
res_model: "foo",
type: "ir.actions.act_window",
views: [
[false, "toy"],
[false, "legacy_toy"],
],
});
assert.containsOnce(target, ".o_switch_view.o_toy.active");
assert.deepEqual(getFacetTexts(target), ["My favorite"]);
await switchView(target, "legacy_toy");
await legacyExtraNextTick();
assert.containsOnce(target, ".o_switch_view.o_legacy_toy.active");
assert.deepEqual(getFacetTexts(target), ["My favorite"]);
await switchView(target, "toy");
assert.containsOnce(target, ".o_switch_view.o_toy.active");
assert.deepEqual(getFacetTexts(target), ["My favorite"]);
}
);
QUnit.test(
"newly created favorite in a new view can be used in a legacy view",
async function (assert) {
assert.expect(5);
patchWithCleanup(browser, { setTimeout: (fn) => fn() });
const webClient = await createWebClient({
serverData,
mockRPC(_, args) {
if (args.method === "create_or_replace") {
assert.ok(typeof args.args[0].domain === "string");
return 7; // fake serverId to simulate the creation of
// the favorite in db.
}
},
});
await doAction(webClient, {
name: "Action name",
res_model: "foo",
type: "ir.actions.act_window",
views: [
[false, "toy"],
[false, "legacy_toy"],
],
});
assert.containsOnce(target, ".o_switch_view.o_toy.active");
await toggleFavoriteMenu(target);
await toggleSaveFavorite(target);
await saveFavorite(target);
assert.deepEqual(getFacetTexts(target), ["Action name"]);
await switchView(target, "legacy_toy");
await legacyExtraNextTick();
assert.containsOnce(target, ".o_switch_view.o_legacy_toy.active");
assert.deepEqual(getFacetTexts(target), ["Action name"]);
}
);
QUnit.test(
"legacy and new views with search model extensions can share search model state",
async function (assert) {
assert.expect(16);
serverData.views[
"foo,1,legacy_toy"
] = ``;
class SearchModelExtension extends SearchModel {
setup() {
super.setup(...arguments);
this.toyExtension = { locationId: "Grand-Rosière" };
}
exportState() {
const exportedState = super.exportState(...arguments);
exportedState.toyExtension = this.toyExtension;
return exportedState;
}
_importState(state) {
super._importState(state);
this.toyExtension = state.toyExtension;
assert.step(JSON.stringify(state.toyExtension));
}
}
const ToyView = viewRegistry.get("toy");
ToyView.SearchModel = SearchModelExtension;
class ToyExtension extends ActionModel.Extension {
importState(state) {
super.importState(state); // done even if state is undefined in legacy code
assert.step(JSON.stringify(state) || "no state");
}
prepareState() {
Object.assign(this.state, {
locationId: "The place to be",
});
}
}
ActionModel.registry.add("toyExtension", ToyExtension);
const LegacyToyView = legacyViewRegistry.get("legacy_toy");
const LegacyToyViewWithExtension = LegacyToyView.extend({
_createSearchModel(params, extraExtensions = {}) {
Object.assign(extraExtensions, { toyExtension: {} });
return this._super(params, extraExtensions);
},
});
legacyViewRegistry.add("legacy_toy_with_extension", LegacyToyViewWithExtension);
const webClient = await createWebClient({ serverData });
await doAction(webClient, {
name: "Action name",
res_model: "foo",
type: "ir.actions.act_window",
views: [
[false, "toy"],
[1, "legacy_toy"],
],
});
assert.containsOnce(target, ".o_switch_view.o_toy.active");
await switchView(target, "legacy_toy");
await legacyExtraNextTick();
assert.containsOnce(target, ".o_switch_view.o_legacy_toy.active");
assert.verifySteps([`{"locationId":"Grand-Rosière"}`]);
await switchView(target, "toy");
assert.containsOnce(target, ".o_switch_view.o_toy.active");
assert.verifySteps([`{"locationId":"Grand-Rosière"}`]);
await doAction(webClient, {
name: "Action name",
res_model: "foo",
type: "ir.actions.act_window",
views: [
[1, "legacy_toy"],
[false, "toy"],
],
});
await legacyExtraNextTick();
assert.containsOnce(target, ".o_switch_view.o_legacy_toy.active");
assert.verifySteps([`no state`]);
await switchView(target, "toy");
assert.containsOnce(target, ".o_switch_view.o_toy.active");
assert.verifySteps([`{"locationId":"The place to be"}`]);
await switchView(target, "legacy_toy");
await legacyExtraNextTick();
assert.containsOnce(target, ".o_switch_view.o_legacy_toy.active");
assert.verifySteps([`{"locationId":"The place to be"}`]);
}
);
});