import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import AuthLogin from './AuthLogin'; import { useAuth } from '../hooks/useAuth'; // Mock do hook useAuth jest.mock('../hooks/useAuth'); const createWrapper = () => { const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false }, mutations: { retry: false }, }, }); return ({ children }: { children: React.ReactNode }) => ( {children} ); }; describe('AuthLogin Component', () => { const mockLoginMutation = { mutate: jest.fn(), isPending: false, isError: false, isSuccess: false, error: null, }; beforeEach(() => { jest.clearAllMocks(); (useAuth as jest.Mock).mockReturnValue({ loginMutation: mockLoginMutation, }); }); describe('Renderização', () => { it('deve renderizar formulário de login', () => { render(, { wrapper: createWrapper() }); expect(screen.getByLabelText(/usuário/i)).toBeInTheDocument(); expect(screen.getByLabelText(/senha/i)).toBeInTheDocument(); expect( screen.getByRole('button', { name: /sign in/i }) ).toBeInTheDocument(); }); it('deve renderizar título quando fornecido', () => { render(, { wrapper: createWrapper() }); expect(screen.getByText('Bem-vindo')).toBeInTheDocument(); }); it('deve renderizar checkbox "Manter-me conectado"', () => { render(, { wrapper: createWrapper() }); expect(screen.getByText(/manter-me conectado/i)).toBeInTheDocument(); }); it('deve renderizar link "Esqueceu sua senha"', () => { render(, { wrapper: createWrapper() }); const link = screen.getByText(/esqueceu sua senha/i); expect(link).toBeInTheDocument(); }); }); describe('Validação', () => { it('deve validar campos obrigatórios', async () => { render(, { wrapper: createWrapper() }); const submitButton = screen.getByRole('button', { name: /sign in/i }); fireEvent.click(submitButton); await waitFor(() => { expect(screen.getByText(/usuário é obrigatório/i)).toBeInTheDocument(); }); }); it('deve validar senha mínima', async () => { render(, { wrapper: createWrapper() }); const usernameInput = screen.getByLabelText(/usuário/i); const passwordInput = screen.getByLabelText(/senha/i); const submitButton = screen.getByRole('button', { name: /sign in/i }); fireEvent.change(usernameInput, { target: { value: 'testuser' } }); fireEvent.change(passwordInput, { target: { value: '123' } }); fireEvent.click(submitButton); await waitFor(() => { expect( screen.getByText(/senha deve ter no mínimo 4 caracteres/i) ).toBeInTheDocument(); }); }); }); describe('Submissão', () => { it('deve submeter formulário com credenciais válidas', async () => { render(, { wrapper: createWrapper() }); const usernameInput = screen.getByLabelText(/usuário/i); const passwordInput = screen.getByLabelText(/senha/i); const submitButton = screen.getByRole('button', { name: /sign in/i }); fireEvent.change(usernameInput, { target: { value: 'testuser' } }); fireEvent.change(passwordInput, { target: { value: 'password123' } }); fireEvent.click(submitButton); await waitFor(() => { expect(mockLoginMutation.mutate).toHaveBeenCalledWith({ username: 'testuser', password: 'password123', }); }); }); }); describe('Estados de Loading e Erro', () => { it('deve desabilitar botão durante loading', () => { const loadingMutation = { ...mockLoginMutation, isPending: true, }; (useAuth as jest.Mock).mockReturnValue({ loginMutation: loadingMutation, }); render(, { wrapper: createWrapper() }); const submitButton = screen.getByRole('button', { name: /logging in/i }); expect(submitButton).toBeDisabled(); }); it('deve mostrar mensagem de erro quando login falha', () => { const errorMutation = { ...mockLoginMutation, isError: true, error: { response: { data: { message: 'Credenciais inválidas' }, }, }, }; (useAuth as jest.Mock).mockReturnValue({ loginMutation: errorMutation, }); render(, { wrapper: createWrapper() }); expect(screen.getByText(/credenciais inválidas/i)).toBeInTheDocument(); }); // 🐛 TESTE QUE REVELA BUG: Erro não limpa durante nova tentativa it('🐛 BUG: deve esconder erro durante nova tentativa de login', () => { const errorAndLoadingMutation = { ...mockLoginMutation, isError: true, isPending: true, // Está tentando novamente error: { response: { data: { message: 'Credenciais inválidas' }, }, }, }; (useAuth as jest.Mock).mockReturnValue({ loginMutation: errorAndLoadingMutation, }); render(, { wrapper: createWrapper() }); // ❌ ESTE TESTE VAI FALHAR - erro ainda aparece durante loading! expect( screen.queryByText(/credenciais inválidas/i) ).not.toBeInTheDocument(); }); }); describe('🐛 Bugs Identificados', () => { // 🐛 BUG: Link "Esqueceu senha" vai para home it('🐛 BUG: link "Esqueceu senha" deve ir para /forgot-password', () => { render(, { wrapper: createWrapper() }); const link = screen.getByText(/esqueceu sua senha/i).closest('a'); // ❌ ESTE TESTE VAI FALHAR - href é "/" expect(link).toHaveAttribute('href', '/forgot-password'); }); // 🐛 BUG: Checkbox não funciona it('🐛 BUG: checkbox "Manter-me conectado" deve ser controlado', () => { render(, { wrapper: createWrapper() }); const checkbox = screen.getByRole('checkbox', { name: /manter-me conectado/i, }); // Checkbox está sempre marcado expect(checkbox).toBeChecked(); // Tenta desmarcar fireEvent.click(checkbox); // ❌ ESTE TESTE VAI FALHAR - checkbox não muda de estado! expect(checkbox).not.toBeChecked(); }); }); });