import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { useAuthStore } from '@/lib/auth-store'; const mockPush = vi.fn(); vi.mock('next/navigation', () => ({ useRouter: () => ({ push: mockPush }), })); vi.mock('next/link', () => ({ default: ({ children, href, ...props }: { children: React.ReactNode; href: string; [key: string]: unknown }) => ( {children} ), })); vi.mock('@/lib/auth-store', () => { const store = { register: vi.fn(), isLoading: false, error: null, clearError: vi.fn(), }; return { useAuthStore: vi.fn((selector) => { if (typeof selector === 'function') return selector(store); return store; }), }; }); import RegisterPage from '../register/page'; const mockedUseAuthStore = vi.mocked(useAuthStore); describe('RegisterPage', () => { let mockStore: { register: ReturnType; isLoading: boolean; error: string | null; clearError: ReturnType; }; beforeEach(() => { vi.clearAllMocks(); mockStore = { register: vi.fn(), isLoading: false, error: null, clearError: vi.fn(), }; mockedUseAuthStore.mockImplementation((selector) => { if (typeof selector === 'function') return (selector as (s: typeof mockStore) => unknown)(mockStore); return mockStore as ReturnType; }); }); it('renders register form with all fields', () => { render(); expect(screen.getByText('Tạo tài khoản')).toBeInTheDocument(); expect(screen.getByLabelText('Họ và tên')).toBeInTheDocument(); expect(screen.getByLabelText('Số điện thoại')).toBeInTheDocument(); expect(screen.getByLabelText(/email/i)).toBeInTheDocument(); expect(screen.getByLabelText('Mật khẩu')).toBeInTheDocument(); expect(screen.getByLabelText('Xác nhận mật khẩu')).toBeInTheDocument(); }); it('renders login link', () => { render(); const loginLink = screen.getByRole('link', { name: /đăng nhập/i }); expect(loginLink).toHaveAttribute('href', '/login'); }); it('submits form with valid data', async () => { mockStore.register.mockResolvedValue(undefined); render(); await userEvent.type(screen.getByLabelText('Họ và tên'), 'Nguyen Van A'); await userEvent.type(screen.getByLabelText('Số điện thoại'), '0912345678'); await userEvent.type(screen.getByLabelText('Mật khẩu'), 'password123'); await userEvent.type(screen.getByLabelText('Xác nhận mật khẩu'), 'password123'); await userEvent.click(screen.getByRole('button', { name: /đăng ký/i })); await waitFor(() => { expect(mockStore.register).toHaveBeenCalledWith({ phone: '0912345678', password: 'password123', fullName: 'Nguyen Van A', email: undefined, }); }); }); it('shows validation error for short password', async () => { render(); await userEvent.type(screen.getByLabelText('Họ và tên'), 'Nguyen Van A'); await userEvent.type(screen.getByLabelText('Số điện thoại'), '0912345678'); await userEvent.type(screen.getByLabelText('Mật khẩu'), 'short'); await userEvent.type(screen.getByLabelText('Xác nhận mật khẩu'), 'short'); await userEvent.click(screen.getByRole('button', { name: /đăng ký/i })); await waitFor(() => { const alerts = screen.getAllByRole('alert'); expect(alerts.length).toBeGreaterThan(0); }); }); it('shows error when passwords do not match', async () => { render(); await userEvent.type(screen.getByLabelText('Họ và tên'), 'Nguyen Van A'); await userEvent.type(screen.getByLabelText('Số điện thoại'), '0912345678'); await userEvent.type(screen.getByLabelText('Mật khẩu'), 'password123'); await userEvent.type(screen.getByLabelText('Xác nhận mật khẩu'), 'differentpw'); await userEvent.click(screen.getByRole('button', { name: /đăng ký/i })); await waitFor(() => { const alerts = screen.getAllByRole('alert'); expect(alerts.length).toBeGreaterThan(0); }); }); it('displays store error message', () => { mockStore.error = 'Số điện thoại đã tồn tại'; render(); expect(screen.getByText('Số điện thoại đã tồn tại')).toBeInTheDocument(); }); it('navigates to home after successful registration', async () => { mockStore.register.mockResolvedValue(undefined); render(); await userEvent.type(screen.getByLabelText('Họ và tên'), 'Nguyen Van A'); await userEvent.type(screen.getByLabelText('Số điện thoại'), '0912345678'); await userEvent.type(screen.getByLabelText('Mật khẩu'), 'password123'); await userEvent.type(screen.getByLabelText('Xác nhận mật khẩu'), 'password123'); await userEvent.click(screen.getByRole('button', { name: /đăng ký/i })); await waitFor(() => { expect(mockPush).toHaveBeenCalledWith('/'); }); }); });