muweb-socket
Version:
WebSocket communication for mudb
159 lines (131 loc) • 4.7 kB
text/typescript
import http = require('http');
import test = require('tape');
import ip = require('ip');
import WebSocket = require('uws');
import { MuSocketServerState } from 'mudb/socket';
import { MuWebSocketServer } from '../server';
function noop () { }
const server = http.createServer();
test.onFinish(() => process.exit(0));
test('server initial state', (t) => {
const socketServer = new MuWebSocketServer({ server });
t.equals(socketServer.state, MuSocketServerState.INIT, 'should be INIT');
t.end();
});
test('socketServer.start() - when INIT', (t) => {
t.plan(2);
const socketServer = new MuWebSocketServer({ server });
socketServer.start({
ready: () => {
t.pass('should invoke ready handler');
t.equals(socketServer.state, MuSocketServerState.RUNNING, 'should change server state to RUNNING');
},
connection: noop,
close: noop,
});
});
test('socketServer.start() - when RUNNING', (t) => {
t.plan(1);
const socketServer = new MuWebSocketServer({ server });
socketServer.start({
ready: () => {
t.throws(
() => socketServer.start({
ready: noop,
connection: noop,
close: noop,
}),
);
},
connection: noop,
close: noop,
});
});
test('socketServer.start() - when SHUTDOWN', (t) => {
t.plan(1);
const socketServer = new MuWebSocketServer({ server });
socketServer.start({
ready: () => {
socketServer.close();
t.throws(
() => socketServer.start({
ready: noop,
connection: noop,
close: noop,
}),
);
},
connection: noop,
close: noop,
});
});
test('when a client connects', (t) => {
t.plan(3);
function id () {
return Math.random().toString(36).substr(2);
}
let url = '';
const socketServer = new MuWebSocketServer({ server });
socketServer.start({
ready: () => {
t.pass('should invoke ready handler');
let numSockets = 0;
const numSocketsToOpen = 5;
const sessionId = id();
function openSocket () {
const socket = new WebSocket(url);
socket.binaryType = 'arraybuffer';
socket.onopen = () => {
socket.onmessage = (ev) => {
if (typeof ev.data === 'string') {
const firstSocket = numSockets === 0;
if (firstSocket && JSON.parse(ev.data).reliable) {
++numSockets;
t.pass('server should indicate first socket as reliable one');
}
if (!firstSocket && !JSON.parse(ev.data).reliable) {
++numSockets;
}
if (numSockets === numSocketsToOpen) {
t.pass('server should indicate other sockets as unreliable ones');
}
if (numSockets > numSocketsToOpen) {
t.fail(`should not open more than ${numSocketsToOpen} sockets`);
}
}
};
socket.send(JSON.stringify({ sessionId }));
};
}
for (let i = 0; i < numSocketsToOpen; ++i) {
openSocket();
}
},
// TODO test if connection handler is invoked with client object
connection: noop,
close: noop,
});
server.listen(() => {
url = `ws://${ip.address()}:${server.address().port}`;
});
});
test('socketServer.close() - when INIT', (t) => {
const socketServer = new MuWebSocketServer({ server });
socketServer.close();
t.equals(socketServer.state, MuSocketServerState.SHUTDOWN, 'should change server state to SHUTDOWN');
t.end();
});
test('socketServer.close() - when RUNNING', (t) => {
const socketServer = new MuWebSocketServer({ server });
socketServer.start({
ready: () => {
socketServer.close();
t.equals(socketServer.state, MuSocketServerState.SHUTDOWN, 'should change server state to SHUTDOWN');
},
connection: noop,
close: (error) => {
t.equals(error, undefined, 'should invoke close handler without error message');
t.end();
},
});
});