import { describe, it, expect } from 'vitest' import { useFormElementDuplication } from '../../../app/composables/useFormElementDuplication' import type { FormElementDto, FormOptionDto, 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[] = [], description?: string ): FormElementDto { return { id: `id-${reference}`, reference, title, type, options, description } } describe('useFormElementDuplication', () => { describe('cloneElement()', () => { it('should generate incremented reference from existing reference with suffix', () => { const { cloneElement } = useFormElementDuplication() const elementToClone = createFormElement('modul_1', 'Module', 'TEXTFIELD', [createOption('value', '')]) const existingElements: FormElementDto[] = [elementToClone] const cloned = cloneElement(elementToClone, existingElements) expect(cloned.reference).toBe('modul_2') }) it('should handle reference without numeric suffix (defaults to _2)', () => { const { cloneElement } = useFormElementDuplication() const elementToClone = createFormElement('modul', 'Module', 'TEXTFIELD', [createOption('value', '')]) const existingElements: FormElementDto[] = [elementToClone] const cloned = cloneElement(elementToClone, existingElements) expect(cloned.reference).toBe('modul_2') }) it('should clear id and formElementSubSectionId on cloned element', () => { const { cloneElement } = useFormElementDuplication() const elementToClone = createFormElement('elem_1', 'Element', 'TEXTFIELD', [createOption('value', '')]) elementToClone.id = 'some-uuid-id' elementToClone.formElementSubSectionId = 'subsection-uuid' const existingElements: FormElementDto[] = [elementToClone] const cloned = cloneElement(elementToClone, existingElements) expect(cloned.id).toBeUndefined() expect(cloned.formElementSubSectionId).toBeUndefined() }) it('should deep clone element (modifying clone does not affect original)', () => { const { cloneElement } = useFormElementDuplication() const elementToClone = createFormElement('elem_1', 'Element', 'SELECT', [ createOption('true', 'Yes'), createOption('false', 'No') ]) const existingElements: FormElementDto[] = [elementToClone] const cloned = cloneElement(elementToClone, existingElements) cloned.options[0]!.value = 'modified' cloned.title = 'Modified Title' expect(elementToClone.options[0]!.value).toBe('true') expect(elementToClone.title).toBe('Element') }) it('should handle multiple existing clones and generate correct next reference', () => { const { cloneElement } = useFormElementDuplication() const element1 = createFormElement('modul_1', 'Module', 'TEXTFIELD', [createOption('value1', '')]) const element2 = createFormElement('modul_2', 'Module', 'TEXTFIELD', [createOption('value2', '')]) const element3 = createFormElement('modul_3', 'Module', 'TEXTFIELD', [createOption('value3', '')]) const existingElements: FormElementDto[] = [element1, element2, element3] const cloned = cloneElement(element1, existingElements) expect(cloned.reference).toBe('modul_4') }) it('should handle elements with no options', () => { const { cloneElement } = useFormElementDuplication() const elementToClone = createFormElement('elem_1', 'Element', 'TEXTFIELD', []) const existingElements: FormElementDto[] = [elementToClone] const cloned = cloneElement(elementToClone, existingElements) expect(cloned.options).toEqual([]) expect(cloned.reference).toBe('elem_2') }) it('should handle sparse numeric suffix correctly', () => { const { cloneElement } = useFormElementDuplication() const element1 = createFormElement('item_1', 'Item', 'TEXTFIELD', [createOption('v1', '')]) const element3 = createFormElement('item_3', 'Item', 'TEXTFIELD', [createOption('v3', '')]) const existingElements: FormElementDto[] = [element1, element3] const cloned = cloneElement(element1, existingElements) expect(cloned.reference).toBe('item_4') }) it('should handle element with formElementSubSectionId undefined already', () => { const { cloneElement } = useFormElementDuplication() const elementToClone = createFormElement('elem_1', 'Element', 'TEXTFIELD', [createOption('value', '')]) const existingElements: FormElementDto[] = [elementToClone] const cloned = cloneElement(elementToClone, existingElements) expect(cloned.formElementSubSectionId).toBeUndefined() }) describe('option value handling by form element type', () => { it('should reset TEXTAREA option values to empty string', () => { const { cloneElement } = useFormElementDuplication() const elementToClone = createFormElement('textarea_1', 'My Title', 'TEXTAREA', [ createOption('Original text content', '') ]) const existingElements: FormElementDto[] = [elementToClone] const cloned = cloneElement(elementToClone, existingElements) expect(cloned.options[0]!.value).toBe('') expect(cloned.reference).toBe('textarea_2') }) it('should reset TEXTFIELD option values to empty string', () => { const { cloneElement } = useFormElementDuplication() const elementToClone = createFormElement('textfield_1', 'My Title', 'TEXTFIELD', [ createOption('Original text content', '') ]) const existingElements: FormElementDto[] = [elementToClone] const cloned = cloneElement(elementToClone, existingElements) expect(cloned.options[0]!.value).toBe('') expect(cloned.reference).toBe('textfield_2') }) it('should preserve SELECT option values', () => { const { cloneElement } = useFormElementDuplication() const elementToClone = createFormElement('select_1', 'Choice', 'SELECT', [ createOption('false', 'Option A'), createOption('true', 'Option B') ]) const existingElements: FormElementDto[] = [elementToClone] const cloned = cloneElement(elementToClone, existingElements) expect(cloned.options[0]!.value).toBe('false') expect(cloned.options[1]!.value).toBe('true') expect(cloned.reference).toBe('select_2') }) it('should preserve CHECKBOX option values', () => { const { cloneElement } = useFormElementDuplication() const elementToClone = createFormElement('checkbox_1', 'Features', 'CHECKBOX', [ createOption('true', 'Feature A'), createOption('false', 'Feature B') ]) const existingElements: FormElementDto[] = [elementToClone] const cloned = cloneElement(elementToClone, existingElements) expect(cloned.options[0]!.value).toBe('true') expect(cloned.options[1]!.value).toBe('false') expect(cloned.reference).toBe('checkbox_2') }) it('should preserve RADIOBUTTON option values', () => { const { cloneElement } = useFormElementDuplication() const elementToClone = createFormElement('radio_1', 'Gender', 'RADIOBUTTON', [ createOption('true', 'Male'), createOption('false', 'Female') ]) const existingElements: FormElementDto[] = [elementToClone] const cloned = cloneElement(elementToClone, existingElements) expect(cloned.options[0]!.value).toBe('true') expect(cloned.options[1]!.value).toBe('false') expect(cloned.reference).toBe('radio_2') }) it('should handle SWITCH element option values', () => { const { cloneElement } = useFormElementDuplication() const elementToClone = createFormElement('switch_1', 'Enable', 'SWITCH', [createOption('true', 'Enabled')]) const existingElements: FormElementDto[] = [elementToClone] const cloned = cloneElement(elementToClone, existingElements) expect(cloned.options[0]!.value).toBe('true') expect(cloned.reference).toBe('switch_2') }) it('should handle DATE element option values', () => { const { cloneElement } = useFormElementDuplication() const elementToClone = createFormElement('date_1', 'Start Date', 'DATE', [createOption('2024-01-15', 'label')]) const existingElements: FormElementDto[] = [elementToClone] const cloned = cloneElement(elementToClone, existingElements) expect(cloned.options[0]!.value).toBe('2024-01-15') expect(cloned.reference).toBe('date_2') }) it('should handle RICH_TEXT element option values', () => { const { cloneElement } = useFormElementDuplication() const elementToClone = createFormElement('richtext_1', 'Notes', 'RICH_TEXT', [ createOption('
Content
', '') ]) const existingElements: FormElementDto[] = [elementToClone] const cloned = cloneElement(elementToClone, existingElements) expect(cloned.options[0]!.value).toBe('Content
') expect(cloned.reference).toBe('richtext_2') }) it('should handle TABLE element option values', () => { const { cloneElement } = useFormElementDuplication() const elementToClone = createFormElement('table_1', 'Employees', 'TABLE', [ createOption('["row1", "row2"]', 'Name'), createOption('["dev", "designer"]', 'Role') ]) const existingElements: FormElementDto[] = [elementToClone] const cloned = cloneElement(elementToClone, existingElements) expect(cloned.options[0]!.value).toBe('["row1", "row2"]') expect(cloned.options[1]!.value).toBe('["dev", "designer"]') expect(cloned.reference).toBe('table_2') }) it('should preserve all FormOptionDto properties when cloning', () => { const { cloneElement } = useFormElementDuplication() const option = createOption('true', 'Yes') option.processingPurpose = 'BUSINESS_PROCESS' option.employeeDataCategory = 'SENSITIVE' const elementToClone = createFormElement('elem_1', 'Element', 'SELECT', [option]) const existingElements: FormElementDto[] = [elementToClone] const cloned = cloneElement(elementToClone, existingElements) expect(cloned.options[0]!.processingPurpose).toBe('BUSINESS_PROCESS') expect(cloned.options[0]!.employeeDataCategory).toBe('SENSITIVE') }) }) }) })