diff options
| author | Aaron Bohy <aab@odoo.com> | 2021-02-09 09:25:15 +0000 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2021-02-11 09:20:26 +0000 |
| commit | 885932ae8e31905e08b79141a445933b6afc9f15 (patch) | |
| tree | 1a6c56abae64b65322e62e06f8f1f60c1313c4b4 /addons/web | |
| parent | 95aebcbc8051f71762724149f6b20f3501485cdd (diff) | |
[FIX] web: keep null/false/true strings in domains
Before this commit, occurences of 'null', 'true' and 'false'
strings as autocomplete values in the search view were replaced
respectively by None, True and False.
Fixes #65743
closes odoo/odoo#65900
X-original-commit: 74311c753e7286c27b83dca2b598e040ed9e586f
Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Diffstat (limited to 'addons/web')
| -rw-r--r-- | addons/web/static/src/js/core/domain.js | 21 | ||||
| -rw-r--r-- | addons/web/static/tests/control_panel/search_bar_tests.js | 78 | ||||
| -rw-r--r-- | addons/web/static/tests/core/domain_tests.js | 16 |
3 files changed, 105 insertions, 10 deletions
diff --git a/addons/web/static/src/js/core/domain.js b/addons/web/static/src/js/core/domain.js index 3e3fd4e4201..dbf2b18eb40 100644 --- a/addons/web/static/src/js/core/domain.js +++ b/addons/web/static/src/js/core/domain.js @@ -234,15 +234,26 @@ var Domain = collections.Tree.extend({ * representation of the Python prefix-array representation of this domain. * * @static - * @param {Array|string} domain + * @param {Array|string|undefined} domain * @returns {string} */ arrayToString: function (domain) { if (_.isString(domain)) return domain; - return JSON.stringify(domain || []) - .replace(/null/g, "None") - .replace(/false/g, "False") - .replace(/true/g, "True"); + const parts = (domain || []).map(part => { + if (_.isArray(part)) { // e.g. ['name', 'ilike', 'foo'] or ['is_active', '=', true] + return "[" + part.map(c => { + switch (c) { + case null: return "None"; + case true: return "True"; + case false: return "False"; + default: return JSON.stringify(c); + } + }).join(',') + "]"; + } else { // e.g. '|' or '&' + return JSON.stringify(part); + } + }); + return "[" + parts.join(',') + "]"; }, /** * Converts a string representation of the Python prefix-array diff --git a/addons/web/static/tests/control_panel/search_bar_tests.js b/addons/web/static/tests/control_panel/search_bar_tests.js index 655464cac1f..ee28b9f43ce 100644 --- a/addons/web/static/tests/control_panel/search_bar_tests.js +++ b/addons/web/static/tests/control_panel/search_bar_tests.js @@ -18,13 +18,14 @@ odoo.define('web.search_bar_tests', function (require) { birthday: { string: "Birthday", type: 'date' }, birth_datetime: { string: "Birth DateTime", type: 'datetime' }, foo: { string: "Foo", type: 'char' }, + bool: { string: "Bool", type: 'boolean' }, }, records: [ - { id: 1, display_name: "First record", foo: "yop", bar: 2, birthday: '1983-07-15', birth_datetime: '1983-07-15 01:00:00' }, - { id: 2, display_name: "Second record", foo: "blip", bar: 1, birthday: '1982-06-04', birth_datetime: '1982-06-04 02:00:00' }, - { id: 3, display_name: "Third record", foo: "gnap", bar: 1, birthday: '1985-09-13', birth_datetime: '1985-09-13 03:00:00' }, - { id: 4, display_name: "Fourth record", foo: "plop", bar: 2, birthday: '1983-05-05', birth_datetime: '1983-05-05 04:00:00' }, - { id: 5, display_name: "Fifth record", foo: "zoup", bar: 2, birthday: '1800-01-01', birth_datetime: '1800-01-01 05:00:00' }, + { id: 1, display_name: "First record", foo: "yop", bar: 2, bool: true, birthday: '1983-07-15', birth_datetime: '1983-07-15 01:00:00' }, + { id: 2, display_name: "Second record", foo: "blip", bar: 1, bool: false, birthday: '1982-06-04', birth_datetime: '1982-06-04 02:00:00' }, + { id: 3, display_name: "Third record", foo: "gnap", bar: 1, bool: false, birthday: '1985-09-13', birth_datetime: '1985-09-13 03:00:00' }, + { id: 4, display_name: "Fourth record", foo: "plop", bar: 2, bool: true, birthday: '1983-05-05', birth_datetime: '1983-05-05 04:00:00' }, + { id: 5, display_name: "Fifth record", foo: "zoup", bar: 2, bool: true, birthday: '1800-01-01', birth_datetime: '1800-01-01 05:00:00' }, ], }, }; @@ -538,6 +539,73 @@ odoo.define('web.search_bar_tests', function (require) { actionManager.destroy(); }); + QUnit.test('"null" as autocomplete value', async function (assert) { + assert.expect(4); + + const actionManager = await createActionManager({ + actions: this.actions, + archs: this.archs, + data: this.data, + mockRPC(route, args) { + if (route === '/web/dataset/search_read') { + assert.step(JSON.stringify(args.domain)); + } + return this._super(...arguments); + }, + }); + + await actionManager.doAction(1); + + await cpHelpers.editSearch(actionManager, "null"); + + assert.strictEqual(actionManager.$('.o_searchview_autocomplete .o_selection_focus').text(), + "Search Foo for: null"); + + await testUtils.dom.click(actionManager.el.querySelector('.o_searchview_autocomplete li.o_selection_focus a')); + + assert.verifySteps([ + JSON.stringify([]), // initial search + JSON.stringify([["foo", "ilike", "null"]]), + ]); + + actionManager.destroy(); + }); + + QUnit.test('autocomplete a boolean value', async function (assert) { + assert.expect(5); + + this.archs['partner,false,search'] = '<search><field name="bool"/></search>'; + + const actionManager = await createActionManager({ + actions: this.actions, + archs: this.archs, + data: this.data, + mockRPC(route, args) { + if (route === '/web/dataset/search_read') { + assert.step(JSON.stringify(args.domain)); + } + return this._super(...arguments); + }, + }); + + await actionManager.doAction(1); + + await cpHelpers.editSearch(actionManager, "y"); + + assert.containsN(actionManager, '.o_searchview_autocomplete li', 2); + assert.strictEqual(actionManager.$('.o_searchview_autocomplete li:last-child').text(), "Yes"); + + // select "Yes" + await testUtils.dom.click(actionManager.el.querySelector('.o_searchview_autocomplete li:last-child')); + + assert.verifySteps([ + JSON.stringify([]), // initial search + JSON.stringify([["bool", "=", true]]), + ]); + + actionManager.destroy(); + }); + QUnit.test("reference fields are supported in search view", async function (assert) { assert.expect(7); diff --git a/addons/web/static/tests/core/domain_tests.js b/addons/web/static/tests/core/domain_tests.js index 017a6fd3703..ff30c53fc0f 100644 --- a/addons/web/static/tests/core/domain_tests.js +++ b/addons/web/static/tests/core/domain_tests.js @@ -142,5 +142,21 @@ QUnit.module('core', {}, function () { assert.expect(1); assert.notOk(new Domain(Domain.FALSE_DOMAIN).compute({})); }); + + QUnit.test("arrayToString", function (assert) { + assert.expect(7); + + const arrayToString = Domain.prototype.arrayToString; + + // domains containing null, false or true + assert.strictEqual(arrayToString([['name', '=', null]]), '[["name","=",None]]'); + assert.strictEqual(arrayToString([['name', '=', false]]), '[["name","=",False]]'); + assert.strictEqual(arrayToString([['name', '=', true]]), '[["name","=",True]]'); + assert.strictEqual(arrayToString([['name', '=', 'null']]), '[["name","=","null"]]'); + assert.strictEqual(arrayToString([['name', '=', 'false']]), '[["name","=","false"]]'); + assert.strictEqual(arrayToString([['name', '=', 'true']]), '[["name","=","true"]]'); + + assert.strictEqual(arrayToString(), '[]'); + }); }); }); |
