@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.
- package/dist/__tests__/content-helper.test.cjs +1009 -0
- package/dist/__tests__/content-helper.test.d.cts +2 -0
- package/dist/__tests__/content-helper.test.d.ts +2 -0
- package/dist/__tests__/content-helper.test.js +716 -0
- package/dist/chunk-7GJAPR7Y.js +218 -0
- package/dist/content-helper.cjs +67 -23
- package/dist/content-helper.d.cts +34 -9
- package/dist/content-helper.d.ts +34 -9
- package/dist/content-helper.js +25 -169
- package/dist/index.cjs +217 -0
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +30 -0
- package/package.json +1 -1
|
@@ -0,0 +1,1009 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (let key of __getOwnPropNames(from))
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
12
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
13
|
+
}
|
|
14
|
+
return to;
|
|
15
|
+
};
|
|
16
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
18
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
19
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
20
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
24
|
+
|
|
25
|
+
// src/__tests__/content-helper.test.ts
|
|
26
|
+
var import_types4 = require("@usertour/types");
|
|
27
|
+
|
|
28
|
+
// src/content-helper.ts
|
|
29
|
+
var import_types3 = require("@usertour/types");
|
|
30
|
+
|
|
31
|
+
// src/helper.ts
|
|
32
|
+
var import_clsx = require("clsx");
|
|
33
|
+
var import_tailwind_merge = require("tailwind-merge");
|
|
34
|
+
var import_uuid = require("uuid");
|
|
35
|
+
var import_cuid2 = require("@paralleldrive/cuid2");
|
|
36
|
+
function cn(...inputs) {
|
|
37
|
+
return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
|
|
38
|
+
}
|
|
39
|
+
var cuid = () => {
|
|
40
|
+
return (0, import_cuid2.createId)();
|
|
41
|
+
};
|
|
42
|
+
function formatDate(input) {
|
|
43
|
+
const date = new Date(input);
|
|
44
|
+
return date.toLocaleDateString("en-US", {
|
|
45
|
+
month: "long",
|
|
46
|
+
day: "numeric",
|
|
47
|
+
year: "numeric"
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
function absoluteUrl(path) {
|
|
51
|
+
return `${path}`;
|
|
52
|
+
}
|
|
53
|
+
var uuidV4 = () => {
|
|
54
|
+
return (0, import_uuid.v4)();
|
|
55
|
+
};
|
|
56
|
+
function hexToRgb(hex) {
|
|
57
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
58
|
+
return result ? {
|
|
59
|
+
r: Number.parseInt(result[1], 16),
|
|
60
|
+
g: Number.parseInt(result[2], 16),
|
|
61
|
+
b: Number.parseInt(result[3], 16)
|
|
62
|
+
} : null;
|
|
63
|
+
}
|
|
64
|
+
var isDark = (hex) => {
|
|
65
|
+
const rgb = hexToRgb(hex);
|
|
66
|
+
if (!rgb) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const { r, g, b } = rgb;
|
|
70
|
+
if (r * 0.299 + g * 0.587 + b * 0.114 > 186) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
};
|
|
75
|
+
var evalCode = (code) => {
|
|
76
|
+
try {
|
|
77
|
+
return eval(code);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error("Usertour.js: Error evaluating code:", error);
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
var getRandomColor = () => {
|
|
84
|
+
const colors = [
|
|
85
|
+
"bg-red-500",
|
|
86
|
+
"bg-orange-500",
|
|
87
|
+
"bg-yellow-500",
|
|
88
|
+
"bg-green-500",
|
|
89
|
+
"bg-teal-500",
|
|
90
|
+
"bg-blue-500",
|
|
91
|
+
"bg-indigo-500",
|
|
92
|
+
"bg-purple-500",
|
|
93
|
+
"bg-pink-500",
|
|
94
|
+
"bg-rose-500"
|
|
95
|
+
];
|
|
96
|
+
return colors[Math.floor(Math.random() * colors.length)];
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// src/conditions/condition.ts
|
|
100
|
+
var import_types2 = require("@usertour/types");
|
|
101
|
+
var import_fast_deep_equal = __toESM(require("fast-deep-equal"), 1);
|
|
102
|
+
|
|
103
|
+
// src/conditions/time.ts
|
|
104
|
+
var import_date_fns = require("date-fns");
|
|
105
|
+
|
|
106
|
+
// src/type-utils.ts
|
|
107
|
+
var nativeIsArray = Array.isArray;
|
|
108
|
+
var ObjProto = Object.prototype;
|
|
109
|
+
var objToString = ObjProto.toString;
|
|
110
|
+
var objHasOwn = ObjProto.hasOwnProperty;
|
|
111
|
+
var isArray = nativeIsArray || ((obj) => objToString.call(obj) === "[object Array]");
|
|
112
|
+
var isObject = (x) => {
|
|
113
|
+
return x === Object(x) && !isArray(x);
|
|
114
|
+
};
|
|
115
|
+
var isString = (x) => {
|
|
116
|
+
return objToString.call(x) === "[object String]";
|
|
117
|
+
};
|
|
118
|
+
var isEmptyString = (x) => isString(x) && x.trim().length === 0;
|
|
119
|
+
|
|
120
|
+
// src/conditions/attribute.ts
|
|
121
|
+
var import_types = require("@usertour/types");
|
|
122
|
+
var import_date_fns2 = require("date-fns");
|
|
123
|
+
|
|
124
|
+
// src/conditions/condition.ts
|
|
125
|
+
var regenerateConditionIds = (conditions) => {
|
|
126
|
+
return conditions.map((condition) => ({
|
|
127
|
+
...condition,
|
|
128
|
+
id: cuid(),
|
|
129
|
+
conditions: condition.conditions ? regenerateConditionIds(condition.conditions) : void 0
|
|
130
|
+
}));
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// src/content-helper.ts
|
|
134
|
+
var isRestrictedType = (type) => {
|
|
135
|
+
const restrictedTypes = [
|
|
136
|
+
import_types3.ContentEditorElementType.NPS,
|
|
137
|
+
import_types3.ContentEditorElementType.STAR_RATING,
|
|
138
|
+
import_types3.ContentEditorElementType.SCALE,
|
|
139
|
+
import_types3.ContentEditorElementType.SINGLE_LINE_TEXT,
|
|
140
|
+
import_types3.ContentEditorElementType.MULTI_LINE_TEXT,
|
|
141
|
+
import_types3.ContentEditorElementType.MULTIPLE_CHOICE
|
|
142
|
+
];
|
|
143
|
+
return restrictedTypes.includes(type);
|
|
144
|
+
};
|
|
145
|
+
var isMissingRequiredData = (element) => {
|
|
146
|
+
var _a, _b, _c, _d;
|
|
147
|
+
if (isRestrictedType(element.type)) {
|
|
148
|
+
return isEmptyString((_a = element.data) == null ? void 0 : _a.name);
|
|
149
|
+
}
|
|
150
|
+
if (element.type === import_types3.ContentEditorElementType.BUTTON) {
|
|
151
|
+
if (isEmptyString((_b = element.data) == null ? void 0 : _b.text)) {
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
if (!((_c = element == null ? void 0 : element.data) == null ? void 0 : _c.actions) || ((_d = element == null ? void 0 : element.data) == null ? void 0 : _d.actions.length) === 0) {
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return false;
|
|
159
|
+
};
|
|
160
|
+
var hasMissingRequiredData = (contents) => {
|
|
161
|
+
return contents.some(
|
|
162
|
+
(group) => group.children.some(
|
|
163
|
+
(column) => column.children.some((item) => isMissingRequiredData(item.element))
|
|
164
|
+
)
|
|
165
|
+
);
|
|
166
|
+
};
|
|
167
|
+
var isQuestionElement = (element) => {
|
|
168
|
+
return element.type === import_types3.ContentEditorElementType.SINGLE_LINE_TEXT || element.type === import_types3.ContentEditorElementType.MULTI_LINE_TEXT || element.type === import_types3.ContentEditorElementType.NPS || element.type === import_types3.ContentEditorElementType.STAR_RATING || element.type === import_types3.ContentEditorElementType.SCALE || element.type === import_types3.ContentEditorElementType.MULTIPLE_CHOICE;
|
|
169
|
+
};
|
|
170
|
+
var isClickableElement = (element) => {
|
|
171
|
+
return element.type === import_types3.ContentEditorElementType.BUTTON || isQuestionElement(element);
|
|
172
|
+
};
|
|
173
|
+
var extractQuestionData = (data) => {
|
|
174
|
+
const result = [];
|
|
175
|
+
function isQuestionRootElement(item) {
|
|
176
|
+
return "element" in item && isQuestionElement(item.element);
|
|
177
|
+
}
|
|
178
|
+
function traverse(item) {
|
|
179
|
+
if (isQuestionRootElement(item)) {
|
|
180
|
+
result.push(item.element);
|
|
181
|
+
}
|
|
182
|
+
if ("children" in item && item.children) {
|
|
183
|
+
for (const child of item.children) {
|
|
184
|
+
traverse(child);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
for (const item of data) {
|
|
189
|
+
traverse(item);
|
|
190
|
+
}
|
|
191
|
+
return result;
|
|
192
|
+
};
|
|
193
|
+
var processQuestionElements = (contents) => {
|
|
194
|
+
if (!contents || !isArray(contents) || contents.length === 0) {
|
|
195
|
+
return [];
|
|
196
|
+
}
|
|
197
|
+
return contents.map((group) => ({
|
|
198
|
+
...group,
|
|
199
|
+
children: group.children.map((column) => ({
|
|
200
|
+
...column,
|
|
201
|
+
children: column.children.map((item) => {
|
|
202
|
+
var _a, _b;
|
|
203
|
+
const element = item.element;
|
|
204
|
+
if (isQuestionElement(element)) {
|
|
205
|
+
const questionElement = element;
|
|
206
|
+
const updatedElement = {
|
|
207
|
+
...questionElement,
|
|
208
|
+
data: {
|
|
209
|
+
...questionElement.data,
|
|
210
|
+
cvid: cuid(),
|
|
211
|
+
...((_a = questionElement.data) == null ? void 0 : _a.actions) && isArray(questionElement.data.actions) ? { actions: regenerateConditionIds(questionElement.data.actions) } : {}
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
return {
|
|
215
|
+
...item,
|
|
216
|
+
element: updatedElement
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
if (element.type === import_types3.ContentEditorElementType.BUTTON) {
|
|
220
|
+
const buttonElement = element;
|
|
221
|
+
if (((_b = buttonElement.data) == null ? void 0 : _b.actions) && isArray(buttonElement.data.actions)) {
|
|
222
|
+
return {
|
|
223
|
+
...item,
|
|
224
|
+
element: {
|
|
225
|
+
...buttonElement,
|
|
226
|
+
data: {
|
|
227
|
+
...buttonElement.data,
|
|
228
|
+
actions: regenerateConditionIds(buttonElement.data.actions)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return item;
|
|
235
|
+
})
|
|
236
|
+
}))
|
|
237
|
+
}));
|
|
238
|
+
};
|
|
239
|
+
var generateUniqueCopyName = (originalName, existingNames) => {
|
|
240
|
+
let name = `${originalName} (copy)`;
|
|
241
|
+
if (existingNames == null ? void 0 : existingNames.includes(name)) {
|
|
242
|
+
let number = 2;
|
|
243
|
+
while (existingNames.includes(`${originalName} (copy ${number})`)) {
|
|
244
|
+
number++;
|
|
245
|
+
}
|
|
246
|
+
name = `${originalName} (copy ${number})`;
|
|
247
|
+
}
|
|
248
|
+
return name;
|
|
249
|
+
};
|
|
250
|
+
var duplicateTriggers = (triggers) => {
|
|
251
|
+
if (!isArray(triggers)) {
|
|
252
|
+
return triggers;
|
|
253
|
+
}
|
|
254
|
+
return triggers.map((trigger) => ({
|
|
255
|
+
...trigger,
|
|
256
|
+
id: cuid(),
|
|
257
|
+
actions: isArray(trigger.actions) ? regenerateConditionIds(trigger.actions) : trigger.actions,
|
|
258
|
+
conditions: isArray(trigger.conditions) ? regenerateConditionIds(trigger.conditions) : trigger.conditions
|
|
259
|
+
}));
|
|
260
|
+
};
|
|
261
|
+
var duplicateTarget = (target) => {
|
|
262
|
+
if (!target) {
|
|
263
|
+
return void 0;
|
|
264
|
+
}
|
|
265
|
+
if (target.actions && isArray(target.actions)) {
|
|
266
|
+
return {
|
|
267
|
+
...target,
|
|
268
|
+
actions: regenerateConditionIds(target.actions)
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
return target;
|
|
272
|
+
};
|
|
273
|
+
var duplicateChecklistData = (data) => {
|
|
274
|
+
if (!data || !isObject(data) || !isArray(data.items)) {
|
|
275
|
+
return data;
|
|
276
|
+
}
|
|
277
|
+
const checklistData = data;
|
|
278
|
+
return {
|
|
279
|
+
...checklistData,
|
|
280
|
+
items: checklistData.items.map((item) => ({
|
|
281
|
+
...item,
|
|
282
|
+
id: uuidV4(),
|
|
283
|
+
clickedActions: isArray(item.clickedActions) ? regenerateConditionIds(item.clickedActions) : item.clickedActions,
|
|
284
|
+
completeConditions: isArray(item.completeConditions) ? regenerateConditionIds(item.completeConditions) : item.completeConditions,
|
|
285
|
+
onlyShowTaskConditions: isArray(item.onlyShowTaskConditions) ? regenerateConditionIds(item.onlyShowTaskConditions) : item.onlyShowTaskConditions
|
|
286
|
+
}))
|
|
287
|
+
};
|
|
288
|
+
};
|
|
289
|
+
var duplicateConfig = (config) => {
|
|
290
|
+
if (!config) {
|
|
291
|
+
return config;
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
...config,
|
|
295
|
+
autoStartRules: config.autoStartRules ? regenerateConditionIds(config.autoStartRules) : config.autoStartRules,
|
|
296
|
+
hideRules: config.hideRules ? regenerateConditionIds(config.hideRules) : config.hideRules
|
|
297
|
+
};
|
|
298
|
+
};
|
|
299
|
+
var duplicateData = (data, contentType) => {
|
|
300
|
+
if (contentType === import_types3.ContentDataType.CHECKLIST) {
|
|
301
|
+
return duplicateChecklistData(data);
|
|
302
|
+
}
|
|
303
|
+
return data;
|
|
304
|
+
};
|
|
305
|
+
var createStepCopy = (originalStep, sequence, existingStepNames) => {
|
|
306
|
+
const { id, cvid, updatedAt, createdAt, ...rest } = originalStep;
|
|
307
|
+
const name = generateUniqueCopyName(originalStep == null ? void 0 : originalStep.name, existingStepNames);
|
|
308
|
+
const trigger = (originalStep == null ? void 0 : originalStep.trigger) ? duplicateTriggers(originalStep == null ? void 0 : originalStep.trigger) : [];
|
|
309
|
+
const data = (originalStep == null ? void 0 : originalStep.data) ? processQuestionElements(originalStep == null ? void 0 : originalStep.data) : [];
|
|
310
|
+
const target = duplicateTarget(originalStep == null ? void 0 : originalStep.target);
|
|
311
|
+
return {
|
|
312
|
+
...rest,
|
|
313
|
+
data,
|
|
314
|
+
trigger,
|
|
315
|
+
target,
|
|
316
|
+
name,
|
|
317
|
+
sequence
|
|
318
|
+
};
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
// src/__tests__/content-helper.test.ts
|
|
322
|
+
jest.mock("../helper", () => ({
|
|
323
|
+
cuid: jest.fn(() => "mock-cuid"),
|
|
324
|
+
uuidV4: jest.fn(() => "mock-uuid")
|
|
325
|
+
}));
|
|
326
|
+
jest.mock("../conditions", () => ({
|
|
327
|
+
regenerateConditionIds: jest.fn(
|
|
328
|
+
(conditions) => conditions == null ? void 0 : conditions.map((c) => ({ ...c, id: `regenerated-${c.id}` }))
|
|
329
|
+
)
|
|
330
|
+
}));
|
|
331
|
+
describe("isRestrictedType", () => {
|
|
332
|
+
test("should return true for NPS type", () => {
|
|
333
|
+
expect(isRestrictedType(import_types4.ContentEditorElementType.NPS)).toBe(true);
|
|
334
|
+
});
|
|
335
|
+
test("should return true for STAR_RATING type", () => {
|
|
336
|
+
expect(isRestrictedType(import_types4.ContentEditorElementType.STAR_RATING)).toBe(true);
|
|
337
|
+
});
|
|
338
|
+
test("should return true for SCALE type", () => {
|
|
339
|
+
expect(isRestrictedType(import_types4.ContentEditorElementType.SCALE)).toBe(true);
|
|
340
|
+
});
|
|
341
|
+
test("should return true for SINGLE_LINE_TEXT type", () => {
|
|
342
|
+
expect(isRestrictedType(import_types4.ContentEditorElementType.SINGLE_LINE_TEXT)).toBe(true);
|
|
343
|
+
});
|
|
344
|
+
test("should return true for MULTI_LINE_TEXT type", () => {
|
|
345
|
+
expect(isRestrictedType(import_types4.ContentEditorElementType.MULTI_LINE_TEXT)).toBe(true);
|
|
346
|
+
});
|
|
347
|
+
test("should return true for MULTIPLE_CHOICE type", () => {
|
|
348
|
+
expect(isRestrictedType(import_types4.ContentEditorElementType.MULTIPLE_CHOICE)).toBe(true);
|
|
349
|
+
});
|
|
350
|
+
test("should return false for BUTTON type", () => {
|
|
351
|
+
expect(isRestrictedType(import_types4.ContentEditorElementType.BUTTON)).toBe(false);
|
|
352
|
+
});
|
|
353
|
+
test("should return false for TEXT type", () => {
|
|
354
|
+
expect(isRestrictedType(import_types4.ContentEditorElementType.TEXT)).toBe(false);
|
|
355
|
+
});
|
|
356
|
+
test("should return false for IMAGE type", () => {
|
|
357
|
+
expect(isRestrictedType(import_types4.ContentEditorElementType.IMAGE)).toBe(false);
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
describe("isMissingRequiredData", () => {
|
|
361
|
+
test("should return true when restricted type element has empty name", () => {
|
|
362
|
+
const element = {
|
|
363
|
+
type: import_types4.ContentEditorElementType.NPS,
|
|
364
|
+
data: { name: "" }
|
|
365
|
+
};
|
|
366
|
+
expect(isMissingRequiredData(element)).toBe(true);
|
|
367
|
+
});
|
|
368
|
+
test("should return false when restricted type element has undefined name (isEmptyString returns false for undefined)", () => {
|
|
369
|
+
const element = {
|
|
370
|
+
type: import_types4.ContentEditorElementType.NPS,
|
|
371
|
+
data: {}
|
|
372
|
+
};
|
|
373
|
+
expect(isMissingRequiredData(element)).toBe(false);
|
|
374
|
+
});
|
|
375
|
+
test("should return false when restricted type element has valid name", () => {
|
|
376
|
+
const element = {
|
|
377
|
+
type: import_types4.ContentEditorElementType.NPS,
|
|
378
|
+
data: { name: "Valid Name" }
|
|
379
|
+
};
|
|
380
|
+
expect(isMissingRequiredData(element)).toBe(false);
|
|
381
|
+
});
|
|
382
|
+
test("should return true when button element has empty text", () => {
|
|
383
|
+
const element = {
|
|
384
|
+
type: import_types4.ContentEditorElementType.BUTTON,
|
|
385
|
+
data: { text: "", actions: [{ id: "1" }] }
|
|
386
|
+
};
|
|
387
|
+
expect(isMissingRequiredData(element)).toBe(true);
|
|
388
|
+
});
|
|
389
|
+
test("should return true when button element has no actions", () => {
|
|
390
|
+
const element = {
|
|
391
|
+
type: import_types4.ContentEditorElementType.BUTTON,
|
|
392
|
+
data: { text: "Button", actions: [] }
|
|
393
|
+
};
|
|
394
|
+
expect(isMissingRequiredData(element)).toBe(true);
|
|
395
|
+
});
|
|
396
|
+
test("should return true when button element has undefined actions", () => {
|
|
397
|
+
const element = {
|
|
398
|
+
type: import_types4.ContentEditorElementType.BUTTON,
|
|
399
|
+
data: { text: "Button" }
|
|
400
|
+
};
|
|
401
|
+
expect(isMissingRequiredData(element)).toBe(true);
|
|
402
|
+
});
|
|
403
|
+
test("should return false when button element has valid text and actions", () => {
|
|
404
|
+
const element = {
|
|
405
|
+
type: import_types4.ContentEditorElementType.BUTTON,
|
|
406
|
+
data: { text: "Button", actions: [{ id: "1" }] }
|
|
407
|
+
};
|
|
408
|
+
expect(isMissingRequiredData(element)).toBe(false);
|
|
409
|
+
});
|
|
410
|
+
test("should return false for non-restricted, non-button type", () => {
|
|
411
|
+
const element = {
|
|
412
|
+
type: import_types4.ContentEditorElementType.TEXT,
|
|
413
|
+
data: {}
|
|
414
|
+
};
|
|
415
|
+
expect(isMissingRequiredData(element)).toBe(false);
|
|
416
|
+
});
|
|
417
|
+
});
|
|
418
|
+
describe("hasMissingRequiredData", () => {
|
|
419
|
+
const createContentRoot = (element) => [
|
|
420
|
+
{
|
|
421
|
+
type: "root",
|
|
422
|
+
children: [
|
|
423
|
+
{
|
|
424
|
+
type: "column",
|
|
425
|
+
children: [
|
|
426
|
+
{
|
|
427
|
+
type: "element",
|
|
428
|
+
element
|
|
429
|
+
}
|
|
430
|
+
]
|
|
431
|
+
}
|
|
432
|
+
]
|
|
433
|
+
}
|
|
434
|
+
];
|
|
435
|
+
test("should return true when content has element with missing required data", () => {
|
|
436
|
+
const element = {
|
|
437
|
+
type: import_types4.ContentEditorElementType.NPS,
|
|
438
|
+
data: { name: "" }
|
|
439
|
+
};
|
|
440
|
+
const contents = createContentRoot(element);
|
|
441
|
+
expect(hasMissingRequiredData(contents)).toBe(true);
|
|
442
|
+
});
|
|
443
|
+
test("should return false when all elements have required data", () => {
|
|
444
|
+
const element = {
|
|
445
|
+
type: import_types4.ContentEditorElementType.NPS,
|
|
446
|
+
data: { name: "Valid Name" }
|
|
447
|
+
};
|
|
448
|
+
const contents = createContentRoot(element);
|
|
449
|
+
expect(hasMissingRequiredData(contents)).toBe(false);
|
|
450
|
+
});
|
|
451
|
+
test("should return false for empty contents array", () => {
|
|
452
|
+
expect(hasMissingRequiredData([])).toBe(false);
|
|
453
|
+
});
|
|
454
|
+
});
|
|
455
|
+
describe("isQuestionElement", () => {
|
|
456
|
+
test("should return true for SINGLE_LINE_TEXT", () => {
|
|
457
|
+
const element = { type: import_types4.ContentEditorElementType.SINGLE_LINE_TEXT };
|
|
458
|
+
expect(isQuestionElement(element)).toBe(true);
|
|
459
|
+
});
|
|
460
|
+
test("should return true for MULTI_LINE_TEXT", () => {
|
|
461
|
+
const element = { type: import_types4.ContentEditorElementType.MULTI_LINE_TEXT };
|
|
462
|
+
expect(isQuestionElement(element)).toBe(true);
|
|
463
|
+
});
|
|
464
|
+
test("should return true for NPS", () => {
|
|
465
|
+
const element = { type: import_types4.ContentEditorElementType.NPS };
|
|
466
|
+
expect(isQuestionElement(element)).toBe(true);
|
|
467
|
+
});
|
|
468
|
+
test("should return true for STAR_RATING", () => {
|
|
469
|
+
const element = { type: import_types4.ContentEditorElementType.STAR_RATING };
|
|
470
|
+
expect(isQuestionElement(element)).toBe(true);
|
|
471
|
+
});
|
|
472
|
+
test("should return true for SCALE", () => {
|
|
473
|
+
const element = { type: import_types4.ContentEditorElementType.SCALE };
|
|
474
|
+
expect(isQuestionElement(element)).toBe(true);
|
|
475
|
+
});
|
|
476
|
+
test("should return true for MULTIPLE_CHOICE", () => {
|
|
477
|
+
const element = { type: import_types4.ContentEditorElementType.MULTIPLE_CHOICE };
|
|
478
|
+
expect(isQuestionElement(element)).toBe(true);
|
|
479
|
+
});
|
|
480
|
+
test("should return false for BUTTON", () => {
|
|
481
|
+
const element = { type: import_types4.ContentEditorElementType.BUTTON };
|
|
482
|
+
expect(isQuestionElement(element)).toBe(false);
|
|
483
|
+
});
|
|
484
|
+
test("should return false for TEXT", () => {
|
|
485
|
+
const element = { type: import_types4.ContentEditorElementType.TEXT };
|
|
486
|
+
expect(isQuestionElement(element)).toBe(false);
|
|
487
|
+
});
|
|
488
|
+
});
|
|
489
|
+
describe("isClickableElement", () => {
|
|
490
|
+
test("should return true for BUTTON type", () => {
|
|
491
|
+
const element = { type: import_types4.ContentEditorElementType.BUTTON, data: {} };
|
|
492
|
+
expect(isClickableElement(element)).toBe(true);
|
|
493
|
+
});
|
|
494
|
+
test("should return true for question elements", () => {
|
|
495
|
+
const element = { type: import_types4.ContentEditorElementType.NPS, data: {} };
|
|
496
|
+
expect(isClickableElement(element)).toBe(true);
|
|
497
|
+
});
|
|
498
|
+
test("should return false for non-clickable elements", () => {
|
|
499
|
+
const element = { type: import_types4.ContentEditorElementType.TEXT, data: [] };
|
|
500
|
+
expect(isClickableElement(element)).toBe(false);
|
|
501
|
+
});
|
|
502
|
+
});
|
|
503
|
+
describe("extractQuestionData", () => {
|
|
504
|
+
test("should extract question elements from content", () => {
|
|
505
|
+
const questionElement = {
|
|
506
|
+
type: import_types4.ContentEditorElementType.NPS,
|
|
507
|
+
data: { name: "NPS Question", cvid: "test-cvid" }
|
|
508
|
+
};
|
|
509
|
+
const contents = [
|
|
510
|
+
{
|
|
511
|
+
type: "root",
|
|
512
|
+
children: [
|
|
513
|
+
{
|
|
514
|
+
type: "column",
|
|
515
|
+
children: [
|
|
516
|
+
{
|
|
517
|
+
type: "element",
|
|
518
|
+
element: questionElement
|
|
519
|
+
}
|
|
520
|
+
]
|
|
521
|
+
}
|
|
522
|
+
]
|
|
523
|
+
}
|
|
524
|
+
];
|
|
525
|
+
const result = extractQuestionData(contents);
|
|
526
|
+
expect(result).toHaveLength(1);
|
|
527
|
+
expect(result[0]).toEqual(questionElement);
|
|
528
|
+
});
|
|
529
|
+
test("should return empty array when no question elements exist", () => {
|
|
530
|
+
const textElement = {
|
|
531
|
+
type: import_types4.ContentEditorElementType.TEXT,
|
|
532
|
+
data: {}
|
|
533
|
+
};
|
|
534
|
+
const contents = [
|
|
535
|
+
{
|
|
536
|
+
type: "root",
|
|
537
|
+
children: [
|
|
538
|
+
{
|
|
539
|
+
type: "column",
|
|
540
|
+
children: [
|
|
541
|
+
{
|
|
542
|
+
type: "element",
|
|
543
|
+
element: textElement
|
|
544
|
+
}
|
|
545
|
+
]
|
|
546
|
+
}
|
|
547
|
+
]
|
|
548
|
+
}
|
|
549
|
+
];
|
|
550
|
+
const result = extractQuestionData(contents);
|
|
551
|
+
expect(result).toHaveLength(0);
|
|
552
|
+
});
|
|
553
|
+
test("should return empty array for empty contents", () => {
|
|
554
|
+
const result = extractQuestionData([]);
|
|
555
|
+
expect(result).toHaveLength(0);
|
|
556
|
+
});
|
|
557
|
+
test("should extract multiple question elements", () => {
|
|
558
|
+
const npsElement = {
|
|
559
|
+
type: import_types4.ContentEditorElementType.NPS,
|
|
560
|
+
data: { name: "NPS" }
|
|
561
|
+
};
|
|
562
|
+
const scaleElement = {
|
|
563
|
+
type: import_types4.ContentEditorElementType.SCALE,
|
|
564
|
+
data: { name: "Scale" }
|
|
565
|
+
};
|
|
566
|
+
const contents = [
|
|
567
|
+
{
|
|
568
|
+
type: "root",
|
|
569
|
+
children: [
|
|
570
|
+
{
|
|
571
|
+
type: "column",
|
|
572
|
+
children: [
|
|
573
|
+
{ type: "element", element: npsElement },
|
|
574
|
+
{ type: "element", element: scaleElement }
|
|
575
|
+
]
|
|
576
|
+
}
|
|
577
|
+
]
|
|
578
|
+
}
|
|
579
|
+
];
|
|
580
|
+
const result = extractQuestionData(contents);
|
|
581
|
+
expect(result).toHaveLength(2);
|
|
582
|
+
});
|
|
583
|
+
});
|
|
584
|
+
describe("processQuestionElements", () => {
|
|
585
|
+
test("should return empty array for undefined contents", () => {
|
|
586
|
+
const result = processQuestionElements(void 0);
|
|
587
|
+
expect(result).toEqual([]);
|
|
588
|
+
});
|
|
589
|
+
test("should return empty array for empty contents", () => {
|
|
590
|
+
const result = processQuestionElements([]);
|
|
591
|
+
expect(result).toEqual([]);
|
|
592
|
+
});
|
|
593
|
+
test("should regenerate cvid for question elements", () => {
|
|
594
|
+
const questionElement = {
|
|
595
|
+
type: import_types4.ContentEditorElementType.NPS,
|
|
596
|
+
data: { name: "NPS Question", cvid: "old-cvid" }
|
|
597
|
+
};
|
|
598
|
+
const contents = [
|
|
599
|
+
{
|
|
600
|
+
type: "root",
|
|
601
|
+
children: [
|
|
602
|
+
{
|
|
603
|
+
type: "column",
|
|
604
|
+
children: [
|
|
605
|
+
{
|
|
606
|
+
type: "element",
|
|
607
|
+
element: questionElement
|
|
608
|
+
}
|
|
609
|
+
]
|
|
610
|
+
}
|
|
611
|
+
]
|
|
612
|
+
}
|
|
613
|
+
];
|
|
614
|
+
const result = processQuestionElements(contents);
|
|
615
|
+
const processedElement = result[0].children[0].children[0].element;
|
|
616
|
+
expect(processedElement.data.cvid).toBe("mock-cuid");
|
|
617
|
+
});
|
|
618
|
+
test("should regenerate actions for button elements", () => {
|
|
619
|
+
var _a;
|
|
620
|
+
const buttonElement = {
|
|
621
|
+
type: import_types4.ContentEditorElementType.BUTTON,
|
|
622
|
+
data: {
|
|
623
|
+
text: "Button",
|
|
624
|
+
actions: [{ id: "action-1", type: "test" }]
|
|
625
|
+
}
|
|
626
|
+
};
|
|
627
|
+
const contents = [
|
|
628
|
+
{
|
|
629
|
+
type: "root",
|
|
630
|
+
children: [
|
|
631
|
+
{
|
|
632
|
+
type: "column",
|
|
633
|
+
children: [
|
|
634
|
+
{
|
|
635
|
+
type: "element",
|
|
636
|
+
element: buttonElement
|
|
637
|
+
}
|
|
638
|
+
]
|
|
639
|
+
}
|
|
640
|
+
]
|
|
641
|
+
}
|
|
642
|
+
];
|
|
643
|
+
const result = processQuestionElements(contents);
|
|
644
|
+
const processedElement = result[0].children[0].children[0].element;
|
|
645
|
+
expect((_a = processedElement.data) == null ? void 0 : _a.actions[0].id).toBe("regenerated-action-1");
|
|
646
|
+
});
|
|
647
|
+
test("should not modify non-question, non-button elements", () => {
|
|
648
|
+
const textElement = {
|
|
649
|
+
type: import_types4.ContentEditorElementType.TEXT,
|
|
650
|
+
data: []
|
|
651
|
+
};
|
|
652
|
+
const contents = [
|
|
653
|
+
{
|
|
654
|
+
type: "root",
|
|
655
|
+
children: [
|
|
656
|
+
{
|
|
657
|
+
type: "column",
|
|
658
|
+
children: [
|
|
659
|
+
{
|
|
660
|
+
type: "element",
|
|
661
|
+
element: textElement
|
|
662
|
+
}
|
|
663
|
+
]
|
|
664
|
+
}
|
|
665
|
+
]
|
|
666
|
+
}
|
|
667
|
+
];
|
|
668
|
+
const result = processQuestionElements(contents);
|
|
669
|
+
const processedElement = result[0].children[0].children[0].element;
|
|
670
|
+
expect(processedElement).toEqual(textElement);
|
|
671
|
+
});
|
|
672
|
+
});
|
|
673
|
+
describe("generateUniqueCopyName", () => {
|
|
674
|
+
test('should generate "Name (copy)" for first copy', () => {
|
|
675
|
+
const result = generateUniqueCopyName("Test");
|
|
676
|
+
expect(result).toBe("Test (copy)");
|
|
677
|
+
});
|
|
678
|
+
test('should generate "Name (copy)" when no existing names provided', () => {
|
|
679
|
+
const result = generateUniqueCopyName("Test", []);
|
|
680
|
+
expect(result).toBe("Test (copy)");
|
|
681
|
+
});
|
|
682
|
+
test('should generate "Name (copy 2)" when "Name (copy)" exists', () => {
|
|
683
|
+
const result = generateUniqueCopyName("Test", ["Test (copy)"]);
|
|
684
|
+
expect(result).toBe("Test (copy 2)");
|
|
685
|
+
});
|
|
686
|
+
test('should generate "Name (copy 3)" when "Name (copy)" and "Name (copy 2)" exist', () => {
|
|
687
|
+
const result = generateUniqueCopyName("Test", ["Test (copy)", "Test (copy 2)"]);
|
|
688
|
+
expect(result).toBe("Test (copy 3)");
|
|
689
|
+
});
|
|
690
|
+
test("should find next available number", () => {
|
|
691
|
+
const result = generateUniqueCopyName("Test", [
|
|
692
|
+
"Test (copy)",
|
|
693
|
+
"Test (copy 2)",
|
|
694
|
+
"Test (copy 3)",
|
|
695
|
+
"Test (copy 4)"
|
|
696
|
+
]);
|
|
697
|
+
expect(result).toBe("Test (copy 5)");
|
|
698
|
+
});
|
|
699
|
+
});
|
|
700
|
+
describe("duplicateTriggers", () => {
|
|
701
|
+
test("should return triggers as-is when not an array", () => {
|
|
702
|
+
const result = duplicateTriggers(null);
|
|
703
|
+
expect(result).toBeNull();
|
|
704
|
+
});
|
|
705
|
+
test("should regenerate trigger IDs", () => {
|
|
706
|
+
const triggers = [
|
|
707
|
+
{
|
|
708
|
+
id: "trigger-1",
|
|
709
|
+
actions: [{ id: "action-1", type: "test", operators: "and", data: {} }],
|
|
710
|
+
conditions: [{ id: "condition-1", type: "test", operators: "and", data: {} }]
|
|
711
|
+
}
|
|
712
|
+
];
|
|
713
|
+
const result = duplicateTriggers(triggers);
|
|
714
|
+
expect(result[0].id).toBe("mock-cuid");
|
|
715
|
+
});
|
|
716
|
+
test("should regenerate action IDs", () => {
|
|
717
|
+
const triggers = [
|
|
718
|
+
{
|
|
719
|
+
id: "trigger-1",
|
|
720
|
+
actions: [{ id: "action-1", type: "test", operators: "and", data: {} }],
|
|
721
|
+
conditions: []
|
|
722
|
+
}
|
|
723
|
+
];
|
|
724
|
+
const result = duplicateTriggers(triggers);
|
|
725
|
+
expect(result[0].actions[0].id).toBe("regenerated-action-1");
|
|
726
|
+
});
|
|
727
|
+
test("should regenerate condition IDs", () => {
|
|
728
|
+
const triggers = [
|
|
729
|
+
{
|
|
730
|
+
id: "trigger-1",
|
|
731
|
+
actions: [],
|
|
732
|
+
conditions: [{ id: "condition-1", type: "test", operators: "and", data: {} }]
|
|
733
|
+
}
|
|
734
|
+
];
|
|
735
|
+
const result = duplicateTriggers(triggers);
|
|
736
|
+
expect(result[0].conditions[0].id).toBe("regenerated-condition-1");
|
|
737
|
+
});
|
|
738
|
+
test("should handle triggers without actions or conditions", () => {
|
|
739
|
+
const triggers = [
|
|
740
|
+
{
|
|
741
|
+
id: "trigger-1"
|
|
742
|
+
}
|
|
743
|
+
];
|
|
744
|
+
const result = duplicateTriggers(triggers);
|
|
745
|
+
expect(result[0].id).toBe("mock-cuid");
|
|
746
|
+
expect(result[0].actions).toBeUndefined();
|
|
747
|
+
expect(result[0].conditions).toBeUndefined();
|
|
748
|
+
});
|
|
749
|
+
});
|
|
750
|
+
describe("duplicateTarget", () => {
|
|
751
|
+
test("should return undefined for undefined target", () => {
|
|
752
|
+
const result = duplicateTarget(void 0);
|
|
753
|
+
expect(result).toBeUndefined();
|
|
754
|
+
});
|
|
755
|
+
test("should return undefined for null target", () => {
|
|
756
|
+
const result = duplicateTarget(null);
|
|
757
|
+
expect(result).toBeUndefined();
|
|
758
|
+
});
|
|
759
|
+
test("should regenerate action IDs in target", () => {
|
|
760
|
+
var _a;
|
|
761
|
+
const target = {
|
|
762
|
+
actions: [{ id: "action-1", type: "test", operators: "and", data: {} }]
|
|
763
|
+
};
|
|
764
|
+
const result = duplicateTarget(target);
|
|
765
|
+
expect((_a = result == null ? void 0 : result.actions) == null ? void 0 : _a[0].id).toBe("regenerated-action-1");
|
|
766
|
+
});
|
|
767
|
+
test("should return target as-is when no actions", () => {
|
|
768
|
+
const target = {
|
|
769
|
+
selector: ".test"
|
|
770
|
+
};
|
|
771
|
+
const result = duplicateTarget(target);
|
|
772
|
+
expect(result).toEqual(target);
|
|
773
|
+
});
|
|
774
|
+
test("should return target as-is when actions is not an array", () => {
|
|
775
|
+
const target = {
|
|
776
|
+
actions: "not-an-array"
|
|
777
|
+
};
|
|
778
|
+
const result = duplicateTarget(target);
|
|
779
|
+
expect(result).toEqual(target);
|
|
780
|
+
});
|
|
781
|
+
});
|
|
782
|
+
describe("duplicateChecklistData", () => {
|
|
783
|
+
test("should return data as-is for null", () => {
|
|
784
|
+
const result = duplicateChecklistData(null);
|
|
785
|
+
expect(result).toBeNull();
|
|
786
|
+
});
|
|
787
|
+
test("should return data as-is for undefined", () => {
|
|
788
|
+
const result = duplicateChecklistData(void 0);
|
|
789
|
+
expect(result).toBeUndefined();
|
|
790
|
+
});
|
|
791
|
+
test("should return data as-is for non-object", () => {
|
|
792
|
+
const result = duplicateChecklistData("string");
|
|
793
|
+
expect(result).toBe("string");
|
|
794
|
+
});
|
|
795
|
+
test("should return data as-is when items is not an array", () => {
|
|
796
|
+
const data = { items: "not-an-array" };
|
|
797
|
+
const result = duplicateChecklistData(data);
|
|
798
|
+
expect(result).toEqual(data);
|
|
799
|
+
});
|
|
800
|
+
test("should regenerate item IDs", () => {
|
|
801
|
+
const data = {
|
|
802
|
+
items: [
|
|
803
|
+
{
|
|
804
|
+
id: "item-1",
|
|
805
|
+
title: "Task 1",
|
|
806
|
+
clickedActions: [],
|
|
807
|
+
completeConditions: [],
|
|
808
|
+
onlyShowTaskConditions: []
|
|
809
|
+
}
|
|
810
|
+
]
|
|
811
|
+
};
|
|
812
|
+
const result = duplicateChecklistData(data);
|
|
813
|
+
expect(result.items[0].id).toBe("mock-uuid");
|
|
814
|
+
});
|
|
815
|
+
test("should regenerate clickedActions IDs", () => {
|
|
816
|
+
const data = {
|
|
817
|
+
items: [
|
|
818
|
+
{
|
|
819
|
+
id: "item-1",
|
|
820
|
+
clickedActions: [{ id: "action-1", type: "test", operators: "and", data: {} }],
|
|
821
|
+
completeConditions: [],
|
|
822
|
+
onlyShowTaskConditions: []
|
|
823
|
+
}
|
|
824
|
+
]
|
|
825
|
+
};
|
|
826
|
+
const result = duplicateChecklistData(data);
|
|
827
|
+
expect(result.items[0].clickedActions[0].id).toBe("regenerated-action-1");
|
|
828
|
+
});
|
|
829
|
+
test("should regenerate completeConditions IDs", () => {
|
|
830
|
+
const data = {
|
|
831
|
+
items: [
|
|
832
|
+
{
|
|
833
|
+
id: "item-1",
|
|
834
|
+
clickedActions: [],
|
|
835
|
+
completeConditions: [{ id: "condition-1", type: "test", operators: "and", data: {} }],
|
|
836
|
+
onlyShowTaskConditions: []
|
|
837
|
+
}
|
|
838
|
+
]
|
|
839
|
+
};
|
|
840
|
+
const result = duplicateChecklistData(data);
|
|
841
|
+
expect(result.items[0].completeConditions[0].id).toBe("regenerated-condition-1");
|
|
842
|
+
});
|
|
843
|
+
test("should regenerate onlyShowTaskConditions IDs", () => {
|
|
844
|
+
const data = {
|
|
845
|
+
items: [
|
|
846
|
+
{
|
|
847
|
+
id: "item-1",
|
|
848
|
+
clickedActions: [],
|
|
849
|
+
completeConditions: [],
|
|
850
|
+
onlyShowTaskConditions: [{ id: "condition-1", type: "test", operators: "and", data: {} }]
|
|
851
|
+
}
|
|
852
|
+
]
|
|
853
|
+
};
|
|
854
|
+
const result = duplicateChecklistData(data);
|
|
855
|
+
expect(result.items[0].onlyShowTaskConditions[0].id).toBe("regenerated-condition-1");
|
|
856
|
+
});
|
|
857
|
+
});
|
|
858
|
+
describe("duplicateConfig", () => {
|
|
859
|
+
test("should return config as-is for null", () => {
|
|
860
|
+
const result = duplicateConfig(null);
|
|
861
|
+
expect(result).toBeNull();
|
|
862
|
+
});
|
|
863
|
+
test("should return config as-is for undefined", () => {
|
|
864
|
+
const result = duplicateConfig(void 0);
|
|
865
|
+
expect(result).toBeUndefined();
|
|
866
|
+
});
|
|
867
|
+
test("should regenerate autoStartRules IDs", () => {
|
|
868
|
+
var _a;
|
|
869
|
+
const config = {
|
|
870
|
+
autoStartRules: [{ id: "rule-1", type: "test", operators: "and", data: {} }]
|
|
871
|
+
};
|
|
872
|
+
const result = duplicateConfig(config);
|
|
873
|
+
expect((_a = result.autoStartRules) == null ? void 0 : _a[0].id).toBe("regenerated-rule-1");
|
|
874
|
+
});
|
|
875
|
+
test("should regenerate hideRules IDs", () => {
|
|
876
|
+
var _a;
|
|
877
|
+
const config = {
|
|
878
|
+
hideRules: [{ id: "rule-1", type: "test", operators: "and", data: {} }]
|
|
879
|
+
};
|
|
880
|
+
const result = duplicateConfig(config);
|
|
881
|
+
expect((_a = result.hideRules) == null ? void 0 : _a[0].id).toBe("regenerated-rule-1");
|
|
882
|
+
});
|
|
883
|
+
test("should handle config without rules", () => {
|
|
884
|
+
const config = {
|
|
885
|
+
someOtherProperty: "value"
|
|
886
|
+
};
|
|
887
|
+
const result = duplicateConfig(config);
|
|
888
|
+
expect(result.autoStartRules).toBeUndefined();
|
|
889
|
+
expect(result.hideRules).toBeUndefined();
|
|
890
|
+
});
|
|
891
|
+
});
|
|
892
|
+
describe("duplicateData", () => {
|
|
893
|
+
test("should process checklist data for CHECKLIST content type", () => {
|
|
894
|
+
const data = {
|
|
895
|
+
items: [
|
|
896
|
+
{
|
|
897
|
+
id: "item-1",
|
|
898
|
+
clickedActions: [],
|
|
899
|
+
completeConditions: [],
|
|
900
|
+
onlyShowTaskConditions: []
|
|
901
|
+
}
|
|
902
|
+
]
|
|
903
|
+
};
|
|
904
|
+
const result = duplicateData(data, import_types4.ContentDataType.CHECKLIST);
|
|
905
|
+
expect(result.items[0].id).toBe("mock-uuid");
|
|
906
|
+
});
|
|
907
|
+
test("should return data as-is for non-CHECKLIST content type", () => {
|
|
908
|
+
const data = { someData: "value" };
|
|
909
|
+
const result = duplicateData(data, "flow");
|
|
910
|
+
expect(result).toEqual(data);
|
|
911
|
+
});
|
|
912
|
+
});
|
|
913
|
+
describe("createStepCopy", () => {
|
|
914
|
+
test("should create a copy of the step with new name", () => {
|
|
915
|
+
const originalStep = {
|
|
916
|
+
id: "step-1",
|
|
917
|
+
cvid: "cvid-1",
|
|
918
|
+
name: "Original Step",
|
|
919
|
+
sequence: 0,
|
|
920
|
+
trigger: [],
|
|
921
|
+
data: [],
|
|
922
|
+
target: void 0,
|
|
923
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
924
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
925
|
+
};
|
|
926
|
+
const result = createStepCopy(originalStep, 1);
|
|
927
|
+
expect(result.name).toBe("Original Step (copy)");
|
|
928
|
+
expect(result.sequence).toBe(1);
|
|
929
|
+
expect(result).not.toHaveProperty("id");
|
|
930
|
+
expect(result).not.toHaveProperty("cvid");
|
|
931
|
+
expect(result).not.toHaveProperty("createdAt");
|
|
932
|
+
expect(result).not.toHaveProperty("updatedAt");
|
|
933
|
+
});
|
|
934
|
+
test("should generate unique name when existing names provided", () => {
|
|
935
|
+
const originalStep = {
|
|
936
|
+
id: "step-1",
|
|
937
|
+
cvid: "cvid-1",
|
|
938
|
+
name: "Step",
|
|
939
|
+
sequence: 0,
|
|
940
|
+
trigger: [],
|
|
941
|
+
data: [],
|
|
942
|
+
target: void 0
|
|
943
|
+
};
|
|
944
|
+
const result = createStepCopy(originalStep, 1, ["Step (copy)"]);
|
|
945
|
+
expect(result.name).toBe("Step (copy 2)");
|
|
946
|
+
});
|
|
947
|
+
test("should process triggers in step copy", () => {
|
|
948
|
+
var _a;
|
|
949
|
+
const originalStep = {
|
|
950
|
+
id: "step-1",
|
|
951
|
+
cvid: "cvid-1",
|
|
952
|
+
name: "Step",
|
|
953
|
+
sequence: 0,
|
|
954
|
+
trigger: [
|
|
955
|
+
{
|
|
956
|
+
id: "trigger-1",
|
|
957
|
+
actions: [{ id: "action-1", type: "test", operators: "and", data: {} }],
|
|
958
|
+
conditions: []
|
|
959
|
+
}
|
|
960
|
+
],
|
|
961
|
+
data: [],
|
|
962
|
+
target: void 0
|
|
963
|
+
};
|
|
964
|
+
const result = createStepCopy(originalStep, 1);
|
|
965
|
+
expect((_a = result.trigger) == null ? void 0 : _a[0].id).toBe("mock-cuid");
|
|
966
|
+
});
|
|
967
|
+
test("should process target in step copy", () => {
|
|
968
|
+
var _a, _b;
|
|
969
|
+
const originalStep = {
|
|
970
|
+
id: "step-1",
|
|
971
|
+
cvid: "cvid-1",
|
|
972
|
+
name: "Step",
|
|
973
|
+
sequence: 0,
|
|
974
|
+
trigger: [],
|
|
975
|
+
data: [],
|
|
976
|
+
target: {
|
|
977
|
+
actions: [{ id: "action-1", type: "test", operators: "and", data: {} }]
|
|
978
|
+
}
|
|
979
|
+
};
|
|
980
|
+
const result = createStepCopy(originalStep, 1);
|
|
981
|
+
expect((_b = (_a = result.target) == null ? void 0 : _a.actions) == null ? void 0 : _b[0].id).toBe("regenerated-action-1");
|
|
982
|
+
});
|
|
983
|
+
test("should handle step without trigger", () => {
|
|
984
|
+
const originalStep = {
|
|
985
|
+
id: "step-1",
|
|
986
|
+
cvid: "cvid-1",
|
|
987
|
+
name: "Step",
|
|
988
|
+
sequence: 0,
|
|
989
|
+
trigger: void 0,
|
|
990
|
+
data: [],
|
|
991
|
+
target: void 0
|
|
992
|
+
};
|
|
993
|
+
const result = createStepCopy(originalStep, 1);
|
|
994
|
+
expect(result.trigger).toEqual([]);
|
|
995
|
+
});
|
|
996
|
+
test("should handle step without data", () => {
|
|
997
|
+
const originalStep = {
|
|
998
|
+
id: "step-1",
|
|
999
|
+
cvid: "cvid-1",
|
|
1000
|
+
name: "Step",
|
|
1001
|
+
sequence: 0,
|
|
1002
|
+
trigger: [],
|
|
1003
|
+
data: void 0,
|
|
1004
|
+
target: void 0
|
|
1005
|
+
};
|
|
1006
|
+
const result = createStepCopy(originalStep, 1);
|
|
1007
|
+
expect(result.data).toEqual([]);
|
|
1008
|
+
});
|
|
1009
|
+
});
|