Files
odoo_source/addons/web/static/tests/views/layout_tests.js
T
Aaron Bohy 5134eac428 [FIX] web: do not display control panel in form views in dialogs
Form views in dialogs should not display a control panel. Before
this commit, they did. To fix the issue, we reworked a bit how we
pass to the Layout component its "display" information (e.g.
whether it should display a control panel, and which parts of it).
Before this commit, it retrieved this info from the searchModel, in
the env. This doesn't allow a specific view to override it, for
instance the form view when it's in a dialog. To ease this, we
changed the Layout component s.t. it now takes a "display" props,
and no longer looks in the searchModel. Each view thus needs to
pass this as props.

closes odoo/odoo#96818

Related: odoo/enterprise#29857
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
2022-07-28 03:51:11 +02:00

258 lines
8.8 KiB
JavaScript

/** @odoo-module **/
import { getFixture, mount } from "@web/../tests/helpers/utils";
import { makeWithSearch, setupControlPanelServiceRegistry } from "@web/../tests/search/helpers";
import { dialogService } from "@web/core/dialog/dialog_service";
import { registry } from "@web/core/registry";
import { Layout } from "@web/search/layout";
import { getDefaultConfig } from "@web/views/view";
import { makeTestEnv } from "@web/../tests/helpers/mock_env";
const { Component, xml, useChildSubEnv } = owl;
const serviceRegistry = registry.category("services");
let target;
let serverData;
QUnit.module("Views", (hooks) => {
hooks.beforeEach(() => {
serverData = {
models: {
foo: {
fields: {
aaa: {
type: "selection",
selection: [
["a", "A"],
["b", "B"],
],
},
},
records: [],
},
},
views: {
"foo,false,search": /* xml */ `
<search>
<searchpanel>
<field name="aaa" />
</searchpanel>
</search>`,
},
};
setupControlPanelServiceRegistry();
serviceRegistry.add("dialog", dialogService);
target = getFixture();
});
QUnit.module("Layout");
QUnit.test("Simple rendering", async (assert) => {
class ToyComponent extends Component {}
ToyComponent.template = xml`
<Layout className="'o_view_sample_data'" display="props.display">
<div class="toy_content" />
</Layout>`;
ToyComponent.components = { Layout };
const env = await makeTestEnv({ config: {} });
await mount(ToyComponent, getFixture(), { env });
assert.containsOnce(target, ".o_view_sample_data");
assert.containsNone(target, ".o_control_panel");
assert.containsNone(target, ".o_component_with_search_panel");
assert.containsNone(target, ".o_search_panel");
assert.containsOnce(target, ".o_content > .toy_content");
});
QUnit.test("Simple rendering: with search", async (assert) => {
class ToyComponent extends Component {}
ToyComponent.template = xml`
<Layout display="props.display">
<t t-set-slot="control-panel-top-right">
<div class="toy_search_bar" />
</t>
<div class="toy_content" />
</Layout>`;
ToyComponent.components = { Layout };
await makeWithSearch({
serverData,
Component: ToyComponent,
resModel: "foo",
searchViewId: false,
});
assert.containsOnce(target, ".o_control_panel .o_cp_top_right .toy_search_bar");
assert.containsOnce(target, ".o_component_with_search_panel .o_search_panel");
assert.containsNone(target, ".o_cp_searchview");
assert.containsOnce(target, ".o_content > .toy_content");
});
QUnit.test("Nested layouts", async (assert) => {
// Component C: bottom (no control panel)
class ToyC extends Component {
get display() {
return {
controlPanel: false,
searchPanel: true,
};
}
}
ToyC.template = xml`
<Layout className="'toy_c'" display="display">
<div class="toy_c_content" />
</Layout>`;
ToyC.components = { Layout };
// Component B: center (with custom search panel)
class SearchPanel extends Component {}
SearchPanel.template = xml`<div class="o_toy_search_panel" />`;
class ToyB extends Component {
setup() {
useChildSubEnv({
config: {
...getDefaultConfig(),
SearchPanel,
},
});
}
}
ToyB.template = xml`
<Layout className="'toy_b'" display="props.display">
<t t-set-slot="control-panel-top-right">
<div class="toy_b_breadcrumbs" />
</t>
<ToyC/>
</Layout>`;
ToyB.components = { Layout, ToyC };
// Component A: top
class ToyA extends Component {}
ToyA.template = xml`
<Layout className="'toy_a'" display="props.display">
<t t-set-slot="control-panel-top-right">
<div class="toy_a_search" />
</t>
<ToyB display="props.display"/>
</Layout>`;
ToyA.components = { Layout, ToyB };
await makeWithSearch({
serverData,
Component: ToyA,
resModel: "foo",
searchViewId: false,
});
assert.containsOnce(target, ".o_content.toy_a .o_content.toy_b .o_content.toy_c"); // Full chain of contents
assert.containsN(target, ".o_control_panel", 2); // Component C has hidden its control panel
assert.containsN(target, ".o_content.o_component_with_search_panel", 3);
assert.containsOnce(target, ".o_search_panel"); // Standard search panel
assert.containsN(target, ".o_toy_search_panel", 2); // Custom search panels
assert.containsOnce(target, ".toy_a_search");
assert.containsOnce(target, ".toy_b_breadcrumbs");
assert.containsOnce(target, ".toy_c_content");
});
QUnit.test("Custom control panel", async (assert) => {
class ToyComponent extends Component {}
ToyComponent.template = xml`
<Layout display="props.display">
<div class="o_toy_content" />
</Layout>`;
ToyComponent.components = { Layout };
class ControlPanel extends Component {}
ControlPanel.template = xml`<div class="o_toy_search_panel" />`;
await makeWithSearch({
serverData,
Component: ToyComponent,
resModel: "foo",
searchViewId: false,
config: { ControlPanel },
});
assert.containsOnce(target, ".o_toy_content");
assert.containsOnce(target, ".o_toy_search_panel");
assert.containsNone(target, ".o_control_panel");
});
QUnit.test("Custom search panel", async (assert) => {
class ToyComponent extends Component {}
ToyComponent.template = xml`
<Layout display="props.display">
<div class="o_toy_content" />
</Layout>`;
ToyComponent.components = { Layout };
class SearchPanel extends Component {}
SearchPanel.template = xml`<div class="o_toy_search_panel" />`;
await makeWithSearch({
serverData,
Component: ToyComponent,
resModel: "foo",
searchViewId: false,
config: { SearchPanel },
});
assert.containsOnce(target, ".o_toy_content");
assert.containsOnce(target, ".o_toy_search_panel");
assert.containsNone(target, ".o_search_panel");
});
QUnit.test("Custom banner: no bannerRoute in env", async (assert) => {
class ToyComponent extends Component {}
ToyComponent.template = xml`
<Layout display="props.display">
<div class="o_toy_content" />
</Layout>`;
ToyComponent.components = { Layout };
class Banner extends Component {}
Banner.template = xml`<div class="o_toy_banner" />`;
await makeWithSearch({
serverData,
Component: ToyComponent,
resModel: "foo",
searchViewId: false,
config: { Banner },
});
assert.containsOnce(target, ".o_toy_content");
assert.containsNone(target, ".o_toy_banner");
});
QUnit.test("Custom banner: with bannerRoute in env", async (assert) => {
class ToyComponent extends Component {}
ToyComponent.template = xml`
<Layout display="props.display">
<div class="o_toy_content" />
</Layout>`;
ToyComponent.components = { Layout };
class Banner extends Component {}
Banner.template = xml`<div class="o_toy_banner" />`;
await makeWithSearch({
serverData,
Component: ToyComponent,
resModel: "foo",
searchViewId: false,
config: { Banner, bannerRoute: "toy/banner/route" },
});
assert.containsOnce(target, ".o_toy_content");
assert.containsOnce(target, ".o_toy_banner");
assert.notOk(target.querySelector(".o_toy_banner").closest(".o_content"));
assert.ok(target.querySelector(".o_toy_content").closest(".o_content"));
});
});