diff --git a/backend/framework/sdk/src/main/resources/i18n/plan.properties b/backend/framework/sdk/src/main/resources/i18n/plan.properties index fd56a7635c..2d3495003f 100644 --- a/backend/framework/sdk/src/main/resources/i18n/plan.properties +++ b/backend/framework/sdk/src/main/resources/i18n/plan.properties @@ -126,4 +126,5 @@ test_plan.mind.strip=条 test_plan.mind.case_count=用例数 test_plan.mind.environment=环境 test_plan.mind.test_resource_pool=资源池 +test_plan.mind.collection_name_repeat=测试集名称重复 diff --git a/backend/framework/sdk/src/main/resources/i18n/plan_en_US.properties b/backend/framework/sdk/src/main/resources/i18n/plan_en_US.properties index 1a1174bc77..d80f68b0fc 100644 --- a/backend/framework/sdk/src/main/resources/i18n/plan_en_US.properties +++ b/backend/framework/sdk/src/main/resources/i18n/plan_en_US.properties @@ -128,4 +128,5 @@ test_plan.mind.parallel=Parallel test_plan.mind.strip=Strip test_plan.mind.case_count=Case count test_plan.mind.environment=Environment -test_plan.mind.test_resource_pool=Resource pool \ No newline at end of file +test_plan.mind.test_resource_pool=Resource pool +test_plan.mind.collection_name_repeat=Duplicate test set name diff --git a/backend/framework/sdk/src/main/resources/i18n/plan_zh_CN.properties b/backend/framework/sdk/src/main/resources/i18n/plan_zh_CN.properties index e455d5f849..cfc6f2960d 100644 --- a/backend/framework/sdk/src/main/resources/i18n/plan_zh_CN.properties +++ b/backend/framework/sdk/src/main/resources/i18n/plan_zh_CN.properties @@ -128,4 +128,5 @@ test_plan.mind.parallel=并 test_plan.mind.strip=条 test_plan.mind.case_count=用例数 test_plan.mind.environment=环境 -test_plan.mind.test_resource_pool=资源池 \ No newline at end of file +test_plan.mind.test_resource_pool=资源池 +test_plan.mind.collection_name_repeat=测试集名称重复 diff --git a/backend/framework/sdk/src/main/resources/i18n/plan_zh_TW.properties b/backend/framework/sdk/src/main/resources/i18n/plan_zh_TW.properties index fa673078f1..de5df6b7ff 100644 --- a/backend/framework/sdk/src/main/resources/i18n/plan_zh_TW.properties +++ b/backend/framework/sdk/src/main/resources/i18n/plan_zh_TW.properties @@ -127,4 +127,5 @@ test_plan.mind.parallel=並 test_plan.mind.strip=條 test_plan.mind.case_count=用例數 test_plan.mind.environment=環境 -test_plan.mind.test_resource_pool=資源池 \ No newline at end of file +test_plan.mind.test_resource_pool=資源池 +test_plan.mind.collection_name_repeat=測試集名稱重複 diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanCollectionMinderService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanCollectionMinderService.java index 8d046bfce1..093cfe29c7 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanCollectionMinderService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanCollectionMinderService.java @@ -9,6 +9,7 @@ import io.metersphere.sdk.constants.ApiBatchRunMode; import io.metersphere.sdk.constants.CaseType; import io.metersphere.sdk.constants.CommonConstants; import io.metersphere.sdk.constants.ModuleConstants; +import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.Translator; import io.metersphere.system.dto.sdk.SessionUser; @@ -257,30 +258,60 @@ public class TestPlanCollectionMinderService { private void dealEditList(TestPlanCollectionMinderEditRequest request, String userId, Map> associateMap) { if (CollectionUtils.isNotEmpty(request.getEditList())) { Map> parentMap = getParentMap(request); + Map> childrenMap = getChildrenMap(request); SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); TestPlanCollectionMapper collectionMapper = sqlSession.getMapper(TestPlanCollectionMapper.class); //新增 - dealAddList(request, userId, associateMap, parentMap, collectionMapper); + Map> addTypeNameMap = dealAddList(request, userId, associateMap, parentMap, collectionMapper); //更新 - dealUpdateList(request, userId, associateMap, parentMap, collectionMapper); + Map> updateTypeNameMap = dealUpdateList(request, userId, associateMap, parentMap, collectionMapper); + //检查同一类型名称重复 + checkNameRepeat(updateTypeNameMap, addTypeNameMap, childrenMap); sqlSession.flushStatements(); SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); } } - private void dealUpdateList(TestPlanCollectionMinderEditRequest request, String userId, Map> associateMap, Map> parentMap, TestPlanCollectionMapper collectionMapper) { + private static void checkNameRepeat(Map> updateTypeNameMap, Map> addTypeNameMap, Map> childrenMap) { + updateTypeNameMap.forEach((k, v)->{ + List nameList = addTypeNameMap.get(k); + if (CollectionUtils.isNotEmpty(nameList)) { + List repeatList = v.stream().filter(nameList::contains).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(repeatList)) { + throw new MSException(Translator.get("test_plan.mind.collection_name_repeat")); + } else { + nameList.addAll(v); + addTypeNameMap.put(k, nameList); + } + } else { + addTypeNameMap.put(k,v); + } + }); + childrenMap.forEach((k, v)->{ + List nameList = addTypeNameMap.get(k); + if (CollectionUtils.isNotEmpty(nameList)) { + List list = v.stream().filter(t -> nameList.contains(t.getName())).toList(); + if (CollectionUtils.isNotEmpty(list)) { + throw new MSException(Translator.get("test_plan.mind.collection_name_repeat")); + } + } + }); + } + + private Map> dealUpdateList(TestPlanCollectionMinderEditRequest request, String userId, Map> associateMap, Map> parentMap, TestPlanCollectionMapper collectionMapper) { List updateList = request.getEditList().stream().filter(t -> StringUtils.isNotBlank(t.getId())).toList(); - - + Map>typeNamesMap = new HashMap<>(); if (CollectionUtils.isNotEmpty(updateList)) { //处理删除 deleteCollection(updateList, request.getPlanId()); //处理更新 for (TestPlanCollectionMinderEditDTO testPlanCollectionMinderEditDTO : updateList) { TestPlanCollection testPlanCollection = updateCollection(request, userId, testPlanCollectionMinderEditDTO, parentMap, collectionMapper); + checkChangeDataReapet(typeNamesMap, testPlanCollection); setAssociateMap(testPlanCollectionMinderEditDTO, associateMap, testPlanCollection); } } + return typeNamesMap; } private void deleteCollection(List updateList, String planId) { @@ -294,14 +325,32 @@ public class TestPlanCollectionMinderService { } } - private static void dealAddList(TestPlanCollectionMinderEditRequest request, String userId, Map> associateMap, Map> parentMap, TestPlanCollectionMapper collectionMapper) { + private Map> dealAddList(TestPlanCollectionMinderEditRequest request, String userId, Map> associateMap, Map> parentMap, TestPlanCollectionMapper collectionMapper) { + Map>typeNamesMap = new HashMap<>(); List 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); + checkChangeDataReapet(typeNamesMap, testPlanCollection); setAssociateMap(testPlanCollectionMinderEditDTO, associateMap, testPlanCollection); } } + return typeNamesMap; + } + + private static void checkChangeDataReapet(Map> typeNamesMap, TestPlanCollection testPlanCollection) { + List nameList = typeNamesMap.get(testPlanCollection.getType()); + if (CollectionUtils.isNotEmpty(nameList)) { + if (nameList.contains(testPlanCollection.getName())) { + throw new MSException(Translator.get("test_plan.mind.collection_name_repeat")); + } else { + nameList.add(testPlanCollection.getName()); + typeNamesMap.put(testPlanCollection.getType(), nameList); + } + } else { + nameList = new ArrayList<>(List.of(testPlanCollection.getName())); + typeNamesMap.put(testPlanCollection.getType(), nameList); + } } @NotNull @@ -312,6 +361,14 @@ public class TestPlanCollectionMinderService { return testPlanCollections.stream().collect(Collectors.groupingBy(TestPlanCollection::getType)); } + @NotNull + private Map> getChildrenMap(TestPlanCollectionMinderEditRequest request) { + TestPlanCollectionExample testPlanCollectionExample = new TestPlanCollectionExample(); + testPlanCollectionExample.createCriteria().andTestPlanIdEqualTo(request.getPlanId()).andParentIdNotEqualTo(ModuleConstants.ROOT_NODE_PARENT_ID); + List testPlanCollections = testPlanCollectionMapper.selectByExample(testPlanCollectionExample); + return testPlanCollections.stream().collect(Collectors.groupingBy(TestPlanCollection::getType)); + } + @NotNull private static TestPlanCollection updateCollection(TestPlanCollectionMinderEditRequest request, String userId, TestPlanCollectionMinderEditDTO testPlanCollectionMinderEditDTO, Map> parentMap, TestPlanCollectionMapper collectionMapper) { TestPlanCollection testPlanCollection = new TestPlanCollection(); diff --git a/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanCollectionMinderControllerTests.java b/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanCollectionMinderControllerTests.java index 55abc7ee82..729887df2b 100644 --- a/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanCollectionMinderControllerTests.java +++ b/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanCollectionMinderControllerTests.java @@ -24,6 +24,8 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestMethodOrder(MethodOrderer.OrderAnnotation.class) @AutoConfigureMockMvc @@ -119,10 +121,32 @@ public class TestPlanCollectionMinderControllerTests extends BaseTest { editList = new ArrayList<>(); editList.add(deleteDTO); request.setEditList(editList); - this.requestPostWithOkAndReturn(EDIT_MIND, request); + this.requestPost(EDIT_MIND, request).andExpect(status().is5xxServerError());; testPlanCollectionExample = new TestPlanCollectionExample(); testPlanCollectionExample.createCriteria().andNameEqualTo("新建名称"); testPlanCollections = testPlanCollectionMapper.selectByExample(testPlanCollectionExample); + Assertions.assertFalse(CollectionUtils.isEmpty(testPlanCollections)); + testPlanCollectionMinderEditDTO = new TestPlanCollectionMinderEditDTO(); + testPlanCollectionMinderEditDTO.setId(testPlanCollections.get(0).getId()); + testPlanCollectionMinderEditDTO.setText("hahaha"); + testPlanCollectionMinderEditDTO.setNum(500L); + testPlanCollectionMinderEditDTO.setExecuteMethod("PARALLEL"); + testPlanCollectionMinderEditDTO.setType("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); + editList = new ArrayList<>(); + editList.add(testPlanCollectionMinderEditDTO); + request.setEditList(editList); + this.requestPostWithOkAndReturn(EDIT_MIND, request); + testPlanCollectionExample.createCriteria().andNameEqualTo("新建名称"); + testPlanCollections = testPlanCollectionMapper.selectByExample(testPlanCollectionExample); Assertions.assertTrue(CollectionUtils.isEmpty(testPlanCollections)); }