feat(测试计划): 归档

This commit is contained in:
WangXu10 2024-05-07 15:13:52 +08:00 committed by 刘瑞斌
parent 1ceb194def
commit 80fab6c61d
10 changed files with 119 additions and 5 deletions

View File

@ -95,3 +95,4 @@ log.test_plan.functional_case=Functional case
log.test_plan.api_case=Api case log.test_plan.api_case=Api case
log.test_plan.api_scenario=Api scenario log.test_plan.api_scenario=Api scenario
test_plan.type.not_blank=Test plan type cannot be empty test_plan.type.not_blank=Test plan type cannot be empty
test_plan.group.not_plan=There are no archived plans in the current testing plan group

View File

@ -95,3 +95,4 @@ log.test_plan.functional_case=功能用例
log.test_plan.api_case=接口用例 log.test_plan.api_case=接口用例
log.test_plan.api_scenario=接口场景 log.test_plan.api_scenario=接口场景
test_plan.type.not_blank=测试计划类型不能为空 test_plan.type.not_blank=测试计划类型不能为空
test_plan.group.not_plan=当前测试计划组没有可归档计划

View File

@ -95,3 +95,4 @@ log.test_plan.functional_case=功能用例
log.test_plan.api_case=接口用例 log.test_plan.api_case=接口用例
log.test_plan.api_scenario=接口場景 log.test_plan.api_scenario=接口場景
test_plan.type.not_blank=測試計劃類型不能為空 test_plan.type.not_blank=測試計劃類型不能為空
test_plan.group.not_plan=當前測試計劃組沒有可歸檔計劃

View File

@ -4,10 +4,13 @@ import io.metersphere.plan.constants.TestPlanResourceConfig;
import io.metersphere.plan.dto.request.*; import io.metersphere.plan.dto.request.*;
import io.metersphere.plan.dto.response.TestPlanCountResponse; import io.metersphere.plan.dto.response.TestPlanCountResponse;
import io.metersphere.plan.dto.response.TestPlanResponse; import io.metersphere.plan.dto.response.TestPlanResponse;
import io.metersphere.plan.service.TestPlanLogService;
import io.metersphere.plan.service.TestPlanManagementService; import io.metersphere.plan.service.TestPlanManagementService;
import io.metersphere.plan.service.TestPlanService; import io.metersphere.plan.service.TestPlanService;
import io.metersphere.sdk.constants.HttpMethodConstants; import io.metersphere.sdk.constants.HttpMethodConstants;
import io.metersphere.sdk.constants.PermissionConstants; import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.system.log.annotation.Log;
import io.metersphere.system.log.constants.OperationLogType;
import io.metersphere.system.security.CheckOwner; import io.metersphere.system.security.CheckOwner;
import io.metersphere.system.utils.Pager; import io.metersphere.system.utils.Pager;
import io.metersphere.system.utils.SessionUtils; import io.metersphere.system.utils.SessionUtils;
@ -111,4 +114,14 @@ public class TestPlanController {
} }
@GetMapping("/archived/{id}")
@Operation(summary = "测试计划-归档")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_UPDATE)
@CheckOwner(resourceId = "#id", resourceType = "test_plan")
@Log(type = OperationLogType.ARCHIVED, expression = "#msClass.archivedLog(#id)", msClass = TestPlanLogService.class)
public void archived(@NotBlank @PathVariable String id) {
String userId = SessionUtils.getUserId();
testPlanService.archived(id, userId);
}
} }

View File

@ -28,4 +28,6 @@ public interface ExtTestPlanMapper {
long updateDefaultGroupId(@Param("list") List<String> groupIds); long updateDefaultGroupId(@Param("list") List<String> groupIds);
String selectProjectIdByTestPlanId(String testPlanId); String selectProjectIdByTestPlanId(String testPlanId);
void batchUpdateStatus(@Param("status") String status, @Param("userId") String userId, @Param("updateTime") Long updateTime, @Param("ids") List<String> ids);
} }

View File

