@@ -224,12 +224,103 @@ describe('serverMode option', () => {
224
224
serverMode : '/bad/path/to/implementation' ,
225
225
port,
226
226
} ,
227
- ( ) => { }
227
+ ( ) => { }
228
228
) ;
229
229
} ) . toThrow ( / s e r v e r M o d e m u s t b e a s t r i n g / ) ;
230
230
} ) ;
231
231
} ) ;
232
232
233
+ describe ( 'without a header' , ( ) => {
234
+ let mockWarn ;
235
+ beforeAll ( ( done ) => {
236
+ server = testServer . start (
237
+ config ,
238
+ {
239
+ port,
240
+ serverMode : class MySockJSServer extends BaseServer {
241
+ constructor ( serv ) {
242
+ super ( serv ) ;
243
+ this . socket = sockjs . createServer ( {
244
+ // Use provided up-to-date sockjs-client
245
+ sockjs_url : '/__webpack_dev_server__/sockjs.bundle.js' ,
246
+ // Limit useless logs
247
+ log : ( severity , line ) => {
248
+ if ( severity === 'error' ) {
249
+ this . server . log . error ( line ) ;
250
+ } else {
251
+ this . server . log . debug ( line ) ;
252
+ }
253
+ } ,
254
+ } ) ;
255
+
256
+ this . socket . installHandlers ( this . server . listeningApp , {
257
+ prefix : this . server . sockPath ,
258
+ } ) ;
259
+ }
260
+
261
+ send ( connection , message ) {
262
+ connection . write ( message ) ;
263
+ }
264
+
265
+ close ( connection ) {
266
+ connection . close ( ) ;
267
+ }
268
+
269
+ onConnection ( f ) {
270
+ this . socket . on ( 'connection' , ( connection ) => {
271
+ f ( connection ) ;
272
+ } ) ;
273
+ }
274
+
275
+ onConnectionClose ( connection , f ) {
276
+ connection . on ( 'close' , f ) ;
277
+ }
278
+ } ,
279
+ } ,
280
+ done
281
+ ) ;
282
+
283
+ mockWarn = jest . spyOn ( server . log , 'warn' ) . mockImplementation ( ( ) => { } ) ;
284
+ } ) ;
285
+
286
+ it ( 'results in an error' , ( done ) => {
287
+ const data = [ ] ;
288
+ const client = new SockJS ( `http://localhost:${ port } /sockjs-node` ) ;
289
+
290
+ client . onopen = ( ) => {
291
+ data . push ( 'open' ) ;
292
+ } ;
293
+
294
+ client . onmessage = ( e ) => {
295
+ data . push ( e . data ) ;
296
+ } ;
297
+
298
+ client . onclose = ( ) => {
299
+ data . push ( 'close' ) ;
300
+ } ;
301
+
302
+ setTimeout ( ( ) => {
303
+ expect ( data ) . toMatchSnapshot ( ) ;
304
+ const calls = mockWarn . mock . calls ;
305
+ mockWarn . mockRestore ( ) ;
306
+
307
+ let foundWarning = false ;
308
+ const regExp = / s e r v e r M o d e i m p l e m e n t a t i o n m u s t p a s s h e a d e r s t o t h e c a l l b a c k o f o n C o n n e c t i o n \( f \) / ;
309
+ calls . every ( ( call ) => {
310
+ if ( regExp . test ( call ) ) {
311
+ foundWarning = true ;
312
+ return false ;
313
+ }
314
+ return true ;
315
+ } ) ;
316
+
317
+ expect ( foundWarning ) . toBeTruthy ( ) ;
318
+
319
+ done ( ) ;
320
+ } , 5000 ) ;
321
+ } ) ;
322
+ } ) ;
323
+
233
324
describe ( 'with a bad host header' , ( ) => {
234
325
beforeAll ( ( done ) => {
235
326
server = testServer . start (
@@ -306,94 +397,90 @@ describe('serverMode option', () => {
306
397
} ) ;
307
398
} ) ;
308
399
309
- describe ( 'without a header' , ( ) => {
310
- let mockWarn ;
311
- beforeAll ( ( done ) => {
312
- server = testServer . start (
400
+ describe ( 'server' , ( ) => {
401
+ let MockSockJSServer ;
402
+ beforeEach ( ( done ) => {
403
+ jest . mock ( '../../lib/servers/SockJSServer' ) ;
404
+ // eslint-disable-next-line global-require
405
+ mockedTestServer = require ( '../helpers/test-server' ) ;
406
+ // eslint-disable-next-line global-require
407
+ MockSockJSServer = require ( '../../lib/servers/SockJSServer' ) ;
408
+
409
+ server = mockedTestServer . start (
313
410
config ,
314
411
{
315
412
port,
316
- serverMode : class MySockJSServer extends BaseServer {
317
- constructor ( serv ) {
318
- super ( serv ) ;
319
- this . socket = sockjs . createServer ( {
320
- // Use provided up-to-date sockjs-client
321
- sockjs_url : '/__webpack_dev_server__/sockjs.bundle.js' ,
322
- // Limit useless logs
323
- log : ( severity , line ) => {
324
- if ( severity === 'error' ) {
325
- this . server . log . error ( line ) ;
326
- } else {
327
- this . server . log . debug ( line ) ;
328
- }
329
- } ,
330
- } ) ;
331
-
332
- this . socket . installHandlers ( this . server . listeningApp , {
333
- prefix : this . server . sockPath ,
334
- } ) ;
335
- }
336
-
337
- send ( connection , message ) {
338
- connection . write ( message ) ;
339
- }
340
-
341
- close ( connection ) {
342
- connection . close ( ) ;
343
- }
344
-
345
- onConnection ( f ) {
346
- this . socket . on ( 'connection' , ( connection ) => {
347
- f ( connection ) ;
348
- } ) ;
349
- }
350
-
351
- onConnectionClose ( connection , f ) {
352
- connection . on ( 'close' , f ) ;
353
- }
354
- } ,
355
413
} ,
356
414
done
357
415
) ;
358
-
359
- mockWarn = jest . spyOn ( server . log , 'warn' ) . mockImplementation ( ( ) => { } ) ;
360
416
} ) ;
361
417
362
- it ( 'results in an error' , ( done ) => {
363
- const data = [ ] ;
364
- const client = new SockJS ( `http://localhost:${ port } /sockjs-node` ) ;
418
+ afterEach ( ( done ) => {
419
+ mockedTestServer . close ( done ) ;
420
+ jest . resetAllMocks ( ) ;
421
+ jest . resetModules ( ) ;
365
422
366
- client . onopen = ( ) => {
367
- data . push ( 'open' ) ;
368
- } ;
423
+ server = null ;
424
+ } ) ;
369
425
370
- client . onmessage = ( e ) => {
371
- data . push ( e . data ) ;
372
- } ;
426
+ it ( 'should use server implementation correctly' , ( ) => {
427
+ const mockServerInstance = MockSockJSServer . mock . instances [ 0 ] ;
373
428
374
- client . onclose = ( ) => {
375
- data . push ( 'close' ) ;
429
+ const connectionObj = {
430
+ foo : 'bar' ,
376
431
} ;
432
+ // this simulates a client connecting to the server
433
+ mockServerInstance . onConnection . mock . calls [ 0 ] [ 0 ] ( connectionObj , {
434
+ host : `localhost:${ port } ` ,
435
+ origin : `http://localhost:${ port } ` ,
436
+ } ) ;
377
437
378
- setTimeout ( ( ) => {
379
- expect ( data ) . toMatchSnapshot ( ) ;
380
- const calls = mockWarn . mock . calls ;
381
- mockWarn . mockRestore ( ) ;
382
-
383
- let foundWarning = false ;
384
- const regExp = / s e r v e r M o d e i m p l e m e n t a t i o n m u s t p a s s h e a d e r s t o t h e c a l l b a c k o f o n C o n n e c t i o n \( f \) / ;
385
- calls . every ( ( call ) => {
386
- if ( regExp . test ( call ) ) {
387
- foundWarning = true ;
388
- return false ;
389
- }
390
- return true ;
391
- } ) ;
438
+ expect ( server . sockets . length ) . toEqual ( 1 ) ;
439
+ expect ( server . sockets ) . toMatchSnapshot ( ) ;
440
+
441
+ // this simulates a client leaving the server
442
+ mockServerInstance . onConnectionClose . mock . calls [ 0 ] [ 1 ] ( connectionObj ) ;
443
+
444
+ expect ( server . sockets . length ) . toEqual ( 0 ) ;
445
+
446
+ // check that the dev server was passed to the socket server implementation constructor
447
+ expect ( MockSockJSServer . mock . calls [ 0 ] . length ) . toEqual ( 1 ) ;
448
+ expect ( MockSockJSServer . mock . calls [ 0 ] [ 0 ] . options . port ) . toEqual ( port ) ;
449
+
450
+ expect ( mockServerInstance . onConnection . mock . calls ) . toMatchSnapshot ( ) ;
451
+ expect ( mockServerInstance . send . mock . calls . length ) . toEqual ( 3 ) ;
452
+ // call 0 to the send() method is liveReload
453
+ expect ( mockServerInstance . send . mock . calls [ 0 ] ) . toMatchSnapshot ( ) ;
454
+ // call 1 to the send() method is hash data, so we skip it
455
+ // call 2 to the send() method is the "ok" message
456
+ expect ( mockServerInstance . send . mock . calls [ 2 ] ) . toMatchSnapshot ( ) ;
457
+ // close should not be called because the server never forcefully closes
458
+ // a successful client connection
459
+ expect ( mockServerInstance . close . mock . calls . length ) . toEqual ( 0 ) ;
460
+ expect ( mockServerInstance . onConnectionClose . mock . calls ) . toMatchSnapshot ( ) ;
461
+ } ) ;
392
462
393
- expect ( foundWarning ) . toBeTruthy ( ) ;
463
+ it ( 'should close client with bad headers' , ( ) => {
464
+ const mockServerInstance = MockSockJSServer . mock . instances [ 0 ] ;
394
465
395
- done ( ) ;
396
- } , 5000 ) ;
466
+ // this simulates a client connecting to the server
467
+ mockServerInstance . onConnection . mock . calls [ 0 ] [ 0 ] (
468
+ {
469
+ foo : 'bar' ,
470
+ } ,
471
+ {
472
+ host : null ,
473
+ }
474
+ ) ;
475
+ expect ( server . sockets . length ) . toEqual ( 0 ) ;
476
+ expect ( MockSockJSServer . mock . calls [ 0 ] . length ) . toEqual ( 1 ) ;
477
+ expect ( MockSockJSServer . mock . calls [ 0 ] [ 0 ] . options . port ) . toEqual ( port ) ;
478
+ expect ( mockServerInstance . onConnection . mock . calls ) . toMatchSnapshot ( ) ;
479
+ // the only call to send() here should be an invalid header message
480
+ expect ( mockServerInstance . send . mock . calls ) . toMatchSnapshot ( ) ;
481
+ expect ( mockServerInstance . close . mock . calls ) . toMatchSnapshot ( ) ;
482
+ // onConnectionClose should never get called since the client should be closed first
483
+ expect ( mockServerInstance . onConnectionClose . mock . calls . length ) . toEqual ( 0 ) ;
397
484
} ) ;
398
485
} ) ;
399
486
} ) ;
0 commit comments