summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/account/static/tests/reconciliation_tests.js9
-rw-r--r--addons/web/static/src/js/core/ajax.js2
-rw-r--r--addons/web/static/src/js/core/service_mixins.js10
-rw-r--r--addons/web/static/src/js/core/session.js9
-rw-r--r--addons/web/static/src/js/services/ajax_service.js25
-rw-r--r--addons/web/static/tests/core/widget_tests.js37
-rw-r--r--addons/web/static/tests/helpers/mock_server.js17
-rw-r--r--addons/web/static/tests/helpers/test_utils.js10
8 files changed, 95 insertions, 24 deletions
diff --git a/addons/account/static/tests/reconciliation_tests.js b/addons/account/static/tests/reconciliation_tests.js
index 93a8a1818b4..4d5b04bf50f 100644
--- a/addons/account/static/tests/reconciliation_tests.js
+++ b/addons/account/static/tests/reconciliation_tests.js
@@ -692,6 +692,9 @@ QUnit.module('account', {
}],
payment_aml_ids: [], new_aml_dicts: []}]],
"Should call process_bank_statement_line with ids");
+ var def = $.Deferred();
+ def.abort = function () {};
+ event.data.callback(def);
});
// click on reconcile button
@@ -734,6 +737,9 @@ QUnit.module('account', {
analytic_tag_ids: [[6, null, []]]
}]}]],
"Should call process_bank_statement_line with ids");
+ var def = $.Deferred();
+ def.abort = function () {};
+ event.data.callback(def);
});
// click on validate button
@@ -787,6 +793,9 @@ QUnit.module('account', {
name: 'SAJ/2014/002 and SAJ/2014/003 : Open balance'
}]}]],
"Should call process_bank_statement_line with ids");
+ var def = $.Deferred();
+ def.abort = function () {};
+ event.data.callback(def);
});
// click on validate button
diff --git a/addons/web/static/src/js/core/ajax.js b/addons/web/static/src/js/core/ajax.js
index fa79c65ef45..036af275f4e 100644
--- a/addons/web/static/src/js/core/ajax.js
+++ b/addons/web/static/src/js/core/ajax.js
@@ -38,7 +38,7 @@ function genericJsonRpc (fct_name, params, settings, fct) {
});
// FIXME: jsonp?
deferred.abort = function () {
- deferred.reject('communication', $.Event(), 'abort', 'abort');
+ deferred.reject({message: "XmlHttpRequestError abort"}, $.Event('abort'));
if (xhr.abort) {
xhr.abort();
}
diff --git a/addons/web/static/src/js/core/service_mixins.js b/addons/web/static/src/js/core/service_mixins.js
index 463b0aef4b1..7ca691cb2ad 100644
--- a/addons/web/static/src/js/core/service_mixins.js
+++ b/addons/web/static/src/js/core/service_mixins.js
@@ -125,8 +125,14 @@ var ServicesMixin = {
*/
_rpc: function (params, options) {
var query = rpc.buildQuery(params);
- var def = this.call('ajax', 'rpc', query.route, query.params, options);
- return def ? def.promise() : $.Deferred().promise();
+ var def = this.call('ajax', 'rpc', query.route, query.params, options, this);
+ if (!def && this.isDestroyed()) {
+ def = $.Deferred();
+ def.abort = function () {};
+ }
+ var promise = def.promise();
+ promise.abort = def.abort.bind(def);
+ return promise;
},
loadFieldView: function (dataset, view_id, view_type, options) {
return this.loadViews(dataset.model, dataset.get_context().eval(), [[view_id, view_type]], options).then(function (result) {
diff --git a/addons/web/static/src/js/core/session.js b/addons/web/static/src/js/core/session.js
index 09b65357404..694285cccdc 100644
--- a/addons/web/static/src/js/core/session.js
+++ b/addons/web/static/src/js/core/session.js
@@ -344,9 +344,11 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, {
}
};
- return deferred.then(function () {
+ var promise = deferred.then(function () {
if (aborted) {
- return $.Deferred().reject('communication', $.Event(), 'abort', 'abort');
+ var def = $.Deferred().reject({message: "XmlHttpRequestError abort"}, $.Event('abort'));
+ def.abort = function () {};
+ return def;
}
// TODO: remove
if (! _.isString(url)) {
@@ -374,6 +376,9 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, {
xhrDef = fct(url, "call", params, options);
return xhrDef;
});
+
+ promise.abort = deferred.abort;
+ return promise;
},
url: function (path, params) {
params = _.extend(params || {});
diff --git a/addons/web/static/src/js/services/ajax_service.js b/addons/web/static/src/js/services/ajax_service.js
index 3446f651a59..6c61fdbf9ed 100644
--- a/addons/web/static/src/js/services/ajax_service.js
+++ b/addons/web/static/src/js/services/ajax_service.js
@@ -8,17 +8,20 @@ var session = require('web.session');
var AjaxService = AbstractService.extend({
name: 'ajax',
rpc: function (route, args, options, target) {
- return $.Deferred(function (def) {
- session.rpc(route, args, options).then(function () {
- if (!target.isDestroyed()) {
- def.resolve.apply(def, arguments);
- }
- }, function () {
- if (!target.isDestroyed()) {
- def.reject.apply(def, arguments);
- }
- });
- }).promise();
+ var def = $.Deferred();
+ var promise = def.promise();
+ var xhrDef = session.rpc(route, args, options);
+ promise.abort = xhrDef.abort.bind(xhrDef);
+ xhrDef.then(function () {
+ if (!target.isDestroyed()) {
+ def.resolve.apply(def, arguments);
+ }
+ }).fail(function () {
+ if (!target.isDestroyed()) {
+ def.reject.apply(def, arguments);
+ }
+ });
+ return promise;
},
});
diff --git a/addons/web/static/tests/core/widget_tests.js b/addons/web/static/tests/core/widget_tests.js
index 19e72cb97b6..9510079e380 100644
--- a/addons/web/static/tests/core/widget_tests.js
+++ b/addons/web/static/tests/core/widget_tests.js
@@ -1,10 +1,12 @@
odoo.define('web.widget_tests', function (require) {
"use strict";
+var AjaxService = require('web.AjaxService');
var concurrency = require('web.concurrency');
var core = require('web.core');
var QWeb = require('web.QWeb');
var Widget = require('web.Widget');
+var testUtils = require('web.test_utils');
QUnit.module('core', {}, function () {
@@ -377,16 +379,47 @@ QUnit.module('core', {}, function () {
});
QUnit.test("calling _rpc on destroyed widgets", function (assert) {
- assert.expect(1);
+ assert.expect(3);
+
+ var def;
+ var parent = new Widget();
+ testUtils.addMockEnvironment(parent, {
+ session: {
+ rpc: function () {
+ def = $.Deferred();
+ def.abort = def.reject;
+ return def;
+ },
+ },
+ services: [AjaxService],
+ });
+ var widget = new Widget(parent);
+
+ widget._rpc({route: '/a/route'}).then(function () {
+ assert.ok(true, "The ajax call should be resolve");
+ });
+ def.resolve();
+ def = null;
- var widget = new Widget();
+ widget._rpc({route: '/a/route'}).always(function () {
+ throw Error("Calling _rpc on a destroyed widget should return a " +
+ "deferred that is never resolved nor rejected");
+ });
widget.destroy();
+ def.resolve();
+ def = null;
+
widget._rpc({route: '/a/route'}).always(function () {
throw Error("Calling _rpc on a destroyed widget should return a " +
"deferred that is never resolved nor rejected");
});
+ assert.ok(!def,
+ "The trigger_up is not performed and the call returns a deferred "+
+ "never resolved nor rejected");
+
assert.ok(true,
"there should be no crash when calling _rpc on a destroyed widget");
+ parent.destroy();
});
QUnit.test('start is not called when widget is destroyed', function (assert) {
diff --git a/addons/web/static/tests/helpers/mock_server.js b/addons/web/static/tests/helpers/mock_server.js
index 75d99621c4b..6a6dd62f2df 100644
--- a/addons/web/static/tests/helpers/mock_server.js
+++ b/addons/web/static/tests/helpers/mock_server.js
@@ -110,7 +110,18 @@ var MockServer = Class.extend({
console.log('%c[rpc] request ' + route, 'color: blue; font-weight: bold;', args);
args = JSON.parse(JSON.stringify(args));
}
- return this._performRpc(route, args).then(function (result) {
+ var def = this._performRpc(route, args);
+
+ var abort = def.abort || def.reject;
+ if (abort) {
+ abort = abort.bind(def);
+ } else {
+ abort = function () {
+ throw new Error("Can't abort this request");
+ };
+ }
+
+ def = def.then(function (result) {
var resultString = JSON.stringify(result || false);
if (debug) {
console.log('%c[rpc] response' + route, 'color: blue; font-weight: bold;', JSON.parse(resultString));
@@ -123,6 +134,10 @@ var MockServer = Class.extend({
}
return $.Deferred().reject(errorString, event || $.Event());
});
+
+ var promise = def.promise();
+ promise.abort = abort;
+ return promise;
},
//--------------------------------------------------------------------------
diff --git a/addons/web/static/tests/helpers/test_utils.js b/addons/web/static/tests/helpers/test_utils.js
index 4720d166a4c..beb39687364 100644
--- a/addons/web/static/tests/helpers/test_utils.js
+++ b/addons/web/static/tests/helpers/test_utils.js
@@ -407,15 +407,15 @@ function addMockEnvironment(widget, params) {
var services = {ajax: null}; // mocked ajax service already loaded
intercept(widget, 'call_service', function (ev) {
var args, result;
- if (ev.data.service === 'ajax') {
+ if (services[ev.data.service]) {
+ var service = services[ev.data.service];
+ args = (ev.data.args || []);
+ result = service[ev.data.method].apply(service, args);
+ } else if (ev.data.service === 'ajax') {
// ajax service is already mocked by the server
var route = ev.data.args[0];
args = ev.data.args[1];
result = mockServer.performRpc(route, args);
- } else if (services[ev.data.service]) {
- var service = services[ev.data.service];
- args = (ev.data.args || []);
- result = service[ev.data.method].apply(service, args);
}
ev.data.callback(result);
});