@applicaster/zapp-react-native-utils 15.0.0-alpha.4429053208 → 15.0.0-alpha.4920595583

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 (36) hide show
  1. package/analyticsUtils/analyticsMapper.ts +10 -2
  2. package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +1 -1
  3. package/appUtils/focusManager/index.ios.ts +7 -8
  4. package/appUtils/focusManagerAux/utils/index.ios.ts +5 -5
  5. package/appUtils/focusManagerAux/utils/utils.ios.ts +10 -21
  6. package/navigationUtils/index.ts +15 -5
  7. package/package.json +4 -4
  8. package/reactHooks/app/__tests__/useAppState.test.ts +1 -1
  9. package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
  10. package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +1 -2
  11. package/reactHooks/cell-click/__tests__/index.test.js +1 -3
  12. package/reactHooks/configuration/__tests__/index.test.tsx +1 -1
  13. package/reactHooks/connection/__tests__/index.test.js +1 -1
  14. package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +32 -23
  15. package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +19 -19
  16. package/reactHooks/feed/__tests__/useEntryScreenId.test.tsx +1 -1
  17. package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +42 -30
  18. package/reactHooks/feed/__tests__/useFeedRefresh.test.tsx +1 -1
  19. package/reactHooks/feed/__tests__/useInflatedUrl.test.tsx +1 -1
  20. package/reactHooks/hookModal/hooks/useHookModalScreenData.ts +12 -8
  21. package/reactHooks/layout/__tests__/index.test.tsx +1 -1
  22. package/reactHooks/layout/__tests__/useLayoutVersion.test.tsx +1 -1
  23. package/reactHooks/navigation/__tests__/index.test.tsx +40 -9
  24. package/reactHooks/navigation/index.ts +15 -4
  25. package/reactHooks/navigation/useRoute.ts +3 -1
  26. package/reactHooks/player/__tests__/useAutoSeek._test.tsx +1 -1
  27. package/reactHooks/player/__tests__/useTapSeek._test.ts +1 -1
  28. package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +1 -1
  29. package/reactHooks/resolvers/__tests__/useComponentResolver.test.tsx +1 -1
  30. package/reactHooks/screen/__tests__/useCurrentScreenData.test.tsx +1 -1
  31. package/reactHooks/screen/__tests__/useScreenBackgroundColor.test.tsx +1 -1
  32. package/reactHooks/screen/__tests__/useScreenData.test.tsx +1 -1
  33. package/reactHooks/screen/__tests__/useTargetScreenData.test.tsx +1 -1
  34. package/reactHooks/utils/__tests__/index.test.js +1 -1
  35. package/screenState/__tests__/index.test.ts +1 -1
  36. package/stringUtils/index.ts +1 -1
@@ -63,10 +63,14 @@ class StateHolder {
63
63
  return value as string;
64
64
  }
65
65
 
