@usertour/helpers 0.0.47 → 0.0.48

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.
@@ -0,0 +1,716 @@
1
+ import {
2
+ createStepCopy,
3
+ duplicateChecklistData,
4
+ duplicateConfig,
5
+ duplicateData,
6
+ duplicateTarget,
7
+ duplicateTriggers,
8
+ extractQuestionData,
9
+ generateUniqueCopyName,
10
+ hasMissingRequiredData,
11
+ isClickableElement,
12
+ isMissingRequiredData,
13
+ isQuestionElement,
14
+ isRestrictedType,
15
+ processQuestionElements
16
+ } from "../chunk-7GJAPR7Y.js";
17
+ import "../chunk-7ODE2AIC.js";
18
+ import "../chunk-SIG4WTEF.js";
19
+ import "../chunk-YYIGUZNZ.js";
20
+ import "../chunk-PAESAL23.js";
21
+ import "../chunk-3KG2HTZ3.js";
22
+ import "../chunk-KYDXF7SU.js";
23
+ import "../chunk-JQWKLXW6.js";
24
+ import "../chunk-GFH3VWOC.js";
25
+ import "../chunk-XEO3YXBM.js";
26
+
27
+ // src/__tests__/content-helper.test.ts
28
+ import { ContentDataType, ContentEditorElementType } from "@usertour/types";
29
+ jest.mock("../helper", () => ({
30
+ cuid: jest.fn(() => "mock-cuid"),
31
+ uuidV4: jest.fn(() => "mock-uuid")
32
+ }));
33
+ jest.mock("../conditions", () => ({
34
+ regenerateConditionIds: jest.fn(
35
+ (conditions) => conditions == null ? void 0 : conditions.map((c) => ({ ...c, id: `regenerated-${c.id}` }))
36
+ )
37
+ }));
38
+ describe("isRestrictedType", () => {
39
+ test("should return true for NPS type", () => {
40
+ expect(isRestrictedType(ContentEditorElementType.NPS)).toBe(true);
41
+ });
42
+ test("should return true for STAR_RATING type", () => {
43
+ expect(isRestrictedType(ContentEditorElementType.STAR_RATING)).toBe(true);
44
+ });
45
+ test("should return true for SCALE type", () => {
46
+ expect(isRestrictedType(ContentEditorElementType.SCALE)).toBe(true);
47
+ });
48
+ test("should return true for SINGLE_LINE_TEXT type", () => {
49
+ expect(isRestrictedType(ContentEditorElementType.SINGLE_LINE_TEXT)).toBe(true);
50
+ });
51
+ test("should return true for MULTI_LINE_TEXT type", () => {
52
+ expect(isRestrictedType(ContentEditorElementType.MULTI_LINE_TEXT)).toBe(true);
53
+ });
54
+ test("should return true for MULTIPLE_CHOICE type", () => {
55
+ expect(isRestrictedType(ContentEditorElementType.MULTIPLE_CHOICE)).toBe(true);
56
+ });
57
+ test("should return false for BUTTON type", () => {
58
+ expect(isRestrictedType(ContentEditorElementType.BUTTON)).toBe(false);
59
+ });
60
+ test("should return false for TEXT type", () => {
61
+ expect(isRestrictedType(ContentEditorElementType.TEXT)).toBe(false);
62
+ });
63
+ test("should return false for IMAGE type", () => {
64
+ expect(isRestrictedType(ContentEditorElementType.IMAGE)).toBe(false);
65
+ });
66
+ });
67
+ describe("isMissingRequiredData", () => {
68
+ test("should return true when restricted type element has empty name", () => {
69
+ const element = {
70
+ type: ContentEditorElementType.NPS,
71
+ data: { name: "" }
72
+ };
73
+ expect(isMissingRequiredData(element)).toBe(true);
74
+ });
75
+ test("should return false when restricted type element has undefined name (isEmptyString returns false for undefined)", () => {
76
+ const element = {
77
+ type: ContentEditorElementType.NPS,
78
+ data: {}
79
+ };
80
+ expect(isMissingRequiredData(element)).toBe(false);
81
+ });
82
+ test("should return false when restricted type element has valid name", () => {
83
+ const element = {
84
+ type: ContentEditorElementType.NPS,
85
+ data: { name: "Valid Name" }
86
+ };
87
+ expect(isMissingRequiredData(element)).toBe(false);
88
+ });
89
+ test("should return true when button element has empty text", () => {
90
+ const element = {
91
+ type: ContentEditorElementType.BUTTON,
92
+ data: { text: "", actions: [{ id: "1" }] }
93
+ };
94
+ expect(isMissingRequiredData(element)).toBe(true);
95
+ });
96
+ test("should return true when button element has no actions", () => {
97
+ const element = {
98
+ type: ContentEditorElementType.BUTTON,
99
+ data: { text: "Button", actions: [] }
100
+ };
101
+ expect(isMissingRequiredData(element)).toBe(true);
102
+ });
103
+ test("should return true when button element has undefined actions", () => {
104
+ const element = {
105
+ type: ContentEditorElementType.BUTTON,
106
+ data: { text: "Button" }
107
+ };
108
+ expect(isMissingRequiredData(element)).toBe(true);
109
+ });
110
+ test("should return false when button element has valid text and actions", () => {
111
+ const element = {
112
+ type: ContentEditorElementType.BUTTON,
113
+ data: { text: "Button", actions: [{ id: "1" }] }
114
+ };
115
+ expect(isMissingRequiredData(element)).toBe(false);
116
+ });
117
+ test("should return false for non-restricted, non-button type", () => {
118
+ const element = {
119
+ type: ContentEditorElementType.TEXT,
120
+ data: {}
121
+ };
122
+ expect(isMissingRequiredData(element)).toBe(false);
123
+ });
124
+ });
125
+ describe("hasMissingRequiredData", () => {
126
+ const createContentRoot = (element) => [
127
+ {
128
+ type: "root",
129
+ children: [
130
+ {
131
+ type: "column",
132
+ children: [
133
+ {
134
+ type: "element",
135
+ element
136
+ }
137
+ ]
138
+ }
139
+ ]
140
+ }
141
+ ];
142
+ test("should return true when content has element with missing required data", () => {
143
+ const element = {
144
+ type: ContentEditorElementType.NPS,
145
+ data: { name: "" }
146
+ };
147
+ const contents = createContentRoot(element);
148
+ expect(hasMissingRequiredData(contents)).toBe(true);
149
+ });
150
+ test("should return false when all elements have required data", () => {
151
+ const element = {
152
+ type: ContentEditorElementType.NPS,
153
+ data: { name: "Valid Name" }
154
+ };
155
+ const contents = createContentRoot(element);
156
+ expect(hasMissingRequiredData(contents)).toBe(false);
157
+ });
158
+ test("should return false for empty contents array", () => {
159
+ expect(hasMissingRequiredData([])).toBe(false);
160
+ });
161
+ });
162
+ describe("isQuestionElement", () => {
163
+ test("should return true for SINGLE_LINE_TEXT", () => {
164
+ const element = { type: ContentEditorElementType.SINGLE_LINE_TEXT };
165
+ expect(isQuestionElement(element)).toBe(true);
166
+ });
167
+ test("should return true for MULTI_LINE_TEXT", () => {
168
+ const element = { type: ContentEditorElementType.MULTI_LINE_TEXT };
169
+ expect(isQuestionElement(element)).toBe(true);
170
+ });
171
+ test("should return true for NPS", () => {
172
+ const element = { type: ContentEditorElementType.NPS };
173
+ expect(isQuestionElement(element)).toBe(true);
174
+ });
175
+ test("should return true for STAR_RATING", () => {
176
+ const element = { type: ContentEditorElementType.STAR_RATING };
177
+ expect(isQuestionElement(element)).toBe(true);
178
+ });
179
+ test("should return true for SCALE", () => {
180
+ const element = { type: ContentEditorElementType.SCALE };
181
+ expect(isQuestionElement(element)).toBe(true);
182
+ });
183
+ test("should return true for MULTIPLE_CHOICE", () => {
184
+ const element = { type: ContentEditorElementType.MULTIPLE_CHOICE };
185
+ expect(isQuestionElement(element)).toBe(true);
186
+ });
187
+ test("should return false for BUTTON", () => {
188
+ const element = { type: ContentEditorElementType.BUTTON };
189
+ expect(isQuestionElement(element)).toBe(false);
190
+ });
191
+ test("should return false for TEXT", () => {
192
+ const element = { type: ContentEditorElementType.TEXT };
193
+ expect(isQuestionElement(element)).toBe(false);
194
+ });
195
+ });
196
+ describe("isClickableElement", () => {
197
+ test("should return true for BUTTON type", () => {
198
+ const element = { type: ContentEditorElementType.BUTTON, data: {} };
199
+ expect(isClickableElement(element)).toBe(true);
200
+ });
201
+ test("should return true for question elements", () => {
202
+ const element = { type: ContentEditorElementType.NPS, data: {} };
203
+ expect(isClickableElement(element)).toBe(true);
204
+ });
205
+ test("should return false for non-clickable elements", () => {
206
+ const element = { type: ContentEditorElementType.TEXT, data: [] };
207
+ expect(isClickableElement(element)).toBe(false);
208
+ });
209
+ });
210
+ describe("extractQuestionData", () => {
211
+ test("should extract question elements from content", () => {
212
+ const questionElement = {
213
+ type: ContentEditorElementType.NPS,
214
+ data: { name: "NPS Question", cvid: "test-cvid" }
215
+ };
216
+ const contents = [
217
+ {
218
+ type: "root",
219
+ children: [
220
+ {
221
+ type: "column",
222
+ children: [
223
+ {
224
+ type: "element",
225
+ element: questionElement
226
+ }
227
+ ]
228
+ }
229
+ ]
230
+ }
231
+ ];
232
+ const result = extractQuestionData(contents);
233
+ expect(result).toHaveLength(1);
234
+ expect(result[0]).toEqual(questionElement);
235
+ });
236
+ test("should return empty array when no question elements exist", () => {
237
+ const textElement = {
238
+ type: ContentEditorElementType.TEXT,
239
+ data: {}
240
+ };
241
+ const contents = [
242
+ {
243
+ type: "root",
244
+ children: [
245
+ {
246
+ type: "column",
247
+ children: [
248
+ {
249
+ type: "element",
250
+ element: textElement
251
+ }
252
+ ]
253
+ }
254
+ ]
255
+ }
256
+ ];
257
+ const result = extractQuestionData(contents);
258
+ expect(result).toHaveLength(0);
259
+ });
260
+ test("should return empty array for empty contents", () => {
261
+ const result = extractQuestionData([]);
262
+ expect(result).toHaveLength(0);
263
+ });
264
+ test("should extract multiple question elements", () => {
265
+ const npsElement = {
266
+ type: ContentEditorElementType.NPS,
267
+ data: { name: "NPS" }
268
+ };
269
+ const scaleElement = {
270
+ type: ContentEditorElementType.SCALE,
271
+ data: { name: "Scale" }
272
+ };
273
+ const contents = [
274
+ {
275
+ type: "root",
276
+ children: [
277
+ {
278
+ type: "column",
279
+ children: [
280
+ { type: "element", element: npsElement },
281
+ { type: "element", element: scaleElement }
282
+ ]
283
+ }
284
+ ]
285
+ }
286
+ ];
287
+ const result = extractQuestionData(contents);
288
+ expect(result).toHaveLength(2);
289
+ });
290
+ });
291
+ describe("processQuestionElements", () => {
292
+ test("should return empty array for undefined contents", () => {
293
+ const result = processQuestionElements(void 0);
294
+ expect(result).toEqual([]);
295
+ });
296
+ test("should return empty array for empty contents", () => {
297
+ const result = processQuestionElements([]);
298
+ expect(result).toEqual([]);
299
+ });
300
+ test("should regenerate cvid for question elements", () => {
301
+ const questionElement = {
302
+ type: ContentEditorElementType.NPS,
303
+ data: { name: "NPS Question", cvid: "old-cvid" }
304
+ };
305
+ const contents = [
306
+ {
307
+ type: "root",
308
+ children: [
309
+ {
310
+ type: "column",
311
+ children: [
312
+ {
313
+ type: "element",
314
+ element: questionElement
315
+ }
316
+ ]
317
+ }
318
+ ]
319
+ }
320
+ ];
321
+ const result = processQuestionElements(contents);
322
+ const processedElement = result[0].children[0].children[0].element;
323
+ expect(processedElement.data.cvid).toBe("mock-cuid");
324
+ });
325
+ test("should regenerate actions for button elements", () => {
326
+ var _a;
327
+ const buttonElement = {
328
+ type: ContentEditorElementType.BUTTON,
329
+ data: {
330
+ text: "Button",
331
+ actions: [{ id: "action-1", type: "test" }]
332
+ }
333
+ };
334
+ const contents = [
335
+ {
336
+ type: "root",
337
+ children: [
338
+ {
339
+ type: "column",
340
+ children: [
341
+ {
342
+ type: "element",
343
+ element: buttonElement
344
+ }
345
+ ]
346
+ }
347
+ ]
348
+ }
349
+ ];
350
+ const result = processQuestionElements(contents);
351
+ const processedElement = result[0].children[0].children[0].element;
352
+ expect((_a = processedElement.data) == null ? void 0 : _a.actions[0].id).toBe("regenerated-action-1");
353
+ });
354
+ test("should not modify non-question, non-button elements", () => {
355
+ const textElement = {
356
+ type: ContentEditorElementType.TEXT,
357
+ data: []
358
+ };
359
+ const contents = [
360
+ {
361
+ type: "root",
362
+ children: [
363
+ {
364
+ type: "column",
365
+ children: [
366
+ {
367
+ type: "element",
368
+ element: textElement
369
+ }
370
+ ]
371
+ }
372
+ ]
373
+ }
374
+ ];
375
+ const result = processQuestionElements(contents);
376
+ const processedElement = result[0].children[0].children[0].element;
377
+ expect(processedElement).toEqual(textElement);
378
+ });
379
+ });
380
+ describe("generateUniqueCopyName", () => {
381
+ test('should generate "Name (copy)" for first copy', () => {
382
+ const result = generateUniqueCopyName("Test");
383
+ expect(result).toBe("Test (copy)");
384
+ });
385
+ test('should generate "Name (copy)" when no existing names provided', () => {
386
+ const result = generateUniqueCopyName("Test", []);
387
+ expect(result).toBe("Test (copy)");
388
+ });
389
+ test('should generate "Name (copy 2)" when "Name (copy)" exists', () => {
390
+ const result = generateUniqueCopyName("Test", ["Test (copy)"]);
391
+ expect(result).toBe("Test (copy 2)");
392
+ });
393
+ test('should generate "Name (copy 3)" when "Name (copy)" and "Name (copy 2)" exist', () => {
394
+ const result = generateUniqueCopyName("Test", ["Test (copy)", "Test (copy 2)"]);
395
+ expect(result).toBe("Test (copy 3)");
396
+ });
397
+ test("should find next available number", () => {
398
+ const result = generateUniqueCopyName("Test", [
399
+ "Test (copy)",
400
+ "Test (copy 2)",
401
+ "Test (copy 3)",
402
+ "Test (copy 4)"
403
+ ]);
404
+ expect(result).toBe("Test (copy 5)");
405
+ });
406
+ });
407
+ describe("duplicateTriggers", () => {
408
+ test("should return triggers as-is when not an array", () => {
409
+ const result = duplicateTriggers(null);
410
+ expect(result).toBeNull();
411
+ });
412
+ test("should regenerate trigger IDs", () => {
413
+ const triggers = [
414
+ {
415
+ id: "trigger-1",
416
+ actions: [{ id: "action-1", type: "test", operators: "and", data: {} }],
417
+ conditions: [{ id: "condition-1", type: "test", operators: "and", data: {} }]
418
+ }
419
+ ];
420
+ const result = duplicateTriggers(triggers);
421
+ expect(result[0].id).toBe("mock-cuid");
422
+ });
423
+ test("should regenerate action IDs", () => {
424
+ const triggers = [
425
+ {
426
+ id: "trigger-1",
427
+ actions: [{ id: "action-1", type: "test", operators: "and", data: {} }],
428
+ conditions: []
429
+ }
430
+ ];
431
+ const result = duplicateTriggers(triggers);
432
+ expect(result[0].actions[0].id).toBe("regenerated-action-1");
433
+ });
434
+ test("should regenerate condition IDs", () => {
435
+ const triggers = [
436
+ {
437
+ id: "trigger-1",
438
+ actions: [],
439
+ conditions: [{ id: "condition-1", type: "test", operators: "and", data: {} }]
440
+ }
441
+ ];
442
+ const result = duplicateTriggers(triggers);
443
+ expect(result[0].conditions[0].id).toBe("regenerated-condition-1");
444
+ });
445
+ test("should handle triggers without actions or conditions", () => {
446
+ const triggers = [
447
+ {
448
+ id: "trigger-1"
449
+ }
450
+ ];
451
+ const result = duplicateTriggers(triggers);
452
+ expect(result[0].id).toBe("mock-cuid");
453
+ expect(result[0].actions).toBeUndefined();
454
+ expect(result[0].conditions).toBeUndefined();
455
+ });
456
+ });
457
+ describe("duplicateTarget", () => {
458
+ test("should return undefined for undefined target", () => {
459
+ const result = duplicateTarget(void 0);
460
+ expect(result).toBeUndefined();
461
+ });
462
+ test("should return undefined for null target", () => {
463
+ const result = duplicateTarget(null);
464
+ expect(result).toBeUndefined();
465
+ });
466
+ test("should regenerate action IDs in target", () => {
467
+ var _a;
468
+ const target = {
469
+ actions: [{ id: "action-1", type: "test", operators: "and", data: {} }]
470
+ };
471
+ const result = duplicateTarget(target);
472
+ expect((_a = result == null ? void 0 : result.actions) == null ? void 0 : _a[0].id).toBe("regenerated-action-1");
473
+ });
474
+ test("should return target as-is when no actions", () => {
475
+ const target = {
476
+ selector: ".test"
477
+ };
478
+ const result = duplicateTarget(target);
479
+ expect(result).toEqual(target);
480
+ });
481
+ test("should return target as-is when actions is not an array", () => {
482
+ const target = {
483
+ actions: "not-an-array"
484
+ };
485
+ const result = duplicateTarget(target);
486
+ expect(result).toEqual(target);
487
+ });
488
+ });
489
+ describe("duplicateChecklistData", () => {
490
+ test("should return data as-is for null", () => {
491
+ const result = duplicateChecklistData(null);
492
+ expect(result).toBeNull();
493
+ });
494
+ test("should return data as-is for undefined", () => {
495
+ const result = duplicateChecklistData(void 0);
496
+ expect(result).toBeUndefined();
497
+ });
498
+ test("should return data as-is for non-object", () => {
499
+ const result = duplicateChecklistData("string");
500
+ expect(result).toBe("string");
501
+ });
502
+ test("should return data as-is when items is not an array", () => {
503
+ const data = { items: "not-an-array" };
504
+ const result = duplicateChecklistData(data);
505
+ expect(result).toEqual(data);
506
+ });
507
+ test("should regenerate item IDs", () => {
508
+ const data = {
509
+ items: [
510
+ {
511
+ id: "item-1",
512
+ title: "Task 1",
513
+ clickedActions: [],
514
+ completeConditions: [],
515
+ onlyShowTaskConditions: []
516
+ }
517
+ ]
518
+ };
519
+ const result = duplicateChecklistData(data);
520
+ expect(result.items[0].id).toBe("mock-uuid");
521
+ });
522
+ test("should regenerate clickedActions IDs", () => {
523
+ const data = {
524
+ items: [
525
+ {
526
+ id: "item-1",
527
+ clickedActions: [{ id: "action-1", type: "test", operators: "and", data: {} }],
528
+ completeConditions: [],
529
+ onlyShowTaskConditions: []
530
+ }
531
+ ]
532
+ };
533
+ const result = duplicateChecklistData(data);
534
+ expect(result.items[0].clickedActions[0].id).toBe("regenerated-action-1");
535
+ });
536
+ test("should regenerate completeConditions IDs", () => {
537
+ const data = {
538
+ items: [
539
+ {
540
+ id: "item-1",
541
+ clickedActions: [],
542
+ completeConditions: [{ id: "condition-1", type: "test", operators: "and", data: {} }],
543
+ onlyShowTaskConditions: []
544
+ }
545
+ ]
546
+ };
547
+ const result = duplicateChecklistData(data);
548
+ expect(result.items[0].completeConditions[0].id).toBe("regenerated-condition-1");
549
+ });
550
+ test("should regenerate onlyShowTaskConditions IDs", () => {
551
+ const data = {
552
+ items: [
553
+ {
554
+ id: "item-1",
555
+ clickedActions: [],
556
+ completeConditions: [],
557
+ onlyShowTaskConditions: [{ id: "condition-1", type: "test", operators: "and", data: {} }]
558
+ }
559
+ ]
560
+ };
561
+ const result = duplicateChecklistData(data);
562
+ expect(result.items[0].onlyShowTaskConditions[0].id).toBe("regenerated-condition-1");
563
+ });
564
+ });
565
+ describe("duplicateConfig", () => {
566
+ test("should return config as-is for null", () => {
567
+ const result = duplicateConfig(null);
568
+ expect(result).toBeNull();
569
+ });
570
+ test("should return config as-is for undefined", () => {
571
+ const result = duplicateConfig(void 0);
572
+ expect(result).toBeUndefined();
573
+ });
574
+ test("should regenerate autoStartRules IDs", () => {
575
+ var _a;
576
+ const config = {
577
+ autoStartRules: [{ id: "rule-1", type: "test", operators: "and", data: {} }]
578
+ };
579
+ const result = duplicateConfig(config);
580
+ expect((_a = result.autoStartRules) == null ? void 0 : _a[0].id).toBe("regenerated-rule-1");
581
+ });
582
+ test("should regenerate hideRules IDs", () => {
583
+ var _a;
584
+ const config = {
585
+ hideRules: [{ id: "rule-1", type: "test", operators: "and", data: {} }]
586
+ };
587
+ const result = duplicateConfig(config);
588
+ expect((_a = result.hideRules) == null ? void 0 : _a[0].id).toBe("regenerated-rule-1");
589
+ });
590
+ test("should handle config without rules", () => {
591
+ const config = {
592
+ someOtherProperty: "value"
593
+ };
594
+ const result = duplicateConfig(config);
595
+ expect(result.autoStartRules).toBeUndefined();
596
+ expect(result.hideRules).toBeUndefined();
597
+ });
598
+ });
599
+ describe("duplicateData", () => {
600
+ test("should process checklist data for CHECKLIST content type", () => {
601
+ const data = {
602
+ items: [
603
+ {
604
+ id: "item-1",
605
+ clickedActions: [],
606
+ completeConditions: [],
607
+ onlyShowTaskConditions: []
608
+ }
609
+ ]
610
+ };
611
+ const result = duplicateData(data, ContentDataType.CHECKLIST);
612
+ expect(result.items[0].id).toBe("mock-uuid");
613
+ });
614
+ test("should return data as-is for non-CHECKLIST content type", () => {
615
+ const data = { someData: "value" };
616
+ const result = duplicateData(data, "flow");
617
+ expect(result).toEqual(data);
618
+ });
619
+ });
620
+ describe("createStepCopy", () => {
621
+ test("should create a copy of the step with new name", () => {
622
+ const originalStep = {
623
+ id: "step-1",
624
+ cvid: "cvid-1",
625
+ name: "Original Step",
626
+ sequence: 0,
627
+ trigger: [],
628
+ data: [],
629
+ target: void 0,
630
+ createdAt: /* @__PURE__ */ new Date(),
631
+ updatedAt: /* @__PURE__ */ new Date()
632
+ };
633
+ const result = createStepCopy(originalStep, 1);
634
+ expect(result.name).toBe("Original Step (copy)");
635
+ expect(result.sequence).toBe(1);
636
+ expect(result).not.toHaveProperty("id");
637
+ expect(result).not.toHaveProperty("cvid");
638
+ expect(result).not.toHaveProperty("createdAt");
639
+ expect(result).not.toHaveProperty("updatedAt");
640
+ });
641
+ test("should generate unique name when existing names provided", () => {
642
+ const originalStep = {
643
+ id: "step-1",
644
+ cvid: "cvid-1",
645
+ name: "Step",
646
+ sequence: 0,
647
+ trigger: [],
648
+ data: [],
649
+ target: void 0
650
+ };
651
+ const result = createStepCopy(originalStep, 1, ["Step (copy)"]);
652
+ expect(result.name).toBe("Step (copy 2)");
653
+ });
654
+ test("should process triggers in step copy", () => {
655
+ var _a;
656
+ const originalStep = {
657
+ id: "step-1",
658
+ cvid: "cvid-1",
659
+ name: "Step",
660
+ sequence: 0,
661
+ trigger: [
662
+ {
663
+ id: "trigger-1",
664
+ actions: [{ id: "action-1", type: "test", operators: "and", data: {} }],
665
+ conditions: []
666
+ }
667
+ ],
668
+ data: [],
669
+ target: void 0
670
+ };
671
+ const result = createStepCopy(originalStep, 1);
672
+ expect((_a = result.trigger) == null ? void 0 : _a[0].id).toBe("mock-cuid");
673
+ });
674
+ test("should process target in step copy", () => {
675
+ var _a, _b;
676
+ const originalStep = {
677
+ id: "step-1",
678
+ cvid: "cvid-1",
679
+ name: "Step",
680
+ sequence: 0,
681
+ trigger: [],
682
+ data: [],
683
+ target: {
684
+ actions: [{ id: "action-1", type: "test", operators: "and", data: {} }]
685
+ }
686
+ };
687
+ const result = createStepCopy(originalStep, 1);
688
+ expect((_b = (_a = result.target) == null ? void 0 : _a.actions) == null ? void 0 : _b[0].id).toBe("regenerated-action-1");
689
+ });
690
+ test("should handle step without trigger", () => {
691
+ const originalStep = {
692
+ id: "step-1",
693
+ cvid: "cvid-1",
694
+ name: "Step",
695
+ sequence: 0,
696
+ trigger: void 0,
697
+ data: [],
698
+ target: void 0
699
+ };
700
+ const result = createStepCopy(originalStep, 1);
701
+ expect(result.trigger).toEqual([]);
702
+ });
703
+ test("should handle step without data", () => {
704
+ const originalStep = {
705
+ id: "step-1",
706
+ cvid: "cvid-1",
707
+ name: "Step",
708
+ sequence: 0,
709
+ trigger: [],
710
+ data: void 0,
711
+ target: void 0
712
+ };
713
+ const result = createStepCopy(originalStep, 1);
714
+ expect(result.data).toEqual([]);
715
+ });
716
+ });