Files
odoo_source/addons/mail/static/tests/helpers/test_utils.js
T
Géry Debongnie 827adcd8fc [FIX] mail: prevent race condition in discuss
The discuss application starting process is strongly asynchronous.
However, it relies implicitely on the fact that the widget is not
destroyed in its starting process.  For example, if the widget is
detroyed before the updateChannel method is called, then any call to the
chat manager service will return undefined and the widget will crash.

When discuss is destroyed exactly between the start and the end of the
creation of its search view (which is asynchronous), then it is possible
to have a crash, because the search view will be destroyed when the
do_search method is called.

Note that we had to fix discuss mobile as well:
The _setChannel method is supposed to return a deferred, but the mobile
override did not return it.  As a result, a test in the mobile suite
failed because this.alive takes a deferred in argument.
2018-04-13 17:19:33 +02:00

105 lines
2.8 KiB
JavaScript

odoo.define('mail.testUtils', function (require) {
"use strict";
var Discuss = require('mail.chat_discuss');
var AbstractService = require('web.AbstractService');
var Bus = require('web.Bus');
var ControlPanel = require('web.ControlPanel');
var testUtils = require('web.test_utils');
var Widget = require('web.Widget');
/**
* Test Utils
*
* In this module, we define some utility functions to create mock objects
* in the mail module, such as the BusService or Discuss.
*/
/**
* Create a mock bus_service, using 'bus' instead of bus.bus
*
* @param {web.bus} bus
* @return {AbstractService} the mock bus_service
*/
function createBusService(bus) {
var BusService = AbstractService.extend({
name: 'bus_service',
/**
* @override
*/
init: function () {
this._super.apply(this, arguments);
if (!bus) {
bus = new Bus();
}
this.bus = new _.extend(bus, {
/**
* Do nothing
*/
start_polling: function () {},
});
},
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
/**
* Get the bus
*/
getBus: function () {
return this.bus;
},
});
return BusService;
}
/**
* Create asynchronously a discuss widget.
* This is async due to chat_manager service that needs to be ready.
*
* @param {Object} params
* @return {$.Promise} resolved with the discuss widget
*/
function createDiscuss(params) {
var Parent = Widget.extend({
do_push_state: function () {},
});
var parent = new Parent();
testUtils.addMockEnvironment(parent, _.extend(params, {
archs: {
'mail.message,false,search': '<search/>',
},
}));
var discuss = new Discuss(parent, params);
discuss.set_cp_bus(new Widget());
var selector = params.debug ? 'body' : '#qunit-fixture';
var controlPanel = new ControlPanel(parent);
controlPanel.appendTo($(selector));
// override 'destroy' of discuss so that it calls 'destroy' on the parent
// instead, which is the parent of discuss and the mockServer.
discuss.destroy = function () {
// remove the override to properly destroy discuss and its children
// when it will be called the second time (by its parent)
delete discuss.destroy;
parent.destroy();
};
// link the view to the control panel
discuss.set_cp_bus(controlPanel.get_bus());
return discuss.appendTo($(selector)).then(function () {
return discuss;
});
}
return {
createBusService: createBusService,
createDiscuss: createDiscuss,
};
});