@dhis2/app-service-offline 3.11.3 → 3.12.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/build/cjs/__tests__/integration.test.js +51 -82
  2. package/build/cjs/index.js +0 -7
  3. package/build/cjs/lib/__tests__/cacheable-section-state.test.js +7 -14
  4. package/build/cjs/lib/__tests__/clear-sensitive-caches.test.js +17 -20
  5. package/build/cjs/lib/__tests__/network-status.test.js +135 -148
  6. package/build/cjs/lib/__tests__/offline-provider.test.js +12 -22
  7. package/build/cjs/lib/__tests__/use-cacheable-section.test.js +87 -98
  8. package/build/cjs/lib/__tests__/use-online-status-message.test.js +7 -14
  9. package/build/cjs/lib/cacheable-section-state.js +27 -38
  10. package/build/cjs/lib/cacheable-section.js +26 -27
  11. package/build/cjs/lib/clear-sensitive-caches.js +14 -24
  12. package/build/cjs/lib/dhis2-connection-status/dev-debug-log.js +1 -3
  13. package/build/cjs/lib/dhis2-connection-status/dhis2-connection-status.js +27 -58
  14. package/build/cjs/lib/dhis2-connection-status/dhis2-connection-status.test.js +287 -230
  15. package/build/cjs/lib/dhis2-connection-status/index.js +0 -1
  16. package/build/cjs/lib/dhis2-connection-status/is-ping-available.js +0 -6
  17. package/build/cjs/lib/dhis2-connection-status/is-ping-available.test.js +0 -1
  18. package/build/cjs/lib/dhis2-connection-status/smart-interval.js +35 -49
  19. package/build/cjs/lib/dhis2-connection-status/use-ping-query.js +4 -5
  20. package/build/cjs/lib/global-state-service.js +9 -27
  21. package/build/cjs/lib/network-status.js +10 -13
  22. package/build/cjs/lib/offline-interface.js +3 -14
  23. package/build/cjs/lib/offline-provider.js +1 -12
  24. package/build/cjs/lib/online-status-message.js +5 -17
  25. package/build/cjs/setupRTL.js +1 -1
  26. package/build/cjs/utils/__tests__/render-counter.test.js +3 -12
  27. package/build/cjs/utils/render-counter.js +2 -10
  28. package/build/cjs/utils/test-mocks.js +13 -18
  29. package/build/es/__tests__/integration.test.js +51 -74
  30. package/build/es/index.js +2 -2
  31. package/build/es/lib/__tests__/cacheable-section-state.test.js +2 -4
  32. package/build/es/lib/__tests__/clear-sensitive-caches.test.js +19 -16
  33. package/build/es/lib/__tests__/network-status.test.js +105 -114
  34. package/build/es/lib/__tests__/offline-provider.test.js +13 -15
  35. package/build/es/lib/__tests__/use-cacheable-section.test.js +69 -73
  36. package/build/es/lib/__tests__/use-online-status-message.test.js +2 -3
  37. package/build/es/lib/cacheable-section-state.js +25 -26
  38. package/build/es/lib/cacheable-section.js +23 -15
  39. package/build/es/lib/clear-sensitive-caches.js +13 -21
  40. package/build/es/lib/dhis2-connection-status/dev-debug-log.js +1 -3
  41. package/build/es/lib/dhis2-connection-status/dhis2-connection-status.js +26 -37
  42. package/build/es/lib/dhis2-connection-status/dhis2-connection-status.test.js +223 -159
  43. package/build/es/lib/dhis2-connection-status/is-ping-available.js +0 -5
  44. package/build/es/lib/dhis2-connection-status/smart-interval.js +34 -42
  45. package/build/es/lib/dhis2-connection-status/use-ping-query.js +6 -3
  46. package/build/es/lib/global-state-service.js +6 -12
  47. package/build/es/lib/network-status.js +10 -9
  48. package/build/es/lib/offline-interface.js +0 -3
  49. package/build/es/lib/offline-provider.js +0 -3
  50. package/build/es/lib/online-status-message.js +3 -2
  51. package/build/es/setupRTL.js +1 -1
  52. package/build/es/utils/__tests__/render-counter.test.js +2 -4
  53. package/build/es/utils/render-counter.js +1 -3
  54. package/build/es/utils/test-mocks.js +8 -9
  55. package/build/types/lib/cacheable-section.d.ts +1 -1
  56. package/build/types/lib/dhis2-connection-status/dhis2-connection-status.d.ts +1 -1
  57. package/build/types/lib/network-status.d.ts +1 -1
  58. package/build/types/lib/online-status-message.d.ts +1 -1
  59. package/build/types/types.d.ts +1 -1
  60. package/package.json +4 -4
@@ -1,35 +1,34 @@
1
1
  import { ConfigProvider } from '@dhis2/app-service-config';
2
- import { renderHook, act } from '@testing-library/react-hooks';
2
+ import { renderHook, act } from '@testing-library/react';
3
3
  import React from 'react';
4
4
  import { mockOfflineInterface } from '../../utils/test-mocks';
5
5
  import { OfflineProvider } from '../offline-provider';
6
6
  import { getLastConnectedKey, useDhis2ConnectionStatus } from './dhis2-connection-status';
7
- import { DEFAULT_INCREMENT_FACTOR, DEFAULT_MAX_DELAY_MS, DEFAULT_INITIAL_DELAY_MS } from './smart-interval'; // eslint-disable-next-line @typescript-eslint/no-unused-vars
7
+ import { DEFAULT_INCREMENT_FACTOR, DEFAULT_MAX_DELAY_MS, DEFAULT_INITIAL_DELAY_MS } from './smart-interval';
8
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
8
9
 
9
10
  // important that this name starts with 'mock' to be hoisted correctly
10
11
  const mockPing = jest.fn().mockImplementation(() => Promise.resolve());
11
12
  jest.mock('./use-ping-query.ts', () => ({
12
13
  usePingQuery: () => mockPing
13
14
  }));
14
-
15
15
  const failedPing = () => Promise.reject({
16
16
  message: 'this is a network error',
17
17
  type: 'network'
18
18
  });
19
-
20
19
  const FIRST_INTERVAL_MS = DEFAULT_INITIAL_DELAY_MS;
21
20
  const SECOND_INTERVAL_MS = FIRST_INTERVAL_MS * DEFAULT_INCREMENT_FACTOR;
22
21
  const THIRD_INTERVAL_MS = SECOND_INTERVAL_MS * DEFAULT_INCREMENT_FACTOR;
