cap-creatives-ui 8.0.280 → 8.0.321

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 (247) hide show
  1. package/.github/workflows/pr-title-check.yml +88 -0
  2. package/app/constants/unified.js +21 -1
  3. package/app/containers/App/constants.js +0 -1
  4. package/app/containers/Login/test/index.test.js +123 -0
  5. package/app/containers/Login/test/selectors.test.js +165 -0
  6. package/app/initialState.js +0 -2
  7. package/app/services/api.js +6 -0
  8. package/app/services/tests/api.test.js +7 -0
  9. package/app/services/tests/getSchema.test.js +95 -0
  10. package/app/utils/common.js +23 -9
  11. package/app/utils/commonUtils.js +64 -93
  12. package/app/utils/tagValidations.js +83 -219
  13. package/app/utils/templateVarUtils.js +172 -0
  14. package/app/utils/tests/common.test.js +265 -323
  15. package/app/utils/tests/commonUtil.test.js +461 -118
  16. package/app/utils/tests/commonUtils.test.js +581 -0
  17. package/app/utils/tests/messageUtils.test.js +95 -0
  18. package/app/utils/tests/smsCharCount.test.js +304 -0
  19. package/app/utils/tests/smsCharCountV2.test.js +213 -10
  20. package/app/utils/tests/tagValidations.test.js +474 -357
  21. package/app/utils/tests/templateVarUtils.test.js +160 -0
  22. package/app/v2Components/CapDeviceContent/index.js +10 -7
  23. package/app/v2Components/CapTagList/index.js +32 -24
  24. package/app/v2Components/CapTagList/style.scss +48 -0
  25. package/app/v2Components/CapTagListWithInput/__tests__/CapTagListWithInput.test.js +63 -0
  26. package/app/v2Components/CapTagListWithInput/index.js +8 -0
  27. package/app/v2Components/CapWhatsappCTA/index.js +2 -0
  28. package/app/v2Components/CapWhatsappCarouselButton/index.js +32 -14
  29. package/app/v2Components/CapWhatsappCarouselButton/tests/index.test.js +120 -2
  30. package/app/v2Components/CommonTestAndPreview/CustomValuesEditor.js +70 -49
  31. package/app/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +39 -0
  32. package/app/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +606 -0
  33. package/app/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.scss +36 -0
  34. package/app/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +79 -0
  35. package/app/v2Components/CommonTestAndPreview/DeliverySettings/index.js +314 -0
  36. package/app/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +141 -0
  37. package/app/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +156 -0
  38. package/app/v2Components/CommonTestAndPreview/SendTestMessage.js +57 -1
  39. package/app/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +20 -1
  40. package/app/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +133 -4
  41. package/app/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +210 -4
  42. package/app/v2Components/CommonTestAndPreview/actions.js +20 -0
  43. package/app/v2Components/CommonTestAndPreview/constants.js +57 -1
  44. package/app/v2Components/CommonTestAndPreview/index.js +878 -156
  45. package/app/v2Components/CommonTestAndPreview/messages.js +41 -3
  46. package/app/v2Components/CommonTestAndPreview/previewApiUtils.js +59 -0
  47. package/app/v2Components/CommonTestAndPreview/reducer.js +47 -0
  48. package/app/v2Components/CommonTestAndPreview/sagas.js +75 -5
  49. package/app/v2Components/CommonTestAndPreview/selectors.js +51 -0
  50. package/app/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +352 -0
  51. package/app/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +1156 -0
  52. package/app/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +334 -0
  53. package/app/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +576 -0
  54. package/app/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +156 -0
  55. package/app/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +199 -1
  56. package/app/v2Components/CommonTestAndPreview/tests/actions.test.js +50 -0
  57. package/app/v2Components/CommonTestAndPreview/tests/constants.test.js +18 -7
  58. package/app/v2Components/CommonTestAndPreview/tests/index.test.js +914 -5
  59. package/app/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +67 -0
  60. package/app/v2Components/CommonTestAndPreview/tests/reducer.test.js +118 -0
  61. package/app/v2Components/CommonTestAndPreview/tests/sagas.test.js +146 -378
  62. package/app/v2Components/CommonTestAndPreview/tests/selectors.test.js +146 -0
  63. package/app/v2Components/ErrorInfoNote/index.js +24 -26
  64. package/app/v2Components/FormBuilder/index.js +182 -204
  65. package/app/v2Components/FormBuilder/messages.js +4 -8
  66. package/app/v2Components/HtmlEditor/HTMLEditor.js +7 -6
  67. package/app/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +1 -1
  68. package/app/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +928 -17
  69. package/app/v2Components/HtmlEditor/components/CodeEditorPane/index.js +4 -2
  70. package/app/v2Components/HtmlEditor/hooks/__tests__/useValidation.test.js +452 -3
  71. package/app/v2Components/HtmlEditor/hooks/useValidation.js +12 -9
  72. package/app/v2Components/HtmlEditor/utils/__tests__/htmlValidator.enhanced.test.js +132 -0
  73. package/app/v2Components/HtmlEditor/utils/htmlValidator.js +4 -2
  74. package/app/v2Components/SmsFallback/SmsFallbackLocalSelector.js +87 -0
  75. package/app/v2Components/SmsFallback/constants.js +73 -0
  76. package/app/v2Components/SmsFallback/index.js +956 -0
  77. package/app/v2Components/SmsFallback/index.scss +265 -0
  78. package/app/v2Components/SmsFallback/messages.js +78 -0
  79. package/app/v2Components/SmsFallback/smsFallbackUtils.js +107 -0
  80. package/app/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +50 -0
  81. package/app/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +147 -0
  82. package/app/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +304 -0
  83. package/app/v2Components/SmsFallback/tests/smsFallbackUi.test.js +197 -0
  84. package/app/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +261 -0
  85. package/app/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +422 -0
  86. package/app/v2Components/SmsFallback/useLocalTemplateList.js +92 -0
  87. package/app/v2Components/TestAndPreviewSlidebox/index.js +22 -1
  88. package/app/v2Components/TestAndPreviewSlidebox/sagas.js +11 -4
  89. package/app/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +3 -1
  90. package/app/v2Components/VarSegmentMessageEditor/constants.js +2 -0
  91. package/app/v2Components/VarSegmentMessageEditor/index.js +125 -0
  92. package/app/v2Components/VarSegmentMessageEditor/index.scss +46 -0
  93. package/app/v2Containers/BeeEditor/index.js +3 -0
  94. package/app/v2Containers/BeePopupEditor/index.js +9 -2
  95. package/app/v2Containers/Cap/mockData.js +0 -14
  96. package/app/v2Containers/Cap/reducer.js +3 -55
  97. package/app/v2Containers/Cap/tests/reducer.test.js +0 -102
  98. package/app/v2Containers/CommunicationFlow/CommunicationFlow.js +291 -0
  99. package/app/v2Containers/CommunicationFlow/CommunicationFlow.scss +25 -0
  100. package/app/v2Containers/CommunicationFlow/Tests/CommunicationFlow.test.js +255 -0
  101. package/app/v2Containers/CommunicationFlow/constants.js +200 -0
  102. package/app/v2Containers/CommunicationFlow/index.js +102 -0
  103. package/app/v2Containers/CommunicationFlow/messages.js +346 -0
  104. package/app/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/ChannelSelectionStep.js +522 -0
  105. package/app/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/ChannelSelectionStep.scss +170 -0
  106. package/app/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/Tests/ChannelSelectionStep.test.js +796 -0
  107. package/app/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/index.js +5 -0
  108. package/app/v2Containers/CommunicationFlow/steps/CommunicationStrategyStep/CommunicationStrategyStep.js +95 -0
  109. package/app/v2Containers/CommunicationFlow/steps/CommunicationStrategyStep/Tests/CommunicationStrategyStep.test.js +133 -0
  110. package/app/v2Containers/CommunicationFlow/steps/CommunicationStrategyStep/index.js +5 -0
  111. package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/DeliverySettingsSection.js +289 -0
  112. package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/DeliverySettingsSection.scss +70 -0
  113. package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/SenderDetails.js +319 -0
  114. package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/SenderDetails.scss +69 -0
  115. package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/DeliverySettingsSection.test.js +616 -0
  116. package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/SenderDetails.test.js +577 -0
  117. package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/deliverySettingsConfig.test.js +1111 -0
  118. package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/deliverySettingsConfig.js +696 -0
  119. package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/index.js +7 -0
  120. package/app/v2Containers/CommunicationFlow/steps/DynamicControlsStep/DynamicControlsStep.js +102 -0
  121. package/app/v2Containers/CommunicationFlow/steps/DynamicControlsStep/DynamicControlsStep.scss +36 -0
  122. package/app/v2Containers/CommunicationFlow/steps/DynamicControlsStep/Tests/DynamicControlsStep.test.js +91 -0
  123. package/app/v2Containers/CommunicationFlow/steps/DynamicControlsStep/index.js +5 -0
  124. package/app/v2Containers/CommunicationFlow/steps/MessageTypeStep/MessageTypeStep.js +86 -0
  125. package/app/v2Containers/CommunicationFlow/steps/MessageTypeStep/Tests/MessageTypeStep.test.js +100 -0
  126. package/app/v2Containers/CommunicationFlow/steps/MessageTypeStep/index.js +5 -0
  127. package/app/v2Containers/CommunicationFlow/utils/getEnabledSteps.js +30 -0
  128. package/app/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +43 -0
  129. package/app/v2Containers/CreativesContainer/SlideBoxContent.js +127 -11
  130. package/app/v2Containers/CreativesContainer/SlideBoxFooter.js +62 -9
  131. package/app/v2Containers/CreativesContainer/SlideBoxHeader.js +29 -4
  132. package/app/v2Containers/CreativesContainer/constants.js +24 -0
  133. package/app/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +67 -0
  134. package/app/v2Containers/CreativesContainer/index.js +346 -71
  135. package/app/v2Containers/CreativesContainer/index.scss +51 -1
  136. package/app/v2Containers/CreativesContainer/messages.js +12 -0
  137. package/app/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +90 -0
  138. package/app/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +69 -1
  139. package/app/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +443 -0
  140. package/app/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +110 -0
  141. package/app/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +147 -4
  142. package/app/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +363 -0
  143. package/app/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +57 -10
  144. package/app/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +258 -0
  145. package/app/v2Containers/CreativesContainer/tests/index.test.js +71 -9
  146. package/app/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +125 -0
  147. package/app/v2Containers/Email/index.js +2 -5
  148. package/app/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +58 -77
  149. package/app/v2Containers/EmailWrapper/components/EmailWrapperView.js +3 -0
  150. package/app/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +158 -89
  151. package/app/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +16 -1
  152. package/app/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +17 -12
  153. package/app/v2Containers/EmailWrapper/index.js +4 -0
  154. package/app/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +1 -0
  155. package/app/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +133 -0
  156. package/app/v2Containers/FTP/index.js +2 -51
  157. package/app/v2Containers/FTP/messages.js +0 -4
  158. package/app/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +110 -155
  159. package/app/v2Containers/InApp/index.js +297 -118
  160. package/app/v2Containers/InApp/tests/index.test.js +17 -6
  161. package/app/v2Containers/InApp/tests/mockData.js +1 -1
  162. package/app/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +19 -0
  163. package/app/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +3 -0
  164. package/app/v2Containers/InAppWrapper/index.js +3 -0
  165. package/app/v2Containers/InappAdvance/index.js +5 -104
  166. package/app/v2Containers/InappAdvance/tests/index.test.js +2 -0
  167. package/app/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +24 -3
  168. package/app/v2Containers/Line/Container/Text/index.js +0 -1
  169. package/app/v2Containers/MobilePush/Create/index.js +105 -28
  170. package/app/v2Containers/MobilePush/Create/messages.js +4 -0
  171. package/app/v2Containers/MobilePush/Edit/index.js +250 -68
  172. package/app/v2Containers/MobilePush/Edit/messages.js +4 -0
  173. package/app/v2Containers/MobilePushNew/components/PlatformContentFields.js +36 -12
  174. package/app/v2Containers/MobilePushNew/components/tests/PlatformContentFields.test.js +68 -27
  175. package/app/v2Containers/MobilePushNew/index.js +78 -35
  176. package/app/v2Containers/MobilePushNew/messages.js +8 -0
  177. package/app/v2Containers/MobilepushWrapper/index.js +11 -1
  178. package/app/v2Containers/Rcs/constants.js +32 -1
  179. package/app/v2Containers/Rcs/index.js +963 -916
  180. package/app/v2Containers/Rcs/index.scss +85 -6
  181. package/app/v2Containers/Rcs/messages.js +10 -1
  182. package/app/v2Containers/Rcs/rcsLibraryHydrationUtils.js +205 -0
  183. package/app/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +41136 -1566
  184. package/app/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +0 -5
  185. package/app/v2Containers/Rcs/tests/index.test.js +41 -38
  186. package/app/v2Containers/Rcs/tests/mockData.js +38 -0
  187. package/app/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +251 -0
  188. package/app/v2Containers/Rcs/tests/utils.test.js +379 -1
  189. package/app/v2Containers/Rcs/utils.js +358 -10
  190. package/app/v2Containers/Sms/Create/index.js +122 -39
  191. package/app/v2Containers/Sms/Create/messages.js +4 -0
  192. package/app/v2Containers/Sms/Edit/index.js +37 -3
  193. package/app/v2Containers/Sms/commonMethods.js +3 -6
  194. package/app/v2Containers/Sms/smsFormDataHelpers.js +67 -0
  195. package/app/v2Containers/Sms/tests/commonMethods.test.js +122 -0
  196. package/app/v2Containers/Sms/tests/smsFormDataHelpers.test.js +253 -0
  197. package/app/v2Containers/SmsTrai/Create/index.js +9 -4
  198. package/app/v2Containers/SmsTrai/Create/index.scss +1 -1
  199. package/app/v2Containers/SmsTrai/Edit/constants.js +2 -0
  200. package/app/v2Containers/SmsTrai/Edit/index.js +667 -160
  201. package/app/v2Containers/SmsTrai/Edit/index.scss +121 -0
  202. package/app/v2Containers/SmsTrai/Edit/messages.js +9 -4
  203. package/app/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4590 -2436
  204. package/app/v2Containers/SmsWrapper/index.js +41 -8
  205. package/app/v2Containers/TagList/index.js +63 -2
  206. package/app/v2Containers/TagList/messages.js +8 -0
  207. package/app/v2Containers/TagList/tests/TagList.test.js +122 -20
  208. package/app/v2Containers/TagList/tests/mockdata.js +17 -0
  209. package/app/v2Containers/Templates/TemplatesActionBar.js +101 -0
  210. package/app/v2Containers/Templates/_templates.scss +61 -2
  211. package/app/v2Containers/Templates/actions.js +11 -0
  212. package/app/v2Containers/Templates/constants.js +2 -0
  213. package/app/v2Containers/Templates/index.js +90 -40
  214. package/app/v2Containers/Templates/reducer.js +3 -1
  215. package/app/v2Containers/Templates/sagas.js +57 -12
  216. package/app/v2Containers/Templates/tests/TemplatesActionBar.test.js +120 -0
  217. package/app/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1043 -1079
  218. package/app/v2Containers/Templates/tests/reducer.test.js +12 -0
  219. package/app/v2Containers/Templates/tests/sagas.test.js +193 -12
  220. package/app/v2Containers/Templates/tests/smsTemplatesListApi.test.js +180 -0
  221. package/app/v2Containers/Templates/utils/smsTemplatesListApi.js +79 -0
  222. package/app/v2Containers/TemplatesV2/TemplatesV2.style.js +72 -1
  223. package/app/v2Containers/TemplatesV2/index.js +147 -49
  224. package/app/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +131 -0
  225. package/app/v2Containers/Viber/index.js +9 -10
  226. package/app/v2Containers/Viber/index.scss +1 -1
  227. package/app/v2Containers/WebPush/Create/components/BrandIconSection.test.js +264 -0
  228. package/app/v2Containers/WebPush/Create/components/MessageSection.js +78 -19
  229. package/app/v2Containers/WebPush/Create/components/MessageSection.test.js +82 -0
  230. package/app/v2Containers/WebPush/Create/components/__snapshots__/BrandIconSection.test.js.snap +187 -0
  231. package/app/v2Containers/WebPush/Create/components/__snapshots__/MessageSection.test.js.snap +25 -17
  232. package/app/v2Containers/WebPush/Create/hooks/useAiraTriggerPosition.js +80 -0
  233. package/app/v2Containers/WebPush/Create/hooks/useAiraTriggerPosition.test.js +210 -0
  234. package/app/v2Containers/WebPush/Create/hooks/useTagManagement.js +1 -5
  235. package/app/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +0 -7
  236. package/app/v2Containers/WebPush/Create/index.js +36 -6
  237. package/app/v2Containers/WebPush/Create/index.scss +5 -0
  238. package/app/v2Containers/WebPush/Create/messages.js +8 -1
  239. package/app/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +269 -0
  240. package/app/v2Containers/WebPush/Create/utils/validation.js +31 -15
  241. package/app/v2Containers/WebPush/Create/utils/validation.test.js +72 -24
  242. package/app/v2Containers/Whatsapp/index.js +28 -53
  243. package/app/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +26939 -3982
  244. package/app/v2Containers/Whatsapp/tests/index.test.js +172 -0
  245. package/app/v2Containers/Zalo/index.js +5 -11
  246. package/package.json +2 -2
  247. package/version +9 -0