@ -359,4 +359,14 @@
</if> </if>
</sql> </sql>
<update id="batchUpdateStatus">
UPDATE test_plan
SET status = #{status}, update_user = #{userId}, update_time = #{updateTime}
WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</update>
</mapper> </mapper>

View File

@ -1,8 +1,10 @@
package io.metersphere.plan.service; package io.metersphere.plan.service;
import io.metersphere.plan.domain.TestPlan; import io.metersphere.plan.domain.TestPlan;
import io.metersphere.plan.mapper.TestPlanMapper;
import io.metersphere.project.domain.Project; import io.metersphere.project.domain.Project;
import io.metersphere.project.mapper.ProjectMapper; import io.metersphere.project.mapper.ProjectMapper;
import io.metersphere.sdk.constants.HttpMethodConstants;
import io.metersphere.sdk.constants.TestPlanConstants; import io.metersphere.sdk.constants.TestPlanConstants;
import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.Translator; import io.metersphere.sdk.util.Translator;
@ -29,6 +31,8 @@ public class TestPlanLogService {
private ProjectMapper projectMapper; private ProjectMapper projectMapper;
@Resource @Resource
private OperationLogService operationLogService; private OperationLogService operationLogService;
@Resource
private TestPlanMapper testPlanMapper;
public void saveAddLog(TestPlan module, String operator, String requestUrl, String requestMethod) { public void saveAddLog(TestPlan module, String operator, String requestUrl, String requestMethod) {
Project project = projectMapper.selectByPrimaryKey(module.getProjectId()); Project project = projectMapper.selectByPrimaryKey(module.getProjectId());
@ -115,7 +119,7 @@ public class TestPlanLogService {
private String generateTestPlanDeleteContent(TestPlan deleteTestPlan) { private String generateTestPlanDeleteContent(TestPlan deleteTestPlan) {
StringBuilder content = new StringBuilder(); StringBuilder content = new StringBuilder();
if(StringUtils.equals(deleteTestPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)){ if (StringUtils.equals(deleteTestPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
content.append(Translator.get("log.delete.test_plan_group")).append(":").append(deleteTestPlan.getName()).append(StringUtils.SPACE); content.append(Translator.get("log.delete.test_plan_group")).append(":").append(deleteTestPlan.getName()).append(StringUtils.SPACE);
} else { } else {
content.append(Translator.get("log.delete.test_plan")).append(":").append(deleteTestPlan.getName()).append(StringUtils.SPACE); content.append(Translator.get("log.delete.test_plan")).append(":").append(deleteTestPlan.getName()).append(StringUtils.SPACE);
@ -123,4 +127,25 @@ public class TestPlanLogService {
return content.toString(); return content.toString();
} }
/**
* 归档日志
*
* @param id
* @return
*/
public LogDTO archivedLog(String id) {
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(id);
LogDTO dto = new LogDTO(
testPlan.getProjectId(),
null,
testPlan.getId(),
null,
OperationLogType.ARCHIVED.name(),
logModule,
testPlan.getName());
dto.setPath("/test-plan/archived");
dto.setMethod(HttpMethodConstants.GET.name());
dto.setOriginalValue(JSON.toJSONBytes(testPlan));
return dto;
}
} }

View File

@ -34,6 +34,7 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
@Service @Service
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@ -360,4 +361,46 @@ public class TestPlanService {
testPlanFollowerMapper.insert(testPlanFollower); testPlanFollowerMapper.insert(testPlanFollower);
} }
} }
/**
* 测试计划归档
*
* @param id
* @param userId
*/
public void archived(String id, String userId) {
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(id);
if (StringUtils.equalsAnyIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
//测试计划组归档
updateGroupStatus(testPlan.getId(), userId);
} else {
//测试计划
testPlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED);
testPlan.setUpdateUser(userId);
testPlan.setUpdateTime(System.currentTimeMillis());
testPlanMapper.updateByPrimaryKeySelective(testPlan);
}
}
/**
* 测试计划组归档
*
* @param id
* @param userId
*/
private void updateGroupStatus(String id, String userId) {
TestPlanExample example = new TestPlanExample();
example.createCriteria().andGroupIdEqualTo(id);
List<TestPlan> testPlanList = testPlanMapper.selectByExample(example);
if (CollectionUtils.isEmpty(testPlanList)) {
throw new MSException(Translator.get("test_plan.group.not_plan"));
}
List<String> ids = testPlanList.stream().filter(item -> StringUtils.equalsIgnoreCase(item.getStatus(), TestPlanConstants.TEST_PLAN_STATUS_COMPLETED)).map(TestPlan::getId).collect(Collectors.toList());
if (CollectionUtils.isEmpty(ids)) {
throw new MSException(Translator.get("test_plan.group.not_plan"));
}
extTestPlanMapper.batchUpdateStatus(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED, userId, System.currentTimeMillis(), ids);
}
} }

