feat(frontend): Add useFormStepper test
This commit is contained in:
237
legalconsenthub/test/unit/composables/useFormStepper.spec.ts
Normal file
237
legalconsenthub/test/unit/composables/useFormStepper.spec.ts
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||||
|
import type { FormElementSectionDto } from '../../../.api-client'
|
||||||
|
import { useFormStepper } from '../../../app/composables/useFormStepper'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
describe('useFormStepper', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('visibleSections', () => {
|
||||||
|
it('should skip only template sections and keep non-template sections', () => {
|
||||||
|
const sections: FormElementSectionDto[] = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
title: 'Normal Section',
|
||||||
|
shortTitle: 'Normal',
|
||||||
|
description: 'A normal section',
|
||||||
|
isTemplate: false,
|
||||||
|
formElementSubSections: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
title: 'Template Section',
|
||||||
|
shortTitle: 'Tmpl',
|
||||||
|
description: 'A template section',
|
||||||
|
isTemplate: true,
|
||||||
|
formElementSubSections: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const composable = useFormStepper(sections)
|
||||||
|
const stepperItems = composable.stepperItems.value
|
||||||
|
|
||||||
|
expect(stepperItems).toHaveLength(1)
|
||||||
|
expect(stepperItems[0]?.title).toBe('Normal')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('stepperItems', () => {
|
||||||
|
it('should be empty when no sections provided', () => {
|
||||||
|
const composable = useFormStepper([])
|
||||||
|
const stepperItems = composable.stepperItems.value
|
||||||
|
|
||||||
|
expect(stepperItems).toEqual([])
|
||||||
|
expect(stepperItems).toHaveLength(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return empty array when all sections are templates', () => {
|
||||||
|
const sections: FormElementSectionDto[] = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
title: 'Template 1',
|
||||||
|
shortTitle: 'T1',
|
||||||
|
description: 'Template description',
|
||||||
|
isTemplate: true,
|
||||||
|
formElementSubSections: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
title: 'Template 2',
|
||||||
|
shortTitle: 'T2',
|
||||||
|
description: 'Another template',
|
||||||
|
isTemplate: true,
|
||||||
|
formElementSubSections: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const composable = useFormStepper(sections)
|
||||||
|
const stepperItems = composable.stepperItems.value
|
||||||
|
|
||||||
|
expect(stepperItems).toHaveLength(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should update stepperItems when formElementSections changes', async () => {
|
||||||
|
const sections = ref<FormElementSectionDto[]>([
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
title: 'Section 1',
|
||||||
|
shortTitle: 'S1',
|
||||||
|
description: 'First',
|
||||||
|
isTemplate: false,
|
||||||
|
formElementSubSections: []
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const composable = useFormStepper(sections)
|
||||||
|
expect(composable.stepperItems.value).toHaveLength(1)
|
||||||
|
|
||||||
|
// Update sections by mutating the ref
|
||||||
|
sections.value = [
|
||||||
|
...sections.value,
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
title: 'Section 2',
|
||||||
|
shortTitle: 'S2',
|
||||||
|
description: 'Second',
|
||||||
|
isTemplate: false,
|
||||||
|
formElementSubSections: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const stepperItems = composable.stepperItems.value
|
||||||
|
expect(stepperItems).toHaveLength(2)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('currentFormElementSection', () => {
|
||||||
|
it('should return the section at activeStepperItemIndex', () => {
|
||||||
|
const sections: FormElementSectionDto[] = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
title: 'Section 1',
|
||||||
|
shortTitle: 'S1',
|
||||||
|
description: 'First',
|
||||||
|
isTemplate: false,
|
||||||
|
formElementSubSections: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
title: 'Section 2',
|
||||||
|
shortTitle: 'S2',
|
||||||
|
description: 'Second',
|
||||||
|
isTemplate: false,
|
||||||
|
formElementSubSections: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '3',
|
||||||
|
title: 'Section 3',
|
||||||
|
shortTitle: 'S3',
|
||||||
|
description: 'Third',
|
||||||
|
isTemplate: false,
|
||||||
|
formElementSubSections: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const composable = useFormStepper(sections)
|
||||||
|
|
||||||
|
// Initially at index 0
|
||||||
|
let current = composable.currentFormElementSection.value
|
||||||
|
expect(current?.id).toBe('1')
|
||||||
|
|
||||||
|
// Change index to 1
|
||||||
|
composable.activeStepperItemIndex.value = 1
|
||||||
|
current = composable.currentFormElementSection.value
|
||||||
|
expect(current?.id).toBe('2')
|
||||||
|
|
||||||
|
// Change index to 2
|
||||||
|
composable.activeStepperItemIndex.value = 2
|
||||||
|
current = composable.currentFormElementSection.value
|
||||||
|
expect(current?.id).toBe('3')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should filter templates when determining current section', () => {
|
||||||
|
const sections: FormElementSectionDto[] = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
title: 'Section 1',
|
||||||
|
shortTitle: 'S1',
|
||||||
|
description: 'First',
|
||||||
|
isTemplate: false,
|
||||||
|
formElementSubSections: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
title: 'Template Section',
|
||||||
|
shortTitle: 'T1',
|
||||||
|
description: 'Template',
|
||||||
|
isTemplate: true,
|
||||||
|
formElementSubSections: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '3',
|
||||||
|
title: 'Section 3',
|
||||||
|
shortTitle: 'S3',
|
||||||
|
description: 'Third',
|
||||||
|
isTemplate: false,
|
||||||
|
formElementSubSections: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const composable = useFormStepper(sections)
|
||||||
|
|
||||||
|
// activeStepperItemIndex refers to visible sections only
|
||||||
|
composable.activeStepperItemIndex.value = 1
|
||||||
|
const current = composable.currentFormElementSection.value
|
||||||
|
// Should get the second visible section (id 3), skipping template
|
||||||
|
expect(current?.id).toBe('3')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('undefined formElementSections', () => {
|
||||||
|
it('should handle undefined formElementSections', () => {
|
||||||
|
const composable = useFormStepper(undefined)
|
||||||
|
const stepperItems = composable.stepperItems.value
|
||||||
|
|
||||||
|
expect(stepperItems).toEqual([])
|
||||||
|
expect(stepperItems).toHaveLength(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should default to empty array and return undefined for currentSection', () => {
|
||||||
|
const composable = useFormStepper(undefined)
|
||||||
|
|
||||||
|
expect(composable.stepperItems.value).toHaveLength(0)
|
||||||
|
expect(composable.currentFormElementSection.value).toBeUndefined()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('stepper and navigateStepper', () => {
|
||||||
|
it.each`
|
||||||
|
direction
|
||||||
|
${'forward'}
|
||||||
|
${'backward'}
|
||||||
|
`(
|
||||||
|
'should call onNavigate callback if provided during navigation ($direction)',
|
||||||
|
async ({ direction }: { direction: 'forward' | 'backward' }) => {
|
||||||
|
const sections: FormElementSectionDto[] = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
title: 'Section 1',
|
||||||
|
shortTitle: 'S1',
|
||||||
|
description: 'First',
|
||||||
|
isTemplate: false,
|
||||||
|
formElementSubSections: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const onNavigate = vi.fn()
|
||||||
|
const composable = useFormStepper(sections, { onNavigate })
|
||||||
|
|
||||||
|
await composable.navigateStepper(direction)
|
||||||
|
|
||||||
|
expect(onNavigate).toHaveBeenCalled()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user