@capillarytech/creatives-library 8.0.263 → 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 (280) hide show
  1. package/assets/Android.png +0 -0
  2. package/assets/iOS.png +0 -0
  3. package/constants/unified.js +1 -3
  4. package/initialReducer.js +0 -2
  5. package/package.json +1 -1
  6. package/services/api.js +0 -15
  7. package/services/tests/api.test.js +0 -34
  8. package/tests/integration/TemplateCreation/TemplateCreation.integration.test.js +35 -17
  9. package/tests/integration/TemplateCreation/api-response.js +1 -31
  10. package/tests/integration/TemplateCreation/msw-handler.js +0 -2
  11. package/utils/common.js +0 -11
  12. package/utils/commonUtils.js +5 -28
  13. package/utils/tests/commonUtil.test.js +0 -224
  14. package/utils/tests/transformerUtils.test.js +0 -297
  15. package/utils/transformTemplateConfig.js +10 -0
  16. package/utils/transformerUtils.js +0 -40
  17. package/v2Components/CapDeviceContent/index.js +56 -61
  18. package/v2Components/CapImageUpload/constants.js +0 -2
  19. package/v2Components/CapImageUpload/index.js +16 -65
  20. package/v2Components/CapImageUpload/index.scss +1 -4
  21. package/v2Components/CapImageUpload/messages.js +1 -5
  22. package/v2Components/CapTagList/index.js +1 -6
  23. package/v2Components/CapTagListWithInput/index.js +1 -5
  24. package/v2Components/CapTagListWithInput/messages.js +1 -1
  25. package/v2Components/CapWhatsappCTA/tests/index.test.js +0 -5
  26. package/v2Components/ErrorInfoNote/index.js +72 -402
  27. package/v2Components/ErrorInfoNote/messages.js +6 -32
  28. package/v2Components/ErrorInfoNote/style.scss +6 -278
  29. package/v2Components/FormBuilder/tests/index.test.js +4 -13
  30. package/v2Components/HtmlEditor/HTMLEditor.js +99 -418
  31. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +133 -1882
  32. package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +16 -27
  33. package/v2Components/HtmlEditor/_htmlEditor.scss +45 -108
  34. package/v2Components/HtmlEditor/_index.lazy.scss +1 -0
  35. package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +102 -23
  36. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +140 -148
  37. package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +1 -2
  38. package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
  39. package/v2Components/HtmlEditor/components/EditorToolbar/_editorToolbar.scss +1 -9
  40. package/v2Components/HtmlEditor/components/EditorToolbar/index.js +6 -31
  41. package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +0 -22
  42. package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +7 -4
  43. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +45 -35
  44. package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +3 -1
  45. package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
  46. package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +6 -7
  47. package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +10 -7
  48. package/v2Components/HtmlEditor/components/PreviewPane/index.js +43 -22
  49. package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
  50. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +152 -0
  51. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/_validationErrorDisplay.scss +0 -18
  52. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +31 -36
  53. package/v2Components/HtmlEditor/components/ValidationPanel/_validationPanel.scss +34 -46
  54. package/v2Components/HtmlEditor/components/ValidationPanel/index.js +46 -52
  55. package/v2Components/HtmlEditor/constants.js +20 -45
  56. package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +16 -373
  57. package/v2Components/HtmlEditor/hooks/__tests__/useValidation.test.js +16 -351
  58. package/v2Components/HtmlEditor/hooks/useEditorContent.js +2 -5
  59. package/v2Components/HtmlEditor/hooks/useInAppContent.js +146 -88
  60. package/v2Components/HtmlEditor/hooks/useValidation.js +56 -213
  61. package/v2Components/HtmlEditor/index.js +1 -1
  62. package/v2Components/HtmlEditor/messages.js +94 -102
  63. package/v2Components/HtmlEditor/utils/__tests__/htmlValidator.enhanced.test.js +45 -214
  64. package/v2Components/HtmlEditor/utils/__tests__/validationAdapter.test.js +0 -134
  65. package/v2Components/HtmlEditor/utils/contentSanitizer.js +41 -40
  66. package/v2Components/HtmlEditor/utils/htmlValidator.js +72 -71
  67. package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +124 -158
  68. package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +25 -23
  69. package/v2Components/HtmlEditor/utils/validationAdapter.js +41 -66
  70. package/v2Components/MobilePushPreviewV2/index.js +7 -33
  71. package/v2Components/TemplatePreview/_templatePreview.scss +24 -55
  72. package/v2Components/TemplatePreview/index.js +32 -47
  73. package/v2Components/TemplatePreview/messages.js +0 -4
  74. package/v2Components/TestAndPreviewSlidebox/_testAndPreviewSlidebox.scss +0 -1
  75. package/v2Containers/App/constants.js +0 -5
  76. package/v2Containers/BeeEditor/index.js +90 -172
  77. package/v2Containers/CreativesContainer/SlideBoxContent.js +53 -184
  78. package/v2Containers/CreativesContainer/SlideBoxFooter.js +13 -163
  79. package/v2Containers/CreativesContainer/SlideBoxHeader.js +1 -3
  80. package/v2Containers/CreativesContainer/constants.js +0 -4
  81. package/v2Containers/CreativesContainer/index.js +46 -408
  82. package/v2Containers/CreativesContainer/messages.js +0 -12
  83. package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +0 -210
  84. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +2 -11
  85. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +50 -342
  86. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +0 -103
  87. package/v2Containers/Email/actions.js +0 -7
  88. package/v2Containers/Email/constants.js +1 -5
  89. package/v2Containers/Email/index.js +36 -237
  90. package/v2Containers/Email/messages.js +0 -32
  91. package/v2Containers/Email/reducer.js +1 -12
  92. package/v2Containers/Email/sagas.js +7 -61
  93. package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +0 -2
  94. package/v2Containers/Email/tests/reducer.test.js +0 -46
  95. package/v2Containers/Email/tests/sagas.test.js +29 -320
  96. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +21 -211
  97. package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +74 -40
  98. package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +67 -2
  99. package/v2Containers/EmailWrapper/constants.js +0 -2
  100. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +77 -629
  101. package/v2Containers/EmailWrapper/index.js +23 -103
  102. package/v2Containers/EmailWrapper/messages.js +1 -65
  103. package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +214 -0
  104. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +77 -594
  105. package/v2Containers/InApp/actions.js +0 -7
  106. package/v2Containers/InApp/constants.js +4 -20
  107. package/v2Containers/InApp/index.js +359 -802
  108. package/v2Containers/InApp/index.scss +3 -4
  109. package/v2Containers/InApp/messages.js +3 -7
  110. package/v2Containers/InApp/reducer.js +3 -21
  111. package/v2Containers/InApp/sagas.js +9 -29
  112. package/v2Containers/InApp/selectors.js +5 -25
  113. package/v2Containers/InApp/tests/index.test.js +50 -154
  114. package/v2Containers/InApp/tests/reducer.test.js +0 -34
  115. package/v2Containers/InApp/tests/sagas.test.js +9 -61
  116. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +0 -3
  117. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +0 -2
  118. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +0 -2
  119. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +0 -9
  120. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +0 -12
  121. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +0 -4
  122. package/v2Containers/TagList/index.js +19 -62
  123. package/v2Containers/Templates/ChannelTypeIllustration.js +1 -13
  124. package/v2Containers/Templates/_templates.scss +1 -265
  125. package/v2Containers/Templates/actions.js +1 -2
  126. package/v2Containers/Templates/constants.js +0 -1
  127. package/v2Containers/Templates/index.js +38 -363
  128. package/v2Containers/Templates/messages.js +0 -28
  129. package/v2Containers/Templates/reducer.js +0 -2
  130. package/v2Containers/Templates/tests/index.test.js +0 -10
  131. package/v2Containers/TemplatesV2/TemplatesV2.style.js +2 -4
  132. package/v2Containers/TemplatesV2/index.js +7 -15
  133. package/v2Containers/TemplatesV2/messages.js +0 -4
  134. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +0 -34
  135. package/utils/imageUrlUpload.js +0 -141
  136. package/v2Components/CapImageUrlUpload/constants.js +0 -26
  137. package/v2Components/CapImageUrlUpload/index.js +0 -365
  138. package/v2Components/CapImageUrlUpload/index.scss +0 -35
  139. package/v2Components/CapImageUrlUpload/messages.js +0 -47
  140. package/v2Components/ErrorInfoNote/constants.js +0 -1
  141. package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +0 -870
  142. package/v2Components/HtmlEditor/components/ValidationPanel/constants.js +0 -6
  143. package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +0 -281
  144. package/v2Components/HtmlEditor/components/ValidationTabs/index.js +0 -295
  145. package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +0 -51
  146. package/v2Components/HtmlEditor/utils/validationConstants.js +0 -38
  147. package/v2Components/MobilePushPreviewV2/constants.js +0 -6
  148. package/v2Containers/BeePopupEditor/_beePopupEditor.scss +0 -14
  149. package/v2Containers/BeePopupEditor/constants.js +0 -10
  150. package/v2Containers/BeePopupEditor/index.js +0 -194
  151. package/v2Containers/BeePopupEditor/tests/index.test.js +0 -627
  152. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +0 -1246
  153. package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +0 -2472
  154. package/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +0 -520
  155. package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +0 -956
  156. package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +0 -376
  157. package/v2Containers/InApp/__tests__/sagas.test.js +0 -363
  158. package/v2Containers/InApp/tests/selectors.test.js +0 -612
  159. package/v2Containers/InAppWrapper/components/InAppWrapperView.js +0 -151
  160. package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +0 -267
  161. package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +0 -23
  162. package/v2Containers/InAppWrapper/constants.js +0 -16
  163. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +0 -473
  164. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +0 -198
  165. package/v2Containers/InAppWrapper/index.js +0 -148
  166. package/v2Containers/InAppWrapper/messages.js +0 -49
  167. package/v2Containers/InappAdvance/index.js +0 -1099
  168. package/v2Containers/InappAdvance/index.scss +0 -10
  169. package/v2Containers/InappAdvance/tests/index.test.js +0 -448
  170. package/v2Containers/WebPush/Create/components/BrandIconSection.js +0 -108
  171. package/v2Containers/WebPush/Create/components/ButtonForm.js +0 -172
  172. package/v2Containers/WebPush/Create/components/ButtonItem.js +0 -101
  173. package/v2Containers/WebPush/Create/components/ButtonList.js +0 -145
  174. package/v2Containers/WebPush/Create/components/ButtonsLinksSection.js +0 -164
  175. package/v2Containers/WebPush/Create/components/ButtonsLinksSection.test.js +0 -463
  176. package/v2Containers/WebPush/Create/components/FormActions.js +0 -54
  177. package/v2Containers/WebPush/Create/components/FormActions.test.js +0 -163
  178. package/v2Containers/WebPush/Create/components/MediaSection.js +0 -142
  179. package/v2Containers/WebPush/Create/components/MediaSection.test.js +0 -341
  180. package/v2Containers/WebPush/Create/components/MessageSection.js +0 -103
  181. package/v2Containers/WebPush/Create/components/MessageSection.test.js +0 -268
  182. package/v2Containers/WebPush/Create/components/NotificationTitleSection.js +0 -87
  183. package/v2Containers/WebPush/Create/components/NotificationTitleSection.test.js +0 -210
  184. package/v2Containers/WebPush/Create/components/TemplateNameSection.js +0 -54
  185. package/v2Containers/WebPush/Create/components/TemplateNameSection.test.js +0 -143
  186. package/v2Containers/WebPush/Create/components/__snapshots__/ButtonsLinksSection.test.js.snap +0 -86
  187. package/v2Containers/WebPush/Create/components/__snapshots__/FormActions.test.js.snap +0 -16
  188. package/v2Containers/WebPush/Create/components/__snapshots__/MediaSection.test.js.snap +0 -41
  189. package/v2Containers/WebPush/Create/components/__snapshots__/MessageSection.test.js.snap +0 -54
  190. package/v2Containers/WebPush/Create/components/__snapshots__/NotificationTitleSection.test.js.snap +0 -37
  191. package/v2Containers/WebPush/Create/components/__snapshots__/TemplateNameSection.test.js.snap +0 -21
  192. package/v2Containers/WebPush/Create/components/_buttons.scss +0 -246
  193. package/v2Containers/WebPush/Create/components/tests/ButtonForm.test.js +0 -554
  194. package/v2Containers/WebPush/Create/components/tests/ButtonItem.test.js +0 -607
  195. package/v2Containers/WebPush/Create/components/tests/ButtonList.test.js +0 -633
  196. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonForm.test.js.snap +0 -666
  197. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonItem.test.js.snap +0 -74
  198. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonList.test.js.snap +0 -78
  199. package/v2Containers/WebPush/Create/hooks/useButtonManagement.js +0 -138
  200. package/v2Containers/WebPush/Create/hooks/useButtonManagement.test.js +0 -406
  201. package/v2Containers/WebPush/Create/hooks/useCharacterCount.js +0 -30
  202. package/v2Containers/WebPush/Create/hooks/useCharacterCount.test.js +0 -151
  203. package/v2Containers/WebPush/Create/hooks/useImageUpload.js +0 -104
  204. package/v2Containers/WebPush/Create/hooks/useImageUpload.test.js +0 -538
  205. package/v2Containers/WebPush/Create/hooks/useTagManagement.js +0 -122
  206. package/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +0 -633
  207. package/v2Containers/WebPush/Create/index.js +0 -1148
  208. package/v2Containers/WebPush/Create/index.scss +0 -134
  209. package/v2Containers/WebPush/Create/messages.js +0 -211
  210. package/v2Containers/WebPush/Create/preview/DevicePreviewContent.js +0 -228
  211. package/v2Containers/WebPush/Create/preview/NotificationContainer.js +0 -294
  212. package/v2Containers/WebPush/Create/preview/PreviewContent.js +0 -90
  213. package/v2Containers/WebPush/Create/preview/PreviewControls.js +0 -305
  214. package/v2Containers/WebPush/Create/preview/PreviewDisclaimer.js +0 -25
  215. package/v2Containers/WebPush/Create/preview/WebPushPreview.js +0 -155
  216. package/v2Containers/WebPush/Create/preview/assets/Light.svg +0 -53
  217. package/v2Containers/WebPush/Create/preview/assets/Top.svg +0 -5
  218. package/v2Containers/WebPush/Create/preview/assets/android-arrow-down.svg +0 -9
  219. package/v2Containers/WebPush/Create/preview/assets/android-arrow-up.svg +0 -9
  220. package/v2Containers/WebPush/Create/preview/assets/chrome-icon.png +0 -0
  221. package/v2Containers/WebPush/Create/preview/assets/edge-icon.png +0 -0
  222. package/v2Containers/WebPush/Create/preview/assets/firefox-icon.svg +0 -106
  223. package/v2Containers/WebPush/Create/preview/assets/iOS.svg +0 -26
  224. package/v2Containers/WebPush/Create/preview/assets/macos-arrow-down-icon.svg +0 -9
  225. package/v2Containers/WebPush/Create/preview/assets/macos-triple-dot-icon.svg +0 -9
  226. package/v2Containers/WebPush/Create/preview/assets/opera-icon.svg +0 -18
  227. package/v2Containers/WebPush/Create/preview/assets/safari-icon.svg +0 -29
  228. package/v2Containers/WebPush/Create/preview/assets/windows-close-icon.svg +0 -9
  229. package/v2Containers/WebPush/Create/preview/assets/windows-triple-dot-icon.svg +0 -9
  230. package/v2Containers/WebPush/Create/preview/components/AndroidMobileChromeHeader.js +0 -51
  231. package/v2Containers/WebPush/Create/preview/components/AndroidMobileExpanded.js +0 -145
  232. package/v2Containers/WebPush/Create/preview/components/IOSHeader.js +0 -45
  233. package/v2Containers/WebPush/Create/preview/components/NotificationExpandedContent.js +0 -68
  234. package/v2Containers/WebPush/Create/preview/components/NotificationHeader.js +0 -61
  235. package/v2Containers/WebPush/Create/preview/components/WindowsChromeExpanded.js +0 -99
  236. package/v2Containers/WebPush/Create/preview/components/tests/AndroidMobileExpanded.test.js +0 -733
  237. package/v2Containers/WebPush/Create/preview/components/tests/WindowsChromeExpanded.test.js +0 -571
  238. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/AndroidMobileExpanded.test.js.snap +0 -85
  239. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/WindowsChromeExpanded.test.js.snap +0 -81
  240. package/v2Containers/WebPush/Create/preview/config/notificationMappings.js +0 -50
  241. package/v2Containers/WebPush/Create/preview/constants.js +0 -637
  242. package/v2Containers/WebPush/Create/preview/notification-container.scss +0 -79
  243. package/v2Containers/WebPush/Create/preview/preview.scss +0 -358
  244. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-chrome.scss +0 -370
  245. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-edge.scss +0 -12
  246. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-firefox.scss +0 -12
  247. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-opera.scss +0 -12
  248. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-chrome.scss +0 -47
  249. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-edge.scss +0 -11
  250. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-firefox.scss +0 -11
  251. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-opera.scss +0 -11
  252. package/v2Containers/WebPush/Create/preview/styles/_base.scss +0 -207
  253. package/v2Containers/WebPush/Create/preview/styles/_ios.scss +0 -153
  254. package/v2Containers/WebPush/Create/preview/styles/_ipados.scss +0 -107
  255. package/v2Containers/WebPush/Create/preview/styles/_macos-chrome.scss +0 -101
  256. package/v2Containers/WebPush/Create/preview/styles/_windows-chrome.scss +0 -229
  257. package/v2Containers/WebPush/Create/preview/tests/DevicePreviewContent.test.js +0 -909
  258. package/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +0 -1081
  259. package/v2Containers/WebPush/Create/preview/tests/PreviewControls.test.js +0 -723
  260. package/v2Containers/WebPush/Create/preview/tests/WebPushPreview.test.js +0 -1327
  261. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/DevicePreviewContent.test.js.snap +0 -131
  262. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/NotificationContainer.test.js.snap +0 -112
  263. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/PreviewControls.test.js.snap +0 -144
  264. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/WebPushPreview.test.js.snap +0 -129
  265. package/v2Containers/WebPush/Create/utils/payloadBuilder.js +0 -96
  266. package/v2Containers/WebPush/Create/utils/payloadBuilder.test.js +0 -396
  267. package/v2Containers/WebPush/Create/utils/previewUtils.js +0 -89
  268. package/v2Containers/WebPush/Create/utils/urlValidation.js +0 -115
  269. package/v2Containers/WebPush/Create/utils/urlValidation.test.js +0 -449
  270. package/v2Containers/WebPush/Create/utils/validation.js +0 -75
  271. package/v2Containers/WebPush/Create/utils/validation.test.js +0 -283
  272. package/v2Containers/WebPush/actions.js +0 -60
  273. package/v2Containers/WebPush/constants.js +0 -132
  274. package/v2Containers/WebPush/index.js +0 -2
  275. package/v2Containers/WebPush/reducer.js +0 -104
  276. package/v2Containers/WebPush/sagas.js +0 -119
  277. package/v2Containers/WebPush/selectors.js +0 -65
  278. package/v2Containers/WebPush/tests/reducer.test.js +0 -863
  279. package/v2Containers/WebPush/tests/sagas.test.js +0 -566
  280. package/v2Containers/WebPush/tests/selectors.test.js +0 -960
