@capillarytech/creatives-library 8.0.248 → 8.0.250-alpha.0

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 (148) hide show
  1. package/assets/Android.png +0 -0
  2. package/assets/iOS.png +0 -0
  3. package/constants/unified.js +2 -1
  4. package/initialReducer.js +2 -0
  5. package/package.json +1 -1
  6. package/services/api.js +10 -0
  7. package/services/tests/api.test.js +18 -0
  8. package/utils/common.js +5 -0
  9. package/utils/commonUtils.js +28 -5
  10. package/utils/tests/commonUtil.test.js +224 -0
  11. package/utils/tests/transformerUtils.test.js +297 -0
  12. package/utils/transformTemplateConfig.js +0 -10
  13. package/utils/transformerUtils.js +40 -0
  14. package/v2Components/CapDeviceContent/index.js +61 -56
  15. package/v2Components/CapTagList/index.js +6 -1
  16. package/v2Components/CapTagListWithInput/index.js +5 -1
  17. package/v2Components/CapTagListWithInput/messages.js +1 -1
  18. package/v2Components/CapWhatsappCTA/tests/index.test.js +5 -0
  19. package/v2Components/ErrorInfoNote/index.js +452 -72
  20. package/v2Components/ErrorInfoNote/messages.js +22 -0
  21. package/v2Components/ErrorInfoNote/style.scss +280 -4
  22. package/v2Components/FormBuilder/tests/index.test.js +13 -4
  23. package/v2Components/HtmlEditor/HTMLEditor.js +640 -94
  24. package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +874 -0
  25. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +1167 -133
  26. package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +27 -16
  27. package/v2Components/HtmlEditor/_htmlEditor.scss +108 -45
  28. package/v2Components/HtmlEditor/_index.lazy.scss +1 -1
  29. package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +13 -101
  30. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +148 -139
  31. package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +2 -1
  32. package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
  33. package/v2Components/HtmlEditor/components/EditorToolbar/_editorToolbar.scss +9 -0
  34. package/v2Components/HtmlEditor/components/EditorToolbar/index.js +1 -1
  35. package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +22 -0
  36. package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +4 -7
  37. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +35 -45
  38. package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +1 -3
  39. package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
  40. package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +7 -6
  41. package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +3 -6
  42. package/v2Components/HtmlEditor/components/PreviewPane/index.js +11 -13
  43. package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
  44. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +49 -31
  45. package/v2Components/HtmlEditor/components/ValidationPanel/index.js +68 -39
  46. package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +254 -0
  47. package/v2Components/HtmlEditor/components/ValidationTabs/index.js +391 -0
  48. package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +51 -0
  49. package/v2Components/HtmlEditor/constants.js +42 -20
  50. package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +373 -16
  51. package/v2Components/HtmlEditor/hooks/__tests__/useValidation.apiErrors.test.js +795 -0
  52. package/v2Components/HtmlEditor/hooks/useEditorContent.js +5 -2
  53. package/v2Components/HtmlEditor/hooks/useInAppContent.js +88 -146
  54. package/v2Components/HtmlEditor/hooks/useValidation.js +189 -53
  55. package/v2Components/HtmlEditor/index.js +1 -1
  56. package/v2Components/HtmlEditor/messages.js +95 -85
  57. package/v2Components/HtmlEditor/utils/__tests__/htmlValidator.enhanced.test.js +94 -45
  58. package/v2Components/HtmlEditor/utils/contentSanitizer.js +40 -41
  59. package/v2Components/HtmlEditor/utils/htmlValidator.js +71 -72
  60. package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +134 -102
  61. package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +23 -25
  62. package/v2Components/HtmlEditor/utils/validationAdapter.js +66 -41
  63. package/v2Components/MobilePushPreviewV2/index.js +32 -7
  64. package/v2Components/TemplatePreview/_templatePreview.scss +44 -24
  65. package/v2Components/TemplatePreview/index.js +47 -32
  66. package/v2Components/TemplatePreview/messages.js +4 -0
  67. package/v2Components/TestAndPreviewSlidebox/_testAndPreviewSlidebox.scss +1 -0
  68. package/v2Containers/BeeEditor/index.js +172 -90
  69. package/v2Containers/BeePopupEditor/constants.js +10 -0
  70. package/v2Containers/BeePopupEditor/index.js +193 -0
  71. package/v2Containers/BeePopupEditor/tests/index.test.js +627 -0
  72. package/v2Containers/CreativesContainer/SlideBoxContent.js +129 -51
  73. package/v2Containers/CreativesContainer/SlideBoxFooter.js +163 -13
  74. package/v2Containers/CreativesContainer/SlideBoxHeader.js +2 -1
  75. package/v2Containers/CreativesContainer/constants.js +2 -0
  76. package/v2Containers/CreativesContainer/index.js +407 -46
  77. package/v2Containers/CreativesContainer/messages.js +8 -0
  78. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +11 -2
  79. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +38 -50
  80. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +106 -0
  81. package/v2Containers/Email/actions.js +7 -0
  82. package/v2Containers/Email/constants.js +5 -1
  83. package/v2Containers/Email/index.js +222 -27
  84. package/v2Containers/Email/messages.js +32 -0
  85. package/v2Containers/Email/reducer.js +12 -1
  86. package/v2Containers/Email/sagas.js +61 -7
  87. package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +2 -0
  88. package/v2Containers/Email/tests/sagas.test.js +320 -29
  89. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +1321 -0
  90. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +210 -15
  91. package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +40 -74
  92. package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +1749 -0
  93. package/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +520 -0
  94. package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +2 -67
  95. package/v2Containers/EmailWrapper/constants.js +2 -0
  96. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +629 -77
  97. package/v2Containers/EmailWrapper/index.js +103 -23
  98. package/v2Containers/EmailWrapper/messages.js +61 -1
  99. package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +643 -0
  100. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +594 -77
  101. package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +376 -0
  102. package/v2Containers/InApp/__tests__/sagas.test.js +363 -0
  103. package/v2Containers/InApp/actions.js +7 -0
  104. package/v2Containers/InApp/constants.js +20 -4
  105. package/v2Containers/InApp/index.js +802 -359
  106. package/v2Containers/InApp/index.scss +4 -3
  107. package/v2Containers/InApp/messages.js +7 -3
  108. package/v2Containers/InApp/reducer.js +21 -3
  109. package/v2Containers/InApp/sagas.js +29 -9
  110. package/v2Containers/InApp/selectors.js +25 -5
  111. package/v2Containers/InApp/tests/index.test.js +154 -50
  112. package/v2Containers/InApp/tests/reducer.test.js +34 -0
  113. package/v2Containers/InApp/tests/sagas.test.js +61 -9
  114. package/v2Containers/InApp/tests/selectors.test.js +612 -0
  115. package/v2Containers/InAppWrapper/components/InAppWrapperView.js +162 -0
  116. package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +267 -0
  117. package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +9 -0
  118. package/v2Containers/InAppWrapper/constants.js +16 -0
  119. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +473 -0
  120. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +198 -0
  121. package/v2Containers/InAppWrapper/index.js +148 -0
  122. package/v2Containers/InAppWrapper/messages.js +49 -0
  123. package/v2Containers/InappAdvance/index.js +1099 -0
  124. package/v2Containers/InappAdvance/index.scss +10 -0
  125. package/v2Containers/InappAdvance/tests/index.test.js +448 -0
  126. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +3 -0
  127. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +2 -0
  128. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +2 -0
  129. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +9 -0
  130. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +12 -0
  131. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4 -0
  132. package/v2Containers/TagList/index.js +62 -19
  133. package/v2Containers/Templates/_templates.scss +60 -1
  134. package/v2Containers/Templates/index.js +89 -4
  135. package/v2Containers/Templates/messages.js +4 -0
  136. package/v2Containers/TemplatesV2/index.js +8 -7
  137. package/v2Containers/WebPush/Create/components/ButtonsLinksSection.test.js +4 -4
  138. package/v2Containers/WebPush/Create/components/__snapshots__/ButtonsLinksSection.test.js.snap +2 -2
  139. package/v2Containers/WebPush/Create/index.js +104 -12
  140. package/v2Containers/WebPush/Create/preview/WebPushPreview.js +6 -1
  141. package/v2Containers/WebPush/Create/preview/tests/WebPushPreview.test.js +384 -0
  142. package/v2Containers/WebPush/Create/utils/payloadBuilder.js +4 -2
  143. package/v2Containers/WebPush/Create/utils/payloadBuilder.test.js +13 -7
  144. package/v2Containers/WebPush/constants.js +6 -2
  145. package/v2Containers/WebPush/tests/selectors.test.js +117 -0
  146. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +34 -0
  147. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +0 -152
  148. package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +0 -214
