@capillarytech/creatives-library 8.0.294 → 8.0.296
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.
- package/package.json +1 -1
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +4 -4
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.scss +2 -1
- package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +2 -2
- package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +3 -3
- package/v2Components/CommonTestAndPreview/constants.js +5 -0
- package/v2Components/CommonTestAndPreview/index.js +50 -1
- package/v2Components/CommonTestAndPreview/tests/index.test.js +441 -1
package/package.json
CHANGED
|
@@ -75,7 +75,7 @@ const ModifyDeliverySettings = (props) => {
|
|
|
75
75
|
const next = cloneDeep(prev);
|
|
76
76
|
next[DELIVERY_SETTING_KEY_SOURCE_ACCOUNT_IDENTIFIER] = sourceAccountId;
|
|
77
77
|
const domain = (senderDetailsOptions || []).find(
|
|
78
|
-
(
|
|
78
|
+
(senderDetails) => senderDetails.sourceAccountIdentifier === sourceAccountId,
|
|
79
79
|
);
|
|
80
80
|
const first = domain?.gsmSenders?.[0];
|
|
81
81
|
if (first?.value != null) {
|
|
@@ -193,7 +193,7 @@ const ModifyDeliverySettings = (props) => {
|
|
|
193
193
|
})));
|
|
194
194
|
}
|
|
195
195
|
const domainForAccount = (senderDetailsOptions || []).find(
|
|
196
|
-
(senderDetails) => senderDetails
|
|
196
|
+
(senderDetails) => senderDetails?.sourceAccountIdentifier === selectedAccId,
|
|
197
197
|
);
|
|
198
198
|
return (domainForAccount?.gsmSenders || []).map((gsmSender) => ({
|
|
199
199
|
label: gsmSender.value,
|
|
@@ -379,7 +379,7 @@ const ModifyDeliverySettings = (props) => {
|
|
|
379
379
|
}
|
|
380
380
|
|
|
381
381
|
return (
|
|
382
|
-
<
|
|
382
|
+
<CapRow className="modify-delivery-settings">
|
|
383
383
|
{getChannelFields().map((field, idx) => renderSelectRow({
|
|
384
384
|
...field,
|
|
385
385
|
rowKey: field.titleMessage?.id || `${ROW_KEY_PREFIX}${idx}`,
|
|
@@ -390,7 +390,7 @@ const ModifyDeliverySettings = (props) => {
|
|
|
390
390
|
<FormattedMessage {...messages.done} />
|
|
391
391
|
</CapButton>
|
|
392
392
|
</CapRow>
|
|
393
|
-
</
|
|
393
|
+
</CapRow>
|
|
394
394
|
);
|
|
395
395
|
};
|
|
396
396
|
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
@import '~@capillarytech/cap-ui-library/styles/_variables.scss';
|
|
6
6
|
|
|
7
7
|
.modify-delivery-settings {
|
|
8
|
+
height: 100%;
|
|
8
9
|
&__field-row {
|
|
9
10
|
margin-bottom: $CAP_SPACE_24;
|
|
10
11
|
}
|
|
@@ -17,7 +18,7 @@
|
|
|
17
18
|
width: 22.85rem;
|
|
18
19
|
|
|
19
20
|
&--disabled {
|
|
20
|
-
background-color:
|
|
21
|
+
background-color: $CAP_G08;
|
|
21
22
|
pointer-events: none;
|
|
22
23
|
}
|
|
23
24
|
}
|
|
@@ -163,7 +163,7 @@ const DeliverySettings = (props) => {
|
|
|
163
163
|
const summaryObject = getSummaryObject();
|
|
164
164
|
|
|
165
165
|
return (
|
|
166
|
-
<
|
|
166
|
+
<CapRow className="delivery-settings">
|
|
167
167
|
<CapRow className="delivery-settings__heading-row">
|
|
168
168
|
<CapHeading type={HEADING_TYPE_H10}>
|
|
169
169
|
<FormattedMessage {...messages.deliverySettings} />
|
|
@@ -218,7 +218,7 @@ const DeliverySettings = (props) => {
|
|
|
218
218
|
)}
|
|
219
219
|
/>
|
|
220
220
|
)}
|
|
221
|
-
</
|
|
221
|
+
</CapRow>
|
|
222
222
|
);
|
|
223
223
|
};
|
|
224
224
|
|
package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js
CHANGED
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
* No cross-repo imports; logic aligned with campaigns domain structure.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import
|
|
10
|
+
import get from 'lodash/get';
|
|
11
11
|
import { CHANNELS } from '../../constants';
|
|
12
12
|
|
|
13
13
|
const getSenderOptions = (contactInfo, key) =>
|
|
14
14
|
(contactInfo || [])
|
|
15
|
-
.filter((
|
|
16
|
-
.sort((
|
|
15
|
+
.filter((contactInfoItem) => contactInfoItem.type === key && contactInfoItem.valid)
|
|
16
|
+
.sort((contact) => (contact.default ? -1 : 0));
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Parse raw API response for one channel into { domains: [...] }
|
|
@@ -179,6 +179,11 @@ export const UNSUBSCRIBE_TAG_NAME = 'unsubscribe';
|
|
|
179
179
|
export const IN_APP_CHANNEL_NAME = 'in-app';
|
|
180
180
|
export const MOBILE_PUSH_CHANNEL_NAME = 'mobile push';
|
|
181
181
|
export const CHANNEL = 'channel';
|
|
182
|
+
export const PHONE_NUMBER = 'PHONE_NUMBER';
|
|
183
|
+
export const DYNAMIC_URL = 'DYNAMIC_URL';
|
|
184
|
+
export const IMAGE = 'IMAGE';
|
|
185
|
+
export const VIDEO = 'VIDEO';
|
|
186
|
+
export const URL = 'URL';
|
|
182
187
|
|
|
183
188
|
// Initial Payload Template (for reference)
|
|
184
189
|
export const INITIAL_PAYLOAD = {
|
|
@@ -65,6 +65,11 @@ import {
|
|
|
65
65
|
IN_APP_CHANNEL_NAME,
|
|
66
66
|
MOBILE_PUSH_CHANNEL_NAME,
|
|
67
67
|
CHANNEL,
|
|
68
|
+
PHONE_NUMBER,
|
|
69
|
+
DYNAMIC_URL,
|
|
70
|
+
IMAGE,
|
|
71
|
+
VIDEO,
|
|
72
|
+
URL,
|
|
68
73
|
} from './constants';
|
|
69
74
|
|
|
70
75
|
// Import utilities
|
|
@@ -542,6 +547,50 @@ const CommonTestAndPreview = (props) => {
|
|
|
542
547
|
* Prepare payload for test message sending based on channel
|
|
543
548
|
* Updated to match API structure with ouId, sourceEntityId, module, deliverySettings, etc.
|
|
544
549
|
*/
|
|
550
|
+
|
|
551
|
+
const getCarouselMappedData = (carouselData = []) => carouselData.map((carousel) => {
|
|
552
|
+
const {
|
|
553
|
+
bodyText, imageUrl, videoUrl, videoPreviewImg, buttons, mediaType, cardVarMapped, bodyTemplate,
|
|
554
|
+
} = carousel || {};
|
|
555
|
+
const buttonData = buttons.map((button, index) => {
|
|
556
|
+
const {
|
|
557
|
+
type, text, phone_number, urlType, url,
|
|
558
|
+
} = button || {};
|
|
559
|
+
const buttonObj = {
|
|
560
|
+
type,
|
|
561
|
+
text,
|
|
562
|
+
index,
|
|
563
|
+
};
|
|
564
|
+
if (type === PHONE_NUMBER) {
|
|
565
|
+
buttonObj.phoneNumber = phone_number;
|
|
566
|
+
}
|
|
567
|
+
if (type === URL) {
|
|
568
|
+
buttonObj.url = url;
|
|
569
|
+
if (urlType === DYNAMIC_URL) {
|
|
570
|
+
const dynamicUrlPayload = url?.match(/{{(.*?)}}/g);
|
|
571
|
+
buttonObj.dynamicUrlPayload = dynamicUrlPayload?.length === 1 ? dynamicUrlPayload[0] : '';
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
return buttonObj;
|
|
575
|
+
});
|
|
576
|
+
return {
|
|
577
|
+
body: bodyText,
|
|
578
|
+
cardVarMapped,
|
|
579
|
+
bodyTemplate,
|
|
580
|
+
media: {
|
|
581
|
+
...(mediaType?.toLowerCase() === IMAGE.toLowerCase() && {
|
|
582
|
+
url: imageUrl,
|
|
583
|
+
}),
|
|
584
|
+
...(mediaType?.toLowerCase() === VIDEO.toLowerCase() && {
|
|
585
|
+
url: videoUrl,
|
|
586
|
+
previewUrl: videoPreviewImg,
|
|
587
|
+
}),
|
|
588
|
+
},
|
|
589
|
+
buttons: buttonData,
|
|
590
|
+
mediaType: mediaType?.toUpperCase(),
|
|
591
|
+
};
|
|
592
|
+
});
|
|
593
|
+
|
|
545
594
|
const prepareTestMessagePayload = (channelType, formDataObj, contentStr, customValuesObj, recipientDetails, previewDataObj, deliverySettingsOverride) => {
|
|
546
595
|
// Base payload structure common to all channels
|
|
547
596
|
const basePayload = {
|
|
@@ -760,7 +809,7 @@ const CommonTestAndPreview = (props) => {
|
|
|
760
809
|
|
|
761
810
|
// Add carousel data if mediaType is CAROUSEL
|
|
762
811
|
if (mediaType === MEDIA_TYPE_CAROUSEL && formDataObj?.carouselData) {
|
|
763
|
-
templateConfigs.cards = formDataObj.carouselData;
|
|
812
|
+
templateConfigs.cards = getCarouselMappedData(formDataObj.carouselData);
|
|
764
813
|
templateConfigs.mediaType = formDataObj?.carouselMediaType?.toUpperCase() || MEDIA_TYPE_IMAGE;
|
|
765
814
|
}
|
|
766
815
|
|
|
@@ -10,7 +10,7 @@ import PropTypes from 'prop-types';
|
|
|
10
10
|
import { render, screen, waitFor } from '@testing-library/react';
|
|
11
11
|
import { IntlProvider } from 'react-intl';
|
|
12
12
|
import CommonTestAndPreview from '../index';
|
|
13
|
-
import { CHANNELS } from '../constants';
|
|
13
|
+
import { CHANNELS, MEDIA_TYPE_CAROUSEL } from '../constants';
|
|
14
14
|
|
|
15
15
|
// Mock html-to-text
|
|
16
16
|
jest.mock('html-to-text', () => ({
|
|
@@ -524,6 +524,446 @@ describe('CommonTestAndPreview', () => {
|
|
|
524
524
|
});
|
|
525
525
|
});
|
|
526
526
|
|
|
527
|
+
describe('Carousel payload (getCarouselMappedData) - handleSendTestMessage', () => {
|
|
528
|
+
it('should map empty carouselData to empty cards when mediaType is CAROUSEL', async () => {
|
|
529
|
+
const props = {
|
|
530
|
+
...defaultProps,
|
|
531
|
+
channel: CHANNELS.WHATSAPP,
|
|
532
|
+
formData: {
|
|
533
|
+
templateMsg: 'Message',
|
|
534
|
+
mediaType: MEDIA_TYPE_CAROUSEL,
|
|
535
|
+
carouselData: [],
|
|
536
|
+
},
|
|
537
|
+
};
|
|
538
|
+
render(
|
|
539
|
+
<TestWrapper>
|
|
540
|
+
<CommonTestAndPreview {...props} />
|
|
541
|
+
</TestWrapper>
|
|
542
|
+
);
|
|
543
|
+
await waitFor(() => {
|
|
544
|
+
expect(lastSendTestMessageProps).toBeDefined();
|
|
545
|
+
expect(typeof lastSendTestMessageProps.handleSendTestMessage).toBe('function');
|
|
546
|
+
});
|
|
547
|
+
lastSendTestMessageProps.handleSendTestMessage();
|
|
548
|
+
expect(mockActions.createMessageMetaRequested).toHaveBeenCalled();
|
|
549
|
+
const [payload] = mockActions.createMessageMetaRequested.mock.calls[0];
|
|
550
|
+
expect(payload.whatsappMessageContent.templateConfigs.cards).toEqual([]);
|
|
551
|
+
expect(payload.whatsappMessageContent.templateConfigs.mediaType).toBe('IMAGE');
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
it('should map carousel with IMAGE media and bodyText to cards with media.url', async () => {
|
|
555
|
+
const props = {
|
|
556
|
+
...defaultProps,
|
|
557
|
+
channel: CHANNELS.WHATSAPP,
|
|
558
|
+
formData: {
|
|
559
|
+
templateMsg: 'Message',
|
|
560
|
+
mediaType: MEDIA_TYPE_CAROUSEL,
|
|
561
|
+
carouselMediaType: 'IMAGE',
|
|
562
|
+
carouselData: [
|
|
563
|
+
{
|
|
564
|
+
bodyText: 'Card body',
|
|
565
|
+
imageUrl: 'https://image.example.com/1.jpg',
|
|
566
|
+
mediaType: 'image',
|
|
567
|
+
buttons: [],
|
|
568
|
+
},
|
|
569
|
+
],
|
|
570
|
+
},
|
|
571
|
+
};
|
|
572
|
+
render(
|
|
573
|
+
<TestWrapper>
|
|
574
|
+
<CommonTestAndPreview {...props} />
|
|
575
|
+
</TestWrapper>
|
|
576
|
+
);
|
|
577
|
+
await waitFor(() => {
|
|
578
|
+
expect(lastSendTestMessageProps).toBeDefined();
|
|
579
|
+
});
|
|
580
|
+
lastSendTestMessageProps.handleSendTestMessage();
|
|
581
|
+
const [payload] = mockActions.createMessageMetaRequested.mock.calls[0];
|
|
582
|
+
const cards = payload.whatsappMessageContent.templateConfigs.cards;
|
|
583
|
+
expect(cards).toHaveLength(1);
|
|
584
|
+
expect(cards[0].body).toBe('Card body');
|
|
585
|
+
expect(cards[0].media).toEqual({ url: 'https://image.example.com/1.jpg' });
|
|
586
|
+
expect(cards[0].mediaType).toBe('IMAGE');
|
|
587
|
+
expect(cards[0].buttons).toEqual([]);
|
|
588
|
+
expect(payload.whatsappMessageContent.templateConfigs.mediaType).toBe('IMAGE');
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
it('should map carousel with VIDEO media to cards with url and previewUrl', async () => {
|
|
592
|
+
const props = {
|
|
593
|
+
...defaultProps,
|
|
594
|
+
channel: CHANNELS.WHATSAPP,
|
|
595
|
+
formData: {
|
|
596
|
+
templateMsg: 'Message',
|
|
597
|
+
mediaType: MEDIA_TYPE_CAROUSEL,
|
|
598
|
+
carouselMediaType: 'VIDEO',
|
|
599
|
+
carouselData: [
|
|
600
|
+
{
|
|
601
|
+
bodyText: 'Video card',
|
|
602
|
+
videoUrl: 'https://video.example.com/1.mp4',
|
|
603
|
+
videoPreviewImg: 'https://preview.example.com/1.jpg',
|
|
604
|
+
mediaType: 'video',
|
|
605
|
+
buttons: [],
|
|
606
|
+
},
|
|
607
|
+
],
|
|
608
|
+
},
|
|
609
|
+
};
|
|
610
|
+
render(
|
|
611
|
+
<TestWrapper>
|
|
612
|
+
<CommonTestAndPreview {...props} />
|
|
613
|
+
</TestWrapper>
|
|
614
|
+
);
|
|
615
|
+
await waitFor(() => {
|
|
616
|
+
expect(lastSendTestMessageProps).toBeDefined();
|
|
617
|
+
});
|
|
618
|
+
lastSendTestMessageProps.handleSendTestMessage();
|
|
619
|
+
const [payload] = mockActions.createMessageMetaRequested.mock.calls[0];
|
|
620
|
+
const cards = payload.whatsappMessageContent.templateConfigs.cards;
|
|
621
|
+
expect(cards).toHaveLength(1);
|
|
622
|
+
expect(cards[0].body).toBe('Video card');
|
|
623
|
+
expect(cards[0].media).toEqual({
|
|
624
|
+
url: 'https://video.example.com/1.mp4',
|
|
625
|
+
previewUrl: 'https://preview.example.com/1.jpg',
|
|
626
|
+
});
|
|
627
|
+
expect(cards[0].mediaType).toBe('VIDEO');
|
|
628
|
+
expect(payload.whatsappMessageContent.templateConfigs.mediaType).toBe('VIDEO');
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
it('should map button type PHONE_NUMBER to buttonObj with phoneNumber', async () => {
|
|
632
|
+
const props = {
|
|
633
|
+
...defaultProps,
|
|
634
|
+
channel: CHANNELS.WHATSAPP,
|
|
635
|
+
formData: {
|
|
636
|
+
templateMsg: 'Message',
|
|
637
|
+
mediaType: MEDIA_TYPE_CAROUSEL,
|
|
638
|
+
carouselData: [
|
|
639
|
+
{
|
|
640
|
+
bodyText: 'Card',
|
|
641
|
+
mediaType: 'image',
|
|
642
|
+
imageUrl: 'https://img.url',
|
|
643
|
+
buttons: [
|
|
644
|
+
{ type: 'PHONE_NUMBER', text: 'Call', phone_number: '+1234567890' },
|
|
645
|
+
],
|
|
646
|
+
},
|
|
647
|
+
],
|
|
648
|
+
},
|
|
649
|
+
};
|
|
650
|
+
render(
|
|
651
|
+
<TestWrapper>
|
|
652
|
+
<CommonTestAndPreview {...props} />
|
|
653
|
+
</TestWrapper>
|
|
654
|
+
);
|
|
655
|
+
await waitFor(() => {
|
|
656
|
+
expect(lastSendTestMessageProps).toBeDefined();
|
|
657
|
+
});
|
|
658
|
+
lastSendTestMessageProps.handleSendTestMessage();
|
|
659
|
+
const [payload] = mockActions.createMessageMetaRequested.mock.calls[0];
|
|
660
|
+
const buttons = payload.whatsappMessageContent.templateConfigs.cards[0].buttons;
|
|
661
|
+
expect(buttons).toHaveLength(1);
|
|
662
|
+
expect(buttons[0].type).toBe('PHONE_NUMBER');
|
|
663
|
+
expect(buttons[0].text).toBe('Call');
|
|
664
|
+
expect(buttons[0].index).toBe(0);
|
|
665
|
+
expect(buttons[0].phoneNumber).toBe('+1234567890');
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
it('should map button type URL without DYNAMIC_URL to buttonObj with url only', async () => {
|
|
669
|
+
const props = {
|
|
670
|
+
...defaultProps,
|
|
671
|
+
channel: CHANNELS.WHATSAPP,
|
|
672
|
+
formData: {
|
|
673
|
+
templateMsg: 'Message',
|
|
674
|
+
mediaType: MEDIA_TYPE_CAROUSEL,
|
|
675
|
+
carouselData: [
|
|
676
|
+
{
|
|
677
|
+
bodyText: 'Card',
|
|
678
|
+
mediaType: 'image',
|
|
679
|
+
imageUrl: 'https://img.url',
|
|
680
|
+
buttons: [
|
|
681
|
+
{ type: 'URL', text: 'Open', urlType: 'STATIC', url: 'https://example.com' },
|
|
682
|
+
],
|
|
683
|
+
},
|
|
684
|
+
],
|
|
685
|
+
},
|
|
686
|
+
};
|
|
687
|
+
render(
|
|
688
|
+
<TestWrapper>
|
|
689
|
+
<CommonTestAndPreview {...props} />
|
|
690
|
+
</TestWrapper>
|
|
691
|
+
);
|
|
692
|
+
await waitFor(() => {
|
|
693
|
+
expect(lastSendTestMessageProps).toBeDefined();
|
|
694
|
+
});
|
|
695
|
+
lastSendTestMessageProps.handleSendTestMessage();
|
|
696
|
+
const [payload] = mockActions.createMessageMetaRequested.mock.calls[0];
|
|
697
|
+
const buttons = payload.whatsappMessageContent.templateConfigs.cards[0].buttons;
|
|
698
|
+
expect(buttons[0].type).toBe('URL');
|
|
699
|
+
expect(buttons[0].url).toBe('https://example.com');
|
|
700
|
+
expect(buttons[0].dynamicUrlPayload).toBeUndefined();
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
it('should set dynamicUrlPayload when button type URL and urlType DYNAMIC_URL with single template', async () => {
|
|
704
|
+
const props = {
|
|
705
|
+
...defaultProps,
|
|
706
|
+
channel: CHANNELS.WHATSAPP,
|
|
707
|
+
formData: {
|
|
708
|
+
templateMsg: 'Message',
|
|
709
|
+
mediaType: MEDIA_TYPE_CAROUSEL,
|
|
710
|
+
carouselData: [
|
|
711
|
+
{
|
|
712
|
+
bodyText: 'Card',
|
|
713
|
+
mediaType: 'image',
|
|
714
|
+
imageUrl: 'https://img.url',
|
|
715
|
+
buttons: [
|
|
716
|
+
{ type: 'URL', text: 'Open', urlType: 'DYNAMIC_URL', url: 'https://example.com/{{id}}' },
|
|
717
|
+
],
|
|
718
|
+
},
|
|
719
|
+
],
|
|
720
|
+
},
|
|
721
|
+
};
|
|
722
|
+
render(
|
|
723
|
+
<TestWrapper>
|
|
724
|
+
<CommonTestAndPreview {...props} />
|
|
725
|
+
</TestWrapper>
|
|
726
|
+
);
|
|
727
|
+
await waitFor(() => {
|
|
728
|
+
expect(lastSendTestMessageProps).toBeDefined();
|
|
729
|
+
});
|
|
730
|
+
lastSendTestMessageProps.handleSendTestMessage();
|
|
731
|
+
const [payload] = mockActions.createMessageMetaRequested.mock.calls[0];
|
|
732
|
+
const buttons = payload.whatsappMessageContent.templateConfigs.cards[0].buttons;
|
|
733
|
+
expect(buttons[0].url).toBe('https://example.com/{{id}}');
|
|
734
|
+
expect(buttons[0].dynamicUrlPayload).toBe('{{id}}');
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
it('should set dynamicUrlPayload to empty when urlType DYNAMIC_URL but multiple or zero matches', async () => {
|
|
738
|
+
const props = {
|
|
739
|
+
...defaultProps,
|
|
740
|
+
channel: CHANNELS.WHATSAPP,
|
|
741
|
+
formData: {
|
|
742
|
+
templateMsg: 'Message',
|
|
743
|
+
mediaType: MEDIA_TYPE_CAROUSEL,
|
|
744
|
+
carouselData: [
|
|
745
|
+
{
|
|
746
|
+
bodyText: 'Card',
|
|
747
|
+
mediaType: 'image',
|
|
748
|
+
imageUrl: 'https://img.url',
|
|
749
|
+
buttons: [
|
|
750
|
+
{ type: 'URL', text: 'Open', urlType: 'DYNAMIC_URL', url: 'https://example.com/{{a}}{{b}}' },
|
|
751
|
+
],
|
|
752
|
+
},
|
|
753
|
+
],
|
|
754
|
+
},
|
|
755
|
+
};
|
|
756
|
+
render(
|
|
757
|
+
<TestWrapper>
|
|
758
|
+
<CommonTestAndPreview {...props} />
|
|
759
|
+
</TestWrapper>
|
|
760
|
+
);
|
|
761
|
+
await waitFor(() => {
|
|
762
|
+
expect(lastSendTestMessageProps).toBeDefined();
|
|
763
|
+
});
|
|
764
|
+
lastSendTestMessageProps.handleSendTestMessage();
|
|
765
|
+
const [payload] = mockActions.createMessageMetaRequested.mock.calls[0];
|
|
766
|
+
const buttons = payload.whatsappMessageContent.templateConfigs.cards[0].buttons;
|
|
767
|
+
expect(buttons[0].dynamicUrlPayload).toBe('');
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
it('should set dynamicUrlPayload to empty when urlType DYNAMIC_URL and url is null/undefined', async () => {
|
|
771
|
+
const props = {
|
|
772
|
+
...defaultProps,
|
|
773
|
+
channel: CHANNELS.WHATSAPP,
|
|
774
|
+
formData: {
|
|
775
|
+
templateMsg: 'Message',
|
|
776
|
+
mediaType: MEDIA_TYPE_CAROUSEL,
|
|
777
|
+
carouselData: [
|
|
778
|
+
{
|
|
779
|
+
bodyText: 'Card',
|
|
780
|
+
mediaType: 'image',
|
|
781
|
+
imageUrl: 'https://img.url',
|
|
782
|
+
buttons: [
|
|
783
|
+
{ type: 'URL', text: 'Open', urlType: 'DYNAMIC_URL', url: null },
|
|
784
|
+
],
|
|
785
|
+
},
|
|
786
|
+
],
|
|
787
|
+
},
|
|
788
|
+
};
|
|
789
|
+
render(
|
|
790
|
+
<TestWrapper>
|
|
791
|
+
<CommonTestAndPreview {...props} />
|
|
792
|
+
</TestWrapper>
|
|
793
|
+
);
|
|
794
|
+
await waitFor(() => {
|
|
795
|
+
expect(lastSendTestMessageProps).toBeDefined();
|
|
796
|
+
});
|
|
797
|
+
lastSendTestMessageProps.handleSendTestMessage();
|
|
798
|
+
const [payload] = mockActions.createMessageMetaRequested.mock.calls[0];
|
|
799
|
+
const buttons = payload.whatsappMessageContent.templateConfigs.cards[0].buttons;
|
|
800
|
+
expect(buttons[0].dynamicUrlPayload).toBe('');
|
|
801
|
+
});
|
|
802
|
+
|
|
803
|
+
it('should pass through cardVarMapped and bodyTemplate on each card', async () => {
|
|
804
|
+
const props = {
|
|
805
|
+
...defaultProps,
|
|
806
|
+
channel: CHANNELS.WHATSAPP,
|
|
807
|
+
formData: {
|
|
808
|
+
templateMsg: 'Message',
|
|
809
|
+
mediaType: MEDIA_TYPE_CAROUSEL,
|
|
810
|
+
carouselData: [
|
|
811
|
+
{
|
|
812
|
+
bodyText: 'Body',
|
|
813
|
+
cardVarMapped: { foo: 'bar' },
|
|
814
|
+
bodyTemplate: 'Body {{foo}}',
|
|
815
|
+
mediaType: 'image',
|
|
816
|
+
imageUrl: 'https://img.url',
|
|
817
|
+
buttons: [],
|
|
818
|
+
},
|
|
819
|
+
],
|
|
820
|
+
},
|
|
821
|
+
};
|
|
822
|
+
render(
|
|
823
|
+
<TestWrapper>
|
|
824
|
+
<CommonTestAndPreview {...props} />
|
|
825
|
+
</TestWrapper>
|
|
826
|
+
);
|
|
827
|
+
await waitFor(() => {
|
|
828
|
+
expect(lastSendTestMessageProps).toBeDefined();
|
|
829
|
+
});
|
|
830
|
+
lastSendTestMessageProps.handleSendTestMessage();
|
|
831
|
+
const [payload] = mockActions.createMessageMetaRequested.mock.calls[0];
|
|
832
|
+
const card = payload.whatsappMessageContent.templateConfigs.cards[0];
|
|
833
|
+
expect(card.cardVarMapped).toEqual({ foo: 'bar' });
|
|
834
|
+
expect(card.bodyTemplate).toBe('Body {{foo}}');
|
|
835
|
+
});
|
|
836
|
+
|
|
837
|
+
it('should not add media url when mediaType is neither image nor video', async () => {
|
|
838
|
+
const props = {
|
|
839
|
+
...defaultProps,
|
|
840
|
+
channel: CHANNELS.WHATSAPP,
|
|
841
|
+
formData: {
|
|
842
|
+
templateMsg: 'Message',
|
|
843
|
+
mediaType: MEDIA_TYPE_CAROUSEL,
|
|
844
|
+
carouselData: [
|
|
845
|
+
{
|
|
846
|
+
bodyText: 'Card',
|
|
847
|
+
mediaType: 'DOCUMENT',
|
|
848
|
+
imageUrl: 'https://img.url',
|
|
849
|
+
videoUrl: 'https://video.url',
|
|
850
|
+
buttons: [],
|
|
851
|
+
},
|
|
852
|
+
],
|
|
853
|
+
},
|
|
854
|
+
};
|
|
855
|
+
render(
|
|
856
|
+
<TestWrapper>
|
|
857
|
+
<CommonTestAndPreview {...props} />
|
|
858
|
+
</TestWrapper>
|
|
859
|
+
);
|
|
860
|
+
await waitFor(() => {
|
|
861
|
+
expect(lastSendTestMessageProps).toBeDefined();
|
|
862
|
+
});
|
|
863
|
+
lastSendTestMessageProps.handleSendTestMessage();
|
|
864
|
+
const [payload] = mockActions.createMessageMetaRequested.mock.calls[0];
|
|
865
|
+
const card = payload.whatsappMessageContent.templateConfigs.cards[0];
|
|
866
|
+
expect(card.media).toEqual({});
|
|
867
|
+
expect(card.mediaType).toBe('DOCUMENT');
|
|
868
|
+
});
|
|
869
|
+
|
|
870
|
+
it('should handle multiple carousel cards with mixed button types', async () => {
|
|
871
|
+
const props = {
|
|
872
|
+
...defaultProps,
|
|
873
|
+
channel: CHANNELS.WHATSAPP,
|
|
874
|
+
formData: {
|
|
875
|
+
templateMsg: 'Message',
|
|
876
|
+
mediaType: MEDIA_TYPE_CAROUSEL,
|
|
877
|
+
carouselData: [
|
|
878
|
+
{
|
|
879
|
+
bodyText: 'First',
|
|
880
|
+
mediaType: 'image',
|
|
881
|
+
imageUrl: 'https://first.jpg',
|
|
882
|
+
buttons: [{ type: 'PHONE_NUMBER', text: 'Call', phone_number: '+111' }],
|
|
883
|
+
},
|
|
884
|
+
{
|
|
885
|
+
bodyText: 'Second',
|
|
886
|
+
mediaType: 'video',
|
|
887
|
+
videoUrl: 'https://second.mp4',
|
|
888
|
+
videoPreviewImg: 'https://second-prev.jpg',
|
|
889
|
+
buttons: [{ type: 'URL', text: 'Link', urlType: 'DYNAMIC_URL', url: 'https://x/{{only}}' }],
|
|
890
|
+
},
|
|
891
|
+
],
|
|
892
|
+
},
|
|
893
|
+
};
|
|
894
|
+
render(
|
|
895
|
+
<TestWrapper>
|
|
896
|
+
<CommonTestAndPreview {...props} />
|
|
897
|
+
</TestWrapper>
|
|
898
|
+
);
|
|
899
|
+
await waitFor(() => {
|
|
900
|
+
expect(lastSendTestMessageProps).toBeDefined();
|
|
901
|
+
});
|
|
902
|
+
lastSendTestMessageProps.handleSendTestMessage();
|
|
903
|
+
const [payload] = mockActions.createMessageMetaRequested.mock.calls[0];
|
|
904
|
+
const cards = payload.whatsappMessageContent.templateConfigs.cards;
|
|
905
|
+
expect(cards).toHaveLength(2);
|
|
906
|
+
expect(cards[0].body).toBe('First');
|
|
907
|
+
expect(cards[0].media.url).toBe('https://first.jpg');
|
|
908
|
+
expect(cards[0].buttons[0].phoneNumber).toBe('+111');
|
|
909
|
+
expect(cards[1].body).toBe('Second');
|
|
910
|
+
expect(cards[1].media.url).toBe('https://second.mp4');
|
|
911
|
+
expect(cards[1].media.previewUrl).toBe('https://second-prev.jpg');
|
|
912
|
+
expect(cards[1].buttons[0].dynamicUrlPayload).toBe('{{only}}');
|
|
913
|
+
});
|
|
914
|
+
|
|
915
|
+
it('should use carouselMediaType for templateConfigs.mediaType when provided', async () => {
|
|
916
|
+
const props = {
|
|
917
|
+
...defaultProps,
|
|
918
|
+
channel: CHANNELS.WHATSAPP,
|
|
919
|
+
formData: {
|
|
920
|
+
templateMsg: 'Message',
|
|
921
|
+
mediaType: MEDIA_TYPE_CAROUSEL,
|
|
922
|
+
carouselMediaType: 'VIDEO',
|
|
923
|
+
carouselData: [
|
|
924
|
+
{ bodyText: 'Card', mediaType: 'image', imageUrl: 'https://img.url', buttons: [] },
|
|
925
|
+
],
|
|
926
|
+
},
|
|
927
|
+
};
|
|
928
|
+
render(
|
|
929
|
+
<TestWrapper>
|
|
930
|
+
<CommonTestAndPreview {...props} />
|
|
931
|
+
</TestWrapper>
|
|
932
|
+
);
|
|
933
|
+
await waitFor(() => {
|
|
934
|
+
expect(lastSendTestMessageProps).toBeDefined();
|
|
935
|
+
});
|
|
936
|
+
lastSendTestMessageProps.handleSendTestMessage();
|
|
937
|
+
const [payload] = mockActions.createMessageMetaRequested.mock.calls[0];
|
|
938
|
+
expect(payload.whatsappMessageContent.templateConfigs.mediaType).toBe('VIDEO');
|
|
939
|
+
});
|
|
940
|
+
|
|
941
|
+
it('should default templateConfigs.mediaType to IMAGE when carouselMediaType is missing', async () => {
|
|
942
|
+
const props = {
|
|
943
|
+
...defaultProps,
|
|
944
|
+
channel: CHANNELS.WHATSAPP,
|
|
945
|
+
formData: {
|
|
946
|
+
templateMsg: 'Message',
|
|
947
|
+
mediaType: MEDIA_TYPE_CAROUSEL,
|
|
948
|
+
carouselData: [
|
|
949
|
+
{ bodyText: 'Card', mediaType: 'image', imageUrl: 'https://img.url', buttons: [] },
|
|
950
|
+
],
|
|
951
|
+
},
|
|
952
|
+
};
|
|
953
|
+
render(
|
|
954
|
+
<TestWrapper>
|
|
955
|
+
<CommonTestAndPreview {...props} />
|
|
956
|
+
</TestWrapper>
|
|
957
|
+
);
|
|
958
|
+
await waitFor(() => {
|
|
959
|
+
expect(lastSendTestMessageProps).toBeDefined();
|
|
960
|
+
});
|
|
961
|
+
lastSendTestMessageProps.handleSendTestMessage();
|
|
962
|
+
const [payload] = mockActions.createMessageMetaRequested.mock.calls[0];
|
|
963
|
+
expect(payload.whatsappMessageContent.templateConfigs.mediaType).toBe('IMAGE');
|
|
964
|
+
});
|
|
965
|
+
});
|
|
966
|
+
|
|
527
967
|
describe('Component Rendering', () => {
|
|
528
968
|
it('should render when show is true', async () => {
|
|
529
969
|
render(
|