summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGéry Debongnie <ged@odoo.com>2017-03-30 16:28:19 +0200
committerAaron Bohy <aab@odoo.com>2017-04-11 19:44:38 +0200
commitcbc63ca8696d8a89c97a88f73743fb0bd5a7c1ec (patch)
tree7bca5c2e9696fea738847c8557e1954713683001
parente3f84e592ea5b734201d0532253fe0790eab49a6 (diff)
[FIX] web: properly handle onchanges after discard
When an onchange is resolved after a discard, it caused a traceback. We now make sure that it does not happen. Note: I think that the test is quite neat.
-rw-r--r--addons/web/static/src/js/views/basic/basic_model.js7
-rw-r--r--addons/web/static/test/views/form_tests.js52
2 files changed, 59 insertions, 0 deletions
diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js
index b2c061f49e7..b4d343d7eb0 100644
--- a/addons/web/static/src/js/views/basic/basic_model.js
+++ b/addons/web/static/src/js/views/basic/basic_model.js
@@ -1049,6 +1049,13 @@ var BasicModel = AbstractModel.extend({
args: [idList, currentData, fields, onchange_spec, context],
})
.then(function (result) {
+ if (!record._changes) {
+ // if the _changes key does not exist anymore, it means that
+ // it was removed by discarding the changes after the rpc
+ // to onchange. So, in that case, the proper response is to
+ // ignore the onchange.
+ return;
+ }
if (result.warning) {
self.trigger_up('warning', {
message: result.warning.message,
diff --git a/addons/web/static/test/views/form_tests.js b/addons/web/static/test/views/form_tests.js
index 651819a7c37..66d9d64090c 100644
--- a/addons/web/static/test/views/form_tests.js
+++ b/addons/web/static/test/views/form_tests.js
@@ -2058,5 +2058,57 @@ QUnit.module('Views', {
});
}
});
+
+ QUnit.test('onchanges that complete after discarding', function (assert) {
+ assert.expect(4);
+
+ var def1 = $.Deferred();
+
+ this.data.partner.onchanges = {
+ foo: function (obj) {
+ obj.int_field = obj.foo.length + 1000;
+ },
+ };
+ var form = createView({
+ View: FormView,
+ model: 'partner',
+ data: this.data,
+ arch: '<form>' +
+ '<group><field name="foo"/><field name="int_field"/></group>' +
+ '</form>',
+ res_id: 2,
+ mockRPC: function (route, args) {
+ var result = this._super.apply(this, arguments);
+ if (args.method === 'onchange') {
+ assert.step('onchange is done');
+ return def1.then(function () {
+ return result;
+ });
+ }
+ return result;
+ },
+ });
+
+ // go into edit mode
+ assert.strictEqual(form.$('span[name="foo"]').text(), "blip",
+ "field foo should be displayed to initial value");
+ form.$buttons.find('.o_form_button_edit').click();
+
+ // edit a value
+ form.$('input').first().val("1234").trigger('input');
+
+ // discard changes
+ form.$buttons.find('.o_form_button_cancel').click();
+ $('.modal .modal-footer .btn-primary').click();
+ assert.strictEqual(form.$('span[name="foo"]').text(), "blip",
+ "field foo should still be displayed to initial value");
+
+ // complete the onchange
+ def1.resolve();
+ assert.strictEqual(form.$('span[name="foo"]').text(), "blip",
+ "field foo should still be displayed to initial value");
+
+ form.destroy();
+ });
});
});