feat(frontend): Add useFormElementDuplication test
This commit is contained in:
@@ -0,0 +1,285 @@
|
||||
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('<p>Content</p>', '')
|
||||
])
|
||||
const existingElements: FormElementDto[] = [elementToClone]
|
||||
|
||||
const cloned = cloneElement(elementToClone, existingElements)
|
||||
|
||||
expect(cloned.options[0]!.value).toBe('<p>Content</p>')
|
||||
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')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user