import { act } from 'react'; import { describe, expect, it } from 'vitest'; import { useEditableForm } from '../../src/hooks/useEditableForm'; import { renderHook } from '../helpers/renderHook'; type FormValues = { username: string; email: string; }; const INITIAL_VALUES: FormValues = { username: '', email: '', }; function validate(values: FormValues) { return { username: values.username.trim().length < 3 ? 'Username too short' : undefined, email: values.email.includes('@') ? undefined : 'Invalid email', }; } describe('useEditableForm', () => { it('supports load/start/discard/commit edit lifecycle', () => { const { result } = renderHook(() => useEditableForm({ initialValues: INITIAL_VALUES, validate, }), ); expect(result.current.isEditing).toBe(false); act(() => { result.current.loadFromSource({ username: 'alice', email: 'alice@example.com' }); }); expect(result.current.values).toEqual({ username: 'alice', email: 'alice@example.com' }); expect(result.current.errors).toEqual({}); act(() => { result.current.startEditing({ username: 'al', email: 'aliceexample.com' }); }); expect(result.current.isEditing).toBe(true); act(() => { result.current.setFieldValue('username', 'a'); }); expect(result.current.errors.username).toBe('Username too short'); act(() => { result.current.discardChanges({ username: 'alice', email: 'alice@example.com' }); }); expect(result.current.isEditing).toBe(false); expect(result.current.values).toEqual({ username: 'alice', email: 'alice@example.com' }); act(() => { result.current.startEditing({ username: 'alice', email: 'alice@example.com' }); result.current.setFieldValue('username', 'alice_2'); result.current.commitSaved({ username: 'alice_2', email: 'alice@example.com' }); }); expect(result.current.isEditing).toBe(false); expect(result.current.values.username).toBe('alice_2'); }); it('exposes direct editing toggles and field error injection', () => { const { result } = renderHook(() => useEditableForm({ initialValues: INITIAL_VALUES, validate, }), ); act(() => { result.current.setIsEditing(true); result.current.setFieldError('username', 'Username already taken'); }); expect(result.current.isEditing).toBe(true); expect(result.current.errors.username).toBe('Username already taken'); }); });