[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:
@@ -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,
|
||||
};
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user