@capillarytech/creatives-library 8.0.330-alpha.0 → 8.0.330

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 (122) hide show
  1. package/constants/unified.js +0 -18
  2. package/package.json +1 -1
  3. package/services/api.js +0 -17
  4. package/services/tests/api.test.js +0 -85
  5. package/utils/commonUtils.js +0 -28
  6. package/utils/tests/commonUtil.test.js +0 -169
  7. package/v2Components/CapTagList/index.js +0 -10
  8. package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +49 -70
  9. package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +2 -8
  10. package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +21 -207
  11. package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +0 -16
  12. package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +10 -85
  13. package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +0 -30
  14. package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +11 -79
  15. package/v2Components/CommonTestAndPreview/SendTestMessage.js +53 -87
  16. package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +1 -20
  17. package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +4 -133
  18. package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +34 -145
  19. package/v2Components/CommonTestAndPreview/actions.js +0 -10
  20. package/v2Components/CommonTestAndPreview/constants.js +1 -53
  21. package/v2Components/CommonTestAndPreview/index.js +168 -998
  22. package/v2Components/CommonTestAndPreview/messages.js +3 -147
  23. package/v2Components/CommonTestAndPreview/reducer.js +0 -10
  24. package/v2Components/CommonTestAndPreview/sagas.js +6 -15
  25. package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +286 -328
  26. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +65 -231
  27. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +5 -118
  28. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +0 -341
  29. package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +24 -65
  30. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +1 -199
  31. package/v2Components/CommonTestAndPreview/tests/constants.test.js +1 -31
  32. package/v2Components/CommonTestAndPreview/tests/index.test.js +4 -168
  33. package/v2Components/CommonTestAndPreview/tests/reducer.test.js +0 -71
  34. package/v2Components/CommonTestAndPreview/tests/sagas.test.js +2 -2
  35. package/v2Components/CommonTestAndPreview/tests/selectors.test.js +0 -17
  36. package/v2Components/FormBuilder/index.js +1 -7
  37. package/v2Components/TestAndPreviewSlidebox/index.js +1 -13
  38. package/v2Components/TestAndPreviewSlidebox/sagas.js +4 -11
  39. package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +1 -3
  40. package/v2Containers/CreativesContainer/SlideBoxContent.js +4 -36
  41. package/v2Containers/CreativesContainer/SlideBoxFooter.js +1 -10
  42. package/v2Containers/CreativesContainer/SlideBoxHeader.js +4 -29
  43. package/v2Containers/CreativesContainer/constants.js +0 -9
  44. package/v2Containers/CreativesContainer/index.js +93 -292
  45. package/v2Containers/CreativesContainer/index.scss +1 -51
  46. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +34 -78
  47. package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +16 -79
  48. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -8
  49. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +98 -357
  50. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +10 -20
  51. package/v2Containers/CreativesContainer/tests/index.test.js +9 -71
  52. package/v2Containers/Rcs/constants.js +3 -40
  53. package/v2Containers/Rcs/index.js +895 -1145
  54. package/v2Containers/Rcs/index.scss +6 -85
  55. package/v2Containers/Rcs/messages.js +2 -12
  56. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +2236 -41719
  57. package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +5 -0
  58. package/v2Containers/Rcs/tests/index.test.js +38 -41
  59. package/v2Containers/Rcs/tests/mockData.js +0 -38
  60. package/v2Containers/Rcs/tests/utils.test.js +1 -435
  61. package/v2Containers/Rcs/utils.js +10 -405
  62. package/v2Containers/Sms/Create/index.js +38 -100
  63. package/v2Containers/SmsTrai/Create/index.js +4 -9
  64. package/v2Containers/SmsTrai/Edit/constants.js +0 -2
  65. package/v2Containers/SmsTrai/Edit/index.js +128 -636
  66. package/v2Containers/SmsTrai/Edit/messages.js +4 -14
  67. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +2604 -4590
  68. package/v2Containers/SmsWrapper/index.js +8 -37
  69. package/v2Containers/TagList/index.js +0 -6
  70. package/v2Containers/Templates/_templates.scss +2 -63
  71. package/v2Containers/Templates/actions.js +0 -11
  72. package/v2Containers/Templates/constants.js +0 -2
  73. package/v2Containers/Templates/index.js +40 -90
  74. package/v2Containers/Templates/sagas.js +12 -57
  75. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1079 -1043
  76. package/v2Containers/Templates/tests/sagas.test.js +123 -193
  77. package/v2Containers/TemplatesV2/TemplatesV2.style.js +1 -72
  78. package/v2Containers/TemplatesV2/index.js +23 -86
  79. package/v2Containers/Whatsapp/index.js +20 -3
  80. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +4872 -5790
  81. package/utils/templateVarUtils.js +0 -201
  82. package/utils/tests/templateVarUtils.test.js +0 -204
  83. package/v2Components/CommonTestAndPreview/AddTestCustomer.js +0 -42
  84. package/v2Components/CommonTestAndPreview/CustomerCreationModal.js +0 -155
  85. package/v2Components/CommonTestAndPreview/ExistingCustomerModal.js +0 -93
  86. package/v2Components/CommonTestAndPreview/previewApiUtils.js +0 -59
  87. package/v2Components/CommonTestAndPreview/tests/AddTestCustomer.test.js +0 -66
  88. package/v2Components/CommonTestAndPreview/tests/CommonTestAndPreview.addTestCustomer.test.js +0 -648
  89. package/v2Components/CommonTestAndPreview/tests/CustomerCreationModal.test.js +0 -174
  90. package/v2Components/CommonTestAndPreview/tests/ExistingCustomerModal.test.js +0 -114
  91. package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +0 -67
  92. package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +0 -87
  93. package/v2Components/SmsFallback/constants.js +0 -73
  94. package/v2Components/SmsFallback/index.js +0 -955
  95. package/v2Components/SmsFallback/index.scss +0 -265
  96. package/v2Components/SmsFallback/messages.js +0 -78
  97. package/v2Components/SmsFallback/smsFallbackUtils.js +0 -118
  98. package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +0 -50
  99. package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +0 -147
  100. package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +0 -304
  101. package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +0 -197
  102. package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +0 -277
  103. package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +0 -422
  104. package/v2Components/SmsFallback/useLocalTemplateList.js +0 -92
  105. package/v2Components/VarSegmentMessageEditor/constants.js +0 -2
  106. package/v2Components/VarSegmentMessageEditor/index.js +0 -125
  107. package/v2Components/VarSegmentMessageEditor/index.scss +0 -46
  108. package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +0 -43
  109. package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +0 -67
  110. package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +0 -90
  111. package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +0 -258
  112. package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +0 -125
  113. package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +0 -225
  114. package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +0 -318
  115. package/v2Containers/Sms/smsFormDataHelpers.js +0 -67
  116. package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +0 -253
  117. package/v2Containers/SmsTrai/Edit/index.scss +0 -121
  118. package/v2Containers/Templates/TemplatesActionBar.js +0 -101
  119. package/v2Containers/Templates/tests/TemplatesActionBar.test.js +0 -120
  120. package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +0 -180
  121. package/v2Containers/Templates/utils/smsTemplatesListApi.js +0 -79
  122. package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +0 -131
