| import { describe, it, expect, vi, beforeEach } from 'vitest'; |
| import { render, screen, waitFor } from '@testing-library/react'; |
| import userEvent from '@testing-library/user-event'; |
| import { MemoryRouter, useParams, useNavigate, useLocation } from 'react-router-dom'; |
| import TorrentDetailcomplain from '../components/TorrentDetailcomplain'; |
| import axios from 'axios'; |
| |
| // 模拟 axios |
| vi.mock('axios'); |
| |
| // 模拟 react-router-dom 的 hooks |
| vi.mock('react-router-dom', async () => { |
| const actual = await vi.importActual('react-router-dom'); |
| return { |
| ...actual, |
| useParams: vi.fn(), |
| useNavigate: vi.fn(), |
| useLocation: vi.fn(), |
| }; |
| }); |
| |
| describe('TorrentDetailcomplain 组件', () => { |
| const mockTorrent = { |
| torrentid: 1, |
| filename: '测试种子文件', |
| torrentSize: 1024 * 1024 * 10, // 10MB |
| uploader_id: 123, |
| uploadTime: '2023-01-01T12:00:00', |
| downloadCount: 100, |
| promotionid: 1, |
| description: '这是一个测试种子', |
| coverImagePath: 'http://example.com/cover.jpg', |
| }; |
| |
| const mockNavigate = vi.fn(); |
| const mockLocation = { |
| state: { |
| duser: 456, |
| torrentid: 1, |
| }, |
| }; |
| |
| beforeEach(() => { |
| vi.clearAllMocks(); |
| |
| // 设置模拟的路由 hooks |
| vi.mocked(useParams).mockReturnValue({ id: '1' }); |
| vi.mocked(useNavigate).mockReturnValue(mockNavigate); |
| vi.mocked(useLocation).mockReturnValue(mockLocation); |
| |
| // 模拟 axios.get 返回种子详情 |
| axios.get.mockResolvedValueOnce({ data: mockTorrent }); |
| }); |
| |
| it('应该正确渲染而不崩溃', async () => { |
| render( |
| <MemoryRouter> |
| <TorrentDetailcomplain /> |
| </MemoryRouter> |
| ); |
| |
| // 等待数据加载 |
| await waitFor(() => { |
| expect(screen.getByText('种子详情')).toBeInTheDocument(); |
| }); |
| |
| // 验证一些基本元素是否存在 |
| expect(screen.getByText('ID: 1')).toBeInTheDocument(); |
| expect(screen.getByText('文件名: 测试种子文件')).toBeInTheDocument(); |
| expect(screen.getByText('大小: 10.00 MB')).toBeInTheDocument(); |
| expect(screen.getByText('上传者ID: 123')).toBeInTheDocument(); |
| expect(screen.getByText('上传时间: 2023/01/01 12:00')).toBeInTheDocument(); |
| expect(screen.getByText('下载次数: 100')).toBeInTheDocument(); |
| expect(screen.getByText('促销: 上传加倍')).toBeInTheDocument(); |
| expect(screen.getByText('描述: 这是一个测试种子')).toBeInTheDocument(); |
| }); |
| |
| it('应该加载种子详情数据', async () => { |
| render( |
| <MemoryRouter> |
| <TorrentDetailcomplain /> |
| </MemoryRouter> |
| ); |
| |
| // 等待数据加载 |
| await waitFor(() => { |
| expect(axios.get).toHaveBeenCalledWith('http://localhost:8080/torrent/1'); |
| }); |
| }); |
| |
| it('应该正确显示封面图片', async () => { |
| render( |
| <MemoryRouter> |
| <TorrentDetailcomplain /> |
| </MemoryRouter> |
| ); |
| |
| // 等待数据加载 |
| await waitFor(() => { |
| expect(screen.getByText('种子详情')).toBeInTheDocument(); |
| }); |
| |
| // 验证封面图片是否渲染 |
| const image = screen.getByAltText('种子封面'); |
| expect(image).toBeInTheDocument(); |
| expect(image).toHaveAttribute('src', 'http://example.com/cover.jpg'); |
| }); |
| |
| it('应该正确处理删除种子按钮点击', async () => { |
| // 模拟 confirm 对话框 |
| vi.mocked(axios.delete).mockResolvedValueOnce({}); |
| |
| render( |
| <MemoryRouter> |
| <TorrentDetailcomplain /> |
| </MemoryRouter> |
| ); |
| |
| // 等待数据加载 |
| await waitFor(() => { |
| expect(screen.getByText('种子详情')).toBeInTheDocument(); |
| }); |
| |
| // 点击删除按钮 |
| const deleteButton = screen.getByText('删除'); |
| userEvent.click(deleteButton); |
| |
| // 验证 confirm 对话框是否被调用 |
| // 注意:由于我们使用了 antd 的 Modal.confirm,我们需要检查 axios.delete 是否被调用 |
| // 这里我们直接验证 axios.delete 是否被调用 |
| await waitFor(() => { |
| expect(axios.delete).toHaveBeenCalledWith('http://localhost:8080/torrent/delete/1', { |
| params: { userid: 1 }, |
| }); |
| }); |
| |
| // 验证导航是否被调用 |
| await waitFor(() => { |
| expect(mockNavigate).toHaveBeenCalledWith(-1); |
| }); |
| |
| // 验证成功消息是否被调用 |
| expect(vi.mocked(message.success)).toHaveBeenCalledWith('种子删除成功'); |
| }); |
| |
| it('应该正确处理下载种子按钮点击', async () => { |
| render( |
| <MemoryRouter> |
| <TorrentDetailcomplain /> |
| </MemoryRouter> |
| ); |
| |
| // 等待数据加载 |
| await waitFor(() => { |
| expect(screen.getByText('种子详情')).toBeInTheDocument(); |
| }); |
| |
| // 点击下载按钮 |
| const downloadButton = screen.getByText('下载'); |
| userEvent.click(downloadButton); |
| |
| // 验证 axios.get 是否被调用(注意:我们实际上使用了 window.open) |
| // 由于我们直接使用了 window.open,我们需要验证它是否被调用 |
| // 这里我们无法直接验证 window.open,但可以验证没有错误发生 |
| // 我们可以验证组件没有崩溃 |
| expect(screen.getByText('种子详情')).toBeInTheDocument(); |
| }); |
| |
| it('应该正确处理扣除保种积分按钮点击', async () => { |
| // 模拟 axios.post |
| vi.mocked(axios.post).mockResolvedValueOnce({ data: { success: true } }); |
| |
| render( |
| <MemoryRouter> |
| <TorrentDetailcomplain /> |
| </MemoryRouter> |
| ); |
| |
| // 等待数据加载 |
| await waitFor(() => { |
| expect(screen.getByText('种子详情')).toBeInTheDocument(); |
| }); |
| |
| // 点击扣除保种积分按钮 |
| const creditButton = screen.getByText('扣除保种积分'); |
| userEvent.click(creditButton); |
| |
| // 验证 axios.post 是否被调用 |
| await waitFor(() => { |
| expect(axios.post).toHaveBeenCalledWith( |
| 'http://localhost:8080/torrent/deducecredit', |
| 'manageid=1&userid=456&credit=3', |
| { |
| headers: { |
| 'Content-Type': 'application/x-www-form-urlencoded', |
| }, |
| } |
| ); |
| }); |
| |
| // 验证成功消息是否被调用 |
| expect(vi.mocked(message.success)).toHaveBeenCalledWith('成功扣除 3 保种积分'); |
| }); |
| |
| it('应该正确处理删除种子失败的情况', async () => { |
| // 模拟 axios.delete 失败 |
| vi.mocked(axios.delete).mockRejectedValueOnce({ |
| response: { |
| status: 403, |
| data: '无权删除此种子', |
| }, |
| }); |
| |
| render( |
| <MemoryRouter> |
| <TorrentDetailcomplain /> |
| </MemoryRouter> |
| ); |
| |
| // 等待数据加载 |
| await waitFor(() => { |
| expect(screen.getByText('种子详情')).toBeInTheDocument(); |
| }); |
| |
| // 点击删除按钮 |
| const deleteButton = screen.getByText('删除'); |
| userEvent.click(deleteButton); |
| |
| // 验证 axios.delete 是否被调用 |
| await waitFor(() => { |
| expect(axios.delete).toHaveBeenCalledWith('http://localhost:8080/torrent/delete/1', { |
| params: { userid: 1 }, |
| }); |
| }); |
| |
| // 验证错误消息是否被调用 |
| expect(vi.mocked(message.error)).toHaveBeenCalledWith('无权删除此种子'); |
| }); |
| |
| it('应该正确处理下载种子失败的情况', async () => { |
| // 模拟 window.open 失败(我们无法直接模拟 window.open,所以这个测试可能有限) |
| // 由于我们直接使用了 window.open,我们无法直接测试它的失败情况 |
| // 我们可以测试组件在点击按钮后没有崩溃 |
| render( |
| <MemoryRouter> |
| <TorrentDetailcomplain /> |
| </MemoryRouter> |
| ); |
| |
| // 等待数据加载 |
| await waitFor(() => { |
| expect(screen.getByText('种子详情')).toBeInTheDocument(); |
| }); |
| |
| // 点击下载按钮 |
| const downloadButton = screen.getByText('下载'); |
| userEvent.click(downloadButton); |
| |
| // 验证组件没有崩溃 |
| expect(screen.getByText('种子详情')).toBeInTheDocument(); |
| }); |
| |
| it('应该正确处理扣除保种积分失败的情况', async () => { |
| // 模拟 axios.post 失败 |
| vi.mocked(axios.post).mockRejectedValueOnce({ |
| response: { |
| status: 500, |
| data: { message: '服务器错误' }, |
| }, |
| }); |
| |
| render( |
| <MemoryRouter> |
| <TorrentDetailcomplain /> |
| </MemoryRouter> |
| ); |
| |
| // 等待数据加载 |
| await waitFor(() => { |
| expect(screen.getByText('种子详情')).toBeInTheDocument(); |
| }); |
| |
| // 点击扣除保种积分按钮 |
| const creditButton = screen.getByText('扣除保种积分'); |
| userEvent.click(creditButton); |
| |
| // 验证 axios.post 是否被调用 |
| await waitFor(() => { |
| expect(axios.post).toHaveBeenCalledWith( |
| 'http://localhost:8080/torrent/deducecredit', |
| 'manageid=1&userid=456&credit=3', |
| { |
| headers: { |
| 'Content-Type': 'application/x-www-form-urlencoded', |
| }, |
| } |
| ); |
| }); |
| |
| // 验证错误消息是否被调用 |
| expect(vi.mocked(message.error)).toHaveBeenCalledWith('服务器错误: 服务器错误'); |
| }); |
| |
| it('应该正确处理种子不存在的情况', async () => { |
| // 模拟 axios.get 返回 404 |
| axios.get.mockRejectedValueOnce({ |
| response: { |
| status: 404, |
| }, |
| }); |
| |
| render( |
| <MemoryRouter> |
| <TorrentDetailcomplain /> |
| </MemoryRouter> |
| ); |
| |
| // 等待错误状态 |
| await waitFor(() => { |
| expect(screen.queryByText('种子详情')).not.toBeInTheDocument(); |
| }); |
| |
| // 验证错误消息是否显示 |
| expect(screen.getByText('种子不存在')).toBeInTheDocument(); |
| expect(screen.getByText('抱歉,您查找的种子不存在或已被删除。')).toBeInTheDocument(); |
| }); |
| |
| it('应该正确处理网络错误的情况', async () => { |
| // 模拟 axios.get 网络错误 |
| axios.get.mockRejectedValueOnce({ |
| message: '网络错误', |
| }); |
| |
| render( |
| <MemoryRouter> |
| <TorrentDetailcomplain /> |
| </MemoryRouter> |
| ); |
| |
| // 等待错误状态 |
| await waitFor(() => { |
| expect(screen.queryByText('种子详情')).not.toBeInTheDocument(); |
| }); |
| |
| // 验证错误消息是否显示 |
| expect(screen.getByText('网络错误,请稍后重试')).toBeInTheDocument(); |
| }); |
| }); |