blob: e8b1cc04f38946d4dcd1db07733766d277718400 [file] [log] [blame]
// Setting.test.jsx
import React from 'react';
import { render, screen, waitFor, fireEvent } from '@testing-library/react';
import { MemoryRouter, useNavigate, useLocation } from 'react-router-dom';
import Setting from './Setting';
import { getUserInfo, updatePassword } from '../../api/personal';
// Mock API 调用
jest.mock('../../api/personal', () => ({
getUserInfo: jest.fn(),
updatePassword: jest.fn()
}));
// Mock react-router-dom hooks
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useNavigate: jest.fn(),
useLocation: jest.fn()
}));
describe('Setting Component', () => {
const mockNavigate = jest.fn();
const mockLocation = {
pathname: '/personal/setting',
state: { dashboardTab: 'settings' }
};
beforeEach(() => {
useNavigate.mockReturnValue(mockNavigate);
useLocation.mockReturnValue(mockLocation);
// 重置所有 mock
jest.clearAllMocks();
// 设置默认 mock 返回值
getUserInfo.mockResolvedValue({
username: 'testuser',
email: 'test@example.com'
});
updatePassword.mockResolvedValue({ success: true });
});
it('应该正确加载并显示用户信息', async () => {
render(
<MemoryRouter>
<Setting />
</MemoryRouter>
);
await waitFor(() => {
expect(screen.getByText('个人设置')).toBeInTheDocument();
expect(screen.getByText('账户信息')).toBeInTheDocument();
expect(screen.getByText('用户名:')).toBeInTheDocument();
expect(screen.getByText('testuser')).toBeInTheDocument();
expect(screen.getByRole('heading', { name: '修改密码' })).toBeInTheDocument();
});
});
it('应该处理密码修改表单提交', async () => {
render(
<MemoryRouter>
<Setting />
</MemoryRouter>
);
// 填写表单
fireEvent.change(screen.getByLabelText('原密码:'), {
target: { value: 'oldpassword123' }
});
fireEvent.change(screen.getByLabelText('新密码:'), {
target: { value: 'newpassword123' }
});
fireEvent.change(screen.getByLabelText('确认新密码:'), {
target: { value: 'newpassword123' }
});
// 提交表单
fireEvent.click(screen.getByRole('button', { name: '修改密码' }));
await waitFor(() => {
expect(updatePassword).toHaveBeenCalledWith('oldpassword123', 'newpassword123');
expect(screen.getByText('密码修改成功')).toBeInTheDocument();
});
});
it('应该处理API错误', async () => {
updatePassword.mockRejectedValue(new Error('原密码不正确'));
render(
<MemoryRouter>
<Setting />
</MemoryRouter>
);
// 填写表单
fireEvent.change(screen.getByLabelText('原密码:'), {
target: { value: 'wrongpassword' }
});
fireEvent.change(screen.getByLabelText('新密码:'), {
target: { value: 'newpassword123' }
});
fireEvent.change(screen.getByLabelText('确认新密码:'), {
target: { value: 'newpassword123' }
});
// 提交表单
fireEvent.click(screen.getByRole('button', { name: '修改密码' }));
await waitFor(() => {
expect(screen.getByText('原密码不正确')).toBeInTheDocument();
});
});
it('应该显示加载状态', async () => {
// 延迟API响应以测试加载状态
updatePassword.mockImplementation(() => new Promise(() => {}));
render(
<MemoryRouter>
<Setting />
</MemoryRouter>
);
// 填写表单
fireEvent.change(screen.getByLabelText('原密码:'), {
target: { value: 'oldpassword123' }
});
fireEvent.change(screen.getByLabelText('新密码:'), {
target: { value: 'newpassword123' }
});
fireEvent.change(screen.getByLabelText('确认新密码:'), {
target: { value: 'newpassword123' }
});
// 提交表单
fireEvent.click(screen.getByRole('button', { name: '修改密码' }));
// 检查加载状态
expect(screen.getByText('处理中...')).toBeInTheDocument();
expect(screen.getByRole('button', { name: '处理中...' })).toBeDisabled();
});
it('应该处理返回按钮点击', async () => {
render(
<MemoryRouter>
<Setting />
</MemoryRouter>
);
const backButton = screen.getByText(/← 返回个人中心/);
fireEvent.click(backButton);
expect(mockNavigate).toHaveBeenCalledWith('/personal', {
state: {
fromSubpage: true,
dashboardTab: 'settings'
},
replace: true
});
});
it('应该清空表单并显示成功消息', async () => {
render(
<MemoryRouter>
<Setting />
</MemoryRouter>
);
// 填写表单
fireEvent.change(screen.getByLabelText('原密码:'), {
target: { value: 'oldpassword123' }
});
fireEvent.change(screen.getByLabelText('新密码:'), {
target: { value: 'newpassword123' }
});
fireEvent.change(screen.getByLabelText('确认新密码:'), {
target: { value: 'newpassword123' }
});
// 提交表单
fireEvent.click(screen.getByRole('button', { name: '修改密码' }));
await waitFor(() => {
// 检查表单是否清空
expect(screen.getByLabelText('原密码:')).toHaveValue('');
expect(screen.getByLabelText('新密码:')).toHaveValue('');
expect(screen.getByLabelText('确认新密码:')).toHaveValue('');
// 检查成功消息
expect(screen.getByText('密码修改成功')).toBeInTheDocument();
});
});
});