@@ -9,16 +9,7 @@ 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 {
13
- CHANNELS,
14
- DESKTOP,
15
- TABLET,
16
- MOBILE,
17
- ANDROID,
18
- IOS,
19
- PREVIEW_TAB_RCS,
20
- PREVIEW_TAB_SMS_FALLBACK,
21
- } from '../../constants';
12
+ import { CHANNELS, DESKTOP, TABLET, MOBILE, ANDROID, IOS } from '../../constants';
22
13
  import messages from '../../messages';
23
14
 
24
15
  // Convert messages object to format expected by IntlProvider
@@ -556,195 +547,6 @@ describe('UnifiedPreview', () => {
556
547
 
557
548
  expect(screen.getByTestId('rcs-sender-id')).toHaveTextContent('RCS_SENDER');
558
549
  });
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
- });
748
550
  });
749
551
 
750
552
  describe('Channel Routing - INAPP', () => {
@@ -54,13 +54,8 @@ import {
54
54
  // API Channel Constants
55
55
  API_CHANNEL_PUSH,
56
56
  // Identifier Type Constants
57
- IDENTIFIER_TYPE_EMAIL,
58
57
  IDENTIFIER_TYPE_MOBILE,
59
- IDENTIFIER_TYPE_PHONE,
60
- INPUT_HAS_ERROR_CLASS,
61
- // Validation Regex
62
- EMAIL_REGEX,
63
- PHONE_REGEX,
58
+ IDENTIFIER_TYPE_EMAIL,
64
59
  // Channel Name Constants
65
60
  CHANNEL_NAME_INAPP,
66
61
  // Channel Mapping Constants
@@ -211,31 +206,6 @@ describe('CommonTestAndPreview Constants', () => {
211
206
  });
212
207
  });
213
208
 
214
- describe('Identifier Type Constants', () => {
215
- it('should export identifier type constants', () => {
216
- expect(IDENTIFIER_TYPE_EMAIL).toBe('email');
217
- expect(IDENTIFIER_TYPE_MOBILE).toBe('mobile');
218
- expect(IDENTIFIER_TYPE_PHONE).toBe('phone');
219
- });
220
- });
221
-
222
- describe('Validation Regex', () => {
223
- it('should export EMAIL_REGEX that validates email format', () => {
224
- expect(EMAIL_REGEX.test('user@example.com')).toBe(true);
225
- expect(EMAIL_REGEX.test('invalid')).toBe(false);
226
- });
227
- it('should export PHONE_REGEX that validates phone format', () => {
228
- expect(PHONE_REGEX.test('9123456789')).toBe(true);
229
- expect(PHONE_REGEX.test('123')).toBe(false);
230
- });
231
- });
232
-
233
- describe('Input has error class', () => {
234
- it('should export INPUT_HAS_ERROR_CLASS', () => {
235
- expect(INPUT_HAS_ERROR_CLASS).toBe(' has-input-error');
236
- });
237
- });
238
-
239
209
  describe('Channel Name Constants', () => {
240
210
  it('should export channel name constants', () => {
241
211
  expect(CHANNEL_NAME_INAPP).toBe('INAPP');
@@ -30,28 +30,23 @@ jest.mock('@capillarytech/cap-ui-library/CapNotification', () => ({
30
30
  }));
31
31
 
32
32
  // Mock child components - must use React.createElement to avoid hoisting issues
33
- let lastLeftPanelContentProps = null;
34
33
  jest.mock('../LeftPanelContent', () => {
35
34
  // eslint-disable-next-line global-require, import/no-extraneous-dependencies
36
35
  const ReactLib = require('react');
37
36
  return {
38
37
  __esModule: true,
39
- default: function MockLeftPanelContent(props) {
40
- lastLeftPanelContentProps = props;
41
- const editorEl = props.renderCustomValuesEditor ? props.renderCustomValuesEditor() : null;
42
- return ReactLib.createElement('div', { 'data-testid': 'left-panel' }, 'Left Panel', editorEl);
38
+ default: function MockLeftPanelContent() {
39
+ return ReactLib.createElement('div', { 'data-testid': 'left-panel' }, 'Left Panel');
43
40
  },
44
41
  };
45
42
  });
46
43
 
47
- let lastCustomValuesEditorProps = null;
48
44
  jest.mock('../CustomValuesEditor', () => {
49
45
  // eslint-disable-next-line global-require, import/no-extraneous-dependencies
50
46
  const ReactLib = require('react');
51
47
  return {
52
48
  __esModule: true,
53
- default: function MockCustomValuesEditor(props) {
54
- lastCustomValuesEditorProps = props;
49
+ default: function MockCustomValuesEditor() {
55
50
  return ReactLib.createElement('div', { 'data-testid': 'custom-values-editor' }, 'Custom Values Editor');
56
51
  },
57
52
  };
@@ -86,12 +81,6 @@ jest.mock('../../../utils/cdnTransformation', () => ({
86
81
  getCdnUrl: jest.fn(({ url }) => `cdn_${url}`),
87
82
  }));
88
83
 
89
- // Mock services/api for add test customer flow
90
- jest.mock('../../../services/api', () => ({
91
- getMembersLookup: jest.fn(),
92
- createTestCustomer: jest.fn(),
93
- }));
94
-
95
84
  // Mock messages - using actual message IDs from messages.js
96
85
  const mockMessages = {
97
86
  'app.v2Components.TestAndPreviewSlidebox.testAndPreviewHeader': { defaultMessage: 'Preview and Test' },
@@ -137,7 +126,6 @@ describe('CommonTestAndPreview', () => {
137
126
  clearPreviewErrors: jest.fn(),
138
127
  getSenderDetailsRequested: jest.fn(),
139
128
  getWeCrmAccountsRequested: jest.fn(),
140
- addTestCustomer: jest.fn(),
141
129
  };
142
130
 
143
131
  const defaultProps = {
@@ -196,8 +184,6 @@ describe('CommonTestAndPreview', () => {
196
184
  beforeEach(() => {
197
185
  jest.clearAllMocks();
198
186
  lastSendTestMessageProps = null;
199
- lastLeftPanelContentProps = null;
200
- lastCustomValuesEditorProps = null;
201
187
  // Reset all mock function implementations
202
188
  Object.values(mockActions).forEach((mockFn) => {
203
189
  if (jest.isMockFunction(mockFn)) {
@@ -252,24 +238,6 @@ describe('CommonTestAndPreview', () => {
252
238
  });
253
239
  });
254
240
 
255
- it('should call getSenderDetailsRequested for RCS and SMS when channel is RCS', async () => {
256
- render(
257
- <TestWrapper>
258
- <CommonTestAndPreview {...defaultProps} channel={CHANNELS.RCS} />
259
- </TestWrapper>
260
- );
261
- await waitFor(() => {
262
- expect(mockActions.getSenderDetailsRequested).toHaveBeenCalledWith({
263
- channel: CHANNELS.RCS,
264
- orgUnitId: -1,
265
- });
266
- expect(mockActions.getSenderDetailsRequested).toHaveBeenCalledWith({
267
- channel: CHANNELS.SMS,
268
- orgUnitId: -1,
269
- });
270
- });
271
- });
272
-
273
241
  it('should not call getSenderDetailsRequested when channel is INAPP', async () => {
274
242
  render(
275
243
  <TestWrapper>
@@ -328,7 +296,7 @@ describe('CommonTestAndPreview', () => {
328
296
  });
329
297
  expect(lastSendTestMessageProps).toBeDefined();
330
298
  expect(lastSendTestMessageProps.deliverySettings).toBeDefined();
331
- expect(lastSendTestMessageProps.senderDetailsByChannel).toEqual(senderDetailsByChannel);
299
+ expect(lastSendTestMessageProps.senderDetailsOptions).toEqual(senderDetailsByChannel[CHANNELS.SMS]);
332
300
  expect(lastSendTestMessageProps.wecrmAccounts).toEqual([]);
333
301
  expect(typeof lastSendTestMessageProps.onSaveDeliverySettings).toBe('function');
334
302
  expect(lastSendTestMessageProps.isLoadingSenderDetails).toBe(false);
@@ -1610,35 +1578,6 @@ describe('CommonTestAndPreview', () => {
1610
1578
 
1611
1579
  expect(screen.getByTestId('send-test-message')).toBeTruthy();
1612
1580
  });
1613
-
1614
- it('should show error notification when sendTestMessageRequested callback receives false', async () => {
1615
- const CapNotification = require('@capillarytech/cap-ui-library/CapNotification');
1616
- mockActions.createMessageMetaRequested.mockImplementation((payload, metaId, cb) => {
1617
- if (cb) cb({ entity: 'meta-123' });
1618
- });
1619
- mockActions.sendTestMessageRequested.mockImplementation((payload, cb) => {
1620
- if (cb) cb(false);
1621
- });
1622
- const props = {
1623
- ...defaultProps,
1624
- selectedTestEntities: ['user-1'],
1625
- testGroups: [],
1626
- };
1627
-
1628
- render(
1629
- <TestWrapper>
1630
- <CommonTestAndPreview {...props} />
1631
- </TestWrapper>
1632
- );
1633
-
1634
- expect(lastSendTestMessageProps).toBeTruthy();
1635
- expect(lastSendTestMessageProps.handleSendTestMessage).toBeDefined();
1636
- lastSendTestMessageProps.handleSendTestMessage();
1637
-
1638
- await waitFor(() => {
1639
- expect(CapNotification.error).toHaveBeenCalled();
1640
- });
1641
- });
1642
1581
  });
1643
1582
 
1644
1583
  describe('Content Extraction', () => {
@@ -3306,107 +3245,4 @@ describe('CommonTestAndPreview', () => {
3306
3245
  });
3307
3246
  });
3308
3247
  });
3309
-
3310
- describe('SMS DLT and mustache tag discrimination (smsTemplateHasMustacheTags / buildSyntheticSmsMustacheTags)', () => {
3311
- it('should return no tags for SMS content that contains only DLT {#var#} tokens', async () => {
3312
- render(
3313
- <TestWrapper>
3314
- <CommonTestAndPreview
3315
- {...defaultProps}
3316
- channel={CHANNELS.SMS}
3317
- formData={{ 0: { 'sms-editor': 'Order {#orderId#} is confirmed' } }}
3318
- extractedTags={[]}
3319
- />
3320
- </TestWrapper>
3321
- );
3322
-
3323
- await waitFor(() => expect(lastLeftPanelContentProps).not.toBeNull());
3324
-
3325
- // smsTemplateHasMustacheTags returns false for DLT-only → extractedTags is []
3326
- expect(lastLeftPanelContentProps.extractedTags).toEqual([]);
3327
- });
3328
-
3329
- it('should build synthetic tags from {{mustache}} tokens, excluding DLT {#var#} tokens', async () => {
3330
- render(
3331
- <TestWrapper>
3332
- <CommonTestAndPreview
3333
- {...defaultProps}
3334
- channel={CHANNELS.SMS}
3335
- formData={{ 0: { 'sms-editor': 'Hi {{name}}, order {#orderId#} shipped' } }}
3336
- extractedTags={[]}
3337
- />
3338
- </TestWrapper>
3339
- );
3340
-
3341
- await waitFor(() => expect(lastLeftPanelContentProps).not.toBeNull());
3342
-
3343
- const tags = lastLeftPanelContentProps.extractedTags;
3344
- // Only {{name}} should become a tag — {#orderId#} must be excluded
3345
- expect(tags).toHaveLength(1);
3346
- expect(tags[0].name).toBe('name');
3347
- });
3348
-
3349
- it('should use API-extracted tags when present instead of building synthetic ones', async () => {
3350
- const apiTags = [{ name: 'firstName', metaData: { userDriven: true }, children: [] }];
3351
- render(
3352
- <TestWrapper>
3353
- <CommonTestAndPreview
3354
- {...defaultProps}
3355
- channel={CHANNELS.SMS}
3356
- formData={{ 0: { 'sms-editor': 'Hi {{firstName}}' } }}
3357
- extractedTags={apiTags}
3358
- />
3359
- </TestWrapper>
3360
- );
3361
-
3362
- await waitFor(() => expect(lastLeftPanelContentProps).not.toBeNull());
3363
-
3364
- // API tags take priority over buildSyntheticSmsMustacheTags
3365
- expect(lastLeftPanelContentProps.extractedTags).toEqual(apiTags);
3366
- });
3367
- });
3368
-
3369
- describe('handleDiscardCustomValues — preview reset', () => {
3370
- it('should call updatePreviewRequested when handleDiscardCustomValues is invoked', async () => {
3371
- render(
3372
- <TestWrapper>
3373
- <CommonTestAndPreview
3374
- {...defaultProps}
3375
- channel={CHANNELS.SMS}
3376
- formData={{ 0: { 'sms-editor': 'Hi {{name}}' } }}
3377
- />
3378
- </TestWrapper>
3379
- );
3380
-
3381
- await waitFor(() => expect(lastCustomValuesEditorProps).not.toBeNull());
3382
-
3383
- lastCustomValuesEditorProps.handleDiscardCustomValues();
3384
-
3385
- expect(mockActions.updatePreviewRequested).toHaveBeenCalledTimes(1);
3386
- });
3387
-
3388
- it('should call updatePreviewRequested with RCS channel when handleDiscardCustomValues is invoked for RCS with fallback', async () => {
3389
- render(
3390
- <TestWrapper>
3391
- <CommonTestAndPreview
3392
- {...defaultProps}
3393
- channel={CHANNELS.RCS}
3394
- smsFallbackContent={{
3395
- templateContent: 'Fallback {{name}}',
3396
- content: 'Fallback {{name}}',
3397
- }}
3398
- formData={{}}
3399
- />
3400
- </TestWrapper>
3401
- );
3402
-
3403
- await waitFor(() => expect(lastCustomValuesEditorProps).not.toBeNull());
3404
-
3405
- lastCustomValuesEditorProps.handleDiscardCustomValues();
3406
-
3407
- // updatePreviewRequested is called; syncSmsFallbackPreview (which hits Api directly) is NOT called
3408
- expect(mockActions.updatePreviewRequested).toHaveBeenCalledTimes(1);
3409
- });
3410
- });
3411
3248
  });
3412
-
@@ -24,7 +24,6 @@ import {
24
24
  GET_TEST_CUSTOMERS_REQUESTED,
25
25
  GET_TEST_CUSTOMERS_SUCCESS,
26
26
  GET_TEST_CUSTOMERS_FAILURE,
27
- ADD_TEST_CUSTOMER,
28
27
  GET_TEST_GROUPS_REQUESTED,
29
28
  GET_TEST_GROUPS_SUCCESS,
30
29
  GET_TEST_GROUPS_FAILURE,
@@ -612,76 +611,6 @@ describe('previewAndTestReducer', () => {
612
611
  });
613
612
  });
614
613
 
615
- describe('ADD_TEST_CUSTOMER', () => {
616
- it('should add new customer to testCustomers list', () => {
617
- const customer = {
618
- userId: 'cust-1',
619
- customerId: 'cust-1',
620
- name: 'John',
621
- email: 'john@example.com',
622
- mobile: '',
623
- };
624
- const action = {
625
- type: ADD_TEST_CUSTOMER,
626
- payload: { customer },
627
- };
628
- const result = previewAndTestReducer(initialState, action);
629
-
630
- const list = result.get('testCustomers');
631
- expect(Array.isArray(list) ? list.length : list.size).toBe(1);
632
- const first = Array.isArray(list) ? list[0] : list.get(0);
633
- const id = first.userId != null ? first.userId : first.get('userId');
634
- const name = first.name != null ? first.name : first.get('name');
635
- expect(id).toBe('cust-1');
636
- expect(name).toBe('John');
637
- });
638
-
639
- it('should not add duplicate customer when userId already in list', () => {
640
- const existing = fromJS([
641
- { userId: 'cust-1', customerId: 'cust-1', name: 'John', email: 'john@example.com', mobile: '' },
642
- ]);
643
- const stateWithCustomer = initialState.set('testCustomers', existing);
644
- const customer = {
645
- userId: 'cust-1',
646
- customerId: 'cust-1',
647
- name: 'John Updated',
648
- email: 'john@example.com',
649
- mobile: '',
650
- };
651
- const action = {
652
- type: ADD_TEST_CUSTOMER,
653
- payload: { customer },
654
- };
655
- const result = previewAndTestReducer(stateWithCustomer, action);
656
-
657
- const list = result.get('testCustomers');
658
- expect(Array.isArray(list) ? list.length : list.size).toBe(1);
659
- const first = Array.isArray(list) ? list[0] : list.get(0);
660
- const name = first.name != null ? first.name : first.get('name');
661
- expect(name).toBe('John');
662
- });
663
-
664
- it('should use customerId when userId is missing', () => {
665
- const customer = {
666
- customerId: 'cust-2',
667
- name: 'Jane',
668
- email: 'jane@example.com',
669
- mobile: '',
670
- };
671
- const action = {
672
- type: ADD_TEST_CUSTOMER,
673
- payload: { customer },
674
- };
675
- const result = previewAndTestReducer(initialState, action);
676
-
677
- const list = result.get('testCustomers');
678
- expect(Array.isArray(list) ? list.length : list.size).toBe(1);
679
- const first = Array.isArray(list) ? list[0] : list.get(0);
680
- const id = first.customerId != null ? first.customerId : first.get('customerId');
681
- expect(id).toBe('cust-2');
682
- });
683
- });
684
-
685
614
  describe('GET_TEST_GROUPS_REQUESTED', () => {
686
615
  it('should set fetching flag and clear error', () => {
687
616
  const action = { type: GET_TEST_GROUPS_REQUESTED };
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import {
8
- call, put, takeLatest, takeEvery, all,
8
+ call, put, takeLatest, all,
9
9
  } from 'redux-saga/effects';
10
10
  import {
11
11
  searchCustomersSaga,
@@ -1333,7 +1333,7 @@ describe('CommonTestAndPreview Sagas', () => {
1333
1333
  it('should watch for GET_SENDER_DETAILS_REQUESTED', () => {
1334
1334
  const generator = watchGetSenderDetails();
1335
1335
  expect(generator.next().value).toEqual(
1336
- takeEvery('app/CommonTestAndPreview/GET_SENDER_DETAILS_REQUESTED', getSenderDetailsSaga)
1336
+ takeLatest('app/CommonTestAndPreview/GET_SENDER_DETAILS_REQUESTED', getSenderDetailsSaga)
1337
1337
  );
1338
1338
  expect(generator.next().done).toBe(true);
1339
1339
  });
@@ -431,23 +431,6 @@ describe('CommonTestAndPreview Selectors', () => {
431
431
  // Should handle null gracefully - returns null when prefilledValues is null
432
432
  expect(result).toBeNull();
433
433
  });
434
-
435
- it('should return undefined when commonTestAndPreview substate is missing', () => {
436
- const selector = makeSelectPrefilledValues();
437
- const result = selector(fromJS({}));
438
-
439
- expect(result).toBeUndefined();
440
- });
441
-
442
- it('should return null when prefilledValues is undefined', () => {
443
- const stateWithUndefined = fromJS({
444
- commonTestAndPreview: {},
445
- });
446
- const selector = makeSelectPrefilledValues();
447
- const result = selector(stateWithUndefined);
448
-
449
- expect(result).toBeNull();
450
- });
451
434
  });
452
435
 
453
436
  describe('makeSelectTestMessageResponse', () => {
@@ -3658,9 +3658,6 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
3658
3658
  channel={channel}
3659
3659
  eventContextTags={this.props?.eventContextTags}
3660
3660
  restrictPersonalization={this.props.restrictPersonalization}
3661
- getPopupContainer={this.props.tagListGetPopupContainer}
3662
- popoverOverlayStyle={this.props.tagListPopoverOverlayStyle}
3663
- popoverOverlayClassName={this.props.tagListPopoverOverlayClassName}
3664
3661
  />
3665
3662
  </CapColumn>
3666
3663
  );
@@ -4351,15 +4348,12 @@ FormBuilder.propTypes = {
4351
4348
  type: PropTypes.string.isRequired,
4352
4349
  isEmailLoading: PropTypes.bool.isRequired,
4353
4350
  moduleType: PropTypes.string.isRequired,
4354
- showLiquidErrorInFooter: PropTypes.func.isRequired,
4351
+ showLiquidErrorInFooter: PropTypes.bool.isRequired,
4355
4352
  eventContextTags: PropTypes.array.isRequired,
4356
4353
  forwardedTags: PropTypes.object.isRequired,
4357
4354
  isLoyaltyModule: PropTypes.bool.isRequired,
4358
4355
  isTestAndPreviewMode: PropTypes.bool, // Add new prop type
4359
4356
  restrictPersonalization: PropTypes.bool,
4360
- tagListGetPopupContainer: PropTypes.func,
4361
- tagListPopoverOverlayStyle: PropTypes.object,
4362
- tagListPopoverOverlayClassName: PropTypes.string,
4363
4357
  };
4364
4358
 
4365
4359
  const mapStateToProps = createStructuredSelector({
@@ -18,7 +18,7 @@ import injectReducer from '../../utils/injectReducer';
18
18
  import injectSaga from '../../utils/injectSaga';
19
19
 
20
20
  import CommonTestAndPreview from '../CommonTestAndPreview';
21
- import { CHANNELS, RCS_SMS_FALLBACK_VAR_MAPPED_PROP } from '../CommonTestAndPreview/constants';
21
+ import { CHANNELS } from '../CommonTestAndPreview/constants';
22
22
  import * as commonTestAndPreviewActions from '../CommonTestAndPreview/actions';
23
23
  import { commonTestAndPreviewSaga } from '../CommonTestAndPreview/sagas';
24
24
  import commonTestAndPreviewReducer from '../CommonTestAndPreview/reducer';
@@ -78,16 +78,6 @@ TestAndPreviewSlidebox.propTypes = {
78
78
  content: PropTypes.string,
79
79
  beeInstance: PropTypes.object,
80
80
  currentTab: PropTypes.number,
81
- smsFallbackContent: PropTypes.shape({
82
- templateContent: PropTypes.string,
83
- senderId: PropTypes.string,
84
- templateName: PropTypes.string,
85
- [RCS_SMS_FALLBACK_VAR_MAPPED_PROP]: PropTypes.object,
86
- }),
87
- /** Passed to CommonTestAndPreview for RCS test-meta resolution (slot semantics vs full-mode). */
88
- rcsTestPreviewOptions: PropTypes.shape({
89
- isLibraryMode: PropTypes.bool,
90
- }),
91
81
  // Redux props are passed through
92
82
  actions: PropTypes.object.isRequired,
93
83
  extractedTags: PropTypes.array.isRequired,
@@ -119,12 +109,10 @@ TestAndPreviewSlidebox.defaultProps = {
119
109
  currentTab: 1,
120
110
  messageMetaConfigId: null,
121
111
  prefilledValues: {},
122
- rcsTestPreviewOptions: undefined,
123
112
  senderDetailsByChannel: {},
124
113
  wecrmAccounts: [],
125
114
  isLoadingSenderDetails: false,
126
115
  orgUnitId: -1,
127
- smsFallbackContent: null,
128
116
  };
129
117
 
130
118
  const mapStateToProps = createStructuredSelector({