/test/socket.io.js
JavaScript | 1325 lines | 1196 code | 124 blank | 5 comment | 55 complexity | 0b051850d7629b5e93df412375ae4e8b 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('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});