23
- const FOURTH_INTERVAL_MS = THIRD_INTERVAL_MS * DEFAULT_INCREMENT_FACTOR; // Explanation: The length of the Nth interval is:
22
+ const FOURTH_INTERVAL_MS = THIRD_INTERVAL_MS * DEFAULT_INCREMENT_FACTOR;
23
+
24
+ // Explanation: The length of the Nth interval is:
24
25
  // initialDelay * incrementFactor ^ (N - 1)
25
26
  // Using some algebra and the law of logs, the Nth interval
26
27
  // which is longer than the max delay is:
27
28
  // N >= (ln (maxDelay / initialDelay) / ln (incrementFactor)) + 1
28
29
  // => then use Math.ceil to handle the 'greater than' effect
29
-
30
30
  const INTERVALS_TO_REACH_MAX_DELAY = Math.ceil(Math.log(DEFAULT_MAX_DELAY_MS / DEFAULT_INITIAL_DELAY_MS) / Math.log(DEFAULT_INCREMENT_FACTOR) + 1);
31
-
32
- const wrapper = (_ref) => {
31
+ const wrapper = _ref => {
33
32
  let {
34
33
  children
35
34
  } = _ref;
@@ -49,6 +48,7 @@ const wrapper = (_ref) => {
49
48
  offlineInterface: mockOfflineInterface
50
49
  }, children));
51
50
  };
51
+
52
52
  /**
53
53
  * Assert on the delay of the last time setTimeoutSpy was called with
54
54
  * the `callbackAndRestart()` function in smartInterval.
@@ -58,11 +58,8 @@ const wrapper = (_ref) => {
58
58
  * an assertion like:
59
59
  * `expect(setTimeoutSpy).toHaveBeenLastCalledWith(..., expectedDelay)`
60
60
  */
