109 lines
3.3 KiB
JavaScript
109 lines
3.3 KiB
JavaScript
|
/** @odoo-module **/
|
||
|
|
||
|
import { WebsocketWorker } from "@bus/workers/websocket_worker";
|
||
|
import { browser } from "@web/core/browser/browser";
|
||
|
import { patchWithCleanup } from "@web/../tests/helpers/utils";
|
||
|
import { registerCleanup } from "@web/../tests/helpers/cleanup";
|
||
|
|
||
|
class WebSocketMock extends EventTarget {
|
||
|
constructor() {
|
||
|
super();
|
||
|
this.readyState = 0;
|
||
|
|
||
|
queueMicrotask(() => {
|
||
|
this.readyState = 1;
|
||
|
const openEv = new Event("open");
|
||
|
this.onopen(openEv);
|
||
|
this.dispatchEvent(openEv);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
close(code = 1000, reason) {
|
||
|
this.readyState = 3;
|
||
|
const closeEv = new CloseEvent("close", {
|
||
|
code,
|
||
|
reason,
|
||
|
wasClean: code === 1000,
|
||
|
});
|
||
|
this.onclose(closeEv);
|
||
|
this.dispatchEvent(closeEv);
|
||
|
}
|
||
|
|
||
|
onclose(closeEv) {}
|
||
|
onerror(errorEv) {}
|
||
|
onopen(openEv) {}
|
||
|
|
||
|
send(data) {
|
||
|
if (this.readyState !== 1) {
|
||
|
const errorEv = new Event("error");
|
||
|
this.onerror(errorEv);
|
||
|
this.dispatchEvent(errorEv);
|
||
|
throw new DOMException("Failed to execute 'send' on 'WebSocket': State is not OPEN");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class SharedWorkerMock extends EventTarget {
|
||
|
constructor(websocketWorker) {
|
||
|
super();
|
||
|
this._websocketWorker = websocketWorker;
|
||
|
this._messageChannel = new MessageChannel();
|
||
|
this.port = this._messageChannel.port1;
|
||
|
// port 1 should be started by the service itself.
|
||
|
this._messageChannel.port2.start();
|
||
|
this._websocketWorker.registerClient(this._messageChannel.port2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class WorkerMock extends SharedWorkerMock {
|
||
|
constructor(websocketWorker) {
|
||
|
super(websocketWorker);
|
||
|
this.port.start();
|
||
|
this.postMessage = this.port.postMessage.bind(this.port);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
let websocketWorker;
|
||
|
/**
|
||
|
* @param {*} params Parameters used to patch the websocket worker.
|
||
|
* @returns {WebsocketWorker} Instance of the worker which will run during the
|
||
|
* test. Usefull to interact with the worker in order to test the
|
||
|
* websocket behavior.
|
||
|
*/
|
||
|
export function patchWebsocketWorkerWithCleanup(params = {}) {
|
||
|
patchWithCleanup(window, {
|
||
|
WebSocket: function () {
|
||
|
return new WebSocketMock();
|
||
|
},
|
||
|
});
|
||
|
patchWithCleanup(websocketWorker || WebsocketWorker.prototype, params);
|
||
|
websocketWorker = websocketWorker || new WebsocketWorker();
|
||
|
websocketWorker.INITIAL_RECONNECT_DELAY = 0;
|
||
|
websocketWorker.RECONNECT_JITTER = 0;
|
||
|
patchWithCleanup(browser, {
|
||
|
SharedWorker: function () {
|
||
|
const sharedWorker = new SharedWorkerMock(websocketWorker);
|
||
|
registerCleanup(() => {
|
||
|
sharedWorker._messageChannel.port1.close();
|
||
|
sharedWorker._messageChannel.port2.close();
|
||
|
});
|
||
|
return sharedWorker;
|
||
|
},
|
||
|
Worker: function () {
|
||
|
const worker = new WorkerMock(websocketWorker);
|
||
|
registerCleanup(() => {
|
||
|
worker._messageChannel.port1.close();
|
||
|
worker._messageChannel.port2.close();
|
||
|
});
|
||
|
return worker;
|
||
|
},
|
||
|
});
|
||
|
registerCleanup(() => {
|
||
|
if (websocketWorker) {
|
||
|
clearTimeout(websocketWorker.connectTimeout);
|
||
|
websocketWorker = null;
|
||
|
}
|
||
|
});
|
||
|
return websocketWorker;
|
||
|
}
|