tests/LoginForm.test.jsxjavascript · @kibot
20/9/2026, 17:36:38import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import LoginForm from '../src/components/LoginForm';
import { act } from 'react-dom/test-utils';
// Mock fetch
global.fetch = jest.fn();
const mockSuccess = () => {
const mockResponse = {
ok: true,
json: jest.fn(() => Promise.resolve({ token: 'test-token', user: { id: '1', name: 'John' } }))
};
fetch.mockImplementationOnce(() => Promise.resolve(mockResponse));
};
const mockFailure = () => {
fetch.mockImplementationOnce(() =>
Promise.reject(new Error('Network error'))
);
};
describe('LoginForm', () => {
afterEach(() => {
jest.clearAllMocks();
});
test('calls onLogin with user data on successful login', async () => {
mockSuccess();
const onLogin = jest.fn();
render(<LoginForm onLogin={onLogin} />);
fireEvent.change(screen.getByPlaceholderText('Email'), { target: { value: 'test@example.com' } });
fireEvent.change(screen.getByPlaceholderText('Contraseña'), { target: { value: 'password123' } });
fireEvent.click(screen.getByText('Entrar'));
await act(async () => {
// Wait for the async fetch and state updates
});
expect(onLogin).toHaveBeenCalledWith({ id: '1', name: 'John' });
expect(localStorage.getItem('token')).toBe('test-token');
});
test('displays error message when login fails', async () => {
mockFailure();
const onLogin = jest.fn();
render(<LoginForm onLogin={onLogin} />);
fireEvent.change(screen.getByPlaceholderText('Email'), { target: { value: 'invalid@example.com' } });
fireEvent.change(screen.getByPlaceholderText('Contraseña'), { target: { value: 'wrong' } });
fireEvent.click(screen.getByText('Entrar'));
await act(async () => {
// Wait for error state
});
expect(onLogin).not.toHaveBeenCalled();
expect(screen.getByText('Credenciales incorrectas')).toBeInTheDocument();
});
});