Files
fast-next-template/frontend/tests/components/auth/LoginForm.test.tsx
Felipe Cardoso 925950d58e Add password reset functionality with form components, pages, and tests
- Implemented `PasswordResetRequestForm` and `PasswordResetConfirmForm` components with email and password validation, strength indicators, and error handling.
- Added dedicated pages for requesting and confirming password resets, integrated with React Query hooks and Next.js API routes.
- Included tests for validation rules, UI states, and token handling to ensure proper functionality and coverage.
- Updated ESLint and configuration files for new components and pages.
- Enhanced `IMPLEMENTATION_PLAN.md` with updated task details and documentation for password reset workflows.
2025-11-01 00:57:57 +01:00

98 lines
3.0 KiB
TypeScript

/**
* Tests for LoginForm component
*/
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { LoginForm } from '@/components/auth/LoginForm';
// Mock router
jest.mock('next/navigation', () => ({
useRouter: () => ({
push: jest.fn(),
}),
}));
// Mock auth store
jest.mock('@/stores/authStore', () => ({
useAuthStore: () => ({
isAuthenticated: false,
setAuth: jest.fn(),
}),
}));
const createWrapper = () => {
const queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false },
mutations: { retry: false },
},
});
return ({ children }: { children: React.ReactNode }) => (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
);
};
describe('LoginForm', () => {
it('renders login form with email and password fields', () => {
render(<LoginForm />, { wrapper: createWrapper() });
expect(screen.getByLabelText(/email/i)).toBeInTheDocument();
expect(screen.getByLabelText(/password/i)).toBeInTheDocument();
expect(screen.getByRole('button', { name: /sign in/i })).toBeInTheDocument();
});
it('shows validation errors for empty fields', async () => {
const user = userEvent.setup();
render(<LoginForm />, { wrapper: createWrapper() });
const submitButton = screen.getByRole('button', { name: /sign in/i });
await user.click(submitButton);
await waitFor(() => {
expect(screen.getByText(/email is required/i)).toBeInTheDocument();
expect(screen.getByText(/password is required/i)).toBeInTheDocument();
});
});
// Note: Email validation is primarily handled by HTML5 type="email" attribute
// Zod provides additional validation layer
it('shows password requirements validation', async () => {
const user = userEvent.setup();
render(<LoginForm />, { wrapper: createWrapper() });
const emailInput = screen.getByLabelText(/email/i);
const passwordInput = screen.getByLabelText(/password/i);
const submitButton = screen.getByRole('button', { name: /sign in/i });
await user.type(emailInput, 'test@example.com');
await user.type(passwordInput, 'short');
await user.click(submitButton);
await waitFor(() => {
expect(screen.getByText(/password must be at least 8 characters/i)).toBeInTheDocument();
});
});
it('shows register link when enabled', () => {
render(<LoginForm showRegisterLink />, { wrapper: createWrapper() });
expect(screen.getByText(/don't have an account/i)).toBeInTheDocument();
expect(screen.getByRole('link', { name: /sign up/i })).toBeInTheDocument();
});
it('shows password reset link when enabled', () => {
render(<LoginForm showPasswordResetLink />, { wrapper: createWrapper() });
expect(screen.getByRole('link', { name: /forgot password/i })).toBeInTheDocument();
});
// Note: Async submission tests require API mocking with MSW
// Will be added in Phase 9 (Testing Infrastructure)
});