@capillarytech/creatives-library 8.0.114-alpha.1 → 8.0.114

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.
Files changed (37) hide show
  1. package/package.json +1 -1
  2. package/utils/commonUtils.js +3 -359
  3. package/utils/tagValidations.js +5 -20
  4. package/utils/tests/commonUtil.test.js +171 -474
  5. package/utils/tests/tagValidations.test.js +2 -89
  6. package/v2Components/ErrorInfoNote/index.js +46 -114
  7. package/v2Components/ErrorInfoNote/messages.js +0 -25
  8. package/v2Components/ErrorInfoNote/style.scss +1 -14
  9. package/v2Components/FormBuilder/index.js +127 -204
  10. package/v2Components/FormBuilder/messages.js +1 -1
  11. package/v2Containers/Cap/reducer.js +4 -4
  12. package/v2Containers/CreativesContainer/SlideBoxContent.js +3 -23
  13. package/v2Containers/CreativesContainer/SlideBoxFooter.js +1 -3
  14. package/v2Containers/CreativesContainer/constants.js +1 -4
  15. package/v2Containers/CreativesContainer/index.js +19 -44
  16. package/v2Containers/CreativesContainer/messages.js +0 -4
  17. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +3 -21
  18. package/v2Containers/Ebill/index.js +3 -3
  19. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +1 -1
  20. package/v2Containers/InApp/index.js +50 -123
  21. package/v2Containers/InApp/tests/index.test.js +1 -1
  22. package/v2Containers/InApp/tests/sagas.test.js +1 -1
  23. package/v2Containers/InApp/utils.js +0 -37
  24. package/v2Containers/MobilePush/Create/index.js +20 -24
  25. package/v2Containers/MobilePush/Edit/index.js +2 -6
  26. package/v2Containers/MobilepushWrapper/index.js +0 -2
  27. package/v2Containers/Sms/Create/index.js +0 -1
  28. package/v2Containers/Sms/Edit/index.js +0 -2
  29. package/v2Containers/SmsWrapper/index.js +0 -2
  30. package/v2Containers/Whatsapp/constants.js +1 -1
  31. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +57476 -0
  32. package/v2Containers/Whatsapp/tests/index.test.js +88 -0
  33. package/v2Components/ErrorInfoNote/ErrorTypeRenderer.js +0 -127
  34. package/v2Components/ErrorInfoNote/ErrorTypeRenderer.test.js +0 -147
  35. package/v2Components/ErrorInfoNote/utils.js +0 -38
  36. package/v2Components/ErrorInfoNote/utils.test.js +0 -156
  37. package/v2Containers/InApp/tests/utils.test.js +0 -41
