From bd0cb2c3c9b8d2cf49fceb7f16a627b1627b6006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul=20=28ACSONE=29?= Date: Sun, 20 Nov 2016 23:23:14 +0100 Subject: [PATCH] [FIX] server_environment_ir_config_param: silently replace values by config values This is much more robust that raising an error, and let modules load ir.config_parameter from xml data files, while still enforcing values from the config files. --- .../README.rst | 4 +- .../models/ir_config_parameter.py | 36 +++++--------- .../tests/test_server_environment_ircp.py | 48 ++++++++++++++----- 3 files changed, 51 insertions(+), 37 deletions(-) diff --git a/server_environment_ir_config_parameter/README.rst b/server_environment_ir_config_parameter/README.rst index 954a7a85cec..07afc8b8747 100644 --- a/server_environment_ir_config_parameter/README.rst +++ b/server_environment_ir_config_parameter/README.rst @@ -26,8 +26,8 @@ When first using a value, the system will read it from the configuration file and override any value that would be present in the database, so the configuration file has precedence. -The user cannot write, create, or delete System Parameters that are defined in the -configuration files. +When creating or modifying values that are in the configuration file, the +module replace changes, enforcing the configuration value. For example you can use this module in combination with web_environment_ribbon: diff --git a/server_environment_ir_config_parameter/models/ir_config_parameter.py b/server_environment_ir_config_parameter/models/ir_config_parameter.py index 14bad0ca870..f00ba08ac05 100644 --- a/server_environment_ir_config_parameter/models/ir_config_parameter.py +++ b/server_environment_ir_config_parameter/models/ir_config_parameter.py @@ -8,7 +8,6 @@ SECTION = 'ir.config_parameter' -CTX_NO_CHECK = 'icp_no_check' class IrConfigParameter(models.Model): @@ -29,36 +28,27 @@ def get_param(self, cr, uid, key, default=False, context=None): # should we have preloaded values in database at, # server startup, modules loading their parameters # from data files would break on unique key error. - self.set_param( - cr, SUPERUSER_ID, key, cvalue, - context={CTX_NO_CHECK: True}) + self.set_param(cr, SUPERUSER_ID, key, cvalue) value = cvalue if value is None: return default return value - def _check_not_in_config(self, keys): - if self.env.context.get(CTX_NO_CHECK): - return - if not serv_config.has_section(SECTION): - return - config_icp_keys = set(serv_config.options(SECTION)) & set(keys) - if config_icp_keys: - raise UserError(_("System Parameter(s) %s is/are defined " - "in server_environment_files.") % - (config_icp_keys, )) - @api.model def create(self, vals): - self._check_not_in_config([vals.get('key')]) + key = vals.get('key') + if serv_config.has_option(SECTION, key): + # enforce value from config file + vals = dict(vals, value=serv_config.get(SECTION, key)) return super(IrConfigParameter, self).create(vals) @api.multi def write(self, vals): - self._check_not_in_config(self.mapped('key')) - return super(IrConfigParameter, self).write(vals) - - @api.multi - def unlink(self): - self._check_not_in_config(self.mapped('key')) - return super(IrConfigParameter, self).unlink() + for rec in self: + key = vals.get('key') or rec.key + if serv_config.has_option(SECTION, key): + # enforce value from config file + newvals = dict(vals, value=serv_config.get(SECTION, key)) + else: + newvals = vals + super(IrConfigParameter, rec).write(newvals) diff --git a/server_environment_ir_config_parameter/tests/test_server_environment_ircp.py b/server_environment_ir_config_parameter/tests/test_server_environment_ircp.py index 07fae446961..8f6f768a5da 100644 --- a/server_environment_ir_config_parameter/tests/test_server_environment_ircp.py +++ b/server_environment_ir_config_parameter/tests/test_server_environment_ircp.py @@ -2,11 +2,14 @@ # Copyright 2016 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from cStringIO import StringIO + from openerp.exceptions import UserError from openerp.tests import common +from openerp.tools import convert -class TestEnv(common.SavepointCase): +class TestEnv(common.TransactionCase): def setUp(self): super(TestEnv, self).setUp() @@ -27,19 +30,27 @@ def test_get_param(self): def test_set_param_1(self): """ We can't set parameters that are in config file """ - # create - with self.assertRaises(UserError): - self.ICP.set_param('ircp_from_config', 'new_value') - # read so it's created in db - self.ICP.get_param('ircp_from_config') - # write + # when creating, the value is overridden by config file + self.ICP.set_param('ircp_from_config', 'new_value') + value = self.ICP.get_param('ircp_from_config') + self.assertEqual(value, 'config_value') + # when writing, the value is overridden by config file + res = self.ICP.search([('key', '=', 'ircp_from_config')]) + self.assertEqual(len(res), 1) + res.write({'value': 'new_value'}) + value = self.ICP.get_param('ircp_from_config') + self.assertEqual(value, 'config_value') + # unlink works normally... + res = self.ICP.search([('key', '=', 'ircp_from_config')]) + self.assertEqual(len(res), 1) + res.unlink() + res = self.ICP.search([('key', '=', 'ircp_from_config')]) + self.assertEqual(len(res), 0) + # but the value is recreated when getting param again + value = self.ICP.get_param('ircp_from_config') + self.assertEqual(value, 'config_value') res = self.ICP.search([('key', '=', 'ircp_from_config')]) self.assertEqual(len(res), 1) - with self.assertRaises(UserError): - res.write({'ircp_from_config': 'new_value'}) - # unlink - with self.assertRaises(UserError): - res.unlink() def test_set_param_2(self): """ We can set parameters that are not in config file """ @@ -55,3 +66,16 @@ def test_empty(self): with self.assertRaises(UserError): self.ICP.get_param('ircp_empty') self.assertEqual(self.ICP.get_param('ircp_nonexistant'), False) + + def test_override_xmldata(self): + xml = """ + + + ircp_from_config + value_from_xml + + + """ + convert.convert_xml_import(self.env.cr, 'testmodule', StringIO(xml)) + value = self.ICP.get_param('ircp_from_config') + self.assertEqual(value, 'config_value')