@@ -2,6 +2,7 @@
2
2
  * Tests for SendTestMessage Component
3
3
  *
4
4
  * Tests the component that handles sending test messages
5
+ * @jest-environment jsdom
5
6
  */
6
7
 
7
8
  import React from 'react';
@@ -11,8 +12,36 @@ import {
11
12
  import { IntlProvider } from 'react-intl';
12
13
  import PropTypes from 'prop-types';
13
14
  import isEmpty from 'lodash/isEmpty';
15
+ // Mock cap-ui-library so SendTestMessage can load (Jest hoists mocks)
16
+ jest.mock('@capillarytech/cap-ui-library/CapRow', () => ({ children, ...rest }) => <div {...rest}>{children}</div>);
17
+ jest.mock('@capillarytech/cap-ui-library/CapButton', () => ({ children, ...rest }) => <button type="button" {...rest}>{children}</button>);
18
+ jest.mock('@capillarytech/cap-ui-library/CapHeader', () => ({ title, description }) => <div><span>{title}</span>{description}</div>);
19
+ jest.mock('@capillarytech/cap-ui-library/CapTreeSelect', () => ({ treeData, onChange, value, placeholder }) => (
20
+ <div data-testid="cap-tree-select"><input onChange={(e) => onChange && onChange(e.target.value)} placeholder={placeholder} /></div>
21
+ ));
22
+
14
23
  import SendTestMessage from '../SendTestMessage';
15
24
 
25
+ // Mock DeliverySettings to assert props
26
+ jest.mock('../DeliverySettings', () => function MockDeliverySettings(props) {
27
+ const smsRows = props.senderDetailsByChannel?.SMS || [];
28
+ return (
29
+ <div data-testid="delivery-settings" data-props={JSON.stringify({
30
+ channel: props.channel,
31
+ hasDeliverySettings: !!props.deliverySettings,
32
+ senderDetailsLength: smsRows.length,
33
+ wecrmAccountsLength: (props.wecrmAccounts || []).length,
34
+ hasOnSave: typeof props.onSaveDeliverySettings === 'function',
35
+ isLoadingSenderDetails: props.isLoadingSenderDetails,
36
+ smsTraiDltEnabled: props.smsTraiDltEnabled,
37
+ registeredSenderIds: props.registeredSenderIds,
38
+ whatsappAccountFromForm: props.whatsappAccountFromForm,
39
+ isChannelSmsFallbackPreviewEnabled: props.isChannelSmsFallbackPreviewEnabled,
40
+ })}
41
+ />
42
+ );
43
+ });
44
+
16
45
  // Mock CapStepsAccordian to always render content expanded
17
46
  jest.mock('@capillarytech/cap-ui-library/CapStepsAccordian', () => {
18
47
  // eslint-disable-next-line global-require, import/no-extraneous-dependencies
@@ -100,6 +129,15 @@ describe('SendTestMessage', () => {
100
129
  },
101
130
  isSendingTestMessage: false,
102
131
  formatMessage: jest.fn((msg) => msg.defaultMessage || msg.id),
132
+ channel: 'EMAIL',
133
+ deliverySettings: {},
134
+ senderDetailsByChannel: {},
135
+ wecrmAccounts: [],
136
+ onSaveDeliverySettings: jest.fn(),
137
+ isLoadingSenderDetails: false,
138
+ smsTraiDltEnabled: false,
139
+ registeredSenderIds: [],
140
+ isChannelSmsFallbackPreviewEnabled: false,
103
141
  };
104
142
 
105
143
  beforeEach(() => {
@@ -162,6 +200,124 @@ describe('SendTestMessage', () => {
162
200
  });
163
201
  });
164
202
 
203
+ describe('DeliverySettings (sender ID / delivery settings)', () => {
204
+ it('should render DeliverySettings when channel is SMS', () => {
205
+ render(
206
+ <TestWrapper>
207
+ <SendTestMessage {...defaultProps} channel="SMS" />
208
+ </TestWrapper>
209
+ );
210
+ const el = screen.getByTestId('delivery-settings');
211
+ expect(el).toBeTruthy();
212
+ const data = JSON.parse(el.getAttribute('data-props'));
213
+ expect(data.channel).toBe('SMS');
214
+ expect(data.hasOnSave).toBe(true);
215
+ });
216
+
217
+ it('should render DeliverySettings when channel is EMAIL', () => {
218
+ render(
219
+ <TestWrapper>
220
+ <SendTestMessage {...defaultProps} channel="EMAIL" />
221
+ </TestWrapper>
222
+ );
223
+ expect(screen.getByTestId('delivery-settings')).toBeTruthy();
224
+ });
225
+
226
+ it('should render DeliverySettings when channel is WHATSAPP', () => {
227
+ render(
228
+ <TestWrapper>
229
+ <SendTestMessage {...defaultProps} channel="WHATSAPP" />
230
+ </TestWrapper>
231
+ );
232
+ expect(screen.getByTestId('delivery-settings')).toBeTruthy();
233
+ });
234
+
235
+ it('should render DeliverySettings when channel is RCS and pass SMS fallback preview flag', () => {
236
+ render(
237
+ <TestWrapper>
238
+ <SendTestMessage
239
+ {...defaultProps}
240
+ channel="RCS"
241
+ isChannelSmsFallbackPreviewEnabled
242
+ />
243
+ </TestWrapper>
244
+ );
245
+ const el = screen.getByTestId('delivery-settings');
246
+ const data = JSON.parse(el.getAttribute('data-props'));
247
+ expect(data.channel).toBe('RCS');
248
+ expect(data.isChannelSmsFallbackPreviewEnabled).toBe(true);
249
+ });
250
+
251
+ it('should not render DeliverySettings when channel is INAPP', () => {
252
+ render(
253
+ <TestWrapper>
254
+ <SendTestMessage {...defaultProps} channel="INAPP" />
255
+ </TestWrapper>
256
+ );
257
+ expect(screen.queryByTestId('delivery-settings')).toBeNull();
258
+ });
259
+
260
+ it('should pass whatsappAccountFromForm when channel is WHATSAPP and formData has accountName', () => {
261
+ render(
262
+ <TestWrapper>
263
+ <SendTestMessage
264
+ {...defaultProps}
265
+ channel="WHATSAPP"
266
+ formData={{ ...defaultProps.formData, accountName: 'My WABA' }}
267
+ />
268
+ </TestWrapper>
269
+ );
270
+ const el = screen.getByTestId('delivery-settings');
271
+ const data = JSON.parse(el.getAttribute('data-props'));
272
+ expect(data.whatsappAccountFromForm).toEqual({ accountName: 'My WABA' });
273
+ });
274
+
275
+ it('should pass whatsappAccountFromForm undefined when channel is WHATSAPP and formData has no accountName', () => {
276
+ render(
277
+ <TestWrapper>
278
+ <SendTestMessage
279
+ {...defaultProps}
280
+ channel="WHATSAPP"
281
+ formData={{ ...defaultProps.formData, accountName: undefined }}
282
+ />
283
+ </TestWrapper>
284
+ );
285
+ const el = screen.getByTestId('delivery-settings');
286
+ const data = JSON.parse(el.getAttribute('data-props'));
287
+ expect(data.whatsappAccountFromForm).toBeUndefined();
288
+ });
289
+
290
+ it('should pass delivery props to DeliverySettings', () => {
291
+ const onSave = jest.fn();
292
+ render(
293
+ <TestWrapper>
294
+ <SendTestMessage
295
+ {...defaultProps}
296
+ channel="SMS"
297
+ deliverySettings={{ domainId: 1 }}
298
+ senderDetailsByChannel={{
299
+ SMS: [{ domainId: 1, domainName: 'SMS Dom' }],
300
+ }}
301
+ wecrmAccounts={[]}
302
+ onSaveDeliverySettings={onSave}
303
+ isLoadingSenderDetails={true}
304
+ smsTraiDltEnabled
305
+ registeredSenderIds={['ID1']}
306
+ />
307
+ </TestWrapper>
308
+ );
309
+ const el = screen.getByTestId('delivery-settings');
310
+ const data = JSON.parse(el.getAttribute('data-props'));
311
+ expect(data.hasDeliverySettings).toBe(true);
312
+ expect(data.senderDetailsLength).toBe(1);
313
+ expect(data.wecrmAccountsLength).toBe(0);
314
+ expect(data.hasOnSave).toBe(true);
315
+ expect(data.isLoadingSenderDetails).toBe(true);
316
+ expect(data.smsTraiDltEnabled).toBe(true);
317
+ expect(data.registeredSenderIds).toEqual(['ID1']);
318
+ });
319
+ });
320
+
165
321
  describe('Loading States', () => {
166
322
  it('should show loading when fetching test customers', () => {
167
323
  const props = {
@@ -9,7 +9,16 @@ import { render, screen } from '@testing-library/react';
9
9
  import '@testing-library/jest-dom';
10
10
  import { injectIntl, IntlProvider } from 'react-intl';
11
11
  import UnifiedPreview from '../../UnifiedPreview';
12
- import { CHANNELS, DESKTOP, TABLET, MOBILE, ANDROID, IOS } from '../../constants';
12
+ import {
13
+ CHANNELS,
14
+ DESKTOP,
15
+ TABLET,
16
+ MOBILE,
17
+ ANDROID,
18
+ IOS,
19
+ PREVIEW_TAB_RCS,
20
+ PREVIEW_TAB_SMS_FALLBACK,
21
+ } from '../../constants';
13
22
  import messages from '../../messages';
14
23
 
15
24
  // Convert messages object to format expected by IntlProvider
@@ -547,6 +556,195 @@ describe('UnifiedPreview', () => {
547
556
 
548
557
  expect(screen.getByTestId('rcs-sender-id')).toHaveTextContent('RCS_SENDER');
549
558
  });
559
+
560
+ describe('RCS SMS fallback — Test & Preview tabs', () => {
561
+ it('without SMS fallback selected, shows only RCS preview (no RCS+SMS tab layout)', () => {
562
+ const props = {
563
+ ...defaultProps,
564
+ channel: CHANNELS.RCS,
565
+ content: { rcsTitle: 'Hello RCS' },
566
+ smsFallbackContent: undefined,
567
+ };
568
+
569
+ const { container } = render(
570
+ <TestWrapper>
571
+ <ComponentToRender {...props} />
572
+ </TestWrapper>
573
+ );
574
+
575
+ expect(container.querySelector('.unified-preview-rcs-tabs')).toBeNull();
576
+ expect(screen.getByTestId('rcs-preview')).toBeInTheDocument();
577
+ expect(screen.queryByTestId('sms-preview')).not.toBeInTheDocument();
578
+ });
579
+
580
+ it('with SMS fallback template body, shows RCS and Fallback SMS tabs', () => {
581
+ const props = {
582
+ ...defaultProps,
583
+ channel: CHANNELS.RCS,
584
+ content: { rcsTitle: 'Hello RCS' },
585
+ smsFallbackContent: {
586
+ content: 'SMS fallback body',
587
+ templateContent: 'SMS fallback body',
588
+ },
589
+ };
590
+
591
+ const { container } = render(
592
+ <TestWrapper>
593
+ <ComponentToRender {...props} />
594
+ </TestWrapper>
595
+ );
596
+
597
+ expect(container.querySelector('.unified-preview-rcs-tabs')).toBeInTheDocument();
598
+ expect(
599
+ screen.getByRole('tab', { name: messages.rcsTab.defaultMessage })
600
+ ).toBeInTheDocument();
601
+ expect(
602
+ screen.getByRole('tab', { name: messages.smsFallbackTab.defaultMessage })
603
+ ).toBeInTheDocument();
604
+ });
605
+
606
+ it('on SMS fallback tab, renders SMS preview with resolved fallback text when smsFallbackResolvedText is set', () => {
607
+ const props = {
608
+ ...defaultProps,
609
+ channel: CHANNELS.RCS,
610
+ content: { rcsTitle: 'Hello RCS' },
611
+ smsFallbackContent: {
612
+ content: '{{var}}',
613
+ templateContent: '{{var}}',
614
+ },
615
+ smsFallbackResolvedText: 'Resolved SMS for preview',
616
+ activePreviewTab: PREVIEW_TAB_SMS_FALLBACK,
617
+ onPreviewTabChange: jest.fn(),
618
+ };
619
+
620
+ render(
621
+ <TestWrapper>
622
+ <ComponentToRender {...props} />
623
+ </TestWrapper>
624
+ );
625
+
626
+ expect(screen.getByTestId('sms-content')).toHaveTextContent('Resolved SMS for preview');
627
+ });
628
+
629
+ it('on RCS tab (default), renders RCS preview when dual tabs are shown', () => {
630
+ const props = {
631
+ ...defaultProps,
632
+ channel: CHANNELS.RCS,
633
+ content: { rcsTitle: 'Only RCS pane' },
634
+ smsFallbackContent: { content: 'SMS', templateContent: 'SMS' },
635
+ activePreviewTab: PREVIEW_TAB_RCS,
636
+ onPreviewTabChange: jest.fn(),
637
+ };
638
+
639
+ render(
640
+ <TestWrapper>
641
+ <ComponentToRender {...props} />
642
+ </TestWrapper>
643
+ );
644
+
645
+ expect(screen.getByTestId('rcs-preview')).toBeInTheDocument();
646
+ expect(screen.getByTestId('rcs-content')).toHaveTextContent(/Only RCS pane/);
647
+ });
648
+
649
+ it('on SMS fallback tab, shows raw template when no varmap and no resolved text', () => {
650
+ const props = {
651
+ ...defaultProps,
652
+ channel: CHANNELS.RCS,
653
+ content: { rcsTitle: 'Hello RCS' },
654
+ smsFallbackContent: {
655
+ content: 'Hello {{name}}',
656
+ templateContent: 'Hello {{name}}',
657
+ // no rcsSmsFallbackVarMapped
658
+ },
659
+ smsFallbackResolvedText: undefined,
660
+ activePreviewTab: PREVIEW_TAB_SMS_FALLBACK,
661
+ onPreviewTabChange: jest.fn(),
662
+ };
663
+
664
+ render(
665
+ <TestWrapper>
666
+ <ComponentToRender {...props} />
667
+ </TestWrapper>
668
+ );
669
+
670
+ // rawFallbackTemplate is shown directly — {{tags}} remain visible
671
+ expect(screen.getByTestId('sms-content')).toHaveTextContent('Hello {{name}}');
672
+ });
673
+
674
+ it('on SMS fallback tab, treats empty resolved text as absent and shows raw template', () => {
675
+ const props = {
676
+ ...defaultProps,
677
+ channel: CHANNELS.RCS,
678
+ content: { rcsTitle: 'Hello RCS' },
679
+ smsFallbackContent: {
680
+ content: 'Raw {{var}} template',
681
+ templateContent: 'Raw {{var}} template',
682
+ },
683
+ smsFallbackResolvedText: '',
684
+ activePreviewTab: PREVIEW_TAB_SMS_FALLBACK,
685
+ onPreviewTabChange: jest.fn(),
686
+ };
687
+
688
+ render(
689
+ <TestWrapper>
690
+ <ComponentToRender {...props} />
691
+ </TestWrapper>
692
+ );
693
+
694
+ expect(screen.getByTestId('sms-content')).toHaveTextContent('Raw {{var}} template');
695
+ });
696
+
697
+ it('on SMS fallback tab, applies varmap slot substitution when varmap entries exist and no resolved text', () => {
698
+ // getFallbackResolvedContent key format: `${fullToken}_${segmentIndex}`
699
+ // 'Hello {{name}}' → segments ['Hello ', '{{name}}'], so {{name}} is at index 1 → key '{{name}}_1'
700
+ const props = {
701
+ ...defaultProps,
702
+ channel: CHANNELS.RCS,
703
+ content: { rcsTitle: 'Hello RCS' },
704
+ smsFallbackContent: {
705
+ content: 'Hello {{name}}',
706
+ templateContent: 'Hello {{name}}',
707
+ rcsSmsFallbackVarMapped: { '{{name}}_1': 'World' },
708
+ },
709
+ smsFallbackResolvedText: undefined,
710
+ activePreviewTab: PREVIEW_TAB_SMS_FALLBACK,
711
+ onPreviewTabChange: jest.fn(),
712
+ };
713
+
714
+ render(
715
+ <TestWrapper>
716
+ <ComponentToRender {...props} />
717
+ </TestWrapper>
718
+ );
719
+
720
+ expect(screen.getByTestId('sms-content')).toHaveTextContent('Hello World');
721
+ });
722
+
723
+ it('on SMS fallback tab, resolved text takes priority over varmap entries', () => {
724
+ const props = {
725
+ ...defaultProps,
726
+ channel: CHANNELS.RCS,
727
+ content: { rcsTitle: 'Hello RCS' },
728
+ smsFallbackContent: {
729
+ content: 'Hello {{name}}',
730
+ templateContent: 'Hello {{name}}',
731
+ rcsSmsFallbackVarMapped: { '{{name}}_1': 'World' },
732
+ },
733
+ smsFallbackResolvedText: 'Hello John',
734
+ activePreviewTab: PREVIEW_TAB_SMS_FALLBACK,
735
+ onPreviewTabChange: jest.fn(),
736
+ };
737
+
738
+ render(
739
+ <TestWrapper>
740
+ <ComponentToRender {...props} />
741
+ </TestWrapper>
742
+ );
743
+
744
+ // resolvedText wins over varmap substitution
745
+ expect(screen.getByTestId('sms-content')).toHaveTextContent('Hello John');
746
+ });
747
+ });
550
748
  });
551
749
 
552
750
  describe('Channel Routing - INAPP', () => {
@@ -17,6 +17,8 @@ import {
17
17
  getPrefilledValuesRequested,
18
18
  clearPrefilledValues,
19
19
  clearPreviewErrors,
20
+ getSenderDetailsRequested,
21
+ getWeCrmAccountsRequested,
20
22
  } from '../actions';
21
23
 
22
24
  import {
@@ -32,6 +34,8 @@ import {
32
34
  GET_PREFILLED_VALUES_REQUESTED,
33
35
  CLEAR_PREFILLED_VALUES,
34
36
  CLEAR_PREVIEW_ERRORS,
37
+ GET_SENDER_DETAILS_REQUESTED,
38
+ GET_WECRM_ACCOUNTS_REQUESTED,
35
39
  } from '../constants';
36
40
 
37
41
  describe('CommonTestAndPreview Actions', () => {
@@ -321,4 +325,50 @@ describe('CommonTestAndPreview Actions', () => {
321
325
  expect(clearPreviewErrors()).toEqual(expectedAction);
322
326
  });
323
327
  });
328
+
329
+ describe('getSenderDetailsRequested', () => {
330
+ it('should create an action to request sender details with channel and orgUnitId', () => {
331
+ const payload = { channel: 'SMS', orgUnitId: 123 };
332
+ const expectedAction = {
333
+ type: GET_SENDER_DETAILS_REQUESTED,
334
+ payload,
335
+ };
336
+ expect(getSenderDetailsRequested(payload)).toEqual(expectedAction);
337
+ });
338
+
339
+ it('should handle EMAIL channel', () => {
340
+ const payload = { channel: 'EMAIL', orgUnitId: -1 };
341
+ expect(getSenderDetailsRequested(payload)).toEqual({
342
+ type: GET_SENDER_DETAILS_REQUESTED,
343
+ payload,
344
+ });
345
+ });
346
+
347
+ it('should handle WHATSAPP channel', () => {
348
+ const payload = { channel: 'WHATSAPP', orgUnitId: 456 };
349
+ expect(getSenderDetailsRequested(payload)).toEqual({
350
+ type: GET_SENDER_DETAILS_REQUESTED,
351
+ payload,
352
+ });
353
+ });
354
+ });
355
+
356
+ describe('getWeCrmAccountsRequested', () => {
357
+ it('should create an action to request WeCRM accounts with sourceName', () => {
358
+ const payload = { sourceName: 'WHATSAPP' };
359
+ const expectedAction = {
360
+ type: GET_WECRM_ACCOUNTS_REQUESTED,
361
+ payload,
362
+ };
363
+ expect(getWeCrmAccountsRequested(payload)).toEqual(expectedAction);
364
+ });
365
+
366
+ it('should handle empty payload', () => {
367
+ const payload = {};
368
+ expect(getWeCrmAccountsRequested(payload)).toEqual({
369
+ type: GET_WECRM_ACCOUNTS_REQUESTED,
370
+ payload: {},
371
+ });
372
+ });
373
+ });
324
374
  });
@@ -30,6 +30,12 @@ import {
30
30
  GET_PREFILLED_VALUES_REQUESTED,
31
31
  GET_PREFILLED_VALUES_SUCCESS,
32
32
  GET_PREFILLED_VALUES_FAILURE,
33
+ GET_SENDER_DETAILS_REQUESTED,
34
+ GET_SENDER_DETAILS_SUCCESS,
35
+ GET_SENDER_DETAILS_FAILURE,
36
+ GET_WECRM_ACCOUNTS_REQUESTED,
37
+ GET_WECRM_ACCOUNTS_SUCCESS,
38
+ GET_WECRM_ACCOUNTS_FAILURE,
33
39
  CLEAR_CUSTOMER_SEARCH_STATE,
34
40
  CLEAR_SEARCH_RESULTS,
35
41
  CLEAR_PREFILLED_VALUES,
@@ -137,6 +143,18 @@ describe('CommonTestAndPreview Constants', () => {
137
143
  expect(GET_PREFILLED_VALUES_FAILURE).toBe('app/CommonTestAndPreview/GET_PREFILLED_VALUES_FAILURE');
138
144
  });
139
145
 
146
+ it('should export all get sender details action types', () => {
147
+ expect(GET_SENDER_DETAILS_REQUESTED).toBe('app/CommonTestAndPreview/GET_SENDER_DETAILS_REQUESTED');
148
+ expect(GET_SENDER_DETAILS_SUCCESS).toBe('app/CommonTestAndPreview/GET_SENDER_DETAILS_SUCCESS');
149
+ expect(GET_SENDER_DETAILS_FAILURE).toBe('app/CommonTestAndPreview/GET_SENDER_DETAILS_FAILURE');
150
+ });
151
+
152
+ it('should export all get wecrm accounts action types', () => {
153
+ expect(GET_WECRM_ACCOUNTS_REQUESTED).toBe('app/CommonTestAndPreview/GET_WECRM_ACCOUNTS_REQUESTED');
154
+ expect(GET_WECRM_ACCOUNTS_SUCCESS).toBe('app/CommonTestAndPreview/GET_WECRM_ACCOUNTS_SUCCESS');
155
+ expect(GET_WECRM_ACCOUNTS_FAILURE).toBe('app/CommonTestAndPreview/GET_WECRM_ACCOUNTS_FAILURE');
156
+ });
157
+
140
158
  it('should export all clear action types', () => {
141
159
  expect(CLEAR_CUSTOMER_SEARCH_STATE).toBe('app/CommonTestAndPreview/CLEAR_CUSTOMER_SEARCH_STATE');
142
160
  expect(CLEAR_SEARCH_RESULTS).toBe('app/CommonTestAndPreview/CLEAR_SEARCH_RESULTS');
@@ -188,13 +206,6 @@ describe('CommonTestAndPreview Constants', () => {
188
206
  });
189
207
  });
190
208
 
191
- describe('Identifier Type Constants', () => {
192
- it('should export identifier type constants', () => {
193
- expect(IDENTIFIER_TYPE_MOBILE).toBe('mobile');
194
- expect(IDENTIFIER_TYPE_EMAIL).toBe('email');
195
- });
196
- });
197
-
198
209
  describe('Channel Name Constants', () => {
199
210
  it('should export channel name constants', () => {
200
211
  expect(CHANNEL_NAME_INAPP).toBe('INAPP');