We want to avoid that a `setTimeout` started in one test has an impact on other tests. This is especially true with the status update loop. Since mail_service is used in multiple tests, the safest solution is to patch timeouts everytime we make a call to getMailServices. There is no need for an unpatch, the patch become the default behaviour until the page is refresh at the end of tests. It is possible to manually add the patch after calling `getMailServices` ``` this.services = mailTestUtils.getMailServices(this); this.timeoutMock = mailTestUtils.patchMailTimeouts(); ``` This can be usefull if we want to get the timeoutMock to simulate time changes. Task: 1856205
208 lines
5.8 KiB
JavaScript
208 lines
5.8 KiB
JavaScript
odoo.define('mail.testUtils', function (require) {
|
|
"use strict";
|
|
|
|
var BusService = require('bus.BusService');
|
|
|
|
var Discuss = require('mail.Discuss');
|
|
var MailService = require('mail.Service');
|
|
var mailUtils = require('mail.utils');
|
|
|
|
var AbstractStorageService = require('web.AbstractStorageService');
|
|
var Class = require('web.Class');
|
|
var ControlPanelView = require('web.ControlPanelView');
|
|
var RamStorage = require('web.RamStorage');
|
|
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 asynchronously a discuss widget.
|
|
* This is async due to mail_manager/mail_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();
|
|
params.archs = params.archs || {
|
|
'mail.message,false,search': '<search/>',
|
|
};
|
|
testUtils.mock.addMockEnvironment(parent, params);
|
|
var discuss = new Discuss(parent, params);
|
|
var selector = params.debug ? 'body' : '#qunit-fixture';
|
|
|
|
// 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();
|
|
};
|
|
|
|
return discuss.appendTo($(selector)).then(function () {
|
|
return discuss;
|
|
});
|
|
}
|
|
|
|
|
|
var MockMailService = Class.extend({
|
|
bus_service: function () {
|
|
return BusService.extend({
|
|
_poll: function () {}, // Do nothing
|
|
isOdooFocused: function () { return true; },
|
|
updateOption: function () {},
|
|
});
|
|
},
|
|
mail_service: function () {
|
|
return MailService;
|
|
},
|
|
local_storage: function () {
|
|
return AbstractStorageService.extend({
|
|
storage: new RamStorage(),
|
|
});
|
|
},
|
|
getServices: function () {
|
|
return {
|
|
mail_service: this.mail_service(),
|
|
bus_service: this.bus_service(),
|
|
local_storage: this.local_storage(),
|
|
};
|
|
},
|
|
});
|
|
|
|
/**
|
|
* Patch all the mailUtils.clearTimeout and mailUtils.setTimeout.
|
|
*
|
|
* @return {Object} helper functions, including unpatch and time management tools.
|
|
*/
|
|
var patchMailTimeouts = function () {
|
|
var currentTime = 0;
|
|
var timeouts = {};
|
|
var countTimeout = 0;
|
|
|
|
mailUtils.clearTimeout = function (id) {
|
|
delete timeouts[id];
|
|
};
|
|
|
|
mailUtils.setTimeout = function (func, duration) {
|
|
duration = duration || 0;
|
|
var executeTime = currentTime + duration;
|
|
countTimeout++;
|
|
timeouts[countTimeout] = {
|
|
executeTime: executeTime,
|
|
func: func
|
|
};
|
|
return countTimeout;
|
|
};
|
|
/**
|
|
* @return {integer|boolean} id of the next timeout in queue, false if queue is empty
|
|
*/
|
|
function getNextTimeoutId() {
|
|
var minKey = false;
|
|
_.each(timeouts, function (value, key) {
|
|
if (minKey === false) {
|
|
minKey = Number(key);
|
|
return;
|
|
}
|
|
var minTime = timeouts[minKey].executeTime;
|
|
if (value.executeTime < minTime || (value.executeTime === minTime && key < minKey)) {
|
|
minKey = Number(key);
|
|
}
|
|
});
|
|
return minKey;
|
|
}
|
|
|
|
/**
|
|
* @return {integer|boolean} delay (time interval) before the next timeout in queue is executed.
|
|
* Useful to know how much time to advance to execute next timer.
|
|
*/
|
|
function getNextTimeoutDelay() {
|
|
var next = getNextTimeoutId();
|
|
if (next === false) {
|
|
return false;
|
|
}
|
|
return timeouts[next].executeTime - currentTime;
|
|
}
|
|
|
|
/**
|
|
* Set the current time to given time
|
|
*
|
|
* @param {integer} time
|
|
*/
|
|
function setTime(time) {
|
|
var next = getNextTimeoutId();
|
|
if (next !== false && timeouts[next].executeTime <= time) {
|
|
currentTime = timeouts[next].executeTime;
|
|
var func = timeouts[next].func;
|
|
// watch out setTimeout inside setTimeout (recursive)
|
|
delete timeouts[next];
|
|
func();
|
|
setTime(time);
|
|
}
|
|
else {
|
|
currentTime = time;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add the given time to current time
|
|
*
|
|
* @param {integer} time
|
|
*/
|
|
function addTime(time) {
|
|
setTime(currentTime + time);
|
|
}
|
|
|
|
/**
|
|
* Set time to the max time in queue and execute all timeouts before this time.
|
|
*/
|
|
function runPendingTimeouts() {
|
|
var maxTimeInQueue = 0;
|
|
_.each(timeouts, function (value, key) {
|
|
if (value.executeTime > maxTimeInQueue) {
|
|
maxTimeInQueue = value.executeTime;
|
|
}
|
|
});
|
|
setTime(maxTimeInQueue);
|
|
}
|
|
|
|
return {
|
|
addTime: addTime,
|
|
getNextTimeoutDelay:getNextTimeoutDelay,
|
|
runPendingTimeouts: runPendingTimeouts,
|
|
setTime: setTime,
|
|
};
|
|
};
|
|
|
|
|
|
/**
|
|
* Returns the list of mail services required by the mail components: a
|
|
* mail_service, and its two dependencies bus_service and local_storage.
|
|
*
|
|
* @return {AbstractService[]} an array of 3 services: mail_service, bus_service
|
|
* and local_storage, in that order
|
|
*/
|
|
function getMailServices() {
|
|
patchMailTimeouts();
|
|
return new MockMailService().getServices();
|
|
}
|
|
|
|
return {
|
|
MockMailService: MockMailService,
|
|
createDiscuss: createDiscuss,
|
|
getMailServices: getMailServices,
|
|
patchMailTimeouts: patchMailTimeouts,
|
|
};
|
|
|
|
});
|