summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Bohy <aab@odoo.com>2019-08-27 08:42:37 +0000
committerAaron Bohy <aab@odoo.com>2019-08-27 10:21:00 +0000
commit906480093a75e54ddf7d212b61c1d10d7f9c55ca (patch)
treec8d81cd744d066f8a622efceb76381addf15e3b0
parent2899a9d1edaafce9b48f808d08c0b61202dcaa3e (diff)
[FIX] web: 'create' in context and non inline subviews
Let's assume an action with 'create': 0 in the context, and a non inline subview in the form view. Before this rev., the 'create': 0 was applied to both the form view and the subview. This rev. applies the same logic as what the server does for inline subviews: the rule is applied to the subview iff its model is the same as the one of the form view (with key 'base_model_name' set in the context). Task 2035653 closes odoo/odoo#36109 Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
-rw-r--r--addons/web/static/src/js/views/form/form_view.js4
-rw-r--r--addons/web/static/tests/helpers/mock_server.js15
-rw-r--r--addons/web/static/tests/views/form_tests.js35
-rw-r--r--addons/web/static/tests/views/view_dialogs_tests.js6
4 files changed, 54 insertions, 6 deletions
diff --git a/addons/web/static/src/js/views/form/form_view.js b/addons/web/static/src/js/views/form/form_view.js
index fb228f5a636..d386981b422 100644
--- a/addons/web/static/src/js/views/form/form_view.js
+++ b/addons/web/static/src/js/views/form/form_view.js
@@ -102,6 +102,10 @@ var FormView = BasicView.extend({
var refinedContext = _.pick(self.loadParams.context, function (value, key) {
return key.indexOf('_view_ref') === -1;
});
+ // Specify the main model to prevent access rights defined in the context
+ // (e.g. create: 0) to apply to subviews. We use here the same logic as
+ // the one applied by the server for inline views.
+ refinedContext.base_model_name = self.controllerParams.modelName;
defs.push(parent.loadViews(
field.relation,
new Context(context, self.userContext, refinedContext).eval(),
diff --git a/addons/web/static/tests/helpers/mock_server.js b/addons/web/static/tests/helpers/mock_server.js
index 75f8afeeff2..c376b6bc5c6 100644
--- a/addons/web/static/tests/helpers/mock_server.js
+++ b/addons/web/static/tests/helpers/mock_server.js
@@ -83,7 +83,7 @@ var MockServer = Class.extend({
throw new Error('Model ' + model + ' was not defined in mock server data');
}
var fields = $.extend(true, {}, this.data[model].fields);
- var fvg = this._fieldsViewGet(params.arch, model, fields, viewOptions.context);
+ var fvg = this._fieldsViewGet(params.arch, model, fields, viewOptions.context || {});
if (toolbar) {
fvg.toolbar = toolbar;
}
@@ -207,6 +207,17 @@ var MockServer = Class.extend({
var inTreeView = (doc.tagName === 'tree');
+ // mock _postprocess_access_rights
+ const isBaseModel = !context.base_model_name || (model === context.base_model_name);
+ var views = ['kanban', 'tree', 'form', 'gantt', 'activity'];
+ if (isBaseModel && views.indexOf(doc.tagName) !== -1) {
+ for (let action of ['create', 'delete', 'edit', 'write']) {
+ if (!doc.getAttribute(action) && action in context && !context[action]) {
+ doc.setAttribute(action, 'false');
+ }
+ }
+ }
+
this._traverse(doc, function (node) {
if (node.nodeType === Node.TEXT_NODE) {
return false;
@@ -302,7 +313,7 @@ var MockServer = Class.extend({
relModel = field.relation;
relFields = $.extend(true, {}, self.data[relModel].fields);
field.views[children.tagName] = self._fieldsViewGet(children, relModel,
- relFields, context);
+ relFields, _.extend({}, context, {base_model_name: model}));
});
}
diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js
index eee1093624f..f37df9baf45 100644
--- a/addons/web/static/tests/views/form_tests.js
+++ b/addons/web/static/tests/views/form_tests.js
@@ -352,8 +352,10 @@ QUnit.module('Views', {
'The correct _view_ref should have been sent to the server, first time');
}
if (args.model === 'partner_type') {
- assert.deepEqual(context, {tree_view_ref: 'some_other_tree_view'},
- 'The correct _view_ref should have been sent to the server for the subview');
+ assert.deepEqual(context, {
+ base_model_name: 'product',
+ tree_view_ref: 'some_other_tree_view',
+ }, 'The correct _view_ref should have been sent to the server for the subview');
}
}
return this._super.apply(this, arguments);
@@ -4526,6 +4528,35 @@ QUnit.module('Views', {
});
});
+ QUnit.test('non inline subview and create=0 in action context', async function (assert) {
+ // the create=0 should apply on the main view (form), but not on subviews
+ assert.expect(2);
+
+ const form = await createView({
+ View: FormView,
+ model: 'partner',
+ data: this.data,
+ arch: '<form><field name="product_ids" mode="kanban"/></form>',
+ archs: {
+ "product,false,kanban": `<kanban>
+ <templates><t t-name="kanban-box">
+ <div><field name="name"/></div>
+ </t></templates>
+ </kanban>`,
+ },
+ res_id: 1,
+ viewOptions: {
+ context: {create: false},
+ mode: 'edit',
+ },
+ });
+
+ assert.containsNone(form, '.o_form_button_create');
+ assert.containsOnce(form, '.o-kanban-button-new');
+
+ form.destroy();
+ });
+
QUnit.test('readonly fields with modifiers may be saved', function (assert) {
// the readonly property on the field description only applies on view,
// this is not a DB constraint. It should be seen as a default value,
diff --git a/addons/web/static/tests/views/view_dialogs_tests.js b/addons/web/static/tests/views/view_dialogs_tests.js
index 332d0142faa..c988d7b775f 100644
--- a/addons/web/static/tests/views/view_dialogs_tests.js
+++ b/addons/web/static/tests/views/view_dialogs_tests.js
@@ -408,8 +408,10 @@ QUnit.module('Views', {
'The correct _view_ref should have been sent to the server, first time');
}
if (ev.data.modelName === 'badassery') {
- assert.deepEqual(evaluatedContext, {tree_view_ref: 'some_other_tree_view'},
- 'The correct _view_ref should have been sent to the server for the subview');
+ assert.deepEqual(evaluatedContext, {
+ base_model_name: 'instrument',
+ tree_view_ref: 'some_other_tree_view',
+ }, 'The correct _view_ref should have been sent to the server for the subview');
}
},
},