[FIX] web: MockServer: better mock loadViews()

Before this rev. parts of the processing of the fields_views and
fields returned by the server done in data_manager were
duplicated in the MockServer and test_utils, and other parts
were missing, so the test environment didn't reproduce well
the tested one.

This rev. refactors the code s.t. it can call the method of the
data_manager that postprocesses the result of a loadViews(). It
also moves the logic to the fieldsViewGet() method so that this
works in every test scenario, not only when a view is created
(e.g. Studio).
This commit is contained in:
Aaron Bohy
2017-04-11 19:44:38 +02:00
parent 348a44855d
commit 0d41d60bb7
2 changed files with 33 additions and 39 deletions
+23 -17
View File
@@ -2,6 +2,7 @@ odoo.define('web.MockServer', function (require) {
"use strict";
var Class = require('web.Class');
var data_manager = require('web.data_manager');
var Domain = require('web.Domain');
var pyeval = require('web.pyeval');
var utils = require('web.utils');
@@ -53,19 +54,20 @@ var MockServer = Class.extend({
/**
* helper: read a string describing an arch, and returns a simulated
* 'field_view_get' call to the server. Note that there is a twist: the
* fields in the 'main' view are supposed to contains all fields, not only
* the ones from the view. This is currently done by the data_manager.
* 'field_view_get' call to the server. Calls processViews() of data_manager
* to mimick the real behavior of a call to loadViews().
*
* @param {string|Object} arch a string OR a parsed xml document
* @param {string} model a model name (that should be in this.data)
* @returns {Object} an object with 2 keys: arch and fields
*/
fieldsViewGet: function (arch, model) {
var fields = this.data[model].fields;
var fvg = this._fieldsViewGet(arch, model);
_.defaults(fvg.fields, fields);
return fvg;
var fields = $.extend(true, {}, this.data[model].fields);
var fvg = this._fieldsViewGet(arch, model, fields);
var fields_views = {};
fields_views[fvg.type] = fvg;
data_manager.processViews(fields_views, fields);
return fields_views[fvg.type];
},
/**
* Simulate a complete RPC call. This is the main method for this class.
@@ -151,19 +153,19 @@ var MockServer = Class.extend({
* @private
* @param {string|Object} arch a string OR a parsed xml document
* @param {string} model a model name (that should be in this.data)
* @returns {Object} an object with 2 keys: arch and fields
* @param {Object} fields
* @returns {Object} an object with 2 keys: arch and fields (the fields
* appearing in the views)
*/
_fieldsViewGet: function (arch, model) {
_fieldsViewGet: function (arch, model, fields) {
var self = this;
var onchanges = this.data[model].onchanges || {};
var fieldNodes = {};
if (typeof arch === 'string') {
var doc = $.parseXML(arch).documentElement;
arch = utils.xml_to_json(doc, true);
}
var fields = this.data[model].fields;
var onchanges = this.data[model].onchanges || {};
var fieldNodes = {};
this._traverse(arch, function (node) {
if (typeof node === "string") {
@@ -197,13 +199,15 @@ var MockServer = Class.extend({
return true;
});
var viewFields = $.extend(true, {}, fields);
var relModel, relFields;
_.each(fieldNodes, function (node, name) {
var field = viewFields[name];
var field = fields[name];
if (field.type === "one2many" || field.type === "many2many") {
field.views = {};
_.each(node.children, function (children) {
field.views[children.tag] = self._fieldsViewGet(children, field.relation);
relModel = field.relation;
relFields = $.extend(true, {}, self.data[relModel].fields);
field.views[children.tag] = self._fieldsViewGet(children, relModel, relFields);
});
}
@@ -214,7 +218,9 @@ var MockServer = Class.extend({
});
return {
arch: arch,
fields: _.pick(viewFields, _.keys(fieldNodes)),
fields: _.pick(fields, _.keys(fieldNodes)),
model: model,
type: arch.tag === 'tree' ? 'list' : arch.tag,
};
},
/**
+10 -22
View File
@@ -15,7 +15,6 @@ var core = require('web.core');
var session = require('web.session');
var MockServer = require('web.MockServer');
var Widget = require('web.Widget');
var DataManager = require('web.DataManager');
/**
@@ -120,7 +119,7 @@ function createAsyncView(params) {
$target.addClass('debug');
}
var mockServer = addMockEnvironment(widget, params);
var fields_view = mockServer.fieldsViewGet(params.arch, params.model);
var viewInfo = mockServer.fieldsViewGet(params.arch, params.model);
var viewOptions = {
modelName: params.model || 'foo',
@@ -133,12 +132,6 @@ function createAsyncView(params) {
_.extend(viewOptions, params.viewOptions);
var viewInfo = DataManager.prototype._processFieldsView({
type: fields_view.arch.tag,
arch: fields_view.arch,
fields: fields_view.fields,
});
var view = new params.View(viewInfo, viewOptions);
$('#qunit-fixture').on('DOMNodeInserted.removeSRC', function () {
@@ -147,7 +140,7 @@ function createAsyncView(params) {
if (params.with_modifiers) {
_.each(params.with_modifiers, function (modifier, name) {
fields_view.fields[name].__attrs.modifiers = JSON.stringify(modifier);
viewInfo.fields[name].__attrs.modifiers = JSON.stringify(modifier);
});
}
@@ -245,11 +238,12 @@ function addMockEnvironment(widget, params) {
logLevel: params.logLevel,
currentDate: params.currentDate,
});
var widgetDestroy;
if ('session' in params) {
var initialSession = _.extend({}, session);
_.extend(session, params.session);
var widgetDestroy = widget.destroy;
widgetDestroy = widget.destroy;
widget.destroy = function () {
for (var key in session) {
delete session[key];
@@ -262,7 +256,7 @@ function addMockEnvironment(widget, params) {
if ('config' in params) {
var initialConfig = _.extend({}, config);
_.extend(config, params.config);
var widgetDestroy = widget.destroy;
widgetDestroy = widget.destroy;
widget.destroy = function () {
for (var key in config) {
delete config[key];
@@ -296,23 +290,17 @@ function addMockEnvironment(widget, params) {
if (params.logLevel === 2) {
console.log('[mock] load_views', event.data);
}
var res = {};
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];
arch = arch && (_.isObject(arch) ? arch : mockServer.fieldsViewGet(arch, model).arch);
res[view_type] = { arch: arch, fields: params.data[model].fields };
});
var views = _.mapObject(res, function (view, viewType) {
return DataManager.prototype._processFieldsView({
type: viewType,
arch: view.arch,
fields: view.fields,
});
if (!arch) {
throw new Error('No arch found for key ' + key);
}
views[view_type] = mockServer.fieldsViewGet(arch, model);
});
event.data.on_success(views);