From baae272ffdbb3b723ce9d2f09dfe720b8bbde27b Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Fri, 17 Nov 2017 15:34:13 +0100 Subject: [PATCH] [REF] web: tests: make load_views RPCs go through mockRPC This allows to inspect those RPCs and the given arguments as well. --- .../tests/fields/relational_fields_tests.js | 27 +++++++----- .../web/static/tests/helpers/mock_server.js | 42 ++++++++++++++++++- addons/web/static/tests/helpers/test_utils.js | 38 +++++++---------- addons/web/static/tests/views/form_tests.js | 8 ++-- .../static/tests/views/view_dialogs_tests.js | 9 ++-- 5 files changed, 82 insertions(+), 42 deletions(-) diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index cc5f3d31ef5..462ea74ac89 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -415,7 +415,7 @@ QUnit.module('relational_fields', { }); QUnit.test('onchanges on many2ones trigger when editing record in form view', function (assert) { - assert.expect(9); + assert.expect(10); this.data.partner.onchanges.user_id = function () {}; this.data.user.fields.other_field = {string: "Other Field", type: "char"}; @@ -454,12 +454,12 @@ QUnit.module('relational_fields', { // save the modal and make sure an onchange is triggered $('.modal .modal-footer .btn-primary').first().click(); - assert.verifySteps(['read', 'get_formview_id', 'read', 'write', 'onchange', 'read']); + assert.verifySteps(['read', 'get_formview_id', 'load_views', 'read', 'write', 'onchange', 'read']); // save the main record, and check that no extra rpcs are done (record // is not dirty, only a related record was modified) form.$buttons.find('.o_form_button_save').click(); - assert.verifySteps(['read', 'get_formview_id', 'read', 'write', 'onchange', 'read']); + assert.verifySteps(['read', 'get_formview_id', 'load_views', 'read', 'write', 'onchange', 'read']); form.destroy(); }); @@ -5902,7 +5902,7 @@ QUnit.module('relational_fields', { // should omit require fields that aren't in the view as they (obviously) // have no value, when checking the validity of required fields // shouldn't consider numerical fields with value 0 as unset - assert.expect(11); + assert.expect(12); this.data.turtle.fields.turtle_foo.required = true; this.data.turtle.fields.turtle_qux.required = true; // required field not in the view @@ -5951,13 +5951,13 @@ QUnit.module('relational_fields', { form.$('.o_field_x2many_list_row_add a').click(); assert.strictEqual(form.$('.o_field_widget[name="int_field"]').val(), "0", "int_field should still be 0 (no onchange should have been done yet)"); - assert.verifySteps(['read', 'default_get'], "no onchange should have been applied"); + assert.verifySteps(['load_views', 'read', 'default_get'], "no onchange should have been applied"); // fill turtle_foo field form.$('.o_field_widget[name="turtle_foo"]').val("some text").trigger('input'); assert.strictEqual(form.$('.o_field_widget[name="int_field"]').val(), "0", "int_field should still be 0 (no onchange should have been done yet)"); - assert.verifySteps(['read', 'default_get'], "no onchange should have been applied"); + assert.verifySteps(['load_views', 'read', 'default_get'], "no onchange should have been applied"); // fill partner_ids field with a tag (all required fields will then be set) var $m2mInput = form.$('.o_field_widget[name=partner_ids] input'); @@ -7140,7 +7140,9 @@ QUnit.module('relational_fields', { }, res_id: 1, mockRPC: function (route, args) { - assert.step(_.last(route.split('/'))); + if (args.method !== 'load_views') { + assert.step(_.last(route.split('/'))); + } if (args.method === 'write' && args.model === 'partner') { assert.deepEqual(args.args[1].timmy, [ [6, false, [12, 15]], @@ -7238,7 +7240,9 @@ QUnit.module('relational_fields', { 'partner_type,false,search': '', }, mockRPC: function (route, args) { - assert.step(_.last(route.split('/'))); + if (args.method !== 'load_views') { + assert.step(_.last(route.split('/'))); + } if (args.method === 'write') { assert.deepEqual(args.args[1].timmy, [ [6, false, [12, 15]], @@ -7544,7 +7548,9 @@ QUnit.module('relational_fields', { '', }, mockRPC: function (route, args) { - assert.step(_.last(route.split('/')) + ' on ' + args.model); + if (args.method !== 'load_views') { + assert.step(_.last(route.split('/')) + ' on ' + args.model); + } if (args.model === 'turtle') { assert.step(args.args[0]); // the read ids } @@ -7629,7 +7635,7 @@ QUnit.module('relational_fields', { }); QUnit.test('many2many list with onchange and edition of a record', function (assert) { - assert.expect(7); + assert.expect(8); this.data.partner.fields.turtles.type = "many2many"; this.data.partner.onchanges.turtles = function () {}; @@ -7666,6 +7672,7 @@ QUnit.module('relational_fields', { assert.verifySteps([ 'read', // read initial record (on partner) 'read', // read many2many turtles + 'load_views', // load arch of turtles form view 'read', // read missing field when opening record in modal form view 'write', // when saving the modal 'onchange', // onchange should be triggered on partner diff --git a/addons/web/static/tests/helpers/mock_server.js b/addons/web/static/tests/helpers/mock_server.js index 9ce15568d46..4bc58dd097d 100644 --- a/addons/web/static/tests/helpers/mock_server.js +++ b/addons/web/static/tests/helpers/mock_server.js @@ -12,11 +12,14 @@ var MockServer = Class.extend({ * @constructor * @param {Object} data * @param {Object} options + * @param {Object} [options.archs={}] dict of archs with keys being strings like + * 'model,id,viewType' * @param {boolean} [options.debug=false] logs RPCs if set to true * @param {string} [options.currentDate] formatted string, default to * current day */ init: function (data, options) { + options = options || {}; this.data = data; for (var modelName in this.data) { var model = this.data[modelName]; @@ -40,9 +43,11 @@ var MockServer = Class.extend({ } } - this.debug = options && options.debug; + this.debug = options.debug; this.currentDate = options.currentDate || moment().format("YYYY-MM-DD"); + + this.archs = options.archs || {}; }, //-------------------------------------------------------------------------- @@ -426,6 +431,38 @@ var MockServer = Class.extend({ } return modelFields; }, + /** + * Simulate a 'load_views' operation + * + * @param {string} model + * @param {Array} args + * @param {Object} kwargs + * @param {Array} kwargs.views + * @param {Object} kwargs.options + * @param {Object} kwargs.context + * @returns {Object} + */ + _mockLoadViews: function (model, kwargs) { + var self = this; + var views = {}; + _.each(kwargs.views, function (view_descr) { + var viewID = view_descr[0] || false; + var viewType = view_descr[1]; + var key = [model, viewID, viewType].join(','); + var arch = self.archs[key]; + if (!arch) { + throw new Error('No arch found for key ' + key); + } + views[viewType] = { + arch: arch, + model: model, + viewOptions: { + context: kwargs.context, + }, + }; + }); + return views; + }, /** * Simulate a 'name_get' operation * @@ -927,6 +964,9 @@ var MockServer = Class.extend({ case 'fields_get': return $.when(this._mockFieldsGet(args.model, args.args)); + case 'load_views': + return $.when(this._mockLoadViews(args.model, args.kwargs)); + case 'name_get': return $.when(this._mockNameGet(args.model, args.args)); diff --git a/addons/web/static/tests/helpers/test_utils.js b/addons/web/static/tests/helpers/test_utils.js index d8a03783288..33b29622ea7 100644 --- a/addons/web/static/tests/helpers/test_utils.js +++ b/addons/web/static/tests/helpers/test_utils.js @@ -245,6 +245,7 @@ function addMockEnvironment(widget, params) { console.log('%c[debug] debug mode activated', 'color: blue; font-weight: bold;', url); } var mockServer = new Server(params.data, { + archs: params.archs, currentDate: params.currentDate, debug: params.debug, }); @@ -313,30 +314,21 @@ function addMockEnvironment(widget, params) { }); intercept(widget, "load_views", function (event) { - if (params.debug) { - console.log('[mock] load_views', event.data); - } - var views = {}; - var model = event.data.modelName; - _.each(event.data.views, function (view_descr) { - var view_id = view_descr[0] || false; - var view_type = view_descr[1]; - var key = [model, view_id, view_type].join(','); - var arch = params.archs[key]; - var viewParams = { - arch: arch, - model: model, - viewOptions: { - context: event.data.context.eval(), - }, - }; - if (!arch) { - throw new Error('No arch found for key ' + key); - } - views[view_type] = mockServer.fieldsViewGet(viewParams); + mockServer.performRpc('/web/dataset/call_kw/' + event.data.modelName, { + args: [], + kwargs: { + context: event.data.context.eval(), + options: event.data.options, + views: event.data.views, + }, + method: 'load_views', + model: event.data.modelName, + }).then(function (views) { + views = _.mapObject(views, function (viewParams) { + return mockServer.fieldsViewGet(viewParams); + }); + event.data.on_success(views); }); - - event.data.on_success(views); }); intercept(widget, "get_session", function (event) { diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js index bf88a921b67..4067a2d4c39 100644 --- a/addons/web/static/tests/views/form_tests.js +++ b/addons/web/static/tests/views/form_tests.js @@ -4272,7 +4272,7 @@ QUnit.module('Views', { }); QUnit.test('open one2many form containing one2many', function (assert) { - assert.expect(8); + assert.expect(9); this.data.partner.records[0].product_ids = [37]; this.data.product.fields.partner_type_ids = { @@ -4326,7 +4326,7 @@ QUnit.module('Views', { "the row should contains the 2 fields defined in the form view"); assert.strictEqual($(modal_row).text(), "gold2", "the value of the fields should be fetched and displayed"); - assert.verifySteps(['read', 'read', 'read', 'read'], + assert.verifySteps(['read', 'read', 'load_views', 'read', 'read'], "there should be 4 read rpcs"); form.destroy(); }); @@ -5905,7 +5905,7 @@ QUnit.module('Views', { // 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); + assert.expect(11); var arch = '
' + '' + @@ -5943,8 +5943,10 @@ QUnit.module('Views', { assert.verifySteps([ "read", // main record "get_formview_id", // id of first form view opened in a dialog + "load_views", // arch of first form view opened in a dialog "read", // first dialog "get_formview_id", // id of second form view opened in a dialog + "load_views", // arch of second form view opened in a dialog "read", // second dialog "write", // save second dialog "read", // reload first dialog diff --git a/addons/web/static/tests/views/view_dialogs_tests.js b/addons/web/static/tests/views/view_dialogs_tests.js index 1d99d5b1cb7..b2dc9c5ab0e 100644 --- a/addons/web/static/tests/views/view_dialogs_tests.js +++ b/addons/web/static/tests/views/view_dialogs_tests.js @@ -88,8 +88,7 @@ QUnit.module('Views', { '', }, mockRPC: function (route, args) { - search++; - if (search === 1 && args.method === 'read_group') { + if (args.method === 'read_group') { assert.deepEqual(args.kwargs, { context: {group_by: "bar"}, domain: [["display_name","like","a"], ["display_name","ilike","piou"], ["foo","ilike","piou"]], @@ -99,7 +98,8 @@ QUnit.module('Views', { lazy: true }, "should search with the complete domain (domain + search), and group by 'bar'"); } - if (search === 2 && route === '/web/dataset/search_read') { + if (search === 0 && route === '/web/dataset/search_read') { + search++; assert.deepEqual(args, { context: {}, domain: [["display_name","like","a"], ["display_name","ilike","piou"], ["foo","ilike","piou"]], @@ -108,8 +108,7 @@ QUnit.module('Views', { limit: 80, sort: "" }, "should search with the complete domain (domain + search)"); - } - if (search === 3 && route === '/web/dataset/search_read') { + } else if (search === 1 && route === '/web/dataset/search_read') { assert.deepEqual(args, { context: {}, domain: [["display_name","like","a"]],