diff options
Diffstat (limited to 'frontend/src/components/Login.test.tsx')
| -rw-r--r-- | frontend/src/components/Login.test.tsx | 101 |
1 files changed, 52 insertions, 49 deletions
diff --git a/frontend/src/components/Login.test.tsx b/frontend/src/components/Login.test.tsx index ef946e2..aea7042 100644 --- a/frontend/src/components/Login.test.tsx +++ b/frontend/src/components/Login.test.tsx @@ -9,70 +9,73 @@ import Login from './Login'; global.fetch = vi.fn(); const renderLogin = () => { - render( - <BrowserRouter> - <Login /> - </BrowserRouter> - ); + render( + <BrowserRouter> + <Login /> + </BrowserRouter> + ); }; describe('Login Component', () => { - beforeEach(() => { - vi.resetAllMocks(); + beforeEach(() => { + vi.resetAllMocks(); + }); + + it('renders login form', () => { + renderLogin(); + expect(screen.getByLabelText(/password/i)).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /login/i })).toBeInTheDocument(); + }); + + it('handles successful login', async () => { + (global.fetch as any).mockResolvedValueOnce({ + ok: true, }); - it('renders login form', () => { - renderLogin(); - expect(screen.getByLabelText(/password/i)).toBeInTheDocument(); - expect(screen.getByRole('button', { name: /login/i })).toBeInTheDocument(); - }); - - it('handles successful login', async () => { - (global.fetch as any).mockResolvedValueOnce({ - ok: true, - }); - - renderLogin(); + renderLogin(); - fireEvent.change(screen.getByLabelText(/password/i), { target: { value: 'secret' } }); - fireEvent.click(screen.getByRole('button', { name: /login/i })); + fireEvent.change(screen.getByLabelText(/password/i), { target: { value: 'secret' } }); + fireEvent.click(screen.getByRole('button', { name: /login/i })); - await waitFor(() => { - expect(global.fetch).toHaveBeenCalledWith('/api/login', expect.objectContaining({ - method: 'POST', - })); - }); - // Navigation assertion is tricky without mocking useNavigate, - // but if no error is shown, we assume success path was taken - expect(screen.queryByText(/login failed/i)).not.toBeInTheDocument(); + await waitFor(() => { + expect(global.fetch).toHaveBeenCalledWith( + '/api/login', + expect.objectContaining({ + method: 'POST', + }) + ); + }); + // Navigation assertion is tricky without mocking useNavigate, + // but if no error is shown, we assume success path was taken + expect(screen.queryByText(/login failed/i)).not.toBeInTheDocument(); + }); + + it('handles failed login', async () => { + (global.fetch as any).mockResolvedValueOnce({ + ok: false, + json: async () => ({ message: 'Bad credentials' }), }); - it('handles failed login', async () => { - (global.fetch as any).mockResolvedValueOnce({ - ok: false, - json: async () => ({ message: 'Bad credentials' }), - }); - - renderLogin(); + renderLogin(); - fireEvent.change(screen.getByLabelText(/password/i), { target: { value: 'wrong' } }); - fireEvent.click(screen.getByRole('button', { name: /login/i })); + fireEvent.change(screen.getByLabelText(/password/i), { target: { value: 'wrong' } }); + fireEvent.click(screen.getByRole('button', { name: /login/i })); - await waitFor(() => { - expect(screen.getByText(/bad credentials/i)).toBeInTheDocument(); - }); + await waitFor(() => { + expect(screen.getByText(/bad credentials/i)).toBeInTheDocument(); }); + }); - it('handles network error', async () => { - (global.fetch as any).mockRejectedValueOnce(new Error('Network error')); + it('handles network error', async () => { + (global.fetch as any).mockRejectedValueOnce(new Error('Network error')); - renderLogin(); + renderLogin(); - fireEvent.change(screen.getByLabelText(/password/i), { target: { value: 'secret' } }); - fireEvent.click(screen.getByRole('button', { name: /login/i })); + fireEvent.change(screen.getByLabelText(/password/i), { target: { value: 'secret' } }); + fireEvent.click(screen.getByRole('button', { name: /login/i })); - await waitFor(() => { - expect(screen.getByText(/network error/i)).toBeInTheDocument(); - }); + await waitFor(() => { + expect(screen.getByText(/network error/i)).toBeInTheDocument(); }); + }); }); |
