import React from 'react'; import { describe, it, expect, vi, beforeEach } from 'vitest'; import { screen, fireEvent, waitFor } from '@testing-library/react'; import { LoginPage } from '../../src/components/LoginPage'; import { AuthProvider } from '../../src/hooks/AuthProvider'; import { renderWithProviders } from '../test-utils'; // Mock react-router vi.mock('react-router', () => ({ useNavigate: () => vi.fn(), })); // Mock sonner vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn(), }, })); // Mock shared UI components - 使用data-testid策略 vi.mock('@d8d/shared-ui-components', () => ({ Button: ({ children, ...props }: any) => { const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props; return React.createElement('button', { ...safeProps, 'data-testid': 'button' }, children); }, Card: ({ children, ...props }: any) => { const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props; return React.createElement('div', { ...safeProps, 'data-testid': 'card' }, children); }, CardContent: ({ children, ...props }: any) => { const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props; return React.createElement('div', { ...safeProps, 'data-testid': 'card-content' }, children); }, CardDescription: ({ children, ...props }: any) => { const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props; return React.createElement('div', { ...safeProps, 'data-testid': 'card-description' }, children); }, CardFooter: ({ children, ...props }: any) => { const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props; return React.createElement('div', { ...safeProps, 'data-testid': 'card-footer' }, children); }, CardHeader: ({ children, ...props }: any) => { const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props; return React.createElement('div', { ...safeProps, 'data-testid': 'card-header' }, children); }, CardTitle: ({ children, ...props }: any) => { const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props; return React.createElement('div', { ...safeProps, 'data-testid': 'card-title' }, children); }, Form: ({ children, ...props }: any) => { const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props; return React.createElement('div', { ...safeProps, 'data-testid': 'form' }, children); }, FormControl: ({ children, ...props }: any) => { const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props; return React.createElement('div', { ...safeProps, 'data-testid': 'form-control' }, children); }, FormField: ({ children, ...props }: any) => { const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props; // FormField有一个render函数,需要处理 if (props.render) { return props.render({ field: {} }); } return React.createElement('div', { ...safeProps, 'data-testid': 'form-field', name: props.name }, children); }, FormItem: ({ children, ...props }: any) => { const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props; return React.createElement('div', { ...safeProps, 'data-testid': 'form-item' }, children); }, FormLabel: ({ children, ...props }: any) => { const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props; return React.createElement('label', { ...safeProps, 'data-testid': 'form-label' }, children); }, FormMessage: ({ children, ...props }: any) => { const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props; return React.createElement('div', { ...safeProps, 'data-testid': 'form-message' }, children); }, Input: ({ ...props }: any) => { const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props; return React.createElement('input', { ...safeProps, 'data-testid': 'input' }); }, })); describe('LoginPage', () => { beforeEach(() => { vi.clearAllMocks(); }); const renderWithAuthProvider = (component: React.ReactElement) => { return renderWithProviders( {component} ); }; it('应该渲染登录页面', () => { renderWithAuthProvider(); // 验证页面基本结构 expect(screen.getByTestId('card')).toBeInTheDocument(); expect(screen.getByTestId('form')).toBeInTheDocument(); expect(screen.getByTestId('button')).toBeInTheDocument(); }); it('应该显示用户名和密码输入框', () => { renderWithAuthProvider(); // 验证输入框存在 const inputs = screen.getAllByTestId('input'); expect(inputs.length).toBeGreaterThan(0); }); it('应该显示登录按钮', () => { renderWithAuthProvider(); // 验证按钮存在 const buttons = screen.getAllByTestId('button'); expect(buttons.length).toBeGreaterThan(0); }); });