@applicaster/quick-brick-core 12.0.0-alpha.5114122134 → 12.0.0-alpha.5208030571

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.
@@ -88,10 +88,10 @@ const getActionInitialStateSetters = (key) => {
88
88
  return R.compose(
89
89
  R.map((subscription: { [x: string]: any; pluginId: any }) => {
90
90
  return async () => {
91
+ const now = performance.now();
92
+
91
93
  logger.info({
92
- message: `Invocation Started - action plugin ${key}, pluginId: ${
93
- subscription.pluginId
94
- }: ${performance.now()}`,
94
+ message: `Invocation Started - action plugin ${key}, pluginId: ${subscription.pluginId}`,
95
95
  });
96
96
 
97
97
  const promiseFunc = subscription[key];
@@ -101,7 +101,7 @@ const getActionInitialStateSetters = (key) => {
101
101
  logger.info({
102
102
  message: `Invocation Completed - action plugin ${key}, pluginId: ${
103
103
  subscription.pluginId
104
- }: ${performance.now()}`,
104
+ }: ${performance.now() - now} ms`,
105
105
  });
106
106
 
107
107
  return result;
@@ -323,7 +323,7 @@ describe("asset cache", () => {
323
323
 
324
324
  expect(saveCacheData).toHaveBeenCalledWith(
325
325
  layoutId,
326
- newFiles.filter(({ url }) => !url.includes("fail")),
326
+ newFiles.filter(({ url }) => !url.includes("fail"))
327
327
  );
328
328
  });
329
329
 
@@ -143,7 +143,12 @@ export async function cacheAssets({
143
143
 
144
144
  newCacheState.forEach(({ file, url }) => (urlFileMap[url] = file));
145
145
 
146
- const updatedLayout = remapAssetPath(layoutAssets, layout, urlFileMap, "layoutAssets");
146
+ const updatedLayout = remapAssetPath(
147
+ layoutAssets,
148
+ layout,
149
+ urlFileMap,
150
+ "layoutAssets"
151
+ );
147
152
 
148
153
  const updatedPluginConfigurations = remapAssetPath(
149
154
  pluginAssets,
@@ -169,6 +174,8 @@ export async function cacheAssets({
169
174
 
170
175
  return { layout, pluginConfigurations, cellStyles };
171
176
  } finally {
172
- log_verbose(`cacheAssets: caching assets took ${performance.now() - time} ms`);
177
+ log_verbose(
178
+ `cacheAssets: caching assets took ${performance.now() - time} ms`
179
+ );
173
180
  }
174
181
  }
@@ -1,7 +1,4 @@
1
- import {
2
- useActions,
3
- usePickFromState,
4
- } from "@applicaster/zapp-react-native-redux/hooks";
1
+ import { useActions } from "@applicaster/zapp-react-native-redux/hooks";
5
2
  import * as R from "ramda";
6
3
  import * as React from "react";
7
4
  import axios from "axios";
@@ -28,6 +25,7 @@ import {
28
25
  } from "../../helpers";
29
26
 
30
27
  import { log_error, log_info } from "../../logger";
28
+ import { useRivers } from "@applicaster/zapp-react-native-utils/reactHooks/state";
31
29
 
32
30
  const getFeed = (query) => ({
33
31
  content: { src: query.data_source },
@@ -60,7 +58,7 @@ export function usePresentSchemeHandler({
60
58
  feedUrl: data_source,
61
59
  });
62
60
 
63
- const { rivers } = usePickFromState(["rivers"]);
61
+ const rivers = useRivers();
64
62
  const screenRiver = findRiver({ screen_id, rivers });
65
63
  const dispatch = useDispatch();
66
64
 
@@ -1,7 +1,5 @@
1
1
  import React from "react";
2
- import { render, waitFor, cleanup } from "@testing-library/react-native";
3
-
4
- jest.mock("react-native");
2
+ import { cleanup, render, waitFor } from "@testing-library/react-native";
5
3
 
6
4
  const theme = {
7
5
  screen_margin_top: 0,
@@ -10,6 +8,8 @@ const theme = {
10
8
 
11
9
  const plugins = [];
12
10
 
11
+ jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation");
12
+
13
13
  jest.mock("@applicaster/zapp-react-native-utils/theme", () => ({
14
14
  useTheme: jest.fn(() => theme),
15
15
  }));
@@ -7,8 +7,6 @@ import { URLSchemeListener } from "../index";
7
7
 
8
8
  const URL = "url";
9
9
 
10
- jest.mock("react-native");
11
-
12
10
  const TestComponent = () => (
13
11
  <View>
14
12
  <Text>I'm a test component</Text>
@@ -13,6 +13,7 @@ import {
13
13
  useNavigation,
14
14
  } from "@applicaster/zapp-react-native-utils/reactHooks";
15
15
  import { useDimensions } from "@applicaster/zapp-react-native-utils/reactHooks/layout";
16
+ import { ModalComponent } from "@applicaster/zapp-react-native-ui-components/Components";
16
17
 
17
18
  const styles = StyleSheet.create({
18
19
  container: {
@@ -55,7 +56,10 @@ export function ModalBottomSheet(props: Props) {
55
56
  modal_bottom_sheet_tablet_max_width: sheetTabletMaxWidth,
56
57
  } = theme;
57
58
 
58
- const { ModalBottomSheetContent, modalBottomSheetContentProps } = props;
59
+ const {
60
+ ModalBottomSheetContent = ModalComponent,
61
+ modalBottomSheetContentProps,
62
+ } = props;
59
63
 
60
64
  const onLayout = useCallback(({ nativeEvent }) => {
61
65
  const calculatedHeight = nativeEvent?.layout?.height;
@@ -17,7 +17,7 @@ const styles = StyleSheet.create({
17
17
  export function ModalContent(props: Props) {
18
18
  const { modalScreenProps } = props;
19
19
 
20
- if (modalScreenProps?.screenData?.ModalBottomSheetContent) {
20
+ if (modalScreenProps?.screenData?.modalBottomSheetContentProps) {
21
21
  const { ModalBottomSheetContent, modalBottomSheetContentProps } =
22
22
  modalScreenProps?.screenData || {};
23
23
 
@@ -1,16 +1,16 @@
1
1
  import * as React from "react";
2
2
 
3
- import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
4
-
5
3
  import { ModalPresenter } from "./ModalPresenter";
6
4
  import { ModalContent } from "./ModalContent";
7
5
  import { ModalChildrenWrapper } from "./ModalChildrenWrapper";
8
6
  import { PathnameContext } from "@applicaster/zapp-react-native-ui-components/Contexts/PathnameContext";
9
7
  import { ScreenContextProvider } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenContext";
10
8
  import { ROUTE_TYPES } from "@applicaster/zapp-react-native-utils/navigationUtils/routeTypes";
9
+ import { useModalStore } from "@applicaster/zapp-react-native-utils/modalState";
11
10
 
12
11
  export function ModalProvider() {
13
- const { modalState } = useNavigation();
12
+ const { modalState } = useModalStore();
13
+
14
14
  const [modalVisible, setModalVisible] = React.useState(false);
15
15
  const [modalShown, setModalShown] = React.useState(false);
16
16
 
@@ -63,6 +63,7 @@ import { findParent } from "@applicaster/zapp-react-native-ui-components/Context
63
63
  import { ZappPipesEntryContext } from "@applicaster/zapp-react-native-ui-components/Contexts";
64
64
  import { PlayNextState } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/OverlayObserver/OverlaysObserver";
65
65
  import { inflateUrl } from "@applicaster/zapp-react-native-ui-components/Components/LinkHandler/LinkHandler";
66
+ import { useModalStore } from "@applicaster/zapp-react-native-utils/modalState";
66
67
 
67
68
  const logger = coreAppLogger.addSubsystem("Navigator");
68
69
 
@@ -92,13 +93,6 @@ const navigationActions = {
92
93
 
93
94
  const platform = getPlatform();
94
95
 
95
- const initialModalState = {
96
- visible: false,
97
- screen: null,
98
- options: {},
99
- props: {},
100
- };
101
-
102
96
  export function NavigationProvider({ children }: Props) {
103
97
  const {
104
98
  appData: { layoutVersion },
@@ -130,8 +124,7 @@ export function NavigationProvider({ children }: Props) {
130
124
  ZappPipesEntryContext.Context
131
125
  );
132
126
 
133
- const [modalState, setModalState] =
134
- React.useState<ModalState>(initialModalState);
127
+ const { openModal, dismissModal } = useModalStore();
135
128
 
136
129
  const playNextOverlayState = React.useRef();
137
130
 
@@ -153,6 +146,12 @@ export function NavigationProvider({ children }: Props) {
153
146
  [pathname, rivers]
154
147
  );
155
148
 
149
+ const getModalState: () => ModalState = () => {
150
+ const { modalState } = useModalStore.getState();
151
+
152
+ return modalState;
153
+ };
154
+
156
155
  const homeRiver = React.useMemo(
157
156
  () => homeRiverSelector({ rivers }),
158
157
  [rivers]
@@ -168,7 +167,7 @@ export function NavigationProvider({ children }: Props) {
168
167
  [rivers, homeRiver]
169
168
  );
170
169
 
171
- const getStack = () => [...stateRef?.current?.stack?.mainStack];
170
+ const getStack = () => [...state?.stack?.mainStack];
172
171
 
173
172
  const openVideoModal = (
174
173
  item: ZappEntry,
@@ -276,7 +275,7 @@ export function NavigationProvider({ children }: Props) {
276
275
  route.includes(pathname)
277
276
  );
278
277
 
279
- return pathnameStackIndex > 1;
278
+ return pathnameStackIndex >= 1;
280
279
  }
281
280
 
282
281
  if (!Number.isNaN(filteredStack?.length)) {
@@ -615,31 +614,6 @@ export function NavigationProvider({ children }: Props) {
615
614
  },
616
615
  });
617
616
 
618
- const openModal = React.useCallback(
619
- ({ item, options = {}, props = {} }: OpenModalArg) => {
620
- setModalState({
621
- visible: true,
622
- screen: item as ZappRiver,
623
- options: {
624
- animated: true,
625
- animationType: "slide",
626
- onShow: () => {},
627
- presentationStyle: "overFullScreen",
628
- transparent: true,
629
- ...options,
630
- onDismiss: () => {
631
- setModalState(initialModalState);
632
- },
633
- onRequestClose: () => {
634
- dismissModal();
635
- },
636
- },
637
- props,
638
- });
639
- },
640
- []
641
- );
642
-
643
617
  const openPiP = React.useCallback(() => {
644
618
  dispatch(setVideoPiP());
645
619
  }, []);
@@ -660,10 +634,6 @@ export function NavigationProvider({ children }: Props) {
660
634
  }
661
635
  }, [state?.options?.videoModal?.previousMode]);
662
636
 
663
- const dismissModal = React.useCallback(() => {
664
- setModalState(() => ({ ...initialModalState }));
665
- }, []);
666
-
667
637
  const openModalBottomSheet = React.useCallback(
668
638
  ({
669
639
  ModalBottomSheetContent,
@@ -695,15 +665,15 @@ export function NavigationProvider({ children }: Props) {
695
665
 
696
666
  // It will only work for the regular stack and pathname, It won't work for modals
697
667
  // TODO: integrate video/hook and regular modal into stack.
698
- const getStackForPathname = React.useCallback((pathname: string):
699
- | NavigationScreenState
700
- | undefined => {
701
- const stack = getStack();
668
+ const getStackForPathname = (
669
+ pathname: string
670
+ ): NavigationScreenState | undefined => {
671
+ const stack = [...state?.stack?.mainStack];
702
672
 
703
673
  const currentStack = stack.find(({ route }) => route === pathname);
704
674
 
705
675
  return currentStack;
706
- }, []);
676
+ };
707
677
 
708
678
  const navigator: QuickBrickAppNavigator = React.useMemo(
709
679
  () => ({
@@ -730,7 +700,7 @@ export function NavigationProvider({ children }: Props) {
730
700
  modalData: state.stack.modal?.state ?? null,
731
701
  openModal,
732
702
  dismissModal,
733
- modalState,
703
+ getModalState,
734
704
  openModalBottomSheet,
735
705
  closeModalBottomSheet,
736
706
  videoModalState: state.options.videoModal,
@@ -747,15 +717,9 @@ export function NavigationProvider({ children }: Props) {
747
717
  replaceTop,
748
718
  getStack,
749
719
  getStackForPathname,
720
+ mainStack: state.stack.mainStack,
750
721
  }),
751
- [
752
- rivers,
753
- plugins,
754
- JSON.stringify(state),
755
- modalState,
756
- appLaunched,
757
- startUpHooks,
758
- ]
722
+ [rivers, plugins, JSON.stringify(state), appLaunched, startUpHooks]
759
723
  );
760
724
 
761
725
  // when running the tests, we pass the dispatch function
@@ -11,7 +11,9 @@ Object {
11
11
  "presentationStyle": "overFullScreen",
12
12
  "transparent": true,
13
13
  },
14
- "props": Object {},
14
+ "props": Object {
15
+ "screenData": Object {},
16
+ },
15
17
  "screen": Object {
16
18
  "id": "A1234",
17
19
  "navigations": Array [],
@@ -30,26 +32,7 @@ Object {
30
32
  }
31
33
  `;
32
34
 
33
- exports[`<NavigationProvider /> modal feature sets the modalState when opening a modal 1`] = `
34
- Object {
35
- "options": Object {
36
- "animated": true,
37
- "animationType": "slide",
38
- "onDismiss": [Function],
39
- "onRequestClose": [Function],
40
- "onShow": [Function],
41
- "presentationStyle": "overFullScreen",
42
- "transparent": true,
43
- },
44
- "props": Object {},
45
- "screen": Object {
46
- "id": "A1234",
47
- "navigations": Array [],
48
- "ui_components": Array [],
49
- },
50
- "visible": true,
51
- }
52
- `;
35
+ exports[`<NavigationProvider /> modal feature sets the modalState when opening a modal 1`] = `undefined`;
53
36
 
54
37
  exports[`<NavigationProvider /> modal feature should reset state to initial when dismissing a modal ( closeModalBottomSheet ) opened by openModalBottomSheet 1`] = `
55
38
  Object {
@@ -5,6 +5,9 @@ import { createStore } from "redux";
5
5
  import { Provider } from "react-redux";
6
6
 
7
7
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
8
+ import { getByTestId } from "@applicaster/zapp-react-native-utils/testUtils/getByTestId";
9
+ // @TODO @szhigunov to complete the migration to @testing-library/react-native
10
+ // import { act, waitFor } from "@testing-library/react-native";
8
11
 
9
12
  const rivers = {
10
13
  A1234: {
@@ -151,37 +154,58 @@ const failingHook = {
151
154
  name: "failing hook",
152
155
  };
153
156
 
157
+ // const store = {
158
+ // rivers,
159
+ // plugins: [hookPlugin, hookPlugin2, failingHook],
160
+ // };
161
+
162
+ const store = createStore(() => ({
163
+ appData: { layoutVersion: "v1" },
164
+ contentTypes: null,
165
+ rivers,
166
+ plugins: [hookPlugin, hookPlugin2, failingHook],
167
+ appState: { appLaunched: true },
168
+ }));
169
+
154
170
  const ContextConsumer = () => {
155
171
  const { state, ...navigator } = useNavigation();
156
172
 
157
- const renderHook = () => {
158
- if (navigator.currentRoute.includes("/hooks/")) {
159
- const { hookPlugin, payload, callback } = navigator.screenData;
160
- const Component = hookPlugin.module.Component;
173
+ let renderHook;
161
174
 
162
- return <Component payload={payload} callback={callback} />;
163
- }
175
+ if (navigator.currentRoute.includes("/hooks/")) {
176
+ const { hookPlugin, payload, callback } = navigator.screenData;
177
+ const Component = hookPlugin.module.Component;
164
178
 
165
- return null;
166
- };
179
+ renderHook = <Component payload={payload} callback={callback} />;
180
+ }
181
+
182
+ renderHook = null;
183
+
184
+ const WrapperView: any = "View";
167
185
 
168
186
  return (
169
- <View navigator={navigator} state={state}>
170
- {renderHook()}
171
- </View>
187
+ <WrapperView testID="WrapperView" navigator={navigator} state={state}>
188
+ {renderHook}
189
+ </WrapperView>
172
190
  );
173
191
  };
174
192
 
175
- const store = createStore(() => ({
176
- appData: { layoutVersion: "v1" },
177
- contentTypes: null,
178
- rivers,
179
- plugins: [hookPlugin, hookPlugin2, failingHook],
180
- appState: { appLaunched: true },
181
- }));
182
-
183
193
  const consoleSpy = jest.spyOn(console, "error").mockImplementation(() => {});
184
194
 
195
+ // const renderContextConsumer = (_store = store) => {
196
+ // return renderWithProviders(<ContextConsumer />, _store);
197
+ // };
198
+
199
+ const renderContextConsumer = (_store = store) => {
200
+ return create(
201
+ <Provider store={store}>
202
+ <NavigationProvider>
203
+ <ContextConsumer />
204
+ </NavigationProvider>
205
+ </Provider>
206
+ );
207
+ };
208
+
185
209
  afterAll(() => {
186
210
  consoleSpy.mockReset();
187
211
  });
@@ -189,86 +213,39 @@ afterAll(() => {
189
213
  describe("<NavigationProvider />", () => {
190
214
  let wrapper;
191
215
 
192
- it("renders correctly", () => {
216
+ it("navigator contains expected properties", () => {
193
217
  act(() => {
194
- wrapper = create(
195
- <Provider store={store}>
196
- <NavigationProvider>
197
- <ContextConsumer />
198
- </NavigationProvider>
199
- </Provider>
200
- );
218
+ wrapper = renderContextConsumer();
201
219
  });
202
220
 
203
- expect(wrapper.toJSON()).toMatchSnapshot();
204
- });
221
+ const view = getByTestId(wrapper, "WrapperView");
205
222
 
206
- describe("navigator Properties", () => {
207
- act(() => {
208
- wrapper = create(
209
- <Provider store={store}>
210
- <NavigationProvider>
211
- <ContextConsumer />
212
- </NavigationProvider>
213
- </Provider>
214
- );
215
- });
216
-
217
- const view = wrapper.root.findByType(View);
218
223
  const { navigator } = view.props;
224
+ expect(navigator.activeRiver).toEqual(rivers.B4567);
225
+ expect(navigator.currentRoute).toEqual("/river/B4567");
226
+ expect(navigator.previousAction).toEqual("REPLACE");
219
227
 
220
- it("exposes the active river", () => {
221
- expect(navigator.activeRiver).toEqual(rivers.B4567);
222
- });
223
-
224
- it("exposes the currentRoute", () => {
225
- expect(navigator.currentRoute).toEqual("/river/B4567");
228
+ expect(navigator.screenData).toEqual({
229
+ ...rivers.B4567,
230
+ targetScreen: rivers.B4567,
226
231
  });
227
232
 
228
- it("exposes the previous action", () => {
229
- expect(navigator.previousAction).toEqual("REPLACE");
230
- });
231
-
232
- it("exposes the screen data", () => {
233
- expect(navigator.screenData).toEqual(rivers.B4567);
234
- });
235
-
236
- it("exposes a routeData function", () => {
237
- const consoleSpy = jest
238
- .spyOn(console, "warn")
239
- .mockImplementation(jest.fn());
240
-
241
- expect(navigator.routeData()).toEqual(rivers.B4567);
242
- consoleSpy.mockRestore();
243
- });
244
-
245
- it("warns in the console when calling navigator.routeData()", () => {
246
- const consoleSpy = jest
247
- .spyOn(console, "warn")
248
- .mockImplementation(jest.fn());
249
-
250
- navigator.routeData();
251
- expect(consoleSpy.mock.calls).toMatchSnapshot();
252
-
253
- consoleSpy.mockRestore();
233
+ expect(navigator.routeData()).toEqual({
234
+ ...rivers.B4567,
235
+ targetScreen: rivers.B4567,
254
236
  });
255
237
  });
256
238
 
257
239
  describe("pushing a new route", () => {
258
240
  act(() => {
259
- wrapper = create(
260
- <Provider store={store}>
261
- <NavigationProvider>
262
- <ContextConsumer />
263
- </NavigationProvider>
264
- </Provider>
265
- );
241
+ wrapper = renderContextConsumer();
266
242
  });
267
243
 
268
- const view = wrapper.root.findByType(View);
244
+ it("sets the data to that route", async () => {
245
+ const view = getByTestId(wrapper, "WrapperView");
269
246
 
270
- it("sets the data to that route", () => {
271
247
  act(() => view.props.navigator.push(rivers.A1234));
248
+
272
249
  expect(view.props.navigator).toHaveProperty("activeRiver", rivers.A1234);
273
250
 
274
251
  expect(view.props.navigator).toHaveProperty(
@@ -276,23 +253,21 @@ describe("<NavigationProvider />", () => {
276
253
  "/river/B4567/river/A1234"
277
254
  );
278
255
 
279
- expect(view.props.navigator.screenData).toEqual(rivers.A1234);
280
- expect(view.props.state.stack.mainStack).toBeArrayOfSize(2);
256
+ expect(view.props.navigator.screenData).toEqual({
257
+ ...rivers.A1234,
258
+ targetScreen: rivers.A1234,
259
+ });
260
+
261
+ expect(view.props.state.stack.mainStack).toHaveLength(2);
281
262
  });
282
263
  });
283
264
 
284
265
  describe("replacing a current route", () => {
285
266
  act(() => {
286
- wrapper = create(
287
- <Provider store={store}>
288
- <NavigationProvider>
289
- <ContextConsumer />
290
- </NavigationProvider>
291
- </Provider>
292
- );
267
+ wrapper = renderContextConsumer();
293
268
  });
294
269
 
295
- const view = wrapper.root.findByType(View);
270
+ const view = getByTestId(wrapper, "WrapperView");
296
271
 
297
272
  it("sets the data to that route", () => {
298
273
  act(() => view.props.navigator.replace(rivers.A1234));
@@ -303,24 +278,22 @@ describe("<NavigationProvider />", () => {
303
278
  "/river/A1234"
304
279
  );
305
280
 
306
- expect(view.props.navigator.screenData).toEqual(rivers.A1234);
307
- expect(view.props.state.stack.mainStack).toBeArrayOfSize(1);
281
+ expect(view.props.navigator.screenData).toEqual({
282
+ ...rivers.A1234,
283
+ targetScreen: rivers.A1234,
284
+ });
285
+
286
+ expect(view.props.state.stack.mainStack).toHaveLength(1);
308
287
  });
309
288
  });
310
289
 
311
290
  describe("going back", () => {
312
291
  describe("when there is no previous route", () => {
313
292
  act(() => {
314
- wrapper = create(
315
- <Provider store={store}>
316
- <NavigationProvider>
317
- <ContextConsumer />
318
- </NavigationProvider>
319
- </Provider>
320
- );
293
+ wrapper = renderContextConsumer();
321
294
  });
322
295
 
323
- const view = wrapper.root.findByType(View);
296
+ const view = getByTestId(wrapper, "WrapperView");
324
297
 
325
298
  it("returns false when calling canGoBack", () => {
326
299
  let result;
@@ -345,23 +318,21 @@ describe("<NavigationProvider />", () => {
345
318
  "/river/B4567"
346
319
  );
347
320
 
348
- expect(view.props.navigator.screenData).toEqual(rivers.B4567);
349
- expect(view.props.state.stack.mainStack).toBeArrayOfSize(1);
321
+ expect(view.props.navigator.screenData).toEqual({
322
+ ...rivers.B4567,
323
+ targetScreen: rivers.B4567,
324
+ });
325
+
326
+ expect(view.props.state.stack.mainStack).toHaveLength(1);
350
327
  });
351
328
  });
352
329
 
353
330
  describe("when there is one route and we're going in a hook", () => {
354
331
  act(() => {
355
- wrapper = create(
356
- <Provider store={store}>
357
- <NavigationProvider>
358
- <ContextConsumer />
359
- </NavigationProvider>
360
- </Provider>
361
- );
332
+ wrapper = renderContextConsumer();
362
333
  });
363
334
 
364
- const view = wrapper.root.findByType(View);
335
+ const view = getByTestId(wrapper, "WrapperView");
365
336
  act(() => view.props.navigator.replace(rivers.A1234));
366
337
 
367
338
  it("returns true when calling goBack()", () => {
@@ -387,25 +358,20 @@ describe("<NavigationProvider />", () => {
387
358
  );
388
359
 
389
360
  expect(view.props.navigator.screenData).toEqual(rivers.A1234);
390
- expect(view.props.state.stack.mainStack).toBeArrayOfSize(1);
361
+ expect(view.props.state.stack.mainStack).toHaveLength(1);
391
362
  });
392
363
  });
393
364
 
394
365
  describe("when there is a previous route", () => {
395
366
  act(() => {
396
- wrapper = create(
397
- <Provider store={store}>
398
- <NavigationProvider>
399
- <ContextConsumer />
400
- </NavigationProvider>
401
- </Provider>
402
- );
367
+ wrapper = renderContextConsumer();
403
368
  });
404
369
 
405
- const view = wrapper.root.findByType(View);
370
+ const view = getByTestId(wrapper, "WrapperView");
406
371
 
407
372
  act(() => view.props.navigator.push(rivers.A1234));
408
- act(() => view.props.navigator.push(rivers.B4567));
373
+
374
+ act(() => view.props.navigator.push({ ...rivers.B4567, id: "B4567-1" }));
409
375
 
410
376
  it("returns true when calling canGoBack", () => {
411
377
  let result;
@@ -414,11 +380,27 @@ describe("<NavigationProvider />", () => {
414
380
  result = view.props.navigator.canGoBack();
415
381
  });
416
382
 
417
- expect(result).toBe(true);
383
+ expect(result).toBeTruthy();
384
+ });
385
+
386
+ it("returns true when calling canGoBack(false, pathname)", () => {
387
+ let result;
388
+
389
+ act(() => {
390
+ result = view.props.navigator.canGoBack(false, "B4567-1");
391
+ });
392
+
393
+ expect(result).toBeTruthy();
394
+
395
+ act(() => {
396
+ result = view.props.navigator.canGoBack(false, "A1234");
397
+ });
398
+
399
+ expect(result).toBeTruthy();
418
400
  });
419
401
 
420
402
  it("returns to the previous route", () => {
421
- expect(view.props.state.stack.mainStack).toBeArrayOfSize(3);
403
+ expect(view.props.state.stack.mainStack).toHaveLength(3);
422
404
 
423
405
  act(() => view.props.navigator.goBack());
424
406
 
@@ -432,160 +414,84 @@ describe("<NavigationProvider />", () => {
432
414
  "/river/B4567/river/A1234"
433
415
  );
434
416
 
435
- expect(view.props.navigator.screenData).toEqual(rivers.A1234);
436
- expect(view.props.state.stack.mainStack).toBeArrayOfSize(2);
417
+ expect(view.props.navigator.screenData).toEqual({
418
+ ...rivers.A1234,
419
+ targetScreen: rivers.A1234,
420
+ });
421
+
422
+ expect(view.props.state.stack.mainStack).toHaveLength(2);
437
423
  });
438
424
  });
439
425
 
440
426
  describe("when there is a previous route and there are hooks", () => {
441
427
  act(() => {
442
- wrapper = create(
443
- <Provider store={store}>
444
- <NavigationProvider>
445
- <ContextConsumer />
446
- </NavigationProvider>
447
- </Provider>
448
- );
428
+ wrapper = renderContextConsumer();
449
429
  });
450
430
 
451
- const view = wrapper.root.findByType(View);
431
+ const view = getByTestId(wrapper, "WrapperView");
452
432
  act(() => view.props.navigator.push(rivers.A1234));
453
433
  act(() => view.props.navigator.push(rivers.C0987));
454
434
 
455
435
  it("returns to the previous entry in the stack which is not a hook", () => {
456
- expect(view.props.state.stack.mainStack).toBeArrayOfSize(5);
436
+ expect(view.props.state.stack.mainStack).toHaveLength(3);
457
437
 
458
438
  expect(view.props.navigator).toHaveProperty(
459
439
  "currentRoute",
460
440
  "/river/B4567/river/A1234/river/C0987"
461
441
  );
462
442
 
463
- expect(view.props.navigator.screenData).toEqual(rivers.C0987);
443
+ expect(view.props.navigator.screenData).toMatchObject({
444
+ ...rivers.C0987,
445
+ targetScreen: rivers.C0987,
446
+ });
464
447
 
465
448
  act(() => view.props.navigator.goBack());
466
449
 
467
- expect(view.props.state.stack.mainStack).toBeArrayOfSize(2);
450
+ expect(view.props.state.stack.mainStack).toHaveLength(2);
468
451
 
469
452
  expect(view.props.navigator).toHaveProperty(
470
453
  "currentRoute",
471
454
  "/river/B4567/river/A1234"
472
455
  );
473
456
 
474
- expect(view.props.navigator.screenData).toEqual(rivers.A1234);
457
+ expect(view.props.navigator.screenData).toMatchObject({
458
+ ...rivers.A1234,
459
+ targetScreen: rivers.A1234,
460
+ });
475
461
  });
476
462
  });
477
463
  });
478
464
 
479
- describe("when changing navBar visibility", () => {
480
- act(() => {
481
- wrapper = create(
482
- <Provider store={store}>
483
- <NavigationProvider>
484
- <ContextConsumer />
485
- </NavigationProvider>
486
- </Provider>
487
- );
488
- });
489
-
490
- const view = wrapper.root.findByType(View);
491
-
492
- it("updates the navbar visibility attribute", () => {
493
- act(() => view.props.navigator.hideNavBar());
494
- expect(view.props.state.options.navBar.visible).toBe(false);
495
- expect(view.props.navigator.isNavBarVisible).toBe(false);
496
- });
497
- });
498
-
499
- describe("set the navbar title", () => {
500
- act(() => {
501
- wrapper = create(
502
- <Provider store={store}>
503
- <NavigationProvider>
504
- <ContextConsumer />
505
- </NavigationProvider>
506
- </Provider>
507
- );
508
- });
509
-
510
- const view = wrapper.root.findByType(View);
511
-
512
- it("updates the navbar title attribute", () => {
513
- const screenTitle = "Screen Title";
514
- act(() => view.props.navigator.setScreenTitle(screenTitle));
515
- expect(view.props.state.options.navBar.title).toBe(screenTitle);
516
- expect(view.props.navigator.screenTitle).toBe(screenTitle);
517
- });
518
- });
519
-
520
- describe("set the navbar summary", () => {
521
- act(() => {
522
- wrapper = create(
523
- <Provider store={store}>
524
- <NavigationProvider>
525
- <ContextConsumer />
526
- </NavigationProvider>
527
- </Provider>
528
- );
529
- });
530
-
531
- const view = wrapper.root.findByType(View);
532
-
533
- it("updates the navbar summary attribute", () => {
534
- const screenSummary = "Screen Summary";
535
- act(() => view.props.navigator.setScreenSummary(screenSummary));
536
- expect(view.props.state.options.navBar.summary).toBe(screenSummary);
537
- expect(view.props.navigator.screenSummary).toBe(screenSummary);
538
- });
539
- });
540
-
541
- describe.only("modal feature", () => {
465
+ describe("modal feature", () => {
542
466
  it("sets the modalState when opening a modal", () => {
543
467
  act(() => {
544
- wrapper = create(
545
- <Provider store={store}>
546
- <NavigationProvider>
547
- <ContextConsumer />
548
- </NavigationProvider>
549
- </Provider>
550
- );
468
+ wrapper = renderContextConsumer();
551
469
  });
552
470
 
553
- const view = wrapper.root.findByType(View);
471
+ const view = getByTestId(wrapper, "WrapperView");
554
472
  act(() => view.props.navigator.openModal({ item: rivers.A1234 }));
555
- expect(view.props.navigator.modalState).toMatchSnapshot();
473
+ expect(view.props.navigator.get).toMatchSnapshot();
556
474
  });
557
475
 
558
476
  it("removes the visible flag when dismissing a modal", () => {
559
477
  act(() => {
560
- wrapper = create(
561
- <Provider store={store}>
562
- <NavigationProvider>
563
- <ContextConsumer />
564
- </NavigationProvider>
565
- </Provider>
566
- );
478
+ wrapper = renderContextConsumer();
567
479
  });
568
480
 
569
- const view = wrapper.root.findByType(View);
481
+ const view = getByTestId(wrapper, "WrapperView");
570
482
  act(() => view.props.navigator.openModal({ item: rivers.A1234 }));
571
- expect(view.props.navigator.modalState).toMatchSnapshot();
483
+ expect(view.props.navigator.getModalState()).toMatchSnapshot();
572
484
  act(() => view.props.navigator.dismissModal());
573
- expect(view.props.navigator.modalState.visible).toBeFalsy();
574
- expect(view.props.navigator.modalState).toMatchSnapshot();
485
+ expect(view.props.navigator.getModalState().visible).toBeFalsy();
486
+ expect(view.props.navigator.getModalState()).toMatchSnapshot();
575
487
  });
576
488
 
577
489
  it("should reset state to initial when dismissing a modal ( closeModalBottomSheet ) opened by openModalBottomSheet", () => {
578
490
  act(() => {
579
- wrapper = create(
580
- <Provider store={store}>
581
- <NavigationProvider>
582
- <ContextConsumer />
583
- </NavigationProvider>
584
- </Provider>
585
- );
491
+ wrapper = renderContextConsumer();
586
492
  });
587
493
 
588
- const view = wrapper.root.findByType(View);
494
+ const view = getByTestId(wrapper, "WrapperView");
589
495
 
590
496
  act(() =>
591
497
  view.props.navigator.openModalBottomSheet({
@@ -594,9 +500,9 @@ describe("<NavigationProvider />", () => {
594
500
  })
595
501
  );
596
502
 
597
- expect(view.props.navigator.modalState).toMatchSnapshot();
503
+ expect(view.props.navigator.getModalState()).toMatchSnapshot();
598
504
  act(() => view.props.navigator.closeModalBottomSheet());
599
- expect(view.props.navigator.modalState).toMatchSnapshot();
505
+ expect(view.props.navigator.getModalState()).toMatchSnapshot();
600
506
  });
601
507
  });
602
508
  });
@@ -1,13 +1,19 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`<RouteManager /> renders correctly 1`] = `
4
- <WithProvider
5
- screenData={
6
- Object {
7
- "id": "A1234",
8
- }
4
+ <RNCSafeAreaProvider
5
+ onInsetsChange={[Function]}
6
+ style={
7
+ Array [
8
+ Object {
9
+ "flex": 1,
10
+ },
11
+ undefined,
12
+ ]
9
13
  }
10
- screenId="A1234"
11
- screenType="river"
12
- />
14
+ >
15
+ <View
16
+ testID="river"
17
+ />
18
+ </RNCSafeAreaProvider>
13
19
  `;
@@ -1,31 +1,42 @@
1
1
  import React from "react";
2
- import { shallow } from "enzyme";
3
- import { shallowToJson } from "enzyme-to-json";
4
2
 
5
- import { ScreenResolver } from "@applicaster/zapp-react-native-ui-components/Components/ScreenResolver";
3
+ const {
4
+ ScreenResolver,
5
+ } = require("@applicaster/zapp-react-native-ui-components/Components/ScreenResolver");
6
+
7
+ import { renderWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
6
8
 
7
9
  jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
8
10
  useNavigation: jest.fn(() => ({
9
11
  screenId: { id: "A1234" },
10
12
  currentRoute: "/river/A1234",
11
13
  screenData: { id: "A1234" },
14
+ videoModalState: { mode: "WINDOWED" },
15
+ })),
16
+ useRoute: jest.fn(() => ({
17
+ pathname: "/river/A1234",
18
+ screenData: { id: "A1234-screenData" },
12
19
  })),
13
20
  }));
14
21
 
15
22
  const { RouteManager } = require("../");
16
23
 
17
24
  describe("<RouteManager />", () => {
18
- const wrapper = shallow(<RouteManager />);
25
+ let wrapper;
26
+
27
+ beforeEach(() => {
28
+ wrapper = renderWithProviders(<RouteManager />);
29
+ });
19
30
 
20
31
  it("renders correctly", () => {
21
- expect(shallowToJson(wrapper)).toMatchSnapshot();
32
+ expect(wrapper.toJSON()).toMatchSnapshot();
22
33
  });
23
34
 
24
35
  it("passes the correct props to ScreenResolver", () => {
25
- expect(wrapper.find(ScreenResolver).props()).toEqual({
36
+ expect(wrapper.UNSAFE_getByType(ScreenResolver).props).toEqual({
26
37
  screenType: "river",
27
38
  screenId: "A1234",
28
- screenData: { id: "A1234" },
39
+ screenData: { id: "A1234-screenData" },
29
40
  });
30
41
  });
31
42
  });
@@ -4,7 +4,7 @@ import * as R from "ramda";
4
4
  import { getPathAttributes } from "@applicaster/zapp-react-native-utils/navigationUtils";
5
5
  import { ScreenResolver } from "@applicaster/zapp-react-native-ui-components/Components/ScreenResolver";
6
6
 
7
- import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
7
+ import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
8
8
 
9
9
  type Props = any;
10
10
 
@@ -14,7 +14,8 @@ type Props = any;
14
14
  * @param {Props}: see props above
15
15
  */
16
16
  export const RouteManager = React.memo(function RouteManager(props: Props) {
17
- const { currentRoute: pathname, screenData } = useNavigation();
17
+ const { pathname, screenData } = useRoute();
18
+
18
19
  const pathAttributes = getPathAttributes({ pathname });
19
20
 
20
21
  if (!pathAttributes.length) {
@@ -15,6 +15,11 @@ jest.mock(
15
15
  // This is meant to silence errors with react-native-gesture-handler
16
16
  jest.mock("../ModalProvider/ModalBottomSheet", () => () => null);
17
17
 
18
+ jest.mock(
19
+ "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation",
20
+ () => () => null
21
+ );
22
+
18
23
  jest.mock("react-native-safe-area-context", () => ({
19
24
  SafeAreaProvider: jest.fn(
20
25
  () =>
@@ -27,6 +27,7 @@ Object {
27
27
  "AppContainer": [Function],
28
28
  "ContentScreen": [Function],
29
29
  "HookRenderer": [Function],
30
+ "ModalComponent": [Function],
30
31
  "PlayerContainer": Object {
31
32
  "$$typeof": Symbol(react.memo),
32
33
  "WrappedComponent": Object {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/quick-brick-core",
3
- "version": "12.0.0-alpha.5114122134",
3
+ "version": "12.0.0-alpha.5208030571",
4
4
  "description": "Core package for Applicaster's Quick Brick App",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -30,15 +30,15 @@
30
30
  },
31
31
  "homepage": "https://github.com/applicaster/quickbrick#readme",
32
32
  "dependencies": {
33
- "@applicaster/applicaster-types": "12.0.0-alpha.5114122134",
34
- "@applicaster/quick-brick-core-plugins": "12.0.0-alpha.5114122134",
35
- "@applicaster/zapp-pipes-v2-client": "12.0.0-alpha.5114122134",
36
- "@applicaster/zapp-react-native-bridge": "12.0.0-alpha.5114122134",
37
- "@applicaster/zapp-react-native-redux": "12.0.0-alpha.5114122134",
38
- "@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.5114122134",
39
- "@applicaster/zapp-react-native-utils": "12.0.0-alpha.5114122134",
33
+ "@applicaster/applicaster-types": "12.0.0-alpha.5208030571",
34
+ "@applicaster/quick-brick-core-plugins": "12.0.0-alpha.5208030571",
35
+ "@applicaster/zapp-pipes-v2-client": "12.0.0-alpha.5208030571",
36
+ "@applicaster/zapp-react-native-bridge": "12.0.0-alpha.5208030571",
37
+ "@applicaster/zapp-react-native-redux": "12.0.0-alpha.5208030571",
38
+ "@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.5208030571",
39
+ "@applicaster/zapp-react-native-utils": "12.0.0-alpha.5208030571",
40
40
  "atob": "^2.1.2",
41
- "axios": "^0.21.2",
41
+ "axios": "^0.28.0",
42
42
  "btoa": "^1.2.1",
43
43
  "camelize": "^1.0.0",
44
44
  "md5": "^2.3.0",