61
-
62
-
63
61
  const assertLastDelay = (setTimeoutSpy, expectedDelay) => {
64
62
  const calls = setTimeoutSpy.mock.calls;
65
-
66
63
  for (let i = calls.length - 1; i >= 0; i--) {
67
64
  if (calls[i][0].name === 'callbackAndRestart') {
68
65
  expect(calls[i][1]).toBe(expectedDelay);
@@ -70,7 +67,6 @@ const assertLastDelay = (setTimeoutSpy, expectedDelay) => {
70
67
  }
71
68
  }
72
69
  };
73
-
74
70
  const testCurrentDate = new Date('Fri, 03 Feb 2023 13:52:31 GMT');
75
71
  beforeAll(() => {
76
72
  jest.useFakeTimers();
@@ -82,8 +78,8 @@ beforeEach(() => {
82
78
  jest.spyOn(document, 'hasFocus').mockReturnValue(true);
83
79
  });
84
80
  afterEach(() => {
85
- jest.clearAllMocks(); // for lastConnected:
86
-
81
+ jest.clearAllMocks();
82
+ // for lastConnected:
87
83
  localStorage.clear();
88
84
  });
89
85
  afterAll(() => {
@@ -102,11 +98,11 @@ describe('initialization to the right values based on offline interface', () =>
102
98
  expect(result.current.lastConnected).toBe(null);
103
99
  });
104
100
  test('when latestIsConnected is false', () => {
105
- const customMockOfflineInterface = { ...mockOfflineInterface,
101
+ const customMockOfflineInterface = {
102
+ ...mockOfflineInterface,
106
103
  latestIsConnected: false
107
104
  };
108
-
109
- const customWrapper = (_ref2) => {
105
+ const customWrapper = _ref2 => {
110
106
  let {
111
107
  children
112
108
  } = _ref2;
@@ -114,31 +110,31 @@ describe('initialization to the right values based on offline interface', () =>
114
110
  offlineInterface: customMockOfflineInterface
115
111
  }, children);
116
112
  };
117
-
118
113
  const {
119
114
  result
120
115
  } = renderHook(() => useDhis2ConnectionStatus(), {
121
116
  wrapper: customWrapper
122
117
  });
123
118
  expect(result.current.isConnected).toBe(false);
124
- expect(result.current.isDisconnected).toBe(true); // If localStorage is clear, sets 'lastConnected' to `now` as a best
119
+ expect(result.current.isDisconnected).toBe(true);
120
+ // If localStorage is clear, sets 'lastConnected' to `now` as a best
125
121
  // effort to provide useful information.
126
122
  // There will be more detailed testing of lastConnected below
127
-
128
123
  expect(result.current.lastConnected).toEqual(testCurrentDate);
129
- }); // This might happen in the unlikely circumstance that the provider
124
+ });
125
+
126
+ // This might happen in the unlikely circumstance that the provider
130
127
  // renders before the offlineInterface has received a value for
131
128
  // lastIsConnected. Normally, the ServerVersionProvider in the app
132
129
  // adapter delays rendering the App Runtime provider (including the
133
130
  // OfflineProvider) until the offline interface is ready, which should
134
131
  // avoid this case.
135
-
136
132
  test('when latestIsConnected is null', () => {
137
- const customMockOfflineInterface = { ...mockOfflineInterface,
133
+ const customMockOfflineInterface = {
134
+ ...mockOfflineInterface,
138
135
  latestIsConnected: null
139
136
  };
140
-
141
- const customWrapper = (_ref3) => {
137
+ const customWrapper = _ref3 => {
142
138
  let {
143
139
  children
144
140
  } = _ref3;
@@ -146,7 +142,6 @@ describe('initialization to the right values based on offline interface', () =>
146
142
  offlineInterface: customMockOfflineInterface
147
143
  }, children);
148
144
  };
149
-
150
145
  const {
151
146
  result
152
147
  } = renderHook(() => useDhis2ConnectionStatus(), {
@@ -167,50 +162,55 @@ describe('interval behavior', () => {
167
162
  });
168
163
  expect(result.current.isConnected).toBe(true);
169
164
  expect(mockPing).not.toHaveBeenCalled();
170
- assertLastDelay(setTimeoutSpy, FIRST_INTERVAL_MS); // 500ms before first interval
165
+ assertLastDelay(setTimeoutSpy, FIRST_INTERVAL_MS);
171
166
 
167
+ // 500ms before first interval
172
168
  jest.advanceTimersByTime(FIRST_INTERVAL_MS - 500);
173
- expect(mockPing).not.toHaveBeenCalled(); // 500ms after first interval
174
-
169
+ expect(mockPing).not.toHaveBeenCalled();
170
+ // 500ms after first interval
175
171
  jest.advanceTimersByTime(1000);
176
172
  expect(mockPing).toHaveBeenCalledTimes(1);
177
- assertLastDelay(setTimeoutSpy, SECOND_INTERVAL_MS); // 500ms before second interval
173
+ assertLastDelay(setTimeoutSpy, SECOND_INTERVAL_MS);
178
174
 
175
+ // 500ms before second interval
179
176
  jest.advanceTimersByTime(SECOND_INTERVAL_MS - 1000);
180
- expect(mockPing).toHaveBeenCalledTimes(1); // 500ms after second interval
181
-
177
+ expect(mockPing).toHaveBeenCalledTimes(1);
178
+ // 500ms after second interval
182
179
  jest.advanceTimersByTime(1000);
183
180
  expect(mockPing).toHaveBeenCalledTimes(2);
184
- assertLastDelay(setTimeoutSpy, THIRD_INTERVAL_MS); // 500ms before third interval
181
+ assertLastDelay(setTimeoutSpy, THIRD_INTERVAL_MS);
185
182
 
183
+ // 500ms before third interval
186
184
  jest.advanceTimersByTime(THIRD_INTERVAL_MS - 1000);
187
- expect(mockPing).toHaveBeenCalledTimes(2); // 500ms after third interval
188
-
185
+ expect(mockPing).toHaveBeenCalledTimes(2);
186
+ // 500ms after third interval
189
187
  jest.advanceTimersByTime(1000);
190
188
  expect(mockPing).toHaveBeenCalledTimes(3);
191
- assertLastDelay(setTimeoutSpy, FOURTH_INTERVAL_MS); // Run a number of intervals to reach the max delay -
189
+ assertLastDelay(setTimeoutSpy, FOURTH_INTERVAL_MS);
190
+
191
+ // Run a number of intervals to reach the max delay -
192
192
  // this number is calculated above to work for any default values.
193
193
  // Since three have already elapsed, there will be some extra too
194
-
195
194
  for (let i = 0; i < INTERVALS_TO_REACH_MAX_DELAY; i++) {
196
195
  // Wrap in act to await async side effects of interval execution
197
196
  // and pings
198
197
  await act(async () => {
199
198
  jest.runOnlyPendingTimers();
200
199
  });
201
- } // Timeout should no longer be incrementing; max has been reached
202
-
200
+ }
203
201
 
202
+ // Timeout should no longer be incrementing; max has been reached
204
203
  expect(mockPing).toHaveBeenCalledTimes(3 + INTERVALS_TO_REACH_MAX_DELAY);
205
- assertLastDelay(setTimeoutSpy, DEFAULT_MAX_DELAY_MS); // Run a few more intervals to make sure it stays at max
204
+ assertLastDelay(setTimeoutSpy, DEFAULT_MAX_DELAY_MS);
206
205
 
206
+ // Run a few more intervals to make sure it stays at max
207
207
  for (let i = 0; i < 3; i++) {
208
208
  await act(async () => {
209
209
  jest.runOnlyPendingTimers();
210
210
  });
211
- } // Expect continued use of the max delay
212
-
211
+ }
213
212
 
213
+ // Expect continued use of the max delay
214
214
  expect(mockPing).toHaveBeenCalledTimes(6 + INTERVALS_TO_REACH_MAX_DELAY);
215
215
  assertLastDelay(setTimeoutSpy, DEFAULT_MAX_DELAY_MS);
216
216
  });
@@ -218,55 +218,63 @@ describe('interval behavior', () => {
218
218
  test('updates postpone pings', () => {
219
219
  renderHook(() => useDhis2ConnectionStatus(), {
220
220
  wrapper: wrapper
221
- }); // get onUpdate function passed to mockOfflineInterface
221
+ });
222
222
 
223
+ // get onUpdate function passed to mockOfflineInterface
223
224
  const {
224
225
  onUpdate
225
- } = mockOfflineInterface.subscribeToDhis2ConnectionStatus.mock.calls[0][0]; // invoke it at a few intervals, before pings are scheduled
226
+ } = mockOfflineInterface.subscribeToDhis2ConnectionStatus.mock.calls[0][0];
226
227
 
228
+ // invoke it at a few intervals, before pings are scheduled
227
229
  for (let i = 0; i < 3; i++) {
228
230
  jest.advanceTimersByTime(DEFAULT_INITIAL_DELAY_MS - 2000);
229
231
  onUpdate({
230
232
  isConnected: true
231
233
  });
232
- } // expect ping mock not to have been called
233
-
234
+ }
234
235
 
236
+ // expect ping mock not to have been called
235
237
  expect(mockPing).not.toHaveBeenCalled;
236
238
  });
237
239
  test('if the status is the same, the ping delay is reset to the current', () => {
238
240
  const setTimeoutSpy = jest.spyOn(window, 'setTimeout');
239
241
  renderHook(() => useDhis2ConnectionStatus(), {
240
242
  wrapper
241
- }); // get onUpdate function passed to mockOfflineInterface
243
+ });
242
244
 
245
+ // get onUpdate function passed to mockOfflineInterface
243
246
  const {
244
247
  onUpdate
245
- } = mockOfflineInterface.subscribeToDhis2ConnectionStatus.mock.calls[0][0]; // let two intervals pass to allow delay to increase
248
+ } = mockOfflineInterface.subscribeToDhis2ConnectionStatus.mock.calls[0][0];
246
249
 
250
+ // let two intervals pass to allow delay to increase
247
251
  jest.advanceTimersByTime(FIRST_INTERVAL_MS + 50);
248
- jest.advanceTimersByTime(SECOND_INTERVAL_MS); // ...delay should now be 'THIRD_INTERVAL_MS'
252
+ jest.advanceTimersByTime(SECOND_INTERVAL_MS);
249
253
 
254
+ // ...delay should now be 'THIRD_INTERVAL_MS'
250
255
  assertLastDelay(setTimeoutSpy, THIRD_INTERVAL_MS);
251
- expect(mockPing).toHaveBeenCalledTimes(2); // simulate updates from the SW/offline interface several times
252
- // invoke it at a few intervals, before pings are scheduled
256
+ expect(mockPing).toHaveBeenCalledTimes(2);
253
257
 
258
+ // simulate updates from the SW/offline interface several times
259
+ // invoke it at a few intervals, before pings are scheduled
254
260
  for (let i = 0; i < 3; i++) {
255
261
  jest.advanceTimersByTime(THIRD_INTERVAL_MS - 2000);
256
262
  onUpdate({
257
263
  isConnected: true
258
264
  });
259
- } // ping mock should STILL only have been called twice
265
+ }
260
266
 
