PageRenderTime 67ms CodeModel.GetById 3ms app.highlight 55ms RepoModel.GetById 2ms app.codeStats 0ms

/test/socket.io.js

https://github.com/narcisoguillen/socket.io
JavaScript | 1325 lines | 1196 code | 124 blank | 5 comment | 55 complexity | 0b051850d7629b5e93df412375ae4e8b MD5 | raw file
   1
   2var http = require('http').Server;
   3var io = require('..');
   4var fs = require('fs');
   5var join = require('path').join;
   6var ioc = require('socket.io-client');
   7var request = require('supertest');
   8var expect = require('expect.js');
   9
  10// creates a socket.io client for the given server
  11function client(srv, nsp, opts){
  12  if ('object' == typeof nsp) {
  13    opts = nsp;
  14    nsp = null;
  15  }
  16  var addr = srv.address();
  17  if (!addr) addr = srv.listen().address();
  18  var url = 'ws://' + addr.address + ':' + addr.port + (nsp || '');
  19  return ioc(url, opts);
  20}
  21
  22describe('socket.io', function(){
  23
  24  it('should be the same version as client', function(){
  25    var version = require('../package').version;
  26    expect(version).to.be(require('socket.io-client/package').version);
  27  });
  28
  29  describe('set', function() {
  30    it('should be able to set ping timeout to engine.io', function() {
  31      var srv = io(http());
  32      srv.set('heartbeat timeout', 10);
  33      expect(srv.eio.pingTimeout).to.be(10);
  34    });
  35
  36    it('should be able to set ping interval to engine.io', function() {
  37      var srv = io(http());
  38      srv.set('heartbeat interval', 10);
  39      expect(srv.eio.pingInterval).to.be(10);
  40    });
  41
  42    it('should be able to set transports to engine.io', function() {
  43      var srv = io(http());
  44      srv.set('transports', ['polling']);
  45      expect(srv.eio.transports).to.eql(['polling']);
  46    });
  47
  48    it('should be able to set maxHttpBufferSize to engine.io', function() {
  49      var srv = io(http());
  50      srv.set('destroy buffer size', 10);
  51      expect(srv.eio.maxHttpBufferSize).to.eql(10);
  52    });
  53
  54    it('should be able to set path with setting resource', function() {
  55      var srv = io(http());
  56      srv.set('resource', '/random');
  57      expect(srv.path()).to.be('/random');
  58    });
  59
  60    it('should be able to set origins to engine.io', function() {
  61      var srv = io(http());
  62      srv.set('origins', 'http://hostname.com:*');
  63      expect(srv.origins()).to.be('http://hostname.com:*');
  64    });
  65
  66    it('should be able to set authorization and send error packet', function(done) {
  67      var httpSrv = http();
  68      var srv = io(httpSrv);
  69      srv.set('authorization', function(o, f) { f(null, false); });
  70
  71      var socket = client(httpSrv);
  72      socket.on('connect', function(){
  73        expect().fail();
  74      });
  75      socket.on('error', function(err) {
  76        expect(err).to.be('Not authorized');
  77        done();
  78      });
  79    });
  80
  81    it('should be able to set authorization and succeed', function(done) {
  82      var httpSrv = http();
  83      var srv = io(httpSrv);
  84      srv.set('authorization', function(o, f) { f(null, true); });
  85
  86      srv.on('connection', function(s) {
  87        s.on('yoyo', function(data) {
  88          expect(data).to.be('data');
  89          done();
  90        });
  91      });
  92
  93      var socket = client(httpSrv);
  94      socket.on('connect', function(){
  95        socket.emit('yoyo', 'data');
  96      });
  97
  98      socket.on('error', function(err) {
  99        expect().fail();
 100      });
 101    });
 102
 103    it('should set the handshake BC object', function(done){
 104      var httpSrv = http();
 105      var srv = io(httpSrv);
 106
 107      srv.on('connection', function(s) {
 108        expect(s.handshake).to.not.be(undefined);
 109
 110        // Headers set and has some valid properties
 111        expect(s.handshake.headers).to.be.an('object');
 112        expect(s.handshake.headers['user-agent']).to.be('node-XMLHttpRequest');
 113
 114        // Time set and is valid looking string
 115        expect(s.handshake.time).to.be.a('string');
 116        expect(s.handshake.time.split(' ').length > 0); // Is "multipart" string representation
 117
 118        // Address, xdomain, secure, issued and url set
 119        expect(s.handshake.address).to.not.be(undefined);
 120        expect(s.handshake.xdomain).to.be.a('boolean');
 121        expect(s.handshake.secure).to.be.a('boolean');
 122        expect(s.handshake.issued).to.be.a('number');
 123        expect(s.handshake.url).to.be.a('string');
 124
 125        // Query set and has some right properties
 126        expect(s.handshake.query).to.be.an('object');
 127        expect(s.handshake.query.EIO).to.not.be(undefined);
 128        expect(s.handshake.query.transport).to.not.be(undefined);
 129        expect(s.handshake.query.t).to.not.be(undefined);
 130
 131        done();
 132      });
 133
 134      var socket = client(httpSrv);
 135    });
 136  });
 137
 138  describe('server attachment', function(){
 139    describe('http.Server', function(){
 140      var clientVersion = require('socket.io-client/package').version;
 141
 142      it('should serve static files', function(done){
 143        var srv = http();
 144        io(srv);
 145        request(srv)
 146        .get('/socket.io/socket.io.js')
 147        .buffer(true)
 148        .end(function(err, res){
 149          if (err) return done(err);
 150          var ctype = res.headers['content-type'];
 151          expect(ctype).to.be('application/javascript');
 152          expect(res.headers.etag).to.be(clientVersion);
 153          expect(res.text).to.match(/engine\.io/);
 154          expect(res.status).to.be(200);
 155          done();
 156        });
 157      });
 158
 159      it('should handle 304', function(done){
 160        var srv = http();
 161        io(srv);
 162        request(srv)
 163        .get('/socket.io/socket.io.js')
 164        .set('ETag', clientVersion)
 165        .end(function(err, res){
 166          if (err) return done(err);
 167          expect(res.statusCode).to.be(304);
 168          done();
 169        });
 170      });
 171
 172      it('should not serve static files', function(done){
 173        var srv = http();
 174        io(srv, { serveClient: false });
 175        request(srv)
 176        .get('/socket.io/socket.io.js')
 177        .expect(400, done);
 178      });
 179
 180      it('should work with #attach', function(done){
 181        var srv = http(function(req, res){
 182          res.writeHead(404);
 183          res.end();
 184        });
 185        var sockets = io();
 186        sockets.attach(srv);
 187        request(srv)
 188        .get('/socket.io/socket.io.js')
 189        .end(function(err, res){
 190          if (err) return done(err);
 191          expect(res.status).to.be(200);
 192          done();
 193        });
 194      });
 195    });
 196
 197    describe('port', function(done){
 198      it('should be bound', function(done){
 199        var sockets = io(54010);
 200        request('http://localhost:54010')
 201        .get('/socket.io/socket.io.js')
 202        .expect(200, done);
 203      });
 204
 205      it('should be bound as a string', function(done) {
 206        var sockets = io('54020');
 207        request('http://localhost:54020')
 208        .get('/socket.io/socket.io.js')
 209        .expect(200, done);
 210      });
 211
 212      it('with listen', function(done){
 213        var sockets = io().listen(54011);
 214        request('http://localhost:54011')
 215        .get('/socket.io/socket.io.js')
 216        .expect(200, done);
 217      });
 218
 219      it('as a string', function(done){
 220        var sockets = io().listen('54012');
 221        request('http://localhost:54012')
 222        .get('/socket.io/socket.io.js')
 223        .expect(200, done);
 224      });
 225    });
 226  });
 227
 228  describe('handshake', function(){
 229    var request = require('superagent');
 230
 231    it('should disallow request when origin defined and none specified', function(done) {
 232      var sockets = io({ origins: 'http://foo.example:*' }).listen('54013');
 233      request.get('http://localhost:54013/socket.io/default/')
 234       .query({ transport: 'polling' })
 235       .end(function (err, res) {
 236          expect(res.status).to.be(400);
 237          done();
 238        });
 239    });
 240
 241    it('should disallow request when origin defined and a different one specified', function(done) {
 242      var sockets = io({ origins: 'http://foo.example:*' }).listen('54014');
 243      request.get('http://localhost:54014/socket.io/default/')
 244       .query({ transport: 'polling' })
 245       .set('origin', 'http://herp.derp')
 246       .end(function (err, res) {
 247          expect(res.status).to.be(400);
 248          done();
 249       });
 250    });
 251
 252    it('should allow request when origin defined an the same is specified', function(done) {
 253      var sockets = io({ origins: 'http://foo.example:*' }).listen('54015');
 254      request.get('http://localhost:54015/socket.io/default/')
 255       .set('origin', 'http://foo.example')
 256       .query({ transport: 'polling' })
 257       .end(function (err, res) {
 258          expect(res.status).to.be(200);
 259          done();
 260        });
 261    });
 262  });
 263
 264  describe('namespaces', function(){
 265    var Socket = require('../lib/socket');
 266    var Namespace = require('../lib/namespace');
 267
 268    describe('default', function(){
 269      it('should be accessible through .sockets', function(){
 270        var sio = io();
 271        expect(sio.sockets).to.be.a(Namespace);
 272      });
 273
 274      it('should be aliased', function(){
 275        var sio = io();
 276        expect(sio.use).to.be.a('function');
 277        expect(sio.to).to.be.a('function');
 278        expect(sio['in']).to.be.a('function');
 279        expect(sio.emit).to.be.a('function');
 280        expect(sio.send).to.be.a('function');
 281        expect(sio.write).to.be.a('function');
 282      });
 283
 284      it('should automatically connect', function(done){
 285        var srv = http();
 286        var sio = io(srv);
 287        srv.listen(function(){
 288          var socket = client(srv);
 289          socket.on('connect', function(){
 290            done();
 291          });
 292        });
 293      });
 294
 295      it('should fire a `connection` event', function(done){
 296        var srv = http();
 297        var sio = io(srv);
 298        srv.listen(function(){
 299          var socket = client(srv);
 300          sio.on('connection', function(socket){
 301            expect(socket).to.be.a(Socket);
 302            done();
 303          });
 304        });
 305      });
 306
 307      it('should fire a `connect` event', function(done){
 308        var srv = http();
 309        var sio = io(srv);
 310        srv.listen(function(){
 311          var socket = client(srv);
 312          sio.on('connect', function(socket){
 313            expect(socket).to.be.a(Socket);
 314            done();
 315          });
 316        });
 317      });
 318
 319      it('should work with many sockets', function(done){
 320        var srv = http();
 321        var sio = io(srv);
 322        srv.listen(function(){
 323          var chat = client(srv, '/chat');
 324          var news = client(srv, '/news');
 325          var total = 2;
 326          chat.on('connect', function(){
 327            --total || done();
 328          });
 329          news.on('connect', function(){
 330            --total || done();
 331          });
 332        });
 333      });
 334
 335      it('should work with `of` and many sockets', function(done){
 336        var srv = http();
 337        var sio = io(srv);
 338        srv.listen(function(){
 339          var chat = client(srv, '/chat');
 340          var news = client(srv, '/news');
 341          var total = 2;
 342          sio.of('/news').on('connection', function(socket){
 343            expect(socket).to.be.a(Socket);
 344            --total || done();
 345          });
 346          sio.of('/news').on('connection', function(socket){
 347            expect(socket).to.be.a(Socket);
 348            --total || done();
 349          });
 350        });
 351      });
 352
 353      it('should work with `of` second param', function(done){
 354        var srv = http();
 355        var sio = io(srv);
 356        srv.listen(function(){
 357          var chat = client(srv, '/chat');
 358          var news = client(srv, '/news');
 359          var total = 2;
 360          sio.of('/news', function(socket){
 361            expect(socket).to.be.a(Socket);
 362            --total || done();
 363          });
 364          sio.of('/news', function(socket){
 365            expect(socket).to.be.a(Socket);
 366            --total || done();
 367          });
 368        });
 369      });
 370
 371      it('should disconnect upon transport disconnection', function(done){
 372        var srv = http();
 373        var sio = io(srv);
 374        srv.listen(function(){
 375          var chat = client(srv, '/chat');
 376          var news = client(srv, '/news');
 377          var total = 2;
 378          var totald = 2;
 379          var s;
 380          sio.of('/news', function(socket){
 381            socket.on('disconnect', function(reason){
 382              --totald || done();
 383            });
 384            --total || close();
 385          });
 386          sio.of('/chat', function(socket){
 387            s = socket;
 388            socket.on('disconnect', function(reason){
 389              --totald || done();
 390            });
 391            --total || close();
 392          });
 393          function close(){
 394            s.disconnect(true);
 395          }
 396        });
 397      });
 398
 399      it('should disconnect both default and custom namespace upon disconnect', function(done){
 400        var srv = http();
 401        var sio = io(srv);
 402        srv.listen(function(){
 403          var lolcats = client(srv, '/lolcats');
 404          var total = 2;
 405          var totald = 2;
 406          var s;
 407          sio.of('/', function(socket){
 408            socket.on('disconnect', function(reason){
 409              --totald || done();
 410            });
 411            --total || close();
 412          });
 413          sio.of('/lolcats', function(socket){
 414            s = socket;
 415            socket.on('disconnect', function(reason){
 416              --totald || done();
 417            });
 418            --total || close();
 419          });
 420          function close(){
 421            s.disconnect(true);
 422          }
 423        });
 424      });
 425    });
 426  });
 427
 428  describe('socket', function(){
 429
 430    it('should not fire events more than once after manually reconnecting', function(done) {
 431      var srv = http();
 432      var sio = io(srv);
 433      srv.listen(function(){
 434        var clientSocket = client(srv, { reconnection: false });
 435        clientSocket.on('connect', function init() {
 436          clientSocket.removeListener('connect', init);
 437          clientSocket.io.engine.close();
 438
 439          clientSocket.connect();
 440          clientSocket.on('connect', function() {
 441            done();
 442          });
 443        });
 444      });
 445    });
 446
 447    it('should not fire reconnect_failed event more than once when server closed', function(done) {
 448      var srv = http();
 449      var sio = io(srv);
 450      srv.listen(function(){
 451        var clientSocket = client(srv, { reconnectionAttempts: 3, reconnectionDelay: 10 });
 452        clientSocket.on('connect', function() {
 453          srv.close();
 454        });
 455
 456        clientSocket.on('reconnect_failed', function() {
 457          done();
 458        });
 459      });
 460    });
 461
 462    it('should receive events', function(done){
 463      var srv = http();
 464      var sio = io(srv);
 465      srv.listen(function(){
 466        var socket = client(srv);
 467        sio.on('connection', function(s){
 468          s.on('random', function(a, b, c){
 469            expect(a).to.be(1);
 470            expect(b).to.be('2');
 471            expect(c).to.eql([3]);
 472            done();
 473          });
 474          socket.emit('random', 1, '2', [3]);
 475        });
 476      });
 477    });
 478
 479    it('should receive message events through `send`', function(done){
 480      var srv = http();
 481      var sio = io(srv);
 482      srv.listen(function(){
 483        var socket = client(srv);
 484        sio.on('connection', function(s){
 485          s.on('message', function(a){
 486            expect(a).to.be(1337);
 487            done();
 488          });
 489          socket.send(1337);
 490        });
 491      });
 492    });
 493
 494    it('should emit events', function(done){
 495      var srv = http();
 496      var sio = io(srv);
 497      srv.listen(function(){
 498        var socket = client(srv);
 499        socket.on('woot', function(a){
 500          expect(a).to.be('tobi');
 501          done();
 502        });
 503        sio.on('connection', function(s){
 504          s.emit('woot', 'tobi');
 505        });
 506      });
 507    });
 508
 509    it('should emit events with utf8 multibyte character', function(done) {
 510      var srv = http();
 511      var sio = io(srv);
 512      srv.listen(function(){
 513        var socket = client(srv);
 514        var i = 0;
 515        socket.on('hoot', function(a){
 516          expect(a).to.be('utf8 — string');
 517          i++;
 518
 519          if (3 == i) {
 520            done();
 521          }
 522        });
 523        sio.on('connection', function(s){
 524          s.emit('hoot', 'utf8 — string');
 525          s.emit('hoot', 'utf8 — string');
 526          s.emit('hoot', 'utf8 — string');
 527        });
 528      });
 529    });
 530
 531    it('should emit events with binary data', function(done){
 532      var srv = http();
 533      var sio = io(srv);
 534      srv.listen(function(){
 535        var socket = client(srv);
 536        var imageData;
 537        socket.on('doge', function(a){
 538          expect(Buffer.isBuffer(a)).to.be(true);
 539          expect(imageData.length).to.equal(a.length);
 540          expect(imageData[0]).to.equal(a[0]);
 541          expect(imageData[imageData.length - 1]).to.equal(a[a.length - 1]);
 542          done();
 543        });
 544        sio.on('connection', function(s){
 545          fs.readFile(join(__dirname, 'support', 'doge.jpg'), function(err, data){
 546            if (err) return done(err);
 547            imageData = data;
 548            s.emit('doge', data);
 549          });
 550        });
 551      });
 552    });
 553
 554    it('should emit events with several types of data (including binary)', function(done){
 555      var srv = http();
 556      var sio = io(srv);
 557      srv.listen(function(){
 558        var socket = client(srv);
 559        socket.on('multiple', function(a, b, c, d, e, f){
 560          expect(a).to.be(1);
 561          expect(Buffer.isBuffer(b)).to.be(true);
 562          expect(c).to.be('3');
 563          expect(d).to.eql([4]);
 564          expect(Buffer.isBuffer(e)).to.be(true);
 565          expect(Buffer.isBuffer(f[0])).to.be(true);
 566          expect(f[1]).to.be('swag');
 567          expect(Buffer.isBuffer(f[2])).to.be(true);
 568          done();
 569        });
 570        sio.on('connection', function(s){
 571          fs.readFile(join(__dirname, 'support', 'doge.jpg'), function(err, data){
 572            if (err) return done(err);
 573            var buf = new Buffer('asdfasdf', 'utf8');
 574            s.emit('multiple', 1, data, '3', [4], buf, [data, 'swag', buf]);
 575          });
 576        });
 577      });
 578    });
 579
 580    it('should receive events with binary data', function(done){
 581      var srv = http();
 582      var sio = io(srv);
 583      srv.listen(function(){
 584        var socket = client(srv);
 585        sio.on('connection', function(s){
 586          s.on('buff', function(a){
 587            expect(Buffer.isBuffer(a)).to.be(true);
 588            done();
 589          });
 590          var buf = new Buffer('abcdefg', 'utf8');
 591          socket.emit('buff', buf);
 592        });
 593      });
 594    });
 595
 596    it('should receive events with several types of data (including binary)', function(done){
 597      var srv = http();
 598      var sio = io(srv);
 599      srv.listen(function(){
 600        var socket = client(srv);
 601        sio.on('connection', function(s){
 602          s.on('multiple', function(a, b, c, d, e, f){
 603          expect(a).to.be(1);
 604          expect(Buffer.isBuffer(b)).to.be(true);
 605          expect(c).to.be('3');
 606          expect(d).to.eql([4]);
 607          expect(Buffer.isBuffer(e)).to.be(true);
 608          expect(Buffer.isBuffer(f[0])).to.be(true);
 609          expect(f[1]).to.be('swag');
 610          expect(Buffer.isBuffer(f[2])).to.be(true);
 611          done();
 612          });
 613          fs.readFile(join(__dirname, 'support', 'doge.jpg'), function(err, data){
 614            if (err) return done(err);
 615            var buf = new Buffer('asdfasdf', 'utf8');
 616            socket.emit('multiple', 1, data, '3', [4], buf, [data, 'swag', buf]);
 617          });
 618        });
 619      });
 620    });
 621
 622    it('should emit message events through `send`', function(done){
 623      var srv = http();
 624      var sio = io(srv);
 625      srv.listen(function(){
 626        var socket = client(srv);
 627        socket.on('message', function(a){
 628          expect(a).to.be('a');
 629          done();
 630        });
 631        sio.on('connection', function(s){
 632          s.send('a');
 633        });
 634      });
 635    });
 636
 637    it('should receive event with callbacks', function(done){
 638      var srv = http();
 639      var sio = io(srv);
 640      srv.listen(function(){
 641        var socket = client(srv);
 642        sio.on('connection', function(s){
 643          s.on('woot', function(fn){
 644            fn(1, 2);
 645          });
 646          socket.emit('woot', function(a, b){
 647            expect(a).to.be(1);
 648            expect(b).to.be(2);
 649            done();
 650          });
 651        });
 652      });
 653    });
 654
 655    it('should receive all events emitted from namespaced client immediately and in order', function(done) {
 656      var srv = http();
 657      var sio = io(srv);
 658      var total = 0;
 659      srv.listen(function(){
 660        sio.of('/chat', function(s){
 661          s.on('hi', function(letter){
 662            total++;
 663            if (total == 2 && letter == 'b') {
 664              done();
 665            } else if (total == 1 && letter != 'a') {
 666              throw new Error('events out of order');
 667            }
 668          });
 669        });
 670
 671        var chat = client(srv, '/chat');
 672        chat.emit('hi', 'a');
 673        setTimeout(function() {
 674          chat.emit('hi', 'b');
 675        }, 50);
 676      });
 677    });
 678
 679    it('should emit events with callbacks', function(done){
 680      var srv = http();
 681      var sio = io(srv);
 682      srv.listen(function(){
 683        var socket = client(srv);
 684        sio.on('connection', function(s){
 685          socket.on('hi', function(fn){
 686            fn();
 687          });
 688          s.emit('hi', function(){
 689            done();
 690          });
 691        });
 692      });
 693    });
 694
 695    it('should receive events with args and callback', function(done){
 696      var srv = http();
 697      var sio = io(srv);
 698      srv.listen(function(){
 699        var socket = client(srv);
 700        sio.on('connection', function(s){
 701          s.on('woot', function(a, b, fn){
 702            expect(a).to.be(1);
 703            expect(b).to.be(2);
 704            fn();
 705          });
 706          socket.emit('woot', 1, 2, function(){
 707            done();
 708          });
 709        });
 710      });
 711    });
 712
 713    it('should emit events with args and callback', function(done){
 714      var srv = http();
 715      var sio = io(srv);
 716      srv.listen(function(){
 717        var socket = client(srv);
 718        sio.on('connection', function(s){
 719          socket.on('hi', function(a, b, fn){
 720            expect(a).to.be(1);
 721            expect(b).to.be(2);
 722            fn();
 723          });
 724          s.emit('hi', 1, 2, function(){
 725            done();
 726          });
 727        });
 728      });
 729    });
 730
 731    it('should receive events with binary args and callbacks', function(done) {
 732      var srv = http();
 733      var sio = io(srv);
 734      srv.listen(function(){
 735        var socket = client(srv);
 736        sio.on('connection', function(s){
 737          s.on('woot', function(buf, fn){
 738            expect(Buffer.isBuffer(buf)).to.be(true);
 739            fn(1, 2);
 740          });
 741          socket.emit('woot', new Buffer(3), function(a, b){
 742            expect(a).to.be(1);
 743            expect(b).to.be(2);
 744            done();
 745          });
 746        });
 747      });
 748    });
 749
 750    it('should emit events with binary args and callback', function(done){
 751      var srv = http();
 752      var sio = io(srv);
 753      srv.listen(function(){
 754        var socket = client(srv);
 755        sio.on('connection', function(s){
 756          socket.on('hi', function(a, fn){
 757            expect(Buffer.isBuffer(a)).to.be(true);
 758            fn();
 759          });
 760          s.emit('hi', new Buffer(4), function(){
 761            done();
 762          });
 763        });
 764      });
 765    });
 766
 767    it('should emit events and receive binary data in a callback', function(done) {
 768      var srv = http();
 769      var sio = io(srv);
 770      srv.listen(function(){
 771        var socket = client(srv);
 772        sio.on('connection', function(s){
 773          socket.on('hi', function(fn){
 774            fn(new Buffer(1));
 775          });
 776          s.emit('hi', function(a){
 777            expect(Buffer.isBuffer(a)).to.be(true);
 778            done();
 779          });
 780        });
 781      });
 782    });
 783
 784    it('should receive events and pass binary data in a callback', function(done) {
 785      var srv = http();
 786      var sio = io(srv);
 787      srv.listen(function(){
 788        var socket = client(srv);
 789        sio.on('connection', function(s){
 790          s.on('woot', function(fn){
 791            fn(new Buffer(2));
 792          });
 793          socket.emit('woot', function(a){
 794            expect(Buffer.isBuffer(a)).to.be(true);
 795            done();
 796          });
 797        });
 798      });
 799    });
 800
 801    it('should have access to the client', function(done){
 802      var srv = http();
 803      var sio = io(srv);
 804      srv.listen(function(){
 805        var socket = client(srv);
 806        sio.on('connection', function(s){
 807          expect(s.client).to.be.an('object');
 808          done();
 809        });
 810      });
 811    });
 812
 813    it('should have access to the connection', function(done){
 814      var srv = http();
 815      var sio = io(srv);
 816      srv.listen(function(){
 817        var socket = client(srv);
 818        sio.on('connection', function(s){
 819          expect(s.client.conn).to.be.an('object');
 820          expect(s.conn).to.be.an('object');
 821          done();
 822        });
 823      });
 824    });
 825
 826    it('should have access to the request', function(done){
 827      var srv = http();
 828      var sio = io(srv);
 829      srv.listen(function(){
 830        var socket = client(srv);
 831        sio.on('connection', function(s){
 832          expect(s.client.request.headers).to.be.an('object');
 833          expect(s.request.headers).to.be.an('object');
 834          done();
 835        });
 836      });
 837    });
 838
 839    it('should see query parameters in the request', function(done) {
 840      var srv = http();
 841      var sio = io(srv);
 842      srv.listen(function() {
 843        var addr = srv.listen().address();
 844        var url = 'ws://' + addr.address + ':' + addr.port + '?key1=1&key2=2';
 845        var socket = ioc(url);
 846        sio.on('connection', function(s) {
 847          var parsed = require('url').parse(s.request.url);
 848          var query = require('querystring').parse(parsed.query);
 849          expect(query.key1).to.be('1');
 850          expect(query.key2).to.be('2');
 851          done();
 852        });
 853      });
 854    });
 855
 856    it('should handle very large json', function(done){
 857      this.timeout();
 858      var srv = http();
 859      var sio = io(srv);
 860      var received = 0;
 861      srv.listen(function(){
 862        var socket = client(srv);
 863        socket.on('big', function(a){
 864          expect(Buffer.isBuffer(a.json)).to.be(false);
 865          if (++received == 3)
 866            done();
 867          else
 868            socket.emit('big', a);
 869        });
 870        sio.on('connection', function(s){
 871          fs.readFile(join(__dirname, 'fixtures', 'big.json'), function(err, data){
 872            if (err) return done(err);
 873            data = JSON.parse(data);
 874            s.emit('big', {hello: 'friend', json: data});
 875          });
 876          s.on('big', function(a){
 877            s.emit('big', a);
 878          });
 879        });
 880      });
 881    });
 882
 883    it('should handle very large binary data', function(done){
 884      var srv = http();
 885      var sio = io(srv);
 886      var received = 0;
 887      srv.listen(function(){
 888        var socket = client(srv);
 889        socket.on('big', function(a){
 890          expect(Buffer.isBuffer(a.image)).to.be(true);
 891          if (++received == 3)
 892            done();
 893          else
 894            socket.emit('big', a);
 895        });
 896        sio.on('connection', function(s){
 897          fs.readFile(join(__dirname, 'fixtures', 'big.jpg'), function(err, data){
 898            if (err) return done(err);
 899            s.emit('big', {hello: 'friend', image: data});
 900          });
 901          s.on('big', function(a){
 902            expect(Buffer.isBuffer(a.image)).to.be(true);
 903            s.emit('big', a);
 904          });
 905        });
 906      });
 907    });
 908  });
 909
 910  describe('messaging many', function(){
 911    it('emits to a namespace', function(done){
 912      var srv = http();
 913      var sio = io(srv);
 914      var total = 2;
 915
 916      srv.listen(function(){
 917        var socket1 = client(srv, { multiplex: false });
 918        var socket2 = client(srv, { multiplex: false });
 919        var socket3 = client(srv, '/test');
 920        socket1.on('a', function(a){
 921          expect(a).to.be('b');
 922          --total || done();
 923        });
 924        socket2.on('a', function(a){
 925          expect(a).to.be('b');
 926          --total || done();
 927        });
 928        socket3.on('a', function(){ done(new Error('not')); });
 929
 930        var sockets = 3;
 931        sio.on('connection', function(socket){
 932          --sockets || emit();
 933        });
 934        sio.of('/test', function(socket){
 935          --sockets || emit();
 936        });
 937
 938        function emit(){
 939          sio.emit('a', 'b');
 940        }
 941      });
 942    });
 943
 944    it('emits binary data to a namespace', function(done){
 945      var srv = http();
 946      var sio = io(srv);
 947      var total = 2;
 948
 949      srv.listen(function(){
 950        var socket1 = client(srv, { multiplex: false });
 951        var socket2 = client(srv, { multiplex: false });
 952        var socket3 = client(srv, '/test');
 953        socket1.on('bin', function(a){
 954          expect(Buffer.isBuffer(a)).to.be(true);
 955          --total || done();
 956        });
 957        socket2.on('bin', function(a){
 958          expect(Buffer.isBuffer(a)).to.be(true);
 959          --total || done();
 960        });
 961        socket3.on('bin', function(){ done(new Error('not')); });
 962
 963        var sockets = 3;
 964        sio.on('connection', function(socket){
 965          --sockets || emit();
 966        });
 967        sio.of('/test', function(socket){
 968          --sockets || emit();
 969        });
 970
 971        function emit(){
 972          sio.emit('bin', new Buffer(10));
 973        }
 974      });
 975    });
 976
 977    it('emits to the rest', function(done){
 978      var srv = http();
 979      var sio = io(srv);
 980      var total = 2;
 981
 982      srv.listen(function(){
 983        var socket1 = client(srv, { multiplex: false });
 984        var socket2 = client(srv, { multiplex: false });
 985        var socket3 = client(srv, '/test');
 986        socket1.on('a', function(a){
 987          expect(a).to.be('b');
 988          socket1.emit('finish');
 989        });
 990        socket2.emit('broadcast');
 991        socket2.on('a', function(){ done(new Error('done')); });
 992        socket3.on('a', function(){ done(new Error('not')); });
 993
 994        var sockets = 2;
 995        sio.on('connection', function(socket){
 996          socket.on('broadcast', function(){
 997            socket.broadcast.emit('a', 'b');
 998          });
 999          socket.on('finish', function(){
1000            done();
1001          });
1002        });
1003      });
1004    });
1005
1006    it('emits to rooms', function(done){
1007      var srv = http();
1008      var sio = io(srv);
1009      var total = 2;
1010
1011      srv.listen(function(){
1012        var socket1 = client(srv, { multiplex: false });
1013        var socket2 = client(srv, { multiplex: false });
1014
1015        socket2.on('a', function(){
1016          done(new Error('not'));
1017        });
1018        socket1.on('a', function(){
1019          done();
1020        });
1021        socket1.emit('join', 'woot', function(){
1022          socket1.emit('emit', 'woot');
1023        });
1024
1025        sio.on('connection', function(socket){
1026          socket.on('join', function(room, fn){
1027            socket.join(room, fn);
1028          });
1029
1030          socket.on('emit', function(room){
1031            sio.in(room).emit('a');
1032          });
1033        });
1034      });
1035    });
1036
1037    it('emits to rooms avoiding dupes', function(done){
1038      var srv = http();
1039      var sio = io(srv);
1040      var total = 2;
1041
1042      srv.listen(function(){
1043        var socket1 = client(srv, { multiplex: false });
1044        var socket2 = client(srv, { multiplex: false });
1045
1046        socket2.on('a', function(){
1047          done(new Error('not'));
1048        });
1049        socket1.on('a', function(){
1050          --total || done();
1051        });
1052        socket2.on('b', function(){
1053          --total || done();
1054        });
1055
1056        socket1.emit('join', 'woot');
1057        socket1.emit('join', 'test');
1058        socket2.emit('join', 'third', function(){
1059          socket2.emit('emit');
1060        });
1061
1062        sio.on('connection', function(socket){
1063          socket.on('join', function(room, fn){
1064            socket.join(room, fn);
1065          });
1066
1067          socket.on('emit', function(room){
1068            sio.in('woot').in('test').emit('a');
1069            sio.in('third').emit('b');
1070          });
1071        });
1072      });
1073    });
1074
1075    it('broadcasts to rooms', function(done){
1076      var srv = http();
1077      var sio = io(srv);
1078      var total = 2;
1079
1080      srv.listen(function(){
1081        var socket1 = client(srv, { multiplex: false });
1082        var socket2 = client(srv, { multiplex: false });
1083        var socket3 = client(srv, { multiplex: false });
1084
1085        socket1.emit('join', 'woot');
1086        socket2.emit('join', 'test');
1087        socket3.emit('join', 'test', function(){
1088          socket3.emit('broadcast');
1089        });
1090
1091        socket1.on('a', function(){
1092          done(new Error('not'));
1093        });
1094        socket2.on('a', function(){
1095          --total || done();
1096        });
1097        socket3.on('a', function(){
1098          done(new Error('not'));
1099        });
1100        socket3.on('b', function(){
1101          --total || done();
1102        });
1103
1104        sio.on('connection', function(socket){
1105          socket.on('join', function(room, fn){
1106            socket.join(room, fn);
1107          });
1108
1109          socket.on('broadcast', function(){
1110            socket.broadcast.to('test').emit('a');
1111            socket.emit('b');
1112          });
1113        });
1114      });
1115    });
1116
1117    it('broadcasts binary data to rooms', function(done){
1118      var srv = http();
1119      var sio = io(srv);
1120      var total = 2;
1121
1122      srv.listen(function(){
1123        var socket1 = client(srv, { multiplex: false });
1124        var socket2 = client(srv, { multiplex: false });
1125        var socket3 = client(srv, { multiplex: false });
1126
1127        socket1.emit('join', 'woot');
1128        socket2.emit('join', 'test');
1129        socket3.emit('join', 'test', function(){
1130          socket3.emit('broadcast');
1131        });
1132
1133        socket1.on('bin', function(data){
1134          throw new Error('got bin in socket1');
1135        });
1136        socket2.on('bin', function(data){
1137          expect(Buffer.isBuffer(data)).to.be(true);
1138          --total || done();
1139        });
1140        socket2.on('bin2', function(data) {
1141          throw new Error('socket2 got bin2');
1142        });
1143        socket3.on('bin', function(data) {
1144          throw new Error('socket3 got bin');
1145        });
1146        socket3.on('bin2', function(data) {
1147          expect(Buffer.isBuffer(data)).to.be(true);
1148          --total || done();
1149        });
1150
1151        sio.on('connection', function(socket){
1152          socket.on('join', function(room, fn){
1153            socket.join(room, fn);
1154          });
1155          socket.on('broadcast', function(){
1156            socket.broadcast.to('test').emit('bin', new Buffer(5));
1157            socket.emit('bin2', new Buffer(5));
1158          });
1159        });
1160      });
1161    });
1162
1163
1164    it('keeps track of rooms', function(done){
1165      var srv = http();
1166      var sio = io(srv);
1167
1168      srv.listen(function(){
1169        var socket = client(srv);
1170        sio.on('connection', function(s){
1171          s.join('a', function(){
1172            expect(s.rooms).to.eql([s.id, 'a']);
1173            s.join('b', function(){
1174              expect(s.rooms).to.eql([s.id, 'a', 'b']);
1175              s.leave('b', function(){
1176                expect(s.rooms).to.eql([s.id, 'a']);
1177                done();
1178              });
1179            });
1180          });
1181        });
1182      });
1183    });
1184  });
1185
1186  describe('middleware', function(done){
1187    var Socket = require('../lib/socket');
1188
1189    it('should call functions', function(done){
1190      var srv = http();
1191      var sio = io(srv);
1192      var run = 0;
1193      sio.use(function(socket, next){
1194        expect(socket).to.be.a(Socket);
1195        run++;
1196        next();
1197      });
1198      sio.use(function(socket, next){
1199        expect(socket).to.be.a(Socket);
1200        run++;
1201        next();
1202      });
1203      srv.listen(function(){
1204        var socket = client(srv);
1205        socket.on('connect', function(){
1206          expect(run).to.be(2);
1207          done();
1208        });
1209      });
1210    });
1211
1212    it('should pass errors', function(done){
1213      var srv = http();
1214      var sio = io(srv);
1215      var run = 0;
1216      sio.use(function(socket, next){
1217        next(new Error('Authentication error'));
1218      });
1219      sio.use(function(socket, next){
1220        done(new Error('nope'));
1221      });
1222      srv.listen(function(){
1223        var socket = client(srv);
1224        socket.on('connect', function(){
1225          done(new Error('nope'));
1226        });
1227        socket.on('error', function(err){
1228          expect(err).to.be('Authentication error');
1229          done();
1230        });
1231      });
1232    });
1233
1234    it('should pass `data` of error object', function(done){
1235      var srv = http();
1236      var sio = io(srv);
1237      var run = 0;
1238      sio.use(function(socket, next){
1239        var err = new Error('Authentication error');
1240        err.data = { a: 'b', c: 3 };
1241        next(err);
1242      });
1243      srv.listen(function(){
1244        var socket = client(srv);
1245        socket.on('connect', function(){
1246          done(new Error('nope'));
1247        });
1248        socket.on('error', function(err){
1249          expect(err).to.eql({ a: 'b', c: 3 });
1250          done();
1251        });
1252      });
1253    });
1254
1255    it('should only call connection after fns', function(done){
1256      var srv = http();
1257      var sio = io(srv);
1258      sio.use(function(socket, next){
1259        socket.name = 'guillermo';
1260        next();
1261      });
1262      srv.listen(function(){
1263        var socket = client(srv);
1264        sio.on('connection', function(socket){
1265          expect(socket.name).to.be('guillermo');
1266          done();
1267        });
1268      });
1269    });
1270
1271    it('should be ignored if socket gets closed', function(done){
1272      var srv = http();
1273      var sio = io(srv);
1274      var socket;
1275      sio.use(function(s, next){
1276        socket.io.engine.on('open', function(){
1277          socket.io.engine.close();
1278          s.client.conn.on('close', function(){
1279            process.nextTick(next);
1280            setTimeout(function(){
1281              done();
1282            }, 50);
1283          });
1284        });
1285      });
1286      srv.listen(function(){
1287        socket = client(srv);
1288        sio.on('connection', function(socket){
1289          done(new Error('should not fire'));
1290        });
1291      });
1292    });
1293
1294    it('should call functions in expected order', function(done){
1295      var srv = http();
1296      var sio = io(srv);
1297      var result = [];
1298
1299      sio.use(function(socket, next) {
1300        result.push(1);
1301        setTimeout(next, 50);
1302      });
1303      sio.use(function(socket, next) {
1304        result.push(2);
1305        setTimeout(next, 50);
1306      });
1307      sio.of('/chat').use(function(socket, next) {
1308        result.push(3);
1309        setTimeout(next, 50);
1310      });
1311      sio.of('/chat').use(function(socket, next) {
1312        result.push(4);
1313        setTimeout(next, 50);
1314      });
1315
1316      srv.listen(function() {
1317        var chat = client(srv, '/chat');
1318        chat.on('connect', function() {
1319          expect(result).to.eql([1, 2, 3, 4]);
1320          done();
1321        });
1322      });
1323    });
1324  });
1325});