summaryrefslogtreecommitdiff
path: root/addons/web/static/tests/control_panel/favorite_menu_tests.js
diff options
context:
space:
mode:
authorJulien Mougenot <jum@odoo.com>2020-03-11 09:38:29 +0000
committerJulien Mougenot <jum@odoo.com>2020-03-13 14:08:33 +0000
commitbb8eb766a84b9fd06007d3fb4ab9a29b70097738 (patch)
treef944ba5c9d0efcb2a9a881d8eeaef7ecc96e6245 /addons/web/static/tests/control_panel/favorite_menu_tests.js
parente68d3bb09d1f844387ceb20aa76022ace48507d9 (diff)
[REF] web: Control panel tests
Use of the new helpers in control panel (and subcomponents) tests and addition of new tests. Part of task 2196029 Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com>
Diffstat (limited to 'addons/web/static/tests/control_panel/favorite_menu_tests.js')
-rw-r--r--addons/web/static/tests/control_panel/favorite_menu_tests.js572
1 files changed, 572 insertions, 0 deletions
diff --git a/addons/web/static/tests/control_panel/favorite_menu_tests.js b/addons/web/static/tests/control_panel/favorite_menu_tests.js
new file mode 100644
index 00000000000..5aadc99f619
--- /dev/null
+++ b/addons/web/static/tests/control_panel/favorite_menu_tests.js
@@ -0,0 +1,572 @@
+odoo.define('web.favorite_menu_tests', function (require) {
+ "use strict";
+
+ const FormView = require('web.FormView');
+ const testUtils = require('web.test_utils');
+
+ const cpHelpers = testUtils.controlPanel;
+ const { createControlPanel, createView, mock } = testUtils;
+ const { patchDate } = mock;
+
+ const searchMenuTypes = ['favorite'];
+
+ QUnit.module('Components', {
+ beforeEach: function () {
+ this.fields = {
+ bar: { string: "Bar", type: "many2one", relation: 'partner' },
+ birthday: { string: "Birthday", type: "date", store: true, sortable: true },
+ date_field: { string: "Date", type: "date", store: true, sortable: true },
+ float_field: { string: "Float", type: "float", group_operator: 'sum' },
+ foo: { string: "Foo", type: "char", store: true, sortable: true },
+ };
+ },
+ }, function () {
+
+ QUnit.module('FavoriteMenu');
+
+ QUnit.test('simple rendering with no favorite', async function (assert) {
+ assert.expect(8);
+
+ const params = {
+ cpStoreConfig: { searchMenuTypes },
+ cpProps: { fields: this.fields, searchMenuTypes, action: { name: "Action Name" } },
+ };
+ const controlPanel = await createControlPanel(params);
+
+ 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(), "Favorites");
+
+ await cpHelpers.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");
+
+ await cpHelpers.toggleSaveFavorite(controlPanel);
+ assert.strictEqual(
+ controlPanel.el.querySelector('.o_add_favorite input[type="text"]').value,
+ 'Action Name'
+ );
+ assert.containsN(controlPanel, '.o_add_favorite .custom-checkbox input[type="checkbox"]', 2);
+ const labelEls = controlPanel.el.querySelectorAll('.o_add_favorite .custom-checkbox label');
+ assert.deepEqual(
+ [...labelEls].map(e => e.innerText.trim()),
+ ["Use by default", "Share with all users"]
+ );
+
+ controlPanel.destroy();
+ });
+
+ QUnit.test('favorites use by default and share are exclusive', async function (assert) {
+ assert.expect(11);
+
+ const params = {
+ cpStoreConfig: {
+ viewInfo: { fields: this.fields },
+ searchMenuTypes
+ },
+ cpProps: {
+ fields: this.fields,
+ searchMenuTypes,
+ action: {},
+ },
+ };
+ const controlPanel = await createControlPanel(params);
+
+ await cpHelpers.toggleFavoriteMenu(controlPanel);
+ await cpHelpers.toggleSaveFavorite(controlPanel);
+ const checkboxes = controlPanel.el.querySelectorAll('input[type="checkbox"]');
+
+ assert.strictEqual(checkboxes.length, 2, '2 checkboxes are present');
+
+ assert.notOk(checkboxes[0].checked, 'Start: None of the checkboxes are checked (1)');
+ assert.notOk(checkboxes[1].checked, 'Start: None of the checkboxes are checked (2)');
+
+ await testUtils.dom.click(checkboxes[0]);
+ assert.ok(checkboxes[0].checked, 'The first checkbox is checked');
+ assert.notOk(checkboxes[1].checked, 'The second checkbox is not checked');
+
+ await testUtils.dom.click(checkboxes[1]);
+ assert.notOk(checkboxes[0].checked,
+ 'Clicking on the second checkbox checks it, and unchecks the first (1)');
+ assert.ok(checkboxes[1].checked,
+ 'Clicking on the second checkbox checks it, and unchecks the first (2)');
+
+ await testUtils.dom.click(checkboxes[0]);
+ assert.ok(checkboxes[0].checked,
+ 'Clicking on the first checkbox checks it, and unchecks the second (1)');
+ assert.notOk(checkboxes[1].checked,
+ 'Clicking on the first checkbox checks it, and unchecks the second (2)');
+
+ await testUtils.dom.click(checkboxes[0]);
+ assert.notOk(checkboxes[0].checked, 'End: None of the checkboxes are checked (1)');
+ assert.notOk(checkboxes[1].checked, 'End: None of the checkboxes are checked (2)');
+
+ controlPanel.destroy();
+ });
+
+ QUnit.test('save filter', async function (assert) {
+ assert.expect(1);
+
+ const params = {
+ cpStoreConfig: {
+ viewInfo: { fields: this.fields },
+ searchMenuTypes
+ },
+ cpProps: {
+ fields: this.fields,
+ searchMenuTypes,
+ action: {},
+ },
+ 'get-controller-query-params': function (callback) {
+ callback({
+ orderedBy: [
+ { asc: true, name: 'foo' },
+ { asc: false, name: 'bar' }
+ ]
+ });
+ },
+ env: {
+ dataManager: {
+ create_filter: async function (filter) {
+ assert.strictEqual(filter.sort, '["foo","bar desc"]',
+ 'The right format for the string "sort" should be sent to the server'
+ );
+ }
+ }
+ },
+ };
+
+ const controlPanel = await createControlPanel(params);
+
+ await cpHelpers.toggleFavoriteMenu(controlPanel);
+ await cpHelpers.toggleSaveFavorite(controlPanel);
+ await cpHelpers.editFavoriteName(controlPanel, "aaa");
+ await cpHelpers.saveFavorite(controlPanel);
+
+ controlPanel.destroy();
+ });
+
+ QUnit.test('dynamic filters are saved dynamic', async function (assert) {
+ assert.expect(3);
+
+ const arch = `
+ <search>
+ <filter string="Float" name="positive" domain="[('date_field', '>=', (context_today() + relativedelta()).strftime('%Y-%m-%d'))]"/>
+ </search>
+ `;
+ const params = {
+ cpStoreConfig: {
+ viewInfo: { fields: {}, arch },
+ searchMenuTypes,
+ actionContext: {
+ search_default_positive: true,
+ }
+ },
+ cpProps: {
+ fields: {},
+ searchMenuTypes,
+ action: {},
+ },
+ 'get-controller-query-params': function (callback) {
+ callback();
+ },
+ env: {
+ dataManager: {
+ create_filter: async function (filter) {
+ assert.strictEqual(
+ filter.domain,
+ "[(\"date_field\", \">=\", (context_today() + relativedelta()).strftime(\"%Y-%m-%d\"))]"
+ );
+ return 1; // serverSideId
+ }
+ }
+ },
+ };
+ const controlPanel = await createControlPanel(params);
+
+ assert.deepEqual(cpHelpers.getFacetTexts(controlPanel), ['Float']);
+
+ await cpHelpers.toggleFavoriteMenu(controlPanel);
+ await cpHelpers.toggleSaveFavorite(controlPanel);
+ await cpHelpers.editFavoriteName(controlPanel, "My favorite");
+ await cpHelpers.saveFavorite(controlPanel);
+
+ assert.deepEqual(cpHelpers.getFacetTexts(controlPanel), ["My favorite"]);
+
+ controlPanel.destroy();
+ });
+
+ QUnit.test('save filters created via autocompletion works', async function (assert) {
+ assert.expect(4);
+
+ const arch = `<search><field name="foo"/></search>`;
+ const params = {
+ cpStoreConfig: {
+ viewInfo: { fields: this.fields, arch },
+ searchMenuTypes,
+ },
+ cpProps: {
+ fields: this.fields,
+ searchMenuTypes,
+ action: {},
+ },
+ 'get-controller-query-params': function (callback) {
+ callback();
+ },
+ env: {
+ dataManager: {
+ create_filter: async function (filter) {
+ assert.strictEqual(
+ filter.domain,
+ `[["foo", "ilike", "a"]]`
+ );
+ return 1; // serverSideId
+ }
+ }
+ },
+ };
+ const controlPanel = await createControlPanel(params);
+
+ assert.deepEqual(cpHelpers.getFacetTexts(controlPanel), []);
+
+ await cpHelpers.editSearch(controlPanel, "a");
+ await cpHelpers.validateSearch(controlPanel);
+
+ assert.deepEqual(cpHelpers.getFacetTexts(controlPanel), ["Foo\na"]);
+
+ await cpHelpers.toggleFavoriteMenu(controlPanel);
+ await cpHelpers.toggleSaveFavorite(controlPanel);
+ await cpHelpers.editFavoriteName(controlPanel, "My favorite");
+ await cpHelpers.saveFavorite(controlPanel);
+
+ assert.deepEqual(cpHelpers.getFacetTexts(controlPanel), ["My favorite"]);
+
+ controlPanel.destroy();
+ });
+
+ QUnit.test('delete an active favorite remove it both in list of favorite and in search bar', async function (assert) {
+ assert.expect(6);
+
+ const favoriteFilters = [{
+ context: "{}",
+ domain: "[['foo', '=', 'qsdf']]",
+ id: 7,
+ is_default: true,
+ name: "My favorite",
+ sort: "[]",
+ user_id: [2, "Mitchell Admin"],
+ }];
+ const params = {
+ cpStoreConfig: { viewInfo: { favoriteFilters }, searchMenuTypes },
+ cpProps: { searchMenuTypes, action: {} },
+ search: function (searchQuery) {
+ const { domain } = searchQuery;
+ assert.deepEqual(domain, []);
+ },
+ env: {
+ dataManager: {
+ delete_filter: function () {
+ return Promise.resolve();
+ }
+ }
+ },
+ };
+ const controlPanel = await createControlPanel(params);
+
+ await cpHelpers.toggleFavoriteMenu(controlPanel);
+
+ 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');
+
+ 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');
+ assert.deepEqual([...itemEls].map(e => e.innerText.trim()), ["Save Current Search"]);
+
+ controlPanel.destroy();
+ });
+
+ QUnit.test('default favorite is not activated if key search_disable_custom_filters is set to true', async function (assert) {
+ assert.expect(2);
+
+ const favoriteFilters = [{
+ context: "{}",
+ domain: "",
+ id: 7,
+ is_default: true,
+ name: "My favorite",
+ sort: "[]",
+ user_id: [2, "Mitchell Admin"],
+ }];
+ const params = {
+ cpStoreConfig: {
+ viewInfo: { favoriteFilters },
+ searchMenuTypes,
+ actionContext: { search_disable_custom_filters: true }
+ },
+ cpProps: { searchMenuTypes, action: {} },
+ };
+ const controlPanel = await createControlPanel(params);
+
+ await cpHelpers.toggleFavoriteMenu(controlPanel);
+
+ const { domain } = controlPanel.getQuery();
+ assert.deepEqual(domain, []);
+ assert.deepEqual(cpHelpers.getFacetTexts(controlPanel), []);
+
+ controlPanel.destroy();
+ });
+
+ QUnit.test('toggle favorite correctly clears filter, groupbys, time ranges and field "options"', async function (assert) {
+ assert.expect(8);
+
+ const unpatchDate = patchDate(2019, 6, 31, 13, 43, 0);
+
+ const favoriteFilters = [{
+ context: "{'group_by': ['foo'], 'time_ranges': {'field': 'birthday', 'range': 'this_year'}}",
+ domain: "['!', ['foo', '=', 'qsdf']]",
+ id: 7,
+ is_default: false,
+ name: "My favorite",
+ sort: "[]",
+ user_id: [2, "Mitchell Admin"],
+ }];
+ const arch = `
+ <search>
+ <field string="Foo" name="foo"/>
+ <filter string="Date Field Filter" name="positive" date="date_field"/>
+ <filter string="Date Field Groupby" name="coolName" context="{'group_by': 'date_field'}"/>
+ </search>
+ `;
+ const searchMenuTypes = ['filter', 'groupBy', 'timeRange', 'favorite'];
+ const params = {
+ cpStoreConfig: {
+ viewInfo: { favoriteFilters, arch, fields: this.fields },
+ searchMenuTypes,
+ actionContext: {
+ search_default_positive: true,
+ search_default_coolName: true,
+ search_default_foo: "a",
+ time_ranges: { field: 'date_field', range: 'today', comparisonRange: 'previous_period' }
+ }
+ },
+ cpProps: { searchMenuTypes, action: {}, fields: this.fields },
+ search: function (searchQuery) {
+ const { domain, groupBy, timeRanges } = searchQuery;
+ assert.deepEqual(domain, ['!', ['foo', '=', 'qsdf']]);
+ assert.deepEqual(groupBy, ['foo']);
+ assert.deepEqual(timeRanges, {
+ fieldDescription: "Birthday",
+ fieldName: "birthday",
+ range: [
+ "&", ["birthday", ">=", "2019-01-01"], ["birthday", "<", "2020-01-01"]
+ ],
+ rangeDescription: "This Year",
+ rangeId: "this_year"
+ });
+ }
+ };
+ const controlPanel = await createControlPanel(params);
+
+ const { domain, groupBy, timeRanges } = controlPanel.getQuery();
+ assert.deepEqual(domain, [
+ "&",
+ ["foo", "=", "a"],
+ "&",
+ ["date_field", ">=", "2019-07-01"],
+ ["date_field", "<=", "2019-07-31"]
+ ]);
+ assert.deepEqual(groupBy, ['date_field:month']);
+ assert.deepEqual(timeRanges, {
+ comparisonRange: [
+ "&", ["date_field", ">=", "2019-07-30"], ["date_field", "<", "2019-07-31"]
+ ],
+ comparisonRangeDescription: "Previous Period",
+ comparisonRangeId: "previous_period",
+ fieldDescription: "Date",
+ fieldName: "date_field",
+ range: [
+ "&", ["date_field", ">=", "2019-07-31"], ["date_field", "<", "2019-08-01"]
+ ],
+ rangeDescription: "Today",
+ rangeId: "today"
+ });
+
+ assert.deepEqual(
+ cpHelpers.getFacetTexts(controlPanel),
+ [
+ 'Foo\na',
+ 'Date Field Filter: July 2019',
+ 'Date Field Groupby: Month',
+ 'Date: Today / Previous Period'
+ ]
+ );
+
+ await cpHelpers.toggleFavoriteMenu(controlPanel);
+ await cpHelpers.toggleMenuItem(controlPanel, 0);
+
+ assert.deepEqual(
+ cpHelpers.getFacetTexts(controlPanel),
+ ["My favorite"]
+ );
+
+ controlPanel.destroy();
+ unpatchDate();
+ });
+
+ QUnit.test('favorites have unique descriptions (the submenus of the favorite menu are correctly updated)', async function (assert) {
+ assert.expect(3);
+
+ const favoriteFilters = [{
+ context: "{}",
+ domain: "[]",
+ id: 1,
+ is_default: false,
+ name: "My favorite",
+ sort: "[]",
+ user_id: [2, "Mitchell Admin"],
+ }];
+ const params = {
+ cpStoreConfig: { viewInfo: { favoriteFilters }, searchMenuTypes },
+ cpProps: { searchMenuTypes, action: {} },
+ 'get-controller-query-params': function (callback) {
+ callback();
+ },
+ env: {
+ session: { uid: 4 },
+ services: {
+ notification: {
+ notify: function (params) {
+ assert.deepEqual(params, {
+ title: "Error",
+ message: "Filter with same name already exists.",
+ type: "danger"
+ });
+ },
+ }
+ },
+ dataManager: {
+ create_filter: async function (irFilter) {
+ assert.deepEqual(irFilter, {
+ "action_id": undefined,
+ "context": { "group_by": [] },
+ "domain": "[]",
+ "is_default": false,
+ "model_id": undefined,
+ "name": "My favorite 2",
+ "sort": "[]",
+ "user_id": 4,
+ });
+ return 2; // serverSideId
+ }
+ }
+ },
+ };
+ const controlPanel = await createControlPanel(params);
+
+ await cpHelpers.toggleFavoriteMenu(controlPanel);
+ await cpHelpers.toggleSaveFavorite(controlPanel);
+
+ // first try: should fail
+ await cpHelpers.editFavoriteName(controlPanel, "My favorite");
+ await cpHelpers.saveFavorite(controlPanel);
+
+ // 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");
+ await cpHelpers.saveFavorite(controlPanel);
+
+ controlPanel.destroy();
+ });
+
+ QUnit.test('save search filter in modal', async function (assert) {
+ assert.expect(5);
+ const data = {
+ partner: {
+ fields: {
+ date_field: { string: "Date", type: "date", store: true, sortable: true, searchable: true },
+ birthday: { string: "Birthday", type: "date", store: true, sortable: true },
+ foo: { string: "Foo", type: "char", store: true, sortable: true },
+ bar: { string: "Bar", type: "many2one", relation: 'partner' },
+ float_field: { string: "Float", type: "float", group_operator: 'sum' },
+ },
+ records: [
+ { id: 1, display_name: "First record", foo: "yop", bar: 2, date_field: "2017-01-25", birthday: "1983-07-15", float_field: 1 },
+ { id: 2, display_name: "Second record", foo: "blip", bar: 1, date_field: "2017-01-24", birthday: "1982-06-04", float_field: 2 },
+ { id: 3, display_name: "Third record", foo: "gnap", bar: 1, date_field: "2017-01-13", birthday: "1985-09-13", float_field: 1.618 },
+ { id: 4, display_name: "Fourth record", foo: "plop", bar: 2, date_field: "2017-02-25", birthday: "1983-05-05", float_field: -1 },
+ { id: 5, display_name: "Fifth record", foo: "zoup", bar: 2, date_field: "2016-01-25", birthday: "1800-01-01", float_field: 13 },
+ { id: 7, display_name: "Partner 6", },
+ { id: 8, display_name: "Partner 7", },
+ { id: 9, display_name: "Partner 8", },
+ { id: 10, display_name: "Partner 9", }
+ ],
+ },
+ };
+ const form = await createView({
+ arch: `
+ <form string="Partners">
+ <sheet>
+ <group>
+ <field name="bar"/>
+ </group>
+ </sheet>
+ </form>`,
+ archs: {
+ 'partner,false,list': '<tree><field name="display_name"/></tree>',
+ 'partner,false,search': '<search><field name="date_field"/></search>',
+ },
+ data,
+ model: 'partner',
+ res_id: 1,
+ View: FormView,
+ env: {
+ dataManager: {
+ create_filter(filter) {
+ assert.strictEqual(filter.name, "Awesome Test Customer Filter",
+ "filter name should be correct");
+ },
+ }
+ },
+ });
+
+ await testUtils.form.clickEdit(form);
+
+ await testUtils.fields.many2one.clickOpenDropdown('bar');
+ await testUtils.fields.many2one.clickItem('bar', 'Search');
+
+ assert.containsN(document.body, 'tr.o_data_row', 9, "should display 9 records");
+
+ 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');
+
+ assert.containsNone(document.body, 'tr.o_data_row', "should display 0 records");
+
+ // Save this search
+ 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");
+
+ await testUtils.fields.editInput(filterNameInput, 'Awesome Test Customer Filter');
+ await testUtils.dom.click(document.querySelector('.o_add_favorite button.btn-primary'));
+
+ form.destroy();
+ });
+ });
+}); \ No newline at end of file