267
+ // ping mock should STILL only have been called twice
268
+ expect(mockPing).toHaveBeenCalledTimes(2);
261
269
 
262
- expect(mockPing).toHaveBeenCalledTimes(2); // the delay should still be THIRD_INTERVAL_MS
270
+ // the delay should still be THIRD_INTERVAL_MS
271
+ assertLastDelay(setTimeoutSpy, THIRD_INTERVAL_MS);
263
272
 
264
- assertLastDelay(setTimeoutSpy, THIRD_INTERVAL_MS); // The timer works as normal for the next tick --
273
+ // The timer works as normal for the next tick --
265
274
  // 500ms before the fourth interval:
266
-
267
275
  jest.advanceTimersByTime(THIRD_INTERVAL_MS - 500);
268
- expect(mockPing).toHaveBeenCalledTimes(2); // 500ms after the fourth interval
269
-
276
+ expect(mockPing).toHaveBeenCalledTimes(2);
277
+ // 500ms after the fourth interval
270
278
  jest.advanceTimersByTime(1000);
271
279
  expect(mockPing).toHaveBeenCalledTimes(3);
272
280
  });
@@ -278,40 +286,45 @@ describe('interval behavior', () => {
278
286
  result
279
287
  } = renderHook(() => useDhis2ConnectionStatus(), {
280
288
  wrapper: wrapper
281
- }); // get onUpdate function passed to mockOfflineInterface
282
-
289
+ });
290
+ // get onUpdate function passed to mockOfflineInterface
283
291
  const {
284
292
  onUpdate
285
293
  } = mockOfflineInterface.subscribeToDhis2ConnectionStatus.mock.calls[0][0];
286
- expect(result.current.isConnected).toBe(true); // Get to third interval
287
- // (Wrap in `act` to await async side effects of the executions)
294
+ expect(result.current.isConnected).toBe(true);
288
295
 
296
+ // Get to third interval
297
+ // (Wrap in `act` to await async side effects of the executions)
289
298
  await act(async () => {
290
299
  jest.runOnlyPendingTimers();
291
300
  jest.runOnlyPendingTimers();
292
301
  });
293
302
  expect(mockPing).toHaveBeenCalledTimes(2);
294
- assertLastDelay(setTimeoutSpy, THIRD_INTERVAL_MS); // Trigger connection status change from offline interface
303
+ assertLastDelay(setTimeoutSpy, THIRD_INTERVAL_MS);
295
304
 
305
+ // Trigger connection status change from offline interface
296
306
  await act(async () => {
297
307
  onUpdate({
298
308
  isConnected: false
299
309
  });
300
- }); // Expect "first interval delay" to be set up
310
+ });
301
311
 
312
+ // Expect "first interval delay" to be set up
302
313
  assertLastDelay(setTimeoutSpy, FIRST_INTERVAL_MS);
303
- expect(result.current.isConnected).toBe(false); // Mock an error for the next ping to maintain `isConnected: false`
314
+ expect(result.current.isConnected).toBe(false);
304
315
 
316
+ // Mock an error for the next ping to maintain `isConnected: false`
305
317
  mockPing.mockImplementationOnce(() => Promise.reject({
306
318
  message: 'this is a network error',
307
319
  type: 'network'
308
- })); // Advance past "first interval" -- make sure incrementing resumes
320
+ }));
321
+ // Advance past "first interval" -- make sure incrementing resumes
309
322
  // while still 'isConnected: false'
310
-
311
323
  await act(async () => {
312
324
  jest.advanceTimersByTime(FIRST_INTERVAL_MS + 50);
313
- }); // Expect another execution with the incremented interval
325
+ });
314
326
 
327
+ // Expect another execution with the incremented interval
315
328
  expect(mockPing).toHaveBeenCalledTimes(3);
316
329
  assertLastDelay(setTimeoutSpy, SECOND_INTERVAL_MS);
317
330
  });
@@ -322,13 +335,15 @@ describe('interval behavior', () => {
322
335
  } = renderHook(() => useDhis2ConnectionStatus(), {
323
336
  wrapper: wrapper
324
337
  });
325
- expect(result.current.isConnected).toBe(true); // Get to third interval
338
+ expect(result.current.isConnected).toBe(true);
326
339
 
340
+ // Get to third interval
327
341
  jest.runOnlyPendingTimers();
328
342
  jest.runOnlyPendingTimers();
329
343
  expect(mockPing).toHaveBeenCalledTimes(2);
330
- assertLastDelay(setTimeoutSpy, THIRD_INTERVAL_MS); // Mock a network error
344
+ assertLastDelay(setTimeoutSpy, THIRD_INTERVAL_MS);
331
345
 
346
+ // Mock a network error
332
347
  mockPing.mockImplementationOnce(() => Promise.reject({
333
348
  message: 'this is a network error',
334
349
  type: 'network'
@@ -347,9 +362,10 @@ describe('pings aren\'t sent when the app is not focused; "standby behavior"', (
347
362
  renderHook(() => useDhis2ConnectionStatus(), {
348
363
  wrapper
349
364
  });
350
- window.dispatchEvent(new Event('blur')); // This recursively executes all timers -- if it's not in standby,
351
- // it will enter a loop
365
+ window.dispatchEvent(new Event('blur'));
352
366
 
367
+ // This recursively executes all timers -- if it's not in standby,
368
+ // it will enter a loop
353
369
  jest.runAllTimers();
354
370
  expect(mockPing).not.toHaveBeenCalled();
355
371
  });
@@ -357,8 +373,9 @@ describe('pings aren\'t sent when the app is not focused; "standby behavior"', (
357
373
  jest.spyOn(document, 'hasFocus').mockReturnValue(false);
358
374
  renderHook(() => useDhis2ConnectionStatus(), {
359
375
  wrapper
360
- }); // This recursively executes all timers
376
+ });
361
377
 
378
+ // This recursively executes all timers
362
379
  jest.runAllTimers();
363
380
  expect(mockPing).not.toHaveBeenCalled();
364
381
  });
@@ -366,27 +383,33 @@ describe('pings aren\'t sent when the app is not focused; "standby behavior"', (
366
383
  renderHook(() => useDhis2ConnectionStatus(), {
367
384
  wrapper
368
385
  });
369
- window.dispatchEvent(new Event('blur')); // wait half of the first interval
370
-
386
+ window.dispatchEvent(new Event('blur'));
387
+ // wait half of the first interval
371
388
  jest.advanceTimersByTime(FIRST_INTERVAL_MS / 2);
372
- window.dispatchEvent(new Event('focus')); // wait for just over the second half of the first interval
389
+ window.dispatchEvent(new Event('focus'));
373
390
 
374
- jest.advanceTimersByTime(FIRST_INTERVAL_MS / 2 + 50); // ping should execute normally
391
+ // wait for just over the second half of the first interval
392
+ jest.advanceTimersByTime(FIRST_INTERVAL_MS / 2 + 50);
375
393
 
394
+ // ping should execute normally
376
395
  expect(mockPing).toHaveBeenCalledTimes(1);
377
396
  });
378
397
  test('if the app is defocused until after a scheduled ping, that ping is not sent until the app is refocused', () => {
379
398
  renderHook(() => useDhis2ConnectionStatus(), {
380
399
  wrapper
381
400
  });
382
- window.dispatchEvent(new Event('blur')); // wait for twice the first interval
401
+ window.dispatchEvent(new Event('blur'));
383
402
 
384
- jest.advanceTimersByTime(FIRST_INTERVAL_MS * 2); // no pings should be sent since it's in standby
403
+ // wait for twice the first interval
404
+ jest.advanceTimersByTime(FIRST_INTERVAL_MS * 2);
385
405
 
386
- expect(mockPing).not.toHaveBeenCalled(); // refocus the page
406
+ // no pings should be sent since it's in standby
407
+ expect(mockPing).not.toHaveBeenCalled();
387
408
 
388
- window.dispatchEvent(new Event('focus')); // ping should execute immediately
409
+ // refocus the page
410
+ window.dispatchEvent(new Event('focus'));
389
411
 
412
+ // ping should execute immediately
390
413
  expect(mockPing).toHaveBeenCalledTimes(1);
391
414
  });
392
415
  });
