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([ { 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() } ) }) })