blob: 309942f9ef5aea8af693980378d4d09357f26aa2 [file] [log] [blame]
Akane121765b61a72025-05-17 13:52:25 +08001import React from 'react';
2import { render, screen, fireEvent, waitFor } from '@testing-library/react';
3import { MemoryRouter, Route, Routes, useLocation } from 'react-router-dom';
4import TorrentDetail from './TorrentDetail';
5import * as torrentApi from '../api/torrent';
6import * as torrentCommentApi from '../api/torrentComment';
7
8// Mock API 模块
9jest.mock('../api/torrent');
10jest.mock('../api/torrentComment');
11
12// Mock useLocation 钩子
13jest.mock('react-router-dom', () => ({
14 ...jest.requireActual('react-router-dom'),
15 useLocation: jest.fn(),
16}));
17
18describe('TorrentDetail 组件', () => {
19 const mockTorrent = {
20 id: '1',
21 torrentName: '测试种子',
22 category: '电影',
23 region: '美国',
24 resolution: '1080P',
25 subtitle: '中文字幕',
26 username: 'user1',
27 createTime: '2023-01-01T00:00:00Z',
28 likeCount: 5,
29 replyCount: 3,
30 description: '这是一个测试种子描述',
31 };
32
33 const mockComments = [
34 {
35 id: 'c1',
36 content: '测试评论1',
37 authorId: 'user2',
38 createTime: '2023-01-01T01:00:00Z',
39 likeCount: 2,
40 replies: [
41 {
42 id: 'c1r1',
43 content: '测试回复1',
44 authorId: 'user3',
45 createTime: '2023-01-01T02:00:00Z',
46 likeCount: 1,
47 }
48 ]
49 }
50 ];
51
52 beforeEach(() => {
53 // 设置模拟的 API 响应
54 torrentApi.getTorrentDetail.mockResolvedValue({
55 data: {
56 code: 200,
57 data: {
58 torrent: mockTorrent,
59 comments: mockComments,
60 }
61 }
62 });
63
64 torrentApi.likeTorrent.mockResolvedValue({ data: { code: 200 } });
65 torrentApi.addTorrentComment.mockResolvedValue({ data: { code: 200 } });
66 torrentCommentApi.likeTorrentComment.mockResolvedValue({ data: { code: 200 } });
67 torrentCommentApi.addCommentReply.mockResolvedValue({ data: { code: 200 } });
68
69 // 模拟 useLocation
70 useLocation.mockReturnValue({
71 state: { fromTab: 'share' }
72 });
73
74 // 设置 localStorage
75 Storage.prototype.getItem = jest.fn((key) => {
76 if (key === 'username') return 'testuser';
77 return null;
78 });
79 });
80
81 afterEach(() => {
82 jest.clearAllMocks();
83 });
84
85 const renderComponent = () => {
86 return render(
87 <MemoryRouter initialEntries={['/torrent/1']}>
88 <Routes>
89 <Route path="/torrent/:id" element={<TorrentDetail />} />
90 </Routes>
91 </MemoryRouter>
92 );
93 };
94
95 it('应该正确加载和显示种子详情', async () => {
96 renderComponent();
97
98 // 检查加载状态
99 expect(screen.getByText('加载中...')).toBeInTheDocument();
100
101 // 等待数据加载完成
102 await waitFor(() => {
103 expect(screen.getByText('测试种子')).toBeInTheDocument();
104 expect(screen.getByText('这是一个测试种子描述')).toBeInTheDocument();
105 expect(screen.getByText('user1')).toBeInTheDocument();
106 });
107 });
108
109 it('应该能够点赞种子', async () => {
110 renderComponent();
111
112 await waitFor(() => {
113 expect(screen.getByText('测试种子')).toBeInTheDocument();
114 });
115
116 fireEvent.click(screen.getByText(/点赞 \(5\)/));
117
118 await waitFor(() => {
119 expect(torrentApi.likeTorrent).toHaveBeenCalledWith('1');
120 });
121 });
122
123 it('应该能够提交评论', async () => {
124 renderComponent();
125
126 await waitFor(() => {
127 expect(screen.getByText('测试种子')).toBeInTheDocument();
128 });
129
130 const commentInput = screen.getByPlaceholderText('写下你的评论...');
131 fireEvent.change(commentInput, { target: { value: '新评论' } });
132 fireEvent.click(screen.getByText('发表评论'));
133
134 await waitFor(() => {
135 expect(torrentApi.addTorrentComment).toHaveBeenCalledWith('1', {
136 content: '新评论',
137 authorId: 'testuser'
138 });
139 });
140 });
141
142 it('应该能够点赞评论', async () => {
143 renderComponent();
144
145 await waitFor(() => {
146 expect(screen.getByText('测试评论1')).toBeInTheDocument();
147 });
148
149 fireEvent.click(screen.getAllByText(/👍 \(2\)/)[0]);
150
151 await waitFor(() => {
152 expect(torrentCommentApi.likeTorrentComment).toHaveBeenCalledWith('c1');
153 });
154 });
155
156 it('应该能够返回资源区', async () => {
157 const { container } = renderComponent();
158
159 await waitFor(() => {
160 expect(screen.getByText('测试种子')).toBeInTheDocument();
161 });
162
163 const backButton = container.querySelector('.back-button');
164 fireEvent.click(backButton);
165
166 // 这里可以添加导航验证,但需要更复杂的路由设置
167 });
168});