[IMP] *: use new dropdown in legacy too

This commit replaces the control panel dropdowns with the new <Dropdown/> component, in order to get consistent through the new/legacy views (because the current Odoo version is in a state where some views uses the new infrastructure and some others are still not converted - see odoo/odoo#73311).

The diff seems massive, but it is mostly due to tests adaptations.

closes odoo/odoo#77001

X-original-commit: d679cd0d8ba9a2420e81a42a698763e9be2327e1
Related: odoo/enterprise#21077
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Co-authored-by: Aaron Bohy <aab@odoo.com>
Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com>
This commit is contained in:
Bruno Boi
2021-09-23 07:17:43 +00:00
committed by Aaron Bohy
co-authored by Aaron Bohy Mathieu Duckerts-Antoine
parent ee2ae9a75b
commit 36988d0edc
62 changed files with 1043 additions and 1291 deletions
@@ -1,18 +1,17 @@
odoo.define('base_import.ImportMenu', function (require) {
"use strict";
const DropdownMenuItem = require('web.DropdownMenuItem');
const FavoriteMenu = require('web.FavoriteMenu');
const { useModel } = require('web.Model');
const { Component } = owl;
/**
* Import Records menu
*
* This component is used to import the records for particular model.
*
* @extends DropdownMenuItem
*/
class ImportMenu extends DropdownMenuItem {
class ImportMenu extends Component {
constructor() {
super(...arguments);
this.model = useModel('searchModel');
@@ -25,7 +24,7 @@ odoo.define('base_import.ImportMenu', function (require) {
/**
* @private
*/
_onImportClick() {
importRecords() {
const action = {
type: 'ir.actions.client',
tag: 'import',
@@ -56,7 +55,7 @@ odoo.define('base_import.ImportMenu', function (require) {
}
ImportMenu.props = {};
ImportMenu.template = 'base_import.ImportMenu';
ImportMenu.template = "base_import.ImportRecords";
FavoriteMenu.registry.add('import-menu', ImportMenu, 1);
@@ -1,12 +1,4 @@
<templates>
<t t-name="base_import.ImportMenu" owl="1">
<li class="o_menu_item o_import_menu" role="menuitem">
<button type="button" class="dropdown-item" t-on-click="_onImportClick">
Import records
</button>
</li>
</t>
<t t-name="ImportView">
<t t-set="_id" t-value="_.uniqueId('export')"/>
<form action="" method="post" enctype="multipart/form-data" class="oe_import">
@@ -6,12 +6,15 @@ const FormView = require('web.FormView');
const ListView = require('web.ListView');
const PivotView = require('web.PivotView');
const testUtils = require('web.test_utils');
const FavoriteMenu = require("web.FavoriteMenu");
const ImportMenu = require("base_import.ImportMenu");
const cpHelpers = testUtils.controlPanel;
const cpHelpers = require('@web/../tests/search/helpers');
const createView = testUtils.createView;
QUnit.module('Base Import Tests', {
beforeEach: function () {
FavoriteMenu.registry.add("import-menu", ImportMenu, 1);
this.data = {
foo: {
fields: {
@@ -42,7 +45,7 @@ QUnit.test('import in favorite dropdown in list', async function (assert) {
await testUtils.dom.click(list.$('.o_favorite_menu button'));
assert.containsOnce(list, '.o_import_menu');
await testUtils.dom.click(list.$('.o_import_menu button'));
await testUtils.dom.click(list.$('.o_import_menu'));
list.destroy();
});
@@ -102,7 +105,7 @@ QUnit.test('import in favorite dropdown in kanban', async function (assert) {
await testUtils.dom.click(kanban.$('.o_favorite_menu button'));
assert.containsOnce(kanban, '.o_import_menu');
await testUtils.dom.click(kanban.$('.o_import_menu button'));
await testUtils.dom.click(kanban.$('.o_import_menu'));
kanban.destroy();
});
@@ -198,8 +201,9 @@ QUnit.test('import should not be available in favorite dropdown in dialog view',
item: 'Search More',
search: '',
});
await cpHelpers.toggleFavoriteMenu('.modal');
assert.containsNone(document.querySelector('.modal'), '.o_import_menu',
const modal = document.querySelector('.modal');
await cpHelpers.toggleFavoriteMenu(modal);
assert.containsNone(modal, '.o_import_menu',
"Import menu should not be available");
form.destroy();
@@ -3,12 +3,11 @@ odoo.define('board.AddToBoardMenu', function (require) {
const Context = require('web.Context');
const Domain = require('web.Domain');
const DropdownMenuItem = require('web.DropdownMenuItem');
const FavoriteMenu = require('web.FavoriteMenu');
const { sprintf } = require('web.utils');
const { useAutofocus } = require('web.custom_hooks');
const { useState } = owl.hooks;
const { Component, useState } = owl;
/**
* 'Add to board' menu
@@ -21,9 +20,8 @@ odoo.define('board.AddToBoardMenu', function (require) {
* properties to the server to add the current view (and its context) to the
* user's dashboard.
* This component is only available in actions of type 'ir.actions.act_window'.
* @extends DropdownMenuItem
*/
class AddToBoardMenu extends DropdownMenuItem {
class AddToBoardMenu extends Component {
constructor() {
super(...arguments);
@@ -46,7 +44,7 @@ odoo.define('board.AddToBoardMenu', function (require) {
* information.
* @private
*/
async _addToBoard() {
async addToBoard() {
const searchQuery = this.env.searchModel.get('query');
const context = new Context(this.env.action.context);
context.add(searchQuery.context);
@@ -116,7 +114,7 @@ odoo.define('board.AddToBoardMenu', function (require) {
* @private
* @param {KeyboardEvent} ev
*/
_onInputKeydown(ev) {
onInputKeydown(ev) {
switch (ev.key) {
case 'Enter':
ev.preventDefault();
@@ -144,7 +142,7 @@ odoo.define('board.AddToBoardMenu', function (require) {
}
AddToBoardMenu.props = {};
AddToBoardMenu.template = 'AddToBoardMenu';
AddToBoardMenu.template = 'board.AddToBoard';
FavoriteMenu.registry.add('add-to-board-menu', AddToBoardMenu, 10);
@@ -80,28 +80,6 @@
<iframe width="100%" frameborder="0" t-att-src="url"/>
</t>
<t t-name="AddToBoardMenu" owl="1">
<li class="o_menu_item o_add_to_board" role="menuitem">
<button type="button" class="dropdown-item"
t-ref="fallback-focus"
t-on-click="state.open = !state.open"
>
<t>Add to my dashboard</t>
</button>
<t t-if="state.open">
<div class="dropdown-item-text">
<input type="text" class="o_input" autofocus=""
t-model.trim="state.name"
t-on-keydown="_onInputKeydown"
/>
</div>
<div class="dropdown-item-text">
<button type="button" class="btn btn-primary" t-on-click="_addToBoard">Add</button>
</div>
</t>
</li>
</t>
<t t-name="SearchView.addtodashboard">
<a href="#" class="dropdown-item o_add_to_dashboard_link o_closed_menu">Add to my Dashboard</a>
<div class="dropdown-item-text o_add_to_dashboard">
+45 -39
View File
@@ -7,21 +7,30 @@ var ListController = require('web.ListController');
var testUtils = require('web.test_utils');
var ListRenderer = require('web.ListRenderer');
var pyUtils = require('web.py_utils');
const registry = require("@web/core/registry");
const { registry } = require("@web/core/registry");
const { makeFakeUserService } = require("@web/../tests/helpers/mock_services");
const {
applyFilter,
applyGroup,
editConditionValue,
toggleAddCustomFilter,
toggleAddCustomGroup,
toggleFilterMenu,
toggleGroupByMenu,
toggleMenuItem,
toggleMenuItemOption,
toggleComparisonMenu,
toggleFavoriteMenu,
} = require("@web/../tests/search/helpers");
const LegacyFavoriteMenu = require("web.FavoriteMenu");
const LegacyAddToBoard = require("board.AddToBoardMenu");
const { AddToBoard } = require('@board/add_to_board/add_to_board');
const cpHelpers = testUtils.controlPanel;
const { createWebClient, doAction } = require("@web/../tests/webclient/helpers");
var createView = testUtils.createView;
const patchDate = testUtils.mock.patchDate;
const favoriteMenuRegistry = registry.category("favoriteMenu");
let serverData;
QUnit.module('Dashboard', {
@@ -59,6 +68,12 @@ QUnit.module('Dashboard', {
},
};
LegacyFavoriteMenu.registry.add('add-to-board-menu', LegacyAddToBoard, 10);
favoriteMenuRegistry.add("add-to-board", {
Component: AddToBoard,
groupNumber: 4,
isDisplayed: ({ searchModel }) => searchModel.action.type === "ir.actions.act_window",
}, { sequence: 10 });
serverData = { models: this.data };
},
});
@@ -771,16 +786,16 @@ QUnit.test("save actions to dashboard", async function (assert) {
await testUtils.dom.click($(".o_column_sortable"));
// Group It
await cpHelpers.toggleGroupByMenu(webClient);
await cpHelpers.toggleAddCustomGroup(webClient);
await cpHelpers.applyGroup(webClient);
await toggleGroupByMenu(webClient);
await toggleAddCustomGroup(webClient);
await applyGroup(webClient);
// add this action to dashboard
await cpHelpers.toggleFavoriteMenu(webClient);
await toggleFavoriteMenu(webClient);
await testUtils.dom.click($(".o_add_to_board > button"));
await testUtils.dom.click($(".o_add_to_board button.o_dropdown_toggler"));
await testUtils.fields.editInput($(".o_add_to_board input"), "a name");
await testUtils.dom.click($(".o_add_to_board div button"));
await testUtils.dom.click($(".o_add_to_board .o_dropdown_menu button"));
testUtils.mock.unpatch(ListController);
});
@@ -827,34 +842,28 @@ QUnit.test("save two searches to dashboard", async function (assert) {
var filter_count = 0;
// Add a first filter
await cpHelpers.toggleFilterMenu(webClient);
await cpHelpers.toggleAddCustomFilter(webClient);
await testUtils.fields.editInput(
webClient.el.querySelector(".o_generator_menu_value .o_input"),
"a"
);
await cpHelpers.applyFilter(webClient);
await toggleFilterMenu(webClient);
await toggleAddCustomFilter(webClient);
await editConditionValue(webClient, 0, "a");
await applyFilter(webClient);
// Add it to dashboard
await cpHelpers.toggleFavoriteMenu(webClient);
await testUtils.dom.click($(".o_add_to_board > button"));
await testUtils.dom.click($(".o_add_to_board div button"));
await toggleFavoriteMenu(webClient);
await testUtils.dom.click($(".o_add_to_board button.o_dropdown_toggler"));
await testUtils.dom.click($(".o_add_to_board .o_dropdown_menu button"));
// Remove it
await testUtils.dom.click(webClient.el.querySelector(".o_facet_remove"));
// Add the second filter
await cpHelpers.toggleFilterMenu(webClient);
await cpHelpers.toggleAddCustomFilter(webClient);
await testUtils.fields.editInput(
webClient.el.querySelector(".o_generator_menu_value .o_input"),
"b"
);
await cpHelpers.applyFilter(webClient);
await toggleFilterMenu(webClient);
await toggleAddCustomFilter(webClient);
await editConditionValue(webClient, 0, "b");
await applyFilter(webClient);
// Add it to dashboard
await cpHelpers.toggleFavoriteMenu(webClient);
await testUtils.dom.click(webClient.el.querySelector(".o_add_to_board > button"));
await testUtils.dom.click(webClient.el.querySelector(".o_add_to_board div button"));
await toggleFavoriteMenu(webClient);
await testUtils.dom.click(webClient.el.querySelector(".o_add_to_board button.o_dropdown_toggler"));
await testUtils.dom.click(webClient.el.querySelector(".o_add_to_board .o_dropdown_menu button"));
});
QUnit.test("save a action domain to dashboard", async function (assert) {
@@ -890,18 +899,15 @@ QUnit.test("save a action domain to dashboard", async function (assert) {
});
// Add a filter
await cpHelpers.toggleFilterMenu(webClient);
await cpHelpers.toggleAddCustomFilter(webClient);
await testUtils.fields.editInput(
webClient.el.querySelector(".o_generator_menu_value .o_input"),
"b"
);
await cpHelpers.applyFilter(webClient);
await toggleFilterMenu(webClient);
await toggleAddCustomFilter(webClient);
await editConditionValue(webClient, 0, "b");
await applyFilter(webClient);
// Add it to dashboard
await cpHelpers.toggleFavoriteMenu(webClient);
await testUtils.dom.click(webClient.el.querySelector(".o_add_to_board > button"));
await toggleFavoriteMenu(webClient);
await testUtils.dom.click(webClient.el.querySelector(".o_add_to_board button.o_dropdown_toggler"));
// add
await testUtils.dom.click(webClient.el.querySelector(".o_add_to_board div button"));
await testUtils.dom.click(webClient.el.querySelector(".o_add_to_board .o_dropdown_menu button"));
});
QUnit.test("Views should be loaded in the user's language", async function (assert) {
@@ -1123,7 +1129,7 @@ QUnit.skip(
// add the view to the dashboard
await toggleFavoriteMenu(webClient);
await testUtils.dom.click($(".o_add_to_board > button"));
await testUtils.dom.click($(".o_add_to_board button.o_dropdown_toggler"));
await testUtils.fields.editInput($(".o_add_to_board input"), "a name");
await testUtils.dom.click($(".o_add_to_board div button"));
@@ -206,8 +206,8 @@ QUnit.module("Views", (hooks) => {
assert.containsOnce(webClient, ".o_switch_view.o_legacy_toy.active");
await cpHelpers.toggleGroupByMenu(webClient);
await cpHelpers.toggleMenuItem(webClient, "Date Field");
await cpHelpers.toggleMenuItemOption(webClient, "Date Field", "Year");
await toggleMenuItem(webClient, "Date Field");
await toggleMenuItemOption(webClient, "Date Field", "Year");
await switchView(webClient, "graph");
@@ -233,8 +233,8 @@ QUnit.module("Views", (hooks) => {
assert.containsOnce(webClient, ".o_switch_view.o_legacy_toy.active");
await cpHelpers.toggleGroupByMenu(webClient);
await cpHelpers.toggleMenuItem(webClient, "Date Field");
await cpHelpers.toggleMenuItemOption(webClient, "Date Field", "Quarter");
await toggleMenuItem(webClient, "Date Field");
await toggleMenuItemOption(webClient, "Date Field", "Quarter");
await switchView(webClient, "graph");
@@ -4,8 +4,6 @@ odoo.define('google_drive.gdrive_integration', function (require) {
const FormView = require('web.FormView');
const testUtils = require('web.test_utils');
const cpHelpers = testUtils.controlPanel;
QUnit.module('Google Drive Integration', {
beforeEach() {
this.data = {
@@ -62,12 +60,12 @@ odoo.define('google_drive.gdrive_integration', function (require) {
hasActionMenus: true,
},
});
await cpHelpers.toggleActionMenu(form);
await testUtils.controlPanel.toggleActionMenu(form);
assert.containsOnce(form, '.oe_share_gdoc_item',
"The button to the google action should be present");
await cpHelpers.toggleMenuItem(form, "Cyberdyne Systems");
await testUtils.controlPanel.toggleMenuItem(form, "Cyberdyne Systems");
form.destroy();
});
@@ -139,14 +137,14 @@ odoo.define('google_drive.gdrive_integration', function (require) {
},
});
await cpHelpers.toggleActionMenu(form);
await cpHelpers.toggleMenuItem(form, "Cyberdyne Systems");
await testUtils.controlPanel.toggleActionMenu(form);
await testUtils.controlPanel.toggleMenuItem(form, "Cyberdyne Systems");
currentRecordId = 2;
await cpHelpers.pagerNext(form);
await testUtils.controlPanel.pagerNext(form);
await cpHelpers.toggleActionMenu(form);
await cpHelpers.toggleMenuItem(form, "Cyberdyne Systems");
await testUtils.controlPanel.toggleActionMenu(form);
await testUtils.controlPanel.toggleMenuItem(form, "Cyberdyne Systems");
form.destroy();
});
@@ -2,18 +2,18 @@ odoo.define('board.AddToGoogleSpreadsheetMenu', function (require) {
"use strict";
const Domain = require('web.Domain');
const DropdownMenuItem = require('web.DropdownMenuItem');
const FavoriteMenu = require('web.FavoriteMenu');
const { Component } = owl;
/**
* 'Add to Google spreadsheet' menu
*
* Component consisting only of a button calling the server to add the current
* view to the user's spreadsheet configuration.
* This component is only available in actions of type 'ir.actions.act_window'.
* @extends DropdownMenuItem
*/
class AddToGoogleSpreadsheetMenu extends DropdownMenuItem {
class AddToGoogleSpreadsheetMenu extends Component {
//---------------------------------------------------------------------
// Handlers
@@ -22,7 +22,7 @@ odoo.define('board.AddToGoogleSpreadsheetMenu', function (require) {
/**
* @private
*/
async _onAddToSpreadsheet() {
async addToGoogleSpreadsheet() {
const searchQuery = this.env.searchModel.get('query');
const listView = this.env.action.views.find(view => view.type === 'list');
const modelName = this.env.action.res_model;
@@ -55,7 +55,7 @@ odoo.define('board.AddToGoogleSpreadsheetMenu', function (require) {
}
AddToGoogleSpreadsheetMenu.props = {};
AddToGoogleSpreadsheetMenu.template = 'AddToGoogleSpreadsheetMenu';
AddToGoogleSpreadsheetMenu.template = "google_spreadsheet.AddToGoogleSpreadsheet";
FavoriteMenu.registry.add('add-to-google-spreadsheet-menu', AddToGoogleSpreadsheetMenu, 20);
@@ -1,7 +0,0 @@
<template>
<t t-name="AddToGoogleSpreadsheetMenu" owl="1">
<li class="o_menu_item o_add_to_spreadsheet" role="menuitem">
<a class="dropdown-item" href="#" t-on-click.prevent="_onAddToSpreadsheet">Add to Google Spreadsheet</a>
</li>
</t>
</template>
+1
View File
@@ -42,6 +42,7 @@ This module provides the core of the Odoo Web Client.
'web/static/src/**/*.xml',
('remove', 'web/static/src/legacy/**/*.xml'),
'web/static/src/legacy/xml/base.xml',
'web/static/src/legacy/xml/control_panel.xml',
'web/static/src/legacy/xml/chart.xml',
'web/static/src/legacy/xml/fields.xml',
'web/static/src/legacy/xml/file_upload_progress_bar.xml',
@@ -1,34 +1,18 @@
odoo.define("web.ComparisonMenu", function (require) {
"use strict";
const DropdownMenu = require("web.DropdownMenu");
const { FACET_ICONS } = require("web.searchUtils");
const { useModel } = require("web.Model");
/**
* "Comparison" menu
*
* Displays a set of comparison options related to the currently selected
* date filters.
* @extends DropdownMenu
*/
class ComparisonMenu extends DropdownMenu {
const { Component } = owl;
class ComparisonMenu extends Component {
constructor() {
super(...arguments);
this.icon = FACET_ICONS.comparison;
this.model = useModel('searchModel');
}
//---------------------------------------------------------------------
// Getters
//---------------------------------------------------------------------
/**
* @override
*/
get icon() {
return FACET_ICONS.comparison;
}
/**
* @override
*/
@@ -36,28 +20,16 @@ odoo.define("web.ComparisonMenu", function (require) {
return this.model.get('filters', f => f.type === 'comparison');
}
/**
* @override
*/
get title() {
return this.env._t("Comparison");
}
//---------------------------------------------------------------------
// Handlers
//---------------------------------------------------------------------
/**
* @private
* @param {OwlEvent} ev
*/
_onItemSelected(ev) {
ev.stopPropagation();
const { item } = ev.detail;
this.model.dispatch("toggleComparison", item.id);
onComparisonSelected(ev) {
const { itemId } = ev.detail.payload;
this.model.dispatch("toggleComparison", itemId);
}
}
ComparisonMenu.template = "web.ComparisonMenu";
return ComparisonMenu;
});
@@ -1,12 +1,12 @@
odoo.define('web.CustomFavoriteItem', function (require) {
"use strict";
const DropdownMenuItem = require('web.DropdownMenuItem');
const FavoriteMenu = require('web.FavoriteMenu');
const { useAutofocus } = require('web.custom_hooks');
const { useModel } = require('web.Model');
const { useRef } = owl.hooks;
const { Component, hooks, useState } = owl;
const { useRef } = hooks;
let favoriteId = 0;
@@ -28,9 +28,8 @@ odoo.define('web.CustomFavoriteItem', function (require) {
* by default' checkbox.
* Finally, there is a 'Save' button used to apply the current configuration
* and save the context to a new filter.
* @extends DropdownMenuItem
*/
class CustomFavoriteItem extends DropdownMenuItem {
class CustomFavoriteItem extends Component {
constructor() {
super(...arguments);
@@ -41,7 +40,7 @@ odoo.define('web.CustomFavoriteItem', function (require) {
this.descriptionRef = useRef('description');
this.model = useModel('searchModel');
this.interactive = true;
Object.assign(this.state, {
this.state = useState({
description: this.env.action.name || "",
isDefault: false,
isShared: false,
@@ -57,7 +56,7 @@ odoo.define('web.CustomFavoriteItem', function (require) {
/**
* @private
*/
_saveFavorite() {
saveFavorite() {
if (!this.state.description.length) {
this.env.services.notification.notify({
message: this.env._t("A name for your favorite filter is required."),
@@ -96,18 +95,23 @@ odoo.define('web.CustomFavoriteItem', function (require) {
* @private
* @param {Event} ev change Event
*/
_onCheckboxChange(ev) {
const { checked, id } = ev.target;
if (this.useByDefaultId === id) {
this.state.isDefault = checked;
if (checked) {
this.state.isShared = false;
}
} else {
this.state.isShared = checked;
if (checked) {
this.state.isDefault = false;
}
onDefaultCheckboxChange(ev) {
const { checked } = ev.target;
this.state.isDefault = checked;
if (checked) {
this.state.isShared = false;
}
}
/**
* @private
* @param {Event} ev change Event
*/
onShareCheckboxChange(ev) {
const { checked } = ev.target;
this.state.isShared = checked;
if (checked) {
this.state.isDefault = false;
}
}
@@ -115,11 +119,11 @@ odoo.define('web.CustomFavoriteItem', function (require) {
* @private
* @param {jQueryEvent} ev
*/
_onInputKeydown(ev) {
onInputKeydown(ev) {
switch (ev.key) {
case 'Enter':
ev.preventDefault();
this._saveFavorite();
this.saveFavorite();
break;
case 'Escape':
// Gives the focus back to the component.
@@ -143,7 +147,7 @@ odoo.define('web.CustomFavoriteItem', function (require) {
}
CustomFavoriteItem.props = {};
CustomFavoriteItem.template = 'web.Legacy.CustomFavoriteItem';
CustomFavoriteItem.template = "web.CustomFavoriteItem";
CustomFavoriteItem.groupNumber = 3; // have 'Save Current Search' in its own group
FavoriteMenu.registry.add('favorite-generator-menu', CustomFavoriteItem, 0);
@@ -3,11 +3,13 @@ odoo.define('web.CustomFilterItem', function (require) {
const { DatePicker, DateTimePicker } = require('web.DatePickerOwl');
const Domain = require('web.Domain');
const DropdownMenuItem = require('web.DropdownMenuItem');
const { FIELD_OPERATORS, FIELD_TYPES } = require('web.searchUtils');
const field_utils = require('web.field_utils');
const { useModel } = require('web.Model');
const { Component, hooks } = owl;
const { useState } = hooks;
/**
* Filter generator menu
*
@@ -39,16 +41,14 @@ odoo.define('web.CustomFilterItem', function (require) {
* [date_field, '>=', x],
* [date_field, '<=', y],
* ]
* @extends DropdownMenuItem
*/
class CustomFilterItem extends DropdownMenuItem {
class CustomFilterItem extends Component {
constructor() {
super(...arguments);
this.model = useModel('searchModel');
this.canBeOpened = true;
this.state.conditions = [];
this.conditions = useState([]);
// Format, filter and sort the fields props
this.fields = Object.values(this.props.fields)
.filter(field => this._validateField(field))
@@ -61,7 +61,7 @@ odoo.define('web.CustomFilterItem', function (require) {
this.FIELD_TYPES = FIELD_TYPES;
// Add first condition
this._addNewCondition();
this.addNewCondition();
}
//---------------------------------------------------------------------
@@ -75,8 +75,8 @@ odoo.define('web.CustomFilterItem', function (require) {
* - a null or empty array value
* @private
*/
_addNewCondition() {
const lastCondition = [...this.state.conditions].pop();
addNewCondition() {
const lastCondition = [...this.conditions].pop();
const condition = lastCondition
? Object.assign({}, lastCondition)
: {
@@ -84,7 +84,7 @@ odoo.define('web.CustomFilterItem', function (require) {
operator: 0,
};
this._setDefaultValue(condition);
this.state.conditions.push(condition);
this.conditions.push(condition);
}
/**
@@ -148,8 +148,8 @@ odoo.define('web.CustomFilterItem', function (require) {
* Convert all conditions to prefilters.
* @private
*/
_onApply() {
const preFilters = this.state.conditions.map(condition => {
onApply() {
const preFilters = this.conditions.map(condition => {
const field = this.fields[condition.field];
const type = this.FIELD_TYPES[field.type];
const operator = this.OPERATORS[type][condition.operator];
@@ -191,10 +191,10 @@ odoo.define('web.CustomFilterItem', function (require) {
this.model.dispatch('createNewFilters', preFilters);
// Reset state
this.state.open = false;
this.state.conditions = [];
this._addNewCondition();
// remove conditions
this.conditions.splice(0, this.conditions.length);
this.addNewCondition();
}
/**
@@ -203,7 +203,7 @@ odoo.define('web.CustomFilterItem', function (require) {
* @param {number} valueIndex
* @param {OwlEvent} ev
*/
_onDateChanged(condition, valueIndex, ev) {
onDateChanged(condition, valueIndex, ev) {
condition.value[valueIndex] = ev.detail.date;
}
@@ -212,7 +212,7 @@ odoo.define('web.CustomFilterItem', function (require) {
* @param {Object} condition
* @param {Event} ev
*/
_onFieldSelect(condition, ev) {
onFieldSelect(condition, ev) {
Object.assign(condition, {
field: ev.target.selectedIndex,
operator: 0,
@@ -225,7 +225,7 @@ odoo.define('web.CustomFilterItem', function (require) {
* @param {Object} condition
* @param {Event} ev
*/
_onOperatorSelect(condition, ev) {
onOperatorSelect(condition, ev) {
condition.operator = ev.target.selectedIndex;
this._setDefaultValue(condition);
}
@@ -234,8 +234,8 @@ odoo.define('web.CustomFilterItem', function (require) {
* @private
* @param {Object} condition
*/
_onRemoveCondition(conditionIndex) {
this.state.conditions.splice(conditionIndex, 1);
onRemoveCondition(conditionIndex) {
this.conditions.splice(conditionIndex, 1);
}
/**
@@ -243,7 +243,7 @@ odoo.define('web.CustomFilterItem', function (require) {
* @param {Object} condition
* @param {Event} ev
*/
_onValueInput(condition, ev) {
onValueChange(condition, ev) {
if (!ev.target.value) {
return this._setDefaultValue(condition);
}
@@ -268,10 +268,8 @@ odoo.define('web.CustomFilterItem', function (require) {
}
CustomFilterItem.components = { DatePicker, DateTimePicker };
CustomFilterItem.props = {
fields: Object,
};
CustomFilterItem.template = 'web.Legacy.CustomFilterItem';
CustomFilterItem.props = { fields: Object };
CustomFilterItem.template = "web.CustomFilterItem";
return CustomFilterItem;
});
@@ -1,24 +1,18 @@
odoo.define('web.CustomGroupByItem', function (require) {
"use strict";
const DropdownMenuItem = require('web.DropdownMenuItem');
const { useModel } = require('web.Model');
/**
* Group by generator menu
*
* Component used to generate new filters of type 'groupBy'. It is composed
* of a button (used to toggle the rendering of the rest of the component) and
* an input (select) used to choose a new field name which will be used as a
* new groupBy value.
* @extends DropdownMenuItem
*/
class CustomGroupByItem extends DropdownMenuItem {
const { Component, hooks } = owl;
const { useState } = hooks;
class CustomGroupByItem extends Component {
constructor() {
super(...arguments);
this.canBeOpened = true;
this.state.fieldName = this.props.fields[0].name;
this.state = useState({
fieldName: this.props.fields[0].name,
});
this.model = useModel('searchModel');
}
@@ -30,14 +24,13 @@ odoo.define('web.CustomGroupByItem', function (require) {
/**
* @private
*/
_onApply() {
onApply() {
const field = this.props.fields.find(f => f.name === this.state.fieldName);
this.model.dispatch('createNewGroupBy', field);
this.state.open = false;
}
}
CustomGroupByItem.template = 'web.Legacy.CustomGroupByItem';
CustomGroupByItem.template = "web.CustomGroupByItem";
CustomGroupByItem.props = {
fields: Array,
};
@@ -2,10 +2,10 @@ odoo.define('web.FavoriteMenu', function (require) {
"use strict";
const Dialog = require('web.OwlDialog');
const DropdownMenu = require('web.DropdownMenu');
const { FACET_ICONS } = require("web.searchUtils");
const Registry = require('web.Registry');
const { useModel } = require('web.Model');
const { Component, useState } = owl;
/**
* 'Favorites' menu
@@ -15,28 +15,19 @@ odoo.define('web.FavoriteMenu', function (require) {
* with the addition of a submenu registry used to display additional components.
* Only the favorite generator (@see CustomFavoriteItem) is registered in
* the `web` module.
* @see DropdownMenu for additional details.
* @extends DropdownMenu
*/
class FavoriteMenu extends DropdownMenu {
class FavoriteMenu extends Component {
constructor() {
super(...arguments);
this.icon = FACET_ICONS.favorite;
this.model = useModel('searchModel');
this.state.deletedFavorite = false;
this.state = useState({ deletedFavorite: false });
}
//---------------------------------------------------------------------
// Getters
//---------------------------------------------------------------------
/**
* @override
*/
get icon() {
return FACET_ICONS.favorite;
}
/**
* @override
*/
@@ -58,23 +49,16 @@ odoo.define('web.FavoriteMenu', function (require) {
return [...favorites, ...registryMenus];
}
/**
* @override
*/
get title() {
return this.env._t("Favorites");
}
//---------------------------------------------------------------------
// Handlers
//---------------------------------------------------------------------
/**
* @private
* @param {OwlEvent} ev
* @param {int} id
*/
_onItemRemoved(ev) {
const favorite = this.items.find(fav => fav.id === ev.detail.item.id);
openConfirmationDialog(id) {
const favorite = this.items.find(fav => fav.id === id);
this.state.deletedFavorite = favorite;
}
@@ -82,9 +66,9 @@ odoo.define('web.FavoriteMenu', function (require) {
* @private
* @param {OwlEvent} ev
*/
_onItemSelected(ev) {
onFavoriteSelected(ev) {
ev.stopPropagation();
this.model.dispatch('toggleFilter', ev.detail.item.id);
this.model.dispatch('toggleFilter', ev.detail.payload.itemId);
}
/**
@@ -97,10 +81,7 @@ odoo.define('web.FavoriteMenu', function (require) {
}
FavoriteMenu.registry = new Registry();
FavoriteMenu.components = Object.assign({}, DropdownMenu.components, {
Dialog,
});
FavoriteMenu.components = { Dialog };
FavoriteMenu.template = 'web.Legacy.FavoriteMenu';
return FavoriteMenu;
@@ -2,24 +2,23 @@ odoo.define('web.FilterMenu', function (require) {
"use strict";
const CustomFilterItem = require('web.CustomFilterItem');
const DropdownMenu = require('web.DropdownMenu');
const { FACET_ICONS } = require("web.searchUtils");
const { useModel } = require('web.Model');
const { Component } = owl;
/**
* 'Filters' menu
*
* Simple rendering of the filters of type `filter` given by the control panel
* model. It uses most of the behaviours implemented by the dropdown menu Component,
* with the addition of a filter generator (@see CustomFilterItem).
* @see DropdownMenu for additional details.
* @extends DropdownMenu
*/
class FilterMenu extends DropdownMenu {
class FilterMenu extends Component {
constructor() {
super(...arguments);
this.icon = FACET_ICONS.filter;
this.model = useModel('searchModel');
}
@@ -27,13 +26,6 @@ odoo.define('web.FilterMenu', function (require) {
// Getters
//---------------------------------------------------------------------
/**
* @override
*/
get icon() {
return FACET_ICONS.filter;
}
/**
* @override
*/
@@ -41,13 +33,6 @@ odoo.define('web.FilterMenu', function (require) {
return this.model.get('filters', f => f.type === 'filter');
}
/**
* @override
*/
get title() {
return this.env._t("Filters");
}
//---------------------------------------------------------------------
// Handlers
//---------------------------------------------------------------------
@@ -56,24 +41,20 @@ odoo.define('web.FilterMenu', function (require) {
* @private
* @param {OwlEvent} ev
*/
_onItemSelected(ev) {
onFilterSelected(ev) {
ev.stopPropagation();
const { item, option } = ev.detail;
if (option) {
this.model.dispatch('toggleFilterWithOptions', item.id, option.id);
const { itemId, optionId } = ev.detail.payload;
if (optionId) {
this.model.dispatch('toggleFilterWithOptions', itemId, optionId);
} else {
this.model.dispatch('toggleFilter', item.id);
this.model.dispatch('toggleFilter', itemId);
}
}
}
FilterMenu.components = Object.assign({}, DropdownMenu.components, {
CustomFilterItem,
});
FilterMenu.props = Object.assign({}, DropdownMenu.props, {
fields: Object,
});
FilterMenu.template = 'web.Legacy.FilterMenu';
FilterMenu.components = { CustomFilterItem };
FilterMenu.props = { fields: Object };
FilterMenu.template = "web.legacy.FilterMenu";
return FilterMenu;
});
@@ -2,23 +2,16 @@ odoo.define('web.GroupByMenu', function (require) {
"use strict";
const CustomGroupByItem = require('web.CustomGroupByItem');
const DropdownMenu = require('web.DropdownMenu');
const { FACET_ICONS, GROUPABLE_TYPES } = require('web.searchUtils');
const { useModel } = require('web.Model');
/**
* 'Group by' menu
*
* Simple rendering of the filters of type `groupBy` given by the control panel
* model. It uses most of the behaviours implemented by the dropdown menu Component,
* with the addition of a groupBy filter generator (@see CustomGroupByItem).
* @see DropdownMenu for additional details.
* @extends DropdownMenu
*/
class GroupByMenu extends DropdownMenu {
const { Component } = owl;
class GroupByMenu extends Component {
constructor() {
super(...arguments);
this.icon = FACET_ICONS.groupBy;
this.fields = Object.values(this.props.fields)
.filter(field => this._validateField(field))
@@ -31,13 +24,6 @@ odoo.define('web.GroupByMenu', function (require) {
// Getters
//---------------------------------------------------------------------
/**
* @override
*/
get icon() {
return FACET_ICONS.groupBy;
}
/**
* @override
*/
@@ -45,13 +31,6 @@ odoo.define('web.GroupByMenu', function (require) {
return this.model.get('filters', f => f.type === 'groupBy');
}
/**
* @override
*/
get title() {
return this.env._t("Group By");
}
//---------------------------------------------------------------------
// Private
//---------------------------------------------------------------------
@@ -77,24 +56,20 @@ odoo.define('web.GroupByMenu', function (require) {
* @private
* @param {OwlEvent} ev
*/
_onItemSelected(ev) {
onGroupBySelected(ev) {
ev.stopPropagation();
const { item, option } = ev.detail;
if (option) {
this.model.dispatch('toggleFilterWithOptions', item.id, option.id);
const { itemId, optionId } = ev.detail.payload;
if (optionId) {
this.model.dispatch('toggleFilterWithOptions', itemId, optionId);
} else {
this.model.dispatch('toggleFilter', item.id);
this.model.dispatch('toggleFilter', itemId);
}
}
}
GroupByMenu.components = Object.assign({}, DropdownMenu.components, {
CustomGroupByItem,
});
GroupByMenu.props = Object.assign({}, DropdownMenu.props, {
fields: Object,
});
GroupByMenu.template = 'web.Legacy.GroupByMenu';
GroupByMenu.components = { CustomGroupByItem };
GroupByMenu.props = { fields: Object };
GroupByMenu.template = "web.GroupByMenu";
return GroupByMenu;
});
@@ -1119,6 +1119,7 @@ var PivotModel = AbstractModel.extend({
groupId: groupId,
height: isLeaf ? (colGroupBys.length + 1 - rowIndex) : 1,
isLeaf: isLeaf,
isFolded: isLeaf && colGroupBys.length > group.values.length,
label: rowIndex === 0 ? undefined : fields[colGroupBys[rowIndex - 1].split(':')[0]].string,
title: group.labels[group.labels.length - 1] || _t('Total'),
width: leafCount * measureCount * (2 * originCount - 1),
@@ -1202,6 +1203,7 @@ var PivotModel = AbstractModel.extend({
groupId: rowGroupId,
indent: indent,
isLeaf: isLeaf,
isFolded: isLeaf && rowGroupBys.length > group.values.length,
subGroupMeasurements: subGroupMeasurements
});
@@ -1,19 +1,18 @@
/** @odoo-module alias=web.PivotRenderer **/
import { useEffect } from "@web/core/utils/hooks";
import DropdownMenu from 'web.DropdownMenu';
import DropdownMenuItem from 'web.DropdownMenuItem';
import OwlAbstractRenderer from '../abstract_renderer_owl';
import field_utils from 'web.field_utils';
import { DEFAULT_INTERVAL, INTERVAL_OPTIONS } from 'web.searchUtils';
import { DEFAULT_INTERVAL, INTERVAL_OPTIONS, getIntervalOptions } from 'web.searchUtils';
const { useExternalListener, useState } = owl.hooks;
const { Component, hooks } = owl;
const { useExternalListener, useState } = hooks;
class PivotCustomGroupByItem extends DropdownMenuItem {
class PivotCustomGroupByItem extends Component {
constructor() {
super(...arguments);
this.canBeOpened = true;
this.state.fieldName = this.props.fields[0].name;
this.state = useState({ fieldName: this.props.fields[0].name });
}
//---------------------------------------------------------------------
@@ -23,7 +22,7 @@
/**
* @private
*/
_onApply() {
onApply() {
const { fieldName } = this.state;
const { type } = this.props.fields.find(f => f.name === fieldName);
let interval = null;
@@ -33,26 +32,12 @@
this.trigger('groupby-menu-selection', { fieldName, interval, custom: true });
this.state.open = false;
}
/**
* Stops propagation of click event if custom groupby menu is toggled.
* Propagates click event when Apply button is clicked to close dropdown
* @param {OwlEvent} ev
*/
_onToggleCustomGroupbyItem(ev) {
if (
!ev.target.classList.contains('o_apply_group_by') &&
(this.el.contains(ev.target) || this.el.contains(document.activeElement))
) {
ev.stopPropagation();
}
}
}
PivotCustomGroupByItem.template = "web.legacy.PivotCustomGroupByItem";
PivotCustomGroupByItem.template = "web.CustomGroupByItem";
PivotCustomGroupByItem.props = { fields: Array };
export class PivotGroupByMenu extends DropdownMenu {
export class PivotGroupByMenu extends Component {
constructor() {
super(...arguments);
@@ -68,16 +53,26 @@
* @override
*/
get items() {
let items = this.props.fields;
if (this.props.hasSearchArchGroupBys) {
const groupBys = this.props.searchModel.get('filters', f => f.type === 'groupBy');
let groupNumber = 1 + Math.max(...groupBys.map(g => g.groupNumber), 0);
items = this.props.searchModel.get('filters', f => f.type === 'groupBy');
let groupNumber = 1 + Math.max(...items.map(g => g.groupNumber), 0);
for (const [_, customGroupBy] of this.props.customGroupBys) {
customGroupBy.groupNumber = groupNumber++;
groupBys.push(customGroupBy);
items.push(customGroupBy);
}
return groupBys;
}
return this.props.fields;
return items.map((item) => ({
...item,
id: item.id || item.name,
fieldName: item.fieldName || item.name,
description: item.description || item.string,
isActive: false,
options:
item.options || ["date", "datetime"].includes(item.type)
? getIntervalOptions()
: undefined,
}));
}
//---------------------------------------------------------------------
@@ -101,7 +96,6 @@
PivotGroupByMenu.template = "web.legacy.PivotGroupByMenu";
PivotGroupByMenu.components = { PivotCustomGroupByItem };
PivotGroupByMenu.props = {
...DropdownMenu.props,
customGroupBys: Map,
fields: Object,
hasSearchArchGroupBys: Boolean,
@@ -198,18 +192,6 @@
return 5 + cell.indent * 30;
}
/**
* Compute if a cell is active (with its groupId)
*
* @private
* @param {Array} groupId GroupId of a cell
* @param {Boolean} isXAxis true if the cell is on the x axis
* @returns {Boolean} true if the cell is active
*/
_isClicked(groupId, isXAxis) {
return _.isEqual(groupId, this.state.activeNodeHeader.groupId) && this.state.activeNodeHeader.isXAxis === isXAxis;
}
/**
* Reset the state of the node.
*
-231
View File
@@ -182,46 +182,6 @@
</div>
</t>
<t t-name="web.Legacy.FavoriteMenu" t-inherit="web.DropdownMenu" t-inherit-mode="primary" owl="1">
<xpath expr="//DropdownMenuItem" position="attributes">
<attribute name="t-on-remove-item.stop">_onItemRemoved</attribute>
</xpath>
<xpath expr="//div[1]" position="inside">
<Dialog t-if="state.deletedFavorite"
title="'Warning'"
size="'medium'"
t-on-dialog-closed="state.deletedFavorite = false"
>
<t t-if="state.deletedFavorite.userId">Are you sure that you want to remove this filter?</t>
<t t-else="">This filter is global and will be removed for everybody if you continue.</t>
<t t-set="buttons">
<button type="button" class="btn btn-primary" t-on-click="_onRemoveFavorite">
<t>Ok</t>
</button>
<button type="button" class="btn btn-secondary" t-on-click.stop="state.deletedFavorite = false">
<t>Cancel</t>
</button>
</t>
</Dialog>
</xpath>
</t>
<t t-name="web.Legacy.FilterMenu" t-inherit="web.DropdownMenu" t-inherit-mode="primary" owl="1">
<xpath expr="//ul[@role='menu']" position="inside">
<li t-if="items.length" class="dropdown-divider" role="separator"/>
<CustomFilterItem fields="props.fields"/>
</xpath>
</t>
<t t-name="web.Legacy.GroupByMenu" t-inherit="web.DropdownMenu" t-inherit-mode="primary" owl="1">
<xpath expr="//ul[@role='menu']" position="inside">
<t t-if="fields.length">
<li t-if="items.length" class="dropdown-divider" role="separator"/>
<CustomGroupByItem fields="fields"/>
</t>
</xpath>
</t>
<t t-name="web.DropdownMenuItem" owl="1">
<li class="o_menu_item" role="menuitem" t-on-keydown="_onKeydown">
<t t-if="canBeOpened">
@@ -280,197 +240,6 @@
</li>
</t>
<t t-name="web.Legacy.CustomFavoriteItem" owl="1">
<li class="o_menu_item o_add_favorite" role="menuitem">
<span type="button"
class="dropdown-item"
t-ref="fallback-focus"
t-on-click="state.open = !state.open"
t-att-class="{ 'active': state.open, 'o_dropdown_item_active_noarrow' : state.open}"
>
<t>Save current search</t>
</span>
<div t-if="state.open" class="dropdown-item-text">
<div class="my-2">
<input type="text"
class="o_input"
autofocus=""
placeholder="My custom search"
t-ref="description"
t-model.trim="state.description"
t-on-keydown="_onInputKeydown"
/>
</div>
<div class="custom-control custom-checkbox">
<input type="checkbox"
t-att-id="useByDefaultId"
class="custom-control-input"
t-att-checked="state.isDefault"
t-on-change="_onCheckboxChange"
/>
<label class="custom-control-label" t-att-for="useByDefaultId">
<t>Use by default</t>
</label>
</div>
<div class="custom-control custom-checkbox">
<input type="checkbox"
t-att-id="shareAllUsersId"
class="custom-control-input"
t-att-checked="state.isShared"
t-on-change="_onCheckboxChange"
/>
<label class="custom-control-label" t-att-for="shareAllUsersId">
<t>Share with all users</t>
</label>
</div>
<div class="mt-3">
<button type="button" class="o_save_favorite btn btn-primary" t-on-click="_saveFavorite">Save</button>
</div>
</div>
</li>
</t>
<t t-name="web.Legacy.CustomFilterItem" owl="1">
<div class="o_generator_menu">
<button class="btn o_add_custom_filter dropdown-item"
aria-expanded="false"
t-ref="fallback-focus"
t-on-click="state.open = !state.open"
t-on-keydown="_onKeydown"
t-att-class="{ 'active': state.open, 'o_dropdown_item_active_noarrow' : state.open}"
>
<t>Add Custom Filter</t>
</button>
<t t-if="state.open">
<t t-set="showRemoveIcons" t-value="state.conditions.length gt 1"/>
<div t-foreach="state.conditions" t-as="condition" t-key="condition_index"
class="o_filter_condition dropdown-item-text position-relative d-flex align-items-center py-2 mb-2"
t-att-class="{ 'o_filter_condition_with_buttons': showRemoveIcons }">
<t t-set="fieldType" t-value="fields[condition.field].type"/>
<t t-set="selectedOperator" t-value="OPERATORS[FIELD_TYPES[fieldType]][condition.operator]"/>
<div t-if="!condition_first" class="o_or_filter text-center text-muted font-italic small">or</div>
<div class="d-flex flex-column">
<select class="o_input o_generator_menu_field pr-3"
t-on-change="_onFieldSelect(condition)"
>
<option t-foreach="fields" t-as="field" t-key="field_index"
t-att-value="field.name"
t-att-selected="field_index === condition.field"
t-esc="field.string"
/>
</select>
<select class="o_input o_generator_menu_operator my-1 pr-3"
t-on-change="_onOperatorSelect(condition)"
>
<option t-foreach="OPERATORS[FIELD_TYPES[fieldType]]" t-as="operator" t-key="operator_index"
t-att-value="operator.symbol"
t-att-selected="operator_index === condition.operator"
t-esc="operator.description"
/>
</select>
<span t-if="!('value' in selectedOperator)" class="o_generator_menu_value">
<t t-if="fieldType === 'date'">
<DatePicker
date="condition.value[0]"
t-on-datetime-changed="_onDateChanged(condition, 0)"
/>
<DatePicker t-if="selectedOperator.symbol === 'between'"
date="condition.value[1]"
t-on-datetime-changed="_onDateChanged(condition, 1)"
/>
</t>
<t t-elif="fieldType === 'datetime'">
<DateTimePicker
date="condition.value[0]"
t-on-datetime-changed="_onDateChanged(condition, 0)"
/>
<DateTimePicker t-if="selectedOperator.symbol === 'between'"
date="condition.value[1]"
t-on-datetime-changed="_onDateChanged(condition, 1)"
/>
</t>
<select t-elif="fieldType === 'selection'" class="o_input"
t-on-change="_onValueInput(condition)"
>
<option t-foreach="fields[condition.field].selection" t-as="option" t-key="option_index"
t-att-value="option[0]"
t-esc="option[1]"
/>
</select>
<input t-elif="fieldType === 'float'"
class="o_input"
step="0.01"
t-att-type="DECIMAL_POINT === '.' ? 'number' : 'text'"
t-attf-title="Number using {{ DECIMAL_POINT }} as decimal separator."
t-attf-pattern="[0-9]+([\{{ DECIMAL_POINT }}][0-9]+)?"
t-att-value="condition.displayedValue"
t-on-input="_onValueInput(condition)"
/>
<input t-elif="['integer', 'id'].includes(fieldType)"
class="o_input"
step="1"
type="number"
t-att-value="condition.displayedValue"
t-on-input="_onValueInput(condition)"
/>
<input t-else=""
type="text"
class="o_input"
t-att-value="condition.displayedValue"
t-on-input="_onValueInput(condition)"
/>
</span>
</div>
<button t-if="showRemoveIcons" class="o_generator_menu_delete btn btn-link text-danger"
aria-label="Delete condition"
title="Delete condition"
t-on-click="_onRemoveCondition(condition_index)">
&#215;
</button>
</div>
<div class="o_add_filter_menu dropdown-item-text pt-2 d-flex justify-content-between text-nowrap">
<button type="button" class="btn btn-primary btn-sm mr-2 o_apply_filter" t-on-click="_onApply">
<t>Apply</t>
</button>
<button type="button" class="o_add_condition btn btn-secondary btn-sm d-flex align-items-center text-left" t-on-click="_addNewCondition">
<i class="fa fa-plus-circle mr-2"/>
<t>Add a condition</t>
</button>
</div>
</t>
</div>
</t>
<t t-name="web.Legacy.CustomGroupByItem" owl="1">
<div class="o_generator_menu">
<span type="button"
class="o_add_custom_group_by dropdown-item"
aria-expanded="false"
t-ref="fallback-focus"
t-on-click="state.open = !state.open"
t-on-keydown="_onKeydown"
t-att-class="{ 'active': state.open, 'o_dropdown_item_active_noarrow' : state.open}"
>
<t>Add Custom Group</t>
</span>
<div t-if="state.open" class="dropdown-item-text my-2">
<select class="w-auto o_input o_group_by_selector" t-model="state.fieldName">
<option t-foreach="props.fields" t-as="field" t-key="field.name"
t-att-value="field.name"
t-esc="field.string"
/>
</select>
</div>
<div t-if="state.open" class="o_add_group_by_menu dropdown-item-text">
<button type="button" class="btn btn-primary o_apply_group_by" t-on-click="_onApply">
<t>Apply</t>
</button>
</div>
</div>
</t>
<t t-name="web.OwlDialog" owl="1">
<Portal target="'body'">
<div class="o_dialog" t-on-focus="_onFocus" t-on-click="_onClick">
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="web.Legacy.FavoriteMenu" t-inherit="web.FavoriteMenu" t-inherit-mode="primary" owl="1">
<xpath expr="//t[@t-set-slot='toggler']" position="inside">
<Dialog t-if="state.deletedFavorite"
title="'Warning'"
size="'medium'"
t-on-dialog-closed="state.deletedFavorite = false"
>
<t t-if="state.deletedFavorite.userId">Are you sure that you want to remove this filter?</t>
<t t-else="">This filter is global and will be removed for everybody if you continue.</t>
<t t-set="buttons">
<button type="button" class="btn btn-primary" t-on-click="_onRemoveFavorite">
<t>Ok</t>
</button>
<button type="button" class="btn btn-secondary" t-on-click.stop="state.deletedFavorite = false">
<t>Cancel</t>
</button>
</t>
</Dialog>
</xpath>
</t>
<t t-name="web.legacy.FilterMenu" t-inherit="web.FilterMenu" t-inherit-mode="primary" owl="1">
<xpath expr="//CustomFilterItem" position="attributes">
<attribute name="fields">props.fields</attribute>
</xpath>
</t>
</templates>
+31 -46
View File
@@ -60,7 +60,7 @@
o_pivot_header_cell_opened: !cell.isLeaf,
}" t-attf-style="{{ isXAxis ? undefined : 'padding-left: ' + _getPadding(cell) + 'px;' }}" t-att-title="cell.label" t-on-click.self.prevent="_onHeaderClick(cell, isXAxis ? 'col' : 'row')">
<span t-on-click.self.prevent="_onHeaderClick(cell, isXAxis ? 'col' : 'row')" t-esc="cell.title"/>
<t t-if="_isClicked(cell.groupId, isXAxis)" t-call="web.legacy.PivotGroupBySelection"/>
<t t-if="cell.isLeaf and !cell.isFolded" t-call="web.legacy.PivotGroupBySelection"/>
</th>
</t>
@@ -75,68 +75,53 @@
</th>
</t>
<div t-name="web.legacy.PivotGroupBySelection" class="dropdown" owl="1">
<t t-name="web.legacy.PivotGroupBySelection" owl="1">
<PivotGroupByMenu
customGroupBys="customGroupBys"
fields="props.groupableFields"
hasSearchArchGroupBys="hasSearchArchGroupBys"
searchModel="props.searchModel"
t-on-groupby-menu-selection="_onGroupByMenuSelection"
/>
</div>
/>
</t>
<t t-name="web.legacy.PivotGroupByMenu" owl="1">
<div class="dropdown-menu o_pivot_field_menu show" data-display="static" role="menu">
<Dropdown class="o_pivot_field_menu" toggler="'parent'">
<t t-set="currentGroup" t-value="null"/>
<t t-foreach="items" t-as="item" t-key="item.fieldName">
<div t-if="item.groupNumber and currentGroup !== null and currentGroup !== item.groupNumber"
class="dropdown-divider"
role="separator"/>
<t t-if="(item.fieldType === 'date') || (item.fieldType === 'datetime')">
<div role="menuitem" aria-haspopup="true" class="o_inline_dropdown">
<a href="#"
t-on-click.prevent.stop="_toggleMenu(item.id)"
class="dropdown-item o_pivot_field_selection position-relative"
t-att-data-field="item.fieldName"
>
<t t-esc="item.description"/>
</a>
<div class="dropdown-menu o_inline_dropdown" t-att-class="{ show: openedSubMenus[item.id] }" role="menu">
<t t-foreach="Object.values(intervalOptions)" t-as="option" t-key="option.id">
<a role="menuitem"
t-att-data-field="item.fieldName"
href="#"
class="dropdown-item"
t-on-click.prevent="_onClickMenuGroupBy(item.fieldName, option.id)"
>
<t t-esc="option.description"/>
</a>
</t>
</div>
</div>
<t t-foreach="items" t-as="item" t-key="item.id">
<t t-if="item.groupNumber and currentGroup !== null and currentGroup !== item.groupNumber">
<li class="dropdown-divider" role="separator"/>
</t>
<a t-else=""
href="#"
role="menuitem"
class="dropdown-item"
t-att-data-field="item.fieldName"
t-on-click.prevent="_onClickMenuGroupBy(item.fieldName, null)"
<t t-if="(item.fieldType === 'date') || (item.fieldType === 'datetime')">
<Dropdown tag="'li'" togglerClass="'o_menu_item dropdown-item'">
<t t-set-slot="toggler">
<t t-esc="item.description"/>
</t>
<t t-foreach="Object.values(intervalOptions)" t-as="option" t-key="option.id">
<DropdownItem
class="o_item_option dropdown-item"
t-on-dropdown-item-selected.stop="_onClickMenuGroupBy(item.fieldName, option.id)"
>
<t t-esc="option.description"/>
</DropdownItem>
</t>
</Dropdown>
</t>
<t t-else="">
<DropdownItem
class="o_menu_item dropdown-item"
t-on-dropdown-item-selected.stop="_onClickMenuGroupBy(item.fieldName, null)"
>
<t t-esc="item.description"/>
</a>
<t t-esc="item.description"/>
</DropdownItem>
</t>
<t t-set="currentGroup" t-value="item.groupNumber"/>
</t>
<t t-if="props.fields.length and props.hasSearchArchGroupBys">
<li t-if="items.length" class="dropdown-divider" role="separator"/>
<PivotCustomGroupByItem fields="props.fields"/>
</t>
</div>
</t>
<t t-name="web.legacy.PivotCustomGroupByItem" t-inherit="web.Legacy.CustomGroupByItem" t-inherit-mode="primary" owl="1">
<xpath expr="//div[hasclass('o_generator_menu')]" position="attributes">
<attribute name="t-on-click">_onToggleCustomGroupbyItem</attribute>
</xpath>
</Dropdown>
</t>
</templates>
@@ -9,6 +9,9 @@ import core from "web.core";
import makeTestEnvironment from "web.test_env";
import { registerCleanup } from "./cleanup";
import { makeTestEnv } from "./mock_env";
import { patchWithCleanup } from "./utils";
import * as FavoriteMenu from "web.FavoriteMenu";
import * as CustomFavoriteItem from "web.CustomFavoriteItem";
const serviceRegistry = registry.category("services");
@@ -40,3 +43,21 @@ export async function makeLegacyDialogMappingTestEnv() {
env,
};
}
function clearLegacyRegistryWithCleanup(r) {
const patch = {
// To improve? Initial data in registry is ignored.
map: Object.create(null),
// Preserve onAdd listeners
listeners: [...r.listeners],
_scoreMapping: Object.create(null),
_sortedKeys: null,
};
patchWithCleanup(r, patch);
}
export function prepareLegacyRegistriesWithCleanup() {
// Clear FavoriteMenu registry and add the "Save favorite" item.
clearLegacyRegistryWithCleanup(FavoriteMenu.registry);
FavoriteMenu.registry.add("favorite-generator-menu", CustomFavoriteItem, 0);
}
@@ -57,6 +57,7 @@ export function prepareRegistriesWithCleanup() {
clearRegistryWithCleanup(registry.category("command_categories"));
clearRegistryWithCleanup(registry.category("debug"));
clearRegistryWithCleanup(registry.category("error_dialogs"));
clearRegistryWithCleanup(registry.category("favoriteMenu"));
clearRegistryWithCleanup(registry.category("ir.actions.report handlers"));
clearRegistryWithCleanup(registry.category("services"));
@@ -6,7 +6,6 @@ odoo.define('web.action_menus_tests', function (require) {
const testUtils = require('web.test_utils');
const { Component } = owl;
const cpHelpers = testUtils.controlPanel;
const { createComponent } = testUtils;
QUnit.module('Components', {
@@ -63,7 +62,7 @@ odoo.define('web.action_menus_tests', function (require) {
assert.strictEqual(dropdowns[1].querySelector('.o_dropdown_title').innerText.trim(), "Action");
assert.containsNone(actionMenus, '.o_dropdown_menu');
await cpHelpers.toggleActionMenu(actionMenus, "Action");
await testUtils.controlPanel.toggleActionMenu(actionMenus, "Action");
assert.containsOnce(actionMenus, '.o_dropdown_menu');
assert.containsN(actionMenus, '.o_dropdown_menu .o_menu_item', 4);
@@ -75,12 +74,12 @@ odoo.define('web.action_menus_tests', function (require) {
"What's taters, precious ?",
], "callbacks should appear before actions");
await cpHelpers.toggleActionMenu(actionMenus, "Print");
await testUtils.controlPanel.toggleActionMenu(actionMenus, "Print");
assert.containsOnce(actionMenus, '.o_dropdown_menu');
assert.containsN(actionMenus, '.o_dropdown_menu .o_menu_item', 1);
await cpHelpers.toggleActionMenu(actionMenus, "Print");
await testUtils.controlPanel.toggleActionMenu(actionMenus, "Print");
assert.containsNone(actionMenus, '.o_dropdown_menu');
@@ -136,8 +135,8 @@ odoo.define('web.action_menus_tests', function (require) {
},
});
await cpHelpers.toggleActionMenu(actionMenus, "Action");
await cpHelpers.toggleMenuItem(actionMenus, "What's taters, precious ?");
await testUtils.controlPanel.toggleActionMenu(actionMenus, "Action");
await testUtils.controlPanel.toggleMenuItem(actionMenus, "What's taters, precious ?");
assert.verifySteps(['load-action', 'do-action']);
@@ -170,8 +169,8 @@ odoo.define('web.action_menus_tests', function (require) {
},
});
await cpHelpers.toggleActionMenu(actionMenus, "Action");
await cpHelpers.toggleMenuItem(actionMenus, "Boil'em");
await testUtils.controlPanel.toggleActionMenu(actionMenus, "Action");
await testUtils.controlPanel.toggleMenuItem(actionMenus, "Boil'em");
await callbackPromise;
@@ -208,8 +207,8 @@ odoo.define('web.action_menus_tests', function (require) {
},
});
await cpHelpers.toggleActionMenu(actionMenus, "Print");
await cpHelpers.toggleMenuItem(actionMenus, "Po-ta-toes");
await testUtils.controlPanel.toggleActionMenu(actionMenus, "Print");
await testUtils.controlPanel.toggleMenuItem(actionMenus, "Po-ta-toes");
assert.verifySteps(['load-action', 'do-action']);
@@ -240,8 +239,8 @@ odoo.define('web.action_menus_tests', function (require) {
},
});
await cpHelpers.toggleActionMenu(actionMenus, "Action");
await cpHelpers.toggleMenuItem(actionMenus, "Stick'em in a stew");
await testUtils.controlPanel.toggleActionMenu(actionMenus, "Action");
await testUtils.controlPanel.toggleMenuItem(actionMenus, "Stick'em in a stew");
assert.verifySteps(['#stew']);
@@ -4,7 +4,6 @@ odoo.define('web.pager_tests', function (require) {
const Pager = require('web.Pager');
const testUtils = require('web.test_utils');
const cpHelpers = testUtils.controlPanel;
const { createComponent } = testUtils;
QUnit.module('Components', {}, function () {
@@ -27,12 +26,12 @@ odoo.define('web.pager_tests', function (require) {
},
});
assert.strictEqual(cpHelpers.getPagerValue(pager), "1-4",
assert.strictEqual(testUtils.controlPanel.getPagerValue(pager), "1-4",
"currentMinimum should be set to 1");
await cpHelpers.pagerNext(pager);
await testUtils.controlPanel.pagerNext(pager);
assert.strictEqual(cpHelpers.getPagerValue(pager), "5-8",
assert.strictEqual(testUtils.controlPanel.getPagerValue(pager), "5-8",
"currentMinimum should now be 5");
pager.destroy();
@@ -58,15 +57,15 @@ odoo.define('web.pager_tests', function (require) {
assert.containsOnce(pager, 'input',
"the pager should contain an input");
assert.strictEqual(cpHelpers.getPagerValue(pager), "1-4",
assert.strictEqual(testUtils.controlPanel.getPagerValue(pager), "1-4",
"the input should have correct value");
// change the limit
await cpHelpers.setPagerValue(pager, "1-6");
await testUtils.controlPanel.setPagerValue(pager, "1-6");
assert.containsNone(pager, 'input',
"the pager should not contain an input anymore");
assert.strictEqual(cpHelpers.getPagerValue(pager), "1-6",
assert.strictEqual(testUtils.controlPanel.getPagerValue(pager), "1-6",
"the limit should have been updated");
pager.destroy();
@@ -90,14 +89,14 @@ odoo.define('web.pager_tests', function (require) {
await testUtils.dom.click(pager.el.querySelector('.o_pager_value'));
assert.containsOnce(pager, "input");
assert.strictEqual(cpHelpers.getPagerValue(pager), "1-4");
assert.strictEqual(testUtils.controlPanel.getPagerValue(pager), "1-4");
assert.verifySteps([]);
// Exit edit mode
await testUtils.dom.triggerEvent(pager.el.querySelector('input'), "keydown", { key: "Enter" });
assert.containsNone(pager, "input");
assert.strictEqual(cpHelpers.getPagerValue(pager), "1-4");
assert.strictEqual(testUtils.controlPanel.getPagerValue(pager), "1-4");
assert.verifySteps(["pager-changed"]);
pager.destroy();
@@ -119,11 +118,11 @@ odoo.define('web.pager_tests', function (require) {
},
});
assert.strictEqual(cpHelpers.getPagerValue(pager), "1-4", "Initial value should be correct");
assert.strictEqual(testUtils.controlPanel.getPagerValue(pager), "1-4", "Initial value should be correct");
async function inputAndAssert(input, expected, reason) {
await cpHelpers.setPagerValue(pager, input);
assert.strictEqual(cpHelpers.getPagerValue(pager), expected,
await testUtils.controlPanel.setPagerValue(pager, input);
assert.strictEqual(testUtils.controlPanel.getPagerValue(pager), expected,
`Pager value should be "${expected}" when given "${input}": ${reason}`);
}
@@ -163,8 +162,8 @@ odoo.define('web.pager_tests', function (require) {
const pagerButtons = pager.el.querySelectorAll('button');
// Click twice
await cpHelpers.pagerNext(pager);
await cpHelpers.pagerNext(pager);
await testUtils.controlPanel.pagerNext(pager);
await testUtils.controlPanel.pagerNext(pager);
// Try to edit the pager value
await testUtils.dom.click(pager.el.querySelector('.o_pager_value'));
@@ -181,7 +180,7 @@ odoo.define('web.pager_tests', function (require) {
assert.strictEqual(pagerButtons.length, 2, "the two buttons should be displayed");
assert.notOk(pagerButtons[0].disabled, "'previous' is enabled");
assert.notOk(pagerButtons[1].disabled, "'next' is enabled");
assert.strictEqual(cpHelpers.getPagerValue(pager), "5-8", "value has been updated");
assert.strictEqual(testUtils.controlPanel.getPagerValue(pager), "5-8", "value has been updated");
await testUtils.dom.click(pager.el.querySelector('.o_pager_value'));
@@ -1,8 +1,8 @@
odoo.define('web.comparison_menu_tests', function (require) {
"use strict";
const cpHelpers = require('@web/../tests/search/helpers');
const {
controlPanel: cpHelpers,
createControlPanel,
mock,
} = require('web.test_utils');
@@ -3,7 +3,7 @@ odoo.define('web.control_panel_tests', function (require) {
const testUtils = require('web.test_utils');
const cpHelpers = testUtils.controlPanel;
const cpHelpers = require('@web/../tests/search/helpers');
const { createControlPanel } = testUtils;
QUnit.module('ControlPanel', {
@@ -167,14 +167,14 @@ odoo.define('web.control_panel_tests', function (require) {
await cpHelpers.toggleFilterMenu(controlPanel);
selectorContainsValue('.o_menu_item a', "FA", true);
selectorContainsValue('.o_menu_item a', "FB", false);
selectorContainsValue('.o_menu_item a', "FC", true);
selectorContainsValue('.o_menu_item', "FA", true);
selectorContainsValue('.o_menu_item', "FB", false);
selectorContainsValue('.o_menu_item', "FC", true);
await cpHelpers.toggleGroupByMenu(controlPanel);
selectorContainsValue('.o_menu_item a', "GA", true);
selectorContainsValue('.o_menu_item a', "GB", false);
selectorContainsValue('.o_menu_item', "GA", true);
selectorContainsValue('.o_menu_item', "GB", false);
// 'a' to filter nothing on bar
await cpHelpers.editSearch(controlPanel, 'a');
@@ -187,14 +187,14 @@ odoo.define('web.control_panel_tests', function (require) {
// The items in the Filters menu and the Group By menu should be the same as before
await cpHelpers.toggleFilterMenu(controlPanel);
selectorContainsValue('.o_menu_item a', "FA", true);
selectorContainsValue('.o_menu_item a', "FB", false);
selectorContainsValue('.o_menu_item a', "FC", true);
selectorContainsValue('.o_menu_item', "FA", true);
selectorContainsValue('.o_menu_item', "FB", false);
selectorContainsValue('.o_menu_item', "FC", true);
await cpHelpers.toggleGroupByMenu(controlPanel);
selectorContainsValue('.o_menu_item a', "GA", true);
selectorContainsValue('.o_menu_item a', "GB", false);
selectorContainsValue('.o_menu_item', "GA", true);
selectorContainsValue('.o_menu_item', "GB", false);
controlPanel.destroy();
});
@@ -7,7 +7,7 @@ odoo.define('web.filter_menu_generator_tests', function (require) {
const pyUtils = require('web.py_utils');
const testUtils = require('web.test_utils');
const cpHelpers = testUtils.controlPanel;
const cpHelpers = require('@web/../tests/search/helpers');
const { createComponent } = testUtils;
QUnit.module('Components', {
@@ -27,7 +27,7 @@ odoo.define('web.filter_menu_generator_tests', function (require) {
QUnit.module('CustomFilterItem (legacy)');
QUnit.test('basic rendering', async function (assert) {
assert.expect(17);
assert.expect(16);
const cfi = await createComponent(CustomFilterItem, {
props: {
@@ -39,34 +39,33 @@ odoo.define('web.filter_menu_generator_tests', function (require) {
});
assert.strictEqual(cfi.el.innerText.trim(), "Add Custom Filter");
assert.hasClass(cfi.el, 'o_generator_menu');
assert.hasClass(cfi.el, 'o_add_custom_filter_menu');
assert.strictEqual(cfi.el.children.length, 1);
await cpHelpers.toggleAddCustomFilter(cfi);
// Single condition
assert.containsOnce(cfi, 'div.o_filter_condition');
assert.containsOnce(cfi, 'div.o_filter_condition select.o_generator_menu_field');
assert.containsOnce(cfi, 'div.o_filter_condition select.o_generator_menu_operator');
assert.containsOnce(cfi, 'div.o_filter_condition span.o_generator_menu_value');
assert.containsNone(cfi, 'div.o_filter_condition .o_or_filter');
assert.containsNone(cfi, 'div.o_filter_condition .o_generator_menu_delete');
assert.containsOnce(cfi, '.o_filter_condition');
assert.containsOnce(cfi, '.o_filter_condition select.o_generator_menu_field');
assert.containsOnce(cfi, '.o_filter_condition select.o_generator_menu_operator');
assert.containsOnce(cfi, '.o_filter_condition span.o_generator_menu_value');
assert.containsNone(cfi, '.o_filter_condition .o_or_filter');
assert.containsNone(cfi, '.o_filter_condition .o_generator_menu_delete');
// no deletion allowed on single condition
assert.containsNone(cfi, 'div.o_filter_condition > i.o_generator_menu_delete');
assert.containsNone(cfi, '.o_filter_condition > i.o_generator_menu_delete');
// Buttons
assert.containsOnce(cfi, 'div.o_add_filter_menu');
assert.containsOnce(cfi, 'div.o_add_filter_menu > button.o_apply_filter');
assert.containsOnce(cfi, 'div.o_add_filter_menu > button.o_add_condition');
assert.containsOnce(cfi, 'button.o_apply_filter');
assert.containsOnce(cfi, 'button.o_add_condition');
assert.containsOnce(cfi, 'div.o_filter_condition');
assert.containsOnce(cfi, '.o_filter_condition');
await testUtils.dom.click('button.o_add_condition');
await cpHelpers.addCondition(cfi);
assert.containsN(cfi, 'div.o_filter_condition', 2);
assert.containsOnce(cfi, 'div.o_filter_condition .o_or_filter');
assert.containsN(cfi, 'div.o_filter_condition .o_generator_menu_delete', 2);
assert.containsN(cfi, '.o_filter_condition', 2);
assert.containsOnce(cfi, '.o_filter_condition .o_or_filter');
assert.containsN(cfi, '.o_filter_condition .o_generator_menu_delete', 2);
cfi.destroy();
});
@@ -95,7 +94,7 @@ odoo.define('web.filter_menu_generator_tests', function (require) {
// Add first filter condition
await testUtils.fields.editSelect(cfi.el.querySelector('.o_generator_menu_field'), fieldSecondValue);
await testUtils.fields.editSelect(cfi.el.querySelector('.o_generator_menu_operator'), operatorSecondValue);
await cpHelpers.editConditionOperator(cfi, 0, operatorSecondValue);
// Add a second conditon on the filter being created
await cpHelpers.addCondition(cfi);
@@ -150,7 +149,7 @@ odoo.define('web.filter_menu_generator_tests', function (require) {
}];
await cpHelpers.toggleAddCustomFilter(cfi);
await testUtils.fields.editSelect(cfi.el.querySelector('.o_generator_menu_field'), 'binary_field');
await testUtils.fields.editSelect(cfi.el.querySelector('.o_generator_menu_operator'), '=');
await cpHelpers.editConditionOperator(cfi, 0, '=');
await cpHelpers.applyFilter(cfi);
cfi.destroy();
@@ -228,13 +227,13 @@ odoo.define('web.filter_menu_generator_tests', function (require) {
// The only thing visible should be the button 'Add Custome Filter';
assert.strictEqual(cfi.el.children.length, 1);
assert.containsOnce(cfi, 'button.o_add_custom_filter');
assert.containsOnce(cfi, 'button.o_dropdown_toggler');
cfi.destroy();
});
QUnit.test('filtering by ID interval works', async function (assert) {
assert.expect(2);
assert.expect(4);
this.fields.id_field = { name: 'id_field', string: "ID", type: "id", searchable: true };
const expectedDomains = [
@@ -264,16 +263,15 @@ odoo.define('web.filter_menu_generator_tests', function (require) {
async function testValue(operator, value) {
// open filter menu generator, select ID field, switch operator, type value, then click apply
await cpHelpers.toggleAddCustomFilter(cfi);
await testUtils.fields.editSelect(cfi.el.querySelector('select.o_generator_menu_field'), 'id_field');
await testUtils.fields.editSelect(cfi.el.querySelector('.o_generator_menu_operator'), operator);
await testUtils.fields.editInput(cfi.el.querySelector(
'div.o_filter_condition span.o_generator_menu_value input'),
await cpHelpers.editConditionField(cfi, 0, 'id_field');
await cpHelpers.editConditionOperator(cfi, 0, operator);
await cpHelpers.editConditionValue(cfi, 0,
value
);
await cpHelpers.applyFilter(cfi);
}
for (const domain of expectedDomains) {
for (const domain of [...expectedDomains]) {
await testValue(domain[0][1], domain[0][2]);
}
@@ -317,9 +315,8 @@ odoo.define('web.filter_menu_generator_tests', function (require) {
async function testValue(value) {
// open filter menu generator, select trululu field and enter string `a`, then click apply
await cpHelpers.toggleAddCustomFilter(cfi);
await testUtils.fields.editSelect(cfi.el.querySelector('select.o_generator_menu_field'), 'many2one_field');
await testUtils.fields.editInput(cfi.el.querySelector(
'div.o_filter_condition span.o_generator_menu_value input'),
await cpHelpers.editConditionField(cfi, 0, 'many2one_field');
await cpHelpers.editConditionValue(cfi, 0,
value
);
await cpHelpers.applyFilter(cfi);
@@ -368,8 +365,8 @@ odoo.define('web.filter_menu_generator_tests', function (require) {
assert.strictEqual(cfi.el.querySelector('.o_generator_menu_field').value, 'date_time_field');
assert.strictEqual(cfi.el.querySelector('.o_generator_menu_operator').value, 'between');
await testUtils.fields.editSelect(cfi.el.querySelector('.o_generator_menu_operator'), '=');
await testUtils.fields.editSelect(cfi.el.querySelector('div.o_filter_condition span.o_generator_menu_value input'), '02/22/2017 11:00:00'); // in TZ
await cpHelpers.editConditionOperator(cfi, 0, '=');
await testUtils.fields.editSelect(cfi.el.querySelector('.o_filter_condition span.o_generator_menu_value input'), '02/22/2017 11:00:00'); // in TZ
await cpHelpers.applyFilter(cfi);
cfi.destroy();
@@ -432,11 +429,10 @@ odoo.define('web.filter_menu_generator_tests', function (require) {
});
await cpHelpers.toggleAddCustomFilter(cfi);
await testUtils.dom.click('button.o_add_condition');
await cpHelpers.addCondition(cfi);
const [floatSelect, idSelect] = cfi.el.querySelectorAll('.o_generator_menu_field');
await testUtils.fields.editSelect(floatSelect, 'float_field');
await testUtils.fields.editSelect(idSelect, 'id');
await cpHelpers.editConditionField(cfi, 0, "float_field");
await cpHelpers.editConditionField(cfi, 1, "id");
const [floatInput, idInput] = cfi.el.querySelectorAll('.o_generator_menu_value .o_input');
@@ -445,18 +441,18 @@ odoo.define('web.filter_menu_generator_tests', function (require) {
assert.strictEqual(idInput.value, "0");
// Float parsing
await testUtils.fields.editInput(floatInput, "4.2");
await cpHelpers.editConditionValue(cfi, 0, "4.2");
assert.strictEqual(floatInput.value, "4.2");
await testUtils.fields.editInput(floatInput, "DefinitelyValidFloat");
await cpHelpers.editConditionValue(cfi, 0, "DefinitelyValidFloat");
// String input in a number input gives "", which is parsed as 0
assert.strictEqual(floatInput.value, "0.0");
// Number parsing
await testUtils.fields.editInput(idInput, "4");
await cpHelpers.editConditionValue(cfi, 1, "4");
assert.strictEqual(idInput.value, "4");
await testUtils.fields.editInput(idInput, "4.2");
await cpHelpers.editConditionValue(cfi, 1, "4.2");
assert.strictEqual(idInput.value, "4");
await testUtils.fields.editInput(idInput, "DefinitelyValidID");
await cpHelpers.editConditionValue(cfi, 1, "DefinitelyValidID");
// String input in a number input gives "", which is parsed as 0
assert.strictEqual(idInput.value, "0");
@@ -482,10 +478,9 @@ odoo.define('web.filter_menu_generator_tests', function (require) {
});
await cpHelpers.toggleAddCustomFilter(cfi);
await testUtils.dom.click('button.o_add_condition');
await cpHelpers.addCondition(cfi);
const [floatSelect] = cfi.el.querySelectorAll('.o_generator_menu_field');
await testUtils.fields.editSelect(floatSelect, 'float_field');
await cpHelpers.editConditionField(cfi, 0, "float_field");
const [floatInput] = cfi.el.querySelectorAll('.o_generator_menu_value .o_input');
@@ -493,13 +488,13 @@ odoo.define('web.filter_menu_generator_tests', function (require) {
assert.strictEqual(floatInput.value, "0,0");
// Float parsing
await testUtils.fields.editInput(floatInput, '4,');
await cpHelpers.editConditionValue(cfi, 0, '4,');
assert.strictEqual(floatInput.value, "4,");
await testUtils.fields.editInput(floatInput, '4,2');
await cpHelpers.editConditionValue(cfi, 0, '4,2');
assert.strictEqual(floatInput.value, "4,2");
await testUtils.fields.editInput(floatInput, '4,2,');
await cpHelpers.editConditionValue(cfi, 0, '4,2,');
assert.strictEqual(floatInput.value, "4,2");
await testUtils.fields.editInput(floatInput, "DefinitelyValidFloat");
await cpHelpers.editConditionValue(cfi, 0, "DefinitelyValidFloat");
// The input here is a string, resulting in a parsing error instead of 0
assert.strictEqual(floatInput.value, "4,2");
@@ -520,8 +515,8 @@ odoo.define('web.filter_menu_generator_tests', function (require) {
type: "filter",
},
{
description: 'Boolean Field is true',
domain: '[["boolean_field","=",True]]',
description: 'Boolean Field is false',
domain: '[["boolean_field","!=",True]]',
type: "filter",
},
{
@@ -548,32 +543,27 @@ odoo.define('web.filter_menu_generator_tests', function (require) {
});
await cpHelpers.toggleAddCustomFilter(cfi);
await testUtils.dom.click('button.o_add_condition');
await testUtils.dom.click('button.o_add_condition');
await testUtils.dom.click('button.o_add_condition');
await testUtils.dom.click('button.o_add_condition');
await cpHelpers.addCondition(cfi);
await cpHelpers.addCondition(cfi);
await cpHelpers.addCondition(cfi);
await cpHelpers.addCondition(cfi);
function getCondition(index, selector) {
const condition = cfi.el.querySelectorAll('.o_filter_condition')[index];
return condition.querySelector(selector);
}
await cpHelpers.editConditionField(cfi, 0, 'date_field');
await cpHelpers.editConditionValue(cfi, 0, '01/09/1997');
await testUtils.fields.editSelect(getCondition(0, '.o_generator_menu_field'), 'date_field');
await testUtils.fields.editSelect(getCondition(0, '.o_generator_menu_value .o_input'), '01/09/1997');
await cpHelpers.editConditionField(cfi, 1, 'boolean_field');
await cpHelpers.editConditionOperator(cfi, 1, '!=');
await testUtils.fields.editSelect(getCondition(1, '.o_generator_menu_field'), 'boolean_field');
await testUtils.fields.editInput(getCondition(1, '.o_generator_menu_operator'), '!=');
await cpHelpers.editConditionField(cfi, 2, 'char_field');
await cpHelpers.editConditionValue(cfi, 2, "I will be deleted anyway");
await testUtils.fields.editSelect(getCondition(2, '.o_generator_menu_field'), 'char_field');
await testUtils.fields.editInput(getCondition(2, '.o_generator_menu_value .o_input'), "I will be deleted anyway");
await cpHelpers.editConditionField(cfi, 3, 'float_field');
await cpHelpers.editConditionValue(cfi, 3, 7.2);
await testUtils.fields.editSelect(getCondition(3, '.o_generator_menu_field'), 'float_field');
await testUtils.fields.editInput(getCondition(3, '.o_generator_menu_value .o_input'), 7.2);
await cpHelpers.editConditionField(cfi, 4, 'id');
await cpHelpers.editConditionValue(cfi, 4, 9);
await testUtils.fields.editSelect(getCondition(4, '.o_generator_menu_field'), 'id');
await testUtils.fields.editInput(getCondition(4, '.o_generator_menu_value .o_input'), 9);
await testUtils.dom.click(getCondition(2, '.o_generator_menu_delete'));
await cpHelpers.removeCondition(cfi, 2);
await cpHelpers.applyFilter(cfi);
@@ -26,18 +26,18 @@ odoo.define('web.groupby_menu_generator_tests', function (require) {
});
assert.strictEqual(cgi.el.innerText.trim(), "Add Custom Group");
assert.hasClass(cgi.el, 'o_generator_menu');
assert.hasClass(cgi.el, 'o_add_custom_group_menu');
assert.strictEqual(cgi.el.children.length, 1);
await testUtils.dom.click(cgi.el.querySelector('.o_generator_menu span.o_add_custom_group_by'));
await testUtils.dom.click(cgi.el.querySelector('.o_add_custom_group_menu .o_dropdown_toggler'));
// Single select node with a single option
assert.containsOnce(cgi, 'div > select.o_group_by_selector');
assert.strictEqual(cgi.el.querySelector('div > select.o_group_by_selector option').innerText.trim(),
assert.containsOnce(cgi, 'li > select');
assert.strictEqual(cgi.el.querySelector('li > select option').innerText.trim(),
"Super Date");
// Button apply
assert.containsOnce(cgi, 'button.o_apply_group_by');
assert.containsOnce(cgi, 'li > button.btn.btn-primary');
cgi.destroy();
});
@@ -61,12 +61,12 @@ odoo.define('web.groupby_menu_generator_tests', function (require) {
env: { searchModel },
});
await testUtils.dom.click(cgi.el.querySelector('.o_generator_menu span.o_add_custom_group_by'));
await testUtils.dom.click(cgi.el.querySelector('.o_generator_menu button.o_apply_group_by'));
await testUtils.dom.click(cgi.el.querySelector('.o_add_custom_group_menu .o_dropdown_toggler'));
await testUtils.dom.click(cgi.el.querySelector('li > button.btn.btn-primary'));
// The only thing visible should be the button 'Add Custome Group';
assert.strictEqual(cgi.el.children.length, 1);
assert.containsOnce(cgi, 'span.o_add_custom_group_by');
assert.containsOnce(cgi, '.o_dropdown_toggler');
cgi.destroy();
});
@@ -4,7 +4,7 @@ odoo.define('web.favorite_menu_tests', function (require) {
const FormView = require('web.FormView');
const testUtils = require('web.test_utils');
const cpHelpers = testUtils.controlPanel;
const cpHelpers = require('@web/../tests/search/helpers');
const { createControlPanel, createView, mock } = testUtils;
const { patchDate } = mock;
@@ -39,7 +39,7 @@ odoo.define('web.favorite_menu_tests', function (require) {
await cpHelpers.toggleFavoriteMenu(controlPanel);
assert.containsNone(controlPanel, '.dropdown-divider');
assert.containsOnce(controlPanel, '.o_add_favorite');
assert.strictEqual(controlPanel.el.querySelector('.o_add_favorite > span').innerText.trim(),
assert.strictEqual(controlPanel.el.querySelector('.o_add_favorite > button span').innerText.trim(),
"Save current search");
await cpHelpers.toggleSaveFavorite(controlPanel);
@@ -281,14 +281,14 @@ odoo.define('web.favorite_menu_tests', function (require) {
const { domain } = controlPanel.getQuery();
assert.deepEqual(domain, [["foo", "=", "qsdf"]]);
assert.deepEqual(cpHelpers.getFacetTexts(controlPanel), ["My favorite"]);
assert.hasClass(controlPanel.el.querySelector('.o_favorite_menu .o_menu_item > a'), 'selected');
assert.hasClass(controlPanel.el.querySelector('.o_favorite_menu .o_menu_item'), 'selected');
await cpHelpers.deleteFavorite(controlPanel, 0);
// confirm deletion
await testUtils.dom.click(document.querySelector('div.o_dialog footer button'));
assert.deepEqual(cpHelpers.getFacetTexts(controlPanel), []);
const itemEls = controlPanel.el.querySelectorAll('.o_favorite_menu .o_menu_item');
const itemEls = controlPanel.el.querySelectorAll('.o_favorite_menu .o_dropdown_item');
assert.deepEqual([...itemEls].map(e => e.innerText.trim()), ["Save current search"]);
controlPanel.destroy();
@@ -492,7 +492,6 @@ odoo.define('web.favorite_menu_tests', function (require) {
// second try: should succeed
await cpHelpers.editFavoriteName(controlPanel, "My favorite 2");
await cpHelpers.saveFavorite(controlPanel);
await cpHelpers.toggleSaveFavorite(controlPanel);
// third try: should fail
await cpHelpers.editFavoriteName(controlPanel, "My favorite 2");
@@ -559,18 +558,19 @@ odoo.define('web.favorite_menu_tests', function (require) {
assert.containsN(document.body, 'tr.o_data_row', 9, "should display 9 records");
await cpHelpers.toggleFilterMenu('.modal');
await cpHelpers.toggleAddCustomFilter('.modal');
const modal = document.body.querySelector(".modal");
await cpHelpers.toggleFilterMenu(modal);
await cpHelpers.toggleAddCustomFilter(modal);
assert.strictEqual(document.querySelector('.o_filter_condition select.o_generator_menu_field').value,
'date_field',
"date field should be selected");
await cpHelpers.applyFilter('.modal');
await cpHelpers.applyFilter(modal);
assert.containsNone(document.body, 'tr.o_data_row', "should display 0 records");
// Save this search
await cpHelpers.toggleFavoriteMenu('.modal');
await cpHelpers.toggleSaveFavorite('.modal');
await cpHelpers.toggleFavoriteMenu(modal);
await cpHelpers.toggleSaveFavorite(modal);
const filterNameInput = document.querySelector('.o_add_favorite input[type="text"]');
assert.isVisible(filterNameInput, "should display an input field for the filter name");
@@ -3,7 +3,8 @@ odoo.define('web.filter_menu_tests', function (require) {
const testUtils = require('web.test_utils');
const { controlPanel: cpHelpers, createControlPanel, mock } = testUtils;
const cpHelpers = require('@web/../tests/search/helpers');
const { createControlPanel, mock } = testUtils;
const { patchDate } = mock;
const searchMenuTypes = ['filter'];
@@ -30,7 +31,7 @@ odoo.define('web.filter_menu_tests', function (require) {
await cpHelpers.toggleFilterMenu(controlPanel);
assert.containsNone(controlPanel, '.o_menu_item, .dropdown-divider');
assert.containsOnce(controlPanel, 'div.o_generator_menu');
assert.containsOnce(controlPanel, '.o_add_custom_filter_menu');
controlPanel.destroy();
});
@@ -51,7 +52,7 @@ odoo.define('web.filter_menu_tests', function (require) {
await cpHelpers.toggleFilterMenu(controlPanel);
assert.containsOnce(controlPanel, '.o_menu_item');
assert.containsOnce(controlPanel, '.dropdown-divider');
assert.containsOnce(controlPanel, 'div.o_generator_menu');
assert.containsOnce(controlPanel, 'li.o_add_custom_filter_menu');
controlPanel.destroy();
});
@@ -67,7 +68,7 @@ odoo.define('web.filter_menu_tests', function (require) {
await cpHelpers.toggleFilterMenu(controlPanel);
await cpHelpers.toggleAddCustomFilter(controlPanel);
const optionEls = controlPanel.el.querySelectorAll('div.o_filter_condition select.o_generator_menu_field option');
const optionEls = controlPanel.el.querySelectorAll('.o_filter_condition select.o_generator_menu_field option');
assert.strictEqual(optionEls[0].innerText.trim(), 'Date');
assert.strictEqual(optionEls[1].innerText.trim(), 'ID');
@@ -126,11 +127,8 @@ odoo.define('web.filter_menu_tests', function (require) {
await cpHelpers.toggleFilterMenu(controlPanel);
await cpHelpers.toggleAddCustomFilter(controlPanel);
// choose ID field in 'Add Custome filter' menu and value 1
await testUtils.fields.editSelect(
controlPanel.el.querySelector('div.o_filter_condition select.o_generator_menu_field'), 'id');
await testUtils.fields.editInput(
controlPanel.el.querySelector('div.o_filter_condition span.o_generator_menu_value > input'), 1);
await cpHelpers.editConditionField(controlPanel, 0, 'id');
await cpHelpers.editConditionValue(controlPanel, 0, 1);
await cpHelpers.applyFilter(controlPanel);
assert.deepEqual(cpHelpers.getFacetTexts(controlPanel), ['ID is "1"']);
@@ -227,7 +225,7 @@ odoo.define('web.filter_menu_tests', function (require) {
await cpHelpers.toggleFilterMenu(controlPanel);
await cpHelpers.toggleMenuItem(controlPanel, "Date");
const optionEls = controlPanel.el.querySelectorAll('ul.o_menu_item_options > li.o_item_option > a');
const optionEls = controlPanel.el.querySelectorAll('li.o_item_option');
// default filter should be activated with the global default period 'this_month'
const { domain } = controlPanel.getQuery();
@@ -3,7 +3,7 @@ odoo.define('web.groupby_menu_tests', function (require) {
const testUtils = require('web.test_utils');
const cpHelpers = testUtils.controlPanel;
const cpHelpers = require('@web/../tests/search/helpers');
const { createControlPanel } = testUtils;
const searchMenuTypes = ['groupBy'];
@@ -32,7 +32,7 @@ odoo.define('web.groupby_menu_tests', function (require) {
};
const controlPanel = await createControlPanel(params);
assert.containsNone(controlPanel, '.o_menu_item, .dropdown-divider, div.o_generator_menu');
assert.containsNone(controlPanel, '.o_menu_item, .dropdown-divider, .o_add_custom_group_menu');
controlPanel.destroy();
});
@@ -48,11 +48,11 @@ odoo.define('web.groupby_menu_tests', function (require) {
await cpHelpers.toggleGroupByMenu(controlPanel);
assert.containsNone(controlPanel, '.o_menu_item, .dropdown-divider');
assert.containsOnce(controlPanel, 'div.o_generator_menu');
assert.containsOnce(controlPanel, '.o_add_custom_group_menu');
await cpHelpers.toggleAddCustomGroup(controlPanel);
const optionEls = controlPanel.el.querySelectorAll('div.o_generator_menu select.o_group_by_selector option');
const optionEls = controlPanel.el.querySelectorAll('.o_add_custom_group_menu select option');
assert.strictEqual(optionEls[0].innerText.trim(), 'Birthday');
assert.strictEqual(optionEls[1].innerText.trim(), 'Date');
assert.strictEqual(optionEls[2].innerText.trim(), 'Foo');
@@ -78,7 +78,7 @@ odoo.define('web.groupby_menu_tests', function (require) {
assert.containsOnce(controlPanel, '.o_menu_item');
assert.strictEqual(controlPanel.el.querySelector('.o_menu_item').innerText.trim(), "Groupby Foo");
assert.containsOnce(controlPanel, '.dropdown-divider');
assert.containsOnce(controlPanel, 'div.o_generator_menu');
assert.containsOnce(controlPanel, '.o_add_custom_group_menu');
controlPanel.destroy();
});
@@ -210,7 +210,7 @@ odoo.define('web.groupby_menu_tests', function (require) {
await cpHelpers.toggleGroupByMenu(controlPanel);
await cpHelpers.toggleMenuItem(controlPanel, 0);
const optionEls = controlPanel.el.querySelectorAll('ul.o_menu_item_options > li.o_item_option > a');
const optionEls = controlPanel.el.querySelectorAll('li.o_item_option');
// default groupby should be activated with the default inteval 'week'
const { groupBy } = controlPanel.getQuery();
@@ -322,7 +322,7 @@ odoo.define('web.groupby_menu_tests', function (require) {
await cpHelpers.toggleGroupByMenu(controlPanel);
await cpHelpers.toggleAddCustomGroup(controlPanel);
const optionEls = controlPanel.el.querySelectorAll('div.o_generator_menu select.o_group_by_selector option');
const optionEls = controlPanel.el.querySelectorAll('.o_add_custom_group_menu select option');
assert.strictEqual(optionEls.length, 1);
assert.strictEqual(optionEls[0].innerText.trim(), "Foo");
@@ -7,16 +7,10 @@ import { Model } from "web.Model";
import Registry from "web.Registry";
import SearchBar from "web.SearchBar";
import { registry } from "@web/core/registry";
import * as cpHelpers from "@web/../tests/search/helpers";
let serverData;
// legacy stuff
let cpHelpers;
QUnit.module("Search Bar (legacy)", (hooks) => {
hooks.before(() => {
cpHelpers = testUtils.controlPanel;
});
hooks.beforeEach(() => {
serverData = {
models: {
@@ -199,7 +193,7 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
assert.containsNone(searchBar, '.o_searchview_autocomplete');
await cpHelpers.editSearch(searchBar, "Hello there");
await testUtils.controlPanel.editSearch(searchBar, "Hello there");
assert.strictEqual(input.value, "Hello there", "input value should be updated");
assert.containsOnce(searchBar, '.o_searchview_autocomplete');
@@ -209,7 +203,7 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
assert.strictEqual(input.value, "", "input value should be empty");
assert.containsNone(searchBar, '.o_searchview_autocomplete');
await cpHelpers.editSearch(searchBar, "General Kenobi");
await testUtils.controlPanel.editSearch(searchBar, "General Kenobi");
assert.strictEqual(input.value, "General Kenobi", "input value should be updated");
assert.containsOnce(searchBar, '.o_searchview_autocomplete');
@@ -481,12 +475,12 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
});
await doAction(webClient, 1);
await cpHelpers.editSearch(webClient, "rec");
await testUtils.controlPanel.editSearch(webClient, "rec");
await testUtils.dom.click(webClient.el.querySelector('.o_searchview_autocomplete li:last-child'));
await cpHelpers.removeFacet(webClient, 0);
await cpHelpers.editSearch(webClient, "rec");
await testUtils.controlPanel.editSearch(webClient, "rec");
await testUtils.dom.click(webClient.el.querySelector('.o_expand'));
await testUtils.dom.click(webClient.el.querySelector('.o_searchview_autocomplete li.o_menu_item.o_indent'));
@@ -512,7 +506,7 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
});
await doAction(webClient, 1);
await cpHelpers.editSearch(webClient, "null");
await testUtils.controlPanel.editSearch(webClient, "null");
assert.strictEqual(
webClient.el.querySelector('.o_searchview_autocomplete .o_selection_focus').innerText,
@@ -545,7 +539,7 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
});
await doAction(webClient, 1);
await cpHelpers.editSearch(webClient, "y");
await testUtils.controlPanel.editSearch(webClient, "y");
assert.containsOnce(webClient, '.o_searchview_autocomplete li');
assert.strictEqual(webClient.el.querySelector('.o_searchview_autocomplete li').innerText, "Search Bool: Yes");
@@ -556,7 +550,7 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
await cpHelpers.removeFacet(webClient, 0);
await cpHelpers.editSearch(webClient, "No");
await testUtils.controlPanel.editSearch(webClient, "No");
assert.containsOnce(webClient, '.o_searchview_autocomplete li');
assert.strictEqual(webClient.el.querySelector('.o_searchview_autocomplete li').innerText, "Search Bool: No");
@@ -583,7 +577,7 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
await cpHelpers.editSearch(webClient, "n");
await testUtils.controlPanel.editSearch(webClient, "n");
assert.containsN(webClient, '.o_searchview_autocomplete li', 2);
assert.strictEqual(webClient.el.querySelector('.o_searchview_autocomplete li:first-child').innerText, "Search Status: New");
@@ -617,13 +611,13 @@ QUnit.module("Search Bar (legacy)", (hooks) => {
});
await doAction(webClient, 1);
await cpHelpers.editSearch(webClient, "ref");
await testUtils.controlPanel.editSearch(webClient, "ref");
await cpHelpers.validateSearch(webClient);
assert.containsN(webClient, ".o_data_row", 5);
await cpHelpers.removeFacet(webClient, 0);
await cpHelpers.editSearch(webClient, "ref002");
await testUtils.controlPanel.editSearch(webClient, "ref002");
await cpHelpers.validateSearch(webClient);
assert.containsOnce(webClient, ".o_data_row");
@@ -4,7 +4,7 @@ odoo.define('web.field_many_to_many_tests', function (require) {
var FormView = require('web.FormView');
var testUtils = require('web.test_utils');
const cpHelpers = testUtils.controlPanel;
const cpHelpers = require('@web/../tests/search/helpers');
var createView = testUtils.createView;
QUnit.module('fields', {}, function () {
@@ -637,12 +637,12 @@ QUnit.module('fields', {}, function () {
form.destroy();
});
QUnit.test('many2many: create & delete attributes', async function (assert) {
assert.expect(4);
QUnit.test('many2many: create & delete attributes (both true)', async function (assert) {
assert.expect(2);
this.data.partner.records[0].timmy = [12, 14];
var form = await createView({
const form = await createView({
View: FormView,
model: 'partner',
data: this.data,
@@ -662,8 +662,14 @@ QUnit.module('fields', {}, function () {
assert.containsN(form, '.o_list_record_remove', 2, "should have the 'Add an item' link");
form.destroy();
});
form = await createView({
QUnit.test('many2many: create & delete attributes (both false)', async function (assert) {
assert.expect(2);
this.data.partner.records[0].timmy = [12, 14];
const form = await createView({
View: FormView,
model: 'partner',
data: this.data,
@@ -1211,8 +1217,9 @@ QUnit.module('fields', {}, function () {
assert.strictEqual($('.modal .o_data_row').length, 1,
"should contain only one row (gold)");
await cpHelpers.editSearch('.modal', 's');
await cpHelpers.validateSearch('.modal');
const modal = document.body.querySelector(".modal");
await cpHelpers.editSearch(modal, 's');
await cpHelpers.validateSearch(modal);
assert.strictEqual($('.modal .o_data_row').length, 0, "should contain no row");
@@ -10,7 +10,7 @@ var StandaloneFieldManagerMixin = require('web.StandaloneFieldManagerMixin');
var testUtils = require('web.test_utils');
var Widget = require('web.Widget');
const cpHelpers = testUtils.controlPanel;
const cpHelpers = require('@web/../tests/search/helpers');
var createView = testUtils.createView;
QUnit.module('fields', {}, function () {
@@ -569,11 +569,13 @@ QUnit.module('fields', {}, function () {
assert.strictEqual($('tr.o_data_row').length, 9, "should display 9 records");
await cpHelpers.toggleFilterMenu('.modal');
await cpHelpers.toggleAddCustomFilter('.modal');
assert.strictEqual(document.querySelector('.modal .o_generator_menu_field').value, 'datetime',
const modal = document.body.querySelector(".modal");
await cpHelpers.toggleFilterMenu(modal);
await cpHelpers.toggleAddCustomFilter(modal);
assert.strictEqual(modal.querySelector('.o_generator_menu_field').value, 'datetime',
"datetime field should be selected");
await cpHelpers.applyFilter('.modal');
await cpHelpers.applyFilter(modal);
assert.strictEqual($('tr.o_data_row').length, 0, "should display 0 records");
form.destroy();
@@ -874,8 +876,9 @@ QUnit.module('fields', {}, function () {
assert.ok(!$('.modal .modal-footer .o_select_button').length,
"there should be no 'Select' button in the footer");
assert.ok($('.modal tbody tr').length > 10, "list should contain more than 10 records");
await cpHelpers.editSearch('.modal', "P");
await cpHelpers.validateSearch('.modal');
const modal = document.body.querySelector(".modal");
await cpHelpers.editSearch(modal, "P");
await cpHelpers.validateSearch(modal);
assert.strictEqual($('.modal tbody tr').length, 10,
"list should be restricted to records containing a P (10 records)");
// choose a record
@@ -3126,18 +3129,18 @@ QUnit.module('fields', {}, function () {
await testUtils.dom.click(document.querySelector(`${filterMenuCss} > .o_dropdown_toggler`));
assert.hasClass(document.querySelector(filterMenuCss), 'show');
assert.isVisible(document.querySelector(`${filterMenuCss} > .dropdown-menu`),
assert.isVisible(document.querySelector(`${filterMenuCss} > .o_dropdown_menu`),
"the filter dropdown menu should be visible");
assert.doesNotHaveClass(document.querySelector(groupByMenuCss), 'show');
assert.isNotVisible(document.querySelector(`${groupByMenuCss} > .dropdown-menu`),
assert.isNotVisible(document.querySelector(`${groupByMenuCss} > .o_dropdown_menu`),
"the Group by dropdown menu should be not visible");
await testUtils.dom.click(document.querySelector(`${groupByMenuCss} > .o_dropdown_toggler`));
assert.hasClass(document.querySelector(groupByMenuCss), 'show');
assert.isVisible(document.querySelector(`${groupByMenuCss} > .dropdown-menu`),
assert.isVisible(document.querySelector(`${groupByMenuCss} > .o_dropdown_menu`),
"the group by dropdown menu should be visible");
assert.doesNotHaveClass(document.querySelector(filterMenuCss), 'show');
assert.isNotVisible(document.querySelector(`${filterMenuCss} > .dropdown-menu`),
assert.isNotVisible(document.querySelector(`${filterMenuCss} > .o_dropdown_menu`),
"the filter dropdown menu should be not visible");
$fakeDialog.remove();
@@ -17,7 +17,7 @@ const { patch, unpatch } = require('web.utils');
const { makeLegacyDialogMappingTestEnv } = require('@web/../tests/helpers/legacy_env_utils');
const cpHelpers = testUtils.controlPanel;
const cpHelpers = require('@web/../tests/search/helpers');
var createView = testUtils.createView;
const { FieldOne2Many } = relationalFields;
@@ -1845,14 +1845,14 @@ QUnit.module('fields', {}, function () {
// move to record 2, which has 3 related records (and shouldn't contain the
// related records of record 1 anymore). Two additional RPCs should have
// been done
await cpHelpers.pagerNext(form);
await testUtils.controlPanel.pagerNext(form);
assert.strictEqual(count, 4, 'two RPCs should have been done');
assert.strictEqual(form.$('.o_kanban_record:not(".o_kanban_ghost")').length, 3,
'one2many kanban should contain 3 cards for record 2');
// move back to record 1, which should contain again its first 40 related
// records
await cpHelpers.pagerPrevious(form);
await testUtils.controlPanel.pagerPrevious(form);
assert.strictEqual(count, 6, 'two RPCs should have been done');
assert.strictEqual(form.$('.o_kanban_record:not(".o_kanban_ghost")').length, 40,
'one2many kanban should contain 40 cards for record 1');
@@ -1865,14 +1865,14 @@ QUnit.module('fields', {}, function () {
'one2many kanban should contain 2 cards for record 1 at page 2');
// move to record 2 again and check that everything is correctly updated
await cpHelpers.pagerNext(form);
await testUtils.controlPanel.pagerNext(form);
assert.strictEqual(count, 9, 'two RPCs should have been done');
assert.strictEqual(form.$('.o_kanban_record:not(".o_kanban_ghost")').length, 3,
'one2many kanban should contain 3 cards for record 2');
// move back to record 1 and move to page 2 again: all data should have
// been correctly reloaded
await cpHelpers.pagerPrevious(form);
await testUtils.controlPanel.pagerPrevious(form);
assert.strictEqual(count, 11, 'two RPCs should have been done');
await testUtils.dom.click(form.$('.o_x2m_control_panel .o_pager_next'));
assert.strictEqual(count, 12, 'one RPC should have been done');
@@ -12,7 +12,7 @@ var testUtils = require('web.test_utils');
const { makeLegacyDialogMappingTestEnv } = require('@web/../tests/helpers/legacy_env_utils');
const cpHelpers = testUtils.controlPanel;
const cpHelpers = require('@web/../tests/search/helpers');
var createView = testUtils.createView;
QUnit.module('fields', {}, function () {
@@ -211,8 +211,9 @@ QUnit.module('relational_fields', {
assert.strictEqual($('.o_pager_value').text(), "181-160", "should display the second page");
assert.strictEqual($('tr.o_data_row').length, 80, "should display 80 record");
await cpHelpers.editSearch('.modal', "first");
await cpHelpers.validateSearch('.modal');
const modal = document.body.querySelector(".modal");
await cpHelpers.editSearch(modal, "first");
await cpHelpers.validateSearch(modal);
assert.strictEqual($('.o_pager_limit').text(), "11", "there should be 1 record");
assert.strictEqual($('.o_pager_value').text(), "11-1", "should display the first page");
@@ -1742,8 +1743,9 @@ QUnit.module('relational_fields', {
});
await testUtils.fields.many2one.clickOpenDropdown('trululu');
await testUtils.fields.many2one.clickItem('trululu', 'Search');
await cpHelpers.toggleGroupByMenu('.modal');
await cpHelpers.toggleMenuItem('.modal', "Bar");
const modal = document.body.querySelector(".modal");
await cpHelpers.toggleGroupByMenu(modal);
await cpHelpers.toggleMenuItem(modal, "Bar");
await testUtils.dom.click($('.modal .o_group_header:first'));
@@ -76,6 +76,8 @@ odoo.define('web.test_env', async function (require) {
return env.session.rpc(query.route, query.params, options);
},
notification: { notify() { } },
hotkey: { add: () => () => {} }, // fake service
ui: { activeElement: document }, // fake service
}, env.services),
session: Object.assign({
rpc(route, params, options) {
@@ -426,7 +426,7 @@ async function addMockEnvironmentOwl(Component, params, mockServer) {
function cleanUp() {
env.bus.destroy();
Object.keys(env.services).forEach(function (s) {
var service = env.services[s];
var service = env.services[s] || {};
if (service.destroy && !service.isDestroyed()) {
service.destroy();
}
@@ -19,7 +19,6 @@ const widgetRegistryOwl = require('web.widgetRegistry');
var Widget = require('web.Widget');
var _t = core._t;
const cpHelpers = testUtils.controlPanel;
var createView = testUtils.createView;
const { legacyExtraNextTick, patchWithCleanup } = require("@web/../tests/helpers/utils");
@@ -2611,18 +2610,18 @@ QUnit.module('Views', {
},
});
await cpHelpers.toggleActionMenu(form);
await testUtils.controlPanel.toggleActionMenu(form);
assert.containsOnce(form, '.o_cp_action_menus a:contains(Archive)');
await cpHelpers.toggleMenuItem(form, "Archive");
await testUtils.controlPanel.toggleMenuItem(form, "Archive");
assert.containsOnce(document.body, '.modal');
await testUtils.dom.click($('.modal-footer .btn-primary'));
await cpHelpers.toggleActionMenu(form);
await testUtils.controlPanel.toggleActionMenu(form);
assert.containsOnce(form, '.o_cp_action_menus a:contains(Unarchive)');
await cpHelpers.toggleMenuItem(form, "Unarchive");
await cpHelpers.toggleActionMenu(form);
await testUtils.controlPanel.toggleMenuItem(form, "Unarchive");
await testUtils.controlPanel.toggleActionMenu(form);
assert.containsOnce(form, '.o_cp_action_menus a:contains(Archive)');
assert.verifySteps([
@@ -2651,7 +2650,7 @@ QUnit.module('Views', {
arch: '<form><field name="foo"/></form>',
});
await cpHelpers.toggleActionMenu(form);
await testUtils.controlPanel.toggleActionMenu(form);
assert.containsNone(form, '.o_cp_action_menus a:contains(Archive)');
assert.containsNone(form, '.o_cp_action_menus a:contains(Unarchive)');
@@ -2675,8 +2674,8 @@ QUnit.module('Views', {
assert.strictEqual(form.$('.o_control_panel .breadcrumb').text(), 'first record',
"should have the display name of the record as title");
await cpHelpers.toggleActionMenu(form);
await cpHelpers.toggleMenuItem(form, "Duplicate");
await testUtils.controlPanel.toggleActionMenu(form);
await testUtils.controlPanel.toggleMenuItem(form, "Duplicate");
assert.strictEqual(form.$('.o_control_panel .breadcrumb').text(), 'first record (copy)',
"should have duplicated the record");
@@ -2708,8 +2707,8 @@ QUnit.module('Views', {
},
});
await cpHelpers.toggleActionMenu(form);
await cpHelpers.toggleMenuItem(form, "Duplicate");
await testUtils.controlPanel.toggleActionMenu(form);
await testUtils.controlPanel.toggleMenuItem(form, "Duplicate");
form.destroy();
});
@@ -3257,8 +3256,8 @@ QUnit.module('Views', {
await testUtils.fields.editInput(form.$('input[name=foo]'), 'tralala');
await testUtils.form.clickSave(form);
await cpHelpers.toggleActionMenu(form);
await cpHelpers.toggleMenuItem(form, "Duplicate");
await testUtils.controlPanel.toggleActionMenu(form);
await testUtils.controlPanel.toggleMenuItem(form, "Duplicate");
assert.strictEqual(form.$('input[name=foo]').val(), 'tralala', 'input should contain ABC');
@@ -3291,8 +3290,8 @@ QUnit.module('Views', {
},
});
assert.strictEqual(cpHelpers.getPagerValue(form), '1', "pager value should be 1");
assert.strictEqual(cpHelpers.getPagerSize(form), '2', "pager limit should be 2");
assert.strictEqual(testUtils.controlPanel.getPagerValue(form), '1', "pager value should be 1");
assert.strictEqual(testUtils.controlPanel.getPagerSize(form), '2', "pager limit should be 2");
// switch to edit mode
await testUtils.form.clickEdit(form);
@@ -3303,14 +3302,14 @@ QUnit.module('Views', {
assert.strictEqual(form.$('input').val(), 'new value', 'input should contain new value');
// click on the pager to switch to the next record (will save record)
await cpHelpers.pagerNext(form);
await testUtils.controlPanel.pagerNext(form);
assert.containsNone(document.body, '.modal', "no confirm modal should be displayed");
assert.strictEqual(cpHelpers.getPagerValue(form), '2', "pager value should be 2");
assert.strictEqual(testUtils.controlPanel.getPagerValue(form), '2', "pager value should be 2");
assert.strictEqual(form.$('input[name=foo]').val(), 'blip', "input should contain blip");
await cpHelpers.pagerPrevious(form);
await testUtils.controlPanel.pagerPrevious(form);
assert.containsNone(document.body, '.modal', "no confirm modal should be displayed");
assert.strictEqual(cpHelpers.getPagerValue(form), '1', "pager value should be 1");
assert.strictEqual(testUtils.controlPanel.getPagerValue(form), '1', "pager value should be 1");
assert.strictEqual(form.$('input[name=foo]').val(), 'new value', "input should contain new value");
assert.strictEqual(nbWrite, 1, 'one write RPC should have been done');
@@ -3335,7 +3334,7 @@ QUnit.module('Views', {
res_id: 1,
});
assert.strictEqual(cpHelpers.getPagerValue(form), '1', "pager value should be 1");
assert.strictEqual(testUtils.controlPanel.getPagerValue(form), '1', "pager value should be 1");
// switch to edit mode
await testUtils.form.clickEdit(form);
@@ -3349,10 +3348,10 @@ QUnit.module('Views', {
await testUtils.form.clickSave(form);
// click on the pager to switch to the next record and cancel the confirm request
await cpHelpers.pagerNext(form);
await testUtils.controlPanel.pagerNext(form);
assert.containsNone(document.body, '.modal:visible',
"no confirm modal should be displayed");
assert.strictEqual(cpHelpers.getPagerValue(form), '2', "pager value should be 2");
assert.strictEqual(testUtils.controlPanel.getPagerValue(form), '2', "pager value should be 2");
assert.containsN(form, '.o_priority .fa-star-o', 2,
'priority widget should have been rendered with correct value');
@@ -3362,10 +3361,10 @@ QUnit.module('Views', {
assert.containsOnce(form, '.o_priority .fa-star',
'priority widget should have been updated');
await cpHelpers.pagerNext(form);
await testUtils.controlPanel.pagerNext(form);
assert.containsNone(document.body, '.modal:visible',
"no confirm modal should be displayed");
assert.strictEqual(cpHelpers.getPagerValue(form), '1', "pager value should be 1");
assert.strictEqual(testUtils.controlPanel.getPagerValue(form), '1', "pager value should be 1");
// switch to edit mode
await testUtils.form.clickEdit(form);
@@ -3377,8 +3376,8 @@ QUnit.module('Views', {
await testUtils.form.clickDiscard(form);
assert.containsNone(document.body, '.modal', "no confirm modal should be displayed");
await cpHelpers.pagerNext(form);
assert.strictEqual(cpHelpers.getPagerValue(form), '2', "pager value should be 2");
await testUtils.controlPanel.pagerNext(form);
assert.strictEqual(testUtils.controlPanel.getPagerValue(form), '2', "pager value should be 2");
form.destroy();
});
@@ -3413,7 +3412,7 @@ QUnit.module('Views', {
assert.hasClass(form.$('.o_notebook .nav-link:eq(1)'), 'active');
// click on the pager to switch to the next record
await cpHelpers.pagerNext(form);
await testUtils.controlPanel.pagerNext(form);
assert.doesNotHaveClass(form.$('.o_notebook .nav-link:eq(0)'), 'active');
assert.hasClass(form.$('.o_notebook .nav-link:eq(1)'), 'active');
@@ -3438,9 +3437,9 @@ QUnit.module('Views', {
});
assert.containsOnce(form, '.o_pager');
assert.strictEqual(cpHelpers.getPagerValue(form), "1",
assert.strictEqual(testUtils.controlPanel.getPagerValue(form), "1",
"current pager value should be 1");
assert.strictEqual(cpHelpers.getPagerSize(form), "2",
assert.strictEqual(testUtils.controlPanel.getPagerSize(form), "2",
"current pager limit should be 1");
await testUtils.form.clickCreate(form);
@@ -3450,9 +3449,9 @@ QUnit.module('Views', {
await testUtils.form.clickSave(form);
assert.containsOnce(form, '.o_pager');
assert.strictEqual(cpHelpers.getPagerValue(form), "3",
assert.strictEqual(testUtils.controlPanel.getPagerValue(form), "3",
"current pager value should be 3");
assert.strictEqual(cpHelpers.getPagerSize(form), "3",
assert.strictEqual(testUtils.controlPanel.getPagerSize(form), "3",
"current pager limit should be 3");
form.destroy();
@@ -3481,11 +3480,11 @@ QUnit.module('Views', {
});
assert.strictEqual(form.mode, 'readonly', 'form view should be in readonly mode');
assert.strictEqual(cpHelpers.getPagerValue(form), "1", 'pager value should be 1');
assert.strictEqual(testUtils.controlPanel.getPagerValue(form), "1", 'pager value should be 1');
await cpHelpers.pagerNext(form);
await testUtils.controlPanel.pagerNext(form);
assert.strictEqual(cpHelpers.getPagerValue(form), "2", 'pager value should be 2');
assert.strictEqual(testUtils.controlPanel.getPagerValue(form), "2", 'pager value should be 2');
assert.strictEqual(form.mode, 'readonly', 'form view should be in readonly mode');
assert.strictEqual(pushStateCount, 2, "should have triggered 2 push_state");
@@ -3587,23 +3586,23 @@ QUnit.module('Views', {
res_id: 1,
});
assert.strictEqual(cpHelpers.getPagerValue(form), "1", 'pager value should be 1');
assert.strictEqual(cpHelpers.getPagerSize(form), "3", 'pager limit should be 3');
assert.strictEqual(testUtils.controlPanel.getPagerValue(form), "1", 'pager value should be 1');
assert.strictEqual(testUtils.controlPanel.getPagerSize(form), "3", 'pager limit should be 3');
assert.strictEqual(form.$('span:contains(yop)').length, 1,
'should have a field with foo value for record 1');
assert.ok(!$('.modal:visible').length, 'no confirm modal should be displayed');
// open action menu and delete
await cpHelpers.toggleActionMenu(form);
await cpHelpers.toggleMenuItem(form, "Delete");
await testUtils.controlPanel.toggleActionMenu(form);
await testUtils.controlPanel.toggleMenuItem(form, "Delete");
assert.ok($('.modal').length, 'a confirm modal should be displayed');
// confirm the delete
await testUtils.dom.click($('.modal-footer button.btn-primary'));
assert.strictEqual(cpHelpers.getPagerValue(form), "1", 'pager value should be 1');
assert.strictEqual(cpHelpers.getPagerSize(form), "2", 'pager limit should be 2');
assert.strictEqual(testUtils.controlPanel.getPagerValue(form), "1", 'pager value should be 1');
assert.strictEqual(testUtils.controlPanel.getPagerSize(form), "2", 'pager limit should be 2');
assert.strictEqual(form.$('span:contains(blip)').length, 1,
'should have a field with foo value for record 2');
form.destroy();
@@ -3629,8 +3628,8 @@ QUnit.module('Views', {
}
});
await cpHelpers.toggleActionMenu(form);
await cpHelpers.toggleMenuItem(form, "Delete");
await testUtils.controlPanel.toggleActionMenu(form);
await testUtils.controlPanel.toggleMenuItem(form, "Delete");
await testUtils.mock.intercept(form, 'history_back', function () {
assert.step('history_back');
@@ -6255,7 +6254,7 @@ QUnit.module('Views', {
assert.containsNone(form, '.o_cp_action_menus .o_dropdown:contains(Print)');
assert.containsOnce(form, '.o_cp_action_menus .o_dropdown:contains(Action)');
await cpHelpers.toggleActionMenu(form);
await testUtils.controlPanel.toggleActionMenu(form);
assert.containsN(form, '.o_cp_action_menus .dropdown-item', 3, "there should be 3 actions");
assert.strictEqual(form.$('.o_cp_action_menus .dropdown-item:last').text().trim(), 'Action partner',
@@ -6268,7 +6267,7 @@ QUnit.module('Views', {
assert.deepEqual(context.active_ids, [1],
"the active_ids should be an array with 1 inside.");
});
await cpHelpers.toggleMenuItem(form, "Action partner");
await testUtils.controlPanel.toggleMenuItem(form, "Action partner");
form.destroy();
});
@@ -6413,7 +6412,7 @@ QUnit.module('Views', {
"first tab should be active");
// click on the pager to switch to the next record
await cpHelpers.pagerNext(form);
await testUtils.controlPanel.pagerNext(form);
assert.strictEqual(form.$('.o_notebook .nav-item:not(.o_invisible_modifier)').length, 1,
"only the second tab should be visible");
@@ -6421,7 +6420,7 @@ QUnit.module('Views', {
"the visible tab should be active");
// click on the pager to switch back to the previous record
await cpHelpers.pagerPrevious(form);
await testUtils.controlPanel.pagerPrevious(form);
assert.strictEqual(form.$('.o_notebook .nav-item:not(.o_invisible_modifier)').length, 2,
"both tabs should be visible again");
@@ -6939,11 +6938,11 @@ QUnit.module('Views', {
assert.containsOnce(form, '.o_form_view .alert > div', "should have a translation alert");
// click on the pager to switch to the next record
await cpHelpers.pagerNext(form);
await testUtils.controlPanel.pagerNext(form);
assert.containsNone(form, '.o_form_view .alert > div', "should not have a translation alert");
// click on the pager to switch back to the previous record
await cpHelpers.pagerPrevious(form);
await testUtils.controlPanel.pagerPrevious(form);
assert.containsOnce(form, '.o_form_view .alert > div', "should have a translation alert");
// remove translation alert by click X and check alert even after form reload
@@ -7754,8 +7753,8 @@ QUnit.module('Views', {
});
// duplicate record 1
await cpHelpers.toggleActionMenu(form);
await cpHelpers.toggleMenuItem(form, "Duplicate");
await testUtils.controlPanel.toggleActionMenu(form);
await testUtils.controlPanel.toggleMenuItem(form, "Duplicate");
assert.containsOnce(form, '.o_form_editable',
"form should be in edit mode");
@@ -7764,8 +7763,8 @@ QUnit.module('Views', {
await testUtils.form.clickSave(form); // save duplicated record
// delete duplicated record
await cpHelpers.toggleActionMenu(form);
await cpHelpers.toggleMenuItem(form, "Delete");
await testUtils.controlPanel.toggleActionMenu(form);
await testUtils.controlPanel.toggleMenuItem(form, "Delete");
assert.strictEqual($('.modal').length, 1, "should have opened a confirm dialog");
await testUtils.dom.click($('.modal-footer .btn-primary'));
@@ -8381,17 +8380,17 @@ QUnit.module('Views', {
res_id: 2,
});
assert.strictEqual(cpHelpers.getPagerValue(form), "2",
assert.strictEqual(testUtils.controlPanel.getPagerValue(form), "2",
'pager should indicate that we are on second record');
assert.strictEqual(cpHelpers.getPagerSize(form), "2",
assert.strictEqual(testUtils.controlPanel.getPagerSize(form), "2",
'pager should indicate that we are on second record');
await testUtils.form.clickEdit(form);
await testUtils.form.clickDiscard(form);
assert.strictEqual(cpHelpers.getPagerValue(form), "2",
assert.strictEqual(testUtils.controlPanel.getPagerValue(form), "2",
'pager value should not have changed');
assert.strictEqual(cpHelpers.getPagerSize(form), "2",
assert.strictEqual(testUtils.controlPanel.getPagerSize(form), "2",
'pager limit should not have changed');
form.destroy();
@@ -8546,8 +8545,8 @@ QUnit.module('Views', {
});
core.bus.on('clear_cache', form, assert.step.bind(assert, 'clear_cache'));
await cpHelpers.toggleActionMenu(form);
await cpHelpers.toggleMenuItem(form, "Delete");
await testUtils.controlPanel.toggleActionMenu(form);
await testUtils.controlPanel.toggleMenuItem(form, "Delete");
await testUtils.dom.click($('.modal-footer .btn-primary'));
assert.verifySteps(['unlink', 'clear_cache']);
@@ -8941,7 +8940,7 @@ QUnit.module('Views', {
await testUtils.fields.many2one.clickOpenDropdown('trululu');
// switch to another record (should ask to discard changes, and reset the domain)
await cpHelpers.pagerNext(form);
await testUtils.controlPanel.pagerNext(form);
assert.containsNone(document.body, '.modal', 'should not open modal');
@@ -11,7 +11,7 @@ const legacyViewRegistry = require("web.view_registry");
const { registry } = require("@web/core/registry");
const { createView } = testUtils;
const cpHelpers = testUtils.controlPanel;
const cpHelpers = require('@web/../tests/search/helpers');
const patchDate = testUtils.mock.patchDate;
const viewRegistry = registry.category("views");
@@ -331,8 +331,8 @@ QUnit.module('Views', {
return this._super(route, args);
},
});
await cpHelpers.toggleMenu(graph, "Measures");
await cpHelpers.toggleMenuItem(graph, "Foo");
await testUtils.controlPanel.toggleMenu(graph, "Measures");
await testUtils.controlPanel.toggleMenuItem(graph, "Foo");
checkLegend(assert, graph, 'Foo');
assert.strictEqual(rpcCount, 2, "should have done 2 rpcs (2 readgroups)");
@@ -414,8 +414,8 @@ QUnit.module('Views', {
},
});
await cpHelpers.toggleComparisonMenu(graph);
await cpHelpers.toggleMenuItem(graph, 'Date: Previous period');
await cpHelpers.toggleComparisonMenu(graph.el);
await cpHelpers.toggleMenuItem(graph.el, 'Date: Previous period');
assert.containsNone(graph, 'div.o_view_nocontent',
"should not display the no content helper");
@@ -496,8 +496,8 @@ QUnit.module('Views', {
}
}, "context should be correct");
await cpHelpers.toggleMenu(graph, "Measures");
await cpHelpers.toggleMenuItem(graph, "Foo");
await testUtils.controlPanel.toggleMenu(graph, "Measures");
await testUtils.controlPanel.toggleMenuItem(graph, "Foo");
assert.deepEqual(graph.getOwnedQueryParams(), {
context: {
@@ -774,8 +774,8 @@ QUnit.module('Views', {
// need to set the measure this way because it cannot be set in the
// arch.
await cpHelpers.toggleMenu(graph, "Measures");
await cpHelpers.toggleMenuItem(graph, "Product");
await testUtils.controlPanel.toggleMenu(graph, "Measures");
await testUtils.controlPanel.toggleMenuItem(graph, "Product");
checkLabels(assert, graph, [['xphone'], ['xpad']]);
checkLegend(assert, graph, 'Product');
@@ -901,7 +901,7 @@ QUnit.module('Views', {
</graph>`,
});
await cpHelpers.toggleMenu(graph, "Measures");
await testUtils.controlPanel.toggleMenu(graph, "Measures");
assert.strictEqual(graph.$buttons.find('.o_graph_measures_list .dropdown-item:first').text(), 'bouh',
"Bouh should be the first measure");
assert.strictEqual(graph.$buttons.find('.o_graph_measures_list .dropdown-item:last').text(), 'Count',
@@ -929,8 +929,8 @@ QUnit.module('Views', {
let yAxisLabel = chart.config.options.scales.yAxes[0].scaleLabel.labelString;
assert.strictEqual(yAxisLabel, "Foo");
await cpHelpers.toggleMenu(graph, "Measures");
await cpHelpers.toggleMenuItem(graph, "Jethalal");
await testUtils.controlPanel.toggleMenu(graph, "Measures");
await testUtils.controlPanel.toggleMenuItem(graph, "Jethalal");
checkLegend(assert, graph, 'Jethalal');
chart = graph.renderer.componentRef.comp.chart;
@@ -1683,53 +1683,53 @@ QUnit.module('Views', {
const facetEls = graph.el.querySelectorAll('.o_searchview_facet');
const facetIndex = [...facetEls].findIndex(el => !!el.querySelector('span.fa-filter'));
if (facetIndex > -1) {
await cpHelpers.removeFacet(graph, facetIndex);
await cpHelpers.removeFacet(graph.el, facetIndex);
}
const [yearId, otherId] = basicDomainId.split('__');
await cpHelpers.toggleFilterMenu(graph);
await cpHelpers.toggleMenuItem(graph, 'Date Filter');
await cpHelpers.toggleMenuItemOption(graph, 'Date Filter', GENERATOR_INDEXES[yearId]);
await cpHelpers.toggleFilterMenu(graph.el);
await cpHelpers.toggleMenuItem(graph.el, 'Date Filter');
await cpHelpers.toggleMenuItemOption(graph.el, 'Date Filter', GENERATOR_INDEXES[yearId]);
if (otherId) {
await cpHelpers.toggleMenuItemOption(graph, 'Date Filter', GENERATOR_INDEXES[otherId]);
await cpHelpers.toggleMenuItemOption(graph.el, 'Date Filter', GENERATOR_INDEXES[otherId]);
}
const itemIndex = COMPARISON_OPTION_INDEXES[comparisonOptionId];
await cpHelpers.toggleComparisonMenu(graph);
await cpHelpers.toggleMenuItem(graph, itemIndex);
await cpHelpers.toggleComparisonMenu(graph.el);
await cpHelpers.toggleMenuItem(graph.el, itemIndex);
};
// groupby menu is assumed to be closed
this.selectDateIntervalOption = async (intervalOption) => {
await cpHelpers.toggleGroupByMenu(graph);
const productWasSelected = cpHelpers.isItemSelected(graph, 'Product');
await cpHelpers.toggleGroupByMenu(graph.el);
const productWasSelected = cpHelpers.isItemSelected(graph.el, 'Product');
const facetEls = graph.el.querySelectorAll('.o_searchview_facet');
const facetIndex = [...facetEls].findIndex(el => !!el.querySelector('span.fa-bars'));
if (facetIndex > -1) {
await cpHelpers.removeFacet(graph, facetIndex);
await cpHelpers.toggleGroupByMenu(graph);
await cpHelpers.removeFacet(graph.el, facetIndex);
await cpHelpers.toggleGroupByMenu(graph.el);
}
if (productWasSelected && !this.keepDateFirst) {
await cpHelpers.toggleMenuItem(graph, 'Product');
await cpHelpers.toggleMenuItem(graph.el, 'Product');
}
const optionIndex = INTERVAL_OPTION_IDS.indexOf(intervalOption);
await cpHelpers.toggleMenuItem(graph, 'Date');
await cpHelpers.toggleMenuItemOption(graph, 'Date', optionIndex);
await cpHelpers.toggleMenuItem(graph.el, 'Date');
await cpHelpers.toggleMenuItemOption(graph.el, 'Date', optionIndex);
if (productWasSelected && this.keepDateFirst) {
await cpHelpers.toggleMenuItem(graph, 'Product');
await cpHelpers.toggleMenuItem(graph.el, 'Product');
}
await cpHelpers.toggleGroupByMenu(graph);
await cpHelpers.toggleGroupByMenu(graph.el);
};
// groupby menu is assumed to be closed
this.selectGroupBy = async (groupByName) => {
await cpHelpers.toggleGroupByMenu(graph);
if (!cpHelpers.isItemSelected(graph, groupByName)) {
await cpHelpers.toggleMenuItem(graph, groupByName);
await cpHelpers.toggleGroupByMenu(graph.el);
if (!cpHelpers.isItemSelected(graph.el, groupByName)) {
await cpHelpers.toggleMenuItem(graph.el, groupByName);
}
await cpHelpers.toggleGroupByMenu(graph);
await cpHelpers.toggleGroupByMenu(graph.el);
};
this.setConfig = async (combination) => {
@@ -17,7 +17,7 @@ const {Markup} = require('web.utils');
var makeTestPromise = testUtils.makeTestPromise;
var nextTick = testUtils.nextTick;
const cpHelpers = testUtils.controlPanel;
const cpHelpers = require('@web/../tests/search/helpers');
var createView = testUtils.createView;
QUnit.module('Views', {
@@ -435,7 +435,7 @@ QUnit.module('Views', {
});
assert.containsOnce(kanban, '.o_pager');
assert.strictEqual(cpHelpers.getPagerSize(kanban), "4", "pager's size should be 4");
assert.strictEqual(testUtils.controlPanel.getPagerSize(kanban), "4", "pager's size should be 4");
kanban.destroy();
});
@@ -459,8 +459,8 @@ QUnit.module('Views', {
},
});
assert.strictEqual(cpHelpers.getPagerValue(kanban), "1-2", "pager's limit should be 2");
assert.strictEqual(cpHelpers.getPagerSize(kanban), "4", "pager's size should be 4");
assert.strictEqual(testUtils.controlPanel.getPagerValue(kanban), "1-2", "pager's limit should be 2");
assert.strictEqual(testUtils.controlPanel.getPagerSize(kanban), "4", "pager's size should be 4");
kanban.destroy();
});
@@ -485,8 +485,8 @@ QUnit.module('Views', {
},
});
assert.strictEqual(cpHelpers.getPagerValue(kanban), "1-3", "pager's limit should be 3");
assert.strictEqual(cpHelpers.getPagerSize(kanban), "4", "pager's size should be 4");
assert.strictEqual(testUtils.controlPanel.getPagerValue(kanban), "1-3", "pager's limit should be 3");
assert.strictEqual(testUtils.controlPanel.getPagerSize(kanban), "4", "pager's size should be 4");
kanban.destroy();
});
@@ -510,22 +510,22 @@ QUnit.module('Views', {
</kanban>`,
});
assert.strictEqual(cpHelpers.getPagerValue(kanban), "1-3",
assert.strictEqual(testUtils.controlPanel.getPagerValue(kanban), "1-3",
"should have 3 records on current page");
assert.strictEqual(cpHelpers.getPagerSize(kanban), "4",
assert.strictEqual(testUtils.controlPanel.getPagerSize(kanban), "4",
"should have 4 records");
// move to next page
await cpHelpers.pagerNext(kanban);
assert.strictEqual(cpHelpers.getPagerValue(kanban), "4-4",
await testUtils.controlPanel.pagerNext(kanban);
assert.strictEqual(testUtils.controlPanel.getPagerValue(kanban), "4-4",
"should be on second page");
// delete a record
await testUtils.dom.click(kanban.$('.o_kanban_record:first a:first'));
await testUtils.dom.click($('.modal-footer button:first'));
assert.strictEqual(cpHelpers.getPagerValue(kanban), "1-3",
assert.strictEqual(testUtils.controlPanel.getPagerValue(kanban), "1-3",
"should have 1 page only");
assert.strictEqual(cpHelpers.getPagerSize(kanban), "3",
assert.strictEqual(testUtils.controlPanel.getPagerSize(kanban), "3",
"should have 4 records");
kanban.destroy();
@@ -3505,7 +3505,7 @@ QUnit.module('Views', {
assert.doesNotHaveClass(kanban.$('.o_kanban_view'), 'o_kanban_grouped');
assert.containsNone(kanban, '.o_control_panel div.o_search_options div.o_group_by_menu');
assert.deepEqual(cpHelpers.getFacetTexts(kanban), []);
assert.deepEqual(cpHelpers.getFacetTexts(kanban.el), []);
kanban.destroy();
KanbanView.prototype.searchMenuTypes = searchMenuTypesOriginal;
@@ -22,7 +22,7 @@ var Widget = require('web.Widget');
var _t = core._t;
const cpHelpers = testUtils.controlPanel;
const cpHelpers = require('@web/../tests/search/helpers');
var createView = testUtils.createView;
const { click, legacyExtraNextTick } = require("@web/../tests/helpers/utils");
@@ -277,8 +277,8 @@ QUnit.module('Views', {
await testUtils.dom.click(list.$('tbody td.o_list_record_selector:first input'));
assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
await cpHelpers.toggleActionMenu(list);
assert.deepEqual(cpHelpers.getMenuItemTexts(list), ['Delete'],
await testUtils.controlPanel.toggleActionMenu(list);
assert.deepEqual(testUtils.controlPanel.getMenuItemTexts(list), ['Delete'],
'action menu should not contain the Export button');
list.destroy();
@@ -309,9 +309,9 @@ QUnit.module('Views', {
await testUtils.dom.click(list.$('tbody td.o_list_record_selector:first input'));
assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
await cpHelpers.toggleActionMenu(list);
await testUtils.controlPanel.toggleActionMenu(list);
assert.deepEqual(
cpHelpers.getMenuItemTexts(list),
testUtils.controlPanel.getMenuItemTexts(list),
['Export', 'Delete'],
'action menu should have Export button'
);
@@ -544,7 +544,7 @@ QUnit.module('Views', {
<field name="foo" />
</tree>`,
});
let cpButtons = cpHelpers.getButtons(list);
let cpButtons = testUtils.controlPanel.getButtons(list);
assert.containsNone(cpButtons[0], 'button[name="x"]');
assert.containsNone(cpButtons[0], '.o_list_selection_box');
assert.containsNone(cpButtons[0], 'button[name="y"]');
@@ -552,7 +552,7 @@ QUnit.module('Views', {
await testUtils.dom.click(
list.el.querySelector('.o_data_row .o_list_record_selector input[type="checkbox"]')
);
cpButtons = cpHelpers.getButtons(list);
cpButtons = testUtils.controlPanel.getButtons(list);
assert.containsOnce(cpButtons[0], 'button[name="x"]');
assert.hasClass(cpButtons[0].querySelector('button[name="x"]'), 'btn btn-secondary');
assert.containsOnce(cpButtons[0], '.o_list_selection_box');
@@ -565,7 +565,7 @@ QUnit.module('Views', {
await testUtils.dom.click(
list.el.querySelector('.o_data_row .o_list_record_selector input[type="checkbox"]')
);
cpButtons = cpHelpers.getButtons(list);
cpButtons = testUtils.controlPanel.getButtons(list);
assert.containsNone(cpButtons[0], 'button[name="x"]');
assert.containsNone(cpButtons[0], '.o_list_selection_box');
assert.containsNone(cpButtons[0], 'button[name="y"]');
@@ -599,7 +599,7 @@ QUnit.module('Views', {
await testUtils.dom.click(
list.el.querySelector('.o_data_row .o_list_record_selector input[type="checkbox"]')
);
const cpButtons = cpHelpers.getButtons(list);
const cpButtons = testUtils.controlPanel.getButtons(list);
assert.ok(
Array.from(cpButtons[0].querySelectorAll('button')).every(btn => !btn.disabled)
);
@@ -697,7 +697,7 @@ QUnit.module('Views', {
await testUtils.dom.click(
list.el.querySelector('.o_data_row .o_list_record_selector input[type="checkbox"]')
);
const cpButtons = cpHelpers.getButtons(list);
const cpButtons = testUtils.controlPanel.getButtons(list);
await testUtils.dom.click(cpButtons[0].querySelector('button[name="x"]'));
list.destroy();
});
@@ -756,7 +756,7 @@ QUnit.module('Views', {
await testUtils.dom.click(
list.el.querySelector('.o_data_row .o_list_record_selector input[type="checkbox"]')
);
const cpButtons = cpHelpers.getButtons(list);
const cpButtons = testUtils.controlPanel.getButtons(list);
await testUtils.dom.click(cpButtons[0].querySelector('.o_list_select_domain'));
assert.verifySteps([]);
@@ -1592,8 +1592,8 @@ QUnit.module('Views', {
});
await cpHelpers.toggleFavoriteMenu(list);
await cpHelpers.toggleMenuItem(list, "My second favorite");
await cpHelpers.toggleFavoriteMenu(list.el);
await cpHelpers.toggleMenuItem(list.el, "My second favorite");
list.destroy();
});
@@ -1866,7 +1866,7 @@ QUnit.module('Views', {
assert.containsOnce(list, '.o_data_row',
"list should contain one record (and thus 3 empty rows)");
assert.strictEqual(cpHelpers.getPagerValue(list), '1-1',
assert.strictEqual(testUtils.controlPanel.getPagerValue(list), '1-1',
"pager should be correct");
await testUtils.dom.click(list.$buttons.find('.o_list_button_add'));
@@ -1875,7 +1875,7 @@ QUnit.module('Views', {
"list should still contain 4 rows");
assert.containsN(list, '.o_data_row', 2,
"list should contain two record (and thus 2 empty rows)");
assert.strictEqual(cpHelpers.getPagerValue(list), '1-2',
assert.strictEqual(testUtils.controlPanel.getPagerValue(list), '1-2',
"pager should be correct");
await testUtils.dom.click(list.$buttons.find('.o_list_button_discard'));
@@ -1884,7 +1884,7 @@ QUnit.module('Views', {
"list should still contain 4 rows");
assert.containsOnce(list, '.o_data_row',
"list should contain one record (and thus 3 empty rows)");
assert.strictEqual(cpHelpers.getPagerValue(list), '1-1',
assert.strictEqual(testUtils.controlPanel.getPagerValue(list), '1-1',
"pager should be correct");
assert.verifySteps(['destroy'],
"should have destroyed the widget of the removed line");
@@ -2008,7 +2008,7 @@ QUnit.module('Views', {
assert.isVisible($(webClient.el).find('.o_list_button_save'), "save button should be visible");
await testUtils.dom.click($(webClient.el).find('.o_dropdown_toggler:contains("Group By")'));
await testUtils.dom.click($(webClient.el).find('.o_group_by_menu .o_menu_item a:contains("candle")'));
await testUtils.dom.click($(webClient.el).find('.o_group_by_menu .o_menu_item:contains("candle")'));
assert.isNotVisible($(webClient.el).find('.o_list_button_add'), "create button should be invisible");
assert.isNotVisible($(webClient.el).find('.o_list_button_save'),
@@ -2049,7 +2049,7 @@ QUnit.module('Views', {
assert.containsNone(list, '.o_control_panel div.o_search_options div.o_group_by_menu',
"there should not be groupby menu");
assert.deepEqual(cpHelpers.getFacetTexts(list), []);
assert.deepEqual(cpHelpers.getFacetTexts(list.el), []);
list.destroy();
ListView.prototype.searchMenuTypes = searchMenuTypesOriginal;
@@ -2633,7 +2633,7 @@ QUnit.module('Views', {
});
var widthPage1 = list.$(`th[data-name=foo]`)[0].offsetWidth;
await cpHelpers.pagerNext(list);
await testUtils.controlPanel.pagerNext(list);
var widthPage2 = list.$(`th[data-name=foo]`)[0].offsetWidth;
assert.ok(widthPage1 > widthPage2,
@@ -3615,8 +3615,8 @@ QUnit.module('Views', {
assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, "Delete");
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, "Delete");
assert.hasClass($('body'),'modal-open', 'body should have modal-open clsss');
await testUtils.dom.click($('body .modal button span:contains(Ok)'));
@@ -3646,8 +3646,8 @@ QUnit.module('Views', {
assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, "Delete");
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, "Delete");
assert.containsOnce(document.body, '.modal', 'should have open the confirmation dialog');
await testUtils.dom.click($('body .modal button span:contains(Ok)'));
@@ -3694,8 +3694,8 @@ QUnit.module('Views', {
assert.containsOnce(list, '.o_list_selection_box .o_list_select_domain');
await testUtils.dom.click(list.$('.o_list_selection_box .o_list_select_domain'));
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, "Delete");
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, "Delete");
assert.strictEqual($('.modal').length, 1, 'a confirm modal should be displayed');
await testUtils.dom.click($('.modal-footer .btn-primary'));
@@ -3746,8 +3746,8 @@ QUnit.module('Views', {
assert.containsOnce(list, '.o_list_selection_box .o_list_select_domain');
await testUtils.dom.click(list.$('.o_list_selection_box .o_list_select_domain'));
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, "Delete");
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, "Delete");
assert.strictEqual($('.modal').length, 1, 'a confirm modal should be displayed');
await testUtils.dom.click($('.modal-footer .btn-primary'));
@@ -3788,14 +3788,14 @@ QUnit.module('Views', {
assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
assert.verifySteps(['/web/dataset/search_read']);
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, "Archive");
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, "Archive");
assert.strictEqual($('.modal').length, 1, 'a confirm modal should be displayed');
await testUtils.dom.click($('.modal-footer .btn-secondary'));
assert.containsN(list, 'tbody td.o_list_record_selector', 4, "still should have 4 records");
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, "Archive");
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, "Archive");
assert.strictEqual($('.modal').length, 1, 'a confirm modal should be displayed');
await testUtils.dom.click($('.modal-footer .btn-primary'));
assert.containsN(list, 'tbody td.o_list_record_selector', 3, "should have 3 records");
@@ -3844,8 +3844,8 @@ QUnit.module('Views', {
assert.containsOnce(list, '.o_list_selection_box .o_list_select_domain');
await testUtils.dom.click(list.$('.o_list_selection_box .o_list_select_domain'));
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, "Archive");
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, "Archive");
assert.strictEqual($('.modal').length, 1, 'a confirm modal should be displayed');
await testUtils.dom.click($('.modal-footer .btn-primary'));
@@ -3899,8 +3899,8 @@ QUnit.module('Views', {
assert.containsOnce(list, '.o_list_selection_box .o_list_select_domain');
await testUtils.dom.click(list.$('.o_list_selection_box .o_list_select_domain'));
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, "Archive");
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, "Archive");
assert.strictEqual($('.modal').length, 1, 'a confirm modal should be displayed');
await testUtils.dom.click($('.modal-footer .btn-primary'));
@@ -3988,9 +3988,9 @@ QUnit.module('Views', {
});
assert.containsOnce(list.el, 'div.o_control_panel .o_cp_pager');
assert.strictEqual(cpHelpers.getPagerSize(list), "4", "pager's size should be 4");
assert.strictEqual(testUtils.controlPanel.getPagerSize(list), "4", "pager's size should be 4");
await list.update({ groupBy: ['bar']});
assert.strictEqual(cpHelpers.getPagerSize(list), "2", "pager's size should be 2");
assert.strictEqual(testUtils.controlPanel.getPagerSize(list), "2", "pager's size should be 2");
list.destroy();
});
@@ -4264,7 +4264,7 @@ QUnit.module('Views', {
res_id: 1,
});
await cpHelpers.pagerNext('.o_field_widget[name=o2m]');
await testUtils.controlPanel.pagerNext('.o_field_widget[name=o2m]');
assert.strictEqual(form.$('tbody tr:first').text(), 'Value 44',
"record 44 should be first");
assert.strictEqual(form.$('tbody tr:eq(4)').text(), 'Value 48',
@@ -4815,8 +4815,8 @@ QUnit.module('Views', {
// Delete all records
await testUtils.dom.click(list.el.querySelector('thead .o_list_record_selector input'));
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, "Delete");
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, "Delete");
await testUtils.dom.click($('.modal-footer .btn-primary'));
// Final state: no more sample data, but nocontent helper displayed
@@ -4916,8 +4916,8 @@ QUnit.module('Views', {
// Delete newly created record
await testUtils.dom.click(list.el.querySelector('.o_data_row input'));
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, "Delete");
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, "Delete");
await testUtils.dom.click($('.modal-footer .btn-primary'));
// Final state: there should be no table, but the no content helper
@@ -5775,14 +5775,14 @@ QUnit.module('Views', {
assert.hasClass(list.$('.o_group_header th:eq(1) > nav'), 'o_pager',
"last cell of open group header should have classname 'o_pager'");
assert.strictEqual(cpHelpers.getPagerValue('.o_group_header'), '1-3',
assert.strictEqual(testUtils.controlPanel.getPagerValue('.o_group_header'), '1-3',
"pager's value should be correct");
assert.containsN(list, '.o_data_row', 3,
"open group should display 3 records");
// go to next page
await cpHelpers.pagerNext('.o_group_header');
assert.strictEqual(cpHelpers.getPagerValue('.o_group_header'), '4-4',
await testUtils.controlPanel.pagerNext('.o_group_header');
assert.strictEqual(testUtils.controlPanel.getPagerValue('.o_group_header'), '4-4',
"pager's value should be correct");
assert.containsOnce(list, '.o_data_row',
"open group should display 1 record");
@@ -6257,8 +6257,8 @@ QUnit.module('Views', {
await testUtils.dom.click(list.$('.o_list_record_selector:first input'));
await cpHelpers.toggleActionMenu(list);
assert.deepEqual(cpHelpers.getMenuItemTexts(list), ['Delete', 'Action event']);
await testUtils.controlPanel.toggleActionMenu(list);
assert.deepEqual(testUtils.controlPanel.getMenuItemTexts(list), ['Delete', 'Action event']);
list.destroy();
});
@@ -6301,14 +6301,14 @@ QUnit.module('Views', {
assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, "Custom Action");
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, "Custom Action");
// unselect first record (will unselect the thead checkbox as well)
await testUtils.dom.click(list.$('tbody .o_list_record_selector:first input'));
assert.containsN(list, '.o_list_record_selector input:checked', 3);
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, "Custom Action");
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, "Custom Action");
// add a domain and select first two records
await list.reload({ domain: [['bar', '=', true]] });
@@ -6319,8 +6319,8 @@ QUnit.module('Views', {
await testUtils.dom.click(list.$('tbody .o_list_record_selector:nth(1) input'));
assert.containsN(list, '.o_list_record_selector input:checked', 2);
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, "Custom Action");
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, "Custom Action");
assert.verifySteps([
'{"action_id":44,"context":{"active_id":1,"active_ids":[1,2,3,4],"active_model":"foo","active_domain":[]}}',
@@ -6368,15 +6368,15 @@ QUnit.module('Views', {
assert.containsOnce(list, '.o_list_selection_box .o_list_select_domain');
assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, "Custom Action");
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, "Custom Action");
// select all domain
await testUtils.dom.click(list.$('.o_list_selection_box .o_list_select_domain'));
assert.containsN(list, '.o_list_record_selector input:checked', 3);
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, "Custom Action");
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, "Custom Action");
// add a domain
await list.reload({ domain: [['bar', '=', true]] });
@@ -6388,8 +6388,8 @@ QUnit.module('Views', {
assert.containsN(list, '.o_list_record_selector input:checked', 3);
assert.containsNone(list, '.o_list_selection_box .o_list_select_domain');
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, "Custom Action");
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, "Custom Action");
assert.verifySteps([
'{"action_id":44,"context":{"active_id":1,"active_ids":[1,2],"active_model":"foo","active_domain":[]}}',
@@ -7065,7 +7065,7 @@ QUnit.module('Views', {
await testUtils.dom.click($('body .modal-content button:contains(Group By)'));
await testUtils.dom.click($('body .modal-content .o_menu_item a:contains(cornichon)'));
await testUtils.dom.click($('body .modal-content .o_menu_item:contains(cornichon)'));
await testUtils.dom.click($('body .modal-content .o_group_header'));
@@ -9304,8 +9304,8 @@ QUnit.module('Views', {
});
assert.strictEqual(cpHelpers.getPagerValue(list), '1-2');
assert.strictEqual(cpHelpers.getPagerSize(list), '4');
assert.strictEqual(testUtils.controlPanel.getPagerValue(list), '1-2');
assert.strictEqual(testUtils.controlPanel.getPagerSize(list), '4');
assert.containsN(list, '.o_data_row', 2,
'should display 2 data rows');
@@ -9444,8 +9444,8 @@ QUnit.module('Views', {
// delete a record
await testUtils.dom.click(list.$('.o_data_row:first .o_list_record_selector input'));
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, "Delete");
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, "Delete");
await testUtils.dom.click($('.modal-footer .btn-primary'));
assert.verifySteps([
@@ -9631,19 +9631,19 @@ QUnit.module('Views', {
// switch pages (should ask to scroll)
await cpHelpers.pagerNext(list);
await cpHelpers.pagerPrevious(list);
await testUtils.controlPanel.pagerNext(list);
await testUtils.controlPanel.pagerPrevious(list);
assert.verifySteps(['scroll', 'scroll'],
"should ask to scroll when switching pages");
// change the limit (should not ask to scroll)
await cpHelpers.setPagerValue(list, '1-2');
await testUtils.controlPanel.setPagerValue(list, '1-2');
await testUtils.nextTick();
assert.strictEqual(cpHelpers.getPagerValue(list), '1-2');
assert.strictEqual(testUtils.controlPanel.getPagerValue(list), '1-2');
assert.verifySteps([], "should not ask to scroll when changing the limit");
// switch pages again (should still ask to scroll)
await cpHelpers.pagerNext(list);
await testUtils.controlPanel.pagerNext(list);
assert.verifySteps(['scroll'], "this is still working after a limit change");
@@ -9828,7 +9828,7 @@ QUnit.module('Views', {
assert.containsNone(list, '.o_data_row');
assert.containsOnce(list, '.o_pager'); // has a pager
await cpHelpers.pagerNext(list); // switch to page 2
await testUtils.controlPanel.pagerNext(list); // switch to page 2
assert.containsN(list, '.o_group_header', 1); // page 2
assert.containsNone(list, '.o_data_row');
@@ -9935,7 +9935,7 @@ QUnit.module('Views', {
]
);
await cpHelpers.pagerNext(list); // switch to page 2
await testUtils.controlPanel.pagerNext(list); // switch to page 2
assert.containsN(list, '.o_group_header', 7); // page 2
assert.containsN(list, '.o_data_row', 7);
@@ -10840,8 +10840,8 @@ QUnit.module('Views', {
},
});
await cpHelpers.toggleGroupByMenu(list);
await cpHelpers.toggleMenuItem(list, 0);
await cpHelpers.toggleGroupByMenu(list.el);
await cpHelpers.toggleMenuItem(list.el, 0);
// expand group
await testUtils.dom.click(list.el.querySelector('th.o_group_name'));
await testUtils.dom.click(list.el.querySelector('td.o_group_field_row_add a'));
@@ -12,7 +12,7 @@ const legacyViewRegistry = require('web.view_registry');
const { createWebClient, doAction } = require('@web/../tests/webclient/helpers');
var _t = core._t;
const cpHelpers = testUtils.controlPanel;
const cpHelpers = require('@web/../tests/search/helpers');
var createView = testUtils.createView;
var patchDate = testUtils.mock.patchDate;
@@ -485,8 +485,8 @@ QUnit.module('Views', {
},
});
await cpHelpers.toggleComparisonMenu(pivot);
await cpHelpers.toggleMenuItem(pivot, 'Date: Previous period');
await cpHelpers.toggleComparisonMenu(pivot.el);
await cpHelpers.toggleMenuItem(pivot.el, 'Date: Previous period');
assert.hasClass(pivot.$('table'), 'o_enable_linking',
"root node should have classname 'o_enable_linking'");
@@ -616,21 +616,32 @@ QUnit.module('Views', {
"should have 3 rows: 1 for the opened header, and 2 for data");
// click on the opened header to close it
await testUtils.dom.click(pivot.$('.o_pivot_header_cell_opened'));
await testUtils.dom.click(pivot.el.querySelector('.o_pivot_header_cell_opened'));
assert.containsOnce(pivot, 'tbody tr', "should have 1 row");
// click on closed header to open dropdown
await testUtils.dom.click(pivot.$('tbody .o_pivot_header_cell_closed'));
assert.containsN(pivot, '.o_pivot_field_menu .dropdown-item[data-field="date"]', 6,
"should have the date field as proposition (Date, Day, Week, Month, Quarter and Year)");
assert.containsOnce(pivot, '.o_pivot_field_menu .dropdown-item[data-field="product_id"]',
"should have the product_id field as proposition");
assert.containsNone(pivot, '.o_pivot_field_menu .dropdown-item[data-field="non_stored_m2o"]',
"should not have the non_stored_m2o field as proposition");
await testUtils.dom.click(pivot.el.querySelector('tbody .o_pivot_header_cell_closed'));
assert.containsOnce(pivot, ".o_pivot .o_dropdown_menu");
assert.strictEqual(
pivot.el.querySelector(".o_pivot .o_dropdown_menu").innerText.replace(/\s/g, ""),
"CompanyTypeCustomerDateOtherProductProductbar"
);
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field="date"]:first'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field="date"][role="menuitem"]:contains(Month)'));
// open the Date sub dropdown
await testUtils.dom.click(pivot.el.querySelector(".o_pivot .o_dropdown_menu .o_dropdown_toggler.o_menu_item"));
assert.strictEqual(
pivot.el
.querySelector(".o_pivot .o_dropdown_menu .o_dropdown_menu")
.innerText.replace(/\s/g, ""),
"YearQuarterMonthWeekDay"
);
await testUtils.dom.click(
pivot.el.querySelectorAll(
".o_pivot .o_dropdown_menu .o_dropdown_menu .o_dropdown_item"
)[2]
);
assert.containsN(pivot, 'tbody tr', 4,
"should have 4 rows: one for header, 3 for data");
@@ -654,14 +665,15 @@ QUnit.module('Views', {
});
// open dropdown to zoom into first row
await testUtils.dom.clickFirst(pivot.$('tbody .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.el.querySelector("tbody .o_pivot_header_cell_closed"));
// click on date by day
pivot.$('.dropdown-menu.show .o_inline_dropdown .dropdown-menu').toggle(); // unfold inline dropdown
await testUtils.nextTick();
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field="date"]:contains("Day")'));
await testUtils.dom.click(pivot.el.querySelector("tbody .o_dropdown_menu .o_dropdown_toggler"));
await testUtils.dom.click(
pivot.el.querySelector("tbody .o_dropdown_menu .o_dropdown_menu li:nth-child(5)")
);
// open dropdown to zoom into second row
await testUtils.dom.clickLast(pivot.$('tbody th.o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.el.querySelectorAll("tbody th.o_pivot_header_cell_closed")[1]);
assert.containsN(pivot, 'tbody tr', 7,
"should have 7 rows (1 for total, 1 for xphone, 1 for xpad, 4 for data)");
@@ -690,7 +702,7 @@ QUnit.module('Views', {
// unfold it
await testUtils.dom.click(pivot.$('thead .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field="product_id"]'));
await testUtils.dom.click(pivot.el.querySelector(".o_dropdown_menu li:nth-child(5)"));
assert.containsN(pivot, 'thead tr', 3);
pivot.destroy();
@@ -715,7 +727,7 @@ QUnit.module('Views', {
// unfold it
await testUtils.dom.click(pivot.$('thead .o_pivot_header_cell_closed:nth(1)'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field="company_type"]'));
await testUtils.dom.click(pivot.el.querySelector(".o_dropdown_menu li:nth-child(1)"));
assert.containsN(pivot, 'thead tr', 4);
values = ['12', '3', '17', '32'];
assert.strictEqual(getCurrentValues(pivot), values.join(','));
@@ -748,23 +760,23 @@ QUnit.module('Views', {
});
// open group by dropdown
await cpHelpers.toggleGroupByMenu(pivot);
await cpHelpers.toggleGroupByMenu(pivot.el);
assert.containsN(pivot, '.o_control_panel .o_cp_bottom_right .o_dropdown_menu .o_menu_item', 3,
"should have 2 dropdown items in searchview groupby");
assert.containsOnce(pivot, '.o_control_panel .o_cp_bottom_right .o_dropdown_menu .o_generator_menu',
assert.containsOnce(pivot, '.o_control_panel .o_cp_bottom_right .o_dropdown_menu .o_add_custom_group_menu',
"should have custom group generator in searchview groupby");
// click on closed header to open dropdown
await testUtils.dom.click(pivot.$('tbody .o_pivot_header_cell_closed:nth(1)'));
assert.containsN(pivot, '.o_pivot_field_menu > .dropdown-item', 3,
await testUtils.dom.click(pivot.el.querySelector('tbody tr:last-child .o_pivot_header_cell_closed'));
assert.containsN(pivot, '.o_pivot_field_menu .dropdown-item', 3,
"should have 3 dropdown items same as searchview groupby");
assert.containsOnce(pivot, '.o_pivot_field_menu .o_generator_menu',
assert.containsOnce(pivot, '.o_pivot_field_menu .o_add_custom_group_menu',
"should have custom group generator same as searchview groupby");
// check custom groupby selection has groupable fields only
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .o_generator_menu .o_add_custom_group_by'));
assert.containsN(pivot, '.o_pivot_field_menu .o_generator_menu .o_group_by_selector option', 6,
"should have 3 fields in custom groupby");
const optionDescriptions = [...pivot.$('.o_pivot_field_menu .o_generator_menu .o_group_by_selector option')]
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .o_add_custom_group_menu .o_dropdown_toggler'));
assert.containsN(pivot, '.o_pivot_field_menu .o_add_custom_group_menu .o_dropdown_menu option', 6,
"should have 6 fields in custom groupby");
const optionDescriptions = [...pivot.$('.o_pivot_field_menu .o_add_custom_group_menu .o_dropdown_menu option')]
.map(option => option.innerText.trim());
assert.deepEqual(
optionDescriptions,
@@ -782,6 +794,71 @@ QUnit.module('Views', {
});
QUnit.test('pivot group dropdown sync with search groupby dropdown', async function (assert) {
assert.expect(6);
const pivot = await createView({
View: PivotView,
model: "partner",
data: this.data,
arch: `
<pivot>
<field name="product_id" type="row"/>
<field name="foo" type="measure"/>
</pivot>`,
archs: {
'partner,false,search': `
<search>
<filter name="bar" string="bar" context="{'group_by': 'bar'}"/>
<filter name="product_id" string="product" context="{'group_by': 'product_id'}"/>
</search>
`,
},
});
// open group by dropdown
await cpHelpers.toggleGroupByMenu(pivot.el);
assert.containsN(pivot, '.o_control_panel .o_cp_bottom_right .o_dropdown_menu .o_menu_item', 2,
"should have 2 dropdown items in searchview groupby");
// click on closed header to open dropdown
await testUtils.dom.click(pivot.el.querySelector('tbody tr:last-child .o_pivot_header_cell_closed'));
assert.containsN(
pivot.el,
".o_dropdown_menu .o_menu_item",
2,
"should have 2 dropdown items in pivot groupby"
);
await cpHelpers.toggleGroupByMenu(pivot.el);
await cpHelpers.toggleAddCustomGroup(pivot.el);
await cpHelpers.applyGroup(pivot.el);
assert.containsN(pivot, '.o_control_panel .o_cp_bottom_right .o_dropdown_menu .o_menu_item', 3,
"should have 3 dropdown items in searchview groupby now");
// click on closed header to open dropdown
await testUtils.dom.click(pivot.el.querySelector('tbody tr:last-child .o_pivot_header_cell_closed'));
// applying groupby/custom groupby will update pivot groupby dropdown while reverse is not true
assert.containsN(pivot, '.o_pivot_field_menu .dropdown-item', 3,
"should have 3 dropdown items same as searchview groupby");
// add a custom group in pivot groupby
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .o_add_custom_group_menu .o_dropdown_toggler'));
await testUtils.fields.editSelect(pivot.$('.o_pivot_field_menu .o_add_custom_group_menu select'), 'date');
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .o_add_custom_group_menu .o_dropdown_menu button'));
// click on closed header to open groupby selection dropdown
await testUtils.dom.click(pivot.el.querySelector('tbody tr:last-child .o_pivot_header_cell_closed'));
assert.containsN(pivot, '.o_pivot_field_menu .o_menu_item', 4,
"should have 4 dropdown items pivot groupby dropdown");
// applying custom groupby in pivot groupby dropdown will not update search dropdown
await cpHelpers.toggleGroupByMenu(pivot.el);
assert.containsN(pivot, '.o_control_panel .o_cp_bottom_right .o_dropdown_menu .o_menu_item', 3,
"should have 3 dropdown items in searchview groupby dropdown");
pivot.destroy();
});
QUnit.test('pivot groupby dropdown renders custom search at the end with separator', async function (assert) {
assert.expect(5);
const pivot = await createView({
@@ -804,81 +881,28 @@ QUnit.module('Views', {
});
// open group by dropdown
await cpHelpers.toggleGroupByMenu(pivot);
await cpHelpers.toggleGroupByMenu(pivot.el);
assert.containsN(pivot, '.o_control_panel .o_cp_bottom_right .o_dropdown_menu .o_menu_item', 2,
"should have 2 dropdown items in searchview groupby");
await cpHelpers.toggleMenuItem(pivot, "bar");
// click on closed header to open dropdown
await testUtils.dom.click(pivot.$('tbody .o_pivot_header_cell_closed:nth(1)'));
await cpHelpers.toggleGroupByMenu(pivot);
await cpHelpers.toggleAddCustomGroup(pivot);
await cpHelpers.applyGroup(pivot);
await cpHelpers.toggleAddCustomGroup(pivot.el);
await cpHelpers.applyGroup(pivot.el);
assert.containsN(pivot, '.o_control_panel .o_cp_bottom_right .o_dropdown_menu .o_menu_item', 3,
"should have 3 dropdown items in searchview groupby now");
// click on closed header to open dropdown
await testUtils.dom.click(pivot.$('tbody .o_pivot_header_cell_closed:nth(1)'));
// applying groupby/custom groupby will update pivot groupby dropdown while reverse is not true
assert.containsN(pivot, '.o_pivot_field_menu > .dropdown-item', 3,
"should have 3 dropdown items same as searchview groupby");
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .o_generator_menu .o_add_custom_group_by'));
await testUtils.fields.editSelect(pivot.$('.o_pivot_field_menu .o_generator_menu .o_group_by_selector'), 'date');
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .o_generator_menu button.o_apply_group_by'));
// click on closed header to open groupby selection dropdown
await testUtils.dom.click(pivot.$('tbody .o_pivot_header_cell_closed:nth(1)'));
assert.containsN(pivot, '.o_pivot_field_menu > [role="menuitem"]', 4,
"should have 4 dropdown items pivot groupby dropdown");
// applying custom groupby in pivot groupby dropdown will not update search dropdown
await cpHelpers.toggleGroupByMenu(pivot);
assert.containsN(pivot, '.o_control_panel .o_cp_bottom_right .o_dropdown_menu .o_menu_item', 3,
"should have 3 dropdown items in searchview groupby dropdown");
pivot.destroy();
});
QUnit.test('pivot groupby dropdown renders custom search at the end with separator', async function (assert) {
assert.expect(4);
const pivot = await createView({
View: PivotView,
model: "partner",
data: this.data,
arch: `
<pivot>
<field name="product_id" type="row"/>
<field name="foo" type="measure"/>
</pivot>`,
archs: {
'partner,false,search': `
<search>
<filter name="bar" string="bar" context="{'group_by': 'bar'}"/>
<filter name="product_id" string="product" context="{'group_by': 'product_id'}"/>
</search>
`,
},
});
// open group by dropdown
await cpHelpers.toggleGroupByMenu(pivot);
assert.containsN(pivot, '.o_control_panel .o_cp_bottom_right .o_dropdown_menu .o_menu_item', 2,
"should have 2 dropdown items in searchview groupby");
await cpHelpers.toggleAddCustomGroup(pivot);
await cpHelpers.applyGroup(pivot);
assert.containsN(pivot, '.o_control_panel .o_cp_bottom_right .o_dropdown_menu .o_menu_item', 3,
"should have 3 dropdown items in searchview groupby now");
// click on closed header to open dropdown
await testUtils.dom.click(pivot.$('tbody .o_pivot_header_cell_closed:nth(1)'));
assert.deepEqual(pivot.$(".o_pivot_field_menu > .dropdown-item:last"),
pivot.$(".o_pivot_field_menu > .dropdown-item[data-field='company_type']"),
"custom group should be last item");
assert.strictEqual(pivot.$(".o_pivot_field_menu > .dropdown-item[data-field='company_type']").prev().attr('role'),
"separator",
"custom group should be separated by separator");
await testUtils.dom.click(pivot.el.querySelector('tbody tr:last-child .o_pivot_header_cell_closed'));
const items = pivot.el.querySelectorAll(".o_menu_item");
assert.deepEqual([...items].map((el) => el.innerText), ["bar", "product", "Company Type"]);
assert.containsN(
pivot,
"tbody .o_dropdown_menu .dropdown-divider", 2,
"pivot groupby menu should have two separators"
);
assert.hasClass(
items[items.length - 1].nextSibling,
"dropdown-divider",
"pivot groupby menu separator is placed after all menu items"
);
pivot.destroy();
});
@@ -916,10 +940,10 @@ QUnit.module('Views', {
// click on closed header to open dropdown and apply groupby on date field
await testUtils.dom.click(pivot.$('thead .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .o_generator_menu .o_add_custom_group_by'));
await testUtils.fields.editSelect(pivot.$('.o_pivot_field_menu .o_generator_menu .o_group_by_selector'), 'date');
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .o_add_custom_group_menu .o_dropdown_toggler'));
await testUtils.fields.editSelect(pivot.$('.o_pivot_field_menu .o_add_custom_group_menu select'), 'date');
checkReadGroup = true;
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .o_generator_menu button.o_apply_group_by'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .o_add_custom_group_menu .btn-primary'));
pivot.destroy();
});
@@ -942,14 +966,14 @@ QUnit.module('Views', {
});
// open group by dropdown
await cpHelpers.toggleGroupByMenu(pivot);
await cpHelpers.toggleGroupByMenu(pivot.el);
assert.containsNone(pivot, '.o_control_panel .o_cp_bottom_right .o_dropdown_menu .o_menu_item',
"should not have any dropdown item in searchview groupby");
// click on closed header to open dropdown
await testUtils.dom.click(pivot.$('tbody .o_pivot_header_cell_closed:nth(1)'));
assert.containsN(pivot, '.o_pivot_field_menu > [role="menuitem"]', 6,
await testUtils.dom.click(pivot.el.querySelector('tbody tr:last-child .o_pivot_header_cell_closed'));
assert.containsN(pivot, '.o_pivot_field_menu .o_menu_item', 6,
"should have 6 dropdown items i.e. all groupable fields available");
assert.containsNone(pivot, '.o_pivot_field_menu .o_generator_menu',
assert.containsNone(pivot, '.o_pivot_field_menu .o_add_custom_group_menu',
"should not have custom group generator in groupby dropdown");
pivot.destroy();
@@ -988,23 +1012,23 @@ QUnit.module('Views', {
});
// open group by dropdown
await cpHelpers.toggleGroupByMenu(pivot);
await cpHelpers.toggleGroupByMenu(pivot.el);
assert.containsOnce(pivot, '.o_control_panel .o_cp_bottom_right .o_dropdown_menu .o_menu_item',
"should have 1 dropdown item in searchview groupby");
assert.containsNone(pivot, '.o_control_panel .o_cp_bottom_right .o_dropdown_menu .o_generator_menu',
assert.containsNone(pivot, '.o_control_panel .o_cp_bottom_right .o_dropdown_menu .o_add_custom_group_menu',
"should not have custom group generator in searchview groupby");
// click on closed header to open dropdown
await testUtils.dom.click(pivot.$('tbody .o_pivot_header_cell_closed'));
assert.containsOnce(pivot, '.o_pivot_field_menu > [role="menuitem"]',
await testUtils.dom.click(pivot.el.querySelector('tbody .o_pivot_header_cell_closed'));
assert.containsOnce(pivot, '.o_pivot_field_menu .o_menu_item',
"should have 1 dropdown items");
assert.containsNone(pivot, '.o_pivot_field_menu .o_generator_menu',
assert.containsNone(pivot, '.o_pivot_field_menu .o_add_custom_group_menu',
"should not have custom group generator in groupby dropdown");
pivot.destroy();
});
QUnit.test('pivot custom groupby: grouping on date field use default interval month', async function (assert) {
QUnit.test('pivot custom groupby: adding a custom group close the pivot groupby menu', async function (assert) {
assert.expect(2);
const pivot = await createView({
@@ -1027,13 +1051,13 @@ QUnit.module('Views', {
// click on closed header to open dropdown and apply groupby on date field
await testUtils.dom.click(pivot.$('thead .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .o_generator_menu .o_add_custom_group_by'));
assert.containsOnce(pivot, '.o_pivot_field_menu .o_generator_menu',
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .o_add_custom_group_menu .o_dropdown_toggler'));
assert.containsOnce(pivot, '.o_pivot_field_menu .o_add_custom_group_menu',
"should have custom group generator in groupby dropdown");
// click on apply button should close dropdown
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .o_generator_menu button.o_apply_group_by'));
assert.containsNone(pivot, '.o_pivot_field_menu .o_generator_menu',
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .o_add_custom_group_menu button.btn-primary'));
assert.containsNone(pivot, '.o_pivot_field_menu .o_add_custom_group_menu',
"should not have custom group generator in groupby dropdown");
pivot.destroy();
@@ -1179,7 +1203,7 @@ QUnit.module('Views', {
// tries to open a field selection menu, to make sure it was not
// removed from the dom.
await testUtils.dom.clickFirst(pivot.$('.o_pivot_header_cell_closed'));
assert.containsOnce(pivot, '.o_pivot_field_menu',
assert.containsOnce(pivot, '.o_dropdown_menu',
"the field selector menu exists");
pivot.destroy();
});
@@ -1464,7 +1488,7 @@ QUnit.module('Views', {
// expand header on field customer
await testUtils.dom.click(pivot.$('thead .o_pivot_header_cell_closed:nth(1)'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field="customer"]:first'));
await testUtils.dom.click(pivot.el.querySelectorAll("thead .o_dropdown_menu .o_dropdown_item")[1]);
assert.deepEqual(pivot.getOwnedQueryParams(), {
context: {
pivot_column_groupby: ['date:day', 'customer'],
@@ -1474,8 +1498,8 @@ QUnit.module('Views', {
}, "context should be correct");
// expand row on field product_id
await testUtils.dom.click(pivot.$('tbody .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field="product_id"]:first'));
await testUtils.dom.click(pivot.el.querySelector('tbody .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.el.querySelectorAll("tbody .o_dropdown_menu .o_dropdown_item")[4]);
assert.deepEqual(pivot.getOwnedQueryParams(), {
context: {
pivot_column_groupby: ['date:day', 'customer'],
@@ -1546,8 +1570,8 @@ QUnit.module('Views', {
},
}, "context should be correct");
await testUtils.dom.click(pivot.$('tbody .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field="product_id"]:first'));
await testUtils.dom.click(pivot.el.querySelector('tbody .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.$('.o_dropdown_menu li:nth-child(5)'));
assert.deepEqual(pivot.getOwnedQueryParams(), {
context: {
@@ -1558,7 +1582,7 @@ QUnit.module('Views', {
}, "context should be correct");
await testUtils.dom.click(pivot.$('thead .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field="customer"]:first'));
await testUtils.dom.click(pivot.$('.o_dropdown_menu li:nth-child(2)'));
assert.deepEqual(pivot.getOwnedQueryParams(), {
context: {
@@ -1613,7 +1637,7 @@ QUnit.module('Views', {
await pivot.reload(reloadParams);
// collapse all headers
await testUtils.dom.click(pivot.$('.o_pivot_header_cell_opened:first'));
await testUtils.dom.click(pivot.$('.o_pivot_header_cell_opened'));
await testUtils.dom.click(pivot.el.querySelector('.o_pivot_header_cell_opened'));
// Check Columns
assert.strictEqual(pivot.$('thead .o_pivot_header_cell_closed').length, 1,
@@ -1672,7 +1696,7 @@ QUnit.module('Views', {
// Set a column groupby
await testUtils.dom.click(pivot.$('thead .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field=customer]'));
await testUtils.dom.click(pivot.el.querySelectorAll("thead .o_dropdown_menu .o_dropdown_item")[1]);
// Set a domain
await pivot.update({domain: [['product_id', '=', 37]], groupBy: [], context: {}});
@@ -1687,7 +1711,7 @@ QUnit.module('Views', {
// Set a column groupby
await testUtils.dom.click(pivot.$('thead .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field=product_id]'));
await testUtils.dom.click(pivot.el.querySelectorAll("thead .o_dropdown_menu .o_dropdown_item")[4]);
// Set a domain
await pivot.update({domain: [['product_id', '=', 41]], groupBy: [], context: {}});
@@ -1725,7 +1749,7 @@ QUnit.module('Views', {
// expand a col group
await testUtils.dom.click(pivot.$('thead .o_pivot_header_cell_closed:nth(1)'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field="customer"]'));
await testUtils.dom.click(pivot.el.querySelectorAll("thead .o_dropdown_menu .o_dropdown_item")[1]);
values = [
"29", "1", "2", "32",
@@ -1735,8 +1759,8 @@ QUnit.module('Views', {
assert.strictEqual(getCurrentValues(pivot), values.join(','));
// expand a row group
await testUtils.dom.click(pivot.$('tbody .o_pivot_header_cell_closed:nth(1)'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field="other_product_id"]'));
await testUtils.dom.click(pivot.el.querySelector('tbody tr:last-child .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.el.querySelectorAll("tbody .o_dropdown_menu .o_dropdown_item")[3]);
values = [
"29", "1", "2", "32",
@@ -1779,7 +1803,7 @@ QUnit.module('Views', {
// Set a column groupby
await testUtils.dom.click(pivot.$('thead .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field=customer]'));
await testUtils.dom.click(pivot.el.querySelectorAll("thead .o_dropdown_menu .o_dropdown_item")[1]);
// Set a domain for empty results
await pivot.update({domain: [['id', '=', false]]});
@@ -1853,21 +1877,21 @@ QUnit.module('Views', {
});
await testUtils.dom.click(pivot.el.querySelector('thead .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.el.querySelectorAll('.o_pivot_field_menu .dropdown-item[data-field="date"]')[0]);
await testUtils.dom.click(pivot.el.querySelector('.o_pivot_field_menu .dropdown-item[data-field="date"][role="menuitem"]:nth-of-type(3)'));
await testUtils.dom.click(pivot.el.querySelector('thead .o_dropdown_menu .o_dropdown_toggler'));
await testUtils.dom.click(pivot.el.querySelectorAll("thead .o_dropdown_menu .o_dropdown_menu .o_dropdown_item")[3]);
// close and reopen row groupings after changing value
this.data.partner.records.find(r => r.product_id === 37).date = '2016-10-27';
await testUtils.dom.click(pivot.el.querySelector('tbody .o_pivot_header_cell_opened'));
await testUtils.dom.click(pivot.el.querySelector('tbody .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.el.querySelector('.o_pivot_field_menu .dropdown-item[data-field="product_id"]'));
await testUtils.dom.click(pivot.el.querySelectorAll("tbody .o_dropdown_menu .o_dropdown_item")[4]);
assert.strictEqual(pivot.el.querySelectorAll('.o_pivot_cell_value')[4].innerText, ''); // xphone December 2016
// invert axis, and reopen column groupings
await testUtils.dom.click(pivot.el.querySelector('.o_cp_buttons .o_pivot_flip_button'));
await testUtils.dom.click(pivot.el.querySelector('thead .o_pivot_header_cell_opened'));
await testUtils.dom.click(pivot.el.querySelector('thead .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.el.querySelector('.o_pivot_field_menu .dropdown-item[data-field="product_id"]'));
await testUtils.dom.click(pivot.el.querySelectorAll("thead .o_dropdown_menu .o_dropdown_item")[4]);
assert.strictEqual(pivot.el.querySelectorAll('.o_pivot_cell_value')[3].innerText, ''); // December 2016 xphone
pivot.destroy();
@@ -2095,8 +2119,8 @@ QUnit.module('Views', {
);
// select filter "Bayou" in control panel
await cpHelpers.toggleFilterMenu(pivot);
await cpHelpers.toggleMenuItem(pivot, "Bayou");
await cpHelpers.toggleFilterMenu(pivot.el);
await cpHelpers.toggleMenuItem(pivot.el, "Bayou");
await testUtils.nextTick();
assert.deepEqual(
@@ -2354,10 +2378,12 @@ QUnit.module('Views', {
'<field name="product_id" type="measure"/>' +
'</pivot>',
});
await testUtils.dom.click(pivot.$('tbody .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.el.querySelector('tbody .o_pivot_header_cell_closed'));
// click on date by month
pivot.$('.dropdown-menu.show .o_inline_dropdown .dropdown-menu').toggle(); // unfold inline dropdown
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field="date"]:contains("Month")'));
await testUtils.dom.click(pivot.el.querySelector("tbody .o_dropdown_menu .o_dropdown_toggler"));
await testUtils.dom.click(
pivot.el.querySelectorAll("tbody .o_dropdown_menu .o_dropdown_menu .o_dropdown_item")[3]
);
assert.strictEqual(pivot.$('.o_pivot_cell_value').text(), '2211',
'should have loaded the proper data');
@@ -2398,9 +2424,9 @@ QUnit.module('Views', {
'</pivot>',
});
await testUtils.dom.click(pivot.$('tbody .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.el.querySelector('tbody .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field="product_id"]:first'));
await testUtils.dom.click(pivot.el.querySelectorAll("tbody .o_dropdown_item")[4]);
assert.strictEqual(pivot.$('.o_pivot_cell_value').text(), '211',
'should have loaded the proper data');
@@ -2421,11 +2447,11 @@ QUnit.module('Views', {
// Set a column groupby
await testUtils.dom.click(pivot.$('thead .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field=customer]:first'));
await testUtils.dom.click(pivot.el.querySelectorAll("thead .o_dropdown_item")[1]);
// Set a Row groupby
await testUtils.dom.click(pivot.$('tbody .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field=product_id]:first'));
await testUtils.dom.click(pivot.el.querySelector('tbody .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.el.querySelectorAll("tbody .o_dropdown_item")[4]);
// Set a domain
await testUtils.pivot.reload(pivot, {domain: [['product_id', '=', 41]]});
@@ -2442,12 +2468,16 @@ QUnit.module('Views', {
assert.deepEqual(pivot.getOwnedQueryParams(), expectedContext,
'The pivot view should have the right context');
var $xpadHeader = pivot.$('tbody .o_pivot_header_cell_closed[data-original-title=Product]');
assert.equal($xpadHeader.length, 1,
'There should be only one product line because of the domain');
assert.equal($xpadHeader.text(), 'xpad',
'The product should be the right one');
assert.containsOnce(
pivot,
"tbody .o_pivot_header_cell_closed",
"There should be only one product line because of the domain"
);
assert.strictEqual(
pivot.el.querySelector("tbody .o_pivot_header_cell_closed").innerText,
"xpad",
"The product should be the right one"
);
pivot.destroy();
});
@@ -2631,16 +2661,16 @@ QUnit.module('Views', {
});
// with no data
await cpHelpers.toggleComparisonMenu(pivot);
await cpHelpers.toggleMenuItem(pivot, 'Date: Previous period');
await cpHelpers.toggleComparisonMenu(pivot.el);
await cpHelpers.toggleMenuItem(pivot.el, 'Date: Previous period');
assert.strictEqual(pivot.$('.o_pivot p.o_view_nocontent_empty_folder').length, 1);
await cpHelpers.toggleFilterMenu(pivot);
await cpHelpers.toggleMenuItem(pivot, 'Date');
await cpHelpers.toggleMenuItemOption(pivot, 'Date', 'December');
await cpHelpers.toggleMenuItemOption(pivot, 'Date', '2016');
await cpHelpers.toggleMenuItemOption(pivot, 'Date', '2015');
await cpHelpers.toggleFilterMenu(pivot.el);
await cpHelpers.toggleMenuItem(pivot.el, 'Date');
await cpHelpers.toggleMenuItemOption(pivot.el, 'Date', 'December');
await cpHelpers.toggleMenuItemOption(pivot.el, 'Date', '2016');
await cpHelpers.toggleMenuItemOption(pivot.el, 'Date', '2015');
assert.containsN(pivot, '.o_pivot thead tr:last th', 9,
"last header row should contains 9 cells (3*[December 2016, November 2016, Variation]");
@@ -2651,7 +2681,7 @@ QUnit.module('Views', {
// with data, with row groupby
await testUtils.dom.click(pivot.$('.o_pivot .o_pivot_header_cell_closed').eq(2));
await testUtils.dom.click(pivot.$('.o_pivot .o_pivot_field_menu a[data-field="product_id"]'));
await testUtils.dom.click(pivot.el.querySelectorAll("tbody .o_dropdown_menu .o_dropdown_item")[4]);
values = [
"19", "0", "-100%", "0", "13", "100%", "19", "13", "-31.58%",
"19", "0", "-100%", "0", "1" , "100%", "19", "1", "-94.74%",
@@ -2686,10 +2716,10 @@ QUnit.module('Views', {
];
assert.strictEqual(getCurrentValues(pivot), values.join());
await cpHelpers.toggleFavoriteMenu(pivot);
await cpHelpers.toggleSaveFavorite(pivot);
await cpHelpers.editFavoriteName(pivot, 'Fav');
await cpHelpers.saveFavorite(pivot);
await cpHelpers.toggleFavoriteMenu(pivot.el);
await cpHelpers.toggleSaveFavorite(pivot.el);
await cpHelpers.editFavoriteName(pivot.el, 'Fav');
await cpHelpers.saveFavorite(pivot.el);
unpatchDate();
pivot.destroy();
@@ -2754,9 +2784,9 @@ QUnit.module('Views', {
});
// open comparison menu
await cpHelpers.toggleComparisonMenu(pivot);
await cpHelpers.toggleComparisonMenu(pivot.el);
// compare October 2016 to September 2016
await cpHelpers.toggleMenuItem(pivot, 'Date: Previous period');
await cpHelpers.toggleMenuItem(pivot.el, 'Date: Previous period');
// With the data above, the time ranges contain no record.
assert.strictEqual(pivot.$('.o_pivot p.o_view_nocontent_empty_folder').length, 1, "there should be no data");
@@ -2764,10 +2794,10 @@ QUnit.module('Views', {
// are deactivated (exception: the 'Measures' button).
assert.ok(pivot.$('.o_control_panel button.o_pivot_download').prop('disabled'));
await cpHelpers.toggleFilterMenu(pivot);
await cpHelpers.toggleMenuItem(pivot, 'Date');
await cpHelpers.toggleMenuItemOption(pivot, 'Date', 'December');
await cpHelpers.toggleMenuItemOption(pivot, 'Date', 'October');
await cpHelpers.toggleFilterMenu(pivot.el);
await cpHelpers.toggleMenuItem(pivot.el, 'Date');
await cpHelpers.toggleMenuItemOption(pivot.el, 'Date', 'December');
await cpHelpers.toggleMenuItemOption(pivot.el, 'Date', 'October');
// With the data above, the time ranges contain some records.
// export data. Should execute 'get_file'
@@ -2840,8 +2870,8 @@ QUnit.module('Views', {
mockMock = true;
// compare December 2016 to November 2016
await cpHelpers.toggleComparisonMenu(pivot);
await cpHelpers.toggleMenuItem(pivot, 'Date: Previous period');
await cpHelpers.toggleComparisonMenu(pivot.el);
await cpHelpers.toggleMenuItem(pivot.el, 'Date: Previous period');
var values = [
"0", "4", "100%",
@@ -2888,8 +2918,8 @@ QUnit.module('Views', {
});
// compare December 2016 to November 2016
await cpHelpers.toggleComparisonMenu(pivot);
await cpHelpers.toggleMenuItem(pivot, 'Date: Previous period');
await cpHelpers.toggleComparisonMenu(pivot.el);
await cpHelpers.toggleMenuItem(pivot.el, 'Date: Previous period');
// initial sanity check
var values = [
@@ -3023,8 +3053,8 @@ QUnit.module('Views', {
});
// compare December 2016 to November 2016
await cpHelpers.toggleComparisonMenu(pivot);
await cpHelpers.toggleMenuItem(pivot, 'Date: Previous period');
await cpHelpers.toggleComparisonMenu(pivot.el);
await cpHelpers.toggleMenuItem(pivot.el, 'Date: Previous period');
// initial sanity check
var values = [
@@ -3126,13 +3156,13 @@ QUnit.module('Views', {
);
// Filter on December 2016
await cpHelpers.toggleFilterMenu(pivot);
await cpHelpers.toggleMenuItem(pivot, 'Date');
await cpHelpers.toggleMenuItemOption(pivot, 'Date', 'December');
await cpHelpers.toggleFilterMenu(pivot.el);
await cpHelpers.toggleMenuItem(pivot.el, 'Date');
await cpHelpers.toggleMenuItemOption(pivot.el, 'Date', 'December');
// compare December 2016 to November 2016
await cpHelpers.toggleComparisonMenu(pivot);
await cpHelpers.toggleMenuItem(pivot, 'Date: Previous period');
await cpHelpers.toggleComparisonMenu(pivot.el);
await cpHelpers.toggleMenuItem(pivot.el, 'Date: Previous period');
assert.strictEqual(
pivot.$('th').slice(0, 7).text(),
@@ -3256,9 +3286,9 @@ QUnit.module('Views', {
// open group by menu and add new groupby
await cpHelpers.toggleGroupByMenu(pivot);
await cpHelpers.toggleAddCustomGroup(pivot);
await cpHelpers.applyGroup(pivot);
await cpHelpers.toggleGroupByMenu(pivot.el);
await cpHelpers.toggleAddCustomGroup(pivot.el);
await cpHelpers.applyGroup(pivot.el);
assert.strictEqual(
pivot.$('th').slice(0, 2).text(),
@@ -3278,8 +3308,8 @@ QUnit.module('Views', {
);
// Set a Row groupby
await testUtils.dom.click(pivot.$('tbody .o_pivot_header_cell_closed').eq(0));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field=product_id]:first'));
await testUtils.dom.click(pivot.el.querySelector('tbody tr:nth-child(2) .o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.el.querySelectorAll("tbody .o_dropdown_item")[4]);
assert.strictEqual(
pivot.$('th').slice(0, 2).text(),
@@ -3301,10 +3331,10 @@ QUnit.module('Views', {
);
// open groupby menu generator and add a new groupby
await cpHelpers.toggleGroupByMenu(pivot);
await cpHelpers.toggleAddCustomGroup(pivot);
await cpHelpers.selectGroup(pivot, 'bar');
await cpHelpers.applyGroup(pivot);
await cpHelpers.toggleGroupByMenu(pivot.el);
await cpHelpers.toggleAddCustomGroup(pivot.el);
await cpHelpers.selectGroup(pivot.el, 'bar');
await cpHelpers.applyGroup(pivot.el);
assert.strictEqual(
pivot.$('th').slice(0, 2).text(),
@@ -3343,14 +3373,14 @@ QUnit.module('Views', {
additionalMeasures: ['product_id'],
},
});
await testUtils.dom.clickFirst(pivot.$('th.o_pivot_header_cell_closed'));
await testUtils.dom.click(pivot.$('.o_pivot_field_menu .dropdown-item[data-field=product_id]:first'));
await testUtils.dom.click(pivot.el.querySelector("thead th.o_pivot_header_cell_closed"));
await testUtils.dom.click(pivot.el.querySelectorAll("thead .o_dropdown_menu .o_dropdown_item")[5]);
// Click on the two dropdown
await testUtils.dom.click(pivot.$('th.o_pivot_header_cell_closed')[0]);
await testUtils.dom.click(pivot.$('th.o_pivot_header_cell_closed')[1]);
await testUtils.dom.click(pivot.el.querySelectorAll("thead th.o_pivot_header_cell_closed")[0]);
await testUtils.dom.click(pivot.el.querySelectorAll("thead th.o_pivot_header_cell_closed")[1]);
assert.containsOnce(pivot, '.o_pivot_field_menu', 'Only one dropdown should be displayed at a time');
assert.containsOnce(pivot, 'thead .o_dropdown_menu', 'Only one dropdown should be displayed at a time');
pivot.destroy();
});
@@ -7,7 +7,6 @@ const ListView = require('web.ListView');
const testUtils = require('web.test_utils');
const SearchPanel = require("web.searchPanel");
const cpHelpers = testUtils.controlPanel;
const createView = testUtils.createView;
const { makeFakeUserService } = require("@web/../tests/helpers/mock_services");
@@ -16,6 +15,12 @@ const { legacyExtraNextTick } = require("@web/../tests/helpers/utils");
const { registry } = require("@web/core/registry");
const { PivotView } = require("@web/views/pivot/pivot_view");
const {
switchView,
toggleFilterMenu,
toggleMenuItem,
} = require("@web/../tests/search/helpers");
/**
* Return the list of counters displayed in the search panel (if any).
* @param {Widget} view, view controller
@@ -1052,8 +1057,8 @@ QUnit.module('Views', {
// Case 2: search domain changed so we wait for the search panel once again
prom = testUtils.makeTestPromise();
await testUtils.controlPanel.toggleFilterMenu(kanban);
await testUtils.controlPanel.toggleMenuItem(kanban, 0);
await toggleFilterMenu(kanban.$el[0]);
await toggleMenuItem(kanban.$el[0], 0);
assert.verifySteps([]);
@@ -1298,8 +1303,8 @@ QUnit.module('Views', {
// trigger a reload and delay the get_filter
def = testUtils.makeTestPromise();
await cpHelpers.toggleFilterMenu(kanban);
await cpHelpers.toggleMenuItem(kanban, 0);
await toggleFilterMenu(kanban.$el[0]);
await toggleMenuItem(kanban.$el[0], 0);
await testUtils.nextTick();
assert.containsN(kanban, '.o_kanban_view .o_kanban_record:not(.o_kanban_ghost)', 4);
@@ -1568,13 +1573,13 @@ QUnit.module('Views', {
]);
// go to page 2 (the domain doesn't change, so the filters should not be reloaded)
await cpHelpers.pagerNext(kanban);
await testUtils.controlPanel.pagerNext(kanban);
assert.verifySteps([]);
// reload with another domain, so the filters should be reloaded
await cpHelpers.toggleFilterMenu(kanban);
await cpHelpers.toggleMenuItem(kanban, 0);
await toggleFilterMenu(kanban.$el[0]);
await toggleMenuItem(kanban.$el[0], 0);
assert.verifySteps([
'search_panel_select_multi_range',
@@ -1634,13 +1639,13 @@ QUnit.module('Views', {
]);
// go to page 2 (the domain doesn't change, so the filters should not be reloaded)
await cpHelpers.pagerNext(kanban);
await testUtils.controlPanel.pagerNext(kanban);
assert.verifySteps([]);
// reload with another domain, so the filters should be reloaded
await cpHelpers.toggleFilterMenu(kanban);
await cpHelpers.toggleMenuItem(kanban, 0);
await toggleFilterMenu(kanban.$el[0]);
await toggleMenuItem(kanban.$el[0], 0);
assert.verifySteps([
'search_panel_select_multi_range',
@@ -1712,7 +1717,7 @@ QUnit.module('Views', {
);
// go to page 2 (the domain doesn't change, so the categories should not be reloaded)
await cpHelpers.pagerNext(kanban);
await testUtils.controlPanel.pagerNext(kanban);
assert.verifySteps([]);
@@ -1724,8 +1729,8 @@ QUnit.module('Views', {
);
// reload with another domain, so the categories 'state' and 'company_id' should be reloaded
await cpHelpers.toggleFilterMenu(kanban);
await cpHelpers.toggleMenuItem(kanban, 0);
await toggleFilterMenu(kanban.$el[0]);
await toggleMenuItem(kanban.$el[0], 0);
assert.verifySteps([
'search_panel_select_range',
@@ -1810,7 +1815,7 @@ QUnit.module('Views', {
);
// go to page 2 (the domain doesn't change, so the categories should not be reloaded)
await cpHelpers.pagerNext(kanban);
await testUtils.controlPanel.pagerNext(kanban);
assert.verifySteps([]);
@@ -1822,8 +1827,8 @@ QUnit.module('Views', {
);
// reload with another domain, so the category 'state' should be reloaded
await cpHelpers.toggleFilterMenu(kanban);
await cpHelpers.toggleMenuItem(kanban, 0);
await toggleFilterMenu(kanban.$el[0]);
await toggleMenuItem(kanban.$el[0], 0);
assert.verifySteps([]);
@@ -2347,12 +2352,12 @@ QUnit.module('Views', {
assert.containsOnce(webClient, '.o_content.o_controller_with_searchpanel .o_kanban_view');
assert.containsOnce(webClient, '.o_content.o_controller_with_searchpanel .o_search_panel');
await cpHelpers.switchView(webClient, 'pivot');
await switchView(webClient, 'pivot');
await testUtils.nextTick();
assert.containsOnce(webClient, '.o_content .o_pivot');
assert.containsNone(webClient, '.o_content .o_search_panel');
await cpHelpers.switchView(webClient, 'list');
await switchView(webClient, 'list');
await legacyExtraNextTick();
assert.containsOnce(webClient, '.o_content.o_controller_with_searchpanel .o_list_view');
assert.containsOnce(webClient, '.o_content.o_controller_with_searchpanel .o_search_panel');
@@ -2382,12 +2387,12 @@ QUnit.module('Views', {
assert.containsOnce(webClient, '.o_content.o_controller_with_searchpanel .o_kanban_view');
assert.containsOnce(webClient, '.o_content.o_controller_with_searchpanel .o_search_panel');
await cpHelpers.switchView(webClient, 'list');
await switchView(webClient, 'list');
await legacyExtraNextTick();
assert.containsOnce(webClient, '.o_content .o_list_view');
assert.containsNone(webClient, '.o_content .o_search_panel');
await cpHelpers.switchView(webClient, 'pivot');
await switchView(webClient, 'pivot');
assert.containsOnce(webClient, '.o_content.o_component_with_search_panel .o_pivot');
assert.containsOnce(webClient, '.o_content.o_component_with_search_panel .o_search_panel');
});
@@ -2414,7 +2419,7 @@ QUnit.module('Views', {
assert.hasClass($(webClient.el).find('.o_search_panel_category_value:nth(1) header'), 'active');
assert.containsN(webClient, '.o_kanban_record:not(.o_kanban_ghost)', 2);
await cpHelpers.switchView(webClient, 'list');
await switchView(webClient, 'list');
await legacyExtraNextTick();
assert.hasClass($(webClient.el).find('.o_search_panel_category_value:nth(1) header'), 'active');
assert.containsN(webClient, '.o_data_row', 2);
@@ -2425,7 +2430,7 @@ QUnit.module('Views', {
assert.hasClass($(webClient.el).find('.o_search_panel_category_value:nth(2) header'), 'active');
assert.containsN(webClient, '.o_data_row', 2);
await cpHelpers.switchView(webClient, 'kanban');
await switchView(webClient, 'kanban');
await legacyExtraNextTick();
assert.hasClass($(webClient.el).find('.o_search_panel_category_value:nth(2) header'), 'active');
assert.containsN(webClient, '.o_kanban_record:not(.o_kanban_ghost)', 2);
@@ -2460,7 +2465,7 @@ QUnit.module('Views', {
assert.containsOnce(webClient, '.o_search_panel_filter_value input:checked');
assert.containsN(webClient, '.o_kanban_record:not(.o_kanban_ghost)', 1);
await cpHelpers.switchView(webClient, 'list');
await switchView(webClient, 'list');
await legacyExtraNextTick();
assert.containsOnce(webClient, '.o_search_panel_filter_value input:checked');
assert.containsN(webClient, '.o_data_row', 1);
@@ -2471,7 +2476,7 @@ QUnit.module('Views', {
assert.containsN(webClient, '.o_search_panel_filter_value input:checked', 2);
assert.containsN(webClient, '.o_data_row', 4);
await cpHelpers.switchView(webClient, 'kanban');
await switchView(webClient, 'kanban');
await legacyExtraNextTick();
assert.containsN(webClient, '.o_search_panel_filter_value input:checked', 2);
assert.containsN(webClient, '.o_kanban_record:not(.o_kanban_ghost)', 4);
@@ -2510,14 +2515,14 @@ QUnit.module('Views', {
assert.containsN(webClient, '.o_kanban_record:not(.o_kanban_ghost)', 1);
// switch to pivot
await cpHelpers.switchView(webClient, 'pivot');
await switchView(webClient, 'pivot');
await legacyExtraNextTick();
assert.containsOnce(webClient, '.o_content .o_pivot');
assert.containsNone(webClient, '.o_content .o_search_panel');
assert.strictEqual($(webClient.el).find('.o_pivot_cell_value').text(), '15');
// switch to list
await cpHelpers.switchView(webClient, 'list');
await switchView(webClient, 'list');
await legacyExtraNextTick();
assert.containsOnce(webClient, '.o_content.o_controller_with_searchpanel .o_list_view');
assert.containsOnce(webClient, '.o_content.o_controller_with_searchpanel .o_search_panel');
@@ -2567,9 +2572,9 @@ QUnit.module('Views', {
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 1);
await cpHelpers.switchView(webClient, 'list');
await switchView(webClient, 'list');
await legacyExtraNextTick();
await cpHelpers.switchView(webClient, 'kanban');
await switchView(webClient, 'kanban');
await legacyExtraNextTick();
assert.verifySteps([
@@ -2603,14 +2608,14 @@ QUnit.module('Views', {
// simulate a scroll in the search panel and switch into list
await scroll(50);
await cpHelpers.switchView(webClient, 'list');
await switchView(webClient, 'list');
await legacyExtraNextTick();
assert.containsOnce(webClient, '.o_content .o_list_view');
assert.strictEqual($(webClient.el).find('.o_search_panel').scrollTop(), 50);
// simulate another scroll and switch back to kanban
await scroll(30);
await cpHelpers.switchView(webClient, 'kanban');
await switchView(webClient, 'kanban');
await legacyExtraNextTick();
assert.containsOnce(webClient, '.o_content .o_kanban_view');
assert.strictEqual($(webClient.el).find('.o_search_panel').scrollTop(), 30);
@@ -4047,8 +4052,8 @@ QUnit.module('Views', {
assert.strictEqual(kanban.el.querySelector('.o_kanban_record span').innerText, 'yop' );
// select DEF in filter menu
await testUtils.controlPanel.toggleFilterMenu(kanban);
await testUtils.controlPanel.toggleMenuItem(kanban, 'DEF');
await toggleFilterMenu(kanban.$el[0]);
await toggleMenuItem(kanban.$el[0], 'DEF');
assert.verifySteps([
'search_panel_select_range',
@@ -4118,8 +4123,8 @@ QUnit.module('Views', {
);
// select DEF in filter menu --> the external domain changes --> the values should be updated
await testUtils.controlPanel.toggleFilterMenu(kanban);
await testUtils.controlPanel.toggleMenuItem(kanban, 'DEF');
await toggleFilterMenu(kanban.$el[0]);
await toggleMenuItem(kanban.$el[0], 'DEF');
assert.verifySteps([
'search_panel_select_range',
@@ -5,6 +5,7 @@ import {
getFacetTexts,
removeFacet,
saveFavorite,
setupControlPanelFavoriteMenuRegistry,
setupControlPanelServiceRegistry,
switchView,
toggleFavoriteMenu,
@@ -68,6 +69,7 @@ QUnit.module("Views", (hooks) => {
`,
},
};
setupControlPanelFavoriteMenuRegistry();
setupControlPanelServiceRegistry();
serviceRegistry.add("dialog", dialogService);
@@ -7,7 +7,7 @@ var testUtils = require('web.test_utils');
var Widget = require('web.Widget');
var FormView = require('web.FormView');
const cpHelpers = testUtils.controlPanel;
const cpHelpers = require('@web/../tests/search/helpers');
var createView = testUtils.createView;
async function createParent(params) {
@@ -207,8 +207,9 @@ QUnit.module('Views', {
dialog = result;
});
await testUtils.nextTick();
await cpHelpers.removeFacet('.modal', "Bar");
await cpHelpers.removeFacet('.modal');
const modal = document.body.querySelector(".modal");
await cpHelpers.removeFacet(modal, "Bar");
await cpHelpers.removeFacet(modal);
parent.destroy();
});
@@ -567,16 +568,17 @@ QUnit.module('Views', {
assert.containsN(dialog, '.o_data_row', 3, "should contain 3 records");
// filter on bar
await cpHelpers.toggleFilterMenu('.modal');
await cpHelpers.toggleMenuItem('.modal', "Bar");
const modal = document.body.querySelector(".modal");
await cpHelpers.toggleFilterMenu(modal);
await cpHelpers.toggleMenuItem(modal, "Bar");
assert.containsN(dialog, '.o_data_row', 2, "should contain 2 records");
// save filter
await cpHelpers.toggleFavoriteMenu('.modal');
await cpHelpers.toggleSaveFavorite('.modal');
await cpHelpers.editFavoriteName('.modal', "some name");
await cpHelpers.saveFavorite('.modal');
await cpHelpers.toggleFavoriteMenu(modal);
await cpHelpers.toggleSaveFavorite(modal);
await cpHelpers.editFavoriteName(modal, "some name");
await cpHelpers.saveFavorite(modal);
testUtils.mock.unpatch(ListController);
parent.destroy();
@@ -6,7 +6,6 @@ const framework = require('web.framework');
const ListView = require('web.ListView');
const testUtils = require('web.test_utils');
const cpHelpers = testUtils.controlPanel;
const createView = testUtils.createView;
QUnit.module('widgets', {
@@ -114,8 +113,8 @@ QUnit.module('widgets', {
await testUtils.dom.click(list.$('thead th.o_list_record_selector input'));
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, 'Export');
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, 'Export');
assert.strictEqual($('.modal').length, 1, "a modal dialog should be open");
assert.strictEqual($('div.o_tree_column:contains(Activities)').length, 1,
@@ -168,8 +167,8 @@ QUnit.module('widgets', {
};
await testUtils.dom.click(list.$('thead th.o_list_record_selector input'));
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, 'Export');
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, 'Export');
assert.containsOnce(document.body, '.modal');
@@ -183,8 +182,8 @@ QUnit.module('widgets', {
};
await testUtils.dom.click(list.$('.o_list_selection_box .o_list_select_domain'));
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, 'Export');
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, 'Export');
assert.containsOnce(document.body, '.modal');
@@ -217,8 +216,8 @@ QUnit.module('widgets', {
await testUtils.dom.click(list.$('thead th.o_list_record_selector input'));
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, 'Export');
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, 'Export');
list.destroy();
});
@@ -248,8 +247,8 @@ QUnit.module('widgets', {
// Open the export modal
await testUtils.dom.click(list.$('thead th.o_list_record_selector input'));
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, 'Export');
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, 'Export');
assert.strictEqual($('.modal').length, 1,
"a modal dialog should be open");
@@ -291,8 +290,8 @@ QUnit.module('widgets', {
// Open the export modal
await testUtils.dom.click(list.$('thead th.o_list_record_selector input'));
await cpHelpers.toggleActionMenu(list);
await cpHelpers.toggleMenuItem(list, 'Export');
await testUtils.controlPanel.toggleActionMenu(list);
await testUtils.controlPanel.toggleMenuItem(list, 'Export');
assert.strictEqual($('.modal .o_export_tree_item:visible').length, 2, "There should be only two items visible");
await testUtils.dom.click($('.modal .o_export_search_input'));
@@ -12,6 +12,7 @@ import {
getFacetTexts,
makeWithSearch,
saveFavorite,
setupControlPanelFavoriteMenuRegistry,
setupControlPanelServiceRegistry,
toggleFavoriteMenu,
toggleSaveFavorite,
@@ -58,6 +59,7 @@ QUnit.module("Search", (hooks) => {
"foo,false,search": `<search/>`,
},
};
setupControlPanelFavoriteMenuRegistry();
setupControlPanelServiceRegistry();
serviceRegistry.add("dialog", dialogService);
});
@@ -12,6 +12,7 @@ import {
getFacetTexts,
isItemSelected,
makeWithSearch,
setupControlPanelFavoriteMenuRegistry,
setupControlPanelServiceRegistry,
toggleComparisonMenu,
toggleFavoriteMenu,
@@ -20,6 +21,7 @@ import {
const serviceRegistry = registry.category("services");
const viewRegistry = registry.category("views");
const favoriteMenuRegistry = registry.category("favoriteMenu");
function getDomain(comp) {
return comp.env.searchModel.domain;
@@ -45,12 +47,48 @@ QUnit.module("Search", (hooks) => {
"foo,false,search": `<search/>`,
},
};
setupControlPanelFavoriteMenuRegistry();
setupControlPanelServiceRegistry();
serviceRegistry.add("dialog", dialogService);
});
QUnit.module("FavoriteMenu");
QUnit.test(
"simple rendering with no favorite (without ability to save)",
async function (assert) {
assert.expect(4);
favoriteMenuRegistry.remove("custom-favorite-item");
const controlPanel = await makeWithSearch({
serverData,
resModel: "foo",
Component: ControlPanel,
searchMenuTypes: ["favorite"],
searchViewId: false,
displayName: "Action Name",
});
assert.containsOnce(controlPanel, "div.o_favorite_menu > button i.fa.fa-star");
assert.strictEqual(
controlPanel.el
.querySelector("div.o_favorite_menu > button span")
.innerText.trim()
.toUpperCase(),
"FAVORITES"
);
await toggleFavoriteMenu(controlPanel);
assert.containsOnce(
controlPanel,
"div.o_favorite_menu > .o_dropdown_menu",
"the menu should be opened"
);
assert.containsNone(controlPanel, ".o_dropdown_menu *", "the menu should be empty");
}
);
QUnit.test("simple rendering with no favorite", async function (assert) {
assert.expect(5);
@@ -73,12 +111,13 @@ QUnit.module("Search", (hooks) => {
);
await toggleFavoriteMenu(controlPanel);
assert.containsNone(controlPanel, ".dropdown-divider");
assert.containsOnce(controlPanel, ".o_add_favorite");
assert.strictEqual(
controlPanel.el.querySelector(".o_add_favorite > button").innerText.trim(),
"Save current search"
assert.containsOnce(
controlPanel,
"div.o_favorite_menu > .o_dropdown_menu",
"the menu should be opened"
);
assert.containsNone(controlPanel, ".o_dropdown_menu .dropdown-divider");
assert.containsOnce(controlPanel, ".o_dropdown_menu .o_add_favorite");
});
QUnit.test(
+15
View File
@@ -7,11 +7,13 @@ import { registry } from "@web/core/registry";
import { WithSearch } from "@web/search/with_search/with_search";
import { viewService } from "@web/views/view_service";
import { actionService } from "@web/webclient/actions/action_service";
import { CustomFavoriteItem } from "@web/search/favorite_menu/custom_favorite_item";
import { registerCleanup } from "../helpers/cleanup";
import { makeTestEnv } from "../helpers/mock_env";
import { click, getFixture, triggerEvent } from "../helpers/utils";
const serviceRegistry = registry.category("services");
const favoriteMenuRegistry = registry.category("favoriteMenu");
const { Component, mount } = owl;
@@ -23,6 +25,14 @@ export const setupControlPanelServiceRegistry = () => {
serviceRegistry.add("view", viewService);
};
export const setupControlPanelFavoriteMenuRegistry = () => {
favoriteMenuRegistry.add(
"custom-favorite-item",
{ Component: CustomFavoriteItem, groupNumber: 3 },
{ sequence: 0 }
);
};
export const makeWithSearch = async (params) => {
const serverData = params.serverData || undefined;
const mockRPC = params.mockRPC || undefined;
@@ -123,6 +133,11 @@ export const addCondition = async (el) => {
await click(findItem(el, `.o_add_custom_filter_menu .o_dropdown_menu button.o_add_condition`));
};
export async function removeCondition(el, index) {
const condition = findItem(el, `.o_filter_condition`, index);
await click(findItem(condition, ".o_generator_menu_delete"));
}
/** Group by menu */
export const toggleGroupByMenu = async (el) => {
+2
View File
@@ -9,6 +9,7 @@ import { legacyProm } from "web.test_legacy";
import { registerCleanup } from "./helpers/cleanup";
import { prepareRegistriesWithCleanup } from "./helpers/mock_env";
import { session as sessionInfo } from "@web/session";
import { prepareLegacyRegistriesWithCleanup } from "./helpers/legacy_env_utils";
const { whenReady, loadFile } = owl.utils;
@@ -193,6 +194,7 @@ export async function setupTests() {
QUnit.testStart(() => {
checkGlobalObjectsIntegrity();
prepareRegistriesWithCleanup();
prepareLegacyRegistriesWithCleanup();
forceLocaleAndTimezoneWithCleanup();
patchBrowserWithCleanup();
patchLegacyCoreBus();
@@ -11,6 +11,7 @@ import { createWebClient, doAction } from "@web/../tests/webclient/helpers";
import {
editFavoriteName,
saveFavorite,
setupControlPanelFavoriteMenuRegistry,
setupControlPanelServiceRegistry,
switchView,
toggleFavoriteMenu,
@@ -273,6 +274,7 @@ QUnit.module("Views", (hooks) => {
},
};
setupControlPanelServiceRegistry();
setupControlPanelFavoriteMenuRegistry();
serviceRegistry.add("dialog", dialogService);
});
@@ -19,6 +19,7 @@ import { makeView } from "./helpers";
import {
applyGroup,
editFavoriteName,
setupControlPanelFavoriteMenuRegistry,
setupControlPanelServiceRegistry,
toggleAddCustomGroup,
toggleComparisonMenu,
@@ -183,6 +184,7 @@ QUnit.module("Views", (hooks) => {
},
},
};
setupControlPanelFavoriteMenuRegistry();
setupControlPanelServiceRegistry();
serviceRegistry.add("dialog", dialogService);
serviceRegistry.add("localization", makeFakeLocalizationService());
@@ -8,19 +8,14 @@ import { legacyExtraNextTick, nextTick } from "../../helpers/utils";
import { registry } from "@web/core/registry";
import testUtils from "web.test_utils";
import { useSetupView } from "@web/views/helpers/view_hook";
import * as cpHelpers from "@web/../tests/search/helpers";
const { Component, tags } = owl;
const actionRegistry = registry.category("actions");
let serverData;
// legacy stuff
let cpHelpers;
QUnit.module("ActionManager", (hooks) => {
hooks.before(() => {
cpHelpers = testUtils.controlPanel;
});
hooks.beforeEach(() => {
serverData = getActionManagerServerData();
});
@@ -21,7 +21,7 @@ import {
doAction,
getActionManagerServerData,
loadState,
setupWebClientServiceRegistry,
setupWebClientRegistries,
} from "./../helpers";
import { errorService } from "@web/core/errors/error_service";
@@ -79,7 +79,7 @@ QUnit.module("ActionManager", (hooks) => {
assert.expect(4);
const hash = "#action=1001";
Object.assign(browser.location, { hash });
setupWebClientServiceRegistry();
setupWebClientRegistries();
const mockRPC = (route) => assert.step(route);
const env = await makeTestEnv({ serverData, mockRPC });
@@ -96,7 +96,7 @@ QUnit.module("ActionManager", (hooks) => {
assert.expect(3);
const hash = "#action=__test__client__action__";
Object.assign(browser.location, { hash });
setupWebClientServiceRegistry();
setupWebClientRegistries();
const mockRPC = (route) => assert.step(route);
const env = await makeTestEnv({ serverData, mockRPC });
@@ -18,20 +18,16 @@ import {
createWebClient,
doAction,
getActionManagerServerData,
setupWebClientServiceRegistry,
setupWebClientRegistries,
} from "./../helpers";
import * as cpHelpers from "@web/../tests/search/helpers";
let serverData;
// legacy stuff
let cpHelpers;
const actionRegistry = registry.category("actions");
const actionHandlersRegistry = registry.category("action_handlers");
QUnit.module("ActionManager", (hooks) => {
hooks.before(() => {
cpHelpers = testUtils.controlPanel;
});
hooks.beforeEach(() => {
serverData = getActionManagerServerData();
});
@@ -54,7 +50,7 @@ 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"));
setupWebClientServiceRegistry();
setupWebClientRegistries();
const env = await makeTestEnv({ serverData });
await doAction(env, 1);
assert.verifySteps(["client_action_db_id"]);
@@ -70,7 +66,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("action doesn't exists", async (assert) => {
assert.expect(1);
setupWebClientServiceRegistry();
setupWebClientRegistries();
const env = await makeTestEnv({ serverData });
try {
await doAction(env, {
@@ -88,7 +84,7 @@ QUnit.module("ActionManager", (hooks) => {
QUnit.test("action in handler registry", async (assert) => {
assert.expect(2);
setupWebClientServiceRegistry();
setupWebClientRegistries();
const env = await makeTestEnv({ serverData });
actionHandlersRegistry.add("ir.action_in_handler_registry", ({ action }) =>
assert.step(action.type)
@@ -123,7 +119,7 @@ QUnit.module("ActionManager", (hooks) => {
}
};
setupWebClientServiceRegistry();
setupWebClientRegistries();
const env = await makeTestEnv({ serverData, mockRPC });
const loadAction = env.services.action.loadAction;
@@ -180,7 +176,7 @@ QUnit.module("ActionManager", (hooks) => {
}
};
setupWebClientServiceRegistry();
setupWebClientRegistries();
const env = await makeTestEnv({ serverData, mockRPC });
const { loadAction } = env.services.action;
const actionParams = {
@@ -3,7 +3,7 @@
import { registry } from "@web/core/registry";
import { makeTestEnv } from "../../helpers/mock_env";
import { makeFakeRouterService } from "../../helpers/mock_services";
import { setupWebClientServiceRegistry, doAction, getActionManagerServerData } from "./../helpers";
import { setupWebClientRegistries, doAction, getActionManagerServerData } from "./../helpers";
let serverData;
const serviceRegistry = registry.category("services");
@@ -24,7 +24,7 @@ QUnit.module("ActionManager", (hooks) => {
},
})
);
setupWebClientServiceRegistry();
setupWebClientRegistries();
const env = await makeTestEnv({ serverData });
await doAction(env, {
type: "ir.actions.act_url",
@@ -23,17 +23,12 @@ import { RPCError } from "@web/core/network/rpc_service";
import { registerCleanup } from "../../helpers/cleanup";
import { WarningDialog } from "@web/core/errors/error_dialogs";
import { makeFakeUserService } from "@web/../tests/helpers/mock_services";
import * as cpHelpers from "@web/../tests/search/helpers";
let serverData;
const serviceRegistry = registry.category("services");
// legacy stuff
let cpHelpers;
QUnit.module("ActionManager", (hooks) => {
hooks.before(() => {
cpHelpers = testUtils.controlPanel;
});
hooks.beforeEach(() => {
serverData = getActionManagerServerData();
});
@@ -1149,13 +1144,9 @@ QUnit.module("ActionManager", (hooks) => {
"list view is not grouped"
);
// open group by dropdown
await testUtils.dom.click(
$(webClient.el).find(".o_control_panel .o_cp_bottom_right button:contains(Group By)")
);
// click on first link
await testUtils.dom.click(
$(webClient.el).find(".o_control_panel .o_group_by_menu a:first")
);
await cpHelpers.toggleGroupByMenu(webClient);
// click on foo link
await cpHelpers.toggleMenuItem(webClient.el, "foo");
await legacyExtraNextTick();
assert.hasClass(
$(webClient.el).find(".o_list_table")[0],
@@ -1365,7 +1356,7 @@ QUnit.module("ActionManager", (hooks) => {
$(webClient.el).find(".o_control_panel .o_cp_bottom_right button:contains(Group By)")
);
await testUtils.dom.click(
$(webClient.el).find(".o_control_panel .o_group_by_menu a:first")
$(webClient.el).find(".o_control_panel .o_group_by_menu li:first")
);
await legacyExtraNextTick();
assert.containsN(
@@ -1793,8 +1784,8 @@ QUnit.module("ActionManager", (hooks) => {
await legacyExtraNextTick();
assert.containsOnce(webClient, ".o_form_view");
// execute the custom action from the action menu
await cpHelpers.toggleActionMenu(webClient.el);
await cpHelpers.toggleMenuItem(webClient.el, "Favorite Ponies");
await testUtils.controlPanel.toggleActionMenu(webClient.el);
await testUtils.controlPanel.toggleMenuItem(webClient.el, "Favorite Ponies");
await legacyExtraNextTick();
assert.containsOnce(webClient, ".o_list_view");
});
+20 -7
View File
@@ -44,19 +44,33 @@ import { userService } from "@web/core/user_service";
import { uiService } from "@web/core/ui/ui_service";
import { ClientActionAdapter, ViewAdapter } from "@web/legacy/action_adapters";
import { commandService } from "@web/core/commands/command_service";
import { CustomFavoriteItem } from "@web/search/favorite_menu/custom_favorite_item";
const { Component, mount, tags } = owl;
const actionRegistry = registry.category("actions");
const serviceRegistry = registry.category("services");
const favoriteMenuRegistry = registry.category("favoriteMenu");
/**
* 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).
* Builds the required registries for tests using a WebClient.
* We use a default version of each required registry item.
* If the registry already contains one of those items,
* the existing one is kept (it means it has been added in the test
* directly, e.g. to have a custom version of the item).
*/
export function setupWebClientServiceRegistry() {
export function setupWebClientRegistries() {
const favoriveMenuItems = {
"custom-favorite-item": {
value: { Component: CustomFavoriteItem, groupNumber: 3 },
options: { sequence: 0 },
},
};
for (let [key, { value, options }] of Object.entries(favoriveMenuItems)) {
if (!favoriteMenuRegistry.contains(key)) {
favoriteMenuRegistry.add(key, value, options);
}
}
const services = {
action: () => actionService,
command: () => commandService,
@@ -168,7 +182,6 @@ export function addLegacyMockEnvironment(env, legacyParams = {}) {
// deploy the legacyActionManagerService (in Wowl env)
const legacyActionManagerService = makeLegacyActionManagerService(legacyEnv);
serviceRegistry.add("legacy_action_manager", legacyActionManagerService);
serviceRegistry.add("legacy_notification", makeLegacyNotificationService(legacyEnv));
// patch DebouncedField delay
const debouncedField = basicFields.DebouncedField;
@@ -206,7 +219,7 @@ export function addLegacyMockEnvironment(env, legacyParams = {}) {
* @param {*} params
*/
export async function createWebClient(params) {
setupWebClientServiceRegistry();
setupWebClientRegistries();
// With the compatibility layer, the action manager keeps legacy alive if they
// are still acessible from the breacrumbs. They are manually destroyed as soon