@capillarytech/creatives-library 8.0.126 → 8.0.127-alpha.1
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/containers/App/constants.js +1 -0
- package/index.html +3 -1
- package/package.json +1 -1
- package/services/api.js +4 -4
- package/tests/integration/TemplateCreation/TemplateCreation.integration.test.js +8 -3
- package/tests/integration/TemplateCreation/api-response.js +5 -0
- package/tests/integration/TemplateCreation/msw-handler.js +42 -63
- package/utils/common.js +7 -0
- package/utils/commonUtils.js +2 -6
- package/utils/createPayload.js +272 -0
- package/utils/tests/createPayload.test.js +761 -0
- package/v2Components/CapImageUpload/index.js +59 -46
- package/v2Components/CapInAppCTA/index.js +1 -0
- package/v2Components/CapMpushCTA/constants.js +25 -0
- package/v2Components/CapMpushCTA/index.js +332 -0
- package/v2Components/CapMpushCTA/index.scss +95 -0
- package/v2Components/CapMpushCTA/messages.js +89 -0
- package/v2Components/CapTagList/index.js +177 -120
- package/v2Components/CapVideoUpload/constants.js +3 -0
- package/v2Components/CapVideoUpload/index.js +167 -110
- package/v2Components/CapVideoUpload/messages.js +16 -0
- package/v2Components/Carousel/index.js +15 -13
- package/v2Components/CustomerSearchSection/index.js +12 -7
- package/v2Components/ErrorInfoNote/style.scss +1 -0
- package/v2Components/MobilePushPreviewV2/index.js +37 -5
- package/v2Components/TemplatePreview/_templatePreview.scss +114 -72
- package/v2Components/TemplatePreview/assets/images/Android _ With date and time.svg +29 -0
- package/v2Components/TemplatePreview/assets/images/android.svg +9 -0
- package/v2Components/TemplatePreview/assets/images/iOS _ With date and time.svg +26 -0
- package/v2Components/TemplatePreview/assets/images/ios.svg +9 -0
- package/v2Components/TemplatePreview/index.js +178 -50
- package/v2Components/TemplatePreview/messages.js +4 -0
- package/v2Components/TestAndPreviewSlidebox/CustomValuesEditor.js +169 -0
- package/v2Components/TestAndPreviewSlidebox/LeftPanelContent.js +95 -0
- package/v2Components/TestAndPreviewSlidebox/PreviewSection.js +69 -0
- package/v2Components/TestAndPreviewSlidebox/SendTestMessage.js +68 -0
- package/v2Components/TestAndPreviewSlidebox/index.js +67 -246
- package/v2Components/TestAndPreviewSlidebox/tests/CustomValuesEditor.test.js +425 -0
- package/v2Components/TestAndPreviewSlidebox/tests/LeftPanelContent.test.js +400 -0
- package/v2Components/TestAndPreviewSlidebox/tests/SendTestMessage.test.js +448 -0
- package/v2Containers/CreativesContainer/SlideBoxContent.js +9 -9
- package/v2Containers/CreativesContainer/index.js +191 -136
- package/v2Containers/Email/index.js +15 -2
- package/v2Containers/InApp/constants.js +1 -0
- package/v2Containers/InApp/index.js +13 -13
- package/v2Containers/MobilePush/Create/index.js +1 -0
- package/v2Containers/MobilePush/commonMethods.js +7 -14
- package/v2Containers/MobilePushNew/actions.js +116 -0
- package/v2Containers/MobilePushNew/components/CtaButtons.js +170 -0
- package/v2Containers/MobilePushNew/components/MediaUploaders.js +754 -0
- package/v2Containers/MobilePushNew/components/PlatformContentFields.js +279 -0
- package/v2Containers/MobilePushNew/components/index.js +5 -0
- package/v2Containers/MobilePushNew/components/tests/CtaButtons.test.js +779 -0
- package/v2Containers/MobilePushNew/components/tests/MediaUploaders.test.js +2114 -0
- package/v2Containers/MobilePushNew/components/tests/PlatformContentFields.test.js +343 -0
- package/v2Containers/MobilePushNew/constants.js +115 -0
- package/v2Containers/MobilePushNew/hooks/tests/usePlatformSync.test.js +1299 -0
- package/v2Containers/MobilePushNew/hooks/tests/useUpload.test.js +1223 -0
- package/v2Containers/MobilePushNew/hooks/usePlatformSync.js +246 -0
- package/v2Containers/MobilePushNew/hooks/useUpload.js +726 -0
- package/v2Containers/MobilePushNew/index.js +2280 -0
- package/v2Containers/MobilePushNew/index.scss +308 -0
- package/v2Containers/MobilePushNew/messages.js +226 -0
- package/v2Containers/MobilePushNew/reducer.js +160 -0
- package/v2Containers/MobilePushNew/sagas.js +198 -0
- package/v2Containers/MobilePushNew/selectors.js +55 -0
- package/v2Containers/MobilePushNew/tests/reducer.test.js +741 -0
- package/v2Containers/MobilePushNew/tests/sagas.test.js +863 -0
- package/v2Containers/MobilePushNew/tests/selectors.test.js +425 -0
- package/v2Containers/MobilePushNew/tests/utils.test.js +322 -0
- package/v2Containers/MobilePushNew/utils.js +33 -0
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +5 -5
- package/v2Containers/TagList/index.js +56 -10
- package/v2Containers/Templates/_templates.scss +101 -1
- package/v2Containers/Templates/index.js +147 -35
- package/v2Containers/Templates/messages.js +8 -0
- package/v2Containers/Templates/sagas.js +2 -0
- package/v2Containers/Whatsapp/constants.js +1 -0
|
@@ -0,0 +1,1223 @@
|
|
|
1
|
+
import { renderHook, act } from '@testing-library/react';
|
|
2
|
+
import { getCdnUrl } from '../../../../utils/cdnTransformation';
|
|
3
|
+
import useUpload from '../useUpload';
|
|
4
|
+
import {
|
|
5
|
+
MOBILE_PUSH_CHANNEL,
|
|
6
|
+
MPUSH_IMG_SIZE,
|
|
7
|
+
MPUSH_VIDEO_SIZE,
|
|
8
|
+
MPUSH_GIF_SIZE,
|
|
9
|
+
ANDROID,
|
|
10
|
+
IMAGE,
|
|
11
|
+
VIDEO,
|
|
12
|
+
GIF,
|
|
13
|
+
CAROUSEL,
|
|
14
|
+
} from '../../constants';
|
|
15
|
+
|
|
16
|
+
// Mock the CDN transformation utility
|
|
17
|
+
jest.mock('../../../../utils/cdnTransformation', () => ({
|
|
18
|
+
getCdnUrl: jest.fn(),
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
describe('useUpload Hook', () => {
|
|
22
|
+
// Mock data and functions
|
|
23
|
+
const mockMobilePushActions = {
|
|
24
|
+
uploadAsset: jest.fn(),
|
|
25
|
+
clearAsset: jest.fn(),
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const mockSetAndroidContent = jest.fn();
|
|
29
|
+
const mockSetIosContent = jest.fn();
|
|
30
|
+
|
|
31
|
+
const defaultProps = {
|
|
32
|
+
mobilePushActions: mockMobilePushActions,
|
|
33
|
+
editData: {},
|
|
34
|
+
uploadedAssetData0: {},
|
|
35
|
+
uploadedAssetData1: {},
|
|
36
|
+
uploadAssetSuccess: false,
|
|
37
|
+
sameContent: false,
|
|
38
|
+
setAndroidContent: mockSetAndroidContent,
|
|
39
|
+
setIosContent: mockSetIosContent,
|
|
40
|
+
activeTab: ANDROID,
|
|
41
|
+
androidContent: { title: 'Test Android', message: 'Test message' },
|
|
42
|
+
iosContent: { title: 'Test iOS', message: 'Test message' },
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
beforeEach(() => {
|
|
46
|
+
jest.clearAllMocks();
|
|
47
|
+
getCdnUrl.mockImplementation(({ url }) => `cdn_${url}`);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('Hook Initialization', () => {
|
|
51
|
+
it('should initialize with default states', () => {
|
|
52
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
53
|
+
|
|
54
|
+
expect(result.current.androidAssetList).toEqual([]);
|
|
55
|
+
expect(result.current.iosAssetList).toEqual([]);
|
|
56
|
+
expect(result.current.mpushVideoSrcAndPreview).toEqual({
|
|
57
|
+
mpushVideoSrc: "",
|
|
58
|
+
mpushVideoPreviewImg: "",
|
|
59
|
+
duration: 0,
|
|
60
|
+
});
|
|
61
|
+
expect(result.current.imageSrc).toEqual({
|
|
62
|
+
androidImageSrc: "",
|
|
63
|
+
iosImageSrc: "",
|
|
64
|
+
});
|
|
65
|
+
expect(result.current.uploadErrors).toEqual({});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should initialize from edit data when provided', () => {
|
|
69
|
+
const editData = {
|
|
70
|
+
templateDetails: {
|
|
71
|
+
versions: {
|
|
72
|
+
base: {
|
|
73
|
+
content: {
|
|
74
|
+
ANDROID: {
|
|
75
|
+
expandableDetails: {
|
|
76
|
+
image: 'test-android-image.jpg',
|
|
77
|
+
video: 'test-video.mp4',
|
|
78
|
+
videoPreview: 'test-preview.jpg',
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
IOS: {
|
|
82
|
+
expandableDetails: {
|
|
83
|
+
image: 'test-ios-image.jpg',
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const { result } = renderHook(() => useUpload(
|
|
93
|
+
mockMobilePushActions,
|
|
94
|
+
editData,
|
|
95
|
+
{},
|
|
96
|
+
{},
|
|
97
|
+
false,
|
|
98
|
+
false,
|
|
99
|
+
mockSetAndroidContent,
|
|
100
|
+
mockSetIosContent,
|
|
101
|
+
ANDROID,
|
|
102
|
+
defaultProps.androidContent,
|
|
103
|
+
defaultProps.iosContent
|
|
104
|
+
));
|
|
105
|
+
|
|
106
|
+
expect(result.current.imageSrc.androidImageSrc).toBe('test-android-image.jpg');
|
|
107
|
+
expect(result.current.imageSrc.iosImageSrc).toBe('test-ios-image.jpg');
|
|
108
|
+
expect(result.current.mpushVideoSrcAndPreview.mpushVideoSrc).toBe('test-video.mp4');
|
|
109
|
+
expect(result.current.mpushVideoSrcAndPreview.mpushVideoPreviewImg).toBe('test-preview.jpg');
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
describe('File Validation Functions', () => {
|
|
114
|
+
describe('validateImageFile', () => {
|
|
115
|
+
it('should pass validation for valid image file', () => {
|
|
116
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
117
|
+
|
|
118
|
+
const validFile = new File(['test'], 'test.jpg', {
|
|
119
|
+
type: 'image/jpeg',
|
|
120
|
+
size: MPUSH_IMG_SIZE - 1000, // Under the limit
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
const errors = result.current.validateImageFile(validFile);
|
|
124
|
+
expect(errors).toEqual([]);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('should fail validation for oversized image file', () => {
|
|
128
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
129
|
+
|
|
130
|
+
// Create a file with data that exceeds the limit
|
|
131
|
+
const oversizedData = new Array(MPUSH_IMG_SIZE + 1000).fill('a').join('');
|
|
132
|
+
const oversizedFile = new File([oversizedData], 'test.jpg', {
|
|
133
|
+
type: 'image/jpeg',
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const errors = result.current.validateImageFile(oversizedFile);
|
|
137
|
+
expect(errors).toContain('File size should be less than 2MB');
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('should fail validation for invalid file type', () => {
|
|
141
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
142
|
+
|
|
143
|
+
const invalidFile = new File(['test'], 'test.pdf', {
|
|
144
|
+
type: 'application/pdf',
|
|
145
|
+
size: 1000,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const errors = result.current.validateImageFile(invalidFile);
|
|
149
|
+
expect(errors).toContain('Only JPEG and PNG files are allowed');
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('should fail validation for both size and type errors', () => {
|
|
153
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
154
|
+
|
|
155
|
+
// Create a file with data that exceeds the limit
|
|
156
|
+
const oversizedData = new Array(MPUSH_IMG_SIZE + 1000).fill('a').join('');
|
|
157
|
+
const invalidFile = new File([oversizedData], 'test.pdf', {
|
|
158
|
+
type: 'application/pdf',
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
const errors = result.current.validateImageFile(invalidFile);
|
|
162
|
+
expect(errors).toHaveLength(2);
|
|
163
|
+
expect(errors).toContain('File size should be less than 2MB');
|
|
164
|
+
expect(errors).toContain('Only JPEG and PNG files are allowed');
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
describe('validateVideoFile', () => {
|
|
169
|
+
it('should pass validation for valid video file', () => {
|
|
170
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
171
|
+
|
|
172
|
+
const validFile = new File(['test'], 'test.mp4', {
|
|
173
|
+
type: 'video/mp4',
|
|
174
|
+
size: MPUSH_VIDEO_SIZE - 1000,
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const errors = result.current.validateVideoFile(validFile);
|
|
178
|
+
expect(errors).toEqual([]);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('should fail validation for oversized video file', () => {
|
|
182
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
183
|
+
|
|
184
|
+
// Mock a file with oversized property
|
|
185
|
+
const oversizedFile = new File(['test'], 'test.mp4', {
|
|
186
|
+
type: 'video/mp4',
|
|
187
|
+
});
|
|
188
|
+
// Override the size property to simulate an oversized file
|
|
189
|
+
Object.defineProperty(oversizedFile, 'size', {
|
|
190
|
+
value: MPUSH_VIDEO_SIZE + 1000,
|
|
191
|
+
writable: false,
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
const errors = result.current.validateVideoFile(oversizedFile);
|
|
195
|
+
expect(errors).toContain('File size should be less than 209.7152MB');
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('should fail validation for invalid video file type', () => {
|
|
199
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
200
|
+
|
|
201
|
+
const invalidFile = new File(['test'], 'test.avi', {
|
|
202
|
+
type: 'video/avi',
|
|
203
|
+
size: 1000,
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
const errors = result.current.validateVideoFile(invalidFile);
|
|
207
|
+
expect(errors).toContain('Only 3GP, MP4, MOV, M4V files are allowed');
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
describe('validateGifFile', () => {
|
|
212
|
+
it('should pass validation for valid GIF file', () => {
|
|
213
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
214
|
+
|
|
215
|
+
const validFile = new File(['test'], 'test.gif', {
|
|
216
|
+
type: 'image/gif',
|
|
217
|
+
size: MPUSH_GIF_SIZE - 1000,
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
const errors = result.current.validateGifFile(validFile);
|
|
221
|
+
expect(errors).toEqual([]);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it('should fail validation for oversized GIF file', () => {
|
|
225
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
226
|
+
|
|
227
|
+
// Mock a file with oversized property
|
|
228
|
+
const oversizedFile = new File(['test'], 'test.gif', {
|
|
229
|
+
type: 'image/gif',
|
|
230
|
+
});
|
|
231
|
+
// Override the size property to simulate an oversized file
|
|
232
|
+
Object.defineProperty(oversizedFile, 'size', {
|
|
233
|
+
value: MPUSH_GIF_SIZE + 1000,
|
|
234
|
+
writable: false,
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
const errors = result.current.validateGifFile(oversizedFile);
|
|
238
|
+
expect(errors).toContain('File size should be less than 209.7152MB');
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it('should fail validation for non-GIF file', () => {
|
|
242
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
243
|
+
|
|
244
|
+
const invalidFile = new File(['test'], 'test.jpg', {
|
|
245
|
+
type: 'image/jpeg',
|
|
246
|
+
size: 1000,
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
const errors = result.current.validateGifFile(invalidFile);
|
|
250
|
+
expect(errors).toContain('Only GIF files are allowed');
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
describe('Upload Asset Function', () => {
|
|
256
|
+
it('should upload valid image file', () => {
|
|
257
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
258
|
+
|
|
259
|
+
const validFile = new File(['test'], 'test.jpg', {
|
|
260
|
+
type: 'image/jpeg',
|
|
261
|
+
size: 1000,
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
act(() => {
|
|
265
|
+
result.current.uploadMpushAsset(validFile, IMAGE.toLowerCase(), {});
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
expect(mockMobilePushActions.uploadAsset).toHaveBeenCalledWith(
|
|
269
|
+
validFile,
|
|
270
|
+
IMAGE.toLowerCase(),
|
|
271
|
+
{},
|
|
272
|
+
0, // Android tab
|
|
273
|
+
{
|
|
274
|
+
source: MOBILE_PUSH_CHANNEL.toLowerCase(),
|
|
275
|
+
channel: MOBILE_PUSH_CHANNEL,
|
|
276
|
+
}
|
|
277
|
+
);
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
it('should upload valid video file', () => {
|
|
281
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
282
|
+
|
|
283
|
+
const validFile = new File(['test'], 'test.mp4', {
|
|
284
|
+
type: 'video/mp4',
|
|
285
|
+
size: 1000,
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
act(() => {
|
|
289
|
+
result.current.uploadMpushAsset(validFile, VIDEO.toLowerCase(), {});
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
expect(mockMobilePushActions.uploadAsset).toHaveBeenCalledWith(
|
|
293
|
+
validFile,
|
|
294
|
+
VIDEO.toLowerCase(),
|
|
295
|
+
{},
|
|
296
|
+
0,
|
|
297
|
+
{
|
|
298
|
+
source: MOBILE_PUSH_CHANNEL.toLowerCase(),
|
|
299
|
+
channel: MOBILE_PUSH_CHANNEL,
|
|
300
|
+
}
|
|
301
|
+
);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it('should upload GIF file as video type', () => {
|
|
305
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
306
|
+
|
|
307
|
+
const validFile = new File(['test'], 'test.gif', {
|
|
308
|
+
type: 'image/gif',
|
|
309
|
+
size: 1000,
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
act(() => {
|
|
313
|
+
result.current.uploadMpushAsset(validFile, GIF.toLowerCase(), {});
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
expect(mockMobilePushActions.uploadAsset).toHaveBeenCalledWith(
|
|
317
|
+
validFile,
|
|
318
|
+
VIDEO.toLowerCase(), // GIF uploads use video type
|
|
319
|
+
{},
|
|
320
|
+
0,
|
|
321
|
+
{
|
|
322
|
+
source: MOBILE_PUSH_CHANNEL.toLowerCase(),
|
|
323
|
+
channel: MOBILE_PUSH_CHANNEL,
|
|
324
|
+
}
|
|
325
|
+
);
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
it('should not upload invalid file and set upload errors', () => {
|
|
329
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
330
|
+
|
|
331
|
+
// Create a file with data that exceeds the limit
|
|
332
|
+
const oversizedData = new Array(MPUSH_IMG_SIZE + 1000).fill('a').join('');
|
|
333
|
+
const invalidFile = new File([oversizedData], 'test.pdf', {
|
|
334
|
+
type: 'application/pdf',
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
act(() => {
|
|
338
|
+
result.current.uploadMpushAsset(invalidFile, IMAGE.toLowerCase(), {});
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
expect(mockMobilePushActions.uploadAsset).not.toHaveBeenCalled();
|
|
342
|
+
expect(result.current.uploadErrors[0]).toHaveLength(2);
|
|
343
|
+
expect(result.current.uploadErrors[0]).toContain('File size should be less than 2MB');
|
|
344
|
+
expect(result.current.uploadErrors[0]).toContain('Only JPEG and PNG files are allowed');
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
it('should handle iOS tab correctly', () => {
|
|
348
|
+
const iosProps = { ...defaultProps, activeTab: 'IOS' };
|
|
349
|
+
const { result } = renderHook(() => useUpload(...Object.values(iosProps)));
|
|
350
|
+
|
|
351
|
+
const validFile = new File(['test'], 'test.jpg', {
|
|
352
|
+
type: 'image/jpeg',
|
|
353
|
+
size: 1000,
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
act(() => {
|
|
357
|
+
result.current.uploadMpushAsset(validFile, IMAGE.toLowerCase(), {});
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
expect(mockMobilePushActions.uploadAsset).toHaveBeenCalledWith(
|
|
361
|
+
validFile,
|
|
362
|
+
IMAGE.toLowerCase(),
|
|
363
|
+
{},
|
|
364
|
+
1, // iOS tab
|
|
365
|
+
expect.any(Object)
|
|
366
|
+
);
|
|
367
|
+
});
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
describe('Image Source Management', () => {
|
|
371
|
+
describe('setUpdateMpushImageSrc', () => {
|
|
372
|
+
it('should update Android image source when sync is disabled', () => {
|
|
373
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
374
|
+
|
|
375
|
+
act(() => {
|
|
376
|
+
result.current.setUpdateMpushImageSrc('test-image.jpg', 0, IMAGE);
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
expect(result.current.imageSrc.androidImageSrc).toBe('test-image.jpg');
|
|
380
|
+
expect(result.current.imageSrc.iosImageSrc).toBe('');
|
|
381
|
+
expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(0);
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
it('should update both platforms when sync is enabled', () => {
|
|
385
|
+
const syncProps = { ...defaultProps, sameContent: true };
|
|
386
|
+
const { result } = renderHook(() => useUpload(...Object.values(syncProps)));
|
|
387
|
+
|
|
388
|
+
act(() => {
|
|
389
|
+
result.current.setUpdateMpushImageSrc('test-image.jpg', 0, IMAGE);
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
expect(result.current.imageSrc.androidImageSrc).toBe('test-image.jpg');
|
|
393
|
+
expect(result.current.imageSrc.iosImageSrc).toBe('test-image.jpg');
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
it('should update iOS image source when iOS tab is active', () => {
|
|
397
|
+
const iosProps = { ...defaultProps, activeTab: 'IOS' };
|
|
398
|
+
const { result } = renderHook(() => useUpload(...Object.values(iosProps)));
|
|
399
|
+
|
|
400
|
+
act(() => {
|
|
401
|
+
result.current.setUpdateMpushImageSrc('test-ios-image.jpg', 1, IMAGE);
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
expect(result.current.imageSrc.androidImageSrc).toBe('');
|
|
405
|
+
expect(result.current.imageSrc.iosImageSrc).toBe('test-ios-image.jpg');
|
|
406
|
+
expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(1);
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
it('should not handle carousel media type', () => {
|
|
410
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
411
|
+
|
|
412
|
+
act(() => {
|
|
413
|
+
result.current.setUpdateMpushImageSrc('test-image.jpg', 0, CAROUSEL);
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
expect(result.current.imageSrc.androidImageSrc).toBe('');
|
|
417
|
+
expect(result.current.imageSrc.iosImageSrc).toBe('');
|
|
418
|
+
expect(mockMobilePushActions.clearAsset).not.toHaveBeenCalled();
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
it('should default to IMAGE media type when mediaType parameter is not provided', () => {
|
|
422
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
423
|
+
|
|
424
|
+
act(() => {
|
|
425
|
+
result.current.setUpdateMpushImageSrc('test-image.jpg', 0); // No mediaType parameter
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
expect(result.current.imageSrc.androidImageSrc).toBe('test-image.jpg');
|
|
429
|
+
expect(result.current.imageSrc.iosImageSrc).toBe('');
|
|
430
|
+
expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(0);
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
it('should default to IMAGE media type for iOS platform when mediaType parameter is not provided', () => {
|
|
434
|
+
const iosProps = { ...defaultProps, activeTab: 'IOS' };
|
|
435
|
+
const { result } = renderHook(() => useUpload(...Object.values(iosProps)));
|
|
436
|
+
|
|
437
|
+
act(() => {
|
|
438
|
+
result.current.setUpdateMpushImageSrc('test-ios-image.jpg', 1); // No mediaType parameter
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
expect(result.current.imageSrc.androidImageSrc).toBe('');
|
|
442
|
+
expect(result.current.imageSrc.iosImageSrc).toBe('test-ios-image.jpg');
|
|
443
|
+
expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(1);
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
it('should default to IMAGE media type when sync is enabled and mediaType parameter is not provided', () => {
|
|
447
|
+
const syncProps = { ...defaultProps, sameContent: true };
|
|
448
|
+
const { result } = renderHook(() => useUpload(...Object.values(syncProps)));
|
|
449
|
+
|
|
450
|
+
act(() => {
|
|
451
|
+
result.current.setUpdateMpushImageSrc('test-image.jpg', 0); // No mediaType parameter
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
expect(result.current.imageSrc.androidImageSrc).toBe('test-image.jpg');
|
|
455
|
+
expect(result.current.imageSrc.iosImageSrc).toBe('test-image.jpg');
|
|
456
|
+
expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(0);
|
|
457
|
+
});
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
describe('updateOnMpushImageReUpload', () => {
|
|
461
|
+
it('should clear Android platform image when sync is disabled and Android tab is active', () => {
|
|
462
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
463
|
+
|
|
464
|
+
// Set initial images for both platforms
|
|
465
|
+
act(() => {
|
|
466
|
+
result.current.setImageSrc({
|
|
467
|
+
androidImageSrc: 'test-android-image.jpg',
|
|
468
|
+
iosImageSrc: 'test-ios-image.jpg',
|
|
469
|
+
});
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
// Clear image (should only clear Android since activeTab is ANDROID)
|
|
473
|
+
act(() => {
|
|
474
|
+
result.current.updateOnMpushImageReUpload();
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
expect(result.current.imageSrc.androidImageSrc).toBe('');
|
|
478
|
+
expect(result.current.imageSrc.iosImageSrc).toBe('test-ios-image.jpg'); // iOS should remain
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
it('should clear iOS platform image when sync is disabled and iOS tab is active', () => {
|
|
482
|
+
const iosProps = { ...defaultProps, activeTab: 'IOS' };
|
|
483
|
+
const { result } = renderHook(() => useUpload(...Object.values(iosProps)));
|
|
484
|
+
|
|
485
|
+
// Set initial images for both platforms
|
|
486
|
+
act(() => {
|
|
487
|
+
result.current.setImageSrc({
|
|
488
|
+
androidImageSrc: 'test-android-image.jpg',
|
|
489
|
+
iosImageSrc: 'test-ios-image.jpg',
|
|
490
|
+
});
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
// Clear image (should only clear iOS since activeTab is IOS)
|
|
494
|
+
act(() => {
|
|
495
|
+
result.current.updateOnMpushImageReUpload();
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
expect(result.current.imageSrc.androidImageSrc).toBe('test-android-image.jpg'); // Android should remain
|
|
499
|
+
expect(result.current.imageSrc.iosImageSrc).toBe(''); // iOS should be cleared
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
it('should clear both platforms when sync is enabled', () => {
|
|
503
|
+
const syncProps = { ...defaultProps, sameContent: true };
|
|
504
|
+
const { result } = renderHook(() => useUpload(...Object.values(syncProps)));
|
|
505
|
+
|
|
506
|
+
// Set initial images
|
|
507
|
+
act(() => {
|
|
508
|
+
result.current.setUpdateMpushImageSrc('test-image.jpg', IMAGE);
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
// Clear images
|
|
512
|
+
act(() => {
|
|
513
|
+
result.current.updateOnMpushImageReUpload();
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
expect(result.current.imageSrc.androidImageSrc).toBe('');
|
|
517
|
+
expect(result.current.imageSrc.iosImageSrc).toBe('');
|
|
518
|
+
});
|
|
519
|
+
});
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
describe('Video Source Management', () => {
|
|
523
|
+
describe('setUpdateMpushVideoSrc', () => {
|
|
524
|
+
it('should update video source and asset list', () => {
|
|
525
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
526
|
+
|
|
527
|
+
const videoData = {
|
|
528
|
+
videoSrc: 'test-video.mp4',
|
|
529
|
+
previewUrl: 'test-preview.jpg',
|
|
530
|
+
videoDuration: 120,
|
|
531
|
+
videoName: 'test-video.mp4',
|
|
532
|
+
fileHandle: 'file-handle-123',
|
|
533
|
+
};
|
|
534
|
+
|
|
535
|
+
act(() => {
|
|
536
|
+
result.current.setUpdateMpushVideoSrc(0, videoData);
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
expect(result.current.mpushVideoSrcAndPreview).toEqual({
|
|
540
|
+
mpushVideoSrc: 'test-video.mp4',
|
|
541
|
+
mpushVideoPreviewImg: 'test-preview.jpg',
|
|
542
|
+
duration: 120,
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
expect(result.current.assetList).toEqual(videoData);
|
|
546
|
+
expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(0);
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
it('should handle partial video data', () => {
|
|
550
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
551
|
+
|
|
552
|
+
const partialVideoData = {
|
|
553
|
+
videoSrc: 'test-video.mp4',
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
act(() => {
|
|
557
|
+
result.current.setUpdateMpushVideoSrc(0, partialVideoData);
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
expect(result.current.mpushVideoSrcAndPreview).toEqual({
|
|
561
|
+
mpushVideoSrc: 'test-video.mp4',
|
|
562
|
+
mpushVideoPreviewImg: '',
|
|
563
|
+
duration: 0,
|
|
564
|
+
});
|
|
565
|
+
});
|
|
566
|
+
});
|
|
567
|
+
|
|
568
|
+
describe('updateOnMpushVideoReUpload', () => {
|
|
569
|
+
it('should clear all video-related state', () => {
|
|
570
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
571
|
+
|
|
572
|
+
// Set initial video data
|
|
573
|
+
act(() => {
|
|
574
|
+
result.current.setUpdateMpushVideoSrc(0, {
|
|
575
|
+
videoSrc: 'test-video.mp4',
|
|
576
|
+
previewUrl: 'test-preview.jpg',
|
|
577
|
+
videoDuration: 120,
|
|
578
|
+
});
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
// Clear video data
|
|
582
|
+
act(() => {
|
|
583
|
+
result.current.updateOnMpushVideoReUpload();
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
expect(result.current.mpushVideoSrcAndPreview).toEqual({
|
|
587
|
+
mpushVideoSrc: '',
|
|
588
|
+
mpushVideoPreviewImg: '',
|
|
589
|
+
duration: 0,
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
expect(result.current.assetList).toEqual([]);
|
|
593
|
+
expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.any(Function));
|
|
594
|
+
expect(mockSetIosContent).toHaveBeenCalledWith(expect.any(Function));
|
|
595
|
+
expect(mockMobilePushActions.clearAsset).toHaveBeenCalledWith(0);
|
|
596
|
+
});
|
|
597
|
+
});
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
describe('Media Payload Generation', () => {
|
|
601
|
+
it('should generate correct payload for IMAGE media type', () => {
|
|
602
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
603
|
+
|
|
604
|
+
// Set image source
|
|
605
|
+
act(() => {
|
|
606
|
+
result.current.setUpdateMpushImageSrc('test-image.jpg', 0, IMAGE);
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
const payload = result.current.getMediaPayload(IMAGE, ANDROID);
|
|
610
|
+
|
|
611
|
+
expect(payload).toEqual({
|
|
612
|
+
imageUrl: 'cdn_test-image.jpg',
|
|
613
|
+
});
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
it('should generate correct payload for VIDEO media type', () => {
|
|
617
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
618
|
+
|
|
619
|
+
// Set video source with preview
|
|
620
|
+
act(() => {
|
|
621
|
+
result.current.setUpdateMpushVideoSrc(0, {
|
|
622
|
+
videoSrc: 'test-video.mp4',
|
|
623
|
+
previewUrl: 'test-preview.jpg',
|
|
624
|
+
videoDuration: 30,
|
|
625
|
+
});
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
const payload = result.current.getMediaPayload(VIDEO, ANDROID);
|
|
629
|
+
|
|
630
|
+
expect(payload).toEqual({
|
|
631
|
+
videoUrl: 'cdn_test-video.mp4',
|
|
632
|
+
videoPreviewImg: 'cdn_test-preview.jpg',
|
|
633
|
+
duration: 30,
|
|
634
|
+
});
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
it('should generate correct payload for GIF media type with preview image', () => {
|
|
638
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
639
|
+
|
|
640
|
+
// Set GIF source with preview
|
|
641
|
+
act(() => {
|
|
642
|
+
result.current.setUpdateMpushVideoSrc(0, {
|
|
643
|
+
videoSrc: 'test-gif.gif',
|
|
644
|
+
previewUrl: 'test-preview.jpg',
|
|
645
|
+
videoDuration: 5,
|
|
646
|
+
});
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
const payload = result.current.getMediaPayload(GIF, ANDROID);
|
|
650
|
+
|
|
651
|
+
expect(payload).toEqual({
|
|
652
|
+
gifUrl: 'cdn_test-gif.gif',
|
|
653
|
+
gifPreviewImg: 'cdn_test-preview.jpg',
|
|
654
|
+
});
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
it('should generate correct payload for GIF media type without preview image (covers line 328)', () => {
|
|
658
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
659
|
+
|
|
660
|
+
// Set GIF source WITHOUT preview to cover the falsy condition on line 328
|
|
661
|
+
act(() => {
|
|
662
|
+
result.current.setUpdateMpushVideoSrc(0, {
|
|
663
|
+
videoSrc: 'test-gif.gif',
|
|
664
|
+
previewUrl: '', // Empty preview URL to trigger the falsy condition
|
|
665
|
+
videoDuration: 5,
|
|
666
|
+
});
|
|
667
|
+
});
|
|
668
|
+
|
|
669
|
+
const payload = result.current.getMediaPayload(GIF, ANDROID);
|
|
670
|
+
|
|
671
|
+
expect(payload).toEqual({
|
|
672
|
+
gifUrl: 'cdn_test-gif.gif',
|
|
673
|
+
gifPreviewImg: '', // This should be empty string due to the falsy condition
|
|
674
|
+
});
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
it('should generate correct payload for GIF media type with null preview image (covers line 328)', () => {
|
|
678
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
679
|
+
|
|
680
|
+
// Set GIF source with null preview to cover the falsy condition on line 328
|
|
681
|
+
act(() => {
|
|
682
|
+
result.current.setUpdateMpushVideoSrc(0, {
|
|
683
|
+
videoSrc: 'test-gif.gif',
|
|
684
|
+
previewUrl: null, // Null preview URL to trigger the falsy condition
|
|
685
|
+
videoDuration: 5,
|
|
686
|
+
});
|
|
687
|
+
});
|
|
688
|
+
|
|
689
|
+
const payload = result.current.getMediaPayload(GIF, ANDROID);
|
|
690
|
+
|
|
691
|
+
expect(payload).toEqual({
|
|
692
|
+
gifUrl: 'cdn_test-gif.gif',
|
|
693
|
+
gifPreviewImg: '', // This should be empty string due to the falsy condition
|
|
694
|
+
});
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
it('should generate correct payload for GIF media type with undefined preview image (covers line 328)', () => {
|
|
698
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
699
|
+
|
|
700
|
+
// Set GIF source with undefined preview to cover the falsy condition on line 328
|
|
701
|
+
act(() => {
|
|
702
|
+
result.current.setUpdateMpushVideoSrc(0, {
|
|
703
|
+
videoSrc: 'test-gif.gif',
|
|
704
|
+
previewUrl: undefined, // Undefined preview URL to trigger the falsy condition
|
|
705
|
+
videoDuration: 5,
|
|
706
|
+
});
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
const payload = result.current.getMediaPayload(GIF, ANDROID);
|
|
710
|
+
|
|
711
|
+
expect(payload).toEqual({
|
|
712
|
+
gifUrl: 'cdn_test-gif.gif',
|
|
713
|
+
gifPreviewImg: '', // This should be empty string due to the falsy condition
|
|
714
|
+
});
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
it('should return empty object for unknown media type', () => {
|
|
718
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
719
|
+
|
|
720
|
+
const payload = result.current.getMediaPayload('UNKNOWN_TYPE', ANDROID);
|
|
721
|
+
|
|
722
|
+
expect(payload).toEqual({});
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
it('should return empty object when no media is set', () => {
|
|
726
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
727
|
+
|
|
728
|
+
// Test with IMAGE but no image source set
|
|
729
|
+
const imagePayload = result.current.getMediaPayload(IMAGE, ANDROID);
|
|
730
|
+
expect(imagePayload).toEqual({});
|
|
731
|
+
|
|
732
|
+
// Test with VIDEO but no video source set
|
|
733
|
+
const videoPayload = result.current.getMediaPayload(VIDEO, ANDROID);
|
|
734
|
+
expect(videoPayload).toEqual({});
|
|
735
|
+
|
|
736
|
+
// Test with GIF but no GIF source set
|
|
737
|
+
const gifPayload = result.current.getMediaPayload(GIF, ANDROID);
|
|
738
|
+
expect(gifPayload).toEqual({});
|
|
739
|
+
});
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
describe('Preview Data Generation', () => {
|
|
743
|
+
describe('getPreviewData', () => {
|
|
744
|
+
it('should generate image preview data', () => {
|
|
745
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
746
|
+
|
|
747
|
+
act(() => {
|
|
748
|
+
result.current.setUpdateMpushImageSrc('test-image.jpg', 0, IMAGE);
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
const previewData = result.current.getPreviewData(IMAGE, ANDROID);
|
|
752
|
+
|
|
753
|
+
expect(previewData).toEqual({
|
|
754
|
+
imageSrc: 'test-image.jpg',
|
|
755
|
+
});
|
|
756
|
+
});
|
|
757
|
+
|
|
758
|
+
it('should generate video preview data', () => {
|
|
759
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
760
|
+
|
|
761
|
+
act(() => {
|
|
762
|
+
result.current.setUpdateMpushVideoSrc(0, {
|
|
763
|
+
videoSrc: 'test-video.mp4',
|
|
764
|
+
previewUrl: 'test-preview.jpg',
|
|
765
|
+
videoDuration: 120,
|
|
766
|
+
});
|
|
767
|
+
});
|
|
768
|
+
|
|
769
|
+
const previewData = result.current.getPreviewData(VIDEO, ANDROID);
|
|
770
|
+
|
|
771
|
+
expect(previewData).toEqual({
|
|
772
|
+
videoSrc: 'test-video.mp4',
|
|
773
|
+
videoPreviewImg: 'test-preview.jpg',
|
|
774
|
+
duration: 120,
|
|
775
|
+
});
|
|
776
|
+
});
|
|
777
|
+
|
|
778
|
+
it('should generate GIF preview data', () => {
|
|
779
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
780
|
+
|
|
781
|
+
act(() => {
|
|
782
|
+
result.current.setUpdateMpushVideoSrc(0, {
|
|
783
|
+
videoSrc: 'test-gif.gif',
|
|
784
|
+
previewUrl: 'test-preview.jpg',
|
|
785
|
+
});
|
|
786
|
+
});
|
|
787
|
+
|
|
788
|
+
const previewData = result.current.getPreviewData(GIF, ANDROID);
|
|
789
|
+
|
|
790
|
+
expect(previewData).toEqual({
|
|
791
|
+
gifSrc: 'test-gif.gif',
|
|
792
|
+
gifPreviewImg: 'test-preview.jpg',
|
|
793
|
+
});
|
|
794
|
+
});
|
|
795
|
+
|
|
796
|
+
it('should generate image preview data for iOS platform', () => {
|
|
797
|
+
const iosProps = { ...defaultProps, activeTab: 'IOS' };
|
|
798
|
+
const { result } = renderHook(() => useUpload(...Object.values(iosProps)));
|
|
799
|
+
|
|
800
|
+
act(() => {
|
|
801
|
+
result.current.setUpdateMpushImageSrc('test-ios-image.jpg', 1, IMAGE);
|
|
802
|
+
});
|
|
803
|
+
|
|
804
|
+
const previewData = result.current.getPreviewData(IMAGE, 'IOS');
|
|
805
|
+
|
|
806
|
+
expect(previewData).toEqual({
|
|
807
|
+
imageSrc: 'test-ios-image.jpg',
|
|
808
|
+
});
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
it('should generate video preview data for iOS platform', () => {
|
|
812
|
+
const iosProps = { ...defaultProps, activeTab: 'IOS' };
|
|
813
|
+
const { result } = renderHook(() => useUpload(...Object.values(iosProps)));
|
|
814
|
+
|
|
815
|
+
act(() => {
|
|
816
|
+
result.current.setUpdateMpushVideoSrc(1, {
|
|
817
|
+
videoSrc: 'test-ios-video.mp4',
|
|
818
|
+
previewUrl: 'test-ios-preview.jpg',
|
|
819
|
+
videoDuration: 90,
|
|
820
|
+
});
|
|
821
|
+
});
|
|
822
|
+
|
|
823
|
+
const previewData = result.current.getPreviewData(VIDEO, 'IOS');
|
|
824
|
+
|
|
825
|
+
expect(previewData).toEqual({
|
|
826
|
+
videoSrc: 'test-ios-video.mp4',
|
|
827
|
+
videoPreviewImg: 'test-ios-preview.jpg',
|
|
828
|
+
duration: 90,
|
|
829
|
+
});
|
|
830
|
+
});
|
|
831
|
+
|
|
832
|
+
it('should generate GIF preview data for iOS platform', () => {
|
|
833
|
+
const iosProps = { ...defaultProps, activeTab: 'IOS' };
|
|
834
|
+
const { result } = renderHook(() => useUpload(...Object.values(iosProps)));
|
|
835
|
+
|
|
836
|
+
act(() => {
|
|
837
|
+
result.current.setUpdateMpushVideoSrc(1, {
|
|
838
|
+
videoSrc: 'test-ios-gif.gif',
|
|
839
|
+
previewUrl: 'test-ios-preview.jpg',
|
|
840
|
+
});
|
|
841
|
+
});
|
|
842
|
+
|
|
843
|
+
const previewData = result.current.getPreviewData(GIF, 'IOS');
|
|
844
|
+
|
|
845
|
+
expect(previewData).toEqual({
|
|
846
|
+
gifSrc: 'test-ios-gif.gif',
|
|
847
|
+
gifPreviewImg: 'test-ios-preview.jpg',
|
|
848
|
+
});
|
|
849
|
+
});
|
|
850
|
+
});
|
|
851
|
+
});
|
|
852
|
+
|
|
853
|
+
describe('Media Upload Validation', () => {
|
|
854
|
+
describe('isMediaUploaded', () => {
|
|
855
|
+
it('should return true for uploaded image', () => {
|
|
856
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
857
|
+
|
|
858
|
+
act(() => {
|
|
859
|
+
result.current.setUpdateMpushImageSrc('test-image.jpg', 0, IMAGE);
|
|
860
|
+
});
|
|
861
|
+
|
|
862
|
+
expect(result.current.isMediaUploaded(IMAGE, ANDROID)).toBe(true);
|
|
863
|
+
});
|
|
864
|
+
|
|
865
|
+
it('should return false for non-uploaded image', () => {
|
|
866
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
867
|
+
|
|
868
|
+
expect(result.current.isMediaUploaded(IMAGE, ANDROID)).toBe(false);
|
|
869
|
+
});
|
|
870
|
+
|
|
871
|
+
it('should return true for uploaded video', () => {
|
|
872
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
873
|
+
|
|
874
|
+
act(() => {
|
|
875
|
+
result.current.setUpdateMpushVideoSrc(0, {
|
|
876
|
+
videoSrc: 'test-video.mp4',
|
|
877
|
+
});
|
|
878
|
+
});
|
|
879
|
+
|
|
880
|
+
expect(result.current.isMediaUploaded(VIDEO, ANDROID)).toBe(true);
|
|
881
|
+
expect(result.current.isMediaUploaded(GIF, ANDROID)).toBe(true);
|
|
882
|
+
});
|
|
883
|
+
|
|
884
|
+
it('should return true for text media types', () => {
|
|
885
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
886
|
+
|
|
887
|
+
expect(result.current.isMediaUploaded('TEXT', ANDROID)).toBe(true);
|
|
888
|
+
expect(result.current.isMediaUploaded('NONE', ANDROID)).toBe(true);
|
|
889
|
+
});
|
|
890
|
+
|
|
891
|
+
it('should return true for uploaded image on iOS platform', () => {
|
|
892
|
+
const iosProps = { ...defaultProps, activeTab: 'IOS' };
|
|
893
|
+
const { result } = renderHook(() => useUpload(...Object.values(iosProps)));
|
|
894
|
+
|
|
895
|
+
act(() => {
|
|
896
|
+
result.current.setUpdateMpushImageSrc('test-ios-image.jpg', IMAGE);
|
|
897
|
+
});
|
|
898
|
+
|
|
899
|
+
expect(result.current.isMediaUploaded(IMAGE, 'IOS')).toBe(true);
|
|
900
|
+
});
|
|
901
|
+
|
|
902
|
+
it('should return false for non-uploaded image on iOS platform', () => {
|
|
903
|
+
const iosProps = { ...defaultProps, activeTab: 'IOS' };
|
|
904
|
+
const { result } = renderHook(() => useUpload(...Object.values(iosProps)));
|
|
905
|
+
|
|
906
|
+
expect(result.current.isMediaUploaded(IMAGE, 'IOS')).toBe(false);
|
|
907
|
+
});
|
|
908
|
+
|
|
909
|
+
it('should return true for uploaded video on iOS platform', () => {
|
|
910
|
+
const iosProps = { ...defaultProps, activeTab: 'IOS' };
|
|
911
|
+
const { result } = renderHook(() => useUpload(...Object.values(iosProps)));
|
|
912
|
+
|
|
913
|
+
act(() => {
|
|
914
|
+
result.current.setUpdateMpushVideoSrc(1, {
|
|
915
|
+
videoSrc: 'test-ios-video.mp4',
|
|
916
|
+
});
|
|
917
|
+
});
|
|
918
|
+
|
|
919
|
+
expect(result.current.isMediaUploaded(VIDEO, 'IOS')).toBe(true);
|
|
920
|
+
expect(result.current.isMediaUploaded(GIF, 'IOS')).toBe(true);
|
|
921
|
+
});
|
|
922
|
+
|
|
923
|
+
it('should return true for text media types on iOS platform', () => {
|
|
924
|
+
const iosProps = { ...defaultProps, activeTab: 'IOS' };
|
|
925
|
+
const { result } = renderHook(() => useUpload(...Object.values(iosProps)));
|
|
926
|
+
|
|
927
|
+
expect(result.current.isMediaUploaded('TEXT', 'IOS')).toBe(true);
|
|
928
|
+
expect(result.current.isMediaUploaded('NONE', 'IOS')).toBe(true);
|
|
929
|
+
});
|
|
930
|
+
});
|
|
931
|
+
});
|
|
932
|
+
|
|
933
|
+
describe('Utility Functions', () => {
|
|
934
|
+
describe('clearImageDataByMediaType', () => {
|
|
935
|
+
it('should clear image data for IMAGE media type', () => {
|
|
936
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
937
|
+
|
|
938
|
+
// Set initial image on both platforms
|
|
939
|
+
act(() => {
|
|
940
|
+
result.current.setImageSrc({
|
|
941
|
+
androidImageSrc: 'test-android.jpg',
|
|
942
|
+
iosImageSrc: 'test-ios.jpg',
|
|
943
|
+
});
|
|
944
|
+
});
|
|
945
|
+
|
|
946
|
+
// Clear image data (should only clear Android since activeTab is ANDROID and sameContent is false)
|
|
947
|
+
act(() => {
|
|
948
|
+
result.current.clearImageDataByMediaType(IMAGE);
|
|
949
|
+
});
|
|
950
|
+
|
|
951
|
+
expect(result.current.imageSrc).toEqual({
|
|
952
|
+
androidImageSrc: '',
|
|
953
|
+
iosImageSrc: 'test-ios.jpg', // iOS should remain unchanged
|
|
954
|
+
});
|
|
955
|
+
});
|
|
956
|
+
|
|
957
|
+
it('should not clear data for non-IMAGE media types', () => {
|
|
958
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
959
|
+
|
|
960
|
+
// Set initial image
|
|
961
|
+
act(() => {
|
|
962
|
+
result.current.setUpdateMpushImageSrc('test-image.jpg', 0, IMAGE);
|
|
963
|
+
});
|
|
964
|
+
|
|
965
|
+
// Try to clear with different media type
|
|
966
|
+
act(() => {
|
|
967
|
+
result.current.clearImageDataByMediaType(VIDEO);
|
|
968
|
+
});
|
|
969
|
+
|
|
970
|
+
expect(result.current.imageSrc.androidImageSrc).toBe('test-image.jpg');
|
|
971
|
+
});
|
|
972
|
+
});
|
|
973
|
+
|
|
974
|
+
describe('resetUploadStates', () => {
|
|
975
|
+
it('should reset all upload states', () => {
|
|
976
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
977
|
+
|
|
978
|
+
// Set some data
|
|
979
|
+
act(() => {
|
|
980
|
+
result.current.setUpdateMpushImageSrc('test-image.jpg', 0, IMAGE);
|
|
981
|
+
result.current.setUpdateMpushVideoSrc(0, {
|
|
982
|
+
videoSrc: 'test-video.mp4',
|
|
983
|
+
previewUrl: 'test-preview.jpg',
|
|
984
|
+
});
|
|
985
|
+
});
|
|
986
|
+
|
|
987
|
+
// Reset all states
|
|
988
|
+
act(() => {
|
|
989
|
+
result.current.resetUploadStates();
|
|
990
|
+
});
|
|
991
|
+
|
|
992
|
+
expect(result.current.imageSrc).toEqual({
|
|
993
|
+
androidImageSrc: '',
|
|
994
|
+
iosImageSrc: '',
|
|
995
|
+
});
|
|
996
|
+
expect(result.current.mpushVideoSrcAndPreview).toEqual({
|
|
997
|
+
mpushVideoSrc: '',
|
|
998
|
+
mpushVideoPreviewImg: '',
|
|
999
|
+
duration: 0,
|
|
1000
|
+
});
|
|
1001
|
+
expect(result.current.assetList).toEqual([]);
|
|
1002
|
+
});
|
|
1003
|
+
});
|
|
1004
|
+
|
|
1005
|
+
describe('CDN URL functions', () => {
|
|
1006
|
+
it('should generate CDN image URL', () => {
|
|
1007
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
1008
|
+
|
|
1009
|
+
const cdnUrl = result.current.getCdnImageUrl('test-image.jpg');
|
|
1010
|
+
|
|
1011
|
+
expect(cdnUrl).toBe('cdn_test-image.jpg');
|
|
1012
|
+
expect(getCdnUrl).toHaveBeenCalledWith({
|
|
1013
|
+
url: 'test-image.jpg',
|
|
1014
|
+
channelName: MOBILE_PUSH_CHANNEL,
|
|
1015
|
+
});
|
|
1016
|
+
});
|
|
1017
|
+
|
|
1018
|
+
it('should return empty string for empty image URL', () => {
|
|
1019
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
1020
|
+
|
|
1021
|
+
const cdnUrl = result.current.getCdnImageUrl('');
|
|
1022
|
+
|
|
1023
|
+
expect(cdnUrl).toBe('');
|
|
1024
|
+
});
|
|
1025
|
+
|
|
1026
|
+
it('should generate CDN video URL', () => {
|
|
1027
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
1028
|
+
|
|
1029
|
+
const cdnUrl = result.current.getCdnVideoUrl('test-video.mp4');
|
|
1030
|
+
|
|
1031
|
+
expect(cdnUrl).toBe('cdn_test-video.mp4');
|
|
1032
|
+
expect(getCdnUrl).toHaveBeenCalledWith({
|
|
1033
|
+
url: 'test-video.mp4',
|
|
1034
|
+
channelName: MOBILE_PUSH_CHANNEL,
|
|
1035
|
+
});
|
|
1036
|
+
});
|
|
1037
|
+
|
|
1038
|
+
it('should return empty string for empty video URL', () => {
|
|
1039
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
1040
|
+
|
|
1041
|
+
const cdnUrl = result.current.getCdnVideoUrl('');
|
|
1042
|
+
|
|
1043
|
+
expect(cdnUrl).toBe('');
|
|
1044
|
+
});
|
|
1045
|
+
});
|
|
1046
|
+
});
|
|
1047
|
+
|
|
1048
|
+
describe('useEffect behaviors', () => {
|
|
1049
|
+
it('should call setAndroidContent and setIosContent when imageSrc changes', () => {
|
|
1050
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
1051
|
+
|
|
1052
|
+
act(() => {
|
|
1053
|
+
result.current.setUpdateMpushImageSrc('test-image.jpg', 0, IMAGE);
|
|
1054
|
+
});
|
|
1055
|
+
|
|
1056
|
+
expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.any(Function));
|
|
1057
|
+
expect(mockSetIosContent).toHaveBeenCalledWith(expect.any(Function));
|
|
1058
|
+
});
|
|
1059
|
+
|
|
1060
|
+
it('should call setAndroidContent and setIosContent when video src changes', () => {
|
|
1061
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
1062
|
+
|
|
1063
|
+
act(() => {
|
|
1064
|
+
result.current.setUpdateMpushVideoSrc(0, {
|
|
1065
|
+
videoSrc: 'test-video.mp4',
|
|
1066
|
+
previewUrl: 'test-preview.jpg',
|
|
1067
|
+
});
|
|
1068
|
+
});
|
|
1069
|
+
|
|
1070
|
+
expect(mockSetAndroidContent).toHaveBeenCalledWith(expect.any(Function));
|
|
1071
|
+
expect(mockSetIosContent).toHaveBeenCalledWith(expect.any(Function));
|
|
1072
|
+
});
|
|
1073
|
+
});
|
|
1074
|
+
|
|
1075
|
+
describe('Edge Cases', () => {
|
|
1076
|
+
it('should handle undefined file in validation functions', () => {
|
|
1077
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
1078
|
+
|
|
1079
|
+
expect(() => {
|
|
1080
|
+
result.current.validateImageFile(undefined);
|
|
1081
|
+
}).toThrow();
|
|
1082
|
+
});
|
|
1083
|
+
|
|
1084
|
+
it('should handle missing file properties gracefully', () => {
|
|
1085
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
1086
|
+
|
|
1087
|
+
const fileWithoutSize = { name: 'test.jpg' };
|
|
1088
|
+
|
|
1089
|
+
expect(() => {
|
|
1090
|
+
result.current.validateImageFile(fileWithoutSize);
|
|
1091
|
+
}).not.toThrow();
|
|
1092
|
+
});
|
|
1093
|
+
|
|
1094
|
+
it('should handle empty edit data gracefully', () => {
|
|
1095
|
+
const { result } = renderHook(() => useUpload(
|
|
1096
|
+
mockMobilePushActions,
|
|
1097
|
+
{ templateDetails: null },
|
|
1098
|
+
{},
|
|
1099
|
+
{},
|
|
1100
|
+
false,
|
|
1101
|
+
false,
|
|
1102
|
+
mockSetAndroidContent,
|
|
1103
|
+
mockSetIosContent,
|
|
1104
|
+
ANDROID,
|
|
1105
|
+
defaultProps.androidContent,
|
|
1106
|
+
defaultProps.iosContent
|
|
1107
|
+
));
|
|
1108
|
+
|
|
1109
|
+
expect(result.current.imageSrc).toEqual({
|
|
1110
|
+
androidImageSrc: '',
|
|
1111
|
+
iosImageSrc: '',
|
|
1112
|
+
});
|
|
1113
|
+
});
|
|
1114
|
+
|
|
1115
|
+
it('should handle malformed edit data structure', () => {
|
|
1116
|
+
const malformedEditData = {
|
|
1117
|
+
templateDetails: {
|
|
1118
|
+
versions: {
|
|
1119
|
+
base: {
|
|
1120
|
+
content: null,
|
|
1121
|
+
},
|
|
1122
|
+
},
|
|
1123
|
+
},
|
|
1124
|
+
};
|
|
1125
|
+
|
|
1126
|
+
const { result } = renderHook(() => useUpload(
|
|
1127
|
+
mockMobilePushActions,
|
|
1128
|
+
malformedEditData,
|
|
1129
|
+
{},
|
|
1130
|
+
{},
|
|
1131
|
+
false,
|
|
1132
|
+
false,
|
|
1133
|
+
mockSetAndroidContent,
|
|
1134
|
+
mockSetIosContent,
|
|
1135
|
+
ANDROID,
|
|
1136
|
+
defaultProps.androidContent,
|
|
1137
|
+
defaultProps.iosContent
|
|
1138
|
+
));
|
|
1139
|
+
|
|
1140
|
+
expect(result.current.imageSrc).toEqual({
|
|
1141
|
+
androidImageSrc: '',
|
|
1142
|
+
iosImageSrc: '',
|
|
1143
|
+
});
|
|
1144
|
+
});
|
|
1145
|
+
});
|
|
1146
|
+
|
|
1147
|
+
describe('Additional Edge Cases for Complete Coverage', () => {
|
|
1148
|
+
it('should handle setUpdateMpushVideoSrc with minimal data', () => {
|
|
1149
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
1150
|
+
|
|
1151
|
+
// Test with minimal data object
|
|
1152
|
+
act(() => {
|
|
1153
|
+
result.current.setUpdateMpushVideoSrc(0, {
|
|
1154
|
+
videoSrc: 'test.mp4',
|
|
1155
|
+
});
|
|
1156
|
+
});
|
|
1157
|
+
|
|
1158
|
+
expect(result.current.mpushVideoSrcAndPreview.mpushVideoSrc).toBe('test.mp4');
|
|
1159
|
+
expect(result.current.mpushVideoSrcAndPreview.mpushVideoPreviewImg).toBe('');
|
|
1160
|
+
expect(result.current.mpushVideoSrcAndPreview.duration).toBe(0);
|
|
1161
|
+
});
|
|
1162
|
+
|
|
1163
|
+
it('should handle setUpdateMpushVideoSrc with extra data spread', () => {
|
|
1164
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
1165
|
+
|
|
1166
|
+
const extraData = {
|
|
1167
|
+
videoSrc: 'test.mp4',
|
|
1168
|
+
previewUrl: 'preview.jpg',
|
|
1169
|
+
videoDuration: 30,
|
|
1170
|
+
extraField: 'extra-value',
|
|
1171
|
+
anotherField: 123,
|
|
1172
|
+
};
|
|
1173
|
+
|
|
1174
|
+
act(() => {
|
|
1175
|
+
result.current.setUpdateMpushVideoSrc(0, extraData);
|
|
1176
|
+
});
|
|
1177
|
+
|
|
1178
|
+
expect(result.current.assetList).toEqual(expect.objectContaining({
|
|
1179
|
+
videoSrc: 'test.mp4',
|
|
1180
|
+
previewUrl: 'preview.jpg',
|
|
1181
|
+
videoDuration: 30,
|
|
1182
|
+
extraField: 'extra-value',
|
|
1183
|
+
anotherField: 123,
|
|
1184
|
+
}));
|
|
1185
|
+
});
|
|
1186
|
+
|
|
1187
|
+
it('should handle clearImageDataByMediaType for non-IMAGE types', () => {
|
|
1188
|
+
const { result } = renderHook(() => useUpload(...Object.values(defaultProps)));
|
|
1189
|
+
|
|
1190
|
+
// Set some image data first
|
|
1191
|
+
act(() => {
|
|
1192
|
+
result.current.setUpdateMpushImageSrc('test-image.jpg', 0, IMAGE);
|
|
1193
|
+
});
|
|
1194
|
+
|
|
1195
|
+
expect(result.current.imageSrc.androidImageSrc).toBe('test-image.jpg');
|
|
1196
|
+
|
|
1197
|
+
// Clear using CAROUSEL type (should not affect image data)
|
|
1198
|
+
act(() => {
|
|
1199
|
+
result.current.clearImageDataByMediaType(CAROUSEL);
|
|
1200
|
+
});
|
|
1201
|
+
|
|
1202
|
+
// Image data should remain unchanged for CAROUSEL
|
|
1203
|
+
expect(result.current.imageSrc.androidImageSrc).toBe('test-image.jpg');
|
|
1204
|
+
|
|
1205
|
+
// Set data for both platforms to test clearing behavior
|
|
1206
|
+
act(() => {
|
|
1207
|
+
result.current.setImageSrc({
|
|
1208
|
+
androidImageSrc: 'test-android.jpg',
|
|
1209
|
+
iosImageSrc: 'test-ios.jpg',
|
|
1210
|
+
});
|
|
1211
|
+
});
|
|
1212
|
+
|
|
1213
|
+
// Clear using IMAGE type (should clear only Android since activeTab is ANDROID and sameContent is false)
|
|
1214
|
+
act(() => {
|
|
1215
|
+
result.current.clearImageDataByMediaType(IMAGE);
|
|
1216
|
+
});
|
|
1217
|
+
|
|
1218
|
+
// Only Android should be cleared when sameContent=false
|
|
1219
|
+
expect(result.current.imageSrc.androidImageSrc).toBe('');
|
|
1220
|
+
expect(result.current.imageSrc.iosImageSrc).toBe('test-ios.jpg');
|
|
1221
|
+
});
|
|
1222
|
+
});
|
|
1223
|
+
});
|