veza/apps/web/src/features/auth/components/LoginForm.test.tsx

207 lines
5.7 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, waitFor, fireEvent } from '@/test/helpers';
import { BrowserRouter } from 'react-router-dom';
import { LoginForm } from './LoginForm';
import * as emailVerificationService from '../services/emailVerificationService';
// Mock useAuthStore
const mockLogin = vi.fn();
const mockClearError = vi.fn();
const mockError = { message: '', code: '' };
vi.mock('@/features/auth/store/authStore', () => ({
useAuthStore: () => ({
login: mockLogin,
isLoading: false,
error: mockError,
clearError: mockClearError,
}),
}));
// Mock useTranslation
vi.mock('@/hooks/useTranslation', () => ({
useTranslation: () => ({
t: (key: string) => key,
}),
}));
// Mock emailVerificationService
vi.mock('../services/emailVerificationService', () => ({
resendVerificationEmail: vi.fn(),
}));
describe('LoginForm - Resend Verification Email', () => {
beforeEach(() => {
vi.clearAllMocks();
mockError.message = '';
mockError.code = '';
});
describe('Resend verification email button', () => {
it('should display resend button when error indicates email not verified', async () => {
mockError.message = 'Email not verified';
render(
<BrowserRouter>
<LoginForm />
</BrowserRouter>,
);
await waitFor(() => {
expect(screen.getByText(/email not verified/i)).toBeInTheDocument();
expect(
screen.getByText(/resend verification email/i),
).toBeInTheDocument();
});
});
it('should not display resend button for other errors', async () => {
mockError.message = 'Invalid credentials';
render(
<BrowserRouter>
<LoginForm />
</BrowserRouter>,
);
await waitFor(() => {
expect(screen.getByText(/invalid credentials/i)).toBeInTheDocument();
expect(
screen.queryByText(/resend verification email/i),
).not.toBeInTheDocument();
});
});
it('should call resendVerificationEmail when resend button is clicked', async () => {
mockError.message = 'Email not verified';
vi.mocked(
emailVerificationService.resendVerificationEmail,
).mockResolvedValue({
message: 'verification email sent',
});
render(
<BrowserRouter>
<LoginForm />
</BrowserRouter>,
);
await waitFor(() => {
expect(
screen.getByText(/resend verification email/i),
).toBeInTheDocument();
});
const emailInput = screen.getByLabelText(/email/i);
fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
const resendButton = screen.getByText(/resend verification email/i);
fireEvent.click(resendButton);
await waitFor(() => {
expect(
emailVerificationService.resendVerificationEmail,
).toHaveBeenCalledWith('test@example.com');
});
});
it('should display cooldown countdown after resending email', async () => {
mockError.message = 'Email not verified';
vi.mocked(
emailVerificationService.resendVerificationEmail,
).mockResolvedValue({
message: 'verification email sent',
});
vi.useFakeTimers();
render(
<BrowserRouter>
<LoginForm />
</BrowserRouter>,
);
await waitFor(() => {
expect(
screen.getByText(/resend verification email/i),
).toBeInTheDocument();
});
const emailInput = screen.getByLabelText(/email/i);
fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
const resendButton = screen.getByText(/resend verification email/i);
fireEvent.click(resendButton);
await waitFor(() => {
expect(screen.getByText(/resend in/i)).toBeInTheDocument();
});
vi.useRealTimers();
});
it('should display confirmation message after successful resend', async () => {
mockError.message = 'Email not verified';
vi.mocked(
emailVerificationService.resendVerificationEmail,
).mockResolvedValue({
message: 'verification email sent',
});
render(
<BrowserRouter>
<LoginForm />
</BrowserRouter>,
);
await waitFor(() => {
expect(
screen.getByText(/resend verification email/i),
).toBeInTheDocument();
});
const emailInput = screen.getByLabelText(/email/i);
fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
const resendButton = screen.getByText(/resend verification email/i);
fireEvent.click(resendButton);
await waitFor(() => {
expect(
screen.getByText(/verification email sent/i),
).toBeInTheDocument();
});
});
it('should display error message when resend fails', async () => {
mockError.message = 'Email not verified';
vi.mocked(
emailVerificationService.resendVerificationEmail,
).mockRejectedValue({
message: 'Failed to resend email',
code: '500',
});
render(
<BrowserRouter>
<LoginForm />
</BrowserRouter>,
);
await waitFor(() => {
expect(
screen.getByText(/resend verification email/i),
).toBeInTheDocument();
});
const emailInput = screen.getByLabelText(/email/i);
fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
const resendButton = screen.getByText(/resend verification email/i);
fireEvent.click(resendButton);
await waitFor(() => {
expect(screen.getByText(/failed to resend email/i)).toBeInTheDocument();
});
});
});
});