@capillarytech/creatives-library 8.0.169 → 8.0.170-beta.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/app.js +4 -0
- package/containers/App/constants.js +2 -0
- package/package.json +2 -1
- package/utils/commonUtils.js +50 -0
- package/utils/tests/newrelic.test.js +546 -0
- package/v2Components/CapWhatsappCTA/index.js +2 -2
- package/v2Components/CapWhatsappCarouselButton/index.js +2 -2
- package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +2 -2
- package/v2Containers/Line/Container/Wrapper/tests/index.test.js +56 -1
- package/v2Containers/Line/Container/Wrapper/utils.js +9 -0
package/app.js
CHANGED
|
@@ -26,6 +26,10 @@ import './styles/main.scss';
|
|
|
26
26
|
import pathConfig from './config/path';
|
|
27
27
|
import ignoredErrorMessages from './utils/ignoredErrorMessages';
|
|
28
28
|
import App from './containers/App';
|
|
29
|
+
import { setupNewrelicWebVitals } from './utils/commonUtils';
|
|
30
|
+
|
|
31
|
+
// Setup New Relic WebVitals tracking
|
|
32
|
+
setupNewrelicWebVitals();
|
|
29
33
|
|
|
30
34
|
// const browserHistory = useRouterHistory(createHistory)({
|
|
31
35
|
// basename: pathConfig.publicPath,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export const HOSTNAME_PATTERN = /^(?:([^.]+)\.)?(?:([^.]+)\.)?intouch\.capillarytech\.com$/;
|
|
2
|
+
|
|
1
3
|
export const GET_SIDEBAR_REQUEST = 'app/App/GET_SIDEBAR_REQUEST';
|
|
2
4
|
export const GET_SIDEBAR_SUCCESS = 'app/App/GET_SIDEBAR_SUCCESS';
|
|
3
5
|
export const GET_SIDEBAR_FAILURE = 'app/App/GET_SIDEBAR_FAILURE';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capillarytech/creatives-library",
|
|
3
3
|
"author": "meharaj",
|
|
4
|
-
"version": "8.0.
|
|
4
|
+
"version": "8.0.170-beta.2",
|
|
5
5
|
"description": "Capillary creatives ui",
|
|
6
6
|
"main": "./index.js",
|
|
7
7
|
"module": "./index.es.js",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"@bugsnag/plugin-react": "7.2.1",
|
|
19
19
|
"@capillarytech/cap-ui-utils": "3.0.4",
|
|
20
20
|
"@capillarytech/vulcan-react-sdk": "^2.3.5",
|
|
21
|
+
"@newrelic/browser-agent": "^1.293.0",
|
|
21
22
|
"@mailupinc/bee-plugin": "^1.2.0",
|
|
22
23
|
"babel-cli": "^6.26.0",
|
|
23
24
|
"chalk": "^2.4.2",
|
package/utils/commonUtils.js
CHANGED
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { FormattedMessage } from 'react-intl';
|
|
3
3
|
import get from 'lodash/get';
|
|
4
4
|
import { convert } from "html-to-text";
|
|
5
|
+
import { BrowserAgent } from '@newrelic/browser-agent';
|
|
5
6
|
import { EMBEDDED } from "../v2Containers/Whatsapp/constants";
|
|
6
7
|
import {
|
|
7
8
|
EDIT,
|
|
@@ -18,6 +19,8 @@ import {
|
|
|
18
19
|
import { GLOBAL_CONVERT_OPTIONS } from "../v2Components/FormBuilder/constants";
|
|
19
20
|
import { checkSupport, extractNames } from "./tagValidations";
|
|
20
21
|
import { SMS_TRAI_VAR } from '../v2Containers/SmsTrai/Edit/constants';
|
|
22
|
+
import appConfig from '../../app-config';
|
|
23
|
+
import { HOSTNAME_PATTERN } from '../containers/App/constants';
|
|
21
24
|
export const apiMessageFormatHandler = (id, fallback) => (
|
|
22
25
|
<FormattedMessage id={id} defaultMessage={fallback} />
|
|
23
26
|
);
|
|
@@ -429,3 +432,50 @@ export const validateInAppContent = async (formData, options) => {
|
|
|
429
432
|
// Errors already reported via the 'onError' callback passed to _validatePlatformSpecificContent
|
|
430
433
|
return false;
|
|
431
434
|
};
|
|
435
|
+
|
|
436
|
+
// New Relic WebVitals tracking setup
|
|
437
|
+
const {
|
|
438
|
+
newrelic: { enabled = false, environments = {}, licenseKey },
|
|
439
|
+
} = appConfig;
|
|
440
|
+
|
|
441
|
+
const getNewrelicAppId = () => {
|
|
442
|
+
const hostname = window.location.hostname;
|
|
443
|
+
const match = hostname.match(HOSTNAME_PATTERN);
|
|
444
|
+
const environment = match?.[2] ?? match?.[1] ?? 'nightly';
|
|
445
|
+
return environments[environment]?.appId;
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
export const setupNewrelicWebVitals = () => {
|
|
449
|
+
if (process.env.NODE_ENV === 'production' && enabled) {
|
|
450
|
+
const options = {
|
|
451
|
+
info: {
|
|
452
|
+
applicationID: getNewrelicAppId(),
|
|
453
|
+
licenseKey: licenseKey,
|
|
454
|
+
},
|
|
455
|
+
init: {
|
|
456
|
+
ajax: { enabled: true },
|
|
457
|
+
distributed_tracing: {
|
|
458
|
+
enabled: true,
|
|
459
|
+
exclude_newrelic_header: true,
|
|
460
|
+
},
|
|
461
|
+
generic_events: { enabled: true },
|
|
462
|
+
jserrors: { enabled: true },
|
|
463
|
+
logging: { enabled: false },
|
|
464
|
+
metrics: { enabled: true },
|
|
465
|
+
page_action: { enabled: true },
|
|
466
|
+
page_view_timing: { enabled: true },
|
|
467
|
+
performance: {
|
|
468
|
+
capture_detail: true,
|
|
469
|
+
},
|
|
470
|
+
privacy: { cookies_enabled: true },
|
|
471
|
+
session_replay: { enabled: false },
|
|
472
|
+
session_trace: { enabled: true },
|
|
473
|
+
soft_navigations: { enabled: true },
|
|
474
|
+
spa: { enabled: true },
|
|
475
|
+
user_actions: { enabled: true },
|
|
476
|
+
},
|
|
477
|
+
};
|
|
478
|
+
// The agent loader code executes immediately on instantiation.
|
|
479
|
+
new BrowserAgent(options);
|
|
480
|
+
}
|
|
481
|
+
};
|
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
const { mockBrowserAgent } = require('../../../__mocks__/newRelicMock');
|
|
2
|
+
import { setupNewrelicWebVitals } from '../commonUtils';
|
|
3
|
+
|
|
4
|
+
describe('commonUtils - New Relic Integration', () => {
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
process.env.NODE_ENV = 'production';
|
|
7
|
+
mockBrowserAgent.reset();
|
|
8
|
+
delete window.location;
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
afterAll(() => {
|
|
12
|
+
process.env.NODE_ENV = 'test';
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
describe('setupNewrelicWebVitals', () => {
|
|
16
|
+
it('should initialize BrowserAgent with correct options - localhost', () => {
|
|
17
|
+
Object.defineProperty(window, 'location', {
|
|
18
|
+
value: { hostname: 'localhost' },
|
|
19
|
+
writable: true,
|
|
20
|
+
configurable: true,
|
|
21
|
+
});
|
|
22
|
+
setupNewrelicWebVitals();
|
|
23
|
+
|
|
24
|
+
expect(mockBrowserAgent).toHaveBeenCalledTimes(1);
|
|
25
|
+
|
|
26
|
+
const expectedOptions = {
|
|
27
|
+
info: {
|
|
28
|
+
applicationID: '718411553',
|
|
29
|
+
licenseKey: '082da40fff',
|
|
30
|
+
},
|
|
31
|
+
init: {
|
|
32
|
+
ajax: { enabled: true },
|
|
33
|
+
distributed_tracing: {
|
|
34
|
+
enabled: true,
|
|
35
|
+
exclude_newrelic_header: true,
|
|
36
|
+
},
|
|
37
|
+
generic_events: { enabled: true },
|
|
38
|
+
jserrors: { enabled: true },
|
|
39
|
+
logging: { enabled: false },
|
|
40
|
+
metrics: { enabled: true },
|
|
41
|
+
page_action: { enabled: true },
|
|
42
|
+
page_view_timing: { enabled: true },
|
|
43
|
+
performance: {
|
|
44
|
+
capture_detail: true,
|
|
45
|
+
},
|
|
46
|
+
privacy: { cookies_enabled: true },
|
|
47
|
+
session_replay: { enabled: false },
|
|
48
|
+
session_trace: { enabled: true },
|
|
49
|
+
soft_navigations: { enabled: true },
|
|
50
|
+
spa: { enabled: true },
|
|
51
|
+
user_actions: { enabled: true },
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
expect(mockBrowserAgent).toHaveBeenCalledWith(expectedOptions);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should initialize BrowserAgent with correct options - nightly', () => {
|
|
59
|
+
Object.defineProperty(window, 'location', {
|
|
60
|
+
value: { hostname: 'nightly.intouch.capillarytech.com' },
|
|
61
|
+
writable: true,
|
|
62
|
+
configurable: true,
|
|
63
|
+
});
|
|
64
|
+
setupNewrelicWebVitals();
|
|
65
|
+
|
|
66
|
+
expect(mockBrowserAgent).toHaveBeenCalledTimes(1);
|
|
67
|
+
|
|
68
|
+
const expectedOptions = {
|
|
69
|
+
info: {
|
|
70
|
+
applicationID: '718411553',
|
|
71
|
+
licenseKey: '082da40fff',
|
|
72
|
+
},
|
|
73
|
+
init: {
|
|
74
|
+
ajax: { enabled: true },
|
|
75
|
+
distributed_tracing: {
|
|
76
|
+
enabled: true,
|
|
77
|
+
exclude_newrelic_header: true,
|
|
78
|
+
},
|
|
79
|
+
generic_events: { enabled: true },
|
|
80
|
+
jserrors: { enabled: true },
|
|
81
|
+
logging: { enabled: false },
|
|
82
|
+
metrics: { enabled: true },
|
|
83
|
+
page_action: { enabled: true },
|
|
84
|
+
page_view_timing: { enabled: true },
|
|
85
|
+
performance: {
|
|
86
|
+
capture_detail: true,
|
|
87
|
+
},
|
|
88
|
+
privacy: { cookies_enabled: true },
|
|
89
|
+
session_replay: { enabled: false },
|
|
90
|
+
session_trace: { enabled: true },
|
|
91
|
+
soft_navigations: { enabled: true },
|
|
92
|
+
spa: { enabled: true },
|
|
93
|
+
user_actions: { enabled: true },
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
expect(mockBrowserAgent).toHaveBeenCalledWith(expectedOptions);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should initialize BrowserAgent with correct options - staging', () => {
|
|
101
|
+
Object.defineProperty(window, 'location', {
|
|
102
|
+
value: { hostname: 'staging.intouch.capillarytech.com' },
|
|
103
|
+
writable: true,
|
|
104
|
+
configurable: true,
|
|
105
|
+
});
|
|
106
|
+
setupNewrelicWebVitals();
|
|
107
|
+
|
|
108
|
+
expect(mockBrowserAgent).toHaveBeenCalledTimes(1);
|
|
109
|
+
|
|
110
|
+
const expectedOptions = {
|
|
111
|
+
info: {
|
|
112
|
+
applicationID: '718413027',
|
|
113
|
+
licenseKey: '082da40fff',
|
|
114
|
+
},
|
|
115
|
+
init: {
|
|
116
|
+
ajax: { enabled: true },
|
|
117
|
+
distributed_tracing: {
|
|
118
|
+
enabled: true,
|
|
119
|
+
exclude_newrelic_header: true,
|
|
120
|
+
},
|
|
121
|
+
generic_events: { enabled: true },
|
|
122
|
+
jserrors: { enabled: true },
|
|
123
|
+
logging: { enabled: false },
|
|
124
|
+
metrics: { enabled: true },
|
|
125
|
+
page_action: { enabled: true },
|
|
126
|
+
page_view_timing: { enabled: true },
|
|
127
|
+
performance: {
|
|
128
|
+
capture_detail: true,
|
|
129
|
+
},
|
|
130
|
+
privacy: { cookies_enabled: true },
|
|
131
|
+
session_replay: { enabled: false },
|
|
132
|
+
session_trace: { enabled: true },
|
|
133
|
+
soft_navigations: { enabled: true },
|
|
134
|
+
spa: { enabled: true },
|
|
135
|
+
user_actions: { enabled: true },
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
expect(mockBrowserAgent).toHaveBeenCalledWith(expectedOptions);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('should initialize BrowserAgent with correct options - ushc', () => {
|
|
143
|
+
Object.defineProperty(window, 'location', {
|
|
144
|
+
value: { hostname: 'ushc.intouch.capillarytech.com' },
|
|
145
|
+
writable: true,
|
|
146
|
+
configurable: true,
|
|
147
|
+
});
|
|
148
|
+
setupNewrelicWebVitals();
|
|
149
|
+
|
|
150
|
+
expect(mockBrowserAgent).toHaveBeenCalledTimes(1);
|
|
151
|
+
|
|
152
|
+
const expectedOptions = {
|
|
153
|
+
info: {
|
|
154
|
+
applicationID: '718413124',
|
|
155
|
+
licenseKey: '082da40fff',
|
|
156
|
+
},
|
|
157
|
+
init: {
|
|
158
|
+
ajax: { enabled: true },
|
|
159
|
+
distributed_tracing: {
|
|
160
|
+
enabled: true,
|
|
161
|
+
exclude_newrelic_header: true,
|
|
162
|
+
},
|
|
163
|
+
generic_events: { enabled: true },
|
|
164
|
+
jserrors: { enabled: true },
|
|
165
|
+
logging: { enabled: false },
|
|
166
|
+
metrics: { enabled: true },
|
|
167
|
+
page_action: { enabled: true },
|
|
168
|
+
page_view_timing: { enabled: true },
|
|
169
|
+
performance: {
|
|
170
|
+
capture_detail: true,
|
|
171
|
+
},
|
|
172
|
+
privacy: { cookies_enabled: true },
|
|
173
|
+
session_replay: { enabled: false },
|
|
174
|
+
session_trace: { enabled: true },
|
|
175
|
+
soft_navigations: { enabled: true },
|
|
176
|
+
spa: { enabled: true },
|
|
177
|
+
user_actions: { enabled: true },
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
expect(mockBrowserAgent).toHaveBeenCalledWith(expectedOptions);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('should initialize BrowserAgent with correct options - apac', () => {
|
|
185
|
+
Object.defineProperty(window, 'location', {
|
|
186
|
+
value: { hostname: 'apac.intouch.capillarytech.com' },
|
|
187
|
+
writable: true,
|
|
188
|
+
configurable: true,
|
|
189
|
+
});
|
|
190
|
+
setupNewrelicWebVitals();
|
|
191
|
+
|
|
192
|
+
expect(mockBrowserAgent).toHaveBeenCalledTimes(1);
|
|
193
|
+
|
|
194
|
+
const expectedOptions = {
|
|
195
|
+
info: {
|
|
196
|
+
applicationID: '718413134',
|
|
197
|
+
licenseKey: '082da40fff',
|
|
198
|
+
},
|
|
199
|
+
init: {
|
|
200
|
+
ajax: { enabled: true },
|
|
201
|
+
distributed_tracing: {
|
|
202
|
+
enabled: true,
|
|
203
|
+
exclude_newrelic_header: true,
|
|
204
|
+
},
|
|
205
|
+
generic_events: { enabled: true },
|
|
206
|
+
jserrors: { enabled: true },
|
|
207
|
+
logging: { enabled: false },
|
|
208
|
+
metrics: { enabled: true },
|
|
209
|
+
page_action: { enabled: true },
|
|
210
|
+
page_view_timing: { enabled: true },
|
|
211
|
+
performance: {
|
|
212
|
+
capture_detail: true,
|
|
213
|
+
},
|
|
214
|
+
privacy: { cookies_enabled: true },
|
|
215
|
+
session_replay: { enabled: false },
|
|
216
|
+
session_trace: { enabled: true },
|
|
217
|
+
soft_navigations: { enabled: true },
|
|
218
|
+
spa: { enabled: true },
|
|
219
|
+
user_actions: { enabled: true },
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
expect(mockBrowserAgent).toHaveBeenCalledWith(expectedOptions);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it('should initialize BrowserAgent with correct options - north-america', () => {
|
|
227
|
+
Object.defineProperty(window, 'location', {
|
|
228
|
+
value: { hostname: 'north-america.intouch.capillarytech.com' },
|
|
229
|
+
writable: true,
|
|
230
|
+
configurable: true,
|
|
231
|
+
});
|
|
232
|
+
setupNewrelicWebVitals();
|
|
233
|
+
|
|
234
|
+
expect(mockBrowserAgent).toHaveBeenCalledTimes(1);
|
|
235
|
+
|
|
236
|
+
const expectedOptions = {
|
|
237
|
+
info: {
|
|
238
|
+
applicationID: '718413144',
|
|
239
|
+
licenseKey: '082da40fff',
|
|
240
|
+
},
|
|
241
|
+
init: {
|
|
242
|
+
ajax: { enabled: true },
|
|
243
|
+
distributed_tracing: {
|
|
244
|
+
enabled: true,
|
|
245
|
+
exclude_newrelic_header: true,
|
|
246
|
+
},
|
|
247
|
+
generic_events: { enabled: true },
|
|
248
|
+
jserrors: { enabled: true },
|
|
249
|
+
logging: { enabled: false },
|
|
250
|
+
metrics: { enabled: true },
|
|
251
|
+
page_action: { enabled: true },
|
|
252
|
+
page_view_timing: { enabled: true },
|
|
253
|
+
performance: {
|
|
254
|
+
capture_detail: true,
|
|
255
|
+
},
|
|
256
|
+
privacy: { cookies_enabled: true },
|
|
257
|
+
session_replay: { enabled: false },
|
|
258
|
+
session_trace: { enabled: true },
|
|
259
|
+
soft_navigations: { enabled: true },
|
|
260
|
+
spa: { enabled: true },
|
|
261
|
+
user_actions: { enabled: true },
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
expect(mockBrowserAgent).toHaveBeenCalledWith(expectedOptions);
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
it('should initialize BrowserAgent with correct options - apac2', () => {
|
|
269
|
+
Object.defineProperty(window, 'location', {
|
|
270
|
+
value: { hostname: 'apac2.intouch.capillarytech.com' },
|
|
271
|
+
writable: true,
|
|
272
|
+
configurable: true,
|
|
273
|
+
});
|
|
274
|
+
setupNewrelicWebVitals();
|
|
275
|
+
|
|
276
|
+
expect(mockBrowserAgent).toHaveBeenCalledTimes(1);
|
|
277
|
+
|
|
278
|
+
const expectedOptions = {
|
|
279
|
+
info: {
|
|
280
|
+
applicationID: '718413155',
|
|
281
|
+
licenseKey: '082da40fff',
|
|
282
|
+
},
|
|
283
|
+
init: {
|
|
284
|
+
ajax: { enabled: true },
|
|
285
|
+
distributed_tracing: {
|
|
286
|
+
enabled: true,
|
|
287
|
+
exclude_newrelic_header: true,
|
|
288
|
+
},
|
|
289
|
+
generic_events: { enabled: true },
|
|
290
|
+
jserrors: { enabled: true },
|
|
291
|
+
logging: { enabled: false },
|
|
292
|
+
metrics: { enabled: true },
|
|
293
|
+
page_action: { enabled: true },
|
|
294
|
+
page_view_timing: { enabled: true },
|
|
295
|
+
performance: {
|
|
296
|
+
capture_detail: true,
|
|
297
|
+
},
|
|
298
|
+
privacy: { cookies_enabled: true },
|
|
299
|
+
session_replay: { enabled: false },
|
|
300
|
+
session_trace: { enabled: true },
|
|
301
|
+
soft_navigations: { enabled: true },
|
|
302
|
+
spa: { enabled: true },
|
|
303
|
+
user_actions: { enabled: true },
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
expect(mockBrowserAgent).toHaveBeenCalledWith(expectedOptions);
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it('should initialize BrowserAgent with correct options - tata', () => {
|
|
311
|
+
Object.defineProperty(window, 'location', {
|
|
312
|
+
value: { hostname: 'tata.intouch.capillarytech.com' },
|
|
313
|
+
writable: true,
|
|
314
|
+
configurable: true,
|
|
315
|
+
});
|
|
316
|
+
setupNewrelicWebVitals();
|
|
317
|
+
|
|
318
|
+
expect(mockBrowserAgent).toHaveBeenCalledTimes(1);
|
|
319
|
+
|
|
320
|
+
const expectedOptions = {
|
|
321
|
+
info: {
|
|
322
|
+
applicationID: '718413165',
|
|
323
|
+
licenseKey: '082da40fff',
|
|
324
|
+
},
|
|
325
|
+
init: {
|
|
326
|
+
ajax: { enabled: true },
|
|
327
|
+
distributed_tracing: {
|
|
328
|
+
enabled: true,
|
|
329
|
+
exclude_newrelic_header: true,
|
|
330
|
+
},
|
|
331
|
+
generic_events: { enabled: true },
|
|
332
|
+
jserrors: { enabled: true },
|
|
333
|
+
logging: { enabled: false },
|
|
334
|
+
metrics: { enabled: true },
|
|
335
|
+
page_action: { enabled: true },
|
|
336
|
+
page_view_timing: { enabled: true },
|
|
337
|
+
performance: {
|
|
338
|
+
capture_detail: true,
|
|
339
|
+
},
|
|
340
|
+
privacy: { cookies_enabled: true },
|
|
341
|
+
session_replay: { enabled: false },
|
|
342
|
+
session_trace: { enabled: true },
|
|
343
|
+
soft_navigations: { enabled: true },
|
|
344
|
+
spa: { enabled: true },
|
|
345
|
+
user_actions: { enabled: true },
|
|
346
|
+
},
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
expect(mockBrowserAgent).toHaveBeenCalledWith(expectedOptions);
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
it('should initialize BrowserAgent with correct options - sea', () => {
|
|
353
|
+
Object.defineProperty(window, 'location', {
|
|
354
|
+
value: { hostname: 'sea.intouch.capillarytech.com' },
|
|
355
|
+
writable: true,
|
|
356
|
+
configurable: true,
|
|
357
|
+
});
|
|
358
|
+
setupNewrelicWebVitals();
|
|
359
|
+
|
|
360
|
+
expect(mockBrowserAgent).toHaveBeenCalledTimes(1);
|
|
361
|
+
|
|
362
|
+
const expectedOptions = {
|
|
363
|
+
info: {
|
|
364
|
+
applicationID: '718413175',
|
|
365
|
+
licenseKey: '082da40fff',
|
|
366
|
+
},
|
|
367
|
+
init: {
|
|
368
|
+
ajax: { enabled: true },
|
|
369
|
+
distributed_tracing: {
|
|
370
|
+
enabled: true,
|
|
371
|
+
exclude_newrelic_header: true,
|
|
372
|
+
},
|
|
373
|
+
generic_events: { enabled: true },
|
|
374
|
+
jserrors: { enabled: true },
|
|
375
|
+
logging: { enabled: false },
|
|
376
|
+
metrics: { enabled: true },
|
|
377
|
+
page_action: { enabled: true },
|
|
378
|
+
page_view_timing: { enabled: true },
|
|
379
|
+
performance: {
|
|
380
|
+
capture_detail: true,
|
|
381
|
+
},
|
|
382
|
+
privacy: { cookies_enabled: true },
|
|
383
|
+
session_replay: { enabled: false },
|
|
384
|
+
session_trace: { enabled: true },
|
|
385
|
+
soft_navigations: { enabled: true },
|
|
386
|
+
spa: { enabled: true },
|
|
387
|
+
user_actions: { enabled: true },
|
|
388
|
+
},
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
expect(mockBrowserAgent).toHaveBeenCalledWith(expectedOptions);
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
it('should initialize BrowserAgent with correct options - eu', () => {
|
|
395
|
+
Object.defineProperty(window, 'location', {
|
|
396
|
+
value: { hostname: 'eu.intouch.capillarytech.com' },
|
|
397
|
+
writable: true,
|
|
398
|
+
configurable: true,
|
|
399
|
+
});
|
|
400
|
+
setupNewrelicWebVitals();
|
|
401
|
+
|
|
402
|
+
expect(mockBrowserAgent).toHaveBeenCalledTimes(1);
|
|
403
|
+
|
|
404
|
+
const expectedOptions = {
|
|
405
|
+
info: {
|
|
406
|
+
applicationID: '718413185',
|
|
407
|
+
licenseKey: '082da40fff',
|
|
408
|
+
},
|
|
409
|
+
init: {
|
|
410
|
+
ajax: { enabled: true },
|
|
411
|
+
distributed_tracing: {
|
|
412
|
+
enabled: true,
|
|
413
|
+
exclude_newrelic_header: true,
|
|
414
|
+
},
|
|
415
|
+
generic_events: { enabled: true },
|
|
416
|
+
jserrors: { enabled: true },
|
|
417
|
+
logging: { enabled: false },
|
|
418
|
+
metrics: { enabled: true },
|
|
419
|
+
page_action: { enabled: true },
|
|
420
|
+
page_view_timing: { enabled: true },
|
|
421
|
+
performance: {
|
|
422
|
+
capture_detail: true,
|
|
423
|
+
},
|
|
424
|
+
privacy: { cookies_enabled: true },
|
|
425
|
+
session_replay: { enabled: false },
|
|
426
|
+
session_trace: { enabled: true },
|
|
427
|
+
soft_navigations: { enabled: true },
|
|
428
|
+
spa: { enabled: true },
|
|
429
|
+
user_actions: { enabled: true },
|
|
430
|
+
},
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
expect(mockBrowserAgent).toHaveBeenCalledWith(expectedOptions);
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
it('should not initialize BrowserAgent in development environment', () => {
|
|
437
|
+
process.env.NODE_ENV = 'development';
|
|
438
|
+
|
|
439
|
+
Object.defineProperty(window, 'location', {
|
|
440
|
+
value: { hostname: 'nightly.intouch.capillarytech.com' },
|
|
441
|
+
writable: true,
|
|
442
|
+
configurable: true,
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
setupNewrelicWebVitals();
|
|
446
|
+
|
|
447
|
+
expect(mockBrowserAgent).not.toHaveBeenCalled();
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
describe('setupNewrelicWebVitals with disabled config', () => {
|
|
452
|
+
beforeEach(() => {
|
|
453
|
+
jest.resetModules();
|
|
454
|
+
jest.doMock('../../../app-config', () => ({
|
|
455
|
+
newrelic: {
|
|
456
|
+
enabled: false,
|
|
457
|
+
licenseKey: '082da40fff',
|
|
458
|
+
environments: {
|
|
459
|
+
nightly: {
|
|
460
|
+
appId: '718411553',
|
|
461
|
+
},
|
|
462
|
+
},
|
|
463
|
+
},
|
|
464
|
+
}));
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
afterEach(() => {
|
|
468
|
+
jest.resetModules();
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
it('should not initialize BrowserAgent when New Relic is disabled in production', () => {
|
|
472
|
+
process.env.NODE_ENV = 'production';
|
|
473
|
+
|
|
474
|
+
Object.defineProperty(window, 'location', {
|
|
475
|
+
value: { hostname: 'nightly.intouch.capillarytech.com' },
|
|
476
|
+
writable: true,
|
|
477
|
+
configurable: true,
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
const { setupNewrelicWebVitals: setupWithDisabledConfig } = require('../commonUtils');
|
|
481
|
+
setupWithDisabledConfig();
|
|
482
|
+
|
|
483
|
+
expect(mockBrowserAgent).not.toHaveBeenCalled();
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
it('should not initialize BrowserAgent when New Relic is disabled in development', () => {
|
|
487
|
+
process.env.NODE_ENV = 'development';
|
|
488
|
+
|
|
489
|
+
Object.defineProperty(window, 'location', {
|
|
490
|
+
value: { hostname: 'nightly.intouch.capillarytech.com' },
|
|
491
|
+
writable: true,
|
|
492
|
+
configurable: true,
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
const { setupNewrelicWebVitals: setupWithDisabledConfig } = require('../commonUtils');
|
|
496
|
+
setupWithDisabledConfig();
|
|
497
|
+
|
|
498
|
+
expect(mockBrowserAgent).not.toHaveBeenCalled();
|
|
499
|
+
});
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
describe('setupNewrelicWebVitals with default config values', () => {
|
|
503
|
+
beforeEach(() => {
|
|
504
|
+
jest.resetModules();
|
|
505
|
+
jest.doMock('../../../app-config', () => ({
|
|
506
|
+
newrelic: {
|
|
507
|
+
licenseKey: '082da40fff',
|
|
508
|
+
},
|
|
509
|
+
}));
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
afterEach(() => {
|
|
513
|
+
jest.resetModules();
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
it('should not initialize BrowserAgent when enabled is missing (defaults to false)', () => {
|
|
517
|
+
process.env.NODE_ENV = 'production';
|
|
518
|
+
|
|
519
|
+
Object.defineProperty(window, 'location', {
|
|
520
|
+
value: { hostname: 'nightly.intouch.capillarytech.com' },
|
|
521
|
+
writable: true,
|
|
522
|
+
configurable: true,
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
const { setupNewrelicWebVitals: setupWithDefaults } = require('../commonUtils');
|
|
526
|
+
setupWithDefaults();
|
|
527
|
+
|
|
528
|
+
expect(mockBrowserAgent).not.toHaveBeenCalled();
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
it('should handle missing environments object (defaults to empty object)', () => {
|
|
532
|
+
process.env.NODE_ENV = 'production';
|
|
533
|
+
|
|
534
|
+
Object.defineProperty(window, 'location', {
|
|
535
|
+
value: { hostname: 'nightly.intouch.capillarytech.com' },
|
|
536
|
+
writable: true,
|
|
537
|
+
configurable: true,
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
const { setupNewrelicWebVitals: setupWithDefaults } = require('../commonUtils');
|
|
541
|
+
|
|
542
|
+
expect(() => setupWithDefaults()).not.toThrow();
|
|
543
|
+
expect(mockBrowserAgent).not.toHaveBeenCalled();
|
|
544
|
+
});
|
|
545
|
+
});
|
|
546
|
+
});
|
|
@@ -20,7 +20,7 @@ import globalMessages from '../../v2Containers/Cap/messages';
|
|
|
20
20
|
import whatsappMsg from '../../v2Containers/Whatsapp/messages';
|
|
21
21
|
import messages from './messages';
|
|
22
22
|
import './index.scss';
|
|
23
|
-
import { isUrl,
|
|
23
|
+
import { isUrl, isValidWhatsappCtaText } from '../../v2Containers/Line/Container/Wrapper/utils';
|
|
24
24
|
import TagList from '../../v2Containers/TagList';
|
|
25
25
|
import {
|
|
26
26
|
CTA_OPTIONS,
|
|
@@ -144,7 +144,7 @@ export const CapWhatsappCTA = (props) => {
|
|
|
144
144
|
const onButtonTextChange = ({ target }) => {
|
|
145
145
|
const { value, id } = target;
|
|
146
146
|
let errorMessage = '';
|
|
147
|
-
if (!
|
|
147
|
+
if (!isValidWhatsappCtaText(value)) {
|
|
148
148
|
errorMessage = formatMessage(messages.ctaButtonErrorMessage);
|
|
149
149
|
}
|
|
150
150
|
setButtonError(errorMessage);
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
KARIX_GUPSHUP_URL_OPTIONS, TWILIO_URL_OPTIONS, DYNAMIC_URL, STATIC_URL,
|
|
35
35
|
} from "../CapWhatsappCTA/constants";
|
|
36
36
|
import globalMessages from '../../v2Containers/Cap/messages';
|
|
37
|
-
import { isUrl,
|
|
37
|
+
import { isUrl, isValidWhatsappCtaText } from '../../v2Containers/Line/Container/Wrapper/utils';
|
|
38
38
|
import { HOST_TWILIO } from "../../v2Containers/Whatsapp/constants";
|
|
39
39
|
import "./index.scss";
|
|
40
40
|
|
|
@@ -119,7 +119,7 @@ export const CapWhatsappCarouselButton = (props) => {
|
|
|
119
119
|
|
|
120
120
|
const onButtonTextChange = (value, buttonIndex) => {
|
|
121
121
|
let errorMessage = '';
|
|
122
|
-
if (!
|
|
122
|
+
if (!isValidWhatsappCtaText(value)) {
|
|
123
123
|
errorMessage = formatMessage(capWhatsappCTAMsg.ctaButtonErrorMessage);
|
|
124
124
|
}
|
|
125
125
|
onValueChange(buttonIndex, [{fieldName: 'text', value}, {fieldName: 'textError', value: errorMessage}]);
|
|
@@ -188,7 +188,7 @@ const useEmailWrapper = ({
|
|
|
188
188
|
CapNotification.error(message);
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
|
-
}, [isUploading, formatMessage,
|
|
191
|
+
}, [isUploading, formatMessage, stopTimerGA, handleZipUploadError, showNextStep]);
|
|
192
192
|
|
|
193
193
|
const handleEdmDefaultTemplateSelection = useCallback((id) => {
|
|
194
194
|
const data = find(CmsTemplates, { _id: id });
|
|
@@ -251,7 +251,7 @@ const useEmailWrapper = ({
|
|
|
251
251
|
getCmsTemplatesInProgress,
|
|
252
252
|
modeContent.id,
|
|
253
253
|
SelectedEdmDefaultTemplate,
|
|
254
|
-
templatesActions,
|
|
254
|
+
// templatesActions,
|
|
255
255
|
handleEdmDefaultTemplateSelection
|
|
256
256
|
]);
|
|
257
257
|
|
|
@@ -5,7 +5,7 @@ import { initialReducer } from '../../../../../initialReducer';
|
|
|
5
5
|
import { mountWithIntl } from '../../../../../helpers/intl-enzym-test-helpers';
|
|
6
6
|
import { LineWrapper } from '../index';
|
|
7
7
|
import { mockData } from './mockData';
|
|
8
|
-
import {isValidText} from '../utils';
|
|
8
|
+
import {isValidText, isValidWhatsappCtaText} from '../utils';
|
|
9
9
|
import history from '../../../../../utils/history';
|
|
10
10
|
|
|
11
11
|
let store;
|
|
@@ -92,5 +92,60 @@ describe('line wrapper test/>', () => {
|
|
|
92
92
|
expect(isValidText(emptyString)).toBe(true);
|
|
93
93
|
});
|
|
94
94
|
});
|
|
95
|
+
|
|
96
|
+
describe('isValidWhatsappCtaText', () => {
|
|
97
|
+
it('should return false for non-string input', () => {
|
|
98
|
+
expect(isValidWhatsappCtaText(123)).toBe(false);
|
|
99
|
+
expect(isValidWhatsappCtaText(null)).toBe(false);
|
|
100
|
+
expect(isValidWhatsappCtaText(undefined)).toBe(false);
|
|
101
|
+
expect(isValidWhatsappCtaText({})).toBe(false);
|
|
102
|
+
expect(isValidWhatsappCtaText([])).toBe(false);
|
|
103
|
+
expect(isValidWhatsappCtaText(true)).toBe(false);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('should return true for multilingual and symbol text', () => {
|
|
107
|
+
const valid = '確認一下 Привет مرحبا मान्य 123 @#&!?.:, -+/\\\'"=&₹€£$^(){}';
|
|
108
|
+
expect(isValidWhatsappCtaText(valid)).toBe(true);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('should return true for full allowed punctuation set', () => {
|
|
112
|
+
const allowed = 'A1 z9 @#&!?.:, -+/\\\'"=&₹€£$^(){}';
|
|
113
|
+
expect(isValidWhatsappCtaText(allowed)).toBe(true);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should return false for whitespace-only', () => {
|
|
117
|
+
expect(isValidWhatsappCtaText(' ')).toBe(false);
|
|
118
|
+
expect(isValidWhatsappCtaText('\t\t')).toBe(false);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('should return true for leading and trailing spaces with valid text', () => {
|
|
122
|
+
expect(isValidWhatsappCtaText(' Hi')).toBe(true);
|
|
123
|
+
expect(isValidWhatsappCtaText('Hi ')).toBe(true);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should return false for control or markdown chars', () => {
|
|
127
|
+
expect(isValidWhatsappCtaText('Hello\nWorld')).toBe(false);
|
|
128
|
+
expect(isValidWhatsappCtaText('Hello\tWorld')).toBe(false);
|
|
129
|
+
expect(isValidWhatsappCtaText('*bold*')).toBe(false);
|
|
130
|
+
expect(isValidWhatsappCtaText('_under_')).toBe(false);
|
|
131
|
+
expect(isValidWhatsappCtaText('~strike~')).toBe(false);
|
|
132
|
+
expect(isValidWhatsappCtaText('`code`')).toBe(false);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('should return false for emojis, flags, ZWJ sequences and VS16', () => {
|
|
136
|
+
expect(isValidWhatsappCtaText('Heart ❤️')).toBe(false);
|
|
137
|
+
expect(isValidWhatsappCtaText('Flag 🇮🇳')).toBe(false);
|
|
138
|
+
expect(isValidWhatsappCtaText('Family 👨👩👧👦')).toBe(false);
|
|
139
|
+
expect(isValidWhatsappCtaText('Sun ☀️')).toBe(false);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('should return false for mixed valid text with emoji inside', () => {
|
|
143
|
+
expect(isValidWhatsappCtaText('Hello @# hi ❤️')).toBe(false);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('should return true for backslash usage', () => {
|
|
147
|
+
expect(isValidWhatsappCtaText('C:\\Path')).toBe(true);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
95
150
|
|
|
96
151
|
});
|
|
@@ -78,3 +78,12 @@ export const isValidText = (text) => {
|
|
|
78
78
|
return regex.test(text);
|
|
79
79
|
};
|
|
80
80
|
|
|
81
|
+
// WhatsApp CTA button text validation - whitelist approach
|
|
82
|
+
// Allow: all letters and numbers (any language), regular space, and safe symbols
|
|
83
|
+
// Safe symbols: @ # & ! ? . : , - + / \ ' " = & ₹ € £ $ ^ ( ) { }
|
|
84
|
+
export const isValidWhatsappCtaText = (text) => {
|
|
85
|
+
if (typeof text !== 'string') return false;
|
|
86
|
+
if (!/\S/.test(text)) return false; // disallow whitespace-only
|
|
87
|
+
const regex = /^[\p{L}\p{M}\p{N} @#&!?.:,\-+/\\'"=&₹€£$^(){}]*$/u;
|
|
88
|
+
return regex.test(text);
|
|
89
|
+
};
|