@applicaster/zapp-react-native-utils 15.0.0-rc.94 → 15.0.0-rc.96

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.
@@ -0,0 +1,678 @@
1
+ import { getAppUrlScheme } from "../urlScheme";
2
+
3
+ // Mock dependencies
4
+ jest.mock("@applicaster/zapp-react-native-redux/AppStore", () => ({
5
+ appStore: {
6
+ get: jest.fn(),
7
+ },
8
+ }));
9
+
10
+ jest.mock("../../reactUtils", () => ({
11
+ isWeb: jest.fn(),
12
+ }));
13
+
14
+ jest.mock("../../stringUtils", () => ({
15
+ isString: jest.fn((value) => typeof value === "string"),
16
+ }));
17
+
18
+ import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
19
+ import { isWeb } from "../../reactUtils";
20
+ import { isString } from "../../stringUtils";
21
+
22
+ describe("appDataUtils - urlScheme", () => {
23
+ const mockAppStoreGet = appStore.get as jest.MockedFunction<
24
+ typeof appStore.get
25
+ >;
26
+
27
+ const mockIsWeb = isWeb as jest.MockedFunction<typeof isWeb>;
28
+ const mockIsString = isString as jest.MockedFunction<typeof isString>;
29
+
30
+ beforeEach(() => {
31
+ jest.clearAllMocks();
32
+
33
+ // Default mocks
34
+ mockIsWeb.mockReturnValue(false);
35
+ mockIsString.mockImplementation((value) => typeof value === "string");
36
+ });
37
+
38
+ describe("getAppUrlScheme", () => {
39
+ describe("web platform", () => {
40
+ it("should return 'self' when running on web", () => {
41
+ mockIsWeb.mockReturnValue(true);
42
+
43
+ mockAppStoreGet.mockReturnValue({
44
+ urlScheme: "myapp",
45
+ });
46
+
47
+ const result = getAppUrlScheme();
48
+
49
+ expect(result).toBe("self");
50
+ expect(mockAppStoreGet).toHaveBeenCalledWith("appData");
51
+ });
52
+
53
+ it("should return 'self' on web even when urlScheme is missing", () => {
54
+ mockIsWeb.mockReturnValue(true);
55
+ mockAppStoreGet.mockReturnValue({});
56
+
57
+ const result = getAppUrlScheme();
58
+
59
+ expect(result).toBe("self");
60
+ });
61
+
62
+ it("should return 'self' on web even when appData is null", () => {
63
+ mockIsWeb.mockReturnValue(true);
64
+ mockAppStoreGet.mockReturnValue(null);
65
+
66
+ const result = getAppUrlScheme();
67
+
68
+ expect(result).toBe("self");
69
+ });
70
+ });
71
+
72
+ describe("native platform - basic functionality", () => {
73
+ it("should return first URL scheme from urlScheme string", () => {
74
+ mockIsWeb.mockReturnValue(false);
75
+
76
+ mockAppStoreGet.mockReturnValue({
77
+ urlScheme: "myapp",
78
+ });
79
+
80
+ const result = getAppUrlScheme();
81
+
82
+ expect(result).toBe("myapp");
83
+ });
84
+
85
+ it("should return first scheme from comma-separated list", () => {
86
+ mockIsWeb.mockReturnValue(false);
87
+
88
+ mockAppStoreGet.mockReturnValue({
89
+ urlScheme: "myapp,secondapp,thirdapp",
90
+ });
91
+
92
+ const result = getAppUrlScheme();
93
+
94
+ expect(result).toBe("myapp");
95
+ });
96
+
97
+ it("should handle URL scheme with spaces after comma", () => {
98
+ mockIsWeb.mockReturnValue(false);
99
+
100
+ mockAppStoreGet.mockReturnValue({
101
+ urlScheme: "myapp, secondapp, thirdapp",
102
+ });
103
+
104
+ const result = getAppUrlScheme();
105
+
106
+ expect(result).toBe("myapp");
107
+ });
108
+
109
+ it("should return undefined when urlScheme is missing", () => {
110
+ mockIsWeb.mockReturnValue(false);
111
+
112
+ mockAppStoreGet.mockReturnValue({
113
+ appName: "My App",
114
+ });
115
+
116
+ const result = getAppUrlScheme();
117
+
118
+ expect(result).toBeUndefined();
119
+ });
120
+
121
+ it("should return undefined when urlScheme is null", () => {
122
+ mockIsWeb.mockReturnValue(false);
123
+
124
+ mockAppStoreGet.mockReturnValue({
125
+ urlScheme: null,
126
+ });
127
+
128
+ const result = getAppUrlScheme();
129
+
130
+ expect(result).toBeUndefined();
131
+ });
132
+
133
+ it("should return undefined when urlScheme is undefined", () => {
134
+ mockIsWeb.mockReturnValue(false);
135
+
136
+ mockAppStoreGet.mockReturnValue({
137
+ urlScheme: undefined,
138
+ });
139
+
140
+ const result = getAppUrlScheme();
141
+
142
+ expect(result).toBeUndefined();
143
+ });
144
+ });
145
+
146
+ describe("native platform - string cleaning", () => {
147
+ it("should remove square brackets from urlScheme", () => {
148
+ mockIsWeb.mockReturnValue(false);
149
+
150
+ mockAppStoreGet.mockReturnValue({
151
+ urlScheme: "[myapp]",
152
+ });
153
+
154
+ const result = getAppUrlScheme();
155
+
156
+ expect(result).toBe("myapp");
157
+ });
158
+
159
+ it("should remove single quotes from urlScheme", () => {
160
+ mockIsWeb.mockReturnValue(false);
161
+
162
+ mockAppStoreGet.mockReturnValue({
163
+ urlScheme: "'myapp'",
164
+ });
165
+
166
+ const result = getAppUrlScheme();
167
+
168
+ expect(result).toBe("myapp");
169
+ });
170
+
171
+ it("should remove brackets and quotes from urlScheme", () => {
172
+ mockIsWeb.mockReturnValue(false);
173
+
174
+ mockAppStoreGet.mockReturnValue({
175
+ urlScheme: "['myapp']",
176
+ });
177
+
178
+ const result = getAppUrlScheme();
179
+
180
+ expect(result).toBe("myapp");
181
+ });
182
+
183
+ it("should remove multiple brackets and quotes", () => {
184
+ mockIsWeb.mockReturnValue(false);
185
+
186
+ mockAppStoreGet.mockReturnValue({
187
+ urlScheme: "[['myapp']]",
188
+ });
189
+
190
+ const result = getAppUrlScheme();
191
+
192
+ expect(result).toBe("myapp");
193
+ });
194
+
195
+ it("should clean comma-separated list with brackets", () => {
196
+ mockIsWeb.mockReturnValue(false);
197
+
198
+ mockAppStoreGet.mockReturnValue({
199
+ urlScheme: "['myapp','secondapp']",
200
+ });
201
+
202
+ const result = getAppUrlScheme();
203
+
204
+ expect(result).toBe("myapp");
205
+ });
206
+
207
+ it("should return null when cleaned string is empty", () => {
208
+ mockIsWeb.mockReturnValue(false);
209
+
210
+ mockAppStoreGet.mockReturnValue({
211
+ urlScheme: "[]",
212
+ });
213
+
214
+ const result = getAppUrlScheme();
215
+
216
+ expect(result).toBeNull();
217
+ });
218
+
219
+ it("should return null when urlScheme contains only quotes and brackets", () => {
220
+ mockIsWeb.mockReturnValue(false);
221
+
222
+ mockAppStoreGet.mockReturnValue({
223
+ urlScheme: "['']",
224
+ });
225
+
226
+ const result = getAppUrlScheme();
227
+
228
+ expect(result).toBeNull();
229
+ });
230
+
231
+ it("should preserve hyphens in URL scheme", () => {
232
+ mockIsWeb.mockReturnValue(false);
233
+
234
+ mockAppStoreGet.mockReturnValue({
235
+ urlScheme: "my-app-scheme",
236
+ });
237
+
238
+ const result = getAppUrlScheme();
239
+
240
+ expect(result).toBe("my-app-scheme");
241
+ });
242
+
243
+ it("should preserve dots in URL scheme", () => {
244
+ mockIsWeb.mockReturnValue(false);
245
+
246
+ mockAppStoreGet.mockReturnValue({
247
+ urlScheme: "com.example.app",
248
+ });
249
+
250
+ const result = getAppUrlScheme();
251
+
252
+ expect(result).toBe("com.example.app");
253
+ });
254
+
255
+ it("should preserve colons in URL scheme", () => {
256
+ mockIsWeb.mockReturnValue(false);
257
+
258
+ mockAppStoreGet.mockReturnValue({
259
+ urlScheme: "myapp://",
260
+ });
261
+
262
+ const result = getAppUrlScheme();
263
+
264
+ expect(result).toBe("myapp://");
265
+ });
266
+ });
267
+
268
+ describe("native platform - type validation", () => {
269
+ it("should return null when urlScheme is not a string (number)", () => {
270
+ mockIsWeb.mockReturnValue(false);
271
+ mockIsString.mockReturnValue(false);
272
+
273
+ mockAppStoreGet.mockReturnValue({
274
+ urlScheme: 12345,
275
+ });
276
+
277
+ const result = getAppUrlScheme();
278
+
279
+ expect(result).toBeNull();
280
+ });
281
+
282
+ it("should return null when urlScheme is not a string (boolean)", () => {
283
+ mockIsWeb.mockReturnValue(false);
284
+ mockIsString.mockReturnValue(false);
285
+
286
+ mockAppStoreGet.mockReturnValue({
287
+ urlScheme: true,
288
+ });
289
+
290
+ const result = getAppUrlScheme();
291
+
292
+ expect(result).toBeNull();
293
+ });
294
+
295
+ it("should return null when urlScheme is not a string (object)", () => {
296
+ mockIsWeb.mockReturnValue(false);
297
+ mockIsString.mockReturnValue(false);
298
+
299
+ mockAppStoreGet.mockReturnValue({
300
+ urlScheme: { scheme: "myapp" },
301
+ });
302
+
303
+ const result = getAppUrlScheme();
304
+
305
+ expect(result).toBeNull();
306
+ });
307
+
308
+ it("should return null when urlScheme is not a string (array)", () => {
309
+ mockIsWeb.mockReturnValue(false);
310
+ mockIsString.mockReturnValue(false);
311
+
312
+ mockAppStoreGet.mockReturnValue({
313
+ urlScheme: ["myapp", "secondapp"],
314
+ });
315
+
316
+ const result = getAppUrlScheme();
317
+
318
+ expect(result).toBeNull();
319
+ });
320
+ });
321
+
322
+ describe("native platform - empty string handling", () => {
323
+ it("should return undefined when urlScheme is empty string", () => {
324
+ mockIsWeb.mockReturnValue(false);
325
+
326
+ mockAppStoreGet.mockReturnValue({
327
+ urlScheme: "",
328
+ });
329
+
330
+ const result = getAppUrlScheme();
331
+
332
+ // Empty string is falsy, function returns undefined (no return statement)
333
+ expect(result).toBeUndefined();
334
+ });
335
+
336
+ it("should return whitespace when urlScheme is only whitespace", () => {
337
+ mockIsWeb.mockReturnValue(false);
338
+
339
+ mockAppStoreGet.mockReturnValue({
340
+ urlScheme: " ",
341
+ });
342
+
343
+ const result = getAppUrlScheme();
344
+
345
+ // Whitespace is preserved by getCleanString, then split by comma
346
+ // urlSchemes[0] returns " " which is truthy, so || null doesn't trigger
347
+ expect(result).toBe(" ");
348
+ });
349
+
350
+ it("should handle empty string after cleaning", () => {
351
+ mockIsWeb.mockReturnValue(false);
352
+
353
+ mockAppStoreGet.mockReturnValue({
354
+ urlScheme: "''",
355
+ });
356
+
357
+ const result = getAppUrlScheme();
358
+
359
+ expect(result).toBeNull();
360
+ });
361
+ });
362
+
363
+ describe("native platform - comma-separated schemes", () => {
364
+ it("should return first scheme when multiple schemes present", () => {
365
+ mockIsWeb.mockReturnValue(false);
366
+
367
+ mockAppStoreGet.mockReturnValue({
368
+ urlScheme: "scheme1,scheme2,scheme3",
369
+ });
370
+
371
+ const result = getAppUrlScheme();
372
+
373
+ expect(result).toBe("scheme1");
374
+ });
375
+
376
+ it("should handle two schemes", () => {
377
+ mockIsWeb.mockReturnValue(false);
378
+
379
+ mockAppStoreGet.mockReturnValue({
380
+ urlScheme: "primary,fallback",
381
+ });
382
+
383
+ const result = getAppUrlScheme();
384
+
385
+ expect(result).toBe("primary");
386
+ });
387
+
388
+ it("should return null when first scheme is empty", () => {
389
+ mockIsWeb.mockReturnValue(false);
390
+
391
+ mockAppStoreGet.mockReturnValue({
392
+ urlScheme: ",secondapp",
393
+ });
394
+
395
+ const result = getAppUrlScheme();
396
+
397
+ // Empty string is falsy, so || null returns null
398
+ expect(result).toBeNull();
399
+ });
400
+
401
+ it("should handle scheme with trailing comma", () => {
402
+ mockIsWeb.mockReturnValue(false);
403
+
404
+ mockAppStoreGet.mockReturnValue({
405
+ urlScheme: "myapp,",
406
+ });
407
+
408
+ const result = getAppUrlScheme();
409
+
410
+ expect(result).toBe("myapp");
411
+ });
412
+
413
+ it("should handle complex comma-separated list with brackets", () => {
414
+ mockIsWeb.mockReturnValue(false);
415
+
416
+ mockAppStoreGet.mockReturnValue({
417
+ urlScheme: "['app1','app2','app3']",
418
+ });
419
+
420
+ const result = getAppUrlScheme();
421
+
422
+ expect(result).toBe("app1");
423
+ });
424
+ });
425
+
426
+ describe("native platform - appStore edge cases", () => {
427
+ it("should handle when appStore.get returns null", () => {
428
+ mockIsWeb.mockReturnValue(false);
429
+ mockAppStoreGet.mockReturnValue(null);
430
+
431
+ const result = getAppUrlScheme();
432
+
433
+ expect(result).toBeUndefined();
434
+ });
435
+
436
+ it("should handle when appStore.get returns undefined", () => {
437
+ mockIsWeb.mockReturnValue(false);
438
+ mockAppStoreGet.mockReturnValue(undefined);
439
+
440
+ const result = getAppUrlScheme();
441
+
442
+ expect(result).toBeUndefined();
443
+ });
444
+
445
+ it("should handle when appData is empty object", () => {
446
+ mockIsWeb.mockReturnValue(false);
447
+ mockAppStoreGet.mockReturnValue({});
448
+
449
+ const result = getAppUrlScheme();
450
+
451
+ expect(result).toBeUndefined();
452
+ });
453
+
454
+ it("should only access urlScheme property from appData", () => {
455
+ mockIsWeb.mockReturnValue(false);
456
+
457
+ mockAppStoreGet.mockReturnValue({
458
+ urlScheme: "myapp",
459
+ appName: "My Application",
460
+ version: "1.0.0",
461
+ });
462
+
463
+ const result = getAppUrlScheme();
464
+
465
+ expect(result).toBe("myapp");
466
+ expect(mockAppStoreGet).toHaveBeenCalledWith("appData");
467
+ expect(mockAppStoreGet).toHaveBeenCalledTimes(1);
468
+ });
469
+ });
470
+
471
+ describe("native platform - special characters", () => {
472
+ it("should handle URL scheme with numbers", () => {
473
+ mockIsWeb.mockReturnValue(false);
474
+
475
+ mockAppStoreGet.mockReturnValue({
476
+ urlScheme: "myapp123",
477
+ });
478
+
479
+ const result = getAppUrlScheme();
480
+
481
+ expect(result).toBe("myapp123");
482
+ });
483
+
484
+ it("should handle URL scheme with uppercase letters", () => {
485
+ mockIsWeb.mockReturnValue(false);
486
+
487
+ mockAppStoreGet.mockReturnValue({
488
+ urlScheme: "MyApp",
489
+ });
490
+
491
+ const result = getAppUrlScheme();
492
+
493
+ expect(result).toBe("MyApp");
494
+ });
495
+
496
+ it("should handle URL scheme with underscores", () => {
497
+ mockIsWeb.mockReturnValue(false);
498
+
499
+ mockAppStoreGet.mockReturnValue({
500
+ urlScheme: "my_app_scheme",
501
+ });
502
+
503
+ const result = getAppUrlScheme();
504
+
505
+ expect(result).toBe("my_app_scheme");
506
+ });
507
+
508
+ it("should handle complex URL scheme format", () => {
509
+ mockIsWeb.mockReturnValue(false);
510
+
511
+ mockAppStoreGet.mockReturnValue({
512
+ urlScheme: "com.example.myapp://deep/link",
513
+ });
514
+
515
+ const result = getAppUrlScheme();
516
+
517
+ expect(result).toBe("com.example.myapp://deep/link");
518
+ });
519
+
520
+ it("should preserve plus signs in URL scheme", () => {
521
+ mockIsWeb.mockReturnValue(false);
522
+
523
+ mockAppStoreGet.mockReturnValue({
524
+ urlScheme: "myapp+custom",
525
+ });
526
+
527
+ const result = getAppUrlScheme();
528
+
529
+ expect(result).toBe("myapp+custom");
530
+ });
531
+ });
532
+
533
+ describe("native platform - integration scenarios", () => {
534
+ it("should handle real-world iOS URL scheme", () => {
535
+ mockIsWeb.mockReturnValue(false);
536
+
537
+ mockAppStoreGet.mockReturnValue({
538
+ urlScheme: "['myiosapp']",
539
+ });
540
+
541
+ const result = getAppUrlScheme();
542
+
543
+ expect(result).toBe("myiosapp");
544
+ });
545
+
546
+ it("should handle real-world Android URL scheme", () => {
547
+ mockIsWeb.mockReturnValue(false);
548
+
549
+ mockAppStoreGet.mockReturnValue({
550
+ urlScheme: "myandroidapp",
551
+ });
552
+
553
+ const result = getAppUrlScheme();
554
+
555
+ expect(result).toBe("myandroidapp");
556
+ });
557
+
558
+ it("should handle multi-platform URL scheme configuration", () => {
559
+ mockIsWeb.mockReturnValue(false);
560
+
561
+ mockAppStoreGet.mockReturnValue({
562
+ urlScheme: "['myapp', 'myapp-dev', 'myapp-staging']",
563
+ });
564
+
565
+ const result = getAppUrlScheme();
566
+
567
+ expect(result).toBe("myapp");
568
+ });
569
+
570
+ it("should handle URL scheme with protocol separator", () => {
571
+ mockIsWeb.mockReturnValue(false);
572
+
573
+ mockAppStoreGet.mockReturnValue({
574
+ urlScheme: "myapp://",
575
+ });
576
+
577
+ const result = getAppUrlScheme();
578
+
579
+ expect(result).toBe("myapp://");
580
+ });
581
+ });
582
+
583
+ describe("native platform - null/undefined return values", () => {
584
+ it("should return null when only brackets remain after cleaning", () => {
585
+ mockIsWeb.mockReturnValue(false);
586
+
587
+ mockAppStoreGet.mockReturnValue({
588
+ urlScheme: "[[]]",
589
+ });
590
+
591
+ const result = getAppUrlScheme();
592
+
593
+ expect(result).toBeNull();
594
+ });
595
+
596
+ it("should return null when cleaned result is zero-length", () => {
597
+ mockIsWeb.mockReturnValue(false);
598
+
599
+ mockAppStoreGet.mockReturnValue({
600
+ urlScheme: "''",
601
+ });
602
+
603
+ const result = getAppUrlScheme();
604
+
605
+ expect(result).toBeNull();
606
+ });
607
+
608
+ it("should return null for array-like string with no content", () => {
609
+ mockIsWeb.mockReturnValue(false);
610
+
611
+ mockAppStoreGet.mockReturnValue({
612
+ urlScheme: "['', '']",
613
+ });
614
+
615
+ const result = getAppUrlScheme();
616
+
617
+ expect(result).toBeNull();
618
+ });
619
+ });
620
+
621
+ describe("isWeb dependency", () => {
622
+ it("should call isWeb to check platform", () => {
623
+ mockIsWeb.mockReturnValue(false);
624
+
625
+ mockAppStoreGet.mockReturnValue({
626
+ urlScheme: "myapp",
627
+ });
628
+
629
+ getAppUrlScheme();
630
+
631
+ expect(mockIsWeb).toHaveBeenCalledTimes(1);
632
+ expect(mockIsWeb).toHaveBeenCalledWith();
633
+ });
634
+
635
+ it("should prioritize web check before appStore access", () => {
636
+ mockIsWeb.mockReturnValue(true);
637
+
638
+ mockAppStoreGet.mockReturnValue({
639
+ urlScheme: "myapp",
640
+ });
641
+
642
+ const result = getAppUrlScheme();
643
+
644
+ expect(result).toBe("self");
645
+ expect(mockIsWeb).toHaveBeenCalled();
646
+ expect(mockAppStoreGet).toHaveBeenCalled();
647
+ });
648
+ });
649
+
650
+ describe("isString dependency", () => {
651
+ it("should call isString to validate urlScheme type", () => {
652
+ mockIsWeb.mockReturnValue(false);
653
+
654
+ mockAppStoreGet.mockReturnValue({
655
+ urlScheme: "myapp",
656
+ });
657
+
658
+ getAppUrlScheme();
659
+
660
+ expect(mockIsString).toHaveBeenCalledWith("myapp");
661
+ });
662
+
663
+ it("should handle isString returning false", () => {
664
+ mockIsWeb.mockReturnValue(false);
665
+ mockIsString.mockReturnValue(false);
666
+
667
+ mockAppStoreGet.mockReturnValue({
668
+ urlScheme: 123,
669
+ });
670
+
671
+ const result = getAppUrlScheme();
672
+
673
+ expect(result).toBeNull();
674
+ expect(mockIsString).toHaveBeenCalledWith(123);
675
+ });
676
+ });
677
+ });
678
+ });