blob: 216cdf2f57fe45ebda6eec085e3f188b6671c4d2 [file] [log] [blame]
xiukirad0a7a082025-06-05 16:28:08 +08001package com.g9.g9backend.controller;
2
xiukira07ea6ee2025-06-06 19:28:24 +08003import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
4import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
xiukirad0a7a082025-06-05 16:28:08 +08005import com.fasterxml.jackson.databind.ObjectMapper;
6import com.g9.g9backend.pojo.*;
7import com.g9.g9backend.pojo.DTO.*;
8import com.g9.g9backend.service.*;
9import org.junit.jupiter.api.BeforeEach;
10import org.junit.jupiter.api.Test;
11import org.mockito.InjectMocks;
12import org.mockito.Mock;
13import org.mockito.MockitoAnnotations;
14import org.springframework.http.MediaType;
15import org.springframework.test.web.servlet.MockMvc;
16import org.springframework.test.web.servlet.setup.MockMvcBuilders;
17
xiukira07ea6ee2025-06-06 19:28:24 +080018import java.util.ArrayList;
19import java.util.Date;
20import java.util.List;
21
xiukirad0a7a082025-06-05 16:28:08 +080022import static org.mockito.ArgumentMatchers.*;
23import static org.mockito.Mockito.when;
24import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
25import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
26
27public class UserControllerTest {
28
29 private MockMvc mockMvc;
30
31 @InjectMocks
32 private UserController userController;
33
34 @Mock
35 private UserService userService;
36
37 @Mock
38 private InvitationService invitationService;
39
40 @Mock
41 private SubscriptionService subscriptionService;
42
xiukira29f8d372025-06-06 18:07:13 +080043 @Mock
44 private SearchHistoryService searchHistoryService;
45
xiukira07ea6ee2025-06-06 19:28:24 +080046 @Mock
47 private RewardService rewardService;
48
49 @Mock
50 private UserCollectionService userCollectionService;
51
52 @Mock
53 private UserUploadService userUploadService;
54
55 @Mock
56 private UserPurchaseService userPurchaseService;
57
58 @Mock
59 private ResourceService resourceService;
60
xiukiraac78f3d2025-06-08 23:38:10 +080061 @Mock
62 private ThreadService threadService;
63
xiukira7333e652025-06-09 22:43:18 +080064 @Mock
65 private GameplayService gameplayService;
66
67 @Mock
68 private ResourceVersionService resourceVersionService;
69
70 @Mock
71 private GameVersionService gameVersionService;
72
73 @Mock
74 private TorrentRecordService torrentRecordService;
75
xiukirad0a7a082025-06-05 16:28:08 +080076 private final ObjectMapper objectMapper = new ObjectMapper();
77
78 @BeforeEach
79 public void setup() {
80 MockitoAnnotations.openMocks(this);
81 mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
82 }
83
84 // 注册
85 @Test
86 public void testRegister_success() throws Exception {
87 /*
88 注意单元测试中(使用Mockito ),当多次为同一个方法设置不同的返回值时,后面的设置会覆盖前面的设置
89 可见单元测试在执行时,本质上在跑实际接口实现,当遇到被mock模拟的方法时,会来测试代码里找对应的when...thenReturn,直接看最后一个设置,所以当测试方法时,测试代码里写的和实际接口的顺序上不是一一对应
90 而是测试代码里写B C A,实际接口代码里写A B C,当实际代码跑到A时去测试代码里从后往前找到A,而不是看测试代码里第一个是不是A若是再用的逻辑
91 所以如果写成如下形式:
92 when(userService.getOne(any())).thenReturn(null);
93 ....其他代码
94 when(userService.getOne(any())).thenReturn(new User(2, "hcy", "123", null, 0, 0, null, 0, 0, 0));
95 则下面的设置会覆盖上面的设置,导致无论什么时候调用该方法,返回的都是非空对象
96 所以应该写成如下形式:
97 when(userService.getOne(any()))
98 .thenReturn(null) // 第一次调用返回null
99 .thenReturn(new User(2, "hcy", "123", null, 0, 0, null, 0, 0, 0)); // 第二次调用返回非空对象
100 */
101
102 when(userService.getOne(any()))
103 .thenReturn(null) // 第一次调用返回null,表示用户名不是已存在的
104 .thenReturn(new User(2, "hcy", "123", null, 0, 0, null, 0, 0, 0)); // 第二次调用返回非空对象,表示获取添加后的用户信息
105 // 邀请码存在且未被使用
106 when(invitationService.getOne(any())).thenReturn(new Invitation("6RCA7Y8J", 1, 0));
107 // 添加新用户
108 when(userService.save(any())).thenReturn(true);
109 // 设置该邀请码被新添加的新用户使用
110 when(invitationService.update(any())).thenReturn(true);
111 // 获取五个新邀请码
112 when(invitationService.generateInvitationCode()).thenReturn(new String[5]);
113 // 分配给新用户邀请码
114 when(invitationService.save(any())).thenReturn(true);
115 mockMvc.perform(post("/user/register")
116 .contentType(MediaType.APPLICATION_JSON)
117 .content(objectMapper.writeValueAsString(new RegisterDTO("hcy", "123", "6RCA7Y8J"))))
118 .andExpect(status().isOk());
119 }
120
121 @Test
122 public void testRegister_userExists() throws Exception {
123 // 用户名不是已存在的
124 when(userService.getOne(any())).thenReturn(new User(2, "hcy", "123", null, 0, 0, null, 0, 0, 0));
125 mockMvc.perform(post("/user/register")
126 .contentType(MediaType.APPLICATION_JSON)
127 .content(objectMapper.writeValueAsString(new RegisterDTO("hcy", "123", "6RCA7Y8J"))))
xiukirab8bd04e2025-06-09 17:31:16 +0800128 .andExpect(status().is(412));
xiukirad0a7a082025-06-05 16:28:08 +0800129 }
130
131 @Test
132 public void testRegister_invitationNotExist() throws Exception {
133 // 用户名不是已存在的
134 when(userService.getOne(any())).thenReturn(null);
135 // 邀请码不存在
136 when(invitationService.getOne(any())).thenReturn(null);
137 mockMvc.perform(post("/user/register")
138 .contentType(MediaType.APPLICATION_JSON)
139 .content(objectMapper.writeValueAsString(new RegisterDTO("hcy", "123", "6RCA7Y8J"))))
140 .andExpect(status().is(409));
141 }
142
143 @Test
144 public void testRegister_invitationUsed() throws Exception {
145 // 用户名不是已存在的
146 when(userService.getOne(any())).thenReturn(null);
147 // 邀请码存在但已被使用
148 when(invitationService.getOne(any())).thenReturn(new Invitation("6RCA7Y8J", 1, 2));
149 mockMvc.perform(post("/user/register")
150 .contentType(MediaType.APPLICATION_JSON)
151 .content(objectMapper.writeValueAsString(new RegisterDTO("hcy", "123", "6RCA7Y8J"))))
152 .andExpect(status().is(410));
153 }
154
155 // 登录
156 @Test
157 public void testLogin_success() throws Exception {
158 // 设置请求参数
159 User user = new User();
160 user.setUsername("hcy");
161 user.setPassword("123");
162
163 when(userService.getOne(any())).thenReturn(new User(1, "hcy", "123", null, 0, 0, null, 0, 0, 0));
164
165 mockMvc.perform(post("/user/login")
166 .contentType(MediaType.APPLICATION_JSON)
167 .content(objectMapper.writeValueAsString(user)))
168 .andExpect(status().isOk());
169 }
170
171 @Test
172 public void testLogin_userNotFound() throws Exception {
173 //设置请求参数
174 User user = new User();
175 user.setUsername("hcy");
176 user.setPassword("123");
177
178 when(userService.getOne(any())).thenReturn(null);
179
180 mockMvc.perform(post("/user/login")
181 .contentType(MediaType.APPLICATION_JSON)
182 .content(objectMapper.writeValueAsString(user)))
183 .andExpect(status().is(406));
184 }
185
186 @Test
187 public void testLogin_wrongPassword() throws Exception {
188 // 设置请求参数
189 User user = new User();
190 user.setUsername("hcy");
191 user.setPassword("wrongPassword");
192
193 when(userService.getOne(any())).thenReturn(new User(1, "hcy", "123", null, 0, 0, null, 0, 0, 0));
194
195 mockMvc.perform(post("/user/login")
196 .contentType(MediaType.APPLICATION_JSON)
197 .content(objectMapper.writeValueAsString(user)))
198 .andExpect(status().is(408));
199 }
200
201 // 关注
202 @Test
203 public void testSubscription() throws Exception {
204 when(subscriptionService.save(any())).thenReturn(true);
205
206 mockMvc.perform(post("/user/subscription")
207 .contentType(MediaType.APPLICATION_JSON)
208 .content(objectMapper.writeValueAsString(new Subscription(1, 2))))
209 .andExpect(status().isOk());
210 }
xiukira29f8d372025-06-06 18:07:13 +0800211
212 // 注销
213 @Test
214 public void testUserDelete_success() throws Exception {
215
216 when(userService.getOne(any())).thenReturn(new User(1, "hcy", "123", null, 0, 0, null, 0, 0, 0));
217
218 mockMvc.perform(delete("/user")
219 .param("userId", "1")
220 .param("password", "123"))
221 .andExpect(status().isNoContent());
222 }
223
224 @Test
225 public void testUserDelete_wrongPassword() throws Exception {
226
227 when(userService.getOne(any())).thenReturn(new User(1, "hcy", "123", null, 0, 0, null, 0, 0, 0));
228
229 mockMvc.perform(delete("/user")
230 .param("userId", "1")
231 .param("password", "wrong"))
232 .andExpect(status().is(408));
233 }
234
235 // 删除搜索历史
236 @Test
237 public void testSearchDelete() throws Exception {
238
239 when(searchHistoryService.removeById(anyInt())).thenReturn(true);
240
241 mockMvc.perform(delete("/user/search")
242 .param("searchHistoryId", "1"))
243 .andExpect(status().isNoContent());
244 }
245
246 // 取消关注
247 @Test
248 public void testSubscriptionDelete() throws Exception {
249
250 when(subscriptionService.remove(any())).thenReturn(true);
251
252 mockMvc.perform(delete("/user/subscription")
253 .param("userId", "1")
254 .param("followerId", "2"))
255 .andExpect(status().isNoContent());
256 }
xiukira07ea6ee2025-06-06 19:28:24 +0800257
258 // 获取用户ID
259 @Test
260 public void testGetUserId() throws Exception {
261
262 when(userService.getOne(any())).thenReturn(new User(1, "hcy", "123", null, 0, 0, null, 0, 0, 0));
263
264 mockMvc.perform(get("/user/getId")
265 .param("username", "hcy")
266 .param("password", "123"))
267 .andExpect(status().isOk());
268 }
269
270 // 获取邀请码
271 @Test
272 public void testGetInvitationCode() throws Exception {
273
274 List<Invitation> invitationList = new ArrayList<>();
275 invitationList.add(new Invitation("1RCA7Y8J", 0, 0));
276 invitationList.add(new Invitation("2RCA7Y8J", 0, 0));
277 invitationList.add(new Invitation("3RCA7Y8J", 0, 0));
278 invitationList.add(new Invitation("4RCA7Y8J", 0, 0));
279 invitationList.add(new Invitation("5RCA7Y8J", 0, 0));
280
281 QueryWrapper<Invitation> invitationQuery = new QueryWrapper<>();
282 invitationQuery.eq("user_id", 1).eq("invitee_id", 0);
283 invitationQuery.select("invitation_code");
284
285 when(invitationService.list(invitationQuery)).thenReturn(invitationList); //这里用any()无法识别,因为list有多种参数可能
286
287 mockMvc.perform(get("/user/invitation-code")
288 .param("userId", "1"))
289 .andExpect(status().isOk());
290 }
291
292 // 获取用户信息
293 @Test
294 public void testGetUserInfo() throws Exception {
295
296 when(userService.getById(anyInt())).thenReturn(new User(1, "user", "pass", null, 0, 0, null, 0, 0, 0));
297
298 mockMvc.perform(get("/user/info")
299 .param("userId", "1"))
300 .andExpect(status().isOk());
301 }
302
303 // 获取悬赏
304 @Test
305 public void testGetUserReward() throws Exception {
306
307 when(rewardService.page(any(), any())).thenReturn(new Page<>(1, 2));
308
309 mockMvc.perform(get("/user/reward")
310 .param("userId", "1")
311 .param("pageNumber", "2")
312 .param("rows", "2"))
313 .andExpect(status().isOk());
314 }
315
316 // 获取收藏
317 @Test
318 public void testGetUserCollection() throws Exception {
319
320 when(userCollectionService.page(any(), any())).thenReturn(new Page<>(1, 2));
xiukiraac78f3d2025-06-08 23:38:10 +0800321 when(resourceService.getById(anyInt())).thenReturn(new Resource(1, "a", null, null, null, new Date(), new Date(), 100, 0, 0, 0, 0, "mod"));
xiukira07ea6ee2025-06-06 19:28:24 +0800322
323 mockMvc.perform(get("/user/collection")
324 .param("userId", "1")
325 .param("pageNumber", "1")
326 .param("rows", "2"))
327 .andExpect(status().isOk());
328 }
329
330 // 获取上传
331 @Test
332 public void testGetUserUpload() throws Exception {
333
334 when(userUploadService.page(any(), any())).thenReturn(new Page<>(1, 2));
xiukiraac78f3d2025-06-08 23:38:10 +0800335 when(resourceService.getById(anyInt())).thenReturn(new Resource(1, "a", null, null, null, new Date(), new Date(), 100, 0, 0, 0, 0, "mod"));
xiukira07ea6ee2025-06-06 19:28:24 +0800336
337 mockMvc.perform(get("/user/upload")
338 .param("userId", "1")
339 .param("pageNumber", "1")
340 .param("rows", "2"))
341 .andExpect(status().isOk());
342 }
343
344 // 获取购买
345 @Test
346 public void testGetUserPurchase() throws Exception {
347
348 when(userPurchaseService.page(any(), any())).thenReturn(new Page<>(1, 2));
xiukiraac78f3d2025-06-08 23:38:10 +0800349 when(resourceService.getById(anyInt())).thenReturn(new Resource(1, "a", null, null, null, new Date(), new Date(), 100, 0, 0, 0, 0, "mod"));
xiukira7333e652025-06-09 22:43:18 +0800350 List<Gameplay> gameplayList = new ArrayList<>();
351 when(gameplayService.list(new QueryWrapper<Gameplay>().eq("resource_id", 1))).thenReturn(gameplayList);
352 List<ResourceVersion> resourceVersionList = new ArrayList<>();
353 when(resourceVersionService.list(new QueryWrapper<ResourceVersion>().eq("resource_id", 1))).thenReturn(resourceVersionList);
354 List<GameVersion> gameVersionList = new ArrayList<>();
355 when( gameVersionService.list(new QueryWrapper<GameVersion>().eq("resource_version_id", 1))).thenReturn(gameVersionList);
356 List<TorrentRecord> torrentRecordList = new ArrayList<>();
357 when(torrentRecordService.list(new QueryWrapper<TorrentRecord>().eq("resource_version_id", 1))).thenReturn(torrentRecordList);
xiukira07ea6ee2025-06-06 19:28:24 +0800358
359 mockMvc.perform(get("/user/purchase")
360 .param("userId", "1")
361 .param("pageNumber", "1")
362 .param("rows", "2"))
363 .andExpect(status().isOk());
364 }
365
366 // 获取搜索历史
367 @Test
368 public void testGetUserSearchHistory() throws Exception {
369
370 List<SearchHistory> searchHistoryList = new ArrayList<>();
371
372 QueryWrapper<SearchHistory> searchHistoryQuery = new QueryWrapper<>();
373 searchHistoryQuery.eq("user_id", 1).orderByDesc("search_history_id").last("LIMIT 10");
374
375 when(searchHistoryService.list(searchHistoryQuery)).thenReturn(searchHistoryList);
376
377 mockMvc.perform(get("/user/search")
378 .param("userId", "1"))
379 .andExpect(status().isOk());
380 }
381
xiukiraac78f3d2025-06-08 23:38:10 +0800382 // 获取发布过的贴子
383 @Test
384 public void testGetUserThread() throws Exception {
385
386 when(threadService.page(any(), any())).thenReturn(new Page<>(1, 2));
387
388 mockMvc.perform(get("/user/thread")
389 .param("userId", "1")
390 .param("pageNumber", "1")
391 .param("rows", "2"))
392 .andExpect(status().isOk());
393 }
394
xiukira07ea6ee2025-06-06 19:28:24 +0800395 // 获取用户数据
396 @Test
397 public void testGetUserData() throws Exception {
398
399 when(userService.getById(1)).thenReturn(new User(1, "hcy", "123", null, 0, 0, null, 0, 0, 0));
400
401 List<UserUpload> UserUpload = new ArrayList<>();
402 QueryWrapper<UserUpload> userUploadQuery = new QueryWrapper<>();
403 userUploadQuery.eq("user_id", 1);
404 when(userUploadService.list(userUploadQuery)).thenReturn(UserUpload);
405
406 when(resourceService.getById(anyInt())).thenReturn(new Resource());
407
408 mockMvc.perform(get("/user/data")
409 .param("userId", "1"))
410 .andExpect(status().isOk());
411 }
412
413 // 获取关注列表
414 @Test
415 public void testGetUserSubscriber() throws Exception {
416
417 QueryWrapper<Subscription> subscriptionQuery = new QueryWrapper<>();
418 subscriptionQuery.eq("follower_id", 1);
419 List<Subscription> subscriptionList = new ArrayList<>();
420
421 when(subscriptionService.list(subscriptionQuery)).thenReturn(subscriptionList);
422 when(userService.getById(1)).thenReturn(new User(1, "hcy", "123", null, 0, 0, null, 0, 0, 0));
423
424 mockMvc.perform(get("/user/subscriber")
425 .param("userId", "1"))
426 .andExpect(status().isOk());
427 }
428
429 // 获取粉丝列表
430 @Test
431 public void testGetUserFollower() throws Exception {
432
433 QueryWrapper<Subscription> subscriptionQuery = new QueryWrapper<>();
434 subscriptionQuery.eq("user_id", 1);
435 List<Subscription> subscriptionList = new ArrayList<>();
436
437 when(subscriptionService.list(subscriptionQuery)).thenReturn(subscriptionList);
438 when(userService.getById(1)).thenReturn(new User(1, "hcy", "123", null, 0, 0, null, 0, 0, 0));
439
440 mockMvc.perform(get("/user/follower")
441 .param("userId", "1"))
442 .andExpect(status().isOk());
443 }
xiukiraa3c84182025-06-06 20:54:38 +0800444
445 // 修改签名
446 @Test
447 public void testModifySignature() throws Exception {
448
449 User user = new User();
450 user.setUserId(1);
451 user.setSignature("New Signature");
452
453 when(userService.update(any())).thenReturn(true);
454
455 mockMvc.perform(put("/user/signature")
456 .contentType(MediaType.APPLICATION_JSON)
457 .content(objectMapper.writeValueAsString(user)))
458 .andExpect(status().isOk());
459 }
460
461 // 修改密码
462 @Test
463 public void testModifyPassword_success() throws Exception {
464
465 // 密码正确
466 when(userService.getOne(any())).thenReturn(new User(1, "hcy", "oldPass", null, 0, 0, null, 0, 0, 0));
467 when(userService.update(any())).thenReturn(true);
468
469 mockMvc.perform(put("/user/password")
470 .contentType(MediaType.APPLICATION_JSON)
471 .content(objectMapper.writeValueAsString(new ModifyPasswordDTO(1, "oldPass", "newPass"))))
472 .andExpect(status().isOk());
473 }
474
475 @Test
476 public void testModifyPassword_wrongPassword() throws Exception {
477
478 // 密码错误
479 when(userService.getOne(any())).thenReturn(new User(1, "hcy", "oldPass", null, 0, 0, null, 0, 0, 0));
480
481 mockMvc.perform(put("/user/password")
482 .contentType(MediaType.APPLICATION_JSON)
483 .content(objectMapper.writeValueAsString(new ModifyPasswordDTO(1, "wrongPassword", "newPass"))))
484 .andExpect(status().is(408));
485 }
486
487 // 修改头像
488 @Test
489 public void testModifyAvatar() throws Exception {
490
491 // 设置请求参数
492 User user = new User();
493 user.setUserId(1);
494 user.setAvatar("avatar.png");
495
496 when(userService.update(any())).thenReturn(true);
497
498 mockMvc.perform(put("/user/avatar")
499 .contentType(MediaType.APPLICATION_JSON)
500 .content(objectMapper.writeValueAsString(user)))
501 .andExpect(status().isOk());
502 }
xiukirad0a7a082025-06-05 16:28:08 +0800503}