@capillarytech/creatives-library 8.0.277 → 8.0.278
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
|
@@ -688,9 +688,10 @@ const EmailHTMLEditor = (props) => {
|
|
|
688
688
|
return;
|
|
689
689
|
}
|
|
690
690
|
|
|
691
|
-
// 2. Validate Unsubscribe Tag (
|
|
692
|
-
//
|
|
693
|
-
|
|
691
|
+
// 2. Validate Unsubscribe Tag when feature is OFF (when flag is false we require unsubscribe)
|
|
692
|
+
// When EMAIL_UNSUBSCRIBE_TAG_MANDATORY is true: do NOT validate for unsubscribe (aligned with FormBuilder).
|
|
693
|
+
// When EMAIL_UNSUBSCRIBE_TAG_MANDATORY is false: validate and require unsubscribe tag.
|
|
694
|
+
if (!isEmailUnsubscribeTagMandatory() && moduleType === OUTBOUND) {
|
|
694
695
|
// Check if content contains unsubscribe tag (either {{unsubscribe}} or {{unsubscribe(#...)})
|
|
695
696
|
const unsubscribeRegex = /{{unsubscribe(\(#[a-zA-Z\d]{6}\))?}}/g; // eslint-disable-line no-useless-escape
|
|
696
697
|
const hasUnsubscribeTag = unsubscribeRegex.test(htmlContent);
|
|
@@ -709,7 +710,7 @@ const EmailHTMLEditor = (props) => {
|
|
|
709
710
|
if (onValidationFail) {
|
|
710
711
|
onValidationFail();
|
|
711
712
|
}
|
|
712
|
-
// Block save - unsubscribe tag is
|
|
713
|
+
// Block save - unsubscribe tag is required when validation is enabled
|
|
713
714
|
return;
|
|
714
715
|
}
|
|
715
716
|
}
|
|
@@ -386,6 +386,7 @@ const defaultProps = {
|
|
|
386
386
|
isGetFormData: false,
|
|
387
387
|
getFormdata: jest.fn(),
|
|
388
388
|
templateData: null,
|
|
389
|
+
isEditEmail: true,
|
|
389
390
|
EmailLayout: null,
|
|
390
391
|
getLiquidTags: jest.fn((content, callback) => callback({ askAiraResponse: { data: [] }, isError: false })),
|
|
391
392
|
showLiquidErrorInFooter: jest.fn(),
|
|
@@ -642,6 +643,45 @@ describe('EmailHTMLEditor', () => {
|
|
|
642
643
|
// Should trigger fetch for new template ID
|
|
643
644
|
expect(emailActions.getTemplateDetails).toHaveBeenCalled();
|
|
644
645
|
});
|
|
646
|
+
|
|
647
|
+
it('does not fetch template details when isEditEmail is false even if templateData has _id (create flow)', async () => {
|
|
648
|
+
const emailActions = {
|
|
649
|
+
...defaultProps.emailActions,
|
|
650
|
+
getTemplateDetails: jest.fn(),
|
|
651
|
+
};
|
|
652
|
+
renderWithIntl({
|
|
653
|
+
isEditEmail: false,
|
|
654
|
+
templateData: { _id: 'stale-template-id', name: 'Stale' },
|
|
655
|
+
params: {},
|
|
656
|
+
location: { query: {}, pathname: '/email/create' },
|
|
657
|
+
Email: { templateDetails: null, getTemplateDetailsInProgress: false, fetchingCmsData: false },
|
|
658
|
+
emailActions,
|
|
659
|
+
});
|
|
660
|
+
|
|
661
|
+
await waitFor(() => {
|
|
662
|
+
expect(emailActions.getTemplateDetails).not.toHaveBeenCalled();
|
|
663
|
+
}, { timeout: 500 });
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
it('uses templateData._id for currentTemplateId and fetches when isEditEmail is true', async () => {
|
|
667
|
+
const emailActions = {
|
|
668
|
+
...defaultProps.emailActions,
|
|
669
|
+
getTemplateDetails: jest.fn(),
|
|
670
|
+
};
|
|
671
|
+
const templateId = 'edit-template-id';
|
|
672
|
+
renderWithIntl({
|
|
673
|
+
isEditEmail: true,
|
|
674
|
+
templateData: { _id: templateId, name: 'Edit Template' },
|
|
675
|
+
params: {},
|
|
676
|
+
location: { query: {}, pathname: '/email/create' },
|
|
677
|
+
Email: { templateDetails: null, getTemplateDetailsInProgress: false, fetchingCmsData: false },
|
|
678
|
+
emailActions,
|
|
679
|
+
});
|
|
680
|
+
|
|
681
|
+
await waitFor(() => {
|
|
682
|
+
expect(emailActions.getTemplateDetails).toHaveBeenCalledWith(templateId, 'email');
|
|
683
|
+
}, { timeout: 500 });
|
|
684
|
+
});
|
|
645
685
|
});
|
|
646
686
|
|
|
647
687
|
describe('Subject Handling', () => {
|
|
@@ -976,8 +1016,9 @@ describe('EmailHTMLEditor', () => {
|
|
|
976
1016
|
}, { timeout: 3000 });
|
|
977
1017
|
});
|
|
978
1018
|
|
|
979
|
-
it('blocks save when unsubscribe
|
|
980
|
-
|
|
1019
|
+
it('blocks save when unsubscribe validation is on (flag false) and tag is missing', async () => {
|
|
1020
|
+
// When EMAIL_UNSUBSCRIBE_TAG_MANDATORY is false we validate and require unsubscribe
|
|
1021
|
+
isEmailUnsubscribeTagMandatory.mockReturnValue(false);
|
|
981
1022
|
const onValidationFail = jest.fn();
|
|
982
1023
|
const CapNotification = require('@capillarytech/cap-ui-library/CapNotification');
|
|
983
1024
|
|
|
@@ -1005,15 +1046,15 @@ describe('EmailHTMLEditor', () => {
|
|
|
1005
1046
|
}, { timeout: 3000 });
|
|
1006
1047
|
});
|
|
1007
1048
|
|
|
1008
|
-
it('allows save when unsubscribe tag is present', () => {
|
|
1009
|
-
isEmailUnsubscribeTagMandatory.mockReturnValue(
|
|
1049
|
+
it('allows save when unsubscribe validation is on and tag is present', () => {
|
|
1050
|
+
isEmailUnsubscribeTagMandatory.mockReturnValue(false);
|
|
1010
1051
|
renderWithIntl({
|
|
1011
1052
|
isGetFormData: true,
|
|
1012
1053
|
subject: 'Valid Subject',
|
|
1013
1054
|
htmlContent: '<p>Content {{unsubscribe}}</p>',
|
|
1014
1055
|
moduleType: 'OUTBOUND',
|
|
1015
1056
|
});
|
|
1016
|
-
// Should proceed with save
|
|
1057
|
+
// Should proceed with save (validation passes)
|
|
1017
1058
|
});
|
|
1018
1059
|
|
|
1019
1060
|
it('blocks save for non-liquid orgs when tag validation fails', async () => {
|
|
@@ -1025,6 +1025,32 @@ describe('useEmailWrapper', () => {
|
|
|
1025
1025
|
expect(mockEmailActions.getTemplateDetails).not.toHaveBeenCalled();
|
|
1026
1026
|
}, { timeout: 1000 });
|
|
1027
1027
|
});
|
|
1028
|
+
|
|
1029
|
+
it('should NOT call getTemplateDetails when isEditEmail is false (create flow)', async () => {
|
|
1030
|
+
const templateId = 'create-flow-id';
|
|
1031
|
+
const createFlowProps = {
|
|
1032
|
+
...newFlowMockProps,
|
|
1033
|
+
isEditEmail: false,
|
|
1034
|
+
params: { id: templateId },
|
|
1035
|
+
location: {
|
|
1036
|
+
pathname: `/email/edit/${templateId}`,
|
|
1037
|
+
query: { id: templateId },
|
|
1038
|
+
},
|
|
1039
|
+
Email: {
|
|
1040
|
+
...newFlowMockProps.Email,
|
|
1041
|
+
templateDetails: null,
|
|
1042
|
+
getTemplateDetailsInProgress: false,
|
|
1043
|
+
},
|
|
1044
|
+
};
|
|
1045
|
+
|
|
1046
|
+
renderHook((props) => useEmailWrapper(props), {
|
|
1047
|
+
initialProps: createFlowProps,
|
|
1048
|
+
});
|
|
1049
|
+
|
|
1050
|
+
await waitFor(() => {
|
|
1051
|
+
expect(mockEmailActions.getTemplateDetails).not.toHaveBeenCalled();
|
|
1052
|
+
}, { timeout: 1000 });
|
|
1053
|
+
});
|
|
1028
1054
|
});
|
|
1029
1055
|
});
|
|
1030
1056
|
|