@applicaster/zapp-react-native-utils 16.0.0-alpha.4380012274 → 16.0.0-alpha.4548770949
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/actionsExecutor/__tests__/StorageActions.test.ts +98 -0
- package/actionsExecutor/__tests__/feedDecorator.test.ts +30 -0
- package/actionsExecutor/__tests__/screenToggleFlag.test.ts +90 -0
- package/actionsExecutor/actions/__tests__/openBottomSheet.inlineItems.test.ts +72 -0
- package/actionsExecutor/actions/openBottomSheet.ts +1 -0
- package/actionsExecutor/actions/screenToggleFlag.ts +1 -3
- package/actionsExecutor/feedDecorator.ts +6 -0
- package/appUtils/contextKeysManager/__tests__/getKey/failure.test.ts +1 -22
- package/appUtils/contextKeysManager/__tests__/getKey/success/fullSearch.test.ts +1 -25
- package/appUtils/contextKeysManager/__tests__/getKey/success/searchInSecure.test.ts +1 -7
- package/appUtils/contextKeysManager/__tests__/removeKey/failure.test.ts +0 -25
- package/appUtils/contextKeysManager/__tests__/removeKey/success.test.ts +0 -6
- package/appUtils/contextKeysManager/__tests__/setKey/failure/failedToSaveInStorage.test.ts +0 -40
- package/appUtils/contextKeysManager/__tests__/setKey/{success/saveItemAndReference.test.ts → success.test.ts} +2 -42
- package/appUtils/contextKeysManager/index.ts +28 -129
- package/configurationUtils/__tests__/modalBlocksParser.test.ts +11 -0
- package/modalState/ModalOrchestrator.ts +1 -0
- package/modalState/__tests__/ModalOrchestrator.phase3.test.ts +23 -0
- package/modalState/index.ts +2 -0
- package/modalState/types.ts +11 -0
- package/package.json +2 -2
- package/reactHooks/feed/__tests__/feedInvalidation.test.tsx +338 -0
- package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +8 -2
- package/reactHooks/feed/useFeedLoader.tsx +28 -1
- package/reactHooks/feed/useLoadPipesDataDispatch.ts +12 -11
- package/appUtils/contextKeysManager/__tests__/getKey/success/byReference.test.ts +0 -56
- package/appUtils/contextKeysManager/__tests__/getKeyByReference/failure.test.ts +0 -265
- package/appUtils/contextKeysManager/__tests__/getKeyByReference/success.test.ts +0 -303
- package/appUtils/contextKeysManager/__tests__/removeReferenceForKey/failure.test.ts +0 -82
- package/appUtils/contextKeysManager/__tests__/removeReferenceForKey/success.test.ts +0 -41
- package/appUtils/contextKeysManager/__tests__/setKey/success/saveItemButNotReference.test.ts +0 -208
- package/appUtils/contextKeysManager/__tests__/setReferenceForKey/failure.test.ts +0 -93
- package/appUtils/contextKeysManager/__tests__/setReferenceForKey/success.test.ts +0 -45
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Provider } from "react-redux";
|
|
3
|
+
import { configureStore } from "@reduxjs/toolkit";
|
|
4
|
+
import { act, renderHook } from "@testing-library/react-native";
|
|
5
|
+
import reducer, {
|
|
6
|
+
loadPipesData,
|
|
7
|
+
unsubscribeFromDataSource,
|
|
8
|
+
zappPipesClear,
|
|
9
|
+
} from "@applicaster/zapp-react-native-redux/ZappPipes";
|
|
10
|
+
import { zappPipesMiddleware } from "../../../../zapp-react-native-redux/ZappPipes/middleware";
|
|
11
|
+
import { useFeedLoader } from "../useFeedLoader";
|
|
12
|
+
|
|
13
|
+
const mockGet = jest.fn();
|
|
14
|
+
const mockPost = jest.fn();
|
|
15
|
+
const mockSubscribe = jest.fn();
|
|
16
|
+
const mockRelease = jest.fn();
|
|
17
|
+
let mockChange: () => void;
|
|
18
|
+
let mockLoad: ReturnType<typeof jest.fn>;
|
|
19
|
+
|
|
20
|
+
jest.mock("@applicaster/zapp-pipes-v2-client", () => ({
|
|
21
|
+
__esModule: true,
|
|
22
|
+
default: jest.fn(() => ({
|
|
23
|
+
get: (...args) => mockGet(...args),
|
|
24
|
+
post: (...args) => mockPost(...args),
|
|
25
|
+
})),
|
|
26
|
+
RequestBuilder: jest.fn(() => ({
|
|
27
|
+
setResolvers() {
|
|
28
|
+
return this;
|
|
29
|
+
},
|
|
30
|
+
build: async () => ({}),
|
|
31
|
+
})),
|
|
32
|
+
subscribeForUrlContextKeyChanges: (...args) => mockSubscribe(...args),
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
jest.mock("../useInflatedUrl", () => ({
|
|
36
|
+
useInflatedUrl: ({ feedUrl }) => feedUrl,
|
|
37
|
+
}));
|
|
38
|
+
|
|
39
|
+
jest.mock("../useLoadPipesDataDispatch", () => ({
|
|
40
|
+
useLoadPipesDataDispatch: () => mockLoad,
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
const url = "https://example.test/feed";
|
|
44
|
+
const data = { id: "feed", type: { value: "feed" }, entry: [] };
|
|
45
|
+
|
|
46
|
+
const settle = async () => {
|
|
47
|
+
for (let index = 0; index < 30; index++) await Promise.resolve();
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const createHarness = (plugins: QuickBrickPlugin[] = []) => {
|
|
51
|
+
const store = configureStore({
|
|
52
|
+
reducer: {
|
|
53
|
+
zappPipes: reducer,
|
|
54
|
+
appData: () => ({ layoutVersion: "v2" }),
|
|
55
|
+
plugins: () => plugins,
|
|
56
|
+
},
|
|
57
|
+
middleware: (defaults) =>
|
|
58
|
+
defaults({ serializableCheck: false }).concat(zappPipesMiddleware),
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
mockLoad = jest.fn((feedUrl, options) =>
|
|
62
|
+
store.dispatch(loadPipesData(feedUrl, options))
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const wrapper = ({ children }) => (
|
|
66
|
+
<Provider store={store}>{children}</Provider>
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
return { store, wrapper };
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
describe("dependency-driven feed invalidation", () => {
|
|
73
|
+
beforeEach(() => {
|
|
74
|
+
jest.clearAllMocks();
|
|
75
|
+
mockGet.mockResolvedValue({ response: data, code: 200 });
|
|
76
|
+
mockPost.mockResolvedValue({ response: data, code: 200 });
|
|
77
|
+
|
|
78
|
+
mockSubscribe.mockImplementation((_url, _options, onChange) => {
|
|
79
|
+
mockChange = onChange;
|
|
80
|
+
|
|
81
|
+
return mockRelease;
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
afterEach(() => unsubscribeFromDataSource());
|
|
86
|
+
|
|
87
|
+
it("silently revalidates a shared mounted feed once and keeps its content", async () => {
|
|
88
|
+
const { store, wrapper } = createHarness();
|
|
89
|
+
|
|
90
|
+
const first = renderHook(() => useFeedLoader({ feedUrl: url }), {
|
|
91
|
+
wrapper,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const second = renderHook(() => useFeedLoader({ feedUrl: url }), {
|
|
95
|
+
wrapper,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
await act(settle);
|
|
99
|
+
|
|
100
|
+
expect(mockGet).toHaveBeenCalledTimes(1);
|
|
101
|
+
expect(mockSubscribe).toHaveBeenCalledTimes(1);
|
|
102
|
+
let finish;
|
|
103
|
+
|
|
104
|
+
mockGet.mockImplementationOnce(
|
|
105
|
+
() =>
|
|
106
|
+
new Promise((resolve) => {
|
|
107
|
+
finish = resolve;
|
|
108
|
+
})
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
await act(async () => {
|
|
112
|
+
mockChange();
|
|
113
|
+
await settle();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
expect(mockGet).toHaveBeenCalledTimes(2);
|
|
117
|
+
expect(first.result.current.data).toEqual(data);
|
|
118
|
+
expect(first.result.current.loading).toBe(false);
|
|
119
|
+
expect(store.getState().zappPipes[url].refreshing).toBe(true);
|
|
120
|
+
|
|
121
|
+
await act(async () => {
|
|
122
|
+
finish({ response: data, code: 200 });
|
|
123
|
+
await settle();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
expect(store.getState().zappPipes[url].stale).toBeUndefined();
|
|
127
|
+
first.unmount();
|
|
128
|
+
second.unmount();
|
|
129
|
+
expect(mockRelease).not.toHaveBeenCalled();
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("invalidates an unmounted cache without fetching and revalidates on remount", async () => {
|
|
133
|
+
const { store, wrapper } = createHarness();
|
|
134
|
+
|
|
135
|
+
const first = renderHook(() => useFeedLoader({ feedUrl: url }), {
|
|
136
|
+
wrapper,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
await act(settle);
|
|
140
|
+
first.unmount();
|
|
141
|
+
|
|
142
|
+
mockChange();
|
|
143
|
+
mockChange();
|
|
144
|
+
await settle();
|
|
145
|
+
|
|
146
|
+
expect(mockGet).toHaveBeenCalledTimes(1);
|
|
147
|
+
|
|
148
|
+
expect(store.getState().zappPipes[url]).toMatchObject({
|
|
149
|
+
stale: true,
|
|
150
|
+
invalidationVersion: 2,
|
|
151
|
+
data,
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const second = renderHook(() => useFeedLoader({ feedUrl: url }), {
|
|
155
|
+
wrapper,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
await act(settle);
|
|
159
|
+
|
|
160
|
+
expect(mockGet).toHaveBeenCalledTimes(2);
|
|
161
|
+
expect(store.getState().zappPipes[url].stale).toBeUndefined();
|
|
162
|
+
second.unmount();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it("runs one follow-up when invalidated repeatedly during a request", async () => {
|
|
166
|
+
const { store, wrapper } = createHarness();
|
|
167
|
+
let finish;
|
|
168
|
+
|
|
169
|
+
mockGet.mockImplementationOnce(
|
|
170
|
+
() =>
|
|
171
|
+
new Promise((resolve) => {
|
|
172
|
+
finish = resolve;
|
|
173
|
+
})
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
const hook = renderHook(() => useFeedLoader({ feedUrl: url }), { wrapper });
|
|
177
|
+
await act(settle);
|
|
178
|
+
|
|
179
|
+
await act(async () => {
|
|
180
|
+
mockChange();
|
|
181
|
+
mockChange();
|
|
182
|
+
await settle();
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
expect(mockGet).toHaveBeenCalledTimes(1);
|
|
186
|
+
|
|
187
|
+
await act(async () => {
|
|
188
|
+
finish({ response: data, code: 200 });
|
|
189
|
+
await settle();
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
expect(mockGet).toHaveBeenCalledTimes(2);
|
|
193
|
+
expect(store.getState().zappPipes[url].stale).toBeUndefined();
|
|
194
|
+
hook.unmount();
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it("stops a failed revalidation until another dependency change", async () => {
|
|
198
|
+
const { wrapper } = createHarness();
|
|
199
|
+
const hook = renderHook(() => useFeedLoader({ feedUrl: url }), { wrapper });
|
|
200
|
+
await act(settle);
|
|
201
|
+
mockGet.mockRejectedValueOnce(new Error("network unavailable"));
|
|
202
|
+
|
|
203
|
+
await act(async () => {
|
|
204
|
+
mockChange();
|
|
205
|
+
await settle();
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
expect(mockGet).toHaveBeenCalledTimes(2);
|
|
209
|
+
expect(hook.result.current.error).toBeDefined();
|
|
210
|
+
|
|
211
|
+
await act(async () => {
|
|
212
|
+
mockChange();
|
|
213
|
+
await settle();
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
expect(mockGet).toHaveBeenCalledTimes(3);
|
|
217
|
+
expect(hook.result.current.error).toBeUndefined();
|
|
218
|
+
hook.unmount();
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it("releases cache subscriptions for direct clear actions", async () => {
|
|
222
|
+
const { store } = createHarness();
|
|
223
|
+
await store.dispatch(loadPipesData(url));
|
|
224
|
+
await store.dispatch(loadPipesData(`${url}/two`));
|
|
225
|
+
store.dispatch(zappPipesClear(url));
|
|
226
|
+
expect(mockRelease).toHaveBeenCalledTimes(1);
|
|
227
|
+
store.dispatch(zappPipesClear());
|
|
228
|
+
expect(mockRelease).toHaveBeenCalledTimes(2);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it("preserves POST method and body when revalidating", async () => {
|
|
232
|
+
const { wrapper } = createHarness();
|
|
233
|
+
const bodyParams = { filter: "recent" };
|
|
234
|
+
|
|
235
|
+
const hook = renderHook(
|
|
236
|
+
() =>
|
|
237
|
+
useFeedLoader({
|
|
238
|
+
feedUrl: url,
|
|
239
|
+
pipesOptions: { method: "post", bodyParams },
|
|
240
|
+
}),
|
|
241
|
+
{ wrapper }
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
await act(settle);
|
|
245
|
+
|
|
246
|
+
await act(async () => {
|
|
247
|
+
mockChange();
|
|
248
|
+
await settle();
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
expect(mockSubscribe).toHaveBeenCalledWith(
|
|
252
|
+
url,
|
|
253
|
+
{ method: "post" },
|
|
254
|
+
expect.any(Function)
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
expect(mockPost).toHaveBeenCalledTimes(2);
|
|
258
|
+
expect(mockPost).toHaveBeenLastCalledWith(url, bodyParams);
|
|
259
|
+
expect(mockGet).not.toHaveBeenCalled();
|
|
260
|
+
hook.unmount();
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it("does not revalidate a skipped mounted feed until loading is enabled", async () => {
|
|
264
|
+
const { store, wrapper } = createHarness();
|
|
265
|
+
await store.dispatch(loadPipesData(url));
|
|
266
|
+
|
|
267
|
+
const hook = renderHook(
|
|
268
|
+
({ skipLoading }) =>
|
|
269
|
+
useFeedLoader({
|
|
270
|
+
feedUrl: url,
|
|
271
|
+
pipesOptions: { skipLoading },
|
|
272
|
+
}),
|
|
273
|
+
{ wrapper, initialProps: { skipLoading: true } }
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
await act(async () => {
|
|
277
|
+
mockChange();
|
|
278
|
+
await settle();
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
expect(mockGet).toHaveBeenCalledTimes(1);
|
|
282
|
+
expect(store.getState().zappPipes[url].stale).toBe(true);
|
|
283
|
+
|
|
284
|
+
hook.rerender({ skipLoading: false });
|
|
285
|
+
await act(settle);
|
|
286
|
+
expect(mockGet).toHaveBeenCalledTimes(2);
|
|
287
|
+
expect(store.getState().zappPipes[url].stale).toBeUndefined();
|
|
288
|
+
hook.unmount();
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it("shares GET revalidation with an omitted or empty unused request body", async () => {
|
|
292
|
+
const { store } = createHarness();
|
|
293
|
+
await store.dispatch(loadPipesData(url));
|
|
294
|
+
mockChange();
|
|
295
|
+
mockGet.mockClear();
|
|
296
|
+
|
|
297
|
+
await Promise.all([
|
|
298
|
+
store.dispatch(loadPipesData(url)),
|
|
299
|
+
store.dispatch(loadPipesData(url, { method: "get", bodyParams: {} })),
|
|
300
|
+
]);
|
|
301
|
+
|
|
302
|
+
expect(mockGet).toHaveBeenCalledTimes(1);
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it("keeps plugin observation until its cache is cleared", async () => {
|
|
306
|
+
const release = jest.fn();
|
|
307
|
+
let changed;
|
|
308
|
+
|
|
309
|
+
const addDataSourceListener = jest.fn((callback) => {
|
|
310
|
+
changed = callback;
|
|
311
|
+
|
|
312
|
+
return release;
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
const { store, wrapper } = createHarness([
|
|
316
|
+
{
|
|
317
|
+
identifier: "generic-provider",
|
|
318
|
+
module: { addDataSourceListener },
|
|
319
|
+
} as QuickBrickPlugin,
|
|
320
|
+
]);
|
|
321
|
+
|
|
322
|
+
const pluginUrl = "pipesv2://generic-provider/feed";
|
|
323
|
+
|
|
324
|
+
const hook = renderHook(() => useFeedLoader({ feedUrl: pluginUrl }), {
|
|
325
|
+
wrapper,
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
await act(settle);
|
|
329
|
+
hook.unmount();
|
|
330
|
+
changed();
|
|
331
|
+
await settle();
|
|
332
|
+
expect(mockGet).toHaveBeenCalledTimes(1);
|
|
333
|
+
expect(store.getState().zappPipes[pluginUrl].stale).toBe(true);
|
|
334
|
+
expect(release).not.toHaveBeenCalled();
|
|
335
|
+
store.dispatch(zappPipesClear(pluginUrl));
|
|
336
|
+
expect(release).toHaveBeenCalledTimes(1);
|
|
337
|
+
});
|
|
338
|
+
});
|
|
@@ -2,6 +2,7 @@ import { renderHook, waitFor } from "@testing-library/react-native";
|
|
|
2
2
|
import { allFeedsIsReady, useBatchLoading } from "../useBatchLoading";
|
|
3
3
|
import { WrappedWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
|
|
4
4
|
import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
|
|
5
|
+
import * as ZappPipes from "@applicaster/zapp-react-native-redux/ZappPipes";
|
|
5
6
|
|
|
6
7
|
jest.mock("../../navigation");
|
|
7
8
|
|
|
@@ -32,11 +33,16 @@ describe("useBatchLoading", () => {
|
|
|
32
33
|
// ... more items
|
|
33
34
|
];
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
jest
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
jest
|
|
38
|
+
.spyOn(ZappPipes, "loadPipesData")
|
|
39
|
+
.mockImplementation((url, options) => async (dispatch) => {
|
|
40
|
+
dispatch(ZappPipes.zappPipesRequestStart(url, options));
|
|
41
|
+
});
|
|
37
42
|
});
|
|
38
43
|
|
|
39
44
|
afterEach(() => {
|
|
45
|
+
jest.restoreAllMocks();
|
|
40
46
|
jest.clearAllMocks();
|
|
41
47
|
});
|
|
42
48
|
|
|
@@ -15,6 +15,7 @@ type Props = {
|
|
|
15
15
|
pipesOptions?: {
|
|
16
16
|
clearCache?: boolean;
|
|
17
17
|
loadLocalFavourites?: boolean;
|
|
18
|
+
loadLocalFavorites?: boolean;
|
|
18
19
|
silentRefresh?: boolean;
|
|
19
20
|
method?: "get" | "post";
|
|
20
21
|
bodyParams?: Record<string, unknown>;
|
|
@@ -45,11 +46,36 @@ export const useFeedLoader = ({
|
|
|
45
46
|
|
|
46
47
|
const loadPipesDataDispatcher = useLoadPipesDataDispatch();
|
|
47
48
|
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (
|
|
51
|
+
currentFeed?.stale &&
|
|
52
|
+
!currentFeed.refreshing &&
|
|
53
|
+
(!currentFeed.error || isInitialRender) &&
|
|
54
|
+
!pipesOptions.skipLoading
|
|
55
|
+
) {
|
|
56
|
+
loadPipesDataDispatcher(
|
|
57
|
+
callableFeedUrl,
|
|
58
|
+
{ ...pipesOptions, clearCache: false, silentRefresh: true },
|
|
59
|
+
{ withResolvers: true }
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
}, [
|
|
63
|
+
callableFeedUrl,
|
|
64
|
+
currentFeed?.stale,
|
|
65
|
+
currentFeed?.invalidationVersion,
|
|
66
|
+
currentFeed?.refreshing,
|
|
67
|
+
currentFeed?.error,
|
|
68
|
+
pipesOptions,
|
|
69
|
+
loadPipesDataDispatcher,
|
|
70
|
+
isInitialRender,
|
|
71
|
+
]);
|
|
72
|
+
|
|
48
73
|
const reloadData = React.useCallback<ReloadDataFunction>(
|
|
49
74
|
(silentRefresh = true, callback) => {
|
|
50
75
|
loadPipesDataDispatcher(
|
|
51
76
|
callableFeedUrl,
|
|
52
77
|
{
|
|
78
|
+
...pipesOptions,
|
|
53
79
|
clearCache: true,
|
|
54
80
|
silentRefresh,
|
|
55
81
|
callback,
|
|
@@ -59,7 +85,7 @@ export const useFeedLoader = ({
|
|
|
59
85
|
}
|
|
60
86
|
);
|
|
61
87
|
},
|
|
62
|
-
[callableFeedUrl]
|
|
88
|
+
[callableFeedUrl, pipesOptions, loadPipesDataDispatcher]
|
|
63
89
|
);
|
|
64
90
|
|
|
65
91
|
const loadNext: FeedLoaderResponse["loadNext"] = React.useCallback(() => {
|
|
@@ -81,6 +107,7 @@ export const useFeedLoader = ({
|
|
|
81
107
|
|
|
82
108
|
useEffect(() => {
|
|
83
109
|
if (
|
|
110
|
+
!currentFeed?.stale &&
|
|
84
111
|
shouldDispatchData(callableFeedUrl, currentFeed, pipesOptions.clearCache)
|
|
85
112
|
) {
|
|
86
113
|
if (callableFeedUrl && !pipesOptions.skipLoading) {
|
|
@@ -19,14 +19,6 @@ export const useLoadPipesDataDispatch = () => {
|
|
|
19
19
|
(screenData as LegacyNavigationScreenData)?.targetScreen?.id ??
|
|
20
20
|
screenData?.id;
|
|
21
21
|
|
|
22
|
-
const onLoadCB = (options) => (data, _err) => {
|
|
23
|
-
options?.callback?.();
|
|
24
|
-
|
|
25
|
-
if (data) {
|
|
26
|
-
applyScreenRouteDefaults(data, screenStateStore, pathname);
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
|
|
30
22
|
return React.useCallback(
|
|
31
23
|
(
|
|
32
24
|
url: string,
|
|
@@ -36,6 +28,9 @@ export const useLoadPipesDataDispatch = () => {
|
|
|
36
28
|
clearCache?: boolean;
|
|
37
29
|
silentRefresh?: boolean;
|
|
38
30
|
parentFeed?: string;
|
|
31
|
+
method?: "get" | "post";
|
|
32
|
+
bodyParams?: Record<string, unknown>;
|
|
33
|
+
loadLocalFavorites?: boolean;
|
|
39
34
|
} = {},
|
|
40
35
|
{
|
|
41
36
|
withResolvers = false,
|
|
@@ -46,18 +41,24 @@ export const useLoadPipesDataDispatch = () => {
|
|
|
46
41
|
} = {}
|
|
47
42
|
) => {
|
|
48
43
|
if (url) {
|
|
49
|
-
dispatch(
|
|
44
|
+
return dispatch(
|
|
50
45
|
ZappPipes.loadPipesData(url, {
|
|
51
46
|
riverId,
|
|
52
47
|
resolvers: withResolvers ? resolvers : undefined,
|
|
53
48
|
...options,
|
|
54
49
|
callback: withScreenRouteMapping
|
|
55
|
-
?
|
|
50
|
+
? (data, error) => {
|
|
51
|
+
options.callback?.(data, error);
|
|
52
|
+
|
|
53
|
+
if (data) {
|
|
54
|
+
applyScreenRouteDefaults(data, screenStateStore, pathname);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
56
57
|
: options?.callback,
|
|
57
58
|
})
|
|
58
59
|
);
|
|
59
60
|
}
|
|
60
61
|
},
|
|
61
|
-
[]
|
|
62
|
+
[dispatch, riverId, resolvers, screenStateStore, pathname]
|
|
62
63
|
);
|
|
63
64
|
};
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { ContextKeysManager } from "../../..";
|
|
2
|
-
|
|
3
|
-
describe("Context Keys Manager - getKey", () => {
|
|
4
|
-
it("returns value if found by reference", async () => {
|
|
5
|
-
// setup
|
|
6
|
-
const key = "namespace.key";
|
|
7
|
-
const value = "value";
|
|
8
|
-
|
|
9
|
-
const mockedLogger = {
|
|
10
|
-
warn: jest.fn(),
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
const mockedSessionStorage = {
|
|
14
|
-
getItem: jest.fn(),
|
|
15
|
-
setItem: jest.fn(),
|
|
16
|
-
removeItem: jest.fn(),
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const mockedLocalStorage = {
|
|
20
|
-
getItem: jest.fn(),
|
|
21
|
-
setItem: jest.fn(),
|
|
22
|
-
removeItem: jest.fn(),
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const mockedSecureStorage = {
|
|
26
|
-
getItem: jest.fn(),
|
|
27
|
-
setItem: jest.fn(),
|
|
28
|
-
removeItem: jest.fn(),
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const contextManager = new ContextKeysManager({
|
|
32
|
-
logger: mockedLogger,
|
|
33
|
-
sessionStorage: mockedSessionStorage,
|
|
34
|
-
localStorage: mockedLocalStorage,
|
|
35
|
-
secureStorage: mockedSecureStorage,
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
const getKeyByReference = jest
|
|
39
|
-
.spyOn(contextManager, "getKeyByReference")
|
|
40
|
-
.mockResolvedValueOnce(value);
|
|
41
|
-
|
|
42
|
-
// run
|
|
43
|
-
const result = await contextManager.getKey(key);
|
|
44
|
-
|
|
45
|
-
// verify
|
|
46
|
-
expect(result).toEqual(value);
|
|
47
|
-
|
|
48
|
-
expect(mockedLogger.warn).not.toHaveBeenCalled();
|
|
49
|
-
|
|
50
|
-
expect(getKeyByReference).toHaveBeenCalledWith("key", "namespace");
|
|
51
|
-
|
|
52
|
-
expect(mockedSessionStorage.getItem).not.toHaveBeenCalled();
|
|
53
|
-
expect(mockedLocalStorage.getItem).not.toHaveBeenCalled();
|
|
54
|
-
expect(mockedSecureStorage.getItem).not.toHaveBeenCalled();
|
|
55
|
-
});
|
|
56
|
-
});
|