@@ -395,8 +418,9 @@ describe('it pings when an offline event is detected', () => {
395
418
  renderHook(() => useDhis2ConnectionStatus(), {
396
419
  wrapper
397
420
  });
398
- window.dispatchEvent(new Event('offline')); // ping should execute immediately
421
+ window.dispatchEvent(new Event('offline'));
399
422
 
423
+ // ping should execute immediately
400
424
  expect(mockPing).toHaveBeenCalledTimes(1);
401
425
  });
402
426
  test('if the app is not focused, it does not ping immediately, but pings immediately when refocused', () => {
@@ -404,11 +428,13 @@ describe('it pings when an offline event is detected', () => {
404
428
  wrapper
405
429
  });
406
430
  window.dispatchEvent(new Event('blur'));
407
- window.dispatchEvent(new Event('offline')); // ping should not execute, but should be queued for refocus
431
+ window.dispatchEvent(new Event('offline'));
408
432
 
409
- expect(mockPing).toHaveBeenCalledTimes(0); // upon refocus, the ping should execute immediately
410
- // despite a full interval not elapsing
433
+ // ping should not execute, but should be queued for refocus
434
+ expect(mockPing).toHaveBeenCalledTimes(0);
411
435
 
436
+ // upon refocus, the ping should execute immediately
437
+ // despite a full interval not elapsing
412
438
  window.dispatchEvent(new Event('focus'));
413
439
  expect(mockPing).toHaveBeenCalledTimes(1);
414
440
  });
@@ -420,11 +446,12 @@ describe('it pings when an offline event is detected', () => {
420
446
  });
421
447
  window.dispatchEvent(new Event('blur'));
422
448
  window.dispatchEvent(new Event('offline'));
423
- window.dispatchEvent(new Event('focus')); // upon refocus, the ping should execute immediately
449
+ window.dispatchEvent(new Event('focus'));
450
+ // upon refocus, the ping should execute immediately
424
451
  // despite a full interval not elapsing
452
+ expect(mockPing).toHaveBeenCalledTimes(1);
425
453
 
426
- expect(mockPing).toHaveBeenCalledTimes(1); // The delay should be the initial again -- it shouldn't increment
427
-
454
+ // The delay should be the initial again -- it shouldn't increment
428
455
  assertLastDelay(setTimeoutSpy, FIRST_INTERVAL_MS);
429
456
  });
430
457
  test('same as previous, but interval is reset if status changes', async () => {
@@ -434,18 +461,21 @@ describe('it pings when an offline event is detected', () => {
434
461
  } = renderHook(() => useDhis2ConnectionStatus(), {
435
462
  wrapper: wrapper
436
463
  });
437
- expect(result.current.isConnected).toBe(true); // Get to third interval
464
+ expect(result.current.isConnected).toBe(true);
438
465
 
466
+ // Get to third interval
439
467
  jest.runOnlyPendingTimers();
440
468
  jest.runOnlyPendingTimers();
441
469
  expect(mockPing).toHaveBeenCalledTimes(2);
442
- assertLastDelay(setTimeoutSpy, THIRD_INTERVAL_MS); // Mock a network error
470
+ assertLastDelay(setTimeoutSpy, THIRD_INTERVAL_MS);
443
471
 
472
+ // Mock a network error
444
473
  mockPing.mockImplementationOnce(() => Promise.reject({
445
474
  message: 'this is a network error',
446
475
  type: 'network'
447
- })); // Blur, trigger 'offline' event, and refocus to trigger a ping
476
+ }));
448
477
 
478
+ // Blur, trigger 'offline' event, and refocus to trigger a ping
449
479
  window.dispatchEvent(new Event('blur'));
450
480
  window.dispatchEvent(new Event('offline'));
451
481
  await act(async () => {
@@ -461,15 +491,18 @@ describe('it pings when an offline event is detected', () => {
461
491
  wrapper
462
492
  });
463
493
  window.dispatchEvent(new Event('blur'));
464
- window.dispatchEvent(new Event('offline')); // Elapse twice one interval - it should enter full standby
494
+ window.dispatchEvent(new Event('offline'));
465
495
 
496
+ // Elapse twice one interval - it should enter full standby
466
497
  jest.advanceTimersByTime(FIRST_INTERVAL_MS * 2);
467
- expect(mockPing).toHaveBeenCalledTimes(0); // Refocusing should trigger a ping from the full standby,
468
- // not just the offline event
498
+ expect(mockPing).toHaveBeenCalledTimes(0);
469
499
 
500
+ // Refocusing should trigger a ping from the full standby,
501
+ // not just the offline event
470
502
  window.dispatchEvent(new Event('focus'));
471
- expect(mockPing).toHaveBeenCalledTimes(1); // The delay should increment this time, as it would from normal standby
503
+ expect(mockPing).toHaveBeenCalledTimes(1);
472
504
 
505
+ // The delay should increment this time, as it would from normal standby
473
506
  assertLastDelay(setTimeoutSpy, SECOND_INTERVAL_MS);
474
507
  });
