tududi/frontend/__tests__/components/Login.test.tsx
Chris 3c1209a5a9
Express migration (#80)
* Initial migration

* Cleanup and create migration scripts

* Introduce test suite

* Fix test issues

* Correct CORS issue and update paths

* Update README
2025-06-16 21:50:44 +03:00

96 lines
No EOL
2.6 KiB
TypeScript

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(
<BrowserRouter>
<Login />
</BrowserRouter>
);
};
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();
});
});