@capillarytech/creatives-library 8.0.264 → 8.0.265

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 (158) hide show
  1. package/constants/unified.js +0 -1
  2. package/package.json +1 -1
  3. package/services/api.js +0 -5
  4. package/utils/common.js +0 -6
  5. package/utils/tagValidations.js +1 -2
  6. package/utils/tests/transformerUtils.test.js +0 -297
  7. package/utils/transformerUtils.js +0 -40
  8. package/v2Components/CapImageUpload/constants.js +0 -2
  9. package/v2Components/CapImageUpload/index.js +16 -65
  10. package/v2Components/CapImageUpload/index.scss +1 -4
  11. package/v2Components/CapImageUpload/messages.js +1 -5
  12. package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +2 -2
  13. package/v2Components/FormBuilder/index.js +8 -8
  14. package/v2Containers/App/constants.js +0 -5
  15. package/v2Containers/CreativesContainer/SlideBoxContent.js +2 -57
  16. package/v2Containers/CreativesContainer/SlideBoxHeader.js +0 -1
  17. package/v2Containers/CreativesContainer/constants.js +0 -3
  18. package/v2Containers/CreativesContainer/index.js +0 -168
  19. package/v2Containers/CreativesContainer/messages.js +0 -4
  20. package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +0 -210
  21. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -304
  22. package/v2Containers/Email/index.js +7 -3
  23. package/v2Containers/FTP/index.js +1 -1
  24. package/v2Containers/InApp/index.js +0 -1
  25. package/v2Containers/Line/Container/Text/index.js +0 -1
  26. package/v2Containers/MobilePushNew/index.js +0 -1
  27. package/v2Containers/Rcs/index.js +0 -3
  28. package/v2Containers/SmsTrai/Edit/index.js +0 -1
  29. package/v2Containers/Templates/ChannelTypeIllustration.js +1 -13
  30. package/v2Containers/Templates/_templates.scss +0 -205
  31. package/v2Containers/Templates/actions.js +1 -2
  32. package/v2Containers/Templates/constants.js +0 -1
  33. package/v2Containers/Templates/index.js +34 -274
  34. package/v2Containers/Templates/messages.js +0 -24
  35. package/v2Containers/Templates/reducer.js +0 -2
  36. package/v2Containers/Templates/tests/index.test.js +0 -10
  37. package/v2Containers/TemplatesV2/index.js +7 -15
  38. package/v2Containers/TemplatesV2/messages.js +0 -4
  39. package/v2Containers/Viber/index.js +0 -1
  40. package/v2Containers/Whatsapp/index.js +0 -1
  41. package/v2Containers/Zalo/index.js +0 -1
  42. package/v2Containers/Zalo/tests/index.test.js +5 -1
  43. package/utils/imageUrlUpload.js +0 -141
  44. package/v2Components/CapImageUrlUpload/constants.js +0 -26
  45. package/v2Components/CapImageUrlUpload/index.js +0 -365
  46. package/v2Components/CapImageUrlUpload/index.scss +0 -35
  47. package/v2Components/CapImageUrlUpload/messages.js +0 -47
  48. package/v2Containers/WebPush/Create/components/BrandIconSection.js +0 -108
  49. package/v2Containers/WebPush/Create/components/ButtonForm.js +0 -172
  50. package/v2Containers/WebPush/Create/components/ButtonItem.js +0 -101
  51. package/v2Containers/WebPush/Create/components/ButtonList.js +0 -145
  52. package/v2Containers/WebPush/Create/components/ButtonsLinksSection.js +0 -164
  53. package/v2Containers/WebPush/Create/components/ButtonsLinksSection.test.js +0 -463
  54. package/v2Containers/WebPush/Create/components/FormActions.js +0 -54
  55. package/v2Containers/WebPush/Create/components/FormActions.test.js +0 -163
  56. package/v2Containers/WebPush/Create/components/MediaSection.js +0 -142
  57. package/v2Containers/WebPush/Create/components/MediaSection.test.js +0 -341
  58. package/v2Containers/WebPush/Create/components/MessageSection.js +0 -103
  59. package/v2Containers/WebPush/Create/components/MessageSection.test.js +0 -268
  60. package/v2Containers/WebPush/Create/components/NotificationTitleSection.js +0 -87
  61. package/v2Containers/WebPush/Create/components/NotificationTitleSection.test.js +0 -210
  62. package/v2Containers/WebPush/Create/components/TemplateNameSection.js +0 -54
  63. package/v2Containers/WebPush/Create/components/TemplateNameSection.test.js +0 -143
  64. package/v2Containers/WebPush/Create/components/__snapshots__/ButtonsLinksSection.test.js.snap +0 -86
  65. package/v2Containers/WebPush/Create/components/__snapshots__/FormActions.test.js.snap +0 -16
  66. package/v2Containers/WebPush/Create/components/__snapshots__/MediaSection.test.js.snap +0 -41
  67. package/v2Containers/WebPush/Create/components/__snapshots__/MessageSection.test.js.snap +0 -54
  68. package/v2Containers/WebPush/Create/components/__snapshots__/NotificationTitleSection.test.js.snap +0 -37
  69. package/v2Containers/WebPush/Create/components/__snapshots__/TemplateNameSection.test.js.snap +0 -21
  70. package/v2Containers/WebPush/Create/components/_buttons.scss +0 -246
  71. package/v2Containers/WebPush/Create/components/tests/ButtonForm.test.js +0 -554
  72. package/v2Containers/WebPush/Create/components/tests/ButtonItem.test.js +0 -607
  73. package/v2Containers/WebPush/Create/components/tests/ButtonList.test.js +0 -633
  74. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonForm.test.js.snap +0 -666
  75. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonItem.test.js.snap +0 -74
  76. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonList.test.js.snap +0 -78
  77. package/v2Containers/WebPush/Create/hooks/useButtonManagement.js +0 -138
  78. package/v2Containers/WebPush/Create/hooks/useButtonManagement.test.js +0 -406
  79. package/v2Containers/WebPush/Create/hooks/useCharacterCount.js +0 -30
  80. package/v2Containers/WebPush/Create/hooks/useCharacterCount.test.js +0 -151
  81. package/v2Containers/WebPush/Create/hooks/useImageUpload.js +0 -104
  82. package/v2Containers/WebPush/Create/hooks/useImageUpload.test.js +0 -538
  83. package/v2Containers/WebPush/Create/hooks/useTagManagement.js +0 -122
  84. package/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +0 -633
  85. package/v2Containers/WebPush/Create/index.js +0 -1148
  86. package/v2Containers/WebPush/Create/index.scss +0 -134
  87. package/v2Containers/WebPush/Create/messages.js +0 -211
  88. package/v2Containers/WebPush/Create/preview/DevicePreviewContent.js +0 -228
  89. package/v2Containers/WebPush/Create/preview/NotificationContainer.js +0 -294
  90. package/v2Containers/WebPush/Create/preview/PreviewContent.js +0 -90
  91. package/v2Containers/WebPush/Create/preview/PreviewControls.js +0 -305
  92. package/v2Containers/WebPush/Create/preview/PreviewDisclaimer.js +0 -25
  93. package/v2Containers/WebPush/Create/preview/WebPushPreview.js +0 -155
  94. package/v2Containers/WebPush/Create/preview/assets/Light.svg +0 -53
  95. package/v2Containers/WebPush/Create/preview/assets/Top.svg +0 -5
  96. package/v2Containers/WebPush/Create/preview/assets/android-arrow-down.svg +0 -9
  97. package/v2Containers/WebPush/Create/preview/assets/android-arrow-up.svg +0 -9
  98. package/v2Containers/WebPush/Create/preview/assets/chrome-icon.png +0 -0
  99. package/v2Containers/WebPush/Create/preview/assets/edge-icon.png +0 -0
  100. package/v2Containers/WebPush/Create/preview/assets/firefox-icon.svg +0 -106
  101. package/v2Containers/WebPush/Create/preview/assets/iOS.svg +0 -26
  102. package/v2Containers/WebPush/Create/preview/assets/macos-arrow-down-icon.svg +0 -9
  103. package/v2Containers/WebPush/Create/preview/assets/macos-triple-dot-icon.svg +0 -9
  104. package/v2Containers/WebPush/Create/preview/assets/opera-icon.svg +0 -18
  105. package/v2Containers/WebPush/Create/preview/assets/safari-icon.svg +0 -29
  106. package/v2Containers/WebPush/Create/preview/assets/windows-close-icon.svg +0 -9
  107. package/v2Containers/WebPush/Create/preview/assets/windows-triple-dot-icon.svg +0 -9
  108. package/v2Containers/WebPush/Create/preview/components/AndroidMobileChromeHeader.js +0 -51
  109. package/v2Containers/WebPush/Create/preview/components/AndroidMobileExpanded.js +0 -145
  110. package/v2Containers/WebPush/Create/preview/components/IOSHeader.js +0 -45
  111. package/v2Containers/WebPush/Create/preview/components/NotificationExpandedContent.js +0 -68
  112. package/v2Containers/WebPush/Create/preview/components/NotificationHeader.js +0 -61
  113. package/v2Containers/WebPush/Create/preview/components/WindowsChromeExpanded.js +0 -99
  114. package/v2Containers/WebPush/Create/preview/components/tests/AndroidMobileExpanded.test.js +0 -733
  115. package/v2Containers/WebPush/Create/preview/components/tests/WindowsChromeExpanded.test.js +0 -571
  116. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/AndroidMobileExpanded.test.js.snap +0 -85
  117. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/WindowsChromeExpanded.test.js.snap +0 -81
  118. package/v2Containers/WebPush/Create/preview/config/notificationMappings.js +0 -50
  119. package/v2Containers/WebPush/Create/preview/constants.js +0 -637
  120. package/v2Containers/WebPush/Create/preview/notification-container.scss +0 -79
  121. package/v2Containers/WebPush/Create/preview/preview.scss +0 -358
  122. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-chrome.scss +0 -370
  123. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-edge.scss +0 -12
  124. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-firefox.scss +0 -12
  125. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-opera.scss +0 -12
  126. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-chrome.scss +0 -47
  127. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-edge.scss +0 -11
  128. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-firefox.scss +0 -11
  129. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-opera.scss +0 -11
  130. package/v2Containers/WebPush/Create/preview/styles/_base.scss +0 -207
  131. package/v2Containers/WebPush/Create/preview/styles/_ios.scss +0 -153
  132. package/v2Containers/WebPush/Create/preview/styles/_ipados.scss +0 -107
  133. package/v2Containers/WebPush/Create/preview/styles/_macos-chrome.scss +0 -101
  134. package/v2Containers/WebPush/Create/preview/styles/_windows-chrome.scss +0 -229
  135. package/v2Containers/WebPush/Create/preview/tests/DevicePreviewContent.test.js +0 -909
  136. package/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +0 -1081
  137. package/v2Containers/WebPush/Create/preview/tests/PreviewControls.test.js +0 -723
  138. package/v2Containers/WebPush/Create/preview/tests/WebPushPreview.test.js +0 -1327
  139. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/DevicePreviewContent.test.js.snap +0 -131
  140. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/NotificationContainer.test.js.snap +0 -112
  141. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/PreviewControls.test.js.snap +0 -144
  142. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/WebPushPreview.test.js.snap +0 -129
  143. package/v2Containers/WebPush/Create/utils/payloadBuilder.js +0 -96
  144. package/v2Containers/WebPush/Create/utils/payloadBuilder.test.js +0 -396
  145. package/v2Containers/WebPush/Create/utils/previewUtils.js +0 -89
  146. package/v2Containers/WebPush/Create/utils/urlValidation.js +0 -115
  147. package/v2Containers/WebPush/Create/utils/urlValidation.test.js +0 -449
  148. package/v2Containers/WebPush/Create/utils/validation.js +0 -76
  149. package/v2Containers/WebPush/Create/utils/validation.test.js +0 -283
  150. package/v2Containers/WebPush/actions.js +0 -60
  151. package/v2Containers/WebPush/constants.js +0 -132
  152. package/v2Containers/WebPush/index.js +0 -2
  153. package/v2Containers/WebPush/reducer.js +0 -104
  154. package/v2Containers/WebPush/sagas.js +0 -119
  155. package/v2Containers/WebPush/selectors.js +0 -65
  156. package/v2Containers/WebPush/tests/reducer.test.js +0 -863
  157. package/v2Containers/WebPush/tests/sagas.test.js +0 -566
  158. package/v2Containers/WebPush/tests/selectors.test.js +0 -960