475
508
  test('the same as previous, but the interval is reset if status has changed', async () => {
@@ -479,23 +512,27 @@ describe('it pings when an offline event is detected', () => {
479
512
  } = renderHook(() => useDhis2ConnectionStatus(), {
480
513
  wrapper: wrapper
481
514
  });
482
- expect(result.current.isConnected).toBe(true); // Get to third interval
515
+ expect(result.current.isConnected).toBe(true);
483
516
 
517
+ // Get to third interval
484
518
  jest.runOnlyPendingTimers();
485
519
  jest.runOnlyPendingTimers();
486
520
  expect(mockPing).toHaveBeenCalledTimes(2);
487
- assertLastDelay(setTimeoutSpy, THIRD_INTERVAL_MS); // Blur and elapse twice the third interval --
488
- // it should enter full standby
521
+ assertLastDelay(setTimeoutSpy, THIRD_INTERVAL_MS);
489
522
 
523
+ // Blur and elapse twice the third interval --
524
+ // it should enter full standby
490
525
  window.dispatchEvent(new Event('blur'));
491
526
  window.dispatchEvent(new Event('offline'));
492
- jest.advanceTimersByTime(THIRD_INTERVAL_MS * 2); // Mock a network error for the next ping
527
+ jest.advanceTimersByTime(THIRD_INTERVAL_MS * 2);
493
528
 
529
+ // Mock a network error for the next ping
494
530
  mockPing.mockImplementationOnce(() => Promise.reject({
495
531
  message: 'this is a network error',
496
532
  type: 'network'
497
- })); // Trigger a ping by refocusing
533
+ }));
498
534
 
535
+ // Trigger a ping by refocusing
499
536
  await act(async () => {
500
537
  window.dispatchEvent(new Event('focus'));
501
538
  });
@@ -523,10 +560,11 @@ describe('it pings when an online event is detected', () => {
523
560
  window.dispatchEvent(new Event('online'));
524
561
  window.dispatchEvent(new Event('offline'));
525
562
  expect(mockPing).toHaveBeenCalledTimes(3);
526
- window.dispatchEvent(new Event('online')); // Another ping should NOT be sent immediately after this latest
563
+ window.dispatchEvent(new Event('online'));
564
+ // Another ping should NOT be sent immediately after this latest
527
565
  // online event
528
-
529
- expect(mockPing).toHaveBeenCalledTimes(3); // (Not testing throttle time here because further pings may interfere)
566
+ expect(mockPing).toHaveBeenCalledTimes(3);
567
+ // (Not testing throttle time here because further pings may interfere)
530
568
  });
531
569
  });
532
570
  describe('lastConnected status', () => {
@@ -536,21 +574,26 @@ describe('lastConnected status', () => {
536
574
  } = renderHook(() => useDhis2ConnectionStatus(), {
537
575
  wrapper: wrapper
538
576
  });
539
- expect(result.current.isConnected).toBe(true); // Mock a network error for the next ping
577
+ expect(result.current.isConnected).toBe(true);
540
578
 
541
- mockPing.mockImplementationOnce(failedPing); // Trigger a ping (to fail and switch to disconnected)
579
+ // Mock a network error for the next ping
580
+ mockPing.mockImplementationOnce(failedPing);
542
581
 
582
+ // Trigger a ping (to fail and switch to disconnected)
543
583
  await act(async () => {
544
584
  jest.runOnlyPendingTimers();
545
585
  });
546
- expect(mockPing).toHaveBeenCalledTimes(1); // Expect 'disconnected' status now
586
+ expect(mockPing).toHaveBeenCalledTimes(1);
547
587
 
588
+ // Expect 'disconnected' status now
548
589
  expect(result.current.isConnected).toBe(false);
549
- expect(result.current.isDisconnected).toBe(true); // Check localStorage for the dummy date
590
+ expect(result.current.isDisconnected).toBe(true);
550
591
 
592
+ // Check localStorage for the dummy date
551
593
  const localStorageDate = localStorage.getItem(getLastConnectedKey());
552
- expect(localStorageDate).toBe(testCurrentDate.toUTCString()); // Check hook return value
594
+ expect(localStorageDate).toBe(testCurrentDate.toUTCString());
553
595
 
596
+ // Check hook return value
554
597
  expect(result.current.lastConnected).toBeInstanceOf(Date);
555
598
  expect(result.current.lastConnected).toEqual(testCurrentDate);
556
599
  });
@@ -560,18 +603,22 @@ describe('lastConnected status', () => {
560
603
  } = renderHook(() => useDhis2ConnectionStatus(), {
561
604
  wrapper: wrapper
562
605
  });
563
- expect(result.current.isConnected).toBe(true); // Mock a network error for the next ping
606
+ expect(result.current.isConnected).toBe(true);
564
607
 
565
- mockPing.mockImplementationOnce(failedPing); // Trigger an immediate ping (to fail and switch to disconnected)
608
+ // Mock a network error for the next ping
609
+ mockPing.mockImplementationOnce(failedPing);
566
610
 
611
+ // Trigger an immediate ping (to fail and switch to disconnected)
567
612
  await act(async () => {
568
613
  jest.runOnlyPendingTimers();
569
614
  });
570
- expect(mockPing).toHaveBeenCalledTimes(1); // Verify hook return value
615
+ expect(mockPing).toHaveBeenCalledTimes(1);
571
616
 
617
+ // Verify hook return value
572
618
  expect(result.current.isConnected).toBe(false);
573
- expect(result.current.lastConnected).toEqual(testCurrentDate); // Trigger a successful ping to go back online
619
+ expect(result.current.lastConnected).toEqual(testCurrentDate);
574
620
 
621
+ // Trigger a successful ping to go back online
575
622
  await act(async () => {
576
623
  jest.runOnlyPendingTimers();
577
624
  });
@@ -585,16 +632,19 @@ describe('lastConnected status', () => {
585
632
  unmount
586
633
  } = renderHook(() => useDhis2ConnectionStatus(), {
587
634
  wrapper: wrapper
588
- }); // Mock a network error for the next ping to trigger 'disconnected'
635
+ });
589
636
 
637
+ // Mock a network error for the next ping to trigger 'disconnected'
590
638
  mockPing.mockImplementationOnce(failedPing);
591
639
  await act(async () => {
592
640
  jest.runOnlyPendingTimers();
593
641
  });
594
- expect(result.current.isConnected).toBe(false); // Unmount
642
+ expect(result.current.isConnected).toBe(false);
595
643
 
596
- unmount(); // Expect value to persist in localStorage
644
+ // Unmount
645
+ unmount();
597
646
 
647
+ // Expect value to persist in localStorage
598
648
  const localStorageDate = localStorage.getItem(getLastConnectedKey());
599
649
  expect(localStorageDate).toBe(testCurrentDate.toUTCString());
600
650
  });
