Files
odoo_source/addons/web/static/tests/search/with_search_tests.js
T
+2 b0f20bcd09 [REF] web: adapt ControlPanel to support new owl views
This commit contains several adaptations of the Layout, WithSearch,
ControlPanel and its children components with respect to the
conversion of kanban, list and form views in owl.

In a nutshell:
 - ActionMenus: we didn't have an implementation yet, as already
   converted views do not need it.
 - ControlPanel: allow to move the focus from the search bar to
   the view and vice-versa + slight rework of the template to
   properly handle hidden areas.
 - CustomFilterItems: adapt to formatter/parser changes.
 - Layout: hide breadcrumbs in dialogs and allow to move control
   panel buttons in the footer (in dialogs as well)
 - WithSearch: only pass search props to the underlying view +
   take its content in a default slot

Part-of: odoo/odoo#92475
Co-authored-by: Aaron Bohy <aab@odoo.com>
Co-authored-by: Bruno Boi <boi@odoo.com>
Co-authored-by: Géry Debongnie <ged@odoo.com>
Co-authored-by: Samuel Degueldre <sad@odoo.com>
Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com>
Co-authored-by: Simon Genin (ges) <ges@odoo.com>
Co-authored-by: Francois (fge) <fge@odoo.com>
Co-authored-by: Michael Mattiello (mcm) <mcm@odoo.com>
Co-authored-by: Julien Mougenot <jum@odoo.com>
Co-authored-by: Lucas Perais (lpe) <lpe@odoo.com>
Co-authored-by: Jorge Pinna Puissant <jpp@odoo.com>
Co-authored-by: luvi <luvi@odoo.com>
2022-06-30 09:29:44 +02:00

346 lines
12 KiB
JavaScript

