@applicaster/zapp-react-native-ui-components 13.0.0-alpha.5033140607 → 13.0.0-alpha.5144285042

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 (179) hide show
  1. package/Components/AppContainer/__tests__/AppContainer.test.js +4 -6
  2. package/Components/AppContainer/__tests__/__snapshots__/AppContainer.test.js.snap +1 -1
  3. package/Components/AudioPlayer/__tests__/Runtime.test.js +5 -8
  4. package/Components/AudioPlayer/__tests__/__snapshots__/Runtime.test.js.snap +4 -4
  5. package/Components/AudioPlayer/__tests__/__snapshots__/artWork.test.js.snap +3 -3
  6. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +56 -113
  7. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayerLayout.test.js.snap +39 -23
  8. package/Components/AudioPlayer/__tests__/__snapshots__/channel.test.js.snap +3 -3
  9. package/Components/AudioPlayer/__tests__/__snapshots__/summary.test.js.snap +2 -2
  10. package/Components/AudioPlayer/__tests__/__snapshots__/title.test.js.snap +2 -2
  11. package/Components/AudioPlayer/__tests__/artWork.test.js +3 -5
  12. package/Components/AudioPlayer/__tests__/audioPlayer.test.js +3 -5
  13. package/Components/AudioPlayer/__tests__/audioPlayerLayout.test.js +7 -8
  14. package/Components/AudioPlayer/__tests__/channel.test.js +3 -5
  15. package/Components/AudioPlayer/__tests__/summary.test.js +3 -5
  16. package/Components/AudioPlayer/__tests__/title.test.js +3 -5
  17. package/Components/BaseFocusable/index.ios.ts +1 -1
  18. package/Components/BaseFocusable/index.tsx +67 -31
  19. package/Components/Cell/Cell.tsx +15 -9
  20. package/Components/Cell/CellWithFocusable.tsx +44 -59
  21. package/Components/Cell/TvOSCellComponent.tsx +23 -30
  22. package/Components/Cell/__tests__/CellWIthFocusable.test.js +13 -6
  23. package/Components/Cell/index.js +3 -1
  24. package/Components/CellRendererResolver/__tests__/cellRendererResolver.test.js +50 -50
  25. package/Components/ComponentResolver/__tests__/__snapshots__/componentResolver.test.js.snap +1 -42
  26. package/Components/ComponentResolver/__tests__/componentResolver.test.js +26 -30
  27. package/Components/ContentScreen/__tests__/contentScreen.test.js +3 -3
  28. package/Components/DisplayState/__tests__/__snapshots__/displayState.test.js.snap +2 -2
  29. package/Components/ErrorScreen/index.tsx +6 -6
  30. package/Components/Focusable/Focusable.tsx +1 -54
  31. package/Components/Focusable/FocusableTvOS.tsx +6 -2
  32. package/Components/Focusable/Touchable.tsx +19 -20
  33. package/Components/Focusable/index.android.tsx +10 -3
  34. package/Components/FocusableGroup/FocusableTvOS.tsx +34 -83
  35. package/Components/FocusableGroup/index.tsx +1 -3
  36. package/Components/FocusableList/index.tsx +26 -10
  37. package/Components/FocusableScrollView/index.tsx +43 -13
  38. package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +76 -7
  39. package/Components/GeneralContentScreen/utils/useCurationAPI.ts +53 -9
  40. package/Components/Layout/TV/NavBarContainer.tsx +19 -23
  41. package/Components/Layout/TV/ScreenContainer.tsx +8 -1
  42. package/Components/Layout/TV/ScreenLayoutContextProvider.tsx +5 -0
  43. package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +3 -1
  44. package/Components/Layout/TV/__tests__/__snapshots__/LayoutContainer.test.tsx.snap +1 -1
  45. package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +6 -5
  46. package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +12 -11
  47. package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +1 -1
  48. package/Components/Layout/TV/__tests__/index.test.tsx +7 -3
  49. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -3
  50. package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx +66 -0
  51. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +4 -1
  52. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +6 -12
  53. package/Components/MasterCell/DefaultComponents/ImageBorderContainer/__tests__/index.test.ts +93 -0
  54. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -2
  55. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/__snapshots__/Image.test.tsx.snap +3 -3
  56. package/Components/MasterCell/DefaultComponents/SecondaryImage/utils.ts +1 -1
  57. package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
  58. package/Components/MasterCell/SharedUI/CollapsibleTextContainer/__tests__/__snapshots__/index.test.tsx.snap +1 -1
  59. package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +2 -8
  60. package/Components/MasterCell/__tests__/__snapshots__/dataAdapter.test.js.snap +180 -180
  61. package/Components/MasterCell/__tests__/__snapshots__/elementMapper.test.js.snap +11 -19
  62. package/Components/MasterCell/__tests__/__snapshots__/masterCell.test.js.snap +6 -235
  63. package/Components/MasterCell/__tests__/elementMapper.test.js +18 -5
  64. package/Components/MasterCell/__tests__/masterCell.test.js +26 -26
  65. package/Components/MasterCell/hooks/useAsyncRendering/MasterCellAsyncRenderManager.ts +2 -2
  66. package/Components/MasterCell/hooks/useAsyncRendering/index.ts +2 -2
  67. package/Components/MasterCell/utils/behaviorProvider.ts +133 -0
  68. package/Components/MasterCell/utils/index.ts +4 -130
  69. package/Components/ModalComponent/Button/index.tsx +6 -6
  70. package/Components/ModalComponent/Header/index.tsx +3 -3
  71. package/Components/NativeFocusables/{index.js → index.ts} +4 -2
  72. package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +2 -2
  73. package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +2 -2
  74. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +0 -5
  75. package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +7 -7
  76. package/Components/OfflineHandler/__tests__/index.test.tsx +28 -25
  77. package/Components/PlayerContainer/PlayerContainer.tsx +13 -19
  78. package/Components/PlayerContainer/PlayerContainerContext.tsx +9 -0
  79. package/Components/PlayerContainer/ProgramInfo/index.tsx +2 -2
  80. package/Components/PlayerImageBackground/index.tsx +23 -3
  81. package/Components/River/ComponentsMap/ComponentsMap.tsx +39 -65
  82. package/Components/River/ComponentsMap/hooks/useLoadingState.ts +78 -51
  83. package/Components/River/RefreshControl.tsx +1 -1
  84. package/Components/River/RiverFooter.tsx +39 -9
  85. package/Components/River/RiverItem.tsx +37 -2
  86. package/Components/River/TV/index.tsx +6 -1
  87. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +114 -45
  88. package/Components/River/__tests__/__snapshots__/river.test.js.snap +21 -83
  89. package/Components/River/__tests__/componentsMap.test.js +64 -17
  90. package/Components/River/__tests__/river.test.js +75 -40
  91. package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +12 -5
  92. package/Components/RouteManager/__tests__/routeManager.test.js +29 -14
  93. package/Components/RouteManager/__tests__/testId.test.js +8 -6
  94. package/Components/Screen/__tests__/Screen.test.tsx +41 -27
  95. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +4 -4
  96. package/Components/Screen/hooks.ts +56 -0
  97. package/Components/Screen/index.tsx +16 -42
  98. package/Components/ScreenResolver/__tests__/screenResolver.test.js +95 -70
  99. package/Components/Tabs/Tab.tsx +12 -9
  100. package/Components/TextInputTv/__tests__/TextInputTv.test.js +42 -42
  101. package/Components/TextInputTv/__tests__/__snapshots__/TextInputTv.test.js.snap +7 -0
  102. package/Components/TextInputTv/index.tsx +6 -5
  103. package/Components/Touchable/__tests__/__snapshots__/touchable.test.tsx.snap +2 -2
  104. package/Components/TrackedView/index.tsx +1 -0
  105. package/Components/Transitioner/AnimationManager.js +15 -15
  106. package/Components/Transitioner/Scene.tsx +53 -24
  107. package/Components/Transitioner/Transitioner.tsx +3 -3
  108. package/Components/Transitioner/__tests__/Scene.test.js +25 -14
  109. package/Components/Transitioner/__tests__/__snapshots__/AnimationManager.test.js.snap +26 -26
  110. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +10 -50
  111. package/Components/Transitioner/__tests__/__snapshots__/config.test.js.snap +20 -20
  112. package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +4 -4
  113. package/Components/Transitioner/__tests__/transitioner.test.js +13 -4
  114. package/Components/Transitioner/index.js +8 -4
  115. package/Components/VideoLive/LiveImageManager.ts +27 -1
  116. package/Components/VideoLive/PlayerLiveImageComponent.tsx +36 -24
  117. package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +63 -8
  118. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +6 -10
  119. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +16 -12
  120. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +5 -1
  121. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +15 -14
  122. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +6 -13
  123. package/Components/VideoModal/ModalAnimation/index.ts +2 -1
  124. package/Components/VideoModal/ModalAnimation/useModalAnimationContext.ts +6 -0
  125. package/Components/VideoModal/ModalAnimation/utils.ts +2 -2
  126. package/Components/VideoModal/OpaqueLayer.tsx +33 -0
  127. package/Components/VideoModal/PlayerDetails.tsx +9 -6
  128. package/Components/VideoModal/PlayerWrapper.tsx +17 -36
  129. package/Components/VideoModal/VideoModal.tsx +14 -23
  130. package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +5 -2
  131. package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +13 -10
  132. package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +4 -4
  133. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +66 -156
  134. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +89 -0
  135. package/Components/VideoModal/hooks/index.ts +7 -0
  136. package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +49 -0
  137. package/Components/VideoModal/hooks/utils/__tests__/showDetails.test.ts +91 -0
  138. package/Components/VideoModal/hooks/utils/index.ts +33 -0
  139. package/Components/VideoModal/utils.ts +3 -5
  140. package/Components/Viewport/ViewportAware/__tests__/__snapshots__/viewportAware.test.js.snap +24 -36
  141. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -18
  142. package/Components/Viewport/ViewportTracker/__tests__/__snapshots__/viewportTracker.test.js.snap +1 -1
  143. package/Components/Viewport/__tests__/utils.test.js +5 -4
  144. package/Components/ZappUIComponent/Placeholder.tsx +3 -1
  145. package/Components/ZappUIComponent/__tests__/{ZappUIComponent.test.js → ZappUIComponent.test.tsx} +26 -10
  146. package/Components/ZappUIComponent/index.tsx +3 -16
  147. package/Components/default-cell-renderer/__tests__/defaultCellRenderer.test.tsx +20 -17
  148. package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/__tests__/DefaultCell.test.tsx +15 -11
  149. package/Contexts/ComponentsMapOffsetContext/index.tsx +49 -0
  150. package/Contexts/ConfigutaionContext/__tests__/__snapshots__/ConfigurationProvider.test.tsx.snap +1 -1
  151. package/Contexts/FocusableGroupContext/withFocusableContext.tsx +4 -10
  152. package/Contexts/HeaderOffsetContext/index.tsx +4 -6
  153. package/Contexts/ScreenContext/index.tsx +6 -12
  154. package/Contexts/ScreenLayoutContext/index.tsx +5 -3
  155. package/Decorators/Analytics/{index.js → index.tsx} +11 -11
  156. package/Decorators/Navigator/__tests__/navigator.test.js +16 -16
  157. package/Decorators/Navigator/index.tsx +1 -1
  158. package/Decorators/RiverFeedLoader/__tests__/__snapshots__/riverFeedLoader.test.tsx.snap +77 -77
  159. package/Decorators/RiverFeedLoader/__tests__/riverFeedLoader.test.tsx +34 -39
  160. package/Decorators/RiverFeedLoader/__tests__/utils.test.ts +0 -9
  161. package/Decorators/RiverFeedLoader/index.tsx +1 -1
  162. package/Decorators/RiverFeedLoader/utils/getDatasourceUrl.ts +39 -0
  163. package/Decorators/RiverFeedLoader/utils/index.ts +29 -0
  164. package/Decorators/RiverFeedLoader/utils/usePipesContexts.ts +40 -0
  165. package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +27 -27
  166. package/Decorators/RiverResolver/index.tsx +6 -8
  167. package/Decorators/ZappPipesDataConnector/__tests__/Hero.js +1 -1
  168. package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +29 -22
  169. package/Decorators/ZappPipesDataConnector/index.tsx +5 -2
  170. package/package.json +13 -10
  171. package/tsconfig.json +2 -3
  172. package/Components/CellRendererResolver/__tests__/__snapshots__/cellRendererResolver.test.js.snap +0 -53
  173. package/Components/RouteManager/__tests__/__snapshots__/testId.test.js.snap +0 -17
  174. package/Components/ScreenResolver/__tests__/__snapshots__/screenResolver.test.js.snap +0 -17
  175. package/Components/ZappUIComponent/__tests__/__snapshots__/ZappUIComponent.test.js.snap +0 -91
  176. package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +0 -338
  177. package/Decorators/Navigator/__tests__/__snapshots__/navigator.test.js.snap +0 -18
  178. package/Decorators/RiverFeedLoader/utils.ts +0 -100
  179. package/Decorators/RiverResolver/__tests__/__snapshots__/riverResolver.test.tsx.snap +0 -28
