@capillarytech/creatives-library 8.0.295 → 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/DeliverySettings.scss +33 -0
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +425 -0
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.scss +36 -0
- package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +92 -0
- package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +251 -0
- package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +111 -0
- package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +88 -0
- package/v2Components/CommonTestAndPreview/SendTestMessage.js +51 -1
- package/v2Components/CommonTestAndPreview/actions.js +20 -0
- package/v2Components/CommonTestAndPreview/constants.js +15 -0
- package/v2Components/CommonTestAndPreview/index.js +200 -16
- package/v2Components/CommonTestAndPreview/reducer.js +47 -0
- package/v2Components/CommonTestAndPreview/sagas.js +61 -0
- package/v2Components/CommonTestAndPreview/selectors.js +51 -0
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +889 -0
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +222 -0
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +235 -0
- package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +135 -0
- package/v2Components/CommonTestAndPreview/tests/actions.test.js +50 -0
- package/v2Components/CommonTestAndPreview/tests/constants.test.js +18 -0
- package/v2Components/CommonTestAndPreview/tests/index.test.js +783 -2
- package/v2Components/CommonTestAndPreview/tests/reducer.test.js +118 -0
- package/v2Components/CommonTestAndPreview/tests/sagas.test.js +145 -0
- package/v2Components/CommonTestAndPreview/tests/selectors.test.js +146 -0
- package/v2Components/FormBuilder/index.js +1 -1
- package/v2Components/HtmlEditor/HTMLEditor.js +0 -1
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +0 -1
- package/v2Components/HtmlEditor/hooks/__tests__/useValidation.test.js +3 -132
- package/v2Components/HtmlEditor/hooks/useValidation.js +9 -12
- package/v2Components/HtmlEditor/utils/htmlValidator.js +2 -4
- package/v2Components/TestAndPreviewSlidebox/index.js +14 -0
- package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +2 -2
- package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +18 -110
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +697 -12
- package/v2Containers/SmsTrai/Edit/index.js +5 -1
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +201 -0
- package/v2Containers/Whatsapp/index.js +1 -1
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +26242 -4225
|
@@ -77,7 +77,6 @@ export const useValidation = (content, variant = 'email', options = {}, formatSa
|
|
|
77
77
|
enableSanitization = true,
|
|
78
78
|
securityLevel = 'standard',
|
|
79
79
|
apiValidationErrors = null, // API validation errors from validateLiquidTemplateContent
|
|
80
|
-
isFullMode = false, // When true, skip liquid validation (standalone/full mode)
|
|
81
80
|
} = options;
|
|
82
81
|
|
|
83
82
|
// Validation state
|
|
@@ -138,7 +137,7 @@ export const useValidation = (content, variant = 'email', options = {}, formatSa
|
|
|
138
137
|
|
|
139
138
|
try {
|
|
140
139
|
// 1. HTML Validation
|
|
141
|
-
const htmlValidation = validateHTML(htmlContent, variant, formatValidatorMessage
|
|
140
|
+
const htmlValidation = validateHTML(htmlContent, variant, formatValidatorMessage);
|
|
142
141
|
|
|
143
142
|
// 2. CSS Validation (extract from HTML)
|
|
144
143
|
const cssValidation = extractAndValidateCSS(htmlContent, formatValidatorMessage);
|
|
@@ -207,7 +206,7 @@ export const useValidation = (content, variant = 'email', options = {}, formatSa
|
|
|
207
206
|
},
|
|
208
207
|
}));
|
|
209
208
|
}
|
|
210
|
-
}, [variant, enableSanitization, securityLevel, formatSanitizerMessage, formatValidatorMessage
|
|
209
|
+
}, [variant, enableSanitization, securityLevel, formatSanitizerMessage, formatValidatorMessage]);
|
|
211
210
|
|
|
212
211
|
/**
|
|
213
212
|
* Validates content with debouncing
|
|
@@ -340,7 +339,7 @@ export const useValidation = (content, variant = 'email', options = {}, formatSa
|
|
|
340
339
|
*/
|
|
341
340
|
const getAllIssues = useCallback(() => {
|
|
342
341
|
// API errors (liquid + standard) are blocking – they block Save/Update/Preview/Test
|
|
343
|
-
const apiLiquidErrors = (
|
|
342
|
+
const apiLiquidErrors = (apiValidationErrors?.liquidErrors || []).map((errorMessage) => {
|
|
344
343
|
const extractedLine = extractLineNumberFromMessage(errorMessage);
|
|
345
344
|
return {
|
|
346
345
|
type: VALIDATION_SEVERITY.ERROR,
|
|
@@ -421,20 +420,19 @@ export const useValidation = (content, variant = 'email', options = {}, formatSa
|
|
|
421
420
|
|
|
422
421
|
// Ensure we always return an array
|
|
423
422
|
return Array.isArray(allIssues) ? allIssues : [];
|
|
424
|
-
}, [validationState, apiValidationErrors, extractLineNumberFromMessage, content
|
|
423
|
+
}, [validationState, apiValidationErrors, extractLineNumberFromMessage, content]);
|
|
425
424
|
|
|
426
425
|
/**
|
|
427
426
|
* Check if validation is clean (no errors or warnings)
|
|
428
427
|
* Includes API validation errors in the check
|
|
429
428
|
*/
|
|
430
429
|
const isClean = useCallback(() => {
|
|
431
|
-
const
|
|
432
|
-
const hasApiErrors = liquidErrorCount + (apiValidationErrors?.standardErrors?.length || 0) > 0;
|
|
430
|
+
const hasApiErrors = (apiValidationErrors?.liquidErrors?.length || 0) + (apiValidationErrors?.standardErrors?.length || 0) > 0;
|
|
433
431
|
return validationState.summary.totalErrors === 0
|
|
434
432
|
&& validationState.summary.totalWarnings === 0
|
|
435
433
|
&& !validationState.summary.hasSecurityIssues
|
|
436
434
|
&& !hasApiErrors;
|
|
437
|
-
}, [validationState.summary, apiValidationErrors
|
|
435
|
+
}, [validationState.summary, apiValidationErrors]);
|
|
438
436
|
|
|
439
437
|
// Effect to validate content when it changes
|
|
440
438
|
useEffect(() => {
|
|
@@ -450,12 +448,11 @@ export const useValidation = (content, variant = 'email', options = {}, formatSa
|
|
|
450
448
|
}
|
|
451
449
|
}, []);
|
|
452
450
|
|
|
453
|
-
const
|
|
454
|
-
const hasApiErrors = hasApiLiquidErrors || (apiValidationErrors?.standardErrors?.length || 0) > 0;
|
|
451
|
+
const hasApiErrors = (apiValidationErrors?.liquidErrors?.length || 0) + (apiValidationErrors?.standardErrors?.length || 0) > 0;
|
|
455
452
|
|
|
456
453
|
const protocolTypes = ['JavaScript Protocol', 'Data URL', 'VBScript Protocol'];
|
|
457
|
-
// Client-side Liquid validation errors are blocking (genuine syntax errors)
|
|
458
|
-
const hasClientSideLiquidErrors =
|
|
454
|
+
// Client-side Liquid validation errors are blocking (genuine syntax errors)
|
|
455
|
+
const hasClientSideLiquidErrors = (validationState.htmlErrors || []).some((e) => e.source === ISSUE_SOURCES.LIQUID && e.severity === VALIDATION_SEVERITY.ERROR);
|
|
459
456
|
const hasBlockingErrors = (validationState.sanitizationWarnings || []).some((w) => BLOCKING_ERROR_RULE_IDS.includes(w.rule)) || (validationState.securityIssues || []).some((s) => protocolTypes.includes(s?.type)) || hasApiErrors || hasClientSideLiquidErrors;
|
|
460
457
|
|
|
461
458
|
return {
|
|
@@ -76,7 +76,7 @@ const CUSTOM_VALIDATIONS = {
|
|
|
76
76
|
* @param {Function} formatMessage - Message formatter function for internationalization
|
|
77
77
|
* @returns {Object} Validation result with errors and warnings
|
|
78
78
|
*/
|
|
79
|
-
export const validateHTML = (html, variant = 'email', formatMessage = defaultMessageFormatter
|
|
79
|
+
export const validateHTML = (html, variant = 'email', formatMessage = defaultMessageFormatter) => {
|
|
80
80
|
if (!html || typeof html !== 'string') {
|
|
81
81
|
return {
|
|
82
82
|
isValid: true,
|
|
@@ -133,9 +133,7 @@ export const validateHTML = (html, variant = 'email', formatMessage = defaultMes
|
|
|
133
133
|
// Always run custom validations and Liquid validation, even if HTMLHint failed
|
|
134
134
|
// This ensures unsafe protocol detection and other critical validations still run
|
|
135
135
|
runCustomValidations(html, variant, results, formatMessage);
|
|
136
|
-
|
|
137
|
-
runLiquidValidation(html, variant, results, formatMessage);
|
|
138
|
-
}
|
|
136
|
+
runLiquidValidation(html, variant, results, formatMessage);
|
|
139
137
|
|
|
140
138
|
return results;
|
|
141
139
|
};
|
|
@@ -40,6 +40,9 @@ import {
|
|
|
40
40
|
makeSelectUpdatePreviewErrors,
|
|
41
41
|
makeSelectFetchPrefilledValuesError,
|
|
42
42
|
makeSelectFetchPrefilledValuesErrors,
|
|
43
|
+
makeSelectSenderDetailsByChannel,
|
|
44
|
+
makeSelectWeCrmAccounts,
|
|
45
|
+
makeSelectIsLoadingSenderDetails,
|
|
43
46
|
} from '../CommonTestAndPreview/selectors';
|
|
44
47
|
|
|
45
48
|
/**
|
|
@@ -91,6 +94,10 @@ TestAndPreviewSlidebox.propTypes = {
|
|
|
91
94
|
prefilledValues: PropTypes.object,
|
|
92
95
|
isSendingTestMessage: PropTypes.bool.isRequired,
|
|
93
96
|
intl: PropTypes.object.isRequired,
|
|
97
|
+
senderDetailsByChannel: PropTypes.object,
|
|
98
|
+
wecrmAccounts: PropTypes.array,
|
|
99
|
+
isLoadingSenderDetails: PropTypes.bool,
|
|
100
|
+
orgUnitId: PropTypes.number,
|
|
94
101
|
};
|
|
95
102
|
|
|
96
103
|
TestAndPreviewSlidebox.defaultProps = {
|
|
@@ -102,6 +109,10 @@ TestAndPreviewSlidebox.defaultProps = {
|
|
|
102
109
|
currentTab: 1,
|
|
103
110
|
messageMetaConfigId: null,
|
|
104
111
|
prefilledValues: {},
|
|
112
|
+
senderDetailsByChannel: {},
|
|
113
|
+
wecrmAccounts: [],
|
|
114
|
+
isLoadingSenderDetails: false,
|
|
115
|
+
orgUnitId: -1,
|
|
105
116
|
};
|
|
106
117
|
|
|
107
118
|
const mapStateToProps = createStructuredSelector({
|
|
@@ -122,6 +133,9 @@ const mapStateToProps = createStructuredSelector({
|
|
|
122
133
|
fetchPrefilledValuesError: makeSelectFetchPrefilledValuesError(),
|
|
123
134
|
fetchPrefilledValuesErrors: makeSelectFetchPrefilledValuesErrors(),
|
|
124
135
|
isSendingTestMessage: makeSelectIsSendingTestMessage(),
|
|
136
|
+
senderDetailsByChannel: makeSelectSenderDetailsByChannel(),
|
|
137
|
+
wecrmAccounts: makeSelectWeCrmAccounts(),
|
|
138
|
+
isLoadingSenderDetails: makeSelectIsLoadingSenderDetails(),
|
|
125
139
|
});
|
|
126
140
|
|
|
127
141
|
function mapDispatchToProps(dispatch) {
|
|
@@ -956,8 +956,8 @@ const EmailHTMLEditor = (props) => {
|
|
|
956
956
|
}
|
|
957
957
|
};
|
|
958
958
|
|
|
959
|
-
// If liquid enabled, validate first using extractTags API
|
|
960
|
-
if (isLiquidEnabled && getLiquidTags
|
|
959
|
+
// If liquid enabled, validate first using extractTags API
|
|
960
|
+
if (isLiquidEnabled && getLiquidTags) {
|
|
961
961
|
// Note: API validation errors are already cleared at the start of handleSave
|
|
962
962
|
// This ensures fresh validation on every save attempt
|
|
963
963
|
|
|
@@ -1176,10 +1176,9 @@ describe('EmailHTMLEditor', () => {
|
|
|
1176
1176
|
mockGetAllIssues.mockReturnValue([]);
|
|
1177
1177
|
|
|
1178
1178
|
// Set subject and content via component interactions
|
|
1179
|
-
// Use isFullMode: false (library mode) to test liquid validation path
|
|
1180
1179
|
const { rerender } = renderWithIntl({
|
|
1181
1180
|
isGetFormData: false,
|
|
1182
|
-
isFullMode:
|
|
1181
|
+
isFullMode: true,
|
|
1183
1182
|
metaEntities: {
|
|
1184
1183
|
tags: {
|
|
1185
1184
|
standard: [{ name: 'customer.name' }],
|
|
@@ -1207,7 +1206,7 @@ describe('EmailHTMLEditor', () => {
|
|
|
1207
1206
|
<EmailHTMLEditor
|
|
1208
1207
|
{...defaultProps}
|
|
1209
1208
|
isGetFormData
|
|
1210
|
-
isFullMode
|
|
1209
|
+
isFullMode
|
|
1211
1210
|
metaEntities={{
|
|
1212
1211
|
tags: {
|
|
1213
1212
|
standard: [{ name: 'customer.name' }],
|
|
@@ -1232,10 +1231,9 @@ describe('EmailHTMLEditor', () => {
|
|
|
1232
1231
|
mockGetAllIssues.mockReturnValue([]);
|
|
1233
1232
|
|
|
1234
1233
|
// Set subject and content via component interactions
|
|
1235
|
-
// Use isFullMode: false (library mode) to test liquid validation path
|
|
1236
1234
|
const { rerender } = renderWithIntl({
|
|
1237
1235
|
isGetFormData: false,
|
|
1238
|
-
isFullMode:
|
|
1236
|
+
isFullMode: true,
|
|
1239
1237
|
isLiquidEnabled: true,
|
|
1240
1238
|
getLiquidTags,
|
|
1241
1239
|
});
|
|
@@ -1255,7 +1253,7 @@ describe('EmailHTMLEditor', () => {
|
|
|
1255
1253
|
await act(async () => {
|
|
1256
1254
|
rerender(
|
|
1257
1255
|
<IntlProvider locale="en" messages={{}}>
|
|
1258
|
-
<EmailHTMLEditor {...defaultProps} isGetFormData isFullMode
|
|
1256
|
+
<EmailHTMLEditor {...defaultProps} isGetFormData isFullMode getLiquidTags={getLiquidTags} />
|
|
1259
1257
|
</IntlProvider>
|
|
1260
1258
|
);
|
|
1261
1259
|
});
|
|
@@ -1283,10 +1281,9 @@ describe('EmailHTMLEditor', () => {
|
|
|
1283
1281
|
mockGetAllIssues.mockReturnValue([]);
|
|
1284
1282
|
|
|
1285
1283
|
// Set subject and content via component interactions
|
|
1286
|
-
// Use isFullMode: false (library mode) to test liquid validation path
|
|
1287
1284
|
const { rerender } = renderWithIntl({
|
|
1288
1285
|
isGetFormData: false,
|
|
1289
|
-
isFullMode:
|
|
1286
|
+
isFullMode: true,
|
|
1290
1287
|
isLiquidEnabled: true,
|
|
1291
1288
|
getLiquidTags,
|
|
1292
1289
|
showLiquidErrorInFooter,
|
|
@@ -1308,7 +1305,7 @@ describe('EmailHTMLEditor', () => {
|
|
|
1308
1305
|
await act(async () => {
|
|
1309
1306
|
rerender(
|
|
1310
1307
|
<IntlProvider locale="en" messages={{}}>
|
|
1311
|
-
<EmailHTMLEditor {...defaultProps} isGetFormData isFullMode
|
|
1308
|
+
<EmailHTMLEditor {...defaultProps} isGetFormData isFullMode getLiquidTags={getLiquidTags} showLiquidErrorInFooter={showLiquidErrorInFooter} onValidationFail={onValidationFail} />
|
|
1312
1309
|
</IntlProvider>
|
|
1313
1310
|
);
|
|
1314
1311
|
});
|
|
@@ -1328,7 +1325,13 @@ describe('EmailHTMLEditor', () => {
|
|
|
1328
1325
|
return Promise.resolve(true);
|
|
1329
1326
|
});
|
|
1330
1327
|
|
|
1331
|
-
const
|
|
1328
|
+
const emailActions = {
|
|
1329
|
+
...defaultProps.emailActions,
|
|
1330
|
+
transformEmailTemplate: jest.fn((obj, callback) => callback(obj)),
|
|
1331
|
+
createTemplate: jest.fn((obj, callback) => {
|
|
1332
|
+
callback({ templateId: { _id: '123', versions: {} } });
|
|
1333
|
+
}),
|
|
1334
|
+
};
|
|
1332
1335
|
const getLiquidTags = jest.fn((content, callback) => {
|
|
1333
1336
|
callback({ askAiraResponse: { data: [] }, isError: false });
|
|
1334
1337
|
});
|
|
@@ -1336,12 +1339,12 @@ describe('EmailHTMLEditor', () => {
|
|
|
1336
1339
|
mockGetAllIssues.mockReturnValue([]);
|
|
1337
1340
|
|
|
1338
1341
|
// Set subject and content via component interactions
|
|
1339
|
-
// Use isFullMode: false (library mode) to test liquid validation path
|
|
1340
1342
|
const { rerender } = renderWithIntl({
|
|
1341
1343
|
isGetFormData: false,
|
|
1342
|
-
isFullMode:
|
|
1344
|
+
isFullMode: true,
|
|
1345
|
+
isLiquidEnabled: true,
|
|
1343
1346
|
getLiquidTags,
|
|
1344
|
-
|
|
1347
|
+
emailActions,
|
|
1345
1348
|
templateName: 'New Template',
|
|
1346
1349
|
});
|
|
1347
1350
|
const input = screen.getByTestId('subject-input');
|
|
@@ -1360,7 +1363,7 @@ describe('EmailHTMLEditor', () => {
|
|
|
1360
1363
|
await act(async () => {
|
|
1361
1364
|
rerender(
|
|
1362
1365
|
<IntlProvider locale="en" messages={{}}>
|
|
1363
|
-
<EmailHTMLEditor {...defaultProps} isGetFormData isFullMode
|
|
1366
|
+
<EmailHTMLEditor {...defaultProps} isGetFormData isFullMode getLiquidTags={getLiquidTags} emailActions={emailActions} templateName="New Template" />
|
|
1364
1367
|
</IntlProvider>
|
|
1365
1368
|
);
|
|
1366
1369
|
});
|
|
@@ -1369,9 +1372,8 @@ describe('EmailHTMLEditor', () => {
|
|
|
1369
1372
|
expect(validateLiquidTemplateContent).toHaveBeenCalled();
|
|
1370
1373
|
}, { timeout: 5000 });
|
|
1371
1374
|
|
|
1372
|
-
// In library mode (isFullMode=false), save proceeds via getFormdata
|
|
1373
1375
|
await waitFor(() => {
|
|
1374
|
-
expect(
|
|
1376
|
+
expect(emailActions.createTemplate).toHaveBeenCalled();
|
|
1375
1377
|
}, { timeout: 5000 });
|
|
1376
1378
|
});
|
|
1377
1379
|
|
|
@@ -2709,98 +2711,4 @@ describe('EmailHTMLEditor', () => {
|
|
|
2709
2711
|
expect(screen.getByTestId('html-editor')).toBeInTheDocument();
|
|
2710
2712
|
});
|
|
2711
2713
|
});
|
|
2712
|
-
|
|
2713
|
-
describe('isFullMode - skip liquid validation on save', () => {
|
|
2714
|
-
it('skips liquid validation when isFullMode is true', async () => {
|
|
2715
|
-
validateLiquidTemplateContent.mockClear();
|
|
2716
|
-
const getLiquidTags = jest.fn((content, callback) => {
|
|
2717
|
-
callback({ askAiraResponse: { data: [] }, isError: false });
|
|
2718
|
-
});
|
|
2719
|
-
const getFormdata = jest.fn();
|
|
2720
|
-
// Ensure no HTML/Label/Liquid errors from HtmlEditor
|
|
2721
|
-
mockGetAllIssues.mockReturnValue([]);
|
|
2722
|
-
|
|
2723
|
-
const { rerender } = renderWithIntl({
|
|
2724
|
-
isGetFormData: false,
|
|
2725
|
-
isFullMode: true,
|
|
2726
|
-
isLiquidEnabled: true,
|
|
2727
|
-
getLiquidTags,
|
|
2728
|
-
getFormdata,
|
|
2729
|
-
});
|
|
2730
|
-
const input = screen.getByTestId('subject-input');
|
|
2731
|
-
await act(async () => {
|
|
2732
|
-
fireEvent.change(input, { target: { value: 'Valid Subject' } });
|
|
2733
|
-
});
|
|
2734
|
-
const changeButton = screen.getByTestId('trigger-content-change');
|
|
2735
|
-
await act(async () => {
|
|
2736
|
-
fireEvent.click(changeButton);
|
|
2737
|
-
});
|
|
2738
|
-
await act(async () => {
|
|
2739
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
2740
|
-
});
|
|
2741
|
-
// Trigger save
|
|
2742
|
-
await act(async () => {
|
|
2743
|
-
rerender(
|
|
2744
|
-
<IntlProvider locale="en" messages={{}}>
|
|
2745
|
-
<EmailHTMLEditor {...defaultProps} isGetFormData isFullMode getLiquidTags={getLiquidTags} getFormdata={getFormdata} />
|
|
2746
|
-
</IntlProvider>
|
|
2747
|
-
);
|
|
2748
|
-
});
|
|
2749
|
-
|
|
2750
|
-
// In full mode, liquid validation should be skipped entirely
|
|
2751
|
-
await act(async () => {
|
|
2752
|
-
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
2753
|
-
});
|
|
2754
|
-
expect(validateLiquidTemplateContent).not.toHaveBeenCalled();
|
|
2755
|
-
});
|
|
2756
|
-
|
|
2757
|
-
it('proceeds directly to save without liquid validation in full mode', async () => {
|
|
2758
|
-
validateLiquidTemplateContent.mockClear();
|
|
2759
|
-
const getLiquidTags = jest.fn((content, callback) => {
|
|
2760
|
-
callback({ askAiraResponse: { data: [] }, isError: false });
|
|
2761
|
-
});
|
|
2762
|
-
const emailActions = {
|
|
2763
|
-
...defaultProps.emailActions,
|
|
2764
|
-
transformEmailTemplate: jest.fn((obj, callback) => callback(obj)),
|
|
2765
|
-
createTemplate: jest.fn((obj, callback) => {
|
|
2766
|
-
callback({ templateId: { _id: '123', versions: {} } });
|
|
2767
|
-
}),
|
|
2768
|
-
};
|
|
2769
|
-
// Ensure no HTML/Label/Liquid errors from HtmlEditor
|
|
2770
|
-
mockGetAllIssues.mockReturnValue([]);
|
|
2771
|
-
|
|
2772
|
-
const { rerender } = renderWithIntl({
|
|
2773
|
-
isGetFormData: false,
|
|
2774
|
-
isFullMode: true,
|
|
2775
|
-
getLiquidTags,
|
|
2776
|
-
emailActions,
|
|
2777
|
-
templateName: 'New Template',
|
|
2778
|
-
});
|
|
2779
|
-
const input = screen.getByTestId('subject-input');
|
|
2780
|
-
await act(async () => {
|
|
2781
|
-
fireEvent.change(input, { target: { value: 'Valid Subject' } });
|
|
2782
|
-
});
|
|
2783
|
-
const changeButton = screen.getByTestId('trigger-content-change');
|
|
2784
|
-
await act(async () => {
|
|
2785
|
-
fireEvent.click(changeButton);
|
|
2786
|
-
});
|
|
2787
|
-
await act(async () => {
|
|
2788
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
2789
|
-
});
|
|
2790
|
-
// Trigger save
|
|
2791
|
-
await act(async () => {
|
|
2792
|
-
rerender(
|
|
2793
|
-
<IntlProvider locale="en" messages={{}}>
|
|
2794
|
-
<EmailHTMLEditor {...defaultProps} isGetFormData isFullMode getLiquidTags={getLiquidTags} emailActions={emailActions} templateName="New Template" />
|
|
2795
|
-
</IntlProvider>
|
|
2796
|
-
);
|
|
2797
|
-
});
|
|
2798
|
-
|
|
2799
|
-
// Should skip liquid validation and proceed to save directly
|
|
2800
|
-
await waitFor(() => {
|
|
2801
|
-
expect(emailActions.createTemplate).toHaveBeenCalled();
|
|
2802
|
-
}, { timeout: 5000 });
|
|
2803
|
-
expect(validateLiquidTemplateContent).not.toHaveBeenCalled();
|
|
2804
|
-
});
|
|
2805
|
-
});
|
|
2806
2714
|
});
|