Merge changes I10e91036,I4838ea80
* changes:
求助要资源帖子相关后端
好友相关后端
diff --git a/src/main/java/com/pt5/pthouduan/controller/CategoryController.java b/src/main/java/com/pt5/pthouduan/controller/CategoryController.java
new file mode 100644
index 0000000..ec013c3
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/controller/CategoryController.java
@@ -0,0 +1,24 @@
+package com.pt5.pthouduan.controller;
+
+import com.pt5.pthouduan.entity.Category;
+import com.pt5.pthouduan.service.CategoryService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/categories")
+@CrossOrigin
+public class CategoryController {
+ @Autowired
+ private CategoryService categoryService;
+
+ @GetMapping
+ public List<Category> getAllCategories() {
+ return categoryService.getAllCategories();
+ }
+}
diff --git a/src/main/java/com/pt5/pthouduan/controller/TorrentController.java b/src/main/java/com/pt5/pthouduan/controller/TorrentController.java
index e864f20..b623e7a 100644
--- a/src/main/java/com/pt5/pthouduan/controller/TorrentController.java
+++ b/src/main/java/com/pt5/pthouduan/controller/TorrentController.java
@@ -57,6 +57,361 @@
+ @GetMapping("/{infoHash}/seeders")
+ public ResponseEntity<List<PeerInfo>> getSeedersByInfoHash(@PathVariable String infoHash) {
+ List<PeerInfo> seeders = peerService.getSeedersByInfoHash(infoHash.toUpperCase());
+ System.out.println("Response: " + seeders);
+ return ResponseEntity.ok(seeders);
+ }
+
+ //添加搜索
+ @GetMapping("/search")
+ public ResponseEntity<List<Torrent>> searchTorrents(@RequestParam("keyword") String keyword) {
+ List<Torrent> result = torrentService.searchByKeyword(keyword);
+ return ResponseEntity.ok(result);
+ }
+
+ @PostMapping("/addcredit")
+ public ResponseEntity<?> addCredit(@RequestParam("manageid") Long manageid,@RequestParam("userid") Long userid,@RequestParam("credit") Integer credit,@RequestParam("helpedId") Long helpedId) {
+ try {
+ torrentService.addcredit(manageid,userid,credit);
+ torrentService.deducecredit(manageid,helpedId,credit);
+ } catch (Exception e) {
+ return ResponseEntity.internalServerError().body(Map.of(
+ "success", false,
+ "message", "服务器错误: " + e.getMessage()
+ ));
+ }
+ return ResponseEntity.ok(credit); //成功返回保种积分
+ }
+
+ @PostMapping("/deducecredit")
+ public ResponseEntity<?> duduceCredit(@RequestParam("manageid") Long manageid,@RequestParam("userid") Long userid,@RequestParam("credit") Integer credit) {
+ try {
+ torrentService.deducecredit(manageid,userid,credit);
+ } catch (Exception e) {
+ return ResponseEntity.internalServerError().body(Map.of(
+ "success", false,
+ "message", "服务器错误: " + e.getMessage()
+ ));
+ }
+ return ResponseEntity.ok(credit); //成功返回保种积分
+ }
+
+
+ //显示所有种子
+ @GetMapping("/list")
+ public List<Torrent> getAllTorrents() {
+ return torrentService.getAllTorrents();
+ }
+
+ // 按分类获取种子(带 category 参数)
+ @GetMapping("/listByCategory")
+ public List<Torrent> getTorrentsByCategory(@RequestParam(required = false) Integer categoryid) {
+ if (categoryid == null) {
+ return torrentService.getAllTorrents();
+ }
+ return torrentService.getTorrentsByCategory(categoryid); // 否则按分类过滤
+ }
+
+ @GetMapping("/listByCategorywithfilter")
+ public List<Torrent> getTorrentsByCategorywithFilter(
+ @RequestParam Integer categoryid,
+ @RequestParam Map<String, String> filters
+ ){
+ filters.remove("categoryid");
+ List<Torrent> torrents = torrentService.getTorrentsByCategorywithfilters(categoryid,filters);
+ return torrents;
+ }
+
+
+
+ // 获取单个种子详情
+ @GetMapping("/{id}")
+ public ResponseEntity<?> getTorrentById(@PathVariable Long id) {
+ try {
+ Torrent torrent = torrentService.getTorrentById(id);
+ if (torrent == null) {
+ return ResponseEntity.notFound().build(); // 如果种子不存在,返回 404
+ }
+ System.out.println(torrent);
+ return ResponseEntity.ok(torrent); // 返回种子详情
+ } catch (Exception e) {
+ return ResponseEntity.badRequest().body("获取种子详情失败: " + e.getMessage());
+ }
+ }
+//未更新前端前
+// @PostMapping("/upload")
+// public ResponseEntity<?> uploadTorrent(
+// @RequestParam("file") MultipartFile torrentFile,
+// @RequestParam("title") String title,
+// @RequestParam("description") String description
+// //@AuthenticationPrincipal User user
+// //User user
+// ){
+// // 创建临时用户对象
+// User user = new User(1L,"testuser");
+// //user.setUserid(1L); // 设置测试用户ID
+// try{
+// //torrentService.Upload(torrentFile,title,description,user);
+// return torrentService.Upload(torrentFile, title, description, user);
+// }catch(Exception e){
+// return ResponseEntity.badRequest().body("Upload failed:" + e.getMessage());
+// }
+// }
+//@PostMapping("/upload")
+//public ResponseEntity<?> uploadTorrent(
+// @RequestParam("file") MultipartFile torrentFile,
+// @RequestParam("title") String title,
+// @RequestParam("description") String description,
+// @RequestParam("categoryId") Integer categoryId,
+// @RequestParam(value = "dpi",required = false) String dpi,
+// @RequestParam(value = "caption", required = false) String caption){
+// // 创建临时用户对象
+// User user = new User(1L,"testuser");
+// //user.setUserid(1L); // 设置测试用户ID
+// try{
+// //torrentService.Upload(torrentFile,title,description,user);
+// return torrentService.Upload(torrentFile, title, description, categoryId, dpi,caption,user);
+// }catch(Exception e){
+// return ResponseEntity.badRequest().body("Upload failed:" + e.getMessage());
+// }
+//}
+
+ @GetMapping("/{userId}/username")
+ public ResponseEntity<String> getUsernameByUserId(@PathVariable Long userId) {
+ try {
+ // 调用 Mapper 查询用户名
+ String username = userMapper.selectUsernameByUserid(userId);
+ //System.out.println("Passkey for userId " + userId + ": " + passkey); // 调试日志
+
+ if (username == null) {
+ // 用户不存在
+ return ResponseEntity.notFound().build();
+ }
+
+ // 返回用户名
+ return ResponseEntity.ok(username);
+ } catch (Exception e) {
+ e.printStackTrace();
+ // 其他异常(如数据库错误)
+ return ResponseEntity.internalServerError().build();
+ }
+ }
+//触发检查是否需要促销
+@PostMapping("/applyPromotions")
+public ResponseEntity<?> applyPromotions(@RequestParam("userid") Long userid)
+{
+ if(userMapper.getpermissionByUserid(userid) == 1)
+ {
+ torrentMapper.setFreePromotion();
+ torrentMapper.setDoubleUpload();
+ torrentMapper.setHalfDownload();
+ torrentMapper.setDoubleUpload();
+ }else{
+ throw new SecurityException("无权执行此操作");
+ }
+
+ return ResponseEntity.ok(Map.of(
+ "success", true,
+ "message", "促销规则已应用"
+ ));
+}
+
+//设置促销类型
+@PostMapping("/setPromotion")
+public ResponseEntity<?> setPromotion(
+ @RequestParam("userid") Long userid,
+ @RequestParam("torrentId") Long torrentId,
+ @RequestParam("promotionId") Long promotionId){
+ try {
+ //1-上传加倍;2-下载减半;3-免费下载;NULL-没有促销
+ torrentService.setPromotion(torrentId, promotionId, userid);
+
+ return ResponseEntity.ok(Map.of(
+ "success", true,
+ "message", "促销类型设置成功"
+ ));
+ } catch (SecurityException e) {
+ return ResponseEntity.status(HttpStatus.FORBIDDEN).body(
+ Map.of("success", false, "message", e.getMessage())
+ );
+ } catch (Exception e) {
+ return ResponseEntity.internalServerError().body(
+ Map.of("success", false, "message", "设置促销类型失败: " + e.getMessage())
+ );
+ }
+}
+@DeleteMapping("/delete/{torrentId}")
+public ResponseEntity<?> deleteTorrent(
+ @RequestParam("userid") Long userid,
+ @PathVariable Long torrentId) {
+ System.out.println("到这里了");
+
+ try {
+ // 验证权限并删除
+ torrentService.deleteTorrent(userid,torrentId);
+ return ResponseEntity.ok().body(
+ Map.of("success", true, "message", "种子删除成功")
+ );
+ } catch (SecurityException e) {
+ return ResponseEntity.status(HttpStatus.FORBIDDEN).body(
+ Map.of("success", false, "message", e.getMessage())
+ );
+ } catch (Exception e) {
+ return ResponseEntity.internalServerError().body(
+ Map.of("success", false, "message", "删除失败: " + e.getMessage())
+ );
+ }
+}
+//@PostMapping("/upload")
+//public ResponseEntity<?> uploadTorrent(
+// @RequestParam("userid") Long userid,
+// @RequestParam("file") MultipartFile torrentFile,
+// @RequestParam("title") String title,
+// @RequestParam("description") String description,
+// @RequestParam("categoryId") Integer categoryId,
+// // 以下为通用扩展字段(根据类型选择性使用)
+// @RequestParam(value = "dpi",required = false) String dpi,
+// @RequestParam(value = "caption", required = false) String caption,
+// @RequestParam(value = "region", required = false) String region,
+// @RequestParam(value = "year", required = false) Integer year,
+// @RequestParam(value = "genre", required = false) String genre,
+// @RequestParam(value = "format", required = false) String format,
+// @RequestParam(value = "resolution", required = false) String resolution,
+// @RequestParam(value = "codecFormat", required = false) String codecFormat,
+// @RequestParam(value = "platform", required = false) String platform,
+// @RequestParam(value = "language", required = false) String language,
+// @RequestParam(value = "eventType", required = false) String eventType,
+// @RequestParam(value = "dataType", required = false) String dataType,
+// @RequestParam(value = "source", required = false) String source,
+// @RequestParam(value = "style", required = false) String style,
+// @RequestParam(value = "isMainland", required = false) Boolean isMainland){
+// // 创建临时用户对象
+// //User user = new User(1L,"testuser");
+// //User user = userMapper.selectById(userid);
+//
+// // 构建扩展参数Map
+// Map<String, String> extraParams = new HashMap<>();
+//
+// // 通用参数
+// putIfNotNull(extraParams, "dpi", dpi);
+// putIfNotNull(extraParams, "caption", caption);
+// putIfNotNull(extraParams, "region", region);
+// putIfNotNull(extraParams, "year", year != null ? year.toString() : null);
+// putIfNotNull(extraParams, "genre", genre);
+// putIfNotNull(extraParams, "format", format);
+// putIfNotNull(extraParams, "resolution", resolution);
+//
+// // 特殊参数
+// putIfNotNull(extraParams, "codecFormat", codecFormat); // 电影编码格式
+// putIfNotNull(extraParams, "platform", platform); // 游戏/软件平台
+// putIfNotNull(extraParams, "language", language); // 游戏语言
+// putIfNotNull(extraParams, "eventType", eventType); // 体育赛事类型
+// putIfNotNull(extraParams, "source", source); // 纪录片来源
+// putIfNotNull(extraParams, "style", style); // 音乐风格
+// putIfNotNull(extraParams, "isMainland", isMainland != null ? isMainland.toString() : null); // 综艺是否大陆
+// putIfNotNull(extraParams, "dataType", dataType);
+//
+//// extraParams.put("region", "CN");
+//// extraParams.put("year", "2023");
+//// extraParams.put("genre", "Action");
+//// extraParams.put("encodeFormat", "H.264");
+//// extraParams.put("resolution", "1080p");
+//
+//
+// //user.setUserid(1L); // 设置测试用户ID
+// try{
+// //torrentService.Upload(torrentFile,title,description,user);
+// //return torrentService.Upload(torrentFile, title, description, categoryId, dpi,caption,user);
+//
+//// return torrentService.uploadWithCategory(
+//// torrentFile, title, description, categoryId, user, dpi, caption,
+//// region, year, genre, format, resolution, codecFormat,
+//// platform, language, eventType, source, style, isMainland
+//// );
+// // 调用Service
+// return torrentService.uploadWithCategory(
+// torrentFile,
+// title,
+// description,
+// categoryId,
+// userid,
+// extraParams
+// );
+// }catch(Exception e){
+// return ResponseEntity.badRequest().body("Upload failed:" + e.getMessage());
+// }
+//}
+@PostMapping("/fullrequest")
+public ResponseEntity<?> uploadTorrentinrequest(
+ @RequestParam("userid") Long userid,
+ @RequestParam("file") MultipartFile torrentFile, // 种子文件
+ @RequestParam("coverImage") MultipartFile coverImage, // 封面图片
+ @RequestParam("title") String title,
+ @RequestParam("description") String description,
+ @RequestParam("categoryId") Integer categoryId,
+ @RequestParam("requestId") Integer requestId,
+ // 以下为通用扩展字段(根据类型选择性使用)
+ @RequestParam(value = "dpi", required = false) String dpi,
+ @RequestParam(value = "caption", required = false) String caption,
+ @RequestParam(value = "region", required = false) String region,
+ @RequestParam(value = "year", required = false) Integer year,
+ @RequestParam(value = "genre", required = false) String genre,
+ @RequestParam(value = "format", required = false) String format,
+ @RequestParam(value = "resolution", required = false) String resolution,
+ @RequestParam(value = "codecFormat", required = false) String codecFormat,
+ @RequestParam(value = "platform", required = false) String platform,
+ @RequestParam(value = "language", required = false) String language,
+ @RequestParam(value = "eventType", required = false) String eventType,
+ @RequestParam(value = "dataType", required = false) String dataType,
+ @RequestParam(value = "source", required = false) String source,
+ @RequestParam(value = "style", required = false) String style,
+ @RequestParam(value = "isMainland", required = false) Boolean isMainland) {
+
+ // 创建临时用户对象
+ //User user = new User(1L,"testuser");
+ //User user = userMapper.selectById(userid);
+
+ // 构建扩展参数Map
+ Map<String, String> extraParams = new HashMap<>();
+
+ // 通用参数
+ putIfNotNull(extraParams, "dpi", dpi);
+ putIfNotNull(extraParams, "caption", caption);
+ putIfNotNull(extraParams, "region", region);
+ putIfNotNull(extraParams, "year", year != null ? year.toString() : null);
+ putIfNotNull(extraParams, "genre", genre);
+ putIfNotNull(extraParams, "format", format);
+ putIfNotNull(extraParams, "resolution", resolution);
+
+ // 特殊参数
+ putIfNotNull(extraParams, "codecFormat", codecFormat); // 电影编码格式
+ putIfNotNull(extraParams, "platform", platform); // 游戏/软件平台
+ putIfNotNull(extraParams, "language", language); // 游戏语言
+ putIfNotNull(extraParams, "eventType", eventType); // 体育赛事类型
+ putIfNotNull(extraParams, "source", source); // 纪录片来源
+ putIfNotNull(extraParams, "style", style); // 音乐风格
+ putIfNotNull(extraParams, "isMainland", isMainland != null ? isMainland.toString() : null); // 综艺是否大陆
+ putIfNotNull(extraParams, "dataType", dataType);
+
+
+ try {
+ // 调用Service,传递封面图片
+ return torrentService.uploadtohelp(
+ requestId,
+ torrentFile,
+ coverImage, // 新增的封面图片参数
+ title,
+ description,
+ categoryId,
+ userid,
+ extraParams
+ );
+ } catch (Exception e) {
+ return ResponseEntity.badRequest().body("Upload failed:" + e.getMessage());
+ }
+}
@PostMapping("/upload")
public ResponseEntity<?> uploadTorrent(
@RequestParam("userid") Long userid,
diff --git a/src/main/java/com/pt5/pthouduan/entity/Category.java b/src/main/java/com/pt5/pthouduan/entity/Category.java
index c338fbb..e134092 100644
--- a/src/main/java/com/pt5/pthouduan/entity/Category.java
+++ b/src/main/java/com/pt5/pthouduan/entity/Category.java
@@ -7,7 +7,7 @@
/**
* <p>
- *
+ * 分类表
* </p>
*
* @author ljx
@@ -21,10 +21,20 @@
@TableId("categoryid")
private Integer categoryid;
- private Integer categorytype;
+ private String category_name; // 数据库列名
- private String categoryName;
+ private String category_description; // 数据库列名
+ // 构造方法
+ public Category() {}
+
+ public Category(Integer categoryid, String category_name, String category_description) {
+ this.categoryid = categoryid;
+ this.category_name = category_name;
+ this.category_description = category_description;
+ }
+
+ // Getter 和 Setter 方法(遵循JavaBean规范)
public Integer getCategoryid() {
return categoryid;
}
@@ -33,28 +43,28 @@
this.categoryid = categoryid;
}
- public Integer getCategorytype() {
- return categorytype;
+ public String getCategory_name() { // 注意方法名必须和属性名一致
+ return category_name;
}
- public void setCategorytype(Integer categorytype) {
- this.categorytype = categorytype;
+ public void setCategory_name(String category_name) { // 注意方法名必须和属性名一致
+ this.category_name = category_name;
}
- public String getCategoryName() {
- return categoryName;
+ public String getCategory_description() {
+ return category_description;
}
- public void setCategoryName(String categoryName) {
- this.categoryName = categoryName;
+ public void setCategory_description(String category_description) {
+ this.category_description = category_description;
}
@Override
public String toString() {
return "Category{" +
- "categoryid = " + categoryid +
- ", categorytype = " + categorytype +
- ", categoryName = " + categoryName +
- "}";
+ "categoryid=" + categoryid +
+ ", category_name='" + category_name + '\'' + // 修正拼写错误
+ ", category_description='" + category_description + '\'' + // 修正字段名
+ '}';
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/com/pt5/pthouduan/mapper/CategoryMapper.java b/src/main/java/com/pt5/pthouduan/mapper/CategoryMapper.java
index fac2a81..5aba81d 100644
--- a/src/main/java/com/pt5/pthouduan/mapper/CategoryMapper.java
+++ b/src/main/java/com/pt5/pthouduan/mapper/CategoryMapper.java
@@ -4,6 +4,8 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
+import java.util.List;
+
/**
* <p>
* Mapper 接口
@@ -14,5 +16,5 @@
*/
@Mapper
public interface CategoryMapper extends BaseMapper<Category> {
-
+ List<Category> getAllCategories();
}
diff --git a/src/main/java/com/pt5/pthouduan/service/CategoryService.java b/src/main/java/com/pt5/pthouduan/service/CategoryService.java
new file mode 100644
index 0000000..6eb2efe
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/service/CategoryService.java
@@ -0,0 +1,9 @@
+package com.pt5.pthouduan.service;
+
+import com.pt5.pthouduan.entity.Category;
+
+import java.util.List;
+
+public interface CategoryService {
+ List<Category> getAllCategories();
+}
diff --git a/src/main/java/com/pt5/pthouduan/service/impl/CategoryServiceImp.java b/src/main/java/com/pt5/pthouduan/service/impl/CategoryServiceImp.java
new file mode 100644
index 0000000..a98507b
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/service/impl/CategoryServiceImp.java
@@ -0,0 +1,19 @@
+package com.pt5.pthouduan.service.impl;
+
+import com.pt5.pthouduan.entity.Category;
+import com.pt5.pthouduan.mapper.CategoryMapper;
+import com.pt5.pthouduan.service.CategoryService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class CategoryServiceImp implements CategoryService {
+ @Autowired
+ private CategoryMapper categoryMapper;
+ @Override
+ public List<Category> getAllCategories() {
+ return categoryMapper.getAllCategories();
+ }
+}
diff --git a/src/main/resources/mapper/xml/CategoryMapper.xml b/src/main/resources/mapper/xml/CategoryMapper.xml
new file mode 100644
index 0000000..7793c47
--- /dev/null
+++ b/src/main/resources/mapper/xml/CategoryMapper.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.pt5.pthouduan.mapper.CategoryMapper">
+
+ <!-- 通用查询映射结果 -->
+ <!-- 定义结果映射 -->
+ <resultMap id="CategoryResultMap" type="com.pt5.pthouduan.entity.Category">
+ <id property="categoryid" column="categoryid"/>
+ <result property="category_name" column="category_name"/>
+ <result property="category_description" column="category_description"/>
+ </resultMap>
+
+ <!-- 通用查询结果列 -->
+ <sql id="Base_Column_List">
+ categoryid, category_name, category_description
+ </sql>
+ <!-- 查询所有分类 -->
+ <select id="getAllCategories" resultMap="CategoryResultMap">
+ SELECT
+ categoryid,
+ category_name,
+ category_description
+ FROM
+ category
+ </select>
+
+</mapper>
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/CategoryControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/CategoryControllerTest.java
new file mode 100644
index 0000000..002cfdb
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/CategoryControllerTest.java
@@ -0,0 +1,58 @@
+package com.pt5.pthouduan.ControllerTest;
+
+import com.pt5.pthouduan.controller.CategoryController;
+import com.pt5.pthouduan.entity.Category;
+import com.pt5.pthouduan.service.CategoryService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+public class CategoryControllerTest {
+
+ private MockMvc mockMvc;
+
+ @Mock
+ private CategoryService categoryService;
+
+ @InjectMocks
+ private CategoryController categoryController;
+
+ @BeforeEach
+ public void setUp() {
+ MockitoAnnotations.openMocks(this);
+ mockMvc = MockMvcBuilders.standaloneSetup(categoryController).build();
+ }
+
+ @Test
+ public void testGetAllCategories() throws Exception {
+ // 准备模拟数据
+ Category category1 = new Category();
+ category1.setCategoryid(1);
+ category1.setCategory_name("电子产品");
+
+ Category category2 = new Category();
+ category2.setCategoryid(2);
+ category2.setCategory_name("服装");
+
+ List<Category> categories = Arrays.asList(category1, category2);
+
+ // 模拟 service 行为
+ when(categoryService.getAllCategories()).thenReturn(categories);
+
+ // 执行请求并验证结果
+ mockMvc.perform(get("/categories"))
+ .andExpect(status().isOk());
+ }
+}
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentAddCreditControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentAddCreditControllerTest.java
new file mode 100644
index 0000000..6730c94
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentAddCreditControllerTest.java
@@ -0,0 +1,125 @@
+package com.pt5.pthouduan.ControllerTest;
+
+
+
+import com.pt5.pthouduan.controller.TorrentController;
+import com.pt5.pthouduan.service.TorrentService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+class TorrentAddCreditControllerTest {
+
+ @Mock
+ private TorrentService torrentService;
+
+ @InjectMocks
+ private TorrentController torrentController;
+
+ private MockMvc mockMvc;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ mockMvc = MockMvcBuilders.standaloneSetup(torrentController).build();
+ }
+
+ @Test
+ void addCredit_WithValidParameters_ShouldReturnSuccess() throws Exception {
+ // Arrange
+ Long manageid = 1L;
+ Long userid = 2L;
+ Integer credit = 10;
+ Long helpedId = 3L;
+
+ // 模拟服务层调用成功
+ doNothing().when(torrentService).addcredit(manageid, userid, credit);
+ doNothing().when(torrentService).deducecredit(manageid, helpedId, credit);
+
+ // Act & Assert
+ mockMvc.perform(post("/torrent/addcredit")
+ .param("manageid", manageid.toString())
+ .param("userid", userid.toString())
+ .param("credit", credit.toString())
+ .param("helpedId", helpedId.toString()))
+ .andExpect(status().isOk())
+ .andExpect(content().string(credit.toString()));
+
+ // 验证服务层方法被调用
+ verify(torrentService, times(1)).addcredit(manageid, userid, credit);
+ verify(torrentService, times(1)).deducecredit(manageid, helpedId, credit);
+ }
+
+ @Test
+ void addCredit_WhenAddCreditFails_ShouldReturnServerError() throws Exception {
+ // Arrange
+ Long manageid = 1L;
+ Long userid = 2L;
+ Integer credit = 10;
+ Long helpedId = 3L;
+
+ // 模拟addcredit抛出异常
+ doThrow(new RuntimeException("Add credit failed")).when(torrentService).addcredit(manageid, userid, credit);
+ // deducecredit不应该被调用
+ doNothing().when(torrentService).deducecredit(anyLong(), anyLong(), anyInt());
+
+ // Act & Assert
+ mockMvc.perform(post("/torrent/addcredit")
+ .param("manageid", manageid.toString())
+ .param("userid", userid.toString())
+ .param("credit", credit.toString())
+ .param("helpedId", helpedId.toString()))
+ .andExpect(status().isInternalServerError())
+ .andExpect(jsonPath("$.success").value(false))
+ .andExpect(jsonPath("$.message").value("服务器错误: Add credit failed"));
+
+ // 验证服务层方法调用情况
+ verify(torrentService, times(1)).addcredit(manageid, userid, credit);
+ verify(torrentService, never()).deducecredit(anyLong(), anyLong(), anyInt());
+ }
+
+ @Test
+ void addCredit_WhenDeduceCreditFails_ShouldReturnServerError() throws Exception {
+ // Arrange
+ Long manageid = 1L;
+ Long userid = 2L;
+ Integer credit = 10;
+ Long helpedId = 3L;
+
+ // 模拟addcredit成功
+ doNothing().when(torrentService).addcredit(manageid, userid, credit);
+ // 模拟deducecredit抛出异常
+ doThrow(new RuntimeException("Deduce credit failed")).when(torrentService).deducecredit(manageid, helpedId, credit);
+
+ // Act & Assert
+ mockMvc.perform(post("/torrent/addcredit")
+ .param("manageid", manageid.toString())
+ .param("userid", userid.toString())
+ .param("credit", credit.toString())
+ .param("helpedId", helpedId.toString()))
+ .andExpect(status().isInternalServerError())
+ .andExpect(jsonPath("$.success").value(false))
+ .andExpect(jsonPath("$.message").value("服务器错误: Deduce credit failed"));
+
+ // 验证服务层方法调用情况
+ verify(torrentService, times(1)).addcredit(manageid, userid, credit);
+ verify(torrentService, times(1)).deducecredit(manageid, helpedId, credit);
+ }
+
+ @Test
+ void addCredit_WithoutParameters_ShouldReturnBadRequest() throws Exception {
+ // Act & Assert
+ mockMvc.perform(post("/torrent/addcredit"))
+ .andExpect(status().isBadRequest());
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentApplyPromotionsControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentApplyPromotionsControllerTest.java
new file mode 100644
index 0000000..78ab203
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentApplyPromotionsControllerTest.java
@@ -0,0 +1,76 @@
+package com.pt5.pthouduan.ControllerTest;
+
+import com.pt5.pthouduan.controller.TorrentController;
+import com.pt5.pthouduan.mapper.TorrentMapper;
+import com.pt5.pthouduan.mapper.UserMapper;
+import com.pt5.pthouduan.service.TorrentService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+class TorrentApplyPromotionsControllerTest {
+
+ @Mock
+ private UserMapper userMapper;
+
+ @Mock
+ private TorrentService torrentService;
+
+ @Mock
+ private TorrentMapper torrentMapper; // Mock TorrentMapper
+
+ @InjectMocks
+ private TorrentController torrentController;
+
+ private MockMvc mockMvc;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ mockMvc = MockMvcBuilders.standaloneSetup(torrentController).build();
+ }
+
+ @Test
+ void applyPromotions_WithPermission_ShouldReturnSuccess() throws Exception {
+ // Arrange
+ Long userid = 1L;
+ Long torrentId = 101L;
+ Long helpedId = 2L;
+
+ // 模拟用户有权限(返回1表示有权限)
+ when(userMapper.getpermissionByUserid(userid)).thenReturn(1);
+
+ // 模拟服务层调用成功
+ doNothing().when(torrentService).addcredit(anyLong(), anyLong(), anyInt());
+ doNothing().when(torrentService).deducecredit(anyLong(), anyLong(), anyInt());
+
+ // 模拟 TorrentMapper 方法调用
+ //when(torrentMapper.setFreePromotion()).thenReturn(1); // 关键:Mock torrentMapper
+
+ // Act & Assert
+ mockMvc.perform(post("/torrent/applyPromotions")
+ .param("userid", userid.toString())
+ .param("torrentid", torrentId.toString())
+ .param("helpedid", helpedId.toString()))
+ .andExpect(status().isOk()) // 验证状态码
+ .andExpect(content().string(containsString("success"))); // 验证响应内容
+ }
+
+
+ @Test
+ void applyPromotions_WithoutParameters_ShouldReturnBadRequest() throws Exception {
+ // Act & Assert
+ mockMvc.perform(post("/torrent/applyPromotions"))
+ .andExpect(status().isBadRequest()); // 验证状态码
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentDeduceCreditControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentDeduceCreditControllerTest.java
new file mode 100644
index 0000000..99c2a09
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentDeduceCreditControllerTest.java
@@ -0,0 +1,87 @@
+package com.pt5.pthouduan.ControllerTest;
+
+
+import com.pt5.pthouduan.controller.TorrentController;
+import com.pt5.pthouduan.service.TorrentService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+class TorrentDeduceCreditControllerTest {
+
+ @Mock
+ private TorrentService torrentService;
+
+ @InjectMocks
+ private TorrentController torrentController;
+
+ private MockMvc mockMvc;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ mockMvc = MockMvcBuilders.standaloneSetup(torrentController).build();
+ }
+
+ @Test
+ void deduceCredit_WithValidParameters_ShouldReturnSuccess() throws Exception {
+ // Arrange
+ Long manageid = 1L;
+ Long userid = 2L;
+ Integer credit = 10;
+
+ // 模拟服务层调用成功
+ doNothing().when(torrentService).deducecredit(manageid, userid, credit);
+
+ // Act & Assert
+ mockMvc.perform(post("/torrent/deducecredit")
+ .param("manageid", manageid.toString())
+ .param("userid", userid.toString())
+ .param("credit", credit.toString()))
+ .andExpect(status().isOk())
+ .andExpect(content().string(credit.toString()));
+
+ // 验证服务层方法被调用
+ verify(torrentService, times(1)).deducecredit(manageid, userid, credit);
+ }
+
+ @Test
+ void deduceCredit_WhenServiceThrowsException_ShouldReturnServerError() throws Exception {
+ // Arrange
+ Long manageid = 1L;
+ Long userid = 2L;
+ Integer credit = 10;
+
+ // 模拟服务层抛出异常
+ doThrow(new RuntimeException("Database error")).when(torrentService).deducecredit(manageid, userid, credit);
+
+ // Act & Assert
+ mockMvc.perform(post("/torrent/deducecredit")
+ .param("manageid", manageid.toString())
+ .param("userid", userid.toString())
+ .param("credit", credit.toString()))
+ .andExpect(status().isInternalServerError())
+ .andExpect(jsonPath("$.success").value(false))
+ .andExpect(jsonPath("$.message").value("服务器错误: Database error"));
+
+ // 验证服务层方法被调用
+ verify(torrentService, times(1)).deducecredit(manageid, userid, credit);
+ }
+
+ @Test
+ void deduceCredit_WithoutParameters_ShouldReturnBadRequest() throws Exception {
+ // Act & Assert
+ mockMvc.perform(post("/torrent/deducecredit"))
+ .andExpect(status().isBadRequest());
+ }
+}
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentDeleteControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentDeleteControllerTest.java
new file mode 100644
index 0000000..ad0bcdb
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentDeleteControllerTest.java
@@ -0,0 +1,104 @@
+package com.pt5.pthouduan.ControllerTest;
+
+
+import com.pt5.pthouduan.controller.TorrentController;
+import com.pt5.pthouduan.service.TorrentService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+class TorrentDeleteControllerTest {
+
+ @Mock
+ private TorrentService torrentService;
+
+ @InjectMocks
+ private TorrentController torrentController;
+
+ private MockMvc mockMvc;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ mockMvc = MockMvcBuilders.standaloneSetup(torrentController).build();
+ }
+
+ @Test
+ void deleteTorrent_WithPermission_ShouldReturnSuccess() throws Exception {
+ // Arrange
+ Long userid = 1L;
+ Long torrentId = 101L;
+
+ // 模拟服务层调用成功
+ doNothing().when(torrentService).deleteTorrent(userid, torrentId);
+
+ // Act & Assert
+ mockMvc.perform(delete("/torrent/delete/{torrentId}", torrentId)
+ .param("userid", userid.toString()))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.success").value(true))
+ .andExpect(jsonPath("$.message").value("种子删除成功"));
+
+ // 验证服务层方法被调用
+ verify(torrentService, times(1)).deleteTorrent(userid, torrentId);
+ }
+
+ @Test
+ void deleteTorrent_WithoutPermission_ShouldReturnForbidden() throws Exception {
+ // Arrange
+ Long userid = 2L;
+ Long torrentId = 101L;
+
+ // 模拟服务层抛出SecurityException
+ doThrow(new SecurityException("无权删除此种子")).when(torrentService).deleteTorrent(userid, torrentId);
+
+ // Act & Assert
+ mockMvc.perform(delete("/torrent/delete/{torrentId}", torrentId)
+ .param("userid", userid.toString()))
+ .andExpect(status().isForbidden())
+ .andExpect(jsonPath("$.success").value(false))
+ .andExpect(jsonPath("$.message").value("无权删除此种子"));
+
+ // 验证服务层方法被调用
+ verify(torrentService, times(1)).deleteTorrent(userid, torrentId);
+ }
+
+ @Test
+ void deleteTorrent_WhenServiceThrowsException_ShouldReturnInternalServerError() throws Exception {
+ // Arrange
+ Long userid = 1L;
+ Long torrentId = 101L;
+
+ // 模拟服务层抛出其他异常
+ doThrow(new RuntimeException("数据库错误")).when(torrentService).deleteTorrent(userid, torrentId);
+
+ // Act & Assert
+ mockMvc.perform(delete("/torrent/delete/{torrentId}", torrentId)
+ .param("userid", userid.toString()))
+ .andExpect(status().isInternalServerError())
+ .andExpect(jsonPath("$.success").value(false))
+ .andExpect(jsonPath("$.message").value("删除失败: 数据库错误"));
+
+ // 验证服务层方法被调用
+ verify(torrentService, times(1)).deleteTorrent(userid, torrentId);
+ }
+
+ @Test
+ void deleteTorrent_WithoutUserIdParameter_ShouldReturnBadRequest() throws Exception {
+ // Arrange
+ Long torrentId = 101L;
+
+ // Act & Assert
+ mockMvc.perform(delete("/torrent/delete/{torrentId}", torrentId))
+ .andExpect(status().isBadRequest());
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentDetailControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentDetailControllerTest.java
new file mode 100644
index 0000000..6c0c33e
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentDetailControllerTest.java
@@ -0,0 +1,83 @@
+package com.pt5.pthouduan.ControllerTest;
+
+import com.pt5.pthouduan.controller.TorrentController;
+import com.pt5.pthouduan.entity.Torrent;
+import com.pt5.pthouduan.service.TorrentService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+class TorrentDetailControllerTest {
+
+ @Mock
+ private TorrentService torrentService;
+
+ @InjectMocks
+ private TorrentController torrentController;
+
+ private MockMvc mockMvc;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ mockMvc = MockMvcBuilders.standaloneSetup(torrentController).build();
+ }
+
+ @Test
+ void getTorrentById_ExistingId_ShouldReturnTorrent() throws Exception {
+ // Arrange
+ Long id = 1L;
+ Torrent torrent = new Torrent();
+ torrent.setTorrentid(id);
+
+ when(torrentService.getTorrentById(id)).thenReturn(torrent);
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/{id}", id))
+ .andExpect(status().isOk());
+ //.andExpect(jsonPath("$.id").value(id));
+
+ // 验证服务层方法被调用
+ verify(torrentService, times(1)).getTorrentById(id);
+ }
+
+ @Test
+ void getTorrentById_NonExistingId_ShouldReturnNotFound() throws Exception {
+ // Arrange
+ Long id = 999L;
+
+ when(torrentService.getTorrentById(id)).thenReturn(null);
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/{id}", id))
+ .andExpect(status().isNotFound());
+
+ // 验证服务层方法被调用
+ verify(torrentService, times(1)).getTorrentById(id);
+ }
+
+ @Test
+ void getTorrentById_WhenServiceThrowsException_ShouldReturnBadRequest() throws Exception {
+ // Arrange
+ Long id = 1L;
+
+ when(torrentService.getTorrentById(id)).thenThrow(new RuntimeException("Database error"));
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/{id}", id))
+ .andExpect(status().isBadRequest());
+ //.andExpect(jsonPath("$.message").value("获取种子详情失败: Database error"));
+
+ // 验证服务层方法被调用
+ verify(torrentService, times(1)).getTorrentById(id);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentFullRequestControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentFullRequestControllerTest.java
new file mode 100644
index 0000000..c4a5983
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentFullRequestControllerTest.java
@@ -0,0 +1,188 @@
+package com.pt5.pthouduan.ControllerTest;
+
+
+import com.pt5.pthouduan.controller.TorrentController;
+import com.pt5.pthouduan.service.TorrentService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.http.ResponseEntity;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.util.Map;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyMap;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+class TorrentFullRequestControllerTest {
+
+ @Mock
+ private TorrentService torrentService;
+
+ @InjectMocks
+ private TorrentController torrentController;
+
+ private MockMvc mockMvc;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ mockMvc = MockMvcBuilders.standaloneSetup(torrentController).build();
+ }
+
+ @Test
+ void uploadTorrentinrequest_WithAllParameters_ShouldReturnSuccess() throws Exception {
+ // Arrange
+ Long userid = 1L;
+ Integer requestId = 101;
+ String title = "Test Torrent";
+ String description = "Test Description";
+ Integer categoryId = 1;
+
+ // 创建模拟文件
+ MockMultipartFile torrentFile = new MockMultipartFile(
+ "torrentFile",
+ "test.torrent",
+ "application/x-bittorrent",
+ "torrent content".getBytes()
+ );
+
+ MockMultipartFile coverImage = new MockMultipartFile(
+ "coverImage",
+ "cover.jpg",
+ "image/jpeg",
+ "image content".getBytes()
+ );
+
+ // 模拟服务层调用成功 - 使用更具体的参数或doReturn语法
+ doReturn(ResponseEntity.ok(Map.of("success", true, "message", "Upload successful")))
+ .when(torrentService).uploadtohelp(
+ anyInt(),
+ any(MockMultipartFile.class),
+ any(MockMultipartFile.class),
+ anyString(),
+ anyString(),
+ anyInt(),
+ anyLong(),
+ anyMap()
+ );
+
+ // Act & Assert
+ mockMvc.perform(multipart("/torrent/fullrequest")
+ .file(torrentFile)
+ .file(coverImage)
+ .param("userid", userid.toString())
+ .param("requestId", requestId.toString())
+ .param("title", title)
+ .param("description", description)
+ .param("categoryId", categoryId.toString())
+ .param("dpi", "300")
+ .param("caption", "Test Caption")
+ .param("region", "Asia")
+ .param("year", "2023")
+ .param("genre", "Action")
+ .param("format", "Blu-ray")
+ .param("resolution", "1080p")
+ .param("codecFormat", "H.264")
+ .param("platform", "PC")
+ .param("language", "English")
+ .param("eventType", "Football")
+ .param("source", "BBC")
+ .param("style", "Rock")
+ .param("isMainland", "true")
+ );
+//
+//
+ }
+
+
+ @Test
+ void uploadTorrentinrequest_WhenServiceThrowsException_ShouldReturnBadRequest() throws Exception {
+ // Arrange
+ Long userid = 1L;
+ Integer requestId = 101;
+ String title = "Test Torrent";
+ String description = "Test Description";
+ Integer categoryId = 1;
+
+ // 创建模拟文件
+ MockMultipartFile torrentFile = new MockMultipartFile(
+ "torrentFile",
+ "test.torrent",
+ "application/x-bittorrent",
+ "torrent content".getBytes()
+ );
+
+ MockMultipartFile coverImage = new MockMultipartFile(
+ "coverImage",
+ "cover.jpg",
+ "image/jpeg",
+ "image content".getBytes()
+ );
+
+ // 模拟服务层抛出异常
+ when(torrentService.uploadtohelp(
+ anyInt(),
+ any(MockMultipartFile.class),
+ any(MockMultipartFile.class),
+ anyString(),
+ anyString(),
+ anyInt(),
+ anyLong(),
+ anyMap()
+ )).thenThrow(new RuntimeException("File processing error"));
+
+ // Act & Assert
+ mockMvc.perform(multipart("/torrent/fullrequest")
+ .file(torrentFile)
+ .file(coverImage)
+ .param("userid", userid.toString())
+ .param("requestId", requestId.toString())
+ .param("title", title)
+ .param("description", description)
+ .param("categoryId", categoryId.toString())
+ )
+ .andExpect(status().isBadRequest());
+ //.andExpect(jsonPath("$.message").value("Upload failed:File processing error"));
+ }
+
+ @Test
+ void uploadTorrentinrequest_WithoutRequiredParameters_ShouldReturnBadRequest() throws Exception {
+ // Arrange
+ // 不提供任何必需参数
+
+ // Act & Assert
+ mockMvc.perform(multipart("/torrent/fullrequest"))
+ .andExpect(status().isBadRequest());
+ }
+
+ @Test
+ void uploadTorrentinrequest_WithoutFileParameters_ShouldReturnBadRequest() throws Exception {
+ // Arrange
+ Long userid = 1L;
+ Integer requestId = 101;
+ String title = "Test Torrent";
+ String description = "Test Description";
+ Integer categoryId = 1;
+
+ // 不提供文件参数
+
+ // Act & Assert
+ mockMvc.perform(multipart("/torrent/fullrequest")
+ .param("userid", userid.toString())
+ .param("requestId", requestId.toString())
+ .param("title", title)
+ .param("description", description)
+ .param("categoryId", categoryId.toString())
+ )
+ .andExpect(status().isBadRequest());
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentListByCategoryControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentListByCategoryControllerTest.java
new file mode 100644
index 0000000..7cb6521
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentListByCategoryControllerTest.java
@@ -0,0 +1,85 @@
+package com.pt5.pthouduan.ControllerTest;
+
+import com.pt5.pthouduan.controller.TorrentController;
+import com.pt5.pthouduan.entity.Torrent;
+import com.pt5.pthouduan.service.TorrentService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+class TorrentListByCategoryControllerTest {
+
+ @Mock
+ private TorrentService torrentService;
+
+ @InjectMocks
+ private TorrentController torrentController;
+
+ private MockMvc mockMvc;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ mockMvc = MockMvcBuilders.standaloneSetup(torrentController).build();
+ }
+
+ @Test
+ void getTorrentsByCategory_WithCategoryId_ShouldReturnFilteredTorrents() throws Exception {
+ // Arrange
+ Integer categoryid = 1;
+ Torrent torrent1 = new Torrent();
+ Torrent torrent2 = new Torrent();
+ List<Torrent> torrents = Arrays.asList(torrent1, torrent2);
+
+ when(torrentService.getTorrentsByCategory(categoryid)).thenReturn(torrents);
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/listByCategory")
+ .param("categoryid", categoryid.toString()))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$").isArray())
+ .andExpect(jsonPath("$.length()").value(2));
+ }
+
+ @Test
+ void getTorrentsByCategory_WithoutCategoryId_ShouldReturnAllTorrents() throws Exception {
+ // Arrange
+ Torrent torrent1 = new Torrent();
+ Torrent torrent2 = new Torrent();
+ List<Torrent> torrents = Arrays.asList(torrent1, torrent2);
+
+ when(torrentService.getAllTorrents()).thenReturn(torrents);
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/listByCategory"))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$").isArray())
+ .andExpect(jsonPath("$.length()").value(2));
+ }
+
+ @Test
+ void getTorrentsByCategory_WithNonExistingCategory_ShouldReturnEmptyList() throws Exception {
+ // Arrange
+ Integer categoryid = 999;
+ when(torrentService.getTorrentsByCategory(categoryid)).thenReturn(Collections.emptyList());
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/listByCategory")
+ .param("categoryid", categoryid.toString()))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$").isArray())
+ .andExpect(jsonPath("$.length()").value(0));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentListByCategoryWithFilterControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentListByCategoryWithFilterControllerTest.java
new file mode 100644
index 0000000..7fbc7fb
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentListByCategoryWithFilterControllerTest.java
@@ -0,0 +1,98 @@
+package com.pt5.pthouduan.ControllerTest;
+
+
+import com.pt5.pthouduan.controller.TorrentController;
+import com.pt5.pthouduan.entity.Torrent;
+import com.pt5.pthouduan.service.TorrentService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.util.*;
+
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+class TorrentListByCategoryWithFilterControllerTest {
+
+ @Mock
+ private TorrentService torrentService;
+
+ @InjectMocks
+ private TorrentController torrentController;
+
+ private MockMvc mockMvc;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ mockMvc = MockMvcBuilders.standaloneSetup(torrentController).build();
+ }
+
+ @Test
+ void getTorrentsByCategorywithFilter_WithCategoryAndFilters_ShouldReturnFilteredTorrents() throws Exception {
+ // Arrange
+ Integer categoryid = 1;
+ Map<String, String> filters = new HashMap<>();
+ filters.put("key1", "value1");
+ filters.put("key2", "value2");
+
+ Torrent torrent1 = new Torrent();
+ Torrent torrent2 = new Torrent();
+ List<Torrent> torrents = Arrays.asList(torrent1, torrent2);
+
+ when(torrentService.getTorrentsByCategorywithfilters(categoryid, filters)).thenReturn(torrents);
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/listByCategorywithfilter")
+ .param("categoryid", categoryid.toString())
+ .param("key1", "value1")
+ .param("key2", "value2"))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$").isArray())
+ .andExpect(jsonPath("$.length()").value(2));
+ }
+
+ @Test
+ void getTorrentsByCategorywithFilter_WithCategoryButNoFilters_ShouldReturnFilteredTorrents() throws Exception {
+ // Arrange
+ Integer categoryid = 1;
+ Map<String, String> filters = new HashMap<>();
+
+ Torrent torrent1 = new Torrent();
+ Torrent torrent2 = new Torrent();
+ List<Torrent> torrents = Arrays.asList(torrent1, torrent2);
+
+ when(torrentService.getTorrentsByCategorywithfilters(categoryid, filters)).thenReturn(torrents);
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/listByCategorywithfilter")
+ .param("categoryid", categoryid.toString()))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$").isArray())
+ .andExpect(jsonPath("$.length()").value(2));
+ }
+
+ @Test
+ void getTorrentsByCategorywithFilter_WithNonExistingCategory_ShouldReturnEmptyList() throws Exception {
+ // Arrange
+ Integer categoryid = 999;
+ Map<String, String> filters = new HashMap<>();
+ filters.put("key1", "value1");
+
+ when(torrentService.getTorrentsByCategorywithfilters(categoryid, filters)).thenReturn(Collections.emptyList());
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/listByCategorywithfilter")
+ .param("categoryid", categoryid.toString())
+ .param("key1", "value1"))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$").isArray())
+ .andExpect(jsonPath("$.length()").value(0));
+ }
+}
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentListControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentListControllerTest.java
new file mode 100644
index 0000000..582e753
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentListControllerTest.java
@@ -0,0 +1,66 @@
+package com.pt5.pthouduan.ControllerTest;
+
+
+import com.pt5.pthouduan.controller.TorrentController;
+import com.pt5.pthouduan.entity.Torrent;
+import com.pt5.pthouduan.service.TorrentService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+class TorrentListControllerTest {
+
+ @Mock
+ private TorrentService torrentService;
+
+ @InjectMocks
+ private TorrentController torrentController;
+
+ private MockMvc mockMvc;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ mockMvc = MockMvcBuilders.standaloneSetup(torrentController).build();
+ }
+
+ @Test
+ void getAllTorrents_ShouldReturnAllTorrents() throws Exception {
+ // Arrange
+ Torrent torrent1 = new Torrent();
+ Torrent torrent2 = new Torrent();
+ List<Torrent> torrents = Arrays.asList(torrent1, torrent2);
+
+ when(torrentService.getAllTorrents()).thenReturn(torrents);
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/list"))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$").isArray())
+ .andExpect(jsonPath("$.length()").value(2));
+ }
+
+ @Test
+ void getAllTorrents_ShouldReturnEmptyListWhenNoTorrents() throws Exception {
+ // Arrange
+ when(torrentService.getAllTorrents()).thenReturn(Collections.emptyList());
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/list"))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$").isArray())
+ .andExpect(jsonPath("$.length()").value(0));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentSearchControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentSearchControllerTest.java
new file mode 100644
index 0000000..9e3aa2f
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentSearchControllerTest.java
@@ -0,0 +1,91 @@
+package com.pt5.pthouduan.ControllerTest;
+
+
+import com.pt5.pthouduan.controller.TorrentController;
+import com.pt5.pthouduan.entity.Torrent;
+import com.pt5.pthouduan.service.TorrentService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+class TorrentSearchControllerTest {
+
+ @Mock
+ private TorrentService torrentService;
+
+ @InjectMocks
+ private TorrentController torrentController;
+
+ private MockMvc mockMvc;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ mockMvc = MockMvcBuilders.standaloneSetup(torrentController).build();
+ }
+
+ @Test
+ void searchTorrents_WithKeyword_ShouldReturnMatchingTorrents() throws Exception {
+ // Arrange
+ String keyword = "test";
+ Torrent torrent1 = new Torrent();
+ Torrent torrent2 = new Torrent();
+ List<Torrent> torrents = Arrays.asList(torrent1, torrent2);
+
+ when(torrentService.searchByKeyword(keyword)).thenReturn(torrents);
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/search")
+ .param("keyword", keyword))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$").isArray())
+ .andExpect(jsonPath("$.length()").value(2));
+ }
+
+ @Test
+ void searchTorrents_WithEmptyKeyword_ShouldReturnEmptyList() throws Exception {
+ // Arrange
+ String keyword = "";
+ when(torrentService.searchByKeyword(keyword)).thenReturn(Collections.emptyList());
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/search")
+ .param("keyword", keyword))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$").isArray())
+ .andExpect(jsonPath("$.length()").value(0));
+ }
+
+ @Test
+ void searchTorrents_WithNoMatchingTorrents_ShouldReturnEmptyList() throws Exception {
+ // Arrange
+ String keyword = "nonexistent";
+ when(torrentService.searchByKeyword(keyword)).thenReturn(Collections.emptyList());
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/search")
+ .param("keyword", keyword))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$").isArray())
+ .andExpect(jsonPath("$.length()").value(0));
+ }
+
+ @Test
+ void searchTorrents_WithoutKeywordParameter_ShouldReturnBadRequest() throws Exception {
+ // Act & Assert
+ mockMvc.perform(get("/torrent/search"))
+ .andExpect(status().isBadRequest());
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentSeederControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentSeederControllerTest.java
new file mode 100644
index 0000000..69cbc9a
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentSeederControllerTest.java
@@ -0,0 +1,78 @@
+package com.pt5.pthouduan.ControllerTest;
+
+import com.pt5.pthouduan.controller.TorrentController;
+import com.pt5.pthouduan.entity.PeerInfo;
+import com.pt5.pthouduan.service.TorrentService;
+import com.pt5.pthouduan.service.impl.PeerService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+//static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+class TorrentSeederControllerTest {
+
+ @Mock
+ private TorrentService torrentService;
+
+ @Mock
+ private PeerService peerService;
+
+
+ @InjectMocks
+ private TorrentController torrentController;
+
+ private MockMvc mockMvc;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ mockMvc = MockMvcBuilders.standaloneSetup(torrentController).build();
+ }
+
+ @Test
+ void getSeedersByInfoHash_ShouldReturnPeers() throws Exception {
+ // Arrange
+ String infoHash = "ABC123";
+ PeerInfo peer1 = new PeerInfo();
+ PeerInfo peer2 = new PeerInfo();
+ List<PeerInfo> peers = Arrays.asList(peer1, peer2);
+
+ // 假设torrentService有一个方法返回PeerInfo列表
+ // 这里需要根据实际torrentService的API进行调整
+ when(peerService.getSeedersByInfoHash(infoHash)).thenReturn(peers);
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/{infoHash}/seeders", infoHash))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$").isArray())
+ .andExpect(jsonPath("$.length()").value(2));
+ }
+
+ @Test
+ void getSeedersByInfoHash_ShouldReturnEmptyListWhenNoPeers() throws Exception {
+ // Arrange
+ String infoHash = "ABC123";
+
+ // 假设torrentService有一个方法返回空列表
+ when(peerService.getSeedersByInfoHash(infoHash)).thenReturn(Collections.emptyList());
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/{infoHash}/seeders", infoHash))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$").isArray())
+ .andExpect(jsonPath("$.length()").value(0));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentSetPromotionControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentSetPromotionControllerTest.java
new file mode 100644
index 0000000..3717f20
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentSetPromotionControllerTest.java
@@ -0,0 +1,109 @@
+package com.pt5.pthouduan.ControllerTest;
+
+import com.pt5.pthouduan.controller.TorrentController;
+import com.pt5.pthouduan.service.TorrentService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+class TorrentSetPromotionControllerTest {
+
+ @Mock
+ private TorrentService torrentService;
+
+ @InjectMocks
+ private TorrentController torrentController;
+
+ private MockMvc mockMvc;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ mockMvc = MockMvcBuilders.standaloneSetup(torrentController).build();
+ }
+
+ @Test
+ void setPromotion_Success_ShouldReturnSuccess() throws Exception {
+ // Arrange
+ Long userid = 1L;
+ Long torrentId = 101L;
+ Long promotionId = 1L;
+
+ // 模拟服务层调用成功
+ doNothing().when(torrentService).setPromotion(torrentId, promotionId, userid);
+
+ // Act & Assert
+ mockMvc.perform(post("/torrent/setPromotion")
+ .param("userid", userid.toString())
+ .param("torrentId", torrentId.toString())
+ .param("promotionId", promotionId.toString()))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.success").value(true))
+ .andExpect(jsonPath("$.message").value("促销类型设置成功"));
+
+ // 验证服务层方法被调用
+ verify(torrentService, times(1)).setPromotion(torrentId, promotionId, userid);
+ }
+
+ @Test
+ void setPromotion_SecurityException_ShouldReturnForbidden() throws Exception {
+ // Arrange
+ Long userid = 1L;
+ Long torrentId = 101L;
+ Long promotionId = 1L;
+
+ // 模拟服务层抛出SecurityException
+ doThrow(new SecurityException("无权设置促销")).when(torrentService).setPromotion(torrentId, promotionId, userid);
+
+ // Act & Assert
+ mockMvc.perform(post("/torrent/setPromotion")
+ .param("userid", userid.toString())
+ .param("torrentId", torrentId.toString())
+ .param("promotionId", promotionId.toString()))
+ .andExpect(status().isForbidden())
+ .andExpect(jsonPath("$.success").value(false))
+ .andExpect(jsonPath("$.message").value("无权设置促销"));
+
+ // 验证服务层方法被调用
+ verify(torrentService, times(1)).setPromotion(torrentId, promotionId, userid);
+ }
+
+ @Test
+ void setPromotion_OtherException_ShouldReturnInternalServerError() throws Exception {
+ // Arrange
+ Long userid = 1L;
+ Long torrentId = 101L;
+ Long promotionId = 1L;
+
+ // 模拟服务层抛出其他异常
+ doThrow(new RuntimeException("数据库错误")).when(torrentService).setPromotion(torrentId, promotionId, userid);
+
+ // Act & Assert
+ mockMvc.perform(post("/torrent/setPromotion")
+ .param("userid", userid.toString())
+ .param("torrentId", torrentId.toString())
+ .param("promotionId", promotionId.toString()))
+ .andExpect(status().isInternalServerError())
+ .andExpect(jsonPath("$.success").value(false))
+ .andExpect(jsonPath("$.message").value("设置促销类型失败: 数据库错误"));
+
+ // 验证服务层方法被调用
+ verify(torrentService, times(1)).setPromotion(torrentId, promotionId, userid);
+ }
+
+ @Test
+ void setPromotion_WithoutParameters_ShouldReturnBadRequest() throws Exception {
+ // Act & Assert
+ mockMvc.perform(post("/torrent/setPromotion"))
+ .andExpect(status().isBadRequest());
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentUsernameControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentUsernameControllerTest.java
new file mode 100644
index 0000000..631ba29
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/TorrentUsernameControllerTest.java
@@ -0,0 +1,88 @@
+package com.pt5.pthouduan.ControllerTest;
+
+
+import com.pt5.pthouduan.controller.TorrentController;
+import com.pt5.pthouduan.mapper.UserMapper;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+class TorrentUsernameControllerTest {
+
+ @Mock
+ private UserMapper userMapper;
+
+ @InjectMocks
+ private TorrentController torrentController;
+
+ private MockMvc mockMvc;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ mockMvc = MockMvcBuilders.standaloneSetup(torrentController).build();
+ }
+
+ @Test
+ void getUsernameByUserId_ExistingUser_ShouldReturnUsername() throws Exception {
+ // Arrange
+ Long userId = 1L;
+ String expectedUsername = "testuser";
+
+ when(userMapper.selectUsernameByUserid(userId)).thenReturn(expectedUsername);
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/{userId}/username", userId))
+ .andExpect(status().isOk())
+ .andExpect(content().string(expectedUsername));
+
+ // 验证userMapper方法被调用
+ verify(userMapper, times(1)).selectUsernameByUserid(userId);
+ }
+
+ @Test
+ void getUsernameByUserId_NonExistingUser_ShouldReturnNotFound() throws Exception {
+ // Arrange
+ Long userId = 999L;
+
+ when(userMapper.selectUsernameByUserid(userId)).thenReturn(null);
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/{userId}/username", userId))
+ .andExpect(status().isNotFound());
+
+ // 验证userMapper方法被调用
+ verify(userMapper, times(1)).selectUsernameByUserid(userId);
+ }
+
+ @Test
+ void getUsernameByUserId_WhenDatabaseErrorOccurs_ShouldReturnInternalServerError() throws Exception {
+ // Arrange
+ Long userId = 1L;
+
+ when(userMapper.selectUsernameByUserid(userId)).thenThrow(new RuntimeException("Database connection failed"));
+
+ // Act & Assert
+ mockMvc.perform(get("/torrent/{userId}/username", userId))
+ .andExpect(status().isInternalServerError());
+
+ // 验证userMapper方法被调用
+ verify(userMapper, times(1)).selectUsernameByUserid(userId);
+ }
+
+ @Test
+ void getUsernameByUserId_WithoutUserIdParameter_ShouldReturnBadRequest() throws Exception {
+ // Act & Assert
+ mockMvc.perform(get("/torrent//username")) // 故意不提供userId
+ .andExpect(status().isBadRequest());
+ }
+}
\ No newline at end of file