feat(测试计划): 新增脑图保存接口

This commit is contained in:
guoyuqi 2024-06-11 19:59:02 +08:00 committed by Craftsman
parent 03ff3517b1
commit f46c2a15b5
14 changed files with 400 additions and 20 deletions

View File

@ -82,6 +82,7 @@ test_resource_pool_is_use=正在使用此资源池,无法删除
test_resource_pool_is_valid_fail = 校验不通过,请管理员检查资源池是否配置正常 test_resource_pool_is_valid_fail = 校验不通过,请管理员检查资源池是否配置正常
only_one_k8s=只能添加一个 K8S only_one_k8s=只能添加一个 K8S
test_resource_pool_not_exists=测试资源池不存在 test_resource_pool_not_exists=测试资源池不存在
default_test_resource_pool_is_empty=默认资源池无法删除
test_resource_pool_invalid=当前测试使用的资源池处于禁用状态 test_resource_pool_invalid=当前测试使用的资源池处于禁用状态
selenium_grid_is_null=selenium_grid不能为空 selenium_grid_is_null=selenium_grid不能为空
ip_is_null=ip 地址/域名不能为空 ip_is_null=ip 地址/域名不能为空

View File

@ -83,6 +83,7 @@ test_resource_pool_is_use=This resource pool is in use and cannot be deleted
test_resource_pool_is_valid_fail =The verification fails, please check whether the resource pool configuration is normal test_resource_pool_is_valid_fail =The verification fails, please check whether the resource pool configuration is normal
only_one_k8s=Only one K8S can be added only_one_k8s=Only one K8S can be added
test_resource_pool_not_exists=Test resource pool not exists test_resource_pool_not_exists=Test resource pool not exists
default_test_resource_pool_is_empty=The default resource pool cannot be delete
test_resource_pool_invalid=Test resource pool invalid test_resource_pool_invalid=Test resource pool invalid
selenium_grid_is_null=selenium_grid cannot be null selenium_grid_is_null=selenium_grid cannot be null
ip_is_null=ip address/domain name cannot be null ip_is_null=ip address/domain name cannot be null

View File

@ -82,6 +82,7 @@ test_resource_pool_is_use=正在使用此资源池,无法删除
test_resource_pool_is_valid_fail = 校验不通过,请管理员检查资源池是否配置正常 test_resource_pool_is_valid_fail = 校验不通过,请管理员检查资源池是否配置正常
only_one_k8s=只能添加一个 K8S only_one_k8s=只能添加一个 K8S
test_resource_pool_not_exists=测试资源池不存在 test_resource_pool_not_exists=测试资源池不存在
default_test_resource_pool_is_empty=默认资源池无法删除
test_resource_pool_invalid=当前测试使用的资源池处于禁用状态 test_resource_pool_invalid=当前测试使用的资源池处于禁用状态
selenium_grid_is_null=selenium_grid不能为空 selenium_grid_is_null=selenium_grid不能为空
ip_is_null=ip 地址/域名不能为空 ip_is_null=ip 地址/域名不能为空

View File

@ -84,6 +84,7 @@ test_resource_pool_is_valid_fail =校驗不通過,請管理員檢查資源池
only_one_k8s=只能添加一個 K8S only_one_k8s=只能添加一個 K8S
test_resource_pool_not_exists=測試資源池不存在 test_resource_pool_not_exists=測試資源池不存在
default_test_resource_pool_is_empty=預設資源池無法刪除
test_resource_pool_invalid=當前測試使用的資源池處於禁用狀態 test_resource_pool_invalid=當前測試使用的資源池處於禁用狀態
selenium_grid_is_null=selenium_grid不能為空 selenium_grid_is_null=selenium_grid不能為空
ip_is_null=ip 地址/域名不能為空 ip_is_null=ip 地址/域名不能為空

View File

