@capillarytech/creatives-library 8.0.266-alpha.1 → 8.0.266

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