@usertour/helpers 0.0.15 → 0.0.18
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__/attribute.test.cjs +1036 -0
- package/dist/__tests__/attribute.test.d.cts +2 -0
- package/dist/__tests__/attribute.test.d.ts +2 -0
- package/dist/__tests__/attribute.test.js +802 -0
- package/dist/__tests__/condition.test.cjs +257 -0
- package/dist/__tests__/condition.test.d.cts +2 -0
- package/dist/__tests__/condition.test.d.ts +2 -0
- package/dist/__tests__/condition.test.js +204 -0
- package/dist/__tests__/time.test.cjs +73 -0
- package/dist/__tests__/time.test.d.cts +2 -0
- package/dist/__tests__/time.test.d.ts +2 -0
- package/dist/__tests__/time.test.js +48 -0
- package/dist/__tests__/url.test.cjs +259 -0
- package/dist/__tests__/url.test.d.cts +2 -0
- package/dist/__tests__/url.test.d.ts +2 -0
- package/dist/__tests__/url.test.js +197 -0
- package/dist/{chunk-B4DTY6GN.js → chunk-4LLDSAHJ.js} +0 -12
- package/dist/chunk-7ODE2AIC.js +0 -0
- package/dist/{chunk-IZFZYGPU.js → chunk-BC7KXBMF.js} +5 -56
- package/dist/chunk-CEK3SCQO.js +31 -0
- package/dist/chunk-PBZSPV5R.js +239 -0
- package/dist/chunk-YOFQHQ7D.js +92 -0
- package/dist/conditions/attribute.cjs +264 -0
- package/dist/conditions/attribute.d.cts +28 -0
- package/dist/conditions/attribute.d.ts +28 -0
- package/dist/conditions/attribute.js +9 -0
- package/dist/conditions/condition.cjs +129 -0
- package/dist/conditions/condition.d.cts +14 -0
- package/dist/conditions/condition.d.ts +14 -0
- package/dist/conditions/condition.js +13 -0
- package/dist/conditions/index.cjs +379 -0
- package/dist/conditions/index.d.cts +6 -0
- package/dist/conditions/index.d.ts +6 -0
- package/dist/conditions/index.js +24 -0
- package/dist/conditions/time.cjs +55 -0
- package/dist/conditions/time.d.cts +10 -0
- package/dist/conditions/time.d.ts +10 -0
- package/dist/conditions/time.js +7 -0
- package/dist/{conditions.cjs → conditions/url.cjs} +9 -71
- package/dist/conditions/url.d.cts +6 -0
- package/dist/conditions/url.d.ts +6 -0
- package/dist/conditions/url.js +9 -0
- package/dist/content.cjs +0 -13
- package/dist/content.d.cts +1 -2
- package/dist/content.d.ts +1 -2
- package/dist/content.js +1 -3
- package/dist/index.cjs +261 -54
- package/dist/index.d.cts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +19 -8
- package/package.json +15 -9
- package/dist/conditions.d.cts +0 -7
- package/dist/conditions.d.ts +0 -7
- package/dist/conditions.js +0 -11
|
@@ -0,0 +1,802 @@
|
|
|
1
|
+
import {
|
|
2
|
+
evaluateFilterConditions
|
|
3
|
+
} from "../chunk-PBZSPV5R.js";
|
|
4
|
+
import "../chunk-XEO3YXBM.js";
|
|
5
|
+
|
|
6
|
+
// src/__tests__/attribute.test.ts
|
|
7
|
+
import { BizAttributeTypes } from "@usertour/types";
|
|
8
|
+
var testAttributes = [
|
|
9
|
+
{
|
|
10
|
+
id: "email-attr",
|
|
11
|
+
codeName: "email",
|
|
12
|
+
dataType: BizAttributeTypes.String
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: "age-attr",
|
|
16
|
+
codeName: "age",
|
|
17
|
+
dataType: BizAttributeTypes.Number
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: "isPremium-attr",
|
|
21
|
+
codeName: "isPremium",
|
|
22
|
+
dataType: BizAttributeTypes.Boolean
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: "roles-attr",
|
|
26
|
+
codeName: "roles",
|
|
27
|
+
dataType: BizAttributeTypes.List
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: "signUpDate-attr",
|
|
31
|
+
codeName: "signUpDate",
|
|
32
|
+
dataType: BizAttributeTypes.DateTime
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: "score-attr",
|
|
36
|
+
codeName: "score",
|
|
37
|
+
dataType: BizAttributeTypes.Number
|
|
38
|
+
}
|
|
39
|
+
];
|
|
40
|
+
var testUserAttributes = {
|
|
41
|
+
email: "user@example.com",
|
|
42
|
+
age: 25,
|
|
43
|
+
isPremium: true,
|
|
44
|
+
roles: ["admin", "user"],
|
|
45
|
+
signUpDate: "2024-01-15T10:30:00Z",
|
|
46
|
+
score: 85.5
|
|
47
|
+
};
|
|
48
|
+
describe("Attribute Filter - Complete Test Suite", () => {
|
|
49
|
+
describe("String conditions (8 cases)", () => {
|
|
50
|
+
test('should evaluate "is" condition correctly', () => {
|
|
51
|
+
const condition = [
|
|
52
|
+
{
|
|
53
|
+
id: "condition-1",
|
|
54
|
+
type: "condition",
|
|
55
|
+
operators: "and",
|
|
56
|
+
data: {
|
|
57
|
+
logic: "is",
|
|
58
|
+
value: "user@example.com",
|
|
59
|
+
attrId: "email-attr"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
];
|
|
63
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
64
|
+
});
|
|
65
|
+
test('should evaluate "not" condition correctly', () => {
|
|
66
|
+
const condition = [
|
|
67
|
+
{
|
|
68
|
+
id: "condition-2",
|
|
69
|
+
type: "condition",
|
|
70
|
+
operators: "and",
|
|
71
|
+
data: {
|
|
72
|
+
logic: "not",
|
|
73
|
+
value: "other@example.com",
|
|
74
|
+
attrId: "email-attr"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
];
|
|
78
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
79
|
+
});
|
|
80
|
+
test('should evaluate "contains" condition correctly', () => {
|
|
81
|
+
const condition = [
|
|
82
|
+
{
|
|
83
|
+
id: "condition-3",
|
|
84
|
+
type: "condition",
|
|
85
|
+
operators: "and",
|
|
86
|
+
data: {
|
|
87
|
+
logic: "contains",
|
|
88
|
+
value: "example.com",
|
|
89
|
+
attrId: "email-attr"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
];
|
|
93
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
94
|
+
});
|
|
95
|
+
test('should evaluate "notContain" condition correctly', () => {
|
|
96
|
+
const condition = [
|
|
97
|
+
{
|
|
98
|
+
id: "condition-4",
|
|
99
|
+
type: "condition",
|
|
100
|
+
operators: "and",
|
|
101
|
+
data: {
|
|
102
|
+
logic: "notContain",
|
|
103
|
+
value: "gmail.com",
|
|
104
|
+
attrId: "email-attr"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
];
|
|
108
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
109
|
+
});
|
|
110
|
+
test('should evaluate "startsWith" condition correctly', () => {
|
|
111
|
+
const condition = [
|
|
112
|
+
{
|
|
113
|
+
id: "condition-5",
|
|
114
|
+
type: "condition",
|
|
115
|
+
operators: "and",
|
|
116
|
+
data: {
|
|
117
|
+
logic: "startsWith",
|
|
118
|
+
value: "user",
|
|
119
|
+
attrId: "email-attr"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
];
|
|
123
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
124
|
+
});
|
|
125
|
+
test('should evaluate "endsWith" condition correctly', () => {
|
|
126
|
+
const condition = [
|
|
127
|
+
{
|
|
128
|
+
id: "condition-6",
|
|
129
|
+
type: "condition",
|
|
130
|
+
operators: "and",
|
|
131
|
+
data: {
|
|
132
|
+
logic: "endsWith",
|
|
133
|
+
value: "example.com",
|
|
134
|
+
attrId: "email-attr"
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
];
|
|
138
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
139
|
+
});
|
|
140
|
+
test('should evaluate "empty" condition correctly', () => {
|
|
141
|
+
const condition = [
|
|
142
|
+
{
|
|
143
|
+
id: "condition-7",
|
|
144
|
+
type: "condition",
|
|
145
|
+
operators: "and",
|
|
146
|
+
data: {
|
|
147
|
+
logic: "empty",
|
|
148
|
+
attrId: "email-attr"
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
];
|
|
152
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(false);
|
|
153
|
+
});
|
|
154
|
+
test('should evaluate "any" condition correctly', () => {
|
|
155
|
+
const condition = [
|
|
156
|
+
{
|
|
157
|
+
id: "condition-8",
|
|
158
|
+
type: "condition",
|
|
159
|
+
operators: "and",
|
|
160
|
+
data: {
|
|
161
|
+
logic: "any",
|
|
162
|
+
attrId: "email-attr"
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
];
|
|
166
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
describe("Number conditions (9 cases)", () => {
|
|
170
|
+
test('should evaluate "is" condition correctly', () => {
|
|
171
|
+
const condition = [
|
|
172
|
+
{
|
|
173
|
+
id: "condition-9",
|
|
174
|
+
type: "condition",
|
|
175
|
+
operators: "and",
|
|
176
|
+
data: {
|
|
177
|
+
logic: "is",
|
|
178
|
+
value: 25,
|
|
179
|
+
attrId: "age-attr"
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
];
|
|
183
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
184
|
+
});
|
|
185
|
+
test('should evaluate "not" condition correctly', () => {
|
|
186
|
+
const condition = [
|
|
187
|
+
{
|
|
188
|
+
id: "condition-10",
|
|
189
|
+
type: "condition",
|
|
190
|
+
operators: "and",
|
|
191
|
+
data: {
|
|
192
|
+
logic: "not",
|
|
193
|
+
value: 30,
|
|
194
|
+
attrId: "age-attr"
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
];
|
|
198
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
199
|
+
});
|
|
200
|
+
test('should evaluate "isLessThan" condition correctly', () => {
|
|
201
|
+
const condition = [
|
|
202
|
+
{
|
|
203
|
+
id: "condition-11",
|
|
204
|
+
type: "condition",
|
|
205
|
+
operators: "and",
|
|
206
|
+
data: {
|
|
207
|
+
logic: "isLessThan",
|
|
208
|
+
value: 30,
|
|
209
|
+
attrId: "age-attr"
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
];
|
|
213
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
214
|
+
});
|
|
215
|
+
test('should evaluate "isLessThanOrEqualTo" condition correctly', () => {
|
|
216
|
+
const condition = [
|
|
217
|
+
{
|
|
218
|
+
id: "condition-12",
|
|
219
|
+
type: "condition",
|
|
220
|
+
operators: "and",
|
|
221
|
+
data: {
|
|
222
|
+
logic: "isLessThanOrEqualTo",
|
|
223
|
+
value: 25,
|
|
224
|
+
attrId: "age-attr"
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
];
|
|
228
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
229
|
+
});
|
|
230
|
+
test('should evaluate "isGreaterThan" condition correctly', () => {
|
|
231
|
+
const condition = [
|
|
232
|
+
{
|
|
233
|
+
id: "condition-13",
|
|
234
|
+
type: "condition",
|
|
235
|
+
operators: "and",
|
|
236
|
+
data: {
|
|
237
|
+
logic: "isGreaterThan",
|
|
238
|
+
value: 18,
|
|
239
|
+
attrId: "age-attr"
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
];
|
|
243
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
244
|
+
});
|
|
245
|
+
test('should evaluate "isGreaterThanOrEqualTo" condition correctly', () => {
|
|
246
|
+
const condition = [
|
|
247
|
+
{
|
|
248
|
+
id: "condition-14",
|
|
249
|
+
type: "condition",
|
|
250
|
+
operators: "and",
|
|
251
|
+
data: {
|
|
252
|
+
logic: "isGreaterThanOrEqualTo",
|
|
253
|
+
value: 25,
|
|
254
|
+
attrId: "age-attr"
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
];
|
|
258
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
259
|
+
});
|
|
260
|
+
test('should evaluate "between" condition correctly', () => {
|
|
261
|
+
const condition = [
|
|
262
|
+
{
|
|
263
|
+
id: "condition-15",
|
|
264
|
+
type: "condition",
|
|
265
|
+
operators: "and",
|
|
266
|
+
data: {
|
|
267
|
+
logic: "between",
|
|
268
|
+
value: 20,
|
|
269
|
+
value2: 30,
|
|
270
|
+
attrId: "age-attr"
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
];
|
|
274
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
275
|
+
});
|
|
276
|
+
test('should evaluate "empty" condition correctly', () => {
|
|
277
|
+
const condition = [
|
|
278
|
+
{
|
|
279
|
+
id: "condition-16",
|
|
280
|
+
type: "condition",
|
|
281
|
+
operators: "and",
|
|
282
|
+
data: {
|
|
283
|
+
logic: "empty",
|
|
284
|
+
attrId: "age-attr"
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
];
|
|
288
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(false);
|
|
289
|
+
});
|
|
290
|
+
test('should evaluate "any" condition correctly', () => {
|
|
291
|
+
const condition = [
|
|
292
|
+
{
|
|
293
|
+
id: "condition-17",
|
|
294
|
+
type: "condition",
|
|
295
|
+
operators: "and",
|
|
296
|
+
data: {
|
|
297
|
+
logic: "any",
|
|
298
|
+
attrId: "age-attr"
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
];
|
|
302
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
describe("Boolean conditions (4 cases)", () => {
|
|
306
|
+
test('should evaluate "true" condition correctly', () => {
|
|
307
|
+
const condition = [
|
|
308
|
+
{
|
|
309
|
+
id: "condition-18",
|
|
310
|
+
type: "condition",
|
|
311
|
+
operators: "and",
|
|
312
|
+
data: {
|
|
313
|
+
logic: "true",
|
|
314
|
+
attrId: "isPremium-attr"
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
];
|
|
318
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
319
|
+
});
|
|
320
|
+
test('should evaluate "false" condition correctly', () => {
|
|
321
|
+
const condition = [
|
|
322
|
+
{
|
|
323
|
+
id: "condition-19",
|
|
324
|
+
type: "condition",
|
|
325
|
+
operators: "and",
|
|
326
|
+
data: {
|
|
327
|
+
logic: "false",
|
|
328
|
+
attrId: "isPremium-attr"
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
];
|
|
332
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(false);
|
|
333
|
+
});
|
|
334
|
+
test('should evaluate "empty" condition correctly', () => {
|
|
335
|
+
const condition = [
|
|
336
|
+
{
|
|
337
|
+
id: "condition-20",
|
|
338
|
+
type: "condition",
|
|
339
|
+
operators: "and",
|
|
340
|
+
data: {
|
|
341
|
+
logic: "empty",
|
|
342
|
+
attrId: "isPremium-attr"
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
];
|
|
346
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(false);
|
|
347
|
+
});
|
|
348
|
+
test('should evaluate "any" condition correctly', () => {
|
|
349
|
+
const condition = [
|
|
350
|
+
{
|
|
351
|
+
id: "condition-21",
|
|
352
|
+
type: "condition",
|
|
353
|
+
operators: "and",
|
|
354
|
+
data: {
|
|
355
|
+
logic: "any",
|
|
356
|
+
attrId: "isPremium-attr"
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
];
|
|
360
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
describe("List conditions (6 cases)", () => {
|
|
364
|
+
test('should evaluate "includesAtLeastOne" condition correctly', () => {
|
|
365
|
+
const condition = [
|
|
366
|
+
{
|
|
367
|
+
id: "condition-22",
|
|
368
|
+
type: "condition",
|
|
369
|
+
operators: "and",
|
|
370
|
+
data: {
|
|
371
|
+
logic: "includesAtLeastOne",
|
|
372
|
+
listValues: ["admin"],
|
|
373
|
+
attrId: "roles-attr"
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
];
|
|
377
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
378
|
+
});
|
|
379
|
+
test('should evaluate "includesAll" condition correctly', () => {
|
|
380
|
+
const condition = [
|
|
381
|
+
{
|
|
382
|
+
id: "condition-23",
|
|
383
|
+
type: "condition",
|
|
384
|
+
operators: "and",
|
|
385
|
+
data: {
|
|
386
|
+
logic: "includesAll",
|
|
387
|
+
listValues: ["admin", "user"],
|
|
388
|
+
attrId: "roles-attr"
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
];
|
|
392
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
393
|
+
});
|
|
394
|
+
test('should evaluate "notIncludesAtLeastOne" condition correctly', () => {
|
|
395
|
+
const condition = [
|
|
396
|
+
{
|
|
397
|
+
id: "condition-24",
|
|
398
|
+
type: "condition",
|
|
399
|
+
operators: "and",
|
|
400
|
+
data: {
|
|
401
|
+
logic: "notIncludesAtLeastOne",
|
|
402
|
+
listValues: ["guest"],
|
|
403
|
+
attrId: "roles-attr"
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
];
|
|
407
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
408
|
+
});
|
|
409
|
+
test('should evaluate "notIncludesAll" condition correctly', () => {
|
|
410
|
+
const condition = [
|
|
411
|
+
{
|
|
412
|
+
id: "condition-25",
|
|
413
|
+
type: "condition",
|
|
414
|
+
operators: "and",
|
|
415
|
+
data: {
|
|
416
|
+
logic: "notIncludesAll",
|
|
417
|
+
listValues: ["admin", "guest"],
|
|
418
|
+
attrId: "roles-attr"
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
];
|
|
422
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
423
|
+
});
|
|
424
|
+
test('should evaluate "empty" condition correctly', () => {
|
|
425
|
+
const condition = [
|
|
426
|
+
{
|
|
427
|
+
id: "condition-26",
|
|
428
|
+
type: "condition",
|
|
429
|
+
operators: "and",
|
|
430
|
+
data: {
|
|
431
|
+
logic: "empty",
|
|
432
|
+
attrId: "roles-attr"
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
];
|
|
436
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(false);
|
|
437
|
+
});
|
|
438
|
+
test('should evaluate "any" condition correctly', () => {
|
|
439
|
+
const condition = [
|
|
440
|
+
{
|
|
441
|
+
id: "condition-27",
|
|
442
|
+
type: "condition",
|
|
443
|
+
operators: "and",
|
|
444
|
+
data: {
|
|
445
|
+
logic: "any",
|
|
446
|
+
attrId: "roles-attr"
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
];
|
|
450
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
451
|
+
});
|
|
452
|
+
});
|
|
453
|
+
describe("DateTime conditions (8 cases)", () => {
|
|
454
|
+
test('should evaluate "lessThan" condition correctly', () => {
|
|
455
|
+
const condition = [
|
|
456
|
+
{
|
|
457
|
+
id: "condition-28",
|
|
458
|
+
type: "condition",
|
|
459
|
+
operators: "and",
|
|
460
|
+
data: {
|
|
461
|
+
logic: "lessThan",
|
|
462
|
+
value: 600,
|
|
463
|
+
// 600 days ago (signUpDate is 575 days ago, which is < 600, so should be false)
|
|
464
|
+
attrId: "signUpDate-attr"
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
];
|
|
468
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
469
|
+
});
|
|
470
|
+
test('should evaluate "exactly" condition correctly', () => {
|
|
471
|
+
const condition = [
|
|
472
|
+
{
|
|
473
|
+
id: "condition-29",
|
|
474
|
+
type: "condition",
|
|
475
|
+
operators: "and",
|
|
476
|
+
data: {
|
|
477
|
+
logic: "exactly",
|
|
478
|
+
value: 30,
|
|
479
|
+
// 30 days ago
|
|
480
|
+
attrId: "signUpDate-attr"
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
];
|
|
484
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(false);
|
|
485
|
+
});
|
|
486
|
+
test('should evaluate "moreThan" condition correctly', () => {
|
|
487
|
+
const condition = [
|
|
488
|
+
{
|
|
489
|
+
id: "condition-30",
|
|
490
|
+
type: "condition",
|
|
491
|
+
operators: "and",
|
|
492
|
+
data: {
|
|
493
|
+
logic: "moreThan",
|
|
494
|
+
value: 500,
|
|
495
|
+
// 500 days ago (signUpDate is 575 days ago, which is > 500, so should be true)
|
|
496
|
+
attrId: "signUpDate-attr"
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
];
|
|
500
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
501
|
+
});
|
|
502
|
+
test('should evaluate "before" condition correctly', () => {
|
|
503
|
+
const condition = [
|
|
504
|
+
{
|
|
505
|
+
id: "condition-31",
|
|
506
|
+
type: "condition",
|
|
507
|
+
operators: "and",
|
|
508
|
+
data: {
|
|
509
|
+
logic: "before",
|
|
510
|
+
value: "2024-02-01T00:00:00Z",
|
|
511
|
+
attrId: "signUpDate-attr"
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
];
|
|
515
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
516
|
+
});
|
|
517
|
+
test('should evaluate "on" condition correctly', () => {
|
|
518
|
+
const condition = [
|
|
519
|
+
{
|
|
520
|
+
id: "condition-32",
|
|
521
|
+
type: "condition",
|
|
522
|
+
operators: "and",
|
|
523
|
+
data: {
|
|
524
|
+
logic: "on",
|
|
525
|
+
value: "2024-01-15T00:00:00Z",
|
|
526
|
+
attrId: "signUpDate-attr"
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
];
|
|
530
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
531
|
+
});
|
|
532
|
+
test('should evaluate "after" condition correctly', () => {
|
|
533
|
+
const condition = [
|
|
534
|
+
{
|
|
535
|
+
id: "condition-33",
|
|
536
|
+
type: "condition",
|
|
537
|
+
operators: "and",
|
|
538
|
+
data: {
|
|
539
|
+
logic: "after",
|
|
540
|
+
value: "2024-01-01T00:00:00Z",
|
|
541
|
+
attrId: "signUpDate-attr"
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
];
|
|
545
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
546
|
+
});
|
|
547
|
+
test('should evaluate "empty" condition correctly', () => {
|
|
548
|
+
const condition = [
|
|
549
|
+
{
|
|
550
|
+
id: "condition-34",
|
|
551
|
+
type: "condition",
|
|
552
|
+
operators: "and",
|
|
553
|
+
data: {
|
|
554
|
+
logic: "empty",
|
|
555
|
+
attrId: "signUpDate-attr"
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
];
|
|
559
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(false);
|
|
560
|
+
});
|
|
561
|
+
test('should evaluate "any" condition correctly', () => {
|
|
562
|
+
const condition = [
|
|
563
|
+
{
|
|
564
|
+
id: "condition-35",
|
|
565
|
+
type: "condition",
|
|
566
|
+
operators: "and",
|
|
567
|
+
data: {
|
|
568
|
+
logic: "any",
|
|
569
|
+
attrId: "signUpDate-attr"
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
];
|
|
573
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
574
|
+
});
|
|
575
|
+
});
|
|
576
|
+
describe("Complex conditions with AND/OR logic", () => {
|
|
577
|
+
test("should evaluate AND condition correctly", () => {
|
|
578
|
+
const condition = [
|
|
579
|
+
{
|
|
580
|
+
id: "condition-36",
|
|
581
|
+
type: "group",
|
|
582
|
+
operators: "and",
|
|
583
|
+
data: {},
|
|
584
|
+
conditions: [
|
|
585
|
+
{
|
|
586
|
+
id: "condition-36-1",
|
|
587
|
+
type: "condition",
|
|
588
|
+
operators: "and",
|
|
589
|
+
data: {
|
|
590
|
+
logic: "contains",
|
|
591
|
+
value: "example.com",
|
|
592
|
+
attrId: "email-attr"
|
|
593
|
+
}
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
id: "condition-36-2",
|
|
597
|
+
type: "condition",
|
|
598
|
+
operators: "and",
|
|
599
|
+
data: {
|
|
600
|
+
logic: "isGreaterThan",
|
|
601
|
+
value: 18,
|
|
602
|
+
attrId: "age-attr"
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
]
|
|
606
|
+
}
|
|
607
|
+
];
|
|
608
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
609
|
+
});
|
|
610
|
+
test("should evaluate OR condition correctly", () => {
|
|
611
|
+
const condition = [
|
|
612
|
+
{
|
|
613
|
+
id: "condition-37",
|
|
614
|
+
type: "group",
|
|
615
|
+
operators: "or",
|
|
616
|
+
data: {},
|
|
617
|
+
conditions: [
|
|
618
|
+
{
|
|
619
|
+
id: "condition-37-1",
|
|
620
|
+
type: "condition",
|
|
621
|
+
operators: "or",
|
|
622
|
+
data: {
|
|
623
|
+
logic: "is",
|
|
624
|
+
value: "wrong@email.com",
|
|
625
|
+
attrId: "email-attr"
|
|
626
|
+
}
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
id: "condition-37-2",
|
|
630
|
+
type: "condition",
|
|
631
|
+
operators: "or",
|
|
632
|
+
data: {
|
|
633
|
+
logic: "isGreaterThan",
|
|
634
|
+
value: 18,
|
|
635
|
+
attrId: "age-attr"
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
]
|
|
639
|
+
}
|
|
640
|
+
];
|
|
641
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
642
|
+
});
|
|
643
|
+
test("should evaluate mixed AND/OR condition correctly", () => {
|
|
644
|
+
const condition = [
|
|
645
|
+
{
|
|
646
|
+
id: "condition-38",
|
|
647
|
+
type: "group",
|
|
648
|
+
operators: "and",
|
|
649
|
+
data: {},
|
|
650
|
+
conditions: [
|
|
651
|
+
{
|
|
652
|
+
id: "condition-38-1",
|
|
653
|
+
type: "condition",
|
|
654
|
+
operators: "and",
|
|
655
|
+
data: {
|
|
656
|
+
logic: "contains",
|
|
657
|
+
value: "example.com",
|
|
658
|
+
attrId: "email-attr"
|
|
659
|
+
}
|
|
660
|
+
},
|
|
661
|
+
{
|
|
662
|
+
id: "condition-38-2",
|
|
663
|
+
type: "group",
|
|
664
|
+
operators: "or",
|
|
665
|
+
data: {},
|
|
666
|
+
conditions: [
|
|
667
|
+
{
|
|
668
|
+
id: "condition-38-2-1",
|
|
669
|
+
type: "condition",
|
|
670
|
+
operators: "or",
|
|
671
|
+
data: {
|
|
672
|
+
logic: "is",
|
|
673
|
+
value: "wrong@email.com",
|
|
674
|
+
attrId: "email-attr"
|
|
675
|
+
}
|
|
676
|
+
},
|
|
677
|
+
{
|
|
678
|
+
id: "condition-38-2-2",
|
|
679
|
+
type: "condition",
|
|
680
|
+
operators: "or",
|
|
681
|
+
data: {
|
|
682
|
+
logic: "isGreaterThan",
|
|
683
|
+
value: 18,
|
|
684
|
+
attrId: "age-attr"
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
]
|
|
688
|
+
}
|
|
689
|
+
]
|
|
690
|
+
}
|
|
691
|
+
];
|
|
692
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(true);
|
|
693
|
+
});
|
|
694
|
+
});
|
|
695
|
+
describe("Edge cases and error handling", () => {
|
|
696
|
+
test("should handle empty conditions array", () => {
|
|
697
|
+
expect(evaluateFilterConditions([], testAttributes, testUserAttributes)).toBe(true);
|
|
698
|
+
});
|
|
699
|
+
test("should handle null/undefined conditions", () => {
|
|
700
|
+
expect(evaluateFilterConditions(null, testAttributes, testUserAttributes)).toBe(true);
|
|
701
|
+
});
|
|
702
|
+
test("should handle missing attribute", () => {
|
|
703
|
+
const condition = [
|
|
704
|
+
{
|
|
705
|
+
id: "condition-39",
|
|
706
|
+
type: "condition",
|
|
707
|
+
operators: "and",
|
|
708
|
+
data: {
|
|
709
|
+
logic: "is",
|
|
710
|
+
value: "test",
|
|
711
|
+
attrId: "non-existent-attr"
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
];
|
|
715
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(false);
|
|
716
|
+
});
|
|
717
|
+
test("should handle missing user attribute value", () => {
|
|
718
|
+
const userAttributesWithoutEmail = {
|
|
719
|
+
age: 25,
|
|
720
|
+
isPremium: true
|
|
721
|
+
};
|
|
722
|
+
const condition = [
|
|
723
|
+
{
|
|
724
|
+
id: "condition-40",
|
|
725
|
+
type: "condition",
|
|
726
|
+
operators: "and",
|
|
727
|
+
data: {
|
|
728
|
+
logic: "is",
|
|
729
|
+
value: "test@example.com",
|
|
730
|
+
attrId: "email-attr"
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
];
|
|
734
|
+
expect(evaluateFilterConditions(condition, testAttributes, userAttributesWithoutEmail)).toBe(
|
|
735
|
+
false
|
|
736
|
+
);
|
|
737
|
+
});
|
|
738
|
+
test("should handle invalid data type", () => {
|
|
739
|
+
const invalidAttribute = [
|
|
740
|
+
{
|
|
741
|
+
id: "invalid-attr",
|
|
742
|
+
codeName: "invalid",
|
|
743
|
+
dataType: 999
|
|
744
|
+
// Invalid data type
|
|
745
|
+
}
|
|
746
|
+
];
|
|
747
|
+
const condition = [
|
|
748
|
+
{
|
|
749
|
+
id: "condition-41",
|
|
750
|
+
type: "condition",
|
|
751
|
+
operators: "and",
|
|
752
|
+
data: {
|
|
753
|
+
logic: "is",
|
|
754
|
+
value: "test",
|
|
755
|
+
attrId: "invalid-attr"
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
];
|
|
759
|
+
expect(evaluateFilterConditions(condition, invalidAttribute, testUserAttributes)).toBe(false);
|
|
760
|
+
});
|
|
761
|
+
test("should handle invalid logic", () => {
|
|
762
|
+
const condition = [
|
|
763
|
+
{
|
|
764
|
+
id: "condition-42",
|
|
765
|
+
type: "condition",
|
|
766
|
+
operators: "and",
|
|
767
|
+
data: {
|
|
768
|
+
logic: "invalidLogic",
|
|
769
|
+
value: "test",
|
|
770
|
+
attrId: "email-attr"
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
];
|
|
774
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(false);
|
|
775
|
+
});
|
|
776
|
+
test("should handle missing data in condition", () => {
|
|
777
|
+
const condition = [
|
|
778
|
+
{
|
|
779
|
+
id: "condition-43",
|
|
780
|
+
type: "condition",
|
|
781
|
+
operators: "and",
|
|
782
|
+
data: void 0
|
|
783
|
+
}
|
|
784
|
+
];
|
|
785
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(false);
|
|
786
|
+
});
|
|
787
|
+
test("should handle missing attrId in condition", () => {
|
|
788
|
+
const condition = [
|
|
789
|
+
{
|
|
790
|
+
id: "condition-44",
|
|
791
|
+
type: "condition",
|
|
792
|
+
operators: "and",
|
|
793
|
+
data: {
|
|
794
|
+
logic: "is",
|
|
795
|
+
value: "test"
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
];
|
|
799
|
+
expect(evaluateFilterConditions(condition, testAttributes, testUserAttributes)).toBe(false);
|
|
800
|
+
});
|
|
801
|
+
});
|
|
802
|
+
});
|