/test/socket.io.js
JavaScript | 1383 lines | 1239 code | 137 blank | 7 comment | 55 complexity | 08d131d76761cd6f1afa398bde393da2 MD5 | raw file
Possible License(s): MIT
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('If-None-Match', 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('close', function(){
265
266 it('should be able to close sio sending a srv', function(){
267 var PORT = 54016;
268 var srv = http().listen(PORT);
269 var sio = io(srv);
270 var net = require('net');
271 var server = net.createServer();
272
273 var clientSocket = client(srv, { reconnection: false });
274
275 clientSocket.on('disconnect', function init() {
276 expect(sio.nsps['/'].sockets.length).to.equal(0);
277 server.listen(PORT);
278 });
279
280 clientSocket.on('connect', function init() {
281 expect(sio.nsps['/'].sockets.length).to.equal(1);
282 sio.close();
283 });
284
285 server.once('listening', function() {
286 // PORT should be free
287 server.close(function(error){
288 expect(error).to.be(undefined);
289 });
290 });
291
292 });
293
294 it('should be able to close sio sending a port', function(){
295 var PORT = 54017;
296 var sio = io(PORT);
297 var net = require('net');
298 var server = net.createServer();
299
300 var clientSocket = ioc('ws://0.0.0.0:' + PORT);
301
302 clientSocket.on('disconnect', function init() {
303 expect(sio.nsps['/'].sockets.length).to.equal(0);
304 server.listen(PORT);
305 });
306
307 clientSocket.on('connect', function init() {
308 expect(sio.nsps['/'].sockets.length).to.equal(1);
309 sio.close();
310 });
311
312 server.once('listening', function() {
313 // PORT should be free
314 server.close(function(error){
315 expect(error).to.be(undefined);
316 });
317 });
318 });
319
320 });
321
322 describe('namespaces', function(){
323 var Socket = require('../lib/socket');
324 var Namespace = require('../lib/namespace');
325
326 describe('default', function(){
327 it('should be accessible through .sockets', function(){
328 var sio = io();
329 expect(sio.sockets).to.be.a(Namespace);
330 });
331
332 it('should be aliased', function(){
333 var sio = io();
334 expect(sio.use).to.be.a('function');
335 expect(sio.to).to.be.a('function');
336 expect(sio['in']).to.be.a('function');
337 expect(sio.emit).to.be.a('function');
338 expect(sio.send).to.be.a('function');
339 expect(sio.write).to.be.a('function');
340 });
341
342 it('should automatically connect', function(done){
343 var srv = http();
344 var sio = io(srv);
345 srv.listen(function(){
346 var socket = client(srv);
347 socket.on('connect', function(){
348 done();
349 });
350 });
351 });
352
353 it('should fire a `connection` event', function(done){
354 var srv = http();
355 var sio = io(srv);
356 srv.listen(function(){
357 var socket = client(srv);
358 sio.on('connection', function(socket){
359 expect(socket).to.be.a(Socket);
360 done();
361 });
362 });
363 });
364
365 it('should fire a `connect` event', function(done){
366 var srv = http();
367 var sio = io(srv);
368 srv.listen(function(){
369 var socket = client(srv);
370 sio.on('connect', function(socket){
371 expect(socket).to.be.a(Socket);
372 done();
373 });
374 });
375 });
376
377 it('should work with many sockets', function(done){
378 var srv = http();
379 var sio = io(srv);
380 srv.listen(function(){
381 var chat = client(srv, '/chat');
382 var news = client(srv, '/news');
383 var total = 2;
384 chat.on('connect', function(){
385 --total || done();
386 });
387 news.on('connect', function(){
388 --total || done();
389 });
390 });
391 });
392
393 it('should work with `of` and many sockets', function(done){
394 var srv = http();
395 var sio = io(srv);
396 srv.listen(function(){
397 var chat = client(srv, '/chat');
398 var news = client(srv, '/news');
399 var total = 2;
400 sio.of('/news').on('connection', function(socket){
401 expect(socket).to.be.a(Socket);
402 --total || done();
403 });
404 sio.of('/news').on('connection', function(socket){
405 expect(socket).to.be.a(Socket);
406 --total || done();
407 });
408 });
409 });
410
411 it('should work with `of` second param', function(done){
412 var srv = http();
413 var sio = io(srv);
414 srv.listen(function(){
415 var chat = client(srv, '/chat');
416 var news = client(srv, '/news');
417 var total = 2;
418 sio.of('/news', function(socket){
419 expect(socket).to.be.a(Socket);
420 --total || done();
421 });
422 sio.of('/news', function(socket){
423 expect(socket).to.be.a(Socket);
424 --total || done();
425 });
426 });
427 });
428
429 it('should disconnect upon transport disconnection', function(done){
430 var srv = http();
431 var sio = io(srv);
432 srv.listen(function(){
433 var chat = client(srv, '/chat');
434 var news = client(srv, '/news');
435 var total = 2;
436 var totald = 2;
437 var s;
438 sio.of('/news', function(socket){
439 socket.on('disconnect', function(reason){
440 --totald || done();
441 });
442 --total || close();
443 });
444 sio.of('/chat', function(socket){
445 s = socket;
446 socket.on('disconnect', function(reason){
447 --totald || done();
448 });
449 --total || close();
450 });
451 function close(){
452 s.disconnect(true);
453 }
454 });
455 });
456
457 it('should disconnect both default and custom namespace upon disconnect', function(done){
458 var srv = http();
459 var sio = io(srv);
460 srv.listen(function(){
461 var lolcats = client(srv, '/lolcats');
462 var total = 2;
463 var totald = 2;
464 var s;
465 sio.of('/', function(socket){
466 socket.on('disconnect', function(reason){
467 --totald || done();
468 });
469 --total || close();
470 });
471 sio.of('/lolcats', function(socket){
472 s = socket;
473 socket.on('disconnect', function(reason){
474 --totald || done();
475 });
476 --total || close();
477 });
478 function close(){
479 s.disconnect(true);
480 }
481 });
482 });
483 });
484 });
485
486 describe('socket', function(){
487
488 it('should not fire events more than once after manually reconnecting', function(done) {
489 var srv = http();
490 var sio = io(srv);
491 srv.listen(function(){
492 var clientSocket = client(srv, { reconnection: false });
493 clientSocket.on('connect', function init() {
494 clientSocket.removeListener('connect', init);
495 clientSocket.io.engine.close();
496
497 clientSocket.connect();
498 clientSocket.on('connect', function() {
499 done();
500 });
501 });
502 });
503 });
504
505 it('should not fire reconnect_failed event more than once when server closed', function(done) {
506 var srv = http();
507 var sio = io(srv);
508 srv.listen(function(){
509 var clientSocket = client(srv, { reconnectionAttempts: 3, reconnectionDelay: 10 });
510 clientSocket.on('connect', function() {
511 srv.close();
512 });
513
514 clientSocket.on('reconnect_failed', function() {
515 done();
516 });
517 });
518 });
519
520 it('should receive events', function(done){
521 var srv = http();
522 var sio = io(srv);
523 srv.listen(function(){
524 var socket = client(srv);
525 sio.on('connection', function(s){
526 s.on('random', function(a, b, c){
527 expect(a).to.be(1);
528 expect(b).to.be('2');
529 expect(c).to.eql([3]);
530 done();
531 });
532 socket.emit('random', 1, '2', [3]);
533 });
534 });
535 });
536
537 it('should receive message events through `send`', function(done){
538 var srv = http();
539 var sio = io(srv);
540 srv.listen(function(){
541 var socket = client(srv);
542 sio.on('connection', function(s){
543 s.on('message', function(a){
544 expect(a).to.be(1337);
545 done();
546 });
547 socket.send(1337);
548 });
549 });
550 });
551
552 it('should emit events', function(done){
553 var srv = http();
554 var sio = io(srv);
555 srv.listen(function(){
556 var socket = client(srv);
557 socket.on('woot', function(a){
558 expect(a).to.be('tobi');
559 done();
560 });
561 sio.on('connection', function(s){
562 s.emit('woot', 'tobi');
563 });
564 });
565 });
566
567 it('should emit events with utf8 multibyte character', function(done) {
568 var srv = http();
569 var sio = io(srv);
570 srv.listen(function(){
571 var socket = client(srv);
572 var i = 0;
573 socket.on('hoot', function(a){
574 expect(a).to.be('utf8 — string');
575 i++;
576
577 if (3 == i) {
578 done();
579 }
580 });
581 sio.on('connection', function(s){
582 s.emit('hoot', 'utf8 — string');
583 s.emit('hoot', 'utf8 — string');
584 s.emit('hoot', 'utf8 — string');
585 });
586 });
587 });
588
589 it('should emit events with binary data', function(done){
590 var srv = http();
591 var sio = io(srv);
592 srv.listen(function(){
593 var socket = client(srv);
594 var imageData;
595 socket.on('doge', function(a){
596 expect(Buffer.isBuffer(a)).to.be(true);
597 expect(imageData.length).to.equal(a.length);
598 expect(imageData[0]).to.equal(a[0]);
599 expect(imageData[imageData.length - 1]).to.equal(a[a.length - 1]);
600 done();
601 });
602 sio.on('connection', function(s){
603 fs.readFile(join(__dirname, 'support', 'doge.jpg'), function(err, data){
604 if (err) return done(err);
605 imageData = data;
606 s.emit('doge', data);
607 });
608 });
609 });
610 });
611
612 it('should emit events with several types of data (including binary)', function(done){
613 var srv = http();
614 var sio = io(srv);
615 srv.listen(function(){
616 var socket = client(srv);
617 socket.on('multiple', function(a, b, c, d, e, f){
618 expect(a).to.be(1);
619 expect(Buffer.isBuffer(b)).to.be(true);
620 expect(c).to.be('3');
621 expect(d).to.eql([4]);
622 expect(Buffer.isBuffer(e)).to.be(true);
623 expect(Buffer.isBuffer(f[0])).to.be(true);
624 expect(f[1]).to.be('swag');
625 expect(Buffer.isBuffer(f[2])).to.be(true);
626 done();
627 });
628 sio.on('connection', function(s){
629 fs.readFile(join(__dirname, 'support', 'doge.jpg'), function(err, data){
630 if (err) return done(err);
631 var buf = new Buffer('asdfasdf', 'utf8');
632 s.emit('multiple', 1, data, '3', [4], buf, [data, 'swag', buf]);
633 });
634 });
635 });
636 });
637
638 it('should receive events with binary data', function(done){
639 var srv = http();
640 var sio = io(srv);
641 srv.listen(function(){
642 var socket = client(srv);
643 sio.on('connection', function(s){
644 s.on('buff', function(a){
645 expect(Buffer.isBuffer(a)).to.be(true);
646 done();
647 });
648 var buf = new Buffer('abcdefg', 'utf8');
649 socket.emit('buff', buf);
650 });
651 });
652 });
653
654 it('should receive events with several types of data (including binary)', function(done){
655 var srv = http();
656 var sio = io(srv);
657 srv.listen(function(){
658 var socket = client(srv);
659 sio.on('connection', function(s){
660 s.on('multiple', function(a, b, c, d, e, f){
661 expect(a).to.be(1);
662 expect(Buffer.isBuffer(b)).to.be(true);
663 expect(c).to.be('3');
664 expect(d).to.eql([4]);
665 expect(Buffer.isBuffer(e)).to.be(true);
666 expect(Buffer.isBuffer(f[0])).to.be(true);
667 expect(f[1]).to.be('swag');
668 expect(Buffer.isBuffer(f[2])).to.be(true);
669 done();
670 });
671 fs.readFile(join(__dirname, 'support', 'doge.jpg'), function(err, data){
672 if (err) return done(err);
673 var buf = new Buffer('asdfasdf', 'utf8');
674 socket.emit('multiple', 1, data, '3', [4], buf, [data, 'swag', buf]);
675 });
676 });
677 });
678 });
679
680 it('should emit message events through `send`', function(done){
681 var srv = http();
682 var sio = io(srv);
683 srv.listen(function(){
684 var socket = client(srv);
685 socket.on('message', function(a){
686 expect(a).to.be('a');
687 done();
688 });
689 sio.on('connection', function(s){
690 s.send('a');
691 });
692 });
693 });
694
695 it('should receive event with callbacks', 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(fn){
702 fn(1, 2);
703 });
704 socket.emit('woot', function(a, b){
705 expect(a).to.be(1);
706 expect(b).to.be(2);
707 done();
708 });
709 });
710 });
711 });
712
713 it('should receive all events emitted from namespaced client immediately and in order', function(done) {
714 var srv = http();
715 var sio = io(srv);
716 var total = 0;
717 srv.listen(function(){
718 sio.of('/chat', function(s){
719 s.on('hi', function(letter){
720 total++;
721 if (total == 2 && letter == 'b') {
722 done();
723 } else if (total == 1 && letter != 'a') {
724 throw new Error('events out of order');
725 }
726 });
727 });
728
729 var chat = client(srv, '/chat');
730 chat.emit('hi', 'a');
731 setTimeout(function() {
732 chat.emit('hi', 'b');
733 }, 50);
734 });
735 });
736
737 it('should emit events with callbacks', function(done){
738 var srv = http();
739 var sio = io(srv);
740 srv.listen(function(){
741 var socket = client(srv);
742 sio.on('connection', function(s){
743 socket.on('hi', function(fn){
744 fn();
745 });
746 s.emit('hi', function(){
747 done();
748 });
749 });
750 });
751 });
752
753 it('should receive events with args and callback', function(done){
754 var srv = http();
755 var sio = io(srv);
756 srv.listen(function(){
757 var socket = client(srv);
758 sio.on('connection', function(s){
759 s.on('woot', function(a, b, fn){
760 expect(a).to.be(1);
761 expect(b).to.be(2);
762 fn();
763 });
764 socket.emit('woot', 1, 2, function(){
765 done();
766 });
767 });
768 });
769 });
770
771 it('should emit events with args and callback', function(done){
772 var srv = http();
773 var sio = io(srv);
774 srv.listen(function(){
775 var socket = client(srv);
776 sio.on('connection', function(s){
777 socket.on('hi', function(a, b, fn){
778 expect(a).to.be(1);
779 expect(b).to.be(2);
780 fn();
781 });
782 s.emit('hi', 1, 2, function(){
783 done();
784 });
785 });
786 });
787 });
788
789 it('should receive events with binary args and callbacks', function(done) {
790 var srv = http();
791 var sio = io(srv);
792 srv.listen(function(){
793 var socket = client(srv);
794 sio.on('connection', function(s){
795 s.on('woot', function(buf, fn){
796 expect(Buffer.isBuffer(buf)).to.be(true);
797 fn(1, 2);
798 });
799 socket.emit('woot', new Buffer(3), function(a, b){
800 expect(a).to.be(1);
801 expect(b).to.be(2);
802 done();
803 });
804 });
805 });
806 });
807
808 it('should emit events with binary args and callback', function(done){
809 var srv = http();
810 var sio = io(srv);
811 srv.listen(function(){
812 var socket = client(srv);
813 sio.on('connection', function(s){
814 socket.on('hi', function(a, fn){
815 expect(Buffer.isBuffer(a)).to.be(true);
816 fn();
817 });
818 s.emit('hi', new Buffer(4), function(){
819 done();
820 });
821 });
822 });
823 });
824
825 it('should emit events and receive binary data in a callback', function(done) {
826 var srv = http();
827 var sio = io(srv);
828 srv.listen(function(){
829 var socket = client(srv);
830 sio.on('connection', function(s){
831 socket.on('hi', function(fn){
832 fn(new Buffer(1));
833 });
834 s.emit('hi', function(a){
835 expect(Buffer.isBuffer(a)).to.be(true);
836 done();
837 });
838 });
839 });
840 });
841
842 it('should receive events and pass binary data in a callback', function(done) {
843 var srv = http();
844 var sio = io(srv);
845 srv.listen(function(){
846 var socket = client(srv);
847 sio.on('connection', function(s){
848 s.on('woot', function(fn){
849 fn(new Buffer(2));
850 });
851 socket.emit('woot', function(a){
852 expect(Buffer.isBuffer(a)).to.be(true);
853 done();
854 });
855 });
856 });
857 });
858
859 it('should have access to the client', function(done){
860 var srv = http();
861 var sio = io(srv);
862 srv.listen(function(){
863 var socket = client(srv);
864 sio.on('connection', function(s){
865 expect(s.client).to.be.an('object');
866 done();
867 });
868 });
869 });
870
871 it('should have access to the connection', function(done){
872 var srv = http();
873 var sio = io(srv);
874 srv.listen(function(){
875 var socket = client(srv);
876 sio.on('connection', function(s){
877 expect(s.client.conn).to.be.an('object');
878 expect(s.conn).to.be.an('object');
879 done();
880 });
881 });
882 });
883
884 it('should have access to the request', function(done){
885 var srv = http();
886 var sio = io(srv);
887 srv.listen(function(){
888 var socket = client(srv);
889 sio.on('connection', function(s){
890 expect(s.client.request.headers).to.be.an('object');
891 expect(s.request.headers).to.be.an('object');
892 done();
893 });
894 });
895 });
896
897 it('should see query parameters in the request', function(done) {
898 var srv = http();
899 var sio = io(srv);
900 srv.listen(function() {
901 var addr = srv.listen().address();
902 var url = 'ws://' + addr.address + ':' + addr.port + '?key1=1&key2=2';
903 var socket = ioc(url);
904 sio.on('connection', function(s) {
905 var parsed = require('url').parse(s.request.url);
906 var query = require('querystring').parse(parsed.query);
907 expect(query.key1).to.be('1');
908 expect(query.key2).to.be('2');
909 done();
910 });
911 });
912 });
913
914 it('should handle very large json', function(done){
915 this.timeout();
916 var srv = http();
917 var sio = io(srv);
918 var received = 0;
919 srv.listen(function(){
920 var socket = client(srv);
921 socket.on('big', function(a){
922 expect(Buffer.isBuffer(a.json)).to.be(false);
923 if (++received == 3)
924 done();
925 else
926 socket.emit('big', a);
927 });
928 sio.on('connection', function(s){
929 fs.readFile(join(__dirname, 'fixtures', 'big.json'), function(err, data){
930 if (err) return done(err);
931 data = JSON.parse(data);
932 s.emit('big', {hello: 'friend', json: data});
933 });
934 s.on('big', function(a){
935 s.emit('big', a);
936 });
937 });
938 });
939 });
940
941 it('should handle very large binary data', function(done){
942 var srv = http();
943 var sio = io(srv);
944 var received = 0;
945 srv.listen(function(){
946 var socket = client(srv);
947 socket.on('big', function(a){
948 expect(Buffer.isBuffer(a.image)).to.be(true);
949 if (++received == 3)
950 done();
951 else
952 socket.emit('big', a);
953 });
954 sio.on('connection', function(s){
955 fs.readFile(join(__dirname, 'fixtures', 'big.jpg'), function(err, data){
956 if (err) return done(err);
957 s.emit('big', {hello: 'friend', image: data});
958 });
959 s.on('big', function(a){
960 expect(Buffer.isBuffer(a.image)).to.be(true);
961 s.emit('big', a);
962 });
963 });
964 });
965 });
966 });
967
968 describe('messaging many', function(){
969 it('emits to a namespace', function(done){
970 var srv = http();
971 var sio = io(srv);
972 var total = 2;
973
974 srv.listen(function(){
975 var socket1 = client(srv, { multiplex: false });
976 var socket2 = client(srv, { multiplex: false });
977 var socket3 = client(srv, '/test');
978 socket1.on('a', function(a){
979 expect(a).to.be('b');
980 --total || done();
981 });
982 socket2.on('a', function(a){
983 expect(a).to.be('b');
984 --total || done();
985 });
986 socket3.on('a', function(){ done(new Error('not')); });
987
988 var sockets = 3;
989 sio.on('connection', function(socket){
990 --sockets || emit();
991 });
992 sio.of('/test', function(socket){
993 --sockets || emit();
994 });
995
996 function emit(){
997 sio.emit('a', 'b');
998 }
999 });
1000 });
1001
1002 it('emits binary data to a namespace', function(done){
1003 var srv = http();
1004 var sio = io(srv);
1005 var total = 2;
1006
1007 srv.listen(function(){
1008 var socket1 = client(srv, { multiplex: false });
1009 var socket2 = client(srv, { multiplex: false });
1010 var socket3 = client(srv, '/test');
1011 socket1.on('bin', function(a){
1012 expect(Buffer.isBuffer(a)).to.be(true);
1013 --total || done();
1014 });
1015 socket2.on('bin', function(a){
1016 expect(Buffer.isBuffer(a)).to.be(true);
1017 --total || done();
1018 });
1019 socket3.on('bin', function(){ done(new Error('not')); });
1020
1021 var sockets = 3;
1022 sio.on('connection', function(socket){
1023 --sockets || emit();
1024 });
1025 sio.of('/test', function(socket){
1026 --sockets || emit();
1027 });
1028
1029 function emit(){
1030 sio.emit('bin', new Buffer(10));
1031 }
1032 });
1033 });
1034
1035 it('emits to the rest', function(done){
1036 var srv = http();
1037 var sio = io(srv);
1038 var total = 2;
1039
1040 srv.listen(function(){
1041 var socket1 = client(srv, { multiplex: false });
1042 var socket2 = client(srv, { multiplex: false });
1043 var socket3 = client(srv, '/test');
1044 socket1.on('a', function(a){
1045 expect(a).to.be('b');
1046 socket1.emit('finish');
1047 });
1048 socket2.emit('broadcast');
1049 socket2.on('a', function(){ done(new Error('done')); });
1050 socket3.on('a', function(){ done(new Error('not')); });
1051
1052 var sockets = 2;
1053 sio.on('connection', function(socket){
1054 socket.on('broadcast', function(){
1055 socket.broadcast.emit('a', 'b');
1056 });
1057 socket.on('finish', function(){
1058 done();
1059 });
1060 });
1061 });
1062 });
1063
1064 it('emits to rooms', function(done){
1065 var srv = http();
1066 var sio = io(srv);
1067 var total = 2;
1068
1069 srv.listen(function(){
1070 var socket1 = client(srv, { multiplex: false });
1071 var socket2 = client(srv, { multiplex: false });
1072
1073 socket2.on('a', function(){
1074 done(new Error('not'));
1075 });
1076 socket1.on('a', function(){
1077 done();
1078 });
1079 socket1.emit('join', 'woot', function(){
1080 socket1.emit('emit', 'woot');
1081 });
1082
1083 sio.on('connection', function(socket){
1084 socket.on('join', function(room, fn){
1085 socket.join(room, fn);
1086 });
1087
1088 socket.on('emit', function(room){
1089 sio.in(room).emit('a');
1090 });
1091 });
1092 });
1093 });
1094
1095 it('emits to rooms avoiding dupes', function(done){
1096 var srv = http();
1097 var sio = io(srv);
1098 var total = 2;
1099
1100 srv.listen(function(){
1101 var socket1 = client(srv, { multiplex: false });
1102 var socket2 = client(srv, { multiplex: false });
1103
1104 socket2.on('a', function(){
1105 done(new Error('not'));
1106 });
1107 socket1.on('a', function(){
1108 --total || done();
1109 });
1110 socket2.on('b', function(){
1111 --total || done();
1112 });
1113
1114 socket1.emit('join', 'woot');
1115 socket1.emit('join', 'test');
1116 socket2.emit('join', 'third', function(){
1117 socket2.emit('emit');
1118 });
1119
1120 sio.on('connection', function(socket){
1121 socket.on('join', function(room, fn){
1122 socket.join(room, fn);
1123 });
1124
1125 socket.on('emit', function(room){
1126 sio.in('woot').in('test').emit('a');
1127 sio.in('third').emit('b');
1128 });
1129 });
1130 });
1131 });
1132
1133 it('broadcasts to rooms', function(done){
1134 var srv = http();
1135 var sio = io(srv);
1136 var total = 2;
1137
1138 srv.listen(function(){
1139 var socket1 = client(srv, { multiplex: false });
1140 var socket2 = client(srv, { multiplex: false });
1141 var socket3 = client(srv, { multiplex: false });
1142
1143 socket1.emit('join', 'woot');
1144 socket2.emit('join', 'test');
1145 socket3.emit('join', 'test', function(){
1146 socket3.emit('broadcast');
1147 });
1148
1149 socket1.on('a', function(){
1150 done(new Error('not'));
1151 });
1152 socket2.on('a', function(){
1153 --total || done();
1154 });
1155 socket3.on('a', function(){
1156 done(new Error('not'));
1157 });
1158 socket3.on('b', function(){
1159 --total || done();
1160 });
1161
1162 sio.on('connection', function(socket){
1163 socket.on('join', function(room, fn){
1164 socket.join(room, fn);
1165 });
1166
1167 socket.on('broadcast', function(){
1168 socket.broadcast.to('test').emit('a');
1169 socket.emit('b');
1170 });
1171 });
1172 });
1173 });
1174
1175 it('broadcasts binary data to rooms', function(done){
1176 var srv = http();
1177 var sio = io(srv);
1178 var total = 2;
1179
1180 srv.listen(function(){
1181 var socket1 = client(srv, { multiplex: false });
1182 var socket2 = client(srv, { multiplex: false });
1183 var socket3 = client(srv, { multiplex: false });
1184
1185 socket1.emit('join', 'woot');
1186 socket2.emit('join', 'test');
1187 socket3.emit('join', 'test', function(){
1188 socket3.emit('broadcast');
1189 });
1190
1191 socket1.on('bin', function(data){
1192 throw new Error('got bin in socket1');
1193 });
1194 socket2.on('bin', function(data){
1195 expect(Buffer.isBuffer(data)).to.be(true);
1196 --total || done();
1197 });
1198 socket2.on('bin2', function(data) {
1199 throw new Error('socket2 got bin2');
1200 });
1201 socket3.on('bin', function(data) {
1202 throw new Error('socket3 got bin');
1203 });
1204 socket3.on('bin2', function(data) {
1205 expect(Buffer.isBuffer(data)).to.be(true);
1206 --total || done();
1207 });
1208
1209 sio.on('connection', function(socket){
1210 socket.on('join', function(room, fn){
1211 socket.join(room, fn);
1212 });
1213 socket.on('broadcast', function(){
1214 socket.broadcast.to('test').emit('bin', new Buffer(5));
1215 socket.emit('bin2', new Buffer(5));
1216 });
1217 });
1218 });
1219 });
1220
1221
1222 it('keeps track of rooms', function(done){
1223 var srv = http();
1224 var sio = io(srv);
1225
1226 srv.listen(function(){
1227 var socket = client(srv);
1228 sio.on('connection', function(s){
1229 s.join('a', function(){
1230 expect(s.rooms).to.eql([s.id, 'a']);
1231 s.join('b', function(){
1232 expect(s.rooms).to.eql([s.id, 'a', 'b']);
1233 s.leave('b', function(){
1234 expect(s.rooms).to.eql([s.id, 'a']);
1235 done();
1236 });
1237 });
1238 });
1239 });
1240 });
1241 });
1242 });
1243
1244 describe('middleware', function(done){
1245 var Socket = require('../lib/socket');
1246
1247 it('should call functions', function(done){
1248 var srv = http();
1249 var sio = io(srv);
1250 var run = 0;
1251 sio.use(function(socket, next){
1252 expect(socket).to.be.a(Socket);
1253 run++;
1254 next();
1255 });
1256 sio.use(function(socket, next){
1257 expect(socket).to.be.a(Socket);
1258 run++;
1259 next();
1260 });
1261 srv.listen(function(){
1262 var socket = client(srv);
1263 socket.on('connect', function(){
1264 expect(run).to.be(2);
1265 done();
1266 });
1267 });
1268 });
1269
1270 it('should pass errors', function(done){
1271 var srv = http();
1272 var sio = io(srv);
1273 var run = 0;
1274 sio.use(function(socket, next){
1275 next(new Error('Authentication error'));
1276 });
1277 sio.use(function(socket, next){
1278 done(new Error('nope'));
1279 });
1280 srv.listen(function(){
1281 var socket = client(srv);
1282 socket.on('connect', function(){
1283 done(new Error('nope'));
1284 });
1285 socket.on('error', function(err){
1286 expect(err).to.be('Authentication error');
1287 done();
1288 });
1289 });
1290 });
1291
1292 it('should pass `data` of error object', function(done){
1293 var srv = http();
1294 var sio = io(srv);
1295 var run = 0;
1296 sio.use(function(socket, next){
1297 var err = new Error('Authentication error');
1298 err.data = { a: 'b', c: 3 };
1299 next(err);
1300 });
1301 srv.listen(function(){
1302 var socket = client(srv);
1303 socket.on('connect', function(){
1304 done(new Error('nope'));
1305 });
1306 socket.on('error', function(err){
1307 expect(err).to.eql({ a: 'b', c: 3 });
1308 done();
1309 });
1310 });
1311 });
1312
1313 it('should only call connection after fns', function(done){
1314 var srv = http();
1315 var sio = io(srv);
1316 sio.use(function(socket, next){
1317 socket.name = 'guillermo';
1318 next();
1319 });
1320 srv.listen(function(){
1321 var socket = client(srv);
1322 sio.on('connection', function(socket){
1323 expect(socket.name).to.be('guillermo');
1324 done();
1325 });
1326 });
1327 });
1328
1329 it('should be ignored if socket gets closed', function(done){
1330 var srv = http();
1331 var sio = io(srv);
1332 var socket;
1333 sio.use(function(s, next){
1334 socket.io.engine.on('open', function(){
1335 socket.io.engine.close();
1336 s.client.conn.on('close', function(){
1337 process.nextTick(next);
1338 setTimeout(function(){
1339 done();
1340 }, 50);
1341 });
1342 });
1343 });
1344 srv.listen(function(){
1345 socket = client(srv);
1346 sio.on('connection', function(socket){
1347 done(new Error('should not fire'));
1348 });
1349 });
1350 });
1351
1352 it('should call functions in expected order', function(done){
1353 var srv = http();
1354 var sio = io(srv);
1355 var result = [];
1356
1357 sio.use(function(socket, next) {
1358 result.push(1);
1359 setTimeout(next, 50);
1360 });
1361 sio.use(function(socket, next) {
1362 result.push(2);
1363 setTimeout(next, 50);
1364 });
1365 sio.of('/chat').use(function(socket, next) {
1366 result.push(3);
1367 setTimeout(next, 50);
1368 });
1369 sio.of('/chat').use(function(socket, next) {
1370 result.push(4);
1371 setTimeout(next, 50);
1372 });
1373
1374 srv.listen(function() {
1375 var chat = client(srv, '/chat');
1376 chat.on('connect', function() {
1377 expect(result).to.eql([1, 2, 3, 4]);
1378 done();
1379 });
1380 });
1381 });
1382 });
1383});