@capillarytech/creatives-library 8.0.130 → 8.0.132

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 (77) hide show
  1. package/containers/App/constants.js +1 -0
  2. package/containers/Login/index.js +1 -2
  3. package/package.json +1 -1
  4. package/services/api.js +5 -0
  5. package/tests/integration/TemplateCreation/TemplateCreation.integration.test.js +8 -3
  6. package/tests/integration/TemplateCreation/api-response.js +5 -0
  7. package/tests/integration/TemplateCreation/msw-handler.js +42 -63
  8. package/utils/common.js +7 -0
  9. package/utils/commonUtils.js +2 -6
  10. package/utils/createMobilePushPayload.js +322 -0
  11. package/utils/tests/createMobilePushPayload.test.js +1054 -0
  12. package/v2Components/CapDeviceContent/index.js +1 -1
  13. package/v2Components/CapImageUpload/index.js +57 -44
  14. package/v2Components/CapInAppCTA/index.js +1 -0
  15. package/v2Components/CapMpushCTA/constants.js +25 -0
  16. package/v2Components/CapMpushCTA/index.js +403 -0
  17. package/v2Components/CapMpushCTA/index.scss +95 -0
  18. package/v2Components/CapMpushCTA/messages.js +101 -0
  19. package/v2Components/CapTagList/index.js +178 -121
  20. package/v2Components/CapVideoUpload/constants.js +3 -0
  21. package/v2Components/CapVideoUpload/index.js +182 -115
  22. package/v2Components/CapVideoUpload/messages.js +16 -0
  23. package/v2Components/Carousel/index.js +15 -13
  24. package/v2Components/ErrorInfoNote/style.scss +1 -0
  25. package/v2Components/MobilePushPreviewV2/index.js +57 -12
  26. package/v2Components/TemplatePreview/_templatePreview.scss +218 -74
  27. package/v2Components/TemplatePreview/assets/images/Android_With_date_and_time.svg +29 -0
  28. package/v2Components/TemplatePreview/assets/images/android.svg +9 -0
  29. package/v2Components/TemplatePreview/assets/images/iOS_With_date_and_time.svg +26 -0
  30. package/v2Components/TemplatePreview/assets/images/ios.svg +9 -0
  31. package/v2Components/TemplatePreview/index.js +234 -107
  32. package/v2Components/TemplatePreview/messages.js +4 -0
  33. package/v2Components/TemplatePreview/tests/__snapshots__/index.test.js.snap +10 -10
  34. package/v2Containers/CreativesContainer/SlideBoxContent.js +127 -62
  35. package/v2Containers/CreativesContainer/index.js +193 -136
  36. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -22
  37. package/v2Containers/InApp/constants.js +1 -0
  38. package/v2Containers/InApp/index.js +13 -13
  39. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +4748 -4658
  40. package/v2Containers/Login/index.js +1 -2
  41. package/v2Containers/MobilePush/Create/index.js +1 -0
  42. package/v2Containers/MobilePush/commonMethods.js +7 -14
  43. package/v2Containers/MobilePush/tests/commonMethods.test.js +401 -0
  44. package/v2Containers/MobilePushNew/actions.js +116 -0
  45. package/v2Containers/MobilePushNew/components/CtaButtons.js +183 -0
  46. package/v2Containers/MobilePushNew/components/MediaUploaders.js +835 -0
  47. package/v2Containers/MobilePushNew/components/PlatformContentFields.js +346 -0
  48. package/v2Containers/MobilePushNew/components/index.js +5 -0
  49. package/v2Containers/MobilePushNew/components/tests/CtaButtons.test.js +565 -0
  50. package/v2Containers/MobilePushNew/components/tests/MediaUploaders.test.js +3180 -0
  51. package/v2Containers/MobilePushNew/components/tests/PlatformContentFields.test.js +654 -0
  52. package/v2Containers/MobilePushNew/constants.js +116 -0
  53. package/v2Containers/MobilePushNew/hooks/tests/usePlatformSync.test.js +1462 -0
  54. package/v2Containers/MobilePushNew/hooks/tests/useUpload.test.js +1459 -0
  55. package/v2Containers/MobilePushNew/hooks/usePlatformSync.js +366 -0
  56. package/v2Containers/MobilePushNew/hooks/useUpload.js +740 -0
  57. package/v2Containers/MobilePushNew/index.js +2158 -0
  58. package/v2Containers/MobilePushNew/index.scss +308 -0
  59. package/v2Containers/MobilePushNew/messages.js +272 -0
  60. package/v2Containers/MobilePushNew/reducer.js +160 -0
  61. package/v2Containers/MobilePushNew/sagas.js +193 -0
  62. package/v2Containers/MobilePushNew/selectors.js +55 -0
  63. package/v2Containers/MobilePushNew/tests/reducer.test.js +741 -0
  64. package/v2Containers/MobilePushNew/tests/sagas.test.js +864 -0
  65. package/v2Containers/MobilePushNew/tests/selectors.test.js +665 -0
  66. package/v2Containers/MobilePushNew/tests/utils.test.js +421 -0
  67. package/v2Containers/MobilePushNew/utils.js +84 -0
  68. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +1176 -976
  69. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +684 -424
  70. package/v2Containers/TagList/index.js +56 -10
  71. package/v2Containers/Templates/_templates.scss +100 -1
  72. package/v2Containers/Templates/index.js +170 -31
  73. package/v2Containers/Templates/messages.js +8 -0
  74. package/v2Containers/Templates/sagas.js +1 -0
  75. package/v2Containers/Whatsapp/constants.js +1 -0
  76. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +3992 -3677
  77. package/assets/loading_img.gif +0 -0
