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
@@ -44,6 +44,9 @@ describe('validation', () => {
44
44
  messageRequired: {
45
45
  defaultMessage: 'Message is required',
46
46
  },
47
+ personalizationTokensErrorMessage: {
48
+ defaultMessage: 'Personalization tags are not supported for anonymous customers',
49
+ },
47
50
  };
48
51
 
49
52
  beforeEach(() => {
@@ -113,6 +116,51 @@ describe('validation', () => {
113
116
  const result = validateTitle(' Valid Title ', mockFormatMessage, mockMessages);
114
117
  expect(result).toBe('');
115
118
  });
119
+
120
+ it('should return personalization error when restrictPersonalization is true and title has personalization tags', () => {
121
+ const result = validateTitle(
122
+ 'Hello {{name}}',
123
+ mockFormatMessage,
124
+ mockMessages,
125
+ true
126
+ );
127
+ expect(result).toBe('Personalization tags are not supported for anonymous customers');
128
+ expect(mockFormatMessage).toHaveBeenCalledWith(mockMessages.personalizationTokensErrorMessage);
129
+ });
130
+
131
+ it('should return brace error when validationConfig is provided and validateTags returns isBraceError', () => {
132
+ const validationConfig = { tagsParam: [], location: {}, tagModule: '' };
133
+ validateTags.mockReturnValue({ isBraceError: true });
134
+ const result = validateTitle(
135
+ 'Valid Title',
136
+ mockFormatMessage,
137
+ mockMessages,
138
+ false,
139
+ validationConfig,
140
+ false
141
+ );
142
+ expect(result).toBe('Unbalanced curly braces');
143
+ expect(mockFormatMessage).toHaveBeenCalledWith(globalMessages.unbalanacedCurlyBraces);
144
+ expect(validateTags).toHaveBeenCalledWith({
145
+ content: 'Valid Title',
146
+ ...validationConfig,
147
+ isFullMode: false,
148
+ });
149
+ });
150
+
151
+ it('should not run tag validation when validationConfig is null', () => {
152
+ validateTags.mockClear();
153
+ const result = validateTitle('Valid Title', mockFormatMessage, mockMessages, false, null);
154
+ expect(result).toBe('');
155
+ expect(validateTags).not.toHaveBeenCalled();
156
+ });
157
+
158
+ it('should not run tag validation when validationConfig is undefined', () => {
159
+ validateTags.mockClear();
160
+ const result = validateTitle('Valid Title', mockFormatMessage, mockMessages, false, undefined);
161
+ expect(result).toBe('');
162
+ expect(validateTags).not.toHaveBeenCalled();
163
+ });
116
164
  });
117
165
 
118
166
  describe('validateUrl', () => {
@@ -169,10 +217,8 @@ describe('validation', () => {
169
217
  describe('validateMessageContent', () => {
170
218
  const mockValidationConfig = {
171
219
  tagsParam: [],
172
- injectedTagsParams: [],
173
220
  location: {},
174
221
  tagModule: '',
175
- eventContextTags: [],
176
222
  };
177
223
 
178
224
  beforeEach(() => {
@@ -211,17 +257,6 @@ describe('validation', () => {
211
257
  });
212
258
  });
213
259
 
214
- it('should return error message for unsupported tags', () => {
215
- validateTags.mockReturnValue({
216
- unsupportedTags: ['tag1', 'tag2'],
217
- });
218
- const result = validateMessageContent('Message with {tag1} and {tag2}', mockFormatMessage, mockMessages, mockValidationConfig);
219
- expect(result).toBe('Unsupported tags: tag1, tag2');
220
- expect(mockFormatMessage).toHaveBeenCalledWith(globalMessages.unsupportedTagsValidationError, {
221
- unsupportedTags: 'tag1, tag2',
222
- });
223
- });
224
-
225
260
  it('should return error message for unbalanced curly braces', () => {
226
261
  validateTags.mockReturnValue({
227
262
  isBraceError: true,
@@ -231,22 +266,11 @@ describe('validation', () => {
231
266
  expect(mockFormatMessage).toHaveBeenCalledWith(globalMessages.unbalanacedCurlyBraces);
232
267
  });
233
268
 
234
- it('should return error message for both unsupported tags and brace error (unsupported tags takes precedence)', () => {
235
- validateTags.mockReturnValue({
236
- unsupportedTags: ['tag1'],
237
- isBraceError: true,
238
- });
239
- const result = validateMessageContent('Message with {tag1}', mockFormatMessage, mockMessages, mockValidationConfig);
240
- expect(result).toBe('Unsupported tags: tag1');
241
- });
242
-
243
269
  it('should pass validation config to validateTags', () => {
244
270
  const customConfig = {
245
271
  tagsParam: [{ id: 1, name: 'Tag1' }],
246
- injectedTagsParams: [{ id: 2, name: 'Tag2' }],
247
272
  location: { query: { type: 'test' } },
248
273
  tagModule: 'custom',
249
- eventContextTags: [{ id: 3, name: 'Tag3' }],
250
274
  };
251
275
  validateTags.mockReturnValue({});
252
276
  validateMessageContent('Valid message', mockFormatMessage, mockMessages, customConfig);
@@ -278,6 +302,30 @@ describe('validation', () => {
278
302
  ...mockValidationConfig,
279
303
  });
280
304
  });
305
+
306
+ it('should return personalization error when restrictPersonalization is true and message has personalization tags', () => {
307
+ validateTags.mockReturnValue({});
308
+ const result = validateMessageContent(
309
+ 'Hello {{name}}',
310
+ mockFormatMessage,
311
+ mockMessages,
312
+ mockValidationConfig,
313
+ true,
314
+ true
315
+ );
316
+ expect(result).toBe('Personalization tags are not supported for anonymous customers');
317
+ expect(mockFormatMessage).toHaveBeenCalledWith(mockMessages.personalizationTokensErrorMessage);
318
+ });
319
+
320
+ it('should pass isFullMode to validateTags when provided', () => {
321
+ validateTags.mockReturnValue({});
322
+ validateMessageContent('Valid message', mockFormatMessage, mockMessages, mockValidationConfig, true);
323
+ expect(validateTags).toHaveBeenCalledWith({
324
+ content: 'Valid message',
325
+ ...mockValidationConfig,
326
+ isFullMode: true,
327
+ });
328
+ });
281
329
  });
282
330
  });
283
331
 
@@ -43,12 +43,12 @@ import { makeSelectTemplates } from '../Templates/selectors';
43
43
  import {
44
44
  isLoadingMetaEntities,
45
45
  makeSelectMetaEntities,
46
- selectCurrentOrgDetails,
47
46
  setInjectedTags,
48
47
  selectMetaDataStatus,
49
48
  } from "../Cap/selectors";
50
49
  import * as WhatsappActions from './actions';
51
50
  import TestAndPreviewSlidebox from '../../v2Components/TestAndPreviewSlidebox';
51
+ import { isAiContentBotDisabled } from '../../utils/common';
52
52
  import './index.scss';
53
53
  import {
54
54
  UNSUBSCRIBE_TEXT_LENGTH,
@@ -88,7 +88,6 @@ import {
88
88
  BUTTON_TEXT,
89
89
  OTP_CONFIG_URI,
90
90
  WHATSAPP_CATEGORIES,
91
- AI_CONTENT_BOT_DISABLED,
92
91
  mediaTypeOptions,
93
92
  carouselMediaOptions,
94
93
  CAROUSEL_INITIAL_DATA,
@@ -119,6 +118,7 @@ import { ANDROID } from '../../v2Components/CommonTestAndPreview/constants';
119
118
  import CapImageUpload from '../../v2Components/CapImageUpload';
120
119
  import TagList from '../TagList';
121
120
  import { validateTags } from '../../utils/tagValidations';
121
+ import { splitContentByOrderedVarTokens } from '../../utils/templateVarUtils';
122
122
  import { capitalizeString } from '../../utils/Formatter';
123
123
  import CapWhatsappCTA from '../../v2Components/CapWhatsappCTA';
124
124
  import {
@@ -180,8 +180,8 @@ export const Whatsapp = (props) => {
180
180
  loadingTags,
181
181
  getFormData,
182
182
  selectedOfferDetails,
183
- currentOrgDetails,
184
183
  eventContextTags,
184
+ waitEventContextTags = {},
185
185
  metaDataStatus = "",
186
186
  showTestAndPreviewSlidebox: propsShowTestAndPreviewSlidebox,
187
187
  handleTestAndPreview: propsHandleTestAndPreview,
@@ -268,10 +268,7 @@ export const Whatsapp = (props) => {
268
268
  const carouselBodyVarRegex = /{{[1-5]}}/g;
269
269
  const previewUrlMatchingRegex = /(http|ftp|https):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])/g;
270
270
 
271
- const { accessibleFeatures = [] } = currentOrgDetails || {};
272
- const isAiContentBotDisabled = accessibleFeatures?.includes(
273
- AI_CONTENT_BOT_DISABLED
274
- );
271
+ const aiContentBotDisabled = isAiContentBotDisabled();
275
272
  const isBtnTypeCta = buttonType === WHATSAPP_BUTTON_TYPES.CTA;
276
273
  const isBtnTypeQuickReply = buttonType === WHATSAPP_BUTTON_TYPES.QUICK_REPLY;
277
274
  const isMediaTypeText = templateMediaType === WHATSAPP_MEDIA_TYPES.TEXT;
@@ -487,28 +484,10 @@ export const Whatsapp = (props) => {
487
484
  );
488
485
  };
489
486
 
490
- const converStringToVarArr = (validVarArr, content) => {
491
- const templateVarArray = [];
492
- while (content?.length !== 0) {
493
- //converting content string to an array split at var
494
- const index = content.indexOf(validVarArr?.[0]);
495
- if (index !== -1) {
496
- templateVarArray.push(content.substring(0, index)); //push string before var
497
- templateVarArray.push(validVarArr?.[0]); //push var
498
- content = content.substring(index + validVarArr?.[0]?.length, content?.length); //remaining str
499
- validVarArr?.shift(); //remove considered var
500
- } else {
501
- templateVarArray.push(content); //remaining str
502
- break;
503
- }
504
- }
505
- return templateVarArray;
506
- }
507
-
508
487
  const computeTextMessage = (msg, varMap, regex) => {
509
488
  const validVarArr = msg?.match(regex) || [];
510
489
  //conerting msg string to variable arr
511
- const templateHeaderArray = converStringToVarArr(validVarArr, msg);
490
+ const templateHeaderArray = splitContentByOrderedVarTokens(validVarArr, msg);
512
491
  if (templateHeaderArray?.length !== 0) {
513
492
  let clonedVarMap = {};
514
493
  if (!isEmpty(varMap)) {
@@ -562,7 +541,7 @@ export const Whatsapp = (props) => {
562
541
  setUnsubscribeRequired(true);
563
542
  }
564
543
  //converting msg string to variable arr
565
- const templateMessageArray = converStringToVarArr(validVarArr, msg);
544
+ const templateMessageArray = splitContentByOrderedVarTokens(validVarArr, msg);
566
545
  updateTempMsgArray(templateMessageArray.filter((i) => i === 0 || i));
567
546
  };
568
547
 
@@ -637,22 +616,21 @@ export const Whatsapp = (props) => {
637
616
  validateTags({
638
617
  content: contentData.join(""),
639
618
  tagsParam: tags,
640
- injectedTagsParams: injectedTags,
641
619
  location,
642
620
  tagModule: getDefaultTags,
643
- eventContextTags,
644
621
  isFullMode,
645
622
  }) || {};
646
- const unsupportedTagsLengthCheck =
647
- validationResponse?.unsupportedTags?.length > 0;
648
623
  if (type === HEADER_TEXT) {
649
624
  headerTagValidationResponse = validationResponse;
650
- updateIsHeaderTagValidationError(unsupportedTagsLengthCheck);
625
+ updateIsHeaderTagValidationError(validationResponse.isBraceError);
651
626
  } else if (type === CAROUSEL_TEXT) {
652
- return [{fieldName: "carouselTagValidationErrMessage", value: validationResponse}, {fieldName: "carouselTagValidationErr", value: unsupportedTagsLengthCheck}];
627
+ return [
628
+ { fieldName: "carouselTagValidationErrMessage", value: validationResponse.isBraceError ? validationResponse : {} },
629
+ { fieldName: "carouselTagValidationErr", value: validationResponse.isBraceError },
630
+ ];
653
631
  } else {
654
632
  tagValidationResponse = validationResponse;
655
- updateIsTagValidationError(unsupportedTagsLengthCheck);
633
+ updateIsTagValidationError(validationResponse.isBraceError);
656
634
  }
657
635
  }
658
636
  };
@@ -956,6 +934,7 @@ const isAuthenticationTemplate = isEqual(templateCategory, WHATSAPP_CATEGORIES.a
956
934
  injectedTags={injectedTags || {}}
957
935
  selectedOfferDetails={selectedOfferDetails}
958
936
  eventContextTags={eventContextTags}
937
+ waitEventContextTags={waitEventContextTags}
959
938
  />
960
939
  )}
961
940
  </>
@@ -1957,6 +1936,7 @@ const isAuthenticationTemplate = isEqual(templateCategory, WHATSAPP_CATEGORIES.a
1957
1936
  injectedTags={injectedTags || {}}
1958
1937
  selectedOfferDetails={selectedOfferDetails}
1959
1938
  eventContextTags={eventContextTags}
1939
+ waitEventContextTags={waitEventContextTags}
1960
1940
  />
1961
1941
  )
1962
1942
  : !isAuthenticationTemplate && (
@@ -2055,11 +2035,11 @@ const isAuthenticationTemplate = isEqual(templateCategory, WHATSAPP_CATEGORIES.a
2055
2035
  const buttonArray = firstCarouselButtonData.map((button) => {
2056
2036
  switch (button?.buttonType) {
2057
2037
  case PHONE_NUMBER:
2058
- return INITIAL_CAROUSEL_PHONE_NUMBER_DATA;
2038
+ return cloneDeep(INITIAL_CAROUSEL_PHONE_NUMBER_DATA);
2059
2039
  case QUICK_REPLY:
2060
- return INITIAL_CAROUSEL_QUICK_REPLY_DATA;
2040
+ return cloneDeep(INITIAL_CAROUSEL_QUICK_REPLY_DATA);
2061
2041
  default:
2062
- return INITIAL_CAROUSEL_URL_DATA;
2042
+ return cloneDeep(INITIAL_CAROUSEL_URL_DATA);
2063
2043
  }
2064
2044
  });
2065
2045
  const newCard = cloneDeep(CAROUSEL_INITIAL_DATA[0]);
@@ -2258,7 +2238,7 @@ const isAuthenticationTemplate = isEqual(templateCategory, WHATSAPP_CATEGORIES.a
2258
2238
  value={templateMessage || ""}
2259
2239
  disabled={isAuthenticationTemplate}
2260
2240
  />
2261
- {!isAiContentBotDisabled && (
2241
+ {!aiContentBotDisabled && (
2262
2242
  <CapAskAira.ContentGenerationBot
2263
2243
  text={templateMessage || ""}
2264
2244
  setText={(text) => onTemplateValueChange({ target: { value: text } }, MESSAGE_TEXT)}
@@ -2682,18 +2662,11 @@ const isAuthenticationTemplate = isEqual(templateCategory, WHATSAPP_CATEGORIES.a
2682
2662
  } else {
2683
2663
  validationResponse = tagValidationResponse;
2684
2664
  }
2685
- const { unsupportedTags = [], isBraceError } = validationResponse;
2686
-
2687
- let tagError = "";
2688
- if (unsupportedTags.length > 0) {
2689
- tagError = formatMessage(globalMessages.unsupportedTagsValidationError, {
2690
- unsupportedTags,
2691
- });
2692
- }
2665
+ const { isBraceError } = validationResponse || {};
2693
2666
  if (isBraceError) {
2694
- tagError = formatMessage(globalMessages.unbalanacedCurlyBraces);
2667
+ return <CapError>{formatMessage(globalMessages.unbalanacedCurlyBraces)}</CapError>;
2695
2668
  }
2696
- return <CapError>{tagError}</CapError>;
2669
+ return null;
2697
2670
  };
2698
2671
 
2699
2672
  const editModeContent = () => (
@@ -2770,6 +2743,7 @@ const isAuthenticationTemplate = isEqual(templateCategory, WHATSAPP_CATEGORIES.a
2770
2743
  injectedTags={injectedTags || {}}
2771
2744
  selectedOfferDetails={selectedOfferDetails}
2772
2745
  eventContextTags={eventContextTags}
2746
+ waitEventContextTags={waitEventContextTags}
2773
2747
  />
2774
2748
  )
2775
2749
  }
@@ -2888,6 +2862,7 @@ const isAuthenticationTemplate = isEqual(templateCategory, WHATSAPP_CATEGORIES.a
2888
2862
  injectedTags={injectedTags || {}}
2889
2863
  selectedOfferDetails={selectedOfferDetails}
2890
2864
  eventContextTags={eventContextTags}
2865
+ waitEventContextTags={waitEventContextTags}
2891
2866
  />
2892
2867
  )}
2893
2868
  {isBtnTypeQuickReply && (
@@ -2970,12 +2945,13 @@ const isAuthenticationTemplate = isEqual(templateCategory, WHATSAPP_CATEGORIES.a
2970
2945
  };
2971
2946
 
2972
2947
  const isEditDoneDisabled = () => {
2948
+ const isBlankInput = (inputValue) => !String(inputValue ?? '').trim();
2973
2949
  let carouselDisableCheck = false;
2974
2950
  if (isMediaTypeCarousel) {
2975
2951
  carouselDisableCheck = carouselData.some((data) => {
2976
2952
  return (
2977
2953
  data.carouselTagValidationErr ||
2978
- Object.values(data.varMap).some((inputValue) => inputValue === "") ||
2954
+ Object.values(data.varMap).some((inputValue) => isBlankInput(inputValue)) ||
2979
2955
  computeTextLength(CAROUSEL_TEXT, data) > TEMPLATE_MESSAGE_MAX_LENGTH ||
2980
2956
  (carouselMediaType === IMAGE.toLowerCase() && !data.imageSrc) ||
2981
2957
  (carouselMediaType === VIDEO.toLowerCase() && !data.videoSrc) ||
@@ -2985,8 +2961,8 @@ const isAuthenticationTemplate = isEqual(templateCategory, WHATSAPP_CATEGORIES.a
2985
2961
  }
2986
2962
  return (isTagValidationError ||
2987
2963
  isHeaderTagValidationError ||
2988
- Object.values(varMap).some((inputValue) => inputValue === "") ||
2989
- Object.values(headerVarMappedData).some((inputValue) => inputValue === "") ||
2964
+ Object.values(varMap).some((inputValue) => isBlankInput(inputValue)) ||
2965
+ Object.values(headerVarMappedData).some((inputValue) => isBlankInput(inputValue)) ||
2990
2966
  computeTextLength(MESSAGE_TEXT) > TEMPLATE_MESSAGE_MAX_LENGTH ||
2991
2967
  computeTextLength(HEADER_TEXT) > TEMPLATE_HEADER_MAX_LENGTH ||
2992
2968
  (isBtnTypeCta && ctaData.some((btn) => btn?.url?.includes("{{1}}"))) || isMediatypeValid()) || carouselDisableCheck;
@@ -3212,7 +3188,7 @@ const isAuthenticationTemplate = isEqual(templateCategory, WHATSAPP_CATEGORIES.a
3212
3188
  <TestAndPreviewSlidebox
3213
3189
  show={propsShowTestAndPreviewSlidebox || showTestAndPreviewSlidebox}
3214
3190
  onClose={handleCloseTestAndPreview}
3215
- formData={null} // WhatsApp doesn't use formData structure like SMS
3191
+ formData={getTemplateContent()}
3216
3192
  content={getTemplateContent()}
3217
3193
  currentChannel={WHATSAPP}
3218
3194
  />
@@ -3227,7 +3203,6 @@ const mapStateToProps = createStructuredSelector({
3227
3203
  metaEntities: makeSelectMetaEntities(),
3228
3204
  loadingTags: isLoadingMetaEntities(),
3229
3205
  injectedTags: setInjectedTags(),
3230
- currentOrgDetails: selectCurrentOrgDetails(),
3231
3206
  metaDataStatus: selectMetaDataStatus(),
3232
3207
  });
3233
3208