import React from 'react'; import { render, screen, fireEvent, waitFor, act } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { BrowserRouter } from 'react-router-dom'; import Login from '../../components/Login'; // Mock fetch global.fetch = jest.fn(); const renderLogin = () => { return render( ); }; describe('Login Component', () => { beforeEach(() => { (fetch as jest.Mock).mockClear(); }); it('renders login form', () => { renderLogin(); expect(screen.getByLabelText(/email/i)).toBeInTheDocument(); expect(screen.getByLabelText(/password/i)).toBeInTheDocument(); expect(screen.getByRole('button', { name: /login/i })).toBeInTheDocument(); }); it('handles form submission with valid credentials', async () => { const user = userEvent.setup(); (fetch as jest.Mock).mockResolvedValueOnce({ ok: true, json: async () => ({ success: true, user: { email: 'test@example.com' } }) }); renderLogin(); await act(async () => { await user.type(screen.getByLabelText(/email/i), 'test@example.com'); await user.type(screen.getByLabelText(/password/i), 'password123'); }); await act(async () => { await user.click(screen.getByRole('button', { name: /login/i })); }); await waitFor(() => { expect(fetch).toHaveBeenCalledWith('/api/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify({ email: 'test@example.com', password: 'password123' }) }); }); }); it('displays error message on failed login', async () => { const user = userEvent.setup(); (fetch as jest.Mock).mockResolvedValueOnce({ ok: false, json: async () => ({ error: 'Invalid credentials' }) }); renderLogin(); await act(async () => { await user.type(screen.getByLabelText(/email/i), 'test@example.com'); await user.type(screen.getByLabelText(/password/i), 'wrongpassword'); }); await act(async () => { await user.click(screen.getByRole('button', { name: /login/i })); }); await waitFor(() => { expect(screen.getByText(/an error occurred/i)).toBeInTheDocument(); }); }); it('validates required fields', async () => { const user = userEvent.setup(); renderLogin(); await act(async () => { await user.click(screen.getByRole('button', { name: /login/i })); }); // Should not make API call with empty fields expect(fetch).not.toHaveBeenCalled(); }); });