@@ -1,14 +1,16 @@
1
- import _, { isEmpty, find } from 'lodash';
2
- import { renderHook, waitFor, act as reactAct } from '@testing-library/react';
1
+ import React from 'react';
3
2
  import useEmailWrapper from '../hooks/useEmailWrapper';
4
3
  import { EmailWrapperMockData } from '../mockdata/mockdata';
4
+ import _, { isEmpty, find } from 'lodash';
5
+ import { renderHook, waitFor, act as reactAct } from '@testing-library/react';
5
6
  import { EMAIL_CREATE_MODES, STEPS } from '../constants';
7
+ import { GA } from '@capillarytech/cap-ui-utils';
6
8
  import { gtmPush } from '../../../utils/gtmTrackers';
7
9
 
8
10
  // Mock dependencies
9
11
  jest.mock('lodash', () => ({
10
12
  ...jest.requireActual('lodash'),
11
- isEmpty: jest.fn().mockImplementation((val) => {
13
+ isEmpty: jest.fn().mockImplementation(val => {
12
14
  if (val === null || val === undefined) return true;
13
15
  if (typeof val === 'object') return Object.keys(val).length === 0;
14
16
  if (typeof val === 'string') return val.trim().length === 0;
@@ -29,10 +31,6 @@ jest.mock('../../../utils/gtmTrackers', () => ({
29
31
  gtmPush: jest.fn(),
30
32
  }));
31
33
 
32
- jest.mock('../../../utils/common', () => ({
33
- hasSupportCKEditor: jest.fn(() => true), // Default to legacy flow
34
- }));
35
-
36
34
  const mockStopTimer = jest.fn();
37
35
 
38
36
  jest.mock('@capillarytech/cap-ui-utils', () => ({
@@ -41,8 +39,8 @@ jest.mock('@capillarytech/cap-ui-utils', () => ({
41
39
  timeTracker: {
42
40
  startTimer: jest.fn(),
43
41
  stopTimer: jest.fn(),
44
- },
45
- },
42
+ }
43
+ }
46
44
  }));
47
45
 
48
46
  describe('useEmailWrapper', () => {
@@ -56,12 +54,12 @@ describe('useEmailWrapper', () => {
56
54
  gtmPush.mockClear();
57
55
  mockStopTimer.mockClear();
58
56
 
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
- });
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
+ });
65
63
 
66
64
  mockProps = {
67
65
  ...EmailWrapperMockData,
@@ -151,8 +149,7 @@ describe('useEmailWrapper', () => {
151
149
  result.current.onChange({ target: { value: EMAIL_CREATE_MODES.UPLOAD } });
152
150
  });
153
151
 
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);
152
+ expect(mockProps.onEmailModeChange).toHaveBeenCalledWith(EMAIL_CREATE_MODES.UPLOAD);
156
153
  });
157
154
 
158
155
  it('handles zip file upload correctly and calls success callbacks', () => {
@@ -171,7 +168,7 @@ describe('useEmailWrapper', () => {
171
168
  const mockFile = {
172
169
  name: 'test.zip',
173
170
  size: 1024 * 1024,
174
- originFileObj: new Blob(['test data'], { type: 'application/zip' }),
171
+ originFileObj: new Blob(['test data'], { type: 'application/zip' })
175
172
  };
176
173
 
177
174
  reactAct(() => {
@@ -204,7 +201,7 @@ describe('useEmailWrapper', () => {
204
201
  const mockFile = {
205
202
  name: 'test.zip',
206
203
  size: 1024 * 1024,
207
- originFileObj: new Blob(['test data'], { type: 'application/zip' }),
204
+ originFileObj: new Blob(['test data'], { type: 'application/zip' })
208
205
  };
209
206
 
210
207
  reactAct(() => {
@@ -221,13 +218,13 @@ describe('useEmailWrapper', () => {
221
218
  const mockFile = {
222
219
  name: 'test.html',
223
220
  size: 1024,
224
- originFileObj: new Blob([mockHtmlContent], { type: 'text/html' }),
221
+ originFileObj: new Blob([mockHtmlContent], { type: 'text/html' })
225
222
  };
226
223
 
227
224
  const mockReader = {
228
225
  onload: null,
229
226
  onerror: null,
230
- readAsText: jest.fn(function () {
227
+ readAsText: jest.fn(function() {
231
228
  this.result = mockHtmlContent;
232
229
  if (this.onload) {
233
230
  this.onload();
@@ -260,13 +257,13 @@ describe('useEmailWrapper', () => {
260
257
  it('shows error for invalid file type during upload', () => {
261
258
  const { result } = renderHook(() => useEmailWrapper({
262
259
  ...mockProps,
263
- isUploading: false,
260
+ isUploading: false
264
261
  }));
265
262
 
266
263
  const mockFile = {
267
264
  name: 'test.txt',
268
265
  size: 1024,
269
- originFileObj: new Blob(['test data'], { type: 'text/plain' }),
266
+ originFileObj: new Blob(['test data'], { type: 'text/plain' })
270
267
  };
271
268
 
272
269
  reactAct(() => {
@@ -283,13 +280,13 @@ describe('useEmailWrapper', () => {
283
280
  it('shows error for oversized file during upload', () => {
284
281
  const { result } = renderHook(() => useEmailWrapper({
285
282
  ...mockProps,
286
- isUploading: false,
283
+ isUploading: false
287
284
  }));
288
285
 
289
286
  const mockFile = {
290
287
  name: 'large_file.zip',
291
288
  size: 6 * 1024 * 1024,
292
- originFileObj: new Blob(['large data'], { type: 'application/zip' }),
289
+ originFileObj: new Blob(['large data'], { type: 'application/zip' })
293
290
  };
294
291
 
295
292
  reactAct(() => {
@@ -297,7 +294,7 @@ describe('useEmailWrapper', () => {
297
294
  });
298
295
 
299
296
  expect(mockCapNotificationError).toHaveBeenCalledWith(expect.objectContaining({
300
- key: "email-upload-error",
297
+ key: "email-upload-error",
301
298
  }));
302
299
  expect(mockProps.templatesActions.handleZipUpload).not.toHaveBeenCalled();
303
300
  });
@@ -305,21 +302,21 @@ describe('useEmailWrapper', () => {
305
302
  it('shows error if no file or originFileObj is provided for upload', () => {
306
303
  const { result } = renderHook(() => useEmailWrapper({
307
304
  ...mockProps,
308
- isUploading: false,
305
+ isUploading: false
309
306
  }));
310
307
 
311
308
  reactAct(() => {
312
309
  result.current.useFileUpload({ file: null });
313
310
  });
314
311
  expect(mockCapNotificationError).toHaveBeenCalledTimes(1);
315
- expect(mockCapNotificationError).toHaveBeenCalledWith(expect.objectContaining({ key: "email-upload-error" }));
312
+ expect(mockCapNotificationError).toHaveBeenCalledWith(expect.objectContaining({ key: "email-upload-error"}));
316
313
 
317
314
  mockCapNotificationError.mockClear();
318
315
  reactAct(() => {
319
- result.current.useFileUpload({ file: { name: 'test.zip', size: 100 } });
316
+ result.current.useFileUpload({ file: { name: 'test.zip', size: 100 } });
320
317
  });
321
318
  expect(mockCapNotificationError).toHaveBeenCalledTimes(1);
322
- expect(mockCapNotificationError).toHaveBeenCalledWith(expect.objectContaining({ key: "email-upload-error" }));
319
+ expect(mockCapNotificationError).toHaveBeenCalledWith(expect.objectContaining({ key: "email-upload-error"}));
323
320
 
324
321
  expect(mockProps.templatesActions.handleZipUpload).not.toHaveBeenCalled();
325
322
  expect(mockProps.templatesActions.handleHtmlUpload).not.toHaveBeenCalled();
@@ -338,10 +335,6 @@ describe('useEmailWrapper', () => {
338
335
  });
339
336
 
340
337
  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
-
345
338
  renderHook(() => useEmailWrapper({
346
339
  ...mockProps,
347
340
  step: STEPS.TEMPLATE_SELECTION,
@@ -374,9 +367,6 @@ describe('useEmailWrapper', () => {
374
367
  });
375
368
 
376
369
  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);
380
370
  // 1. Setup
381
371
  const templateId = 'editorTemplate456';
382
372
  const mockTemplateData = { _id: templateId, name: 'Selected Editor Template' };
@@ -407,7 +397,7 @@ describe('useEmailWrapper', () => {
407
397
  // selectedCreateMode is initially '' from hook's useState
408
398
  };
409
399
  const { result, rerender } = renderHook((props) => useEmailWrapper(props), {
410
- initialProps,
400
+ initialProps: initialProps
411
401
  });
412
402
 
413
403
  // 4. Simulate user selecting a template ID via the exposed callback (useEditor)
@@ -419,21 +409,17 @@ describe('useEmailWrapper', () => {
419
409
  expect(result.current.modeContent).toEqual({ id: templateId }); // State updated
420
410
  expect(mockProps.showNextStep).toHaveBeenCalledTimes(1); // User action effect
421
411
 
422
- // Clear mocks after user action to isolate effect calls
423
- mockProps.templatesActions.setEdmTemplate.mockClear();
424
- mockProps.templatesActions.setBEETemplate.mockClear();
425
-
426
412
  // 5. Rerender with step changed to CREATE_TEMPLATE_CONTENT
427
413
  const createContentProps = {
428
414
  ...initialProps, // Base props
429
415
  step: STEPS.CREATE_TEMPLATE_CONTENT, // *** Change step ***
430
- SelectedEdmDefaultTemplate: null, // *** Ensure this is null ***
416
+ SelectedEdmDefaultTemplate: null // *** Ensure this is null ***
431
417
  // The internal state `modeContent = { id: templateId }` persists
432
418
  // The internal state `selectedCreateMode = ''` also persists (not changed yet)
433
419
  };
434
420
 
435
421
  // Mock isEmpty just before rerender for the specific check inside the effect
436
- isEmpty.mockImplementation((val) => {
422
+ isEmpty.mockImplementation(val => {
437
423
  // console.log('DEBUG: isEmpty called with', JSON.stringify(val)); // Optional debug
438
424
  // Return true ONLY for the 'SelectedEdmDefaultTemplate' check (which is null)
439
425
  if (val === null) return true;
@@ -448,48 +434,28 @@ describe('useEmailWrapper', () => {
448
434
 
449
435
  // 6. Wait for effects triggered by the rerender
450
436
  await reactAct(async () => {
451
- // Allow React to process the rerender and run effects
452
- await new Promise((resolve) => setTimeout(resolve, 10));
437
+ // Short pause allows React's scheduler to run effects
438
+ await new Promise(resolve => setTimeout(resolve, 0));
453
439
  });
454
440
 
441
+
455
442
  // Assert that the template setting actions were called as a result of the effect
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
- }
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);
481
447
  });
482
448
 
483
449
  it('sets selectedCreateMode in useEffect when in UPLOAD mode and CREATE_TEMPLATE_CONTENT step with EmailLayout', async () => {
484
450
  const initialRenderProps = {
485
- ...mockProps,
486
- step: STEPS.MODE_SELECTION,
487
- emailCreateMode: EMAIL_CREATE_MODES.UPLOAD,
488
- EmailLayout: null,
489
- };
451
+ ...mockProps,
452
+ step: STEPS.MODE_SELECTION,
453
+ emailCreateMode: EMAIL_CREATE_MODES.UPLOAD,
454
+ EmailLayout: null,
455
+ };
490
456
 
491
457
  const { result, rerender } = renderHook((props) => useEmailWrapper(props), {
492
- initialProps: initialRenderProps,
458
+ initialProps: initialRenderProps
493
459
  });
494
460
 
495
461
  const rerenderProps = {
@@ -501,11 +467,11 @@ describe('useEmailWrapper', () => {
501
467
 
502
468
  // Reset isEmpty to default before setting the specific mock for the effect
503
469
  isEmpty.mockImplementation((val) => {
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
- });
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
+ });
509
475
  // Mock isEmpty specifically for the EmailLayout check inside the useEffect
510
476
  isEmpty.mockImplementationOnce(() => false); // Mock !isEmpty(EmailLayout) to be true
511
477
 
@@ -513,16 +479,16 @@ describe('useEmailWrapper', () => {
513
479
 
514
480
  // Wait for the effect to run, set selectedCreateMode, and isShowEmailCreate to update
515
481
  await waitFor(() => {
516
- expect(result.current.isShowEmailCreate).toBe(true);
482
+ expect(result.current.isShowEmailCreate).toBe(true);
517
483
  });
518
484
 
519
485
  // Restore default isEmpty behavior after the specific mock is used
520
486
  isEmpty.mockImplementation((val) => {
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
- });
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
+ });
526
492
  isEmpty.mockClear(); // Clear any remaining mock state if needed
527
493
 
528
494
  expect(mockProps.templatesActions.setEdmTemplate).not.toHaveBeenCalled();
@@ -567,11 +533,11 @@ describe('useEmailWrapper', () => {
567
533
 
568
534
  // Reset isEmpty to default before setting the specific mock for the effect
569
535
  isEmpty.mockImplementation((val) => {
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
- });
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
+ });
575
541
  // Mock isEmpty specifically for the EmailLayout check inside the useEffect
576
542
  isEmpty.mockImplementationOnce(() => false); // Mock !isEmpty(EmailLayout) to be true
577
543
 
@@ -579,16 +545,16 @@ describe('useEmailWrapper', () => {
579
545
 
580
546
  // Wait for the effect to run, set selectedCreateMode, and isShowEmailCreate to update
581
547
  await waitFor(() => {
582
- expect(result.current.isShowEmailCreate).toBe(true);
548
+ expect(result.current.isShowEmailCreate).toBe(true);
583
549
  });
584
550
 
585
551
  // Restore default isEmpty behavior after the specific mock is used
586
552
  isEmpty.mockImplementation((val) => {
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
- });
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
+ });
592
558
  isEmpty.mockClear(); // Clear any remaining mock state if needed
593
559
 
594
560
  // --- Case 3: EDITOR mode selected, Template becomes available -> true (via effect) ---
@@ -597,11 +563,11 @@ describe('useEmailWrapper', () => {
597
563
  find.mockReturnValue(mockTemplate); // Ensure find is mocked for this case
598
564
 
599
565
  const editorPropsInitial = {
600
- ...mockProps,
601
- step: STEPS.TEMPLATE_SELECTION,
602
- emailCreateMode: EMAIL_CREATE_MODES.EDITOR,
603
- CmsTemplates: [mockTemplate],
604
- SelectedEdmDefaultTemplate: null,
566
+ ...mockProps,
567
+ step: STEPS.TEMPLATE_SELECTION,
568
+ emailCreateMode: EMAIL_CREATE_MODES.EDITOR,
569
+ CmsTemplates: [mockTemplate],
570
+ SelectedEdmDefaultTemplate: null,
605
571
  };
606
572
  rerender(editorPropsInitial);
607
573
 
@@ -613,12 +579,12 @@ describe('useEmailWrapper', () => {
613
579
  expect(result.current.modeContent).toEqual({ id: templateId });
614
580
 
615
581
  const editorPropsFinal = {
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
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
622
588
  };
623
589
 
624
590
  // Mock isEmpty specifically for the check within the useEffect triggered by rerender
@@ -632,487 +598,4 @@ describe('useEmailWrapper', () => {
632
598
  find.mockClear();
633
599
  isEmpty.mockClear();
634
600
  });
635
-
636
- describe('New Flow (hasSupportCKEditor = false) - Editor Type Determination', () => {
637
- let newFlowMockProps;
638
- let mockEmailActions;
639
-
640
- beforeEach(() => {
641
- const { hasSupportCKEditor } = require('../../../utils/common');
642
- hasSupportCKEditor.mockReturnValue(false); // New flow
643
-
644
- mockEmailActions = {
645
- getTemplateDetails: jest.fn(),
646
- getCmsAccounts: jest.fn(),
647
- };
648
-
649
- newFlowMockProps = {
650
- ...mockProps,
651
- emailActions: mockEmailActions,
652
- Email: {
653
- templateDetails: null,
654
- BEETemplate: null,
655
- getTemplateDetailsInProgress: false,
656
- isBeeEnabled: true,
657
- },
658
- location: {
659
- pathname: '/email/create',
660
- query: {},
661
- },
662
- params: {},
663
- templateData: null,
664
- };
665
- });
666
-
667
- describe('Create Flow', () => {
668
- it('should set HTML editor when HTML_EDITOR mode is selected', async () => {
669
- const { result } = renderHook((props) => useEmailWrapper(props), {
670
- initialProps: newFlowMockProps,
671
- });
672
-
673
- // Select HTML Editor mode
674
- reactAct(() => {
675
- result.current.onChange({ target: { value: EMAIL_CREATE_MODES.HTML_EDITOR } });
676
- });
677
-
678
- await waitFor(() => {
679
- const emailProps = result.current.emailProps;
680
- expect(emailProps.editor).toBe('HTML');
681
- expect(emailProps.selectedEditorMode).toBe(EMAIL_CREATE_MODES.HTML_EDITOR);
682
- });
683
- });
684
- });
685
-
686
- describe('Edit Flow - HTML Editor Template', () => {
687
- it('should call getTemplateDetails and set HTML editor for HTML template', async () => {
688
- const templateId = 'html-template-123';
689
- const htmlTemplateData = {
690
- _id: templateId,
691
- name: 'HTML Template',
692
- versions: {
693
- base: {
694
- activeTab: 'en',
695
- en: {
696
- is_drag_drop: false,
697
- html_content: '<html><body>Test</body></html>',
698
- },
699
- },
700
- },
701
- };
702
-
703
- const editProps = {
704
- ...newFlowMockProps,
705
- params: { id: templateId },
706
- location: {
707
- pathname: `/email/edit/${templateId}`,
708
- query: { id: templateId },
709
- },
710
- Email: {
711
- ...newFlowMockProps.Email,
712
- templateDetails: null,
713
- getTemplateDetailsInProgress: false,
714
- },
715
- };
716
-
717
- const { result, rerender } = renderHook((props) => useEmailWrapper(props), {
718
- initialProps: editProps,
719
- });
720
-
721
- // Verify getTemplateDetails is called
722
- await waitFor(() => {
723
- expect(mockEmailActions.getTemplateDetails).toHaveBeenCalledWith(templateId, 'email');
724
- });
725
-
726
- // Simulate template data loaded
727
- rerender({
728
- ...editProps,
729
- Email: {
730
- ...editProps.Email,
731
- templateDetails: htmlTemplateData,
732
- getTemplateDetailsInProgress: false,
733
- },
734
- });
735
-
736
- await waitFor(() => {
737
- const emailProps = result.current.emailProps;
738
- expect(emailProps.editor).toBe('HTML');
739
- expect(emailProps.selectedEditorMode).toBe(EMAIL_CREATE_MODES.HTML_EDITOR);
740
- });
741
- });
742
-
743
- it('should detect HTML template from templateData prop (library mode)', async () => {
744
- const htmlTemplateData = {
745
- _id: 'html-template-456',
746
- name: 'HTML Template',
747
- base: {
748
- is_drag_drop: false,
749
- html_content: '<html><body>Test</body></html>',
750
- },
751
- };
752
-
753
- const editProps = {
754
- ...newFlowMockProps,
755
- templateData: htmlTemplateData,
756
- location: {
757
- pathname: '/email/edit',
758
- query: { type: 'embedded', module: 'library' },
759
- },
760
- };
761
-
762
- const { result } = renderHook((props) => useEmailWrapper(props), {
763
- initialProps: editProps,
764
- });
765
-
766
- await waitFor(() => {
767
- const emailProps = result.current.emailProps;
768
- expect(emailProps.editor).toBe('HTML');
769
- expect(emailProps.selectedEditorMode).toBe(EMAIL_CREATE_MODES.HTML_EDITOR);
770
- });
771
- });
772
- });
773
-
774
- describe('Edit Flow - BEE Editor Template', () => {
775
- it('should call getTemplateDetails and set BEE editor for BEE template', async () => {
776
- const templateId = 'bee-template-123';
777
- const beeTemplateData = {
778
- _id: templateId,
779
- name: 'BEE Template',
780
- versions: {
781
- base: {
782
- activeTab: 'en',
783
- en: {
784
- is_drag_drop: true,
785
- drag_drop_id: 'drag-drop-123',
786
- },
787
- },
788
- },
789
- };
790
-
791
- const editProps = {
792
- ...newFlowMockProps,
793
- params: { id: templateId },
794
- location: {
795
- pathname: `/email/edit/${templateId}`,
796
- query: { id: templateId },
797
- },
798
- Email: {
799
- ...newFlowMockProps.Email,
800
- templateDetails: null,
801
- getTemplateDetailsInProgress: false,
802
- isBeeEnabled: true,
803
- },
804
- };
805
-
806
- const { result, rerender } = renderHook((props) => useEmailWrapper(props), {
807
- initialProps: editProps,
808
- });
809
-
810
- // Verify getTemplateDetails is called
811
- await waitFor(() => {
812
- expect(mockEmailActions.getTemplateDetails).toHaveBeenCalledWith(templateId, 'email');
813
- });
814
-
815
- // Simulate template data loaded
816
- rerender({
817
- ...editProps,
818
- Email: {
819
- ...editProps.Email,
820
- templateDetails: beeTemplateData,
821
- getTemplateDetailsInProgress: false,
822
- isBeeEnabled: true,
823
- },
824
- });
825
-
826
- await waitFor(() => {
827
- const emailProps = result.current.emailProps;
828
- expect(emailProps.editor).toBe('BEE');
829
- expect(emailProps.selectedEditorMode).toBe(null);
830
- });
831
- });
832
-
833
- it('should detect BEE template from templateData prop with base.is_drag_drop (library mode)', async () => {
834
- const beeTemplateData = {
835
- _id: 'bee-template-456',
836
- name: 'BEE Template',
837
- base: {
838
- is_drag_drop: true,
839
- drag_drop_id: 'drag-drop-456',
840
- },
841
- };
842
-
843
- const editProps = {
844
- ...newFlowMockProps,
845
- templateData: beeTemplateData,
846
- location: {
847
- pathname: '/email/edit',
848
- query: { type: 'embedded', module: 'library' },
849
- },
850
- Email: {
851
- ...newFlowMockProps.Email,
852
- isBeeEnabled: true,
853
- },
854
- };
855
-
856
- const { result } = renderHook((props) => useEmailWrapper(props), {
857
- initialProps: editProps,
858
- });
859
-
860
- await waitFor(() => {
861
- const emailProps = result.current.emailProps;
862
- expect(emailProps.editor).toBe('BEE');
863
- expect(emailProps.selectedEditorMode).toBe(null);
864
- });
865
- });
866
-
867
- it('should detect BEE template with language-specific is_drag_drop (actual API format)', async () => {
868
- // This matches the actual API response format shown by the user
869
- const beeTemplateData = {
870
- _id: 'bee-template-lang',
871
- name: 'BEE Template',
872
- versions: {
873
- base: {
874
- activeTab: 'en',
875
- en: {
876
- is_drag_drop: true,
877
- drag_drop_id: '',
878
- lang_id: 69,
879
- iso_code: 'en',
880
- language: 'English',
881
- },
882
- },
883
- },
884
- };
885
-
886
- const editProps = {
887
- ...newFlowMockProps,
888
- templateData: beeTemplateData,
889
- Email: {
890
- ...newFlowMockProps.Email,
891
- isBeeEnabled: true,
892
- },
893
- };
894
-
895
- const { result } = renderHook((props) => useEmailWrapper(props), {
896
- initialProps: editProps,
897
- });
898
-
899
- await waitFor(() => {
900
- const emailProps = result.current.emailProps;
901
- expect(emailProps.editor).toBe('BEE');
902
- expect(emailProps.selectedEditorMode).toBe(null);
903
- });
904
- });
905
-
906
- it('should fallback to HTML editor if BEE template but BEE is disabled', async () => {
907
- const beeTemplateData = {
908
- _id: 'bee-template-disabled',
909
- name: 'BEE Template',
910
- versions: {
911
- base: {
912
- activeTab: 'en',
913
- en: {
914
- is_drag_drop: true,
915
- },
916
- },
917
- },
918
- };
919
-
920
- const editProps = {
921
- ...newFlowMockProps,
922
- templateData: beeTemplateData,
923
- Email: {
924
- ...newFlowMockProps.Email,
925
- isBeeEnabled: false, // BEE disabled
926
- },
927
- };
928
-
929
- const { result } = renderHook((props) => useEmailWrapper(props), {
930
- initialProps: editProps,
931
- });
932
-
933
- await waitFor(() => {
934
- const emailProps = result.current.emailProps;
935
- // Should fallback to HTML editor when BEE is disabled
936
- expect(emailProps.editor).toBe('HTML');
937
- expect(emailProps.selectedEditorMode).toBe(EMAIL_CREATE_MODES.HTML_EDITOR);
938
- });
939
- });
940
- });
941
-
942
- describe('Edit Flow - API Call Verification', () => {
943
- it('should NOT call getTemplateDetails if template data already exists', async () => {
944
- const templateId = 'existing-template';
945
- const existingTemplateData = {
946
- _id: templateId,
947
- name: 'Existing Template',
948
- versions: {
949
- base: {
950
- activeTab: 'en',
951
- en: {
952
- is_drag_drop: false,
953
- },
954
- },
955
- },
956
- };
957
-
958
- const editProps = {
959
- ...newFlowMockProps,
960
- params: { id: templateId },
961
- Email: {
962
- ...newFlowMockProps.Email,
963
- templateDetails: existingTemplateData, // Already loaded
964
- getTemplateDetailsInProgress: false,
965
- },
966
- };
967
-
968
- renderHook((props) => useEmailWrapper(props), {
969
- initialProps: editProps,
970
- });
971
-
972
- // Wait a bit to ensure effect runs
973
- await waitFor(() => {
974
- // Should NOT call getTemplateDetails since data already exists
975
- expect(mockEmailActions.getTemplateDetails).not.toHaveBeenCalled();
976
- }, { timeout: 1000 });
977
- });
978
-
979
- it('should NOT call getTemplateDetails if templateData prop is provided', async () => {
980
- const templateData = {
981
- _id: 'prop-template',
982
- base: {
983
- is_drag_drop: false,
984
- },
985
- };
986
-
987
- const editProps = {
988
- ...newFlowMockProps,
989
- params: { id: 'prop-template' },
990
- templateData, // Provided via prop
991
- Email: {
992
- ...newFlowMockProps.Email,
993
- templateDetails: null,
994
- },
995
- };
996
-
997
- renderHook((props) => useEmailWrapper(props), {
998
- initialProps: editProps,
999
- });
1000
-
1001
- // Wait a bit to ensure effect runs
1002
- await waitFor(() => {
1003
- // Should NOT call getTemplateDetails since templateData prop is provided
1004
- expect(mockEmailActions.getTemplateDetails).not.toHaveBeenCalled();
1005
- }, { timeout: 1000 });
1006
- });
1007
-
1008
- it('should NOT call getTemplateDetails if already loading', async () => {
1009
- const templateId = 'loading-template';
1010
-
1011
- const editProps = {
1012
- ...newFlowMockProps,
1013
- params: { id: templateId },
1014
- Email: {
1015
- ...newFlowMockProps.Email,
1016
- templateDetails: null,
1017
- getTemplateDetailsInProgress: true, // Already loading
1018
- },
1019
- };
1020
-
1021
- renderHook((props) => useEmailWrapper(props), {
1022
- initialProps: editProps,
1023
- });
1024
-
1025
- // Wait a bit to ensure effect runs
1026
- await waitFor(() => {
1027
- // Should NOT call getTemplateDetails since already loading
1028
- expect(mockEmailActions.getTemplateDetails).not.toHaveBeenCalled();
1029
- }, { timeout: 1000 });
1030
- });
1031
- });
1032
- });
1033
-
1034
- describe('getStepFromTemplateStep (tested indirectly through behavior)', () => {
1035
- it('should handle numeric step 1 (MODE_SELECTION)', () => {
1036
- const { result } = renderHook(() => useEmailWrapper({
1037
- ...mockProps,
1038
- step: 1,
1039
- }));
1040
-
1041
- // When step is 1 (MODE_SELECTION), isShowEmailCreate should be false
1042
- // This tests that getStepFromTemplateStep converts 1 to MODE_SELECTION
1043
- expect(result.current.isShowEmailCreate).toBe(false);
1044
- });
1045
-
1046
- it('should handle numeric step 2 (TEMPLATE_SELECTION)', () => {
1047
- const { result } = renderHook(() => useEmailWrapper({
1048
- ...mockProps,
1049
- step: 2,
1050
- emailCreateMode: EMAIL_CREATE_MODES.EDITOR,
1051
- }));
1052
-
1053
- // When step is 2 (TEMPLATE_SELECTION), isShowEmailCreate should be false
1054
- expect(result.current.isShowEmailCreate).toBe(false);
1055
- });
1056
-
1057
- it('should handle numeric step 3 (CREATE_TEMPLATE_CONTENT)', () => {
1058
- const { result } = renderHook(() => useEmailWrapper({
1059
- ...mockProps,
1060
- step: 3,
1061
- emailCreateMode: EMAIL_CREATE_MODES.EDITOR,
1062
- SelectedEdmDefaultTemplate: { id: 'template1' },
1063
- }));
1064
-
1065
- // When step is 3 (CREATE_TEMPLATE_CONTENT) and template is selected, isShowEmailCreate should be true
1066
- expect(result.current.isShowEmailCreate).toBe(true);
1067
- });
1068
-
1069
- it('should handle string step value', () => {
1070
- const { result } = renderHook(() => useEmailWrapper({
1071
- ...mockProps,
1072
- step: STEPS.CREATE_TEMPLATE_CONTENT,
1073
- emailCreateMode: EMAIL_CREATE_MODES.EDITOR,
1074
- SelectedEdmDefaultTemplate: { id: 'template1' },
1075
- }));
1076
-
1077
- // String step should work the same way
1078
- expect(result.current.isShowEmailCreate).toBe(true);
1079
- });
1080
-
1081
- it('should default to MODE_SELECTION when step is null or undefined', () => {
1082
- const { result: result1 } = renderHook(() => useEmailWrapper({
1083
- ...mockProps,
1084
- step: null,
1085
- }));
1086
-
1087
- // Should default to MODE_SELECTION behavior
1088
- expect(result1.current.isShowEmailCreate).toBe(false);
1089
-
1090
- const { result: result2 } = renderHook(() => useEmailWrapper({
1091
- ...mockProps,
1092
- step: undefined,
1093
- }));
1094
-
1095
- expect(result2.current.isShowEmailCreate).toBe(false);
1096
- });
1097
- });
1098
-
1099
- describe('Template mode selection logic', () => {
1100
- it('should set HTML_EDITOR mode when HTML_EDITOR is selected and supportCKEditor is false', () => {
1101
- const { hasSupportCKEditor } = require('../../../utils/common');
1102
- hasSupportCKEditor.mockReturnValueOnce(false);
1103
-
1104
- const { result } = renderHook(() => useEmailWrapper({
1105
- ...mockProps,
1106
- emailCreateMode: EMAIL_CREATE_MODES.HTML_EDITOR,
1107
- modeContent: { id: 'mode1' },
1108
- step: STEPS.CREATE_TEMPLATE_CONTENT,
1109
- }));
1110
-
1111
- expect(result.current.emailProps.selectedEditorMode).toBe(EMAIL_CREATE_MODES.HTML_EDITOR);
1112
- });
1113
-
1114
- // Note: DRAG_DROP and EDITOR mode selection logic is complex and depends on multiple conditions
1115
- // These are tested through integration tests and actual component usage
1116
- // The logic is covered in existing tests that test the full flow
1117
- });
1118
- });
601
+ });