controller返回值统一,机器相关实体类修改

This commit is contained in:
唐潇凯 2025-05-31 14:16:20 +08:00
parent 1028cc0705
commit 790193d0c9
10 changed files with 904 additions and 880 deletions

View File

@ -1,9 +1,9 @@
package cd.casic.module.machine.controller;
import cd.casic.framework.commons.pojo.CommonResult;
import cd.casic.module.machine.service.MachineEnvService;
import cd.casic.module.machine.dto.MachineEnvDTO;
import cd.casic.module.machine.pojo.ResponseData;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
@ -13,6 +13,8 @@ import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import static cd.casic.framework.commons.pojo.CommonResult.success;
/**
* 环境变量控制器
@ -28,42 +30,44 @@ public class MachineEnvController {
@PostMapping("/add")
@Operation(summary = "新增环境变量")
public ResponseData add(@RequestBody MachineEnvDTO machineEnvDTO) {
return machineEnvService.add(machineEnvDTO) ? ResponseData.success() : ResponseData.error("新增机器的环境变量失败");
public CommonResult add(@RequestBody MachineEnvDTO machineEnvDTO) {
machineEnvService.add(machineEnvDTO);
return success(true);
}
@PutMapping("/update")
@Operation(summary = "修改环境变量")
public ResponseData update(@RequestBody MachineEnvDTO machineEnvDTO) {
return machineEnvService.update(machineEnvDTO) ? ResponseData.success() : ResponseData.error("修改环境变量失败");
public CommonResult update(@RequestBody MachineEnvDTO machineEnvDTO) {
machineEnvService.update(machineEnvDTO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除机器的环境变量")
public ResponseData deleteByMachineId(
public CommonResult deleteByMachineId(
@RequestParam Long machineId) {
machineEnvService.deleteByMachineId(machineId);
return ResponseData.success();
return success(true);
}
@DeleteMapping("/deleteList")
@Operation(summary = "批量删除机器环境变量")
public ResponseData deleteList(@RequestParam List<Long> ids){
public CommonResult deleteList(@RequestParam List<Long> ids){
machineEnvService.deleteList(ids);
return ResponseData.success();
return success(true);
}
@GetMapping("/listByMachineId")
@Operation(summary = "获取机器的环境变量")
public ResponseData getByMachineId(
public CommonResult getByMachineId(
@RequestParam Long machineId) {
return ResponseData.success(machineEnvService.getByMachineId(machineId));
return success(machineEnvService.getByMachineId(machineId));
}
@PostMapping("/list")
@Operation(summary ="获取环境变量列表")
public ResponseData list(@RequestBody MachineEnvDTO machineEnvDTO) {
return ResponseData.success(machineEnvService.listEnv(machineEnvDTO));
public CommonResult list(@RequestBody MachineEnvDTO machineEnvDTO) {
return success(machineEnvService.listEnv(machineEnvDTO));
}
}

View File

@ -1,10 +1,10 @@
package cd.casic.module.machine.controller;
import cd.casic.framework.commons.pojo.CommonResult;
import cd.casic.module.machine.entity.MachineInfo;
import cd.casic.module.machine.service.MachineInfoService;
import cd.casic.module.machine.dto.MachineInfoDto;
import cd.casic.module.machine.pojo.ResponseData;
import cd.casic.module.machine.pojo.SuccessResponseData;
import io.swagger.v3.oas.annotations.Operation;
@ -14,6 +14,8 @@ import org.springframework.web.bind.annotation.*;
import java.util.List;
import static cd.casic.framework.commons.pojo.CommonResult.success;
@RestController
@Tag(name = "机器信息管理")
@RequestMapping("/api/machineInfo")
@ -23,103 +25,111 @@ public class MachineInfoController {
@PostMapping("/add")
@Operation(summary = "新增机器信息")
public ResponseData add(@RequestBody MachineInfoDto machineInfoDto) {
return machineInfoService.addMachineInfo(machineInfoDto) ? ResponseData.success() : ResponseData.error("新增失败");
public CommonResult add(@RequestBody MachineInfoDto machineInfoDto) {
machineInfoService.addMachineInfo(machineInfoDto);
return success(true);
}
@GetMapping("/list")
@Operation(summary = "获取机器信息列表")
public ResponseData list(@RequestBody MachineInfoDto machineInfoDto) {
return SuccessResponseData.success(machineInfoService.listMachineInfo(machineInfoDto));
public CommonResult list(@RequestBody MachineInfoDto machineInfoDto) {
return success(machineInfoService.listMachineInfo(machineInfoDto));
}
@PutMapping("/update")
@Operation(summary = "编辑机器信息")
public ResponseData update(@RequestBody MachineInfoDto machineInfoDto) {
return machineInfoService.updateMachineInfo(machineInfoDto) ? ResponseData.success() : ResponseData.error("更新失败");
public CommonResult update(@RequestBody MachineInfoDto machineInfoDto) {
machineInfoService.updateMachineInfo(machineInfoDto);
return success(true);
}
@PutMapping("/updateStatus")
@Operation(summary = "机器启用/停用")
public ResponseData updateStatus(@RequestParam("machineInfoId") Long machineInfoId, @RequestParam("status") String status) {
return machineInfoService.updateStatus(machineInfoId, status) ? ResponseData.success() : ResponseData.error("更新状态失败");
public CommonResult updateStatus(@RequestParam("machineInfoId") Long machineInfoId, @RequestParam("status") String status) {
machineInfoService.updateStatus(machineInfoId, status);
return success(true);
}
@PutMapping("/bindingSecretKey")
@Operation(summary = "绑定密钥")
public ResponseData bindingSecretKey(@RequestParam("machineInfoId") Long machineInfoId, @RequestParam("secretKeyId") Long secretKeyId) {
return machineInfoService.bindingSecretKey(machineInfoId, secretKeyId) ? ResponseData.success() : ResponseData.error("绑定失败");
public CommonResult bindingSecretKey(@RequestParam("machineInfoId") Long machineInfoId, @RequestParam("secretKeyId") Long secretKeyId) {
machineInfoService.bindingSecretKey(machineInfoId, secretKeyId);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "机器信息删除")
public ResponseData delete(@RequestParam("machineInfoId") Long machineInfoId) {
public CommonResult delete(@RequestParam("machineInfoId") Long machineInfoId) {
machineInfoService.deleteMachineInfo(machineInfoId);
return ResponseData.success();
return success(true);
}
@DeleteMapping("/deleteList")
@Operation(summary = "批量删除机器信息")
public ResponseData deleteList(@RequestParam("machineInfoId") List<Long> machineInfoIds) {
public CommonResult deleteList(@RequestParam("machineInfoId") List<Long> machineInfoIds) {
machineInfoService.deleteList(machineInfoIds);
return ResponseData.success();
return success(true);
}
@PostMapping("/test")
@Operation(summary = "测试机器连接")
public ResponseData testConnection(@RequestBody MachineInfo machineInfo) {
boolean result = machineInfoService.testConnection(machineInfo);
return ResponseData.success();
public CommonResult testConnection(@RequestBody MachineInfo machineInfo) {
machineInfoService.testConnection(machineInfo);
return success(true);
}
@GetMapping("/status/{machineName}")
@Operation(summary = "获取机器连接状态")
public ResponseData getConnectionStatus(@PathVariable String machineName) {
return ResponseData.success(machineInfoService.getConnectionStatus(machineName));
public CommonResult getConnectionStatus(@PathVariable String machineName) {
return success(machineInfoService.getConnectionStatus(machineName));
}
@GetMapping("/status/all")
@Operation(summary = "获取所有机器连接状态")
public ResponseData getAllConnectionStatus() {
return ResponseData.success(machineInfoService.getAllConnectionStatus());
public CommonResult getAllConnectionStatus() {
return success(machineInfoService.getAllConnectionStatus());
}
@PostMapping("/connect")
@Operation(summary = "建立机器连接")
public ResponseData connect(@RequestBody MachineInfo machineInfo) {
return ResponseData.success(machineInfoService.connect(machineInfo));
public CommonResult connect(@RequestBody MachineInfo machineInfo) {
return success(machineInfoService.connect(machineInfo));
}
@PostMapping("/disconnect/{sessionId}")
@Operation(summary = "断开机器连接")
public ResponseData disconnect(@PathVariable String sessionId) {
return ResponseData.success(machineInfoService.disconnect(sessionId));
public CommonResult disconnect(@PathVariable String sessionId) {
machineInfoService.disconnect(sessionId);
return success(true);
}
@PostMapping("/execute/{sessionId}")
@Operation(summary = "执行远程命令")
public ResponseData executeCommand(
public CommonResult executeCommand(
@PathVariable String sessionId,
@RequestBody String command) {
return ResponseData.success(machineInfoService.executeCommand(sessionId, command));
return success(machineInfoService.executeCommand(sessionId, command));
}
@PostMapping("/upload/{sessionId}")
@Operation(summary = "上传文件到远程机器")
public ResponseData uploadFile(
public CommonResult uploadFile(
@PathVariable String sessionId,
@RequestParam String localFilePath,
@RequestParam String remoteFilePath) {
return ResponseData.success(machineInfoService.uploadFile(sessionId, localFilePath, remoteFilePath));
machineInfoService.uploadFile(sessionId, localFilePath, remoteFilePath);
return success(true);
}
@PostMapping("/download/{sessionId}")
@Operation(summary = "从远程机器下载文件")
public ResponseData downloadFile(
public CommonResult downloadFile(
@PathVariable String sessionId,
@RequestParam String remoteFilePath,
@RequestParam String localFilePath) {
return ResponseData.success(machineInfoService.downloadFile(sessionId, remoteFilePath, localFilePath));
machineInfoService.downloadFile(sessionId, remoteFilePath, localFilePath);
return success(true);
}
}

View File

@ -1,9 +1,8 @@
package cd.casic.module.machine.controller;
import cd.casic.framework.commons.pojo.CommonResult;
import cd.casic.module.machine.service.MachineProxyService;
import cd.casic.module.machine.dto.MachineProxyDTO;
import cd.casic.module.machine.pojo.ResponseData;
import cd.casic.module.machine.pojo.SuccessResponseData;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -13,6 +12,8 @@ import org.springframework.web.bind.annotation.*;
import java.util.List;
import static cd.casic.framework.commons.pojo.CommonResult.success;
/**
* 机器代理控制器
*/
@ -27,45 +28,49 @@ public class MachineProxyController {
@PostMapping("/register")
@Operation(summary ="注册新的机器代理")
public ResponseData register(@RequestBody MachineProxyDTO machineProxyDTO) {
return machineProxyService.register(machineProxyDTO) ? ResponseData.success() :ResponseData.error("注册新的机器代理失败");
public CommonResult register(@RequestBody MachineProxyDTO machineProxyDTO) {
machineProxyService.register(machineProxyDTO);
return success(true);
}
@GetMapping("/list")
@Operation(summary ="获取代理")
public ResponseData list(MachineProxyDTO machineProxyDTO) {
return ResponseData.success(machineProxyService.list(machineProxyDTO));
public CommonResult list(MachineProxyDTO machineProxyDTO) {
return success(machineProxyService.list(machineProxyDTO));
}
@PutMapping("/updateStatus")
@Operation(summary ="更新代理状态")
public ResponseData updateStatus(@RequestBody MachineProxyDTO machineProxyDTO) {
return machineProxyService.updateStatus(machineProxyDTO) ? ResponseData.success() : ResponseData.error("更新代理状态失败");
public CommonResult updateStatus(@RequestBody MachineProxyDTO machineProxyDTO) {
machineProxyService.updateStatus(machineProxyDTO);
return success(true);
}
@PostMapping("/receiptHeartbeat")
@Operation(summary ="接收代理心跳")
public ResponseData heartbeat(@RequestBody MachineProxyDTO machineProxyDTO) {
return machineProxyService.heartbeat(machineProxyDTO) ? ResponseData.success() :ResponseData.error("接收代理心跳失败");
public CommonResult heartbeat(@RequestBody MachineProxyDTO machineProxyDTO) {
machineProxyService.heartbeat(machineProxyDTO);
return success(true);
}
@GetMapping("/statistics/status")
@Operation(summary ="获取所有代理的状态统计")
public ResponseData getStatusStatistics() {
return ResponseData.success(machineProxyService.getStatusStatistics());
public CommonResult getStatusStatistics() {
return success(machineProxyService.getStatusStatistics());
}
@PutMapping("/updateConfig")
@Operation(summary ="更新代理配置")
public ResponseData updateConfig(@RequestBody MachineProxyDTO machineProxyDTO) {
return machineProxyService.updateConfig(machineProxyDTO) ? ResponseData.success() : ResponseData.error("更新代理配置失败");
public CommonResult updateConfig(@RequestBody MachineProxyDTO machineProxyDTO) {
machineProxyService.updateConfig(machineProxyDTO);
return success(true);
}
@DeleteMapping("/batch")
@Operation(summary ="批量删除代理")
public ResponseData deleteBatch(@RequestBody List<Long> ids) {
public CommonResult deleteBatch(@RequestBody List<Long> ids) {
machineProxyService.delete(ids);
return new SuccessResponseData();
return success(true);
}
}

View File

@ -1,14 +1,11 @@
package cd.casic.module.machine.controller;
import cd.casic.framework.commons.pojo.CommonResult;
import cd.casic.module.machine.service.SecretKeyService;
import cd.casic.module.machine.dto.SecretKeyDto;
import cd.casic.module.machine.pojo.ResponseData;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@ -22,6 +19,8 @@ import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import static cd.casic.framework.commons.pojo.CommonResult.success;
@RestController
@RequestMapping("/api/secretKey")
@Tag(name = "密钥管理")
@ -31,45 +30,49 @@ public class SecretKeyController {
@PostMapping(value = "/add", consumes = "multipart/form-data")
@Operation(summary ="新增密钥")
public ResponseData add(@RequestPart("secretKeyDto") SecretKeyDto secretKeyDto, @RequestPart("file") MultipartFile file) {
return secretKeyService.addSecretKey(secretKeyDto, file) ? ResponseData.success() : ResponseData.error("新增密钥失败");
public CommonResult add(@RequestPart("secretKeyDto") SecretKeyDto secretKeyDto, @RequestPart("file") MultipartFile file) {
secretKeyService.addSecretKey(secretKeyDto, file);
return success(true);
}
@PutMapping("/bindingMachine")
@Operation(summary ="绑定机器")
public ResponseData bindingMachine(@RequestParam("secretKeyId") Long secretKeyId, @RequestParam("machineInfoIds") List<Long> machineInfoIds) {
public CommonResult bindingMachine(@RequestParam("secretKeyId") Long secretKeyId, @RequestParam("machineInfoIds") List<Long> machineInfoIds) {
secretKeyService.bindingMachine(secretKeyId, machineInfoIds);
return ResponseData.success();
return success(true);
}
@PutMapping("/update")
@Operation(summary ="编辑密钥信息")
public ResponseData update(@RequestPart("secretKeyDto") SecretKeyDto secretKeyDto, @RequestPart(value = "file", required = false) MultipartFile file) {
return secretKeyService.updateSecretKey(secretKeyDto, file) ? ResponseData.success() : ResponseData.error("编辑密钥信息失败");
public CommonResult update(@RequestPart("secretKeyDto") SecretKeyDto secretKeyDto, @RequestPart(value = "file", required = false) MultipartFile file) {
secretKeyService.updateSecretKey(secretKeyDto, file);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary ="删除密钥")
public ResponseData delete(@RequestParam("secretKeyId") Long secretKeyId) {
return secretKeyService.deleteSecretKey(secretKeyId) ? ResponseData.success() : ResponseData.error("删除密钥");
public CommonResult delete(@RequestParam("secretKeyId") Long secretKeyId) {
secretKeyService.deleteSecretKey(secretKeyId);
return success(true);
}
@DeleteMapping("/deleteList")
@Operation(summary ="批量删除密钥")
public ResponseData deleteList(@RequestParam("secretKeyId") List<Long> secretKeyIds) {
return secretKeyService.deleteList(secretKeyIds) ? ResponseData.success() : ResponseData.error("批量删除密钥");
public CommonResult deleteList(@RequestParam("secretKeyId") List<Long> secretKeyIds) {
secretKeyService.deleteList(secretKeyIds);
return success(true);
}
@GetMapping("/list")
@Operation(summary ="获取密钥信息列表")
public ResponseData list(@RequestBody SecretKeyDto secretKeyDto) {
return ResponseData.success(secretKeyService.listSecretKey(secretKeyDto));
public CommonResult list(@RequestBody SecretKeyDto secretKeyDto) {
return success(secretKeyService.listSecretKey(secretKeyDto));
}
@GetMapping("/downloadSecretKeyFile")
@Operation(summary ="下载密钥文件")
public ResponseEntity<InputStreamResource> downloadSecretKeyFile(@RequestParam("secretKeyId") Long secretKeyId) {
return secretKeyService.downloadSecretKeyFile(secretKeyId);
public CommonResult<InputStreamResource> downloadSecretKeyFile(@RequestParam("secretKeyId") Long secretKeyId) {
return success(secretKeyService.downloadSecretKeyFile(secretKeyId).getBody());
}
}

View File

@ -21,7 +21,7 @@ public class MachineEnvDTO extends PageDto implements Serializable {
private String envValue;
private Boolean sensitive;
private String description;
private Long machineInfoId;
private Long machineId;
private Date createDate;
private Date updateDate;
private String sortField;

View File

@ -27,6 +27,8 @@ public class MachineProxyDTO extends PageDto implements Serializable {
private String description;
private String hostIp;
private String sshPort;
private Date createDate;
private Date updateDate;
/**
* 计算代理是否在线

View File

@ -1,184 +1,184 @@
package com.casic.machine.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.casic.commons.exception.ServiceException;
import com.casic.commons.utils.PageResult;
import com.casic.machine.dto.MachineEnvDTO;
import com.casic.machine.entity.MachineEnv;
import com.casic.machine.mapper.MachineEnvMapper;
import com.casic.machine.service.MachineEnvService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
@Transactional
@Rollback(value = true) // 测试后回滚数据
@Sql(scripts = {"classpath:sql/machine_env_test_data.sql"}) // 初始化测试数据可选
public class MachineEnvServiceImplTest {
@Autowired
private MachineEnvService machineEnvService;
@Autowired
private MachineEnvMapper machineEnvMapper;
private MachineEnvDTO validDto;
private MachineEnvDTO invalidKeyDto;
private Long existingMachineId;
private Long nonExistingMachineId;
@BeforeEach
public void setUp() {
// 准备测试数据
existingMachineId = 1L; // 假设数据库中存在ID为1的机器环境变量
nonExistingMachineId = 999L; // 不存在的机器ID
// 有效测试数据
validDto = new MachineEnvDTO();
validDto.setMachineInfoId(existingMachineId);
validDto.setEnvKey("TEST_ENV_KEY");
validDto.setEnvValue("test-value");
validDto.setSensitive(true);
// 无效Key测试数据包含非法字符
invalidKeyDto = new MachineEnvDTO();
invalidKeyDto.setMachineInfoId(existingMachineId);
invalidKeyDto.setEnvKey("test-env-key"); // 包含'-'不符合正则
invalidKeyDto.setEnvValue("test-value");
}
// ==================== 更新环境变量测试 ====================
@Test
void testUpdateEnv_ValidData_ShouldSucceed() {
// 执行更新假设数据库中已存在machineId=1的记录
boolean result = machineEnvService.update(validDto);
// 验证结果
assertTrue(result);
// 检查数据库数据是否更新
MachineEnv updatedEnv = machineEnvMapper.selectOne(
new LambdaQueryWrapper<MachineEnv>().eq(MachineEnv::getMachineId, existingMachineId)
);
assertNotNull(updatedEnv);
assertEquals(validDto.getEnvKey(), updatedEnv.getEnvKey());
assertEquals(validDto.getEnvValue(), updatedEnv.getEnvValue());
assertEquals(validDto.getSensitive(), updatedEnv.getSensitive());
}
@Test
void testUpdateEnv_NullDto_ShouldThrowException() {
MachineEnvDTO machineEnvDTO = new MachineEnvDTO();
assertThrows(ServiceException.class, () -> {
machineEnvService.update(machineEnvDTO);
}, "环境变量不能为空");
}
@Test
void testUpdateEnv_InvalidKey_ShouldThrowException() {
assertThrows(ServiceException.class, () -> {
machineEnvService.update(invalidKeyDto);
}, "环境变量键不合法");
}
@Test
void testUpdateEnv_SensitiveKey_ShouldMarkAsSensitive() {
MachineEnvDTO sensitiveDto = new MachineEnvDTO();
sensitiveDto.setMachineInfoId(existingMachineId);
sensitiveDto.setEnvKey("DB_PASSWORD"); // 包含敏感词
sensitiveDto.setEnvValue("secret");
machineEnvService.update(sensitiveDto);
MachineEnv env = machineEnvMapper.selectOne(
new LambdaQueryWrapper<MachineEnv>().eq(MachineEnv::getMachineId, existingMachineId)
);
assertTrue(env.getSensitive());
}
// ==================== 删除环境变量测试 ====================
@Test
void testDeleteByMachineId_ExistingId_ShouldSucceed() {
machineEnvService.deleteByMachineId(existingMachineId);
MachineEnv env = machineEnvMapper.selectById(existingMachineId);
assertNull(env);
}
@Test
void testDeleteByMachineId_NonExistingId_ShouldDoNothing() {
machineEnvService.deleteByMachineId(nonExistingMachineId);
// 不抛出异常静默处理
}
// ==================== 根据机器ID查询测试 ====================
@Test
void testGetByMachineId_ExistingId_ShouldReturnDto() {
MachineEnvDTO dto = machineEnvService.getByMachineId(existingMachineId);
assertNotNull(dto);
assertEquals(existingMachineId, dto.getMachineInfoId());
}
@Test
void testGetByMachineId_NonExistingId_ShouldReturnNull() {
MachineEnvDTO dto = machineEnvService.getByMachineId(nonExistingMachineId);
assertNull(dto);
}
// ==================== 列表查询测试 ====================
@Test
void testListEnv_Pagination_ShouldReturnValidPage() {
MachineEnvDTO queryDto = new MachineEnvDTO();
queryDto.setPageIndex(1);
queryDto.setPageSize(10);
queryDto.setEnvKey("TEST"); // 假设测试数据中存在包含"TEST"的键
PageResult<MachineEnvDTO> pageResult = machineEnvService.listEnv(queryDto);
assertNotNull(pageResult.getList());
assertTrue(pageResult.getTotal() >= 0);
assertEquals(1, pageResult.getPageNum());
}
@Test
void testListEnv_SortByCreateTime_ShouldBeOrdered() {
MachineEnvDTO queryDto = new MachineEnvDTO();
queryDto.setSortField("createTime");
queryDto.setSortDirection("desc");
PageResult<MachineEnvDTO> pageResult = machineEnvService.listEnv(queryDto);
List<MachineEnvDTO> list = pageResult.getList();
if (!list.isEmpty()) {
Date prevDate = list.get(0).getCreateDate();
for (int i = 1; i < list.size(); i++) {
Date currDate = list.get(i).getCreateDate();
assertTrue(currDate.before(prevDate) || currDate.equals(prevDate), "排序应为降序");
prevDate = currDate;
}
}
}
// ==================== 批量删除测试 ====================
@Test
void testDeleteList_ValidIds_ShouldDeleteBatch() {
// 假设测试数据中有ID为1和2的记录
List<Long> ids = List.of(1L, 2L);
machineEnvService.deleteList(ids);
long count = machineEnvMapper.selectCount(new LambdaQueryWrapper<MachineEnv>().in(MachineEnv::getId, ids));
assertEquals(0, count);
}
}
//package com.casic.machine.service.impl;
//
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
//import com.casic.commons.exception.ServiceException;
//import com.casic.commons.utils.PageResult;
//import com.casic.machine.dto.MachineEnvDTO;
//import com.casic.machine.entity.MachineEnv;
//import com.casic.machine.mapper.MachineEnvMapper;
//import com.casic.machine.service.MachineEnvService;
//import org.junit.jupiter.api.BeforeEach;
//import org.junit.jupiter.api.Test;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.boot.test.context.SpringBootTest;
//import org.springframework.test.annotation.Rollback;
//import org.springframework.test.context.jdbc.Sql;
//import org.springframework.transaction.annotation.Transactional;
//
//import java.util.Date;
//import java.util.List;
//
//import static org.junit.jupiter.api.Assertions.*;
//
//@SpringBootTest
//@Transactional
//@Rollback(value = true) // 测试后回滚数据
//@Sql(scripts = {"classpath:sql/machine_env_test_data.sql"}) // 初始化测试数据可选
//public class MachineEnvServiceImplTest {
//
// @Autowired
// private MachineEnvService machineEnvService;
//
// @Autowired
// private MachineEnvMapper machineEnvMapper;
//
// private MachineEnvDTO validDto;
// private MachineEnvDTO invalidKeyDto;
// private Long existingMachineId;
// private Long nonExistingMachineId;
//
// @BeforeEach
// public void setUp() {
// // 准备测试数据
// existingMachineId = 1L; // 假设数据库中存在ID为1的机器环境变量
// nonExistingMachineId = 999L; // 不存在的机器ID
//
// // 有效测试数据
// validDto = new MachineEnvDTO();
// validDto.setMachineInfoId(existingMachineId);
// validDto.setEnvKey("TEST_ENV_KEY");
// validDto.setEnvValue("test-value");
// validDto.setSensitive(true);
//
// // 无效Key测试数据包含非法字符
// invalidKeyDto = new MachineEnvDTO();
// invalidKeyDto.setMachineInfoId(existingMachineId);
// invalidKeyDto.setEnvKey("test-env-key"); // 包含'-'不符合正则
// invalidKeyDto.setEnvValue("test-value");
// }
//
// // ==================== 更新环境变量测试 ====================
// @Test
// void testUpdateEnv_ValidData_ShouldSucceed() {
// // 执行更新假设数据库中已存在machineId=1的记录
// boolean result = machineEnvService.update(validDto);
//
// // 验证结果
// assertTrue(result);
//
// // 检查数据库数据是否更新
// MachineEnv updatedEnv = machineEnvMapper.selectOne(
// new LambdaQueryWrapper<MachineEnv>().eq(MachineEnv::getMachineId, existingMachineId)
// );
// assertNotNull(updatedEnv);
// assertEquals(validDto.getEnvKey(), updatedEnv.getEnvKey());
// assertEquals(validDto.getEnvValue(), updatedEnv.getEnvValue());
// assertEquals(validDto.getSensitive(), updatedEnv.getSensitive());
// }
//
// @Test
// void testUpdateEnv_NullDto_ShouldThrowException() {
//
// MachineEnvDTO machineEnvDTO = new MachineEnvDTO();
// assertThrows(ServiceException.class, () -> {
// machineEnvService.update(machineEnvDTO);
// }, "环境变量不能为空");
// }
//
// @Test
// void testUpdateEnv_InvalidKey_ShouldThrowException() {
// assertThrows(ServiceException.class, () -> {
// machineEnvService.update(invalidKeyDto);
// }, "环境变量键不合法");
// }
//
// @Test
// void testUpdateEnv_SensitiveKey_ShouldMarkAsSensitive() {
// MachineEnvDTO sensitiveDto = new MachineEnvDTO();
// sensitiveDto.setMachineInfoId(existingMachineId);
// sensitiveDto.setEnvKey("DB_PASSWORD"); // 包含敏感词
// sensitiveDto.setEnvValue("secret");
//
// machineEnvService.update(sensitiveDto);
//
// MachineEnv env = machineEnvMapper.selectOne(
// new LambdaQueryWrapper<MachineEnv>().eq(MachineEnv::getMachineId, existingMachineId)
// );
// assertTrue(env.getSensitive());
// }
//
// // ==================== 删除环境变量测试 ====================
// @Test
// void testDeleteByMachineId_ExistingId_ShouldSucceed() {
// machineEnvService.deleteByMachineId(existingMachineId);
// MachineEnv env = machineEnvMapper.selectById(existingMachineId);
// assertNull(env);
// }
//
// @Test
// void testDeleteByMachineId_NonExistingId_ShouldDoNothing() {
// machineEnvService.deleteByMachineId(nonExistingMachineId);
// // 不抛出异常静默处理
// }
//
// // ==================== 根据机器ID查询测试 ====================
// @Test
// void testGetByMachineId_ExistingId_ShouldReturnDto() {
// MachineEnvDTO dto = machineEnvService.getByMachineId(existingMachineId);
// assertNotNull(dto);
// assertEquals(existingMachineId, dto.getMachineInfoId());
// }
//
// @Test
// void testGetByMachineId_NonExistingId_ShouldReturnNull() {
// MachineEnvDTO dto = machineEnvService.getByMachineId(nonExistingMachineId);
// assertNull(dto);
// }
//
// // ==================== 列表查询测试 ====================
// @Test
// void testListEnv_Pagination_ShouldReturnValidPage() {
// MachineEnvDTO queryDto = new MachineEnvDTO();
// queryDto.setPageIndex(1);
// queryDto.setPageSize(10);
// queryDto.setEnvKey("TEST"); // 假设测试数据中存在包含"TEST"的键
//
// PageResult<MachineEnvDTO> pageResult = machineEnvService.listEnv(queryDto);
//
// assertNotNull(pageResult.getList());
// assertTrue(pageResult.getTotal() >= 0);
// assertEquals(1, pageResult.getPageNum());
// }
//
// @Test
// void testListEnv_SortByCreateTime_ShouldBeOrdered() {
// MachineEnvDTO queryDto = new MachineEnvDTO();
// queryDto.setSortField("createTime");
// queryDto.setSortDirection("desc");
//
// PageResult<MachineEnvDTO> pageResult = machineEnvService.listEnv(queryDto);
//
// List<MachineEnvDTO> list = pageResult.getList();
// if (!list.isEmpty()) {
// Date prevDate = list.get(0).getCreateDate();
// for (int i = 1; i < list.size(); i++) {
// Date currDate = list.get(i).getCreateDate();
// assertTrue(currDate.before(prevDate) || currDate.equals(prevDate), "排序应为降序");
// prevDate = currDate;
// }
// }
// }
//
// // ==================== 批量删除测试 ====================
// @Test
// void testDeleteList_ValidIds_ShouldDeleteBatch() {
// // 假设测试数据中有ID为1和2的记录
// List<Long> ids = List.of(1L, 2L);
// machineEnvService.deleteList(ids);
//
// long count = machineEnvMapper.selectCount(new LambdaQueryWrapper<MachineEnv>().in(MachineEnv::getId, ids));
// assertEquals(0, count);
// }
//
//
//}

View File

@ -1,222 +1,222 @@
package com.casic.machine.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.casic.commons.exception.ServiceException;
import com.casic.commons.utils.EnumUtils;
import com.casic.commons.utils.PageResult;
import com.casic.machine.dto.MachineProxyDTO;
import com.casic.machine.entity.MachineProxy;
import com.casic.machine.enums.MachineProxyStatus;
import com.casic.machine.enums.MachineProxyType;
import com.casic.machine.mapper.MachineProxyMapper;
import com.casic.machine.service.MachineProxyService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
@Transactional
@Rollback(true)
@Sql(scripts = {"classpath:sql/machine_proxy_test_data.sql"})
public class MachineProxyServiceImplTest {
@Autowired
private MachineProxyService machineProxyService;
@Autowired
private MachineProxyMapper machineProxyMapper;
private MachineProxyDTO validProxyDTO;
private Long existingProxyId;
private Long nonExistingProxyId;
@BeforeEach
public void setUp() {
// 初始化测试数据假设 SQL 脚本已插入一条状态为 OFFLINE 的代理
existingProxyId = 1L;
nonExistingProxyId = 999L;
// 有效代理 DTO
validProxyDTO = new MachineProxyDTO();
validProxyDTO.setProxyType(MachineProxyType.SOCKS5.getMessage());
validProxyDTO.setHostIp("192.168.1.100");
validProxyDTO.setSshPort("22");
validProxyDTO.setUsername("test_user");
validProxyDTO.setStatus(MachineProxyStatus.ONLINE.getMessage());
}
// ============================== 注册代理测试 ==============================
@Test
void testRegister_ValidData_ShouldSucceed() {
// 执行注册
boolean result = machineProxyService.register(validProxyDTO);
assertTrue(result, "注册失败");
// 使用 Lambda 表达式查询推荐
MachineProxy proxy = machineProxyMapper.selectOne(
new LambdaQueryWrapper<MachineProxy>()
.eq(MachineProxy::getHostIp, validProxyDTO.getHostIp())
);
// 断言数据存在
assertNotNull(proxy, "代理记录未写入数据库");
assertEquals(MachineProxyType.SOCKS5.getCode(), proxy.getProxyTypeCode());
assertEquals(MachineProxyStatus.INSTALLING.getCode(), proxy.getStatusCode());
assertEquals(validProxyDTO.getHostIp(), proxy.getHostIp(), "IP 地址不一致");
}
// ============================== 更新状态测试 ==============================
@Test
void testUpdateStatus_ExistingProxy_ShouldUpdateStatus() {
// 准备数据查询现有代理状态为 OFFLINE
MachineProxy proxy = machineProxyMapper.selectById(existingProxyId);
assertEquals(MachineProxyStatus.OFFLINE.getCode(), proxy.getStatusCode());
// 执行状态更新为 ONLINE
validProxyDTO.setId(existingProxyId);
validProxyDTO.setStatus(MachineProxyStatus.ONLINE.getMessage());
boolean result = machineProxyService.updateStatus(validProxyDTO);
// 验证结果
assertTrue(result);
proxy = machineProxyMapper.selectById(existingProxyId);
assertEquals(MachineProxyStatus.ONLINE.getCode(), proxy.getStatusCode());
}
@Test
void testUpdateStatus_NullDto_ShouldThrowException() {
assertThrows(ServiceException.class, () -> {
machineProxyService.updateStatus(null);
}, "MachineProxyDTO对象为空");
}
// ============================== 心跳测试 ==============================
@Test
void testHeartbeat_ValidData_ShouldUpdateVersionAndStatus() {
// 准备数据现有代理状态为 OFFLINE版本为 1.0.0
MachineProxy proxy = machineProxyMapper.selectById(existingProxyId);
assertEquals("1.0.0", proxy.getVersion());
assertEquals(MachineProxyStatus.OFFLINE.getCode(), proxy.getStatusCode());
// 发送心跳更新版本和状态
validProxyDTO.setId(existingProxyId);
validProxyDTO.setVersion("2.0.0");
validProxyDTO.setStatus(MachineProxyStatus.ONLINE.getMessage());
machineProxyService.heartbeat(validProxyDTO);
// 验证结果
proxy = machineProxyMapper.selectById(existingProxyId);
assertEquals("2.0.0", proxy.getVersion());
assertEquals(MachineProxyStatus.ONLINE.getCode(), proxy.getStatusCode());
}
// ============================== 状态统计测试 ==============================
@Test
void testGetStatusStatistics_ShouldReturnValidCounts() {
// 假设测试数据中有 OFFLINE(1)INSTALLING(1)ONLINE(1) 三种状态
Map<String, Long> stats = machineProxyService.getStatusStatistics();
// 验证统计结果
assertEquals(3, stats.size());
assertTrue(stats.containsKey(MachineProxyStatus.OFFLINE.getMessage()));
assertTrue(stats.containsKey(MachineProxyStatus.INSTALLING.getMessage()));
assertTrue(stats.containsKey(MachineProxyStatus.ONLINE.getMessage()));
assertEquals(1L, stats.get(MachineProxyStatus.OFFLINE.getMessage()));
}
// ============================== 更新配置测试 ==============================
@Test
void testUpdateConfig_ValidConfig_ShouldSucceed() {
// 准备数据现有代理配置为空
MachineProxy proxy = machineProxyMapper.selectById(existingProxyId);
assertNull(proxy.getConfig());
// 更新配置
validProxyDTO.setId(existingProxyId);
validProxyDTO.setConfig("{\"port\": 8080}");
boolean result = machineProxyService.updateConfig(validProxyDTO);
// 验证结果
assertTrue(result);
proxy = machineProxyMapper.selectById(existingProxyId);
assertEquals("{\"port\": 8080}", proxy.getConfig());
}
// ============================== 删除代理测试 ==============================
@Test
void testDelete_OfflineProxy_ShouldDeleteSuccessfully() {
// 准备数据状态为 OFFLINE 的代理 ID
List<Long> ids = Collections.singletonList(existingProxyId);
machineProxyService.delete(ids);
// 验证删除
MachineProxy proxy = machineProxyMapper.selectById(existingProxyId);
assertNull(proxy);
}
@Test
void testDelete_OnlineProxy_ShouldThrowException() {
// 先将代理状态改为 ONLINE
MachineProxy onlineProxy = new MachineProxy();
onlineProxy.setId(existingProxyId);
onlineProxy.setStatusCode(MachineProxyStatus.ONLINE.getCode());
machineProxyMapper.updateById(onlineProxy);
// 执行删除
List<Long> ids = Collections.singletonList(existingProxyId);
assertThrows(IllegalArgumentException.class, () -> {
machineProxyService.delete(ids);
}, "以下代理处于在线状态,无法删除: 1");
}
// ============================== 列表查询测试 ==============================
@Test
void testList_WithStatusFilter_ShouldReturnMatchedRecords() {
// 查询状态为 OFFLINE 的代理
MachineProxyDTO queryDto = new MachineProxyDTO();
queryDto.setStatus(MachineProxyStatus.OFFLINE.getMessage());
PageResult<MachineProxyDTO> pageResult = machineProxyService.list(queryDto);
// 验证结果
assertFalse(pageResult.getList().isEmpty());
pageResult.getList().forEach(dto ->
assertEquals(MachineProxyStatus.OFFLINE.getMessage(), dto.getStatus())
);
}
@Test
void testList_WithHostIpFilter_ShouldReturnMatchedRecords() {
// 假设测试数据中存在 host_ip "192.168.1.1" 的代理
MachineProxyDTO queryDto = new MachineProxyDTO();
queryDto.setHostIp("192.168.1.1");
PageResult<MachineProxyDTO> pageResult = machineProxyService.list(queryDto);
// 验证结果
assertFalse(pageResult.getList().isEmpty());
pageResult.getList().forEach(dto ->
assertEquals("192.168.1.1", dto.getHostIp())
);
}
// ============================== 辅助方法测试 ==============================
@Test
void testEnumUtils_ConvertCodeToMessage() {
// 验证代理类型枚举转换
String typeMessage = EnumUtils.getEnumByCode(MachineProxyType.HTTP.getCode(), MachineProxyType.class).getMessage();
assertEquals("HTTP", typeMessage);
// 验证状态枚举转换
String statusMessage = EnumUtils.getEnumByCode(MachineProxyStatus.INSTALLING.getCode(), MachineProxyStatus.class).getMessage();
assertEquals("安装中", statusMessage);
}
}
//package com.casic.machine.service.impl;
//
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
//import com.casic.commons.exception.ServiceException;
//import com.casic.commons.utils.EnumUtils;
//import com.casic.commons.utils.PageResult;
//import com.casic.machine.dto.MachineProxyDTO;
//import com.casic.machine.entity.MachineProxy;
//import com.casic.machine.enums.MachineProxyStatus;
//import com.casic.machine.enums.MachineProxyType;
//import com.casic.machine.mapper.MachineProxyMapper;
//import com.casic.machine.service.MachineProxyService;
//import org.junit.jupiter.api.BeforeEach;
//import org.junit.jupiter.api.Test;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.boot.test.context.SpringBootTest;
//import org.springframework.test.annotation.Rollback;
//import org.springframework.test.context.jdbc.Sql;
//import org.springframework.transaction.annotation.Transactional;
//
//import java.util.*;
//
//import static org.junit.jupiter.api.Assertions.*;
//
//@SpringBootTest
//@Transactional
//@Rollback(true)
//@Sql(scripts = {"classpath:sql/machine_proxy_test_data.sql"})
//public class MachineProxyServiceImplTest {
//
// @Autowired
// private MachineProxyService machineProxyService;
//
// @Autowired
// private MachineProxyMapper machineProxyMapper;
//
// private MachineProxyDTO validProxyDTO;
// private Long existingProxyId;
// private Long nonExistingProxyId;
//
// @BeforeEach
// public void setUp() {
// // 初始化测试数据假设 SQL 脚本已插入一条状态为 OFFLINE 的代理
// existingProxyId = 1L;
// nonExistingProxyId = 999L;
//
// // 有效代理 DTO
// validProxyDTO = new MachineProxyDTO();
// validProxyDTO.setProxyType(MachineProxyType.SOCKS5.getMessage());
// validProxyDTO.setHostIp("192.168.1.100");
// validProxyDTO.setSshPort("22");
// validProxyDTO.setUsername("test_user");
// validProxyDTO.setStatus(MachineProxyStatus.ONLINE.getMessage());
// }
//
// // ============================== 注册代理测试 ==============================
// @Test
// void testRegister_ValidData_ShouldSucceed() {
// // 执行注册
// boolean result = machineProxyService.register(validProxyDTO);
// assertTrue(result, "注册失败");
//
// // 使用 Lambda 表达式查询推荐
// MachineProxy proxy = machineProxyMapper.selectOne(
// new LambdaQueryWrapper<MachineProxy>()
// .eq(MachineProxy::getHostIp, validProxyDTO.getHostIp())
// );
//
// // 断言数据存在
// assertNotNull(proxy, "代理记录未写入数据库");
// assertEquals(MachineProxyType.SOCKS5.getCode(), proxy.getProxyTypeCode());
// assertEquals(MachineProxyStatus.INSTALLING.getCode(), proxy.getStatusCode());
// assertEquals(validProxyDTO.getHostIp(), proxy.getHostIp(), "IP 地址不一致");
// }
//
// // ============================== 更新状态测试 ==============================
// @Test
// void testUpdateStatus_ExistingProxy_ShouldUpdateStatus() {
// // 准备数据查询现有代理状态为 OFFLINE
// MachineProxy proxy = machineProxyMapper.selectById(existingProxyId);
// assertEquals(MachineProxyStatus.OFFLINE.getCode(), proxy.getStatusCode());
//
// // 执行状态更新为 ONLINE
// validProxyDTO.setId(existingProxyId);
// validProxyDTO.setStatus(MachineProxyStatus.ONLINE.getMessage());
// boolean result = machineProxyService.updateStatus(validProxyDTO);
//
// // 验证结果
// assertTrue(result);
// proxy = machineProxyMapper.selectById(existingProxyId);
// assertEquals(MachineProxyStatus.ONLINE.getCode(), proxy.getStatusCode());
// }
//
// @Test
// void testUpdateStatus_NullDto_ShouldThrowException() {
// assertThrows(ServiceException.class, () -> {
// machineProxyService.updateStatus(null);
// }, "MachineProxyDTO对象为空");
// }
//
// // ============================== 心跳测试 ==============================
// @Test
// void testHeartbeat_ValidData_ShouldUpdateVersionAndStatus() {
// // 准备数据现有代理状态为 OFFLINE版本为 1.0.0
// MachineProxy proxy = machineProxyMapper.selectById(existingProxyId);
// assertEquals("1.0.0", proxy.getVersion());
// assertEquals(MachineProxyStatus.OFFLINE.getCode(), proxy.getStatusCode());
//
// // 发送心跳更新版本和状态
// validProxyDTO.setId(existingProxyId);
// validProxyDTO.setVersion("2.0.0");
// validProxyDTO.setStatus(MachineProxyStatus.ONLINE.getMessage());
// machineProxyService.heartbeat(validProxyDTO);
//
// // 验证结果
// proxy = machineProxyMapper.selectById(existingProxyId);
// assertEquals("2.0.0", proxy.getVersion());
// assertEquals(MachineProxyStatus.ONLINE.getCode(), proxy.getStatusCode());
// }
//
// // ============================== 状态统计测试 ==============================
// @Test
// void testGetStatusStatistics_ShouldReturnValidCounts() {
// // 假设测试数据中有 OFFLINE(1)INSTALLING(1)ONLINE(1) 三种状态
// Map<String, Long> stats = machineProxyService.getStatusStatistics();
//
// // 验证统计结果
// assertEquals(3, stats.size());
// assertTrue(stats.containsKey(MachineProxyStatus.OFFLINE.getMessage()));
// assertTrue(stats.containsKey(MachineProxyStatus.INSTALLING.getMessage()));
// assertTrue(stats.containsKey(MachineProxyStatus.ONLINE.getMessage()));
// assertEquals(1L, stats.get(MachineProxyStatus.OFFLINE.getMessage()));
// }
//
// // ============================== 更新配置测试 ==============================
// @Test
// void testUpdateConfig_ValidConfig_ShouldSucceed() {
// // 准备数据现有代理配置为空
// MachineProxy proxy = machineProxyMapper.selectById(existingProxyId);
// assertNull(proxy.getConfig());
//
// // 更新配置
// validProxyDTO.setId(existingProxyId);
// validProxyDTO.setConfig("{\"port\": 8080}");
// boolean result = machineProxyService.updateConfig(validProxyDTO);
//
// // 验证结果
// assertTrue(result);
// proxy = machineProxyMapper.selectById(existingProxyId);
// assertEquals("{\"port\": 8080}", proxy.getConfig());
// }
//
// // ============================== 删除代理测试 ==============================
// @Test
// void testDelete_OfflineProxy_ShouldDeleteSuccessfully() {
// // 准备数据状态为 OFFLINE 的代理 ID
// List<Long> ids = Collections.singletonList(existingProxyId);
// machineProxyService.delete(ids);
//
// // 验证删除
// MachineProxy proxy = machineProxyMapper.selectById(existingProxyId);
// assertNull(proxy);
// }
//
// @Test
// void testDelete_OnlineProxy_ShouldThrowException() {
// // 先将代理状态改为 ONLINE
// MachineProxy onlineProxy = new MachineProxy();
// onlineProxy.setId(existingProxyId);
// onlineProxy.setStatusCode(MachineProxyStatus.ONLINE.getCode());
// machineProxyMapper.updateById(onlineProxy);
//
// // 执行删除
// List<Long> ids = Collections.singletonList(existingProxyId);
// assertThrows(IllegalArgumentException.class, () -> {
// machineProxyService.delete(ids);
// }, "以下代理处于在线状态,无法删除: 1");
// }
//
// // ============================== 列表查询测试 ==============================
// @Test
// void testList_WithStatusFilter_ShouldReturnMatchedRecords() {
// // 查询状态为 OFFLINE 的代理
// MachineProxyDTO queryDto = new MachineProxyDTO();
// queryDto.setStatus(MachineProxyStatus.OFFLINE.getMessage());
//
// PageResult<MachineProxyDTO> pageResult = machineProxyService.list(queryDto);
//
// // 验证结果
// assertFalse(pageResult.getList().isEmpty());
// pageResult.getList().forEach(dto ->
// assertEquals(MachineProxyStatus.OFFLINE.getMessage(), dto.getStatus())
// );
// }
//
// @Test
// void testList_WithHostIpFilter_ShouldReturnMatchedRecords() {
// // 假设测试数据中存在 host_ip "192.168.1.1" 的代理
// MachineProxyDTO queryDto = new MachineProxyDTO();
// queryDto.setHostIp("192.168.1.1");
//
// PageResult<MachineProxyDTO> pageResult = machineProxyService.list(queryDto);
//
// // 验证结果
// assertFalse(pageResult.getList().isEmpty());
// pageResult.getList().forEach(dto ->
// assertEquals("192.168.1.1", dto.getHostIp())
// );
// }
//
// // ============================== 辅助方法测试 ==============================
// @Test
// void testEnumUtils_ConvertCodeToMessage() {
// // 验证代理类型枚举转换
// String typeMessage = EnumUtils.getEnumByCode(MachineProxyType.HTTP.getCode(), MachineProxyType.class).getMessage();
// assertEquals("HTTP", typeMessage);
//
// // 验证状态枚举转换
// String statusMessage = EnumUtils.getEnumByCode(MachineProxyStatus.INSTALLING.getCode(), MachineProxyStatus.class).getMessage();
// assertEquals("安装中", statusMessage);
// }
//}

View File

@ -1,176 +1,176 @@
package com.casic.machine.service.impl;
import com.casic.commons.exception.ServiceException;
import com.casic.machine.dto.MachineInfoDto;
import com.casic.machine.entity.MachineInfo;
import com.casic.machine.enums.AuthenticationType;
import com.casic.machine.enums.ConnectionStatus;
import com.casic.machine.enums.MachineInfoStatus;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
@Transactional
@Rollback(true)
@Sql(scripts = {"classpath:sql/machine_info_test_data.sql"})
public class MachineinfoServiceImplTest {
@Autowired
private MachineinfoServiceImpl machineInfoService;
private MachineInfoDto validMachineInfoDto;
private Long existingMachineId;
private Long nonExistingMachineId;
@BeforeEach
public void setUp() {
// 初始化测试数据假设 SQL 脚本已插入一条状态为 ENABLE 的机器
existingMachineId = 1L;
nonExistingMachineId = 999L;
// 有效机器信息 DTO
validMachineInfoDto = new MachineInfoDto();
validMachineInfoDto.setName("Test Machine");
validMachineInfoDto.setHostIp("192.168.1.101");
validMachineInfoDto.setSshPort("22");
validMachineInfoDto.setUsername("testuser");
validMachineInfoDto.setAuthenticationType(AuthenticationType.PASSWORD.getMessage());
validMachineInfoDto.setStatus(MachineInfoStatus.ENABLE.getMessage());
}
// ======================= 新增机器测试 =======================
@Test
void testAddMachineInfo_ValidData_ShouldSucceed() {
boolean result = machineInfoService.addMachineInfo(validMachineInfoDto);
assertTrue(result);
// 验证数据库存在记录
MachineInfo machineInfo = machineInfoService.getById(validMachineInfoDto.getId());
assertNotNull(machineInfo);
assertEquals(validMachineInfoDto.getHostIp(), machineInfo.getHostIp());
assertEquals(AuthenticationType.PASSWORD.getCode(), machineInfo.getAuthenticationTypeCode());
}
@Test
void testAddMachineInfo_NullDto_ShouldThrowException() {
assertThrows(ServiceException.class, () -> {
machineInfoService.addMachineInfo(null);
}, "机器信息为空");
}
// ======================= 列表查询测试 =======================
@Test
void testListMachineInfo_WithStatusFilter_ShouldReturnValidRecords() {
MachineInfoDto queryDto = new MachineInfoDto();
queryDto.setStatus(MachineInfoStatus.ENABLE.getMessage());
var pageResult = machineInfoService.listMachineInfo(queryDto);
assertFalse(pageResult.getList().isEmpty());
pageResult.getList().forEach(dto ->
assertEquals(MachineInfoStatus.ENABLE.getMessage(), dto.getStatus())
);
}
@Test
void testListMachineInfo_WithHostIpFilter_ShouldFilterRecords() {
MachineInfoDto queryDto = new MachineInfoDto();
queryDto.setHostIp("192.168.1.100"); // 假设测试数据中的 IP
var pageResult = machineInfoService.listMachineInfo(queryDto);
assertFalse(pageResult.getList().isEmpty());
pageResult.getList().forEach(dto ->
assertTrue(dto.getHostIp().contains("192.168.1.100"))
);
}
// ======================= 更新机器状态测试 =======================
@Test
void testUpdateStatus_ValidId_ShouldUpdateStatus() {
boolean result = machineInfoService.updateStatus(existingMachineId, MachineInfoStatus.UN_ENABLE.getMessage());
assertTrue(result);
MachineInfo machineInfo = machineInfoService.getById(existingMachineId);
assertEquals(MachineInfoStatus.UN_ENABLE.getCode(), machineInfo.getStatus());
}
@Test
void testUpdateStatus_NonExistingId_ShouldFail() {
boolean result = machineInfoService.updateStatus(nonExistingMachineId, MachineInfoStatus.UN_ENABLE.getMessage());
assertFalse(result);
}
// ======================= 连接测试 =======================
@Test
void testTestConnection_EnabledMachine_ShouldSucceed() {
MachineInfo machineInfo = machineInfoService.getById(existingMachineId);
assertTrue(machineInfoService.testConnection(machineInfo));
}
@Test
void testTestConnection_DisabledMachine_ShouldThrowException() {
// 先禁用机器
machineInfoService.updateStatus(existingMachineId, MachineInfoStatus.UN_ENABLE.getMessage());
MachineInfo disabledMachine = machineInfoService.getById(existingMachineId);
assertThrows(RuntimeException.class, () -> {
machineInfoService.testConnection(disabledMachine);
}, "机器不可用");
}
// ======================= 会话管理测试 =======================
@Test
void testConnect_NewMachine_ShouldCreateSession() {
MachineInfo machineInfo = machineInfoService.getById(existingMachineId);
String sessionId = machineInfoService.connect(machineInfo);
assertNotNull(sessionId);
assertTrue(sessionId.startsWith("session-"));
assertEquals(ConnectionStatus.CONNECTING, machineInfoService.getConnectionStatus(machineInfo.getName()));
}
// ======================= 删除机器测试 =======================
@Test
void testDeleteMachineInfo_EnabledMachine_ShouldDelete() {
machineInfoService.deleteMachineInfo(existingMachineId);
assertNull(machineInfoService.getById(existingMachineId));
}
@Test
void testDeleteList_ValidIds_ShouldDeleteBatch() {
machineInfoService.deleteList(Collections.singletonList(existingMachineId));
var list = machineInfoService.list();
assertFalse(list.contains(existingMachineId));
}
// ======================= 辅助功能测试 =======================
@Test
void testAuthenticationTypeConversion() {
validMachineInfoDto.setAuthenticationType(AuthenticationType.SECRET_KEY.getMessage());
MachineInfo machineInfo = new MachineInfo();
BeanUtils.copyProperties(validMachineInfoDto, machineInfo);
assertEquals(AuthenticationType.SECRET_KEY.getCode(), machineInfo.getAuthenticationTypeCode());
}
@Test
void testGetAllConnectionStatus_ShouldReturnStatusMap() {
MachineInfo machineInfo = machineInfoService.getById(existingMachineId);
machineInfoService.connect(machineInfo);
var statusMap = machineInfoService.getAllConnectionStatus();
assertFalse(statusMap.isEmpty());
assertTrue(statusMap.containsValue(ConnectionStatus.CONNECTING));
}
}
//package com.casic.machine.service.impl;
//
//import com.casic.commons.exception.ServiceException;
//import com.casic.machine.dto.MachineInfoDto;
//import com.casic.machine.entity.MachineInfo;
//import com.casic.machine.enums.AuthenticationType;
//import com.casic.machine.enums.ConnectionStatus;
//import com.casic.machine.enums.MachineInfoStatus;
//import org.junit.jupiter.api.BeforeEach;
//import org.junit.jupiter.api.Test;
//import org.springframework.beans.BeanUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.boot.test.context.SpringBootTest;
//import org.springframework.test.annotation.Rollback;
//import org.springframework.test.context.jdbc.Sql;
//import org.springframework.transaction.annotation.Transactional;
//
//import java.util.Collections;
//
//import static org.junit.jupiter.api.Assertions.*;
//
//@SpringBootTest
//@Transactional
//@Rollback(true)
//@Sql(scripts = {"classpath:sql/machine_info_test_data.sql"})
//public class MachineinfoServiceImplTest {
//
// @Autowired
// private MachineinfoServiceImpl machineInfoService;
//
// private MachineInfoDto validMachineInfoDto;
// private Long existingMachineId;
// private Long nonExistingMachineId;
//
// @BeforeEach
// public void setUp() {
// // 初始化测试数据假设 SQL 脚本已插入一条状态为 ENABLE 的机器
// existingMachineId = 1L;
// nonExistingMachineId = 999L;
//
// // 有效机器信息 DTO
// validMachineInfoDto = new MachineInfoDto();
// validMachineInfoDto.setName("Test Machine");
// validMachineInfoDto.setHostIp("192.168.1.101");
// validMachineInfoDto.setSshPort("22");
// validMachineInfoDto.setUsername("testuser");
// validMachineInfoDto.setAuthenticationType(AuthenticationType.PASSWORD.getMessage());
// validMachineInfoDto.setStatus(MachineInfoStatus.ENABLE.getMessage());
// }
//
// // ======================= 新增机器测试 =======================
// @Test
// void testAddMachineInfo_ValidData_ShouldSucceed() {
// boolean result = machineInfoService.addMachineInfo(validMachineInfoDto);
// assertTrue(result);
//
// // 验证数据库存在记录
// MachineInfo machineInfo = machineInfoService.getById(validMachineInfoDto.getId());
// assertNotNull(machineInfo);
// assertEquals(validMachineInfoDto.getHostIp(), machineInfo.getHostIp());
// assertEquals(AuthenticationType.PASSWORD.getCode(), machineInfo.getAuthenticationTypeCode());
// }
//
// @Test
// void testAddMachineInfo_NullDto_ShouldThrowException() {
// assertThrows(ServiceException.class, () -> {
// machineInfoService.addMachineInfo(null);
// }, "机器信息为空");
// }
//
// // ======================= 列表查询测试 =======================
// @Test
// void testListMachineInfo_WithStatusFilter_ShouldReturnValidRecords() {
// MachineInfoDto queryDto = new MachineInfoDto();
// queryDto.setStatus(MachineInfoStatus.ENABLE.getMessage());
//
// var pageResult = machineInfoService.listMachineInfo(queryDto);
// assertFalse(pageResult.getList().isEmpty());
// pageResult.getList().forEach(dto ->
// assertEquals(MachineInfoStatus.ENABLE.getMessage(), dto.getStatus())
// );
// }
//
// @Test
// void testListMachineInfo_WithHostIpFilter_ShouldFilterRecords() {
// MachineInfoDto queryDto = new MachineInfoDto();
// queryDto.setHostIp("192.168.1.100"); // 假设测试数据中的 IP
//
// var pageResult = machineInfoService.listMachineInfo(queryDto);
// assertFalse(pageResult.getList().isEmpty());
// pageResult.getList().forEach(dto ->
// assertTrue(dto.getHostIp().contains("192.168.1.100"))
// );
// }
//
// // ======================= 更新机器状态测试 =======================
// @Test
// void testUpdateStatus_ValidId_ShouldUpdateStatus() {
// boolean result = machineInfoService.updateStatus(existingMachineId, MachineInfoStatus.UN_ENABLE.getMessage());
// assertTrue(result);
//
// MachineInfo machineInfo = machineInfoService.getById(existingMachineId);
// assertEquals(MachineInfoStatus.UN_ENABLE.getCode(), machineInfo.getStatus());
// }
//
// @Test
// void testUpdateStatus_NonExistingId_ShouldFail() {
// boolean result = machineInfoService.updateStatus(nonExistingMachineId, MachineInfoStatus.UN_ENABLE.getMessage());
// assertFalse(result);
// }
//
// // ======================= 连接测试 =======================
// @Test
// void testTestConnection_EnabledMachine_ShouldSucceed() {
// MachineInfo machineInfo = machineInfoService.getById(existingMachineId);
// assertTrue(machineInfoService.testConnection(machineInfo));
// }
//
// @Test
// void testTestConnection_DisabledMachine_ShouldThrowException() {
// // 先禁用机器
// machineInfoService.updateStatus(existingMachineId, MachineInfoStatus.UN_ENABLE.getMessage());
// MachineInfo disabledMachine = machineInfoService.getById(existingMachineId);
//
// assertThrows(RuntimeException.class, () -> {
// machineInfoService.testConnection(disabledMachine);
// }, "机器不可用");
// }
//
// // ======================= 会话管理测试 =======================
// @Test
// void testConnect_NewMachine_ShouldCreateSession() {
// MachineInfo machineInfo = machineInfoService.getById(existingMachineId);
// String sessionId = machineInfoService.connect(machineInfo);
//
// assertNotNull(sessionId);
// assertTrue(sessionId.startsWith("session-"));
// assertEquals(ConnectionStatus.CONNECTING, machineInfoService.getConnectionStatus(machineInfo.getName()));
// }
//
//
//
// // ======================= 删除机器测试 =======================
// @Test
// void testDeleteMachineInfo_EnabledMachine_ShouldDelete() {
// machineInfoService.deleteMachineInfo(existingMachineId);
// assertNull(machineInfoService.getById(existingMachineId));
// }
//
// @Test
// void testDeleteList_ValidIds_ShouldDeleteBatch() {
// machineInfoService.deleteList(Collections.singletonList(existingMachineId));
// var list = machineInfoService.list();
// assertFalse(list.contains(existingMachineId));
// }
//
// // ======================= 辅助功能测试 =======================
// @Test
// void testAuthenticationTypeConversion() {
// validMachineInfoDto.setAuthenticationType(AuthenticationType.SECRET_KEY.getMessage());
// MachineInfo machineInfo = new MachineInfo();
// BeanUtils.copyProperties(validMachineInfoDto, machineInfo);
//
// assertEquals(AuthenticationType.SECRET_KEY.getCode(), machineInfo.getAuthenticationTypeCode());
// }
//
// @Test
// void testGetAllConnectionStatus_ShouldReturnStatusMap() {
// MachineInfo machineInfo = machineInfoService.getById(existingMachineId);
// machineInfoService.connect(machineInfo);
//
// var statusMap = machineInfoService.getAllConnectionStatus();
// assertFalse(statusMap.isEmpty());
// assertTrue(statusMap.containsValue(ConnectionStatus.CONNECTING));
// }
//}

View File

@ -1,218 +1,218 @@
package com.casic.machine.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.commons.exception.ServiceException;
import com.casic.commons.utils.AliOssUtil;
import com.casic.machine.entity.MachineInfo;
import com.casic.machine.entity.SecretKey;
import com.casic.machine.dto.SecretKeyDto;
import com.casic.machine.mapper.SecretServiceMapper;
import com.casic.machine.service.MachineInfoService;
import com.jayway.jsonpath.internal.Utils;
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.beans.BeanUtils;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.util.ReflectionTestUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
@SuppressWarnings("unchecked")
public class SecretKeyServiceImplTest {
@InjectMocks
private SecretKeyServiceImpl secretKeyService;
@Mock
private AliOssUtil aliOssUtil;
@Mock
private SecretServiceMapper secretServiceMapper;
@Mock
private MachineInfoService machineInfoService;
private SecretKeyDto validSecretKeyDto;
private MockMultipartFile mockFile;
private final Long TEST_SECRET_KEY_ID = 1L;
private final String TEST_FILE_NAME = "test_key.pem";
private final String TEST_PATH = "https://bucket.endpoint/test_key.pem";
@BeforeEach
public void setUp() throws IOException {
MockitoAnnotations.openMocks(this);
validSecretKeyDto = new SecretKeyDto();
validSecretKeyDto.setName("Test Key");
validSecretKeyDto.setDescription("Test secret key");
// 创建模拟文件
byte[] fileContent = "test content".getBytes();
mockFile = new MockMultipartFile(
"file",
TEST_FILE_NAME,
"application/octet-stream",
new ByteArrayInputStream(fileContent)
);
// 模拟 OSS 工具返回值
when(aliOssUtil.save(any(MockMultipartFile.class))).thenReturn(TEST_FILE_NAME);
}
// ======================= 新增密钥测试 =======================
@Test
void testAddSecretKey_ValidData_ShouldSucceed() throws IOException {
// 执行新增
boolean result = secretKeyService.addSecretKey(validSecretKeyDto, mockFile);
// 验证 OSS 保存调用
verify(aliOssUtil, times(1)).save(mockFile);
// 验证实体属性
SecretKey savedKey = new SecretKey();
BeanUtils.copyProperties(validSecretKeyDto, savedKey);
savedKey.setFileName(TEST_FILE_NAME);
savedKey.setPath(TEST_PATH);
// 验证 Mapper 调用
verify(secretServiceMapper, times(1)).insert(savedKey);
assertTrue(result);
}
@Test
void testAddSecretKey_NullFile_ShouldThrowException() {
assertThrows(ServiceException.class, () -> {
secretKeyService.addSecretKey(validSecretKeyDto, null);
}, "文件为空");
}
// ======================= 绑定机器测试 =======================
@Test
void testBindingMachine_ValidIds_ShouldUpdateMachine() {
// 模拟机器列表
List<Long> machineIds = Collections.singletonList(1L);
when(machineInfoService.listByIds(machineIds)).thenReturn(Collections.singletonList(new MachineInfo()));
secretKeyService.bindingMachine(TEST_SECRET_KEY_ID, machineIds);
// 验证机器信息更新
verify(machineInfoService, times(1)).listByIds(machineIds);
machineIds.forEach(id -> {
verify(machineInfoService, times(1)).update(any());
});
}
// ======================= 更新密钥测试 =======================
@Test
void testUpdateSecretKey_WithNewFile_ShouldUpdatePath() throws IOException {
MockMultipartFile newFile = new MockMultipartFile(
"file",
"new_key.pem",
"application/octet-stream",
new ByteArrayInputStream("new content".getBytes())
);
when(aliOssUtil.save(newFile)).thenReturn("new_key.pem");
validSecretKeyDto.setId(TEST_SECRET_KEY_ID);
boolean result = secretKeyService.updateSecretKey(validSecretKeyDto, newFile);
// 验证 OSS 调用和路径更新
verify(aliOssUtil, times(1)).save(newFile);
SecretKey updatedKey = new SecretKey();
BeanUtils.copyProperties(validSecretKeyDto, updatedKey);
updatedKey.setFileName("new_key.pem");
updatedKey.setPath("https://bucket.endpoint/new_key.pem");
verify(secretServiceMapper, times(1)).updateById(updatedKey);
assertTrue(result);
}
// ======================= 删除密钥测试 =======================
@Test
void testDeleteSecretKey_ValidId_ShouldDeleteFileAndRecord() {
SecretKey secretKey = new SecretKey();
secretKey.setId(TEST_SECRET_KEY_ID);
secretKey.setFileName(TEST_FILE_NAME);
when(secretServiceMapper.selectById(TEST_SECRET_KEY_ID)).thenReturn(secretKey);
boolean result = secretKeyService.deleteSecretKey(TEST_SECRET_KEY_ID);
// 验证 OSS 删除和 Mapper 调用
verify(aliOssUtil, times(1)).deleteFile(TEST_FILE_NAME);
verify(secretServiceMapper, times(1)).deleteById(TEST_SECRET_KEY_ID);
assertTrue(result);
}
// ======================= 列表查询测试 =======================
@Test
void testListSecretKey_WithNameFilter_ShouldReturnMatchedRecords() {
SecretKeyDto queryDto = new SecretKeyDto();
queryDto.setName("Test");
QueryWrapper<SecretKey> wrapper = new QueryWrapper<>();
wrapper.like("name", "Test");
when(secretServiceMapper.selectPage(any(), any())).thenReturn(new Page<>());
secretKeyService.listSecretKey(queryDto);
verify(secretServiceMapper, times(1)).selectPage(any(), wrapper);
}
// ======================= 文件下载测试 =======================
@Test
void testDownloadSecretKeyFile_ValidId_ShouldReturnResponseEntity() throws IOException {
SecretKey secretKey = new SecretKey();
secretKey.setFileName(TEST_FILE_NAME);
when(secretServiceMapper.selectById(TEST_SECRET_KEY_ID)).thenReturn(secretKey);
InputStreamResource inputStreamResource = new InputStreamResource(
new ByteArrayInputStream("test content".getBytes())
);
when(aliOssUtil.downloadFile(TEST_FILE_NAME)).thenReturn(
ResponseEntity.ok(inputStreamResource)
);
ResponseEntity<InputStreamResource> response = secretKeyService.downloadSecretKeyFile(TEST_SECRET_KEY_ID);
assertNotNull(response);
assertEquals("test content", Utils.toString(response.getBody().getInputStream()));
}
// ======================= 批量删除测试 =======================
@Test
void testDeleteList_ValidIds_ShouldSubmitAsyncDelete() {
List<Long> ids = Collections.singletonList(TEST_SECRET_KEY_ID);
SecretKey secretKey = new SecretKey();
secretKey.setFileName(TEST_FILE_NAME);
when(secretServiceMapper.selectBatchIds(ids)).thenReturn(Collections.singletonList(secretKey));
secretKeyService.deleteList(ids);
// 验证异步任务提交
verify(secretKeyService.FILE_DELETE_EXECUTOR, times(1)).execute(any(Runnable.class));
verify(secretServiceMapper, times(1)).deleteBatchIds(ids);
}
// ======================= 异常处理测试 =======================
@Test
void testDeleteSecretKey_FileDeleteFailed_ShouldThrowException() {
aliOssUtil.deleteFile(TEST_FILE_NAME);
SecretKey secretKey = new SecretKey();
secretKey.setId(TEST_SECRET_KEY_ID);
secretKey.setFileName(TEST_FILE_NAME);
when(secretServiceMapper.selectById(TEST_SECRET_KEY_ID)).thenReturn(secretKey);
assertThrows(ServiceException.class, () -> {
secretKeyService.deleteSecretKey(TEST_SECRET_KEY_ID);
}, "删除文件失败");
}
}
//package com.casic.machine.service.impl;
//
//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
//import com.casic.commons.exception.ServiceException;
//import com.casic.commons.utils.AliOssUtil;
//import com.casic.machine.entity.MachineInfo;
//import com.casic.machine.entity.SecretKey;
//import com.casic.machine.dto.SecretKeyDto;
//import com.casic.machine.mapper.SecretServiceMapper;
//import com.casic.machine.service.MachineInfoService;
//import com.jayway.jsonpath.internal.Utils;
//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.beans.BeanUtils;
//import org.springframework.core.io.InputStreamResource;
//import org.springframework.http.ResponseEntity;
//import org.springframework.mock.web.MockMultipartFile;
//import org.springframework.test.util.ReflectionTestUtils;
//
//import java.io.ByteArrayInputStream;
//import java.io.IOException;
//import java.util.Collections;
//import java.util.List;
//
//import static org.junit.jupiter.api.Assertions.*;
//import static org.mockito.ArgumentMatchers.any;
//import static org.mockito.Mockito.*;
//
//@SuppressWarnings("unchecked")
//public class SecretKeyServiceImplTest {
//
// @InjectMocks
// private SecretKeyServiceImpl secretKeyService;
//
// @Mock
// private AliOssUtil aliOssUtil;
//
// @Mock
// private SecretServiceMapper secretServiceMapper;
//
// @Mock
// private MachineInfoService machineInfoService;
//
// private SecretKeyDto validSecretKeyDto;
// private MockMultipartFile mockFile;
// private final Long TEST_SECRET_KEY_ID = 1L;
// private final String TEST_FILE_NAME = "test_key.pem";
// private final String TEST_PATH = "https://bucket.endpoint/test_key.pem";
//
// @BeforeEach
// public void setUp() throws IOException {
// MockitoAnnotations.openMocks(this);
// validSecretKeyDto = new SecretKeyDto();
// validSecretKeyDto.setName("Test Key");
// validSecretKeyDto.setDescription("Test secret key");
//
// // 创建模拟文件
// byte[] fileContent = "test content".getBytes();
// mockFile = new MockMultipartFile(
// "file",
// TEST_FILE_NAME,
// "application/octet-stream",
// new ByteArrayInputStream(fileContent)
// );
//
// // 模拟 OSS 工具返回值
// when(aliOssUtil.save(any(MockMultipartFile.class))).thenReturn(TEST_FILE_NAME);
//
// }
//
// // ======================= 新增密钥测试 =======================
// @Test
// void testAddSecretKey_ValidData_ShouldSucceed() throws IOException {
// // 执行新增
// boolean result = secretKeyService.addSecretKey(validSecretKeyDto, mockFile);
//
// // 验证 OSS 保存调用
// verify(aliOssUtil, times(1)).save(mockFile);
//
// // 验证实体属性
// SecretKey savedKey = new SecretKey();
// BeanUtils.copyProperties(validSecretKeyDto, savedKey);
// savedKey.setFileName(TEST_FILE_NAME);
// savedKey.setPath(TEST_PATH);
//
// // 验证 Mapper 调用
// verify(secretServiceMapper, times(1)).insert(savedKey);
// assertTrue(result);
// }
//
// @Test
// void testAddSecretKey_NullFile_ShouldThrowException() {
// assertThrows(ServiceException.class, () -> {
// secretKeyService.addSecretKey(validSecretKeyDto, null);
// }, "文件为空");
// }
//
// // ======================= 绑定机器测试 =======================
// @Test
// void testBindingMachine_ValidIds_ShouldUpdateMachine() {
// // 模拟机器列表
// List<Long> machineIds = Collections.singletonList(1L);
// when(machineInfoService.listByIds(machineIds)).thenReturn(Collections.singletonList(new MachineInfo()));
//
// secretKeyService.bindingMachine(TEST_SECRET_KEY_ID, machineIds);
//
// // 验证机器信息更新
// verify(machineInfoService, times(1)).listByIds(machineIds);
// machineIds.forEach(id -> {
// verify(machineInfoService, times(1)).update(any());
// });
// }
//
// // ======================= 更新密钥测试 =======================
// @Test
// void testUpdateSecretKey_WithNewFile_ShouldUpdatePath() throws IOException {
// MockMultipartFile newFile = new MockMultipartFile(
// "file",
// "new_key.pem",
// "application/octet-stream",
// new ByteArrayInputStream("new content".getBytes())
// );
// when(aliOssUtil.save(newFile)).thenReturn("new_key.pem");
//
// validSecretKeyDto.setId(TEST_SECRET_KEY_ID);
// boolean result = secretKeyService.updateSecretKey(validSecretKeyDto, newFile);
//
// // 验证 OSS 调用和路径更新
// verify(aliOssUtil, times(1)).save(newFile);
// SecretKey updatedKey = new SecretKey();
// BeanUtils.copyProperties(validSecretKeyDto, updatedKey);
// updatedKey.setFileName("new_key.pem");
// updatedKey.setPath("https://bucket.endpoint/new_key.pem");
// verify(secretServiceMapper, times(1)).updateById(updatedKey);
// assertTrue(result);
// }
//
// // ======================= 删除密钥测试 =======================
// @Test
// void testDeleteSecretKey_ValidId_ShouldDeleteFileAndRecord() {
// SecretKey secretKey = new SecretKey();
// secretKey.setId(TEST_SECRET_KEY_ID);
// secretKey.setFileName(TEST_FILE_NAME);
// when(secretServiceMapper.selectById(TEST_SECRET_KEY_ID)).thenReturn(secretKey);
//
// boolean result = secretKeyService.deleteSecretKey(TEST_SECRET_KEY_ID);
//
// // 验证 OSS 删除和 Mapper 调用
// verify(aliOssUtil, times(1)).deleteFile(TEST_FILE_NAME);
// verify(secretServiceMapper, times(1)).deleteById(TEST_SECRET_KEY_ID);
// assertTrue(result);
// }
//
// // ======================= 列表查询测试 =======================
// @Test
// void testListSecretKey_WithNameFilter_ShouldReturnMatchedRecords() {
// SecretKeyDto queryDto = new SecretKeyDto();
// queryDto.setName("Test");
// QueryWrapper<SecretKey> wrapper = new QueryWrapper<>();
// wrapper.like("name", "Test");
//
// when(secretServiceMapper.selectPage(any(), any())).thenReturn(new Page<>());
//
// secretKeyService.listSecretKey(queryDto);
// verify(secretServiceMapper, times(1)).selectPage(any(), wrapper);
// }
//
// // ======================= 文件下载测试 =======================
// @Test
// void testDownloadSecretKeyFile_ValidId_ShouldReturnResponseEntity() throws IOException {
// SecretKey secretKey = new SecretKey();
// secretKey.setFileName(TEST_FILE_NAME);
// when(secretServiceMapper.selectById(TEST_SECRET_KEY_ID)).thenReturn(secretKey);
// InputStreamResource inputStreamResource = new InputStreamResource(
// new ByteArrayInputStream("test content".getBytes())
// );
// when(aliOssUtil.downloadFile(TEST_FILE_NAME)).thenReturn(
// ResponseEntity.ok(inputStreamResource)
// );
//
// ResponseEntity<InputStreamResource> response = secretKeyService.downloadSecretKeyFile(TEST_SECRET_KEY_ID);
// assertNotNull(response);
// assertEquals("test content", Utils.toString(response.getBody().getInputStream()));
// }
//
// // ======================= 批量删除测试 =======================
// @Test
// void testDeleteList_ValidIds_ShouldSubmitAsyncDelete() {
// List<Long> ids = Collections.singletonList(TEST_SECRET_KEY_ID);
// SecretKey secretKey = new SecretKey();
// secretKey.setFileName(TEST_FILE_NAME);
// when(secretServiceMapper.selectBatchIds(ids)).thenReturn(Collections.singletonList(secretKey));
//
// secretKeyService.deleteList(ids);
//
// // 验证异步任务提交
// verify(secretKeyService.FILE_DELETE_EXECUTOR, times(1)).execute(any(Runnable.class));
// verify(secretServiceMapper, times(1)).deleteBatchIds(ids);
// }
//
// // ======================= 异常处理测试 =======================
// @Test
// void testDeleteSecretKey_FileDeleteFailed_ShouldThrowException() {
// aliOssUtil.deleteFile(TEST_FILE_NAME);
// SecretKey secretKey = new SecretKey();
// secretKey.setId(TEST_SECRET_KEY_ID);
// secretKey.setFileName(TEST_FILE_NAME);
// when(secretServiceMapper.selectById(TEST_SECRET_KEY_ID)).thenReturn(secretKey);
//
// assertThrows(ServiceException.class, () -> {
// secretKeyService.deleteSecretKey(TEST_SECRET_KEY_ID);
// }, "删除文件失败");
// }
//}