Binary file
package/assets/iOS.png CHANGED
Binary file
@@ -45,6 +45,7 @@ export const GIFT_CARDS = 'GIFT_CARDS';
45
45
  export const PROMO_ENGINE = 'PROMO_ENGINE';
46
46
  export const LIQUID_SUPPORT = 'ENABLE_LIQUID_SUPPORT';
47
47
  export const ENABLE_NEW_MPUSH = 'ENABLE_NEW_MPUSH';
48
+ export const SUPPORT_CK_EDITOR = 'SUPPORT_CK_EDITOR';
48
49
  export const CUSTOM_TAG = 'CustomTagMessage';
49
50
  export const CUSTOMER_EXTENDED_FIELD = 'Customer extended fields';
50
51
  export const EXTENDED_TAG = 'ExtendedTagMessage';
@@ -169,7 +170,7 @@ export const JAPANESE_HIDE_DATE_TAGS = [
169
170
  "dd.mm.yy",
170
171
  "dd Mon",
171
172
  "dd/m/yyyy",
172
- ];
173
+ ];
173
174
 
174
175
  export const LIQUID_SUPPORTED_CHANNELS = [EMAIL, SMS, MOBILE_PUSH, INAPP];
175
176
 
package/initialReducer.js CHANGED
@@ -15,6 +15,7 @@ import galleryReducer from './v2Containers/Assets/Gallery/reducer';
15
15
  import CapCollapsibleLeftNavigationReducer from '@capillarytech/cap-ui-library/CapCollapsibleLeftNavigation/reducer';
