@capillarytech/creatives-library 9.0.54-alpha.4 → 9.0.54

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.
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
2
 
3
3
  jest.mock('../../../services/api', () => ({
4
- createCommDefinition: jest.fn(),
5
- editCommDefinition: jest.fn(),
4
+ createCentralCommsMetaId: jest.fn(),
5
+ getCentralCommsMetaIds: jest.fn(),
6
6
  }));
7
7
 
8
8
  jest.mock('../../CreativesContainer', () => function MockCreativesContainer({
@@ -38,7 +38,7 @@ import { IntlProvider } from 'react-intl';
38
38
  import history from '../../../utils/history';
39
39
  import { initialReducer } from '../../../initialReducer';
40
40
  import CommunicationFlow from '../CommunicationFlow';
41
- import { createCommDefinition, editCommDefinition } from '../../../services/api';
41
+ import { createCentralCommsMetaId, getCentralCommsMetaIds } from '../../../services/api';
42
42
  import { getEnabledSteps } from '../utils/getEnabledSteps';
43
43
  import {
44
44
  CHANNELS,
@@ -359,241 +359,82 @@ describe('isSaveDisabled', () => {
359
359
  });
360
360
 
361
361
  describe('handleSave — CCS flow', () => {
362
- const ccsConfig = { ...baseConfig, context: { name: 'Order Placed Notification' }, features: {} };
363
-
364
362
  beforeEach(() => {
365
- createCommDefinition.mockResolvedValue({
366
- response: { data: { id: 'cd_123', referenceId: 'ORDER_PLACED_123', status: 'DRAFT', version: { version: 1 } } },
367
- });
363
+ createCentralCommsMetaId.mockResolvedValue({ response: { data: { id: 'meta-123' } } });
364
+ getCentralCommsMetaIds.mockResolvedValue({ response: { data: {} } });
368
365
  });
369
366
 
370
367
  afterEach(() => {
371
368
  jest.clearAllMocks();
372
369
  });
373
370
 
374
- it('calls createCommDefinition with a SINGLE-strategy payload when useCCS is not false', async () => {
371
+ it('calls createCentralCommsMetaId for each content item when useCCS is not false', async () => {
375
372
  const onSave = jest.fn();
376
373
  renderWithFlow({
377
374
  features: {},
378
- config: ccsConfig,
379
375
  initialData: {
380
- contentItems: [{ channel: 'sms', templateData: { message: 'Hello' } }],
376
+ contentItems: [{ channel: 'sms', templateData: { smsBody: 'Hello' } }],
381
377
  },
382
378
  onSave,
383
379
  });
384
380
 
385
381
  await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
386
382
 
387
- await waitFor(() => expect(createCommDefinition).toHaveBeenCalledTimes(1));
388
- expect(createCommDefinition).toHaveBeenCalledWith(
383
+ await waitFor(() => expect(createCentralCommsMetaId).toHaveBeenCalledTimes(1));
384
+ expect(createCentralCommsMetaId).toHaveBeenCalledWith(
389
385
  expect.objectContaining({
390
- name: 'Order Placed Notification',
391
- strategyType: 'SINGLE',
392
- singleChannelStrategy: expect.objectContaining({
393
- variant: expect.objectContaining({
394
- channel: 'SMS',
395
- smsMessageContent: { channel: 'SMS', message: 'Hello' },
396
- }),
397
- }),
386
+ centralCommsPayload: expect.objectContaining({ channel: 'SMS', module: 'CAMPAIGNS' }),
398
387
  }),
399
388
  );
400
389
  expect(onSave).toHaveBeenCalledTimes(1);
401
390
  });
402
391
 
403
- it('transforms EMAIL content from the legacy editor shape (emailSubject) to CCS\'s messageSubject', async () => {
404
- const onSave = jest.fn();
392
+ it('calls getCentralCommsMetaIds when metaIds are returned from createCentralCommsMetaId', async () => {
405
393
  renderWithFlow({
406
394
  features: {},
407
- config: ccsConfig,
408
- initialData: {
409
- contentItems: [{
410
- channel: 'EMAIL',
411
- templateData: { emailSubject: 'Order Confirmed', emailBody: '<html>Hi</html>' },
412
- }],
413
- },
414
- onSave,
395
+ initialData: { contentItems: [{ channel: 'EMAIL', templateData: {} }] },
415
396
  });
416
397
 
417
398
  await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
418
399
 
419
- await waitFor(() => expect(createCommDefinition).toHaveBeenCalledTimes(1));
420
- expect(createCommDefinition).toHaveBeenCalledWith(
421
- expect.objectContaining({
422
- singleChannelStrategy: expect.objectContaining({
423
- variant: expect.objectContaining({
424
- channel: 'EMAIL',
425
- emailMessageContent: {
426
- channel: 'EMAIL',
427
- messageSubject: 'Order Confirmed',
428
- messageBody: '<html>Hi</html>',
429
- },
430
- }),
431
- }),
432
- }),
433
- );
400
+ await waitFor(() => expect(getCentralCommsMetaIds).toHaveBeenCalledWith('meta-123'));
434
401
  });
435
402
 
436
- it('transforms WEBPUSH content from the legacy editor\'s messageContent.content wrapping to CCS\'s flat shape', async () => {
437
- const onSave = jest.fn();
438
- const cta = { type: 'SITE_URL', actionLink: 'https://example.com' };
439
- const expandableDetails = { media: [{ url: 'https://example.com/banner.png', type: 'IMAGE' }], ctas: [] };
403
+ it('skips getCentralCommsMetaIds when response contains no id', async () => {
404
+ createCentralCommsMetaId.mockResolvedValue({ response: { data: {} } });
440
405
  renderWithFlow({
441
406
  features: {},
442
- config: ccsConfig,
443
- initialData: {
444
- contentItems: [{
445
- channel: 'WEBPUSH',
446
- templateData: {
447
- messageContent: {
448
- content: {
449
- channel: 'WEBPUSH',
450
- accountId: 13792,
451
- content: { title: 'Hi', message: 'Body', iconImageUrl: 'https://example.com/icon.png', cta, expandableDetails },
452
- messageSubject: 'Subject',
453
- offers: [],
454
- },
455
- },
456
- },
457
- }],
458
- },
459
- onSave,
460
- });
461
-
462
- await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
463
-
464
- await waitFor(() => expect(createCommDefinition).toHaveBeenCalledTimes(1));
465
- expect(createCommDefinition).toHaveBeenCalledWith(
466
- expect.objectContaining({
467
- singleChannelStrategy: expect.objectContaining({
468
- variant: expect.objectContaining({
469
- channel: 'WEBPUSH',
470
- webPushMessageContent: {
471
- channel: 'WEBPUSH',
472
- messageSubject: 'Subject',
473
- accountId: 13792,
474
- content: { title: 'Hi', message: 'Body', iconImageUrl: 'https://example.com/icon.png', cta, expandableDetails },
475
- },
476
- }),
477
- }),
478
- }),
479
- );
480
- });
481
-
482
- it('normalizes the internal MOBILEPUSH channel to CCS\'s PUSH enum (keys stay mpush*), even when templateData/channelSetting carry their own stray channel field', async () => {
483
- const onSave = jest.fn();
484
- renderWithFlow({
485
- features: {},
486
- config: ccsConfig,
487
- initialData: {
488
- // `channel: 'MOBILEPUSH'` inline on templateData reproduces the real
489
- // production bug: contentItem.templateData carries the UI's own
490
- // internal channel identifier, which must not win over the
491
- // normalized 'PUSH' enum once spread into mpushMessageContent.
492
- contentItems: [{ channel: 'MOBILEPUSH', templateData: { channel: 'MOBILEPUSH', messageSubject: 'Hi' } }],
493
- // Likewise, deliverySetting.channelSetting.PUSH carrying its own
494
- // stray `channel` key must not win over the normalized value once
495
- // spread into mpushDeliverySettings.channelSettings.
496
- deliverySetting: { channelSetting: { PUSH: { channel: 'MOBILEPUSH', domainId: 2002 } } },
497
- },
498
- onSave,
499
- });
500
-
501
- await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
502
-
503
- await waitFor(() => expect(createCommDefinition).toHaveBeenCalledTimes(1));
504
- expect(createCommDefinition).toHaveBeenCalledWith(
505
- expect.objectContaining({
506
- singleChannelStrategy: expect.objectContaining({
507
- variant: expect.objectContaining({
508
- channel: 'PUSH',
509
- mpushMessageContent: { channel: 'PUSH', messageSubject: 'Hi' },
510
- mpushDeliverySettings: {
511
- channelSettings: { channel: 'PUSH', domainId: 2002 },
512
- },
513
- }),
514
- }),
515
- }),
516
- );
517
- });
518
-
519
- it('merges ccsCommDefinition into the data passed to onSave when create succeeds', async () => {
520
- const onSave = jest.fn();
521
- renderWithFlow({
522
- features: {},
523
- config: ccsConfig,
524
407
  initialData: { contentItems: [{ channel: 'SMS', templateData: {} }] },
525
- onSave,
526
408
  });
527
409
 
528
410
  await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
529
411
 
530
- await waitFor(() => expect(onSave).toHaveBeenCalledTimes(1));
531
- expect(onSave).toHaveBeenCalledWith(
532
- expect.objectContaining({
533
- ccsCommDefinition: { id: 'cd_123', referenceId: 'ORDER_PLACED_123', version: 1, status: 'DRAFT' },
534
- }),
535
- );
412
+ await waitFor(() => expect(createCentralCommsMetaId).toHaveBeenCalled());
413
+ expect(getCentralCommsMetaIds).not.toHaveBeenCalled();
536
414
  });
537
415
 
538
- it('preserves a real version of 0 from CCS (not coerced to 1 by a falsy-zero fallback)', async () => {
539
- const onSave = jest.fn();
540
- createCommDefinition.mockResolvedValueOnce({
541
- response: { data: { id: 'cd_123', referenceId: 'ORDER_PLACED_123', status: 'DRAFT', version: { version: 0 } } },
542
- });
416
+ it('uses ouId and module from config.context when provided', async () => {
543
417
  renderWithFlow({
544
418
  features: {},
545
- config: ccsConfig,
419
+ config: { ...baseConfig, context: { ouId: 42, module: 'LOYALTY' }, features: {} },
546
420
  initialData: { contentItems: [{ channel: 'SMS', templateData: {} }] },
547
- onSave,
548
421
  });
549
422
 
550
423
  await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
551
424
 
552
- await waitFor(() => expect(onSave).toHaveBeenCalledTimes(1));
553
- expect(onSave).toHaveBeenCalledWith(
425
+ await waitFor(() => expect(createCentralCommsMetaId).toHaveBeenCalled());
426
+ expect(createCentralCommsMetaId).toHaveBeenCalledWith(
554
427
  expect.objectContaining({
555
- ccsCommDefinition: { id: 'cd_123', referenceId: 'ORDER_PLACED_123', version: 0, status: 'DRAFT' },
428
+ centralCommsPayload: expect.objectContaining({ ouId: 42, module: 'LOYALTY' }),
556
429
  }),
557
430
  );
558
431
  });
559
432
 
560
- it('generates a referenceId from name when config.context.referenceId is absent', async () => {
561
- // moduleMocks.js spies on Date.now globally, but this config's resetMocks:true
562
- // clears that return value before every test — set it explicitly here.
563
- jest.spyOn(Date, 'now').mockReturnValue(1612267539410);
564
- renderWithFlow({
565
- features: {},
566
- config: ccsConfig,
567
- initialData: { contentItems: [{ channel: 'SMS', templateData: {} }] },
568
- });
569
-
570
- await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
571
-
572
- await waitFor(() => expect(createCommDefinition).toHaveBeenCalled());
573
- const payload = createCommDefinition.mock.calls[0][0];
574
- expect(payload.referenceId).toBe('ORDER_PLACED_NOTIFICATION_1612267539410');
575
- });
576
-
577
- it('uses config.context.referenceId and description when provided', async () => {
578
- renderWithFlow({
579
- features: {},
580
- config: { ...ccsConfig, context: { ...ccsConfig.context, referenceId: 'ORDER_PLACED', description: 'desc' } },
581
- initialData: { contentItems: [{ channel: 'SMS', templateData: {} }] },
582
- });
583
-
584
- await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
585
-
586
- await waitFor(() => expect(createCommDefinition).toHaveBeenCalled());
587
- expect(createCommDefinition).toHaveBeenCalledWith(
588
- expect.objectContaining({ referenceId: 'ORDER_PLACED', description: 'desc' }),
589
- );
590
- });
591
-
592
433
  it('skips CCS entirely when useCCS is false', async () => {
593
434
  const onSave = jest.fn();
594
435
  renderWithFlow({
595
436
  features: {},
596
- config: { ...ccsConfig, useCCS: false },
437
+ config: { ...baseConfig, useCCS: false, features: {} },
597
438
  initialData: { contentItems: [{ channel: 'SMS', templateData: {} }] },
598
439
  onSave,
599
440
  });
@@ -601,15 +442,14 @@ describe('handleSave — CCS flow', () => {
601
442
  await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
602
443
 
603
444
  await waitFor(() => expect(onSave).toHaveBeenCalledTimes(1));
604
- expect(createCommDefinition).not.toHaveBeenCalled();
605
- expect(onSave).toHaveBeenCalledWith(expect.not.objectContaining({ ccsCommDefinition: expect.anything() }));
445
+ expect(createCentralCommsMetaId).not.toHaveBeenCalled();
606
446
  });
607
447
 
608
- it('skips createCommDefinition when config.context.name is absent (mandatory)', async () => {
448
+ it('still calls onSave when createCentralCommsMetaId rejects', async () => {
449
+ createCentralCommsMetaId.mockRejectedValue(new Error('Network error'));
609
450
  const onSave = jest.fn();
610
451
  renderWithFlow({
611
452
  features: {},
612
- config: { ...baseConfig, features: {} },
613
453
  initialData: { contentItems: [{ channel: 'SMS', templateData: {} }] },
614
454
  onSave,
615
455
  });
@@ -617,70 +457,12 @@ describe('handleSave — CCS flow', () => {
617
457
  await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
618
458
 
619
459
  await waitFor(() => expect(onSave).toHaveBeenCalledTimes(1));
620
- expect(createCommDefinition).not.toHaveBeenCalled();
621
- });
622
-
623
- it('skips createCommDefinition for multi-channel strategies (CHANNEL_PRIORITY/AB_TEST)', async () => {
624
- const onSave = jest.fn();
625
- renderWithFlow({
626
- features: {},
627
- config: ccsConfig,
628
- initialData: {
629
- communicationStrategy: CHANNEL_PRIORITY,
630
- channels: ['SMS', 'EMAIL'],
631
- contentItems: [{ channel: 'SMS', templateData: {} }, { channel: 'EMAIL', templateData: {} }],
632
- },
633
- onSave,
634
- });
635
-
636
- await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
637
-
638
- await waitFor(() => expect(onSave).toHaveBeenCalledTimes(1));
639
- expect(createCommDefinition).not.toHaveBeenCalled();
640
460
  });
641
461
 
642
- it('still calls onSave (without ccsCommDefinition) when createCommDefinition rejects', async () => {
643
- createCommDefinition.mockRejectedValue(new Error('Network error'));
462
+ it('skips createCentralCommsMetaId when contentItems is empty', async () => {
644
463
  const onSave = jest.fn();
645
464
  renderWithFlow({
646
465
  features: {},
647
- config: ccsConfig,
648
- initialData: { contentItems: [{ channel: 'SMS', templateData: {} }] },
649
- onSave,
650
- });
651
-
652
- await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
653
-
654
- await waitFor(() => expect(onSave).toHaveBeenCalledTimes(1));
655
- expect(onSave).toHaveBeenCalledWith(expect.not.objectContaining({ ccsCommDefinition: expect.anything() }));
656
- });
657
-
658
- it('blocks save and shows an error when createCommDefinition resolves with a duplicate REFERENCE_ID_EXISTS conflict', async () => {
659
- createCommDefinition.mockResolvedValue({
660
- success: false,
661
- status: { isError: true, code: 409, message: 'REFERENCE_ID_EXISTS' },
662
- message: 'REFERENCE_ID_EXISTS',
663
- });
664
- const onSave = jest.fn();
665
- renderWithFlow({
666
- features: {},
667
- config: ccsConfig,
668
- initialData: { contentItems: [{ channel: 'SMS', templateData: {} }] },
669
- onSave,
670
- });
671
-
672
- await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
673
-
674
- await waitFor(() => expect(createCommDefinition).toHaveBeenCalledTimes(1));
675
- expect(await screen.findByText(/already in use in your organization/i)).toBeInTheDocument();
676
- expect(onSave).not.toHaveBeenCalled();
677
- });
678
-
679
- it('skips createCommDefinition when contentItems is empty', async () => {
680
- const onSave = jest.fn();
681
- renderWithFlow({
682
- features: {},
683
- config: ccsConfig,
684
466
  initialData: { contentItems: [] },
685
467
  onSave,
686
468
  });
@@ -688,13 +470,12 @@ describe('handleSave — CCS flow', () => {
688
470
  await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
689
471
 
690
472
  await waitFor(() => expect(onSave).toHaveBeenCalledTimes(1));
691
- expect(createCommDefinition).not.toHaveBeenCalled();
473
+ expect(createCentralCommsMetaId).not.toHaveBeenCalled();
692
474
  });
693
475
 
694
- it('places additionalSettings derived from dynamicControls under settings.additionalSettings (not delivery settings)', async () => {
476
+ it('includes additionalSettings derived from dynamicControls in the payload', async () => {
695
477
  renderWithFlow({
696
478
  features: {},
697
- config: ccsConfig,
698
479
  initialData: {
699
480
  contentItems: [{ channel: 'SMS', templateData: {} }],
700
481
  dynamicControls: {
@@ -708,116 +489,14 @@ describe('handleSave — CCS flow', () => {
708
489
 
709
490
  await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
710
491
 
711
- await waitFor(() => expect(createCommDefinition).toHaveBeenCalled());
712
- const payload = createCommDefinition.mock.calls[0][0];
713
- expect(payload.settings.additionalSettings).toEqual({
492
+ await waitFor(() => expect(createCentralCommsMetaId).toHaveBeenCalled());
493
+ const payload = createCentralCommsMetaId.mock.calls[0][0];
494
+ expect(payload.centralCommsPayload.smsDeliverySettings.additionalSettings).toEqual({
714
495
  useTinyUrl: true,
715
496
  encryptUrl: true,
716
497
  linkTrackingEnabled: true,
717
498
  userSubscriptionDisabled: true,
718
499
  });
719
- expect(payload.singleChannelStrategy.variant.smsDeliverySettings.additionalSettings).toBeUndefined();
720
- });
721
-
722
- it('includes channelSettings from deliverySetting.channelSetting in the payload', async () => {
723
- renderWithFlow({
724
- features: {},
725
- config: ccsConfig,
726
- initialData: {
727
- contentItems: [{ channel: 'SMS', templateData: {} }],
728
- deliverySetting: { channelSetting: { SMS: { domainId: 1001, gsmSenderId: 'BRAND1' } } },
729
- },
730
- });
731
-
732
- await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
733
-
734
- await waitFor(() => expect(createCommDefinition).toHaveBeenCalled());
735
- const payload = createCommDefinition.mock.calls[0][0];
736
- expect(payload.singleChannelStrategy.variant.smsDeliverySettings.channelSettings).toEqual({
737
- channel: 'SMS',
738
- domainId: 1001,
739
- gsmSenderId: 'BRAND1',
740
- });
741
- });
742
-
743
- it('does not call editCommDefinition when config.context.existingCommDefinitionId is absent', async () => {
744
- const onSave = jest.fn();
745
- renderWithFlow({
746
- features: {},
747
- config: ccsConfig,
748
- initialData: { contentItems: [{ channel: 'SMS', templateData: {} }] },
749
- onSave,
750
- });
751
-
752
- await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
753
-
754
- await waitFor(() => expect(createCommDefinition).toHaveBeenCalledTimes(1));
755
- expect(editCommDefinition).not.toHaveBeenCalled();
756
- });
757
-
758
- it('calls editCommDefinition (not createCommDefinition) and merges the existing id into ccsCommDefinition when config.context.existingCommDefinitionId is set', async () => {
759
- editCommDefinition.mockResolvedValue({
760
- response: { data: { version: { version: 2 }, status: 'DRAFT' } },
761
- });
762
- const onSave = jest.fn();
763
- renderWithFlow({
764
- features: {},
765
- config: {
766
- ...ccsConfig,
767
- context: { ...ccsConfig.context, referenceId: 'ORDER_PLACED', existingCommDefinitionId: 'cd_existing_1' },
768
- },
769
- initialData: { contentItems: [{ channel: 'SMS', templateData: {} }] },
770
- onSave,
771
- });
772
-
773
- await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
774
-
775
- await waitFor(() => expect(editCommDefinition).toHaveBeenCalledTimes(1));
776
- expect(editCommDefinition).toHaveBeenCalledWith(
777
- 'cd_existing_1',
778
- expect.objectContaining({
779
- strategyType: 'SINGLE',
780
- settings: expect.anything(),
781
- singleChannelStrategy: expect.anything(),
782
- }),
783
- );
784
- expect(createCommDefinition).not.toHaveBeenCalled();
785
-
786
- await waitFor(() => expect(onSave).toHaveBeenCalledTimes(1));
787
- expect(onSave).toHaveBeenCalledWith(
788
- expect.objectContaining({
789
- ccsCommDefinition: {
790
- id: 'cd_existing_1',
791
- referenceId: 'ORDER_PLACED',
792
- version: 2,
793
- status: 'DRAFT',
794
- },
795
- }),
796
- );
797
- });
798
-
799
- it('blocks save and shows an error when editCommDefinition resolves with a duplicate REFERENCE_ID_EXISTS conflict', async () => {
800
- editCommDefinition.mockResolvedValue({
801
- success: false,
802
- status: { isError: true, code: 409, message: 'REFERENCE_ID_EXISTS' },
803
- message: 'REFERENCE_ID_EXISTS',
804
- });
805
- const onSave = jest.fn();
806
- renderWithFlow({
807
- features: {},
808
- config: {
809
- ...ccsConfig,
810
- context: { ...ccsConfig.context, referenceId: 'ORDER_PLACED', existingCommDefinitionId: 'cd_existing_1' },
811
- },
812
- initialData: { contentItems: [{ channel: 'SMS', templateData: {} }] },
813
- onSave,
814
- });
815
-
816
- await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
817
-
818
- await waitFor(() => expect(editCommDefinition).toHaveBeenCalledTimes(1));
819
- expect(await screen.findByText(/already in use in your organization/i)).toBeInTheDocument();
820
- expect(onSave).not.toHaveBeenCalled();
821
500
  });
822
501
  });
823
502
 
@@ -873,34 +552,39 @@ describe('optional chaining safety', () => {
873
552
  jest.clearAllMocks();
874
553
  });
875
554
 
876
- it('does not crash and skips CCS when config.context is entirely absent', async () => {
877
- const onSave = jest.fn();
555
+ it('defaults ouId to -1 when config.context is absent', async () => {
556
+ createCentralCommsMetaId.mockResolvedValue({ response: { data: { id: 'x' } } });
878
557
  renderWithFlow({
879
558
  features: {},
880
- config: { ...baseConfig, features: {} },
881
559
  initialData: { contentItems: [{ channel: 'SMS', templateData: {} }] },
882
- onSave,
883
560
  });
884
561
 
885
562
  await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
886
563
 
887
- await waitFor(() => expect(onSave).toHaveBeenCalledTimes(1));
888
- expect(createCommDefinition).not.toHaveBeenCalled();
564
+ await waitFor(() => expect(createCentralCommsMetaId).toHaveBeenCalled());
565
+ expect(createCentralCommsMetaId).toHaveBeenCalledWith(
566
+ expect.objectContaining({
567
+ centralCommsPayload: expect.objectContaining({ ouId: -1 }),
568
+ }),
569
+ );
889
570
  });
890
571
 
891
- it('does not crash when config.context is present but empty', async () => {
892
- const onSave = jest.fn();
572
+ it('defaults module to consumer.toUpperCase() when config.context.module absent', async () => {
573
+ createCentralCommsMetaId.mockResolvedValue({ response: { data: { id: 'x' } } });
893
574
  renderWithFlow({
894
575
  features: {},
895
- config: { ...baseConfig, context: {}, features: {} },
576
+ config: { ...baseConfig, consumer: 'loyalty', features: {} },
896
577
  initialData: { contentItems: [{ channel: 'SMS', templateData: {} }] },
897
- onSave,
898
578
  });
899
579
 
900
580
  await userEvent.click(screen.getByRole('button', { name: /^save$/i }));
901
581
 
902
- await waitFor(() => expect(onSave).toHaveBeenCalledTimes(1));
903
- expect(createCommDefinition).not.toHaveBeenCalled();
582
+ await waitFor(() => expect(createCentralCommsMetaId).toHaveBeenCalled());
583
+ expect(createCentralCommsMetaId).toHaveBeenCalledWith(
584
+ expect.objectContaining({
585
+ centralCommsPayload: expect.objectContaining({ module: 'LOYALTY' }),
586
+ }),
587
+ );
904
588
  });
905
589
 
906
590
  it('initializes channel from config.channel when initialData.channel is absent', () => {
@@ -108,22 +108,6 @@ describe('CommunicationFlowCard', () => {
108
108
  fireEvent.click(screen.getByText('Add creatives'));
109
109
  expect(screen.getByTestId('comm-flow-mock')).toHaveAttribute('data-mode', 'create');
110
110
  });
111
-
112
- it('disables the Add creatives button when disabled prop is true', () => {
113
- renderCard({ disabled: true, disabledTooltip: 'Enter an Alert name to add content' });
114
- expect(screen.getByText('Add creatives').closest('button')).toBeDisabled();
115
- });
116
-
117
- it('does not open SlideBox when Add creatives is clicked while disabled', () => {
118
- renderCard({ disabled: true, disabledTooltip: 'Enter an Alert name to add content' });
119
- fireEvent.click(screen.getByText('Add creatives'));
120
- expect(screen.queryByTestId('slide-box')).not.toBeInTheDocument();
121
- });
122
-
123
- it('Add creatives button is enabled by default (disabled prop absent)', () => {
124
- renderCard();
125
- expect(screen.getByText('Add creatives').closest('button')).not.toBeDisabled();
126
- });
127
111
  });
128
112
 
129
113
  describe('configured state (initialData provided)', () => {
@@ -247,11 +231,11 @@ describe('CommunicationFlowCard', () => {
247
231
  expect(screen.getByText(/Sender ID/)).toBeInTheDocument();
248
232
  });
249
233
 
250
- it('shows senderId for EMAIL with Sender ID label', () => {
234
+ it('shows senderEmail for EMAIL with Sender ID label', () => {
251
235
  renderCard({
252
236
  initialData: makeSavedData({
253
237
  contentItems: [{ channel: 'EMAIL', templateData: {} }],
254
- deliverySetting: { channelSetting: { EMAIL: { senderId: 'test@example.com' } } },
238
+ deliverySetting: { channelSetting: { EMAIL: { senderEmail: 'test@example.com' } } },
255
239
  }),
256
240
  });
257
241
  expect(screen.getByText(/test@example.com/)).toBeInTheDocument();