feat(frontend): Add useSectionSpawning test
This commit is contained in:
464
legalconsenthub/test/unit/composables/useSectionSpawning.spec.ts
Normal file
464
legalconsenthub/test/unit/composables/useSectionSpawning.spec.ts
Normal file
@@ -0,0 +1,464 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { useSectionSpawning } from '../../../app/composables/useSectionSpawning'
|
||||
import type {
|
||||
FormElementSectionDto,
|
||||
FormElementSubSectionDto,
|
||||
FormElementDto,
|
||||
FormOptionDto,
|
||||
SectionSpawnTriggerDto,
|
||||
FormElementType
|
||||
} from '../../../.api-client'
|
||||
|
||||
// Helper to create a FormOptionDto
|
||||
function createOption(value: string, label: string): FormOptionDto {
|
||||
return {
|
||||
value,
|
||||
label,
|
||||
processingPurpose: 'NONE',
|
||||
employeeDataCategory: 'NONE'
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to create a FormElementDto
|
||||
function createFormElement(
|
||||
reference: string,
|
||||
title: string,
|
||||
type: FormElementType,
|
||||
options: FormOptionDto[] = [],
|
||||
sectionSpawnTriggers: SectionSpawnTriggerDto[] = []
|
||||
): FormElementDto {
|
||||
return {
|
||||
id: `id-${reference}`,
|
||||
reference,
|
||||
title,
|
||||
type,
|
||||
options,
|
||||
sectionSpawnTriggers
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to create a SectionSpawnTriggerDto
|
||||
function createSpawnTrigger(
|
||||
templateReference: string,
|
||||
conditionType: 'SHOW' | 'HIDE' = 'SHOW',
|
||||
expectedValue: string = 'true',
|
||||
operator: 'EQUALS' | 'NOT_EQUALS' | 'IS_EMPTY' | 'IS_NOT_EMPTY' | 'CONTAINS' | 'NOT_CONTAINS' = 'EQUALS'
|
||||
): SectionSpawnTriggerDto {
|
||||
return {
|
||||
templateReference,
|
||||
sectionSpawnConditionType: conditionType,
|
||||
sectionSpawnExpectedValue: expectedValue,
|
||||
sectionSpawnOperator: operator
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to create a template section with title interpolation
|
||||
function createTemplateSection(
|
||||
templateReference: string,
|
||||
title: string,
|
||||
titleTemplate?: string,
|
||||
shortTitle?: string,
|
||||
description?: string,
|
||||
formElementSubSections: FormElementSubSectionDto[] = []
|
||||
): FormElementSectionDto {
|
||||
return {
|
||||
id: `template-${templateReference}`,
|
||||
title,
|
||||
shortTitle,
|
||||
description,
|
||||
titleTemplate,
|
||||
isTemplate: true,
|
||||
templateReference,
|
||||
formElementSubSections
|
||||
}
|
||||
}
|
||||
|
||||
describe('useSectionSpawning', () => {
|
||||
it('should remove spawned section when condition no longer met', () => {
|
||||
const { processSpawnTriggers } = useSectionSpawning()
|
||||
|
||||
const templateSection = createTemplateSection('template-1', 'Template Section')
|
||||
const spawnedSection: FormElementSectionDto = {
|
||||
id: 'spawned-1',
|
||||
title: 'Spawned Section',
|
||||
isTemplate: false,
|
||||
spawnedFromElementReference: 'trigger_1',
|
||||
templateReference: 'template-1',
|
||||
formElementSubSections: []
|
||||
}
|
||||
|
||||
const trigger = createSpawnTrigger('template-1', 'SHOW', 'true', 'EQUALS')
|
||||
const triggerElement = createFormElement(
|
||||
'trigger_1',
|
||||
'Trigger',
|
||||
'SELECT',
|
||||
[createOption('true', 'No'), createOption('false', 'Yes')],
|
||||
[trigger]
|
||||
)
|
||||
|
||||
const sections = [templateSection, spawnedSection]
|
||||
const result = processSpawnTriggers(sections, [triggerElement])
|
||||
|
||||
expect(result).toHaveLength(1)
|
||||
expect(result[0]!.isTemplate).toBe(true)
|
||||
})
|
||||
|
||||
it('should NOT remove spawned section if another trigger for same template still satisfies condition', () => {
|
||||
const { processSpawnTriggers } = useSectionSpawning()
|
||||
|
||||
const templateSection = createTemplateSection('template-1', 'Template Section')
|
||||
const spawnedSection: FormElementSectionDto = {
|
||||
id: 'spawned-1',
|
||||
title: 'Spawned Section',
|
||||
isTemplate: false,
|
||||
spawnedFromElementReference: 'trigger_1',
|
||||
templateReference: 'template-1',
|
||||
formElementSubSections: []
|
||||
}
|
||||
|
||||
const trigger1 = createSpawnTrigger('template-1', 'SHOW', 'true', 'EQUALS')
|
||||
const trigger2 = createSpawnTrigger('template-1', 'SHOW', 'maybe', 'EQUALS')
|
||||
const triggerElement = createFormElement(
|
||||
'trigger_1',
|
||||
'Trigger',
|
||||
'SELECT',
|
||||
[createOption('false', 'No'), createOption('false', 'Yes'), createOption('true', 'Maybe')],
|
||||
[trigger1, trigger2]
|
||||
)
|
||||
|
||||
const sections = [templateSection, spawnedSection]
|
||||
const result = processSpawnTriggers(sections, [triggerElement])
|
||||
|
||||
expect(result).toHaveLength(2)
|
||||
expect(result[1]!.spawnedFromElementReference).toBe('trigger_1')
|
||||
})
|
||||
|
||||
it('should update titles with {{triggerValue}} interpolation when value changes', () => {
|
||||
const { processSpawnTriggers } = useSectionSpawning()
|
||||
|
||||
const templateSection = createTemplateSection(
|
||||
'template-1',
|
||||
'Section title',
|
||||
'Section template title {{triggerValue}}',
|
||||
'Short title {{triggerValue}}',
|
||||
'Description {{triggerValue}}'
|
||||
)
|
||||
const spawnedSection: FormElementSectionDto = {
|
||||
id: 'spawned-1',
|
||||
title: 'Section OldValue',
|
||||
shortTitle: 'Short OldValue',
|
||||
description: 'Description OldValue',
|
||||
isTemplate: false,
|
||||
spawnedFromElementReference: 'trigger_1',
|
||||
templateReference: 'template-1',
|
||||
formElementSubSections: []
|
||||
}
|
||||
|
||||
const trigger = createSpawnTrigger('template-1', 'SHOW', 'yes', 'EQUALS')
|
||||
const triggerElement = createFormElement(
|
||||
'trigger_1',
|
||||
'Trigger',
|
||||
'SELECT',
|
||||
[createOption('false', 'No'), createOption('true', 'Yes')],
|
||||
[trigger]
|
||||
)
|
||||
|
||||
const sections = [templateSection, spawnedSection]
|
||||
const result = processSpawnTriggers(sections, [triggerElement])
|
||||
|
||||
expect(result[1]!.title).toBe('Section template title Yes')
|
||||
expect(result[1]!.shortTitle).toBe('Short title Yes')
|
||||
expect(result[1]!.description).toBe('Description Yes')
|
||||
})
|
||||
|
||||
it('should insert spawned section after template section', () => {
|
||||
const { processSpawnTriggers } = useSectionSpawning()
|
||||
|
||||
const templateSection = createTemplateSection('template-1', 'Template Section')
|
||||
const otherSection: FormElementSectionDto = {
|
||||
id: 'other-1',
|
||||
title: 'Other Section',
|
||||
isTemplate: false,
|
||||
formElementSubSections: []
|
||||
}
|
||||
|
||||
const trigger = createSpawnTrigger('template-1', 'SHOW', 'Yes', 'EQUALS')
|
||||
const triggerElement = createFormElement(
|
||||
'trigger_1',
|
||||
'Trigger',
|
||||
'SELECT',
|
||||
[createOption('false', 'No'), createOption('true', 'Yes')],
|
||||
[trigger]
|
||||
)
|
||||
|
||||
const sections = [templateSection, otherSection]
|
||||
const result = processSpawnTriggers(sections, [triggerElement])
|
||||
|
||||
expect(result).toHaveLength(3)
|
||||
expect(result[0]!.isTemplate).toBe(true)
|
||||
expect(result[1]!.spawnedFromElementReference).toBe('trigger_1')
|
||||
expect(result[2]!.id).toBe('other-1')
|
||||
})
|
||||
|
||||
it('should handle TEXTFIELD element value extraction', () => {
|
||||
const { processSpawnTriggers } = useSectionSpawning()
|
||||
|
||||
const templateSection = createTemplateSection('template-1', 'Section {{triggerValue}}', 'Section {{triggerValue}}')
|
||||
const trigger = createSpawnTrigger('template-1', 'SHOW', 'john', 'EQUALS')
|
||||
const triggerElement = createFormElement('trigger_1', 'Name', 'TEXTFIELD', [createOption('john', '')], [trigger])
|
||||
|
||||
const sections = [templateSection]
|
||||
const result = processSpawnTriggers(sections, [triggerElement])
|
||||
|
||||
expect(result).toHaveLength(2)
|
||||
expect(result[1]!.title).toBe('Section john')
|
||||
})
|
||||
|
||||
it('should interpolate shortTitle with {{triggerValue}}', () => {
|
||||
const { processSpawnTriggers } = useSectionSpawning()
|
||||
|
||||
const templateSection = createTemplateSection('template-1', 'Template', undefined, 'Short {{triggerValue}}')
|
||||
const spawnedSection: FormElementSectionDto = {
|
||||
id: 'spawned-1',
|
||||
title: 'Spawned',
|
||||
shortTitle: 'Short OldValue',
|
||||
isTemplate: false,
|
||||
spawnedFromElementReference: 'trigger_1',
|
||||
templateReference: 'template-1',
|
||||
formElementSubSections: []
|
||||
}
|
||||
|
||||
const trigger = createSpawnTrigger('template-1', 'SHOW', 'yes', 'EQUALS')
|
||||
const triggerElement = createFormElement(
|
||||
'trigger_1',
|
||||
'Trigger',
|
||||
'SELECT',
|
||||
[createOption('false', 'No'), createOption('true', 'Yes')],
|
||||
[trigger]
|
||||
)
|
||||
|
||||
const sections = [templateSection, spawnedSection]
|
||||
const result = processSpawnTriggers(sections, [triggerElement])
|
||||
|
||||
expect(result[1]!.shortTitle).toBe('Short Yes')
|
||||
})
|
||||
|
||||
it('should interpolate description with {{triggerValue}}', () => {
|
||||
const { processSpawnTriggers } = useSectionSpawning()
|
||||
|
||||
const templateSection = createTemplateSection(
|
||||
'template-1',
|
||||
'Template',
|
||||
undefined,
|
||||
undefined,
|
||||
'Description {{triggerValue}}'
|
||||
)
|
||||
const spawnedSection: FormElementSectionDto = {
|
||||
id: 'spawned-1',
|
||||
title: 'Spawned',
|
||||
description: 'Description OldValue',
|
||||
isTemplate: false,
|
||||
spawnedFromElementReference: 'trigger_1',
|
||||
templateReference: 'template-1',
|
||||
formElementSubSections: []
|
||||
}
|
||||
|
||||
const trigger = createSpawnTrigger('template-1', 'SHOW', 'yes', 'EQUALS')
|
||||
const triggerElement = createFormElement(
|
||||
'trigger_1',
|
||||
'Trigger',
|
||||
'SELECT',
|
||||
[createOption('false', 'No'), createOption('true', 'Yes')],
|
||||
[trigger]
|
||||
)
|
||||
|
||||
const sections = [templateSection, spawnedSection]
|
||||
const result = processSpawnTriggers(sections, [triggerElement])
|
||||
|
||||
expect(result[1]!.description).toBe('Description Yes')
|
||||
})
|
||||
|
||||
it('should preserve non-triggering elements during processing', () => {
|
||||
const { processSpawnTriggers } = useSectionSpawning()
|
||||
|
||||
const templateSection = createTemplateSection('template-1', 'Template')
|
||||
const nonTriggerElement = createFormElement('other_1', 'Other', 'TEXTFIELD', [createOption('value', '')])
|
||||
|
||||
const trigger = createSpawnTrigger('template-1', 'SHOW', 'Yes', 'EQUALS')
|
||||
const triggerElement = createFormElement(
|
||||
'trigger_1',
|
||||
'Trigger',
|
||||
'SELECT',
|
||||
[createOption('false', 'No'), createOption('true', 'Yes')],
|
||||
[trigger]
|
||||
)
|
||||
|
||||
const sections = [templateSection]
|
||||
const result = processSpawnTriggers(sections, [triggerElement, nonTriggerElement])
|
||||
|
||||
expect(result).toHaveLength(2)
|
||||
expect(result[1]!.spawnedFromElementReference).toBe('trigger_1')
|
||||
})
|
||||
|
||||
it('should handle empty trigger list on element', () => {
|
||||
const { processSpawnTriggers } = useSectionSpawning()
|
||||
|
||||
const templateSection = createTemplateSection('template-1', 'Template')
|
||||
const triggerElement = createFormElement(
|
||||
'trigger_1',
|
||||
'Trigger',
|
||||
'SELECT',
|
||||
[createOption('false', 'No'), createOption('true', 'Yes')],
|
||||
[]
|
||||
)
|
||||
|
||||
const sections = [templateSection]
|
||||
const result = processSpawnTriggers(sections, [triggerElement])
|
||||
|
||||
expect(result).toHaveLength(1)
|
||||
})
|
||||
|
||||
describe('operators', () => {
|
||||
describe('EQUALS', () => {
|
||||
it('should spawn section when SHOW/EQUALS condition is met with SELECT element', () => {
|
||||
const { processSpawnTriggers } = useSectionSpawning()
|
||||
|
||||
const templateSection = createTemplateSection('template-1', 'Template Section', 'Section Title Template')
|
||||
const trigger = createSpawnTrigger('template-1', 'SHOW', 'Yes', 'EQUALS')
|
||||
const triggerElement = createFormElement(
|
||||
'trigger_1',
|
||||
'Trigger',
|
||||
'SELECT',
|
||||
[createOption('false', 'No'), createOption('true', 'Yes')],
|
||||
[trigger]
|
||||
)
|
||||
|
||||
const result = processSpawnTriggers([templateSection], [triggerElement])
|
||||
|
||||
expect(result).toHaveLength(2)
|
||||
expect(result[1]!.spawnedFromElementReference).toBe('trigger_1')
|
||||
expect(result[1]!.templateReference).toBe('template-1')
|
||||
expect(result[1]!.title).toBe('Section Title Template')
|
||||
})
|
||||
|
||||
it('should NOT spawn section when SHOW/EQUALS condition is NOT met', () => {
|
||||
const { processSpawnTriggers } = useSectionSpawning()
|
||||
|
||||
const templateSection = createTemplateSection('template-1', 'Template Section')
|
||||
const trigger = createSpawnTrigger('template-1', 'SHOW', 'Yes', 'EQUALS')
|
||||
const triggerElement = createFormElement(
|
||||
'trigger_1',
|
||||
'Trigger',
|
||||
'SELECT',
|
||||
[createOption('true', 'No'), createOption('false', 'Yes')],
|
||||
[trigger]
|
||||
)
|
||||
|
||||
const sections = [templateSection]
|
||||
const result = processSpawnTriggers(sections, [triggerElement])
|
||||
|
||||
expect(result).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('should handle case-insensitive comparison for EQUALS operator', () => {
|
||||
const { processSpawnTriggers } = useSectionSpawning()
|
||||
|
||||
const templateSection = createTemplateSection('template-1', 'Template')
|
||||
const trigger = createSpawnTrigger('template-1', 'SHOW', 'YES', 'EQUALS')
|
||||
const triggerElement = createFormElement(
|
||||
'trigger_1',
|
||||
'Trigger',
|
||||
'SELECT',
|
||||
[createOption('false', 'No'), createOption('true', 'yes')],
|
||||
[trigger]
|
||||
)
|
||||
|
||||
const sections = [templateSection]
|
||||
const result = processSpawnTriggers(sections, [triggerElement])
|
||||
|
||||
expect(result).toHaveLength(2)
|
||||
})
|
||||
})
|
||||
|
||||
describe('NOT_EQUALS', () => {
|
||||
it('should handle NOT_EQUALS operator', () => {
|
||||
const { processSpawnTriggers } = useSectionSpawning()
|
||||
|
||||
const templateSection = createTemplateSection('template-1', 'Template')
|
||||
const trigger = createSpawnTrigger('template-1', 'SHOW', 'Yes', 'NOT_EQUALS')
|
||||
const triggerElement = createFormElement(
|
||||
'trigger_1',
|
||||
'Trigger',
|
||||
'SELECT',
|
||||
[createOption('true', 'No'), createOption('false', 'Yes')],
|
||||
[trigger]
|
||||
)
|
||||
|
||||
const sections = [templateSection]
|
||||
const result = processSpawnTriggers(sections, [triggerElement])
|
||||
|
||||
expect(result).toHaveLength(2)
|
||||
expect(result[1]!.spawnedFromElementReference).toBe('trigger_1')
|
||||
})
|
||||
})
|
||||
|
||||
describe('IS_EMPTY', () => {
|
||||
it('should handle IS_EMPTY operator', () => {
|
||||
const { processSpawnTriggers } = useSectionSpawning()
|
||||
|
||||
const templateSection = createTemplateSection('template-1', 'Template Section')
|
||||
const trigger = createSpawnTrigger('template-1', 'SHOW', 'PLACEHOLDER', 'IS_EMPTY')
|
||||
const triggerElement = createFormElement('trigger_1', 'Trigger', 'TEXTFIELD', [createOption('', '')], [trigger])
|
||||
|
||||
const sections = [templateSection]
|
||||
const result = processSpawnTriggers(sections, [triggerElement])
|
||||
|
||||
expect(result).toHaveLength(2)
|
||||
expect(result[1]!.spawnedFromElementReference).toBe('trigger_1')
|
||||
})
|
||||
})
|
||||
|
||||
describe('IS_NOT_EMPTY', () => {
|
||||
it('should handle IS_NOT_EMPTY operator', () => {
|
||||
const { processSpawnTriggers } = useSectionSpawning()
|
||||
|
||||
const templateSection = createTemplateSection('template-1', 'Template Section')
|
||||
const trigger = createSpawnTrigger('template-1', 'SHOW', 'PLACEHOLDER', 'IS_NOT_EMPTY')
|
||||
const triggerElement = createFormElement(
|
||||
'trigger_1',
|
||||
'Trigger',
|
||||
'TEXTFIELD',
|
||||
[createOption('some value', '')],
|
||||
[trigger]
|
||||
)
|
||||
|
||||
const sections = [templateSection]
|
||||
const result = processSpawnTriggers(sections, [triggerElement])
|
||||
|
||||
expect(result).toHaveLength(2)
|
||||
expect(result[1]!.spawnedFromElementReference).toBe('trigger_1')
|
||||
})
|
||||
})
|
||||
|
||||
describe('HIDE', () => {
|
||||
it('should handle HIDE condition type', () => {
|
||||
const { processSpawnTriggers } = useSectionSpawning()
|
||||
|
||||
const templateSection = createTemplateSection('template-1', 'Template Section')
|
||||
const trigger = createSpawnTrigger('template-1', 'HIDE', 'No', 'EQUALS')
|
||||
const triggerElement = createFormElement(
|
||||
'trigger_1',
|
||||
'Trigger',
|
||||
'SELECT',
|
||||
[createOption('true', 'No'), createOption('false', 'Yes')],
|
||||
[trigger]
|
||||
)
|
||||
|
||||
const sections = [templateSection]
|
||||
const result = processSpawnTriggers(sections, [triggerElement])
|
||||
|
||||
expect(result).toHaveLength(1)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user