16
16
  import { AIRA_REDUCER_DOMAIN, askAiraReducer } from '@capillarytech/cap-ui-library/CapAskAira';
17
17
  import previewAndTestReducer from './v2Components/TestAndPreviewSlidebox/reducer';
18
+ import inAppReducer from './v2Containers/InApp/reducer';
18
19
 
19
20
  export const initialReducer = {
20
21
  language: languageProviderReducer,
@@ -33,4 +34,5 @@ export const initialReducer = {
33
34
  gallery: galleryReducer,
34
35
  navigationConfig: CapCollapsibleLeftNavigationReducer,
35
36
  previewAndTest: previewAndTestReducer,
37
+ inApp: inAppReducer,
36
38
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "8.0.248",
4
+ "version": "8.0.250-alpha.0",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
package/services/api.js CHANGED
@@ -470,6 +470,11 @@ export const getCmsTemplateSettingsV2 = (cmsType, projectId, cmsMode, langId, is
470
470
  return API.get(url);
471
471
  };
472
472
 
473
+ export const getCmsAccounts = (cmsType) => {
474
+ const url = `${API_ENDPOINT}/cms/accounts?type=${cmsType}`;
475
+ return API.get(url);
476
+ };
477
+
473
478
  export const getCmsTemplateData = (cmsType, projectId, langId) => {
474
479
  const url = `${API_ENDPOINT}/cms/getContent?type=${cmsType}&projectId=${projectId}&langId=${langId}`;
475
480
  return API.get(url);
@@ -725,4 +730,9 @@ export const getAssetStatus = (type, assetId) => {
725
730
  return request(url, getAPICallObject('GET'));
726
731
  };
727
732
 
733
+ export const getBeePopupBuilderToken = () => {
734
+ const url = `${API_ENDPOINT}/common/getInappTokenData`;
735
+ return request(url, getAPICallObject('GET'));
736
+ };
737
+
728
738
  export {request, getAPICallObject};
@@ -26,6 +26,7 @@ import {
26
26
  updateMetaConfig,
27
27
  getMediaDetails,
28
28
  getAssetStatus,
29
+ getBeePopupBuilderToken,
29
30
  } from '../api';
30
31
  import { mockData } from './mockData';
31
32
  import getSchema from '../getSchema';
@@ -973,3 +974,20 @@ describe('getAssetStatus', () => {
973
974
  expect(callArgs[0]).toContain('/assets/video/asset-456/status');
974
975
  });
975
976
  });
977
+
978
+ describe('getBeePopupBuilderToken', () => {
979
+ it('should return correct response', async () => {
980
+ global.fetch.mockReturnValue(Promise.resolve({
981
+ status: 200,
982
+ json: () => Promise.resolve({
983
+ status: 200,
984
+ response: 'test',
985
+ }),
986
+ }));
987
+ const result = await getBeePopupBuilderToken();
988
+ expect(result).toEqual({
989
+ status: 200,
990
+ response: 'test',
991
+ });
992
+ });
993
+ });
package/utils/common.js CHANGED
@@ -23,6 +23,7 @@ import {
23
23
  ENABLE_WECHAT,
24
24
  ENABLE_WEBPUSH,
25
25
  LIQUID_SUPPORT,
26
+ SUPPORT_CK_EDITOR,
26
27
  ENABLE_NEW_MPUSH
27
28
  } from '../constants/unified';
28
29
  import { apiMessageFormatHandler } from './commonUtils';
@@ -96,6 +97,10 @@ export const hasLiquidSupportFeature = Auth.hasFeatureAccess.bind(
96
97
  LIQUID_SUPPORT,
97
98
  );
98
99
 
100
+ export const hasSupportCKEditor = Auth.hasFeatureAccess.bind(
101
+ null,
102
+ SUPPORT_CK_EDITOR,
103
+ );
99
104
 
100
105
  export const hasGiftVoucherFeature = Auth.hasFeatureAccess.bind(
101
106
  null,
@@ -173,20 +173,30 @@ export const validateLiquidTemplateContent = async (
173
173
  // Handle API errors or empty content
174
174
  if (result?.errors?.length > 0 || !validString || isError) {
175
175
  let standardErrors = [];
176
+ let liquidErrors = [];
177
+
178
+ // Empty content errors are NOT from liquid endpoints, so they go to standardErrors
176
179
  if (!validString) {
177
180
  standardErrors = [emptyBodyError];
178
181
  }
179
- let liquidErrors;
180
- if (result && Array.isArray(result?.errors)) {
181
- liquidErrors = result?.errors?.map((error) => {
182
+
183
+ // IMPORTANT: Errors from extractTags and liquidValidation endpoints should ALWAYS be categorized as liquidErrors
184
+ // These endpoints are: /extractTags and /ask-aira-service/creatives_ai/liquidValidation
185
+ // Only errors from these endpoints should appear in Liquid Issues tab
186
+ if (result && Array.isArray(result?.errors) && result.errors.length > 0) {
187
+ // Errors from extractTags or liquidValidation endpoints
188
+ liquidErrors = result.errors.map((error) => {
182
189
  const message = typeof error?.message === "string"
183
190
  ? error.message
184
191
  : somethingWrongMsg;
185
192
  return message;
186
193
  });
187
- } else {
194
+ } else if (isError) {
195
+ // If isError is true, it means the API call to extractTags/liquidValidation failed
196
+ // This is also a liquid endpoint error, so categorize as liquidErrors
188
197
  liquidErrors = [somethingWrongMsg];
189
198
  }
199
+
190
200
  onError({
191
201
  standardErrors,
192
202
  liquidErrors,
@@ -398,7 +408,20 @@ export const validateMobilePushContent = async (formData, options) => {
398
408
  // Helper function to extract content for a platform
399
409
  export const extractContent = (platformData) => {
400
410
  if (!platformData) return '';
401
- const { title, message, ctas } = platformData;
411
+ const { title, message, ctas, isBEEeditor, beeHtml } = platformData;
412
+
413
+ // For BEE editor, extract content from beeHtml
414
+ if (isBEEeditor && beeHtml) {
415
+ // beeHtml can be an object with value property or a string
416
+ const beeHtmlContent = typeof beeHtml === 'string' ? beeHtml : (beeHtml?.value || '');
417
+ return [
418
+ title,
419
+ beeHtmlContent,
420
+ ...((ctas?.map((cta) => cta?.text || cta?.actionLink)) || []),
421
+ ].filter(Boolean).join(' ');
422
+ }
423
+
424
+ // For regular content
402
425
  return [
403
426
  title,
404
427
  message,
@@ -1376,4 +1376,228 @@ describe("validateCarouselCards", () => {
1376
1376
  expect(result.isValid).toBe(true);
1377
1377
  });
1378
1378
  });
1379
+
1380
+ describe('extractContent BEE Editor Logic (L404-L412)', () => {
1381
+ it('extracts content from beeHtml as string', () => {
1382
+ const platformData = {
1383
+ title: 'Test Title',
1384
+ isBEEeditor: true,
1385
+ beeHtml: '<p>BEE HTML Content</p>',
1386
+ ctas: [
1387
+ { text: 'Click Here', actionLink: 'https://example.com' },
1388
+ ],
1389
+ };
1390
+
1391
+ const result = extractContent(platformData);
1392
+
1393
+ expect(result).toContain('Test Title');
1394
+ expect(result).toContain('<p>BEE HTML Content</p>');
1395
+ expect(result).toContain('Click Here');
1396
+ });
1397
+
1398
+ it('extracts content from beeHtml as object with value property', () => {
1399
+ const platformData = {
1400
+ title: 'Test Title',
1401
+ isBEEeditor: true,
1402
+ beeHtml: { value: '<p>BEE HTML from Object</p>' },
1403
+ ctas: [
1404
+ { text: 'Button Text' },
1405
+ ],
1406
+ };
1407
+
1408
+ const result = extractContent(platformData);
1409
+
1410
+ expect(result).toContain('Test Title');
1411
+ expect(result).toContain('<p>BEE HTML from Object</p>');
1412
+ expect(result).toContain('Button Text');
1413
+ });
1414
+
1415
+ it('handles beeHtml as object without value property', () => {
1416
+ const platformData = {
1417
+ title: 'Test Title',
1418
+ isBEEeditor: true,
1419
+ beeHtml: { someOtherProperty: 'data' },
1420
+ ctas: [],
1421
+ };
1422
+
1423
+ const result = extractContent(platformData);
1424
+
1425
+ // Should extract title and empty beeHtml (since value is undefined)
1426
+ expect(result).toContain('Test Title');
1427
+ expect(result).not.toContain('someOtherProperty');
1428
+ });
1429
+
1430
+ it('extracts ctas with text property', () => {
1431
+ const platformData = {
1432
+ title: 'Title',
1433
+ isBEEeditor: true,
1434
+ beeHtml: '<p>Content</p>',
1435
+ ctas: [
1436
+ { text: 'CTA Text 1' },
1437
+ { text: 'CTA Text 2' },
1438
+ ],
1439
+ };
1440
+
1441
+ const result = extractContent(platformData);
1442
+
1443
+ expect(result).toContain('CTA Text 1');
1444
+ expect(result).toContain('CTA Text 2');
1445
+ });
1446
+
1447
+ it('extracts ctas with actionLink when text is missing', () => {
1448
+ const platformData = {
1449
+ title: 'Title',
1450
+ isBEEeditor: true,
1451
+ beeHtml: '<p>Content</p>',
1452
+ ctas: [
1453
+ { actionLink: 'https://link1.com' },
1454
+ { actionLink: 'https://link2.com' },
1455
+ ],
1456
+ };
1457
+
1458
+ const result = extractContent(platformData);
1459
+
1460
+ expect(result).toContain('https://link1.com');
1461
+ expect(result).toContain('https://link2.com');
1462
+ });
1463
+
1464
+ it('filters out falsy values with filter(Boolean)', () => {
1465
+ const platformData = {
1466
+ title: '',
1467
+ isBEEeditor: true,
1468
+ beeHtml: null,
1469
+ ctas: [
1470
+ { text: null, actionLink: null },
1471
+ { text: 'Valid Text' },
1472
+ ],
1473
+ };
1474
+
1475
+ const result = extractContent(platformData);
1476
+
1477
+ // Should only contain 'Valid Text' after filtering
1478
+ expect(result).toBe('Valid Text');
1479
+ });
1480
+
1481
+ it('handles empty ctas array', () => {
1482
+ const platformData = {
1483
+ title: 'Title Only',
1484
+ isBEEeditor: true,
1485
+ beeHtml: '<p>BEE Content</p>',
1486
+ ctas: [],
1487
+ };
1488
+
1489
+ const result = extractContent(platformData);
1490
+
1491
+ expect(result).toContain('Title Only');
1492
+ expect(result).toContain('<p>BEE Content</p>');
1493
+ });
1494
+
1495
+ it('handles undefined ctas', () => {
1496
+ const platformData = {
1497
+ title: 'Title',
1498
+ isBEEeditor: true,
1499
+ beeHtml: '<p>Content</p>',
1500
+ ctas: undefined,
1501
+ };
1502
+
1503
+ const result = extractContent(platformData);
1504
+
1505
+ expect(result).toContain('Title');
1506
+ expect(result).toContain('<p>Content</p>');
1507
+ });
1508
+
1509
+ it('joins all content with spaces', () => {
1510
+ const platformData = {
1511
+ title: 'Title',
1512
+ isBEEeditor: true,
1513
+ beeHtml: 'HTML',
1514
+ ctas: [
1515
+ { text: 'CTA1' },
1516
+ { text: 'CTA2' },
1517
+ ],
1518
+ };
1519
+
1520
+ const result = extractContent(platformData);
1521
+
1522
+ expect(result).toBe('Title HTML CTA1 CTA2');
1523
+ });
1524
+
1525
+ it('falls back to regular content when not BEE editor', () => {
1526
+ const platformData = {
1527
+ title: 'Title',
1528
+ message: 'Message',
1529
+ isBEEeditor: false,
1530
+ beeHtml: '<p>Should be ignored</p>',
1531
+ ctas: [
1532
+ { text: 'CTA' },
1533
+ ],
1534
+ };
1535
+
1536
+ const result = extractContent(platformData);
1537
+
1538
+ expect(result).toContain('Title');
1539
+ expect(result).toContain('Message');
1540
+ expect(result).toContain('CTA');
1541
+ expect(result).not.toContain('<p>Should be ignored</p>');
1542
+ });
1543
+
1544
+ it('handles null beeHtml', () => {
1545
+ const platformData = {
1546
+ title: 'Title',
1547
+ isBEEeditor: true,
1548
+ beeHtml: null,
1549
+ ctas: [{ text: 'CTA' }],
1550
+ };
1551
+
1552
+ const result = extractContent(platformData);
1553
+
1554
+ expect(result).toContain('Title');
1555
+ expect(result).toContain('CTA');
1556
+ });
1557
+
1558
+ it('handles undefined beeHtml', () => {
1559
+ const platformData = {
1560
+ title: 'Title',
1561
+ isBEEeditor: true,
1562
+ beeHtml: undefined,
1563
+ ctas: [],
1564
+ };
1565
+
1566
+ const result = extractContent(platformData);
1567
+
1568
+ expect(result).toBe('Title');
1569
+ });
1570
+
1571
+ it('handles complex ctas with both text and actionLink', () => {
1572
+ const platformData = {
1573
+ title: 'Title',
1574
+ isBEEeditor: true,
1575
+ beeHtml: 'Content',
1576
+ ctas: [
1577
+ { text: 'CTA Text', actionLink: 'https://example.com' },
1578
+ ],
1579
+ };
1580
+
1581
+ const result = extractContent(platformData);
1582
+
1583
+ // Should prefer text over actionLink
1584
+ expect(result).toContain('CTA Text');
1585
+ expect(result).toContain('Title');
1586
+ expect(result).toContain('Content');
1587
+ });
1588
+
1589
+ it('handles empty string beeHtml', () => {
1590
+ const platformData = {
1591
+ title: 'Title',
1592
+ isBEEeditor: true,
1593
+ beeHtml: '',
1594
+ ctas: [{ text: 'CTA' }],
1595
+ };
1596
+
1597
+ const result = extractContent(platformData);
1598
+
1599
+ expect(result).toBe('Title CTA');
1600
+ });
1601
+ });
1379
1602
  });
1603
+