import { describe, it, expect, beforeEach, vi } from 'vitest'; import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { renderWithProviders } from '@/test/utils'; vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn() } })); vi.mock('@/components/ui/PwaLoginCard', () => ({ default: () => null })); // Altcha هنگام mount خودش fetch می‌زند؛ استاب‌کردنش «بدون fetch» را واقعاً معنادار می‌کند vi.mock('@/components/ui/Altcha', () => ({ default: () => null })); import { toast } from 'sonner'; import LoginPage from '@/pages/LoginPage'; const errorToast = toast.error as ReturnType; beforeEach(() => { vi.stubGlobal('fetch', vi.fn()); }); describe('LoginPage — حالت رمز عبور', () => { it('submit با فیلد خالی → خطای اعتبارسنجی و بدون fetch', async () => { renderWithProviders(, { route: '/admin/login' }); await userEvent.click(screen.getByRole('button', { name: 'ورود به سیستم' })); expect(errorToast).toHaveBeenCalledWith('شماره موبایل و رمز عبور الزامی است'); expect(fetch).not.toHaveBeenCalled(); }); }); describe('LoginPage — تعویض حالت', () => { it('کلیک «ورود با پیامک» فرم پیامک را نشان می‌دهد', async () => { renderWithProviders(, { route: '/admin/login' }); await userEvent.click(screen.getByRole('button', { name: 'ورود با پیامک' })); expect(screen.getByRole('button', { name: 'ارسال کد تأیید' })).toBeInTheDocument(); }); it('شماره موبایل نامعتبر در حالت پیامک → خطا', async () => { renderWithProviders(, { route: '/admin/login' }); await userEvent.click(screen.getByRole('button', { name: 'ورود با پیامک' })); await userEvent.type(screen.getByPlaceholderText('09xxxxxxxxx'), '12345'); await userEvent.click(screen.getByRole('button', { name: 'ارسال کد تأیید' })); expect(errorToast).toHaveBeenCalledWith('شماره موبایل معتبر نیست'); }); });