import { describe, it, expect, vi, beforeEach } from 'vitest'; import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import { ToastProvider } from '@/components/ui/Toast'; import { I18nProvider } from '@/lib/i18n'; import LoginPage from '@/app/(auth)/login/page'; // Mock the API module vi.mock('@/lib/api', () => ({ login: vi.fn(), setTokens: vi.fn(), clearTokens: vi.fn(), isAuthenticated: () => false, })); // Mock next/navigation vi.mock('next/navigation', () => ({ useRouter: () => ({ push: vi.fn(), replace: vi.fn(), back: vi.fn(), refresh: vi.fn(), }), redirect: vi.fn(), })); import { login as mockLogin } from '@/lib/api'; describe('LoginPage', () => { beforeEach(() => { vi.clearAllMocks(); }); it('renders the login form with email and password fields', () => { render( ); expect(screen.getByTestId('login-form')).toBeInTheDocument(); expect(screen.getByTestId('email-input')).toBeInTheDocument(); expect(screen.getByTestId('password-input')).toBeInTheDocument(); expect(screen.getByTestId('login-button')).toBeInTheDocument(); }); it('shows validation errors for empty fields', async () => { render( ); const submitButton = screen.getByTestId('login-button'); fireEvent.click(submitButton); await waitFor(() => { expect(screen.getByText('E-Mail-Adresse ist erforderlich')).toBeInTheDocument(); expect(screen.getByText('Passwort ist erforderlich')).toBeInTheDocument(); }); }); it('calls login API on submit with valid credentials', async () => { (mockLogin as any).mockResolvedValue({ access_token: 'fake-token', refresh_token: 'fake-refresh', token_type: 'bearer', expires_in: 900, }); render( ); const emailInput = screen.getByTestId('email-input'); const passwordInput = screen.getByTestId('password-input'); const submitButton = screen.getByTestId('login-button'); fireEvent.change(emailInput, { target: { value: 'admin@test.com' } }); fireEvent.change(passwordInput, { target: { value: 'Admin12345!' } }); fireEvent.click(submitButton); await waitFor(() => { expect(mockLogin).toHaveBeenCalledWith('admin@test.com', 'Admin12345!'); }); }); it('shows error toast on login failure', async () => { (mockLogin as any).mockRejectedValue({ error: { code: 'INVALID_CREDENTIALS', message: 'Invalid email or password' }, }); render( ); const emailInput = screen.getByTestId('email-input'); const passwordInput = screen.getByTestId('password-input'); const submitButton = screen.getByTestId('login-button'); fireEvent.change(emailInput, { target: { value: 'wrong@test.com' } }); fireEvent.change(passwordInput, { target: { value: 'wrongpass' } }); fireEvent.click(submitButton); await waitFor(() => { const toastContainer = screen.getByTestId('toast-container'); expect(toastContainer).toHaveTextContent('Invalid email or password'); }); }); it('renders with English locale when selected', () => { render( ); expect(screen.getAllByText('Sign In').length).toBeGreaterThanOrEqual(1); expect(screen.getByText('Email Address')).toBeInTheDocument(); expect(screen.getByText('Password')).toBeInTheDocument(); }); });