/** @odoo-module **/
import { makeTestEnv } from "@web/../tests/helpers/mock_env";
import { getFixture, nextTick } from "@web/../tests/helpers/utils";
import { hotkeyService } from "@web/core/hotkeys/hotkey_service";
import { ormService } from "@web/core/orm_service";
import { registry } from "@web/core/registry";
import { FilterMenu } from "@web/search/filter_menu/filter_menu";
import { GroupByMenu } from "@web/search/group_by_menu/group_by_menu";
import { WithSearch } from "@web/search/with_search/with_search";
import { viewService } from "@web/views/view_service";
import { mount } from "../helpers/utils";
import {
getMenuItemTexts,
makeWithSearch,
toggleFilterMenu,
toggleGroupByMenu,
toggleMenuItem,
} from "./helpers";
const { Component, onWillUpdateProps, onWillStart, useState, xml } = owl;
const serviceRegistry = registry.category("services");
let target;
let serverData;
QUnit.module("Search", (hooks) => {
hooks.beforeEach(async () => {
serverData = {
models: {
animal: {
fields: {
birthday: { string: "Birthday", type: "date", store: true },
type: {
string: "Type",
type: "selection",
selection: [
["omnivorous", "Omnivorous"],
["herbivorous", "Herbivorous"],
["carnivorous", "Carnivorous"],
],
store: true,
},
},
},
},
views: {
"animal,false,search": `<search/>`,
"animal,1,search": `
<search>
<filter name="filter" string="True domain" domain="[(1, '=', 1)]"/>
<filter name="group_by" context="{ 'group_by': 'name' }"/>
</search>
`,
},
};
serviceRegistry.add("hotkey", hotkeyService);
serviceRegistry.add("orm", ormService);
serviceRegistry.add("view", viewService);
target = getFixture();
});
QUnit.module("WithSearch");
QUnit.test("simple rendering", async function (assert) {
assert.expect(2);
class TestComponent extends Component {}
TestComponent.template = xml`<div class="o_test_component">Test component content</div>`;
await makeWithSearch({
serverData,
resModel: "animal",
Component: TestComponent,
});
assert.containsOnce(target, ".o_test_component");
assert.strictEqual(
target.querySelector(".o_test_component").innerText,
"Test component content"
);
});
QUnit.test("search model in sub env", async function (assert) {
assert.expect(1);
class TestComponent extends Component {}
TestComponent.template = xml`<div class="o_test_component">Test component content</div>`;
const component = await makeWithSearch({
serverData,
resModel: "animal",
Component: TestComponent,
});
assert.ok(component.env.searchModel);
});
QUnit.test(
"search query props are passed as props to concrete component",
async function (assert) {
assert.expect(4);
class TestComponent extends Component {
setup() {
const { context, domain, groupBy, orderBy } = this.props;
assert.deepEqual(context, {
lang: "en",
tz: "taht",
uid: 7,
key: "val",
});
assert.deepEqual(domain, [[0, "=", 1]]);
assert.deepEqual(groupBy, ["birthday"]);
assert.deepEqual(orderBy, ["bar"]);
}
}
TestComponent.template = xml`<div class="o_test_component">Test component content</div>`;
await makeWithSearch({
serverData,
resModel: "animal",
Component: TestComponent,
domain: [[0, "=", 1]],
groupBy: ["birthday"],
context: { key: "val" },
orderBy: ["bar"],
});
}
);
QUnit.test("do not load search view description by default", async function (assert) {
assert.expect(1);
class TestComponent extends Component {}
TestComponent.template = xml`<div class="o_test_component">Test component content</div>`;
await makeWithSearch({
serverData,
mockRPC: function (_, args) {
if (args.method === "get_views") {
throw new Error("No get_views should be done");
}
},
resModel: "animal",
Component: TestComponent,
});
assert.ok(true);
});
QUnit.test(
"load search view description if not provided and loadSearchView=true",
async function (assert) {
assert.expect(1);
class TestComponent extends Component {}
TestComponent.template = xml`<div class="o_test_component">Test component content</div>`;
await makeWithSearch({
serverData,
mockRPC: function (_, args) {
if (args.method === "get_views") {
assert.deepEqual(args.kwargs, {
context: {
lang: "en",
tz: "taht",
uid: 7,
},
options: {
action_id: false,
load_filters: false,
toolbar: false,
},
views: [[false, "search"]],
});
}
},
resModel: "animal",
Component: TestComponent,
searchViewId: false,
});
}
);
QUnit.test(
"do not load the search view description if provided even if loadSearchView=true",
async function (assert) {
assert.expect(1);
class TestComponent extends Component {}
TestComponent.template = xml`<div class="o_test_component">Test component content</div>`;
await makeWithSearch({
serverData,
mockRPC: function (_, args) {
if (args.method === "get_views") {
throw new Error("No get_views should be done");
}
},
resModel: "animal",
Component: TestComponent,
searchViewArch: "<search/>",
searchViewFields: {},
searchViewId: false,
});
assert.ok(true);
}
);
QUnit.test(
"load view description if it is not complete and loadSearchView=true",
async function (assert) {
assert.expect(1);
class TestComponent extends Component {}
TestComponent.template = xml`<div class="o_test_component">Test component content</div>`;
await makeWithSearch({
serverData,
mockRPC: function (_, args) {
if (args.method === "get_views") {
assert.deepEqual(args.kwargs.options, {
action_id: false,
load_filters: true,
toolbar: false,
});
}
},
resModel: "animal",
Component: TestComponent,
searchViewArch: "<search/>",
searchViewFields: {},
searchViewId: true,
loadIrFilters: true,
});
}
);
QUnit.test(
"load view description with given id if it is not provided and loadSearchView=true",
async function (assert) {
assert.expect(3);
class TestComponent extends Component {}
TestComponent.components = { FilterMenu, GroupByMenu };
TestComponent.template = xml`
<div class="o_test_component">
<FilterMenu/>
<GroupByMenu/>
</div>
`;
await makeWithSearch({
serverData,
mockRPC: function (_, args) {
if (args.method === "get_views") {
assert.deepEqual(args.kwargs.views, [[1, "search"]]);
}
},
resModel: "animal",
Component: TestComponent,
searchViewId: 1,
});
await toggleFilterMenu(target);
await assert.ok(getMenuItemTexts(target), ["True Domain"]);
await toggleGroupByMenu(target);
await assert.ok(getMenuItemTexts(target), ["Name"]);
}
);
QUnit.test(
"toggle a filter render the underlying component with an updated domain",
async function (assert) {
assert.expect(2);
class TestComponent extends Component {
setup() {
owl.onWillStart(() => {
assert.deepEqual(this.props.domain, []);
});
owl.onWillUpdateProps((nextProps) => {
assert.deepEqual(nextProps.domain, [[1, "=", 1]]);
});
}
}
TestComponent.components = { FilterMenu };
TestComponent.template = xml`
<div class="o_test_component">
<FilterMenu/>
</div>
`;
await makeWithSearch({
serverData,
resModel: "animal",
Component: TestComponent,
searchViewId: 1,
});
await toggleFilterMenu(target);
await toggleMenuItem(target, "True domain");
}
);
QUnit.test("react to prop 'domain' changes", async function (assert) {
assert.expect(2);
class TestComponent extends Component {
setup() {
onWillStart(() => {
assert.deepEqual(this.props.domain, [["type", "=", "carnivorous"]]);
});
onWillUpdateProps((nextProps) => {
assert.deepEqual(nextProps.domain, [["type", "=", "herbivorous"]]);
});
}
}
TestComponent.template = xml`<div class="o_test_component">Test component content</div>`;
const env = await makeTestEnv(serverData);
const target = getFixture();
class Parent extends Component {
setup() {
this.searchState = useState({
resModel: "animal",
domain: [["type", "=", "carnivorous"]],
});
}
}
Parent.template = xml`
<WithSearch t-props="searchState" t-slot-scope="search">
<TestComponent
domain="search.domain"
/>
</WithSearch>
`;
Parent.components = { WithSearch, TestComponent };
const parent = await mount(Parent, target, { env });
parent.searchState.domain = [["type", "=", "herbivorous"]];
await nextTick();
});
});