保存本地对routes.ts的修改

Change-Id: I4f4dbd8069893d7363e251130791dc0594be44e1
diff --git a/src/test/work/WorkPage.test.tsx b/src/test/work/WorkPage.test.tsx
new file mode 100644
index 0000000..4dc5036
--- /dev/null
+++ b/src/test/work/WorkPage.test.tsx
@@ -0,0 +1,268 @@
+import { render, screen } from '@testing-library/react';
+import WorkPage from '../../feature/work/WorkPage';
+import { Provider } from 'react-redux';
+import { store } from '../../store/store';
+import { MemoryRouter, Route, Routes, useNavigate } from 'react-router';
+import { act } from 'react-dom/test-utils';
+import WorkAPI from '../../api/workApi';
+import type { Work } from '../../api/otherType';
+import '@testing-library/jest-dom';
+
+// 模拟整个WorkAPI类
+jest.mock('../../api/workApi', () => {
+  return {
+    __esModule: true,
+    default: {
+      getWorkById: jest.fn(),
+      likeWork: jest.fn(),
+      // 添加其他可能用到的方法
+      getBugReports: jest.fn(),
+      getDiscussions: jest.fn()
+    }
+  }
+});
+
+// 模拟子组件
+jest.mock('../../components/BugReportSection', () => () => (
+  <div data-testid="bug-report-mock">BugReportSection Mock</div>
+));
+
+jest.mock('../../components/DiscussionSection', () => () => (
+  <div data-testid="discussion-mock">DiscussionSection Mock</div>
+));
+
+// 模拟react-router-dom的useNavigate
+jest.mock('react-router-dom', () => ({
+  ...jest.requireActual('react-router-dom'),
+  useNavigate: () => jest.fn()
+}));
+
+describe('WorkPage Component', () => {
+  const mockWork: Work = {
+      id: 1,
+      title: '测试作品',
+      author: '测试作者',
+      categoryName: '测试分类',
+      views: 100,
+      likes: 50,
+      createTime: '2023-01-01T00:00:00Z',
+      description: '测试描述',
+      content: '测试内容',
+      size: '',
+      data: function (): unknown {
+          throw new Error('Function not implemented.');
+      },
+      artist: '',
+      quality: '',
+      genre: [],
+      authorId: 0,
+      categoryId: 0,
+      coverUrl: '',
+      attachments: [],
+      bugCount: 0,
+      discussionCount: 0
+  };
+
+  beforeEach(() => {
+    // 重置所有模拟
+    jest.clearAllMocks();
+    
+    // 设置默认模拟实现
+    (WorkAPI.getWorkById as jest.Mock).mockResolvedValue(mockWork);
+    (WorkAPI.likeWork as jest.Mock).mockResolvedValue({});
+  });
+
+  it('renders loading spinner initially', async () => {
+    // 延迟API响应以测试加载状态
+    let resolvePromise: (value: Work) => void;
+    (WorkAPI.getWorkById as jest.Mock).mockImplementation(
+      () => new Promise<Work>((resolve) => {
+        resolvePromise = resolve;
+      })
+    );
+
+    render(
+      <MemoryRouter initialEntries={['/works/1']}>
+        <Provider store={store}>
+          <Routes>
+            <Route path="/works/:id" element={<WorkPage />} />
+          </Routes>
+        </Provider>
+      </MemoryRouter>
+    );
+
+    // 验证加载状态
+    expect(screen.getByRole('status')).toBeInTheDocument();
+    expect(screen.getByText(/加载/)).toBeInTheDocument();
+    
+    // 完成API请求
+    await act(async () => {
+      resolvePromise(mockWork);
+    });
+
+    // 验证加载完成后内容
+    expect(await screen.findByText('测试作品')).toBeInTheDocument();
+  });
+
+  it('renders work details after loading', async () => {
+    render(
+      <MemoryRouter initialEntries={['/works/1']}>
+        <Provider store={store}>
+          <Routes>
+            <Route path="/works/:id" element={<WorkPage />} />
+          </Routes>
+        </Provider>
+      </MemoryRouter>
+    );
+
+    // 等待数据加载完成
+    expect(await screen.findByText('测试作品')).toBeInTheDocument();
+    
+    // 验证头部信息
+    expect(screen.getByText('作者: 测试作者')).toBeInTheDocument();
+    expect(screen.getByText('测试分类')).toHaveClass('ant-tag');
+    expect(screen.getByText('浏览: 100')).toBeInTheDocument();
+    expect(screen.getByText('点赞: 50')).toBeInTheDocument();
+    expect(screen.getByText(/2023/)).toBeInTheDocument();
+    
+    // 验证作品内容
+    expect(screen.getByRole('heading', { level: 4, name: '作品描述' })).toBeInTheDocument();
+    expect(screen.getByText('测试描述')).toBeInTheDocument();
+    expect(screen.getByRole('heading', { level: 4, name: '作品内容' })).toBeInTheDocument();
+    expect(screen.getByText('测试内容')).toBeInTheDocument();
+    
+    // 验证标签页
+    expect(screen.getByRole('tab', { name: '作品详情' })).toBeInTheDocument();
+    expect(screen.getByRole('tab', { name: /Bug反馈/ })).toBeInTheDocument();
+    expect(screen.getByRole('tab', { name: /交流区/ })).toBeInTheDocument();
+  });
+
+  it('handles back button click', async () => {
+    const mockNavigate = jest.fn();
+    (useNavigate as jest.Mock).mockReturnValue(mockNavigate);
+
+    render(
+      <MemoryRouter initialEntries={['/works/1']}>
+        <Provider store={store}>
+          <Routes>
+            <Route path="/works/:id" element={<WorkPage />} />
+          </Routes>
+        </Provider>
+      </MemoryRouter>
+    );
+
+    // 等待数据加载完成
+    await screen.findByText('测试作品');
+    
+    // 点击返回按钮
+    const backButton = screen.getByRole('button', { name: '返回' });
+    await act(async () => {
+      backButton.click();
+    });
+    
+    // 验证导航被调用
+    expect(mockNavigate).toHaveBeenCalledWith(-1);
+  });
+
+  it('handles like button click', async () => {
+    render(
+      <MemoryRouter initialEntries={['/works/1']}>
+        <Provider store={store}>
+          <Routes>
+            <Route path="/works/:id" element={<WorkPage />} />
+          </Routes>
+        </Provider>
+      </MemoryRouter>
+    );
+
+    // 等待数据加载完成
+    await screen.findByText('测试作品');
+    
+    // 点击点赞按钮
+    const likeButton = screen.getByRole('button', { name: '点赞' });
+    await act(async () => {
+      likeButton.click();
+    });
+    
+    // 验证API调用
+    expect(WorkAPI.likeWork).toHaveBeenCalledTimes(1);
+    expect(WorkAPI.likeWork).toHaveBeenCalledWith(1);
+    
+    // 验证UI反馈
+    expect(await screen.findByText('点赞成功')).toBeInTheDocument();
+  });
+
+  it('shows error message when work loading fails', async () => {
+    const errorMessage = '加载失败';
+    (WorkAPI.getWorkById as jest.Mock).mockRejectedValue(new Error(errorMessage));
+
+    const mockNavigate = jest.fn();
+    (useNavigate as jest.Mock).mockReturnValue(mockNavigate);
+
+    render(
+      <MemoryRouter initialEntries={['/works/1']}>
+        <Provider store={store}>
+          <Routes>
+            <Route path="/works/:id" element={<WorkPage />} />
+          </Routes>
+        </Provider>
+      </MemoryRouter>
+    );
+
+    // 验证错误消息
+    expect(await screen.findByText('作品不存在')).toBeInTheDocument();
+    
+    // 验证导航到首页
+    expect(mockNavigate).toHaveBeenCalledWith('/');
+  });
+
+  it('switches between tabs correctly', async () => {
+    render(
+      <MemoryRouter initialEntries={['/works/1']}>
+        <Provider store={store}>
+          <Routes>
+            <Route path="/works/:id" element={<WorkPage />} />
+          </Routes>
+        </Provider>
+      </MemoryRouter>
+    );
+
+    // 等待数据加载完成
+    await screen.findByText('测试作品');
+    
+    // 初始显示作品详情
+    expect(screen.getByText('测试描述')).toBeInTheDocument();
+    expect(screen.queryByTestId('bug-report-mock')).not.toBeInTheDocument();
+    expect(screen.queryByTestId('discussion-mock')).not.toBeInTheDocument();
+    
+    // 点击Bug反馈标签
+    const bugTab = screen.getByRole('tab', { name: /Bug反馈/ });
+    await act(async () => {
+      bugTab.click();
+    });
+    
+    // 验证Bug反馈内容显示
+    expect(screen.queryByText('测试描述')).not.toBeInTheDocument();
+    expect(screen.getByTestId('bug-report-mock')).toBeInTheDocument();
+    
+    // 点击交流区标签
+    const discussionTab = screen.getByRole('tab', { name: /交流区/ });
+    await act(async () => {
+      discussionTab.click();
+    });
+    
+    // 验证交流区内容显示
+    expect(screen.queryByTestId('bug-report-mock')).not.toBeInTheDocument();
+    expect(screen.getByTestId('discussion-mock')).toBeInTheDocument();
+    
+    // 切换回作品详情
+    const detailsTab = screen.getByRole('tab', { name: '作品详情' });
+    await act(async () => {
+      detailsTab.click();
+    });
+    
+    // 验证作品详情再次显示
+    expect(screen.getByText('测试描述')).toBeInTheDocument();
+    expect(screen.queryByTestId('discussion-mock')).not.toBeInTheDocument();
+  });
+});
\ No newline at end of file