From 74c27d81ed299441d3ba07c2181d0e9830b1fec0 Mon Sep 17 00:00:00 2001 From: Martin Geubelle Date: Thu, 14 Sep 2017 16:35:14 +0200 Subject: [PATCH] [FIX] web: deal with `can_create` and `can_write` option in M2O The server postproccess the view to add attributes on many2one fields, i.e. `can_create` and `can_write`, according to access rights. These attributes are parsed by the client as string but should also be parsed by the many2one when evaluating them. The mock server has also been adapted to set these attributes. --- .../static/src/js/fields/relational_fields.js | 8 ++- .../tests/fields/relational_fields_tests.js | 50 +++++++++++++++++++ .../web/static/tests/helpers/mock_server.js | 4 ++ 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index c2bd4f5d5b8..4cbbf498e82 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -93,8 +93,12 @@ var FieldMany2One = AbstractField.extend({ this._super.apply(this, arguments); this.limit = 7; this.orderer = new concurrency.DropMisordered(); - this.can_create = ('can_create' in this.attrs ? this.attrs.can_create : true) && !this.nodeOptions.no_create; - this.can_write = 'can_write' in this.attrs ? this.attrs.can_write : true; + + // should normally also be set, except in standalone M20 + this.can_create = ('can_create' in this.attrs ? JSON.parse(this.attrs.can_create) : true) && + !this.nodeOptions.no_create; + this.can_write = 'can_write' in this.attrs ? JSON.parse(this.attrs.can_write) : true; + this.nodeOptions = _.defaults(this.nodeOptions, { quick_create: true, }); diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index 2020e0124f3..75ee8e8bf3e 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -1362,6 +1362,56 @@ QUnit.module('relational_fields', { form.destroy(); }); + QUnit.test('can_create and can_write option on a many2one', function (assert) { + assert.expect(5); + + this.data.product.options = { + can_create: "false", + can_write: "false", + }; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + '' + + '' + + '' + + '
', + archs: { + 'product,false,form': '
', + }, + mockRPC: function (route) { + if (route === '/web/dataset/call_kw/product/get_formview_id') { + return $.when(false); + } + return this._super.apply(this, arguments); + }, + }); + + form.$('.o_field_many2one input').click(); + assert.strictEqual($('.ui-autocomplete .o_m2o_dropdown_option:contains(Create)').length, 0, + "there shouldn't be any option to search and create"); + + $('.ui-autocomplete li:contains(xpad)').mouseenter().click(); + assert.strictEqual(form.$('.o_field_many2one input').val(), "xpad", + "the correct record should be selected"); + assert.strictEqual(form.$('.o_field_many2one .o_external_button').length, 1, + "there should be an external button displayed"); + + form.$('.o_field_many2one .o_external_button').click(); + assert.strictEqual($('.modal .o_form_view.o_form_readonly').length, 1, + "there should be a readonly form view opened"); + + $('.modal .o_form_button_cancel').click(); + + form.$('.o_field_many2one input').val('new product').trigger('keyup').trigger('focusout'); + + assert.strictEqual($('.modal').length, 0, "should not display the create modal"); + form.destroy(); + }); + QUnit.test('pressing enter in a m2o in an editable list', function (assert) { assert.expect(9); var done = assert.async(); diff --git a/addons/web/static/tests/helpers/mock_server.js b/addons/web/static/tests/helpers/mock_server.js index eb78153265c..9523f8b0c0f 100644 --- a/addons/web/static/tests/helpers/mock_server.js +++ b/addons/web/static/tests/helpers/mock_server.js @@ -255,6 +255,10 @@ var MockServer = Class.extend({ var relModel, relFields; _.each(fieldNodes, function (node, name) { var field = fields[name]; + if (field.type === "many2one" || field.type === "many2many") { + node.attrs.can_create = node.attrs.can_create || "true"; + node.attrs.can_write = node.attrs.can_write || "true"; + } if (field.type === "one2many" || field.type === "many2many") { field.views = {}; _.each(node.children, function (children) {