odoo.define('web.control_panel_tests', function (require) { "use strict"; var ControlPanelView = require('web.ControlPanelView'); var testUtils = require('web.test_utils'); var createControlPanel = testUtils.createControlPanel; function createControlPanelFactory(arch, fields, params) { params = params || {}; arch = arch || ""; fields = fields || {}; var viewInfo = {arch: arch, fields: fields}; var controlPanelFactory = new ControlPanelView({viewInfo: viewInfo, context: {}}); return controlPanelFactory; } QUnit.module('Views', { beforeEach: function () { this.data = { partner: { fields: { display_name: { string: "Displayed name", type: 'char' }, foo: {string: "Foo", type: "char", default: "My little Foo Value", store: true, sortable: true}, date_field: {string: "Date", type: "date", store: true, sortable: true}, float_field: {string: "Float", type: "float"}, bar: {string: "Bar", type: "many2one", relation: 'partner'}, }, records: [], onchanges: {}, }, }; } }, function () { QUnit.module('ControlPanelView'); QUnit.module('Control Panel Arch Parsing'); QUnit.test('empty arch', function (assert) { assert.expect(1); var controlPanelFactory = createControlPanelFactory(); assert.deepEqual( controlPanelFactory.loadParams.groups, [], "there should be no group at all" ); }); QUnit.test('parse one field tag', function (assert) { assert.expect(1); var arch = "" + "" + ""; var fields = this.data.partner.fields; var controlPanelFactory = createControlPanelFactory(arch, fields); assert.deepEqual( controlPanelFactory.loadParams.groups, [[{ attrs: { name: "bar", string: "Bar" }, autoCompleteValues: [], description: "bar", isDefault: false, type: "field" }]], "there should be one group with one field" ); }); QUnit.test('parse one separator tag', function (assert) { assert.expect(1); var arch = "" + "" + ""; var fields = this.data.partner.fields; var controlPanelFactory = createControlPanelFactory(arch, fields); assert.deepEqual( controlPanelFactory.loadParams.groups, [], "there should be no group at all"); }); QUnit.test('parse one separator tag and one field tag', function (assert) { assert.expect(1); var arch = "" + "" + "" + ""; var fields = this.data.partner.fields; var controlPanelFactory = createControlPanelFactory(arch, fields); assert.deepEqual( controlPanelFactory.loadParams.groups, [[ { attrs: { name: "bar", string: "Bar" }, autoCompleteValues: [], description: "bar", isDefault: false, type: "field" } ]], "there should be one group with one field" ); }); QUnit.test('parse one filter tag', function (assert) { assert.expect(1); var arch = "" + "" + ""; var fields = this.data.partner.fields; var controlPanelFactory = createControlPanelFactory(arch, fields); assert.deepEqual( controlPanelFactory.loadParams.groups, [[{ context: {}, description: "Hello", groupNumber: 2, domain: "[]", isDefault: false, type: "filter" }]], "there should be one group with one filter" ); }); QUnit.test('parse one groupBy tag', function (assert) { assert.expect(1); var arch = "" + "" + ""; var fields = this.data.partner.fields; var controlPanelFactory = createControlPanelFactory(arch, fields); assert.deepEqual( controlPanelFactory.loadParams.groups, [[ { currentOptionIds: new Set(), defaultOptionId: "day", description: "Hi", fieldName: "date_field", fieldType: "date", groupNumber: 2, hasOptions: true, isDefault: false, options: [ { description: "Year", groupId: 1, optionId: "year" }, { description: "Quarter", groupId: 1, optionId: "quarter" }, { description: "Month", groupId: 1, optionId: "month" }, { description: "Week", groupId: 1, optionId: "week" }, { description: "Day", groupId: 1, optionId: "day" } ], type: "groupBy" } ]], "there should be one group with one groupBy with options" ); }); QUnit.test('parse two filter tags', function (assert) { assert.expect(1); var arch = "" + "" + "" + ""; var fields = this.data.partner.fields; var controlPanelFactory = createControlPanelFactory(arch, fields); assert.deepEqual( controlPanelFactory.loadParams.groups, [[ { "context": {}, "description": "Hello One", "domain": "[]", "groupNumber": 2, "isDefault": false, "type": "filter" }, { "context": {}, "description": "Hello Two", "domain": "[('bar', '=', 3)]", "groupNumber": 2, "isDefault": false, "type": "filter" } ]], 'there should be one group of two filters' ); }); QUnit.test('parse two filter tags separated by a separator', function (assert) { assert.expect(1); var arch = "" + "" + "" + "" + ""; var fields = this.data.partner.fields; var controlPanelFactory = createControlPanelFactory(arch, fields); assert.deepEqual( controlPanelFactory.loadParams.groups, [ [ { context: {}, description: "Hello One", domain: "[]", groupNumber: 2, isDefault: false, type: "filter" } ], [ { context: {}, description: "Hello Two", domain: "[('bar', '=', 3)]", groupNumber: 4, isDefault: false, type: "filter" } ] ], "there should be two groups of one filter" ); }); QUnit.test('parse one filter tag and one field', function (assert) { assert.expect(1); var arch = "" + "" + "" + ""; var fields = this.data.partner.fields; var controlPanelFactory = createControlPanelFactory(arch, fields); assert.deepEqual( controlPanelFactory.loadParams.groups, [ [ { context: {}, description: "Hello", domain: "[]", groupNumber: 2, isDefault: false, type: "filter" } ], [ { attrs: { name: "bar", string: "Bar" }, autoCompleteValues: [], description: "bar", isDefault: false, type: "field" } ] ], "there should be one group with a filter and one group with a field" ); }); QUnit.test('parse two field tags', function (assert) { assert.expect(1); var arch = "" + "" + "" + ""; var fields = this.data.partner.fields; var controlPanelFactory = createControlPanelFactory(arch, fields); assert.deepEqual( controlPanelFactory.loadParams.groups, [ [ { attrs: { name: "foo", string: "Foo" }, autoCompleteValues: [], description: "foo", isDefault: false, type: "field" } ], [ { attrs: { name: "bar", string: "Bar" }, autoCompleteValues: [], description: "bar", isDefault: false, type: "field" } ] ], "there should be two groups of a single field" ); }); QUnit.module('Control Panel Rendering'); QUnit.test('invisible filters are not rendered', async function (assert) { assert.expect(2); var controlPanel = await createControlPanel({ model: 'partner', arch: "" + "" + "" + "", data: this.data, searchMenuTypes: ['filter'], context: { search_disable_custom_filters: true, }, }); await testUtils.dom.click(controlPanel.$('.o_filters_menu_button')); assert.containsOnce(controlPanel, '.o_menu_item a:contains("A")'); assert.containsOnce(controlPanel, '.o_menu_item.d-none a:contains("B")'); controlPanel.destroy(); }); QUnit.module('Control Panel behaviour'); QUnit.test('remove a facet with backspace', async function (assert) { assert.expect(2); var controlPanel = await createControlPanel({ model: 'partner', arch: "", data: this.data, searchMenuTypes: ['filter'], }); await testUtils.dom.click(controlPanel.$('.o_filters_menu_button')); await testUtils.dom.click($('.o_menu_item a')); assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').text().trim(), 'A', 'should have a facet with A'); // delete a facet controlPanel.$('input.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.BACKSPACE, keyCode: $.ui.keyCode.BACKSPACE, })); await testUtils.nextTick(); assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').length, 0, 'there should be no facet'); // delete nothing (should not crash) controlPanel.$('input.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.BACKSPACE, keyCode: $.ui.keyCode.BACKSPACE, })); await testUtils.nextTick(); controlPanel.destroy(); }); QUnit.module('Control Panel Rendering'); QUnit.test('invisible filters are not rendered', async function (assert) { assert.expect(2); var controlPanel = await createControlPanel({ model: 'partner', arch: "" + "" + "" + "", data: this.data, searchMenuTypes: ['filter'], context: { search_disable_custom_filters: true, }, }); await testUtils.dom.click(controlPanel.$('.o_filters_menu_button')); assert.containsOnce(controlPanel, '.o_menu_item a:contains("A")'); assert.containsOnce(controlPanel, '.o_menu_item.d-none a:contains("B")'); controlPanel.destroy(); }); QUnit.test('Favorites Use by Default and Share are exclusive', async function (assert) { assert.expect(11); var controlPanel = await createControlPanel({ model: 'partner', arch: "", data: this.data, searchMenuTypes: ['favorite'], }); testUtils.dom.click(controlPanel.$('.o_favorites_menu_button')); testUtils.dom.click(controlPanel.$('button.o_add_favorite')); var $checkboxes = controlPanel.$('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)'); testUtils.dom.click($checkboxes.eq(0)); assert.ok($checkboxes[0].checked, 'The first checkbox is checked'); assert.notOk($checkboxes[1].checked, 'The second checkbox is not checked'); testUtils.dom.click($checkboxes.eq(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)'); testUtils.dom.click($checkboxes.eq(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)'); testUtils.dom.click($checkboxes.eq(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('load filter', async function (assert) { assert.expect(1); var controlPanel = await createControlPanel({ model: 'partner', arch: "", data: this.data, searchMenuTypes: ['filter'], intercepts: { load_filters: function (ev) { ev.data.on_success([ { user_id: [2,"Mitchell Admin"], name: 'sorted filter', id: 5, context: {}, sort: "[\"foo\", \"-bar\"]", domain: "[('user_id', '=', uid)]", } ]); } } }); _.each(controlPanel.exportState().filters, function (filter) { if (filter.type === 'favorite') { assert.deepEqual(filter.orderedBy, [{ name: 'foo', asc: true, }, { name: 'bar', asc: false, }], 'the filter should have the right orderedBy values'); } }); controlPanel.destroy(); }); QUnit.test('save filter', async function (assert) { assert.expect(1); var controlPanel = await createControlPanel({ model: 'partner', arch: "", data: this.data, searchMenuTypes: ['filter'], intercepts: { create_filter: function (ev) { assert.strictEqual(ev.data.filter.sort, "[\"foo\",\"bar desc\"]", 'The right format for the string "sort" should be sent to the server'); }, get_controller_query_params: function (ev) { ev.data.callback({ orderedBy: [ { name: 'foo', asc: true, }, { name: 'bar', asc: false, } ] }); } } }); controlPanel._onNewFavorite({ data: { description: 'Morbier', type: 'favorite', }, stopPropagation: function () {return;} }); controlPanel.destroy(); }); }); });