Skip to content

Commit e2ea831

Browse files
Add more unit tests to cover differences between jsonpath and jsonpath-plus
1 parent 07afa39 commit e2ea831

1 file changed

Lines changed: 67 additions & 1 deletion

File tree

tests/engine/unit/segments/segment_evaluators.test.ts

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,71 @@ describe('getIdentitySegments single segment evaluation', () => {
345345
});
346346
});
347347

348+
describe('traitsMatchSegmentCondition with $.identity.traits.* properties', () => {
349+
const mockContext: EvaluationContext = {
350+
environment: { key: 'env', name: 'test' },
351+
identity: {
352+
key: 'user',
353+
identifier: 'user@example.com',
354+
traits: {
355+
age: 25,
356+
tamaño: 'grande',
357+
サイズ: 'medium',
358+
'[$the.size$]': 'small'
359+
}
360+
},
361+
segments: {},
362+
features: {}
363+
};
364+
365+
test.each([
366+
// dot notation – normal trait name
367+
[{ property: '$.identity.traits.age', operator: 'EQUAL', value: '25' }, true],
368+
[{ property: '$.identity.traits.age', operator: 'EQUAL', value: '30' }, false],
369+
// dot notation – unicode trait name
370+
[{ property: '$.identity.traits.tamaño', operator: 'EQUAL', value: 'grande' }, true],
371+
[{ property: '$.identity.traits.サイズ', operator: 'EQUAL', value: 'medium' }, true],
372+
// bracket notation – special characters in trait name that break jsonpath-plus
373+
[
374+
{ property: "$.identity.traits['[$the.size$]']", operator: 'EQUAL', value: 'small' },
375+
true
376+
],
377+
[
378+
{ property: "$.identity.traits['[$the.size$]']", operator: 'EQUAL', value: 'large' },
379+
false
380+
],
381+
// non-existent trait
382+
[{ property: '$.identity.traits.nonexistent', operator: 'EQUAL', value: 'any' }, false],
383+
// IS_SET / IS_NOT_SET
384+
[{ property: '$.identity.traits.age', operator: 'IS_SET', value: null }, true],
385+
[{ property: '$.identity.traits.nonexistent', operator: 'IS_SET', value: null }, false],
386+
[{ property: '$.identity.traits.nonexistent', operator: 'IS_NOT_SET', value: null }, true],
387+
[{ property: '$.identity.traits.age', operator: 'IS_NOT_SET', value: null }, false],
388+
// IN operator
389+
[
390+
{
391+
property: '$.identity.traits.tamaño',
392+
operator: CONDITION_OPERATORS.IN,
393+
value: ['grande', 'pequeño']
394+
},
395+
true
396+
],
397+
[
398+
{
399+
property: '$.identity.traits.tamaño',
400+
operator: CONDITION_OPERATORS.IN,
401+
value: ['pequeño']
402+
},
403+
false
404+
]
405+
] as Array<[SegmentCondition | InSegmentCondition, boolean]>)(
406+
'evaluates %j to %s',
407+
(condition, expected) => {
408+
expect(traitsMatchSegmentCondition(condition, 'seg', mockContext)).toBe(expected);
409+
}
410+
);
411+
});
412+
348413
describe('getContextValue', () => {
349414
const mockContext: EvaluationContext = {
350415
environment: {
@@ -354,6 +419,7 @@ describe('getContextValue', () => {
354419
identity: {
355420
key: 'user-123',
356421
identifier: 'user@example.com'
422+
// intentionally no traits – tests below confirm paths that require traits return undefined
357423
},
358424
segments: {},
359425
features: {}
@@ -371,7 +437,7 @@ describe('getContextValue', () => {
371437

372438
// Undefined or invalid cases
373439
test.each([
374-
['$.identity.traits.user_type', 'unsupported nested path'],
440+
['$.identity.traits.user_type', 'no traits in context'],
375441
['identity.identifier', 'missing $ prefix'],
376442
['$.invalid.path', 'completely invalid path'],
377443
['$.identity.nonexistent', 'valid structure but missing property'],

0 commit comments

Comments
 (0)