个人中心全部,模糊乱序搜索,类型筛选
Change-Id: Id635654fccccaea80bfbf4d1480abd55f7d12046
diff --git a/src/components/Personal/Exchange.test.jsx b/src/components/Personal/Exchange.test.jsx
new file mode 100644
index 0000000..20fe641
--- /dev/null
+++ b/src/components/Personal/Exchange.test.jsx
@@ -0,0 +1,196 @@
+import React from 'react';
+import { render, screen, waitFor, fireEvent } from '@testing-library/react';
+import { MemoryRouter, useNavigate, useLocation } from 'react-router-dom';
+import Exchange from './Exchange';
+import {
+ generateInviteCode,
+ getUserInviteCodes,
+ exchangeUpload,
+ getUserInfo
+} from '../../api/personal';
+
+// Mock API 调用
+jest.mock('../../api/personal', () => ({
+ generateInviteCode: jest.fn(),
+ getUserInviteCodes: jest.fn(),
+ exchangeUpload: jest.fn(),
+ getUserInfo: jest.fn()
+}));
+
+// Mock react-router-dom hooks
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
+ useNavigate: jest.fn(),
+ useLocation: jest.fn()
+}));
+
+describe('Exchange Component', () => {
+ const mockNavigate = jest.fn();
+ const mockLocation = {
+ pathname: '/personal/exchange',
+ state: { dashboardTab: 'exchange' }
+ };
+
+ const mockUserInfo = {
+ magicPoints: 100,
+ username: 'testuser'
+ };
+
+ const mockInviteCodes = [
+ { code: 'ABCD-1234', isUsed: false },
+ { code: 'EFGH-5678', isUsed: true }
+ ];
+
+ beforeEach(() => {
+ useNavigate.mockReturnValue(mockNavigate);
+ useLocation.mockReturnValue(mockLocation);
+ jest.clearAllMocks();
+
+ // 设置默认 mock 返回值
+ getUserInfo.mockResolvedValue(mockUserInfo);
+ getUserInviteCodes.mockResolvedValue(mockInviteCodes);
+ generateInviteCode.mockResolvedValue({ code: 'NEW-CODE', isUsed: false });
+ exchangeUpload.mockResolvedValue({ success: true });
+ });
+
+ it('应该正确加载并显示用户信息和邀请码', async () => {
+ render(
+ <MemoryRouter>
+ <Exchange />
+ </MemoryRouter>
+ );
+
+ // 初始加载状态
+ expect(screen.getByText('加载中...')).toBeInTheDocument();
+
+ // 等待数据加载完成
+ await waitFor(() => {
+ expect(screen.getByText('兑换区')).toBeInTheDocument();
+ expect(screen.getByText('当前魔力值: 100')).toBeInTheDocument();
+ expect(screen.getByText('ABCD-1234')).toBeInTheDocument();
+ expect(screen.getByText('EFGH-5678')).toBeInTheDocument();
+ expect(screen.getByText('可用')).toBeInTheDocument();
+ expect(screen.getByText('已使用')).toBeInTheDocument();
+ });
+ });
+
+ it('应该处理生成邀请码操作', async () => {
+ render(
+ <MemoryRouter>
+ <Exchange />
+ </MemoryRouter>
+ );
+
+ await waitFor(() => {
+ // 使用更精确的选择器定位按钮
+ const generateButtons = screen.getAllByRole('button', { name: '兑换邀请码' });
+ // 选择第一个按钮(或根据实际情况选择正确的按钮)
+ fireEvent.click(generateButtons[0]);
+ });
+
+ expect(generateInviteCode).toHaveBeenCalled();
+ await waitFor(() => {
+ expect(getUserInfo).toHaveBeenCalledTimes(2); // 初始加载 + 生成后刷新
+ });
+ });
+
+ it('应该处理兑换上传量操作', async () => {
+ render(
+ <MemoryRouter>
+ <Exchange />
+ </MemoryRouter>
+ );
+
+ await waitFor(() => {
+ const input = screen.getByPlaceholderText('输入要兑换的魔力值');
+ const exchangeButton = screen.getByRole('button', { name: '兑换上传量' });
+
+ // 输入有效值
+ fireEvent.change(input, { target: { value: '50' } });
+ fireEvent.click(exchangeButton);
+ });
+
+ expect(exchangeUpload).toHaveBeenCalledWith(50);
+ await waitFor(() => {
+ expect(getUserInfo).toHaveBeenCalledTimes(2); // 初始加载 + 兑换后刷新
+ });
+ });
+
+
+ it('应该处理返回按钮点击', async () => {
+ render(
+ <MemoryRouter>
+ <Exchange />
+ </MemoryRouter>
+ );
+
+ await waitFor(() => {
+ const backButton = screen.getByText(/← 返回个人中心/);
+ fireEvent.click(backButton);
+
+ expect(mockNavigate).toHaveBeenCalledWith('/personal', {
+ state: {
+ fromSubpage: true,
+ dashboardTab: 'exchange'
+ },
+ replace: true
+ });
+ });
+ });
+
+ it('应该显示错误信息当API调用失败', async () => {
+ getUserInfo.mockRejectedValueOnce(new Error('获取用户信息失败'));
+
+ render(
+ <MemoryRouter>
+ <Exchange />
+ </MemoryRouter>
+ );
+
+ await waitFor(() => {
+ expect(screen.getByText('错误: 获取用户信息失败')).toBeInTheDocument();
+ });
+ });
+
+ it('应该禁用兑换按钮当魔力值不足', async () => {
+ getUserInfo.mockResolvedValueOnce({ magicPoints: 5 }); // 设置魔力值不足
+
+ render(
+ <MemoryRouter>
+ <Exchange />
+ </MemoryRouter>
+ );
+
+ await waitFor(() => {
+ const inviteButtons = screen.getAllByRole('button', { name: '兑换邀请码' });
+ expect(inviteButtons[0]).toBeDisabled();
+ });
+ });
+
+ it('应该正确处理空邀请码列表', async () => {
+ getUserInviteCodes.mockResolvedValueOnce([]);
+
+ render(
+ <MemoryRouter>
+ <Exchange />
+ </MemoryRouter>
+ );
+
+ await waitFor(() => {
+ expect(screen.queryByText('我的邀请码')).not.toBeInTheDocument();
+ });
+ });
+
+ it('应该显示加载状态', async () => {
+ // 延迟API响应以测试加载状态
+ getUserInfo.mockImplementation(() => new Promise(() => {}));
+
+ render(
+ <MemoryRouter>
+ <Exchange />
+ </MemoryRouter>
+ );
+
+ expect(screen.getByText('加载中...')).toBeInTheDocument();
+ });
+});
\ No newline at end of file