diff options
| author | Aaron Bohy <aab@odoo.com> | 2020-03-27 10:25:00 +0000 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2020-03-30 09:55:08 +0000 |
| commit | 7af5fb31ec7a3ef4bfce1756aa01824cba30e592 (patch) | |
| tree | 4aa270929c2b7bd48d7cd11865cfaadb18af1958 /addons/web/static/tests | |
| parent | 9be9a75e67ac0727e2d5a0f7584f350f4ee638fb (diff) | |
[IMP] web: selection in list views
This commit allows the user to apply actions to all records
matching the current domain in list views. It also ensures that
the user is aware of the set of records actually selected.
The number of selected records is now displayed in the control
panel, and the user can, with an additional click, select all
records matching the current domain instead of the ones of the
current page.
Task 2185145
Diffstat (limited to 'addons/web/static/tests')
| -rw-r--r-- | addons/web/static/tests/components/action_menus_tests.js | 2 | ||||
| -rw-r--r-- | addons/web/static/tests/helpers/mock_server.js | 17 | ||||
| -rw-r--r-- | addons/web/static/tests/views/list_tests.js | 160 |
3 files changed, 169 insertions, 10 deletions
diff --git a/addons/web/static/tests/components/action_menus_tests.js b/addons/web/static/tests/components/action_menus_tests.js index f4229b30493..e17ae95ba78 100644 --- a/addons/web/static/tests/components/action_menus_tests.js +++ b/addons/web/static/tests/components/action_menus_tests.js @@ -105,7 +105,6 @@ odoo.define('web.action_menus_tests', function (require) { active_id: 23, active_ids: [23], active_model: 'hobbit', - select_all: false, // default props }; assert.deepEqual(args.context, expectedContext); assert.step('load-action'); @@ -178,7 +177,6 @@ odoo.define('web.action_menus_tests', function (require) { active_id: 23, active_ids: [23], active_model: 'hobbit', - select_all: false, // default props }; assert.deepEqual(args.context, expectedContext); assert.step('load-action'); diff --git a/addons/web/static/tests/helpers/mock_server.js b/addons/web/static/tests/helpers/mock_server.js index a59a925306f..d59cafacd28 100644 --- a/addons/web/static/tests/helpers/mock_server.js +++ b/addons/web/static/tests/helpers/mock_server.js @@ -1094,6 +1094,20 @@ var MockServer = Class.extend({ return true; }, /** + * Simulate a 'search' operation + * + * @private + * @param {string} model + * @param {Array} args + * @param {Object} kwargs + * @param {integer} [kwargs.limit] + * @returns {integer[]} + */ + _mockSearch: function (model, args, kwargs) { + const limit = kwargs.limit || Number.MAX_VALUE; + return this._getRecords(model, args[0]).map(r => r.id).slice(0, limit); + }, + /** * Simulate a 'search_count' operation * * @private @@ -1340,6 +1354,9 @@ var MockServer = Class.extend({ case 'read_progress_bar': return Promise.resolve(this._mockReadProgressBar(args.model, args.kwargs)); + case 'search': + return Promise.resolve(this._mockSearch(args.model, args.args, args.kwargs)); + case 'search_count': return Promise.resolve(this._mockSearchCount(args.model, args.args)); diff --git a/addons/web/static/tests/views/list_tests.js b/addons/web/static/tests/views/list_tests.js index 852c74d922b..cf0736f86f1 100644 --- a/addons/web/static/tests/views/list_tests.js +++ b/addons/web/static/tests/views/list_tests.js @@ -1251,8 +1251,76 @@ QUnit.module('Views', { list.destroy(); }); + QUnit.test('selection box is properly displayed (single page)', async function (assert) { + assert.expect(11); + + var list = await createView({ + View: ListView, + model: 'foo', + data: this.data, + arch: '<tree><field name="foo"/><field name="bar"/></tree>', + }); + + assert.containsN(list, '.o_data_row', 4); + assert.containsNone(list.$('.o_cp_buttons'), '.o_list_selection_box'); + + // select a record + await testUtils.dom.click(list.$('.o_data_row:first .o_list_record_selector input')); + assert.containsOnce(list.$('.o_cp_buttons'), '.o_list_selection_box'); + assert.containsNone(list.$('.o_list_selection_box'), '.o_list_select_domain'); + assert.strictEqual(list.$('.o_list_selection_box').text().trim(), '1 selected'); + + // select all records of first page + await testUtils.dom.click(list.$('thead .o_list_record_selector input')); + assert.containsOnce(list.$('.o_cp_buttons'), '.o_list_selection_box'); + assert.containsNone(list.$('.o_list_selection_box'), '.o_list_select_domain'); + assert.strictEqual(list.$('.o_list_selection_box').text().trim(), '4 selected'); + + // unselect a record + await testUtils.dom.click(list.$('.o_data_row:nth(1) .o_list_record_selector input')); + assert.containsOnce(list.$('.o_cp_buttons'), '.o_list_selection_box'); + assert.containsNone(list.$('.o_list_selection_box'), '.o_list_select_domain'); + assert.strictEqual(list.$('.o_list_selection_box').text().trim(), '3 selected'); + + list.destroy(); + }); + + QUnit.test('selection box is properly displayed (multi pages)', async function (assert) { + assert.expect(10); + + var list = await createView({ + View: ListView, + model: 'foo', + data: this.data, + arch: '<tree limit="3"><field name="foo"/><field name="bar"/></tree>', + }); + + assert.containsN(list, '.o_data_row', 3); + assert.containsNone(list.$('.o_cp_buttons'), '.o_list_selection_box'); + + // select a record + await testUtils.dom.click(list.$('.o_data_row:first .o_list_record_selector input')); + assert.containsOnce(list.$('.o_cp_buttons'), '.o_list_selection_box'); + assert.containsNone(list.$('.o_list_selection_box'), '.o_list_select_domain'); + assert.strictEqual(list.$('.o_list_selection_box').text().trim(), '1 selected'); + + // select all records of first page + await testUtils.dom.click(list.$('thead .o_list_record_selector input')); + assert.containsOnce(list.$('.o_cp_buttons'), '.o_list_selection_box'); + assert.containsOnce(list.$('.o_list_selection_box'), '.o_list_select_domain'); + assert.strictEqual(list.$('.o_list_selection_box').text().replace(/\s+/g, ' ').trim(), + '3 selected Select all 4'); + + // select all domain + await testUtils.dom.click(list.$('.o_list_selection_box .o_list_select_domain')); + assert.containsOnce(list.$('.o_cp_buttons'), '.o_list_selection_box'); + assert.strictEqual(list.$('.o_list_selection_box').text().trim(), 'All 4 selected'); + + list.destroy(); + }); + QUnit.test('selection is reset on reload', async function (assert) { - assert.expect(5); + assert.expect(8); var list = await createView({ View: ListView, @@ -1264,6 +1332,7 @@ QUnit.module('Views', { '</tree>', }); + assert.containsNone(list.$('.o_cp_buttons'), '.o_list_selection_box'); assert.strictEqual(list.$('tfoot td:nth(2)').text(), '32', "total should be 32 (no record selected)"); @@ -1271,6 +1340,7 @@ QUnit.module('Views', { var $firstRowSelector = list.$('tbody .o_list_record_selector input').first(); testUtils.dom.click($firstRowSelector); assert.ok($firstRowSelector.is(':checked'), "first row should be selected"); + assert.containsOnce(list.$('.o_cp_buttons'), '.o_list_selection_box'); assert.strictEqual(list.$('tfoot td:nth(2)').text(), '10', "total should be 10 (first record selected)"); @@ -1279,6 +1349,7 @@ QUnit.module('Views', { $firstRowSelector = list.$('tbody .o_list_record_selector input').first(); assert.notOk($firstRowSelector.is(':checked'), "first row should no longer be selected"); + assert.containsNone(list.$('.o_cp_buttons'), '.o_list_selection_box'); assert.strictEqual(list.$('tfoot td:nth(2)').text(), '32', "total should be 32 (no more record selected)"); @@ -1286,7 +1357,7 @@ QUnit.module('Views', { }); QUnit.test('selection is kept on render without reload', async function (assert) { - assert.expect(6); + assert.expect(10); var list = await createView({ View: ListView, @@ -1301,17 +1372,20 @@ QUnit.module('Views', { }); assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus'); + assert.containsNone(list.$('.o_cp_buttons'), '.o_list_selection_box'); // open blip grouping and check all lines await testUtils.dom.click(list.$('.o_group_header:contains("blip (2)")')); await testUtils.dom.click(list.$('.o_data_row:first input')); assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus'); + assert.containsOnce(list.$('.o_cp_buttons'), '.o_list_selection_box'); // open yop grouping and verify blip are still checked await testUtils.dom.click(list.$('.o_group_header:contains("yop (1)")')); assert.containsOnce(list, '.o_data_row input:checked', "opening a grouping does not uncheck others"); assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus'); + assert.containsOnce(list.$('.o_cp_buttons'), '.o_list_selection_box'); // close and open blip grouping and verify blip are unchecked await testUtils.dom.click(list.$('.o_group_header:contains("blip (2)")')); @@ -1319,6 +1393,7 @@ QUnit.module('Views', { assert.containsNone(list, '.o_data_row input:checked', "opening and closing a grouping uncheck its elements"); assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus'); + assert.containsNone(list.$('.o_cp_buttons'), '.o_list_selection_box'); list.destroy(); }); @@ -2865,7 +2940,7 @@ QUnit.module('Views', { list.destroy(); }); - QUnit.test('list without import button', async function (assert) { + QUnit.test('list with group_by_no_leaf flag in context', async function (assert) { assert.expect(1); var list = await createView({ @@ -2878,7 +2953,7 @@ QUnit.module('Views', { } }); - assert.ok(!list.$buttons, "should not have any buttons"); + assert.containsNone(list, '.o_list_buttons', "should not have any buttons"); list.destroy(); }); @@ -4260,7 +4335,7 @@ QUnit.module('Views', { list.destroy(); }); - QUnit.test('execute ActionMenus actions with correct params', async function (assert) { + QUnit.test('execute ActionMenus actions with correct params (single page)', async function (assert) { assert.expect(12); const list = await createView({ @@ -4320,9 +4395,78 @@ QUnit.module('Views', { await cpHelpers.toggleMenuItem(list, "Custom Action"); assert.verifySteps([ - '{"action_id":44,"context":{"active_id":1,"active_ids":[1,2,3,4],"active_model":"foo","select_all":true,"active_domain":[]}}', - '{"action_id":44,"context":{"active_id":2,"active_ids":[2,3,4],"active_model":"foo","select_all":false,"active_domain":[]}}', - '{"action_id":44,"context":{"active_id":1,"active_ids":[1,2],"active_model":"foo","select_all":false,"active_domain":[["bar","=",true]]}}', + '{"action_id":44,"context":{"active_id":1,"active_ids":[1,2,3,4],"active_model":"foo","active_domain":[]}}', + '{"action_id":44,"context":{"active_id":2,"active_ids":[2,3,4],"active_model":"foo","active_domain":[]}}', + '{"action_id":44,"context":{"active_id":1,"active_ids":[1,2],"active_model":"foo","active_domain":[["bar","=",true]]}}', + ]); + + list.destroy(); + }); + + QUnit.test('execute ActionMenus actions with correct params (multi pages)', async function (assert) { + assert.expect(13); + + const list = await createView({ + View: ListView, + model: 'foo', + data: this.data, + arch: '<tree limit="2"><field name="foo"/></tree>', + toolbar: { + action: [{ + id: 44, + name: 'Custom Action', + type: 'ir.actions.server', + }], + print: [], + }, + mockRPC: function (route, args) { + if (route === '/web/action/load') { + assert.step(JSON.stringify(args)); + return Promise.resolve({}); + } + return this._super(...arguments); + }, + viewOptions: { + hasActionMenus: true, + }, + }); + + assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus'); + assert.containsN(list, '.o_data_row', 2); + + // select all records + await testUtils.dom.click(list.$('thead .o_list_record_selector input')); + assert.containsN(list, '.o_list_record_selector input:checked', 3); + assert.containsOnce(list, '.o_list_selection_box .o_list_select_domain'); + assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus'); + + await cpHelpers.toggleActionMenu(list); + await cpHelpers.toggleMenuItem(list, "Custom Action"); + + // select all domain + await testUtils.dom.click(list.$('.o_list_selection_box .o_list_select_domain')); + assert.containsN(list, '.o_list_record_selector input:checked', 3); + + await cpHelpers.toggleActionMenu(list); + await cpHelpers.toggleMenuItem(list, "Custom Action"); + + // add a domain + await list.reload({ domain: [['bar', '=', true]] }); + assert.containsNone(list, '.o_list_selection_box .o_list_select_domain'); + + // select all domain + await testUtils.dom.click(list.$('thead .o_list_record_selector input')); + await testUtils.dom.click(list.$('.o_list_selection_box .o_list_select_domain')); + assert.containsN(list, '.o_list_record_selector input:checked', 3); + assert.containsNone(list, '.o_list_selection_box .o_list_select_domain'); + + await cpHelpers.toggleActionMenu(list); + await cpHelpers.toggleMenuItem(list, "Custom Action"); + + assert.verifySteps([ + '{"action_id":44,"context":{"active_id":1,"active_ids":[1,2],"active_model":"foo","active_domain":[]}}', + '{"action_id":44,"context":{"active_id":1,"active_ids":[1,2,3,4],"active_model":"foo","active_domain":[]}}', + '{"action_id":44,"context":{"active_id":1,"active_ids":[1,2,3],"active_model":"foo","active_domain":[["bar","=",true]]}}', ]); list.destroy(); |
