koa-socket-2
Version:
Koa meets socket.io connected socket
191 lines (141 loc) • 4.75 kB
JavaScript
'use strict';
const http = require( 'http' );
const tape = require( 'tape' );
const Koa = require( 'koa' );
const ioc = require( 'socket.io-client' );
const socketIO = require( 'socket.io' );
const IO = require( '../' );
const application = require( './helpers/utils' ).application;
const connection = require( './helpers/utils' ).connection;
tape( 'socket.start alters the app to include socket.io', t => {
t.plan( 2 );
const app = new Koa();
const socket = new IO();
socket.attach( app );
t.ok( app.io, 'socket is attached to koa app' );
t.ok( app.server, 'server created linking socket and the koa callback' );
});
tape( 'should not alter a koa app that already has ._io unless called with a namespace', t => {
t.plan( 1 );
const app = new Koa();
const socket = new IO();
app._io = {};
t.throws( () => {
socket.attach( app );
}, null, 'calling .attach throws an error when ._io already exists without a namespace' );
});
tape( 'should work with koa app that already has .server', t => {
t.plan( 1 );
const app = new Koa();
const socket = new IO();
app.server = http.createServer();
socket.attach( app );
t.ok( app.io, 'socket is attached to koa app' );
});
tape( 'shouldn\'t work if app.server exists but it\'s not an http server', t => {
t.plan( 1 );
const app = new Koa();
const socket = new IO();
app.server = {};
t.throws( () => {
socket.attach( app );
}, null, 'calling .attach throws an error when .server already exists but it\'s not an http server' );
});
tape( 'Attaching a namespace to a koa app with socket.io existing is all cool', t => {
t.plan( 2 );
const app = new Koa();
const socket = new IO();
const chat = new IO( 'chat' );
socket.attach( app );
t.doesNotThrow( () => {
chat.attach( app );
t.ok( app.chat, 'the chat namespace has been attached to the app' );
}, null, 'Attaching a new namespace works great' );
});
tape( 'Attaching a namespace to a \'clean\' koa app is fine', t => {
t.plan( 3 );
const app = new Koa();
const chat = new IO( 'chat' );
t.doesNotThrow( () => {
chat.attach( app );
t.ok( app.chat, 'the chat namespace has been attached to the app' );
t.ok( app._io, 'io will be attached, it just isnt listening' );
}, null, 'Attaching only a namespace is fine' );
});
tape( 'Manually creating the socketIO instance and attaching namespaces without a default is fine', t => {
t.plan( 1 );
const app = new Koa();
const chat = new IO( 'chat' );
const server = http.createServer( app.callback() );
const io = socketIO( server );
app._io = io;
t.doesNotThrow( () => {
chat.attach( app );
}, null, 'Attaching a namespace is fine' );
});
tape( 'Attaching a namespace should be done via an options object', t => {
t.plan( 2 );
const app = new Koa();
const chat = new IO({
namespace: 'chat'
});
t.doesNotThrow( () => {
chat.attach( app );
t.ok( app.chat, 'the chat namespace has been attached to the app' );
}, null, 'Attaching only a namespace via options hash is fine' );
});
tape( 'Attaching a namespace will attach the IO class', t => {
t.plan( 2 );
const app = new Koa();
const chat = new IO( 'chat' );
chat.attach( app );
t.ok( app.chat, 'the chat namespace has been attached to the app' );
t.ok( app.chat instanceof IO, 'an IO instance has been attached' );
});
tape( 'Namespaces can be hidden from the app object', t => {
t.plan( 2 );
const app = new Koa();
const chat = new IO({
namespace: 'chat',
hidden: true
});
chat.attach( app );
const srv = app.server.listen();
const client = ioc( 'ws://localhost:' + srv.address().port + '/chat', {
transports: [ 'websocket' ]
});
client.on( 'disconnect', () => {
srv.close();
});
client.on( 'connect', () => {
client.disconnect();
});
chat.on( 'connection', ctx => {
t.notOk( app.chat, 'chat should exist but not be available on the app' );
t.ok( true, 'Client can connect to the chat namespace even though it is not available on the app' );
});
});
tape( 'The default namespace can not be hidden, app.io must be attached to app', t => {
t.plan( 1 );
const app = new Koa();
const io = new IO({
hidden: true
});
t.throws( () => {
io.attach( app );
}, null, 'Attaching a hidden default instance will throw' );
});
tape( 'Calling app.listen calls app.server.listen', t => {
t.plan( 2 );
const app = new Koa();
const io = new IO();
io.attach( app );
app.server.listen = function() {
t.pass( 'Calling app.listen called app.server.listen' );
};
t.doesNotThrow( () => {
var srv = app.listen( () => {
srv.close();
})
}, 'Calling app.listen does not throw' );
});