1+ import { act , renderHook } from "@testing-library/react" ;
2+ import useIsOnline from "./useIsOnline" ;
3+
4+ const dispatchWindowEvent = ( type ) => {
5+ act ( ( ) => {
6+ window . dispatchEvent ( new Event ( type ) ) ;
7+ } ) ;
8+ } ;
9+
10+ describe ( "useIsOnline" , ( ) => {
11+ let swEventTarget ;
12+
13+ beforeEach ( ( ) => {
14+ Object . defineProperty ( navigator , "onLine" , {
15+ configurable : true ,
16+ get : ( ) => true ,
17+ } ) ;
18+
19+ // jsdom doesn't implement navigator.serviceWorker so provide a minimal stub
20+ swEventTarget = new EventTarget ( ) ;
21+ Object . defineProperty ( navigator , "serviceWorker" , {
22+ configurable : true ,
23+ value : swEventTarget ,
24+ } ) ;
25+ } ) ;
26+
27+ const dispatchSWMessage = ( data ) => {
28+ act ( ( ) => {
29+ swEventTarget . dispatchEvent ( new MessageEvent ( "message" , { data } ) ) ;
30+ } ) ;
31+ } ;
32+
33+ test ( "returns true when navigator.onLine is true" , ( ) => {
34+ const { result } = renderHook ( ( ) => useIsOnline ( ) ) ;
35+ expect ( result . current ) . toBe ( true ) ;
36+ } ) ;
37+
38+ test ( "returns false when navigator.onLine is false" , ( ) => {
39+ Object . defineProperty ( navigator , "onLine" , {
40+ configurable : true ,
41+ get : ( ) => false ,
42+ } ) ;
43+ const { result } = renderHook ( ( ) => useIsOnline ( ) ) ;
44+ expect ( result . current ) . toBe ( false ) ;
45+ } ) ;
46+
47+ test ( "updates to false when the offline window event fires" , ( ) => {
48+ const { result } = renderHook ( ( ) => useIsOnline ( ) ) ;
49+ expect ( result . current ) . toBe ( true ) ;
50+ dispatchWindowEvent ( "offline" ) ;
51+ expect ( result . current ) . toBe ( false ) ;
52+ } ) ;
53+
54+ test ( "updates to true when the online window event fires" , ( ) => {
55+ Object . defineProperty ( navigator , "onLine" , {
56+ configurable : true ,
57+ get : ( ) => false ,
58+ } ) ;
59+ const { result } = renderHook ( ( ) => useIsOnline ( ) ) ;
60+ expect ( result . current ) . toBe ( false ) ;
61+ dispatchWindowEvent ( "online" ) ;
62+ expect ( result . current ) . toBe ( true ) ;
63+ } ) ;
64+
65+ test ( "updates to false when the service worker broadcasts OFFLINE" , ( ) => {
66+ const { result } = renderHook ( ( ) => useIsOnline ( ) ) ;
67+ expect ( result . current ) . toBe ( true ) ;
68+ dispatchSWMessage ( { type : "OFFLINE" } ) ;
69+ expect ( result . current ) . toBe ( false ) ;
70+ } ) ;
71+
72+ test ( "ignores service worker messages with a different type" , ( ) => {
73+ const { result } = renderHook ( ( ) => useIsOnline ( ) ) ;
74+ dispatchSWMessage ( { type : "OTHER" } ) ;
75+ expect ( result . current ) . toBe ( true ) ;
76+ } ) ;
77+ } ) ;
0 commit comments