import React from 'react'; | |
import { render, screen, fireEvent, waitFor } from '@testing-library/react'; | |
import { MemoryRouter, Route, Routes, useLocation } from 'react-router-dom'; | |
import TorrentDetail from './TorrentDetail'; | |
import * as torrentApi from '../api/torrent'; | |
import * as torrentCommentApi from '../api/torrentComment'; | |
// Mock API 模块 | |
jest.mock('../api/torrent'); | |
jest.mock('../api/torrentComment'); | |
// Mock useLocation 钩子 | |
jest.mock('react-router-dom', () => ({ | |
...jest.requireActual('react-router-dom'), | |
useLocation: jest.fn(), | |
})); | |
describe('TorrentDetail 组件', () => { | |
const mockTorrent = { | |
id: '1', | |
torrentName: '测试种子', | |
category: '电影', | |
region: '美国', | |
resolution: '1080P', | |
subtitle: '中文字幕', | |
username: 'user1', | |
createTime: '2023-01-01T00:00:00Z', | |
likeCount: 5, | |
replyCount: 3, | |
description: '这是一个测试种子描述', | |
}; | |
const mockComments = [ | |
{ | |
id: 'c1', | |
content: '测试评论1', | |
authorId: 'user2', | |
createTime: '2023-01-01T01:00:00Z', | |
likeCount: 2, | |
replies: [ | |
{ | |
id: 'c1r1', | |
content: '测试回复1', | |
authorId: 'user3', | |
createTime: '2023-01-01T02:00:00Z', | |
likeCount: 1, | |
} | |
] | |
} | |
]; | |
beforeEach(() => { | |
// 设置模拟的 API 响应 | |
torrentApi.getTorrentDetail.mockResolvedValue({ | |
data: { | |
code: 200, | |
data: { | |
torrent: mockTorrent, | |
comments: mockComments, | |
} | |
} | |
}); | |
torrentApi.likeTorrent.mockResolvedValue({ data: { code: 200 } }); | |
torrentApi.addTorrentComment.mockResolvedValue({ data: { code: 200 } }); | |
torrentCommentApi.likeTorrentComment.mockResolvedValue({ data: { code: 200 } }); | |
torrentCommentApi.addCommentReply.mockResolvedValue({ data: { code: 200 } }); | |
// 模拟 useLocation | |
useLocation.mockReturnValue({ | |
state: { fromTab: 'share' } | |
}); | |
// 设置 localStorage | |
Storage.prototype.getItem = jest.fn((key) => { | |
if (key === 'username') return 'testuser'; | |
return null; | |
}); | |
}); | |
afterEach(() => { | |
jest.clearAllMocks(); | |
}); | |
const renderComponent = () => { | |
return render( | |
<MemoryRouter initialEntries={['/torrent/1']}> | |
<Routes> | |
<Route path="/torrent/:id" element={<TorrentDetail />} /> | |
</Routes> | |
</MemoryRouter> | |
); | |
}; | |
it('应该正确加载和显示种子详情', async () => { | |
renderComponent(); | |
// 检查加载状态 | |
expect(screen.getByText('加载中...')).toBeInTheDocument(); | |
// 等待数据加载完成 | |
await waitFor(() => { | |
expect(screen.getByText('测试种子')).toBeInTheDocument(); | |
expect(screen.getByText('这是一个测试种子描述')).toBeInTheDocument(); | |
expect(screen.getByText('user1')).toBeInTheDocument(); | |
}); | |
}); | |
it('应该能够点赞种子', async () => { | |
renderComponent(); | |
await waitFor(() => { | |
expect(screen.getByText('测试种子')).toBeInTheDocument(); | |
}); | |
fireEvent.click(screen.getByText(/点赞 \(5\)/)); | |
await waitFor(() => { | |
expect(torrentApi.likeTorrent).toHaveBeenCalledWith('1'); | |
}); | |
}); | |
it('应该能够提交评论', async () => { | |
renderComponent(); | |
await waitFor(() => { | |
expect(screen.getByText('测试种子')).toBeInTheDocument(); | |
}); | |
const commentInput = screen.getByPlaceholderText('写下你的评论...'); | |
fireEvent.change(commentInput, { target: { value: '新评论' } }); | |
fireEvent.click(screen.getByText('发表评论')); | |
await waitFor(() => { | |
expect(torrentApi.addTorrentComment).toHaveBeenCalledWith('1', { | |
content: '新评论', | |
authorId: 'testuser' | |
}); | |
}); | |
}); | |
it('应该能够点赞评论', async () => { | |
renderComponent(); | |
await waitFor(() => { | |
expect(screen.getByText('测试评论1')).toBeInTheDocument(); | |
}); | |
fireEvent.click(screen.getAllByText(/👍 \(2\)/)[0]); | |
await waitFor(() => { | |
expect(torrentCommentApi.likeTorrentComment).toHaveBeenCalledWith('c1'); | |
}); | |
}); | |
it('应该能够返回资源区', async () => { | |
const { container } = renderComponent(); | |
await waitFor(() => { | |
expect(screen.getByText('测试种子')).toBeInTheDocument(); | |
}); | |
const backButton = container.querySelector('.back-button'); | |
fireEvent.click(backButton); | |
// 这里可以添加导航验证,但需要更复杂的路由设置 | |
}); | |
}); |