@capillarytech/creatives-library 8.0.85-alpha.0 → 8.0.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import { expectSaga } from 'redux-saga-test-plan';
2
- import { call } from 'redux-saga/effects';
2
+ import { call, put } from 'redux-saga/effects';
3
3
  import { throwError } from 'redux-saga-test-plan/providers';
4
4
  import * as Api from '../../../services/api';
5
5
  import * as types from '../constants';
@@ -10,79 +10,472 @@ describe('Email Template Sagas', () => {
10
10
  jest.setTimeout(1000);
11
11
 
12
12
  describe('createTemplate Saga', () => {
13
- const template = { name: 'New Template' };
13
+ const template = { name: 'Test Template', content: 'Test Content' };
14
14
 
15
- it('handles creating a template successfully', () => {
16
- const fakeResponse = {
17
- response: { id: 1, name: 'New Template' },
15
+ it('should handle successful template creation', () => {
16
+ const generator = sagas.createTemplate(template);
17
+ const response = {
18
+ response: { id: 1, name: 'Test Template' },
18
19
  status: { code: 200 },
19
20
  };
20
21
 
21
- return expectSaga(sagas.createTemplate, template)
22
- .provide([
23
- [call(Api.createEmailTemplate, template), fakeResponse],
24
- ])
25
- .put({
22
+ expect(generator.next().value)
23
+ .toEqual(call(Api.createEmailTemplate, template));
24
+
25
+ expect(generator.next(response).value)
26
+ .toEqual(put({
26
27
  type: types.CREATE_TEMPLATE_SUCCESS,
27
- data: fakeResponse.response,
28
- statusCode: 200,
28
+ data: response.response,
29
+ statusCode: response.status.code,
29
30
  errorMsg: undefined,
30
- })
31
- .run();
31
+ }));
32
+
33
+ expect(generator.next().done).toBeTruthy();
32
34
  });
33
35
 
34
- it('handles failure when creating a template', () => {
35
- const error = new Error('Failed to create template');
36
+ it('should handle server error with status code 500', () => {
37
+ const generator = sagas.createTemplate(template);
38
+ const response = {
39
+ message: 'Internal Server Error',
40
+ status: { code: 500 },
41
+ };
36
42
 
37
- return expectSaga(sagas.createTemplate, template)
38
- .provide([
39
- [call(Api.createEmailTemplate, template), throwError(error)],
40
- ])
41
- .put({
43
+ expect(generator.next().value)
44
+ .toEqual(call(Api.createEmailTemplate, template));
45
+
46
+ expect(generator.next(response).value)
47
+ .toEqual(put({
48
+ type: types.CREATE_TEMPLATE_SUCCESS,
49
+ data: undefined,
50
+ statusCode: 500,
51
+ errorMsg: 'Internal Server Error',
52
+ }));
53
+
54
+ expect(generator.next().done).toBeTruthy();
55
+ });
56
+
57
+ it('should handle API error response with message', () => {
58
+ const generator = sagas.createTemplate(template);
59
+ const response = {
60
+ message: 'Validation Error',
61
+ status: { code: 400 },
62
+ };
63
+
64
+ expect(generator.next().value)
65
+ .toEqual(call(Api.createEmailTemplate, template));
66
+
67
+ expect(generator.next(response).value)
68
+ .toEqual(put({
69
+ type: types.CREATE_TEMPLATE_SUCCESS,
70
+ data: undefined,
71
+ statusCode: 400,
72
+ errorMsg: 'Validation Error',
73
+ }));
74
+
75
+ expect(generator.next().done).toBeTruthy();
76
+ });
77
+
78
+ it('should handle API call exception', () => {
79
+ const generator = sagas.createTemplate(template);
80
+ const error = new Error('Network Error');
81
+
82
+ expect(generator.next().value)
83
+ .toEqual(call(Api.createEmailTemplate, template));
84
+
85
+ expect(generator.throw(error).value)
86
+ .toEqual(put({
42
87
  type: types.CREATE_TEMPLATE_FAILURE,
43
88
  error,
44
89
  errorMsg: undefined,
45
- })
46
- .run();
90
+ }));
91
+
92
+ expect(generator.next().done).toBeTruthy();
93
+ });
94
+
95
+ it('should set empty string statusCode when status is null', () => {
96
+ const generator = sagas.createTemplate(template);
97
+ const response = {
98
+ response: { id: 1, name: 'Test Template' },
99
+ status: null,
100
+ message: 'Success',
101
+ };
102
+
103
+ expect(generator.next().value)
104
+ .toEqual(call(Api.createEmailTemplate, template));
105
+
106
+ expect(generator.next(response).value)
107
+ .toEqual(put({
108
+ type: types.CREATE_TEMPLATE_SUCCESS,
109
+ data: response.response,
110
+ statusCode: "",
111
+ errorMsg: response.message,
112
+ }));
113
+
114
+ expect(generator.next().done).toBeTruthy();
115
+ });
116
+
117
+ it('should set empty string statusCode when status is undefined', () => {
118
+ const generator = sagas.createTemplate(template);
119
+ const response = {
120
+ response: { id: 1, name: 'Test Template' },
121
+ message: 'Success',
122
+ };
123
+
124
+ expect(generator.next().value)
125
+ .toEqual(call(Api.createEmailTemplate, template));
126
+
127
+ expect(generator.next(response).value)
128
+ .toEqual(put({
129
+ type: types.CREATE_TEMPLATE_SUCCESS,
130
+ data: response.response,
131
+ statusCode: "",
132
+ errorMsg: response.message,
133
+ }));
134
+
135
+ expect(generator.next().done).toBeTruthy();
136
+ });
137
+
138
+ it('should set empty string statusCode when status.code is null', () => {
139
+ const generator = sagas.createTemplate(template);
140
+ const response = {
141
+ response: { id: 1, name: 'Test Template' },
142
+ status: { code: null },
143
+ message: 'Success',
144
+ };
145
+
146
+ expect(generator.next().value)
147
+ .toEqual(call(Api.createEmailTemplate, template));
148
+
149
+ expect(generator.next(response).value)
150
+ .toEqual(put({
151
+ type: types.CREATE_TEMPLATE_SUCCESS,
152
+ data: response.response,
153
+ statusCode: null,
154
+ errorMsg: response.message,
155
+ }));
156
+
157
+ expect(generator.next().done).toBeTruthy();
158
+ });
159
+
160
+ it('should set empty string statusCode when status.code is undefined', () => {
161
+ const generator = sagas.createTemplate(template);
162
+ const response = {
163
+ response: { id: 1, name: 'Test Template' },
164
+ status: { code: undefined },
165
+ message: 'Success',
166
+ };
167
+
168
+ expect(generator.next().value)
169
+ .toEqual(call(Api.createEmailTemplate, template));
170
+
171
+ expect(generator.next(response).value)
172
+ .toEqual(put({
173
+ type: types.CREATE_TEMPLATE_SUCCESS,
174
+ data: response.response,
175
+ statusCode: undefined,
176
+ errorMsg: response.message,
177
+ }));
178
+
179
+ expect(generator.next().done).toBeTruthy();
180
+ });
181
+
182
+ it('should set empty string statusCode when status is an empty object', () => {
183
+ const generator = sagas.createTemplate(template);
184
+ const response = {
185
+ response: { id: 1, name: 'Test Template' },
186
+ status: {},
187
+ message: 'Success',
188
+ };
189
+
190
+ expect(generator.next().value)
191
+ .toEqual(call(Api.createEmailTemplate, template));
192
+
193
+ expect(generator.next(response).value)
194
+ .toEqual(put({
195
+ type: types.CREATE_TEMPLATE_SUCCESS,
196
+ data: response.response,
197
+ statusCode: undefined,
198
+ errorMsg: response.message,
199
+ }));
200
+
201
+ expect(generator.next().done).toBeTruthy();
47
202
  });
48
203
  });
49
204
 
50
- describe('duplicateTemplate Saga', () => {
51
- const id = 1;
205
+ describe('duplicateTemplate saga', () => {
206
+ const templateId = 123;
52
207
  const channel = 'email';
53
208
 
54
- it('handles duplicating a template successfully', () => {
55
- const fakeResponse = {
56
- response: { id: 2, name: 'Duplicated Template' },
209
+ it('should handle successful template duplication with complete response', () => {
210
+ const generator = sagas.duplicateTemplate(templateId, channel);
211
+ const response = {
212
+ response: { id: 456, name: 'Duplicated Template' },
57
213
  status: { code: 200 },
214
+ message: 'Template duplicated successfully',
58
215
  };
59
216
 
60
- return expectSaga(sagas.duplicateTemplate, id, channel)
61
- .provide([
62
- [call(Api.duplicateTemplate, id, channel), fakeResponse],
63
- ])
64
- .put({
217
+ expect(generator.next().value)
218
+ .toEqual(call(Api.duplicateTemplate, templateId, channel));
219
+
220
+ expect(generator.next(response).value)
221
+ .toEqual(put({
65
222
  type: types.DUPLICATE_TEMPLATE_SUCCESS,
66
- data: fakeResponse.response,
223
+ data: response.response,
224
+ statusCode: response.status.code,
225
+ errorMsg: response.message,
226
+ }));
227
+
228
+ expect(generator.next().done).toBeTruthy();
229
+ });
230
+
231
+ it('should handle response with missing status object', () => {
232
+ const generator = sagas.duplicateTemplate(templateId, channel);
233
+ const response = {
234
+ response: { id: 456, name: 'Duplicated Template' },
235
+ message: 'Success without status',
236
+ };
237
+
238
+ expect(generator.next().value)
239
+ .toEqual(call(Api.duplicateTemplate, templateId, channel));
240
+
241
+ expect(generator.next(response).value)
242
+ .toEqual(put({
243
+ type: types.DUPLICATE_TEMPLATE_SUCCESS,
244
+ data: response.response,
245
+ statusCode: '',
246
+ errorMsg: response.message,
247
+ }));
248
+
249
+ expect(generator.next().done).toBeTruthy();
250
+ });
251
+
252
+ it('should handle response with empty status object', () => {
253
+ const generator = sagas.duplicateTemplate(templateId, channel);
254
+ const response = {
255
+ response: { id: 456, name: 'Duplicated Template' },
256
+ status: {},
257
+ message: 'Success with empty status',
258
+ };
259
+
260
+ expect(generator.next().value)
261
+ .toEqual(call(Api.duplicateTemplate, templateId, channel));
262
+
263
+ expect(generator.next(response).value)
264
+ .toEqual(put({
265
+ type: types.DUPLICATE_TEMPLATE_SUCCESS,
266
+ data: response.response,
267
+ statusCode: undefined,
268
+ errorMsg: response.message,
269
+ }));
270
+
271
+ expect(generator.next().done).toBeTruthy();
272
+ });
273
+
274
+ it('should handle response with null status', () => {
275
+ const generator = sagas.duplicateTemplate(templateId, channel);
276
+ const response = {
277
+ response: { id: 456, name: 'Duplicated Template' },
278
+ status: null,
279
+ message: 'Success with null status',
280
+ };
281
+
282
+ expect(generator.next().value)
283
+ .toEqual(call(Api.duplicateTemplate, templateId, channel));
284
+
285
+ expect(generator.next(response).value)
286
+ .toEqual(put({
287
+ type: types.DUPLICATE_TEMPLATE_SUCCESS,
288
+ data: response.response,
289
+ statusCode: '',
290
+ errorMsg: response.message,
291
+ }));
292
+
293
+ expect(generator.next().done).toBeTruthy();
294
+ });
295
+
296
+ it('should handle response with undefined status code', () => {
297
+ const generator = sagas.duplicateTemplate(templateId, channel);
298
+ const response = {
299
+ response: { id: 456, name: 'Duplicated Template' },
300
+ status: { code: undefined },
301
+ message: 'Success with undefined status code',
302
+ };
303
+
304
+ expect(generator.next().value)
305
+ .toEqual(call(Api.duplicateTemplate, templateId, channel));
306
+
307
+ expect(generator.next(response).value)
308
+ .toEqual(put({
309
+ type: types.DUPLICATE_TEMPLATE_SUCCESS,
310
+ data: response.response,
311
+ statusCode: undefined,
312
+ errorMsg: response.message,
313
+ }));
314
+
315
+ expect(generator.next().done).toBeTruthy();
316
+ });
317
+
318
+ it('should handle response with missing response data', () => {
319
+ const generator = sagas.duplicateTemplate(templateId, channel);
320
+ const response = {
321
+ status: { code: 200 },
322
+ message: 'Success but no response data',
323
+ };
324
+
325
+ expect(generator.next().value)
326
+ .toEqual(call(Api.duplicateTemplate, templateId, channel));
327
+
328
+ expect(generator.next(response).value)
329
+ .toEqual(put({
330
+ type: types.DUPLICATE_TEMPLATE_SUCCESS,
331
+ data: undefined,
332
+ statusCode: response.status.code,
333
+ errorMsg: response.message,
334
+ }));
335
+
336
+ expect(generator.next().done).toBeTruthy();
337
+ });
338
+
339
+ it('should handle error response', () => {
340
+ const generator = sagas.duplicateTemplate(templateId, channel);
341
+ const error = new Error('Duplication failed');
342
+
343
+ expect(generator.next().value)
344
+ .toEqual(call(Api.duplicateTemplate, templateId, channel));
345
+
346
+ expect(generator.throw(error).value)
347
+ .toEqual(put({
348
+ type: types.DUPLICATE_TEMPLATE_FAILURE,
349
+ error,
350
+ errorMsg: undefined,
351
+ }));
352
+
353
+ expect(generator.next().done).toBeTruthy();
354
+ });
355
+
356
+ it('should set errorMsg when status code is 500', () => {
357
+ const generator = sagas.duplicateTemplate(templateId, channel);
358
+ const response = {
359
+ response: { id: 456 },
360
+ status: { code: 500 },
361
+ message: 'Internal Server Error',
362
+ };
363
+
364
+ expect(generator.next().value)
365
+ .toEqual(call(Api.duplicateTemplate, templateId, channel));
366
+
367
+ expect(generator.next(response).value)
368
+ .toEqual(put({
369
+ type: types.DUPLICATE_TEMPLATE_SUCCESS,
370
+ data: response.response,
371
+ statusCode: 500,
372
+ errorMsg: 'Internal Server Error',
373
+ }));
374
+
375
+ expect(generator.next().done).toBeTruthy();
376
+ });
377
+
378
+ it('should set errorMsg when both message exists and status code is 500', () => {
379
+ const generator = sagas.duplicateTemplate(templateId, channel);
380
+ const response = {
381
+ response: null,
382
+ status: { code: 500 },
383
+ message: 'Custom Error Message',
384
+ };
385
+
386
+ expect(generator.next().value)
387
+ .toEqual(call(Api.duplicateTemplate, templateId, channel));
388
+
389
+ expect(generator.next(response).value)
390
+ .toEqual(put({
391
+ type: types.DUPLICATE_TEMPLATE_SUCCESS,
392
+ data: null,
393
+ statusCode: 500,
394
+ errorMsg: 'Custom Error Message',
395
+ }));
396
+
397
+ expect(generator.next().done).toBeTruthy();
398
+ });
399
+
400
+ it('should set errorMsg when message exists but status code is not 500', () => {
401
+ const generator = sagas.duplicateTemplate(templateId, channel);
402
+ const response = {
403
+ response: { id: 456 },
404
+ status: { code: 400 },
405
+ message: 'Bad Request Error',
406
+ };
407
+
408
+ expect(generator.next().value)
409
+ .toEqual(call(Api.duplicateTemplate, templateId, channel));
410
+
411
+ expect(generator.next(response).value)
412
+ .toEqual(put({
413
+ type: types.DUPLICATE_TEMPLATE_SUCCESS,
414
+ data: response.response,
415
+ statusCode: 400,
416
+ errorMsg: 'Bad Request Error',
417
+ }));
418
+
419
+ expect(generator.next().done).toBeTruthy();
420
+ });
421
+
422
+ it('should handle case when status code is 500 but no message exists', () => {
423
+ const generator = sagas.duplicateTemplate(templateId, channel);
424
+ const response = {
425
+ response: { id: 456 },
426
+ status: { code: 500 },
427
+ };
428
+
429
+ expect(generator.next().value)
430
+ .toEqual(call(Api.duplicateTemplate, templateId, channel));
431
+
432
+ expect(generator.next(response).value)
433
+ .toEqual(put({
434
+ type: types.DUPLICATE_TEMPLATE_SUCCESS,
435
+ data: response.response,
436
+ statusCode: 500,
437
+ errorMsg: undefined,
438
+ }));
439
+
440
+ expect(generator.next().done).toBeTruthy();
441
+ });
442
+
443
+ it('should not set errorMsg when no message and status code is not 500', () => {
444
+ const generator = sagas.duplicateTemplate(templateId, channel);
445
+ const response = {
446
+ response: { id: 456 },
447
+ status: { code: 200 },
448
+ };
449
+
450
+ expect(generator.next().value)
451
+ .toEqual(call(Api.duplicateTemplate, templateId, channel));
452
+
453
+ expect(generator.next(response).value)
454
+ .toEqual(put({
455
+ type: types.DUPLICATE_TEMPLATE_SUCCESS,
456
+ data: response.response,
67
457
  statusCode: 200,
68
458
  errorMsg: undefined,
69
- })
70
- .run();
459
+ }));
460
+
461
+ expect(generator.next().done).toBeTruthy();
71
462
  });
72
463
 
73
- it('handles failure when duplicating a template', () => {
74
- const error = new Error('Failed to duplicate template');
464
+ it('should handle case when accessing status.code throws error', () => {
465
+ const generator = sagas.duplicateTemplate(templateId, channel);
466
+ const error = new TypeError("Cannot read property 'code' of undefined");
75
467
 
76
- return expectSaga(sagas.duplicateTemplate, id, channel)
77
- .provide([
78
- [call(Api.duplicateTemplate, id, channel), throwError(error)],
79
- ])
80
- .put({
468
+ expect(generator.next().value)
469
+ .toEqual(call(Api.duplicateTemplate, templateId, channel));
470
+
471
+ expect(generator.throw(error).value)
472
+ .toEqual(put({
81
473
  type: types.DUPLICATE_TEMPLATE_FAILURE,
82
474
  error,
83
475
  errorMsg: undefined,
84
- })
85
- .run();
476
+ }));
477
+
478
+ expect(generator.next().done).toBeTruthy();
86
479
  });
87
480
  });
88
481
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "8.0.85-alpha.0",
4
+ "version": "8.0.86",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -525,10 +525,10 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
525
525
  return actionLink;
526
526
  }).filter((actionLink) => actionLink);
527
527
  // Check if base URL already has query parameters
528
- const baseUrl = obj.versions.base.ANDROID.cta.actionLink;
528
+ const baseUrl = obj?.versions?.base?.ANDROID?.cta?.actionLink;
529
529
  if (params.length) {
530
530
  // Only append parameters if the URL doesn't already have them
531
- if (baseUrl.indexOf('?') === -1) {
531
+ if (baseUrl?.indexOf('?') === -1) {
532
532
  obj.versions.base.ANDROID.cta.actionLink = `${baseUrl}?${params.join('&')}`;
533
533
  } else {
534
534
  // URL already has parameters, don't append them again
@@ -604,10 +604,10 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
604
604
  return actionLink;
605
605
  }).filter((actionLink) => actionLink);
606
606
  // Check if base URL already has query parameters
607
- const baseUrl = obj.versions.base.IOS.cta.actionLink;
607
+ const baseUrl = obj?.versions?.base?.IOS?.cta?.actionLink;
608
608
  if (params.length) {
609
609
  // Only append parameters if the URL doesn't already have them
610
- if (baseUrl.indexOf('?') === -1) {
610
+ if (baseUrl?.indexOf('?') === -1) {
611
611
  obj.versions.base.IOS.cta.actionLink = `${baseUrl}?${params.join('&')}`;
612
612
  } else {
613
613
  // URL already has parameters, don't append them again
@@ -775,12 +775,12 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
775
775
  const originalUrl = android['cta-deeplink-secondary-cta-0-select'];
776
776
 
777
777
  // Check if URL contains custom parameters that need extraction
778
- if (originalUrl.includes('custom_param=')) {
778
+ if (originalUrl?.includes('custom_param=')) {
779
779
  const link = originalUrl.split('?')[0];
780
780
  const params = originalUrl.split('?')[1] && originalUrl.split('?')[1].split('&');
781
781
 
782
782
  // Only process and extract custom parameters
783
- const customParams = params?.filter(param => param.startsWith('custom_param='));
783
+ const customParams = params?.filter(param => param?.startsWith('custom_param='));
784
784
 
785
785
  if (customParams?.length) {
786
786
  android['cta-deeplink-secondary-cta-0-select'] = link;
@@ -792,25 +792,25 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
792
792
  // If no custom parameters, keep original URL intact
793
793
  // android['cta-deeplink-secondary-cta-0-select'] remains unchanged
794
794
  }
795
- if (androidData.expandableDetails && androidData.expandableDetails.ctas && androidData.expandableDetails.ctas.length > 1) {
795
+ if (androidData?.expandableDetails && androidData?.expandableDetails?.ctas && androidData?.expandableDetails?.ctas?.length > 1) {
796
796
  android['add-sec-cta-2'] = true;
797
- android['cta-deeplink-secondary-cta-1'] = androidData.expandableDetails.ctas[1].type === "DEEP_LINK" ? "Deeplink" : "External Link";
798
- if (androidData.expandableDetails.ctas[1].type === "DEEP_LINK") {
799
- android['cta-deeplink-secondary-cta-1-select'] = androidData.expandableDetails.ctas[1].actionLink;
797
+ android['cta-deeplink-secondary-cta-1'] = androidData?.expandableDetails?.ctas[1]?.type === "DEEP_LINK" ? "Deeplink" : "External Link";
798
+ if (androidData?.expandableDetails?.ctas[1]?.type === "DEEP_LINK") {
799
+ android['cta-deeplink-secondary-cta-1-select'] = androidData?.expandableDetails?.ctas[1]?.actionLink;
800
800
  } else {
801
- android['cta-deeplink-secondary-cta-1-text'] = androidData.expandableDetails.ctas[1].actionLink;
801
+ android['cta-deeplink-secondary-cta-1-text'] = androidData?.expandableDetails?.ctas[1]?.actionLink;
802
802
  }
803
- android['secondary-cta-1-label'] = androidData.expandableDetails.ctas[1].actionText;
804
- if (androidData.expandableDetails.ctas[1].type === "DEEP_LINK" && android['cta-deeplink-secondary-cta-1-select']) {
803
+ android['secondary-cta-1-label'] = androidData?.expandableDetails?.ctas[1]?.actionText;
804
+ if (androidData?.expandableDetails?.ctas[1]?.type === "DEEP_LINK" && android['cta-deeplink-secondary-cta-1-select']) {
805
805
  const originalUrl = android['cta-deeplink-secondary-cta-1-select'];
806
806
 
807
807
  // Check if URL contains custom parameters that need extraction
808
- if (originalUrl.includes('custom_param=')) {
808
+ if (originalUrl?.includes('custom_param=')) {
809
809
  const link = originalUrl.split('?')[0];
810
810
  const params = originalUrl.split('?')[1] && originalUrl.split('?')[1].split('&');
811
811
 
812
812
  // Only process and extract custom parameters
813
- const customParams = params?.filter(param => param.startsWith('custom_param='));
813
+ const customParams = params?.filter(param => param?.startsWith('custom_param='));
814
814
 
815
815
  if (customParams?.length) {
816
816
  android['cta-deeplink-secondary-cta-1-select'] = link;
@@ -822,9 +822,6 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
822
822
  // If no custom parameters, keep original URL intact
823
823
  // android['cta-deeplink-secondary-cta-1-select'] remains unchanged
824
824
  }
825
- if (androidData.expandableDetails && androidData.expandableDetails.ctas?.[1]?.type === "DEEP_LINK") {
826
- android['cta-deeplink-secondary-cta-1-select'] = androidData.expandableDetails.ctas[1].actionLink;
827
- }
828
825
  }
829
826
  }
830
827
  }
@@ -864,12 +861,12 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
864
861
  const originalUrl = ios['cta-deeplink-secondary-cta-1-select2'];
865
862
 
866
863
  // Check if URL contains custom parameters that need extraction
867
- if (originalUrl.includes('custom_param=')) {
864
+ if (originalUrl?.includes('custom_param=')) {
868
865
  const link = originalUrl.split('?')[0];
869
866
  const params = originalUrl.split('?')[1] && originalUrl.split('?')[1].split('&');
870
867
 
871
868
  // Only process and extract custom parameters
872
- const customParams = params?.filter(param => param.startsWith('custom_param='));
869
+ const customParams = params?.filter(param => param?.startsWith('custom_param='));
873
870
 
874
871
  if (customParams?.length) {
875
872
  ios['cta-deeplink-secondary-cta-1-select2'] = link;