summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorErik Larkö <erik@mullvad.net>2017-05-28 13:31:48 +0200
committerErik Larkö <erik@mullvad.net>2017-05-28 13:31:48 +0200
commita99e3585e0f06657d0813ec65d8bab7423379d2d (patch)
tree049e9bcb8fca6664ef181a2462c58becb46cc573
parentf6cc8959a01bb245095f959f6c7ff0be1867e2fa (diff)
parent9f68855437a52da5586d146a2a1f8dda056c8f91 (diff)
downloadmullvadvpn-a99e3585e0f06657d0813ec65d8bab7423379d2d.tar.xz
mullvadvpn-a99e3585e0f06657d0813ec65d8bab7423379d2d.zip
Merge branch 'test-ipc-on-connect'
-rw-r--r--app/lib/backend.js2
-rw-r--r--app/lib/ipc-facade.js2
-rw-r--r--app/lib/jsonrpc-ws-ipc.js6
-rw-r--r--test/ipc.spec.js76
4 files changed, 82 insertions, 4 deletions
diff --git a/app/lib/backend.js b/app/lib/backend.js
index ce7c6d17c3..7cf1d5b043 100644
--- a/app/lib/backend.js
+++ b/app/lib/backend.js
@@ -171,7 +171,7 @@ export default class Backend extends EventEmitter {
*/
constructor(ipc: IpcFacade) {
super();
- this._ipc = ipc || new RealIpc(undefined);
+ this._ipc = ipc || new RealIpc('');
this._registerIpcListeners();
// check for network reachability
diff --git a/app/lib/ipc-facade.js b/app/lib/ipc-facade.js
index 03fa4f961a..f344c80d7b 100644
--- a/app/lib/ipc-facade.js
+++ b/app/lib/ipc-facade.js
@@ -25,7 +25,7 @@ export class RealIpc implements IpcFacade {
_ipc: JsonRpcWs;
- constructor(connectionString: ?string) {
+ constructor(connectionString: string) {
this._ipc = new JsonRpcWs(connectionString);
}
diff --git a/app/lib/jsonrpc-ws-ipc.js b/app/lib/jsonrpc-ws-ipc.js
index 1fdcdf6428..a327696e27 100644
--- a/app/lib/jsonrpc-ws-ipc.js
+++ b/app/lib/jsonrpc-ws-ipc.js
@@ -48,12 +48,14 @@ export default class Ipc {
_subscriptions: {[string]: (any) => void};
_websocket: WebSocket;
_backoff: ReconnectionBackoff;
+ _websocketFactory: (string) => WebSocket;
- constructor(connectionString: ?string) {
+ constructor(connectionString: string, websocketFactory: ?(string)=>WebSocket) {
this._connectionString = connectionString;
this._onConnect = [];
this._unansweredRequests = {};
this._subscriptions = {};
+ this._websocketFactory = websocketFactory || (connectionString => new WebSocket(connectionString));
this._backoff = new ReconnectionBackoff();
this._reconnect();
@@ -170,7 +172,7 @@ export default class Ipc {
if (!connectionString) return;
log.info('Connecting to websocket', connectionString);
- this._websocket = new WebSocket(connectionString);
+ this._websocket = this._websocketFactory(connectionString);
this._websocket.onopen = () => {
log.debug('Websocket is connected');
diff --git a/test/ipc.spec.js b/test/ipc.spec.js
new file mode 100644
index 0000000000..afac3ad704
--- /dev/null
+++ b/test/ipc.spec.js
@@ -0,0 +1,76 @@
+// @flow
+
+import Ipc from '../app/lib/jsonrpc-ws-ipc.js';
+import jsonrpc from 'jsonrpc-lite';
+import { expect } from 'chai';
+import type { JsonRpcMessage } from '../app/lib/jsonrpc-ws-ipc.js';
+
+describe('The IPC server', () => {
+
+ it('should send as soon as the websocket connects', () => {
+ const { ws, ipc } = setupIpc();
+ ws.close();
+
+ let sent = false;
+ const p = ipc.send('hello')
+ .then(() => {
+ expect(sent).to.be.true;
+ });
+
+ ws.on('hello', (msg) => {
+ sent = true;
+
+ ws.replyOk(msg.id);
+ });
+ ws.acceptConnection();
+
+ return p;
+ });
+});
+
+function mockWebsocket() {
+ const ws : any = {
+ listeners: {},
+ readyState: 1,
+ };
+
+ ws.on = (event, listener) => ws.listeners[event] = listener;
+ ws.send = (data) => {
+ const listener = ws.listeners[data.method];
+ if (listener) {
+ listener(data);
+ }
+ };
+
+ ws.factory = () => ws;
+
+ ws.acceptConnection = () => {
+ ws.readyState = 1;
+ ws.onopen();
+ };
+ ws.close = () => {
+ ws.readyState = 3;
+ ws.onclose();
+ };
+
+ ws.reply = (msg: JsonRpcMessage) => {
+ ws.onmessage({data: JSON.stringify(msg)});
+ };
+ ws.replyOk = (id: string, msg) => {
+ ws.reply(jsonrpc.success(id, msg || ''));
+ };
+ ws.replyFail = (id: string, msg: string, code: number) => {
+ ws.reply(jsonrpc.error(id, new jsonrpc.JsonRpcError(msg, code)));
+ };
+
+ return ws;
+}
+
+function setupIpc() {
+ const ws = mockWebsocket();
+ return {
+ ws: ws,
+ ipc: new Ipc('1.2.3.4', ws.factory),
+ };
+}
+