View File

@ -120,6 +120,7 @@ public class TestPlanTests extends BaseTest {
private static final String URL_POST_RESOURCE_API_SCENARIO_SORT = "/test-plan/api/scenario/sort"; private static final String URL_POST_RESOURCE_API_SCENARIO_SORT = "/test-plan/api/scenario/sort";
private static final String URL_TEST_PLAN_EDIT_FOLLOWER = "/test-plan/edit/follower"; private static final String URL_TEST_PLAN_EDIT_FOLLOWER = "/test-plan/edit/follower";
private static final String URL_TEST_PLAN_ARCHIVED = "/test-plan/archived/%s";
private static String groupTestPlanId7 = null; private static String groupTestPlanId7 = null;
private static String groupTestPlanId15 = null; private static String groupTestPlanId15 = null;
@ -2081,4 +2082,16 @@ public class TestPlanTests extends BaseTest {
Assertions.assertNotNull(returnId); Assertions.assertNotNull(returnId);
} }
@Test
@Order(302)
public void testArchived() throws Exception {
//计划
this.requestGetWithOk(String.format(URL_TEST_PLAN_ARCHIVED, "wx_test_plan_id_1"));
//计划组
this.requestGet(String.format(URL_TEST_PLAN_ARCHIVED, "wx_test_plan_id_2"));
this.requestGet(String.format(URL_TEST_PLAN_ARCHIVED, "wx_test_plan_id_3"));
this.requestGetWithOk(String.format(URL_TEST_PLAN_ARCHIVED, "wx_test_plan_id_5"));
}
} }

View File

@ -1,3 +1,8 @@
INSERT INTO `test_plan`(`id`, `num`, `project_id`, `group_id`, `module_id`, `name`, `status`, `type`, `tags`, `create_time`, `create_user`, `update_time`, `update_user`, `planned_start_time`, `planned_end_time`, `actual_start_time`, `actual_end_time`, `description`) INSERT INTO `test_plan`(`id`, `num`, `project_id`, `group_id`, `module_id`, `name`, `status`, `type`, `tags`, `create_time`, `create_user`, `update_time`, `update_user`, `planned_start_time`, `planned_end_time`, `actual_start_time`, `actual_end_time`, `description`)
VALUES VALUES
('wx_test_plan_id_1', 5000, 'wx', 'NONE', '1', '测试一下计划', 'PREPARED', 'TEST_PLAN', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'); ('wx_test_plan_id_1', 5000, 'wx', 'NONE', '1', '测试一下计划', 'PREPARED', 'TEST_PLAN', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
('wx_test_plan_id_2', 10000, 'wx', 'NONE', '1', '测试一下组', 'PREPARED', 'GROUP', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
('wx_test_plan_id_3', 15000, 'wx', 'NONE', '1', '测试一下组2', 'PREPARED', 'GROUP', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
('wx_test_plan_id_4', 20000, 'wx', 'wx_test_plan_id_3', '1', '测试一下计划2', 'PREPARED', 'TEST_PLAN', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
('wx_test_plan_id_5', 25000, 'wx', 'NONE', '1', '测试一下组3', 'PREPARED', 'GROUP', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
('wx_test_plan_id_6', 30000, 'wx', 'wx_test_plan_id_5', '1', '测试组3下计划', 'COMPLETED', 'TEST_PLAN', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11');