@capillarytech/creatives-library 7.13.16 → 7.13.17
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 +9 -1
- package/services/tests/api.test.js +6 -1
- package/utils/cdnTransformation.js +0 -2
- package/utils/tests/cdnTransformation.mockdata.js +37 -0
- package/utils/tests/cdnTransformation.test.js +66 -2
- package/v2Components/FormBuilder/index.js +1 -0
- package/v2Components/TemplatePreview/index.js +2 -1
- package/v2Containers/CreativesContainer/SlideBoxContent.js +4 -0
- package/v2Containers/CreativesContainer/constants.js +1 -1
- package/v2Containers/CreativesContainer/index.js +1 -0
- package/v2Containers/Email/index.js +48 -8
- package/v2Containers/MobilePush/Create/index.js +1 -0
- package/v2Containers/MobilePush/Edit/index.js +1 -0
- package/v2Containers/MobilepushWrapper/index.js +1 -0
- package/v2Containers/Templates/sagas.js +2 -3
- package/v2Containers/Templates/tests/mockData.js +30 -0
- package/v2Containers/Templates/tests/sagas.test.js +76 -0
- package/v2Containers/TemplatesV2/index.js +1 -0
- package/v2Containers/Email/mockdata/mockdata.js +0 -54
- package/v2Containers/Email/tests/index.test.js +0 -35
package/package.json
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capillarytech/creatives-library",
|
|
3
3
|
"author": "meharaj",
|
|
4
|
-
"
|
|
4
|
+
"sideEffects": [
|
|
5
|
+
"*.css",
|
|
6
|
+
"*.scss",
|
|
7
|
+
"*/styles/",
|
|
8
|
+
"*global-styles*",
|
|
9
|
+
"*font*",
|
|
10
|
+
"*moment/locale*"
|
|
11
|
+
],
|
|
12
|
+
"version": "7.13.17",
|
|
5
13
|
"description": "Capillary creatives ui",
|
|
6
14
|
"main": "./index.js",
|
|
7
15
|
"module": "./index.es.js",
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import { getSenderDetails, uploadFile } from "../api";
|
|
1
|
+
import { getSenderDetails, uploadFile, getCdnTransformationConfig } from "../api";
|
|
2
2
|
|
|
3
3
|
describe("getSenderDetails -- Test with valid responses", () => {
|
|
4
4
|
it("Should return correct response", () =>
|
|
5
5
|
expect(getSenderDetails("WHATSAPP", -1)).toEqual(Promise.resolve()));
|
|
6
6
|
});
|
|
7
7
|
|
|
8
|
+
describe("getCdnTransformationConfigs -- Test with valid responses", () => {
|
|
9
|
+
it("Should return correct response", () =>
|
|
10
|
+
expect(getCdnTransformationConfig()).toEqual(Promise.resolve()));
|
|
11
|
+
});
|
|
12
|
+
|
|
8
13
|
describe("uploadFile -- whatsapp image upload", () => {
|
|
9
14
|
it("Should return correct response", () =>
|
|
10
15
|
expect(
|
|
@@ -299,3 +299,40 @@ export const emailTemplateRaw = {
|
|
|
299
299
|
"type": "EMAIL",
|
|
300
300
|
"name": "test template1"
|
|
301
301
|
}
|
|
302
|
+
|
|
303
|
+
export const emailTemplateRawWithError = {
|
|
304
|
+
"versions": {
|
|
305
|
+
"base": {
|
|
306
|
+
"activeTab": "en",
|
|
307
|
+
"selectedLanguages": [
|
|
308
|
+
"en"
|
|
309
|
+
],
|
|
310
|
+
"base": true,
|
|
311
|
+
"tabKey": "6",
|
|
312
|
+
"subject": "hello subject"
|
|
313
|
+
},
|
|
314
|
+
"history": [
|
|
315
|
+
{
|
|
316
|
+
"activeTab": "en",
|
|
317
|
+
"en": {
|
|
318
|
+
"is_drag_drop": false,
|
|
319
|
+
"lang_id": 69,
|
|
320
|
+
"iso_code": "en",
|
|
321
|
+
"language": "English",
|
|
322
|
+
"template-content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional //EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:v=\"urn:schemas-microsoft-com:vml\">\n<head><!--[if gte mso 9]><xml><o:OfficeDocumentSettings><o:AllowPNG/><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml><![endif]--><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><meta name=\"viewport\" content=\"width=device-width\"><!--[if !mso]><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><!--<![endif]-->\n\t<title></title>\n\t<!--[if !mso]><!--<![endif]-->\n\t<style type=\"text/css\">body {\n margin: 0;\n padding: 0; }\n\ntable,\ntd,\ntr {\n vertical-align: top;\n border-collapse: collapse; }\n\n* {\n line-height: inherit; }\n\na[x-apple-data-detectors=true] {\n color: inherit !important;\n text-decoration: none !important; }\n\t</style>\n\t<style id=\"media-query\" type=\"text/css\">@media (max-width: 520px) {\n .block-grid,\n.col {\n min-width: 320px !important;\n max-width: 100% !important;\n display: block !important;\n }\n\n .block-grid {\n width: 100% !important;\n }\n\n .col {\n width: 100% !important;\n }\n\n .col > div {\n margin: 0 auto;\n }\n\n img.fullwidth,\nimg.fullwidthOnMobile {\n max-width: 100% !important;\n }\n\n .no-stack .col {\n min-width: 0 !important;\n display: table-cell !important;\n }\n\n .no-stack.two-up .col {\n width: 50% !important;\n }\n\n .no-stack .col.num4 {\n width: 33% !important;\n }\n\n .no-stack .col.num8 {\n width: 66% !important;\n }\n\n .no-stack .col.num4 {\n width: 33% !important;\n }\n\n .no-stack .col.num3 {\n width: 25% !important;\n }\n\n .no-stack .col.num6 {\n width: 50% !important;\n }\n\n .no-stack .col.num9 {\n width: 75% !important;\n }\n\n .video-block {\n max-width: none !important;\n }\n\n .mobile_hide {\n min-height: 0px;\n max-height: 0px;\n max-width: 0px;\n display: none;\n overflow: hidden;\n font-size: 0px;\n }\n\n .desktop_hide {\n display: block !important;\n max-height: none !important;\n }\n}\n\t</style>\n</head>\n<body class=\"clean-body\" style=\"margin: 0; padding: 0; -webkit-text-size-adjust: 100%; background-color: #FFFFFF;\">\n<p><!--[if IE]><div class=\"ie-browser\"><![endif]-->hello world</p>\n\n<p><img alt=\"Capillary Image\" height=\"171\" src=\"https://crm-nightly-new-fileservice.s3.amazonaws.com/intouch_creative_assets/b4b63b22-8a81-41ee-a8df-6db967fc.jpg\" width=\"257\" /></p>\n\n<table bgcolor=\"#FFFFFF\" cellpadding=\"0\" cellspacing=\"0\" class=\"nl-container\" role=\"presentation\" style=\"background-color:#ffffff; border-collapse:collapse; border-spacing:0; margin:0 auto; min-width:320px; mso-table-lspace:0pt; mso-table-rspace:0pt; table-layout:fixed; vertical-align:top; width:100%\" valign=\"top\">\n\t<tbody>\n\t\t<tr style=\"vertical-align:top\" valign=\"top\">\n\t\t\t<td style=\"vertical-align:top; word-break:break-word\"><!--[if (mso)|(IE)]><table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><tr><td align=\"center\" style=\"background-color:#FFFFFF\"><![endif]-->\n\t\t\t<div style=\"background-color:transparent\">\n\t\t\t<div class=\"block-grid\" style=\"background-color:transparent; margin-bottom:0; margin-left:auto; margin-right:auto; margin-top:0; max-width:500px; min-width:320px; overflow-wrap:break-word; word-break:break-word; word-wrap:break-word\">\n\t\t\t<div style=\"background-color:transparent; border-collapse:collapse; display:table; width:100%\"><!--[if (mso)|(IE)]><table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"background-color:transparent;\"><tr><td align=\"center\"><table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"width:500px\"><tr class=\"layout-full-width\" style=\"background-color:transparent\"><![endif]--><!--[if (mso)|(IE)]><td align=\"center\" width=\"500\" style=\"background-color:transparent;width:500px; border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent;\" valign=\"top\"><table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><tr><td style=\"padding-right: 0px; padding-left: 0px; padding-top:5px; padding-bottom:5px;\"><![endif]-->\n\t\t\t<div class=\"col num12\" style=\"display:table-cell; max-width:500px; min-width:320px; vertical-align:top; width:500px\">\n\t\t\t<div style=\"width:100% !important\"><!--[if (!mso)&(!IE)]><div style=\"border-top:0px solid transparent; border-left:0px solid transparent; border-bottom:0px solid transparent; border-right:0px solid transparent; padding-top:5px; padding-bottom:5px; padding-right: 0px; padding-left: 0px;\"><!--<![endif]--><!--[if (!mso)&(!IE)]></div><!--<![endif]--></div>\n\t\t\t</div>\n\t\t\t<!--[if (mso)|(IE)]></td></tr></table><![endif]--><!--[if (mso)|(IE)]></td></tr></table></td></tr></table><![endif]--></div>\n\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!--[if (mso)|(IE)]></td></tr></table><![endif]--></td>\n\t\t</tr>\n\t</tbody>\n</table>\n<!--[if (IE)]></div><![endif]--></body>\n</html>\n",
|
|
323
|
+
"drag_drop_id": "",
|
|
324
|
+
"tabKey": "6",
|
|
325
|
+
"id": "5f7b61605f09ebe595ff404e"
|
|
326
|
+
},
|
|
327
|
+
"selectedLanguages": [
|
|
328
|
+
"en"
|
|
329
|
+
],
|
|
330
|
+
"base": true,
|
|
331
|
+
"tabKey": "6",
|
|
332
|
+
"subject": "hello subject"
|
|
333
|
+
}
|
|
334
|
+
]
|
|
335
|
+
},
|
|
336
|
+
"type": "EMAIL",
|
|
337
|
+
"name": "test template1"
|
|
338
|
+
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import * as cdnUtils from "../cdnTransformation";
|
|
2
2
|
import * as mockdata from "./cdnTransformation.mockdata";
|
|
3
|
+
import * as nodeHtmlParser from 'node-html-parser'
|
|
4
|
+
import Bugsnag from '@bugsnag/js';
|
|
3
5
|
|
|
6
|
+
var bugsnagSpy;
|
|
7
|
+
var localStorageMock;
|
|
4
8
|
beforeEach(() => {
|
|
5
|
-
|
|
9
|
+
localStorageMock = (function () {
|
|
6
10
|
var store = {
|
|
7
11
|
CREATIVES_CDN_TRANSFORMATION_URL_SUFFIX: "cdn-cgi/image",
|
|
8
12
|
CREATIVES_S3_BUCKET_PATH: "intouch_creative_assets",
|
|
@@ -25,7 +29,8 @@ beforeEach(() => {
|
|
|
25
29
|
},
|
|
26
30
|
};
|
|
27
31
|
})();
|
|
28
|
-
Object.defineProperty(window, "localStorage", { value: localStorageMock });
|
|
32
|
+
Object.defineProperty(window, "localStorage", { value: localStorageMock, writable: true, configurable: true});
|
|
33
|
+
bugsnagSpy = jest.spyOn(Bugsnag, 'notify');
|
|
29
34
|
});
|
|
30
35
|
|
|
31
36
|
afterEach(() => {
|
|
@@ -36,6 +41,8 @@ afterEach(() => {
|
|
|
36
41
|
localStorage.setItem(
|
|
37
42
|
"CREATIVES_S3_BUCKET_PATH", "intouch_creative_assets"
|
|
38
43
|
);
|
|
44
|
+
jest.restoreAllMocks();
|
|
45
|
+
jest.resetAllMocks();
|
|
39
46
|
});
|
|
40
47
|
|
|
41
48
|
describe("cdnTransformationTests", () => {
|
|
@@ -212,6 +219,14 @@ describe("cdnTransformationTests", () => {
|
|
|
212
219
|
expect(cdnUtils.updateImagesInHtml(null)).toEqual(null);
|
|
213
220
|
expect(cdnUtils.updateImagesInHtml("")).toEqual("");
|
|
214
221
|
});
|
|
222
|
+
|
|
223
|
+
it("should call bugsnag when parse() throws some unexpected error.", () => {
|
|
224
|
+
const spy = jest.spyOn(nodeHtmlParser, 'parse').mockImplementation(()=>{
|
|
225
|
+
throw new Error();
|
|
226
|
+
})
|
|
227
|
+
expect(cdnUtils.updateImagesInHtml(mockdata.emailRawInput)).toEqual(mockdata.emailRawInput);
|
|
228
|
+
expect(bugsnagSpy).toHaveBeenCalled();
|
|
229
|
+
});
|
|
215
230
|
});
|
|
216
231
|
|
|
217
232
|
describe("transformEmailTemplate()", () => {
|
|
@@ -221,6 +236,13 @@ describe("cdnTransformationTests", () => {
|
|
|
221
236
|
cdnUtils.transformEmailTemplates(emailTemplateInput);
|
|
222
237
|
expect(emailTemplateOutput).toMatchSnapshot();
|
|
223
238
|
});
|
|
239
|
+
it("should return original contents transform email template throws an error inside. This might be due to improper input or unexpected error.", () => {
|
|
240
|
+
const emailTemplateInputWithError = mockdata.emailTemplateRawWithError;
|
|
241
|
+
const emailTemplateOutput =
|
|
242
|
+
cdnUtils.transformEmailTemplates(emailTemplateInputWithError);
|
|
243
|
+
expect(emailTemplateInputWithError).toEqual(emailTemplateOutput);
|
|
244
|
+
expect(bugsnagSpy).toHaveBeenCalled();
|
|
245
|
+
});
|
|
224
246
|
});
|
|
225
247
|
|
|
226
248
|
describe("saveCdnConfigs()", () => {
|
|
@@ -238,6 +260,7 @@ describe("cdnTransformationTests", () => {
|
|
|
238
260
|
LINE: 75,
|
|
239
261
|
DEFAULT: 75,
|
|
240
262
|
},
|
|
263
|
+
bucketPath: 'intouch_creative_assets'
|
|
241
264
|
};
|
|
242
265
|
|
|
243
266
|
const expected = {
|
|
@@ -245,6 +268,7 @@ describe("cdnTransformationTests", () => {
|
|
|
245
268
|
CREATIVES_CDN_BASE_URL: "https://storage.crm.n.content-cdn.io",
|
|
246
269
|
CREATIVES_CDN_QUALITY_CONFIG:
|
|
247
270
|
'{"EMAIL":75,"RCS":75,"VIBER":75,"WHATSAPP":75,"MOBILE_PUSH":75,"FACEBOOK":75,"LINE":75,"DEFAULT":75}',
|
|
271
|
+
CREATIVES_S3_BUCKET_PATH: 'intouch_creative_assets',
|
|
248
272
|
};
|
|
249
273
|
cdnUtils.saveCdnConfigs(cdnConfigs);
|
|
250
274
|
|
|
@@ -257,6 +281,19 @@ describe("cdnTransformationTests", () => {
|
|
|
257
281
|
expect(localStorage.getItem("CREATIVES_CDN_QUALITY_CONFIG")).toBe(
|
|
258
282
|
expected.CREATIVES_CDN_QUALITY_CONFIG
|
|
259
283
|
);
|
|
284
|
+
expect(localStorage.getItem("CREATIVES_S3_BUCKET_PATH")).toBe(
|
|
285
|
+
expected.CREATIVES_S3_BUCKET_PATH
|
|
286
|
+
);
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
it("should clear items from localStorage if qualityConfigs is not present", () => {
|
|
290
|
+
const cdnConfigs = {
|
|
291
|
+
bucketPath: "intouch_creative_assets",
|
|
292
|
+
};
|
|
293
|
+
cdnUtils.saveCdnConfigs(cdnConfigs);
|
|
294
|
+
expect(localStorage.getItem("CREATIVES_CDN_QUALITY_CONFIG")).toBe(
|
|
295
|
+
undefined
|
|
296
|
+
);
|
|
260
297
|
});
|
|
261
298
|
|
|
262
299
|
it("should clear items from localStorage if input does not contain hostname or transformationUrlSuffix", () => {
|
|
@@ -301,5 +338,32 @@ describe("cdnTransformationTests", () => {
|
|
|
301
338
|
expect(localStorage.getItem("CREATIVES_CDN_BASE_URL")).toBe(undefined);
|
|
302
339
|
expect(localStorage.getItem("CREATIVES_CDN_QUALITY_CONFIG")).toBe(undefined);
|
|
303
340
|
});
|
|
341
|
+
|
|
342
|
+
it("should call bugsnag notify if any unexpected error occured during removeAllCdnLocalStorageItems", () => {
|
|
343
|
+
delete window.localStorage.removeItem;
|
|
344
|
+
|
|
345
|
+
cdnUtils.removeAllCdnLocalStorageItems('CREATIVES_CDN_BASE_URL');
|
|
346
|
+
|
|
347
|
+
expect(bugsnagSpy).toHaveBeenCalled();
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
it("should call bugsnag notify if any unexpected error occured during saveCdnConfigs", () => {
|
|
351
|
+
delete window?.localStorage?.setItem; //this is a case used to mimick any unexpected error
|
|
352
|
+
|
|
353
|
+
const cdnConfigs = {
|
|
354
|
+
transformationUrlSuffix: "cdn-cgi/image",
|
|
355
|
+
hostname: "https://storage.crm.n.content-cdn.io",
|
|
356
|
+
qualityCfg: {
|
|
357
|
+
DEFAULT: 75,
|
|
358
|
+
},
|
|
359
|
+
bucketPath: 'intouch_creative_assets'
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
cdnUtils.saveCdnConfigs(cdnConfigs);
|
|
363
|
+
|
|
364
|
+
expect(bugsnagSpy).toHaveBeenCalled();
|
|
365
|
+
|
|
366
|
+
window.localStorage.setItem = ()=>{};
|
|
367
|
+
});
|
|
304
368
|
});
|
|
305
369
|
});
|
|
@@ -3092,6 +3092,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
3092
3092
|
onTestContentClicked={this.props.onTestContentClicked}
|
|
3093
3093
|
templateDataRaw={this.props.templateData}
|
|
3094
3094
|
module={this.props.location.query.module}
|
|
3095
|
+
hideTestAndPreviewBtn={this.props.hideTestAndPreviewBtn}
|
|
3095
3096
|
>
|
|
3096
3097
|
</TemplatePreview>
|
|
3097
3098
|
</CapColumn>
|
|
@@ -160,6 +160,7 @@ export class TemplatePreview extends React.Component { // eslint-disable-line re
|
|
|
160
160
|
intl,
|
|
161
161
|
templateData,
|
|
162
162
|
rcsIosPreview,
|
|
163
|
+
hideTestAndPreviewBtn
|
|
163
164
|
} = this.props;
|
|
164
165
|
const { formatMessage } = intl;
|
|
165
166
|
const { buttonText, imageURL, rcsPreviewContent, messageContent: viberMessageContent } = content || {};
|
|
@@ -193,7 +194,7 @@ export class TemplatePreview extends React.Component { // eslint-disable-line re
|
|
|
193
194
|
const disablePreviewAndTest = this.props.channel === 'MOBILEPUSH' ? !this.props.content.header : (this.props.channel === 'SMS' ? !this.props.content : false);
|
|
194
195
|
const showTestAndPreview = showTestAndPreviewIcon &&
|
|
195
196
|
channel !== WECHAT &&
|
|
196
|
-
['outbound', 'library'].includes(module);
|
|
197
|
+
['outbound', 'library'].includes(module) && !hideTestAndPreviewBtn;
|
|
197
198
|
|
|
198
199
|
const renderLineMultiText = (content) => {
|
|
199
200
|
let textCount = 0;
|
|
@@ -147,6 +147,7 @@ export function SlideBoxContent(props) {
|
|
|
147
147
|
orgUnitId,
|
|
148
148
|
smsRegister,
|
|
149
149
|
enableNewChannels,
|
|
150
|
+
hideTestAndPreviewBtn
|
|
150
151
|
} = props;
|
|
151
152
|
const type = (messageDetails.type || '').toLowerCase(); // type is context in get tags values : outbound | dvs | referral | loyalty | coupons
|
|
152
153
|
const query = { type: !isFullMode && 'embedded', module: isFullMode ? 'default' : 'library', isEditFromCampaigns: (templateData || {}).isEditFromCampaigns};
|
|
@@ -407,6 +408,7 @@ export function SlideBoxContent(props) {
|
|
|
407
408
|
orgUnitId={orgUnitId}
|
|
408
409
|
smsRegister={smsRegister}
|
|
409
410
|
enableNewChannels={enableNewChannels}
|
|
411
|
+
hideTestAndPreviewBtn={hideTestAndPreviewBtn}
|
|
410
412
|
/>
|
|
411
413
|
)}
|
|
412
414
|
{isPreview && (
|
|
@@ -602,6 +604,7 @@ export function SlideBoxContent(props) {
|
|
|
602
604
|
onPreviewContentClicked={onPreviewContentClicked}
|
|
603
605
|
onTestContentClicked={onTestContentClicked}
|
|
604
606
|
type={type}
|
|
607
|
+
hideTestAndPreviewBtn={hideTestAndPreviewBtn}
|
|
605
608
|
/>
|
|
606
609
|
}
|
|
607
610
|
{isCreateMPush &&
|
|
@@ -628,6 +631,7 @@ export function SlideBoxContent(props) {
|
|
|
628
631
|
onValidationFail={onValidationFail}
|
|
629
632
|
selectedOfferDetails={selectedOfferDetails}
|
|
630
633
|
onPreviewContentClicked={onPreviewContentClicked}
|
|
634
|
+
hideTestAndPreviewBtn={hideTestAndPreviewBtn}
|
|
631
635
|
onTestContentClicked={onTestContentClicked}/>
|
|
632
636
|
}
|
|
633
637
|
{
|
|
@@ -22,4 +22,4 @@ export const RCS = "RCS";
|
|
|
22
22
|
export const SHOW_CONTANER_LOADER = "app/CreativesContainer/SHOW_CONTANER_LOADER";
|
|
23
23
|
export const HIDE_CONTAINER_LOADER = "app/CreativesContainer/HIDE_CONTAINER_LOADER";
|
|
24
24
|
|
|
25
|
-
export const WHATSAPP_HELP_DOC_LINK = "https://
|
|
25
|
+
export const WHATSAPP_HELP_DOC_LINK = "https://support.capillarytech.com/en/support/solutions/articles/4000180620-create-whatsapp-template";
|
|
@@ -1107,6 +1107,7 @@ export class Creatives extends React.Component {
|
|
|
1107
1107
|
messageStrategy={this.props.strategy}
|
|
1108
1108
|
orgUnitId={this.props.orgUnitId}
|
|
1109
1109
|
enableNewChannels={enableNewChannels}
|
|
1110
|
+
hideTestAndPreviewBtn={this.props.hideTestAndPreviewBtn}
|
|
1110
1111
|
/>
|
|
1111
1112
|
}
|
|
1112
1113
|
footer={this.shouldShowFooter() &&
|
|
@@ -324,7 +324,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
|
|
|
324
324
|
if (this.state.isEdit && nextProps.location.query.module === "library" && !_.isEmpty(nextProps.templateData) && !this.props.params.id && !nextProps.isGetFormData && _.isEmpty(_.get(this, `state.formData['template-subject']`))) {
|
|
325
325
|
this.startTemplateCreation(nextProps.templateData);
|
|
326
326
|
}
|
|
327
|
-
if (nextProps.location.query.module === 'library' && nextProps.isGetFormData && (this.props.isGetFormData
|
|
327
|
+
if (nextProps.location.query.module === 'library' && nextProps.isGetFormData && (this.props.isGetFormData!==nextProps.isGetFormData)) {
|
|
328
328
|
const formData = this.state.formData;
|
|
329
329
|
let isBeeEditor = false;
|
|
330
330
|
const isBEEEnable = this.checkBeeEditorAllowedForLibrary();
|
|
@@ -681,9 +681,9 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
|
|
|
681
681
|
channel: EMAIL,
|
|
682
682
|
timeTaken,
|
|
683
683
|
content: base?.[activeTab]?.['template-content'],
|
|
684
|
-
mode: isEdit ? EDIT : CREATE
|
|
684
|
+
mode: isEdit ? EDIT : CREATE
|
|
685
685
|
});
|
|
686
|
-
|
|
686
|
+
|
|
687
687
|
// this.resetSchema();
|
|
688
688
|
let message;
|
|
689
689
|
if (isEdit) {
|
|
@@ -872,6 +872,46 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
|
|
|
872
872
|
} else {
|
|
873
873
|
schema.containers[index].isActive = false;
|
|
874
874
|
}
|
|
875
|
+
// const isLanguageSupport = this.props.location.query.isLanguageSupport;
|
|
876
|
+
|
|
877
|
+
_.forEach(data.selectedLanguages, (lang, langIndex) => {
|
|
878
|
+
if ((type !== 'embedded' || (type === 'embedded' && isLanguageSupport === 'true')) && lang !== this.props.currentOrgDetails.basic_details.base_language) {
|
|
879
|
+
const tabContent = _.cloneDeep(containers[0].tabContent.sections[0]);
|
|
880
|
+
const tabContentSection = tabContent.inputFields[0].cols[0];
|
|
881
|
+
const panes = containers[0].panes.slice();
|
|
882
|
+
const firstPane = _.cloneDeep(panes[0]);
|
|
883
|
+
const sections = [];
|
|
884
|
+
_.forEach(firstPane.sections, (section) => {
|
|
885
|
+
let sect = _.cloneDeep(section);
|
|
886
|
+
|
|
887
|
+
if (sect.type === 'col-label') {
|
|
888
|
+
sect = this.cloneColLabel(sect, (langIndex + 1));
|
|
889
|
+
} else if (sect.type === 'multicols') {
|
|
890
|
+
sect = this.cloneMultiCol(sect, (langIndex + 1));
|
|
891
|
+
} else if (sect.type === 'parent') {
|
|
892
|
+
sect = this.cloneParent(sect, (langIndex + 1));
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
sections.push(sect);
|
|
896
|
+
return true;
|
|
897
|
+
});
|
|
898
|
+
//
|
|
899
|
+
|
|
900
|
+
this.map[`template-content${data.selectedLanguages.indexOf(lang) + 1}`] = this.map['template-content'];
|
|
901
|
+
tabContentSection.id = `${tabContentSection.id}${index + 1}`;
|
|
902
|
+
tabContentSection.value = `${data[lang].language}`;
|
|
903
|
+
|
|
904
|
+
firstPane.sections = sections;
|
|
905
|
+
firstPane.sectionsHeaders = [tabContent];
|
|
906
|
+
|
|
907
|
+
// panes.push(firstPane);
|
|
908
|
+
|
|
909
|
+
schema.containers[index].panes.push(firstPane);
|
|
910
|
+
} else if (lang !== this.props.currentOrgDetails.basic_details.base_language) {
|
|
911
|
+
delete data[lang];
|
|
912
|
+
data.selectedLanguages.splice(langIndex, 1);
|
|
913
|
+
}
|
|
914
|
+
});
|
|
875
915
|
}
|
|
876
916
|
if (data.base) {
|
|
877
917
|
formData.base = data;
|
|
@@ -2333,7 +2373,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
|
|
|
2333
2373
|
const response = {
|
|
2334
2374
|
action: "getFormData",
|
|
2335
2375
|
postAction: this.state.getFormDataValue || 'next',
|
|
2336
|
-
id: _.get(this.props, 'Email.templateDetails._id', ''),
|
|
2376
|
+
id : _.get(this.props, 'Email.templateDetails._id', ''),
|
|
2337
2377
|
value: this.transformFormData(passedData),
|
|
2338
2378
|
validity: this.state.isFormValid,
|
|
2339
2379
|
type: 'EMAIL',
|
|
@@ -2367,9 +2407,9 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
|
|
|
2367
2407
|
const newdata = data;
|
|
2368
2408
|
|
|
2369
2409
|
if (!isNaN(index) && newdata) {
|
|
2370
|
-
|
|
2371
|
-
const baseLangTabKey = newdata[baseLanguage]?.tabKey || newdata.tabKey;
|
|
2410
|
+
const baseLangTabKey = newdata[baseLanguage].tabKey;
|
|
2372
2411
|
newdata.tabKey = baseLangTabKey;
|
|
2412
|
+
newdata.activeTab = baseLanguage;
|
|
2373
2413
|
if (newdata.base) {
|
|
2374
2414
|
baseKey = baseLangTabKey;
|
|
2375
2415
|
}
|
|
@@ -2391,7 +2431,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
|
|
|
2391
2431
|
obj.versions.base = formData.base;
|
|
2392
2432
|
obj.versions.base.tabKey = baseKey;
|
|
2393
2433
|
obj.versions.base.subject = formData['template-subject'];
|
|
2394
|
-
obj.versions.base.activeTab =
|
|
2434
|
+
obj.versions.base.activeTab = baseLanguage;
|
|
2395
2435
|
_.forEach(obj.versions.base.selectedLanguages, (language) => {
|
|
2396
2436
|
if (obj.versions.base[language].is_drag_drop) {
|
|
2397
2437
|
delete obj.versions.base[language].edmeditorsrc;
|
|
@@ -2690,7 +2730,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
|
|
|
2690
2730
|
isEdit={this.state.isEdit}
|
|
2691
2731
|
iframeParent={parent}
|
|
2692
2732
|
router={this.props.router}
|
|
2693
|
-
baseLanguage={this.
|
|
2733
|
+
baseLanguage={this.props.currentOrgDetails.basic_details.base_language}
|
|
2694
2734
|
supportedLanguages={this.getSupportedLanguages(this.props)}
|
|
2695
2735
|
isSchemaChanged={this.state.isSchemaChanged}
|
|
2696
2736
|
cmsTemplates={this.props.Templates.cmsTemplates}
|
|
@@ -1737,6 +1737,7 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
|
|
|
1737
1737
|
onPreviewContentClicked={this.props.onPreviewContentClicked}
|
|
1738
1738
|
onTestContentClicked={this.props.onTestContentClicked}
|
|
1739
1739
|
templateData={this.props.templateData}
|
|
1740
|
+
hideTestAndPreviewBtn={this.props.hideTestAndPreviewBtn}
|
|
1740
1741
|
/>
|
|
1741
1742
|
</CapColumn>
|
|
1742
1743
|
{this.props.iosCtasData && this.state.showIosCtaTable &&
|
|
@@ -1821,6 +1821,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1821
1821
|
onPreviewContentClicked={this.props.onPreviewContentClicked}
|
|
1822
1822
|
onTestContentClicked={this.props.onTestContentClicked}
|
|
1823
1823
|
templateData={this.props.templateData}
|
|
1824
|
+
hideTestAndPreviewBtn={this.props.hideTestAndPreviewBtn}
|
|
1824
1825
|
/>}
|
|
1825
1826
|
</CapColumn>
|
|
1826
1827
|
{this.props.iosCtasData && this.state.showIosCtaTable &&
|
|
@@ -115,6 +115,7 @@ export class MobilepushWrapper extends React.Component { // eslint-disable-line
|
|
|
115
115
|
onPreviewContentClicked={onPreviewContentClicked}
|
|
116
116
|
onTestContentClicked={onTestContentClicked}
|
|
117
117
|
templateData={templateData}
|
|
118
|
+
hideTestAndPreviewBtn={this.props.hideTestAndPreviewBtn}
|
|
118
119
|
/>
|
|
119
120
|
|
|
120
121
|
|
|
@@ -86,10 +86,9 @@ export function* getOrgLevelCampaignSettings() {
|
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
function* getCdnTransformationConfig() {
|
|
89
|
+
export function* getCdnTransformationConfig() {
|
|
90
90
|
try {
|
|
91
91
|
const res = yield call(Api.getCdnTransformationConfig);
|
|
92
|
-
|
|
93
92
|
if (res?.success && res?.status?.code === 200) {
|
|
94
93
|
const cdnConfigs = res?.response;
|
|
95
94
|
saveCdnConfigs(cdnConfigs);
|
|
@@ -239,7 +238,7 @@ function* watchGetSenderDetails() {
|
|
|
239
238
|
yield cancel(watcher);
|
|
240
239
|
}
|
|
241
240
|
|
|
242
|
-
function* watchGetCdnTransformationConfig() {
|
|
241
|
+
export function* watchGetCdnTransformationConfig() {
|
|
243
242
|
yield takeLatest(
|
|
244
243
|
types.GET_CDN_TRANSFORMATION_CONFIG_REQUEST,
|
|
245
244
|
getCdnTransformationConfig
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export const getCdnTransformationConfigSuccess = {
|
|
2
|
+
"success": true,
|
|
3
|
+
"status": {
|
|
4
|
+
"isError": false,
|
|
5
|
+
"code": 200,
|
|
6
|
+
"message": "success"
|
|
7
|
+
},
|
|
8
|
+
"message": "CDN transformation config fetched",
|
|
9
|
+
"response": {
|
|
10
|
+
"hostname": "https://storage.crm.staging.content-cdn.io",
|
|
11
|
+
"transformationUrlSuffix": "cdn-cgi/image",
|
|
12
|
+
"bucketPath": "intouch_creative_assets",
|
|
13
|
+
"qualityCfg": {
|
|
14
|
+
"EMAIL": 65,
|
|
15
|
+
"RCS": 75,
|
|
16
|
+
"VIBER": 75,
|
|
17
|
+
"WHATSAPP": 75,
|
|
18
|
+
"MOBILE_PUSH": 75,
|
|
19
|
+
"FACEBOOK": 75,
|
|
20
|
+
"LINE": 75,
|
|
21
|
+
"DEFAULT": 75
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const getCdnTransformationConfigFailure = {
|
|
27
|
+
"isError": true,
|
|
28
|
+
"message": "Resource Not Found",
|
|
29
|
+
"error": {}
|
|
30
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { expectSaga } from 'redux-saga-test-plan';
|
|
2
|
+
import { take, call, takeLatest, takeEvery } from 'redux-saga/effects';
|
|
3
|
+
import * as matchers from 'redux-saga-test-plan/matchers';
|
|
4
|
+
import * as api from '../../../services/api';
|
|
5
|
+
import * as types from '../constants';
|
|
6
|
+
import * as cdnUtils from '../../../utils/cdnTransformation';
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
getCdnTransformationConfig,
|
|
10
|
+
watchGetCdnTransformationConfig
|
|
11
|
+
} from '../sagas';
|
|
12
|
+
|
|
13
|
+
import * as mockData from './mockData';
|
|
14
|
+
|
|
15
|
+
describe('getCdnTransformationConfig saga', () => {
|
|
16
|
+
it("handle valid response from api", () => {
|
|
17
|
+
const saveCdnConfigsSpy = jest.spyOn(cdnUtils, "saveCdnConfigs");
|
|
18
|
+
|
|
19
|
+
expectSaga(getCdnTransformationConfig)
|
|
20
|
+
.provide([
|
|
21
|
+
[
|
|
22
|
+
call(api.getCdnTransformationConfig),
|
|
23
|
+
mockData.getCdnTransformationConfigSuccess,
|
|
24
|
+
],
|
|
25
|
+
])
|
|
26
|
+
.run();
|
|
27
|
+
expect(saveCdnConfigsSpy).toHaveBeenCalled();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("handle error response from api", () => {
|
|
31
|
+
const removeAllCdnLocalStorageItemsSpy = jest.spyOn(
|
|
32
|
+
cdnUtils,
|
|
33
|
+
"removeAllCdnLocalStorageItems"
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
expectSaga(getCdnTransformationConfig)
|
|
37
|
+
.provide([
|
|
38
|
+
[
|
|
39
|
+
call(api.getCdnTransformationConfig),
|
|
40
|
+
mockData.getCdnTransformationConfigFailure,
|
|
41
|
+
],
|
|
42
|
+
])
|
|
43
|
+
.run();
|
|
44
|
+
expect(removeAllCdnLocalStorageItemsSpy).toHaveBeenCalled();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("remove localStorage items when an error is thrown", () => {
|
|
48
|
+
const saveCdnConfigsSpy = jest.spyOn(cdnUtils, "saveCdnConfigs").mockImplementation(()=>{
|
|
49
|
+
throw new Error()
|
|
50
|
+
});
|
|
51
|
+
const removeAllCdnLocalStorageItemsSpy = jest.spyOn(
|
|
52
|
+
cdnUtils,
|
|
53
|
+
"removeAllCdnLocalStorageItems"
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
expectSaga(getCdnTransformationConfig)
|
|
57
|
+
.provide([
|
|
58
|
+
[
|
|
59
|
+
call(api.getCdnTransformationConfig),
|
|
60
|
+
mockData.getCdnTransformationConfigSuccess,
|
|
61
|
+
],
|
|
62
|
+
])
|
|
63
|
+
.run();
|
|
64
|
+
expect(removeAllCdnLocalStorageItemsSpy).toHaveBeenCalled();
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
describe('watchForGetJourneyList saga', () => {
|
|
70
|
+
const generator = watchGetCdnTransformationConfig();
|
|
71
|
+
it('should call watchers functions', () => {
|
|
72
|
+
expect(generator.next().value).toEqual(
|
|
73
|
+
takeLatest(types.GET_CDN_TRANSFORMATION_CONFIG_REQUEST, getCdnTransformationConfig),
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -260,6 +260,7 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
|
|
|
260
260
|
handlePeviewTemplate={this.props.handlePeviewTemplate}
|
|
261
261
|
messageStrategy={this.props.messageStrategy}
|
|
262
262
|
smsRegister={smsRegister}
|
|
263
|
+
hideTestAndPreviewBtn={this.props.hideTestAndPreviewBtn}
|
|
263
264
|
/>);
|
|
264
265
|
}
|
|
265
266
|
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
export const EMAILPreviewMockData = {
|
|
2
|
-
loadingStatus: 0,
|
|
3
|
-
formData: {},
|
|
4
|
-
tabCount: 1,
|
|
5
|
-
currentTab: 1,
|
|
6
|
-
events: {
|
|
7
|
-
blur: (() => {}),
|
|
8
|
-
afterPaste: (() => {}),
|
|
9
|
-
change: (() => {}),
|
|
10
|
-
},
|
|
11
|
-
isEdit: false,
|
|
12
|
-
schema: {},
|
|
13
|
-
loading: false,
|
|
14
|
-
isFormValid: true,
|
|
15
|
-
injectedTags: {},
|
|
16
|
-
checkValidation: false,
|
|
17
|
-
saveEdmDataMode: 'save',
|
|
18
|
-
tabKey: '',
|
|
19
|
-
showEmailPreview: false,
|
|
20
|
-
device: "desktop",
|
|
21
|
-
editorInstanse: undefined,
|
|
22
|
-
showImageSelectionBox: false,
|
|
23
|
-
isDragDrop: false,
|
|
24
|
-
showConfirmationModal: false,
|
|
25
|
-
modalContent: {title: "", body: "", type: 'confirm', id: 'email-language-delete-modal'},
|
|
26
|
-
showModal: false,
|
|
27
|
-
page: 1,
|
|
28
|
-
perPageLimit: 25,
|
|
29
|
-
totalCount: 0,
|
|
30
|
-
searchText: '',
|
|
31
|
-
saveCount: 0,
|
|
32
|
-
cmsDataCount: 0,
|
|
33
|
-
targetSaveCount: 0,
|
|
34
|
-
saveObj: {},
|
|
35
|
-
showEdmEmailTemplates: false,
|
|
36
|
-
editDataSet: false,
|
|
37
|
-
languageDataSet: false,
|
|
38
|
-
addLanguageType: '',
|
|
39
|
-
startValidation: false,
|
|
40
|
-
saveForm: false,
|
|
41
|
-
|
|
42
|
-
params: {},
|
|
43
|
-
location: {
|
|
44
|
-
pathname: '/creatives/ui/v2',
|
|
45
|
-
search: '',
|
|
46
|
-
hash: '',
|
|
47
|
-
key: 'm54f44',
|
|
48
|
-
query: {module: "library"},
|
|
49
|
-
},
|
|
50
|
-
Templates: {},
|
|
51
|
-
Email: {},
|
|
52
|
-
isGetFormData: true,
|
|
53
|
-
currentOrgDetails: {basic_details: {}},
|
|
54
|
-
};
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { injectIntl } from 'react-intl';
|
|
3
|
-
import '@testing-library/jest-dom';
|
|
4
|
-
import {
|
|
5
|
-
render,
|
|
6
|
-
} from '../../../utils/test-utils';
|
|
7
|
-
import { EMAILPreviewMockData } from '../mockdata/mockdata';
|
|
8
|
-
import { Email } from "../index";
|
|
9
|
-
|
|
10
|
-
const initializeComponent = () => {
|
|
11
|
-
const Component = injectIntl(Email);
|
|
12
|
-
const resetUploadData = jest.fn();
|
|
13
|
-
const clearStoreValues = jest.fn();
|
|
14
|
-
const clearCRUDResponse = jest.fn();
|
|
15
|
-
const fetchSchemaForEntity = jest.fn();
|
|
16
|
-
|
|
17
|
-
return render( <Component
|
|
18
|
-
{...EMAILPreviewMockData}
|
|
19
|
-
templatesActions={{resetUploadData}}
|
|
20
|
-
actions={{
|
|
21
|
-
clearStoreValues,
|
|
22
|
-
clearCRUDResponse,
|
|
23
|
-
}}
|
|
24
|
-
globalActions={{
|
|
25
|
-
fetchSchemaForEntity,
|
|
26
|
-
}}
|
|
27
|
-
/>);
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
describe('renders a message', () => {
|
|
31
|
-
it("Test if Email component renders", () => {
|
|
32
|
-
initializeComponent();
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
|