[FIX] web: evaluate the view context for the subviews not inline

Before this commit, the xml attributes defined with 'context.get(key)' in the
subviews not inline were not evaluated correctly. This was caused
by the loss of the one context in the '_loadSubviews' method.

This commit fixes this issue and modifies the mockserver in order to be able
to use the parameter 'viewOptions.context'.
This commit is contained in:
fwi-odoo
2017-09-11 16:41:58 +02:00
parent 268e6d9530
commit 68d1e6d8b1
4 changed files with 82 additions and 13 deletions
@@ -264,7 +264,7 @@ var AbstractView = Class.extend({
}
defs.push(parent.loadViews(
field.relation,
new Context(context, self.userContext),
new Context(context, self.userContext, self.loadParams.context),
[[null, attrs.mode === 'tree' ? 'list' : attrs.mode]])
.then(function (views) {
for (var viewName in views) {
+16 -7
View File
@@ -57,16 +57,22 @@ var MockServer = Class.extend({
* '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)
* @param {Object} params
* @param {string|Object} params.arch a string OR a parsed xml document
* @param {string} params.model a model name (that should be in this.data)
* @param {Object} params.toolbar the actions possible in the toolbar
* @param {Object} [params.viewOptions] the view options set in the test (optional)
* @returns {Object} an object with 2 keys: arch and fields
*/
fieldsViewGet: function (arch, model, toolbar) {
fieldsViewGet: function (params) {
var model = params.model;
var toolbar = params.toolbar;
var viewOptions = params.viewOptions || {};
if (!(model in this.data)) {
throw new Error('Model ' + model + ' was not defined in mock server data');
}
var fields = $.extend(true, {}, this.data[model].fields);
var fvg = this._fieldsViewGet(arch, model, fields);
var fvg = this._fieldsViewGet(params.arch, model, fields, viewOptions.context);
var fields_views = {};
fields_views[fvg.type] = fvg;
data_manager.processViews(fields_views, fields);
@@ -155,10 +161,11 @@ var MockServer = Class.extend({
* @param {string|Object} arch a string OR a parsed xml document
* @param {string} model a model name (that should be in this.data)
* @param {Object} fields
* @param {Object} context
* @returns {Object} an object with 2 keys: arch and fields (the fields
* appearing in the views)
*/
_fieldsViewGet: function (arch, model, fields) {
_fieldsViewGet: function (arch, model, fields, context) {
var self = this;
var modifiersNames = ['invisible', 'readonly', 'required'];
var onchanges = this.data[model].onchanges || {};
@@ -224,7 +231,8 @@ var MockServer = Class.extend({
}
_.each(modifiersNames, function (a) {
if (node.attrs[a]) {
var v = pyeval.py_eval(node.attrs[a]) ? true: false;
var pyevalContext = window.py.dict.fromJSON(context || {});
var v = pyeval.py_eval(node.attrs[a], {context: pyevalContext}) ? true: false;
if (inTreeView && a === 'invisible') {
modifiers['tree_invisible'] = v;
} else if (v || !(a in modifiers) || !_.isArray(modifiers[a])) {
@@ -252,7 +260,8 @@ var MockServer = Class.extend({
_.each(node.children, function (children) {
relModel = field.relation;
relFields = $.extend(true, {}, self.data[relModel].fields);
field.views[children.tag] = self._fieldsViewGet(children, relModel, relFields);
field.views[children.tag] = self._fieldsViewGet(children, relModel,
relFields, context);
});
}
@@ -129,7 +129,7 @@ function createAsyncView(params) {
// add mock environment: mock server, session, fieldviewget, ...
var mockServer = addMockEnvironment(widget, params);
var viewInfo = mockServer.fieldsViewGet(params.arch, params.model, params.toolbar);
var viewInfo = mockServer.fieldsViewGet(params);
// create the view
var viewOptions = {
@@ -321,10 +321,17 @@ function addMockEnvironment(widget, params) {
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(arch, model);
views[view_type] = mockServer.fieldsViewGet(viewParams);
});
event.data.on_success(views);
+56 -3
View File
@@ -3885,7 +3885,7 @@ QUnit.module('Views', {
QUnit.test('*_view_ref in context are passed correctly', function (assert) {
var done = assert.async();
assert.expect(4);
assert.expect(3);
createAsyncView({
View: FormView,
@@ -3902,8 +3902,6 @@ QUnit.module('Views', {
var context = event.data.context.eval();
assert.strictEqual(context.tree_view_ref, 'module.tree_view_ref',
"context should contain tree_view_ref");
assert.notOk('some_context' in context,
"should not send record's context to load p's fields_view");
event.data.on_success();
}
},
@@ -5789,5 +5787,60 @@ QUnit.module('Views', {
form.destroy();
});
QUnit.test('process the context for inline subview', function (assert) {
assert.expect(1);
this.data.partner.records[0].p = [2];
var form = createView({
View: FormView,
model: 'partner',
data: this.data,
arch: '<form string="Partners">' +
'<field name="p">' +
'<tree>' +
'<field name="foo"/>' +
'<field name="bar" invisible="context.get(\'hide_bar\', False)"/>' +
'</tree>' +
'</field>' +
'</form>',
res_id: 1,
viewOptions: {
context: {hide_bar: true},
},
});
assert.strictEqual(form.$('.o_list_view thead tr th').length, 1,
"there should be only one column");
form.destroy();
});
QUnit.test('process the context for subview not inline', function (assert) {
assert.expect(1);
this.data.partner.records[0].p = [2];
var form = createView({
View: FormView,
model: 'partner',
data: this.data,
arch: '<form string="Partners">' +
'<field name="p"/>' +
'</form>',
archs: {
"partner,false,list": '<tree>' +
'<field name="foo"/>' +
'<field name="bar" invisible="context.get(\'hide_bar\', False)"/>' +
'</tree>',
},
res_id: 1,
viewOptions: {
context: {hide_bar: true},
},
});
assert.strictEqual(form.$('.o_list_view thead tr th').length, 1,
"there should be only one column");
form.destroy();
});
});
});