diff options
| author | Christophe Simonis <chs@odoo.com> | 2017-08-31 12:55:41 +0200 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2017-08-31 12:55:41 +0200 |
| commit | 4879ce040797fd4a47b6b8326c3aacd365c8ab91 (patch) | |
| tree | 45479b47c5dcfba0d0ced4f05d770b0852f31263 /addons/web/static/tests | |
| parent | dae6178a0a5629ce678b20fcc9226caa44a5b0ce (diff) | |
| parent | fe77df3ba480d40b3d6b25736397bd52c684ce03 (diff) | |
[MERGE] forward port branch saas-17 up to fe77df3ba48
Diffstat (limited to 'addons/web/static/tests')
| -rw-r--r-- | addons/web/static/tests/fields/basic_fields_tests.js | 58 | ||||
| -rw-r--r-- | addons/web/static/tests/fields/relational_fields_tests.js | 128 | ||||
| -rw-r--r-- | addons/web/static/tests/helpers/test_utils.js | 15 | ||||
| -rw-r--r-- | addons/web/static/tests/views/form_tests.js | 177 | ||||
| -rw-r--r-- | addons/web/static/tests/views/graph_tests.js | 46 | ||||
| -rw-r--r-- | addons/web/static/tests/views/list_tests.js | 75 | ||||
| -rw-r--r-- | addons/web/static/tests/views/pivot_tests.js | 76 |
7 files changed, 565 insertions, 10 deletions
diff --git a/addons/web/static/tests/fields/basic_fields_tests.js b/addons/web/static/tests/fields/basic_fields_tests.js index b533f5056d2..6347ed63432 100644 --- a/addons/web/static/tests/fields/basic_fields_tests.js +++ b/addons/web/static/tests/fields/basic_fields_tests.js @@ -1259,6 +1259,8 @@ QUnit.module('basic_fields', { // Copying from a div tag with white-space:pre-wrap doesn't work in Firefox assert.strictEqual(form.$('[name="txt"]').prop("tagName").toLowerCase(), 'span', "the field contents should be surrounded by a span tag"); + + form.destroy(); }); QUnit.module('FieldBinary'); @@ -1594,6 +1596,24 @@ QUnit.module('basic_fields', { form.destroy(); }); + QUnit.test('handle widget with falsy values', function (assert) { + assert.expect(1); + + var list = createView({ + View: ListView, + model: 'partner', + data: this.data, + arch: '<tree>' + + '<field name="sequence" widget="handle"/>' + + '<field name="display_name"/>' + + '</tree>', + }); + + assert.strictEqual(list.$('.o_row_handle:visible').length, this.data.partner.records.length, + 'there should be a visible handle for each record'); + list.destroy(); + }); + QUnit.module('FieldDate'); @@ -3878,6 +3898,44 @@ QUnit.module('basic_fields', { "field selector popover should contain 'Color index' field"); form.destroy(); }); + + QUnit.test('domain field: handle false domain as []', function (assert) { + assert.expect(2); + + this.data.partner.records[0].foo = false; + this.data.partner.fields.bar.type = "char"; + this.data.partner.records[0].bar = "product"; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: + '<form>' + + '<sheet>' + + '<group>' + + '<field name="bar"/>' + + '<field name="foo" widget="domain" options="{\'model\': \'bar\'}"/>' + + '</group>' + + '</sheet>' + + '</form>', + mockRPC: function (route, args) { + if (args.method === 'search_count') { + assert.deepEqual(args.args[0], [], "should send a valid domain"); + } + return this._super.apply(this, arguments); + }, + res_id: 1, + viewOptions: { + mode: 'edit', + }, + }); + + var $warning = form.$('.o_field_widget[name=foo] .text-warning'); + assert.strictEqual($warning.length, 0, "should not display that the domain is invalid"); + + form.destroy(); + }); }); }); }); diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index 82b668a11fb..b6b463fdc32 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -998,14 +998,15 @@ QUnit.module('relational_fields', { }); QUnit.test('list in form: default_get with x2many create', function (assert) { - assert.expect(3); + assert.expect(5); + var displayName = 'brandon is the new timmy'; this.data.partner.onchanges.timmy = function (obj) { assert.deepEqual( obj.timmy, [ [6, false, []], - [0, obj.timmy[1][1], {display_name: 'brandon is the new timmy', name: 'brandon'}] + [0, obj.timmy[1][1], {display_name: displayName, name: 'brandon'}] ], "should have properly created the x2many command list"); obj.int_field = obj.timmy.length; @@ -1029,6 +1030,15 @@ QUnit.module('relational_fields', { if (args.method === 'default_get') { return $.when({timmy: [[0, 0, {display_name: 'brandon is the new timmy', name: 'brandon'}]]}); } + if (args.method === 'create') { + assert.deepEqual(args.args[0], { + int_field: 2, + timmy: [ + [6, false, []], + [0, false, {display_name: displayName, name: 'brandon'}], + ], + }, "should send the correct values to create"); + } return this._super.apply(this, arguments); }, }); @@ -1038,6 +1048,12 @@ QUnit.module('relational_fields', { assert.strictEqual($('input.o_field_integer').val(), '2', "should have called and executed the onchange properly"); + // edit the subrecord and save + displayName = 'new value'; + form.$('.o_data_cell').click(); + form.$('.o_data_cell input').val(displayName).trigger('input'); + form.$buttons.find('.o_form_button_save').click(); + form.destroy(); }); @@ -2521,6 +2537,7 @@ QUnit.module('relational_fields', { arch:'<form string="Partners">' + '<field name="p">' + '<kanban create="0">' + + '<field name="display_name"/>' + '<templates>' + '<t t-name="kanban-box">' + '<div class="oe_kanban_global_click">' + @@ -3499,7 +3516,7 @@ QUnit.module('relational_fields', { rpcCount++; if (args.method === 'write') { assert.deepEqual(args.args[1].p, [[0, args.args[1].p[0][1], { - display_name: false, int_field: 123, product_id: 41 + int_field: 123, product_id: 41 }]]); } return this._super(route, args); @@ -3736,7 +3753,7 @@ QUnit.module('relational_fields', { if (args.method === 'default_get') { var expected = counter === 0 ? [[4, 2, false]] : - [[4, 2, false], [0, args.kwargs.context.turtles[1][1], {display_name: false, turtle_foo: 'hammer'}]]; + [[4, 2, false], [0, args.kwargs.context.turtles[1][1], {turtle_foo: 'hammer'}]]; assert.deepEqual(args.kwargs.context.turtles, expected, "should have properly evaluated turtles key in context"); counter++; @@ -5483,6 +5500,43 @@ QUnit.module('relational_fields', { form.destroy(); }); + QUnit.test('onchange and required fields with override in arch', function (assert) { + assert.expect(4); + + this.data.partner.onchanges = { + turtles: function (obj) {} + }; + this.data.turtle.fields.turtle_foo.required = true; + this.data.partner.records[0].turtles = []; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch:'<form string="Partners">' + + '<field name="turtles">' + + '<tree editable="bottom">' + + '<field name="turtle_int"/>' + + '<field name="turtle_foo" required="0"/>' + + '</tree>' + + '</field>' + + '</form>', + res_id: 1, + mockRPC: function (route, args) { + assert.step(args.method); + return this._super.apply(this, arguments); + }, + }); + form.$buttons.find('.o_form_button_edit').click(); + + // triggers an onchange on partner, because the new record is valid + form.$('.o_field_x2many_list_row_add a').click(); + + assert.verifySteps(['read', 'default_get', 'onchange']); + form.destroy(); + }); + + QUnit.module('FieldMany2Many'); @@ -5638,6 +5692,7 @@ QUnit.module('relational_fields', { arch:'<form string="Partners">' + '<field name="timmy">' + '<kanban create="0">' + + '<field name="display_name"/>' + '<templates>' + '<t t-name="kanban-box">' + '<div class="oe_kanban_global_click">' + @@ -6977,6 +7032,71 @@ QUnit.module('relational_fields', { list.destroy(); }); + QUnit.test('search more in many2one: group and use the pager', function (assert) { + assert.expect(2); + + this.data.partner.records.push({ + id: 5, + display_name: "Partner 4", + }, { + id: 6, + display_name: "Partner 5", + }, { + id: 7, + display_name: "Partner 6", + }, { + id: 8, + display_name: "Partner 7", + }, { + id: 9, + display_name: "Partner 8", + }, { + id: 10, + display_name: "Partner 9", + }); + + this.data.partner.fields.datetime.searchable = true; + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '<form string="Partners">' + + '<sheet>' + + '<group>' + + '<field name="trululu"/>' + + '</group>' + + '</sheet>' + + '</form>', + + res_id: 1, + archs: { + 'partner,false,list': '<tree limit="7"><field name="display_name"/></tree>', + 'partner,false,search': '<search><group>' + + ' <filter name="bar" string="Bar" context="{\'group_by\': \'bar\'}"/>' + + '</group></search>', + }, + viewOptions: { + mode: 'edit', + }, + }); + + var $dropdown = form.$('.o_field_many2one input').autocomplete('widget'); + form.$('.o_field_many2one input').click(); + $dropdown.find('.o_m2o_dropdown_option:contains(Search)').mouseenter().click(); // Open Search More + + $('.modal .o_searchview_more').click(); // Magnifying class for more filters + $('.modal .o_search_options .o_group_by_menu a:contains(Bar)').click(); // group by 'Bar' + + $('.modal .o_group_header:first').click(); + assert.strictEqual($('.modal tbody:nth(1) .o_data_row').length, 7, + "should display 7 records in the first page"); + $('.modal .o_group_header:first .o_pager_next').click(); + assert.strictEqual($('.modal tbody:nth(1) .o_data_row').length, 1, + "should display 1 record in the second page"); + + form.destroy(); + }); + QUnit.test('field many2many_tags keeps focus when being edited', function (assert) { assert.expect(7); diff --git a/addons/web/static/tests/helpers/test_utils.js b/addons/web/static/tests/helpers/test_utils.js index fdc70507a12..65cbc16fda0 100644 --- a/addons/web/static/tests/helpers/test_utils.js +++ b/addons/web/static/tests/helpers/test_utils.js @@ -470,6 +470,20 @@ function triggerPositionalMouseEvent(x, y, type){ } /** + * simulate a keypress event for a given character + * @param {string} the character + */ +function triggerKeypressEvent(char) { + var keycode; + if (char === "Enter") { + keycode = $.ui.keyCode.ENTER; + } else { + keycode = char.charCodeAt(0); + } + return $('body').trigger($.Event('keypress', {which: keycode, keyCode: keycode})); +} + +/** * Removes the src attribute on images and iframes to prevent not found errors, * and optionally triggers an rpc with the src url as route on a widget. * @@ -518,6 +532,7 @@ return $.when( dragAndDrop: dragAndDrop, triggerMouseEvent: triggerMouseEvent, triggerPositionalMouseEvent: triggerPositionalMouseEvent, + triggerKeypressEvent: triggerKeypressEvent, removeSrcAttribute: removeSrcAttribute, }; }); diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js index dcb422b00ca..f87eea2d154 100644 --- a/addons/web/static/tests/views/form_tests.js +++ b/addons/web/static/tests/views/form_tests.js @@ -1136,7 +1136,7 @@ QUnit.module('Views', { mockRPC: function (route, args) { if (args.method === "onchange") { assert.deepEqual(args.args[3], - {"foo": "1", "p": "", "p.bar": "", "p.display_name": "", "p.product_id": "", "timmy": "", "timmy.name": ""}, + {"foo": "1", "p": "", "p.bar": "", "p.product_id": "", "timmy": "", "timmy.name": ""}, "should send only the fields used in the views"); } return this._super(route, args); @@ -1284,7 +1284,6 @@ QUnit.module('Views', { if (args.method === 'onchange') { assert.deepEqual(args.args[3], { p: '', - 'p.display_name': '', 'p.foo': '1' }, "onchangeSpec should be correct (with sub fields)"); } @@ -2678,7 +2677,7 @@ QUnit.module('Views', { form.destroy(); }); - QUnit.test('button box is not rendered in create mode', function (assert) { + QUnit.test('button box is rendered in create mode', function (assert) { assert.expect(3); var form = createView({ @@ -2708,8 +2707,8 @@ QUnit.module('Views', { // create mode (leave edition first!) form.$buttons.find('.o_form_button_cancel').click(); form.$buttons.find('.o_form_button_create').click(); - assert.strictEqual(form.$('.oe_stat_button').length, 0, - "button box should not be displayed when creating a new record"); + assert.strictEqual(form.$('.oe_stat_button').length, 1, + "button box should be displayed when creating a new record as well"); form.destroy(); }); @@ -2863,6 +2862,92 @@ QUnit.module('Views', { form.destroy(); }); + QUnit.test('display_name not sent for onchanges if not in view', function (assert) { + assert.expect(7); + + this.data.partner.records[0].timmy = [12]; + this.data.partner.onchanges = { + foo: function () {}, + }; + this.data.partner_type.onchanges = { + name: function () {}, + }; + var readInModal = false; + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '<form string="Partners">' + + '<group>' + + '<field name="foo"/>' + + '<field name="timmy">' + + '<tree>' + + '<field name="name"/>' + + '</tree>' + + '<form>' + + '<field name="name"/>' + + '<field name="color"/>' + + '</form>' + + '</field>' + + '</group>' + + '</form>', + mockRPC: function (route, args) { + if (args.method === 'read' && args.model === 'partner') { + assert.deepEqual(args.args[1], ['foo', 'timmy', 'display_name'], + "should read display_name even if not in the view"); + } + if (args.method === 'read' && args.model === 'partner_type') { + if (!readInModal) { + assert.deepEqual(args.args[1], ['name'], + "should not read display_name for records in the list"); + } else { + assert.deepEqual(args.args[1], ['name', 'color', 'display_name'], + "should read display_name when opening the subrecord"); + } + } + if (args.method === 'onchange' && args.model === 'partner') { + assert.deepEqual(args.args[1], { + id: 1, + foo: 'coucou', + timmy: [[6, false, [12]]], + }, "should only send the value of fields in the view (+ id)"); + assert.deepEqual(args.args[3], { + foo: '1', + timmy: '', + 'timmy.name': '1', + 'timmy.color': '', + }, "only the fields in the view should be in the onchange spec"); + } + if (args.method === 'onchange' && args.model === 'partner_type') { + assert.deepEqual(args.args[1], { + id: 12, + name: 'new name', + color: 2, + }, "should only send the value of fields in the view (+ id)"); + assert.deepEqual(args.args[3], { + name: '1', + color: '', + }, "only the fields in the view should be in the onchange spec"); + } + return this._super.apply(this, arguments); + }, + res_id: 1, + viewOptions: { + mode: 'edit', + }, + }); + + // trigger the onchange + form.$('.o_field_widget[name=foo]').val("coucou").trigger('input'); + + // open a subrecord and trigger an onchange + readInModal = true; + form.$('.o_data_row .o_data_cell:first').click(); + $('.modal .o_field_widget[name=name]').val("new name").trigger('input'); + + form.destroy(); + }); + QUnit.test('onchanges on date(time) fields', function (assert) { assert.expect(6); @@ -3761,7 +3846,6 @@ QUnit.module('Views', { if (args.method === 'create') { var command = args.args[0].p; assert.deepEqual(command, [[0, command[0][1], { - display_name: false, timmy: [[6, false, [12]]], }]], "the default partner_type_id should be equal to 12"); } @@ -4233,6 +4317,32 @@ QUnit.module('Views', { form.destroy(); }); + QUnit.test('no autofocus with disable_autofocus option [REQUIRE FOCUS]', function (assert) { + assert.expect(2); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '<form string="Partners">' + + '<field name="int_field"/>' + + '<field name="foo"/>' + + '</form>', + viewOptions: { + disable_autofocus: true, + }, + }); + assert.notStrictEqual(document.activeElement, form.$('input[name="int_field"]')[0], + "int_field field should not have focus"); + + form.update({}); + + assert.notStrictEqual(document.activeElement, form.$('input[name="int_field"]')[0], + "int_field field should not have focus"); + + form.destroy(); + }); + QUnit.test('open one2many form containing many2many_tags', function (assert) { assert.expect(4); @@ -5625,6 +5735,61 @@ QUnit.module('Views', { form.destroy(); }); + QUnit.test('reload event is handled only once', function (assert) { + // In this test, several form controllers are nested (two of them are + // opened in dialogs). When the users clicks on save in the last + // opened dialog, a 'reload' event is triggered up to reload the (direct) + // parent view. If this event isn't stopPropagated by the first controller + // catching it, it will crash when the other one will try to handle it, + // as this one doesn't know at all the dataPointID to reload. + assert.expect(9); + + var arch = '<form>' + + '<field name="display_name"/>' + + '<field name="trululu"/>' + + '</form>'; + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: arch, + archs: { + 'partner,false,form': arch, + }, + res_id: 2, + mockRPC: function (route, args) { + assert.step(args.method); + if (args.method === 'get_formview_id') { + return $.when(false); + } + return this._super.apply(this, arguments); + }, + viewOptions: { + mode: 'edit', + }, + }); + + form.$('.o_external_button').click(); // open the many2one record in a modal + $('.modal .o_external_button').click(); // in the modal, open the many2one record in another modal + + $('.modal:nth(1) .o_field_widget[name=display_name]').val('new name').trigger('input'); + $('.modal:nth(1) .modal-footer .btn-primary').first().click(); // save changes + + assert.strictEqual($('.modal .o_field_widget[name=trululu] input').val(), 'new name', + "record should have been reloaded"); + assert.verifySteps([ + "read", // main record + "get_formview_id", // id of first form view opened in a dialog + "read", // first dialog + "get_formview_id", // id of second form view opened in a dialog + "read", // second dialog + "write", // save second dialog + "read", // reload first dialog + ]); + + form.destroy(); + }); + QUnit.test('rainbowman attributes correctly passed on button click', function (assert) { assert.expect(1); diff --git a/addons/web/static/tests/views/graph_tests.js b/addons/web/static/tests/views/graph_tests.js index c7d69b194ff..07f7d060347 100644 --- a/addons/web/static/tests/views/graph_tests.js +++ b/addons/web/static/tests/views/graph_tests.js @@ -372,6 +372,52 @@ QUnit.module('Views', { }); }); + QUnit.test('correctly uses graph_ keys from the context (at reload)', function (assert) { + var done = assert.async(); + assert.expect(8); + + var graph = createView({ + View: GraphView, + model: "foo", + data: this.data, + arch: '<graph><field name="product_id"/></graph>', + }); + + assert.strictEqual(graph.renderer.state.mode, "bar", "should be in bar chart mode"); + assert.ok(graph.$buttons.find('button[data-mode="bar"]').hasClass('active'), + 'bar chart button should be active'); + + var reloadParams = { + context: { + graph_measure: 'foo', + graph_mode: 'line', + graph_groupbys: ['color_id'], + }, + }; + graph.reload(reloadParams); + return concurrency.delay(0).then(function () { + // check measure + assert.strictEqual(graph.$('text.nv-legend-text:contains(Foo)').length, 1, + "should now use the 'foo' measure"); + + // check mode + assert.strictEqual(graph.renderer.state.mode, "line", "should be in line chart mode"); + assert.notOk(graph.$buttons.find('button[data-mode="bar"]').hasClass('active'), + 'bar chart button should not be active'); + assert.ok(graph.$buttons.find('button[data-mode="line"]').hasClass('active'), + 'line chart button should be active'); + + // check groupbys + assert.strictEqual(graph.$('text:contains(xphone)').length, 0, + "should not contain a text element with product in legend"); + assert.strictEqual(graph.$('text:contains(red)').length, 1, + "should contain a text element with color in legend"); + + graph.destroy(); + done(); + }); + }); + QUnit.test('reload graph with correct fields', function (assert) { assert.expect(2); diff --git a/addons/web/static/tests/views/list_tests.js b/addons/web/static/tests/views/list_tests.js index 4b33af9f0a6..2ac373dbcd0 100644 --- a/addons/web/static/tests/views/list_tests.js +++ b/addons/web/static/tests/views/list_tests.js @@ -19,6 +19,7 @@ QUnit.module('Views', { int_field: {string: "int_field", type: "integer", sortable: true}, qux: {string: "my float", type: "float"}, m2o: {string: "M2O field", type: "many2one", relation: "bar"}, + o2m: {string: "O2M field", type: "one2many", relation: "bar"}, m2m: {string: "M2M field", type: "many2many", relation: "bar"}, amount: {string: "Monetary field", type: "monetary"}, currency_id: {string: "Currency", type: "many2one", @@ -1994,6 +1995,80 @@ QUnit.module('Views', { list.destroy(); }); + QUnit.test('navigation with tab on a list with create="0"', function (assert) { + assert.expect(4); + + var list = createView({ + View: ListView, + model: 'foo', + data: this.data, + arch: '<tree editable="bottom" create="0">' + + '<field name="display_name"/>' + + '</tree>', + }); + + assert.strictEqual(list.$('.o_data_row').length, 4, + "the list should contain 4 rows"); + + list.$('.o_data_row:nth(2) .o_data_cell:first').click(); + assert.ok(list.$('.o_data_row:nth(2)').hasClass('o_selected_row'), + "third row should be in edition"); + + // Press 'Tab' -> should go to next line + list.$('.o_selected_row input').trigger({type: 'keydown', which: 9}); + assert.ok(list.$('.o_data_row:nth(3)').hasClass('o_selected_row'), + "fourth row should be in edition"); + + // Press 'Tab' -> should go back to first line as the create action isn't available + list.$('.o_selected_row input').trigger({type: 'keydown', which: 9}); + assert.ok(list.$('.o_data_row:first').hasClass('o_selected_row'), + "first row should be in edition"); + + list.destroy(); + }); + + + QUnit.test('navigation with tab on a one2many list with create="0"', function (assert) { + assert.expect(4); + + this.data.foo.records[0].o2m = [1, 2]; + var form = createView({ + View: FormView, + model: 'foo', + data: this.data, + arch: '<form><sheet>' + + '<field name="o2m">' + + '<tree editable="bottom" create="0">' + + '<field name="display_name"/>' + + '</tree>' + + '</field>' + + '</sheet></form>', + res_id: 1, + viewOptions: { + mode: 'edit', + }, + }); + + assert.strictEqual(form.$('.o_field_widget[name=o2m] .o_data_row').length, 2, + "there should be two records in the many2many"); + + form.$('.o_field_widget[name=o2m] .o_data_cell:first').click(); + assert.ok(form.$('.o_field_widget[name=o2m] .o_data_row:first').hasClass('o_selected_row'), + "first row should be in edition"); + + // Press 'Tab' -> should go to next line + form.$('.o_field_widget[name=o2m] .o_selected_row input').trigger({type: 'keydown', which: 9}); + assert.ok(form.$('.o_field_widget[name=o2m] .o_data_row:nth(1)').hasClass('o_selected_row'), + "second row should be in edition"); + + // Press 'Tab' -> should go back to first line as the create action isn't available + form.$('.o_field_widget[name=o2m] .o_selected_row input').trigger({type: 'keydown', which: 9}); + assert.ok(form.$('.o_field_widget[name=o2m] .o_data_row:first').hasClass('o_selected_row'), + "first row should be in edition"); + + form.destroy(); + }); + QUnit.test('edition, then navigation with tab (with a readonly field)', function (assert) { // This test makes sure that if we have 2 cells in a row, the first in // edit mode, and the second one readonly, then if we edit and press TAB, diff --git a/addons/web/static/tests/views/pivot_tests.js b/addons/web/static/tests/views/pivot_tests.js index 267437845b0..fe8c4c5b3f9 100644 --- a/addons/web/static/tests/views/pivot_tests.js +++ b/addons/web/static/tests/views/pivot_tests.js @@ -825,6 +825,53 @@ QUnit.module('Views', { pivot.destroy(); }); + QUnit.test('correctly uses pivot_ keys from the context (at reload)', function (assert) { + assert.expect(8); + + this.data.partner.fields.amount = {string: "Amount", type: "float"}; + + var pivot = createView({ + View: PivotView, + model: "partner", + data: this.data, + arch: '<pivot>' + + '<field name="date" interval="day" type="col"/>' + + '<field name="amount" type="measure"/>' + + '</pivot>', + }); + + assert.strictEqual(pivot.$('tbody tr:first td.o_pivot_cell_value:last').text(), '0.00', + "the active measure should be amount"); + + var reloadParams = { + context: { + pivot_measures: ['foo'], + pivot_column_groupby: ['customer'], + pivot_row_groupby: ['product_id'], + }, + }; + pivot.reload(reloadParams); + + assert.strictEqual(pivot.$('thead .o_pivot_header_cell_opened').length, 1, + "column: should have one opened header"); + assert.strictEqual(pivot.$('thead .o_pivot_header_cell_closed:contains(First)').length, 1, + "column: should display one closed header with 'First'"); + assert.strictEqual(pivot.$('thead .o_pivot_header_cell_closed:contains(Second)').length, 1, + "column: should display one closed header with 'Second'"); + + assert.strictEqual(pivot.$('tbody .o_pivot_header_cell_opened').length, 1, + "row: should have one opened header"); + assert.strictEqual(pivot.$('tbody .o_pivot_header_cell_closed:contains(xphone)').length, 1, + "row: should display one closed header with 'xphone'"); + assert.strictEqual(pivot.$('tbody .o_pivot_header_cell_closed:contains(xpad)').length, 1, + "row: should display one closed header with 'xpad'"); + + assert.strictEqual(pivot.$('tbody tr:first td:nth(3)').text(), '32', + "selected measure should be foo, with total 32"); + + pivot.destroy(); + }); + QUnit.test('correctly use group_by key from the context', function (assert) { assert.expect(7); @@ -859,4 +906,33 @@ QUnit.module('Views', { pivot.destroy(); }); + QUnit.test('pivot still handles __count__ measure', function (assert) { + // for retro-compatibility reasons, the pivot view still handles + // '__count__' measure. + assert.expect(2); + + var pivot = createView({ + View: PivotView, + model: "partner", + data: this.data, + arch: '<pivot></pivot>', + mockRPC: function (route, args) { + if (args.method === 'read_group') { + assert.deepEqual(args.kwargs.fields, ['__count'], + "should make a read_group with field __count"); + } + return this._super(route, args); + }, + viewOptions: { + context: { + pivot_measures: ['__count__'], + }, + }, + }); + + var $countMeasure = pivot.$buttons.find('li[data-field=__count]'); + assert.ok($countMeasure.hasClass('selected'), "The count measure should be activated"); + + pivot.destroy(); + }); });}); |