@@ -1,31 +1,46 @@
1
1
  import React from "react";
2
- import { shallow } from "enzyme";
3
- import { shallowToJson } from "enzyme-to-json";
2
+ import { render } from "@testing-library/react-native";
4
3
 
5
- const pathname = "/river/A1234";
6
- const screenData = { id: "A1234" };
4
+ import { RouteManager } from "../";
5
+
6
+ const mockPathname = "/river/A1234";
7
+ const mockScreenData = { id: "A1234" };
7
8
 
8
9
  jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
9
- useRoute: jest.fn(() => ({ pathname: pathname, screenData: screenData })),
10
+ useRoute: jest.fn(() => ({
11
+ pathname: mockPathname,
12
+ screenData: mockScreenData,
13
+ })),
10
14
  }));
11
15
 
12
- const {
13
- ScreenResolver,
14
- } = require("@applicaster/zapp-react-native-ui-components/Components/ScreenResolver");
16
+ jest.mock(
17
+ "@applicaster/zapp-react-native-ui-components/Components/ScreenResolver",
18
+ () => {
19
+ const { View } = jest.requireActual("react-native");
15
20
 
16
- const { RouteManager } = require("../index");
21
+ return {
22
+ ScreenResolver: (props) => <View testID="screen-resolver" {...props} />,
23
+ };
24
+ }
25
+ );
17
26
 