@@ -1,525 +1,222 @@
1
- import {
2
- validateLiquidTemplateContent,
3
- validateMobilePushContent,
4
- validateInAppContent,
5
- getChannelData
6
- } from "../commonUtils";
7
-
8
- describe("validateLiquidTemplateContent", () => {
9
- const formatMessage = jest.fn((msg, vars) =>
10
- vars ? `${msg.id}:${vars.unsupportedTags}` : msg.id
11
- );
12
- const messages = {
13
- emailBodyEmptyError: { id: "empty" },
14
- somethingWentWrong: { id: "wrong" },
15
- unsupportedTagsValidationError: { id: "unsupported" }
16
- };
17
- const tagLookupMap = { foo: true };
18
- const eventContextTags = [{ tagName: "bar" }];
19
- const onError = jest.fn();
20
- const onSuccess = jest.fn();
21
-
22
- beforeEach(() => {
23
- jest.clearAllMocks();
24
- });
25
-
26
- it("calls onError for empty content", async () => {
27
- const getLiquidTags = jest.fn((content, cb) =>
28
- cb({ errors: [], data: [] })
29
- );
30
- await validateLiquidTemplateContent("", {
31
- getLiquidTags,
32
- formatMessage,
33
- messages,
34
- onError,
35
- onSuccess,
36
- tagLookupMap,
37
- eventContextTags
38
- });
39
- expect(onError).toHaveBeenCalledWith({
40
- standardErrors: [undefined],
41
- liquidErrors: [],
42
- tabType: undefined
43
- });
44
- expect(onSuccess).not.toHaveBeenCalled();
45
- });
46
-
47
- it("calls onError for API errors", async () => {
48
- const getLiquidTags = jest.fn((content, cb) =>
49
- cb({ errors: [{ message: "API error" }], data: [] })
50
- );
51
- await validateLiquidTemplateContent("foo", {
52
- getLiquidTags,
53
- formatMessage,
54
- messages,
55
- onError,
56
- onSuccess,
57
- tagLookupMap,
58
- eventContextTags
59
- });
60
- expect(onError).toHaveBeenCalledWith({
61
- standardErrors: [],
62
- liquidErrors: ["API error"],
63
- tabType: undefined
64
- });
65
- expect(onSuccess).not.toHaveBeenCalled();
1
+ import "@testing-library/jest-dom";
2
+ import get from 'lodash/get';
3
+ import { getTreeStructuredTags } from "../common";
4
+ import * as mockdata from "./common.mockdata";
5
+ import { addBaseToTemplate, isEmbeddedEditOrPreview, transformCustomFieldsData } from "../commonUtils";
6
+ import { EMBEDDED, FULL } from "../../v2Containers/Whatsapp/constants";
7
+ import { CREATE, EDIT, PREVIEW } from "../../v2Containers/App/constants";
8
+
9
+ jest.mock('@capillarytech/cap-ui-utils', () => ({
10
+ Auth: {
11
+ hasAccess: () => jest.fn(() => true),
12
+ hasFeatureAccess: () => jest.fn(() => true),
13
+ authHoc: jest.fn(),
14
+ initialize: jest.fn(),
15
+ },
16
+ }));
17
+
18
+ jest.mock('lodash/get');
19
+
20
+ describe("common utils test", () => {
21
+ it("test for getTreeStructuredTags when tagsList is not empty", () => {
22
+ expect(getTreeStructuredTags({tagsList: mockdata.tagsList})).toEqual(mockdata.output2);
23
+ });
24
+ it("test for getTreeStructuredTags when tagsList is empty", () => {
25
+ expect(getTreeStructuredTags({tagsList: []})).toEqual([]);
66
26
  });
27
+ });
67
28
 
68
- it("calls onError for unsupported tags", async () => {
69
- const getLiquidTags = jest.fn((content, cb) =>
70
- cb({ errors: [], data: [{ name: "baz" }] })
71
- );
72
- await validateLiquidTemplateContent("foo", {
73
- getLiquidTags,
74
- formatMessage,
75
- messages,
76
- onError,
77
- onSuccess,
78
- tagLookupMap,
79
- eventContextTags
80
- });
81
- expect(onError).toHaveBeenCalledWith({
82
- standardErrors: [],
83
- liquidErrors: [undefined],
84
- tabType: undefined
85
- });
86
- expect(onSuccess).not.toHaveBeenCalled();
29
+ describe('addBaseToTemplate', () => {
30
+ it('should add the first item in history as base if history exists', () => {
31
+ const template = {
32
+ versions: {
33
+ history: ['v1', 'v2', 'v3'],
34
+ },
35
+ };
36
+ const expected = {
37
+ versions: {
38
+ history: ['v1', 'v2', 'v3'],
39
+ base: {
40
+ 0: "v", 1: "1", subject: undefined,
41
+ },
42
+ },
43
+ };
44
+ expect(addBaseToTemplate(template)).toEqual(expected);
87
45
  });
88
46
 
89
- it("calls onSuccess for valid content", async () => {
90
- const getLiquidTags = jest.fn((content, cb) =>
91
- cb({ errors: [], data: [{ name: "foo" }, { name: "bar" }] })
92
- );
93
- await validateLiquidTemplateContent("foo", {
94
- getLiquidTags,
95
- formatMessage,
96
- messages,
97
- onError,
98
- onSuccess,
99
- tagLookupMap,
100
- eventContextTags
101
- });
102
- expect(onSuccess).toHaveBeenCalledWith("foo", undefined);
47
+ it('should return the original template if history is empty', () => {
48
+ const template = {
49
+ versions: {
50
+ history: [],
51
+ },
52
+ };
53
+ expect(addBaseToTemplate(template)).toEqual(template);
103
54
  });
104
55
 
105
- it("calls onError with emailBodyEmptyError when validString is falsy", async () => {
106
- const getLiquidTags = jest.fn((content, cb) => cb({ errors: [], data: [] }));
107
- const formatMessage = jest.fn((msg) => msg.id);
108
- const messages = {
109
- emailBodyEmptyError: { id: 'empty' },
110
- somethingWentWrong: { id: 'wrong' },
111
- unsupportedTagsValidationError: { id: 'unsupported' },
56
+ it('should return the original template if history is undefined', () => {
57
+ const template = {
58
+ versions: {},
112
59
  };
113
- const onError = jest.fn();
114
- const onSuccess = jest.fn();
115
- const tagLookupMap = {};
116
- const eventContextTags = [];
117
- await validateLiquidTemplateContent('', {
118
- getLiquidTags,
119
- formatMessage,
120
- messages,
121
- onError,
122
- onSuccess,
123
- tagLookupMap,
124
- eventContextTags,
125
- });
126
- expect(formatMessage).toHaveBeenCalledWith(messages.emailBodyEmptyError);
127
- expect(onError).toHaveBeenCalledWith({
128
- standardErrors: ['empty'],
129
- liquidErrors: [],
130
- tabType: undefined,
131
- });
132
- expect(onSuccess).not.toHaveBeenCalled();
60
+ expect(addBaseToTemplate(template)).toEqual(template);
133
61
  });
134
- });
135
62
 
136
- describe("validateMobilePushContent", () => {
137
- const formatMessage = jest.fn(msg => msg.id);
138
- const messages = {
139
- emailBodyEmptyError: { id: "empty" },
140
- somethingWentWrong: { id: "wrong" },
141
- unsupportedTagsValidationError: { id: "unsupported" }
142
- };
143
- const tagLookupMap = { foo: true };
144
- const eventContextTags = [{ tagName: "foo" }];
145
- const onError = jest.fn();
146
- const onSuccess = jest.fn();
147
-
148
- beforeEach(() => {
149
- jest.clearAllMocks();
63
+ it('should return the original template if versions is undefined', () => {
64
+ const template = {};
65
+ expect(addBaseToTemplate(template)).toEqual(template);
150
66
  });
151
67
 
152
- it("calls onError for empty formData", async () => {
153
- const getLiquidTags = jest.fn((content, cb) =>
154
- cb({ errors: [], data: [] })
155
- );
156
- await validateMobilePushContent(
157
- {},
158
- {
159
- getLiquidTags,
160
- formatMessage,
161
- messages,
162
- onError,
163
- onSuccess,
164
- tagLookupMap,
165
- eventContextTags,
166
- currentTab: 1
167
- }
168
- );
169
- expect(onError).toHaveBeenCalled();
68
+ it('should handle null input gracefully', () => {
69
+ expect(addBaseToTemplate(null)).toBeNull();
170
70
  });
171
71
 
172
- it("calls onSuccess for valid android and ios content", async () => {
173
- const getLiquidTags = jest.fn((content, cb) =>
174
- cb({ errors: [], data: [] })
175
- );
176
- const formData = [{ foo: "bar" }, { baz: "qux" }];
177
- await validateMobilePushContent(formData, {
178
- getLiquidTags,
179
- formatMessage,
180
- messages,
181
- onError,
182
- onSuccess,
183
- tagLookupMap,
184
- eventContextTags,
185
- currentTab: 1
186
- });
187
- expect(onSuccess).toHaveBeenCalled();
72
+ it('should handle undefined input gracefully', () => {
73
+ expect(addBaseToTemplate(undefined)).toBeUndefined();
188
74
  });
189
75
 
190
- it("calls onSuccess with android content when tab is 1", async () => {
191
- const getLiquidTags = jest.fn((content, cb) =>
192
- cb({ errors: [], data: [] })
193
- );
194
- const formData = [{ android: "content" }, { ios: "content" }];
195
- await validateMobilePushContent(formData, {
196
- getLiquidTags,
197
- formatMessage,
198
- messages,
199
- onError,
200
- onSuccess,
201
- tagLookupMap,
202
- eventContextTags,
203
- currentTab: 1
204
- });
205
- expect(onSuccess).toHaveBeenCalledWith(JSON.stringify(formData[0]), "android");
76
+ it('should not modify the original template object', () => {
77
+ const template = {
78
+ versions: {
79
+ history: ['v1', 'v2', 'v3'],
80
+ },
81
+ };
82
+ const originalTemplateCopy = JSON.parse(JSON.stringify(template));
83
+ addBaseToTemplate(template);
84
+ expect(template).toEqual(originalTemplateCopy);
206
85
  });
86
+ });
207
87
 
208
- it("calls onSuccess with ios content when tab is 2", async () => {
209
- const getLiquidTags = jest.fn((content, cb) =>
210
- cb({ errors: [], data: [] })
211
- );
212
- const formData = [{ android: "content" }, { ios: "content" }];
213
- await validateMobilePushContent(formData, {
214
- getLiquidTags,
215
- formatMessage,
216
- messages,
217
- onError,
218
- onSuccess,
219
- tagLookupMap,
220
- eventContextTags,
221
- currentTab: 2
222
- });
223
- expect(onSuccess).toHaveBeenCalledWith(JSON.stringify(formData[1]), "ios");
88
+ describe('isEmbeddedEditOrPreview', () => {
89
+ beforeEach(() => {
90
+ get.mockClear();
224
91
  });
225
92
 
226
- it("falls back to android content when no tab selected and android exists", async () => {
227
- const getLiquidTags = jest.fn((content, cb) =>
228
- cb({ errors: [], data: [] })
229
- );
230
- const formData = [{ android: "content" }, null];
231
- await validateMobilePushContent(formData, {
232
- getLiquidTags,
233
- formatMessage,
234
- messages,
235
- onError,
236
- onSuccess,
237
- tagLookupMap,
238
- eventContextTags
239
- });
240
- expect(onSuccess).toHaveBeenCalledWith(JSON.stringify(formData[0]), "android");
93
+ it('should return true when query type is embedded and creatives mode is edit', () => {
94
+ const queryType = EMBEDDED;
95
+ const creativesMode = EDIT;
96
+ expect(isEmbeddedEditOrPreview(queryType, creativesMode)).toBe(true);
241
97
  });
242
98
 
243
- it("falls back to ios content when no tab selected and only ios exists", async () => {
244
- const getLiquidTags = jest.fn((content, cb) =>
245
- cb({ errors: [], data: [] })
246
- );
247
- const formData = [null, { ios: "content" }];
248
- await validateMobilePushContent(formData, {
249
- getLiquidTags,
250
- formatMessage,
251
- messages,
252
- onError,
253
- onSuccess,
254
- tagLookupMap,
255
- eventContextTags
256
- });
257
- expect(onSuccess).toHaveBeenCalledWith("null", "android");
99
+ it('should return true when query type is embedded and creatives mode is preview', () => {
100
+ const queryType = EMBEDDED;
101
+ const creativesMode = PREVIEW;
102
+ expect(isEmbeddedEditOrPreview(queryType, creativesMode)).toBe(true);
258
103
  });
259
104
 
260
- it("calls onError for null formData", async () => {
261
- const getLiquidTags = jest.fn((content, cb) => cb({ errors: [], data: [] }));
262
- await validateMobilePushContent(
263
- null,
264
- {
265
- getLiquidTags,
266
- formatMessage,
267
- messages,
268
- onError,
269
- onSuccess,
270
- tagLookupMap,
271
- eventContextTags,
272
- currentTab: 1,
273
- },
274
- );
275
- expect(onError).toHaveBeenCalled();
105
+ it('should return false when query type is not embedded', () => {
106
+ const queryType = FULL;
107
+ const creativesMode = PREVIEW;
108
+ expect(isEmbeddedEditOrPreview(queryType, creativesMode)).toBe(false);
276
109
  });
277
110
 
278
- it("calls onError for undefined formData", async () => {
279
- const getLiquidTags = jest.fn((content, cb) => cb({ errors: [], data: [] }));
280
- await validateMobilePushContent(
281
- undefined,
282
- {
283
- getLiquidTags,
284
- formatMessage,
285
- messages,
286
- onError,
287
- onSuccess,
288
- tagLookupMap,
289
- eventContextTags,
290
- currentTab: 1,
291
- },
292
- );
293
- expect(onError).toHaveBeenCalled();
111
+ it('should return false when creatives mode is not edit or preview', () => {
112
+ const queryType = EMBEDDED;
113
+ const creativesMode = CREATE;
114
+ expect(isEmbeddedEditOrPreview(queryType, creativesMode)).toBe(false);
294
115
  });
116
+ });
295
117
 
296
- it("calls onError for empty string formData", async () => {
297
- const getLiquidTags = jest.fn((content, cb) => cb({ errors: [], data: [] }));
298
- await validateMobilePushContent(
299
- '',
300
- {
301
- getLiquidTags,
302
- formatMessage,
303
- messages,
304
- onError,
305
- onSuccess,
306
- tagLookupMap,
307
- eventContextTags,
308
- currentTab: 1,
118
+ describe('transformCustomFieldsData', () => {
119
+ it('should transform registration custom fields correctly', () => {
120
+ const input = {
121
+ 1: {
122
+ name: 'age_group',
123
+ label: 'Age Group',
124
+ scope: 'loyalty_registration',
309
125
  },
310
- );
311
- expect(onError).toHaveBeenCalled();
312
- });
313
-
314
- it("calls onError for empty array formData", async () => {
315
- const getLiquidTags = jest.fn((content, cb) => cb({ errors: [], data: [] }));
316
- await validateMobilePushContent(
317
- [],
318
- {
319
- getLiquidTags,
320
- formatMessage,
321
- messages,
322
- onError,
323
- onSuccess,
324
- tagLookupMap,
325
- eventContextTags,
326
- currentTab: 1,
126
+ 2: {
127
+ name: 'gender',
128
+ label: 'Gender',
129
+ scope: 'loyalty_registration',
327
130
  },
328
- );
329
- expect(onError).toHaveBeenCalled();
330
- });
131
+ };
331
132
 
332
- it("calls onError for both android and ios missing", async () => {
333
- const getLiquidTags = jest.fn((content, cb) => cb({ errors: [], data: [] }));
334
- await validateMobilePushContent(
335
- [{}, {}],
336
- {
337
- getLiquidTags,
338
- formatMessage,
339
- messages,
340
- onError,
341
- onSuccess,
342
- tagLookupMap,
343
- eventContextTags,
133
+ const expected = {
134
+ 'Registration custom fields': {
135
+ name: 'Registration custom fields',
136
+ subtags: {
137
+ 'custom_field.age_group': {
138
+ name: 'age_group',
139
+ desc: 'age_group',
140
+ },
141
+ 'custom_field.gender': {
142
+ name: 'gender',
143
+ desc: 'gender',
144
+ },
145
+ },
344
146
  },
345
- );
346
- expect(onError).toHaveBeenCalled();
347
- });
147
+ };
348
148
 
349
- it("calls onError for both android and ios null", async () => {
350
- const getLiquidTags = jest.fn((content, cb) => cb({ errors: [], data: [] }));
351
- await validateMobilePushContent(
352
- [null, null],
353
- {
354
- getLiquidTags,
355
- formatMessage,
356
- messages,
357
- onError,
358
- onSuccess,
359
- tagLookupMap,
360
- eventContextTags,
361
- },
362
- );
363
- expect(onError).toHaveBeenCalled();
149
+ expect(transformCustomFieldsData(input)).toEqual(expected);
364
150
  });
365
151
 
366
- it("calls onError for android and ios as empty strings", async () => {
367
- const getLiquidTags = jest.fn((content, cb) => cb({ errors: [], data: [] }));
368
- await validateMobilePushContent(
369
- [{ android: '' }, { ios: '' }],
370
- {
371
- getLiquidTags,
372
- formatMessage,
373
- messages,
374
- onError,
375
- onSuccess,
376
- tagLookupMap,
377
- eventContextTags,
152
+ it('should transform organization custom fields correctly', () => {
153
+ const input = {
154
+ 1: {
155
+ name: 'org_phone',
156
+ label: 'Phone',
157
+ scope: 'org_custom_field',
378
158
  },
379
- );
380
- expect(onError).toHaveBeenCalled();
381
- });
382
-
383
- it("calls onError for non-object types in formData", async () => {
384
- const getLiquidTags = jest.fn((content, cb) => cb({ errors: [], data: [] }));
385
- await validateMobilePushContent(
386
- [123, 456],
387
- {
388
- getLiquidTags,
389
- formatMessage,
390
- messages,
391
- onError,
392
- onSuccess,
393
- tagLookupMap,
394
- eventContextTags,
159
+ 2: {
160
+ name: 'store_location',
161
+ label: 'Location',
162
+ scope: 'store_custom_fields',
395
163
  },
396
- );
397
- expect(onError).toHaveBeenCalled();
398
- });
164
+ };
399
165
 
400
- it("calls onError for string types in formData", async () => {
401
- const getLiquidTags = jest.fn((content, cb) => cb({ errors: [], data: [] }));
402
- await validateMobilePushContent(
403
- ['', ''],
404
- {
405
- getLiquidTags,
406
- formatMessage,
407
- messages,
408
- onError,
409
- onSuccess,
410
- tagLookupMap,
411
- eventContextTags,
166
+ const expected = {
167
+ 'Organization custom fields': {
168
+ name: 'Organization custom fields',
169
+ subtags: {
170
+ 'org_custom_field.org_phone': {
171
+ name: 'org_phone',
172
+ desc: 'org_phone',
173
+ },
174
+ 'store_custom_field.store_location': {
175
+ name: 'store_location',
176
+ desc: 'store_location',
177
+ },
178
+ },
412
179
  },
413
- );
414
- expect(onError).toHaveBeenCalled();
415
- });
416
- });
417
-
418
- describe("validateInAppContent", () => {
419
- const formatMessage = jest.fn(msg => msg.id);
420
- const messages = {
421
- emailBodyEmptyError: { id: "empty" },
422
- somethingWentWrong: { id: "wrong" },
423
- unsupportedTagsValidationError: { id: "unsupported" }
424
- };
425
- const tagLookupMap = { foo: true };
426
- const eventContextTags = [{ tagName: "foo" }];
427
- const onError = jest.fn();
428
- const onSuccess = jest.fn();
429
-
430
- beforeEach(() => {
431
- jest.clearAllMocks();
432
- });
433
-
434
- it("calls onError for empty formData", async () => {
435
- const getLiquidTags = jest.fn((content, cb) =>
436
- cb({ errors: [], data: [] })
437
- );
438
- await validateInAppContent(
439
- {},
440
- {
441
- getLiquidTags,
442
- formatMessage,
443
- messages,
444
- onError,
445
- onSuccess,
446
- tagLookupMap,
447
- eventContextTags,
448
- }
449
- );
450
- expect(onError).toHaveBeenCalled();
451
- });
452
-
453
- it("calls onSuccess for valid android and ios content", async () => {
454
- const getLiquidTags = jest.fn((content, cb) =>
455
- cb({ errors: [], data: [] })
456
- );
457
- const formData = {
458
- versions: {
459
- base: {
460
- content: {
461
- ANDROID: { title: "t", message: "m", ctas: [{ text: "c" }] },
462
- IOS: { title: "t2", message: "m2", ctas: [{ text: "c2" }] }
463
- }
464
- }
465
- }
466
180
  };
467
- await validateInAppContent(formData, {
468
- getLiquidTags,
469
- formatMessage,
470
- messages,
471
- onError,
472
- onSuccess,
473
- tagLookupMap,
474
- eventContextTags,
475
- });
476
- expect(onSuccess).toHaveBeenCalled();
477
- });
478
- });
479
181
 
480
- describe("getChannelData", () => {
481
- it("returns converted email content for EMAIL channel with template-content", () => {
482
- const formData = { base: { en: { "template-content": "<h1>Hello</h1>" } } };
483
- // Mock convert to just return the input string for test
484
- jest.mock("html-to-text", () => ({ convert: (str) => str }));
485
- expect(getChannelData("email", formData)).toBe("");
182
+ expect(transformCustomFieldsData(input)).toEqual(expected);
486
183
  });
487
184
 
488
- it("returns empty string for EMAIL channel with missing template-content", () => {
489
- const formData = { base: { en: {} } };
490
- jest.mock("html-to-text", () => ({ convert: (str) => str }));
491
- expect(getChannelData("email", formData)).toBe("");
185
+ it('should handle empty input correctly', () => {
186
+ expect(transformCustomFieldsData({})).toEqual({});
492
187
  });
493
188
 
494
- it("returns SMS editor and template name for SMS channel", () => {
495
- const formData = { base: { "sms-editor": "Hi" }, "template-name": "Test" };
496
- expect(getChannelData("SMS", formData)).toBe("Hi Test");
497
- });
498
-
499
- it("returns string with undefineds for SMS channel with missing fields", () => {
500
- const formData = { base: {}, "template-name": undefined };
501
- expect(getChannelData("SMS", formData)).toBe("undefined undefined");
502
- });
503
- it("returns string with undefineds for SMS channel with missing fields", () => {
504
- expect(getChannelData("SMS", "")).toBe("undefined undefined");
505
- });
189
+ it('should handle fields with missing properties', () => {
190
+ const input = {
191
+ 1: {
192
+ scope: 'loyalty_registration',
193
+ },
194
+ };
506
195
 
507
- it("returns JSON string for unknown channel", () => {
508
- const formData = { foo: "bar" };
509
- expect(getChannelData("unknown", formData)).toBe(JSON.stringify(formData));
510
- });
196
+ const expected = {
197
+ 'Registration custom fields': {
198
+ name: 'Registration custom fields',
199
+ subtags: {
200
+ 'custom_field.undefined': {
201
+ name: undefined,
202
+ desc: undefined,
203
+ },
204
+ },
205
+ },
206
+ };
511
207
 
512
- it("returns JSON string for null formData", () => {
513
- expect(getChannelData("SMS", null)).toBe("undefined undefined");
208
+ expect(transformCustomFieldsData(input)).toEqual(expected);
514
209
  });
515
210
 
516
- it("returns JSON string for undefined formData", () => {
517
- expect(getChannelData("SMS", undefined)).toBe("undefined undefined");
518
- });
211
+ it('should ignore fields with invalid scope', () => {
212
+ const input = {
213
+ 1: {
214
+ name: 'test',
215
+ label: 'Test',
216
+ scope: 'invalid_scope',
217
+ },
218
+ };
519
219
 
520
- it("handles missing base/en gracefully for EMAIL", () => {
521
- expect(getChannelData("email", {})).toBe("");
522
- expect(getChannelData("email", { base: {} })).toBe("");
523
- expect(getChannelData("email", { base: { en: null } })).toBe("");
220
+ expect(transformCustomFieldsData(input)).toEqual({});
524
221
  });
525
222
  });