@capillarytech/creatives-library 9.0.53-alpha.0 → 9.0.53-alpha.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "9.0.53-alpha.0",
4
+ "version": "9.0.53-alpha.2",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -39,6 +39,7 @@ import {
39
39
  CCS_STRATEGY_TYPE_SINGLE,
40
40
  CCS_CHANNEL_CONTENT_KEY_MAP,
41
41
  CCS_CHANNEL_DELIVERY_KEY_MAP,
42
+ CCS_CHANNEL_NAME_MAP,
42
43
  } from './constants';
43
44
  import { getEnabledSteps } from './utils/getEnabledSteps';
44
45
  import messages from './messages';
@@ -186,7 +187,8 @@ const CommunicationFlow = ({
186
187
  // CCS create is SINGLE-strategy only this phase (D1); CHANNEL_PRIORITY/AB_TEST
187
188
  // carry multiple content items with no CCS equivalent yet.
188
189
  if (!isMultiChannel && contentItem && name) {
189
- const channel = (contentItem.channel || '').toUpperCase();
190
+ const rawChannel = (contentItem.channel || '').toUpperCase();
191
+ const channel = CCS_CHANNEL_NAME_MAP[rawChannel] || rawChannel;
190
192
  const contentKey = CCS_CHANNEL_CONTENT_KEY_MAP[channel];
191
193
  const deliveryKey = CCS_CHANNEL_DELIVERY_KEY_MAP[channel];
192
194
  const { dynamicControls = {} } = aggregatedData;
@@ -208,9 +210,11 @@ const CommunicationFlow = ({
208
210
  executionParams: {},
209
211
  },
210
212
  singleChannelStrategy: {
211
- channel,
212
- ...(contentKey && { [contentKey]: contentItem.templateData }),
213
- ...(deliveryKey && { [deliveryKey]: { channelSettings: { channel, ...channelSettings } } }),
213
+ variant: {
214
+ channel,
215
+ ...(contentKey && { [contentKey]: contentItem.templateData }),
216
+ ...(deliveryKey && { [deliveryKey]: { channelSettings: { channel, ...channelSettings } } }),
217
+ },
214
218
  },
215
219
  };
216
220
 
@@ -227,7 +231,7 @@ const CommunicationFlow = ({
227
231
  ccsCommDefinition = {
228
232
  id: data.id,
229
233
  referenceId: data.referenceId,
230
- version: data.version?.version || 1,
234
+ version: data.version?.version ?? 1,
231
235
  status: data.status,
232
236
  };
233
237
  }
@@ -389,14 +389,42 @@ describe('handleSave — CCS flow', () => {
389
389
  name: 'Order Placed Notification',
390
390
  strategyType: 'SINGLE',
391
391
  singleChannelStrategy: expect.objectContaining({
392
- channel: 'SMS',
393
- smsMessageContent: { message: 'Hello' },
392
+ variant: expect.objectContaining({
393
+ channel: 'SMS',
394
+ smsMessageContent: { message: 'Hello' },
395
+ }),
394
396
  }),
395
397
  }),
396
398
  );
397
399
  expect(onSave).toHaveBeenCalledTimes(1);
398
400
  });
399
401
 
402
+ it('normalizes the internal MOBILEPUSH channel to CCS\'s MPUSH enum and key names', async () => {
403
+ const onSave = jest.fn();
404
+ renderWithFlow({
405
+ features: {},
406
+ config: ccsConfig,
407
+ initialData: {
408
+ contentItems: [{ channel: 'MOBILEPUSH', templateData: { messageSubject: 'Hi' } }],
409
+ },
410
+ onSave,
411
+ });
412
+
413
+ await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
414
+
415
+ await waitFor(() => expect(createCommDefinition).toHaveBeenCalledTimes(1));
416
+ expect(createCommDefinition).toHaveBeenCalledWith(
417
+ expect.objectContaining({
418
+ singleChannelStrategy: expect.objectContaining({
419
+ variant: expect.objectContaining({
420
+ channel: 'MPUSH',
421
+ mpushMessageContent: { messageSubject: 'Hi' },
422
+ }),
423
+ }),
424
+ }),
425
+ );
426
+ });
427
+
400
428
  it('merges ccsCommDefinition into the data passed to onSave when create succeeds', async () => {
401
429
  const onSave = jest.fn();
402
430
  renderWithFlow({
@@ -416,6 +444,28 @@ describe('handleSave — CCS flow', () => {
416
444
  );
417
445
  });
418
446
 
447
+ it('preserves a real version of 0 from CCS (not coerced to 1 by a falsy-zero fallback)', async () => {
448
+ const onSave = jest.fn();
449
+ createCommDefinition.mockResolvedValueOnce({
450
+ response: { data: { id: 'cd_123', referenceId: 'ORDER_PLACED_123', status: 'DRAFT', version: { version: 0 } } },
451
+ });
452
+ renderWithFlow({
453
+ features: {},
454
+ config: ccsConfig,
455
+ initialData: { contentItems: [{ channel: 'SMS', templateData: {} }] },
456
+ onSave,
457
+ });
458
+
459
+ await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
460
+
461
+ await waitFor(() => expect(onSave).toHaveBeenCalledTimes(1));
462
+ expect(onSave).toHaveBeenCalledWith(
463
+ expect.objectContaining({
464
+ ccsCommDefinition: { id: 'cd_123', referenceId: 'ORDER_PLACED_123', version: 0, status: 'DRAFT' },
465
+ }),
466
+ );
467
+ });
468
+
419
469
  it('generates a referenceId from name when config.context.referenceId is absent', async () => {
420
470
  // moduleMocks.js spies on Date.now globally, but this config's resetMocks:true
421
471
  // clears that return value before every test — set it explicitly here.
@@ -575,7 +625,7 @@ describe('handleSave — CCS flow', () => {
575
625
  linkTrackingEnabled: true,
576
626
  userSubscriptionDisabled: true,
577
627
  });
578
- expect(payload.singleChannelStrategy.smsDeliverySettings.additionalSettings).toBeUndefined();
628
+ expect(payload.singleChannelStrategy.variant.smsDeliverySettings.additionalSettings).toBeUndefined();
579
629
  });
580
630
 
581
631
  it('includes channelSettings from deliverySetting.channelSetting in the payload', async () => {
@@ -592,7 +642,7 @@ describe('handleSave — CCS flow', () => {
592
642
 
593
643
  await waitFor(() => expect(createCommDefinition).toHaveBeenCalled());
594
644
  const payload = createCommDefinition.mock.calls[0][0];
595
- expect(payload.singleChannelStrategy.smsDeliverySettings.channelSettings).toEqual({
645
+ expect(payload.singleChannelStrategy.variant.smsDeliverySettings.channelSettings).toEqual({
596
646
  channel: 'SMS',
597
647
  domainId: 1001,
598
648
  gsmSenderId: 'BRAND1',
@@ -44,15 +44,14 @@ export const SINGLE_TEMPLATE = 'SINGLE_TEMPLATE';
44
44
  export const CCS_STRATEGY_TYPE_SINGLE = 'SINGLE';
45
45
 
46
46
  // Mirrors CCS's SingleChannelStrategy field names exactly (Cap Notify API
47
- // Design doc, "Channel Strategy overview" / class dump). Kept separate from
48
- // CHANNEL_CONTENT_KEY_MAP/CHANNEL_DELIVERY_KEY_MAP below, which are the legacy
49
- // messageMeta payload's keys and do not match CCS naming for every channel
50
- // (e.g. legacy uses lowercase 'mpushMessageContent'; CCS uses 'mPushMessageContent').
47
+ // Design doc sample payloads, verified against real create responses). Kept
48
+ // separate from CHANNEL_CONTENT_KEY_MAP/CHANNEL_DELIVERY_KEY_MAP below, which
49
+ // are the legacy messageMeta payload's keys.
51
50
  export const CCS_CHANNEL_CONTENT_KEY_MAP = {
52
51
  SMS: 'smsMessageContent',
53
52
  EMAIL: 'emailMessageContent',
54
53
  WHATSAPP: 'whatsappMessageContent',
55
- MPUSH: 'mPushMessageContent',
54
+ MPUSH: 'mpushMessageContent',
56
55
  INAPP: 'inAppMessageContent',
57
56
  ANDROID: 'androidMessageContent',
58
57
  IOS: 'iosMessageContent',
@@ -67,7 +66,7 @@ export const CCS_CHANNEL_DELIVERY_KEY_MAP = {
67
66
  SMS: 'smsDeliverySettings',
68
67
  EMAIL: 'emailDeliverySettings',
69
68
  WHATSAPP: 'whatsappDeliverySettings',
70
- MPUSH: 'mPushDeliverySettings',
69
+ MPUSH: 'mpushDeliverySettings',
71
70
  INAPP: 'inAppDeliverySettings',
72
71
  ANDROID: 'androidDeliverySettings',
73
72
  IOS: 'iosDeliverySettings',
@@ -78,6 +77,14 @@ export const CCS_CHANNEL_DELIVERY_KEY_MAP = {
78
77
  RCS: 'rcsDeliverySettings',
79
78
  };
80
79
 
80
+ // The UI's own internal channel identifier for mobile push is 'MOBILEPUSH'
81
+ // (see CreativesContainer/constants.js MOBILE_PUSH), but CCS's channel enum
82
+ // only recognises 'MPUSH' (globals.js CCS_CHANNELS) — normalize before
83
+ // building the CCS payload. Every other channel identifier matches CCS as-is.
84
+ export const CCS_CHANNEL_NAME_MAP = {
85
+ MOBILEPUSH: 'MPUSH',
86
+ };
87
+
81
88
  // Channel config - single source of truth for CreativesContainer and TemplatesV2
82
89
  // paneKey: TemplatesV2 defaultPanes object key (for channelsToHide)
83
90
  // channelProp: CreativesContainer channel prop (must match pane.key for tab to be active)