PageRenderTime 71ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 1ms

/test/socket.io.js

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