mirror of
https://github.com/socketio/socket.io.git
synced 2026-01-13 17:07:54 -05:00
This reverts commit f78a575f66.
This commit contains a breaking change which deviates from semver,
which we try to follow as closely as possible. That's why this change
is reverted and we will rather suggest users to upgrade to v3.
Related: https://github.com/socketio/socket.io/discussions/3741
2477 lines
71 KiB
JavaScript
2477 lines
71 KiB
JavaScript
'use strict';
|
|
|
|
var http = require('http').Server;
|
|
var io = require('../lib');
|
|
var fs = require('fs');
|
|
var join = require('path').join;
|
|
var exec = require('child_process').exec;
|
|
var ioc = require('socket.io-client');
|
|
var request = require('supertest');
|
|
var expect = require('expect.js');
|
|
|
|
// Creates a socket.io client for the given server
|
|
function client(srv, nsp, opts){
|
|
if ('object' == typeof nsp) {
|
|
opts = nsp;
|
|
nsp = null;
|
|
}
|
|
var addr = srv.address();
|
|
if (!addr) addr = srv.listen().address();
|
|
var url = 'ws://localhost:' + addr.port + (nsp || '');
|
|
return ioc(url, opts);
|
|
}
|
|
|
|
describe('socket.io', function(){
|
|
|
|
it.skip('should be the same version as client', function(){
|
|
var version = require('../package').version;
|
|
expect(version).to.be(require('socket.io-client/package').version);
|
|
});
|
|
|
|
describe('set', function() {
|
|
it('should be able to set ping timeout to engine.io', function() {
|
|
var srv = io(http());
|
|
srv.set('heartbeat timeout', 10);
|
|
expect(srv.eio.pingTimeout).to.be(10);
|
|
});
|
|
|
|
it('should be able to set ping interval to engine.io', function() {
|
|
var srv = io(http());
|
|
srv.set('heartbeat interval', 10);
|
|
expect(srv.eio.pingInterval).to.be(10);
|
|
});
|
|
|
|
it('should be able to set transports to engine.io', function() {
|
|
var srv = io(http());
|
|
srv.set('transports', ['polling']);
|
|
expect(srv.eio.transports).to.eql(['polling']);
|
|
});
|
|
|
|
it('should be able to set maxHttpBufferSize to engine.io', function() {
|
|
var srv = io(http());
|
|
srv.set('destroy buffer size', 10);
|
|
expect(srv.eio.maxHttpBufferSize).to.eql(10);
|
|
});
|
|
|
|
it('should be able to set path with setting resource', function(done) {
|
|
var eio = io();
|
|
var srv = http();
|
|
|
|
eio.set('resource', '/random');
|
|
eio.attach(srv);
|
|
|
|
// Check that the server is accessible through the specified path
|
|
request(srv)
|
|
.get('/random/socket.io.js')
|
|
.buffer(true)
|
|
.end(function(err, res){
|
|
if (err) return done(err);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should be able to set origins to engine.io', function() {
|
|
var srv = io(http());
|
|
srv.set('origins', 'http://hostname.com:*');
|
|
expect(srv.origins()).to.be('http://hostname.com:*');
|
|
});
|
|
|
|
it('should be able to set authorization and send error packet', function(done) {
|
|
var httpSrv = http();
|
|
var srv = io(httpSrv);
|
|
srv.set('authorization', function(o, f) { f(null, false); });
|
|
|
|
var socket = client(httpSrv);
|
|
socket.on('connect', function(){
|
|
expect().fail();
|
|
});
|
|
socket.on('error', function(err) {
|
|
expect(err).to.be('Not authorized');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should be able to set authorization and succeed', function(done) {
|
|
var httpSrv = http();
|
|
var srv = io(httpSrv);
|
|
srv.set('authorization', function(o, f) { f(null, true); });
|
|
|
|
srv.on('connection', function(s) {
|
|
s.on('yoyo', function(data) {
|
|
expect(data).to.be('data');
|
|
done();
|
|
});
|
|
});
|
|
|
|
var socket = client(httpSrv);
|
|
socket.on('connect', function(){
|
|
socket.emit('yoyo', 'data');
|
|
});
|
|
|
|
socket.on('error', function(err) {
|
|
expect().fail();
|
|
});
|
|
});
|
|
|
|
it('should set the handshake BC object', function(done){
|
|
var httpSrv = http();
|
|
var srv = io(httpSrv);
|
|
|
|
srv.on('connection', function(s) {
|
|
expect(s.handshake).to.not.be(undefined);
|
|
|
|
// Headers set and has some valid properties
|
|
expect(s.handshake.headers).to.be.an('object');
|
|
expect(s.handshake.headers['user-agent']).to.be('node-XMLHttpRequest');
|
|
|
|
// Time set and is valid looking string
|
|
expect(s.handshake.time).to.be.a('string');
|
|
expect(s.handshake.time.split(' ').length > 0); // Is "multipart" string representation
|
|
|
|
// Address, xdomain, secure, issued and url set
|
|
expect(s.handshake.address).to.contain('127.0.0.1');
|
|
expect(s.handshake.xdomain).to.be.a('boolean');
|
|
expect(s.handshake.secure).to.be.a('boolean');
|
|
expect(s.handshake.issued).to.be.a('number');
|
|
expect(s.handshake.url).to.be.a('string');
|
|
|
|
// Query set and has some right properties
|
|
expect(s.handshake.query).to.be.an('object');
|
|
expect(s.handshake.query.EIO).to.not.be(undefined);
|
|
expect(s.handshake.query.transport).to.not.be(undefined);
|
|
expect(s.handshake.query.t).to.not.be(undefined);
|
|
|
|
done();
|
|
});
|
|
|
|
var socket = client(httpSrv);
|
|
});
|
|
});
|
|
|
|
describe('server attachment', function(){
|
|
describe('http.Server', function(){
|
|
var clientVersion = require('socket.io-client/package').version;
|
|
|
|
it('should serve static files', function(done){
|
|
var srv = http();
|
|
io(srv);
|
|
request(srv)
|
|
.get('/socket.io/socket.io.js')
|
|
.buffer(true)
|
|
.end(function(err, res){
|
|
if (err) return done(err);
|
|
var ctype = res.headers['content-type'];
|
|
expect(ctype).to.be('application/javascript');
|
|
expect(res.headers.etag).to.be('"' + clientVersion + '"');
|
|
expect(res.text).to.match(/engine\.io/);
|
|
expect(res.status).to.be(200);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should handle 304', function(done){
|
|
var srv = http();
|
|
io(srv);
|
|
request(srv)
|
|
.get('/socket.io/socket.io.js')
|
|
.set('If-None-Match', '"' + clientVersion + '"')
|
|
.end(function(err, res){
|
|
if (err) return done(err);
|
|
expect(res.statusCode).to.be(304);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should not serve static files', function(done){
|
|
var srv = http();
|
|
io(srv, { serveClient: false });
|
|
request(srv)
|
|
.get('/socket.io/socket.io.js')
|
|
.expect(400, done);
|
|
});
|
|
|
|
it('should work with #attach', function(done){
|
|
var srv = http(function(req, res){
|
|
res.writeHead(404);
|
|
res.end();
|
|
});
|
|
var sockets = io();
|
|
sockets.attach(srv);
|
|
request(srv)
|
|
.get('/socket.io/socket.io.js')
|
|
.end(function(err, res){
|
|
if (err) return done(err);
|
|
expect(res.status).to.be(200);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('port', function(done){
|
|
it('should be bound', function(done){
|
|
var sockets = io(54010);
|
|
request('http://localhost:54010')
|
|
.get('/socket.io/socket.io.js')
|
|
.expect(200, done);
|
|
});
|
|
|
|
it('should be bound as a string', function(done) {
|
|
var sockets = io('54020');
|
|
request('http://localhost:54020')
|
|
.get('/socket.io/socket.io.js')
|
|
.expect(200, done);
|
|
});
|
|
|
|
it('with listen', function(done){
|
|
var sockets = io().listen(54011);
|
|
request('http://localhost:54011')
|
|
.get('/socket.io/socket.io.js')
|
|
.expect(200, done);
|
|
});
|
|
|
|
it('as a string', function(done){
|
|
var sockets = io().listen('54012');
|
|
request('http://localhost:54012')
|
|
.get('/socket.io/socket.io.js')
|
|
.expect(200, done);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('handshake', function(){
|
|
var request = require('superagent');
|
|
|
|
it('should disallow request when origin defined and none specified', function(done) {
|
|
var sockets = io({ origins: 'http://foo.example:*' }).listen('54013');
|
|
request.get('http://localhost:54013/socket.io/default/')
|
|
.query({ transport: 'polling' })
|
|
.end(function (err, res) {
|
|
expect(res.status).to.be(403);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should disallow request when origin defined and a different one specified', function(done) {
|
|
var sockets = io({ origins: 'http://foo.example:*' }).listen('54014');
|
|
request.get('http://localhost:54014/socket.io/default/')
|
|
.query({ transport: 'polling' })
|
|
.set('origin', 'http://herp.derp')
|
|
.end(function (err, res) {
|
|
expect(res.status).to.be(403);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should allow request when origin defined an the same is specified', function(done) {
|
|
var sockets = io({ origins: 'http://foo.example:*' }).listen('54015');
|
|
request.get('http://localhost:54015/socket.io/default/')
|
|
.set('origin', 'http://foo.example')
|
|
.query({ transport: 'polling' })
|
|
.end(function (err, res) {
|
|
expect(res.status).to.be(200);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should allow request when origin defined as function and same is supplied', function(done) {
|
|
var sockets = io({ origins: function(origin,callback){
|
|
if (origin == 'http://foo.example') {
|
|
return callback(null, true);
|
|
}
|
|
return callback(null, false);
|
|
} }).listen('54016');
|
|
request.get('http://localhost:54016/socket.io/default/')
|
|
.set('origin', 'http://foo.example')
|
|
.query({ transport: 'polling' })
|
|
.end(function (err, res) {
|
|
expect(res.status).to.be(200);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should allow request when origin defined as function and different is supplied', function(done) {
|
|
var sockets = io({ origins: function(origin,callback){
|
|
if (origin == 'http://foo.example') {
|
|
return callback(null, true);
|
|
}
|
|
return callback(null, false);
|
|
} }).listen('54017');
|
|
request.get('http://localhost:54017/socket.io/default/')
|
|
.set('origin', 'http://herp.derp')
|
|
.query({ transport: 'polling' })
|
|
.end(function (err, res) {
|
|
expect(res.status).to.be(403);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should allow request when origin defined as function and no origin is supplied', function(done) {
|
|
var sockets = io({ origins: function(origin,callback){
|
|
if (origin == '*') {
|
|
return callback(null, true);
|
|
}
|
|
return callback(null, false);
|
|
} }).listen('54021');
|
|
request.get('http://localhost:54021/socket.io/default/')
|
|
.query({ transport: 'polling' })
|
|
.end(function (err, res) {
|
|
expect(res.status).to.be(200);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should default to port 443 when protocol is https', function(done) {
|
|
var sockets = io({ origins: 'https://foo.example:443' }).listen('54036');
|
|
request.get('http://localhost:54036/socket.io/default/')
|
|
.set('origin', 'https://foo.example')
|
|
.query({ transport: 'polling' })
|
|
.end(function (err, res) {
|
|
expect(res.status).to.be(200);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should allow request if custom function in opts.allowRequest returns true', function(done){
|
|
var sockets = io(http().listen(54022), { allowRequest: function (req, callback) {
|
|
return callback(null, true);
|
|
}, origins: 'http://foo.example:*' });
|
|
|
|
request.get('http://localhost:54022/socket.io/default/')
|
|
.query({ transport: 'polling' })
|
|
.end(function (err, res) {
|
|
expect(res.status).to.be(200);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should disallow request if custom function in opts.allowRequest returns false', function(done){
|
|
var sockets = io(http().listen(54023), { allowRequest: function (req, callback) {
|
|
return callback(null, false);
|
|
} });
|
|
request.get('http://localhost:54023/socket.io/default/')
|
|
.set('origin', 'http://foo.example')
|
|
.query({ transport: 'polling' })
|
|
.end(function (err, res) {
|
|
expect(res.status).to.be(403);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should allow request when using an array of origins', function(done) {
|
|
io({ origins: [ 'http://foo.example:54024' ] }).listen('54024');
|
|
request.get('http://localhost:54024/socket.io/default/')
|
|
.set('origin', 'http://foo.example:54024')
|
|
.query({ transport: 'polling' })
|
|
.end(function (err, res) {
|
|
expect(res.status).to.be(200);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('close', function(){
|
|
|
|
it('should be able to close sio sending a srv', function(){
|
|
var PORT = 54018;
|
|
var srv = http().listen(PORT);
|
|
var sio = io(srv);
|
|
var net = require('net');
|
|
var server = net.createServer();
|
|
|
|
var clientSocket = client(srv, { reconnection: false });
|
|
|
|
clientSocket.on('disconnect', function init() {
|
|
expect(Object.keys(sio.nsps['/'].sockets).length).to.equal(0);
|
|
server.listen(PORT);
|
|
});
|
|
|
|
clientSocket.on('connect', function init() {
|
|
expect(Object.keys(sio.nsps['/'].sockets).length).to.equal(1);
|
|
sio.close();
|
|
});
|
|
|
|
server.once('listening', function() {
|
|
// PORT should be free
|
|
server.close(function(error){
|
|
expect(error).to.be(undefined);
|
|
});
|
|
});
|
|
|
|
});
|
|
|
|
it('should be able to close sio sending a port', function(){
|
|
var PORT = 54019;
|
|
var sio = io(PORT);
|
|
var net = require('net');
|
|
var server = net.createServer();
|
|
|
|
var clientSocket = ioc('ws://0.0.0.0:' + PORT, { reconnection: false });
|
|
|
|
clientSocket.on('disconnect', function init() {
|
|
expect(Object.keys(sio.nsps['/'].sockets).length).to.equal(0);
|
|
server.listen(PORT);
|
|
});
|
|
|
|
clientSocket.on('connect', function init() {
|
|
expect(Object.keys(sio.nsps['/'].sockets).length).to.equal(1);
|
|
sio.close();
|
|
});
|
|
|
|
server.once('listening', function() {
|
|
// PORT should be free
|
|
server.close(function(error){
|
|
expect(error).to.be(undefined);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('graceful close', function(){
|
|
function fixture(filename) {
|
|
return '"' + process.execPath + '" "' +
|
|
join(__dirname, 'fixtures', filename) + '"';
|
|
}
|
|
|
|
it('should stop socket and timers', function(done){
|
|
exec(fixture('server-close.js'), done);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('namespaces', function(){
|
|
var Socket = require('../lib/socket');
|
|
var Namespace = require('../lib/namespace');
|
|
|
|
it('should be accessible through .sockets', function(){
|
|
var sio = io();
|
|
expect(sio.sockets).to.be.a(Namespace);
|
|
});
|
|
|
|
it('should be aliased', function(){
|
|
var sio = io();
|
|
expect(sio.use).to.be.a('function');
|
|
expect(sio.to).to.be.a('function');
|
|
expect(sio['in']).to.be.a('function');
|
|
expect(sio.emit).to.be.a('function');
|
|
expect(sio.send).to.be.a('function');
|
|
expect(sio.write).to.be.a('function');
|
|
expect(sio.clients).to.be.a('function');
|
|
expect(sio.compress).to.be.a('function');
|
|
expect(sio.json).to.be(sio);
|
|
expect(sio.volatile).to.be(sio);
|
|
expect(sio.sockets.flags).to.eql({ json: true, volatile: true });
|
|
delete sio.sockets.flags;
|
|
});
|
|
|
|
it('should automatically connect', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
socket.on('connect', function(){
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should fire a `connection` event', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(socket){
|
|
expect(socket).to.be.a(Socket);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should fire a `connect` event', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connect', function(socket){
|
|
expect(socket).to.be.a(Socket);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should work with many sockets', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
sio.of('/chat');
|
|
sio.of('/news');
|
|
var chat = client(srv, '/chat');
|
|
var news = client(srv, '/news');
|
|
var total = 2;
|
|
chat.on('connect', function(){
|
|
--total || done();
|
|
});
|
|
news.on('connect', function(){
|
|
--total || done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should be able to equivalently start with "" or "/" on server', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var total = 2;
|
|
sio.of('').on('connection', function(){
|
|
--total || done();
|
|
});
|
|
sio.of('abc').on('connection', function(){
|
|
--total || done();
|
|
});
|
|
var c1 = client(srv, '/');
|
|
var c2 = client(srv, '/abc');
|
|
});
|
|
|
|
it('should be equivalent for "" and "/" on client', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
sio.of('/').on('connection', function(){
|
|
done();
|
|
});
|
|
var c1 = client(srv, '');
|
|
});
|
|
|
|
it('should work with `of` and many sockets', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var chat = client(srv, '/chat');
|
|
var news = client(srv, '/news');
|
|
var total = 2;
|
|
sio.of('/news').on('connection', function(socket){
|
|
expect(socket).to.be.a(Socket);
|
|
--total || done();
|
|
});
|
|
sio.of('/news').on('connection', function(socket){
|
|
expect(socket).to.be.a(Socket);
|
|
--total || done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should work with `of` second param', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var chat = client(srv, '/chat');
|
|
var news = client(srv, '/news');
|
|
var total = 2;
|
|
sio.of('/news', function(socket){
|
|
expect(socket).to.be.a(Socket);
|
|
--total || done();
|
|
});
|
|
sio.of('/news', function(socket){
|
|
expect(socket).to.be.a(Socket);
|
|
--total || done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should disconnect upon transport disconnection', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var chat = client(srv, '/chat');
|
|
var news = client(srv, '/news');
|
|
var total = 2;
|
|
var totald = 2;
|
|
var s;
|
|
sio.of('/news', function(socket){
|
|
socket.on('disconnect', function(reason){
|
|
--totald || done();
|
|
});
|
|
--total || close();
|
|
});
|
|
sio.of('/chat', function(socket){
|
|
s = socket;
|
|
socket.on('disconnect', function(reason){
|
|
--totald || done();
|
|
});
|
|
--total || close();
|
|
});
|
|
function close(){
|
|
s.disconnect(true);
|
|
}
|
|
});
|
|
});
|
|
|
|
it('should disconnect both default and custom namespace upon disconnect', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var lolcats = client(srv, '/lolcats');
|
|
var total = 2;
|
|
var totald = 2;
|
|
var s;
|
|
sio.of('/', function(socket){
|
|
socket.on('disconnect', function(reason){
|
|
--totald || done();
|
|
});
|
|
--total || close();
|
|
});
|
|
sio.of('/lolcats', function(socket){
|
|
s = socket;
|
|
socket.on('disconnect', function(reason){
|
|
--totald || done();
|
|
});
|
|
--total || close();
|
|
});
|
|
function close(){
|
|
s.disconnect(true);
|
|
}
|
|
});
|
|
});
|
|
|
|
it('should not crash while disconnecting socket', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv,'/ns');
|
|
sio.on('connection', function(socket){
|
|
socket.disconnect();
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should fire a `disconnecting` event just before leaving all rooms', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
|
|
sio.on('connection', function(s){
|
|
s.join('a', function(){
|
|
s.disconnect();
|
|
});
|
|
|
|
var total = 2;
|
|
s.on('disconnecting', function(reason){
|
|
expect(Object.keys(s.rooms)).to.eql([s.id, 'a']);
|
|
total--;
|
|
});
|
|
|
|
s.on('disconnect', function(reason){
|
|
expect(Object.keys(s.rooms)).to.eql([]);
|
|
--total || done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should return error connecting to non-existent namespace', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv,'/doesnotexist');
|
|
socket.on('error', function(err) {
|
|
expect(err).to.be('Invalid namespace');
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should not reuse same-namespace connections', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var connections = 0;
|
|
|
|
srv.listen(function() {
|
|
var clientSocket1 = client(srv);
|
|
var clientSocket2 = client(srv);
|
|
sio.on('connection', function() {
|
|
connections++;
|
|
if (connections === 2) {
|
|
done();
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should find all clients in a namespace', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var chatSids = [];
|
|
var otherSid = null;
|
|
srv.listen(function(){
|
|
var c1 = client(srv, '/chat');
|
|
var c2 = client(srv, '/chat', {forceNew: true});
|
|
var c3 = client(srv, '/other', {forceNew: true});
|
|
var total = 3;
|
|
sio.of('/chat').on('connection', function(socket){
|
|
chatSids.push(socket.id);
|
|
--total || getClients();
|
|
});
|
|
sio.of('/other').on('connection', function(socket){
|
|
otherSid = socket.id;
|
|
--total || getClients();
|
|
});
|
|
});
|
|
function getClients() {
|
|
sio.of('/chat').clients(function(error, sids) {
|
|
expect(error).to.not.be.ok();
|
|
expect(sids).to.contain(chatSids[0]);
|
|
expect(sids).to.contain(chatSids[1]);
|
|
expect(sids).to.not.contain(otherSid);
|
|
done();
|
|
});
|
|
}
|
|
});
|
|
|
|
it('should find all clients in a namespace room', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var chatFooSid = null;
|
|
var chatBarSid = null;
|
|
var otherSid = null;
|
|
srv.listen(function(){
|
|
var c1 = client(srv, '/chat');
|
|
var c2 = client(srv, '/chat', {forceNew: true});
|
|
var c3 = client(srv, '/other', {forceNew: true});
|
|
var chatIndex = 0;
|
|
var total = 3;
|
|
sio.of('/chat').on('connection', function(socket){
|
|
if (chatIndex++) {
|
|
socket.join('foo', function() {
|
|
chatFooSid = socket.id;
|
|
--total || getClients();
|
|
});
|
|
} else {
|
|
socket.join('bar', function() {
|
|
chatBarSid = socket.id;
|
|
--total || getClients();
|
|
});
|
|
}
|
|
});
|
|
sio.of('/other').on('connection', function(socket){
|
|
socket.join('foo', function() {
|
|
otherSid = socket.id;
|
|
--total || getClients();
|
|
});
|
|
});
|
|
});
|
|
function getClients() {
|
|
sio.of('/chat').in('foo').clients(function(error, sids) {
|
|
expect(error).to.not.be.ok();
|
|
expect(sids).to.contain(chatFooSid);
|
|
expect(sids).to.not.contain(chatBarSid);
|
|
expect(sids).to.not.contain(otherSid);
|
|
done();
|
|
});
|
|
}
|
|
});
|
|
|
|
it('should find all clients across namespace rooms', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var chatFooSid = null;
|
|
var chatBarSid = null;
|
|
var otherSid = null;
|
|
srv.listen(function(){
|
|
var c1 = client(srv, '/chat');
|
|
var c2 = client(srv, '/chat', {forceNew: true});
|
|
var c3 = client(srv, '/other', {forceNew: true});
|
|
var chatIndex = 0;
|
|
var total = 3;
|
|
sio.of('/chat').on('connection', function(socket){
|
|
if (chatIndex++) {
|
|
socket.join('foo', function() {
|
|
chatFooSid = socket.id;
|
|
--total || getClients();
|
|
});
|
|
} else {
|
|
socket.join('bar', function() {
|
|
chatBarSid = socket.id;
|
|
--total || getClients();
|
|
});
|
|
}
|
|
});
|
|
sio.of('/other').on('connection', function(socket){
|
|
socket.join('foo', function() {
|
|
otherSid = socket.id;
|
|
--total || getClients();
|
|
});
|
|
});
|
|
});
|
|
function getClients() {
|
|
sio.of('/chat').clients(function(error, sids) {
|
|
expect(error).to.not.be.ok();
|
|
expect(sids).to.contain(chatFooSid);
|
|
expect(sids).to.contain(chatBarSid);
|
|
expect(sids).to.not.contain(otherSid);
|
|
done();
|
|
});
|
|
}
|
|
});
|
|
|
|
it('should not emit volatile event after regular event', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
|
|
var counter = 0;
|
|
srv.listen(function(){
|
|
sio.of('/chat').on('connection', function(s){
|
|
// Wait to make sure there are no packets being sent for opening the connection
|
|
setTimeout(function() {
|
|
sio.of('/chat').emit('ev', 'data');
|
|
sio.of('/chat').volatile.emit('ev', 'data');
|
|
}, 50);
|
|
});
|
|
|
|
var socket = client(srv, '/chat');
|
|
socket.on('ev', function() {
|
|
counter++;
|
|
});
|
|
});
|
|
|
|
setTimeout(function() {
|
|
expect(counter).to.be(1);
|
|
done();
|
|
}, 500);
|
|
});
|
|
|
|
it('should emit volatile event', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
|
|
var counter = 0;
|
|
srv.listen(function(){
|
|
sio.of('/chat').on('connection', function(s){
|
|
// Wait to make sure there are no packets being sent for opening the connection
|
|
setTimeout(function() {
|
|
sio.of('/chat').volatile.emit('ev', 'data');
|
|
}, 100);
|
|
});
|
|
|
|
var socket = client(srv, '/chat');
|
|
socket.on('ev', function() {
|
|
counter++;
|
|
});
|
|
});
|
|
|
|
setTimeout(function() {
|
|
expect(counter).to.be(1);
|
|
done();
|
|
}, 500);
|
|
});
|
|
|
|
it('should enable compression by default', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv, '/chat');
|
|
sio.of('/chat').on('connection', function(s){
|
|
s.conn.once('packetCreate', function(packet) {
|
|
expect(packet.options.compress).to.be(true);
|
|
done();
|
|
});
|
|
sio.of('/chat').emit('woot', 'hi');
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should disable compression', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv, '/chat');
|
|
sio.of('/chat').on('connection', function(s){
|
|
s.conn.once('packetCreate', function(packet) {
|
|
expect(packet.options.compress).to.be(false);
|
|
done();
|
|
});
|
|
sio.of('/chat').compress(false).emit('woot', 'hi');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('dynamic namespaces', function () {
|
|
it('should allow connections to dynamic namespaces with a regex', function(done){
|
|
const srv = http();
|
|
const sio = io(srv);
|
|
let count = 0;
|
|
srv.listen(function(){
|
|
const socket = client(srv, '/dynamic-101');
|
|
let dynamicNsp = sio.of(/^\/dynamic-\d+$/).on('connect', (socket) => {
|
|
expect(socket.nsp.name).to.be('/dynamic-101');
|
|
dynamicNsp.emit('hello', 1, '2', { 3: '4'});
|
|
if (++count === 4) done();
|
|
}).use((socket, next) => {
|
|
next();
|
|
if (++count === 4) done();
|
|
});
|
|
socket.on('error', function(err) {
|
|
expect().fail();
|
|
});
|
|
socket.on('connect', () => {
|
|
if (++count === 4) done();
|
|
});
|
|
socket.on('hello', (a, b, c) => {
|
|
expect(a).to.eql(1);
|
|
expect(b).to.eql('2');
|
|
expect(c).to.eql({ 3: '4' });
|
|
if (++count === 4) done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should allow connections to dynamic namespaces with a function', function(done){
|
|
const srv = http();
|
|
const sio = io(srv);
|
|
srv.listen(function(){
|
|
const socket = client(srv, '/dynamic-101');
|
|
sio.of((name, query, next) => next(null, '/dynamic-101' === name));
|
|
socket.on('connect', done);
|
|
});
|
|
});
|
|
|
|
it('should disallow connections when no dynamic namespace matches', function(done){
|
|
const srv = http();
|
|
const sio = io(srv);
|
|
srv.listen(function(){
|
|
const socket = client(srv, '/abc');
|
|
sio.of(/^\/dynamic-\d+$/);
|
|
sio.of((name, query, next) => next(null, '/dynamic-101' === name));
|
|
socket.on('error', (err) => {
|
|
expect(err).to.be('Invalid namespace');
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('socket', function(){
|
|
|
|
it('should not fire events more than once after manually reconnecting', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var clientSocket = client(srv, { reconnection: false });
|
|
clientSocket.on('connect', function init() {
|
|
clientSocket.removeListener('connect', init);
|
|
clientSocket.io.engine.close();
|
|
|
|
clientSocket.connect();
|
|
clientSocket.on('connect', function() {
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should not fire reconnect_failed event more than once when server closed', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var clientSocket = client(srv, { reconnectionAttempts: 3, reconnectionDelay: 10 });
|
|
clientSocket.on('connect', function() {
|
|
srv.close();
|
|
});
|
|
|
|
clientSocket.on('reconnect_failed', function() {
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should receive events', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
s.on('random', function(a, b, c){
|
|
expect(a).to.be(1);
|
|
expect(b).to.be('2');
|
|
expect(c).to.eql([3]);
|
|
done();
|
|
});
|
|
socket.emit('random', 1, '2', [3]);
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should receive message events through `send`', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
s.on('message', function(a){
|
|
expect(a).to.be(1337);
|
|
done();
|
|
});
|
|
socket.send(1337);
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should error with null messages', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
s.on('message', function(a){
|
|
expect(a).to.be(null);
|
|
done();
|
|
});
|
|
socket.send(null);
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should handle transport null messages', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv, { reconnection: false });
|
|
sio.on('connection', function(s){
|
|
s.on('error', function(err){
|
|
expect(err).to.be.an(Error);
|
|
s.on('disconnect', function(reason){
|
|
expect(reason).to.be('forced close');
|
|
done();
|
|
});
|
|
});
|
|
s.client.ondata(null);
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should emit events', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
socket.on('woot', function(a){
|
|
expect(a).to.be('tobi');
|
|
done();
|
|
});
|
|
sio.on('connection', function(s){
|
|
s.emit('woot', 'tobi');
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should emit events with utf8 multibyte character', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
var i = 0;
|
|
socket.on('hoot', function(a){
|
|
expect(a).to.be('utf8 — string');
|
|
i++;
|
|
|
|
if (3 == i) {
|
|
done();
|
|
}
|
|
});
|
|
sio.on('connection', function(s){
|
|
s.emit('hoot', 'utf8 — string');
|
|
s.emit('hoot', 'utf8 — string');
|
|
s.emit('hoot', 'utf8 — string');
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should emit events with binary data', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
var imageData;
|
|
socket.on('doge', function(a){
|
|
expect(Buffer.isBuffer(a)).to.be(true);
|
|
expect(imageData.length).to.equal(a.length);
|
|
expect(imageData[0]).to.equal(a[0]);
|
|
expect(imageData[imageData.length - 1]).to.equal(a[a.length - 1]);
|
|
done();
|
|
});
|
|
sio.on('connection', function(s){
|
|
fs.readFile(join(__dirname, 'support', 'doge.jpg'), function(err, data){
|
|
if (err) return done(err);
|
|
imageData = data;
|
|
s.emit('doge', data);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should emit events with several types of data (including binary)', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
socket.on('multiple', function(a, b, c, d, e, f){
|
|
expect(a).to.be(1);
|
|
expect(Buffer.isBuffer(b)).to.be(true);
|
|
expect(c).to.be('3');
|
|
expect(d).to.eql([4]);
|
|
expect(Buffer.isBuffer(e)).to.be(true);
|
|
expect(Buffer.isBuffer(f[0])).to.be(true);
|
|
expect(f[1]).to.be('swag');
|
|
expect(Buffer.isBuffer(f[2])).to.be(true);
|
|
done();
|
|
});
|
|
sio.on('connection', function(s){
|
|
fs.readFile(join(__dirname, 'support', 'doge.jpg'), function(err, data){
|
|
if (err) return done(err);
|
|
var buf = Buffer.from('asdfasdf', 'utf8');
|
|
s.emit('multiple', 1, data, '3', [4], buf, [data, 'swag', buf]);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should receive events with binary data', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
s.on('buff', function(a){
|
|
expect(Buffer.isBuffer(a)).to.be(true);
|
|
done();
|
|
});
|
|
var buf = Buffer.from('abcdefg', 'utf8');
|
|
socket.emit('buff', buf);
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should receive events with several types of data (including binary)', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
s.on('multiple', function(a, b, c, d, e, f){
|
|
expect(a).to.be(1);
|
|
expect(Buffer.isBuffer(b)).to.be(true);
|
|
expect(c).to.be('3');
|
|
expect(d).to.eql([4]);
|
|
expect(Buffer.isBuffer(e)).to.be(true);
|
|
expect(Buffer.isBuffer(f[0])).to.be(true);
|
|
expect(f[1]).to.be('swag');
|
|
expect(Buffer.isBuffer(f[2])).to.be(true);
|
|
done();
|
|
});
|
|
fs.readFile(join(__dirname, 'support', 'doge.jpg'), function(err, data){
|
|
if (err) return done(err);
|
|
var buf = Buffer.from('asdfasdf', 'utf8');
|
|
socket.emit('multiple', 1, data, '3', [4], buf, [data, 'swag', buf]);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should not emit volatile event after regular event (polling)', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv, { transports: ['polling'] });
|
|
|
|
var counter = 0;
|
|
srv.listen(function(){
|
|
sio.on('connection', function(s){
|
|
s.emit('ev', 'data');
|
|
s.volatile.emit('ev', 'data');
|
|
});
|
|
|
|
var socket = client(srv, { transports: ['polling'] });
|
|
socket.on('ev', function() {
|
|
counter++;
|
|
});
|
|
});
|
|
|
|
setTimeout(function() {
|
|
expect(counter).to.be(1);
|
|
done();
|
|
}, 200);
|
|
});
|
|
|
|
it('should not emit volatile event after regular event (ws)', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv, { transports: ['websocket'] });
|
|
|
|
var counter = 0;
|
|
srv.listen(function(){
|
|
sio.on('connection', function(s){
|
|
s.emit('ev', 'data');
|
|
s.volatile.emit('ev', 'data');
|
|
});
|
|
|
|
var socket = client(srv, { transports: ['websocket'] });
|
|
socket.on('ev', function() {
|
|
counter++;
|
|
});
|
|
});
|
|
|
|
setTimeout(function() {
|
|
expect(counter).to.be(1);
|
|
done();
|
|
}, 200);
|
|
});
|
|
|
|
it('should emit volatile event (polling)', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv, { transports: ['polling'] });
|
|
|
|
var counter = 0;
|
|
srv.listen(function(){
|
|
sio.on('connection', function(s){
|
|
// Wait to make sure there are no packets being sent for opening the connection
|
|
setTimeout(function() {
|
|
s.volatile.emit('ev', 'data');
|
|
}, 100);
|
|
});
|
|
|
|
var socket = client(srv, { transports: ['polling'] });
|
|
socket.on('ev', function() {
|
|
counter++;
|
|
});
|
|
});
|
|
|
|
setTimeout(function() {
|
|
expect(counter).to.be(1);
|
|
done();
|
|
}, 500);
|
|
});
|
|
|
|
it('should emit volatile event (ws)', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv, { transports: ['websocket'] });
|
|
|
|
var counter = 0;
|
|
srv.listen(function(){
|
|
sio.on('connection', function(s){
|
|
// Wait to make sure there are no packets being sent for opening the connection
|
|
setTimeout(function() {
|
|
s.volatile.emit('ev', 'data');
|
|
}, 20);
|
|
});
|
|
|
|
var socket = client(srv, { transports: ['websocket'] });
|
|
socket.on('ev', function() {
|
|
counter++;
|
|
});
|
|
});
|
|
|
|
setTimeout(function() {
|
|
expect(counter).to.be(1);
|
|
done();
|
|
}, 200);
|
|
});
|
|
|
|
it('should emit only one consecutive volatile event (polling)', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv, { transports: ['polling'] });
|
|
|
|
var counter = 0;
|
|
srv.listen(function(){
|
|
sio.on('connection', function(s){
|
|
// Wait to make sure there are no packets being sent for opening the connection
|
|
setTimeout(function() {
|
|
s.volatile.emit('ev', 'data');
|
|
s.volatile.emit('ev', 'data');
|
|
}, 100);
|
|
});
|
|
|
|
var socket = client(srv, { transports: ['polling'] });
|
|
socket.on('ev', function() {
|
|
counter++;
|
|
});
|
|
});
|
|
|
|
setTimeout(function() {
|
|
expect(counter).to.be(1);
|
|
done();
|
|
}, 500);
|
|
});
|
|
|
|
it('should emit only one consecutive volatile event (ws)', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv, { transports: ['websocket'] });
|
|
|
|
var counter = 0;
|
|
srv.listen(function(){
|
|
sio.on('connection', function(s){
|
|
// Wait to make sure there are no packets being sent for opening the connection
|
|
setTimeout(function() {
|
|
s.volatile.emit('ev', 'data');
|
|
s.volatile.emit('ev', 'data');
|
|
}, 20);
|
|
});
|
|
|
|
var socket = client(srv, { transports: ['websocket'] });
|
|
socket.on('ev', function() {
|
|
counter++;
|
|
});
|
|
});
|
|
|
|
setTimeout(function() {
|
|
expect(counter).to.be(1);
|
|
done();
|
|
}, 200);
|
|
});
|
|
|
|
it('should emit regular events after trying a failed volatile event (polling)', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv, { transports: ['polling'] });
|
|
|
|
var counter = 0;
|
|
srv.listen(function(){
|
|
sio.on('connection', function(s){
|
|
// Wait to make sure there are no packets being sent for opening the connection
|
|
setTimeout(function() {
|
|
s.emit('ev', 'data');
|
|
s.volatile.emit('ev', 'data');
|
|
s.emit('ev', 'data');
|
|
}, 20);
|
|
});
|
|
|
|
var socket = client(srv, { transports: ['polling'] });
|
|
socket.on('ev', function() {
|
|
counter++;
|
|
});
|
|
});
|
|
|
|
setTimeout(function() {
|
|
expect(counter).to.be(2);
|
|
done();
|
|
}, 200);
|
|
});
|
|
|
|
it('should emit regular events after trying a failed volatile event (ws)', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv, { transports: ['websocket'] });
|
|
|
|
var counter = 0;
|
|
srv.listen(function(){
|
|
sio.on('connection', function(s){
|
|
// Wait to make sure there are no packets being sent for opening the connection
|
|
setTimeout(function() {
|
|
s.emit('ev', 'data');
|
|
s.volatile.emit('ev', 'data');
|
|
s.emit('ev', 'data');
|
|
}, 20);
|
|
});
|
|
|
|
var socket = client(srv, { transports: ['websocket'] });
|
|
socket.on('ev', function() {
|
|
counter++;
|
|
});
|
|
});
|
|
|
|
setTimeout(function() {
|
|
expect(counter).to.be(2);
|
|
done();
|
|
}, 200);
|
|
});
|
|
|
|
it('should emit message events through `send`', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
socket.on('message', function(a){
|
|
expect(a).to.be('a');
|
|
done();
|
|
});
|
|
sio.on('connection', function(s){
|
|
s.send('a');
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should receive event with callbacks', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
s.on('woot', function(fn){
|
|
fn(1, 2);
|
|
});
|
|
socket.emit('woot', function(a, b){
|
|
expect(a).to.be(1);
|
|
expect(b).to.be(2);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should receive all events emitted from namespaced client immediately and in order', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var total = 0;
|
|
srv.listen(function(){
|
|
sio.of('/chat', function(s){
|
|
s.on('hi', function(letter){
|
|
total++;
|
|
if (total == 2 && letter == 'b') {
|
|
done();
|
|
} else if (total == 1 && letter != 'a') {
|
|
throw new Error('events out of order');
|
|
}
|
|
});
|
|
});
|
|
|
|
var chat = client(srv, '/chat');
|
|
chat.emit('hi', 'a');
|
|
setTimeout(function() {
|
|
chat.emit('hi', 'b');
|
|
}, 50);
|
|
});
|
|
});
|
|
|
|
it('should emit events with callbacks', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
socket.on('hi', function(fn){
|
|
fn();
|
|
});
|
|
s.emit('hi', function(){
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should receive events with args and callback', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
s.on('woot', function(a, b, fn){
|
|
expect(a).to.be(1);
|
|
expect(b).to.be(2);
|
|
fn();
|
|
});
|
|
socket.emit('woot', 1, 2, function(){
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should emit events with args and callback', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
socket.on('hi', function(a, b, fn){
|
|
expect(a).to.be(1);
|
|
expect(b).to.be(2);
|
|
fn();
|
|
});
|
|
s.emit('hi', 1, 2, function(){
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should receive events with binary args and callbacks', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
s.on('woot', function(buf, fn){
|
|
expect(Buffer.isBuffer(buf)).to.be(true);
|
|
fn(1, 2);
|
|
});
|
|
socket.emit('woot', Buffer.alloc(3), function(a, b){
|
|
expect(a).to.be(1);
|
|
expect(b).to.be(2);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should emit events with binary args and callback', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
socket.on('hi', function(a, fn){
|
|
expect(Buffer.isBuffer(a)).to.be(true);
|
|
fn();
|
|
});
|
|
s.emit('hi', Buffer.alloc(4), function(){
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should emit events and receive binary data in a callback', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
socket.on('hi', function(fn){
|
|
fn(Buffer.alloc(1));
|
|
});
|
|
s.emit('hi', function(a){
|
|
expect(Buffer.isBuffer(a)).to.be(true);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should receive events and pass binary data in a callback', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
s.on('woot', function(fn){
|
|
fn(Buffer.alloc(2));
|
|
});
|
|
socket.emit('woot', function(a){
|
|
expect(Buffer.isBuffer(a)).to.be(true);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should have access to the client', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
expect(s.client).to.be.an('object');
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should have access to the connection', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
expect(s.client.conn).to.be.an('object');
|
|
expect(s.conn).to.be.an('object');
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should have access to the request', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
expect(s.client.request.headers).to.be.an('object');
|
|
expect(s.request.headers).to.be.an('object');
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should see query parameters in the request', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function() {
|
|
var socket = client(srv, {query: {key1: 1, key2: 2}});
|
|
sio.on('connection', function(s) {
|
|
var parsed = require('url').parse(s.request.url);
|
|
var query = require('querystring').parse(parsed.query);
|
|
expect(query.key1).to.be('1');
|
|
expect(query.key2).to.be('2');
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should see query parameters sent from secondary namespace connections in handshake object', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var client1 = client(srv);
|
|
var client2 = client(srv, '/connection2', {query: {key1: 'aa', key2: '&=bb'}});
|
|
sio.on('connection', function(s){
|
|
});
|
|
sio.of('/connection2').on('connection', function(s){
|
|
expect(s.handshake.query.key1).to.be('aa');
|
|
expect(s.handshake.query.key2).to.be('&=bb');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should see the query options sent in the Socket.IO handshake (specific to the given socket)', (done) => {
|
|
const srv = http();
|
|
const sio = io(srv);
|
|
const socket = client(srv, '/namespace',{ query: { key1: 'a', key2: 'b' }}); // manager-specific query option
|
|
socket.query = { key2: 'c' }; // socket-specific query option
|
|
|
|
const success = () => {
|
|
sio.close();
|
|
socket.close();
|
|
done();
|
|
}
|
|
|
|
sio.of('/namespace').on('connection', (s) => {
|
|
expect(s.handshake.query.key1).to.be('a'); // in the query params
|
|
expect(s.handshake.query.key2).to.be('c'); // in the Socket.IO handshake
|
|
success();
|
|
});
|
|
});
|
|
|
|
it('should handle very large json', function(done){
|
|
this.timeout(30000);
|
|
var srv = http();
|
|
var sio = io(srv, { perMessageDeflate: false });
|
|
var received = 0;
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
socket.on('big', function(a){
|
|
expect(Buffer.isBuffer(a.json)).to.be(false);
|
|
if (++received == 3)
|
|
done();
|
|
else
|
|
socket.emit('big', a);
|
|
});
|
|
sio.on('connection', function(s){
|
|
fs.readFile(join(__dirname, 'fixtures', 'big.json'), function(err, data){
|
|
if (err) return done(err);
|
|
data = JSON.parse(data);
|
|
s.emit('big', {hello: 'friend', json: data});
|
|
});
|
|
s.on('big', function(a){
|
|
s.emit('big', a);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should handle very large binary data', function(done){
|
|
this.timeout(30000);
|
|
var srv = http();
|
|
var sio = io(srv, { perMessageDeflate: false });
|
|
var received = 0;
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
socket.on('big', function(a){
|
|
expect(Buffer.isBuffer(a.image)).to.be(true);
|
|
if (++received == 3)
|
|
done();
|
|
else
|
|
socket.emit('big', a);
|
|
});
|
|
sio.on('connection', function(s){
|
|
fs.readFile(join(__dirname, 'fixtures', 'big.jpg'), function(err, data){
|
|
if (err) return done(err);
|
|
s.emit('big', {hello: 'friend', image: data});
|
|
});
|
|
s.on('big', function(a){
|
|
expect(Buffer.isBuffer(a.image)).to.be(true);
|
|
s.emit('big', a);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should be able to emit after server close and restart', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
|
|
sio.on('connection', function(socket){
|
|
socket.on('ev', function(data){
|
|
expect(data).to.be('payload');
|
|
done();
|
|
});
|
|
});
|
|
|
|
srv.listen(function(){
|
|
var port = srv.address().port;
|
|
var clientSocket = client(srv, { reconnectionAttempts: 10, reconnectionDelay: 100 });
|
|
clientSocket.once('connect', function(){
|
|
srv.close(function(){
|
|
clientSocket.on('reconnect', function(){
|
|
clientSocket.emit('ev', 'payload');
|
|
});
|
|
sio.listen(port);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should enable compression by default', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv, '/chat');
|
|
sio.of('/chat').on('connection', function(s){
|
|
s.conn.once('packetCreate', function(packet) {
|
|
expect(packet.options.compress).to.be(true);
|
|
done();
|
|
});
|
|
sio.of('/chat').emit('woot', 'hi');
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should disable compression', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv, '/chat');
|
|
sio.of('/chat').on('connection', function(s){
|
|
s.conn.once('packetCreate', function(packet) {
|
|
expect(packet.options.compress).to.be(false);
|
|
done();
|
|
});
|
|
sio.of('/chat').compress(false).emit('woot', 'hi');
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should error with raw binary and warn', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv, { reconnection: false });
|
|
sio.on('connection', function(s){
|
|
s.conn.on('upgrade', function(){
|
|
console.log('\u001b[96mNote: warning expected and normal in test.\u001b[39m');
|
|
socket.io.engine.write('5woooot');
|
|
setTimeout(function(){
|
|
done();
|
|
}, 100);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should not crash when receiving an error packet without handler', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv, { reconnection: false });
|
|
sio.on('connection', function(s){
|
|
s.conn.on('upgrade', function(){
|
|
console.log('\u001b[96mNote: warning expected and normal in test.\u001b[39m');
|
|
socket.io.engine.write('44["handle me please"]');
|
|
setTimeout(function(){
|
|
done();
|
|
}, 100);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should not crash with raw binary', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv, { reconnection: false });
|
|
sio.on('connection', function(s){
|
|
s.once('error', function(err){
|
|
expect(err.message).to.match(/Illegal attachments/);
|
|
done();
|
|
});
|
|
s.conn.on('upgrade', function(){
|
|
socket.io.engine.write('5woooot');
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should handle empty binary packet', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv, { reconnection: false });
|
|
sio.on('connection', function(s){
|
|
s.once('error', function(err){
|
|
expect(err.message).to.match(/Illegal attachments/);
|
|
done();
|
|
});
|
|
s.conn.on('upgrade', function(){
|
|
socket.io.engine.write('5');
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should not crash when messing with Object prototype (and other globals)', function(done){
|
|
Object.prototype.foo = 'bar';
|
|
global.File = '';
|
|
global.Blob = [];
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
|
|
sio.on('connection', function(s){
|
|
s.disconnect(true);
|
|
sio.close();
|
|
setTimeout(function(){
|
|
done();
|
|
}, 100);
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should always trigger the callback (if provided) when joining a room', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
s.join('a', function(){
|
|
s.join('a', done);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
});
|
|
|
|
describe('messaging many', function(){
|
|
it('emits to a namespace', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var total = 2;
|
|
|
|
srv.listen(function(){
|
|
var socket1 = client(srv, { multiplex: false });
|
|
var socket2 = client(srv, { multiplex: false });
|
|
var socket3 = client(srv, '/test');
|
|
socket1.on('a', function(a){
|
|
expect(a).to.be('b');
|
|
--total || done();
|
|
});
|
|
socket2.on('a', function(a){
|
|
expect(a).to.be('b');
|
|
--total || done();
|
|
});
|
|
socket3.on('a', function(){ done(new Error('not')); });
|
|
|
|
var sockets = 3;
|
|
sio.on('connection', function(socket){
|
|
--sockets || emit();
|
|
});
|
|
sio.of('/test', function(socket){
|
|
--sockets || emit();
|
|
});
|
|
|
|
function emit(){
|
|
sio.emit('a', 'b');
|
|
}
|
|
});
|
|
});
|
|
|
|
it('emits binary data to a namespace', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var total = 2;
|
|
|
|
srv.listen(function(){
|
|
var socket1 = client(srv, { multiplex: false });
|
|
var socket2 = client(srv, { multiplex: false });
|
|
var socket3 = client(srv, '/test');
|
|
socket1.on('bin', function(a){
|
|
expect(Buffer.isBuffer(a)).to.be(true);
|
|
--total || done();
|
|
});
|
|
socket2.on('bin', function(a){
|
|
expect(Buffer.isBuffer(a)).to.be(true);
|
|
--total || done();
|
|
});
|
|
socket3.on('bin', function(){ done(new Error('not')); });
|
|
|
|
var sockets = 3;
|
|
sio.on('connection', function(socket){
|
|
--sockets || emit();
|
|
});
|
|
sio.of('/test', function(socket){
|
|
--sockets || emit();
|
|
});
|
|
|
|
function emit(){
|
|
sio.emit('bin', Buffer.alloc(10));
|
|
}
|
|
});
|
|
});
|
|
|
|
it('emits to the rest', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var total = 2;
|
|
|
|
srv.listen(function(){
|
|
var socket1 = client(srv, { multiplex: false });
|
|
var socket2 = client(srv, { multiplex: false });
|
|
var socket3 = client(srv, '/test');
|
|
socket1.on('a', function(a){
|
|
expect(a).to.be('b');
|
|
socket1.emit('finish');
|
|
});
|
|
socket2.emit('broadcast');
|
|
socket2.on('a', function(){ done(new Error('done')); });
|
|
socket3.on('a', function(){ done(new Error('not')); });
|
|
|
|
var sockets = 2;
|
|
sio.on('connection', function(socket){
|
|
socket.on('broadcast', function(){
|
|
socket.broadcast.emit('a', 'b');
|
|
});
|
|
socket.on('finish', function(){
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('emits to rooms', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var total = 2;
|
|
|
|
srv.listen(function(){
|
|
var socket1 = client(srv, { multiplex: false });
|
|
var socket2 = client(srv, { multiplex: false });
|
|
|
|
socket2.on('a', function(){
|
|
done(new Error('not'));
|
|
});
|
|
socket1.on('a', function(){
|
|
done();
|
|
});
|
|
socket1.emit('join', 'woot', function(){
|
|
socket1.emit('emit', 'woot');
|
|
});
|
|
|
|
sio.on('connection', function(socket){
|
|
socket.on('join', function(room, fn){
|
|
socket.join(room, fn);
|
|
});
|
|
|
|
socket.on('emit', function(room){
|
|
sio.in(room).emit('a');
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('emits to rooms avoiding dupes', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var total = 2;
|
|
|
|
srv.listen(function(){
|
|
var socket1 = client(srv, { multiplex: false });
|
|
var socket2 = client(srv, { multiplex: false });
|
|
|
|
socket2.on('a', function(){
|
|
done(new Error('not'));
|
|
});
|
|
socket1.on('a', function(){
|
|
--total || done();
|
|
});
|
|
socket2.on('b', function(){
|
|
--total || done();
|
|
});
|
|
|
|
socket1.emit('join', 'woot');
|
|
socket1.emit('join', 'test');
|
|
socket2.emit('join', 'third', function(){
|
|
socket2.emit('emit');
|
|
});
|
|
|
|
sio.on('connection', function(socket){
|
|
socket.on('join', function(room, fn){
|
|
socket.join(room, fn);
|
|
});
|
|
|
|
socket.on('emit', function(room){
|
|
sio.in('woot').in('test').emit('a');
|
|
sio.in('third').emit('b');
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('broadcasts to rooms', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var total = 2;
|
|
|
|
srv.listen(function(){
|
|
var socket1 = client(srv, { multiplex: false });
|
|
var socket2 = client(srv, { multiplex: false });
|
|
var socket3 = client(srv, { multiplex: false });
|
|
|
|
socket1.emit('join', 'woot');
|
|
socket2.emit('join', 'test');
|
|
socket3.emit('join', 'test', function(){
|
|
socket3.emit('broadcast');
|
|
});
|
|
|
|
socket1.on('a', function(){
|
|
done(new Error('not'));
|
|
});
|
|
socket2.on('a', function(){
|
|
--total || done();
|
|
});
|
|
socket3.on('a', function(){
|
|
done(new Error('not'));
|
|
});
|
|
socket3.on('b', function(){
|
|
--total || done();
|
|
});
|
|
|
|
sio.on('connection', function(socket){
|
|
socket.on('join', function(room, fn){
|
|
socket.join(room, fn);
|
|
});
|
|
|
|
socket.on('broadcast', function(){
|
|
socket.broadcast.to('test').emit('a');
|
|
socket.emit('b');
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('broadcasts binary data to rooms', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var total = 2;
|
|
|
|
srv.listen(function(){
|
|
var socket1 = client(srv, { multiplex: false });
|
|
var socket2 = client(srv, { multiplex: false });
|
|
var socket3 = client(srv, { multiplex: false });
|
|
|
|
socket1.emit('join', 'woot');
|
|
socket2.emit('join', 'test');
|
|
socket3.emit('join', 'test', function(){
|
|
socket3.emit('broadcast');
|
|
});
|
|
|
|
socket1.on('bin', function(data){
|
|
throw new Error('got bin in socket1');
|
|
});
|
|
socket2.on('bin', function(data){
|
|
expect(Buffer.isBuffer(data)).to.be(true);
|
|
--total || done();
|
|
});
|
|
socket2.on('bin2', function(data) {
|
|
throw new Error('socket2 got bin2');
|
|
});
|
|
socket3.on('bin', function(data) {
|
|
throw new Error('socket3 got bin');
|
|
});
|
|
socket3.on('bin2', function(data) {
|
|
expect(Buffer.isBuffer(data)).to.be(true);
|
|
--total || done();
|
|
});
|
|
|
|
sio.on('connection', function(socket){
|
|
socket.on('join', function(room, fn){
|
|
socket.join(room, fn);
|
|
});
|
|
socket.on('broadcast', function(){
|
|
socket.broadcast.to('test').emit('bin', Buffer.alloc(5));
|
|
socket.emit('bin2', Buffer.alloc(5));
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
|
|
it('keeps track of rooms', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
s.join('a', function(){
|
|
expect(Object.keys(s.rooms)).to.eql([s.id, 'a']);
|
|
s.join('b', function(){
|
|
expect(Object.keys(s.rooms)).to.eql([s.id, 'a', 'b']);
|
|
s.join( 'c', function(){
|
|
expect(Object.keys(s.rooms)).to.eql([s.id, 'a', 'b', 'c']);
|
|
s.leave('b', function(){
|
|
expect(Object.keys(s.rooms)).to.eql([s.id, 'a', 'c']);
|
|
s.leaveAll();
|
|
expect(Object.keys(s.rooms)).to.eql([]);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('deletes empty rooms', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
s.join('a', function(){
|
|
expect(s.nsp.adapter.rooms).to.have.key('a');
|
|
s.leave('a', function(){
|
|
expect(s.nsp.adapter.rooms).to.not.have.key('a');
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should properly cleanup left rooms', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
s.join('a', function(){
|
|
expect(Object.keys(s.rooms)).to.eql([s.id, 'a']);
|
|
s.join('b', function(){
|
|
expect(Object.keys(s.rooms)).to.eql([s.id, 'a', 'b']);
|
|
s.leave('unknown', function(){
|
|
expect(Object.keys(s.rooms)).to.eql([s.id, 'a', 'b']);
|
|
s.leaveAll();
|
|
expect(Object.keys(s.rooms)).to.eql([]);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('allows to join several rooms at once', function(done) {
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(s){
|
|
s.join(['a', 'b', 'c'], function(){
|
|
expect(Object.keys(s.rooms)).to.eql([s.id, 'a', 'b', 'c']);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('middleware', function(done){
|
|
var Socket = require('../lib/socket');
|
|
|
|
it('should call functions', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var run = 0;
|
|
sio.use(function(socket, next){
|
|
expect(socket).to.be.a(Socket);
|
|
run++;
|
|
next();
|
|
});
|
|
sio.use(function(socket, next){
|
|
expect(socket).to.be.a(Socket);
|
|
run++;
|
|
next();
|
|
});
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
socket.on('connect', function(){
|
|
expect(run).to.be(2);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should pass errors', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var run = 0;
|
|
sio.use(function(socket, next){
|
|
next(new Error('Authentication error'));
|
|
});
|
|
sio.use(function(socket, next){
|
|
done(new Error('nope'));
|
|
});
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
socket.on('connect', function(){
|
|
done(new Error('nope'));
|
|
});
|
|
socket.on('error', function(err){
|
|
expect(err).to.be('Authentication error');
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should pass `data` of error object', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var run = 0;
|
|
sio.use(function(socket, next){
|
|
var err = new Error('Authentication error');
|
|
err.data = { a: 'b', c: 3 };
|
|
next(err);
|
|
});
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
socket.on('connect', function(){
|
|
done(new Error('nope'));
|
|
});
|
|
socket.on('error', function(err){
|
|
expect(err).to.eql({ a: 'b', c: 3 });
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should only call connection after fns', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
sio.use(function(socket, next){
|
|
socket.name = 'guillermo';
|
|
next();
|
|
});
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
sio.on('connection', function(socket){
|
|
expect(socket.name).to.be('guillermo');
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should only call connection after (lengthy) fns', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var authenticated = false;
|
|
|
|
sio.use(function(socket, next){
|
|
setTimeout(function () {
|
|
authenticated = true;
|
|
next();
|
|
}, 300);
|
|
});
|
|
srv.listen(function(){
|
|
var socket = client(srv);
|
|
socket.on('connect', function(){
|
|
expect(authenticated).to.be(true);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should be ignored if socket gets closed', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var socket;
|
|
sio.use(function(s, next){
|
|
socket.io.engine.on('open', function(){
|
|
socket.io.engine.close();
|
|
s.client.conn.on('close', function(){
|
|
process.nextTick(next);
|
|
setTimeout(function(){
|
|
done();
|
|
}, 50);
|
|
});
|
|
});
|
|
});
|
|
srv.listen(function(){
|
|
socket = client(srv);
|
|
sio.on('connection', function(socket){
|
|
done(new Error('should not fire'));
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should call functions in expected order', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var result = [];
|
|
|
|
sio.use(function(socket, next) {
|
|
result.push(1);
|
|
setTimeout(next, 50);
|
|
});
|
|
sio.use(function(socket, next) {
|
|
result.push(2);
|
|
setTimeout(next, 50);
|
|
});
|
|
sio.of('/chat').use(function(socket, next) {
|
|
result.push(3);
|
|
setTimeout(next, 50);
|
|
});
|
|
sio.of('/chat').use(function(socket, next) {
|
|
result.push(4);
|
|
setTimeout(next, 50);
|
|
});
|
|
|
|
srv.listen(function() {
|
|
var chat = client(srv, '/chat');
|
|
chat.on('connect', function() {
|
|
expect(result).to.eql([1, 2, 3, 4]);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should disable the merge of handshake packets', function(done){
|
|
var srv = http();
|
|
var sio = io();
|
|
sio.use(function(socket, next){
|
|
next();
|
|
});
|
|
sio.listen(srv);
|
|
var socket = client(srv);
|
|
socket.on('connect', function(){
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should work with a custom namespace', (done) => {
|
|
var srv = http();
|
|
var sio = io();
|
|
sio.listen(srv);
|
|
sio.of('/chat').use(function(socket, next){
|
|
next();
|
|
});
|
|
|
|
var count = 0;
|
|
client(srv, '/').on('connect', () => {
|
|
if (++count === 2) done();
|
|
});
|
|
client(srv, '/chat').on('connect', () => {
|
|
if (++count === 2) done();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('socket middleware', function(done){
|
|
var Socket = require('../lib/socket');
|
|
|
|
it('should call functions', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
var run = 0;
|
|
|
|
srv.listen(function(){
|
|
var socket = client(srv, { multiplex: false });
|
|
|
|
socket.emit('join', 'woot');
|
|
|
|
sio.on('connection', function(socket){
|
|
socket.use(function(event, next){
|
|
expect(event).to.eql(['join', 'woot']);
|
|
event.unshift('wrap');
|
|
run++;
|
|
next();
|
|
});
|
|
socket.use(function(event, next){
|
|
expect(event).to.eql(['wrap', 'join', 'woot']);
|
|
run++;
|
|
next();
|
|
});
|
|
socket.on('wrap', function(data1, data2){
|
|
expect(data1).to.be('join');
|
|
expect(data2).to.be('woot');
|
|
expect(run).to.be(2);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should pass errors', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
|
|
srv.listen(function(){
|
|
var clientSocket = client(srv, { multiplex: false });
|
|
|
|
clientSocket.emit('join', 'woot');
|
|
|
|
clientSocket.on('error', function(err){
|
|
expect(err).to.be('Authentication error');
|
|
done();
|
|
});
|
|
|
|
sio.on('connection', function(socket){
|
|
socket.use(function(event, next){
|
|
next(new Error('Authentication error'));
|
|
});
|
|
socket.use(function(event, next){
|
|
done(new Error('nope'));
|
|
});
|
|
|
|
socket.on('join', function(){
|
|
done(new Error('nope'));
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should pass `data` of error object', function(done){
|
|
var srv = http();
|
|
var sio = io(srv);
|
|
|
|
srv.listen(function(){
|
|
var clientSocket = client(srv, { multiplex: false });
|
|
|
|
clientSocket.emit('join', 'woot');
|
|
|
|
clientSocket.on('error', function(err){
|
|
expect(err).to.eql({ a: 'b', c: 3 });
|
|
done();
|
|
});
|
|
|
|
sio.on('connection', function(socket){
|
|
socket.use(function(event, next){
|
|
var err = new Error('Authentication error');
|
|
err.data = { a: 'b', c: 3 };
|
|
next(err);
|
|
});
|
|
|
|
socket.on('join', function(){
|
|
done(new Error('nope'));
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|