This commit is contained in:
81
tests/hooks/useEditableForm.test.tsx
Normal file
81
tests/hooks/useEditableForm.test.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
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');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user