@capillarytech/creatives-library 8.0.319 → 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.
- package/constants/unified.js +14 -0
- package/package.json +1 -1
- package/utils/templateVarUtils.js +172 -0
- package/utils/tests/tagValidations.test.js +34 -0
- package/utils/tests/templateVarUtils.test.js +160 -0
- package/v2Components/CapTagList/index.js +25 -22
- package/v2Components/CapTagList/style.scss +48 -0
- package/v2Components/CapTagListWithInput/__tests__/CapTagListWithInput.test.js +63 -0
- package/v2Components/CapTagListWithInput/index.js +4 -0
- package/v2Components/CapWhatsappCTA/index.js +2 -0
- package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +70 -49
- package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +8 -2
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +207 -21
- package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +16 -0
- package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +85 -10
- package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +30 -0
- package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +79 -11
- package/v2Components/CommonTestAndPreview/SendTestMessage.js +11 -5
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +20 -1
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +133 -4
- package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +12 -0
- package/v2Components/CommonTestAndPreview/constants.js +38 -0
- package/v2Components/CommonTestAndPreview/index.js +693 -155
- package/v2Components/CommonTestAndPreview/messages.js +41 -3
- package/v2Components/CommonTestAndPreview/previewApiUtils.js +59 -0
- package/v2Components/CommonTestAndPreview/sagas.js +15 -6
- package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +352 -0
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +269 -1
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +118 -5
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +341 -0
- package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +25 -4
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +199 -1
- package/v2Components/CommonTestAndPreview/tests/index.test.js +132 -4
- package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +67 -0
- package/v2Components/CommonTestAndPreview/tests/sagas.test.js +2 -2
- package/v2Components/FormBuilder/index.js +14 -1
- package/v2Components/HtmlEditor/HTMLEditor.js +6 -1
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +1 -0
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +927 -2
- package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +3 -0
- package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +87 -0
- package/v2Components/SmsFallback/constants.js +73 -0
- package/v2Components/SmsFallback/index.js +956 -0
- package/v2Components/SmsFallback/index.scss +265 -0
- package/v2Components/SmsFallback/messages.js +78 -0
- package/v2Components/SmsFallback/smsFallbackUtils.js +107 -0
- package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +50 -0
- package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +147 -0
- package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +304 -0
- package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +197 -0
- package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +261 -0
- package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +422 -0
- package/v2Components/SmsFallback/useLocalTemplateList.js +92 -0
- package/v2Components/TestAndPreviewSlidebox/index.js +8 -1
- package/v2Components/TestAndPreviewSlidebox/sagas.js +11 -4
- package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +3 -1
- package/v2Components/VarSegmentMessageEditor/constants.js +2 -0
- package/v2Components/VarSegmentMessageEditor/index.js +125 -0
- package/v2Components/VarSegmentMessageEditor/index.scss +46 -0
- package/v2Containers/BeeEditor/index.js +3 -0
- package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +43 -0
- package/v2Containers/CreativesContainer/SlideBoxContent.js +64 -5
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +10 -1
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +29 -4
- package/v2Containers/CreativesContainer/constants.js +9 -0
- package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +67 -0
- package/v2Containers/CreativesContainer/index.js +292 -99
- package/v2Containers/CreativesContainer/index.scss +51 -1
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +90 -0
- package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +104 -0
- package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +110 -0
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +8 -0
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +363 -0
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +20 -10
- package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +258 -0
- package/v2Containers/CreativesContainer/tests/index.test.js +71 -9
- package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +125 -0
- package/v2Containers/Email/index.js +1 -0
- package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +7 -1
- package/v2Containers/EmailWrapper/components/EmailWrapperView.js +3 -0
- package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +20 -2
- package/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +16 -1
- package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +3 -0
- package/v2Containers/EmailWrapper/index.js +4 -0
- package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +1 -0
- package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +9 -0
- package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +19 -0
- package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +3 -0
- package/v2Containers/InAppWrapper/index.js +3 -0
- package/v2Containers/MobilePush/Create/index.js +2 -0
- package/v2Containers/MobilePush/Edit/index.js +2 -0
- package/v2Containers/MobilepushWrapper/index.js +3 -1
- package/v2Containers/Rcs/constants.js +32 -1
- package/v2Containers/Rcs/index.js +951 -873
- package/v2Containers/Rcs/index.scss +85 -6
- package/v2Containers/Rcs/messages.js +10 -1
- package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +205 -0
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +40834 -1963
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +0 -5
- package/v2Containers/Rcs/tests/index.test.js +41 -38
- package/v2Containers/Rcs/tests/mockData.js +38 -0
- package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +251 -0
- package/v2Containers/Rcs/tests/utils.test.js +379 -1
- package/v2Containers/Rcs/utils.js +358 -10
- package/v2Containers/Sms/Create/index.js +83 -36
- package/v2Containers/Sms/Edit/index.js +2 -0
- package/v2Containers/Sms/smsFormDataHelpers.js +67 -0
- package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +253 -0
- package/v2Containers/SmsTrai/Create/index.js +9 -4
- package/v2Containers/SmsTrai/Edit/constants.js +2 -0
- package/v2Containers/SmsTrai/Edit/index.js +611 -128
- package/v2Containers/SmsTrai/Edit/index.scss +121 -0
- package/v2Containers/SmsTrai/Edit/messages.js +9 -4
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4327 -2374
- package/v2Containers/SmsWrapper/index.js +39 -8
- package/v2Containers/TagList/index.js +47 -2
- package/v2Containers/TagList/messages.js +4 -0
- package/v2Containers/TagList/tests/TagList.test.js +122 -20
- package/v2Containers/TagList/tests/mockdata.js +17 -0
- package/v2Containers/Templates/TemplatesActionBar.js +101 -0
- package/v2Containers/Templates/_templates.scss +61 -2
- package/v2Containers/Templates/actions.js +11 -0
- package/v2Containers/Templates/constants.js +2 -0
- package/v2Containers/Templates/index.js +90 -40
- package/v2Containers/Templates/sagas.js +57 -12
- package/v2Containers/Templates/tests/TemplatesActionBar.test.js +120 -0
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1043 -1079
- package/v2Containers/Templates/tests/sagas.test.js +193 -12
- package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +180 -0
- package/v2Containers/Templates/utils/smsTemplatesListApi.js +79 -0
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +72 -1
- package/v2Containers/TemplatesV2/index.js +86 -23
- package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +131 -0
- package/v2Containers/Viber/index.js +5 -0
- package/v2Containers/WebPush/Create/hooks/useTagManagement.js +0 -2
- package/v2Containers/WebPush/Create/index.js +9 -1
- package/v2Containers/Whatsapp/index.js +8 -20
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +598 -34
- package/v2Containers/Zalo/index.js +2 -0
|
@@ -30,23 +30,28 @@ 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;
|
|
33
34
|
jest.mock('../LeftPanelContent', () => {
|
|
34
35
|
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
|
|
35
36
|
const ReactLib = require('react');
|
|
36
37
|
return {
|
|
37
38
|
__esModule: true,
|
|
38
|
-
default: function MockLeftPanelContent() {
|
|
39
|
-
|
|
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);
|
|
40
43
|
},
|
|
41
44
|
};
|
|
42
45
|
});
|
|
43
46
|
|
|
47
|
+
let lastCustomValuesEditorProps = null;
|
|
44
48
|
jest.mock('../CustomValuesEditor', () => {
|
|
45
49
|
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
|
|
46
50
|
const ReactLib = require('react');
|
|
47
51
|
return {
|
|
48
52
|
__esModule: true,
|
|
49
|
-
default: function MockCustomValuesEditor() {
|
|
53
|
+
default: function MockCustomValuesEditor(props) {
|
|
54
|
+
lastCustomValuesEditorProps = props;
|
|
50
55
|
return ReactLib.createElement('div', { 'data-testid': 'custom-values-editor' }, 'Custom Values Editor');
|
|
51
56
|
},
|
|
52
57
|
};
|
|
@@ -184,6 +189,8 @@ describe('CommonTestAndPreview', () => {
|
|
|
184
189
|
beforeEach(() => {
|
|
185
190
|
jest.clearAllMocks();
|
|
186
191
|
lastSendTestMessageProps = null;
|
|
192
|
+
lastLeftPanelContentProps = null;
|
|
193
|
+
lastCustomValuesEditorProps = null;
|
|
187
194
|
// Reset all mock function implementations
|
|
188
195
|
Object.values(mockActions).forEach((mockFn) => {
|
|
189
196
|
if (jest.isMockFunction(mockFn)) {
|
|
@@ -238,6 +245,24 @@ describe('CommonTestAndPreview', () => {
|
|
|
238
245
|
});
|
|
239
246
|
});
|
|
240
247
|
|
|
248
|
+
it('should call getSenderDetailsRequested for RCS and SMS when channel is RCS', async () => {
|
|
249
|
+
render(
|
|
250
|
+
<TestWrapper>
|
|
251
|
+
<CommonTestAndPreview {...defaultProps} channel={CHANNELS.RCS} />
|
|
252
|
+
</TestWrapper>
|
|
253
|
+
);
|
|
254
|
+
await waitFor(() => {
|
|
255
|
+
expect(mockActions.getSenderDetailsRequested).toHaveBeenCalledWith({
|
|
256
|
+
channel: CHANNELS.RCS,
|
|
257
|
+
orgUnitId: -1,
|
|
258
|
+
});
|
|
259
|
+
expect(mockActions.getSenderDetailsRequested).toHaveBeenCalledWith({
|
|
260
|
+
channel: CHANNELS.SMS,
|
|
261
|
+
orgUnitId: -1,
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
|
|
241
266
|
it('should not call getSenderDetailsRequested when channel is INAPP', async () => {
|
|
242
267
|
render(
|
|
243
268
|
<TestWrapper>
|
|
@@ -296,7 +321,7 @@ describe('CommonTestAndPreview', () => {
|
|
|
296
321
|
});
|
|
297
322
|
expect(lastSendTestMessageProps).toBeDefined();
|
|
298
323
|
expect(lastSendTestMessageProps.deliverySettings).toBeDefined();
|
|
299
|
-
expect(lastSendTestMessageProps.
|
|
324
|
+
expect(lastSendTestMessageProps.senderDetailsByChannel).toEqual(senderDetailsByChannel);
|
|
300
325
|
expect(lastSendTestMessageProps.wecrmAccounts).toEqual([]);
|
|
301
326
|
expect(typeof lastSendTestMessageProps.onSaveDeliverySettings).toBe('function');
|
|
302
327
|
expect(lastSendTestMessageProps.isLoadingSenderDetails).toBe(false);
|
|
@@ -3245,4 +3270,107 @@ describe('CommonTestAndPreview', () => {
|
|
|
3245
3270
|
});
|
|
3246
3271
|
});
|
|
3247
3272
|
});
|
|
3273
|
+
|
|
3274
|
+
describe('SMS DLT and mustache tag discrimination (smsTemplateHasMustacheTags / buildSyntheticSmsMustacheTags)', () => {
|
|
3275
|
+
it('should return no tags for SMS content that contains only DLT {#var#} tokens', async () => {
|
|
3276
|
+
render(
|
|
3277
|
+
<TestWrapper>
|
|
3278
|
+
<CommonTestAndPreview
|
|
3279
|
+
{...defaultProps}
|
|
3280
|
+
channel={CHANNELS.SMS}
|
|
3281
|
+
formData={{ 0: { 'sms-editor': 'Order {#orderId#} is confirmed' } }}
|
|
3282
|
+
extractedTags={[]}
|
|
3283
|
+
/>
|
|
3284
|
+
</TestWrapper>
|
|
3285
|
+
);
|
|
3286
|
+
|
|
3287
|
+
await waitFor(() => expect(lastLeftPanelContentProps).not.toBeNull());
|
|
3288
|
+
|
|
3289
|
+
// smsTemplateHasMustacheTags returns false for DLT-only → extractedTags is []
|
|
3290
|
+
expect(lastLeftPanelContentProps.extractedTags).toEqual([]);
|
|
3291
|
+
});
|
|
3292
|
+
|
|
3293
|
+
it('should build synthetic tags from {{mustache}} tokens, excluding DLT {#var#} tokens', async () => {
|
|
3294
|
+
render(
|
|
3295
|
+
<TestWrapper>
|
|
3296
|
+
<CommonTestAndPreview
|
|
3297
|
+
{...defaultProps}
|
|
3298
|
+
channel={CHANNELS.SMS}
|
|
3299
|
+
formData={{ 0: { 'sms-editor': 'Hi {{name}}, order {#orderId#} shipped' } }}
|
|
3300
|
+
extractedTags={[]}
|
|
3301
|
+
/>
|
|
3302
|
+
</TestWrapper>
|
|
3303
|
+
);
|
|
3304
|
+
|
|
3305
|
+
await waitFor(() => expect(lastLeftPanelContentProps).not.toBeNull());
|
|
3306
|
+
|
|
3307
|
+
const tags = lastLeftPanelContentProps.extractedTags;
|
|
3308
|
+
// Only {{name}} should become a tag — {#orderId#} must be excluded
|
|
3309
|
+
expect(tags).toHaveLength(1);
|
|
3310
|
+
expect(tags[0].name).toBe('name');
|
|
3311
|
+
});
|
|
3312
|
+
|
|
3313
|
+
it('should use API-extracted tags when present instead of building synthetic ones', async () => {
|
|
3314
|
+
const apiTags = [{ name: 'firstName', metaData: { userDriven: true }, children: [] }];
|
|
3315
|
+
render(
|
|
3316
|
+
<TestWrapper>
|
|
3317
|
+
<CommonTestAndPreview
|
|
3318
|
+
{...defaultProps}
|
|
3319
|
+
channel={CHANNELS.SMS}
|
|
3320
|
+
formData={{ 0: { 'sms-editor': 'Hi {{firstName}}' } }}
|
|
3321
|
+
extractedTags={apiTags}
|
|
3322
|
+
/>
|
|
3323
|
+
</TestWrapper>
|
|
3324
|
+
);
|
|
3325
|
+
|
|
3326
|
+
await waitFor(() => expect(lastLeftPanelContentProps).not.toBeNull());
|
|
3327
|
+
|
|
3328
|
+
// API tags take priority over buildSyntheticSmsMustacheTags
|
|
3329
|
+
expect(lastLeftPanelContentProps.extractedTags).toEqual(apiTags);
|
|
3330
|
+
});
|
|
3331
|
+
});
|
|
3332
|
+
|
|
3333
|
+
describe('handleDiscardCustomValues — preview reset', () => {
|
|
3334
|
+
it('should call updatePreviewRequested when handleDiscardCustomValues is invoked', async () => {
|
|
3335
|
+
render(
|
|
3336
|
+
<TestWrapper>
|
|
3337
|
+
<CommonTestAndPreview
|
|
3338
|
+
{...defaultProps}
|
|
3339
|
+
channel={CHANNELS.SMS}
|
|
3340
|
+
formData={{ 0: { 'sms-editor': 'Hi {{name}}' } }}
|
|
3341
|
+
/>
|
|
3342
|
+
</TestWrapper>
|
|
3343
|
+
);
|
|
3344
|
+
|
|
3345
|
+
await waitFor(() => expect(lastCustomValuesEditorProps).not.toBeNull());
|
|
3346
|
+
|
|
3347
|
+
lastCustomValuesEditorProps.handleDiscardCustomValues();
|
|
3348
|
+
|
|
3349
|
+
expect(mockActions.updatePreviewRequested).toHaveBeenCalledTimes(1);
|
|
3350
|
+
});
|
|
3351
|
+
|
|
3352
|
+
it('should call updatePreviewRequested with RCS channel when handleDiscardCustomValues is invoked for RCS with fallback', async () => {
|
|
3353
|
+
render(
|
|
3354
|
+
<TestWrapper>
|
|
3355
|
+
<CommonTestAndPreview
|
|
3356
|
+
{...defaultProps}
|
|
3357
|
+
channel={CHANNELS.RCS}
|
|
3358
|
+
smsFallbackContent={{
|
|
3359
|
+
templateContent: 'Fallback {{name}}',
|
|
3360
|
+
content: 'Fallback {{name}}',
|
|
3361
|
+
}}
|
|
3362
|
+
formData={{}}
|
|
3363
|
+
/>
|
|
3364
|
+
</TestWrapper>
|
|
3365
|
+
);
|
|
3366
|
+
|
|
3367
|
+
await waitFor(() => expect(lastCustomValuesEditorProps).not.toBeNull());
|
|
3368
|
+
|
|
3369
|
+
lastCustomValuesEditorProps.handleDiscardCustomValues();
|
|
3370
|
+
|
|
3371
|
+
// updatePreviewRequested is called; syncSmsFallbackPreview (which hits Api directly) is NOT called
|
|
3372
|
+
expect(mockActions.updatePreviewRequested).toHaveBeenCalledTimes(1);
|
|
3373
|
+
});
|
|
3374
|
+
});
|
|
3248
3375
|
});
|
|
3376
|
+
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import {
|
|
2
|
+
normalizePreviewApiPayload,
|
|
3
|
+
extractPreviewFromLiquidResponse,
|
|
4
|
+
getSmsFallbackTextForTagExtraction,
|
|
5
|
+
} from '../previewApiUtils';
|
|
6
|
+
import { RCS_SMS_FALLBACK_VAR_MAPPED_PROP } from '../constants';
|
|
7
|
+
|
|
8
|
+
describe('previewApiUtils', () => {
|
|
9
|
+
describe('normalizePreviewApiPayload', () => {
|
|
10
|
+
it('maps messageBody to resolvedBody when resolvedBody is missing', () => {
|
|
11
|
+
expect(normalizePreviewApiPayload({ messageBody: 'Hello' }).resolvedBody).toBe('Hello');
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
describe('extractPreviewFromLiquidResponse', () => {
|
|
16
|
+
it('accepts nested data shape', () => {
|
|
17
|
+
const r = { data: { resolvedBody: 'ok' } };
|
|
18
|
+
expect(extractPreviewFromLiquidResponse(r)).toEqual({ resolvedBody: 'ok' });
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('accepts top-level preview (typical SMS)', () => {
|
|
22
|
+
const r = { messageBody: 'sms text' };
|
|
23
|
+
expect(extractPreviewFromLiquidResponse(r)).toMatchObject({
|
|
24
|
+
messageBody: 'sms text',
|
|
25
|
+
resolvedBody: 'sms text',
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('returns null when errors array is non-empty', () => {
|
|
30
|
+
expect(extractPreviewFromLiquidResponse({ errors: [{ code: 1 }] })).toBeNull();
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('getSmsFallbackTextForTagExtraction', () => {
|
|
35
|
+
it('returns empty string when context is missing or has no template body', () => {
|
|
36
|
+
expect(getSmsFallbackTextForTagExtraction(null)).toBe('');
|
|
37
|
+
expect(getSmsFallbackTextForTagExtraction({})).toBe('');
|
|
38
|
+
expect(getSmsFallbackTextForTagExtraction({ templateContent: '', content: '' })).toBe('');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('returns raw template when rcsSmsFallbackVarMapped is absent or empty', () => {
|
|
42
|
+
const raw = '{{optout}} {{fullname}} test SMS';
|
|
43
|
+
expect(getSmsFallbackTextForTagExtraction({ templateContent: raw })).toBe(raw);
|
|
44
|
+
expect(getSmsFallbackTextForTagExtraction({
|
|
45
|
+
content: raw,
|
|
46
|
+
[RCS_SMS_FALLBACK_VAR_MAPPED_PROP]: {},
|
|
47
|
+
})).toBe(raw);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('prefers templateContent over content when both are set', () => {
|
|
51
|
+
expect(getSmsFallbackTextForTagExtraction({
|
|
52
|
+
templateContent: 'A',
|
|
53
|
+
content: 'B',
|
|
54
|
+
})).toBe('A');
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('applies VarSegment slot map so preview / meta payloads are not stale vs raw template', () => {
|
|
58
|
+
const rawTemplateWithSlots = '{{optout}} tail';
|
|
59
|
+
const rcsSmsFallbackVarMappedSlots = { '{{optout}}_0': 'STOP' };
|
|
60
|
+
const resolvedFallbackText = getSmsFallbackTextForTagExtraction({
|
|
61
|
+
templateContent: rawTemplateWithSlots,
|
|
62
|
+
[RCS_SMS_FALLBACK_VAR_MAPPED_PROP]: rcsSmsFallbackVarMappedSlots,
|
|
63
|
+
});
|
|
64
|
+
expect(resolvedFallbackText).toBe('STOP tail');
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
|
-
call, put, takeLatest, all,
|
|
8
|
+
call, put, takeLatest, takeEvery, 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
|
-
|
|
1336
|
+
takeEvery('app/CommonTestAndPreview/GET_SENDER_DETAILS_REQUESTED', getSenderDetailsSaga)
|
|
1337
1337
|
);
|
|
1338
1338
|
expect(generator.next().done).toBe(true);
|
|
1339
1339
|
});
|
|
@@ -2990,6 +2990,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2990
2990
|
selectedOfferDetails={this.props.selectedOfferDetails}
|
|
2991
2991
|
eventContextTags={this.props?.eventContextTags}
|
|
2992
2992
|
restrictPersonalization={this.props.restrictPersonalization}
|
|
2993
|
+
waitEventContextTags={this.props?.waitEventContextTags}
|
|
2993
2994
|
/>
|
|
2994
2995
|
</CapColumn>
|
|
2995
2996
|
);
|
|
@@ -3019,6 +3020,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
3019
3020
|
userLocale={this.props.userLocale}
|
|
3020
3021
|
selectedOfferDetails={this.props.selectedOfferDetails}
|
|
3021
3022
|
eventContextTags={this.props?.eventContextTags}
|
|
3023
|
+
waitEventContextTags={this.props?.waitEventContextTags}
|
|
3022
3024
|
moduleFilterEnabled={this.props.location && this.props.location.query && this.props.location.query.type !== 'embedded'}
|
|
3023
3025
|
containerStyle={val.style || {}}
|
|
3024
3026
|
inputProps={val.inputProps || {}}
|
|
@@ -3658,6 +3660,10 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
3658
3660
|
channel={channel}
|
|
3659
3661
|
eventContextTags={this.props?.eventContextTags}
|
|
3660
3662
|
restrictPersonalization={this.props.restrictPersonalization}
|
|
3663
|
+
waitEventContextTags={this.props?.waitEventContextTags}
|
|
3664
|
+
getPopupContainer={this.props.tagListGetPopupContainer}
|
|
3665
|
+
popoverOverlayStyle={this.props.tagListPopoverOverlayStyle}
|
|
3666
|
+
popoverOverlayClassName={this.props.tagListPopoverOverlayClassName}
|
|
3661
3667
|
/>
|
|
3662
3668
|
</CapColumn>
|
|
3663
3669
|
);
|
|
@@ -3704,6 +3710,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
3704
3710
|
userLocale={this.state.translationLang}
|
|
3705
3711
|
selectedOfferDetails={this.props.selectedOfferDetails}
|
|
3706
3712
|
eventContextTags={this.props?.eventContextTags}
|
|
3713
|
+
waitEventContextTags={this.props?.waitEventContextTags}
|
|
3707
3714
|
moduleFilterEnabled={moduleFilterEnabledForCapTagList}
|
|
3708
3715
|
containerStyle={val.style || {}}
|
|
3709
3716
|
inputProps={val.inputProps || {}}
|
|
@@ -3998,6 +4005,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
3998
4005
|
onContextChange={this.props.onContextChange}
|
|
3999
4006
|
moduleFilterEnabled={isModuleFilterEnabled}
|
|
4000
4007
|
eventContextTags={this.props?.eventContextTags}
|
|
4008
|
+
waitEventContextTags={this.props?.waitEventContextTags}
|
|
4001
4009
|
/>
|
|
4002
4010
|
</CapColumn>
|
|
4003
4011
|
);
|
|
@@ -4300,6 +4308,7 @@ FormBuilder.defaultProps = {
|
|
|
4300
4308
|
userLocale: localStorage.getItem('jlocale') || 'en',
|
|
4301
4309
|
showLiquidErrorInFooter: () => {},
|
|
4302
4310
|
metaDataStatus: "",
|
|
4311
|
+
waitEventContextTags: {},
|
|
4303
4312
|
isTestAndPreviewMode: false, // Default to false to maintain existing behavior
|
|
4304
4313
|
};
|
|
4305
4314
|
|
|
@@ -4348,12 +4357,16 @@ FormBuilder.propTypes = {
|
|
|
4348
4357
|
type: PropTypes.string.isRequired,
|
|
4349
4358
|
isEmailLoading: PropTypes.bool.isRequired,
|
|
4350
4359
|
moduleType: PropTypes.string.isRequired,
|
|
4351
|
-
showLiquidErrorInFooter: PropTypes.
|
|
4360
|
+
showLiquidErrorInFooter: PropTypes.func.isRequired,
|
|
4352
4361
|
eventContextTags: PropTypes.array.isRequired,
|
|
4362
|
+
waitEventContextTags: PropTypes.object,
|
|
4353
4363
|
forwardedTags: PropTypes.object.isRequired,
|
|
4354
4364
|
isLoyaltyModule: PropTypes.bool.isRequired,
|
|
4355
4365
|
isTestAndPreviewMode: PropTypes.bool, // Add new prop type
|
|
4356
4366
|
restrictPersonalization: PropTypes.bool,
|
|
4367
|
+
tagListGetPopupContainer: PropTypes.func,
|
|
4368
|
+
tagListPopoverOverlayStyle: PropTypes.object,
|
|
4369
|
+
tagListPopoverOverlayClassName: PropTypes.string,
|
|
4357
4370
|
};
|
|
4358
4371
|
|
|
4359
4372
|
const mapStateToProps = createStructuredSelector({
|
|
@@ -94,6 +94,7 @@ const HTMLEditor = forwardRef(({
|
|
|
94
94
|
injectedTags = {},
|
|
95
95
|
location,
|
|
96
96
|
eventContextTags = [],
|
|
97
|
+
waitEventContextTags,
|
|
97
98
|
selectedOfferDetails = [],
|
|
98
99
|
channel,
|
|
99
100
|
userLocale = 'en',
|
|
@@ -361,7 +362,7 @@ const HTMLEditor = forwardRef(({
|
|
|
361
362
|
const issueCounts = calculateIssueCounts();
|
|
362
363
|
const isContentEmpty = !currentContent || currentContent.trim() === '';
|
|
363
364
|
|
|
364
|
-
// hasErrors = only Rule Group #1 (Input & Sanitization)
|
|
365
|
+
// hasErrors = only Rule Group #1 (Input & Sanitization) - gates Done/Update/Preview/Test
|
|
365
366
|
const newState = {
|
|
366
367
|
isContentEmpty,
|
|
367
368
|
issueCounts,
|
|
@@ -663,6 +664,7 @@ const HTMLEditor = forwardRef(({
|
|
|
663
664
|
injectedTags={injectedTags}
|
|
664
665
|
location={location}
|
|
665
666
|
eventContextTags={eventContextTags}
|
|
667
|
+
waitEventContextTags={waitEventContextTags}
|
|
666
668
|
selectedOfferDetails={selectedOfferDetails}
|
|
667
669
|
channel={channel}
|
|
668
670
|
userLocale={userLocale}
|
|
@@ -734,6 +736,7 @@ const HTMLEditor = forwardRef(({
|
|
|
734
736
|
injectedTags={injectedTags}
|
|
735
737
|
location={location}
|
|
736
738
|
eventContextTags={eventContextTags}
|
|
739
|
+
waitEventContextTags={waitEventContextTags}
|
|
737
740
|
selectedOfferDetails={selectedOfferDetails}
|
|
738
741
|
channel={channel}
|
|
739
742
|
userLocale={userLocale}
|
|
@@ -772,6 +775,7 @@ HTMLEditor.propTypes = {
|
|
|
772
775
|
injectedTags: PropTypes.object,
|
|
773
776
|
location: PropTypes.object,
|
|
774
777
|
eventContextTags: PropTypes.array,
|
|
778
|
+
waitEventContextTags: PropTypes.object,
|
|
775
779
|
selectedOfferDetails: PropTypes.array,
|
|
776
780
|
channel: PropTypes.string,
|
|
777
781
|
userLocale: PropTypes.string,
|
|
@@ -805,6 +809,7 @@ HTMLEditor.defaultProps = {
|
|
|
805
809
|
injectedTags: {},
|
|
806
810
|
location: null,
|
|
807
811
|
eventContextTags: [],
|
|
812
|
+
waitEventContextTags: {},
|
|
808
813
|
selectedOfferDetails: [],
|
|
809
814
|
channel: null,
|
|
810
815
|
userLocale: 'en',
|