@@ -224,12 +224,103 @@ describe('serverMode option', () => {
224224 serverMode : '/bad/path/to/implementation' ,
225225 port,
226226 } ,
227- ( ) => { }
227+ ( ) => { }
228228 ) ;
229229 } ) . toThrow ( / s e r v e r M o d e m u s t b e a s t r i n g / ) ;
230230 } ) ;
231231 } ) ;
232232
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+
233324 describe ( 'with a bad host header' , ( ) => {
234325 beforeAll ( ( done ) => {
235326 server = testServer . start (
@@ -306,94 +397,90 @@ describe('serverMode option', () => {
306397 } ) ;
307398 } ) ;
308399
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 (
313410 config ,
314411 {
315412 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- } ,
355413 } ,
356414 done
357415 ) ;
358-
359- mockWarn = jest . spyOn ( server . log , 'warn' ) . mockImplementation ( ( ) => { } ) ;
360416 } ) ;
361417
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 ( ) ;
365422
366- client . onopen = ( ) => {
367- data . push ( 'open' ) ;
368- } ;
423+ server = null ;
424+ } ) ;
369425
370- client . onmessage = ( e ) => {
371- data . push ( e . data ) ;
372- } ;
426+ it ( 'should use server implementation correctly' , ( ) => {
427+ const mockServerInstance = MockSockJSServer . mock . instances [ 0 ] ;
373428
374- client . onclose = ( ) => {
375- data . push ( 'close' ) ;
429+ const connectionObj = {
430+ foo : 'bar' ,
376431 } ;
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+ } ) ;
377437
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+ } ) ;
392462
393- expect ( foundWarning ) . toBeTruthy ( ) ;
463+ it ( 'should close client with bad headers' , ( ) => {
464+ const mockServerInstance = MockSockJSServer . mock . instances [ 0 ] ;
394465
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 ) ;
397484 } ) ;
398485 } ) ;
399486} ) ;
0 commit comments