@@ -352,4 +352,111 @@ describe('useWebSocket', () => {
352
352
expect ( mockWebSocket . prototype . send ) . toBeCalledWith ( 'bleep bloop' )
353
353
} )
354
354
} )
355
+
356
+ describe ( 'heartbeat' , ( ) => {
357
+ vi . useFakeTimers ( )
358
+
359
+ it ( 'should send a heartbeat if heartbeat=true' , async ( ) => {
360
+ vm = useSetup ( ( ) => {
361
+ const ref = useWebSocket ( 'wss://server.example.com' , {
362
+ heartbeat : {
363
+ interval : 500 ,
364
+ } ,
365
+ } )
366
+
367
+ return {
368
+ ref,
369
+ }
370
+ } )
371
+
372
+ vm . ref . ws . value ?. onopen ?.( new Event ( 'open' ) )
373
+ await vi . advanceTimersByTimeAsync ( 500 )
374
+ expect ( mockWebSocket . prototype . send ) . toBeCalledWith ( 'ping' )
375
+ } )
376
+ it ( 'should not send a heartbeat if heartbeat=false' , async ( ) => {
377
+ vm = useSetup ( ( ) => {
378
+ const ref = useWebSocket ( 'wss://server.example.com' , {
379
+ heartbeat : false ,
380
+ } )
381
+
382
+ return {
383
+ ref,
384
+ }
385
+ } )
386
+
387
+ vm . ref . ws . value ?. onopen ?.( new Event ( 'open' ) )
388
+ await vi . advanceTimersByTimeAsync ( 500 )
389
+ expect ( mockWebSocket . prototype . send ) . not . toHaveBeenCalled ( )
390
+ } )
391
+ it ( 'should call close on pongTimeout' , async ( ) => {
392
+ vm = useSetup ( ( ) => {
393
+ const ref = useWebSocket ( 'wss://server.example.com' , {
394
+ heartbeat : {
395
+ interval : 500 ,
396
+ pongTimeout : 1000 ,
397
+ } ,
398
+ } )
399
+
400
+ return {
401
+ ref,
402
+ }
403
+ } )
404
+
405
+ vm . ref . ws . value ?. onopen ?.( new Event ( 'open' ) )
406
+ expect ( vm . ref . status . value ) . toBe ( 'OPEN' )
407
+ mockWebSocket . prototype . close . mockClear ( )
408
+ await vi . advanceTimersByTimeAsync ( 1499 )
409
+ expect ( mockWebSocket . prototype . close ) . not . toHaveBeenCalled ( )
410
+ await vi . advanceTimersByTimeAsync ( 1 )
411
+ expect ( mockWebSocket . prototype . close ) . toHaveBeenCalledOnce ( )
412
+ } )
413
+ it ( 'should not call close on pongTimeout if connection already closed' , async ( ) => {
414
+ vm = useSetup ( ( ) => {
415
+ const ref = useWebSocket ( 'wss://server.example.com' , {
416
+ heartbeat : {
417
+ message : 'ping' ,
418
+ interval : 500 ,
419
+ pongTimeout : 1000 ,
420
+ } ,
421
+ } )
422
+
423
+ return {
424
+ ref,
425
+ }
426
+ } )
427
+ vm . ref . ws . value ?. onopen ?.( new Event ( 'open' ) )
428
+ expect ( vm . ref . status . value ) . toBe ( 'OPEN' )
429
+ const ev = new CloseEvent ( 'close' )
430
+ vm . ref . ws . value ?. onclose ?.( ev )
431
+ expect ( vm . ref . status . value ) . toBe ( 'CLOSED' )
432
+ mockWebSocket . prototype . close . mockClear ( )
433
+ await vi . advanceTimersByTimeAsync ( 1500 )
434
+ expect ( mockWebSocket . prototype . close ) . not . toHaveBeenCalled ( )
435
+ } )
436
+ it ( 'should not send a heartbeat if the connection is closed' , async ( ) => {
437
+ const messageSpy = vi . fn ( ( ) => 'ping' )
438
+ vm = useSetup ( ( ) => {
439
+ const ref = useWebSocket ( 'wss://server.example.com' , {
440
+ heartbeat : {
441
+ message : messageSpy ,
442
+ interval : 500 ,
443
+ pongTimeout : 1000 ,
444
+ } ,
445
+ } )
446
+
447
+ return {
448
+ ref,
449
+ }
450
+ } )
451
+ expect ( vm . ref . status . value ) . toBe ( 'CONNECTING' )
452
+ vm . ref . ws . value ?. onopen ?.( new Event ( 'open' ) )
453
+ expect ( vm . ref . status . value ) . toBe ( 'OPEN' )
454
+ await vi . advanceTimersByTimeAsync ( 500 )
455
+ expect ( messageSpy ) . toHaveBeenCalledTimes ( 1 )
456
+ vm . ref . ws . value ?. onclose ?.( new CloseEvent ( 'close' ) )
457
+ expect ( vm . ref . status . value ) . toBe ( 'CLOSED' )
458
+ await vi . advanceTimersByTimeAsync ( 2500 )
459
+ expect ( messageSpy ) . toHaveBeenCalledTimes ( 1 )
460
+ } )
461
+ } )
355
462
} )
0 commit comments