From 79e4a1f1b116a447b72fb9d1c846260ae6b3ac2c Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Thu, 8 Jun 2017 10:11:50 +0200 Subject: [PATCH] [FIX] web: ModelFieldSelector: add a way to clear the cache The ModelFieldSelector keeps an internal cache for the fields_get. This cache needs to be cleared in the tests environment because a model with the same name may be defined several times accross the tests modules, but they may contain different fields. This could also be a problem with studio: when a field is created, the ModelFieldSelector cache must be cleared as well (in addition to the data_manager one). We thus introduce a new 'clear_cache' event on core.bus. When triggered, the ModelFieldSelector and the data_manager clear their respective cache. We use this event in the test environment to ensure that the cache is cleared at the end of each test using a mockEnvironment. This rev. also fixes an infinite loop in the override of destroy() in the mockEnvironment, which occured when both session and config were specified in the params. --- .../static/src/js/services/data_manager.js | 1 + .../src/js/widgets/model_field_selector.js | 5 ++ addons/web/static/tests/helpers/test_utils.js | 63 ++++++++++--------- 3 files changed, 38 insertions(+), 31 deletions(-) diff --git a/addons/web/static/src/js/services/data_manager.js b/addons/web/static/src/js/services/data_manager.js index 5131db19028..41fc293e383 100644 --- a/addons/web/static/src/js/services/data_manager.js +++ b/addons/web/static/src/js/services/data_manager.js @@ -11,6 +11,7 @@ var utils = require('web.utils'); return core.Class.extend({ init: function () { this._init_cache(); + core.bus.on('clear_cache', this, this.invalidate.bind(this)); }, _init_cache: function () { diff --git a/addons/web/static/src/js/widgets/model_field_selector.js b/addons/web/static/src/js/widgets/model_field_selector.js index 279428e8939..6607561a2bb 100644 --- a/addons/web/static/src/js/widgets/model_field_selector.js +++ b/addons/web/static/src/js/widgets/model_field_selector.js @@ -16,6 +16,11 @@ var modelFieldsCache = { cacheDefs: {}, }; +core.bus.on('clear_cache', null, function () { + modelFieldsCache.cache = {}; + modelFieldsCache.cacheDefs = {}; +}); + /** * The ModelFieldSelector widget can be used to display/select a particular * field chain from a given model. diff --git a/addons/web/static/tests/helpers/test_utils.js b/addons/web/static/tests/helpers/test_utils.js index 3632e251a33..bc2cf05f360 100644 --- a/addons/web/static/tests/helpers/test_utils.js +++ b/addons/web/static/tests/helpers/test_utils.js @@ -252,52 +252,53 @@ function addMockEnvironment(widget, params) { logLevel: params.logLevel, currentDate: params.currentDate, }); - var widgetDestroy; - // make sure the debounce value for input fields is set to 0 var initialDebounce = DebouncedField.prototype.DEBOUNCE; DebouncedField.prototype.DEBOUNCE = params.fieldDebounce || 0; - + var initialSession, initialConfig, initialParameters; if ('session' in params) { - var initialSession = _.extend({}, session); + initialSession = _.extend({}, session); _.extend(session, params.session); - widgetDestroy = widget.destroy; - widget.destroy = function () { - for (var key in session) { + } + if ('config' in params) { + initialConfig = _.extend({}, config); + _.extend(config, params.config); + } + if ('translateParameters' in params) { + initialParameters = _.extend({}, core._t.database.parameters); + _.extend(core._t.database.parameters, params.translateParameters); + } + + var widgetDestroy = widget.destroy; + widget.destroy = function () { + // clear the caches (e.g. data_manager, ModelFieldSelector) when the + // widget is destroyed, at the end of each test to avoid collisions + core.bus.trigger('clear_cache'); + + DebouncedField.prototype.DEBOUNCE = initialDebounce; + + var key; + if ('session' in params) { + for (key in session) { delete session[key]; } _.extend(session, initialSession); - widgetDestroy.call(this); - }; - } - - if ('config' in params) { - var initialConfig = _.extend({}, config); - _.extend(config, params.config); - widgetDestroy = widget.destroy; - widget.destroy = function () { - for (var key in config) { + } + if ('config' in params) { + for (key in config) { delete config[key]; } _.extend(config, initialConfig); - DebouncedField.prototype.DEBOUNCE = initialDebounce; - widgetDestroy.call(this); - }; - } - - if ('translateParameters' in params) { - var initialParameters = _.extend({}, core._t.database.parameters); - _.extend(core._t.database.parameters, params.translateParameters); - var oldDestroy = widget.destroy; - widget.destroy = function () { - for (var key in core._t.database.parameters) { + } + if ('translateParameters' in params) { + for (key in core._t.database.parameters) { delete core._t.database.parameters[key]; } _.extend(core._t.database.parameters, initialParameters); - oldDestroy.call(this); - }; - } + } + widgetDestroy.call(this); + }; intercept(widget, 'call_service', function (event) { if (event.data.service === 'ajax') {