diff options
| author | Christophe Simonis <chs@odoo.com> | 2019-01-09 19:59:27 +0100 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2019-01-09 19:59:27 +0100 |
| commit | d7c5bc02cc2b27442f0d4c8aca70266762be2a32 (patch) | |
| tree | 3a675d15b539a4474be38704405b318bebecdce7 /addons/web/static/tests | |
| parent | 37b518f1749aff3d6ffb2246c32f2aa1e67d9067 (diff) | |
| parent | 8aa8548d8ab68feb13f3bde51c557db84877e809 (diff) | |
[MERGE] forward port branch saas-12.1 up to 8aa8548d8ab
Diffstat (limited to 'addons/web/static/tests')
| -rw-r--r-- | addons/web/static/tests/chrome/action_manager_tests.js | 193 | ||||
| -rw-r--r-- | addons/web/static/tests/core/py_utils_tests.js | 7 | ||||
| -rw-r--r-- | addons/web/static/tests/fields/relational_fields_tests.js | 166 | ||||
| -rw-r--r-- | addons/web/static/tests/helpers/test_utils_create.js | 1 | ||||
| -rw-r--r-- | addons/web/static/tests/helpers/test_utils_dom.js | 17 | ||||
| -rw-r--r-- | addons/web/static/tests/tools/debug_manager_tests.js | 4 | ||||
| -rw-r--r-- | addons/web/static/tests/views/calendar_tests.js | 92 | ||||
| -rw-r--r-- | addons/web/static/tests/views/control_panel_tests.js | 62 | ||||
| -rw-r--r-- | addons/web/static/tests/views/form_tests.js | 72 | ||||
| -rw-r--r-- | addons/web/static/tests/views/graph_tests.js | 33 | ||||
| -rw-r--r-- | addons/web/static/tests/views/kanban_mobile_tests.js | 6 | ||||
| -rw-r--r-- | addons/web/static/tests/views/kanban_tests.js | 63 | ||||
| -rw-r--r-- | addons/web/static/tests/views/pivot_tests.js | 161 | ||||
| -rw-r--r-- | addons/web/static/tests/views/search_filters_menu_tests.js | 140 | ||||
| -rw-r--r-- | addons/web/static/tests/views/search_view_tests.js | 34 |
15 files changed, 898 insertions, 153 deletions
diff --git a/addons/web/static/tests/chrome/action_manager_tests.js b/addons/web/static/tests/chrome/action_manager_tests.js index e1b14b4d363..990c166a419 100644 --- a/addons/web/static/tests/chrome/action_manager_tests.js +++ b/addons/web/static/tests/chrome/action_manager_tests.js @@ -735,6 +735,37 @@ QUnit.module('ActionManager', { actionManager.destroy(); }); + QUnit.test('properly load default record', function (assert) { + assert.expect(5); + + var actionManager = createActionManager({ + actions: this.actions, + archs: this.archs, + data: this.data, + mockRPC: function (route, args) { + assert.step(args.method || route); + return this._super.apply(this, arguments); + }, + }); + actionManager.loadState({ + action: 3, + id: "", // might happen with bbq and id=& in URL + model: 'partner', + view_type: 'form', + }); + + assert.containsOnce(actionManager, '.o_form_view', + "should have rendered a form view"); + + assert.verifySteps([ + '/web/action/load', + 'load_views', + 'default_get', + ]); + + actionManager.destroy(); + }); + QUnit.test('load requested view for act window actions', function (assert) { assert.expect(6); @@ -2095,6 +2126,39 @@ QUnit.module('ActionManager', { actionManager.destroy(); }); + QUnit.test('sidebar is present in list view', function (assert) { + assert.expect(5); + + var actionManager = createActionManager({ + actions: this.actions, + archs: this.archs, + data: this.data, + mockRPC: function (route, args) { + var res = this._super.apply(this, arguments); + if (args.method === 'load_views') { + assert.strictEqual(args.kwargs.options.toolbar, true, + "should ask for toolbar information"); + return res.then(function (fieldsViews) { + fieldsViews.list.toolbar = { + print: [{name: "Print that record"}], + }; + return fieldsViews; + }); + } + return res; + }, + }); + actionManager.doAction(3); + + assert.isNotVisible(actionManager.$('.o_cp_sidebar button.o_dropdown_toggler_btn:contains("Print")')); + assert.isNotVisible(actionManager.$('.o_cp_sidebar button.o_dropdown_toggler_btn:contains("Action")')); + testUtils.dom.clickFirst(actionManager.$('input.custom-control-input')); + assert.isVisible(actionManager.$('.o_cp_sidebar button.o_dropdown_toggler_btn:contains("Print")')); + assert.isVisible(actionManager.$('.o_cp_sidebar button.o_dropdown_toggler_btn:contains("Action")')); + + actionManager.destroy(); + }); + QUnit.test('can switch between views', function (assert) { assert.expect(18); @@ -2155,6 +2219,62 @@ QUnit.module('ActionManager', { actionManager.destroy(); }); + QUnit.test('orderedBy in context is not propagated when executing another action', function (assert) { + assert.expect(6); + + this.data.partner.fields.foo.sortable = true, + + this.archs['partner,false,form'] = '<header>' + + '<button name="8" string="Execute action" type="action"/>' + + '</header>'; + + var searchReadCount = 1; + var actionManager = createActionManager({ + actions: this.actions, + archs: this.archs, + data: this.data, + mockRPC: function (route, args) { + if (route === '/web/dataset/search_read') { + if (searchReadCount === 1) { + assert.strictEqual(args.model, 'partner'); + assert.notOk(args.sort); + } + if (searchReadCount === 2) { + assert.strictEqual(args.model, 'partner'); + assert.strictEqual(args.sort, "foo ASC"); + } + if (searchReadCount === 3) { + assert.strictEqual(args.model, 'pony'); + assert.notOk(args.sort); + } + searchReadCount += 1; + } + return this._super.apply(this, arguments); + }, + }); + actionManager.doAction(3); + + // Simulate the activation of a filter + var searchData = { + domains: [[["foo", "=", "yop"]]], + contexts: [{ + orderedBy: [], + }], + }; + actionManager.trigger_up('search', searchData); + + // Sort records + actionManager.$('.o_list_view th.o_column_sortable').click(); + + // get to the form view of the model, on the first record + actionManager.$('.o_data_cell:first').click(); + + // Change model by clicking on the button within the form + actionManager.$('.o_form_view button').click(); + + actionManager.destroy(); + }); + QUnit.test('breadcrumbs are updated when switching between views', function (assert) { assert.expect(10); @@ -3314,6 +3434,79 @@ QUnit.module('ActionManager', { actionManager.destroy(); }); + QUnit.test('fullscreen on action change: back to a "current" action', function (assert) { + assert.expect(3); + + this.actions[0].target = 'fullscreen'; + this.archs['partner,false,form'] = '<form>' + + '<button name="1" type="action" class="oe_stat_button" />' + + '</form>'; + + var actionManager = createActionManager({ + actions: this.actions, + archs: this.archs, + data: this.data, + intercepts: { + toggle_fullscreen: function (ev) { + var fullscreen = ev.data.fullscreen; + + switch (toggleFullscreenCalls) { + case 0: + assert.strictEqual(fullscreen, false); + break; + case 1: + assert.strictEqual(fullscreen, true); + break; + case 2: + assert.strictEqual(fullscreen, false); + break; + } + }, + }, + + }); + + var toggleFullscreenCalls = 0; + actionManager.doAction(6); + + toggleFullscreenCalls = 1; + actionManager.$('button[name=1]').click(); + + toggleFullscreenCalls = 2; + $('.breadcrumb li a:first').click(); + + actionManager.destroy(); + }); + + QUnit.test('fullscreen on action change: all "fullscreen" actions', function (assert) { + assert.expect(3); + + this.actions[5].target = 'fullscreen'; + this.archs['partner,false,form'] = '<form>' + + '<button name="1" type="action" class="oe_stat_button" />' + + '</form>'; + + var actionManager = createActionManager({ + actions: this.actions, + archs: this.archs, + data: this.data, + intercepts: { + toggle_fullscreen: function (ev) { + var fullscreen = ev.data.fullscreen; + assert.strictEqual(fullscreen, true); + }, + }, + }); + + actionManager.doAction(6); + + actionManager.$('button[name=1]').click(); + + $('.breadcrumb li a:first').click(); + + actionManager.destroy(); + }); + QUnit.module('"ir.actions.act_window_close" actions'); QUnit.test('close the currently opened dialog', function (assert) { diff --git a/addons/web/static/tests/core/py_utils_tests.js b/addons/web/static/tests/core/py_utils_tests.js index d59fd30f957..be5760fc6c7 100644 --- a/addons/web/static/tests/core/py_utils_tests.js +++ b/addons/web/static/tests/core/py_utils_tests.js @@ -1254,6 +1254,13 @@ QUnit.module('core', function () { assert.checkAST(expr); }); + QUnit.test("parse escaped quoted strings", function (assert) { + assert.expect(2); + + assert.checkAST(`'\"'`, "a string containing \""); + assert.checkAST(`'\'`, "a string containing \'"); + }); + QUnit.module('pyutils (_normalizeDomain)'); QUnit.assert.checkNormalization = function (domain, normalizedDomain) { diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index 6c3493828ad..15999ca952e 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -228,6 +228,90 @@ QUnit.module('relational_fields', { form.destroy(); }); + QUnit.test('widget many2many_checkboxes in a subview', function (assert) { + assert.expect(2); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch:'<form string="Partners">' + + '<sheet>' + + '<notebook>' + + '<page string="Turtles">' + + '<field name="turtles" mode="tree">' + + '<tree>' + + '<field name="id"/>' + + '</tree>' + + '</field>' + + '</page>' + + '</notebook>' + + '</sheet>' + + '</form>', + archs: { + 'turtle,false,form': '<form>' + + '<field name="partner_ids" widget="many2many_checkboxes"/>' + + '</form>', + }, + res_id: 1, + }); + + form.$buttons.find('.o_form_button_edit').click(); + form.$('.o_data_cell').click(); + // edit the partner_ids field by (un)checking boxes on the widget + var $firstCheckbox = $('.modal .custom-control-input').first(); + $firstCheckbox.click(); + assert.ok($firstCheckbox.prop('checked'), "the checkbox should be ticked"); + var $secondCheckbox = $('.modal .custom-control-input').eq(1); + $secondCheckbox.click(); + assert.notOk($secondCheckbox.prop('checked'), "the checkbox should be unticked"); + form.destroy(); + }); + + QUnit.test('delete a record while adding another one in a multipage', function (assert) { + // in a many2one with at least 2 pages, add a new line. Delete the line above it. + // (the onchange makes it so that the virtualID is inserted in the middle of the currentResIDs.) + // it should load the next line to display it on the page. + assert.expect(2); + + this.data.partner.records[0].turtles = [2, 3]; + this.data.partner.onchanges.turtles = function (obj) { + obj.turtles = [[5]].concat(obj.turtles); + }; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch:'<form string="Partners">' + + '<sheet>' + + '<group>' + + '<field name="turtles">' + + '<tree editable="bottom" limit="1" decoration-muted="turtle_bar == False">' + + '<field name="turtle_foo"/>' + + '<field name="turtle_bar"/>' + + '</tree>' + + '</field>' + + '</group>' + + '</sheet>' + + '</form>', + res_id: 1, + }); + + form.$buttons.find('.o_form_button_edit').click(); + // add a line (virtual record) + form.$('.o_field_x2many_list_row_add a').click(); + form.$('.o_input').val('pi').trigger('input'); + // delete the line above it + form.$('.o_list_record_remove').first().click(); + // the next line should be displayed below the newly added one + assert.strictEqual(form.$('.o_data_row').length, 2, "should have 2 records"); + assert.strictEqual(form.$('.o_data_row .o_data_cell:first-child').text(), 'pikawa', + "should display the correct records on page 1"); + + form.destroy(); + }); + QUnit.test('one2many, onchange, edition and multipage...', function (assert) { assert.expect(7); @@ -252,7 +336,7 @@ QUnit.module('relational_fields', { '</form>', res_id: 1, mockRPC: function (route, args) { - assert.step(args.method + ' ' + args.model) + assert.step(args.method + ' ' + args.model); return this._super(route, args); }, viewOptions: { @@ -362,6 +446,39 @@ QUnit.module('relational_fields', { form.destroy(); }); + QUnit.test('many2many read, field context is properly sent', function (assert) { + assert.expect(4); + + this.data.partner.fields.timmy.context = {hello: 'world'}; + this.data.partner.records[0].timmy = [12]; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '<form string="Partners">' + + '<field name="timmy" widget="many2many_tags"/>' + + '</form>', + res_id: 1, + mockRPC: function (route, args) { + if (args.method === 'read' && args.model === 'partner_type') { + assert.step(args.kwargs.context.hello); + } + return this._super.apply(this, arguments); + }, + }); + + assert.verifySteps(['world']); + + form.$buttons.find('.o_form_button_edit').click(); + var $m2mInput = form.$('.o_field_many2manytags input'); + $m2mInput.click(); + $m2mInput.autocomplete('widget').find('li:first()').click(); + assert.verifySteps(['world', 'world']); + + form.destroy(); + }); + QUnit.module('FieldStatus'); QUnit.test('static statusbar widget on many2one field', function (assert) { @@ -1323,6 +1440,53 @@ QUnit.module('relational_fields', { form.destroy(); }); + QUnit.test('widget many2many_tags in one2many with display_name', function (assert) { + assert.expect(4); + this.data.turtle.records[0].partner_ids = [2]; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '<form string="Partners">' + + '<sheet>' + + '<field name="turtles">' + + '<tree>' + + '<field name="partner_ids" widget="many2many_tags"/>' + // will use display_name + '</tree>' + + '<form>' + + '<sheet>' + + '<field name="partner_ids"/>' + + '</sheet>' + + '</form>' + + '</field>' + + '</sheet>' + + '</form>', + archs: { + 'partner,false,list': '<tree><field name="foo"/></tree>', + }, + res_id: 1, + }); + + assert.strictEqual(form.$('.o_field_one2many[name="turtles"] .o_list_view .o_field_many2manytags[name="partner_ids"]').text().replace(/\s/g, ''), + "secondrecordaaa", "the tags should be correctly rendered"); + + // open the x2m form view + form.$('.o_field_one2many[name="turtles"] .o_list_view td.o_data_cell:first').click(); + assert.strictEqual($('.modal .o_form_view .o_field_many2many[name="partner_ids"] .o_list_view .o_data_cell').text(), + "blipMy little Foo Value", "the list view should be correctly rendered with foo"); + + $('.modal button.o_form_button_cancel').click(); + assert.strictEqual(form.$('.o_field_one2many[name="turtles"] .o_list_view .o_field_many2manytags[name="partner_ids"]').text().replace(/\s/g, ''), + "secondrecordaaa", "the tags should still be correctly rendered"); + + form.$buttons.find('.o_form_button_edit').click(); + assert.strictEqual(form.$('.o_field_one2many[name="turtles"] .o_list_view .o_field_many2manytags[name="partner_ids"]').text().replace(/\s/g, ''), + "secondrecordaaa", "the tags should still be correctly rendered"); + + form.destroy(); + }); + QUnit.test('widget many2many_tags: tags title attribute', function (assert) { assert.expect(1); this.data.turtle.records[0].partner_ids = [2]; diff --git a/addons/web/static/tests/helpers/test_utils_create.js b/addons/web/static/tests/helpers/test_utils_create.js index 0adb13d466f..5a64512260e 100644 --- a/addons/web/static/tests/helpers/test_utils_create.js +++ b/addons/web/static/tests/helpers/test_utils_create.js @@ -135,6 +135,7 @@ function createAsyncView(params) { currentId: 'res_id' in params ? params.res_id : undefined, domain: params.domain || [], context: params.context || {}, + hasSidebar: false, }); // patch the View to handle the groupBy given in params, as we can't give it // in init (unlike the domain and context which can be set in the action) diff --git a/addons/web/static/tests/helpers/test_utils_dom.js b/addons/web/static/tests/helpers/test_utils_dom.js index b89f5a8eb5f..dcf9eab6e15 100644 --- a/addons/web/static/tests/helpers/test_utils_dom.js +++ b/addons/web/static/tests/helpers/test_utils_dom.js @@ -17,6 +17,10 @@ odoo.define('web.test_utils_dom', function () { * events, but it is enough to help test drag and drop operations with jqueryUI * sortable. * + * @todo: remove the withTrailingClick option when the jquery update branch is + * merged. This is not the default as of now, because handlers are triggered + * synchronously, which is not the same as the 'reality'. + * * @param {jqueryElement} $el * @param {jqueryElement} $to * @param {Object} [options] @@ -27,9 +31,13 @@ odoo.define('web.test_utils_dom', function () { * @param {boolean} [options.continueMove=false] whether to trigger the * mousedown action (will only work after another call of this function with * without this option) + * @param {boolean} [options.withTrailingClick=false] if true, this utility + * function will also trigger a click on the target after the mouseup event + * (this is actually what happens when a drag and drop operation is done) */ function dragAndDrop($el, $to, options) { - var position = (options && options.position) || 'center'; + options = options || {}; + var position = options.position || 'center'; var elementCenter = $el.offset(); var toOffset = $to.offset(); @@ -58,7 +66,7 @@ function dragAndDrop($el, $to, options) { toOffset.top += bound.top; } $el.trigger($.Event("mouseenter")); - if (!(options && options.continueMove)) { + if (!(options.continueMove)) { elementCenter.left += $el.outerWidth() / 2; elementCenter.top += $el.outerHeight() / 2; @@ -75,12 +83,15 @@ function dragAndDrop($el, $to, options) { pageY: toOffset.top })); - if (!(options && options.disableDrop)) { + if (!options.disableDrop) { $el.trigger($.Event("mouseup", { which: 1, pageX: toOffset.left, pageY: toOffset.top })); + if (options.withTrailingClick) { + $el.click(); + } } else { // It's impossible to drag another element when one is already // being dragged. So it's necessary to finish the drop when the test is diff --git a/addons/web/static/tests/tools/debug_manager_tests.js b/addons/web/static/tests/tools/debug_manager_tests.js index fde90105bfb..fb454aae0d1 100644 --- a/addons/web/static/tests/tools/debug_manager_tests.js +++ b/addons/web/static/tests/tools/debug_manager_tests.js @@ -46,6 +46,10 @@ QUnit.module('DebugManager', {}, function () { intercepts: { do_action: function (event) { assert.deepEqual(event.data.action, { + context: { + default_res_model: "test.model", + default_res_id: 5, + }, domain: [["res_model", "=", "test.model"],["res_id", "=", 5]], name: "Manage Attachments", res_model: "ir.attachment", diff --git a/addons/web/static/tests/views/calendar_tests.js b/addons/web/static/tests/views/calendar_tests.js index 3f4c6376d5b..264a00cc52a 100644 --- a/addons/web/static/tests/views/calendar_tests.js +++ b/addons/web/static/tests/views/calendar_tests.js @@ -557,6 +557,98 @@ QUnit.module('Views', { $view.remove(); }); + QUnit.test('default week start (US)', function (assert) { + // if not given any option, default week start is on Sunday + assert.expect(1); + var done = assert.async(); + + createAsyncView({ + View: CalendarView, + model: 'event', + data: this.data, + arch: + '<calendar class="o_calendar_test" '+ + 'date_start="start" '+ + 'date_stop="stop" '+ + 'mode="week">'+ + '</calendar>', + archs: archs, + + viewOptions: { + initialDate: initialDate, + }, + }).then(function (calendar) { + assert.strictEqual(calendar.$('.fc-day-header').first().text(), "Sun 12/11", + "The first day of the week should be Sunday"); + calendar.destroy(); + done(); + }); + }); + + QUnit.test('European week start', function (assert) { + // the week start depends on the locale + assert.expect(1); + var done = assert.async(); + + createAsyncView({ + View: CalendarView, + model: 'event', + data: this.data, + arch: + '<calendar class="o_calendar_test" '+ + 'date_start="start" '+ + 'date_stop="stop" '+ + 'mode="week">'+ + '</calendar>', + archs: archs, + + viewOptions: { + initialDate: initialDate, + }, + translateParameters: { + week_start: 1, + }, + }).then(function (calendar) { + assert.strictEqual(calendar.$('.fc-day-header').first().text(), "Mon 12/12", + "The first day of the week should be Monday"); + calendar.destroy(); + done(); + }); + }); + + QUnit.test('week numbering', function (assert) { + // week number depends on the week start, which depends on the locale + // the calendar library uses numbers [0 .. 6], while Odoo uses [1 .. 7] + // so if the modulo is not done, the week number is incorrect + assert.expect(1); + var done = assert.async(); + + createAsyncView({ + View: CalendarView, + model: 'event', + data: this.data, + arch: + '<calendar class="o_calendar_test" '+ + 'date_start="start" '+ + 'date_stop="stop" '+ + 'mode="week">'+ + '</calendar>', + archs: archs, + + viewOptions: { + initialDate: initialDate, + }, + translateParameters: { + week_start: 7, + }, + }).then(function (calendar) { + assert.strictEqual(calendar.$('.fc-week-number').text(), "W51", + "We should be on the 51st week"); + calendar.destroy(); + done(); + }); + }); + QUnit.test('create event with timezone in week mode with formViewDialog European locale', function (assert) { assert.expect(8); diff --git a/addons/web/static/tests/views/control_panel_tests.js b/addons/web/static/tests/views/control_panel_tests.js index 08cc1391719..ee191e4d3a9 100644 --- a/addons/web/static/tests/views/control_panel_tests.js +++ b/addons/web/static/tests/views/control_panel_tests.js @@ -120,6 +120,7 @@ QUnit.module('Views', { assert.deepEqual( controlPanelFactory.loadParams.groups, [[{ + context: {}, description: "Hello", groupNumber: 2, domain: "[]", @@ -198,6 +199,7 @@ QUnit.module('Views', { controlPanelFactory.loadParams.groups, [[ { + "context": {}, "description": "Hello One", "domain": "[]", "groupNumber": 2, @@ -205,6 +207,7 @@ QUnit.module('Views', { "type": "filter" }, { + "context": {}, "description": "Hello Two", "domain": "[('bar', '=', 3)]", "groupNumber": 2, @@ -233,6 +236,7 @@ QUnit.module('Views', { [ [ { + context: {}, description: "Hello One", domain: "[]", groupNumber: 2, @@ -242,6 +246,7 @@ QUnit.module('Views', { ], [ { + context: {}, description: "Hello Two", domain: "[('bar', '=', 3)]", groupNumber: 4, @@ -267,6 +272,7 @@ QUnit.module('Views', { [ [ { + context: {}, description: "Hello", domain: "[]", groupNumber: 2, @@ -353,5 +359,61 @@ QUnit.module('Views', { 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: "<search><filter name=\"filterA\" string=\"A\" domain=\"[]\"/></search>", + data: this.data, + searchMenuTypes: ['filter'], + }); + testUtils.dom.click(controlPanel.$('.o_filters_menu_button')); + 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, + })); + 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, + })); + + 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: "<search>" + + "<filter name=\"filterA\" string=\"A\" domain=\"[]\"/>" + + "<filter name=\"filterB\" string=\"B\" invisible=\"1\" domain=\"[]\"/>" + + "</search>", + data: this.data, + searchMenuTypes: ['filter'], + context: { + search_disable_custom_filters: true, + }, + }); + testUtils.dom.click(controlPanel.$('.o_filters_menu_button')); + assert.containsOnce(controlPanel, '.o_menu_item a:contains("A")'); + assert.containsNone(controlPanel, '.o_menu_item a:contains("B")'); + + controlPanel.destroy(); + }); }); }); diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js index a120a6a7547..e1cb3277dba 100644 --- a/addons/web/static/tests/views/form_tests.js +++ b/addons/web/static/tests/views/form_tests.js @@ -17,6 +17,7 @@ var Widget = require('web.Widget'); var _t = core._t; var createView = testUtils.createView; var createAsyncView = testUtils.createAsyncView; +var createActionManager = testUtils.createActionManager; QUnit.module('Views', { beforeEach: function () { @@ -299,7 +300,78 @@ QUnit.module('Views', { form.destroy(); }); + QUnit.test('Form and subview with _view_ref contexts', function (assert) { + assert.expect(2); + + this.data.product.fields.partner_type_ids = {string: "one2many field", type: "one2many", relation: "partner_type"}, + this.data.product.records = [{id: 1, name: 'Tromblon', partner_type_ids: [12,14]}]; + this.data.partner.records[0].product_id = 1; + + var actionManager = createActionManager({ + data: this.data, + archs: { + 'product,false,form': '<form>'+ + '<field name="name"/>'+ + '<field name="partner_type_ids" context="{\'tree_view_ref\': \'some_other_tree_view\'}"/>' + + '</form>', + 'partner_type,false,list': '<tree>'+ + '<field name="color"/>'+ + '</tree>', + 'product,false,search': '<search></search>', + }, + mockRPC: function (route, args) { + if (args.method === 'load_views') { + var context = args.kwargs.context; + if (args.model === 'product') { + assert.deepEqual(context, {tree_view_ref: 'some_tree_view'}, + 'The correct _view_ref should have been sent to the server, first time'); + } + if (args.model === 'partner_type') { + assert.deepEqual(context, {tree_view_ref: 'some_other_tree_view'}, + 'The correct _view_ref should have been sent to the server for the subview'); + } + } + return this._super.apply(this, arguments); + }, + }); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '<form>' + + '<field name="name"/>' + + '<field name="product_id" context="{\'tree_view_ref\': \'some_tree_view\'}"/>' + + '</form>', + res_id: 1, + + mockRPC: function(route, args) { + if (args.method === 'get_formview_action') { + return $.when({ + res_id: 1, + type: 'ir.actions.act_window', + target: 'current', + res_model: args.model, + context: args.kwargs.context, + 'view_type': 'form', + 'view_mode': 'form', + 'views': [[false, 'form']], + }); + } + return this._super(route, args); + }, + + interceptsPropagate: { + do_action: function (ev) { + actionManager.doAction(ev.data.action); + }, + }, + }); + form.$('.o_field_widget[name="product_id"]').click(); + form.destroy(); + actionManager.destroy(); + }); QUnit.test('invisible fields are properly hidden', function (assert) { assert.expect(4); diff --git a/addons/web/static/tests/views/graph_tests.js b/addons/web/static/tests/views/graph_tests.js index 73f2179dc8f..d651afc030c 100644 --- a/addons/web/static/tests/views/graph_tests.js +++ b/addons/web/static/tests/views/graph_tests.js @@ -785,13 +785,40 @@ QUnit.module('Views', { '</graph>', }); - assert.strictEqual(graph.$("svg.nvd3-svg:contains('Undefined')").length, 0); - assert.strictEqual(graph.$("svg.nvd3-svg:contains('March')").length, 1); + assert.strictEqual(graph.$("svg.nvd3-svg .nv-x:contains('Undefined')").length, 0); + assert.strictEqual(graph.$("svg.nvd3-svg:contains('January')").length, 1); testUtils.dom.click(graph.$buttons.find('.o_graph_button[data-mode=bar]')); - assert.strictEqual(graph.$("svg.nvd3-svg:contains('Undefined')").length, 1); + assert.strictEqual(graph.$("svg.nvd3-svg .nv-x:contains('Undefined')").length, 1); + assert.strictEqual(graph.$("svg.nvd3-svg:contains('January')").length, 1); + + graph.destroy(); + }); + + QUnit.test('Undefined should appear in bar, pie graph but not in line graph with multiple groupbys', function (assert) { + assert.expect(6); + + var graph = createView({ + View: GraphView, + model: "foo", + groupBy:['date', 'color_id'], + data: this.data, + arch: '<graph string="Partners" type="line">' + + '<field name="bar"/>' + + '</graph>', + }); + + assert.strictEqual(graph.$("svg.nvd3-svg .nv-x:contains('Undefined')").length, 0); assert.strictEqual(graph.$("svg.nvd3-svg:contains('January')").length, 1); + graph.$buttons.find('.o_graph_button[data-mode=bar]').click(); + assert.strictEqual(graph.$("svg.nvd3-svg .nv-x:contains('Undefined')").length, 1); + assert.strictEqual(graph.$("svg.nvd3-svg:contains('January')").length, 1); + + // Undefined should not appear after switching back to line chart + graph.$buttons.find('.o_graph_button[data-mode=line]').click(); + assert.strictEqual(graph.$("svg.nvd3-svg .nv-x:contains('Undefined')").length, 0); + assert.strictEqual(graph.$("svg.nvd3-svg:contains('January')").length, 1); graph.destroy(); }); }); diff --git a/addons/web/static/tests/views/kanban_mobile_tests.js b/addons/web/static/tests/views/kanban_mobile_tests.js index 98e65d1ea9c..a9eec223143 100644 --- a/addons/web/static/tests/views/kanban_mobile_tests.js +++ b/addons/web/static/tests/views/kanban_mobile_tests.js @@ -56,7 +56,7 @@ QUnit.module('Views', { QUnit.module('KanbanView Mobile'); QUnit.test('mobile grouped rendering', function (assert) { - assert.expect(9); + assert.expect(11); var kanban = createView({ View: KanbanView, @@ -75,6 +75,8 @@ QUnit.module('Views', { assert.containsN(kanban, '.o_kanban_group', 2, "should have 2 columns" ); assert.hasClass(kanban.$('.o_kanban_mobile_tab:first'),'o_current', "first tab is the active tab with class 'o_current'"); + assert.hasClass(kanban.$('.o_kanban_group:first'),'o_current', + "first column is the active column with class 'o_current'"); assert.containsN(kanban, '.o_kanban_group:first > div.o_kanban_record', 2, "there are 2 records in active tab"); assert.strictEqual(kanban.$('.o_kanban_group:nth(1) > div.o_kanban_record').length, 0, @@ -89,6 +91,8 @@ QUnit.module('Views', { kanban.$('.o_kanban_mobile_tab:nth(1)').trigger('click'); assert.hasClass(kanban.$('.o_kanban_mobile_tab:nth(1)'),'o_current', "second tab is now active with class 'o_current'"); + assert.hasClass(kanban.$('.o_kanban_group:nth(1)'),'o_current', + "second column is now active with class 'o_current'"); assert.strictEqual(kanban.$('.o_kanban_group:nth(1) > div.o_kanban_record').length, 2, "the 2 records of the second group have now been loaded"); diff --git a/addons/web/static/tests/views/kanban_tests.js b/addons/web/static/tests/views/kanban_tests.js index c398e9df09f..6702a9bee37 100644 --- a/addons/web/static/tests/views/kanban_tests.js +++ b/addons/web/static/tests/views/kanban_tests.js @@ -465,7 +465,7 @@ QUnit.module('Views', { }); QUnit.test('quick create record with quick_create_view', function (assert) { - assert.expect(17); + assert.expect(19); var kanban = createView({ View: KanbanView, @@ -497,6 +497,7 @@ QUnit.module('Views', { }, }); + assert.containsOnce(kanban, '.o_cp_controller', 'should have one control panel'); assert.containsOnce(kanban, '.o_kanban_group:first .o_kanban_record', "first column should contain one record"); @@ -508,6 +509,7 @@ QUnit.module('Views', { "should have a quick create element in the first column"); assert.strictEqual($quickCreate.find('.o_form_view.o_xxs_form_view').length, 1, "should have rendered an XXS form view"); + assert.containsOnce(kanban, '.o_cp_controller', 'should not have instantiated an extra control panel'); assert.strictEqual($quickCreate.find('input').length, 2, "should have two inputs"); assert.strictEqual($quickCreate.find('.o_field_widget').length, 3, @@ -2376,9 +2378,60 @@ QUnit.module('Views', { kanban.destroy(); }); + QUnit.test('wait x2manys batch fetches to re-render', function (assert) { + assert.expect(4); + var done = assert.async(); + + var def; + var kanban = createView({ + View: KanbanView, + model: 'partner', + data: this.data, + arch: '<kanban class="o_kanban_test">' + + '<field name="product_id"/>' + + '<templates><t t-name="kanban-box">' + + '<div>' + + '<field name="category_ids" widget="many2many_tags"/>' + + '</div>' + + '</t></templates>' + + '</kanban>', + groupBy: ['product_id'], + mockRPC: function (route, args) { + var result = this._super(route, args); + if (args.method === 'read') { + return $.when(def).then(function() { + return result; + }); + } + return result; + }, + }); + + def = $.Deferred(); + assert.containsN(kanban, '.o_tag', 2); + kanban.update({groupBy: ['state']}); + + def.resolve().then(function () { + assert.containsN(kanban, '.o_tag', 2, + 'Should display 2 tags after update'); + assert.strictEqual(kanban.$('.o_kanban_group:eq(1) .o_tag').text(), + 'gold', 'First category should be \'gold\''); + assert.strictEqual(kanban.$('.o_kanban_group:eq(2) .o_tag').text(), + 'silver', 'Second category should be \'silver\''); + kanban.destroy(); + done(); + }); + }); + QUnit.test('can drag and drop a record from one column to the next', function (assert) { assert.expect(9); + // @todo: remove this resequenceDef whenever the jquery upgrade branch + // is merged. This is currently necessary to simulate the reality: we + // need the click handlers to be executed after the end of the drag and + // drop operation, not before. + var resequenceDef = $.Deferred(); + var envIDs = [1, 3, 2, 4]; // the ids that should be in the environment during this test this.data.partner.fields.sequence = {type: 'number', string: "Sequence"}; var kanban = createView({ @@ -2388,7 +2441,7 @@ QUnit.module('Views', { arch: '<kanban class="o_kanban_test" on_create="quick_create">' + '<field name="product_id"/>' + '<templates><t t-name="kanban-box">' + - '<div><field name="foo"/>' + + '<div class="oe_kanban_global_click"><field name="foo"/>' + '<t t-if="widget.editable"><span class="thisiseditable">edit</span></t>' + '</div>' + '</t></templates>' + @@ -2397,7 +2450,7 @@ QUnit.module('Views', { mockRPC: function (route, args) { if (route === '/web/dataset/resequence') { assert.ok(true, "should call resequence"); - return $.when(true); + return resequenceDef.then(_.constant(true)); } return this._super(route, args); }, @@ -2410,13 +2463,15 @@ QUnit.module('Views', { var $record = kanban.$('.o_kanban_group:nth-child(1) .o_kanban_record:first'); var $group = kanban.$('.o_kanban_group:nth-child(2)'); envIDs = [3, 2, 4, 1]; // first record of first column moved to the bottom of second column - testUtils.dom.dragAndDrop($record, $group); + testUtils.dom.dragAndDrop($record, $group, {withTrailingClick: true}); + resequenceDef.resolve(); assert.containsOnce(kanban, '.o_kanban_group:nth-child(1) .o_kanban_record'); assert.containsN(kanban, '.o_kanban_group:nth-child(2) .o_kanban_record', 3); assert.containsN(kanban, '.thisiseditable', 4); assert.deepEqual(kanban.exportState().resIds, envIDs); + resequenceDef.resolve(); kanban.destroy(); }); diff --git a/addons/web/static/tests/views/pivot_tests.js b/addons/web/static/tests/views/pivot_tests.js index 46c28529bed..930fadbbb7b 100644 --- a/addons/web/static/tests/views/pivot_tests.js +++ b/addons/web/static/tests/views/pivot_tests.js @@ -149,6 +149,23 @@ QUnit.module('Views', { pivot.destroy(); }); + QUnit.test('pivot rendering with string attribute on non stored field', function (assert) { + assert.expect(1); + + this.data.partner.fields.fubar = {string: "Fubar", type: "integer", store:false}; + + var pivot = createView({ + View: PivotView, + model: "partner", + data: this.data, + arch: '<pivot string="Partners">' + + '<field name="fubar" string="fubar" type="measure"/>' + + '</pivot>', + }); + assert.containsOnce(pivot, '.o_pivot', 'Non stored fields can have a string attribute'); + pivot.destroy(); + }); + QUnit.test('pivot rendering with invisible attribute on field', function (assert) { assert.expect(2); // when invisible, a field should neither be an active measure, @@ -1415,7 +1432,7 @@ QUnit.module('Views', { actionManager.destroy(); }); - QUnit.test('export data in excel with comparison', function (assert) { + QUnit.test('export data in excel with comparison', function (assert) { assert.expect(10); this.data.partner.records[0].date = '2016-12-15'; @@ -1570,5 +1587,147 @@ QUnit.module('Views', { unpatchDate(); actionManager.destroy(); }); + + QUnit.module('Sort in comparison mode', { + beforeEach: function () { + this.data.partner.records[0].date = '2016-12-15'; + this.data.partner.records[1].date = '2016-12-17'; + this.data.partner.records[2].date = '2016-11-22'; + this.data.partner.records[3].date = '2016-11-03'; + + this.data.partner.fields.company_type = {string: "Company Type", type: "selection", selection: [["company", "Company"], ["individual", "individual"]], searchable: true, store: true, sortable: true}; + + this.data.partner.records[0].company_type = 'company'; + this.data.partner.records[1].company_type = 'individual'; + this.data.partner.records[2].company_type = 'company'; + this.data.partner.records[3].company_type = 'individual'; + + + this.unpatchDate = patchDate(2016, 11, 20, 1, 0, 0); + + this.actualResult = function () { + var actualResult = $('.o_pivot .o_pivot_cell_value div').map(function() { + return $( this ).text(); + }).get().join(); + return actualResult; + }; + + // create an action manager to test the interactions with the search view + this.actionManager = createActionManager({ + data: this.data, + archs: { + 'partner,false,pivot': '<pivot>' + + '<field name="date" interval="day" type="row"/>' + + '<field name="company_type" type="col"/>' + + '<field name="foo" type="measure"/>' + + '</pivot>', + 'partner,false,search': '<search></search>', + }, + debug: 1, + }); + + this.actionManager.doAction({ + res_model: 'partner', + type: 'ir.actions.act_window', + views: [[false, 'pivot']], + flags: { + pivot: { + additionalMeasures: ['product_id'], + } + } + }); + + // open time range menu + testUtils.dom.click($('.o_control_panel .o_time_range_menu_button')); + // select 'Today' as range + testUtils.fields.editInput($('.o_control_panel .o_time_range_selector'), 'this_month'); + // check checkbox 'Compare To' + testUtils.dom.click($('.o_control_panel .o_time_range_menu .o_comparison_checkbox')); + // Click on 'Apply' button + testUtils.dom.click($('.o_control_panel .o_time_range_menu .o_apply_range')); + // We are in comparison mode + }, + afterEach: function () { + this.unpatchDate(); + this.actionManager.destroy(); + }, + }, function () { + QUnit.test('when clicking on measure, sort by "This Month" (period of interest)', function (assert) { + assert.expect(1); + + // click on 'Foo' in column Total/Company + testUtils.dom.click($('.o_pivot_measure_row').eq(0)); + var results = [ + "12", "17", "-29.41%", "1", "2", "-50%", "13", "19", "-31.58%", + "12", "0", "100%", "12", "0" , "100%", + "1", "0", "100%", "1" , "0", "100%", + "0", "17", "-100%", "0", "17", "-100%", + "0", "2", "-100%", "0" , "2" , "-100%" + ]; + assert.strictEqual(this.actualResult(), results.join()); + }); + + QUnit.test( + 'click on a period of interest header sort according to the appropriate column ' + + 'first in ascending order then in descending order', + function (assert) { + assert.expect(2); + + // click on 'This Month' in column Total/Individual/Foo + testUtils.dom.click($('.o_pivot_measure_row').eq(6)); + var results = [ + "12", "17", "-29.41%", "1", "2", "-50%", "13", "19", "-31.58%", + "1", "0", "100%", "1" , "0", "100%", + "12", "0", "100%", "12", "0" , "100%", + "0", "17", "-100%", "0", "17", "-100%", + "0", "2", "-100%", "0" , "2" , "-100%" + ]; + var actualResult = $('.o_pivot .o_pivot_cell_value div').text(); + assert.strictEqual(actualResult, results.join('')); + + // click once again on 'This Month' in column Total/Individual/Foo + testUtils.dom.click($('.o_pivot_measure_row').eq(6)); + results = [ + "12", "17", "-29.41%", "1", "2", "-50%", "13", "19", "-31.58%", + "12", "0", "100%", "12", "0" , "100%", + "0", "17", "-100%", "0", "17", "-100%", + "0", "2", "-100%", "0" , "2" , "-100%", + "1", "0", "100%", "1" , "0", "100%" + ]; + assert.strictEqual(this.actualResult(), results.join()); + }); + + QUnit.test('click on a period of comparison header sort according to appropriate column', + function (assert) { + assert.expect(1); + + // click on 'Previous Period' in column Total/Individual/Foo + testUtils.dom.click($('.o_pivot_measure_row').eq(7)); + var results = [ + "12", "17", "-29.41%", "1", "2", "-50%", "13", "19", "-31.58%", + "0", "2", "-100%", "0" , "2" , "-100%", + "12", "0", "100%", "12", "0" , "100%", + "1", "0", "100%", "1" , "0", "100%", + "0", "17", "-100%", "0", "17", "-100%" + ]; + assert.strictEqual(this.actualResult(), results.join()); + }); + + QUnit.test('click on a variation header sort according to appropriate column', + function (assert) { + assert.expect(1); + + // click on 'Variation' in column Total/Individual/Foo + testUtils.dom.click($('.o_pivot_measure_row').eq(11)); + var results = [ + "12", "17", "-29.41%", "1", "2", "-50%", "13", "19", "-31.58%", + "12", "0", "100%", "12", "0" , "100%", + "1", "0", "100%", "1" , "0", "100%", + "0", "17", "-100%", "0", "17", "-100%", + "0", "2", "-100%", "0" , "2" , "-100%" + ]; + assert.strictEqual(this.actualResult(), results.join()); + }); + }); }); }); diff --git a/addons/web/static/tests/views/search_filters_menu_tests.js b/addons/web/static/tests/views/search_filters_menu_tests.js deleted file mode 100644 index e9246520f1d..00000000000 --- a/addons/web/static/tests/views/search_filters_menu_tests.js +++ /dev/null @@ -1,140 +0,0 @@ -odoo.define('web.search_filters_menu_tests', function (require) { -"use strict"; - -var FilterMenu = require('web.FilterMenu'); -var testUtils = require('web.test_utils'); - -function createFilterMenu(filters, fields, params) { - params = params || {}; - var target = params.debug ? document.body : $('#qunit-fixture'); - var menu = new FilterMenu(null, filters, fields); - testUtils.mock.addMockEnvironment(menu, params); - menu.appendTo(target); - return menu; -} - -QUnit.module('FilterMenu', { - beforeEach: function () { - this.filters = [ - { - isActive: false, - description: 'some filter', - domain: '', - groupNumber: 1, - }, - ]; - this.fields = { - boolean_field: {string: "Boolean Field", type: "boolean", default: true, searchable: true}, - date_field: {string: "A date", type: "date", searchable: true}, - char_field: {string: "Char Field", type: "char", default: "foo", searchable: true, trim: true}, - }; - }, -}, function () { - - QUnit.test('simple rendering with no filter', function (assert) { - assert.expect(4); - - var filterMenu = createFilterMenu([], this.fields); - testUtils.dom.click(filterMenu.$('span.fa-filter')); - assert.containsOnce(filterMenu, '.dropdown-divider'); - assert.ok(!filterMenu.$('.dropdown-divider').is(':visible')); - assert.containsN(filterMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text', 3, - 'should have 3 elements: a hidden divider, a add custom filter item, a apply button + add condition button'); - assert.containsOnce(filterMenu, '.o_add_custom_filter.o_closed_menu'); - filterMenu.destroy(); - }); - - QUnit.test('simple rendering with a filter', function (assert) { - assert.expect(2); - - var filterMenu = createFilterMenu(this.filters, this.fields); - assert.containsN(filterMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text', 5, - 'should have 4 elements: a hidden, separator, a filter, a separator, a add custom filter item, a apply button + add condition button'); - assert.containsOnce(filterMenu, '.o_add_custom_filter.o_closed_menu'); - filterMenu.destroy(); - }); - - QUnit.test('click on add custom filter opens the submenu', function (assert) { - assert.expect(3); - - var filterMenu = createFilterMenu([], this.fields); - // open menu dropdown - testUtils.dom.click(filterMenu.$('span.fa-filter')); - // open add custom filter submenu - testUtils.dom.click(filterMenu.$('.o_add_custom_filter')); - assert.hasClass(filterMenu.$('.o_add_custom_filter'), 'o_open_menu'); - assert.ok(filterMenu.$('.o_add_filter_menu').is(':visible')); - assert.containsN(filterMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text', 4, - 'should have 3 elements: a hidden divider, a add custom filter item, a proposition, a apply button + add condition button'); - - filterMenu.destroy(); - }); - - QUnit.test('removing last prop disable the apply button', function (assert) { - assert.expect(2); - - var filterMenu = createFilterMenu([], this.fields); - // open menu dropdown and custom filter submenu - testUtils.dom.click(filterMenu.$('span.fa-filter')); - testUtils.dom.click(filterMenu.$('.o_add_custom_filter')); - - // remove the current unique proposition - testUtils.dom.click(filterMenu.$('.o_searchview_extended_delete_prop')); - - assert.ok(filterMenu.$('.o_apply_filter').attr('disabled')); - - assert.containsN(filterMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text', 3, - 'should have 3 elements: a hidden separator, a add custom filter item, a apply button + add condition button'); - - filterMenu.destroy(); - }); - - QUnit.test('readding a proposition reenable apply button', function (assert) { - assert.expect(1); - - var filterMenu = createFilterMenu([], this.fields); - // open menu dropdown and custom filter submenu, remove existing prop - testUtils.dom.click(filterMenu.$('span.fa-filter')); - testUtils.dom.click(filterMenu.$('.o_add_custom_filter')); - testUtils.dom.click(filterMenu.$('.o_searchview_extended_delete_prop')); - // read a proposition - testUtils.dom.click(filterMenu.$('.o_add_condition')); - assert.ok(!filterMenu.$('.o_apply_filter').attr('disabled')); - - filterMenu.destroy(); - }); - - QUnit.test('adding a simple filter works', function (assert) { - assert.expect(6); - - delete this.fields.date_field; - var filterMenu = createFilterMenu([], this.fields, { - debug: true, - intercepts: { - new_filters: function (ev) { - var filter = ev.data.filters[0]; - assert.strictEqual(filter.type, 'filter'); - assert.strictEqual(filter.description, 'Boolean Field is true'); - assert.strictEqual(filter.domain, '[[\"boolean_field\",\"=\",True]]'); - filterMenu.update([{ - isActive: true, - description: '?', - domain: '?', - groupNumber: 1, - }]); - }, - }, - }); - // open menu dropdown and custom filter submenu, remove existing prop - testUtils.dom.click(filterMenu.$('span.fa-filter')); - testUtils.dom.click(filterMenu.$('.o_add_custom_filter')); - // click on apply to activate filter - testUtils.dom.click(filterMenu.$('.o_apply_filter')); - assert.hasClass(filterMenu.$('.o_add_custom_filter'), 'o_closed_menu'); - assert.containsNone(filterMenu, '.o_filter_condition'); - assert.containsOnce(filterMenu, '.dropdown-divider:visible', - 'there should be a separator between filters and add custom filter menu'); - filterMenu.destroy(); - }); -}); -}); diff --git a/addons/web/static/tests/views/search_view_tests.js b/addons/web/static/tests/views/search_view_tests.js index fa3fe817c2a..f4b0163ce07 100644 --- a/addons/web/static/tests/views/search_view_tests.js +++ b/addons/web/static/tests/views/search_view_tests.js @@ -2,6 +2,7 @@ odoo.define('web.search_view_tests', function (require) { "use strict"; var FormView = require('web.FormView'); +var ListView = require('web.ListView'); var testUtils = require('web.test_utils'); var createActionManager = testUtils.createActionManager; @@ -694,6 +695,39 @@ QUnit.module('Search View', { window.Date = RealDate; }); + QUnit.test('`context` key in <filter> is used', function (assert) { + assert.expect(3); + + this.archs['partner,4,search'] = '<search>'+ + '<filter string="AAA" name="some_filter" context="{\'coucou_1\': 1}"></filter>' + + '</search>'; + + var actionManager = createActionManager({ + actions: this.actions, + archs: this.archs, + data: this.data, + mockRPC: function (route, args) { + if (route === '/web/dataset/search_read') { + assert.step(JSON.stringify(args.context)); + } + return this._super.apply(this, arguments); + }, + }); + + actionManager.doAction(5); + + // select filter + testUtils.dom.click($('.o_search_options .fa-filter')); + testUtils.dom.click($('.o_menu_item:contains(AAA)')); + + assert.verifySteps([ + "{}", + "{\"coucou_1\":1}", + ]); + + actionManager.destroy(); + }); + QUnit.module('Favorites Menu'); QUnit.test('dynamic filters are saved dynamic', function (assert) { |
