blob: 02011be0ba37c327eb1890f231751150bdfc9a24 [file] [log] [blame]
Akane12173a7bb972025-06-01 01:05:27 +08001// Setting.test.jsx
2import React from 'react';
3import { render, screen, waitFor, fireEvent } from '@testing-library/react';
4import { MemoryRouter, useNavigate, useLocation } from 'react-router-dom';
5import Setting from './Setting';
6import { getUserInfo, updatePassword } from '../../api/personal';
7
8// Mock API 调用
9jest.mock('../../api/personal', () => ({
10 getUserInfo: jest.fn(),
11 updatePassword: jest.fn()
12}));
13
14// Mock react-router-dom hooks
15jest.mock('react-router-dom', () => ({
16 ...jest.requireActual('react-router-dom'),
17 useNavigate: jest.fn(),
18 useLocation: jest.fn()
19}));
20
21describe('Setting Component', () => {
22 const mockNavigate = jest.fn();
23 const mockLocation = {
24 pathname: '/personal/setting',
25 state: { dashboardTab: 'settings' }
26 };
27
28 beforeEach(() => {
29 useNavigate.mockReturnValue(mockNavigate);
30 useLocation.mockReturnValue(mockLocation);
31
32 // 重置所有 mock
33 jest.clearAllMocks();
34
35 // 设置默认 mock 返回值
36 getUserInfo.mockResolvedValue({
37 username: 'testuser',
38 email: 'test@example.com'
39 });
40
41 updatePassword.mockResolvedValue({ success: true });
42 });
43
44 it('应该正确加载并显示用户信息', async () => {
45 render(
46 <MemoryRouter>
47 <Setting />
48 </MemoryRouter>
49 );
50
51 await waitFor(() => {
52 expect(screen.getByText('个人设置')).toBeInTheDocument();
53 expect(screen.getByText('账户信息')).toBeInTheDocument();
54 expect(screen.getByText('用户名:')).toBeInTheDocument();
55 expect(screen.getByText('testuser')).toBeInTheDocument();
56 expect(screen.getByRole('heading', { name: '修改密码' })).toBeInTheDocument();
57 });
58 });
59
60 it('应该处理密码修改表单提交', async () => {
61 render(
62 <MemoryRouter>
63 <Setting />
64 </MemoryRouter>
65 );
66
67 // 填写表单
68 fireEvent.change(screen.getByLabelText('原密码:'), {
69 target: { value: 'oldpassword123' }
70 });
71 fireEvent.change(screen.getByLabelText('新密码:'), {
72 target: { value: 'newpassword123' }
73 });
74 fireEvent.change(screen.getByLabelText('确认新密码:'), {
75 target: { value: 'newpassword123' }
76 });
77
78 // 提交表单
79 fireEvent.click(screen.getByRole('button', { name: '修改密码' }));
80
81 await waitFor(() => {
82 expect(updatePassword).toHaveBeenCalledWith('oldpassword123', 'newpassword123');
83 expect(screen.getByText('密码修改成功')).toBeInTheDocument();
84 });
85 });
86
87
88 it('应该处理API错误', async () => {
89 updatePassword.mockRejectedValue(new Error('原密码不正确'));
90
91 render(
92 <MemoryRouter>
93 <Setting />
94 </MemoryRouter>
95 );
96
97 // 填写表单
98 fireEvent.change(screen.getByLabelText('原密码:'), {
99 target: { value: 'wrongpassword' }
100 });
101 fireEvent.change(screen.getByLabelText('新密码:'), {
102 target: { value: 'newpassword123' }
103 });
104 fireEvent.change(screen.getByLabelText('确认新密码:'), {
105 target: { value: 'newpassword123' }
106 });
107
108 // 提交表单
109 fireEvent.click(screen.getByRole('button', { name: '修改密码' }));
110
111 await waitFor(() => {
112 expect(screen.getByText('原密码不正确')).toBeInTheDocument();
113 });
114 });
115
116 it('应该显示加载状态', async () => {
117 // 延迟API响应以测试加载状态
118 updatePassword.mockImplementation(() => new Promise(() => {}));
119
120 render(
121 <MemoryRouter>
122 <Setting />
123 </MemoryRouter>
124 );
125
126 // 填写表单
127 fireEvent.change(screen.getByLabelText('原密码:'), {
128 target: { value: 'oldpassword123' }
129 });
130 fireEvent.change(screen.getByLabelText('新密码:'), {
131 target: { value: 'newpassword123' }
132 });
133 fireEvent.change(screen.getByLabelText('确认新密码:'), {
134 target: { value: 'newpassword123' }
135 });
136
137 // 提交表单
138 fireEvent.click(screen.getByRole('button', { name: '修改密码' }));
139
140 // 检查加载状态
141 expect(screen.getByText('处理中...')).toBeInTheDocument();
142 expect(screen.getByRole('button', { name: '处理中...' })).toBeDisabled();
143 });
144
145 it('应该处理返回按钮点击', async () => {
146 render(
147 <MemoryRouter>
148 <Setting />
149 </MemoryRouter>
150 );
151
DREW5b1883e2025-06-07 10:41:32 +0800152 const backButton = screen.getByText(/返回个人中心/);
Akane12173a7bb972025-06-01 01:05:27 +0800153 fireEvent.click(backButton);
154
155 expect(mockNavigate).toHaveBeenCalledWith('/personal', {
156 state: {
157 fromSubpage: true,
158 dashboardTab: 'settings'
159 },
160 replace: true
161 });
162 });
163
164 it('应该清空表单并显示成功消息', async () => {
165 render(
166 <MemoryRouter>
167 <Setting />
168 </MemoryRouter>
169 );
170
171 // 填写表单
172 fireEvent.change(screen.getByLabelText('原密码:'), {
173 target: { value: 'oldpassword123' }
174 });
175 fireEvent.change(screen.getByLabelText('新密码:'), {
176 target: { value: 'newpassword123' }
177 });
178 fireEvent.change(screen.getByLabelText('确认新密码:'), {
179 target: { value: 'newpassword123' }
180 });
181
182 // 提交表单
183 fireEvent.click(screen.getByRole('button', { name: '修改密码' }));
184
185 await waitFor(() => {
186 // 检查表单是否清空
187 expect(screen.getByLabelText('原密码:')).toHaveValue('');
188 expect(screen.getByLabelText('新密码:')).toHaveValue('');
189 expect(screen.getByLabelText('确认新密码:')).toHaveValue('');
190
191 // 检查成功消息
192 expect(screen.getByText('密码修改成功')).toBeInTheDocument();
193 });
194 });
195});