66
+ public get analyticsCustomPropertiesConsumed(): boolean {
67
+ return this._cap !== undefined;
68
+ }
69
+
66
70
  private acp(prefix: string, suffix: string): string | null {
67
71
  if (this._cap === undefined) {
68
- this._cap = this.pluckedParams[prefix]
69
- ? JSON.parse(this.pluckedParams[prefix])
72
+ this._cap = this.event.params[prefix]
73
+ ? JSON.parse(this.event.params[prefix])
70
74
  : null;
71
75
 
72
76
  delete this.pluckedParams[prefix];
@@ -254,6 +258,10 @@ export class Mapper {
254
258
 
255
259
  let params = resultParams.size ? Object.fromEntries(resultParams) : {};
256
260
 
261
+ if (state.analyticsCustomPropertiesConsumed) {
262
+ delete params[sourceType.analyticsCustomProperties];
263
+ }
264
+
257
265
  // deal with the remaining params
258
266
  if (!isEmptyOrNil(state.pluckedParams)) {
259
267
  if (rule.strategy) {
@@ -73,7 +73,7 @@ exports[`focusManagerIOS should be defined 1`] = `
73
73
  "isFocusOn": [Function],
74
74
  "isFocusOnContent": [Function],
75
75
  "isFocusOnMenu": [Function],
76
- "isFocusOnTabsScreen": [Function],
76
+ "isFocusOnTabsScreenContent": [Function],
77
77
  "isGroupItemFocused": [Function],
78
78
  "moveFocus": [Function],
79
79
  "on": [Function],
@@ -6,7 +6,7 @@ import {
6
6
  isChildOf as isChildOfUtils,
7
7
  isPartOfMenu,
8
8
  isPartOfContent,
9
- isPartOfTabsScreen,
9
+ isPartOfTabsScreenContent,
10
10
  } from "../focusManagerAux/utils/index.ios";
11
11
 
12
12
  import { Tree } from "./treeDataStructure/Tree";
@@ -17,7 +17,6 @@ import { findChild } from "./utils";
17
17
  import {
18
18
  emitRegistered,
19
19
  emitUnregistered,
20
- emitWillFocused,
21
20
  } from "../focusManagerAux/utils/utils.ios";
22
21
 
23
22
  const { FocusableManagerModule } = NativeModules;
@@ -292,8 +291,6 @@ export const focusManager = (function () {
292
291
  blur(direction);
293
292
  currentFocus = id;
294
293
 
295
- emitWillFocused(id);
296
-
297
294
  // Extract groupFocusedChanged with a default value of false
298
295
  let groupFocusedChanged = false;
299
296
 
@@ -439,12 +436,14 @@ export const focusManager = (function () {
439
436
  return isPartOfContent(focusableTree, currentFocusable?.props?.id);
440
437
  }
441
438
 
442
- function isFocusOnTabsScreen(tabsScreenContainerId: string): boolean {
439
+ function isFocusOnTabsScreenContent(
440
+ screenPickerContentContainerId: string
441
+ ): boolean {
443
442
  const currentFocusable = getCurrentFocus();
444
443
 
445
- return isPartOfTabsScreen(
444
+ return isPartOfTabsScreenContent(
446
445
  focusableTree,
447
- tabsScreenContainerId,
446
+ screenPickerContentContainerId,
448
447
  currentFocusable?.props?.id
449
448
  );
450
449
  }
@@ -477,7 +476,7 @@ export const focusManager = (function () {
477
476
  isFocusOn,
478
477
  isFocusOnMenu,
479
478
  isFocusOnContent,
480
- isFocusOnTabsScreen,
479
+ isFocusOnTabsScreenContent,
481
480
  isChildOf,
482
481
  };
483
482
  })();
@@ -9,9 +9,9 @@ const isNavBar = (node) => startsWith(QUICK_BRICK_NAVBAR, node?.id);
9
9
  const isContent = (node) => startsWith(QUICK_BRICK_CONTENT, node?.id);
10
10
  const isRoot = (node) => node?.id === "root";
11
11
 
12
- export const isPartOfTabsScreen = (
12
+ export const isPartOfTabsScreenContent = (
13
13
  focusableTree,
14
- tabsScreenContainerId,
14
+ screenPickerContentContainerId,
15
15
  id
16
16
  ) => {
17
17
  const node = focusableTree.findInTree(id);
@@ -32,13 +32,13 @@ export const isPartOfTabsScreen = (
32
32
  return false;
33
33
  }
34
34
 
35
- if (node?.id === tabsScreenContainerId) {
35
+ if (node?.id === screenPickerContentContainerId) {
36
36
  return true;
37
37
  }
38
38
 
39
- return isPartOfTabsScreen(
39
+ return isPartOfTabsScreenContent(
40
40
  focusableTree,
41
- tabsScreenContainerId,
41
+ screenPickerContentContainerId,
42
42
  node.parent?.id
43
43
  );
44
44
  };
@@ -178,34 +178,27 @@ export const emitNativeRegistered = ({
178
178
  }
179
179
  };
180
180
 
181
- // Focusable has been focused
182
- const willFocusedSubject$ = new Subject<FocusableID>();
183
- const didFocusedSubject$ = new Subject<FocusableID>();
181
+ // /////
184
182
 
185
- export const willFocused$ = willFocusedSubject$.asObservable();
183
+ const focusedSubject$ = new Subject<FocusableID>();
186
184
 
187
- export const didFocused$ = didFocusedSubject$.asObservable();
185
+ const focused$ = focusedSubject$.asObservable();
188
186
 
189
- export const emitWillFocused = (id: FocusableID): void => {
190
- willFocusedSubject$.next(id);
187
+ export const emitFocused = (id: FocusableID): void => {
188
+ focusedSubject$.next(id);
191
189
  };
192
190
 
193
- export const emitDidFocused = (id: FocusableID): void => {
194
- didFocusedSubject$.next(id);
195
- };
196
-
197
- export const topMenuItemDidFocused$ = didFocused$.pipe(
191
+ export const topMenuItemFocused$ = focused$.pipe(
198
192
  filter((id) => id && isPartOfMenu(focusManager.focusableTree, id))
199
193
  );
200
194
 
201
- export const contentDidFocused$ = didFocused$.pipe(
195
+ export const contentFocused$ = focused$.pipe(
202
196
  filter((id) => {
203
197
  const isContent = isPartOfContent(focusManager.focusableTree, id);
204
198
 
205
199
  return id && isContent;
206
200
  })
207
201
  );
208
- // Focusable has been focused
209
202
 
210
203
  const createFocusableRegistry = () => {
211
204
  const subject$ = new ReplaySubject<FocusableID | undefined>(1);
@@ -226,17 +219,13 @@ const createFocusableRegistry = () => {
226
219
  /// HOME_TOP_MENU_ITEM
227
220
  export const HomeTopMenuItemRegistry = createFocusableRegistry();
228
221
 
229
- export const homeTopMenuItemDidFocused$ = topMenuItemDidFocused$.pipe(
222
+ export const homeTopMenuItemFocused$ = topMenuItemFocused$.pipe(
230
223
  withLatestFrom(HomeTopMenuItemRegistry.observable$),
231
224
  filter(([id, homeId]) => id === homeId)
232
225
  );
233
226
 
234
- /// TABS SCREEN
235
- export const TabsScreenContentContainerRegistry = createFocusableRegistry();
236
-
237
- export const TabsScreenScreenSelectorContainerRegistry =
238
- createFocusableRegistry();
239
- /// TABS SCREEN
227
+ /// SCREEN_PICKER
228
+ export const ScreenPickerContentContainerRegistry = createFocusableRegistry();
240
229
 
241
230
  /// SEARCH_INPUT
242
231
  export const SearchInputRegistry = createFocusableRegistry();
@@ -5,7 +5,8 @@ import { layoutV2TypeMatcher } from "./layoutV2TypeMatcher";
5
5
  import { HOOKS_EVENTS } from "../appUtils/HooksManager/constants";
6
6
  import { HooksManager } from "../appUtils/HooksManager";
7
7
  import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
8
- import { HookModalContextT } from "@applicaster/zapp-react-native-ui-components/Contexts/ZappHookModalContext";
8
+
9
+ import { zappHookModalStore } from "@applicaster/zapp-react-native-ui-components/Contexts/ZappHookModalContext";
9
10
  import { logger } from "@applicaster/zapp-react-native-utils/logger";
10
11
  import {
11
12
  isGeneralPlugin,
@@ -15,6 +16,8 @@ import {
15
16
  } from "./itemTypeMatchers";
16
17
  import { RootState } from "@applicaster/zapp-react-native-redux/store";
17
18
 
19
+ import { pick } from "@applicaster/zapp-react-native-utils/utils";
20
+
18
21
  type PathAttribute = {
19
22
  screenType: string;
20
23
  screenId: string;
@@ -403,15 +406,22 @@ export const mapContentTypesToRivers = (
403
406
  };
404
407
 
405
408
  export const runZappHooksForEntry = async (
406
- entry: HookPluginProps["payload"],
407
- {
409
+ entry: HookPluginProps["payload"]
410
+ ): Promise<{ success: boolean; payload: ZappEntry }> => {
411
+ const {
408
412
  setState,
409
413
  resetState,
410
414
  setIsHooksExecutionInProgress,
411
415
  setIsPresentingFullScreen,
412
416
  setIsRunningInBackground,
413
- }: Partial<HookModalContextT>
414
- ): Promise<{ success: boolean; payload: ZappEntry }> => {
417
+ } = pick(zappHookModalStore.getState(), [
418
+ "setState",
419
+ "resetState",
420
+ "setIsHooksExecutionInProgress",
421
+ "setIsPresentingFullScreen",
422
+ "setIsRunningInBackground",
423
+ ]);
424
+
415
425
  resetState?.();
416
426
 
417
427
  let success;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-utils",
3
- "version": "15.0.0-alpha.4429053208",
3
+ "version": "15.0.0-alpha.4920595583",
4
4
  "description": "Applicaster Zapp React Native utilities package",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -27,13 +27,13 @@
27
27
  },
28
28
  "homepage": "https://github.com/applicaster/quickbrick#readme",
29
29
  "dependencies": {
30
- "@applicaster/applicaster-types": "15.0.0-alpha.4429053208",
30
+ "@applicaster/applicaster-types": "15.0.0-alpha.4920595583",
31
31
  "buffer": "^5.2.1",
32
32
  "camelize": "^1.0.0",
33
33
  "dayjs": "^1.11.10",
34
+ "handlebars": "4.7.8",
34
35
  "memoizee": "0.4.15",
35
- "prop-types": "^15.0.0",
36
- "react-native-handlebars": "^5.0.0-alpha.1"
36
+ "prop-types": "^15.0.0"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@applicaster/zapp-pipes-v2-client": "*",
@@ -1,5 +1,5 @@
1
1
  import EventEmitter from "events";
2
- import { renderHook, act } from "@testing-library/react-hooks";
2
+ import { renderHook, act } from "@testing-library/react-native";
3
3
  import { useAppState } from "../useAppState";
4
4
 
5
5
  const emitter = new EventEmitter();
@@ -1,4 +1,4 @@
1
- import { renderHook } from "@testing-library/react-hooks";
1
+ import { renderHook } from "@testing-library/react-native";
2
2
 
3
3
  jest.mock(
4
4
  "@applicaster/zapp-react-native-ui-components/Contexts/ScreenTrackedViewPositionsContext",
@@ -1,7 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { renderHook } from "@testing-library/react-hooks";
4
- import { act, waitFor } from "@testing-library/react-native";
3
+ import { renderHook, act, waitFor } from "@testing-library/react-native";
5
4
  import { Provider } from "react-redux";
6
5
  import configureStore from "redux-mock-store";
7
6
  import { useTrackedView } from "../useTrackedView";
@@ -1,10 +1,8 @@
1
1
  import * as React from "react";
2
- import { cleanup, renderHook } from "@testing-library/react-hooks";
2
+ import { cleanup, renderHook, waitFor } from "@testing-library/react-native";
3
3
  import { CellTapContext } from "@applicaster/zapp-react-native-ui-components/Contexts/CellTapContext";
4
4
  import { ActionExecutorContext } from "@applicaster/zapp-react-native-utils/actionsExecutor/ActionExecutorContext";
5
5
 
6
- import { waitFor } from "@testing-library/react-native";
7
-
8
6
  const mockNavigator = {
9
7
  getPathname: () => "pathnameMock",
10
8
  push: jest.fn(),
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable react/prop-types */
2
2
  import React from "react";
3
- import { renderHook, cleanup } from "@testing-library/react-hooks";
3
+ import { renderHook, cleanup } from "@testing-library/react-native";
4
4
  import { ConfigurationContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ConfigutaionContext";
5
5
  import { useConfiguration } from "@applicaster/zapp-react-native-utils/reactHooks/configuration";
6
6
 
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import { renderHook, cleanup } from "@testing-library/react-hooks";
2
+ import { renderHook, cleanup } from "@testing-library/react-native";
3
3
  import { NetworkStatusContext } from "@applicaster/zapp-react-native-ui-components/Contexts/NetworkStatusContext";
4
4
 
5
5
  const MockNetInfo = {
@@ -1,8 +1,7 @@
1
- import { renderHook } from "@testing-library/react-hooks";
1
+ 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 { waitFor } from "@testing-library/react-native";
6
5
 
7
6
  jest.mock("../../navigation");
8
7
 
@@ -16,7 +15,11 @@ jest.mock(
16
15
  })
17
16
  );
18
17
 
19
- const wrapper = WrappedWithProviders;
18
+ const getWrapper =
19
+ (store) =>
20
+ ({ children }) => (
21
+ <WrappedWithProviders store={store}>{children}</WrappedWithProviders>
22
+ );
20
23
 
21
24
  describe("useBatchLoading", () => {
22
25
  const data = [
@@ -63,8 +66,7 @@ describe("useBatchLoading", () => {
63
66
  const riverId = "123";
64
67
 
65
68
  renderHook(() => useBatchLoading(data, { initialBatchSize, riverId }), {
66
- wrapper,
67
- initialProps: { store },
69
+ wrapper: getWrapper(store),
68
70
  });
69
71
 
70
72
  const actions = (appStore.getStore() as any).getActions();
@@ -84,7 +86,7 @@ describe("useBatchLoading", () => {
84
86
  });
85
87
  });
86
88
 
87
- it("loadPipesData start loading new feed when 1 feed is done loading and 1 is in loading state", () => {
89
+ it("loadPipesData start loading new feed when 1 feed is done loading and 1 is in loading state", async () => {
88
90
  const store = {
89
91
  zappPipes: {
90
92
  url1: {
@@ -110,13 +112,14 @@ describe("useBatchLoading", () => {
110
112
  const riverId = "123";
111
113
 
112
114
  renderHook(() => useBatchLoading(data, { initialBatchSize, riverId }), {
113
- wrapper,
114
- initialProps: { store },
115
+ wrapper: getWrapper(store),
115
116
  });
116
117
 
117
118
  const actions = (appStore.getStore() as any).getActions();
118
119
 
119
- expect(actions).toHaveLength(1);
120
+ await waitFor(() => {
121
+ expect(actions).toHaveLength(1);
122
+ });
120
123
 
121
124
  expect(actions[0]).toMatchObject({
122
125
  type: "ZAPP_PIPES_REQUEST_START",
@@ -124,7 +127,7 @@ describe("useBatchLoading", () => {
124
127
  });
125
128
  });
126
129
 
127
- it("loadPipesData has been called when no data cached", () => {
130
+ it("loadPipesData has been called when no data cached", async () => {
128
131
  const store = {
129
132
  zappPipes: {},
130
133
  test: "true",
@@ -134,16 +137,17 @@ describe("useBatchLoading", () => {
134
137
  const riverId = "123";
135
138
 
136
139
  renderHook(() => useBatchLoading(data, { initialBatchSize, riverId }), {
137
- wrapper,
138
- initialProps: { store },
140
+ wrapper: getWrapper(store),
139
141
  });
140
142
 
141
143
  const actions = (appStore.getStore() as any).getActions();
142
144
 
143
- expect(actions).toHaveLength(3);
145
+ await waitFor(() => {
146
+ expect(actions).toHaveLength(3);
147
+ });
144
148
  });
145
149
 
146
- it("initial batch ready when all initial items loaded", () => {
150
+ it("initial batch ready when all initial items loaded", async () => {
147
151
  const store = {
148
152
  zappPipes: {
149
153
  url1: {
@@ -169,13 +173,15 @@ describe("useBatchLoading", () => {
169
173
 
170
174
  const { result } = renderHook(
171
175
  () => useBatchLoading(data, { initialBatchSize, riverId }),
172
- { wrapper, initialProps: { store } }
176
+ { wrapper: getWrapper(store) }
173
177
  );
174
178
 
175
- expect(result.current).toBe(true);
179
+ await waitFor(() => {
180
+ expect(result.current).toBe(true);
181
+ });
176
182
  });
177
183
 
178
- it("gallery-qb: loadPipesData should be called only once for first component in the gallery", () => {
184
+ it("gallery-qb: loadPipesData should be called only once for first component in the gallery", async () => {
179
185
  const store = {
180
186
  zappPipes: {},
181
187
  test: "true",
@@ -198,16 +204,17 @@ describe("useBatchLoading", () => {
198
204
  ];
199
205
 
200
206
  renderHook(() => useBatchLoading(data, { initialBatchSize, riverId }), {
201
- wrapper,
202
- initialProps: { store },
207
+ wrapper: getWrapper(store),
203
208
  });
204
209
 
205
210
  const actions = (appStore.getStore() as any).getActions();
206
211
 
207
- expect(actions).toHaveLength(1);
212
+ await waitFor(() => {
213
+ expect(actions).toHaveLength(1);
214
+ });
208
215
  });
209
216
 
210
- it("gallery-qb: initial batch ready when all initial items loaded", () => {
217
+ it("gallery-qb: initial batch ready when all initial items loaded", async () => {
211
218
  const store = {
212
219
  zappPipes: {
213
220
  url1: {
@@ -233,10 +240,12 @@ describe("useBatchLoading", () => {
233
240
 
234
241
  const { result } = renderHook(
235
242
  () => useBatchLoading(data, { initialBatchSize, riverId }),
236
- { wrapper, initialProps: { store } }
243
+ { wrapper: getWrapper(store) }
237
244
  );
238
245
 
239
- expect(result.current).toBe(true);
246
+ await waitFor(() => {
247
+ expect(result.current).toBe(true);
248
+ });
240
249
  });
241
250
  });
242
251
 
@@ -1,4 +1,4 @@
1
- import { renderHook } from "@testing-library/react-hooks";
1
+ import { renderHook, waitFor } from "@testing-library/react-native";
2
2
  import { encodeParams } from "@applicaster/zapp-pipes-v2-client/src/utils";
3
3
 
4
4
  const appData = {
@@ -42,26 +42,26 @@ describe("useBuildPipesUrl", () => {
42
42
  build: jest.fn(() => Promise.resolve(buildResult)),
43
43
  };
44
44
 
45
- const { result, waitForNextUpdate } = renderHook(() =>
45
+ const { result } = renderHook(() =>
46
46
  useBuildPipesUrl({ url, mapping, requestBuilder: mockedRequestBuilder })
47
47
  );
48
48
 
49
49
  expect(result.current.url).toBe("http://foo.com/show/show-1");
50
50
  expect(result.current.requestParams).toBeNull();
51
51
 
52
- await waitForNextUpdate();
53
-
54
- expect(result.current.requestParams).toEqual(
55
- expect.objectContaining({
56
- params: {
57
- version: appData.version_name,
58
- ctx: encodeParams({ platform: appData.platform }),
59
- },
60
- headers: {
61
- SDK: appData.sdk_version,
62
- },
63
- })
64
- );
52
+ await waitFor(() => {
53
+ expect(result.current.requestParams).toEqual(
54
+ expect.objectContaining({
55
+ params: {
56
+ version: appData.version_name,
57
+ ctx: encodeParams({ platform: appData.platform }),
58
+ },
59
+ headers: {
60
+ SDK: appData.sdk_version,
61
+ },
62
+ })
63
+ );
64
+ });
65
65
  });
66
66
 
67
67
  it("returns empty object if url is not in endpoints", async () => {
@@ -81,15 +81,15 @@ describe("useBuildPipesUrl", () => {
81
81
  build: jest.fn(() => Promise.resolve(buildResult)),
82
82
  };
83
83
 
84
- const { result, waitForNextUpdate } = renderHook(() =>
84
+ const { result } = renderHook(() =>
85
85
  useBuildPipesUrl({ url, mapping, requestBuilder: mockedRequestBuilder })
86
86
  );
87
87
 
88
88
  expect(result.current.url).toBe("http://foobar.com/show-1");
89
89
  expect(result.current.requestParams).toBeNull();
90
90
 
91
- await waitForNextUpdate();
92
-
93
- expect(result.current.requestParams).toEqual({});
91
+ await waitFor(() => {
92
+ expect(result.current.requestParams).toEqual({});
93
+ });
94
94
  });
95
95
  });
@@ -1,6 +1,6 @@
1
1
  import * as R from "ramda";
2
2
  import React from "react";
3
- import { renderHook } from "@testing-library/react-hooks";
3
+ import { renderHook } from "@testing-library/react-native";
4
4
  import { Provider } from "react-redux";
5
5
  import { createStore } from "redux";
6
6
 
@@ -1,4 +1,4 @@
1
- import { renderHook } from "@testing-library/react-hooks";
1
+ import { renderHook } from "@testing-library/react-native";
2
2
  import * as R from "ramda";
3
3
  import * as zappPipesModule from "@applicaster/zapp-react-native-redux/ZappPipes";
4
4
  import * as reactReduxModules from "react-redux";
@@ -50,6 +50,16 @@ const mockZappPipesData = {
50
50
  url: "test://testfakeurl",
51
51
  };
52
52
 
53
+ const createWrapper = (
54
+ getStore: () => any
55
+ ): React.FC<{ children: React.ReactNode }> => {
56
+ const Wrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => (
57
+ <WrappedWithProviders store={getStore()}>{children}</WrappedWithProviders>
58
+ );
59
+
60
+ return Wrapper;
61
+ };
62
+
53
63
  describe("useFeedLoader", () => {
54
64
  describe("with cached feed url", () => {
55
65
  const store = {
@@ -57,11 +67,7 @@ describe("useFeedLoader", () => {
57
67
  zappPipes: { "test://testfakeurl": mockZappPipesData },
58
68
  };
59
69
 
60
- const wrapper: React.FC<any> = ({ children, ...props }) => (
61
- <WrappedWithProviders store={props.store || store}>
62
- {children}
63
- </WrappedWithProviders>
64
- );
70
+ const wrapper = createWrapper(() => store);
65
71
 
66
72
  it("returns cached feed", () => {
67
73
  const { result } = renderHook(
@@ -109,12 +115,6 @@ describe("useFeedLoader", () => {
109
115
  describe("without cached feeds", () => {
110
116
  const feedUrl = "test://testfakeurl2";
111
117
 
112
- const wrapper: React.FC<any> = ({ children, ...props }) => (
113
- <WrappedWithProviders store={props.store}>
114
- {children}
115
- </WrappedWithProviders>
116
- );
117
-
118
118
  it("It loads data for new url and returns it", () => {
119
119
  const useDispatchSpy = jest
120
120
  .spyOn(reactReduxModules, "useDispatch")
@@ -129,9 +129,12 @@ describe("useFeedLoader", () => {
129
129
  zappPipes: { "test://testfakeurl": "foobar" },
130
130
  };
131
131
 
132
+ let store = initialStore;
133
+ const wrapper = createWrapper(() => store);
134
+
132
135
  const { result, rerender } = renderHook(
133
- () => useFeedLoader({ feedUrl: "test://testfakeurl2" }),
134
- { wrapper, initialProps: { store: initialStore } }
136
+ ({ feedUrl: url }) => useFeedLoader({ feedUrl: url }),
137
+ { wrapper, initialProps: { feedUrl } }
135
138
  );
136
139
 
137
140
  expect(result.current.data).toBeNull();
@@ -150,7 +153,8 @@ describe("useFeedLoader", () => {
150
153
  zappPipes: { "test://testfakeurl2": mockZappPipesData },
151
154
  };
152
155
 
153
- rerender({ store: store2 });
156
+ store = store2;
157
+ rerender({ feedUrl });
154
158
 
155
159
  expect(R.omit(["reloadData", "loadNext"], result.current)).toEqual(
156
160
  mockZappPipesData
@@ -174,9 +178,12 @@ describe("useFeedLoader", () => {
174
178
  zappPipes: { "test://testfakeurl": "foobar" },
175
179
  };
176
180
 
181
+ let store = initialStore;
182
+ const wrapper = createWrapper(() => store);
183
+
177
184
  const { result, rerender } = renderHook(
178
- () => useFeedLoader({ feedUrl: "test://testfakeurl2" }),
179
- { wrapper, initialProps: { store: initialStore } }
185
+ ({ feedUrl: url }) => useFeedLoader({ feedUrl: url }),
186
+ { wrapper, initialProps: { feedUrl } }
180
187
  );
181
188
 
182
189
  expect(result.current.data).toBeNull();
@@ -198,7 +205,8 @@ describe("useFeedLoader", () => {
198
205
  zappPipes: { "test://testfakeurl2": mockZappPipesData },
199
206
  };
200
207
 
201
- rerender({ store: store2 });
208
+ store = store2;
209
+ rerender({ feedUrl });
202
210
 
203
211
  loadPipesDataSpy.mockRestore();
204
212
  useDispatchSpy.mockRestore();
@@ -209,12 +217,6 @@ describe("useFeedLoader", () => {
209
217
  const feedUrl = "test://testfakeurl";
210
218
  const feedUrlWithNext = "test://withnexttestfakeurl";
211
219
 
212
- const wrapper: React.FC<any> = ({ children, ...props }) => (
213
- <WrappedWithProviders store={props.store || {}}>
214
- {children}
215
- </WrappedWithProviders>
216
- );
217
-
218
220
  describe("reloadData", () => {
219
221
  it("Tries to reload data in the redux store", () => {
220
222
  const loadPipesDataSpy = jest
@@ -230,10 +232,17 @@ describe("useFeedLoader", () => {
230
232
  zappPipes: { [feedUrl]: "foobar" },
231
233
  };
232
234
 
233
- const { result } = renderHook(() => useFeedLoader({ feedUrl }), {
234
- wrapper,
235
- initialProps: { store: initialStore },
236
- });
235
+ const store = initialStore;
236
+
237
+ const wrapper = createWrapper(() => store);
238
+
239
+ const { result } = renderHook(
240
+ ({ feedUrl: url }) => useFeedLoader({ feedUrl: url }),
241
+ {
242
+ wrapper,
243
+ initialProps: { feedUrl },
244
+ }
245
+ );
237
246
 
238
247
  const { reloadData } = result.current;
239
248
 
@@ -279,11 +288,14 @@ describe("useFeedLoader", () => {
279
288
  zappPipes: { [feedUrlWithNext]: { data: { next: nextUrl } } },
280
289
  };
281
290
 
291
+ const store = initialStore;
292
+ const wrapper = createWrapper(() => store);
293
+
282
294
  const { result } = renderHook(
283
- () => useFeedLoader({ feedUrl: feedUrlWithNext }),
295
+ ({ feedUrl: url }) => useFeedLoader({ feedUrl: url }),
284
296
  {
285
297
  wrapper,
286
- initialProps: { store: initialStore },
298
+ initialProps: { feedUrl: feedUrlWithNext },
287
299
  }
288
300
  );
289
301
 
@@ -1,4 +1,4 @@
1
- import { renderHook } from "@testing-library/react-hooks";
1
+ import { renderHook } from "@testing-library/react-native";
2
2
 
3
3
  jest.useFakeTimers();
4
4
 
@@ -214,7 +214,7 @@ describe("getSearchContext", () => {
214
214
  });
215
215
 
216
216
  describe("useGetUrlInflater", () => {
217
- const { renderHook } = require("@testing-library/react-hooks");
217
+ const { renderHook } = require("@testing-library/react-native");
218
218
 
219
219
  it("returns original url when mapping is not provided", () => {
220
220
  const { result } = renderHook(() => useGetUrlInflater(), {
@@ -1,20 +1,24 @@
1
1
  import { reactHooksLogger } from "../../logger";
2
- import { useZappHooksModalState } from "@applicaster/zapp-react-dom-ui-components/Components/ZappHooksModal/hooks/useZappHooksModalState";
2
+ import { useZappHookModalStore } from "@applicaster/zapp-react-native-ui-components/Contexts/ZappHookModalContext";
3
3
 
4
4
  const logger = reactHooksLogger.addSubsystem("useHookModalScreenData");
5
5
 
6
6
  type VariousScreenData = LegacyNavigationScreenData | ZappRiver | ZappEntry;
7
7
 
8
- export const useHookModalScreenData = (): VariousScreenData | undefined => {
9
- const hookModalState = useZappHooksModalState();
8
+ export const useHookModalScreenData = (
9
+ skipSubscription: boolean
10
+ ): VariousScreenData | undefined => {
11
+ const hookModalState = useZappHookModalStore((state) =>
12
+ skipSubscription ? undefined : state.state
13
+ );
10
14
 
11
- if (!hookModalState.state?.screenData) {
15
+ if (!hookModalState?.screenData) {
12
16
  return;
13
17
  }
14
18
 
15
19
  try {
16
- const screenData = hookModalState.state.screenData?.payload;
17
- const hookPlugin = hookModalState.state.screenData.hookPlugin;
20
+ const screenData = hookModalState.screenData?.payload;
21
+ const hookPlugin = hookModalState.screenData.hookPlugin;
18
22
 
19
23
  if (hookPlugin?.screen_id) {
20
24
  return {
@@ -23,7 +27,7 @@ export const useHookModalScreenData = (): VariousScreenData | undefined => {
23
27
  };
24
28
  }
25
29
 
26
- return hookModalState.state.screenData?.payload;
30
+ return hookModalState.screenData?.payload;
27
31
  } catch (error) {
28
32
  logger.error({
29
33
  message: "Hook modal screen data creation failed",
@@ -34,6 +38,6 @@ export const useHookModalScreenData = (): VariousScreenData | undefined => {
34
38
  jsOnly: true,
35
39
  });
36
40
 
37
- return hookModalState.state.screenData?.payload;
41
+ return hookModalState.screenData?.payload;
38
42
  }
39
43
  };
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { cleanup, renderHook } from "@testing-library/react-hooks";
3
+ import { cleanup, renderHook } from "@testing-library/react-native";
4
4
  import { Provider } from "react-redux";
5
5
  import configureStore from "redux-mock-store";
6
6
 
@@ -1,4 +1,4 @@
1
- import { renderHook } from "@testing-library/react-hooks";
1
+ import { renderHook } from "@testing-library/react-native";
2
2
  import configureStore from "redux-mock-store";
3
3
 
4
4
  const mockStore = configureStore();
@@ -1,11 +1,10 @@
1
1
  import React from "react";
2
2
  import { PathnameContext } from "@applicaster/zapp-react-native-ui-components/Contexts/PathnameContext";
3
- import { renderHook } from "@testing-library/react-hooks";
3
+ import { renderHook } from "@testing-library/react-native";
4
4
  import { isNavBarVisible, useRoute } from "../";
5
5
  import { Provider } from "react-redux";
6
6
  import configureMockStore from "redux-mock-store";
7
7
  import { NavigationContext } from "@applicaster/zapp-react-native-ui-components/Contexts/NavigationContext";
8
- import { ZappHookModalContext } from "@applicaster/zapp-react-native-ui-components/Contexts";
9
8
  import { ROUTE_TYPES } from "@applicaster/zapp-react-native-utils/navigationUtils/routeTypes";
10
9
  import { ScreenDataContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenDataContext";
11
10
 
@@ -83,10 +82,44 @@ const hookModalContextState = {
83
82
  },
84
83
  setState: jest.fn(),
85
84
  resetState: jest.fn(),
85
+ hookPresentationMode: null,
86
86
  };
87
87
 
88
88
  const hooksModalPathname = `${ROUTE_TYPES.HOOKS_MODAL}/${hookModalContextState.state.screenData.payload.id}`;
89
89
  const videoModalPathname = `${ROUTE_TYPES.VIDEO_MODAL}/${videoModalNavigator.videoModalState.item.id}`;
90
+
91
+ jest.mock(
92
+ "@applicaster/zapp-react-native-ui-components/Contexts/ZappHookModalContext",
93
+ () => {
94
+ const mockState = {
95
+ isRunningInBackground: false,
96
+ setIsRunningInBackground: jest.fn(),
97
+ setIsPresentingFullScreen: jest.fn(),
98
+ isPresentationFullScreen: true,
99
+ isHooksExecutionInProgress: true,
100
+ setIsHooksExecutionInProgress: jest.fn(),
101
+ state: {
102
+ path: "/home",
103
+ screenData: { payload: { id: "hookExecutedInModal" } },
104
+ },
105
+ setState: jest.fn(),
106
+ resetState: jest.fn(),
107
+ hookPresentationMode: null,
108
+ };
109
+
110
+ const mockHook = jest.fn((selector) => {
111
+ return selector ? selector(mockState) : mockState;
112
+ }) as jest.MockedFunction<any> & { getState: () => typeof mockState };
113
+
114
+ mockHook.getState = jest.fn(() => mockState);
115
+
116
+ return {
117
+ useZappHookModalStore: mockHook,
118
+ zappHookModalStore: mockHook,
119
+ };
120
+ }
121
+ );
122
+
90
123
  const mockStore = configureMockStore();
91
124
 
92
125
  const store = mockStore({
@@ -125,13 +158,11 @@ const videoModalWrapper = ({ children }) => (
125
158
 
126
159
  const hookModalWrapper = ({ children }) => (
127
160
  <Provider store={store}>
128
- <ZappHookModalContext.ReactContext.Provider value={hookModalContextState}>
129
- <NavigationContext.Provider value={hookModalNavigator}>
130
- <PathnameContext.Provider value={hooksModalPathname}>
131
- {children}
132
- </PathnameContext.Provider>
133
- </NavigationContext.Provider>
134
- </ZappHookModalContext.ReactContext.Provider>
161
+ <NavigationContext.Provider value={hookModalNavigator}>
162
+ <PathnameContext.Provider value={hooksModalPathname}>
163
+ {children}
164
+ </PathnameContext.Provider>
165
+ </NavigationContext.Provider>
135
166
  </Provider>
136
167
  );
137
168
 
@@ -1,5 +1,6 @@
1
- import { useContext, useEffect, useMemo, useRef } from "react";
1
+ import { useEffect, useMemo, useRef } from "react";
2
2
  import { BackHandler } from "react-native";
3
+ import { shallow } from "zustand/shallow";
3
4
 
4
5
  import {
5
6
  useContentTypes,
@@ -8,13 +9,13 @@ import {
8
9
  import { HooksManager } from "@applicaster/zapp-react-native-utils/appUtils/HooksManager";
9
10
 
10
11
  import { LONG_KEY_PRESS_TIMEOUT } from "@applicaster/quick-brick-core/const";
11
- import { ZappHookModalContext } from "@applicaster/zapp-react-native-ui-components/Contexts";
12
- import { HookModalContextT } from "@applicaster/zapp-react-native-ui-components/Contexts/ZappHookModalContext";
12
+ import { useZappHookModalStore } from "@applicaster/zapp-react-native-ui-components/Contexts/ZappHookModalContext";
13
13
  import { HOOKS_EVENTS } from "../../appUtils/HooksManager/constants";
14
14
  import { getRiverFromRoute, getTargetRoute } from "../../navigationUtils";
15
15
  import { useConnectionInfo } from "../connection";
16
16
 
17
17
  import { isTV, isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
18
+ import { pick } from "@applicaster/zapp-react-native-utils/utils";
18
19
  import { useNavbarState } from "../screen";
19
20
  import { useRivers } from "../state";
20
21
  import { useLayoutVersion } from "../layout";
@@ -168,7 +169,17 @@ export const useZappHooksForEntry = (
168
169
  setIsHooksExecutionInProgress,
169
170
  setIsPresentingFullScreen,
170
171
  setIsRunningInBackground,
171
- }: HookModalContextT = useContext(ZappHookModalContext.ReactContext);
172
+ } = useZappHookModalStore(
173
+ (state) =>
174
+ pick(state, [
175
+ "setState",
176
+ "resetState",
177
+ "setIsHooksExecutionInProgress",
178
+ "setIsPresentingFullScreen",
179
+ "setIsRunningInBackground",
180
+ ]),
181
+ shallow
182
+ );
172
183
 
173
184
  const plugins = usePlugins();
174
185
  const rivers = useRivers();
@@ -54,7 +54,9 @@ export const useRoute = (
54
54
 
55
55
  const modalScreenData = modalState.screen;
56
56
 
57
- const hookModalScreenData = useHookModalScreenData();
57
+ const hookModalScreenData = useHookModalScreenData(
58
+ !isHookModalPathname(pathname)
59
+ );
58
60
 
59
61
  const videoModalScreenData =
60
62
  navigator?.videoModalState?.item &&
@@ -1,4 +1,4 @@
1
- import { act, renderHook } from "@testing-library/react-hooks";
1
+ import { act, renderHook } from "@testing-library/react-native";
2
2
  import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
3
3
 
4
4
  import { ON_HOLD_INTERVAL, SEEK_TYPE, SKIP_TIME_BASE } from "../const";
@@ -1,4 +1,4 @@
1
- import { renderHook } from "@testing-library/react-hooks";
1
+ import { renderHook } from "@testing-library/react-native";
2
2
  import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
3
3
  import { useTapSeek } from "../useTapSeek";
4
4
 
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
  import { View } from "react-native";
3
- import { cleanup, renderHook } from "@testing-library/react-hooks";
3
+ import { cleanup, renderHook } from "@testing-library/react-native";
4
4
  import configureStore from "redux-mock-store";
5
5
  import { Provider } from "react-redux";
6
6
 
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import { renderHook, cleanup } from "@testing-library/react-hooks";
2
+ import { renderHook, cleanup } from "@testing-library/react-native";
3
3
  import configureStore from "redux-mock-store";
4
4
  import { Provider } from "react-redux";
5
5
 
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
  import { Provider } from "react-redux";
3
- import { renderHook } from "@testing-library/react-hooks";
3
+ import { renderHook } from "@testing-library/react-native";
4
4
  import configureStore from "redux-mock-store";
5
5
  import { thunk } from "redux-thunk";
6
6
 
@@ -1,4 +1,4 @@
1
- import { renderHook } from "@testing-library/react-hooks";
1
+ import { renderHook } from "@testing-library/react-native";
2
2
 
3
3
  jest.mock(
4
4
  "@applicaster/zapp-react-native-ui-components/Components/River/useScreenConfiguration",
@@ -1,4 +1,4 @@
1
- import { renderHook } from "@testing-library/react-hooks";
1
+ import { renderHook } from "@testing-library/react-native";
2
2
  import configureStore from "redux-mock-store";
3
3
 
4
4
  const mockStore = configureStore();
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
  import { Provider } from "react-redux";
3
- import { renderHook } from "@testing-library/react-hooks";
3
+ import { renderHook } from "@testing-library/react-native";
4
4
  import configureStore from "redux-mock-store";
5
5
  import { thunk } from "redux-thunk";
6
6
 
@@ -1,5 +1,5 @@
1
1
  import { usePrevious, useIsInitialRender } from "../";
2
- import { renderHook, cleanup } from "@testing-library/react-hooks";
2
+ import { renderHook, cleanup } from "@testing-library/react-native";
3
3
 
4
4
  describe("usePrevious", () => {
5
5
  it("renders", () => {
@@ -1,4 +1,4 @@
1
- import { act, renderHook } from "@testing-library/react-hooks";
1
+ import { act, renderHook } from "@testing-library/react-native";
2
2
  import { useScreenState } from "../index";
3
3
 
4
4
  describe("useScreenState", () => {
@@ -4,7 +4,7 @@ declare const global;
4
4
  import * as R from "ramda";
5
5
  import camelize from "camelize";
6
6
  // @ts-ignore
7
- import Handlebars from "react-native-handlebars";
7
+ import Handlebars from "handlebars";
8
8
 
9
9
  global.Buffer = global.Buffer || require("buffer").Buffer;
10
10