@@ -1,538 +0,0 @@
1
- import { renderHook } from '@testing-library/react';
2
- import { act } from 'react';
3
- import { useImageUpload } from './useImageUpload';
4
- import { IMAGE_UPLOAD_METHODS } from '../../constants';
5
-
6
- describe('useImageUpload', () => {
7
- const mockClearWebPushAsset = jest.fn();
8
- const mockUploadWebPushAsset = jest.fn();
9
-
10
- const mockWebPushActions = {
11
- clearWebPushAsset: mockClearWebPushAsset,
12
- uploadWebPushAsset: mockUploadWebPushAsset,
13
- };
14
-
15
- const defaultWebPush = {};
16
-
17
- beforeEach(() => {
18
- jest.clearAllMocks();
19
- });
20
-
21
- describe('Initialization', () => {
22
- it('should initialize with default upload method', () => {
23
- const { result } = renderHook(() =>
24
- useImageUpload({
25
- webPush: defaultWebPush,
26
- webPushActions: mockWebPushActions,
27
- index: 0,
28
- })
29
- );
30
-
31
- expect(result.current.uploadMethod).toBe(IMAGE_UPLOAD_METHODS.UPLOAD_IMAGE);
32
- expect(result.current.imageSrc).toBe('');
33
- expect(result.current.imageUrl).toBe('');
34
- expect(result.current.isValidating).toBe(false);
35
- expect(result.current.isUploading).toBe(false);
36
- });
37
-
38
- it('should initialize with custom upload method', () => {
39
- const { result } = renderHook(() =>
40
- useImageUpload({
41
- webPush: defaultWebPush,
42
- webPushActions: mockWebPushActions,
43
- index: 0,
44
- initialUploadMethod: IMAGE_UPLOAD_METHODS.ADD_IMAGE_URL,
45
- })
46
- );
47
-
48
- expect(result.current.uploadMethod).toBe(IMAGE_UPLOAD_METHODS.ADD_IMAGE_URL);
49
- });
50
- });
51
-
52
- describe('Upload Method Changes', () => {
53
- it('should change upload method', () => {
54
- const { result } = renderHook(() =>
55
- useImageUpload({
56
- webPush: defaultWebPush,
57
- webPushActions: mockWebPushActions,
58
- index: 0,
59
- })
60
- );
61
-
62
- const event = {
63
- target: {
64
- value: IMAGE_UPLOAD_METHODS.ADD_IMAGE_URL,
65
- },
66
- };
67
-
68
- act(() => {
69
- result.current.handleUploadMethodChange(event);
70
- });
71
-
72
- expect(result.current.uploadMethod).toBe(IMAGE_UPLOAD_METHODS.ADD_IMAGE_URL);
73
- expect(result.current.imageSrc).toBe('');
74
- expect(result.current.imageUrl).toBe('');
75
- });
76
-
77
- it('should clear imageSrc and imageUrl when upload method changes', () => {
78
- const { result } = renderHook(() =>
79
- useImageUpload({
80
- webPush: defaultWebPush,
81
- webPushActions: mockWebPushActions,
82
- index: 0,
83
- })
84
- );
85
-
86
- act(() => {
87
- result.current.setImageSrc('path/to/image.jpg');
88
- result.current.setImageUrl('https://example.com/image.jpg');
89
- });
90
-
91
- const event = {
92
- target: {
93
- value: IMAGE_UPLOAD_METHODS.ADD_IMAGE_URL,
94
- },
95
- };
96
-
97
- act(() => {
98
- result.current.handleUploadMethodChange(event);
99
- });
100
-
101
- expect(result.current.imageSrc).toBe('');
102
- expect(result.current.imageUrl).toBe('');
103
- });
104
- });
105
-
106
- describe('Image Source Management', () => {
107
- it('should set image source', () => {
108
- const { result } = renderHook(() =>
109
- useImageUpload({
110
- webPush: defaultWebPush,
111
- webPushActions: mockWebPushActions,
112
- index: 0,
113
- })
114
- );
115
-
116
- act(() => {
117
- result.current.setImageSrc('path/to/image.jpg');
118
- });
119
-
120
- expect(result.current.imageSrc).toBe('path/to/image.jpg');
121
- });
122
-
123
- it('should clear asset when setting image source', () => {
124
- const { result } = renderHook(() =>
125
- useImageUpload({
126
- webPush: defaultWebPush,
127
- webPushActions: mockWebPushActions,
128
- index: 0,
129
- })
130
- );
131
-
132
- act(() => {
133
- result.current.setUpdateImageSrc('path/to/image.jpg');
134
- });
135
-
136
- expect(mockClearWebPushAsset).toHaveBeenCalledWith(0);
137
- expect(result.current.imageSrc).toBe('path/to/image.jpg');
138
- });
139
-
140
- it('should use correct index when clearing asset', () => {
141
- const { result } = renderHook(() =>
142
- useImageUpload({
143
- webPush: defaultWebPush,
144
- webPushActions: mockWebPushActions,
145
- index: 1,
146
- })
147
- );
148
-
149
- act(() => {
150
- result.current.setUpdateImageSrc('path/to/image.jpg');
151
- });
152
-
153
- expect(mockClearWebPushAsset).toHaveBeenCalledWith(1);
154
- });
155
-
156
- it('should update on re-upload', () => {
157
- const { result } = renderHook(() =>
158
- useImageUpload({
159
- webPush: defaultWebPush,
160
- webPushActions: mockWebPushActions,
161
- index: 0,
162
- })
163
- );
164
-
165
- act(() => {
166
- result.current.setImageSrc('path/to/image.jpg');
167
- });
168
-
169
- act(() => {
170
- result.current.updateOnReUpload();
171
- });
172
-
173
- expect(result.current.imageSrc).toBe('');
174
- });
175
- });
176
-
177
- describe('Image URL Management', () => {
178
- it('should set image URL', () => {
179
- const { result } = renderHook(() =>
180
- useImageUpload({
181
- webPush: defaultWebPush,
182
- webPushActions: mockWebPushActions,
183
- index: 0,
184
- })
185
- );
186
-
187
- act(() => {
188
- result.current.setImageUrl('https://example.com/image.jpg');
189
- });
190
-
191
- expect(result.current.imageUrl).toBe('https://example.com/image.jpg');
192
- });
193
-
194
- it('should clear imageSrc when URL changes', () => {
195
- const { result } = renderHook(() =>
196
- useImageUpload({
197
- webPush: defaultWebPush,
198
- webPushActions: mockWebPushActions,
199
- index: 0,
200
- })
201
- );
202
-
203
- act(() => {
204
- result.current.setImageSrc('path/to/image.jpg');
205
- });
206
-
207
- act(() => {
208
- result.current.handleUrlChange('https://example.com/image.jpg');
209
- });
210
-
211
- expect(result.current.imageSrc).toBe('');
212
- });
213
-
214
- it('should not clear imageSrc when URL is the same', () => {
215
- const { result } = renderHook(() =>
216
- useImageUpload({
217
- webPush: defaultWebPush,
218
- webPushActions: mockWebPushActions,
219
- index: 0,
220
- })
221
- );
222
-
223
- // First set imageSrc to a non-empty value
224
- act(() => {
225
- result.current.setImageSrc('path/to/image.jpg');
226
- });
227
-
228
- // Then set imageUrl
229
- act(() => {
230
- result.current.setImageUrl('https://example.com/image.jpg');
231
- });
232
-
233
- // Capture the non-empty imageSrc
234
- const nonEmptyImageSrc = result.current.imageSrc;
235
- expect(nonEmptyImageSrc).toBe('path/to/image.jpg');
236
- expect(nonEmptyImageSrc).not.toBe('');
237
-
238
- // Call handleUrlChange with the same URL
239
- act(() => {
240
- result.current.handleUrlChange('https://example.com/image.jpg');
241
- });
242
-
243
- // Verify imageSrc is preserved (not cleared)
244
- expect(result.current.imageSrc).toBe(nonEmptyImageSrc);
245
- expect(result.current.imageSrc).toBe('path/to/image.jpg');
246
- });
247
- });
248
-
249
- describe('Asset Upload', () => {
250
- it('should call uploadWebPushAsset with correct parameters', () => {
251
- const { result } = renderHook(() =>
252
- useImageUpload({
253
- webPush: defaultWebPush,
254
- webPushActions: mockWebPushActions,
255
- index: 0,
256
- })
257
- );
258
-
259
- const file = new File(['test'], 'test.jpg', { type: 'image/jpeg' });
260
- const type = 'image';
261
- const fileParams = { width: 100, height: 100 };
262
-
263
- act(() => {
264
- result.current.uploadAsset(file, type, fileParams);
265
- });
266
-
267
- expect(mockUploadWebPushAsset).toHaveBeenCalledWith(file, type, fileParams, 0);
268
- });
269
-
270
- it('should use correct index for upload', () => {
271
- const { result } = renderHook(() =>
272
- useImageUpload({
273
- webPush: defaultWebPush,
274
- webPushActions: mockWebPushActions,
275
- index: 1,
276
- })
277
- );
278
-
279
- const file = new File(['test'], 'test.jpg', { type: 'image/jpeg' });
280
-
281
- act(() => {
282
- result.current.uploadAsset(file, 'image', {});
283
- });
284
-
285
- expect(mockUploadWebPushAsset).toHaveBeenCalledWith(file, 'image', {}, 1);
286
- });
287
- });
288
-
289
- describe('Validation and Upload State', () => {
290
- it('should update validation state', () => {
291
- const { result } = renderHook(() =>
292
- useImageUpload({
293
- webPush: defaultWebPush,
294
- webPushActions: mockWebPushActions,
295
- index: 0,
296
- })
297
- );
298
-
299
- act(() => {
300
- result.current.handleValidationStateChange(true);
301
- });
302
-
303
- expect(result.current.isValidating).toBe(true);
304
-
305
- act(() => {
306
- result.current.handleValidationStateChange(false);
307
- });
308
-
309
- expect(result.current.isValidating).toBe(false);
310
- });
311
-
312
- it('should update upload state', () => {
313
- const { result } = renderHook(() =>
314
- useImageUpload({
315
- webPush: defaultWebPush,
316
- webPushActions: mockWebPushActions,
317
- index: 0,
318
- })
319
- );
320
-
321
- act(() => {
322
- result.current.handleUploadStateChange(true);
323
- });
324
-
325
- expect(result.current.isUploading).toBe(true);
326
-
327
- act(() => {
328
- result.current.handleUploadStateChange(false);
329
- });
330
-
331
- expect(result.current.isUploading).toBe(false);
332
- });
333
- });
334
-
335
- describe('Restoring Image from Uploaded Asset', () => {
336
- it('should restore image from uploadedAssetData0', () => {
337
- const webPush = {
338
- uploadedAssetData0: {
339
- metaInfo: {
340
- secure_file_path: 'secure/path/to/image.jpg',
341
- },
342
- },
343
- };
344
-
345
- const { result } = renderHook(() =>
346
- useImageUpload({
347
- webPush,
348
- webPushActions: mockWebPushActions,
349
- index: 0,
350
- })
351
- );
352
-
353
- expect(result.current.imageSrc).toBe('secure/path/to/image.jpg');
354
- });
355
-
356
- it('should restore image from uploadedAssetData for index 0', () => {
357
- const webPush = {
358
- uploadedAssetData: {
359
- metaInfo: {
360
- secure_file_path: 'secure/path/to/image.jpg',
361
- },
362
- },
363
- };
364
-
365
- const { result } = renderHook(() =>
366
- useImageUpload({
367
- webPush,
368
- webPushActions: mockWebPushActions,
369
- index: 0,
370
- })
371
- );
372
-
373
- expect(result.current.imageSrc).toBe('secure/path/to/image.jpg');
374
- });
375
-
376
- it('should restore image from uploadedAssetData{index} for non-zero index', () => {
377
- const webPush = {
378
- uploadedAssetData1: {
379
- metaInfo: {
380
- secure_file_path: 'secure/path/to/brand-icon.jpg',
381
- },
382
- },
383
- };
384
-
385
- const { result } = renderHook(() =>
386
- useImageUpload({
387
- webPush,
388
- webPushActions: mockWebPushActions,
389
- index: 1,
390
- })
391
- );
392
-
393
- expect(result.current.imageSrc).toBe('secure/path/to/brand-icon.jpg');
394
- });
395
-
396
- it('should not restore image when secure_file_path is missing', () => {
397
- const webPush = {
398
- uploadedAssetData0: {
399
- metaInfo: {},
400
- },
401
- };
402
-
403
- const { result } = renderHook(() =>
404
- useImageUpload({
405
- webPush,
406
- webPushActions: mockWebPushActions,
407
- index: 0,
408
- })
409
- );
410
-
411
- expect(result.current.imageSrc).toBe('');
412
- });
413
-
414
- it('should not restore image when metaInfo is missing', () => {
415
- const webPush = {
416
- uploadedAssetData0: {},
417
- };
418
-
419
- const { result } = renderHook(() =>
420
- useImageUpload({
421
- webPush,
422
- webPushActions: mockWebPushActions,
423
- index: 0,
424
- })
425
- );
426
-
427
- expect(result.current.imageSrc).toBe('');
428
- });
429
-
430
- it('should not restore image when uploadedAssetData is missing', () => {
431
- const { result } = renderHook(() =>
432
- useImageUpload({
433
- webPush: {},
434
- webPushActions: mockWebPushActions,
435
- index: 0,
436
- })
437
- );
438
-
439
- expect(result.current.imageSrc).toBe('');
440
- });
441
-
442
- it('should update image when webPush changes', () => {
443
- const { result, rerender } = renderHook(
444
- ({ webPush }) =>
445
- useImageUpload({
446
- webPush,
447
- webPushActions: mockWebPushActions,
448
- index: 0,
449
- }),
450
- {
451
- initialProps: {
452
- webPush: {},
453
- },
454
- }
455
- );
456
-
457
- expect(result.current.imageSrc).toBe('');
458
-
459
- const newWebPush = {
460
- uploadedAssetData0: {
461
- metaInfo: {
462
- secure_file_path: 'new/path/to/image.jpg',
463
- },
464
- },
465
- };
466
-
467
- rerender({ webPush: newWebPush });
468
-
469
- expect(result.current.imageSrc).toBe('new/path/to/image.jpg');
470
- });
471
-
472
- it('should preserve image when webPush asset data is removed (edit mode compatibility)', () => {
473
- const webPush = {
474
- uploadedAssetData0: {
475
- metaInfo: {
476
- secure_file_path: 'secure/path/to/image.jpg',
477
- },
478
- },
479
- };
480
-
481
- const { result, rerender } = renderHook(
482
- ({ webPush }) =>
483
- useImageUpload({
484
- webPush,
485
- webPushActions: mockWebPushActions,
486
- index: 0,
487
- }),
488
- {
489
- initialProps: {
490
- webPush,
491
- },
492
- }
493
- );
494
-
495
- expect(result.current.imageSrc).toBe('secure/path/to/image.jpg');
496
-
497
- // Image should persist when asset data is removed (e.g., in edit mode)
498
- rerender({ webPush: {} });
499
-
500
- expect(result.current.imageSrc).toBe('secure/path/to/image.jpg');
501
- });
502
- });
503
-
504
- describe('Edge Cases', () => {
505
- it('should handle empty secure_file_path', () => {
506
- const webPush = {
507
- uploadedAssetData0: {
508
- metaInfo: {
509
- secure_file_path: '',
510
- },
511
- },
512
- };
513
-
514
- const { result } = renderHook(() =>
515
- useImageUpload({
516
- webPush,
517
- webPushActions: mockWebPushActions,
518
- index: 0,
519
- })
520
- );
521
-
522
- expect(result.current.imageSrc).toBe('');
523
- });
524
-
525
- it('should handle null webPush', () => {
526
- const { result } = renderHook(() =>
527
- useImageUpload({
528
- webPush: null,
529
- webPushActions: mockWebPushActions,
530
- index: 0,
531
- })
532
- );
533
-
534
- expect(result.current.imageSrc).toBe('');
535
- });
536
- });
537
- });
538
-
@@ -1,122 +0,0 @@
1
- import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
2
- import get from 'lodash/get';
3
- import {
4
- ALL,
5
- TAG,
6
- EMBEDDED,
7
- DEFAULT,
8
- FULL,
9
- LIBRARY,
10
- } from '../../../Whatsapp/constants';
11
- import { SMS } from '../../../CreativesContainer/constants';
12
- import { EMPTY_ARRAY } from '../../constants';
13
-
14
- /**
15
- * Custom hook for managing tags (fetching and context changes)
16
- * @param {Object} params - Hook parameters
17
- * @returns {Object} Tag state and handlers
18
- */
19
- export const useTagManagement = ({
20
- location,
21
- globalActions,
22
- metaEntities,
23
- getDefaultTags,
24
- supportedTags = EMPTY_ARRAY,
25
- injectedTags,
26
- eventContextTags = EMPTY_ARRAY,
27
- }) => {
28
- const [tags, setTags] = useState([]);
29
- const tagFetchKeyRef = useRef(null);
30
-
31
- // Memoize location-derived values to prevent unnecessary re-renders
32
- const locationType = useMemo(() => location?.query?.type || '', [location?.query?.type]);
33
- const locationModule = useMemo(() => location?.query?.module || '', [location?.query?.module]);
34
-
35
- const tagFetchKey = useMemo(
36
- () =>
37
- JSON.stringify({
38
- type: locationType,
39
- module: locationModule,
40
- defaultTags: getDefaultTags || '',
41
- }),
42
- [locationModule, locationType, getDefaultTags],
43
- );
44
-
45
- useEffect(() => {
46
- if (!globalActions?.fetchSchemaForEntity) return;
47
-
48
- const { type, module } = location?.query || {};
49
- const isEmbedded = type === EMBEDDED;
50
- const context = isEmbedded ? module : DEFAULT;
51
- const embedded = isEmbedded ? type : FULL;
52
- const query = {
53
- layout: SMS,
54
- type: TAG,
55
- context,
56
- embedded,
57
- };
58
- if (getDefaultTags) {
59
- query.context = getDefaultTags;
60
- }
61
-
62
- if (tagFetchKeyRef.current === tagFetchKey) {
63
- return;
64
- }
65
- tagFetchKeyRef.current = tagFetchKey;
66
- globalActions.fetchSchemaForEntity(query);
67
- // tagFetchKey is memoized and captures all dependencies; including globalActions/location?.query causes infinite loops
68
- // eslint-disable-next-line react-hooks/exhaustive-deps
69
- }, [tagFetchKey]);
70
-
71
- // Update tags from metaEntities and supported tags
72
- // supportedTags must be memoized by the caller
73
- useEffect(() => {
74
- if (!metaEntities) return;
75
- let tagList = get(metaEntities, 'tags.standard', []);
76
- if (locationType === EMBEDDED && locationModule === LIBRARY && !getDefaultTags) {
77
- tagList = supportedTags;
78
- }
79
- setTags(tagList);
80
- }, [metaEntities, locationModule, locationType, getDefaultTags, supportedTags]);
81
-
82
- const handleOnTagsContextChange = useCallback(
83
- (data) => {
84
- if (!globalActions?.fetchSchemaForEntity) return;
85
-
86
- const isEmbedded = locationType === EMBEDDED;
87
- const embedded = isEmbedded ? locationType : FULL;
88
- const normalized = (data ?? '').toLowerCase();
89
- const context = (!normalized || normalized === ALL) ? DEFAULT : normalized;
90
- const query = {
91
- layout: SMS,
92
- type: TAG,
93
- context,
94
- embedded,
95
- };
96
- if (getDefaultTags) {
97
- query.context = getDefaultTags;
98
- }
99
- globalActions.fetchSchemaForEntity(query);
100
- },
101
- [globalActions, getDefaultTags, locationType],
102
- );
103
-
104
- // Memoize validation configuration
105
- const validationConfig = useMemo(
106
- () => ({
107
- tagsParam: tags,
108
- injectedTagsParams: injectedTags,
109
- location,
110
- tagModule: getDefaultTags,
111
- eventContextTags,
112
- }),
113
- [tags, injectedTags, location, getDefaultTags, eventContextTags],
114
- );
115
-
116
- return {
117
- tags,
118
- handleOnTagsContextChange,
119
- validationConfig,
120
- };
121
- };
122
-