@ -1,17 +1,18 @@
package io.metersphere.plan.controller; package io.metersphere.plan.controller;
import io.metersphere.plan.dto.TestPlanCollectionMinderTreeDTO; import io.metersphere.plan.dto.TestPlanCollectionMinderTreeDTO;
import io.metersphere.plan.dto.request.TestPlanCollectionMinderEditRequest;
import io.metersphere.plan.service.TestPlanCollectionMinderService; import io.metersphere.plan.service.TestPlanCollectionMinderService;
import io.metersphere.sdk.constants.PermissionConstants; import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.system.security.CheckOwner; import io.metersphere.system.security.CheckOwner;
import io.metersphere.system.utils.SessionUtils;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List; import java.util.List;
@ -31,4 +32,21 @@ public class TestPlanCollectionMinderController {
return testPlanCollectionMinderService.getMindTestPlanCase(planId); return testPlanCollectionMinderService.getMindTestPlanCase(planId);
} }
@PostMapping("/data/edit")
@Operation(summary = "测试规划脑图列表")
@RequiresPermissions(value = {
PermissionConstants.TEST_PLAN_READ,
PermissionConstants.TEST_PLAN_READ_ADD,
PermissionConstants.TEST_PLAN_READ_UPDATE,
PermissionConstants.TEST_PLAN_READ_DELETE,
PermissionConstants.TEST_PLAN_READ_ASSOCIATION,
}, logical = Logical.OR)
@CheckOwner(resourceId = "#request.planId", resourceType = "test_plan")
public void editMindTestPlanCase(@Validated @RequestBody TestPlanCollectionMinderEditRequest request) {
String userId = SessionUtils.getUserId();
testPlanCollectionMinderService.editMindTestPlanCase(request, userId);
}
} }

View File

@ -0,0 +1,26 @@
package io.metersphere.plan.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
* @author guoyuqi
*/
@Data
public class TestPlanCollectionAssociateDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "关联关系的ids", requiredMode = Schema.RequiredMode.REQUIRED)
private List<String> ids;
@Schema(description = "关联关系的type(功能FUNCTIONAL_CASE/接口定义API/接口用例API_CASE/场景SCENARIO_CASE)", requiredMode = Schema.RequiredMode.REQUIRED)
private String associateType;
}

View File

@ -0,0 +1,79 @@
package io.metersphere.plan.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
* @author guoyuqi
*/
@Data
public class TestPlanCollectionMinderEditDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "节点ID(新增的时候前端传UUid更新的时候必填)")
private String id;
@Schema(description = "节点名称")
@NotBlank(message = "{test_plan_collection.name.not_blank}")
private String name;
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{test_plan_collection.num.not_blank}")
private Long num;
@Schema(description = "串并行值(串SERIAL/并PARALLEL)")
@NotBlank(message = "{test_plan_collection.execute_method.not_blank}")
private String executeMethod;
@Schema(description = "测试集类型(功能FUNCTIONAL_CASE/接口用例API_CASE/场景SCENARIO_CASE)", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{test_plan_collection_minder_edit.collection_type.not_blank}")
private String collectionType;
@Schema(description = "是否继承", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "{test_plan_collection.extended.not_blank}")
private Boolean extended;
@Schema(description = "是否使用环境组", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "{test_plan_collection.grouped.not_blank}")
private Boolean grouped;
@Schema(description = "环境ID/环境组ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{test_plan_collection.environment_id.not_blank}")
private String environmentId;
@Schema(description = "测试资源池ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{test_plan_collection.test_resource_pool_id.not_blank}")
private String testResourcePoolId;
@Schema(description = "是否失败重试", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "{test_plan_collection.retry_on_fail.not_blank}")
private Boolean retryOnFail;
@Schema(description = "失败重试类型(步骤:STEP/场景:SCENARIO)", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{test_plan_collection.retry_type.not_blank}")
private String retryType;
@Schema(description = "失败重试次数", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "{test_plan_collection.retry_times.not_blank}")
private Integer retryTimes;
@Schema(description = "失败重试间隔(单位: ms)", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "{test_plan_collection.retry_interval.not_blank}")
private Integer retryInterval;
@Schema(description = "是否失败停止", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "{test_plan_collection.stop_on_fail.not_blank}")
private Boolean stopOnFail;
@Schema(description = "关联关系的数据")
private List<TestPlanCollectionAssociateDTO>associateDTOS;
}

View File

@ -23,7 +23,7 @@ public class TestPlanCollectionMinderTreeNodeDTO {
private int num; private int num;
@Schema(description = "串并行") @Schema(description = "串并行")
private String priority; private int priority;
@Schema(description = "串并行值") @Schema(description = "串并行值")
private String executeMethod; private String executeMethod;

View File

@ -0,0 +1,30 @@
package io.metersphere.plan.dto.request;
import io.metersphere.plan.dto.TestPlanCollectionMinderEditDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = false)
public class TestPlanCollectionMinderEditRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "测试计划id", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{functional_case.project_id.not_blank}")
private String planId;
@Schema(description = "新增/修改的节点集合", requiredMode = Schema.RequiredMode.REQUIRED)
private List<TestPlanCollectionMinderEditDTO> editList;
@Schema(description = "删除的节点集合", requiredMode = Schema.RequiredMode.REQUIRED)
private List<String> deletedIds;
}