@@ -605,22 +655,26 @@ describe('lastConnected status', () => {
605
655
  } = renderHook(() => useDhis2ConnectionStatus(), {
606
656
  wrapper
607
657
  });
608
- expect(result.current.isConnected).toBe(true); // Mock a network error for the next ping to trigger disconnected
658
+ expect(result.current.isConnected).toBe(true);
609
659
 
660
+ // Mock a network error for the next ping to trigger disconnected
610
661
  mockPing.mockImplementationOnce(failedPing);
611
662
  await act(async () => {
612
663
  jest.runOnlyPendingTimers();
613
664
  });
614
- expect(result.current.isConnected).toBe(false); // Check localStorage for the dummy date
665
+ expect(result.current.isConnected).toBe(false);
615
666
 
667
+ // Check localStorage for the dummy date
616
668
  const localStorageDate = localStorage.getItem(getLastConnectedKey());
617
- expect(localStorageDate).toBe(testCurrentDate.toUTCString()); // Trigger another ping to go back to connected
669
+ expect(localStorageDate).toBe(testCurrentDate.toUTCString());
618
670
 
671
+ // Trigger another ping to go back to connected
619
672
  await act(async () => {
620
673
  jest.runOnlyPendingTimers();
621
674
  });
622
- expect(result.current.isConnected).toBe(true); // Unmount and expect localStorage to be clear for next session
675
+ expect(result.current.isConnected).toBe(true);
623
676
 
677
+ // Unmount and expect localStorage to be clear for next session
624
678
  unmount();
625
679
  expect(localStorage.getItem(getLastConnectedKey())).toBe(null);
626
680
  });
@@ -628,36 +682,38 @@ describe('lastConnected status', () => {
628
682
  test('it sets lastConnected to `now` if nothing is found in localStorage', async () => {
629
683
  // use a custom offlineInterface with `latestIsConnected: false`
630
684
  // to initialize the `isConnected` state to false
631
- const customMockOfflineInterface = { ...mockOfflineInterface,
685
+ const customMockOfflineInterface = {
686
+ ...mockOfflineInterface,
632
687
  latestIsConnected: false
633
688
  };
634
-
635
- const customWrapper = (_ref4) => {
689
+ const customWrapper = _ref4 => {
636
690
  let {
637
691
  children
638
692
  } = _ref4;
639
693
  return /*#__PURE__*/React.createElement(OfflineProvider, {
640
694
  offlineInterface: customMockOfflineInterface
641
695
  }, children);
642
- }; // render hook with custom wrapper
643
-
696
+ };
644
697
 
698
+ // render hook with custom wrapper
645
699
  renderHook(() => useDhis2ConnectionStatus(), {
646
700
  wrapper: customWrapper
647
- }); // expect correct lastConnected time (mocked Date.now())
701
+ });
648
702
 
703
+ // expect correct lastConnected time (mocked Date.now())
649
704
  expect(localStorage.getItem(getLastConnectedKey())).toBe(testCurrentDate.toUTCString());
650
705
  });
651
706
  test('if a value is already in localStorage, it uses that without overwriting', async () => {
652
707
  // seed localStorage with an imaginary 'lastConnected' value from last session
653
708
  const testPreviousDate = new Date('2023-01-01');
654
- localStorage.setItem(getLastConnectedKey(), testPreviousDate.toUTCString()); // render hook with custom wrapper
709
+ localStorage.setItem(getLastConnectedKey(), testPreviousDate.toUTCString());
655
710
 
656
- const customMockOfflineInterface = { ...mockOfflineInterface,
711
+ // render hook with custom wrapper
712
+ const customMockOfflineInterface = {
713
+ ...mockOfflineInterface,
657
714
  latestIsConnected: false
658
715
  };
659
-
660
- const customWrapper = (_ref5) => {
716
+ const customWrapper = _ref5 => {
661
717
  let {
662
718
  children
663
719
  } = _ref5;
@@ -665,29 +721,30 @@ describe('lastConnected status', () => {
665
721
  offlineInterface: customMockOfflineInterface
666
722
  }, children);
667
723
  };
668
-
669
724
  const {
670
725
  result
671
726
  } = renderHook(() => useDhis2ConnectionStatus(), {
672
727
  wrapper: customWrapper
673
- }); // On render, the hook should retain last connected
728
+ });
674
729
 
730
+ // On render, the hook should retain last connected
675
731
  expect(result.current.lastConnected).not.toBe(null);
676
- expect(result.current.lastConnected).toEqual(testPreviousDate); // should be the same in localStorage too
677
-
732
+ expect(result.current.lastConnected).toEqual(testPreviousDate);
733
+ // should be the same in localStorage too
678
734
  expect(localStorage.getItem(getLastConnectedKey())).toBe(testPreviousDate.toUTCString());
679
735
  });
680
736
  });
