@applicaster/zapp-react-native-utils 15.0.0-rc.10 → 15.0.0-rc.101
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/actionsExecutor/ActionExecutorContext.tsx +3 -6
- package/actionsExecutor/feedDecorator.ts +6 -6
- package/adsUtils/__tests__/createVMAP.test.ts +419 -0
- package/adsUtils/index.ts +2 -2
- package/analyticsUtils/README.md +1 -1
- package/analyticsUtils/analyticsMapper.ts +10 -2
- package/appDataUtils/__tests__/urlScheme.test.ts +678 -0
- package/appUtils/HooksManager/__tests__/__snapshots__/hooksManager.test.js.snap +0 -188
- package/appUtils/HooksManager/__tests__/hooksManager.test.js +16 -2
- package/appUtils/HooksManager/index.ts +10 -10
- package/appUtils/RiverFocusManager/{index.js → index.ts} +25 -18
- package/appUtils/accessibilityManager/__tests__/utils.test.ts +360 -0
- package/appUtils/accessibilityManager/const.ts +4 -0
- package/appUtils/accessibilityManager/hooks.ts +20 -13
- package/appUtils/accessibilityManager/index.ts +28 -1
- package/appUtils/accessibilityManager/utils.ts +59 -8
- package/appUtils/contextKeysManager/__tests__/getKeys/failure.test.ts +7 -2
- package/appUtils/contextKeysManager/__tests__/getKeys/success.test.ts +48 -0
- package/appUtils/contextKeysManager/contextResolver.ts +51 -22
- package/appUtils/contextKeysManager/index.ts +65 -10
- package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +4 -0
- package/appUtils/focusManager/index.ios.ts +59 -3
- package/appUtils/focusManager/treeDataStructure/Tree/__tests__/Tree.test.js +46 -0
- package/appUtils/focusManager/treeDataStructure/Tree/index.js +18 -18
- package/appUtils/focusManagerAux/utils/index.ios.ts +122 -0
- package/appUtils/focusManagerAux/utils/index.ts +19 -1
- package/appUtils/focusManagerAux/utils/utils.ios.ts +231 -0
- package/appUtils/keyCodes/keys/keys.web.ts +1 -4
- package/appUtils/orientationHelper.ts +2 -4
- package/appUtils/platform/platformUtils.ts +117 -18
- package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +94 -4
- package/appUtils/playerManager/OverlayObserver/utils.ts +32 -20
- package/appUtils/playerManager/player.ts +4 -0
- package/appUtils/playerManager/playerNative.ts +31 -17
- package/appUtils/playerManager/usePlayerState.tsx +14 -2
- package/arrayUtils/__tests__/allTruthy.test.ts +24 -0
- package/arrayUtils/__tests__/anyThruthy.test.ts +24 -0
- package/arrayUtils/index.ts +5 -0
- package/cellUtils/index.ts +32 -0
- package/cloudEventsUtils/__tests__/index.test.ts +529 -0
- package/cloudEventsUtils/index.ts +65 -1
- package/configurationUtils/__tests__/imageSrcFromMediaItem.test.ts +38 -0
- package/configurationUtils/__tests__/manifestKeyParser.test.ts +26 -26
- package/configurationUtils/index.ts +17 -11
- package/dateUtils/__tests__/dayjs.test.ts +330 -0
- package/enumUtils/__tests__/getEnumKeyByEnumValue.test.ts +207 -0
- package/errorUtils/__tests__/GeneralError.test.ts +97 -0
- package/errorUtils/__tests__/HttpStatusCode.test.ts +344 -0
- package/errorUtils/__tests__/MissingPluginError.test.ts +113 -0
- package/errorUtils/__tests__/NetworkError.test.ts +202 -0
- package/errorUtils/__tests__/getParsedResponse.test.ts +188 -0
- package/errorUtils/__tests__/invariant.test.ts +112 -0
- package/focusManager/aux/index.ts +1 -1
- package/headersUtils/__tests__/headersUtils.test.js +11 -1
- package/headersUtils/index.ts +2 -1
- package/manifestUtils/defaultManifestConfigurations/player.js +109 -11
- package/manifestUtils/keys.js +21 -0
- package/manifestUtils/platformIsTV.js +13 -0
- package/manifestUtils/sharedConfiguration/screenPicker/utils.js +1 -0
- package/manifestUtils/tvAction/container/index.js +1 -1
- package/navigationUtils/index.ts +15 -5
- package/numberUtils/__tests__/toNumber.test.ts +12 -0
- package/numberUtils/__tests__/toPositiveNumber.test.ts +165 -0
- package/numberUtils/index.ts +19 -1
- package/package.json +4 -4
- package/playerUtils/usePlayerTTS.ts +8 -3
- package/pluginUtils/index.ts +4 -0
- package/reactHooks/advertising/index.ts +2 -2
- package/reactHooks/analytics/__tests__/useSendAnalyticsOnPress.test.ts +537 -0
- package/reactHooks/app/__tests__/useAppState.test.ts +1 -1
- package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
- package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +1 -2
- package/reactHooks/cell-click/__tests__/index.test.js +1 -3
- package/reactHooks/configuration/__tests__/index.test.tsx +1 -1
- package/reactHooks/connection/__tests__/index.test.js +1 -1
- package/reactHooks/debugging/__tests__/index.test.js +4 -4
- package/reactHooks/dev/__tests__/useReRenderLog.test.ts +188 -0
- package/reactHooks/device/useIsTablet.tsx +14 -19
- package/reactHooks/device/useMemoizedIsTablet.ts +3 -3
- package/reactHooks/events/index.ts +20 -0
- package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +32 -23
- package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +19 -19
- package/reactHooks/feed/__tests__/useEntryScreenId.test.tsx +4 -1
- package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +42 -30
- package/reactHooks/feed/__tests__/useFeedRefresh.test.tsx +1 -1
- package/reactHooks/feed/__tests__/{useInflatedUrl.test.ts → useInflatedUrl.test.tsx} +62 -7
- package/reactHooks/feed/useBatchLoading.ts +7 -1
- package/reactHooks/feed/useEntryScreenId.ts +2 -2
- package/reactHooks/feed/useInflatedUrl.ts +43 -17
- package/reactHooks/feed/usePipesCacheReset.ts +3 -1
- package/reactHooks/flatList/useLoadNextPageIfNeeded.ts +13 -16
- package/reactHooks/hookModal/hooks/useHookModalScreenData.ts +12 -8
- package/reactHooks/index.ts +2 -0
- package/reactHooks/layout/__tests__/index.test.tsx +1 -1
- package/reactHooks/layout/__tests__/useLayoutVersion.test.tsx +1 -1
- package/reactHooks/layout/index.ts +1 -1
- package/reactHooks/layout/useDimensions/__tests__/{useDimensions.test.ts → useDimensions.test.tsx} +105 -25
- package/reactHooks/layout/useDimensions/useDimensions.ts +2 -2
- package/reactHooks/navigation/__tests__/index.test.tsx +40 -9
- package/reactHooks/navigation/index.ts +27 -11
- package/reactHooks/navigation/useRoute.ts +11 -7
- package/reactHooks/player/TVSeekControlller/TVSeekController.ts +27 -10
- package/reactHooks/player/__tests__/useAutoSeek._test.tsx +1 -1
- package/reactHooks/player/__tests__/useTapSeek._test.ts +1 -1
- package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +1 -1
- package/reactHooks/resolvers/__tests__/useComponentResolver.test.tsx +1 -1
- package/reactHooks/resolvers/useCellResolver.ts +6 -2
- package/reactHooks/resolvers/useComponentResolver.ts +8 -2
- package/reactHooks/screen/__tests__/useCurrentScreenData.test.tsx +2 -2
- package/reactHooks/screen/__tests__/useScreenBackgroundColor.test.tsx +1 -1
- package/reactHooks/screen/__tests__/useScreenData.test.tsx +1 -1
- package/reactHooks/screen/__tests__/useTargetScreenData.test.tsx +12 -4
- package/reactHooks/screen/useTargetScreenData.ts +4 -2
- package/reactHooks/state/useRefWithInitialValue.ts +10 -0
- package/reactHooks/state/useRivers.ts +1 -1
- package/reactHooks/ui/__tests__/useFadeOutWhenBlurred.test.ts +580 -0
- package/reactHooks/usePluginConfiguration.ts +2 -2
- package/reactHooks/utils/__tests__/index.test.js +1 -1
- package/rectUtils/__tests__/index.test.ts +549 -0
- package/rectUtils/index.ts +2 -2
- package/screenPickerUtils/__tests__/index.test.ts +333 -0
- package/screenState/__tests__/index.test.ts +1 -1
- package/searchUtils/const.ts +7 -0
- package/searchUtils/index.ts +3 -0
- package/services/storageServiceSync.web.ts +1 -1
- package/stringUtils/index.ts +1 -1
- package/testUtils/index.tsx +30 -21
- package/time/__tests__/BackgroundTimer.test.ts +156 -0
- package/time/__tests__/Timer.test.ts +236 -0
- package/typeGuards/__tests__/isString.test.ts +21 -0
- package/typeGuards/index.ts +4 -0
- package/utils/__tests__/mapAccum.test.ts +73 -0
- package/utils/__tests__/mergeRight.test.ts +48 -0
- package/utils/__tests__/selectors.test.ts +124 -0
- package/utils/index.ts +20 -0
- package/utils/mapAccum.ts +23 -0
- package/utils/mergeRight.ts +5 -0
- package/utils/path.ts +6 -3
- package/utils/pathOr.ts +5 -1
- package/utils/selectors.ts +46 -0
- package/zappFrameworkUtils/HookCallback/callbackNavigationAction.ts +49 -12
- package/zappFrameworkUtils/HookCallback/hookCallbackManifestExtensions.config.js +1 -1
- package/reactHooks/componentsMap/index.ts +0 -55
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getFocusableId,
|
|
3
|
+
getPickerSelectorId,
|
|
4
|
+
SCREEN_PICKER_CONTAINER,
|
|
5
|
+
getScreenPickerId,
|
|
6
|
+
getScreenPickerSelectorContainerId,
|
|
7
|
+
getScreenPickerContentContainerId,
|
|
8
|
+
} from "../index";
|
|
9
|
+
|
|
10
|
+
describe("screenPickerUtils", () => {
|
|
11
|
+
describe("getFocusableId", () => {
|
|
12
|
+
it("should generate focusable ID with PickerItem prefix", () => {
|
|
13
|
+
expect(getFocusableId("item1")).toBe("PickerItem.item1");
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("should handle numeric IDs", () => {
|
|
17
|
+
expect(getFocusableId(123)).toBe("PickerItem.123");
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("should handle string IDs with special characters", () => {
|
|
21
|
+
expect(getFocusableId("item-123_test")).toBe("PickerItem.item-123_test");
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("should handle empty string ID", () => {
|
|
25
|
+
expect(getFocusableId("")).toBe("PickerItem.");
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("should handle IDs with spaces", () => {
|
|
29
|
+
expect(getFocusableId("my item")).toBe("PickerItem.my item");
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("should handle IDs with dots", () => {
|
|
33
|
+
expect(getFocusableId("parent.child")).toBe("PickerItem.parent.child");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("should handle null ID", () => {
|
|
37
|
+
expect(getFocusableId(null)).toBe("PickerItem.null");
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("should handle undefined ID", () => {
|
|
41
|
+
expect(getFocusableId(undefined)).toBe("PickerItem.undefined");
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
describe("getPickerSelectorId", () => {
|
|
46
|
+
it("should generate picker selector ID with PickerSelector prefix", () => {
|
|
47
|
+
expect(getPickerSelectorId("selector1")).toBe("PickerSelector.selector1");
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("should handle numeric IDs", () => {
|
|
51
|
+
expect(getPickerSelectorId(456)).toBe("PickerSelector.456");
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("should handle string IDs with special characters", () => {
|
|
55
|
+
expect(getPickerSelectorId("selector-abc_xyz")).toBe(
|
|
56
|
+
"PickerSelector.selector-abc_xyz"
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("should handle empty string ID", () => {
|
|
61
|
+
expect(getPickerSelectorId("")).toBe("PickerSelector.");
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("should handle IDs with spaces", () => {
|
|
65
|
+
expect(getPickerSelectorId("my selector")).toBe(
|
|
66
|
+
"PickerSelector.my selector"
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("should handle null ID", () => {
|
|
71
|
+
expect(getPickerSelectorId(null)).toBe("PickerSelector.null");
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("should handle undefined ID", () => {
|
|
75
|
+
expect(getPickerSelectorId(undefined)).toBe("PickerSelector.undefined");
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe("SCREEN_PICKER_CONTAINER", () => {
|
|
80
|
+
it("should have correct constant value", () => {
|
|
81
|
+
expect(SCREEN_PICKER_CONTAINER).toBe("ScreenPickerContainer");
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("should be a string", () => {
|
|
85
|
+
expect(typeof SCREEN_PICKER_CONTAINER).toBe("string");
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
describe("getScreenPickerId", () => {
|
|
90
|
+
it("should generate screen picker ID with container prefix", () => {
|
|
91
|
+
expect(getScreenPickerId("screen1")).toBe(
|
|
92
|
+
"ScreenPickerContainer.screen1"
|
|
93
|
+
);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("should use SCREEN_PICKER_CONTAINER constant", () => {
|
|
97
|
+
const id = "test";
|
|
98
|
+
expect(getScreenPickerId(id)).toBe(`${SCREEN_PICKER_CONTAINER}.${id}`);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("should handle numeric IDs", () => {
|
|
102
|
+
expect(getScreenPickerId(789)).toBe("ScreenPickerContainer.789");
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("should handle string IDs with special characters", () => {
|
|
106
|
+
expect(getScreenPickerId("screen-123_test")).toBe(
|
|
107
|
+
"ScreenPickerContainer.screen-123_test"
|
|
108
|
+
);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("should handle empty string ID", () => {
|
|
112
|
+
expect(getScreenPickerId("")).toBe("ScreenPickerContainer.");
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("should handle IDs with spaces", () => {
|
|
116
|
+
expect(getScreenPickerId("my screen")).toBe(
|
|
117
|
+
"ScreenPickerContainer.my screen"
|
|
118
|
+
);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("should handle null ID", () => {
|
|
122
|
+
expect(getScreenPickerId(null)).toBe("ScreenPickerContainer.null");
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("should handle undefined ID", () => {
|
|
126
|
+
expect(getScreenPickerId(undefined)).toBe(
|
|
127
|
+
"ScreenPickerContainer.undefined"
|
|
128
|
+
);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
describe("getScreenPickerSelectorContainerId", () => {
|
|
133
|
+
it("should generate selector container ID with suffix", () => {
|
|
134
|
+
expect(getScreenPickerSelectorContainerId("screen1")).toBe(
|
|
135
|
+
"ScreenPickerContainer.screen1-screen-selector"
|
|
136
|
+
);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it("should build on top of getScreenPickerId", () => {
|
|
140
|
+
const id = "test";
|
|
141
|
+
const baseId = getScreenPickerId(id);
|
|
142
|
+
|
|
143
|
+
expect(getScreenPickerSelectorContainerId(id)).toBe(
|
|
144
|
+
`${baseId}-screen-selector`
|
|
145
|
+
);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it("should handle numeric IDs", () => {
|
|
149
|
+
expect(getScreenPickerSelectorContainerId(123)).toBe(
|
|
150
|
+
"ScreenPickerContainer.123-screen-selector"
|
|
151
|
+
);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it("should handle string IDs with special characters", () => {
|
|
155
|
+
expect(getScreenPickerSelectorContainerId("screen-abc_xyz")).toBe(
|
|
156
|
+
"ScreenPickerContainer.screen-abc_xyz-screen-selector"
|
|
157
|
+
);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it("should handle empty string ID", () => {
|
|
161
|
+
expect(getScreenPickerSelectorContainerId("")).toBe(
|
|
162
|
+
"ScreenPickerContainer.-screen-selector"
|
|
163
|
+
);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("should handle IDs with spaces", () => {
|
|
167
|
+
expect(getScreenPickerSelectorContainerId("my screen")).toBe(
|
|
168
|
+
"ScreenPickerContainer.my screen-screen-selector"
|
|
169
|
+
);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it("should handle null ID", () => {
|
|
173
|
+
expect(getScreenPickerSelectorContainerId(null)).toBe(
|
|
174
|
+
"ScreenPickerContainer.null-screen-selector"
|
|
175
|
+
);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it("should handle undefined ID", () => {
|
|
179
|
+
expect(getScreenPickerSelectorContainerId(undefined)).toBe(
|
|
180
|
+
"ScreenPickerContainer.undefined-screen-selector"
|
|
181
|
+
);
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
describe("getScreenPickerContentContainerId", () => {
|
|
186
|
+
it("should generate content container ID with suffix", () => {
|
|
187
|
+
expect(getScreenPickerContentContainerId("screen1")).toBe(
|
|
188
|
+
"ScreenPickerContainer.screen1-screen-container"
|
|
189
|
+
);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it("should build on top of getScreenPickerId", () => {
|
|
193
|
+
const id = "test";
|
|
194
|
+
const baseId = getScreenPickerId(id);
|
|
195
|
+
|
|
196
|
+
expect(getScreenPickerContentContainerId(id)).toBe(
|
|
197
|
+
`${baseId}-screen-container`
|
|
198
|
+
);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it("should handle numeric IDs", () => {
|
|
202
|
+
expect(getScreenPickerContentContainerId(456)).toBe(
|
|
203
|
+
"ScreenPickerContainer.456-screen-container"
|
|
204
|
+
);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it("should handle string IDs with special characters", () => {
|
|
208
|
+
expect(getScreenPickerContentContainerId("content-abc_xyz")).toBe(
|
|
209
|
+
"ScreenPickerContainer.content-abc_xyz-screen-container"
|
|
210
|
+
);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it("should handle empty string ID", () => {
|
|
214
|
+
expect(getScreenPickerContentContainerId("")).toBe(
|
|
215
|
+
"ScreenPickerContainer.-screen-container"
|
|
216
|
+
);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it("should handle IDs with spaces", () => {
|
|
220
|
+
expect(getScreenPickerContentContainerId("my content")).toBe(
|
|
221
|
+
"ScreenPickerContainer.my content-screen-container"
|
|
222
|
+
);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it("should handle null ID", () => {
|
|
226
|
+
expect(getScreenPickerContentContainerId(null)).toBe(
|
|
227
|
+
"ScreenPickerContainer.null-screen-container"
|
|
228
|
+
);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it("should handle undefined ID", () => {
|
|
232
|
+
expect(getScreenPickerContentContainerId(undefined)).toBe(
|
|
233
|
+
"ScreenPickerContainer.undefined-screen-container"
|
|
234
|
+
);
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
describe("ID relationships", () => {
|
|
239
|
+
it("should generate different IDs for different functions", () => {
|
|
240
|
+
const id = "test";
|
|
241
|
+
|
|
242
|
+
const focusableId = getFocusableId(id);
|
|
243
|
+
const selectorId = getPickerSelectorId(id);
|
|
244
|
+
const screenPickerId = getScreenPickerId(id);
|
|
245
|
+
|
|
246
|
+
expect(focusableId).not.toBe(selectorId);
|
|
247
|
+
expect(focusableId).not.toBe(screenPickerId);
|
|
248
|
+
expect(selectorId).not.toBe(screenPickerId);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
it("should have consistent prefixes across calls", () => {
|
|
252
|
+
expect(getFocusableId("a")).toContain("PickerItem.");
|
|
253
|
+
expect(getFocusableId("b")).toContain("PickerItem.");
|
|
254
|
+
expect(getPickerSelectorId("a")).toContain("PickerSelector.");
|
|
255
|
+
expect(getPickerSelectorId("b")).toContain("PickerSelector.");
|
|
256
|
+
expect(getScreenPickerId("a")).toContain("ScreenPickerContainer.");
|
|
257
|
+
expect(getScreenPickerId("b")).toContain("ScreenPickerContainer.");
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it("should generate selector and content IDs from same base", () => {
|
|
261
|
+
const id = "common";
|
|
262
|
+
const baseId = getScreenPickerId(id);
|
|
263
|
+
const selectorId = getScreenPickerSelectorContainerId(id);
|
|
264
|
+
const contentId = getScreenPickerContentContainerId(id);
|
|
265
|
+
|
|
266
|
+
expect(selectorId).toContain(baseId);
|
|
267
|
+
expect(contentId).toContain(baseId);
|
|
268
|
+
expect(selectorId).not.toBe(contentId);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it("should distinguish between selector and content containers", () => {
|
|
272
|
+
const id = "test";
|
|
273
|
+
|
|
274
|
+
const selectorId = getScreenPickerSelectorContainerId(id);
|
|
275
|
+
const contentId = getScreenPickerContentContainerId(id);
|
|
276
|
+
|
|
277
|
+
expect(selectorId).toContain("-screen-selector");
|
|
278
|
+
expect(contentId).toContain("-screen-container");
|
|
279
|
+
expect(selectorId).not.toBe(contentId);
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
describe("special characters and edge cases", () => {
|
|
284
|
+
it("should handle IDs with slashes", () => {
|
|
285
|
+
const id = "path/to/screen";
|
|
286
|
+
|
|
287
|
+
expect(getFocusableId(id)).toBe("PickerItem.path/to/screen");
|
|
288
|
+
expect(getPickerSelectorId(id)).toBe("PickerSelector.path/to/screen");
|
|
289
|
+
|
|
290
|
+
expect(getScreenPickerId(id)).toBe(
|
|
291
|
+
"ScreenPickerContainer.path/to/screen"
|
|
292
|
+
);
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it("should handle IDs with Unicode characters", () => {
|
|
296
|
+
const id = "écran-日本語";
|
|
297
|
+
|
|
298
|
+
expect(getFocusableId(id)).toBe("PickerItem.écran-日本語");
|
|
299
|
+
expect(getPickerSelectorId(id)).toBe("PickerSelector.écran-日本語");
|
|
300
|
+
expect(getScreenPickerId(id)).toBe("ScreenPickerContainer.écran-日本語");
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it("should handle very long IDs", () => {
|
|
304
|
+
const id = "a".repeat(1000);
|
|
305
|
+
|
|
306
|
+
expect(getFocusableId(id)).toContain("PickerItem.");
|
|
307
|
+
expect(getPickerSelectorId(id)).toContain("PickerSelector.");
|
|
308
|
+
expect(getScreenPickerId(id)).toContain("ScreenPickerContainer.");
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
it("should handle IDs with equals signs", () => {
|
|
312
|
+
const id = "key=value";
|
|
313
|
+
|
|
314
|
+
expect(getFocusableId(id)).toBe("PickerItem.key=value");
|
|
315
|
+
expect(getPickerSelectorId(id)).toBe("PickerSelector.key=value");
|
|
316
|
+
expect(getScreenPickerId(id)).toBe("ScreenPickerContainer.key=value");
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
it("should handle boolean values", () => {
|
|
320
|
+
expect(getFocusableId(true)).toBe("PickerItem.true");
|
|
321
|
+
expect(getPickerSelectorId(false)).toBe("PickerSelector.false");
|
|
322
|
+
expect(getScreenPickerId(true)).toBe("ScreenPickerContainer.true");
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
it("should handle object IDs", () => {
|
|
326
|
+
const obj = { toString: () => "customId" };
|
|
327
|
+
|
|
328
|
+
expect(getFocusableId(obj)).toContain("PickerItem.");
|
|
329
|
+
expect(getPickerSelectorId(obj)).toContain("PickerSelector.");
|
|
330
|
+
expect(getScreenPickerId(obj)).toContain("ScreenPickerContainer.");
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
});
|
|
@@ -17,7 +17,7 @@ export const resolveStorageContextKey = (storageKey: string) => {
|
|
|
17
17
|
const key = splitKey[1];
|
|
18
18
|
|
|
19
19
|
if (!key) {
|
|
20
|
-
return getFromSessionOrLocalStorage(
|
|
20
|
+
return getFromSessionOrLocalStorage(namespaceOrKey);
|
|
21
21
|
} else {
|
|
22
22
|
return getFromSessionOrLocalStorage(key, namespaceOrKey);
|
|
23
23
|
}
|
package/stringUtils/index.ts
CHANGED
package/testUtils/index.tsx
CHANGED
|
@@ -4,7 +4,7 @@ import React, { PropsWithChildren } from "react";
|
|
|
4
4
|
import configureStore from "redux-mock-store";
|
|
5
5
|
import { Provider } from "react-redux";
|
|
6
6
|
import { View } from "react-native";
|
|
7
|
-
import thunk from "redux-thunk";
|
|
7
|
+
import { thunk } from "redux-thunk";
|
|
8
8
|
import * as R from "ramda";
|
|
9
9
|
|
|
10
10
|
import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
|
|
@@ -56,9 +56,29 @@ const initialState = {
|
|
|
56
56
|
contentTypes: null,
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
+
const themeObjDefault = {
|
|
60
|
+
component_margin_top: 0,
|
|
61
|
+
component_margin_bottom: 0,
|
|
62
|
+
component_margin_left: 0,
|
|
63
|
+
component_margin_right: 0,
|
|
64
|
+
component_padding_top: 0,
|
|
65
|
+
component_padding_bottom: 0,
|
|
66
|
+
component_padding_left: 0,
|
|
67
|
+
component_padding_right: 0,
|
|
68
|
+
component_gutter_vertical: 0,
|
|
69
|
+
component_gutter_horizontal: 0,
|
|
70
|
+
component_corner_radius: 0,
|
|
71
|
+
app_background_color: "rgba(0,0,0,0)",
|
|
72
|
+
screen_margin_top: 0,
|
|
73
|
+
screen_margin_bottom: 0,
|
|
74
|
+
component_anchor_point_y: 0,
|
|
75
|
+
assets: "",
|
|
76
|
+
};
|
|
77
|
+
|
|
59
78
|
export const WrappedWithProviders = ({
|
|
60
79
|
children,
|
|
61
80
|
store: storeObj = {},
|
|
81
|
+
theme: themeObj = themeObjDefault,
|
|
62
82
|
}: any) => {
|
|
63
83
|
const _store = configureStore([thunk])(
|
|
64
84
|
R.mergeDeepRight(initialState, { ...storeObj })
|
|
@@ -70,24 +90,7 @@ export const WrappedWithProviders = ({
|
|
|
70
90
|
<ThemeContext.Provider
|
|
71
91
|
value={{
|
|
72
92
|
themes: {
|
|
73
|
-
light:
|
|
74
|
-
component_margin_top: 0,
|
|
75
|
-
component_margin_bottom: 0,
|
|
76
|
-
component_margin_left: 0,
|
|
77
|
-
component_margin_right: 0,
|
|
78
|
-
component_padding_top: 0,
|
|
79
|
-
component_padding_bottom: 0,
|
|
80
|
-
component_padding_left: 0,
|
|
81
|
-
component_padding_right: 0,
|
|
82
|
-
component_gutter_vertical: 0,
|
|
83
|
-
component_gutter_horizontal: 0,
|
|
84
|
-
component_corner_radius: 0,
|
|
85
|
-
app_background_color: "rgba(0,0,0,0)",
|
|
86
|
-
screen_margin_top: 0,
|
|
87
|
-
screen_margin_bottom: 0,
|
|
88
|
-
component_anchor_point_y: 0,
|
|
89
|
-
assets: "",
|
|
90
|
-
},
|
|
93
|
+
light: themeObj,
|
|
91
94
|
},
|
|
92
95
|
selectedThemeId: "light",
|
|
93
96
|
setSelectedThemeId: () => {},
|
|
@@ -113,11 +116,17 @@ export const WrappedWithProviders = ({
|
|
|
113
116
|
* @param store optional store to pass to the provider
|
|
114
117
|
* @returns
|
|
115
118
|
*/
|
|
116
|
-
export const renderWithProviders = (
|
|
119
|
+
export const renderWithProviders = (
|
|
120
|
+
component,
|
|
121
|
+
storeObj?: unknown,
|
|
122
|
+
themeObj?: unknown
|
|
123
|
+
) => {
|
|
117
124
|
return render(component, {
|
|
118
125
|
wrapper: function TestWrapper({ children }: PropsWithChildren<any>) {
|
|
119
126
|
return (
|
|
120
|
-
<WrappedWithProviders store={storeObj}
|
|
127
|
+
<WrappedWithProviders store={storeObj} theme={themeObj}>
|
|
128
|
+
{children}
|
|
129
|
+
</WrappedWithProviders>
|
|
121
130
|
);
|
|
122
131
|
},
|
|
123
132
|
});
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
const mockBackgroundTimerModule = {
|
|
2
|
+
setTimeout: jest.fn(),
|
|
3
|
+
clearTimeout: jest.fn(),
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
jest.mock("../../reactUtils", () => ({
|
|
7
|
+
platformSelect: jest.fn((options) => options.android || options.default),
|
|
8
|
+
}));
|
|
9
|
+
|
|
10
|
+
describe("BackgroundTimer", () => {
|
|
11
|
+
let BackgroundTimer: any;
|
|
12
|
+
|
|
13
|
+
const setupTimer = (withNativeModule = true) => {
|
|
14
|
+
jest.resetModules();
|
|
15
|
+
|
|
16
|
+
jest.doMock("react-native", () => ({
|
|
17
|
+
NativeModules: {
|
|
18
|
+
BackgroundTimer: withNativeModule
|
|
19
|
+
? mockBackgroundTimerModule
|
|
20
|
+
: undefined,
|
|
21
|
+
},
|
|
22
|
+
DeviceEventEmitter: {
|
|
23
|
+
addListener: jest.fn(),
|
|
24
|
+
removeListener: jest.fn(),
|
|
25
|
+
},
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
BackgroundTimer = require("../BackgroundTimer").default;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
jest.clearAllMocks();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("Native Module Environment", () => {
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
setupTimer(true);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("should initialize device event listener on startup", () => {
|
|
41
|
+
const { DeviceEventEmitter } = require("react-native");
|
|
42
|
+
|
|
43
|
+
expect(DeviceEventEmitter.addListener).toHaveBeenCalledWith(
|
|
44
|
+
"BackgroundTimer.timer.fired",
|
|
45
|
+
expect.any(Function)
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("should delegate setTimeout to native module and return a unique ID", () => {
|
|
50
|
+
const callback1 = jest.fn();
|
|
51
|
+
const callback2 = jest.fn();
|
|
52
|
+
const timeout = 1000;
|
|
53
|
+
|
|
54
|
+
const id1 = BackgroundTimer.setTimeout(callback1, timeout);
|
|
55
|
+
const id2 = BackgroundTimer.setTimeout(callback2, timeout);
|
|
56
|
+
|
|
57
|
+
expect(mockBackgroundTimerModule.setTimeout).toHaveBeenCalledWith(
|
|
58
|
+
id1,
|
|
59
|
+
timeout
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
expect(mockBackgroundTimerModule.setTimeout).toHaveBeenCalledWith(
|
|
63
|
+
id2,
|
|
64
|
+
timeout
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
expect(id1).not.toBe(id2);
|
|
68
|
+
expect(typeof id1).toBe("number");
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("should delegate clearTimeout to native module", () => {
|
|
72
|
+
const id = BackgroundTimer.setTimeout(jest.fn(), 1000);
|
|
73
|
+
BackgroundTimer.clearTimeout(id);
|
|
74
|
+
|
|
75
|
+
expect(mockBackgroundTimerModule.clearTimeout).toHaveBeenCalledWith(id);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("should execute callback when native timer fires", () => {
|
|
79
|
+
const { DeviceEventEmitter } = require("react-native");
|
|
80
|
+
const callback = jest.fn();
|
|
81
|
+
|
|
82
|
+
const id = BackgroundTimer.setTimeout(callback, 1000);
|
|
83
|
+
|
|
84
|
+
const listener = DeviceEventEmitter.addListener.mock.calls[0][1];
|
|
85
|
+
|
|
86
|
+
listener(id);
|
|
87
|
+
|
|
88
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("should cleanup callback after execution (prevent double firing)", () => {
|
|
92
|
+
const { DeviceEventEmitter } = require("react-native");
|
|
93
|
+
const callback = jest.fn();
|
|
94
|
+
|
|
95
|
+
const id = BackgroundTimer.setTimeout(callback, 1000);
|
|
96
|
+
const listener = DeviceEventEmitter.addListener.mock.calls[0][1];
|
|
97
|
+
|
|
98
|
+
listener(id);
|
|
99
|
+
listener(id);
|
|
100
|
+
|
|
101
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("should not execute callback if cleared before firing", () => {
|
|
105
|
+
const { DeviceEventEmitter } = require("react-native");
|
|
106
|
+
const callback = jest.fn();
|
|
107
|
+
|
|
108
|
+
const id = BackgroundTimer.setTimeout(callback, 1000);
|
|
109
|
+
BackgroundTimer.clearTimeout(id);
|
|
110
|
+
|
|
111
|
+
const listener = DeviceEventEmitter.addListener.mock.calls[0][1];
|
|
112
|
+
listener(id);
|
|
113
|
+
|
|
114
|
+
expect(callback).not.toHaveBeenCalled();
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it("should ignore events for unknown/invalid IDs", () => {
|
|
118
|
+
const { DeviceEventEmitter } = require("react-native");
|
|
119
|
+
const callback = jest.fn();
|
|
120
|
+
|
|
121
|
+
BackgroundTimer.setTimeout(callback, 1000);
|
|
122
|
+
|
|
123
|
+
const listener = DeviceEventEmitter.addListener.mock.calls[0][1];
|
|
124
|
+
listener(99999);
|
|
125
|
+
|
|
126
|
+
expect(callback).not.toHaveBeenCalled();
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
describe("Fallback Environment (No Native Module)", () => {
|
|
131
|
+
beforeEach(() => {
|
|
132
|
+
setupTimer(false);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it("should use global setTimeout when native module is missing", () => {
|
|
136
|
+
const callback = jest.fn();
|
|
137
|
+
const timeout = 500;
|
|
138
|
+
|
|
139
|
+
const globalSpy = jest.spyOn(global, "setTimeout");
|
|
140
|
+
|
|
141
|
+
BackgroundTimer.setTimeout(callback, timeout);
|
|
142
|
+
|
|
143
|
+
expect(globalSpy).toHaveBeenCalledWith(callback, timeout);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it("should use global clearTimeout when native module is missing", () => {
|
|
147
|
+
const callback = jest.fn();
|
|
148
|
+
const globalSpy = jest.spyOn(global, "clearTimeout");
|
|
149
|
+
|
|
150
|
+
const id = BackgroundTimer.setTimeout(callback, 500);
|
|
151
|
+
BackgroundTimer.clearTimeout(id);
|
|
152
|
+
|
|
153
|
+
expect(globalSpy).toHaveBeenCalledWith(id);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
});
|