import { describe, it, expect, vi, beforeEach } from 'vitest'; import { screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; vi.mock('../../src/api/usrApi', () => ({ fetchCompanies: vi.fn(), login: vi.fn(), })); import { fetchCompanies, login } from '../../src/api/usrApi'; import LoginPage from '../../src/pages/usr/Login/LoginPage'; import { renderWithProviders } from './renderLogin'; const mockedFetch = fetchCompanies as unknown as ReturnType; const mockedLogin = login as unknown as ReturnType; async function selectVersion(user: ReturnType, label: string) { const combobox = screen.getByRole('combobox'); await user.click(combobox); const option = await screen.findByText(label); await user.click(option); } describe('LoginPage 必填校验', () => { beforeEach(() => { vi.clearAllMocks(); localStorage.clear(); mockedFetch.mockResolvedValue([ { id: 1, sCompanyName: '甲公司', sVersion: '标准版' }, { id: 2, sCompanyName: '乙公司', sVersion: null }, ]); }); it('blocks submit and shows required messages when empty', async () => { renderWithProviders(); // 等待版本加载完成 expect(await screen.findByText('请选择版本')).toBeInTheDocument(); const user = userEvent.setup(); await user.click(screen.getByRole('button', { name: /登\s*录/ })); // 校验错误文案渲染在 .ant-form-item-explain-error,逐条断言(避免与 Select placeholder 文案冲突) await waitFor(() => { const errors = Array.from( document.querySelectorAll('.ant-form-item-explain-error'), ).map((el) => el.textContent); expect(errors).toContain('请输入用户名'); expect(errors).toContain('请输入密码'); expect(errors).toContain('请选择版本'); }); expect(mockedLogin).not.toHaveBeenCalled(); }); it('submits with payload when all filled', async () => { mockedLogin.mockReturnValue(new Promise(() => {})); // 挂起,只断言入参 renderWithProviders(); expect(await screen.findByText('请选择版本')).toBeInTheDocument(); const user = userEvent.setup(); await user.type(screen.getByPlaceholderText('请输入你的用户名'), 'admin'); await user.type(screen.getByPlaceholderText('请输入你的密码'), 'secret'); await selectVersion(user, '乙公司'); await user.click(screen.getByRole('button', { name: /登\s*录/ })); await waitFor(() => expect(mockedLogin).toHaveBeenCalledWith({ sUserName: 'admin', password: 'secret', companyId: 2, }), ); }); });