681
737
  test("it doesn't change lastConnected if already disconnected", async () => {
682
738
  // seed localStorage with an imaginary 'lastConnected' value from last session
683
739
  const testPreviousDate = new Date('2023-01-01');
684
- localStorage.setItem(getLastConnectedKey(), testPreviousDate.toUTCString()); // render hook with custom wrapper
740
+ localStorage.setItem(getLastConnectedKey(), testPreviousDate.toUTCString());
685
741
 
686
- const customMockOfflineInterface = { ...mockOfflineInterface,
742
+ // render hook with custom wrapper
743
+ const customMockOfflineInterface = {
744
+ ...mockOfflineInterface,
687
745
  latestIsConnected: false
688
746
  };
689
-
690
- const customWrapper = (_ref6) => {
747
+ const customWrapper = _ref6 => {
691
748
  let {
692
749
  children
693
750
  } = _ref6;
@@ -706,26 +763,29 @@ describe('lastConnected status', () => {
706
763
  offlineInterface: customMockOfflineInterface
707
764
  }, children));
708
765
  };
709
-
710
766
  const {
711
767
  result
712
768
  } = renderHook(() => useDhis2ConnectionStatus(), {
713
769
  wrapper: customWrapper
714
- }); // As in previous test, the hook should retain last connected
770
+ });
715
771
 
716
- expect(result.current.lastConnected).toEqual(testPreviousDate); // Mock a network error for the next ping and trigger
772
+ // As in previous test, the hook should retain last connected
773
+ expect(result.current.lastConnected).toEqual(testPreviousDate);
717
774
 
775
+ // Mock a network error for the next ping and trigger
718
776
  mockPing.mockImplementationOnce(failedPing);
719
777
  await act(async () => {
720
778
  jest.runOnlyPendingTimers();
721
779
  });
722
- expect(mockPing).toHaveBeenCalledTimes(1); // Expect the same lastConnected as before
780
+ expect(mockPing).toHaveBeenCalledTimes(1);
723
781
 
724
- expect(result.current.lastConnected).toEqual(testPreviousDate); // should be the same in localStorage too
782
+ // Expect the same lastConnected as before
783
+ expect(result.current.lastConnected).toEqual(testPreviousDate);
784
+ // should be the same in localStorage too
785
+ expect(localStorage.getItem(getLastConnectedKey())).toBe(testPreviousDate.toUTCString());
725
786
 
726
- expect(localStorage.getItem(getLastConnectedKey())).toBe(testPreviousDate.toUTCString()); // Verify the same with a signal from the service worker
787
+ // Verify the same with a signal from the service worker
727
788
  // get onUpdate function passed to mockOfflineInterface
728
-
729
789
  const {
730
790
  onUpdate
731
791
  } = mockOfflineInterface.subscribeToDhis2ConnectionStatus.mock.calls[0][0];
@@ -733,8 +793,9 @@ describe('lastConnected status', () => {
733
793
  onUpdate({
734
794
  isConnected: false
735
795
  });
736
- }); // Expect the same lastConnected as before
796
+ });
737
797
 
798
+ // Expect the same lastConnected as before
738
799
  expect(result.current.lastConnected).toEqual(testPreviousDate);
739
800
  });
740
801
  test('lastConnected is saved specifically to an app if a name is provided', async () => {
@@ -742,13 +803,14 @@ describe('lastConnected status', () => {
742
803
  const testAppName = 'test-app-name';
743
804
  const lastConnectedKey = getLastConnectedKey(testAppName);
744
805
  const testPreviousDate = new Date('2023-01-01');
745
- localStorage.setItem(lastConnectedKey, testPreviousDate.toUTCString()); // render hook with custom wrapper to start disconnected with app name
806
+ localStorage.setItem(lastConnectedKey, testPreviousDate.toUTCString());
746
807
 
747
- const customMockOfflineInterface = { ...mockOfflineInterface,
808
+ // render hook with custom wrapper to start disconnected with app name
809
+ const customMockOfflineInterface = {
810
+ ...mockOfflineInterface,
748
811
  latestIsConnected: false
749
812
  };
750
-
751
- const customWrapper = (_ref7) => {
813
+ const customWrapper = _ref7 => {
752
814
  let {
753
815
  children
754
816
  } = _ref7;
@@ -768,15 +830,16 @@ describe('lastConnected status', () => {
768
830
  offlineInterface: customMockOfflineInterface
769
831
  }, children));
770
832
  };
771
-
772
833
  const {
773
834
  result
774
835
  } = renderHook(() => useDhis2ConnectionStatus(), {
775
836
  wrapper: customWrapper
776
- }); // Expect previous value to be read correctly
837
+ });
777
838
 
778
- expect(result.current.lastConnected).toEqual(testPreviousDate); // Go to connected then disconnected again to generate a new date
839
+ // Expect previous value to be read correctly
840
+ expect(result.current.lastConnected).toEqual(testPreviousDate);
779
841
 
842
+ // Go to connected then disconnected again to generate a new date
780
843
  await act(async () => {
781
844
  jest.runOnlyPendingTimers();
782
845
  });
@@ -787,15 +850,16 @@ describe('lastConnected status', () => {
787
850
  await act(async () => {
788
851
  jest.runOnlyPendingTimers();
789
852
  });
790
- expect(result.current.isConnected).toBe(false); // Note the new date:
791
-
792
- expect(result.current.lastConnected).toEqual(testCurrentDate); // Verify localStorage
853
+ expect(result.current.isConnected).toBe(false);
854
+ // Note the new date:
855
+ expect(result.current.lastConnected).toEqual(testCurrentDate);
793
856
 
857
+ // Verify localStorage
794
858
  expect(localStorage.getItem(lastConnectedKey)).toBe(testCurrentDate.toUTCString());
795
859
  });
796
860
  });
797
861
  describe("when the /api/ping endpoint isn't supported", () => {
798
- const customWrapper = (_ref8) => {
862
+ const customWrapper = _ref8 => {
799
863
  let {
800
864
  children
801
865
  } = _ref8;
@@ -815,7 +879,6 @@ describe("when the /api/ping endpoint isn't supported", () => {
815
879
  offlineInterface: mockOfflineInterface
816
880
  }, children));
817
881
  };
818
-
819
882
  test("pings aren't sent", async () => {
820
883
  const setTimeoutSpy = jest.spyOn(window, 'setTimeout');
821
884
  renderHook(() => useDhis2ConnectionStatus(), {
@@ -832,13 +895,14 @@ describe("when the /api/ping endpoint isn't supported", () => {
832
895
  result
833
896
  } = renderHook(() => useDhis2ConnectionStatus(), {
834
897
  wrapper: wrapper
835
- }); // get onUpdate function passed to mockOfflineInterface
836
-
898
+ });
899
+ // get onUpdate function passed to mockOfflineInterface
837
900
  const {
838
901
  onUpdate
839
902
  } = mockOfflineInterface.subscribeToDhis2ConnectionStatus.mock.calls[0][0];
840
- expect(result.current.isConnected).toBe(true); // Trigger connection status change from offline interface
903
+ expect(result.current.isConnected).toBe(true);
841
904
 
905
+ // Trigger connection status change from offline interface
842
906
  await act(async () => {
843
907
  onUpdate({
844
908
  isConnected: false