@@ -0,0 +1,1459 @@
1
+ import { renderHook, act } from '@testing-library/react';
2
+ import useUpload from '../useUpload';
3
+ import {
4
+ ANDROID,
5
+ IOS,
6
+ MOBILE_PUSH_CHANNEL,
7
+ MPUSH_IMG_SIZE,
8
+ MPUSH_VIDEO_SIZE,
9
+ MPUSH_GIF_SIZE,
10
+ IMAGE,
11
+ VIDEO,
12
+ GIF,
13
+ CAROUSEL,
14
+ } from '../../constants';
15
+
16
+ // Mock cdnTransformation module
17
+ jest.mock('../../../../utils/cdnTransformation', () => ({
18
+ getCdnUrl: ({ url, channelName }) => {
19
+ if (!url) return '';
20
+ return `cdn/${channelName}/${url}`;
21
+ },
22
+ getLocalStorageItem: (key, parse = false) => {
23
+ const mockData = {
24
+ CREATIVES_CDN_BASE_URL: 'https://cdn.example.com',
25
+ CREATIVES_CDN_QUALITY_CONFIG: '{"MOBILEPUSH":75,"DEFAULT":80}',
26
+ CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX: 'cdn-cgi/image',
27
+ CREATIVES_S3_BUCKET_PATH: 'intouch_creative_assets',
28
+ };
29
+ const val = mockData[key];
30
+ if (parse && val) {
31
+ return JSON.parse(val);
32
+ }
33
+ return val;
34
+ },
35
+ }));
36
+
37
+ describe('useUpload Hook', () => {
38
+ // Mock data and functions
39
+ let mockMobilePushActions;
40
+ let androidContent;
41
+ let iosContent;
42
+ let mockSetAndroidContent;
43
+ let mockSetIosContent;
44
+
45
+ // Mock formatMessage function
46
+ const mockFormatMessage = (message, values = {}) => {
47
+ if (message.id === 'app.containers.MobilePushNew.fileSizeError') {
48
+ return `File size should be less than ${values.size}MB`;
49
+ }
50
+ if (message.id === 'app.containers.MobilePushNew.imageFileTypeError') {
51
+ return 'Only JPEG and PNG files are allowed';
52
+ }
53
+ if (message.id === 'app.containers.MobilePushNew.videoFileTypeError') {
54
+ return 'Only 3GP, MP4, MOV, M4V files are allowed';
55
+ }
56
+ if (message.id === 'app.containers.MobilePushNew.gifFileTypeError') {
57
+ return 'Only GIF files are allowed';
58
+ }
59
+ return message.defaultMessage;
60
+ };
61
+
62
+ // Helper function to create hook instance
63
+ const createHook = (props = {}) => renderHook(() => useUpload(
64
+ mockMobilePushActions,
65
+ props.editData || {},
66
+ props.uploadedAssetData0 || {},
67
+ props.uploadedAssetData1 || {},
68
+ props.uploadAssetSuccess || false,
69
+ props.sameContent || false,
70
+ mockSetAndroidContent,
71
+ mockSetIosContent,
72
+ props.activeTab || ANDROID,
73
+ androidContent,
74
+ iosContent,
75
+ mockFormatMessage,
76
+ ));
77
+
78
+ beforeEach(() => {
79
+ mockMobilePushActions = {
80
+ uploadAsset: jest.fn(),
81
+ clearAsset: jest.fn(),
82
+ };
83
+
84
+ androidContent = { title: 'Test Android', message: 'Test message' };
85
+ iosContent = { title: 'Test iOS', message: 'Test message' };
86
+
87
+ mockSetAndroidContent = jest.fn((updater) => {
88
+ if (typeof updater === 'function') {
89
+ androidContent = updater(androidContent);
90
+ } else {
91
+ androidContent = { ...androidContent, ...updater };
92
+ }
93
+ });
94
+
95
+ mockSetIosContent = jest.fn((updater) => {
96
+ if (typeof updater === 'function') {
97
+ iosContent = updater(iosContent);
98
+ } else {
99
+ iosContent = { ...iosContent, ...updater };
100
+ }
101
+ });
102
+
103
+ // Reset all mocks
104
+ jest.clearAllMocks();
105
+ });
106
+
107
+ describe('Asset Upload', () => {
108
+ it('should handle image upload with validation', () => {
109
+ const { result } = createHook();
110
+
111
+ // Test valid image upload
112
+ const validFile = new File([''], 'test.jpg', { type: 'image/jpeg' });
113
+ Object.defineProperty(validFile, 'size', { value: MPUSH_IMG_SIZE - 1000 }); // Just under limit
114
+ act(() => {
115
+ result.current.uploadMpushAsset(validFile, IMAGE.toLowerCase(), {});
116
+ });
117
+ expect(mockMobilePushActions.uploadAsset).toHaveBeenCalledWith(
118
+ validFile,
119
+ IMAGE.toLowerCase(),
120
+ {},
121
+ 0,
122
+ { source: MOBILE_PUSH_CHANNEL.toLowerCase(), channel: MOBILE_PUSH_CHANNEL }
123
+ );
124
+
125
+ // Test invalid image upload
126
+ const invalidFile = new File([''], 'test.txt', { type: 'text/plain' });
127
+ act(() => {
128
+ result.current.uploadMpushAsset(invalidFile, IMAGE.toLowerCase(), {});
129
+ });
130
+ expect(result.current.uploadErrors[0]).toEqual(['Only JPEG and PNG files are allowed']);
131
+ });
132
+
133
+ it('should handle video upload with validation', () => {
134
+ const { result } = createHook();
135
+
136
+ // Test valid video upload
137
+ const validFile = new File([''], 'test.mp4', { type: 'video/mp4' });
138
+ Object.defineProperty(validFile, 'size', { value: MPUSH_VIDEO_SIZE - 1000 }); // Just under limit
139
+ act(() => {
140
+ result.current.uploadMpushAsset(validFile, VIDEO.toLowerCase(), {});
141
+ });
142
+ expect(mockMobilePushActions.uploadAsset).toHaveBeenCalledWith(
143
+ validFile,
144
+ VIDEO.toLowerCase(),
145
+ {},
146
+ 0,
147
+ { source: MOBILE_PUSH_CHANNEL.toLowerCase(), channel: MOBILE_PUSH_CHANNEL }
148
+ );
149
+
150
+ // Test invalid video upload
151
+ const invalidFile = new File([''], 'test.txt', { type: 'text/plain' });
152
+ act(() => {
153
+ result.current.uploadMpushAsset(invalidFile, VIDEO.toLowerCase(), {});
154
+ });
155
+ expect(result.current.uploadErrors[0]).toEqual(['Only 3GP, MP4, MOV, M4V files are allowed']);
156
+ });
157
+
158
+ it('should handle GIF upload with validation', () => {
159
+ const { result } = createHook();
160
+
161
+ // Test valid GIF upload
162
+ const validFile = new File([''], 'test.gif', { type: 'image/gif' });
163
+ Object.defineProperty(validFile, 'size', { value: MPUSH_GIF_SIZE - 1000 }); // Just under limit
164
+ act(() => {
165
+ result.current.uploadMpushAsset(validFile, GIF.toLowerCase(), {});
166
+ });
167
+ expect(mockMobilePushActions.uploadAsset).toHaveBeenCalledWith(
168
+ validFile,
169
+ VIDEO.toLowerCase(), // GIF uses video type internally
170
+ {},
171
+ 0,
172
+ { source: MOBILE_PUSH_CHANNEL.toLowerCase(), channel: MOBILE_PUSH_CHANNEL }
173
+ );
174
+
175
+ // Test invalid GIF upload
176
+ const invalidFile = new File([''], 'test.jpg', { type: 'image/jpeg' });
177
+ act(() => {
178
+ result.current.uploadMpushAsset(invalidFile, GIF.toLowerCase(), {});
179
+ });
180
+ expect(result.current.uploadErrors[0]).toEqual(['Only GIF files are allowed']);
181
+ });
182
+ });
183
+
184
+ describe('Media Payload Generation', () => {
185
+ it('should generate correct payload for IMAGE type', () => {
186
+ const { result } = createHook();
187
+
188
+ act(() => {
189
+ result.current.setImageSrc({
190
+ androidImageSrc: 'test-image.jpg',
191
+ iosImageSrc: 'test-image-ios.jpg',
192
+ });
193
+ });
194
+
195
+ const androidPayload = result.current.getMediaPayload(IMAGE, ANDROID);
196
+ expect(androidPayload).toHaveProperty('imageUrl');
197
+ expect(androidPayload.imageUrl).toBe('cdn/MOBILEPUSH/test-image.jpg');
198
+
199
+ const iosPayload = result.current.getMediaPayload(IMAGE, IOS);
200
+ expect(iosPayload).toHaveProperty('imageUrl');
201
+ expect(iosPayload.imageUrl).toBe('cdn/MOBILEPUSH/test-image-ios.jpg');
202
+ });
203
+
204
+ it('should generate correct payload for VIDEO type', () => {
205
+ const { result } = createHook();
206
+
207
+ act(() => {
208
+ result.current.setVideoState({
209
+ androidVideoSrc: 'test-video.mp4',
210
+ androidVideoPreview: 'test-preview.jpg',
211
+ androidVideoDuration: 30,
212
+ iosVideoSrc: 'test-video-ios.mp4',
213
+ iosVideoPreview: 'test-preview-ios.jpg',
214
+ iosVideoDuration: 30,
215
+ });
216
+ });
217
+
218
+ const androidPayload = result.current.getMediaPayload(VIDEO, ANDROID);
219
+ expect(androidPayload).toHaveProperty('videoUrl');
220
+ expect(androidPayload).toHaveProperty('videoPreviewImg');
221
+ expect(androidPayload).toHaveProperty('duration');
222
+ expect(androidPayload.videoUrl).toBe('cdn/MOBILEPUSH/test-video.mp4');
223
+ expect(androidPayload.videoPreviewImg).toBe('cdn/MOBILEPUSH/test-preview.jpg');
224
+ expect(androidPayload.duration).toBe(30);
225
+
226
+ const iosPayload = result.current.getMediaPayload(VIDEO, IOS);
227
+ expect(iosPayload).toHaveProperty('videoUrl');
228
+ expect(iosPayload).toHaveProperty('videoPreviewImg');
229
+ expect(iosPayload).toHaveProperty('duration');
230
+ expect(iosPayload.videoUrl).toBe('cdn/MOBILEPUSH/test-video-ios.mp4');
231
+ expect(iosPayload.videoPreviewImg).toBe('cdn/MOBILEPUSH/test-preview-ios.jpg');
232
+ expect(iosPayload.duration).toBe(30);
233
+ });
234
+
235
+ it('should generate correct payload for GIF type', () => {
236
+ const { result } = createHook();
237
+
238
+ act(() => {
239
+ result.current.setVideoState({
240
+ androidVideoSrc: 'test.gif',
241
+ androidVideoPreview: 'test-preview.jpg',
242
+ iosVideoSrc: 'test-ios.gif',
243
+ iosVideoPreview: 'test-preview-ios.jpg',
244
+ });
245
+ });
246
+
247
+ const androidPayload = result.current.getMediaPayload(GIF, ANDROID);
248
+ expect(androidPayload).toHaveProperty('gifUrl');
249
+ expect(androidPayload).toHaveProperty('gifPreviewImg');
250
+ expect(androidPayload.gifUrl).toBe('cdn/MOBILEPUSH/test.gif');
251
+ expect(androidPayload.gifPreviewImg).toBe('cdn/MOBILEPUSH/test-preview.jpg');
252
+
253
+ const iosPayload = result.current.getMediaPayload(GIF, IOS);
254
+ expect(iosPayload).toHaveProperty('gifUrl');
255
+ expect(iosPayload).toHaveProperty('gifPreviewImg');
256
+ expect(iosPayload.gifUrl).toBe('cdn/MOBILEPUSH/test-ios.gif');
257
+ expect(iosPayload.gifPreviewImg).toBe('cdn/MOBILEPUSH/test-preview-ios.jpg');
258
+ });
259
+
260
+ it('should return empty object for unknown media type', () => {
261
+ const { result } = createHook();
262
+ const payload = result.current.getMediaPayload('UNKNOWN', ANDROID);
263
+ expect(payload).toEqual({});
264
+ });
265
+ });
266
+
267
+ describe('Preview Data Generation', () => {
268
+ it('should generate correct preview data for IMAGE type', () => {
269
+ const { result } = createHook();
270
+
271
+ act(() => {
272
+ result.current.setImageSrc({
273
+ androidImageSrc: 'test-image.jpg',
274
+ iosImageSrc: 'test-image-ios.jpg',
275
+ });
276
+ });
277
+
278
+ const androidPreview = result.current.getPreviewData(IMAGE, ANDROID);
279
+ expect(androidPreview).toHaveProperty('imageSrc', 'test-image.jpg');
280
+
281
+ const iosPreview = result.current.getPreviewData(IMAGE, IOS);
282
+ expect(iosPreview).toHaveProperty('imageSrc', 'test-image-ios.jpg');
283
+ });
284
+
285
+ it('should generate correct preview data for VIDEO type', () => {
286
+ const { result } = createHook();
287
+
288
+ act(() => {
289
+ result.current.setVideoState({
290
+ androidVideoSrc: 'test-video.mp4',
291
+ androidVideoPreview: 'test-preview.jpg',
292
+ androidVideoDuration: 30,
293
+ iosVideoSrc: 'test-video-ios.mp4',
294
+ iosVideoPreview: 'test-preview-ios.jpg',
295
+ iosVideoDuration: 30,
296
+ });
297
+ });
298
+
299
+ const androidPreview = result.current.getPreviewData(VIDEO, ANDROID);
300
+ expect(androidPreview).toEqual({
301
+ videoSrc: 'test-video.mp4',
302
+ videoPreviewImg: 'test-preview.jpg',
303
+ duration: 30,
304
+ });
305
+
306
+ const iosPreview = result.current.getPreviewData(VIDEO, IOS);
307
+ expect(iosPreview).toEqual({
308
+ videoSrc: 'test-video-ios.mp4',
309
+ videoPreviewImg: 'test-preview-ios.jpg',
310
+ duration: 30,
311
+ });
312
+ });
313
+
314
+ it('should generate correct preview data for GIF type', () => {
315
+ const { result } = createHook();
316
+
317
+ act(() => {
318
+ result.current.setVideoState({
319
+ androidVideoSrc: 'test.gif',
320
+ androidVideoPreview: 'test-preview.jpg',
321
+ iosVideoSrc: 'test-ios.gif',
322
+ iosVideoPreview: 'test-preview-ios.jpg',
323
+ });
324
+ });
325
+
326
+ const androidPreview = result.current.getPreviewData(GIF, ANDROID);
327
+ expect(androidPreview).toEqual({
328
+ gifSrc: 'test.gif',
329
+ gifPreviewImg: 'test-preview.jpg',
330
+ });
331
+
332
+ const iosPreview = result.current.getPreviewData(GIF, IOS);
333
+ expect(iosPreview).toEqual({
334
+ gifSrc: 'test-ios.gif',
335
+ gifPreviewImg: 'test-preview-ios.jpg',
336
+ });
337
+ });
338
+
339
+ it('should return empty object for unknown media type', () => {
340
+ const { result } = createHook();
341
+ const preview = result.current.getPreviewData('UNKNOWN', ANDROID);
342
+ expect(preview).toEqual({});
343
+ });
344
+ });
345
+
346
+ describe('Media Upload Status', () => {
347
+ it('should correctly check if IMAGE is uploaded', () => {
348
+ const { result } = createHook();
349
+
350
+ act(() => {
351
+ result.current.setImageSrc({
352
+ androidImageSrc: 'test-image.jpg',
353
+ iosImageSrc: 'test-image-ios.jpg',
354
+ });
355
+ });
356
+
357
+ expect(result.current.isMediaUploaded(IMAGE, ANDROID)).toBe(true);
358
+ expect(result.current.isMediaUploaded(IMAGE, IOS)).toBe(true);
359
+ });
360
+
361
+ it('should correctly check if VIDEO is uploaded', () => {
362
+ const { result } = createHook();
363
+
364
+ act(() => {
365
+ result.current.setVideoState({
366
+ androidVideoSrc: 'test-video.mp4',
367
+ iosVideoSrc: 'test-video-ios.mp4',
368
+ });
369
+ });
370
+
371
+ expect(result.current.isMediaUploaded(VIDEO, ANDROID)).toBe(true);
372
+ expect(result.current.isMediaUploaded(VIDEO, IOS)).toBe(true);
373
+ });
374
+
375
+ it('should correctly check if GIF is uploaded', () => {
376
+ const { result } = createHook();
377
+
378
+ act(() => {
379
+ result.current.setVideoState({
380
+ androidVideoSrc: 'test.gif',
381
+ iosVideoSrc: 'test-ios.gif',
382
+ });
383
+ });
384
+
385
+ expect(result.current.isMediaUploaded(GIF, ANDROID)).toBe(true);
386
+ expect(result.current.isMediaUploaded(GIF, IOS)).toBe(true);
387
+ });
388
+
389
+ it('should return true for unknown media type', () => {
390
+ const { result } = createHook();
391
+ expect(result.current.isMediaUploaded('UNKNOWN', ANDROID)).toBe(true);
392
+ });
393
+ });
394
+
395
+ describe('Edit Mode Initialization', () => {
396
+ it('should initialize from edit data with Android content', () => {
397
+ const editData = {
398
+ templateDetails: {
399
+ versions: {
400
+ base: {
401
+ content: {
402
+ ANDROID: {
403
+ expandableDetails: {
404
+ image: 'android-image.jpg',
405
+ video: 'android-video.mp4',
406
+ videoPreview: 'android-preview.jpg',
407
+ videoDuration: 30,
408
+ },
409
+ },
410
+ },
411
+ },
412
+ },
413
+ },
414
+ };
415
+
416
+ const { result } = createHook({ editData });
417
+
418
+ expect(result.current.imageSrc.androidImageSrc).toBe('android-image.jpg');
419
+ expect(result.current.videoState.androidVideoSrc).toBe('android-video.mp4');
420
+ expect(result.current.videoState.androidVideoPreview).toBe('android-preview.jpg');
421
+ expect(result.current.videoState.androidVideoDuration).toBe(30);
422
+ });
423
+
424
+ it('should initialize from edit data with iOS content', () => {
425
+ const editData = {
426
+ templateDetails: {
427
+ versions: {
428
+ base: {
429
+ content: {
430
+ IOS: {
431
+ expandableDetails: {
432
+ image: 'ios-image.jpg',
433
+ video: 'ios-video.mp4',
434
+ videoPreview: 'ios-preview.jpg',
435
+ videoDuration: 30,
436
+ },
437
+ },
438
+ },
439
+ },
440
+ },
441
+ },
442
+ };
443
+
444
+ const { result } = createHook({ editData });
445
+
446
+ expect(result.current.imageSrc.iosImageSrc).toBe('ios-image.jpg');
447
+ expect(result.current.videoState.iosVideoSrc).toBe('ios-video.mp4');
448
+ expect(result.current.videoState.iosVideoPreview).toBe('ios-preview.jpg');
449
+ expect(result.current.videoState.iosVideoDuration).toBe(30);
450
+ });
451
+
452
+ it('should handle missing video preview and duration in edit data', () => {
453
+ const editData = {
454
+ templateDetails: {
455
+ versions: {
456
+ base: {
457
+ content: {
458
+ ANDROID: {
459
+ expandableDetails: {
460
+ video: 'android-video.mp4',
461
+ },
462
+ },
463
+ IOS: {
464
+ expandableDetails: {
465
+ video: 'ios-video.mp4',
466
+ },
467
+ },
468
+ },
469
+ },
470
+ },
471
+ },
472
+ };
473
+
474
+ const { result } = createHook({ editData });
475
+
476
+ expect(result.current.videoState.androidVideoSrc).toBe('android-video.mp4');
477
+ expect(result.current.videoState.androidVideoPreview).toBe('');
478
+ expect(result.current.videoState.androidVideoDuration).toBe(0);
479
+ expect(result.current.videoState.iosVideoSrc).toBe('ios-video.mp4');
480
+ expect(result.current.videoState.iosVideoPreview).toBe('');
481
+ expect(result.current.videoState.iosVideoDuration).toBe(0);
482
+ });
483
+ });
484
+
485
+ describe('CDN URL Generation', () => {
486
+ it('should generate CDN URLs for images and videos', () => {
487
+ const { result } = createHook();
488
+
489
+ // Test image URL generation
490
+ const imageUrl = result.current.getCdnImageUrl('test-image.jpg');
491
+ expect(imageUrl).toBeDefined();
492
+ expect(imageUrl).toBe('cdn/MOBILEPUSH/test-image.jpg');
493
+
494
+ // Test video URL generation
495
+ const videoUrl = result.current.getCdnVideoUrl('test-video.mp4');
496
+ expect(videoUrl).toBeDefined();
497
+ expect(videoUrl).toBe('cdn/MOBILEPUSH/test-video.mp4');
498
+
499
+ // Test empty URL handling
500
+ expect(result.current.getCdnImageUrl('')).toBe('');
501
+ expect(result.current.getCdnVideoUrl('')).toBe('');
502
+ });
503
+ });
504
+
505
+ describe('Reset Upload States', () => {
506
+ it('should reset all upload states', () => {
507
+ const { result } = createHook();
508
+
509
+ // Set some initial state
510
+ act(() => {
511
+ result.current.setImageSrc({
512
+ androidImageSrc: 'test-image.jpg',
513
+ iosImageSrc: 'test-image-ios.jpg',
514
+ });
515
+ result.current.setVideoState({
516
+ androidVideoSrc: 'test-video.mp4',
517
+ androidVideoPreview: 'test-preview.jpg',
518
+ androidVideoDuration: 30,
519
+ iosVideoSrc: 'test-video-ios.mp4',
520
+ iosVideoPreview: 'test-preview-ios.jpg',
521
+ iosVideoDuration: 30,
522
+ });
523
+ result.current.setMpushVideoSrcAndPreview({
524
+ mpushVideoSrc: 'test-video.mp4',
525
+ mpushVideoPreviewImg: 'test-preview.jpg',
526
+ duration: 30,
527
+ });
528
+ });
529
+
530
+ // Reset all states
531
+ act(() => {
532
+ result.current.resetUploadStates();
533
+ });
534
+
535
+ // Verify all states are reset
536
+ expect(result.current.imageSrc).toEqual({
537
+ androidImageSrc: '',
538
+ iosImageSrc: '',
539
+ });
540
+ expect(result.current.videoState).toEqual({
541
+ androidVideoSrc: '',
542
+ iosVideoSrc: '',
543
+ androidVideoPreview: '',
544
+ iosVideoPreview: '',
545
+ androidVideoDuration: 0,
546
+ iosVideoDuration: 0,
547
+ });
548
+ expect(result.current.mpushVideoSrcAndPreview).toEqual({
549
+ mpushVideoSrc: '',
550
+ mpushVideoPreviewImg: '',
551
+ duration: 0,
552
+ });
553
+ expect(result.current.androidAssetList).toEqual([]);
554
+ expect(result.current.iosAssetList).toEqual([]);
555
+ });
556
+ });
557
+
558
+ describe('Image Re-upload Handlers', () => {
559
+ it('should handle image re-upload with sync enabled', () => {
560
+ const { result } = createHook({ sameContent: true });
561
+
562
+ // Set initial state
563
+ act(() => {
564
+ result.current.setImageSrc({
565
+ androidImageSrc: 'test-image.jpg',
566
+ iosImageSrc: 'test-image.jpg',
567
+ });
568
+ });
569
+
570
+ // Re-upload image
571
+ act(() => {
572
+ result.current.updateOnMpushImageReUpload();
573
+ });
574
+
575
+ // Verify both platforms are cleared
576
+ expect(result.current.imageSrc).toEqual({
577
+ androidImageSrc: '',
578
+ iosImageSrc: '',
579
+ });
580
+ });
581
+
582
+ it('should handle image re-upload with sync disabled', () => {
583
+ const { result } = createHook({ sameContent: false, activeTab: ANDROID });
584
+
585
+ // Set initial state
586
+ act(() => {
587
+ result.current.setImageSrc({
588
+ androidImageSrc: 'test-image.jpg',
589
+ iosImageSrc: 'test-image-ios.jpg',
590
+ });
591
+ });
592
+
593
+ // Re-upload image
594
+ act(() => {
595
+ result.current.updateOnMpushImageReUpload();
596
+ });
597
+
598
+ // Verify only Android is cleared
599
+ expect(result.current.imageSrc).toEqual({
600
+ androidImageSrc: '',
601
+ iosImageSrc: 'test-image-ios.jpg',
602
+ });
603
+ });
604
+
605
+ it('should handle image source update with sync enabled', () => {
606
+ const { result } = createHook({ sameContent: true });
607
+
608
+ // Update image source
609
+ act(() => {
610
+ result.current.setUpdateMpushImageSrc('test-image.jpg', 0);
611
+ });
612
+
613
+ // Verify both platforms are updated
614
+ expect(result.current.imageSrc).toEqual({
615
+ androidImageSrc: 'test-image.jpg',
616
+ iosImageSrc: 'test-image.jpg',
617
+ });
618
+ expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(0);
619
+ });
620
+
621
+ it('should handle image source update with sync disabled', () => {
622
+ const { result } = createHook({ sameContent: false });
623
+
624
+ // Update Android image source
625
+ act(() => {
626
+ result.current.setUpdateMpushImageSrc('test-image.jpg', 0);
627
+ });
628
+
629
+ // Verify only Android is updated
630
+ expect(result.current.imageSrc).toEqual({
631
+ androidImageSrc: 'test-image.jpg',
632
+ iosImageSrc: '',
633
+ });
634
+ expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(0);
635
+
636
+ // Update iOS image source
637
+ act(() => {
638
+ result.current.setUpdateMpushImageSrc('test-image-ios.jpg', 1);
639
+ });
640
+
641
+ // Verify iOS is updated
642
+ expect(result.current.imageSrc).toEqual({
643
+ androidImageSrc: 'test-image.jpg',
644
+ iosImageSrc: 'test-image-ios.jpg',
645
+ });
646
+ expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(1);
647
+ });
648
+
649
+ it('should handle carousel image source update', () => {
650
+ const { result } = createHook({ sameContent: true });
651
+
652
+ // Update carousel image source
653
+ act(() => {
654
+ result.current.setUpdateMpushImageSrc('test-image.jpg', 0, CAROUSEL);
655
+ });
656
+
657
+ // Verify both platforms are updated but clearAsset is not called
658
+ expect(result.current.imageSrc).toEqual({
659
+ androidImageSrc: 'test-image.jpg',
660
+ iosImageSrc: 'test-image.jpg',
661
+ });
662
+ expect(mockMobilePushActions.clearAsset).not.toHaveBeenCalled();
663
+ });
664
+ });
665
+
666
+ describe('Video Re-upload Handlers', () => {
667
+ it('should handle video re-upload with sync enabled', () => {
668
+ const { result } = createHook({ sameContent: true });
669
+
670
+ // Set initial state
671
+ act(() => {
672
+ result.current.setVideoState({
673
+ androidVideoSrc: 'test-video.mp4',
674
+ androidVideoPreview: 'test-preview.jpg',
675
+ androidVideoDuration: 30,
676
+ iosVideoSrc: 'test-video.mp4',
677
+ iosVideoPreview: 'test-preview.jpg',
678
+ iosVideoDuration: 30,
679
+ });
680
+ result.current.setMpushVideoSrcAndPreview({
681
+ mpushVideoSrc: 'test-video.mp4',
682
+ mpushVideoPreviewImg: 'test-preview.jpg',
683
+ duration: 30,
684
+ });
685
+ });
686
+
687
+ // Re-upload video
688
+ act(() => {
689
+ result.current.updateOnMpushVideoReUpload();
690
+ });
691
+
692
+ // Verify all states are cleared
693
+ expect(result.current.videoState).toEqual({
694
+ androidVideoSrc: '',
695
+ iosVideoSrc: '',
696
+ androidVideoPreview: '',
697
+ iosVideoPreview: '',
698
+ androidVideoDuration: 0,
699
+ iosVideoDuration: 0,
700
+ });
701
+ expect(result.current.mpushVideoSrcAndPreview).toEqual({
702
+ mpushVideoSrc: '',
703
+ mpushVideoPreviewImg: '',
704
+ duration: 0,
705
+ });
706
+ expect(result.current.androidAssetList).toEqual([]);
707
+ expect(result.current.iosAssetList).toEqual([]);
708
+ expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(0);
709
+ expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(1);
710
+ });
711
+
712
+ it('should handle video re-upload with sync disabled', () => {
713
+ const { result } = createHook({ sameContent: false, activeTab: ANDROID });
714
+
715
+ // Set initial state
716
+ act(() => {
717
+ result.current.setVideoState({
718
+ androidVideoSrc: 'test-video.mp4',
719
+ androidVideoPreview: 'test-preview.jpg',
720
+ androidVideoDuration: 30,
721
+ iosVideoSrc: 'test-video-ios.mp4',
722
+ iosVideoPreview: 'test-preview-ios.jpg',
723
+ iosVideoDuration: 30,
724
+ });
725
+ });
726
+
727
+ // Re-upload video
728
+ act(() => {
729
+ result.current.updateOnMpushVideoReUpload();
730
+ });
731
+
732
+ // Verify only Android states are cleared
733
+ expect(result.current.videoState).toEqual({
734
+ androidVideoSrc: '',
735
+ androidVideoPreview: '',
736
+ androidVideoDuration: 0,
737
+ iosVideoSrc: 'test-video-ios.mp4',
738
+ iosVideoPreview: 'test-preview-ios.jpg',
739
+ iosVideoDuration: 30,
740
+ });
741
+ expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(0);
742
+ expect(mockMobilePushActions.clearAsset).not.toHaveBeenCalledWith(1);
743
+ });
744
+
745
+ it('should handle video source update with sync enabled', () => {
746
+ const { result } = createHook({ sameContent: true });
747
+
748
+ // Update video source
749
+ act(() => {
750
+ result.current.setUpdateMpushVideoSrc(0, {
751
+ videoSrc: 'test-video.mp4',
752
+ previewUrl: 'test-preview.jpg',
753
+ videoDuration: 30,
754
+ videoName: 'test.mp4',
755
+ fileHandle: 'handle',
756
+ });
757
+ });
758
+
759
+ // Verify both platforms are updated
760
+ expect(result.current.videoState).toEqual({
761
+ androidVideoSrc: 'test-video.mp4',
762
+ iosVideoSrc: 'test-video.mp4',
763
+ androidVideoPreview: 'test-preview.jpg',
764
+ iosVideoPreview: 'test-preview.jpg',
765
+ androidVideoDuration: 30,
766
+ iosVideoDuration: 30,
767
+ });
768
+ expect(result.current.mpushVideoSrcAndPreview).toEqual({
769
+ mpushVideoSrc: 'test-video.mp4',
770
+ mpushVideoPreviewImg: 'test-preview.jpg',
771
+ duration: 30,
772
+ });
773
+ expect(result.current.androidAssetList).toEqual({
774
+ videoSrc: 'test-video.mp4',
775
+ previewUrl: 'test-preview.jpg',
776
+ videoDuration: 30,
777
+ videoName: 'test.mp4',
778
+ fileHandle: 'handle',
779
+ });
780
+ expect(result.current.iosAssetList).toEqual({
781
+ videoSrc: 'test-video.mp4',
782
+ previewUrl: 'test-preview.jpg',
783
+ videoDuration: 30,
784
+ videoName: 'test.mp4',
785
+ fileHandle: 'handle',
786
+ });
787
+ expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(0);
788
+ });
789
+
790
+ it('should handle video source update with sync disabled', () => {
791
+ const { result } = createHook({ sameContent: false });
792
+
793
+ // Update Android video source
794
+ act(() => {
795
+ result.current.setUpdateMpushVideoSrc(0, {
796
+ videoSrc: 'test-video.mp4',
797
+ previewUrl: 'test-preview.jpg',
798
+ videoDuration: 30,
799
+ videoName: 'test.mp4',
800
+ fileHandle: 'handle',
801
+ });
802
+ });
803
+
804
+ // Verify only Android is updated
805
+ expect(result.current.videoState).toEqual({
806
+ androidVideoSrc: 'test-video.mp4',
807
+ androidVideoPreview: 'test-preview.jpg',
808
+ androidVideoDuration: 30,
809
+ iosVideoSrc: '',
810
+ iosVideoPreview: '',
811
+ iosVideoDuration: 0,
812
+ });
813
+ expect(result.current.androidAssetList).toEqual({
814
+ videoSrc: 'test-video.mp4',
815
+ previewUrl: 'test-preview.jpg',
816
+ videoDuration: 30,
817
+ videoName: 'test.mp4',
818
+ fileHandle: 'handle',
819
+ });
820
+ expect(result.current.iosAssetList).toEqual([]);
821
+ expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(0);
822
+
823
+ // Update iOS video source
824
+ act(() => {
825
+ result.current.setUpdateMpushVideoSrc(1, {
826
+ videoSrc: 'test-video-ios.mp4',
827
+ previewUrl: 'test-preview-ios.jpg',
828
+ videoDuration: 30,
829
+ videoName: 'test-ios.mp4',
830
+ fileHandle: 'handle-ios',
831
+ });
832
+ });
833
+
834
+ // Verify iOS is updated
835
+ expect(result.current.videoState).toEqual({
836
+ androidVideoSrc: 'test-video.mp4',
837
+ androidVideoPreview: 'test-preview.jpg',
838
+ androidVideoDuration: 30,
839
+ iosVideoSrc: 'test-video-ios.mp4',
840
+ iosVideoPreview: 'test-preview-ios.jpg',
841
+ iosVideoDuration: 30,
842
+ });
843
+ expect(result.current.iosAssetList).toEqual({
844
+ videoSrc: 'test-video-ios.mp4',
845
+ previewUrl: 'test-preview-ios.jpg',
846
+ videoDuration: 30,
847
+ videoName: 'test-ios.mp4',
848
+ fileHandle: 'handle-ios',
849
+ });
850
+ expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(1);
851
+ });
852
+
853
+ it('should not clear asset during initialization', () => {
854
+ const { result } = createHook({ sameContent: true });
855
+
856
+ // Update video source with isInitialization=true
857
+ act(() => {
858
+ result.current.setUpdateMpushVideoSrc(0, {
859
+ videoSrc: 'test-video.mp4',
860
+ previewUrl: 'test-preview.jpg',
861
+ videoDuration: 30,
862
+ videoName: 'test.mp4',
863
+ fileHandle: 'handle',
864
+ }, true);
865
+ });
866
+
867
+ // Verify states are updated but clearAsset is not called
868
+ expect(result.current.videoState.androidVideoSrc).toBe('test-video.mp4');
869
+ expect(mockMobilePushActions.clearAsset).not.toHaveBeenCalled();
870
+ });
871
+ });
872
+
873
+ describe('Platform-specific Logic', () => {
874
+ it('should get correct video properties for Android', () => {
875
+ const { result } = createHook({ activeTab: ANDROID });
876
+
877
+ // Test Android video properties
878
+ act(() => {
879
+ result.current.setVideoState({
880
+ androidVideoSrc: 'test-video.mp4',
881
+ androidVideoPreview: 'test-preview.jpg',
882
+ androidVideoDuration: 30,
883
+ iosVideoSrc: 'test-video-ios.mp4',
884
+ iosVideoPreview: 'test-preview-ios.jpg',
885
+ iosVideoDuration: 25,
886
+ });
887
+ });
888
+
889
+ const androidPayload = result.current.getMediaPayload(VIDEO, ANDROID);
890
+ expect(androidPayload.videoUrl).toBe('cdn/MOBILEPUSH/test-video.mp4');
891
+ expect(androidPayload.videoPreviewImg).toBe('cdn/MOBILEPUSH/test-preview.jpg');
892
+ expect(androidPayload.duration).toBe(30);
893
+ });
894
+
895
+ it('should get correct video properties for iOS', () => {
896
+ const { result } = createHook({ activeTab: IOS });
897
+
898
+ // Test iOS video properties
899
+ act(() => {
900
+ result.current.setVideoState({
901
+ androidVideoSrc: 'test-video.mp4',
902
+ androidVideoPreview: 'test-preview.jpg',
903
+ androidVideoDuration: 30,
904
+ iosVideoSrc: 'test-video-ios.mp4',
905
+ iosVideoPreview: 'test-preview-ios.jpg',
906
+ iosVideoDuration: 25,
907
+ });
908
+ });
909
+
910
+ const iosPayload = result.current.getMediaPayload(VIDEO, IOS);
911
+ expect(iosPayload.videoUrl).toBe('cdn/MOBILEPUSH/test-video-ios.mp4');
912
+ expect(iosPayload.videoPreviewImg).toBe('cdn/MOBILEPUSH/test-preview-ios.jpg');
913
+ expect(iosPayload.duration).toBe(25);
914
+ });
915
+
916
+ it('should handle image re-upload for iOS', () => {
917
+ const { result } = createHook({ sameContent: false, activeTab: IOS });
918
+
919
+ // Set initial state
920
+ act(() => {
921
+ result.current.setImageSrc({
922
+ androidImageSrc: 'test-image.jpg',
923
+ iosImageSrc: 'test-image-ios.jpg',
924
+ });
925
+ });
926
+
927
+ // Re-upload image
928
+ act(() => {
929
+ result.current.updateOnMpushImageReUpload();
930
+ });
931
+
932
+ // Verify only iOS is cleared
933
+ expect(result.current.imageSrc).toEqual({
934
+ androidImageSrc: 'test-image.jpg',
935
+ iosImageSrc: '',
936
+ });
937
+ });
938
+
939
+ it('should handle video re-upload for iOS', () => {
940
+ const { result } = createHook({ sameContent: false, activeTab: IOS });
941
+
942
+ // Set initial state
943
+ act(() => {
944
+ result.current.setVideoState({
945
+ androidVideoSrc: 'test-video.mp4',
946
+ androidVideoPreview: 'test-preview.jpg',
947
+ androidVideoDuration: 30,
948
+ iosVideoSrc: 'test-video-ios.mp4',
949
+ iosVideoPreview: 'test-preview-ios.jpg',
950
+ iosVideoDuration: 25,
951
+ });
952
+ });
953
+
954
+ // Re-upload video
955
+ act(() => {
956
+ result.current.updateOnMpushVideoReUpload();
957
+ });
958
+
959
+ // Verify only iOS states are cleared
960
+ expect(result.current.videoState).toEqual({
961
+ androidVideoSrc: 'test-video.mp4',
962
+ androidVideoPreview: 'test-preview.jpg',
963
+ androidVideoDuration: 30,
964
+ iosVideoSrc: '',
965
+ iosVideoPreview: '',
966
+ iosVideoDuration: 0,
967
+ });
968
+ expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(1);
969
+ expect(mockMobilePushActions.clearAsset).not.toHaveBeenCalledWith(0);
970
+ });
971
+
972
+ it('should handle carousel image source update for iOS', () => {
973
+ const { result } = createHook({ sameContent: false, activeTab: IOS });
974
+
975
+ // Update carousel image source for iOS
976
+ act(() => {
977
+ result.current.setUpdateMpushImageSrc('test-image-ios.jpg', 1, CAROUSEL);
978
+ });
979
+
980
+ // Verify only iOS is updated and clearAsset is not called
981
+ expect(result.current.imageSrc).toEqual({
982
+ androidImageSrc: '',
983
+ iosImageSrc: 'test-image-ios.jpg',
984
+ });
985
+ expect(mockMobilePushActions.clearAsset).not.toHaveBeenCalled();
986
+ });
987
+
988
+ it('should handle empty file paths', () => {
989
+ const { result } = createHook();
990
+
991
+ // Test empty image URL
992
+ expect(result.current.getCdnImageUrl('')).toBe('');
993
+
994
+ // Test empty video URL
995
+ expect(result.current.getCdnVideoUrl('')).toBe('');
996
+
997
+ // Test empty image source update
998
+ act(() => {
999
+ result.current.setUpdateMpushImageSrc('', 0);
1000
+ });
1001
+ expect(result.current.imageSrc).toEqual({
1002
+ androidImageSrc: '',
1003
+ iosImageSrc: '',
1004
+ });
1005
+
1006
+ // Test empty video source update
1007
+ act(() => {
1008
+ result.current.setUpdateMpushVideoSrc(0, {
1009
+ videoSrc: '',
1010
+ previewUrl: '',
1011
+ videoDuration: 0,
1012
+ });
1013
+ });
1014
+ expect(result.current.videoState).toEqual({
1015
+ androidVideoSrc: '',
1016
+ androidVideoPreview: '',
1017
+ androidVideoDuration: 0,
1018
+ iosVideoSrc: '',
1019
+ iosVideoPreview: '',
1020
+ iosVideoDuration: 0,
1021
+ });
1022
+ });
1023
+
1024
+ it('should handle missing video preview and duration in source update', () => {
1025
+ const { result } = createHook();
1026
+
1027
+ // Update video source without preview and duration
1028
+ act(() => {
1029
+ result.current.setUpdateMpushVideoSrc(0, {
1030
+ videoSrc: 'test-video.mp4',
1031
+ });
1032
+ });
1033
+
1034
+ // Verify default values are used
1035
+ expect(result.current.videoState).toEqual({
1036
+ androidVideoSrc: 'test-video.mp4',
1037
+ androidVideoPreview: '',
1038
+ androidVideoDuration: 0,
1039
+ iosVideoSrc: '',
1040
+ iosVideoPreview: '',
1041
+ iosVideoDuration: 0,
1042
+ });
1043
+ expect(result.current.mpushVideoSrcAndPreview).toEqual({
1044
+ mpushVideoSrc: 'test-video.mp4',
1045
+ mpushVideoPreviewImg: '',
1046
+ duration: 0,
1047
+ });
1048
+ });
1049
+
1050
+ it('should handle missing file name and handle in source update', () => {
1051
+ const { result } = createHook();
1052
+
1053
+ const videoData = {
1054
+ videoSrc: 'test-video.mp4',
1055
+ previewUrl: 'test-preview.jpg',
1056
+ videoDuration: 30,
1057
+ videoName: '',
1058
+ fileHandle: '',
1059
+ };
1060
+
1061
+ // Update video source without file name and handle
1062
+ act(() => {
1063
+ result.current.setUpdateMpushVideoSrc(0, videoData);
1064
+ });
1065
+
1066
+ // Verify asset data is still updated
1067
+ expect(result.current.androidAssetList).toEqual({
1068
+ ...videoData,
1069
+ });
1070
+ });
1071
+ });
1072
+
1073
+ describe('Clear Media Data', () => {
1074
+ beforeEach(() => {
1075
+ jest.clearAllMocks();
1076
+ });
1077
+
1078
+ it('should clear image data with sync enabled', () => {
1079
+ const { result } = createHook({ sameContent: true });
1080
+
1081
+ // Set initial state
1082
+ act(() => {
1083
+ result.current.setImageSrc({
1084
+ androidImageSrc: 'test-image.jpg',
1085
+ iosImageSrc: 'test-image.jpg',
1086
+ });
1087
+ });
1088
+
1089
+ // Clear image data
1090
+ act(() => {
1091
+ result.current.clearImageDataByMediaType(IMAGE);
1092
+ });
1093
+
1094
+ // Verify both platforms are cleared
1095
+ expect(result.current.imageSrc).toEqual({
1096
+ androidImageSrc: '',
1097
+ iosImageSrc: '',
1098
+ });
1099
+ });
1100
+
1101
+ it('should clear image data with sync disabled', () => {
1102
+ const { result } = createHook({ sameContent: false, activeTab: ANDROID });
1103
+
1104
+ // Set initial state
1105
+ act(() => {
1106
+ result.current.setImageSrc({
1107
+ androidImageSrc: 'test-image.jpg',
1108
+ iosImageSrc: 'test-image-ios.jpg',
1109
+ });
1110
+ });
1111
+
1112
+ // Clear image data
1113
+ act(() => {
1114
+ result.current.clearImageDataByMediaType(IMAGE);
1115
+ });
1116
+
1117
+ // Verify only Android is cleared
1118
+ expect(result.current.imageSrc).toEqual({
1119
+ androidImageSrc: '',
1120
+ iosImageSrc: 'test-image-ios.jpg',
1121
+ });
1122
+ });
1123
+
1124
+ it('should clear video data with sync enabled', () => {
1125
+ const { result } = createHook({ sameContent: true });
1126
+
1127
+ // Set initial state
1128
+ act(() => {
1129
+ result.current.setVideoState({
1130
+ androidVideoSrc: 'test-video.mp4',
1131
+ androidVideoPreview: 'test-preview.jpg',
1132
+ androidVideoDuration: 30,
1133
+ iosVideoSrc: 'test-video.mp4',
1134
+ iosVideoPreview: 'test-preview.jpg',
1135
+ iosVideoDuration: 30,
1136
+ });
1137
+ });
1138
+
1139
+ // Clear video data
1140
+ act(() => {
1141
+ result.current.clearImageDataByMediaType(VIDEO);
1142
+ });
1143
+
1144
+ // Verify both platforms are cleared
1145
+ expect(result.current.videoState).toEqual({
1146
+ androidVideoSrc: '',
1147
+ androidVideoPreview: '',
1148
+ androidVideoDuration: 0,
1149
+ iosVideoSrc: '',
1150
+ iosVideoPreview: '',
1151
+ iosVideoDuration: 0,
1152
+ });
1153
+
1154
+ // Verify content is cleared
1155
+ expect(androidContent).toMatchObject({
1156
+ title: 'Test Android',
1157
+ message: 'Test message',
1158
+ videoSrc: '',
1159
+ videoPreview: '',
1160
+ videoDuration: 0,
1161
+ });
1162
+ expect(iosContent).toMatchObject({
1163
+ title: 'Test iOS',
1164
+ message: 'Test message',
1165
+ videoSrc: '',
1166
+ videoPreview: '',
1167
+ videoDuration: 0,
1168
+ });
1169
+
1170
+ // Verify Redux state is cleared
1171
+ expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(0);
1172
+ expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(1);
1173
+ });
1174
+
1175
+ it('should clear video data with sync disabled', () => {
1176
+ const { result } = createHook({ sameContent: false, activeTab: ANDROID });
1177
+
1178
+ // Set initial state
1179
+ act(() => {
1180
+ result.current.setVideoState({
1181
+ androidVideoSrc: 'test-video.mp4',
1182
+ androidVideoPreview: 'test-preview.jpg',
1183
+ androidVideoDuration: 30,
1184
+ iosVideoSrc: 'test-video-ios.mp4',
1185
+ iosVideoPreview: 'test-preview-ios.jpg',
1186
+ iosVideoDuration: 25,
1187
+ });
1188
+ });
1189
+
1190
+ // Clear video data
1191
+ act(() => {
1192
+ result.current.clearImageDataByMediaType(VIDEO);
1193
+ });
1194
+
1195
+ // Verify only Android is cleared
1196
+ expect(result.current.videoState).toEqual({
1197
+ androidVideoSrc: '',
1198
+ androidVideoPreview: '',
1199
+ androidVideoDuration: 0,
1200
+ iosVideoSrc: 'test-video-ios.mp4',
1201
+ iosVideoPreview: 'test-preview-ios.jpg',
1202
+ iosVideoDuration: 25,
1203
+ });
1204
+
1205
+ // Verify only Android content is cleared
1206
+ expect(androidContent).toMatchObject({
1207
+ title: 'Test Android',
1208
+ message: 'Test message',
1209
+ videoSrc: '',
1210
+ videoPreview: '',
1211
+ videoDuration: 0,
1212
+ });
1213
+ expect(iosContent).toMatchObject({
1214
+ title: 'Test iOS',
1215
+ message: 'Test message',
1216
+ });
1217
+
1218
+ // Verify only Android Redux state is cleared
1219
+ expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(0);
1220
+ expect(mockMobilePushActions.clearAsset).not.toHaveBeenCalledWith(1);
1221
+ });
1222
+
1223
+ it('should clear GIF data with sync enabled', () => {
1224
+ const { result } = createHook({ sameContent: true });
1225
+
1226
+ // Set initial state
1227
+ act(() => {
1228
+ result.current.setVideoState({
1229
+ androidVideoSrc: 'test.gif',
1230
+ androidVideoPreview: 'test-preview.jpg',
1231
+ androidVideoDuration: 30,
1232
+ iosVideoSrc: 'test.gif',
1233
+ iosVideoPreview: 'test-preview.jpg',
1234
+ iosVideoDuration: 30,
1235
+ });
1236
+ });
1237
+
1238
+ // Clear GIF data
1239
+ act(() => {
1240
+ result.current.clearImageDataByMediaType(GIF);
1241
+ });
1242
+
1243
+ // Verify both platforms are cleared
1244
+ expect(result.current.videoState).toEqual({
1245
+ androidVideoSrc: '',
1246
+ androidVideoPreview: '',
1247
+ androidVideoDuration: 0,
1248
+ iosVideoSrc: '',
1249
+ iosVideoPreview: '',
1250
+ iosVideoDuration: 0,
1251
+ });
1252
+
1253
+ // Verify content is cleared
1254
+ expect(androidContent).toMatchObject({
1255
+ title: 'Test Android',
1256
+ message: 'Test message',
1257
+ videoSrc: '',
1258
+ videoPreview: '',
1259
+ videoDuration: 0,
1260
+ });
1261
+ expect(iosContent).toMatchObject({
1262
+ title: 'Test iOS',
1263
+ message: 'Test message',
1264
+ videoSrc: '',
1265
+ videoPreview: '',
1266
+ videoDuration: 0,
1267
+ });
1268
+
1269
+ // Verify Redux state is cleared
1270
+ expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(0);
1271
+ expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(1);
1272
+ });
1273
+
1274
+ it('should clear GIF data with sync disabled', () => {
1275
+ const { result } = createHook({ sameContent: false, activeTab: ANDROID });
1276
+
1277
+ // Set initial state
1278
+ act(() => {
1279
+ result.current.setVideoState({
1280
+ androidVideoSrc: 'test.gif',
1281
+ androidVideoPreview: 'test-preview.jpg',
1282
+ androidVideoDuration: 30,
1283
+ iosVideoSrc: 'test-ios.gif',
1284
+ iosVideoPreview: 'test-preview-ios.jpg',
1285
+ iosVideoDuration: 25,
1286
+ });
1287
+ });
1288
+
1289
+ // Clear GIF data
1290
+ act(() => {
1291
+ result.current.clearImageDataByMediaType(GIF);
1292
+ });
1293
+
1294
+ // Verify only Android is cleared
1295
+ expect(result.current.videoState).toEqual({
1296
+ androidVideoSrc: '',
1297
+ androidVideoPreview: '',
1298
+ androidVideoDuration: 0,
1299
+ iosVideoSrc: 'test-ios.gif',
1300
+ iosVideoPreview: 'test-preview-ios.jpg',
1301
+ iosVideoDuration: 25,
1302
+ });
1303
+
1304
+ // Verify only Android content is cleared
1305
+ expect(androidContent).toMatchObject({
1306
+ title: 'Test Android',
1307
+ message: 'Test message',
1308
+ videoSrc: '',
1309
+ videoPreview: '',
1310
+ videoDuration: 0,
1311
+ });
1312
+ expect(iosContent).toMatchObject({
1313
+ title: 'Test iOS',
1314
+ message: 'Test message',
1315
+ });
1316
+
1317
+ // Verify only Android Redux state is cleared
1318
+ expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(0);
1319
+ expect(mockMobilePushActions.clearAsset).not.toHaveBeenCalledWith(1);
1320
+ });
1321
+
1322
+ it('should do nothing for unknown media type', () => {
1323
+ const { result } = createHook({ sameContent: true });
1324
+
1325
+ // Set initial state
1326
+ act(() => {
1327
+ result.current.setImageSrc({
1328
+ androidImageSrc: 'test-image.jpg',
1329
+ iosImageSrc: 'test-image.jpg',
1330
+ });
1331
+ result.current.setVideoState({
1332
+ androidVideoSrc: 'test-video.mp4',
1333
+ androidVideoPreview: 'test-preview.jpg',
1334
+ androidVideoDuration: 30,
1335
+ iosVideoSrc: 'test-video.mp4',
1336
+ iosVideoPreview: 'test-preview.jpg',
1337
+ iosVideoDuration: 30,
1338
+ });
1339
+ });
1340
+
1341
+ // Clear unknown media type
1342
+ act(() => {
1343
+ result.current.clearImageDataByMediaType('UNKNOWN');
1344
+ });
1345
+
1346
+ // Verify nothing is cleared
1347
+ expect(result.current.imageSrc).toEqual({
1348
+ androidImageSrc: 'test-image.jpg',
1349
+ iosImageSrc: 'test-image.jpg',
1350
+ });
1351
+ expect(result.current.videoState).toEqual({
1352
+ androidVideoSrc: 'test-video.mp4',
1353
+ androidVideoPreview: 'test-preview.jpg',
1354
+ androidVideoDuration: 30,
1355
+ iosVideoSrc: 'test-video.mp4',
1356
+ iosVideoPreview: 'test-preview.jpg',
1357
+ iosVideoDuration: 30,
1358
+ });
1359
+ expect(androidContent).toMatchObject({
1360
+ title: 'Test Android',
1361
+ message: 'Test message',
1362
+ });
1363
+ expect(iosContent).toMatchObject({
1364
+ title: 'Test iOS',
1365
+ message: 'Test message',
1366
+ });
1367
+ expect(mockMobilePushActions.clearAsset).not.toHaveBeenCalled();
1368
+ });
1369
+ });
1370
+
1371
+ describe('Image Source Updates', () => {
1372
+ it('should update content when imageSrc changes with sync enabled', () => {
1373
+ const { result } = createHook({ sameContent: true });
1374
+
1375
+ // Set image source
1376
+ act(() => {
1377
+ result.current.setImageSrc({
1378
+ androidImageSrc: 'test-image.jpg',
1379
+ iosImageSrc: '',
1380
+ });
1381
+ });
1382
+
1383
+ // Verify both platforms are updated with Android image
1384
+ expect(androidContent).toMatchObject({
1385
+ title: 'Test Android',
1386
+ message: 'Test message',
1387
+ imageSrc: 'test-image.jpg',
1388
+ });
1389
+ expect(iosContent).toMatchObject({
1390
+ title: 'Test iOS',
1391
+ message: 'Test message',
1392
+ imageSrc: 'test-image.jpg',
1393
+ });
1394
+
1395
+ // Set iOS image source
1396
+ act(() => {
1397
+ result.current.setImageSrc({
1398
+ androidImageSrc: '',
1399
+ iosImageSrc: 'test-image-ios.jpg',
1400
+ });
1401
+ });
1402
+
1403
+ // Verify both platforms are updated with iOS image
1404
+ expect(androidContent).toMatchObject({
1405
+ title: 'Test Android',
1406
+ message: 'Test message',
1407
+ imageSrc: 'test-image-ios.jpg',
1408
+ });
1409
+ expect(iosContent).toMatchObject({
1410
+ title: 'Test iOS',
1411
+ message: 'Test message',
1412
+ imageSrc: 'test-image-ios.jpg',
1413
+ });
1414
+ });
1415
+
1416
+ it('should update content when imageSrc changes with sync disabled', () => {
1417
+ const { result } = createHook({ sameContent: false });
1418
+
1419
+ // Set Android image source
1420
+ act(() => {
1421
+ result.current.setImageSrc({
1422
+ androidImageSrc: 'test-image.jpg',
1423
+ iosImageSrc: '',
1424
+ });
1425
+ });
1426
+
1427
+ // Verify only Android is updated
1428
+ expect(androidContent).toMatchObject({
1429
+ title: 'Test Android',
1430
+ message: 'Test message',
1431
+ imageSrc: 'test-image.jpg',
1432
+ });
1433
+ expect(iosContent).toMatchObject({
1434
+ title: 'Test iOS',
1435
+ message: 'Test message',
1436
+ });
1437
+
1438
+ // Set iOS image source
1439
+ act(() => {
1440
+ result.current.setImageSrc({
1441
+ androidImageSrc: 'test-image.jpg',
1442
+ iosImageSrc: 'test-image-ios.jpg',
1443
+ });
1444
+ });
1445
+
1446
+ // Verify both platforms have their respective images
1447
+ expect(androidContent).toMatchObject({
1448
+ title: 'Test Android',
1449
+ message: 'Test message',
1450
+ imageSrc: 'test-image.jpg',
1451
+ });
1452
+ expect(iosContent).toMatchObject({
1453
+ title: 'Test iOS',
1454
+ message: 'Test message',
1455
+ imageSrc: 'test-image-ios.jpg',
1456
+ });
1457
+ });
1458
+ });
1459
+ });