From 56318875940ae28a9896628612e078ade980cedf Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Fri, 4 Nov 2022 12:53:00 +0000 Subject: [PATCH] [FIX] web: "Set Defaults" feature from the debug menu Since odoo/odoo#99660 the `depends` field attribute is no longer passed from the server to the web client. Because of this, the "Set Defaults" feature of the debug menu is completely unusable, as the list of fields on which to set a default is empty because of it. The use of this `depends` field attribute has been introduced in revision odoo/odoo@ce9bbf6c10962e64138c04ca34b7485084e4cdaa In the commit description, we can read that setting a default on computed fields having depends has been disabled because the defaults set were being overwritten by the call to onchange. Note that only the fact the field has depends is required, the actual list of field names is not used, just the fact the list is not empty. However, since revision odoo/odoo@488e334fc8fd6601e304635fa577c98b9bfd18e6, available since Odoo 14.0, this is no longer the case, the defaults are no longer being overwritten by the call to `onchange`, since the `default_get` has been integrated into the `onchange`. A video attached to the pull request of this revision shows the behavior difference. Hence, setting a default on a computed fields having depends (with an inverse method, hence not readonly) can be allowed again in this "Set defaults" debug feature, therefore avoiding to have to send back the `depends` field attributes to the web client. opw-3031290 opw-3038711 opw-3055292 X-original-commit: 48ac799288e76a0256b9ce0712a70ed5abc0f62e Part-of: odoo/odoo#105251 --- addons/contacts/__manifest__.py | 5 ++ .../tests/tours/debug_menu_set_defaults.js | 70 +++++++++++++++++++ addons/contacts/tests/__init__.py | 4 ++ addons/contacts/tests/test_ui.py | 33 +++++++++ addons/web/static/src/legacy/debug_manager.js | 4 +- addons/web/static/src/views/debug_items.js | 4 +- .../tests/core/debug/debug_manager_tests.js | 5 -- 7 files changed, 114 insertions(+), 11 deletions(-) create mode 100644 addons/contacts/static/tests/tours/debug_menu_set_defaults.js create mode 100644 addons/contacts/tests/__init__.py create mode 100644 addons/contacts/tests/test_ui.py diff --git a/addons/contacts/__manifest__.py b/addons/contacts/__manifest__.py index c783ef17c72..0a910c80538 100644 --- a/addons/contacts/__manifest__.py +++ b/addons/contacts/__manifest__.py @@ -17,4 +17,9 @@ You can track your vendors, customers and other contacts. ], 'application': True, 'license': 'LGPL-3', + 'assets': { + 'web.assets_tests': [ + 'contacts/static/tests/tours/**/*', + ], + } } diff --git a/addons/contacts/static/tests/tours/debug_menu_set_defaults.js b/addons/contacts/static/tests/tours/debug_menu_set_defaults.js new file mode 100644 index 00000000000..54fec23d36b --- /dev/null +++ b/addons/contacts/static/tests/tours/debug_menu_set_defaults.js @@ -0,0 +1,70 @@ +odoo.define('debug_menu_set_defaults.tour', function (require) { + "use strict"; + + var tour = require('web_tour.tour'); + + tour.register('debug_menu_set_defaults', { + test: true, + url: '/web?debug=1', + }, + [ + ...tour.stepUtils.goToAppSteps('contacts.menu_contacts', "Open the contacts menu"), + { + content: "Create a new contact", + trigger: '.o-kanban-button-new', + }, + { + content: "Check that Company is checked by default, and not Individual", + trigger: '.o_field_widget[name="company_type"] input[data-value="company"]:checked', + run: function () {}, + }, + { + content: "Select the individual radio button", + trigger: '.o_field_widget[name="company_type"] input[data-value="person"]', + }, + { + content: "Open the debug menu", + trigger: '.o_debug_manager button', + }, + { + content: "Click the Set Defaults menu", + trigger: '.o_debug_manager .dropdown-item:contains(Set Defaults)', + }, + { + content: "Choose Company Type = Individual", + trigger: '#formview_default_fields', + run: function () { + const element_field = document.querySelector('select#formview_default_fields'); + element_field.value = 'company_type'; + element_field.dispatchEvent(new Event("change")); + }, + }, + { + content: "Save the new default", + trigger: 'footer button:contains(Save default)', + }, + { + content: "Discard the contact creation", + trigger: 'button.o_form_button_cancel', + }, + { + trigger: '.o-kanban-button-new', + }, + { + content: "Check that Individual is checked instead of Company", + trigger: '.o_field_widget[name="company_type"] input[data-value="person"]:checked', + run: function () {}, + }, + { + content: "Discard the contact creation", + trigger: 'button.o_form_button_cancel', + }, + { + content: "Wait for discard", + trigger: '.o_control_panel .o-kanban-button-new', + run() {}, + }, + ] + ); + +}); diff --git a/addons/contacts/tests/__init__.py b/addons/contacts/tests/__init__.py new file mode 100644 index 00000000000..2235dde4188 --- /dev/null +++ b/addons/contacts/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import test_ui diff --git a/addons/contacts/tests/test_ui.py b/addons/contacts/tests/test_ui.py new file mode 100644 index 00000000000..a3fb1c5845f --- /dev/null +++ b/addons/contacts/tests/test_ui.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from ast import literal_eval + +import odoo.tests + + +@odoo.tests.tagged('-at_install', 'post_install') +class TestUi(odoo.tests.HttpCase): + def test_set_defaults(self): + """Tests the "Set Defaults" feature of the debug menu on the res.partner form. + + Set a user-defined default on the computed (with inverse) field `company_type` + so the default "Company" becomes "Indivdual". + """ + # Ensure the requirements of the test: + # The tour assumptions are currently that `res.partner.company_type` is a non-readonly computed field + # currently defaulting to "company" in the `res.partner` form. + # If the below assertions change in the future, the tour needs to be adapted, as well as these assertions. + company_type_field = self.env['res.partner']._fields['company_type'] + self.assertTrue(company_type_field.compute) + self.assertFalse(company_type_field.readonly) + action_context = literal_eval(self.env.ref('contacts.action_contacts').context) + self.assertTrue(action_context.get('default_is_company')) + # Make sure there is currently no user-defined default on res.partner.company_type + # so "Company" is the default value for the field res.partner.company_type + self.env['ir.default'].search([ + ('field_id', '=', self.env.ref('base.field_res_partner__company_type').id), + ]).unlink() + self.assertEqual(self.env['res.partner'].with_context(**action_context).new().company_type, "company") + + self.start_tour("/web", 'debug_menu_set_defaults', login="admin") diff --git a/addons/web/static/src/legacy/debug_manager.js b/addons/web/static/src/legacy/debug_manager.js index 2d7a2f1c3a1..8cf180a526a 100644 --- a/addons/web/static/src/legacy/debug_manager.js +++ b/addons/web/static/src/legacy/debug_manager.js @@ -133,9 +133,7 @@ class SetDefaultDialog extends Component { fieldInfo.type === "one2many" || fieldInfo.type === "many2many" || fieldInfo.type === "binary" || - fieldsInfo[fieldName].options.isPassword || - fieldInfo.depends === undefined || - fieldInfo.depends.length !== 0 + fieldsInfo[fieldName].options.isPassword ) { return false; } diff --git a/addons/web/static/src/views/debug_items.js b/addons/web/static/src/views/debug_items.js index 5e16b4d5a82..bf2b5f0dd6b 100644 --- a/addons/web/static/src/views/debug_items.js +++ b/addons/web/static/src/views/debug_items.js @@ -236,9 +236,7 @@ class SetDefaultDialog extends Component { fieldInfo.type === "one2many" || fieldInfo.type === "many2many" || fieldInfo.type === "binary" || - this.fieldsInfo[fieldName].options.isPassword || - fieldInfo.depends === undefined || - fieldInfo.depends.length !== 0 + this.fieldsInfo[fieldName].options.isPassword ) { return false; } diff --git a/addons/web/static/tests/core/debug/debug_manager_tests.js b/addons/web/static/tests/core/debug/debug_manager_tests.js index 6fc658d97ff..21abe9bf608 100644 --- a/addons/web/static/tests/core/debug/debug_manager_tests.js +++ b/addons/web/static/tests/core/debug/debug_manager_tests.js @@ -536,9 +536,6 @@ QUnit.module("DebugMenu", (hooks) => { fields: {}, records: [{ id: 18 }], }; - serverData.models.partner.fields.m2o.depends = []; - serverData.models.partner.fields.foo.depends = []; - serverData.models.partner.fields.o2m.depends = []; serverData.models.partner.records = [{ id: 1, display_name: "p1", foo: "hello" }]; const mockRPC = async (route, args) => { @@ -585,7 +582,6 @@ QUnit.module("DebugMenu", (hooks) => { fields: {}, records: [{ id: 18 }], }; - serverData.models.partner.fields.foo.depends = []; serverData.models.partner.records = [{ id: 1, display_name: "p1", foo: "hello" }]; const mockRPC = async (route, args) => { @@ -635,7 +631,6 @@ QUnit.module("DebugMenu", (hooks) => { fields: {}, records: [{ id: 18 }], }; - serverData.models.partner.fields.foo.depends = []; serverData.models.partner.records = [{ id: 1, display_name: "p1", foo: "hello" }]; const mockRPC = async (route, args) => {