@capillarytech/creatives-library 8.0.242-alpha.0 → 8.0.242-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.
Files changed (215) hide show
  1. package/assets/Android.png +0 -0
  2. package/assets/iOS.png +0 -0
  3. package/constants/unified.js +2 -1
  4. package/initialReducer.js +2 -0
  5. package/package.json +1 -1
  6. package/sagas/__tests__/assetPolling.test.js +74 -3
  7. package/sagas/assetPolling.js +8 -1
  8. package/services/api.js +10 -5
  9. package/services/tests/api.test.js +18 -0
  10. package/translations/en.json +0 -1
  11. package/utils/common.js +5 -0
  12. package/utils/commonUtils.js +14 -1
  13. package/utils/tests/commonUtil.test.js +224 -0
  14. package/utils/transformTemplateConfig.js +0 -10
  15. package/utils/transformerUtils.js +0 -42
  16. package/v2Components/CapDeviceContent/index.js +61 -56
  17. package/v2Components/CapImageUpload/constants.js +0 -2
  18. package/v2Components/CapImageUpload/index.js +14 -54
  19. package/v2Components/CapImageUpload/index.scss +1 -4
  20. package/v2Components/CapImageUpload/messages.js +0 -4
  21. package/v2Components/CapTagList/index.js +6 -1
  22. package/v2Components/CapTagListWithInput/index.js +5 -1
  23. package/v2Components/CapTagListWithInput/messages.js +1 -1
  24. package/v2Components/CapWhatsappCTA/tests/index.test.js +5 -0
  25. package/v2Components/ErrorInfoNote/index.js +412 -72
  26. package/v2Components/ErrorInfoNote/messages.js +22 -0
  27. package/v2Components/ErrorInfoNote/style.scss +279 -2
  28. package/v2Components/HtmlEditor/HTMLEditor.js +210 -89
  29. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +1132 -133
  30. package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +17 -12
  31. package/v2Components/HtmlEditor/_htmlEditor.scss +8 -23
  32. package/v2Components/HtmlEditor/_index.lazy.scss +1 -1
  33. package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +13 -101
  34. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +148 -139
  35. package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +2 -1
  36. package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
  37. package/v2Components/HtmlEditor/components/EditorToolbar/index.js +1 -1
  38. package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +1 -0
  39. package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +4 -7
  40. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +35 -45
  41. package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +1 -3
  42. package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
  43. package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +7 -6
  44. package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +3 -6
  45. package/v2Components/HtmlEditor/components/PreviewPane/index.js +10 -11
  46. package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
  47. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +87 -62
  48. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +49 -31
  49. package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +254 -0
  50. package/v2Components/HtmlEditor/components/ValidationTabs/index.js +362 -0
  51. package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +51 -0
  52. package/v2Components/HtmlEditor/constants.js +29 -20
  53. package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +373 -16
  54. package/v2Components/HtmlEditor/hooks/useEditorContent.js +5 -2
  55. package/v2Components/HtmlEditor/hooks/useInAppContent.js +88 -146
  56. package/v2Components/HtmlEditor/index.js +1 -1
  57. package/v2Components/HtmlEditor/messages.js +95 -85
  58. package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +99 -101
  59. package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +23 -25
  60. package/v2Components/HtmlEditor/utils/validationAdapter.js +34 -41
  61. package/v2Components/MobilePushPreviewV2/index.js +32 -7
  62. package/v2Components/TemplatePreview/_templatePreview.scss +44 -24
  63. package/v2Components/TemplatePreview/index.js +47 -32
  64. package/v2Components/TemplatePreview/messages.js +4 -0
  65. package/v2Components/TestAndPreviewSlidebox/index.js +31 -25
  66. package/v2Containers/App/constants.js +0 -5
  67. package/v2Containers/BeeEditor/index.js +82 -80
  68. package/v2Containers/BeePopupEditor/constants.js +10 -0
  69. package/v2Containers/BeePopupEditor/index.js +193 -0
  70. package/v2Containers/BeePopupEditor/tests/index.test.js +627 -0
  71. package/v2Containers/Cap/tests/__snapshots__/index.test.js.snap +0 -1
  72. package/v2Containers/CreativesContainer/SlideBoxContent.js +148 -120
  73. package/v2Containers/CreativesContainer/SlideBoxFooter.js +9 -3
  74. package/v2Containers/CreativesContainer/SlideBoxHeader.js +2 -2
  75. package/v2Containers/CreativesContainer/constants.js +1 -2
  76. package/v2Containers/CreativesContainer/index.js +173 -193
  77. package/v2Containers/CreativesContainer/messages.js +4 -4
  78. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +38 -50
  79. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +36 -0
  80. package/v2Containers/Email/actions.js +7 -0
  81. package/v2Containers/Email/constants.js +5 -1
  82. package/v2Containers/Email/index.js +13 -0
  83. package/v2Containers/Email/messages.js +32 -0
  84. package/v2Containers/Email/reducer.js +12 -1
  85. package/v2Containers/Email/sagas.js +41 -6
  86. package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +2 -0
  87. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +1045 -0
  88. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +193 -7
  89. package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +40 -74
  90. package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +2 -67
  91. package/v2Containers/EmailWrapper/constants.js +2 -0
  92. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +436 -67
  93. package/v2Containers/EmailWrapper/index.js +99 -23
  94. package/v2Containers/EmailWrapper/messages.js +61 -1
  95. package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +26 -1
  96. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +111 -77
  97. package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +376 -0
  98. package/v2Containers/InApp/__tests__/sagas.test.js +363 -0
  99. package/v2Containers/InApp/actions.js +7 -0
  100. package/v2Containers/InApp/constants.js +20 -4
  101. package/v2Containers/InApp/index.js +800 -357
  102. package/v2Containers/InApp/index.scss +4 -3
  103. package/v2Containers/InApp/messages.js +7 -3
  104. package/v2Containers/InApp/reducer.js +21 -3
  105. package/v2Containers/InApp/sagas.js +29 -9
  106. package/v2Containers/InApp/selectors.js +25 -5
  107. package/v2Containers/InApp/tests/index.test.js +154 -50
  108. package/v2Containers/InApp/tests/reducer.test.js +34 -0
  109. package/v2Containers/InApp/tests/sagas.test.js +61 -9
  110. package/v2Containers/InApp/tests/selectors.test.js +612 -0
  111. package/v2Containers/InAppWrapper/components/InAppWrapperView.js +162 -0
  112. package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +267 -0
  113. package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +9 -0
  114. package/v2Containers/InAppWrapper/constants.js +16 -0
  115. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +473 -0
  116. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +198 -0
  117. package/v2Containers/InAppWrapper/index.js +148 -0
  118. package/v2Containers/InAppWrapper/messages.js +49 -0
  119. package/v2Containers/InappAdvance/index.js +1099 -0
  120. package/v2Containers/InappAdvance/index.scss +10 -0
  121. package/v2Containers/InappAdvance/tests/index.test.js +448 -0
  122. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +3 -3
  123. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +2 -2
  124. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +2 -25
  125. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +9 -18
  126. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +12 -46
  127. package/v2Containers/SmsTrai/Create/tests/__snapshots__/index.test.js.snap +0 -4
  128. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4 -8
  129. package/v2Containers/TagList/index.js +67 -1
  130. package/v2Containers/Templates/ChannelTypeIllustration.js +1 -13
  131. package/v2Containers/Templates/_templates.scss +56 -200
  132. package/v2Containers/Templates/actions.js +1 -2
  133. package/v2Containers/Templates/constants.js +0 -1
  134. package/v2Containers/Templates/index.js +124 -277
  135. package/v2Containers/Templates/messages.js +4 -24
  136. package/v2Containers/Templates/reducer.js +0 -2
  137. package/v2Containers/Templates/tests/index.test.js +0 -10
  138. package/v2Containers/TemplatesV2/index.js +2 -3
  139. package/v2Containers/TemplatesV2/messages.js +0 -4
  140. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +35 -132
  141. package/v2Components/CapImageUrlUpload/constants.js +0 -19
  142. package/v2Components/CapImageUrlUpload/index.js +0 -455
  143. package/v2Components/CapImageUrlUpload/index.scss +0 -35
  144. package/v2Components/CapImageUrlUpload/messages.js +0 -47
  145. package/v2Containers/WebPush/Create/components/ButtonForm.js +0 -175
  146. package/v2Containers/WebPush/Create/components/ButtonItem.js +0 -101
  147. package/v2Containers/WebPush/Create/components/ButtonList.js +0 -144
  148. package/v2Containers/WebPush/Create/components/_buttons.scss +0 -246
  149. package/v2Containers/WebPush/Create/components/tests/ButtonForm.test.js +0 -554
  150. package/v2Containers/WebPush/Create/components/tests/ButtonItem.test.js +0 -607
  151. package/v2Containers/WebPush/Create/components/tests/ButtonList.test.js +0 -633
  152. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonForm.test.js.snap +0 -666
  153. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonItem.test.js.snap +0 -74
  154. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonList.test.js.snap +0 -80
  155. package/v2Containers/WebPush/Create/index.js +0 -1755
  156. package/v2Containers/WebPush/Create/index.scss +0 -123
  157. package/v2Containers/WebPush/Create/messages.js +0 -199
  158. package/v2Containers/WebPush/Create/preview/DevicePreviewContent.js +0 -241
  159. package/v2Containers/WebPush/Create/preview/NotificationContainer.js +0 -290
  160. package/v2Containers/WebPush/Create/preview/PreviewContent.js +0 -81
  161. package/v2Containers/WebPush/Create/preview/PreviewControls.js +0 -240
  162. package/v2Containers/WebPush/Create/preview/PreviewDisclaimer.js +0 -23
  163. package/v2Containers/WebPush/Create/preview/WebPushPreview.js +0 -144
  164. package/v2Containers/WebPush/Create/preview/assets/Light.svg +0 -53
  165. package/v2Containers/WebPush/Create/preview/assets/Top.svg +0 -5
  166. package/v2Containers/WebPush/Create/preview/assets/chrome-icon.png +0 -0
  167. package/v2Containers/WebPush/Create/preview/assets/edge-icon.png +0 -0
  168. package/v2Containers/WebPush/Create/preview/assets/firefox-icon.svg +0 -106
  169. package/v2Containers/WebPush/Create/preview/assets/iOS.svg +0 -26
  170. package/v2Containers/WebPush/Create/preview/assets/opera-icon.svg +0 -18
  171. package/v2Containers/WebPush/Create/preview/assets/safari-icon.svg +0 -29
  172. package/v2Containers/WebPush/Create/preview/components/AndroidMobileChromeHeader.js +0 -44
  173. package/v2Containers/WebPush/Create/preview/components/AndroidMobileExpanded.js +0 -110
  174. package/v2Containers/WebPush/Create/preview/components/IOSHeader.js +0 -45
  175. package/v2Containers/WebPush/Create/preview/components/NotificationExpandedContent.js +0 -72
  176. package/v2Containers/WebPush/Create/preview/components/NotificationHeader.js +0 -55
  177. package/v2Containers/WebPush/Create/preview/components/WindowsChromeExpanded.js +0 -70
  178. package/v2Containers/WebPush/Create/preview/components/tests/AndroidMobileExpanded.test.js +0 -512
  179. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/AndroidMobileExpanded.test.js.snap +0 -77
  180. package/v2Containers/WebPush/Create/preview/config/notificationMappings.js +0 -527
  181. package/v2Containers/WebPush/Create/preview/constants.js +0 -162
  182. package/v2Containers/WebPush/Create/preview/notification-container.scss +0 -104
  183. package/v2Containers/WebPush/Create/preview/preview.scss +0 -409
  184. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-chrome.scss +0 -300
  185. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-edge.scss +0 -12
  186. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-firefox.scss +0 -12
  187. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-opera.scss +0 -12
  188. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-chrome.scss +0 -303
  189. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-edge.scss +0 -11
  190. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-firefox.scss +0 -11
  191. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-opera.scss +0 -11
  192. package/v2Containers/WebPush/Create/preview/styles/_base.scss +0 -188
  193. package/v2Containers/WebPush/Create/preview/styles/_ios.scss +0 -106
  194. package/v2Containers/WebPush/Create/preview/styles/_ipados.scss +0 -107
  195. package/v2Containers/WebPush/Create/preview/styles/_macos-chrome.scss +0 -75
  196. package/v2Containers/WebPush/Create/preview/styles/_windows-chrome.scss +0 -174
  197. package/v2Containers/WebPush/Create/preview/tests/DevicePreviewContent.test.js +0 -909
  198. package/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +0 -1077
  199. package/v2Containers/WebPush/Create/preview/tests/PreviewControls.test.js +0 -723
  200. package/v2Containers/WebPush/Create/preview/tests/WebPushPreview.test.js +0 -943
  201. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/DevicePreviewContent.test.js.snap +0 -128
  202. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/NotificationContainer.test.js.snap +0 -121
  203. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/PreviewControls.test.js.snap +0 -144
  204. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/WebPushPreview.test.js.snap +0 -127
  205. package/v2Containers/WebPush/Create/utils/urlValidation.js +0 -116
  206. package/v2Containers/WebPush/Create/utils/urlValidation.test.js +0 -449
  207. package/v2Containers/WebPush/actions.js +0 -60
  208. package/v2Containers/WebPush/constants.js +0 -108
  209. package/v2Containers/WebPush/index.js +0 -2
  210. package/v2Containers/WebPush/reducer.js +0 -104
  211. package/v2Containers/WebPush/sagas.js +0 -119
  212. package/v2Containers/WebPush/selectors.js +0 -65
  213. package/v2Containers/WebPush/tests/reducer.test.js +0 -863
  214. package/v2Containers/WebPush/tests/sagas.test.js +0 -566
  215. package/v2Containers/WebPush/tests/selectors.test.js +0 -960
