Files
crewli/apps/portal/tests/composables/useConditionalLogic.test.ts
bert.hausmans b159fdcc26 test(portal): add Vitest setup and public-form tests
Introduces vitest config, jsdom setup, and first suites covering
FieldRenderer dispatch and useConditionalLogic evaluation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 17:21:04 +02:00

95 lines
4.1 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { evaluateConditionalLogic } from '@/composables/useConditionalLogic'
import type { ConditionalLogic } from '@/types/formBuilder'
describe('evaluateConditionalLogic', () => {
it('returns true when logic is null or undefined', () => {
expect(evaluateConditionalLogic(null, {})).toBe(true)
expect(evaluateConditionalLogic(undefined, {})).toBe(true)
expect(evaluateConditionalLogic({}, {})).toBe(true)
})
it('handles simple equals / not_equals', () => {
const logic: ConditionalLogic = {
show_when: { all: [{ field_slug: 'foo', operator: 'equals', value: 'bar' }] },
}
expect(evaluateConditionalLogic(logic, { foo: 'bar' })).toBe(true)
expect(evaluateConditionalLogic(logic, { foo: 'baz' })).toBe(false)
const negative: ConditionalLogic = {
show_when: { all: [{ field_slug: 'foo', operator: 'not_equals', value: 'bar' }] },
}
expect(evaluateConditionalLogic(negative, { foo: 'baz' })).toBe(true)
expect(evaluateConditionalLogic(negative, { foo: 'bar' })).toBe(false)
})
it('handles in / not_in over single and array values', () => {
const logic: ConditionalLogic = {
show_when: { all: [{ field_slug: 'tags', operator: 'in', value: ['a', 'b'] }] },
}
expect(evaluateConditionalLogic(logic, { tags: 'a' })).toBe(true)
expect(evaluateConditionalLogic(logic, { tags: 'c' })).toBe(false)
expect(evaluateConditionalLogic(logic, { tags: ['c', 'a'] })).toBe(true)
const negative: ConditionalLogic = {
show_when: { all: [{ field_slug: 'tags', operator: 'not_in', value: ['a'] }] },
}
expect(evaluateConditionalLogic(negative, { tags: 'a' })).toBe(false)
expect(evaluateConditionalLogic(negative, { tags: ['b', 'c'] })).toBe(true)
})
it('handles empty / not_empty across string, array, null', () => {
const empty: ConditionalLogic = { show_when: { all: [{ field_slug: 'x', operator: 'empty' }] } }
expect(evaluateConditionalLogic(empty, {})).toBe(true)
expect(evaluateConditionalLogic(empty, { x: null })).toBe(true)
expect(evaluateConditionalLogic(empty, { x: '' })).toBe(true)
expect(evaluateConditionalLogic(empty, { x: [] })).toBe(true)
expect(evaluateConditionalLogic(empty, { x: 'hi' })).toBe(false)
const notEmpty: ConditionalLogic = { show_when: { all: [{ field_slug: 'x', operator: 'not_empty' }] } }
expect(evaluateConditionalLogic(notEmpty, { x: 'hi' })).toBe(true)
expect(evaluateConditionalLogic(notEmpty, {})).toBe(false)
})
it('evaluates nested all/any groups', () => {
const logic: ConditionalLogic = {
show_when: {
all: [
{ field_slug: 'role', operator: 'equals', value: 'admin' },
{
any: [
{ field_slug: 'region', operator: 'equals', value: 'NL' },
{ field_slug: 'region', operator: 'equals', value: 'BE' },
],
},
],
},
}
expect(evaluateConditionalLogic(logic, { role: 'admin', region: 'BE' })).toBe(true)
expect(evaluateConditionalLogic(logic, { role: 'admin', region: 'DE' })).toBe(false)
expect(evaluateConditionalLogic(logic, { role: 'guest', region: 'NL' })).toBe(false)
})
it('does not throw on missing field values', () => {
const eq: ConditionalLogic = {
show_when: { all: [{ field_slug: 'missing', operator: 'equals', value: 'x' }] },
}
expect(() => evaluateConditionalLogic(eq, {})).not.toThrow()
expect(evaluateConditionalLogic(eq, {})).toBe(false)
const emptyCheck: ConditionalLogic = {
show_when: { all: [{ field_slug: 'missing', operator: 'empty' }] },
}
expect(evaluateConditionalLogic(emptyCheck, {})).toBe(true)
})
it('handles greater_than / less_than with non-numeric fallback', () => {
const gt: ConditionalLogic = {
show_when: { all: [{ field_slug: 'age', operator: 'greater_than', value: 18 }] },
}
expect(evaluateConditionalLogic(gt, { age: 20 })).toBe(true)
expect(evaluateConditionalLogic(gt, { age: 17 })).toBe(false)
expect(evaluateConditionalLogic(gt, { age: 'not-a-number' })).toBe(false)
})
})