@dhis2/app-service-offline 3.8.0 → 3.9.0
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.
- package/build/cjs/__tests__/integration.test.js +37 -24
- package/build/cjs/index.js +18 -10
- package/build/cjs/lib/__tests__/clear-sensitive-caches.test.js +5 -1
- package/build/cjs/lib/__tests__/{online-status.test.js → network-status.test.js} +41 -20
- package/build/cjs/lib/__tests__/offline-provider.test.js +5 -1
- package/build/cjs/lib/__tests__/use-cacheable-section.test.js +77 -35
- package/build/cjs/lib/__tests__/{use-online-staus-message.test.js → use-online-status-message.test.js} +8 -5
- package/build/cjs/lib/cacheable-section-state.js +17 -13
- package/build/cjs/lib/cacheable-section.js +14 -12
- package/build/cjs/lib/clear-sensitive-caches.js +9 -5
- package/build/cjs/lib/dhis2-connection-status/dev-debug-log.js +26 -0
- package/build/cjs/lib/dhis2-connection-status/dhis2-connection-status.js +224 -0
- package/build/cjs/lib/dhis2-connection-status/dhis2-connection-status.test.js +841 -0
- package/build/cjs/lib/dhis2-connection-status/index.js +19 -0
- package/build/cjs/lib/dhis2-connection-status/is-ping-available.js +43 -0
- package/build/cjs/lib/dhis2-connection-status/is-ping-available.test.js +76 -0
- package/build/cjs/lib/dhis2-connection-status/smart-interval.js +211 -0
- package/build/cjs/lib/dhis2-connection-status/use-ping-query.js +21 -0
- package/build/cjs/lib/global-state-service.js +16 -11
- package/build/cjs/lib/{online-status.js → network-status.js} +8 -5
- package/build/cjs/lib/offline-interface.js +7 -4
- package/build/cjs/lib/offline-provider.js +9 -5
- package/build/cjs/lib/online-status-message.js +5 -4
- package/build/cjs/utils/render-counter.js +6 -4
- package/build/cjs/utils/test-mocks.js +17 -10
- package/build/es/__tests__/integration.test.js +37 -24
- package/build/es/index.js +5 -3
- package/build/es/lib/__tests__/clear-sensitive-caches.test.js +5 -1
- package/build/es/lib/__tests__/{online-status.test.js → network-status.test.js} +35 -14
- package/build/es/lib/__tests__/offline-provider.test.js +5 -1
- package/build/es/lib/__tests__/use-cacheable-section.test.js +77 -34
- package/build/es/lib/__tests__/{use-online-staus-message.test.js → use-online-status-message.test.js} +8 -5
- package/build/es/lib/cacheable-section-state.js +14 -10
- package/build/es/lib/cacheable-section.js +13 -11
- package/build/es/lib/clear-sensitive-caches.js +8 -4
- package/build/es/lib/dhis2-connection-status/dev-debug-log.js +20 -0
- package/build/es/lib/dhis2-connection-status/dhis2-connection-status.js +194 -0
- package/build/es/lib/dhis2-connection-status/dhis2-connection-status.test.js +831 -0
- package/build/es/lib/dhis2-connection-status/index.js +1 -0
- package/build/es/lib/dhis2-connection-status/is-ping-available.js +36 -0
- package/build/es/lib/dhis2-connection-status/is-ping-available.test.js +73 -0
- package/build/es/lib/dhis2-connection-status/smart-interval.js +199 -0
- package/build/es/lib/dhis2-connection-status/use-ping-query.js +12 -0
- package/build/es/lib/global-state-service.js +15 -10
- package/build/es/lib/{online-status.js → network-status.js} +7 -4
- package/build/es/lib/offline-interface.js +7 -4
- package/build/es/lib/offline-provider.js +8 -5
- package/build/es/lib/online-status-message.js +4 -3
- package/build/es/utils/render-counter.js +6 -4
- package/build/es/utils/test-mocks.js +16 -9
- package/build/types/index.d.ts +2 -1
- package/build/types/lib/dhis2-connection-status/dev-debug-log.d.ts +9 -0
- package/build/types/lib/dhis2-connection-status/dhis2-connection-status.d.ts +28 -0
- package/build/types/lib/dhis2-connection-status/index.d.ts +1 -0
- package/build/types/lib/dhis2-connection-status/is-ping-available.d.ts +14 -0
- package/build/types/lib/dhis2-connection-status/smart-interval.d.ts +18 -0
- package/build/types/lib/dhis2-connection-status/use-ping-query.d.ts +1 -0
- package/build/types/lib/{online-status.d.ts → network-status.d.ts} +3 -3
- package/build/types/types.d.ts +6 -0
- package/build/types/utils/test-mocks.d.ts +2 -0
- package/package.json +2 -2
|
@@ -11,10 +11,11 @@ const renderCounts = {};
|
|
|
11
11
|
|
|
12
12
|
const identity = arg => arg;
|
|
13
13
|
|
|
14
|
-
const TestControls = ({
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
const TestControls = (_ref) => {
|
|
15
|
+
let {
|
|
16
|
+
id,
|
|
17
|
+
makeRecordingHandler = identity
|
|
18
|
+
} = _ref;
|
|
18
19
|
const {
|
|
19
20
|
startRecording,
|
|
20
21
|
remove,
|
|
@@ -23,37 +24,40 @@ const TestControls = ({
|
|
|
23
24
|
recordingState
|
|
24
25
|
} = useCacheableSection(id);
|
|
25
26
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(RenderCounter, {
|
|
26
|
-
id:
|
|
27
|
+
id: `controls-rc-${id}`,
|
|
27
28
|
countsObj: renderCounts
|
|
28
29
|
}), /*#__PURE__*/React.createElement("button", {
|
|
29
|
-
"data-testid":
|
|
30
|
+
"data-testid": `start-recording-${id}`,
|
|
30
31
|
onClick: makeRecordingHandler(startRecording)
|
|
31
32
|
}), /*#__PURE__*/React.createElement("button", {
|
|
32
|
-
"data-testid":
|
|
33
|
+
"data-testid": `remove-${id}`,
|
|
33
34
|
onClick: () => {
|
|
34
35
|
remove();
|
|
35
36
|
}
|
|
36
37
|
}), /*#__PURE__*/React.createElement("div", {
|
|
37
|
-
"data-testid":
|
|
38
|
+
"data-testid": `is-cached-${id}`
|
|
38
39
|
}, isCached ? 'yes' : 'no'), /*#__PURE__*/React.createElement("div", {
|
|
39
|
-
"data-testid":
|
|
40
|
+
"data-testid": `last-updated-${id}`
|
|
40
41
|
}, lastUpdated || 'never'), /*#__PURE__*/React.createElement("div", {
|
|
41
|
-
"data-testid":
|
|
42
|
+
"data-testid": `recording-state-${id}`
|
|
42
43
|
}, recordingState));
|
|
43
44
|
};
|
|
44
45
|
|
|
45
|
-
const TestSection = ({
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
46
|
+
const TestSection = (_ref2) => {
|
|
47
|
+
let {
|
|
48
|
+
id,
|
|
49
|
+
children
|
|
50
|
+
} = _ref2;
|
|
51
|
+
return /*#__PURE__*/React.createElement(CacheableSection, {
|
|
52
|
+
id: id,
|
|
53
|
+
loadingMask: /*#__PURE__*/React.createElement("div", {
|
|
54
|
+
"data-testid": `loading-mask-${id}`
|
|
55
|
+
})
|
|
56
|
+
}, /*#__PURE__*/React.createElement(RenderCounter, {
|
|
57
|
+
id: `section-rc-${id}`,
|
|
58
|
+
countsObj: renderCounts
|
|
59
|
+
}), children);
|
|
60
|
+
};
|
|
57
61
|
|
|
58
62
|
const TestSingleSection = props => {
|
|
59
63
|
// Props are spread so they can be overwritten
|
|
@@ -71,9 +75,13 @@ const originalError = console.error;
|
|
|
71
75
|
beforeEach(() => {
|
|
72
76
|
// This is done before each because the 'recording error' test uses its own
|
|
73
77
|
// spy on console.error
|
|
74
|
-
jest.spyOn(console, 'error').mockImplementation((
|
|
78
|
+
jest.spyOn(console, 'error').mockImplementation(function () {
|
|
75
79
|
const pattern = /Warning: An update to .* inside a test was not wrapped in act/;
|
|
76
80
|
|
|
81
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
82
|
+
args[_key] = arguments[_key];
|
|
83
|
+
}
|
|
84
|
+
|
|
77
85
|
if (typeof args[0] === 'string' && pattern.test(args[0])) {
|
|
78
86
|
return;
|
|
79
87
|
}
|
|
@@ -139,9 +147,14 @@ describe('Coordination between useCacheableSection and CacheableSection', () =>
|
|
|
139
147
|
});
|
|
140
148
|
it('handles a recording that encounters an error', async done => {
|
|
141
149
|
// Suppress the expected error from console (in addition to 'act' warning)
|
|
142
|
-
jest.spyOn(console, 'error').mockImplementation((
|
|
150
|
+
jest.spyOn(console, 'error').mockImplementation(function () {
|
|
143
151
|
const actPattern = /Warning: An update to .* inside a test was not wrapped in act/;
|
|
144
152
|
const errPattern = /Error during recording/;
|
|
153
|
+
|
|
154
|
+
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
155
|
+
args[_key2] = arguments[_key2];
|
|
156
|
+
}
|
|
157
|
+
|
|
145
158
|
const matchesPattern = actPattern.test(args[0]) || errPattern.test(args[0]);
|
|
146
159
|
|
|
147
160
|
if (typeof args[0] === 'string' && matchesPattern) {
|
package/build/es/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { OfflineProvider } from './lib/offline-provider';
|
|
2
2
|
export { CacheableSection, useCacheableSection } from './lib/cacheable-section';
|
|
3
|
-
export { useCachedSections } from './lib/cacheable-section-state';
|
|
4
|
-
|
|
3
|
+
export { useCachedSections } from './lib/cacheable-section-state'; // Use "useOnlineStatus" name for backwards compatibility
|
|
4
|
+
|
|
5
|
+
export { useNetworkStatus as useOnlineStatus } from './lib/network-status';
|
|
5
6
|
export { useOnlineStatusMessage } from './lib/online-status-message';
|
|
6
|
-
export { clearSensitiveCaches } from './lib/clear-sensitive-caches';
|
|
7
|
+
export { clearSensitiveCaches } from './lib/clear-sensitive-caches';
|
|
8
|
+
export { useDhis2ConnectionStatus } from './lib/dhis2-connection-status';
|
|
@@ -26,9 +26,13 @@ afterEach(() => {
|
|
|
26
26
|
|
|
27
27
|
const originalDebug = console.debug;
|
|
28
28
|
beforeAll(() => {
|
|
29
|
-
jest.spyOn(console, 'debug').mockImplementation((
|
|
29
|
+
jest.spyOn(console, 'debug').mockImplementation(function () {
|
|
30
30
|
const pattern = /Clearing sensitive caches/;
|
|
31
31
|
|
|
32
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
33
|
+
args[_key] = arguments[_key];
|
|
34
|
+
}
|
|
35
|
+
|
|
32
36
|
if (typeof args[0] === 'string' && pattern.test(args[0])) {
|
|
33
37
|
return;
|
|
34
38
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { render, screen, waitFor } from '@testing-library/react';
|
|
2
2
|
import { act, renderHook } from '@testing-library/react-hooks';
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import { useOnlineStatus } from '../
|
|
4
|
+
import { useNetworkStatus as useOnlineStatus } from '../network-status';
|
|
5
5
|
|
|
6
6
|
function wait(ms) {
|
|
7
7
|
return new Promise(resolve => {
|
|
@@ -42,7 +42,9 @@ describe('state changes in response to browser "online" and "offline" events', (
|
|
|
42
42
|
const {
|
|
43
43
|
result,
|
|
44
44
|
waitForNextUpdate
|
|
45
|
-
} = renderHook(
|
|
45
|
+
} = renderHook(function () {
|
|
46
|
+
return useOnlineStatus(...arguments);
|
|
47
|
+
}, {
|
|
46
48
|
initialProps: {
|
|
47
49
|
debounceDelay: 50
|
|
48
50
|
}
|
|
@@ -65,7 +67,9 @@ describe('state changes in response to browser "online" and "offline" events', (
|
|
|
65
67
|
const {
|
|
66
68
|
result,
|
|
67
69
|
waitForNextUpdate
|
|
68
|
-
} = renderHook(
|
|
70
|
+
} = renderHook(function () {
|
|
71
|
+
return useOnlineStatus(...arguments);
|
|
72
|
+
}, {
|
|
69
73
|
initialProps: {
|
|
70
74
|
debounceDelay: 50
|
|
71
75
|
}
|
|
@@ -113,7 +117,9 @@ describe('debouncing state changes', () => {
|
|
|
113
117
|
const {
|
|
114
118
|
result,
|
|
115
119
|
waitForNextUpdate
|
|
116
|
-
} = renderHook(
|
|
120
|
+
} = renderHook(function () {
|
|
121
|
+
return useOnlineStatus(...arguments);
|
|
122
|
+
}, {
|
|
117
123
|
initialProps: {
|
|
118
124
|
debounceDelay: 50
|
|
119
125
|
}
|
|
@@ -139,7 +145,9 @@ describe('debouncing state changes', () => {
|
|
|
139
145
|
const {
|
|
140
146
|
result,
|
|
141
147
|
waitForNextUpdate
|
|
142
|
-
} = renderHook(
|
|
148
|
+
} = renderHook(function () {
|
|
149
|
+
return useOnlineStatus(...arguments);
|
|
150
|
+
}, {
|
|
143
151
|
initialProps: {
|
|
144
152
|
debounceDelay: 0
|
|
145
153
|
}
|
|
@@ -166,7 +174,9 @@ describe('debouncing state changes', () => {
|
|
|
166
174
|
result,
|
|
167
175
|
waitForNextUpdate,
|
|
168
176
|
rerender
|
|
169
|
-
} = renderHook(
|
|
177
|
+
} = renderHook(function () {
|
|
178
|
+
return useOnlineStatus(...arguments);
|
|
179
|
+
}, {
|
|
170
180
|
initialProps: {
|
|
171
181
|
debounceDelay: 150
|
|
172
182
|
}
|
|
@@ -243,9 +253,10 @@ describe('debouncing state changes', () => {
|
|
|
243
253
|
const events = {};
|
|
244
254
|
window.addEventListener = jest.fn((event, cb) => events[event] = cb);
|
|
245
255
|
|
|
246
|
-
const TestComponent = ({
|
|
247
|
-
|
|
248
|
-
|
|
256
|
+
const TestComponent = (_ref) => {
|
|
257
|
+
let {
|
|
258
|
+
options
|
|
259
|
+
} = _ref;
|
|
249
260
|
const {
|
|
250
261
|
online
|
|
251
262
|
} = useOnlineStatus(options);
|
|
@@ -341,7 +352,9 @@ describe('it updates the lastOnline value in local storage', () => {
|
|
|
341
352
|
const {
|
|
342
353
|
result,
|
|
343
354
|
waitForNextUpdate
|
|
344
|
-
} = renderHook(
|
|
355
|
+
} = renderHook(function () {
|
|
356
|
+
return useOnlineStatus(...arguments);
|
|
357
|
+
}, {
|
|
345
358
|
initialProps: {
|
|
346
359
|
debounceDelay: 0
|
|
347
360
|
}
|
|
@@ -374,7 +387,9 @@ describe('it updates the lastOnline value in local storage', () => {
|
|
|
374
387
|
window.addEventListener = jest.fn((event, cb) => events[event] = cb);
|
|
375
388
|
const {
|
|
376
389
|
result
|
|
377
|
-
} = renderHook(
|
|
390
|
+
} = renderHook(function () {
|
|
391
|
+
return useOnlineStatus(...arguments);
|
|
392
|
+
}, {
|
|
378
393
|
initialProps: {
|
|
379
394
|
debounceDelay: 0
|
|
380
395
|
}
|
|
@@ -392,7 +407,9 @@ describe('it updates the lastOnline value in local storage', () => {
|
|
|
392
407
|
window.addEventListener = jest.fn((event, cb) => events[event] = cb);
|
|
393
408
|
const {
|
|
394
409
|
result
|
|
395
|
-
} = renderHook(
|
|
410
|
+
} = renderHook(function () {
|
|
411
|
+
return useOnlineStatus(...arguments);
|
|
412
|
+
}, {
|
|
396
413
|
initialProps: {
|
|
397
414
|
debounceDelay: 0
|
|
398
415
|
}
|
|
@@ -417,7 +434,9 @@ describe('it updates the lastOnline value in local storage', () => {
|
|
|
417
434
|
const {
|
|
418
435
|
result,
|
|
419
436
|
waitForNextUpdate
|
|
420
|
-
} = renderHook(
|
|
437
|
+
} = renderHook(function () {
|
|
438
|
+
return useOnlineStatus(...arguments);
|
|
439
|
+
}, {
|
|
421
440
|
initialProps: {
|
|
422
441
|
debounceDelay: 0
|
|
423
442
|
}
|
|
@@ -445,7 +464,9 @@ describe('it updates the lastOnline value in local storage', () => {
|
|
|
445
464
|
const {
|
|
446
465
|
result,
|
|
447
466
|
waitForNextUpdate
|
|
448
|
-
} = renderHook(
|
|
467
|
+
} = renderHook(function () {
|
|
468
|
+
return useOnlineStatus(...arguments);
|
|
469
|
+
}, {
|
|
449
470
|
initialProps: {
|
|
450
471
|
debounceDelay: 0
|
|
451
472
|
}
|
|
@@ -7,9 +7,13 @@ import { OfflineProvider } from '../offline-provider'; // Suppress 'act' warning
|
|
|
7
7
|
|
|
8
8
|
const originalError = console.error;
|
|
9
9
|
beforeEach(() => {
|
|
10
|
-
jest.spyOn(console, 'error').mockImplementation((
|
|
10
|
+
jest.spyOn(console, 'error').mockImplementation(function () {
|
|
11
11
|
const pattern = /Warning: An update to .* inside a test was not wrapped in act/;
|
|
12
12
|
|
|
13
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
14
|
+
args[_key] = arguments[_key];
|
|
15
|
+
}
|
|
16
|
+
|
|
13
17
|
if (typeof args[0] === 'string' && pattern.test(args[0])) {
|
|
14
18
|
return;
|
|
15
19
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { AlertsProvider } from '@dhis2/app-service-alerts';
|
|
2
1
|
import { renderHook, act } from '@testing-library/react-hooks';
|
|
3
2
|
import React from 'react';
|
|
4
3
|
import { errorRecordingMock, failedMessageRecordingMock, mockOfflineInterface } from '../../utils/test-mocks';
|
|
@@ -7,9 +6,13 @@ import { OfflineProvider } from '../offline-provider'; // Suppress 'act' warning
|
|
|
7
6
|
|
|
8
7
|
const originalError = console.error;
|
|
9
8
|
beforeEach(() => {
|
|
10
|
-
jest.spyOn(console, 'error').mockImplementation((
|
|
9
|
+
jest.spyOn(console, 'error').mockImplementation(function () {
|
|
11
10
|
const pattern = /Warning: An update to .* inside a test was not wrapped in act/;
|
|
12
11
|
|
|
12
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
13
|
+
args[_key] = arguments[_key];
|
|
14
|
+
}
|
|
15
|
+
|
|
13
16
|
if (typeof args[0] === 'string' && pattern.test(args[0])) {
|
|
14
17
|
return;
|
|
15
18
|
}
|
|
@@ -23,14 +26,19 @@ afterEach(() => {
|
|
|
23
26
|
console.error.mockRestore();
|
|
24
27
|
});
|
|
25
28
|
it('renders in the default state initially', () => {
|
|
29
|
+
const wrapper = (_ref) => {
|
|
30
|
+
let {
|
|
31
|
+
children
|
|
32
|
+
} = _ref;
|
|
33
|
+
return /*#__PURE__*/React.createElement(OfflineProvider, {
|
|
34
|
+
offlineInterface: mockOfflineInterface
|
|
35
|
+
}, children);
|
|
36
|
+
};
|
|
37
|
+
|
|
26
38
|
const {
|
|
27
39
|
result
|
|
28
40
|
} = renderHook(() => useCacheableSection('one'), {
|
|
29
|
-
wrapper
|
|
30
|
-
children
|
|
31
|
-
}) => /*#__PURE__*/React.createElement(AlertsProvider, null, /*#__PURE__*/React.createElement(OfflineProvider, {
|
|
32
|
-
offlineInterface: mockOfflineInterface
|
|
33
|
-
}, children))
|
|
41
|
+
wrapper
|
|
34
42
|
});
|
|
35
43
|
expect(result.current.recordingState).toBe('default');
|
|
36
44
|
expect(result.current.isCached).toBe(false);
|
|
@@ -44,15 +52,21 @@ it('handles a successful recording', async done => {
|
|
|
44
52
|
lastUpdated: new Date()
|
|
45
53
|
}])
|
|
46
54
|
};
|
|
55
|
+
|
|
56
|
+
const wrapper = (_ref2) => {
|
|
57
|
+
let {
|
|
58
|
+
children
|
|
59
|
+
} = _ref2;
|
|
60
|
+
return /*#__PURE__*/React.createElement(OfflineProvider, {
|
|
61
|
+
offlineInterface: testOfflineInterface
|
|
62
|
+
}, children);
|
|
63
|
+
};
|
|
64
|
+
|
|
47
65
|
const {
|
|
48
66
|
result,
|
|
49
67
|
waitFor
|
|
50
68
|
} = renderHook(() => useCacheableSection(sectionId), {
|
|
51
|
-
wrapper
|
|
52
|
-
children
|
|
53
|
-
}) => /*#__PURE__*/React.createElement(AlertsProvider, null, /*#__PURE__*/React.createElement(OfflineProvider, {
|
|
54
|
-
offlineInterface: testOfflineInterface
|
|
55
|
-
}, children))
|
|
69
|
+
wrapper
|
|
56
70
|
});
|
|
57
71
|
|
|
58
72
|
const assertRecordingStarted = () => {
|
|
@@ -91,9 +105,14 @@ it('handles a successful recording', async done => {
|
|
|
91
105
|
});
|
|
92
106
|
it('handles a recording that encounters an error', async done => {
|
|
93
107
|
// Suppress the expected error from console (in addition to 'act' warning)
|
|
94
|
-
jest.spyOn(console, 'error').mockImplementation((
|
|
108
|
+
jest.spyOn(console, 'error').mockImplementation(function () {
|
|
95
109
|
const actPattern = /Warning: An update to .* inside a test was not wrapped in act/;
|
|
96
110
|
const errPattern = /Error during recording/;
|
|
111
|
+
|
|
112
|
+
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
113
|
+
args[_key2] = arguments[_key2];
|
|
114
|
+
}
|
|
115
|
+
|
|
97
116
|
const matchesPattern = actPattern.test(args[0]) || errPattern.test(args[0]);
|
|
98
117
|
|
|
99
118
|
if (typeof args[0] === 'string' && matchesPattern) {
|
|
@@ -105,14 +124,20 @@ it('handles a recording that encounters an error', async done => {
|
|
|
105
124
|
const testOfflineInterface = { ...mockOfflineInterface,
|
|
106
125
|
startRecording: errorRecordingMock
|
|
107
126
|
};
|
|
127
|
+
|
|
128
|
+
const wrapper = (_ref3) => {
|
|
129
|
+
let {
|
|
130
|
+
children
|
|
131
|
+
} = _ref3;
|
|
132
|
+
return /*#__PURE__*/React.createElement(OfflineProvider, {
|
|
133
|
+
offlineInterface: testOfflineInterface
|
|
134
|
+
}, children);
|
|
135
|
+
};
|
|
136
|
+
|
|
108
137
|
const {
|
|
109
138
|
result
|
|
110
139
|
} = renderHook(() => useCacheableSection('one'), {
|
|
111
|
-
wrapper
|
|
112
|
-
children
|
|
113
|
-
}) => /*#__PURE__*/React.createElement(AlertsProvider, null, /*#__PURE__*/React.createElement(OfflineProvider, {
|
|
114
|
-
offlineInterface: testOfflineInterface
|
|
115
|
-
}, children))
|
|
140
|
+
wrapper
|
|
116
141
|
});
|
|
117
142
|
|
|
118
143
|
const assertRecordingStarted = () => {
|
|
@@ -145,14 +170,20 @@ it('handles an error starting the recording', async () => {
|
|
|
145
170
|
const testOfflineInterface = { ...mockOfflineInterface,
|
|
146
171
|
startRecording: failedMessageRecordingMock
|
|
147
172
|
};
|
|
173
|
+
|
|
174
|
+
const wrapper = (_ref4) => {
|
|
175
|
+
let {
|
|
176
|
+
children
|
|
177
|
+
} = _ref4;
|
|
178
|
+
return /*#__PURE__*/React.createElement(OfflineProvider, {
|
|
179
|
+
offlineInterface: testOfflineInterface
|
|
180
|
+
}, children);
|
|
181
|
+
};
|
|
182
|
+
|
|
148
183
|
const {
|
|
149
184
|
result
|
|
150
185
|
} = renderHook(() => useCacheableSection('err'), {
|
|
151
|
-
wrapper
|
|
152
|
-
children
|
|
153
|
-
}) => /*#__PURE__*/React.createElement(AlertsProvider, null, /*#__PURE__*/React.createElement(OfflineProvider, {
|
|
154
|
-
offlineInterface: testOfflineInterface
|
|
155
|
-
}, children))
|
|
186
|
+
wrapper
|
|
156
187
|
});
|
|
157
188
|
await expect(result.current.startRecording()).rejects.toThrow('Failed message' // from failedMessageRecordingMock
|
|
158
189
|
);
|
|
@@ -165,15 +196,21 @@ it('handles remove and updates sections', async () => {
|
|
|
165
196
|
lastUpdated: new Date()
|
|
166
197
|
}]).mockResolvedValueOnce([])
|
|
167
198
|
};
|
|
199
|
+
|
|
200
|
+
const wrapper = (_ref5) => {
|
|
201
|
+
let {
|
|
202
|
+
children
|
|
203
|
+
} = _ref5;
|
|
204
|
+
return /*#__PURE__*/React.createElement(OfflineProvider, {
|
|
205
|
+
offlineInterface: testOfflineInterface
|
|
206
|
+
}, children);
|
|
207
|
+
};
|
|
208
|
+
|
|
168
209
|
const {
|
|
169
210
|
result,
|
|
170
211
|
waitFor
|
|
171
212
|
} = renderHook(() => useCacheableSection(sectionId), {
|
|
172
|
-
wrapper
|
|
173
|
-
children
|
|
174
|
-
}) => /*#__PURE__*/React.createElement(AlertsProvider, null, /*#__PURE__*/React.createElement(OfflineProvider, {
|
|
175
|
-
offlineInterface: testOfflineInterface
|
|
176
|
-
}, children))
|
|
213
|
+
wrapper
|
|
177
214
|
}); // Wait for state to sync with indexedDB
|
|
178
215
|
|
|
179
216
|
await waitFor(() => result.current.isCached === true);
|
|
@@ -195,16 +232,22 @@ it('handles a change in ID', async () => {
|
|
|
195
232
|
lastUpdated: new Date()
|
|
196
233
|
}])
|
|
197
234
|
};
|
|
235
|
+
|
|
236
|
+
const wrapper = (_ref6) => {
|
|
237
|
+
let {
|
|
238
|
+
children
|
|
239
|
+
} = _ref6;
|
|
240
|
+
return /*#__PURE__*/React.createElement(OfflineProvider, {
|
|
241
|
+
offlineInterface: testOfflineInterface
|
|
242
|
+
}, children);
|
|
243
|
+
};
|
|
244
|
+
|
|
198
245
|
const {
|
|
199
246
|
result,
|
|
200
247
|
waitFor,
|
|
201
248
|
rerender
|
|
202
|
-
} = renderHook(
|
|
203
|
-
wrapper
|
|
204
|
-
children
|
|
205
|
-
}) => /*#__PURE__*/React.createElement(AlertsProvider, null, /*#__PURE__*/React.createElement(OfflineProvider, {
|
|
206
|
-
offlineInterface: testOfflineInterface
|
|
207
|
-
}, children)),
|
|
249
|
+
} = renderHook(id => useCacheableSection(id), {
|
|
250
|
+
wrapper,
|
|
208
251
|
initialProps: 'id-one'
|
|
209
252
|
}); // Wait for state to sync with indexedDB
|
|
210
253
|
|
|
@@ -5,11 +5,14 @@ import { OfflineProvider } from '../offline-provider';
|
|
|
5
5
|
import { useOnlineStatusMessage } from '../online-status-message';
|
|
6
6
|
describe('useOnlineStatusMessage', () => {
|
|
7
7
|
it('should allow the online status to be updated ', () => {
|
|
8
|
-
const wrapper = ({
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
const wrapper = (_ref) => {
|
|
9
|
+
let {
|
|
10
|
+
children
|
|
11
|
+
} = _ref;
|
|
12
|
+
return /*#__PURE__*/React.createElement(OfflineProvider, {
|
|
13
|
+
offlineInterface: mockOfflineInterface
|
|
14
|
+
}, children);
|
|
15
|
+
};
|
|
13
16
|
|
|
14
17
|
const {
|
|
15
18
|
result
|
|
@@ -12,14 +12,17 @@ import { useOfflineInterface } from './offline-interface'; // Functions in here
|
|
|
12
12
|
* @returns {Object} An object of sections, keyed by ID
|
|
13
13
|
*/
|
|
14
14
|
function getSectionsById(sectionsArray) {
|
|
15
|
-
return sectionsArray.reduce((result, {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}) => ({ ...result,
|
|
19
|
-
[sectionId]: {
|
|
15
|
+
return sectionsArray.reduce((result, _ref) => {
|
|
16
|
+
let {
|
|
17
|
+
sectionId,
|
|
20
18
|
lastUpdated
|
|
21
|
-
}
|
|
22
|
-
|
|
19
|
+
} = _ref;
|
|
20
|
+
return { ...result,
|
|
21
|
+
[sectionId]: {
|
|
22
|
+
lastUpdated
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}, {});
|
|
23
26
|
}
|
|
24
27
|
/**
|
|
25
28
|
* Create a store for Cacheable Section state.
|
|
@@ -57,9 +60,10 @@ function useConst(factory) {
|
|
|
57
60
|
*/
|
|
58
61
|
|
|
59
62
|
|
|
60
|
-
export function CacheableSectionProvider({
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
export function CacheableSectionProvider(_ref2) {
|
|
64
|
+
let {
|
|
65
|
+
children
|
|
66
|
+
} = _ref2;
|
|
63
67
|
const offlineInterface = useOfflineInterface();
|
|
64
68
|
const store = useConst(createCacheableSectionStore); // On load, get sections and add to store
|
|
65
69
|
|
|
@@ -45,12 +45,13 @@ export function useCacheableSection(id) {
|
|
|
45
45
|
};
|
|
46
46
|
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
47
47
|
|
|
48
|
-
function startRecording({
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
48
|
+
function startRecording() {
|
|
49
|
+
let {
|
|
50
|
+
recordingTimeoutDelay = 1000,
|
|
51
|
+
onStarted,
|
|
52
|
+
onCompleted,
|
|
53
|
+
onError
|
|
54
|
+
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
54
55
|
// This promise resolving means that the message to the service worker
|
|
55
56
|
// to start recording was successful. Waiting for resolution prevents
|
|
56
57
|
// unnecessarily rerendering the whole component in case of an error
|
|
@@ -108,11 +109,12 @@ export function useCacheableSection(id) {
|
|
|
108
109
|
* intended to prevent other interaction with the app that might interfere
|
|
109
110
|
* with the recording process.
|
|
110
111
|
*/
|
|
111
|
-
export function CacheableSection({
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
112
|
+
export function CacheableSection(_ref) {
|
|
113
|
+
let {
|
|
114
|
+
id,
|
|
115
|
+
loadingMask,
|
|
116
|
+
children
|
|
117
|
+
} = _ref;
|
|
116
118
|
// Accesses recording state that useCacheableSection controls
|
|
117
119
|
const {
|
|
118
120
|
recordingState
|
|
@@ -22,9 +22,12 @@ const clearDB = async dbName => {
|
|
|
22
22
|
|
|
23
23
|
const dbs = await window.indexedDB.databases();
|
|
24
24
|
|
|
25
|
-
if (!dbs.some(({
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
if (!dbs.some((_ref) => {
|
|
26
|
+
let {
|
|
27
|
+
name
|
|
28
|
+
} = _ref;
|
|
29
|
+
return name === dbName;
|
|
30
|
+
})) {
|
|
28
31
|
// Sections-db is not created; nothing to do here
|
|
29
32
|
return;
|
|
30
33
|
}
|
|
@@ -59,7 +62,8 @@ const clearDB = async dbName => {
|
|
|
59
62
|
*/
|
|
60
63
|
|
|
61
64
|
|
|
62
|
-
export async function clearSensitiveCaches(
|
|
65
|
+
export async function clearSensitiveCaches() {
|
|
66
|
+
let dbName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : SECTIONS_DB;
|
|
63
67
|
console.debug('Clearing sensitive caches');
|
|
64
68
|
let cacheKeys; // caches.keys can fail in insecure contexts, see:
|
|
65
69
|
// https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const shouldLog = localStorage.getItem('dhis2.debugConnectionStatus');
|
|
2
|
+
|
|
3
|
+
if (shouldLog) {
|
|
4
|
+
console.log('Logging for dhis2ConnectionStatus is enabled. Remove the `dhis2.debugConnectionStatus` item in localStorage to disable logging.');
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* This can be used to log info if the `dhis2.debugConnectionStatus` value
|
|
8
|
+
* in localStorage is set to a truthy value during development.
|
|
9
|
+
* Set the value manually and refresh the page to see the logs.
|
|
10
|
+
*
|
|
11
|
+
* The behavior of the connection status can be quite hard to inspect without
|
|
12
|
+
* logs, but the logs are quite chatty and should be omitted normally.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
export function devDebugLog() {
|
|
17
|
+
if (shouldLog) {
|
|
18
|
+
console.log(...arguments);
|
|
19
|
+
}
|
|
20
|
+
}
|