LoginPage.test.tsx 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import React from 'react';
  2. import { describe, it, expect, vi, beforeEach } from 'vitest';
  3. import { screen, fireEvent, waitFor } from '@testing-library/react';
  4. import { LoginPage } from '../../src/components/LoginPage';
  5. import { AuthProvider } from '../../src/hooks/AuthProvider';
  6. import { renderWithProviders } from '../test-utils';
  7. // Mock react-router
  8. vi.mock('react-router', () => ({
  9. useNavigate: () => vi.fn(),
  10. }));
  11. // Mock sonner
  12. vi.mock('sonner', () => ({
  13. toast: {
  14. success: vi.fn(),
  15. error: vi.fn(),
  16. },
  17. }));
  18. // Mock shared UI components - 使用data-testid策略
  19. vi.mock('@d8d/shared-ui-components', () => ({
  20. Button: ({ children, ...props }: any) => {
  21. const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props;
  22. return React.createElement('button', { ...safeProps, 'data-testid': 'button' }, children);
  23. },
  24. Card: ({ children, ...props }: any) => {
  25. const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props;
  26. return React.createElement('div', { ...safeProps, 'data-testid': 'card' }, children);
  27. },
  28. CardContent: ({ children, ...props }: any) => {
  29. const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props;
  30. return React.createElement('div', { ...safeProps, 'data-testid': 'card-content' }, children);
  31. },
  32. CardDescription: ({ children, ...props }: any) => {
  33. const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props;
  34. return React.createElement('div', { ...safeProps, 'data-testid': 'card-description' }, children);
  35. },
  36. CardFooter: ({ children, ...props }: any) => {
  37. const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props;
  38. return React.createElement('div', { ...safeProps, 'data-testid': 'card-footer' }, children);
  39. },
  40. CardHeader: ({ children, ...props }: any) => {
  41. const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props;
  42. return React.createElement('div', { ...safeProps, 'data-testid': 'card-header' }, children);
  43. },
  44. CardTitle: ({ children, ...props }: any) => {
  45. const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props;
  46. return React.createElement('div', { ...safeProps, 'data-testid': 'card-title' }, children);
  47. },
  48. Form: ({ children, ...props }: any) => {
  49. const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props;
  50. return React.createElement('div', { ...safeProps, 'data-testid': 'form' }, children);
  51. },
  52. FormControl: ({ children, ...props }: any) => {
  53. const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props;
  54. return React.createElement('div', { ...safeProps, 'data-testid': 'form-control' }, children);
  55. },
  56. FormField: ({ children, ...props }: any) => {
  57. const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props;
  58. // FormField有一个render函数,需要处理
  59. if (props.render) {
  60. return props.render({ field: {} });
  61. }
  62. return React.createElement('div', { ...safeProps, 'data-testid': 'form-field', name: props.name }, children);
  63. },
  64. FormItem: ({ children, ...props }: any) => {
  65. const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props;
  66. return React.createElement('div', { ...safeProps, 'data-testid': 'form-item' }, children);
  67. },
  68. FormLabel: ({ children, ...props }: any) => {
  69. const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props;
  70. return React.createElement('label', { ...safeProps, 'data-testid': 'form-label' }, children);
  71. },
  72. FormMessage: ({ children, ...props }: any) => {
  73. const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props;
  74. return React.createElement('div', { ...safeProps, 'data-testid': 'form-message' }, children);
  75. },
  76. Input: ({ ...props }: any) => {
  77. const { render, handleSubmit, setValue, getValues, resetField, clearErrors, setError, setFocus, getFieldState, formState, subscribe, trigger, register, watch, reset, unregister, ...safeProps } = props;
  78. return React.createElement('input', { ...safeProps, 'data-testid': 'input' });
  79. },
  80. }));
  81. describe('LoginPage', () => {
  82. beforeEach(() => {
  83. vi.clearAllMocks();
  84. });
  85. const renderWithAuthProvider = (component: React.ReactElement) => {
  86. return renderWithProviders(
  87. <AuthProvider>
  88. {component}
  89. </AuthProvider>
  90. );
  91. };
  92. it('应该渲染登录页面', () => {
  93. renderWithAuthProvider(<LoginPage />);
  94. // 验证页面基本结构
  95. expect(screen.getByTestId('card')).toBeInTheDocument();
  96. expect(screen.getByTestId('form')).toBeInTheDocument();
  97. expect(screen.getByTestId('button')).toBeInTheDocument();
  98. });
  99. it('应该显示用户名和密码输入框', () => {
  100. renderWithAuthProvider(<LoginPage />);
  101. // 验证输入框存在
  102. const inputs = screen.getAllByTestId('input');
  103. expect(inputs.length).toBeGreaterThan(0);
  104. });
  105. it('应该显示登录按钮', () => {
  106. renderWithAuthProvider(<LoginPage />);
  107. // 验证按钮存在
  108. const buttons = screen.getAllByTestId('button');
  109. expect(buttons.length).toBeGreaterThan(0);
  110. });
  111. });