diff options
| author | Aaron Bohy <aab@odoo.com> | 2017-05-19 10:13:24 +0200 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2017-05-19 15:51:57 +0200 |
| commit | c929a81e8f015f9234f68749a29fe6a9c21577b6 (patch) | |
| tree | 4471550e5f2c70ffe75137d3fc272f97a8e25ef8 /addons/web/static/tests/fields/basic_fields_tests.js | |
| parent | a845ecffa13657922ba75dbc7f37c7bad8c0e4c0 (diff) | |
[FIX] web: DebounceField: do nothing after widget destruction
DebounceFields debounce the function that notify field changes to
their environment (using _.debounce). It may happen that this
function is called once the field widget is destroyed (e.g.
type something in a char field and quickly click on Save, the
function is called directly by _commitChanges, but the debounced
call is still pending). It may be a problem if the subsequent
code does something like this.getSession().some_key, as if the
widget is destroyed, it has no parent that can provide it the
session, and thus it crashes.
Also rename attribute _debouncedStarted into _isDirty as it makes
much more sense.
Diffstat (limited to 'addons/web/static/tests/fields/basic_fields_tests.js')
| -rw-r--r-- | addons/web/static/tests/fields/basic_fields_tests.js | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/addons/web/static/tests/fields/basic_fields_tests.js b/addons/web/static/tests/fields/basic_fields_tests.js index ca951506e28..07d13fbe93a 100644 --- a/addons/web/static/tests/fields/basic_fields_tests.js +++ b/addons/web/static/tests/fields/basic_fields_tests.js @@ -1,6 +1,7 @@ odoo.define('web.basic_fields_tests', function (require) { "use strict"; +var basicFields = require('web.basic_fields'); var concurrency = require('web.concurrency'); var core = require('web.core'); var FormView = require('web.FormView'); @@ -10,6 +11,7 @@ var session = require('web.session'); var testUtils = require('web.test_utils'); var createView = testUtils.createView; +var DebouncedField = basicFields.DebouncedField; var _t = core._t; QUnit.module('fields', {}, function () { @@ -120,6 +122,66 @@ QUnit.module('basic_fields', { } }, function () { + QUnit.module('DebouncedField'); + + QUnit.test('debounced fields do not trigger call _setValue once destroyed', function (assert) { + var done = assert.async(); + assert.expect(4); + + var def = $.Deferred(); + var _doAction = DebouncedField.prototype._doAction; + DebouncedField.prototype._doAction = function () { + _doAction.apply(this, arguments); + def.resolve(); + }; + var _setValue = DebouncedField.prototype._setValue; + DebouncedField.prototype._setValue = function () { + assert.step('_setValue'); + _setValue.apply(this, arguments); + }; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '<form string="Partners">' + + '<sheet>' + + '<group>' + + '<field name="foo"/>' + + '</group>' + + '</sheet>' + + '</form>', + res_id: 1, + fieldDebounce: 3, + viewOptions: { + mode: 'edit', + }, + }); + + // change the value + form.$('input').val('new value').trigger('input'); + assert.verifySteps([], "_setValue shouldn't have been called yet"); + + // save + form.$buttons.find('.o_form_button_save').click(); + assert.verifySteps(['_setValue'], "_setValue should have been called once"); + + // destroy the form view + def = $.Deferred(); + form.destroy(); + + // wait for the debounced callback to be called + def.then(function () { + assert.verifySteps(['_setValue'], + "_setValue should not have been called after widget destruction"); + + DebouncedField.prototype._doAction = _doAction; + DebouncedField.prototype._setValue = _setValue; + done(); + }); + + }); + QUnit.module('FieldBoolean'); QUnit.test('boolean field in form view', function (assert) { |
