diff options
| author | Aaron Bohy <aab@odoo.com> | 2019-08-27 08:42:37 +0000 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2019-08-27 10:21:00 +0000 |
| commit | 906480093a75e54ddf7d212b61c1d10d7f9c55ca (patch) | |
| tree | c8d81cd744d066f8a622efceb76381addf15e3b0 | |
| parent | 2899a9d1edaafce9b48f808d08c0b61202dcaa3e (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.js | 4 | ||||
| -rw-r--r-- | addons/web/static/tests/helpers/mock_server.js | 15 | ||||
| -rw-r--r-- | addons/web/static/tests/views/form_tests.js | 35 | ||||
| -rw-r--r-- | addons/web/static/tests/views/view_dialogs_tests.js | 6 |
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'); } }, }, |