18
27
  describe("<RouteManager />", () => {
19
- const wrapper = shallow(
20
- <RouteManager pathname={pathname} screenData={screenData} />
21
- );
28
+ let wrapper;
29
+
30
+ beforeEach(() => {
31
+ jest.clearAllMocks();
32
+
33
+ wrapper = render(
34
+ <RouteManager pathname={mockPathname} screenData={mockScreenData} />
35
+ );
36
+ });
22
37
 
23
38
  it("renders correctly", () => {
24
- expect(shallowToJson(wrapper)).toMatchSnapshot();
39
+ expect(wrapper.toJSON()).toMatchSnapshot();
25
40
  });
26
41
 
27
42
  it("passes the correct props to ScreenResolver", () => {
28
- expect(wrapper.find(ScreenResolver).props()).toEqual({
43
+ expect(wrapper.getByTestId("screen-resolver").props).toMatchObject({
29
44
  pathname: "/river/A1234",
30
45
  screenType: "river",
31
46
  screenId: "A1234",
@@ -2,8 +2,8 @@
2
2
  /* eslint-disable react/prop-types */
3
3
  import React from "react";
4
4
  import { View, Text } from "react-native";
5
- import { shallow } from "enzyme";
6
- import { shallowToJson } from "enzyme-to-json";
5
+
6
+ import { render } from "@testing-library/react-native";
7
7
 
8
8
  import { TestId } from "../TestId";
9
9
 
@@ -17,14 +17,16 @@ const screenId = "A1234";
17
17
 
18
18
  describe("TestId", () => {
19
19
  it("renders correctly and assigns the testID to a wrapping view", () => {
20
- const wrapper = shallow(
20
+ const wrapper = render(
21
21
  <TestId screenId={screenId}>
22
22
  <TestComponent name="dev test" />
23
23
  </TestId>
24
24
  );
25
25
 
26
- expect(shallowToJson(wrapper)).toMatchSnapshot();
27
- expect(wrapper.find(View).prop("testID")).toEqual(screenId);
28
- expect(wrapper.find(View).prop("accessibilityLabel")).toEqual(screenId);
26
+ expect(wrapper.getByTestId(screenId)).toBeTruthy();
27
+
28
+ expect(wrapper.getByTestId(screenId).props.accessibilityLabel).toEqual(
29
+ screenId
30
+ );
29
31
  });
30
32
  });
@@ -46,27 +46,37 @@ jest.mock("@applicaster/zapp-react-native-utils/theme", () => ({
46
46
  })),
47
47
  }));
48
48
 
49
- const NavBar = jest.fn((props) => <View testID="navBar" {...props} />);
49
+ const mockNavBar = jest.fn((props) => {
50
+ const View = jest.requireActual("react-native").View;
51
+
52
+ return <View testID="navBar" {...props} />;
53
+ });
50
54
 
51
55
  jest.mock(
52
56
  "@applicaster/zapp-react-native-app/App/Layout/layoutHelpers",
53
57
  () => ({
54
- getNavigationPluginModule: () => NavBar,
58
+ getNavigationPluginModule: () => mockNavBar,
55
59
  })
56
60
  );
57
61
 
58
- jest.mock("@applicaster/zapp-react-native-utils/reactHooks/screen", () => ({
59
- ...(jest.requireActual(
60
- "@applicaster/zapp-react-native-utils/reactHooks/screen"
61
- ) as any),
62
- useScreenData: jest.fn(() => ({
63
- id: "testId",
64
- navigations: [{ id: "testId", category: "nav_bar" }],
65
- })),
66
- useCurrentScreenData: jest.fn(() => ({
67
- id: "testId",
68
- })),
69
- }));
62
+ jest.mock(
63
+ "@applicaster/zapp-react-native-utils/reactHooks/screen/useCurrentScreenData",
64
+ () => ({
65
+ useCurrentScreenData: jest.fn(() => ({
66
+ id: "testId",
67
+ })),
68
+ })
69
+ );
70
+
71
+ jest.mock(
72
+ "@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenData",
73
+ () => ({
74
+ useScreenData: jest.fn(() => ({
75
+ id: "testId",
76
+ navigations: [{ id: "testId", category: "nav_bar" }],
77
+ })),
78
+ })
79
+ );
70
80
 
71
81
  jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
72
82
  isNavBarVisible: mockIsNavBarVisible,
@@ -84,20 +94,24 @@ jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation", () => ({
84
94
  useIsScreenActive: jest.fn().mockReturnValue(true),
85
95
  }));
86
96
 
87
- jest.mock("@applicaster/zapp-react-native-redux/hooks", () => ({
88
- usePickFromState: () => ({
89
- plugins: [
90
- {
91
- name: "Offline Plugin",
92
- identifier: "offline-experience",
93
- type: "general",
94
- module: {
95
- OfflineFallbackScreen: ({ children }) => <View>{children}</View>, // eslint-disable-line
97
+ jest.mock("@applicaster/zapp-react-native-redux/hooks/usePickFromState", () => {
98
+ const View = jest.requireActual("react-native").View;
99
+
100
+ return {
101
+ usePickFromState: () => ({
102
+ plugins: [
103
+ {
104
+ name: "Offline Plugin",
105
+ identifier: "offline-experience",
106
+ type: "general",
107
+ module: {
108
+ OfflineFallbackScreen: ({ children }) => <View>{children}</View>, // eslint-disable-line
109
+ },
96
110
  },
97
- },
98
- ],
99
- }),
100
- }));
111
+ ],
112
+ }),
113
+ };
114
+ });
101
115
 
102
116
  const {
103
117
  allowedOrientationsForScreen,
@@ -3,7 +3,7 @@
3
3
  exports[`<Screen Component /> when the navbar should be hidden renders correctly 1`] = `
4
4
  <View
5
5
  style={
6
- Object {
6
+ {
7
7
  "backgroundColor": "blue",
8
8
  "flex": 1,
9
9
  "paddingTop": 0,
@@ -22,7 +22,7 @@ exports[`<Screen Component /> when the navbar should be hidden renders correctly
22
22
  <View
23
23
  pathname="/river/testId"
24
24
  screenData={
25
- Object {
25
+ {
26
26
  "id": "testId",
27
27
  }
28
28
  }
@@ -35,7 +35,7 @@ exports[`<Screen Component /> when the navbar should be hidden renders correctly
35
35
  exports[`<Screen Component /> when the navbar should show renders correctly 1`] = `
36
36
  <View
37
37
  style={
38
- Object {
38
+ {
39
39
  "backgroundColor": "blue",
40
40
  "flex": 1,
41
41
  "paddingTop": 0,
@@ -54,7 +54,7 @@ exports[`<Screen Component /> when the navbar should show renders correctly 1`]
54
54
  <View
55
55
  pathname="/river/testId"
56
56
  screenData={
57
- Object {
57
+ {
58
58
  "id": "testId",
59
59
  }
60
60
  }
@@ -0,0 +1,56 @@
1
+ import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
2
+ import {
3
+ useGetScreenOrientation,
4
+ isOrientationCompatible,
5
+ } from "@applicaster/zapp-react-native-utils/appUtils/orientationHelper";
6
+ import {
7
+ useCurrentScreenData,
8
+ useDimensions,
9
+ useRoute,
10
+ } from "@applicaster/zapp-react-native-utils/reactHooks";
11
+ import { useMemo, useEffect, useState } from "react";
12
+
13
+ export const useWaitForValidOrientation = () => {
14
+ const {
15
+ width: screenWidth,
16
+ height,
17
+ deviceInfo,
18
+ } = useDimensions("screen", {
19
+ fullDimensions: true,
20
+ updateForInactiveScreens: false,
21
+ });
22
+
23
+ const currentScreenData = useCurrentScreenData();
24
+
25
+ const { screenData } = useRoute();
26
+
27
+ const [readyState, setReadyState] = useState(false);
28
+
29
+ const isTablet = deviceInfo?.isTablet;
30
+
31
+ const { appData } = usePickFromState(["appData"]);
32
+ const isTabletPortrait = appData?.isTabletPortrait;
33
+
34
+ const layoutData = useMemo(
35
+ () => ({ isTablet, isTabletPortrait, width: screenWidth, height }),
36
+ [isTablet, isTabletPortrait, screenWidth, height]
37
+ );
38
+
39
+ const targetScreenData =
40
+ currentScreenData || (screenData as any)?.targetScreen || screenData;
41
+
42
+ const orientation = useGetScreenOrientation(targetScreenData);
43
+
44
+ const isReadyForDisplay = isOrientationCompatible({
45
+ orientation,
46
+ layoutData,
47
+ });
48
+
49
+ useEffect(() => {
50
+ if (isReadyForDisplay && !readyState) {
51
+ setReadyState(true);
52
+ }
53
+ }, [readyState, orientation, layoutData]);
54
+
55
+ return readyState;
56
+ };
@@ -2,31 +2,27 @@
2
2
  import React from "react";
3
3
  import { View } from "react-native";
4
4
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
5
- import {
6
- isOrientationCompatible,
7
- useGetScreenOrientation,
8
- } from "@applicaster/zapp-react-native-utils/appUtils/orientationHelper";
9
5
 
10
6
  import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
11
7
  import { getComponentModule } from "@applicaster/zapp-react-native-utils/pluginUtils";
12
8
  import {
13
- shouldNavBarDisplayMenu,
14
9
  getNavBarProps,
15
10
  getScreenId,
11
+ shouldNavBarDisplayMenu,
16
12
  } from "@applicaster/zapp-react-native-utils/navigationUtils";
17
13
  import {
18
- useDimensions,
19
- useRoute,
20
14
  useCurrentScreenData,
21
15
  useNavbarState,
22
- useScreenData,
23
16
  useNavigation,
17
+ useRoute,
18
+ useScreenData,
24
19
  } from "@applicaster/zapp-react-native-utils/reactHooks";
25
20
  import { getNavigationPluginModule } from "@applicaster/zapp-react-native-app/App/Layout/layoutHelpers";
26
21
 
27
22
  import { RouteManager } from "../RouteManager";
28
23
  import { useScreenConfiguration } from "../River/useScreenConfiguration";
29
24
  import { isValidColor } from "./utils";
25
+ import { useWaitForValidOrientation } from "./hooks";
30
26
 
31
27
  const screenStyles = {
32
28
  flex: 1,
@@ -50,14 +46,6 @@ export function Screen(_props: Props) {
50
46
  const currentScreenData = useCurrentScreenData();
51
47
  const { backgroundColor } = useScreenConfiguration(currentScreenData.id);
52
48
 
53
- const {
54
- width: screenWidth,
55
- height,
56
- deviceInfo,
57
- } = useDimensions("screen", {
58
- fullDimensions: true,
59
- });
60
-
61
49
  const { screenData, pathname } = useRoute();
62
50
 
63
51
  const currentRiver = useScreenData(
@@ -66,13 +54,6 @@ export function Screen(_props: Props) {
66
54
 
67
55
  const { title } = useNavbarState();
68
56
 
69
- const isTablet = deviceInfo?.isTablet;
70
-
71
- const { appData } = usePickFromState(["appData"]);
72
- const isTabletPortrait = appData?.isTabletPortrait;
73
-
74
- const layoutData = { isTablet, isTabletPortrait, width: screenWidth, height };
75
-
76
57
  const hasMenu = shouldNavBarDisplayMenu(currentRiver, plugins);
77
58
 
78
59
  const navBarProps = React.useMemo<MobileNavBarPluginProps | null>(
@@ -108,30 +89,23 @@ export function Screen(_props: Props) {
108
89
  [theme.app_background_color, backgroundColor]
109
90
  );
110
91
 
111
- const targetScreenData =
112
- currentScreenData || (screenData as any)?.targetScreen || screenData;
113
-
114
- const orientation = useGetScreenOrientation(targetScreenData);
92
+ // Set ready state when screen is rotated to desired orientation
93
+ const isReady = useWaitForValidOrientation();
115
94
 
116
95
  // We prevent rendering of the screen until UI is actually rotated to screen desired orientation.
117
96
  // This saves unnecessary re-renders and user will not see distorted aspect screen.
118
- if (
119
- !isOrientationCompatible({
120
- orientation,
121
- layoutData,
122
- })
123
- ) {
124
- return <View style={style} />;
125
- }
126
-
127
97
  return (
128
98
  <View style={style}>
129
- {navBarProps && <NavBar {...navBarProps} hasMenu={hasMenu} />}
130
-
131
- <OfflineFallbackScreen>
132
- {/* @TODO RouteManager doesn't use props, can they be removed ? */}
133
- <RouteManager pathname={pathname} screenData={screenData} />
134
- </OfflineFallbackScreen>
99
+ {isReady ? (
100
+ <>
101
+ {navBarProps ? <NavBar {...navBarProps} hasMenu={hasMenu} /> : null}
102
+
103
+ <OfflineFallbackScreen>
104
+ {/* @TODO RouteManager doesn't use props, can they be removed ? */}
105
+ <RouteManager pathname={pathname} screenData={screenData} />
106
+ </OfflineFallbackScreen>
107
+ </>
108
+ ) : null}
135
109
  </View>
136
110
  );
137
111
  }
@@ -1,157 +1,180 @@
1
1
  import React from "react";
2
2
  import { View } from "react-native";
3
- import { shallow } from "enzyme";
4
- import { shallowToJson } from "enzyme-to-json";
5
- import { connect as realConnect } from "react-redux";
3
+ import { renderWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
6
4
 
7
5
  const pluginConfiguration = { foo: "bar" };
8
6
 
9
- const ScreenType1 = jest.fn(() => <View />);
10
- const ScreenType2 = jest.fn(() => <View />);
7
+ const MockModuleView = (testID) => {
8
+ // eslint-disable-next-line react/display-name
9
+ return function (props) {
10
+ return <View testID={testID} {...props} />;
11
+ };
12
+ };
13
+
14
+ const ScreenType1 = MockModuleView("screen_type_1");
15
+ const ScreenType2 = MockModuleView("screen_type_2");
16
+ const PlayerController = MockModuleView("player_controller");
11
17
 
12
- const ScreenType3 = {
13
- module: jest.fn(() => <View />),
18
+ const mockScreenType3 = {
19
+ module: MockModuleView("screen_type_3"),
14
20
  name: "ScreenType3",
15
21
  type: "screen_type_3",
16
22
  configuration: pluginConfiguration,
17
23
  };
18
24
 
19
- const ScreenType4 = {
20
- module: jest.fn(() => <View />),
25
+ const mockScreenType4 = {
26
+ module: MockModuleView("screen_type_4"),
21
27
  name: "ScreenType4",
22
28
  type: "screen_type_4",
23
29
  };
24
30
 
25
- const PlayerController = jest.fn(() => <View />);
26
-
27
- const playerPlugin = {
28
- module: jest.fn(() => <View />),
31
+ const mockPlayerPlugin = {
32
+ module: MockModuleView("player_plugin"),
29
33
  name: "playerPlugin",
30
34
  type: "player",
31
35
  };
32
36
 
33
- const ScreenPlugin = {
34
- module: jest.fn(() => <View />),
37
+ const mockScreenPlugin = {
38
+ module: MockModuleView("screen_plugin"),
35
39
  type: "general",
36
40
  name: "Screen plugin",
37
41
  identifier: "screen-plugin",
38
42
  };
39
43
 
40
- const PluginWithConfig = {
41
- module: jest.fn(() => <View />),
44
+ const mockPluginWithConfig = {
45
+ module: MockModuleView("plugin_with_config"),
42
46
  type: "general",
43
47
  name: "Plugin with config",
44
48
  identifier: "plugin-with-config",
45
49
  configuration: pluginConfiguration,
46
50
  };
47
51
 
48
- const components = { ScreenType1, ScreenType2, PlayerController };
49
-
50
- const plugins = {
51
- ScreenType3,
52
- ScreenType4,
53
- playerPlugin,
54
- ScreenPlugin,
55
- PluginWithConfig,
52
+ const mockComponents = { ScreenType1, ScreenType2, PlayerController };
53
+
54
+ const mockState = {
55
+ components: mockComponents,
56
+ plugins: [
57
+ mockScreenType3,
58
+ mockScreenType4,
59
+ mockPlayerPlugin,
60
+ mockScreenPlugin,
61
+ mockPluginWithConfig,
62
+ ],
63
+ rivers: {
64
+ A1234: {},
65
+ },
56
66
  };
57
67
 
58
- const withAnalytics = {
59
- sendOnClickEvent: jest.fn(),
60
- sendMenuClickEvent: jest.fn(),
61
- sendMenuToggleEvent: jest.fn(),
62
- sendBackButtonClickEvent: jest.fn(),
63
- sendOnNavItemClickEvent: jest.fn(),
64
- sendHeaderClickEvent: jest.fn(),
65
- sendHardwareBackButtonClickEvent: jest.fn(),
66
- sendScreenEvent: jest.fn(),
67
- };
68
+ jest.mock(
69
+ "@applicaster/zapp-react-native-utils/analyticsUtils/helpers/hooks",
70
+ () => ({
71
+ useScreenAnalytics: jest.fn(),
72
+ })
73
+ );
68
74
 
69
- jest.mock("@applicaster/zapp-react-native-utils/analyticsUtils", () => ({
70
- useAnalytics: jest.fn().mockReturnValue(withAnalytics),
71
- }));
75
+ jest.mock(
76
+ "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation",
77
+ () => ({
78
+ useNavigation: jest.fn(() => ({
79
+ closeVideoModal: jest.fn(),
80
+ videoModalState: {
81
+ mode: "test",
82
+ },
83
+ })),
84
+ })
85
+ );
72
86
 
73
- jest.mock("@applicaster/zapp-react-native-redux/hooks", () => ({
74
- usePickFromState: jest.fn(() => ({ components, plugins })),
75
- }));
87
+ jest.mock(
88
+ "@applicaster/zapp-react-native-utils/reactHooks/navigation/useRoute",
89
+ () => ({
90
+ useRoute: jest.fn(() => ({ screenId: "1234" })),
91
+ })
92
+ );
76
93
 
77
94
  jest.mock(
78
- "@applicaster/zapp-react-native-utils/analyticsUtils/helpers/hooks",
95
+ "@applicaster/zapp-react-native-utils/reactHooks/navigation/useIsScreenActive",
79
96
  () => ({
80
- useScreenAnalytics: jest.fn(() => {}),
97
+ useIsScreenActive: () => ({
98
+ isScreenActive: true,
99
+ }),
81
100
  })
82
101
  );
83
102
 
84
- jest.mock("react-redux", () => ({
85
- useDispatch: jest.fn(() => () => {}),
86
- connect: realConnect,
87
- }));
103
+ jest.mock("../../PlayerContainer", () => {
104
+ const { View } = jest.requireActual("react-native");
88
105
 
89
- jest.mock("@applicaster/zapp-react-native-utils/reactHooks", () => ({
90
- useNavigation: jest.fn(() => ({
91
- videoModalState: {
92
- mode: "test",
93
- },
94
- })),
95
- useRoute: jest.fn(() => ({ screenId: "1234" })),
96
- }));
106
+ return {
107
+ PlayerContainer: (props) => (
108
+ <View {...props}>
109
+ <props.Player />
110
+ </View>
111
+ ),
112
+ };
113
+ });
97
114
 
98
- const { ScreenResolverComponent: ScreenResolver } = require("..");
115
+ const getWrapper = (screenId, screenType, screenData) => {
116
+ const ScreenResolver = require("../").ScreenResolverComponent;
99
117
 
100
- const getWrapper = (screenId, screenType, screenData) =>
101
- shallow(
118
+ return renderWithProviders(
102
119
  <ScreenResolver
103
120
  {...{
104
121
  screenId,
105
122
  screenType,
106
123
  screenData,
107
124
  }}
108
- />
125
+ />,
126
+ mockState
109
127
  );
128
+ };
110
129
 
111
130
  describe("<ScreenResolver />", () => {
112
131
  it("renders correctly", () => {
113
132
  const wrapper = getWrapper("1234", "screen_type_1", {});
114
133
 
115
- expect(shallowToJson(wrapper)).toMatchSnapshot();
134
+ expect(wrapper.getByTestId("screen_type_1")).toBeDefined();
116
135
  });
117
136
 
118
137
  it("picks screen from plugins if it exists", () => {
119
138
  const wrapper = getWrapper("A1234", "screen_type_3", {});
120
139
 
121
- expect(wrapper.find(ScreenType3.module)).toHaveProperty("length", 1);
140
+ expect(wrapper.getByTestId("screen_type_3")).toBeDefined();
122
141
  });
123
142
 
124
143
  it("picks the screen from its identifier if it exists", () => {
125
144
  const wrapper = getWrapper("A1234", "screen-plugin", {});
126
145
 
127
- expect(wrapper.find(ScreenPlugin.module)).toHaveProperty("length", 1);
146
+ expect(wrapper.getByTestId("screen_plugin")).toBeDefined();
128
147
  });
129
148
 
130
149
  it("picks screen from components if it doesn't exist in plugins", () => {
131
150
  const wrapper = getWrapper("A1234", "screen_type_2", {});
132
151
 
133
- expect(wrapper.find(ScreenType2)).toHaveProperty("length", 1);
152
+ expect(wrapper.getByTestId("screen_type_2")).toBeDefined();
134
153
  });
135
154
 
136
155
  it("renders the screen and passes screenId & locationState as props", () => {
137
156
  const wrapper = getWrapper("A1234", "screen_type_3", "foo");
138
157
 
139
- const screenWrapper = wrapper.find(ScreenType3.module);
158
+ const screenWrapper = wrapper.getByTestId("screen_type_3");
140
159
 
141
- expect(screenWrapper.prop("screenId")).toEqual("A1234");
142
- expect(screenWrapper.prop("screenData")).toEqual("foo");
160
+ expect(screenWrapper.props).toMatchObject({
161
+ screenId: "A1234",
162
+ screenData: "foo",
163
+ });
143
164
  });
144
165
 
145
166
  it("renders null if the screen is not found", () => {
146
167
  const wrapper = getWrapper(null, "screen_type_5", {});
147
168
 
148
- expect(wrapper.getElement()).toBe(null);
169
+ expect(wrapper.queryAllByTestId("screen_type_5")).toBeEmpty();
149
170
  });
150
171
 
151
172
  it("injects the plugin configuration if it exists", () => {
152
173
  const wrapper = getWrapper("A1234", "plugin-with-config", {});
153
174
 
154
- expect(wrapper.find(PluginWithConfig.module).props()).toHaveProperty(
175
+ const screenWrapper = wrapper.getByTestId("plugin_with_config");
176
+
177
+ expect(screenWrapper.props).toHaveProperty(
155
178
  "configuration",
156
179
  expect.objectContaining(pluginConfiguration)
157
180
  );
@@ -160,7 +183,9 @@ describe("<ScreenResolver />", () => {
160
183
  it("injects the plugin configuration if it exists, even when plugin is resolved by type", () => {
161
184
  const wrapper = getWrapper("A1234", "screen_type_3", {});
162
185
 
163
- expect(wrapper.find(ScreenType3.module).props()).toHaveProperty(
186
+ const screenWrapper = wrapper.getByTestId("screen_type_3");
187
+
188
+ expect(screenWrapper.props).toHaveProperty(
164
189
  "configuration",
165
190
  expect.objectContaining(pluginConfiguration)
166
191
  );
@@ -168,6 +193,6 @@ describe("<ScreenResolver />", () => {
168
193
 
169
194
  it("wraps the player with the playerController component when the screenType is playable", () => {
170
195
  const wrapper = getWrapper("A1234", "playable", {});
171
- expect(shallowToJson(wrapper)).toMatchSnapshot();
196
+ expect(wrapper.getByTestId("player_plugin")).toBeDefined();
172
197
  });
173
198
  });