View File

@ -485,7 +485,9 @@ public class TestPlanApiCaseService extends TestPlanResourceService implements G
//处理数据 //处理数据
handleApiData(collectionAssociates.get(AssociateCaseType.API), userId, testPlanApiCaseList, planId); handleApiData(collectionAssociates.get(AssociateCaseType.API), userId, testPlanApiCaseList, planId);
handleApiCaseData(collectionAssociates.get(AssociateCaseType.API_CASE), userId, testPlanApiCaseList, planId); handleApiCaseData(collectionAssociates.get(AssociateCaseType.API_CASE), userId, testPlanApiCaseList, planId);
testPlanApiCaseMapper.batchInsert(testPlanApiCaseList); if (CollectionUtils.isNotEmpty(testPlanApiCaseList)) {
testPlanApiCaseMapper.batchInsert(testPlanApiCaseList);
}
} }
private void handleApiCaseData(List<BaseCollectionAssociateRequest> apiCaseList, String userId, List<TestPlanApiCase> testPlanApiCaseList, String planId) { private void handleApiCaseData(List<BaseCollectionAssociateRequest> apiCaseList, String userId, List<TestPlanApiCase> testPlanApiCaseList, String planId) {

View File

@ -1,22 +1,26 @@
package io.metersphere.plan.service; package io.metersphere.plan.service;
import io.metersphere.plan.domain.*; import io.metersphere.plan.domain.*;
import io.metersphere.plan.dto.TestPlanCollectionConfigDTO; import io.metersphere.plan.dto.*;
import io.metersphere.plan.dto.TestPlanCollectionMinderTreeDTO; import io.metersphere.plan.dto.request.BaseCollectionAssociateRequest;
import io.metersphere.plan.dto.TestPlanCollectionMinderTreeNodeDTO; import io.metersphere.plan.dto.request.TestPlanCollectionMinderEditRequest;
import io.metersphere.plan.mapper.ExtTestPlanCollectionMapper; import io.metersphere.plan.mapper.*;
import io.metersphere.plan.mapper.TestPlanApiCaseMapper;
import io.metersphere.plan.mapper.TestPlanApiScenarioMapper;
import io.metersphere.plan.mapper.TestPlanFunctionalCaseMapper;
import io.metersphere.sdk.constants.ApiBatchRunMode; import io.metersphere.sdk.constants.ApiBatchRunMode;
import io.metersphere.sdk.constants.CaseType; import io.metersphere.sdk.constants.CaseType;
import io.metersphere.sdk.constants.ModuleConstants; import io.metersphere.sdk.constants.ModuleConstants;
import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.Translator; import io.metersphere.sdk.util.Translator;
import io.metersphere.system.uid.IDGenerator;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.mybatis.spring.SqlSessionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -39,6 +43,18 @@ public class TestPlanCollectionMinderService {
@Resource @Resource
private TestPlanApiScenarioMapper testPlanApiScenarioMapper; private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
@Resource
private TestPlanService testPlanService;
@Resource
private TestPlanCollectionMapper testPlanCollectionMapper;
@Resource
SqlSessionFactory sqlSessionFactory;
@Autowired
private ApplicationContext applicationContext;
/** /**
* 测试计划-脑图用例列表查询 * 测试计划-脑图用例列表查询
* *
@ -82,11 +98,11 @@ public class TestPlanCollectionMinderService {
private static TestPlanCollectionMinderTreeNodeDTO buildTypeChildData(TestPlanCollection testPlanCollection) { private static TestPlanCollectionMinderTreeNodeDTO buildTypeChildData(TestPlanCollection testPlanCollection) {
TestPlanCollectionMinderTreeNodeDTO typeTreeNodeDTO = new TestPlanCollectionMinderTreeNodeDTO(); TestPlanCollectionMinderTreeNodeDTO typeTreeNodeDTO = new TestPlanCollectionMinderTreeNodeDTO();
BeanUtils.copyBean(typeTreeNodeDTO, testPlanCollection); BeanUtils.copyBean(typeTreeNodeDTO, testPlanCollection);
typeTreeNodeDTO.setText(testPlanCollection.getName()); typeTreeNodeDTO.setText(Translator.get(testPlanCollection.getName(), testPlanCollection.getName()));
if (StringUtils.equalsIgnoreCase(testPlanCollection.getExecuteMethod(), ApiBatchRunMode.PARALLEL.toString())) { if (StringUtils.equalsIgnoreCase(testPlanCollection.getExecuteMethod(), ApiBatchRunMode.PARALLEL.toString())) {
typeTreeNodeDTO.setPriority(Translator.get("test_plan.mind.serial")); typeTreeNodeDTO.setPriority(2);
} else { } else {
typeTreeNodeDTO.setPriority(Translator.get("test_plan.mind.parallel")); typeTreeNodeDTO.setPriority(3);
} }
return typeTreeNodeDTO; return typeTreeNodeDTO;
} }
@ -220,4 +236,115 @@ public class TestPlanCollectionMinderService {
} }
public void editMindTestPlanCase(TestPlanCollectionMinderEditRequest request, String userId) {
//处理删除
if (CollectionUtils.isNotEmpty(request.getDeletedIds())) {
testPlanService.deletePlanCollectionResource(request.getDeletedIds());
}
Map<String, List<BaseCollectionAssociateRequest>> associateMap = new HashMap<>();
//处理新增与更新
dealEditList(request, userId, associateMap);
//处理关联关系
Map<String, TestPlanResourceService> beansOfType = applicationContext.getBeansOfType(TestPlanResourceService.class);
beansOfType.forEach((k, v) -> {
v.associateCollection(request.getPlanId(), associateMap, userId);
});
}
private void dealEditList(TestPlanCollectionMinderEditRequest request, String userId, Map<String, List<BaseCollectionAssociateRequest>> associateMap) {
if (CollectionUtils.isNotEmpty(request.getEditList())) {
Map<String, List<TestPlanCollection>> parentMap = getParentMap(request);
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
TestPlanCollectionMapper collectionMapper = sqlSession.getMapper(TestPlanCollectionMapper.class);
//新增
dealAddList(request, userId, associateMap, parentMap, collectionMapper);
//更新
dealUpdateList(request, userId, associateMap, parentMap, collectionMapper);
sqlSession.flushStatements();
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
}
}
private static void dealUpdateList(TestPlanCollectionMinderEditRequest request, String userId, Map<String, List<BaseCollectionAssociateRequest>> associateMap, Map<String, List<TestPlanCollection>> parentMap, TestPlanCollectionMapper collectionMapper) {
List<TestPlanCollectionMinderEditDTO> updateList = request.getEditList().stream().filter(t -> StringUtils.isNotBlank(t.getId())).toList();
if (CollectionUtils.isNotEmpty(updateList)) {
for (TestPlanCollectionMinderEditDTO testPlanCollectionMinderEditDTO : updateList) {
TestPlanCollection testPlanCollection = updateCollection(request, userId, testPlanCollectionMinderEditDTO, parentMap, collectionMapper);
setAssociateMap(testPlanCollectionMinderEditDTO, associateMap, testPlanCollection);
}
}
}
private static void dealAddList(TestPlanCollectionMinderEditRequest request, String userId, Map<String, List<BaseCollectionAssociateRequest>> associateMap, Map<String, List<TestPlanCollection>> parentMap, TestPlanCollectionMapper collectionMapper) {
List<TestPlanCollectionMinderEditDTO> addList = request.getEditList().stream().filter(t -> StringUtils.isBlank(t.getId())).toList();
if (CollectionUtils.isNotEmpty(addList)) {
for (TestPlanCollectionMinderEditDTO testPlanCollectionMinderEditDTO : addList) {
TestPlanCollection testPlanCollection = addCollection(request, userId, testPlanCollectionMinderEditDTO, parentMap, collectionMapper);
setAssociateMap(testPlanCollectionMinderEditDTO, associateMap, testPlanCollection);
}
}
}
@NotNull
private Map<String, List<TestPlanCollection>> getParentMap(TestPlanCollectionMinderEditRequest request) {
TestPlanCollectionExample testPlanCollectionExample = new TestPlanCollectionExample();
testPlanCollectionExample.createCriteria().andTestPlanIdEqualTo(request.getPlanId()).andParentIdEqualTo(ModuleConstants.ROOT_NODE_PARENT_ID);
List<TestPlanCollection> testPlanCollections = testPlanCollectionMapper.selectByExample(testPlanCollectionExample);
return testPlanCollections.stream().collect(Collectors.groupingBy(TestPlanCollection::getType));
}
@NotNull
private static TestPlanCollection updateCollection(TestPlanCollectionMinderEditRequest request, String userId, TestPlanCollectionMinderEditDTO testPlanCollectionMinderEditDTO, Map<String, List<TestPlanCollection>> parentMap, TestPlanCollectionMapper collectionMapper) {
TestPlanCollection testPlanCollection = new TestPlanCollection();
BeanUtils.copyBean(testPlanCollection, testPlanCollectionMinderEditDTO);
testPlanCollection.setId(testPlanCollectionMinderEditDTO.getId());
testPlanCollection.setTestPlanId(request.getPlanId());
testPlanCollection.setType(testPlanCollectionMinderEditDTO.getCollectionType());
TestPlanCollection parent = parentMap.get(testPlanCollectionMinderEditDTO.getCollectionType()).get(0);
testPlanCollection.setParentId(parent.getId());
testPlanCollection.setCreateUser(userId);
testPlanCollection.setCreateTime(null);
testPlanCollection.setPos(testPlanCollectionMinderEditDTO.getNum());
collectionMapper.updateByPrimaryKeySelective(testPlanCollection);
return testPlanCollection;
}
@NotNull
private static TestPlanCollection addCollection(TestPlanCollectionMinderEditRequest request, String userId, TestPlanCollectionMinderEditDTO testPlanCollectionMinderEditDTO, Map<String, List<TestPlanCollection>> parentMap, TestPlanCollectionMapper collectionMapper) {
TestPlanCollection testPlanCollection = new TestPlanCollection();
BeanUtils.copyBean(testPlanCollection, testPlanCollectionMinderEditDTO);
testPlanCollection.setId(IDGenerator.nextStr());
testPlanCollection.setTestPlanId(request.getPlanId());
testPlanCollection.setType(testPlanCollectionMinderEditDTO.getCollectionType());
TestPlanCollection parent = parentMap.get(testPlanCollectionMinderEditDTO.getCollectionType()).get(0);
testPlanCollection.setParentId(parent.getId());
testPlanCollection.setCreateUser(userId);
testPlanCollection.setCreateTime(System.currentTimeMillis());
testPlanCollection.setPos(testPlanCollectionMinderEditDTO.getNum());
collectionMapper.insert(testPlanCollection);
return testPlanCollection;
}
private static void setAssociateMap(TestPlanCollectionMinderEditDTO testPlanCollectionMinderEditDTO, Map<String, List<BaseCollectionAssociateRequest>> associateMap, TestPlanCollection testPlanCollection) {
List<TestPlanCollectionAssociateDTO> associateDTOS = testPlanCollectionMinderEditDTO.getAssociateDTOS();
for (TestPlanCollectionAssociateDTO associateDTO : associateDTOS) {
String associateType = associateDTO.getAssociateType();
List<BaseCollectionAssociateRequest> baseCollectionAssociateRequests = associateMap.get(associateType);
if (baseCollectionAssociateRequests == null) {
baseCollectionAssociateRequests = new ArrayList<>();
addAssociate(associateDTO, testPlanCollection, baseCollectionAssociateRequests, associateMap, associateType);
} else {
addAssociate(associateDTO, testPlanCollection, baseCollectionAssociateRequests, associateMap, associateType);
}
}
}
private static void addAssociate(TestPlanCollectionAssociateDTO associateDTO, TestPlanCollection testPlanCollection, List<BaseCollectionAssociateRequest> baseCollectionAssociateRequests, Map<String, List<BaseCollectionAssociateRequest>> associateMap, String associateType) {
BaseCollectionAssociateRequest baseCollectionAssociateRequest = new BaseCollectionAssociateRequest();
baseCollectionAssociateRequest.setCollectionId(testPlanCollection.getId());
baseCollectionAssociateRequest.setIds(associateDTO.getIds());
baseCollectionAssociateRequests.add(baseCollectionAssociateRequest);
associateMap.put(associateType, baseCollectionAssociateRequests);
}
} }

View File

@ -662,10 +662,12 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService {
public void associateCollection(String planId, Map<String, List<BaseCollectionAssociateRequest>> collectionAssociates, String userId) { public void associateCollection(String planId, Map<String, List<BaseCollectionAssociateRequest>> collectionAssociates, String userId) {
List<TestPlanFunctionalCase> testPlanFunctionalCaseList = new ArrayList<>(); List<TestPlanFunctionalCase> testPlanFunctionalCaseList = new ArrayList<>();
List<BaseCollectionAssociateRequest> functionalList = collectionAssociates.get(AssociateCaseType.FUNCTIONAL); List<BaseCollectionAssociateRequest> functionalList = collectionAssociates.get(AssociateCaseType.FUNCTIONAL);
functionalList.forEach(functional -> { if (CollectionUtils.isNotEmpty(functionalList)) {
buildTestPlanFunctionalCase(planId, functional, userId, testPlanFunctionalCaseList); functionalList.forEach(functional -> buildTestPlanFunctionalCase(planId, functional, userId, testPlanFunctionalCaseList));
}); }
testPlanFunctionalCaseMapper.batchInsert(testPlanFunctionalCaseList); if (CollectionUtils.isNotEmpty(testPlanFunctionalCaseList)) {
testPlanFunctionalCaseMapper.batchInsert(testPlanFunctionalCaseList);
}
} }
/** /**

View File

@ -1,17 +1,27 @@
package io.metersphere.plan.controller; package io.metersphere.plan.controller;
import io.metersphere.plan.domain.TestPlanCollection;
import io.metersphere.plan.domain.TestPlanCollectionExample;
import io.metersphere.plan.dto.TestPlanCollectionAssociateDTO;
import io.metersphere.plan.dto.TestPlanCollectionMinderEditDTO;
import io.metersphere.plan.dto.TestPlanCollectionMinderTreeDTO; import io.metersphere.plan.dto.TestPlanCollectionMinderTreeDTO;
import io.metersphere.plan.dto.request.TestPlanCollectionMinderEditRequest;
import io.metersphere.plan.mapper.TestPlanCollectionMapper;
import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.JSON;
import io.metersphere.system.base.BaseTest; import io.metersphere.system.base.BaseTest;
import io.metersphere.system.controller.handler.ResultHolder; import io.metersphere.system.controller.handler.ResultHolder;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.junit.jupiter.api.*; import org.junit.jupiter.api.*;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.SqlConfig; import org.springframework.test.context.jdbc.SqlConfig;
import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.MvcResult;
import org.testcontainers.shaded.org.apache.commons.lang3.StringUtils;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List; import java.util.List;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ -21,6 +31,11 @@ public class TestPlanCollectionMinderControllerTests extends BaseTest {
private static final String PLAN_MIND = "/test-plan/mind/data/"; private static final String PLAN_MIND = "/test-plan/mind/data/";
private static final String EDIT_MIND = "/test-plan/mind/data/edit";
@Resource
private TestPlanCollectionMapper testPlanCollectionMapper;
@Test @Test
@Order(1) @Order(1)
@Sql(scripts = {"/dml/init_test_plan_mind.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED)) @Sql(scripts = {"/dml/init_test_plan_mind.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
@ -37,5 +52,76 @@ public class TestPlanCollectionMinderControllerTests extends BaseTest {
Assertions.assertNotNull(testPlanCollectionMinderTreeDTOS); Assertions.assertNotNull(testPlanCollectionMinderTreeDTOS);
} }
@Test
@Order(2)
void editMind() throws Exception {
TestPlanCollectionMinderEditRequest request = new TestPlanCollectionMinderEditRequest();
request.setPlanId("gyq_plan_1");
List<TestPlanCollectionMinderEditDTO> editList = new ArrayList<>();
TestPlanCollectionMinderEditDTO testPlanCollectionMinderEditDTO = new TestPlanCollectionMinderEditDTO();
testPlanCollectionMinderEditDTO.setId("gyq_wxxx_4");
testPlanCollectionMinderEditDTO.setName("更新名称");
testPlanCollectionMinderEditDTO.setNum(500L);
testPlanCollectionMinderEditDTO.setExecuteMethod("PARALLEL");
testPlanCollectionMinderEditDTO.setCollectionType("API");
testPlanCollectionMinderEditDTO.setExtended(false);
testPlanCollectionMinderEditDTO.setGrouped(false);
testPlanCollectionMinderEditDTO.setEnvironmentId("gyq_123");
testPlanCollectionMinderEditDTO.setTestResourcePoolId("gyq_123_pool");
testPlanCollectionMinderEditDTO.setRetryOnFail(true);
testPlanCollectionMinderEditDTO.setRetryType("SCENARIO");
testPlanCollectionMinderEditDTO.setRetryTimes(5);
testPlanCollectionMinderEditDTO.setRetryInterval(1000);
testPlanCollectionMinderEditDTO.setStopOnFail(true);
List<TestPlanCollectionAssociateDTO>associateDTOS = new ArrayList<>();
TestPlanCollectionAssociateDTO testPlanCollectionAssociateDTO = new TestPlanCollectionAssociateDTO();
testPlanCollectionAssociateDTO.setAssociateType("API_CASE");
testPlanCollectionAssociateDTO.setIds(List.of("gyq_plan_api-case-associate-1"));
associateDTOS.add(testPlanCollectionAssociateDTO);
testPlanCollectionMinderEditDTO.setAssociateDTOS(associateDTOS);
editList.add(testPlanCollectionMinderEditDTO);
request.setEditList(editList);
this.requestPostWithOkAndReturn(EDIT_MIND, request);
TestPlanCollection testPlanCollection = testPlanCollectionMapper.selectByPrimaryKey("gyq_wxxx_4");
Assertions.assertTrue(StringUtils.equalsIgnoreCase(testPlanCollection.getName(),"更新名称"));
editList = new ArrayList<>();
testPlanCollectionMinderEditDTO = new TestPlanCollectionMinderEditDTO();
testPlanCollectionMinderEditDTO.setId(null);
testPlanCollectionMinderEditDTO.setName("新建名称");
testPlanCollectionMinderEditDTO.setNum(500L);
testPlanCollectionMinderEditDTO.setExecuteMethod("PARALLEL");
testPlanCollectionMinderEditDTO.setCollectionType("API");
testPlanCollectionMinderEditDTO.setExtended(false);
testPlanCollectionMinderEditDTO.setGrouped(false);
testPlanCollectionMinderEditDTO.setEnvironmentId("gyq_123");
testPlanCollectionMinderEditDTO.setTestResourcePoolId("gyq_123_pool");
testPlanCollectionMinderEditDTO.setRetryOnFail(true);
testPlanCollectionMinderEditDTO.setRetryType("SCENARIO");
testPlanCollectionMinderEditDTO.setRetryTimes(5);
testPlanCollectionMinderEditDTO.setRetryInterval(1000);
testPlanCollectionMinderEditDTO.setStopOnFail(true);
associateDTOS = new ArrayList<>();
testPlanCollectionAssociateDTO = new TestPlanCollectionAssociateDTO();
testPlanCollectionAssociateDTO.setAssociateType("API_CASE");
testPlanCollectionAssociateDTO.setIds(List.of("gyq_plan_api-case-associate-1"));
associateDTOS.add(testPlanCollectionAssociateDTO);
testPlanCollectionMinderEditDTO.setAssociateDTOS(associateDTOS);
editList.add(testPlanCollectionMinderEditDTO);
request.setEditList(editList);
this.requestPostWithOkAndReturn(EDIT_MIND, request);
TestPlanCollectionExample testPlanCollectionExample = new TestPlanCollectionExample();
testPlanCollectionExample.createCriteria().andNameEqualTo("新建名称");
List<TestPlanCollection> testPlanCollections = testPlanCollectionMapper.selectByExample(testPlanCollectionExample);
Assertions.assertTrue(CollectionUtils.isNotEmpty(testPlanCollections));
request.setEditList(new ArrayList<>());
request.setDeletedIds(List.of(testPlanCollections.get(0).getId()));
this.requestPostWithOkAndReturn(EDIT_MIND, request);
testPlanCollectionExample = new TestPlanCollectionExample();
testPlanCollectionExample.createCriteria().andNameEqualTo("新建名称");
testPlanCollections = testPlanCollectionMapper.selectByExample(testPlanCollectionExample);
Assertions.assertTrue(CollectionUtils.isEmpty(testPlanCollections));
}
} }

View File

@ -13,6 +13,12 @@ VALUES ('gyq_plan_project', null, 'organization-associate-case-test', '用例评
INSERT INTO test_plan_api_case(id, test_plan_id, api_case_id, environment_id, last_exec_result, last_exec_report_id, execute_user, create_time, create_user, pos, test_plan_collection_id, last_exec_time) INSERT INTO test_plan_api_case(id, test_plan_id, api_case_id, environment_id, last_exec_result, last_exec_report_id, execute_user, create_time, create_user, pos, test_plan_collection_id, last_exec_time)
VALUES ('gyq_wxxx_1', 'gyq_plan_1', 'wxxx_api_case_1', 'gyq_123', NULL, NULL, 'admin', 1716370415311, 'admin', 2, 'gyq_wxxx_4', 1716370415311); VALUES ('gyq_wxxx_1', 'gyq_plan_1', 'wxxx_api_case_1', 'gyq_123', NULL, NULL, 'admin', 1716370415311, 'admin', 2, 'gyq_wxxx_4', 1716370415311);
INSERT INTO api_test_case(id, name, priority, num, tags, status, last_report_status, last_report_id, pos, project_id, api_definition_id, version_id, environment_id, create_time, create_user, update_time, update_user, delete_time, delete_user, deleted)
VALUES ('gyq_plan_api-case-associate-1','test4938131', 'P0', 10000023131, null, 'Underway', 'PENDING', null, 1, 'gyq_plan_project', 'gyq_plan_api_definition_id_1', '100570499574136985', 'test_associate_env_id', UNIX_TIMESTAMP() * 1000, 'admin', UNIX_TIMESTAMP() * 1000, 'admin', null, null, false);
INSERT INTO api_definition(id, name, protocol, method, path, status, num, tags, pos, project_id, module_id, latest, version_id, ref_id, description, create_time, create_user, update_time, update_user, delete_user, delete_time, deleted)
VALUES ('gyq_plan_api_definition_id_1', 'gyq_associate_api_definition_id_1', 'HTTP', 'POST','api/test','test-api-status', 1000001, null, 1, 'gyq_plan_project' , 'gyq_associate_test_module', true, 'v1.10','gyq_associate_api_definition_id_1', null, UNIX_TIMESTAMP() * 1000,'admin', UNIX_TIMESTAMP() * 1000,'admin', null,null,false);
INSERT INTO `test_plan_functional_case`(id, test_plan_id, functional_case_id, create_time, create_user, execute_user, last_exec_time, last_exec_result, pos, test_plan_collection_id) INSERT INTO `test_plan_functional_case`(id, test_plan_id, functional_case_id, create_time, create_user, execute_user, last_exec_time, last_exec_result, pos, test_plan_collection_id)
VALUES('gyq_functional_case_1', 'gyq_plan_1', 'functional_case_id', 1716797474979, 'admin', 'admin', 1716866691313, 'SUCCESS', 4096, 'gyq_wxxx_5'); VALUES('gyq_functional_case_1', 'gyq_plan_1', 'functional_case_id', 1716797474979, 'admin', 'admin', 1716866691313, 'SUCCESS', 4096, 'gyq_wxxx_5');