mediahub-fe/__tests__/auth-flow.test.ts

167 lines
4.8 KiB
TypeScript

import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { AuthPage } from '../app/[locale]/auth/page';
import { useEmailValidation } from '../hooks/use-auth';
// Mock the hooks
jest.mock('../hooks/use-auth', () => ({
useAuth: () => ({
login: jest.fn(),
logout: jest.fn(),
refreshToken: jest.fn(),
isAuthenticated: false,
user: null,
loading: false,
error: null,
}),
useEmailValidation: jest.fn(),
useEmailSetup: () => ({
setupEmail: jest.fn(),
loading: false,
error: null,
}),
useOTPVerification: () => ({
verifyOTP: jest.fn(),
loading: false,
error: null,
}),
}));
// Mock the components
jest.mock('../components/auth/auth-layout', () => ({
AuthLayout: ({ children }: { children: React.ReactNode }) => <div data-testid="auth-layout">{children}</div>,
}));
jest.mock('../components/auth/login-form', () => ({
LoginForm: ({ onSuccess, onError }: any) => (
<div data-testid="login-form">
<button onClick={() => onSuccess({ username: 'testuser', password: 'testpass' })}>
Login Success
</button>
<button onClick={() => onError('Login failed')}>
Login Error
</button>
</div>
),
}));
jest.mock('../components/auth/email-setup-form', () => ({
EmailSetupForm: ({ onSuccess, onError, onBack }: any) => (
<div data-testid="email-setup-form">
<button onClick={() => onSuccess()}>Email Setup Success</button>
<button onClick={() => onError('Email setup failed')}>Email Setup Error</button>
<button onClick={() => onBack()}>Back</button>
</div>
),
}));
jest.mock('../components/auth/otp-form', () => ({
OTPForm: ({ onSuccess, onError, onResend }: any) => (
<div data-testid="otp-form">
<button onClick={() => onSuccess()}>OTP Success</button>
<button onClick={() => onError('OTP failed')}>OTP Error</button>
<button onClick={() => onResend()}>Resend OTP</button>
</div>
),
}));
// Mock toast
jest.mock('sonner', () => ({
toast: {
error: jest.fn(),
success: jest.fn(),
info: jest.fn(),
},
}));
describe('Auth Flow', () => {
const mockValidateEmail = jest.fn();
beforeEach(() => {
jest.clearAllMocks();
(useEmailValidation as jest.Mock).mockReturnValue({
validateEmail: mockValidateEmail,
loading: false,
error: null,
});
});
it('should start with login form', () => {
render(<AuthPage params={{ locale: 'en' }} />);
expect(screen.getByTestId('login-form')).toBeInTheDocument();
});
it('should transition to email setup when validation returns "setup"', async () => {
mockValidateEmail.mockResolvedValue('setup');
render(<AuthPage params={{ locale: 'en' }} />);
// Click login success to trigger email validation
fireEvent.click(screen.getByText('Login Success'));
await waitFor(() => {
expect(screen.getByTestId('email-setup-form')).toBeInTheDocument();
});
});
it('should transition to OTP when validation returns "otp"', async () => {
mockValidateEmail.mockResolvedValue('otp');
render(<AuthPage params={{ locale: 'en' }} />);
// Click login success to trigger email validation
fireEvent.click(screen.getByText('Login Success'));
await waitFor(() => {
expect(screen.getByTestId('otp-form')).toBeInTheDocument();
});
});
it('should stay on login when validation returns "success"', async () => {
mockValidateEmail.mockResolvedValue('success');
render(<AuthPage params={{ locale: 'en' }} />);
// Click login success to trigger email validation
fireEvent.click(screen.getByText('Login Success'));
await waitFor(() => {
expect(screen.getByTestId('login-form')).toBeInTheDocument();
});
});
it('should transition from email setup to OTP', async () => {
mockValidateEmail.mockResolvedValue('setup');
render(<AuthPage params={{ locale: 'en' }} />);
// First, go to email setup
fireEvent.click(screen.getByText('Login Success'));
await waitFor(() => {
expect(screen.getByTestId('email-setup-form')).toBeInTheDocument();
});
// Then go to OTP
fireEvent.click(screen.getByText('Email Setup Success'));
await waitFor(() => {
expect(screen.getByTestId('otp-form')).toBeInTheDocument();
});
});
it('should go back from email setup to login', async () => {
mockValidateEmail.mockResolvedValue('setup');
render(<AuthPage params={{ locale: 'en' }} />);
// First, go to email setup
fireEvent.click(screen.getByText('Login Success'));
await waitFor(() => {
expect(screen.getByTestId('email-setup-form')).toBeInTheDocument();
});
// Then go back to login
fireEvent.click(screen.getByText('Back'));
await waitFor(() => {
expect(screen.getByTestId('login-form')).toBeInTheDocument();
});
});
});