fix(接口测试): 接口分享重名校验问题

This commit is contained in:
song-cc-rock 2024-10-16 17:43:55 +08:00 committed by Craftsman
parent a6ba89f077
commit 3aa53ef5c4
14 changed files with 235 additions and 2 deletions

View File

@ -152,6 +152,8 @@ public class PermissionConstants {
public static final String PROJECT_APPLICATION_PERFORMANCE_TEST_UPDATE = "PROJECT_APPLICATION_PERFORMANCE_TEST:UPDATE";
public static final String PROJECT_APPLICATION_API_READ = "PROJECT_APPLICATION_API:READ";
public static final String PROJECT_APPLICATION_API_UPDATE = "PROJECT_APPLICATION_API:UPDATE";
public static final String PROJECT_APPLICATION_TASK_READ = "PROJECT_APPLICATION_TASK:READ";
public static final String PROJECT_APPLICATION_TASK_UPDATE = "PROJECT_APPLICATION_TASK:UPDATE";
public static final String PROJECT_APPLICATION_CASE_READ = "PROJECT_APPLICATION_CASE:READ";
public static final String PROJECT_APPLICATION_CASE_UPDATE = "PROJECT_APPLICATION_CASE:UPDATE";
public static final String PROJECT_APPLICATION_BUG_READ = "PROJECT_APPLICATION_BUG:READ";

View File

@ -14,6 +14,16 @@ public class ProjectApplicationType {
}
/**
* 任务中心
*/
public enum TASK {
/**
* 清理报告
*/
TASK_CLEAN_REPORT,
}
//接口测试
public enum API {
API_URL_REPEATABLE,

View File

@ -40,6 +40,8 @@ public class CleanupApiReportServiceImpl implements BaseCleanUpReport {
private ApiScenarioReportLogMapper apiScenarioReportLogMapper;
@Resource
private ApiScenarioReportDetailBlobMapper apiScenarioReportDetailBlobMapper;
@Resource
private ApiReportRelateTaskMapper apiReportRelateTaskMapper;
@Override
public void cleanReport(Map<String, String> map, String projectId) {
@ -54,6 +56,9 @@ public class CleanupApiReportServiceImpl implements BaseCleanUpReport {
ApiReport report = new ApiReport();
report.setDeleted(true);
apiReportMapper.updateByExampleSelective(report, reportExample);
// 任务执行结果存在报告明细做保留
List<String> taskReportIds = getTaskReportIds(ids);
ids.removeAll(taskReportIds);
deleteApiReport(ids);
apiReportCount = extApiReportMapper.countApiReportByTime(timeMills, projectId);
}
@ -65,11 +70,26 @@ public class CleanupApiReportServiceImpl implements BaseCleanUpReport {
ApiScenarioReport report = new ApiScenarioReport();
report.setDeleted(true);
apiScenarioReportMapper.updateByExampleSelective(report, reportExample);
// 任务执行结果存在报告明细做保留
List<String> taskReportIds = getTaskReportIds(ids);
ids.removeAll(taskReportIds);
deleteScenarioReport(ids);
scenarioReportCount = extApiScenarioReportMapper.countScenarioReportByTime(timeMills, projectId);
}
}
/**
* 获取任务报告ID
* @param reportIds 报告ID集合
* @return 任务报告ID集合
*/
private List<String> getTaskReportIds(List<String> reportIds) {
ApiReportRelateTaskExample example = new ApiReportRelateTaskExample();
example.createCriteria().andReportIdIn(reportIds);
List<ApiReportRelateTask> relateTasks = apiReportRelateTaskMapper.selectByExample(example);
return relateTasks.stream().map(ApiReportRelateTask::getReportId).toList();
}
private void deleteApiReport(List<String> ids) {
ApiReportStepExample stepExample = new ApiReportStepExample();
stepExample.createCriteria().andReportIdIn(ids);

View File

@ -0,0 +1,56 @@
package io.metersphere.api.service;
import io.metersphere.api.domain.ApiReportRelateTaskExample;
import io.metersphere.api.mapper.ApiReportRelateTaskMapper;
import io.metersphere.sdk.constants.ProjectApplicationType;
import io.metersphere.sdk.util.LogUtils;
import io.metersphere.sdk.util.SubListUtils;
import io.metersphere.system.mapper.ExtExecTaskItemMapper;
import io.metersphere.system.mapper.ExtExecTaskMapper;
import io.metersphere.system.service.BaseCleanUpReport;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
import static io.metersphere.sdk.util.ShareUtil.getCleanDate;
/**
* @author song-cc-rock
*/
@Component
@Transactional(rollbackFor = Exception.class)
public class CleanupTaskResultServiceImpl implements BaseCleanUpReport {
@Resource
private ExtExecTaskMapper extExecTaskMapper;
@Resource
private ExtExecTaskItemMapper extExecTaskItemMapper;
@Resource
private ApiReportRelateTaskMapper apiReportRelateTaskMapper;
@Override
public void cleanReport(Map<String, String> map, String projectId) {
LogUtils.info("清理当前项目[" + projectId + "]任务中心执行结果");
String expr = map.get(ProjectApplicationType.TASK.TASK_CLEAN_REPORT.name());
long timeMills = getCleanDate(expr);
List<String> cleanTaskIds = extExecTaskMapper.getTaskIdsByTime(timeMills, projectId);
List<String> cleanTaskItemIds = extExecTaskItemMapper.getTaskItemIdsByTime(timeMills, projectId);
List<String> cleanIds = ListUtils.union(cleanTaskIds, cleanTaskItemIds);
LogUtils.info("清理当前项目[" + projectId + "]任务中心执行结果, 共[" + cleanIds.size() + "]条");
if (CollectionUtils.isNotEmpty(cleanIds)) {
// 清理任务-报告关系表
SubListUtils.dealForSubList(cleanIds, 100, ids -> {
ApiReportRelateTaskExample example = new ApiReportRelateTaskExample();
example.createCriteria().andTaskResourceIdIn(cleanIds);
apiReportRelateTaskMapper.deleteByExample(example);
});
}
LogUtils.info("清理当前项目[" + projectId + "]任务中心执行结果结束!");
}
}

View File

@ -0,0 +1,56 @@
package io.metersphere.api.controller;
import io.metersphere.api.service.CleanupTaskResultServiceImpl;
import io.metersphere.sdk.constants.ProjectApplicationType;
import io.metersphere.system.domain.ExecTask;
import io.metersphere.system.mapper.ExecTaskMapper;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.HashMap;
import java.util.Map;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@AutoConfigureMockMvc
public class CleanupTaskResultTests {
@Resource
private ExecTaskMapper execTaskMapper;
@Resource
private CleanupTaskResultServiceImpl cleanupTaskResultServiceImpl;
public void initTaskData() {
ExecTask task = new ExecTask();
task.setId("clean-task-id");
task.setNum(1L);
task.setTaskName("clean-task-name");
task.setStatus("PENDING");
task.setCaseCount(1L);
task.setTaskType("clean-task-type");
task.setTriggerMode("clean-trigger-mode");
task.setOrganizationId("clean-organization-id");
task.setProjectId("clean-project-id");
task.setIntegrated(true);
task.setStartTime(1700000000000L);
task.setResult("PENDING");
task.setCreateUser("admin");
task.setCreateTime(System.currentTimeMillis());
execTaskMapper.insert(task);
}
@Test
@Order(1)
public void testCleanupTaskResult() {
initTaskData();
Map<String, String> map = new HashMap<>();
map.put(ProjectApplicationType.TASK.TASK_CLEAN_REPORT.name(), "1D");
cleanupTaskResultServiceImpl.cleanReport(map, "clean-project-id");
cleanupTaskResultServiceImpl.cleanReport(map, "clean-project-not-exit-id");
}
}

View File

@ -87,6 +87,22 @@ public class ProjectApplicationController {
return configMap;
}
@PostMapping("/update/task")
@Operation(summary = "任务中心-配置")
@RequiresPermissions(PermissionConstants.PROJECT_APPLICATION_TASK_UPDATE)
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateTaskLog(#application)", msClass = ProjectApplicationService.class)
public void updateTask(@Validated({Updated.class}) @RequestBody ProjectApplication application) {
projectApplicationService.update(application, SessionUtils.getUserId());
}
@PostMapping("/task")
@Operation(summary = "任务中心-获取配置")
@RequiresPermissions(PermissionConstants.PROJECT_APPLICATION_TASK_READ)
public Map<String, Object> getTask(@Validated @RequestBody ProjectApplicationRequest request) {
List<String> types = Arrays.stream(ProjectApplicationType.TASK.values()).map(ProjectApplicationType.TASK::name).collect(Collectors.toList());
return projectApplicationService.get(request, types);
}
@GetMapping("/api/user/{projectId}")
@Operation(summary = "接口测试-获取审核人")
@RequiresPermissions(PermissionConstants.PROJECT_APPLICATION_API_READ)

View File

@ -317,6 +317,16 @@ public class ProjectApplicationService {
return delLog(application, OperationLogModule.PROJECT_MANAGEMENT_PERMISSION_MENU_MANAGEMENT, "接口测试配置");
}
/**
* 任务中心 日志
*
* @param application 配置项
* @return 日志
*/
public LogDTO updateTaskLog(ProjectApplication application) {
return delLog(application, OperationLogModule.PROJECT_MANAGEMENT_PERMISSION_MENU_MANAGEMENT, "任务中心配置");
}
/**
* 用例管理 日志

View File

@ -116,6 +116,25 @@ public class ProjectApplicationControllerTests extends BaseTest {
* ==========测试计划配置 end==========
*/
/**
* ========== 任务中心 start==========
*/
public static final String TASK_UPDATE_URL = "/project/application/update/task";
public static final String GET_TASK_URL = "/project/application/task";
// 任务中心 - 获取配置
@Test
@Order(4)
public void testGetTask() throws Exception {
ProjectApplicationRequest request = this.getRequest("TASK");
this.requestPostWithOkAndReturn(GET_TASK_URL, request);
}
// 任务中心 - 获取配置
@Test
@Order(5)
public void testUpdateTask() throws Exception {
ProjectApplication request = creatRequest(ProjectApplicationType.TASK.TASK_CLEAN_REPORT.name(), "1D");
this.requestPostWithOkAndReturn(TASK_UPDATE_URL, request);
}
/**

View File

@ -72,6 +72,16 @@ public class CleanUpReportJob {
map.put(ProjectApplicationType.API.API_CLEAN_REPORT.name(), "3M");
}
// task
applicationExample.clear();
applicationExample.createCriteria().andProjectIdEqualTo(project.getId()).andTypeEqualTo(ProjectApplicationType.TASK.TASK_CLEAN_REPORT.name());
List<ProjectApplication> task = projectApplicationMapper.selectByExample(applicationExample);
if (CollectionUtils.isNotEmpty(task)) {
map.put(ProjectApplicationType.TASK.TASK_CLEAN_REPORT.name(), task.getFirst().getTypeValue());
} else {
map.put(ProjectApplicationType.TASK.TASK_CLEAN_REPORT.name(), "3M");
}
Map<String, BaseCleanUpReport> beansOfType = applicationContext.getBeansOfType(BaseCleanUpReport.class);
beansOfType.forEach((k, v) -> {
v.cleanReport(map, project.getId());

View File

@ -22,4 +22,12 @@ public interface ExtExecTaskItemMapper {
List<ExecTaskItem> getResourcePoolsByTaskIds(@Param("taskIds") List<String> taskIds);
void batchUpdateTaskItemStatus(@Param("taskIds") List<String> taskIds, @Param("userId") String userId, @Param("organizationId") String organizationId, @Param("projectId") String projectId, @Param("status") String status);
/**
* 查询时间范围内的任务项ID集合
* @param timeMills 时间戳
* @param projectId 项目ID
* @return 任务项ID列表
*/
List<String> getTaskItemIdsByTime(@Param("timeMills") long timeMills, @Param("projectId") String projectId);
}

View File

@ -17,6 +17,10 @@
</foreach>
</select>
<select id="getTaskItemIdsByTime" resultType="java.lang.String">
select id from exec_task_item where project_id = #{projectId} and start_time &lt;= #{timeMills}
</select>
<select id="selectItemByTaskIds" resultType="io.metersphere.system.domain.ExecTaskItem">
select id, task_id, `status`, result
from exec_task_item

View File

@ -1,6 +1,5 @@
package io.metersphere.system.mapper;
import io.metersphere.system.domain.ExecTask;
import io.metersphere.system.dto.sdk.BasePageRequest;
import io.metersphere.system.dto.table.TableBatchProcessDTO;
import io.metersphere.system.dto.taskhub.TaskHubDTO;
@ -19,4 +18,12 @@ public interface ExtExecTaskMapper {
List<String> getIds(@Param("request") TableBatchProcessDTO request);
void batchUpdateTaskStatus(@Param("ids") List<String> ids, @Param("userId") String userId, @Param("organizationId") String organizationId, @Param("projectId") String projectId, @Param("status") String status);
/**
* 查询时间范围内的任务ID集合
* @param timeMills 时间戳
* @param projectId 项目ID
* @return 任务ID列表
*/
List<String> getTaskIdsByTime(@Param("timeMills") long timeMills, @Param("projectId") String projectId);
}

View File

@ -105,4 +105,8 @@
</if>
and `status` = 'RUNNING'
</update>
<select id="getTaskIdsByTime" resultType="java.lang.String">
select id from exec_task where project_id = #{projectId} and start_time &lt;= #{timeMills}
</select>
</mapper>

View File

@ -1,6 +1,9 @@
package io.metersphere.plan.service;
import com.google.common.collect.Maps;
import io.metersphere.api.domain.ApiReportRelateTask;
import io.metersphere.api.domain.ApiReportRelateTaskExample;
import io.metersphere.api.mapper.ApiReportRelateTaskMapper;
import io.metersphere.api.service.ApiCommonService;
import io.metersphere.bug.dto.response.BugDTO;
import io.metersphere.bug.service.BugCommonService;
@ -121,6 +124,8 @@ public class TestPlanReportService {
private BaseTaskHubService baseTaskHubService;
@Resource
private ProjectMapper projectMapper;
@Resource
private ApiReportRelateTaskMapper apiReportRelateTaskMapper;
private static final int MAX_REPORT_NAME_LENGTH = 300;
@ -190,13 +195,19 @@ public class TestPlanReportService {
*/
public void cleanAndDeleteReport(List<String> reportIdList) {
if (CollectionUtils.isNotEmpty(reportIdList)) {
// 获取任务执行结果报告ID集合
ApiReportRelateTaskExample taskReportExample = new ApiReportRelateTaskExample();
taskReportExample.createCriteria().andReportIdIn(reportIdList);
List<ApiReportRelateTask> relateTasks = apiReportRelateTaskMapper.selectByExample(taskReportExample);
List<String> taskReportIds = relateTasks.stream().map(ApiReportRelateTask::getReportId).toList();
SubListUtils.dealForSubList(reportIdList, SubListUtils.DEFAULT_BATCH_SIZE, subList -> {
TestPlanReportExample example = new TestPlanReportExample();
example.createCriteria().andIdIn(subList);
TestPlanReport testPlanReport = new TestPlanReport();
testPlanReport.setDeleted(true);
testPlanReportMapper.updateByExampleSelective(testPlanReport, example);
// 任务执行结果存在报告明细做保留
subList.removeAll(taskReportIds);
this.deleteTestPlanReportBlobs(subList);
});
}