@@ -1,16 +1,14 @@
1
- import React from 'react';
2
- import useEmailWrapper from '../hooks/useEmailWrapper';
3
- import { EmailWrapperMockData } from '../mockdata/mockdata';
4
1
  import _, { isEmpty, find } from 'lodash';
5
2
  import { renderHook, waitFor, act as reactAct } from '@testing-library/react';
3
+ import useEmailWrapper from '../hooks/useEmailWrapper';
4
+ import { EmailWrapperMockData } from '../mockdata/mockdata';
6
5
  import { EMAIL_CREATE_MODES, STEPS } from '../constants';
7
- import { GA } from '@capillarytech/cap-ui-utils';
8
6
  import { gtmPush } from '../../../utils/gtmTrackers';
9
7
 
10
8
  // Mock dependencies
11
9
  jest.mock('lodash', () => ({
12
10
  ...jest.requireActual('lodash'),
13
- isEmpty: jest.fn().mockImplementation(val => {
11
+ isEmpty: jest.fn().mockImplementation((val) => {
14
12
  if (val === null || val === undefined) return true;
15
13
  if (typeof val === 'object') return Object.keys(val).length === 0;
16
14
  if (typeof val === 'string') return val.trim().length === 0;
@@ -31,6 +29,10 @@ jest.mock('../../../utils/gtmTrackers', () => ({
31
29
  gtmPush: jest.fn(),
32
30
  }));
33
31
 
32
+ jest.mock('../../../utils/common', () => ({
33
+ hasSupportCKEditor: jest.fn(() => true), // Default to legacy flow
34
+ }));
35
+
34
36
  const mockStopTimer = jest.fn();
35
37
 
36
38
  jest.mock('@capillarytech/cap-ui-utils', () => ({
@@ -39,8 +41,8 @@ jest.mock('@capillarytech/cap-ui-utils', () => ({
39
41
  timeTracker: {
40
42
  startTimer: jest.fn(),
41
43
  stopTimer: jest.fn(),
42
- }
43
- }
44
+ },
45
+ },
44
46
  }));
45
47
 
46
48
  describe('useEmailWrapper', () => {
@@ -54,12 +56,12 @@ describe('useEmailWrapper', () => {
54
56
  gtmPush.mockClear();
55
57
  mockStopTimer.mockClear();
56
58
 
57
- isEmpty.mockImplementation(val => {
58
- if (val === null || val === undefined) return true;
59
- if (typeof val === 'object') return Object.keys(val).length === 0;
60
- if (typeof val === 'string') return val.trim().length === 0;
61
- return !val;
62
- });
59
+ isEmpty.mockImplementation((val) => {
60
+ if (val === null || val === undefined) return true;
61
+ if (typeof val === 'object') return Object.keys(val).length === 0;
62
+ if (typeof val === 'string') return val.trim().length === 0;
63
+ return !val;
64
+ });
63
65
 
64
66
  mockProps = {
65
67
  ...EmailWrapperMockData,
@@ -149,7 +151,8 @@ describe('useEmailWrapper', () => {
149
151
  result.current.onChange({ target: { value: EMAIL_CREATE_MODES.UPLOAD } });
150
152
  });
151
153
 
152
- expect(mockProps.onEmailModeChange).toHaveBeenCalledWith(EMAIL_CREATE_MODES.UPLOAD);
154
+ // onEmailModeChange is called with (mappedValue, value) - both are UPLOAD in this case
155
+ expect(mockProps.onEmailModeChange).toHaveBeenCalledWith(EMAIL_CREATE_MODES.UPLOAD, EMAIL_CREATE_MODES.UPLOAD);
153
156
  });
154
157
 
155
158
  it('handles zip file upload correctly and calls success callbacks', () => {
@@ -168,7 +171,7 @@ describe('useEmailWrapper', () => {
168
171
  const mockFile = {
169
172
  name: 'test.zip',
170
173
  size: 1024 * 1024,
171
- originFileObj: new Blob(['test data'], { type: 'application/zip' })
174
+ originFileObj: new Blob(['test data'], { type: 'application/zip' }),
172
175
  };
173
176
 
174
177
  reactAct(() => {
@@ -201,7 +204,7 @@ describe('useEmailWrapper', () => {
201
204
  const mockFile = {
202
205
  name: 'test.zip',
203
206
  size: 1024 * 1024,
204
- originFileObj: new Blob(['test data'], { type: 'application/zip' })
207
+ originFileObj: new Blob(['test data'], { type: 'application/zip' }),
205
208
  };
206
209
 
207
210
  reactAct(() => {
@@ -218,13 +221,13 @@ describe('useEmailWrapper', () => {
218
221
  const mockFile = {
219
222
  name: 'test.html',
220
223
  size: 1024,
221
- originFileObj: new Blob([mockHtmlContent], { type: 'text/html' })
224
+ originFileObj: new Blob([mockHtmlContent], { type: 'text/html' }),
222
225
  };
223
226
 
224
227
  const mockReader = {
225
228
  onload: null,
226
229
  onerror: null,
227
- readAsText: jest.fn(function() {
230
+ readAsText: jest.fn(function () {
228
231
  this.result = mockHtmlContent;
229
232
  if (this.onload) {
230
233
  this.onload();
@@ -257,13 +260,13 @@ describe('useEmailWrapper', () => {
257
260
  it('shows error for invalid file type during upload', () => {
258
261
  const { result } = renderHook(() => useEmailWrapper({
259
262
  ...mockProps,
260
- isUploading: false
263
+ isUploading: false,
261
264
  }));
262
265
 
263
266
  const mockFile = {
264
267
  name: 'test.txt',
265
268
  size: 1024,
266
- originFileObj: new Blob(['test data'], { type: 'text/plain' })
269
+ originFileObj: new Blob(['test data'], { type: 'text/plain' }),
267
270
  };
268
271
 
269
272
  reactAct(() => {
@@ -280,13 +283,13 @@ describe('useEmailWrapper', () => {
280
283
  it('shows error for oversized file during upload', () => {
281
284
  const { result } = renderHook(() => useEmailWrapper({
282
285
  ...mockProps,
283
- isUploading: false
286
+ isUploading: false,
284
287
  }));
285
288
 
286
289
  const mockFile = {
287
290
  name: 'large_file.zip',
288
291
  size: 6 * 1024 * 1024,
289
- originFileObj: new Blob(['large data'], { type: 'application/zip' })
292
+ originFileObj: new Blob(['large data'], { type: 'application/zip' }),
290
293
  };
291
294
 
292
295
  reactAct(() => {
@@ -294,7 +297,7 @@ describe('useEmailWrapper', () => {
294
297
  });
295
298
 
296
299
  expect(mockCapNotificationError).toHaveBeenCalledWith(expect.objectContaining({
297
- key: "email-upload-error",
300
+ key: "email-upload-error",
298
301
  }));
299
302
  expect(mockProps.templatesActions.handleZipUpload).not.toHaveBeenCalled();
300
303
  });
@@ -302,21 +305,21 @@ describe('useEmailWrapper', () => {
302
305
  it('shows error if no file or originFileObj is provided for upload', () => {
303
306
  const { result } = renderHook(() => useEmailWrapper({
304
307
  ...mockProps,
305
- isUploading: false
308
+ isUploading: false,
306
309
  }));
307
310
 
308
311
  reactAct(() => {
309
312
  result.current.useFileUpload({ file: null });
310
313
  });
311
314
  expect(mockCapNotificationError).toHaveBeenCalledTimes(1);
312
- expect(mockCapNotificationError).toHaveBeenCalledWith(expect.objectContaining({ key: "email-upload-error"}));
315
+ expect(mockCapNotificationError).toHaveBeenCalledWith(expect.objectContaining({ key: "email-upload-error" }));
313
316
 
314
317
  mockCapNotificationError.mockClear();
315
318
  reactAct(() => {
316
- result.current.useFileUpload({ file: { name: 'test.zip', size: 100 } });
319
+ result.current.useFileUpload({ file: { name: 'test.zip', size: 100 } });
317
320
  });
318
321
  expect(mockCapNotificationError).toHaveBeenCalledTimes(1);
319
- expect(mockCapNotificationError).toHaveBeenCalledWith(expect.objectContaining({ key: "email-upload-error"}));
322
+ expect(mockCapNotificationError).toHaveBeenCalledWith(expect.objectContaining({ key: "email-upload-error" }));
320
323
 
321
324
  expect(mockProps.templatesActions.handleZipUpload).not.toHaveBeenCalled();
322
325
  expect(mockProps.templatesActions.handleHtmlUpload).not.toHaveBeenCalled();
@@ -335,6 +338,10 @@ describe('useEmailWrapper', () => {
335
338
  });
336
339
 
337
340
  it('calls getDefaultBeeTemplates in useEffect when in EDITOR mode, TEMPLATE_SELECTION step, and no templates', () => {
341
+ // Ensure hasSupportCKEditor returns true for legacy flow
342
+ const { hasSupportCKEditor } = require('../../../utils/common');
343
+ hasSupportCKEditor.mockReturnValue(true);
344
+
338
345
  renderHook(() => useEmailWrapper({
339
346
  ...mockProps,
340
347
  step: STEPS.TEMPLATE_SELECTION,
@@ -367,6 +374,9 @@ describe('useEmailWrapper', () => {
367
374
  });
368
375
 
369
376
  it('calls setEdmTemplate/setBEETemplate in useEffect when in EDITOR mode and CREATE_TEMPLATE_CONTENT step', async () => {
377
+ // Ensure hasSupportCKEditor returns true for legacy flow
378
+ const { hasSupportCKEditor } = require('../../../utils/common');
379
+ hasSupportCKEditor.mockReturnValue(true);
370
380
  // 1. Setup
371
381
  const templateId = 'editorTemplate456';
372
382
  const mockTemplateData = { _id: templateId, name: 'Selected Editor Template' };
@@ -397,7 +407,7 @@ describe('useEmailWrapper', () => {
397
407
  // selectedCreateMode is initially '' from hook's useState
398
408
  };
399
409
  const { result, rerender } = renderHook((props) => useEmailWrapper(props), {
400
- initialProps: initialProps
410
+ initialProps,
401
411
  });
402
412
 
403
413
  // 4. Simulate user selecting a template ID via the exposed callback (useEditor)
@@ -409,17 +419,21 @@ describe('useEmailWrapper', () => {
409
419
  expect(result.current.modeContent).toEqual({ id: templateId }); // State updated
410
420
  expect(mockProps.showNextStep).toHaveBeenCalledTimes(1); // User action effect
411
421
 
422
+ // Clear mocks after user action to isolate effect calls
423
+ mockProps.templatesActions.setEdmTemplate.mockClear();
424
+ mockProps.templatesActions.setBEETemplate.mockClear();
425
+
412
426
  // 5. Rerender with step changed to CREATE_TEMPLATE_CONTENT
413
427
  const createContentProps = {
414
428
  ...initialProps, // Base props
415
429
  step: STEPS.CREATE_TEMPLATE_CONTENT, // *** Change step ***
416
- SelectedEdmDefaultTemplate: null // *** Ensure this is null ***
430
+ SelectedEdmDefaultTemplate: null, // *** Ensure this is null ***
417
431
  // The internal state `modeContent = { id: templateId }` persists
418
432
  // The internal state `selectedCreateMode = ''` also persists (not changed yet)
419
433
  };
420
434
 
421
435
  // Mock isEmpty just before rerender for the specific check inside the effect
422
- isEmpty.mockImplementation(val => {
436
+ isEmpty.mockImplementation((val) => {
423
437
  // console.log('DEBUG: isEmpty called with', JSON.stringify(val)); // Optional debug
424
438
  // Return true ONLY for the 'SelectedEdmDefaultTemplate' check (which is null)
425
439
  if (val === null) return true;
@@ -434,28 +448,48 @@ describe('useEmailWrapper', () => {
434
448
 
435
449
  // 6. Wait for effects triggered by the rerender
436
450
  await reactAct(async () => {
437
- // Short pause allows React's scheduler to run effects
438
- await new Promise(resolve => setTimeout(resolve, 0));
451
+ // Allow React to process the rerender and run effects
452
+ await new Promise((resolve) => setTimeout(resolve, 10));
439
453
  });
440
454
 
441
-
442
455
  // Assert that the template setting actions were called as a result of the effect
443
- expect(mockProps.templatesActions.setEdmTemplate).toHaveBeenCalledTimes(1);
444
- expect(mockProps.templatesActions.setEdmTemplate).toHaveBeenCalledWith(mockTemplateData);
445
- expect(mockProps.templatesActions.setBEETemplate).toHaveBeenCalledTimes(1);
446
- expect(mockProps.templatesActions.setBEETemplate).toHaveBeenCalledWith(mockTemplateData);
456
+ // Note: The effect may run multiple times in React 18+ StrictMode or due to dependency changes
457
+ // We verify that it was called at least once with the correct data after clearing mocks
458
+ const setEdmTemplateCalls = mockProps.templatesActions.setEdmTemplate.mock.calls;
459
+ const setBEETemplateCalls = mockProps.templatesActions.setBEETemplate.mock.calls;
460
+
461
+ // The effect should call handleEdmDefaultTemplateSelection, which calls both functions
462
+ // We expect at least 1 call each after clearing mocks (the effect call)
463
+ expect(setEdmTemplateCalls.length).toBeGreaterThanOrEqual(1);
464
+ expect(setBEETemplateCalls.length).toBeGreaterThanOrEqual(1);
465
+
466
+ // Verify the first call after clearing was with the correct data
467
+ expect(setEdmTemplateCalls[0]).toEqual([mockTemplateData]);
468
+ expect(setBEETemplateCalls[0]).toEqual([mockTemplateData]);
469
+
470
+ // If there are multiple calls (due to effect running twice), verify all are correct
471
+ if (setEdmTemplateCalls.length > 1) {
472
+ setEdmTemplateCalls.forEach((call) => {
473
+ expect(call).toEqual([mockTemplateData]);
474
+ });
475
+ }
476
+ if (setBEETemplateCalls.length > 1) {
477
+ setBEETemplateCalls.forEach((call) => {
478
+ expect(call).toEqual([mockTemplateData]);
479
+ });
480
+ }
447
481
  });
448
482
 
449
483
  it('sets selectedCreateMode in useEffect when in UPLOAD mode and CREATE_TEMPLATE_CONTENT step with EmailLayout', async () => {
450
484
  const initialRenderProps = {
451
- ...mockProps,
452
- step: STEPS.MODE_SELECTION,
453
- emailCreateMode: EMAIL_CREATE_MODES.UPLOAD,
454
- EmailLayout: null,
455
- };
485
+ ...mockProps,
486
+ step: STEPS.MODE_SELECTION,
487
+ emailCreateMode: EMAIL_CREATE_MODES.UPLOAD,
488
+ EmailLayout: null,
489
+ };
456
490
 
457
491
  const { result, rerender } = renderHook((props) => useEmailWrapper(props), {
458
- initialProps: initialRenderProps
492
+ initialProps: initialRenderProps,
459
493
  });
460
494
 
461
495
  const rerenderProps = {
@@ -467,11 +501,11 @@ describe('useEmailWrapper', () => {
467
501
 
468
502
  // Reset isEmpty to default before setting the specific mock for the effect
469
503
  isEmpty.mockImplementation((val) => {
470
- if (val === null || val === undefined) return true;
471
- if (typeof val === 'object') return Object.keys(val).length === 0;
472
- if (typeof val === 'string') return val.trim().length === 0;
473
- return !val;
474
- });
504
+ if (val === null || val === undefined) return true;
505
+ if (typeof val === 'object') return Object.keys(val).length === 0;
506
+ if (typeof val === 'string') return val.trim().length === 0;
507
+ return !val;
508
+ });
475
509
  // Mock isEmpty specifically for the EmailLayout check inside the useEffect
476
510
  isEmpty.mockImplementationOnce(() => false); // Mock !isEmpty(EmailLayout) to be true
477
511
 
@@ -479,16 +513,16 @@ describe('useEmailWrapper', () => {
479
513
 
480
514
  // Wait for the effect to run, set selectedCreateMode, and isShowEmailCreate to update
481
515
  await waitFor(() => {
482
- expect(result.current.isShowEmailCreate).toBe(true);
516
+ expect(result.current.isShowEmailCreate).toBe(true);
483
517
  });
484
518
 
485
519
  // Restore default isEmpty behavior after the specific mock is used
486
520
  isEmpty.mockImplementation((val) => {
487
- if (val === null || val === undefined) return true;
488
- if (typeof val === 'object') return Object.keys(val).length === 0;
489
- if (typeof val === 'string') return val.trim().length === 0;
490
- return !val;
491
- });
521
+ if (val === null || val === undefined) return true;
522
+ if (typeof val === 'object') return Object.keys(val).length === 0;
523
+ if (typeof val === 'string') return val.trim().length === 0;
524
+ return !val;
525
+ });
492
526
  isEmpty.mockClear(); // Clear any remaining mock state if needed
493
527
 
494
528
  expect(mockProps.templatesActions.setEdmTemplate).not.toHaveBeenCalled();
@@ -533,11 +567,11 @@ describe('useEmailWrapper', () => {
533
567
 
534
568
  // Reset isEmpty to default before setting the specific mock for the effect
535
569
  isEmpty.mockImplementation((val) => {
536
- if (val === null || val === undefined) return true;
537
- if (typeof val === 'object') return Object.keys(val).length === 0;
538
- if (typeof val === 'string') return val.trim().length === 0;
539
- return !val;
540
- });
570
+ if (val === null || val === undefined) return true;
571
+ if (typeof val === 'object') return Object.keys(val).length === 0;
572
+ if (typeof val === 'string') return val.trim().length === 0;
573
+ return !val;
574
+ });
541
575
  // Mock isEmpty specifically for the EmailLayout check inside the useEffect
542
576
  isEmpty.mockImplementationOnce(() => false); // Mock !isEmpty(EmailLayout) to be true
543
577
 
@@ -545,16 +579,16 @@ describe('useEmailWrapper', () => {
545
579
 
546
580
  // Wait for the effect to run, set selectedCreateMode, and isShowEmailCreate to update
547
581
  await waitFor(() => {
548
- expect(result.current.isShowEmailCreate).toBe(true);
582
+ expect(result.current.isShowEmailCreate).toBe(true);
549
583
  });
550
584
 
551
585
  // Restore default isEmpty behavior after the specific mock is used
552
586
  isEmpty.mockImplementation((val) => {
553
- if (val === null || val === undefined) return true;
554
- if (typeof val === 'object') return Object.keys(val).length === 0;
555
- if (typeof val === 'string') return val.trim().length === 0;
556
- return !val;
557
- });
587
+ if (val === null || val === undefined) return true;
588
+ if (typeof val === 'object') return Object.keys(val).length === 0;
589
+ if (typeof val === 'string') return val.trim().length === 0;
590
+ return !val;
591
+ });
558
592
  isEmpty.mockClear(); // Clear any remaining mock state if needed
559
593
 
560
594
  // --- Case 3: EDITOR mode selected, Template becomes available -> true (via effect) ---
@@ -563,11 +597,11 @@ describe('useEmailWrapper', () => {
563
597
  find.mockReturnValue(mockTemplate); // Ensure find is mocked for this case
564
598
 
565
599
  const editorPropsInitial = {
566
- ...mockProps,
567
- step: STEPS.TEMPLATE_SELECTION,
568
- emailCreateMode: EMAIL_CREATE_MODES.EDITOR,
569
- CmsTemplates: [mockTemplate],
570
- SelectedEdmDefaultTemplate: null,
600
+ ...mockProps,
601
+ step: STEPS.TEMPLATE_SELECTION,
602
+ emailCreateMode: EMAIL_CREATE_MODES.EDITOR,
603
+ CmsTemplates: [mockTemplate],
604
+ SelectedEdmDefaultTemplate: null,
571
605
  };
572
606
  rerender(editorPropsInitial);
573
607
 
@@ -579,12 +613,12 @@ describe('useEmailWrapper', () => {
579
613
  expect(result.current.modeContent).toEqual({ id: templateId });
580
614
 
581
615
  const editorPropsFinal = {
582
- ...mockProps, // Use fresh props base
583
- step: STEPS.CREATE_TEMPLATE_CONTENT, // Move to the create step
584
- emailCreateMode: EMAIL_CREATE_MODES.EDITOR,
585
- CmsTemplates: [mockTemplate],
586
- SelectedEdmDefaultTemplate: null, // Template not yet selected in props
587
- // modeContent state ({id: templateId}) should persist internally from the reactAct call
616
+ ...mockProps, // Use fresh props base
617
+ step: STEPS.CREATE_TEMPLATE_CONTENT, // Move to the create step
618
+ emailCreateMode: EMAIL_CREATE_MODES.EDITOR,
619
+ CmsTemplates: [mockTemplate],
620
+ SelectedEdmDefaultTemplate: null, // Template not yet selected in props
621
+ // modeContent state ({id: templateId}) should persist internally from the reactAct call
588
622
  };
589
623
 
590
624
  // Mock isEmpty specifically for the check within the useEffect triggered by rerender
@@ -598,4 +632,4 @@ describe('useEmailWrapper', () => {
598
632
  find.mockClear();
599
633
  isEmpty.mockClear();
600
634
  });
601
- });
635
+ });