Refactor useAuth hook, settings components, and docs for formatting and readability improvements
- Consolidated multi-line arguments into single lines where appropriate in `useAuth`. - Improved spacing and readability in data processing across components (`ProfileSettingsForm`, `PasswordChangeForm`, `SessionCard`). - Applied consistent table and markdown formatting in design system docs (e.g., `README.md`, `08-ai-guidelines.md`, `00-quick-start.md`). - Updated code snippets to ensure adherence to Prettier rules and streamlined JSX structures.
This commit is contained in:
@@ -10,37 +10,21 @@ import { FieldError } from 'react-hook-form';
|
||||
describe('FormField', () => {
|
||||
describe('Basic Rendering', () => {
|
||||
it('renders with label and input', () => {
|
||||
render(
|
||||
<FormField
|
||||
label="Email"
|
||||
name="email"
|
||||
type="email"
|
||||
/>
|
||||
);
|
||||
render(<FormField label="Email" name="email" type="email" />);
|
||||
|
||||
expect(screen.getByLabelText('Email')).toBeInTheDocument();
|
||||
expect(screen.getByRole('textbox')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders with description', () => {
|
||||
render(
|
||||
<FormField
|
||||
label="Username"
|
||||
name="username"
|
||||
description="Choose a unique username"
|
||||
/>
|
||||
);
|
||||
render(<FormField label="Username" name="username" description="Choose a unique username" />);
|
||||
|
||||
expect(screen.getByText('Choose a unique username')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders children content', () => {
|
||||
render(
|
||||
<FormField
|
||||
label="Password"
|
||||
name="password"
|
||||
type="password"
|
||||
>
|
||||
<FormField label="Password" name="password" type="password">
|
||||
<p>Password requirements: 8+ characters</p>
|
||||
</FormField>
|
||||
);
|
||||
@@ -51,25 +35,13 @@ describe('FormField', () => {
|
||||
|
||||
describe('Required Field', () => {
|
||||
it('shows asterisk when required is true', () => {
|
||||
render(
|
||||
<FormField
|
||||
label="Email"
|
||||
name="email"
|
||||
required
|
||||
/>
|
||||
);
|
||||
render(<FormField label="Email" name="email" required />);
|
||||
|
||||
expect(screen.getByText('*')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not show asterisk when required is false', () => {
|
||||
render(
|
||||
<FormField
|
||||
label="Email"
|
||||
name="email"
|
||||
required={false}
|
||||
/>
|
||||
);
|
||||
render(<FormField label="Email" name="email" required={false} />);
|
||||
|
||||
expect(screen.queryByText('*')).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -82,13 +54,7 @@ describe('FormField', () => {
|
||||
message: 'Email is required',
|
||||
};
|
||||
|
||||
render(
|
||||
<FormField
|
||||
label="Email"
|
||||
name="email"
|
||||
error={error}
|
||||
/>
|
||||
);
|
||||
render(<FormField label="Email" name="email" error={error} />);
|
||||
|
||||
expect(screen.getByText('Email is required')).toBeInTheDocument();
|
||||
});
|
||||
@@ -99,13 +65,7 @@ describe('FormField', () => {
|
||||
message: 'Email is required',
|
||||
};
|
||||
|
||||
render(
|
||||
<FormField
|
||||
label="Email"
|
||||
name="email"
|
||||
error={error}
|
||||
/>
|
||||
);
|
||||
render(<FormField label="Email" name="email" error={error} />);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
expect(input).toHaveAttribute('aria-invalid', 'true');
|
||||
@@ -117,13 +77,7 @@ describe('FormField', () => {
|
||||
message: 'Email is required',
|
||||
};
|
||||
|
||||
render(
|
||||
<FormField
|
||||
label="Email"
|
||||
name="email"
|
||||
error={error}
|
||||
/>
|
||||
);
|
||||
render(<FormField label="Email" name="email" error={error} />);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
expect(input).toHaveAttribute('aria-describedby', 'email-error');
|
||||
@@ -135,13 +89,7 @@ describe('FormField', () => {
|
||||
message: 'Email is required',
|
||||
};
|
||||
|
||||
render(
|
||||
<FormField
|
||||
label="Email"
|
||||
name="email"
|
||||
error={error}
|
||||
/>
|
||||
);
|
||||
render(<FormField label="Email" name="email" error={error} />);
|
||||
|
||||
const errorElement = screen.getByRole('alert');
|
||||
expect(errorElement).toHaveTextContent('Email is required');
|
||||
@@ -150,12 +98,7 @@ describe('FormField', () => {
|
||||
|
||||
describe('Accessibility', () => {
|
||||
it('links label to input via htmlFor/id', () => {
|
||||
render(
|
||||
<FormField
|
||||
label="Email"
|
||||
name="email"
|
||||
/>
|
||||
);
|
||||
render(<FormField label="Email" name="email" />);
|
||||
|
||||
const label = screen.getByText('Email');
|
||||
const input = screen.getByRole('textbox');
|
||||
@@ -165,13 +108,7 @@ describe('FormField', () => {
|
||||
});
|
||||
|
||||
it('sets aria-describedby with description ID when description exists', () => {
|
||||
render(
|
||||
<FormField
|
||||
label="Username"
|
||||
name="username"
|
||||
description="Choose a unique username"
|
||||
/>
|
||||
);
|
||||
render(<FormField label="Username" name="username" description="Choose a unique username" />);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
expect(input).toHaveAttribute('aria-describedby', 'username-description');
|
||||
@@ -223,12 +160,7 @@ describe('FormField', () => {
|
||||
ref: jest.fn(),
|
||||
};
|
||||
|
||||
render(
|
||||
<FormField
|
||||
label="Email"
|
||||
{...registerProps}
|
||||
/>
|
||||
);
|
||||
render(<FormField label="Email" {...registerProps} />);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
expect(input).toBeInTheDocument();
|
||||
@@ -243,12 +175,7 @@ describe('FormField', () => {
|
||||
const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
expect(() => {
|
||||
render(
|
||||
<FormField
|
||||
label="Email"
|
||||
name={undefined}
|
||||
/>
|
||||
);
|
||||
render(<FormField label="Email" name={undefined} />);
|
||||
}).toThrow('FormField: name must be provided either explicitly or via register()');
|
||||
|
||||
consoleError.mockRestore();
|
||||
@@ -257,12 +184,7 @@ describe('FormField', () => {
|
||||
|
||||
describe('Layout and Styling', () => {
|
||||
it('applies correct spacing classes', () => {
|
||||
const { container } = render(
|
||||
<FormField
|
||||
label="Email"
|
||||
name="email"
|
||||
/>
|
||||
);
|
||||
const { container } = render(<FormField label="Email" name="email" />);
|
||||
|
||||
const wrapper = container.firstChild as HTMLElement;
|
||||
expect(wrapper).toHaveClass('space-y-2');
|
||||
@@ -274,13 +196,7 @@ describe('FormField', () => {
|
||||
message: 'Email is required',
|
||||
};
|
||||
|
||||
render(
|
||||
<FormField
|
||||
label="Email"
|
||||
name="email"
|
||||
error={error}
|
||||
/>
|
||||
);
|
||||
render(<FormField label="Email" name="email" error={error} />);
|
||||
|
||||
const errorElement = screen.getByRole('alert');
|
||||
expect(errorElement).toHaveClass('text-sm', 'text-destructive');
|
||||
@@ -288,11 +204,7 @@ describe('FormField', () => {
|
||||
|
||||
it('applies correct description styling', () => {
|
||||
const { container } = render(
|
||||
<FormField
|
||||
label="Email"
|
||||
name="email"
|
||||
description="We'll never share your email"
|
||||
/>
|
||||
<FormField label="Email" name="email" description="We'll never share your email" />
|
||||
);
|
||||
|
||||
const description = container.querySelector('#email-description');
|
||||
|
||||
@@ -70,9 +70,7 @@ describe('useFormError', () => {
|
||||
it('handles API error with general error message', () => {
|
||||
const { result } = renderHook(() => useTestForm());
|
||||
|
||||
const apiError = [
|
||||
{ code: 'AUTH_001', message: 'Invalid credentials' },
|
||||
];
|
||||
const apiError = [{ code: 'AUTH_001', message: 'Invalid credentials' }];
|
||||
|
||||
act(() => {
|
||||
result.current.formError.handleFormError(apiError);
|
||||
@@ -98,9 +96,7 @@ describe('useFormError', () => {
|
||||
});
|
||||
|
||||
it('handles API errors with field-specific errors without crashing', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useTestForm({ email: '', password: '', username: '' })
|
||||
);
|
||||
const { result } = renderHook(() => useTestForm({ email: '', password: '', username: '' }));
|
||||
|
||||
const apiError = [
|
||||
{ code: 'VAL_004', message: 'Email is required', field: 'email' },
|
||||
@@ -129,7 +125,9 @@ describe('useFormError', () => {
|
||||
result.current.formError.handleFormError(unexpectedError);
|
||||
});
|
||||
|
||||
expect(result.current.formError.serverError).toBe('An unexpected error occurred. Please try again.');
|
||||
expect(result.current.formError.serverError).toBe(
|
||||
'An unexpected error occurred. Please try again.'
|
||||
);
|
||||
});
|
||||
|
||||
it('handles string errors', () => {
|
||||
@@ -139,7 +137,9 @@ describe('useFormError', () => {
|
||||
result.current.formError.handleFormError('Some error string');
|
||||
});
|
||||
|
||||
expect(result.current.formError.serverError).toBe('An unexpected error occurred. Please try again.');
|
||||
expect(result.current.formError.serverError).toBe(
|
||||
'An unexpected error occurred. Please try again.'
|
||||
);
|
||||
});
|
||||
|
||||
it('handles null errors', () => {
|
||||
@@ -149,7 +149,9 @@ describe('useFormError', () => {
|
||||
result.current.formError.handleFormError(null);
|
||||
});
|
||||
|
||||
expect(result.current.formError.serverError).toBe('An unexpected error occurred. Please try again.');
|
||||
expect(result.current.formError.serverError).toBe(
|
||||
'An unexpected error occurred. Please try again.'
|
||||
);
|
||||
});
|
||||
|
||||
it('handles undefined errors', () => {
|
||||
@@ -159,7 +161,9 @@ describe('useFormError', () => {
|
||||
result.current.formError.handleFormError(undefined);
|
||||
});
|
||||
|
||||
expect(result.current.formError.serverError).toBe('An unexpected error occurred. Please try again.');
|
||||
expect(result.current.formError.serverError).toBe(
|
||||
'An unexpected error occurred. Please try again.'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -179,9 +183,7 @@ describe('useFormError', () => {
|
||||
});
|
||||
|
||||
it('clears form errors', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useTestForm({ email: '', password: '', username: '' })
|
||||
);
|
||||
const { result } = renderHook(() => useTestForm({ email: '', password: '', username: '' }));
|
||||
|
||||
// Set field errors
|
||||
act(() => {
|
||||
@@ -199,9 +201,7 @@ describe('useFormError', () => {
|
||||
});
|
||||
|
||||
it('clears both server and form errors', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useTestForm({ email: '', password: '', username: '' })
|
||||
);
|
||||
const { result } = renderHook(() => useTestForm({ email: '', password: '', username: '' }));
|
||||
|
||||
act(() => {
|
||||
result.current.formError.setServerError('Server error');
|
||||
@@ -219,14 +219,10 @@ describe('useFormError', () => {
|
||||
|
||||
describe('Integration Scenarios', () => {
|
||||
it('handles typical login flow with API error', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useTestForm({ email: '', password: '', username: '' })
|
||||
);
|
||||
const { result } = renderHook(() => useTestForm({ email: '', password: '', username: '' }));
|
||||
|
||||
// Simulate API error response
|
||||
const apiError = [
|
||||
{ code: 'AUTH_001', message: 'Invalid email or password' },
|
||||
];
|
||||
const apiError = [{ code: 'AUTH_001', message: 'Invalid email or password' }];
|
||||
|
||||
act(() => {
|
||||
result.current.formError.handleFormError(apiError);
|
||||
|
||||
Reference in New Issue
Block a user