From 5e647b2070bddb4284bfc5ecea66a17d4585581d Mon Sep 17 00:00:00 2001 From: WangXu10 Date: Wed, 3 Jul 2024 15:17:41 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=B5=8B=E8=AF=95=E8=AE=A1=E5=88=92):=20?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD=E7=94=A8?= =?UTF-8?q?=E4=BE=8B=E7=9A=84=E5=85=B3=E8=81=94=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapper/ExtFunctionalCaseTestMapper.java | 7 +- .../mapper/ExtFunctionalCaseTestMapper.xml | 39 ++++++++ .../service/FunctionalTestCaseService.java | 5 +- .../dto/TestPlanCollectionAssociateDTO.java | 9 ++ .../plan/service/TestPlanApiCaseService.java | 2 +- .../service/TestPlanApiScenarioService.java | 2 +- .../TestPlanFunctionalCaseService.java | 91 ++++++++++++++++++- .../TestPlanCaseControllerTests.java | 3 + .../dml/init_test_plan_case_relate_bug.sql | 4 +- 9 files changed, 153 insertions(+), 9 deletions(-) diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseTestMapper.java b/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseTestMapper.java index e6158efa51..8bb84a1e38 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseTestMapper.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseTestMapper.java @@ -1,5 +1,7 @@ package io.metersphere.functional.mapper; +import io.metersphere.api.domain.ApiScenario; +import io.metersphere.api.domain.ApiTestCase; import io.metersphere.functional.dto.FunctionalCaseTestDTO; import io.metersphere.functional.dto.FunctionalCaseTestPlanDTO; import io.metersphere.functional.dto.TestPlanCaseExecuteHistoryDTO; @@ -20,6 +22,9 @@ public interface ExtFunctionalCaseTestMapper { List getPlanList(@Param("request") AssociatePlanPageRequest request); - ListgetPlanExecuteHistoryList(@Param("caseId") String caseId, @Param("planId") String planId); + List getPlanExecuteHistoryList(@Param("caseId") String caseId, @Param("planId") String planId); + List selectApiCaseByCaseIds(@Param("caseIds") List caseIds); + + List selectApiScenarioByCaseIds(@Param("caseIds") List caseIds); } diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseTestMapper.xml b/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseTestMapper.xml index 473f26c47c..51cc3c3c96 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseTestMapper.xml +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseTestMapper.xml @@ -205,4 +205,43 @@ + + + + + + \ No newline at end of file diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalTestCaseService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalTestCaseService.java index 97f0138e2d..74bed1e62f 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalTestCaseService.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalTestCaseService.java @@ -23,6 +23,7 @@ import io.metersphere.request.*; import io.metersphere.sdk.util.LogUtils; import io.metersphere.sdk.util.Translator; import io.metersphere.system.dto.sdk.BaseTreeNode; +import io.metersphere.system.uid.IDGenerator; import jakarta.annotation.Resource; import org.apache.commons.collections4.CollectionUtils; import org.apache.ibatis.session.ExecutorType; @@ -134,7 +135,7 @@ public class FunctionalTestCaseService { functionalCaseTest.setSourceId(apiScenario.getId()); functionalCaseTest.setVersionId(apiScenario.getVersionId()); functionalCaseTest.setSourceType(request.getSourceType()); - functionalCaseTest.setId(IdGenerator.random().generateId()); + functionalCaseTest.setId(IDGenerator.nextStr()); functionalCaseTest.setCreateUser(userId); functionalCaseTest.setCreateTime(System.currentTimeMillis()); functionalCaseTest.setUpdateUser(userId); @@ -160,7 +161,7 @@ public class FunctionalTestCaseService { functionalCaseTest.setSourceId(apiTestCase.getId()); functionalCaseTest.setVersionId(apiTestCase.getVersionId()); functionalCaseTest.setSourceType(request.getSourceType()); - functionalCaseTest.setId(IdGenerator.random().generateId()); + functionalCaseTest.setId(IDGenerator.nextStr()); functionalCaseTest.setCreateUser(userId); functionalCaseTest.setCreateTime(System.currentTimeMillis()); functionalCaseTest.setUpdateUser(userId); diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/TestPlanCollectionAssociateDTO.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/TestPlanCollectionAssociateDTO.java index f00b52f5e9..edce978c19 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/TestPlanCollectionAssociateDTO.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/TestPlanCollectionAssociateDTO.java @@ -31,5 +31,14 @@ public class TestPlanCollectionAssociateDTO implements Serializable { @NotBlank(message = "{functional_case.project_id.not_blank}") private String projectId; + @Schema(description = "是否同步添加功能用例的关联用例") + private boolean syncCase = false; + + @Schema(description = "接口计划集id") + private String apiCaseCollectionId; + + @Schema(description = "场景计划集id") + private String apiScenarioCollectionId; + } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseService.java index 9922b30b52..5f6e1d2751 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseService.java @@ -628,7 +628,7 @@ public class TestPlanApiCaseService extends TestPlanResourceService { * @param user * @param testPlanApiCaseList */ - private void buildTestPlanApiCaseDTO(BaseCollectionAssociateRequest apiCase, List apiTestCaseList, TestPlan testPlan, SessionUser user, List testPlanApiCaseList) { + public void buildTestPlanApiCaseDTO(BaseCollectionAssociateRequest apiCase, List apiTestCaseList, TestPlan testPlan, SessionUser user, List testPlanApiCaseList) { AtomicLong nextOrder = new AtomicLong(getNextOrder(apiCase.getCollectionId())); apiTestCaseList.forEach(apiTestCase -> { TestPlanApiCase testPlanApiCase = new TestPlanApiCase(); diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioService.java index 4d53296ecd..75d08818cd 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioService.java @@ -217,7 +217,7 @@ public class TestPlanApiScenarioService extends TestPlanResourceService { * @param user * @param testPlanApiScenarioList */ - private void buildTestPlanApiScenarioDTO(BaseCollectionAssociateRequest apiScenario, List scenarioList, TestPlan testPlan, SessionUser user, List testPlanApiScenarioList) { + public void buildTestPlanApiScenarioDTO(BaseCollectionAssociateRequest apiScenario, List scenarioList, TestPlan testPlan, SessionUser user, List testPlanApiScenarioList) { AtomicLong nextOrder = new AtomicLong(getNextOrder(apiScenario.getCollectionId())); scenarioList.forEach(scenario -> { TestPlanApiScenario testPlanApiScenario = new TestPlanApiScenario(); diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanFunctionalCaseService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanFunctionalCaseService.java index a48faa2f58..044ca7960f 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanFunctionalCaseService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanFunctionalCaseService.java @@ -1,5 +1,8 @@ package io.metersphere.plan.service; +import com.alibaba.excel.util.BooleanUtils; +import io.metersphere.api.domain.ApiScenario; +import io.metersphere.api.domain.ApiTestCase; import io.metersphere.bug.domain.Bug; import io.metersphere.bug.domain.BugRelationCase; import io.metersphere.bug.domain.BugRelationCaseExample; @@ -15,6 +18,7 @@ import io.metersphere.functional.domain.FunctionalCaseModule; import io.metersphere.functional.dto.*; import io.metersphere.functional.mapper.ExtFunctionalCaseMapper; import io.metersphere.functional.mapper.ExtFunctionalCaseModuleMapper; +import io.metersphere.functional.mapper.ExtFunctionalCaseTestMapper; import io.metersphere.functional.mapper.FunctionalCaseMapper; import io.metersphere.functional.service.FunctionalCaseAttachmentService; import io.metersphere.functional.service.FunctionalCaseModuleService; @@ -122,6 +126,16 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService { private TestPlanConfigService testPlanConfigService; @Resource private ExtFunctionalCaseMapper extFunctionalCaseMapper; + @Resource + private TestPlanApiCaseService testPlanApiCaseService; + @Resource + private ExtFunctionalCaseTestMapper extFunctionalCaseTestMapper; + @Resource + private TestPlanApiCaseMapper testPlanApiCaseMapper; + @Resource + private TestPlanApiScenarioService testPlanApiScenarioService; + @Resource + private TestPlanApiScenarioMapper testPlanApiScenarioMapper; @Override public long copyResource(String originalTestPlanId, String newTestPlanId, Map oldCollectionIdToNewCollectionId, String operator, long operatorTime) { @@ -783,15 +797,86 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService { if (selectAllModule) { // 选择了全部模块 List functionalCaseList = extFunctionalCaseMapper.selectAllFunctionalCase(isRepeat, functional.getModules().getProjectId(), testPlan.getId()); - bulidTestPlanFunctionalCaseDTO(functional, functionalCaseList, testPlan, user, testPlanFunctionalCaseList); + buildTestPlanFunctionalCaseDTO(functional, functionalCaseList, testPlan, user, testPlanFunctionalCaseList); + handleSyncCase(functionalCaseList, functional, testPlan, user); } else { AssociateCaseDTO dto = super.getCaseIds(moduleMaps); List functionalCaseList = extFunctionalCaseMapper.selectCaseByModules(isRepeat, functional.getModules().getProjectId(), dto, testPlan.getId()); - bulidTestPlanFunctionalCaseDTO(functional, functionalCaseList, testPlan, user, testPlanFunctionalCaseList); + buildTestPlanFunctionalCaseDTO(functional, functionalCaseList, testPlan, user, testPlanFunctionalCaseList); + handleSyncCase(functionalCaseList, functional, testPlan, user); } } - private void bulidTestPlanFunctionalCaseDTO(BaseCollectionAssociateRequest functional, List functionalCaseList, TestPlan testPlan, SessionUser user, List testPlanFunctionalCaseList) { + + /** + * 处理同步添加功能用例关联的用例 + * + * @param functionalCaseList + * @param functional + * @param testPlan + * @param user + */ + private void handleSyncCase(List functionalCaseList, BaseCollectionAssociateRequest functional, TestPlan testPlan, SessionUser user) { + if (BooleanUtils.isTrue(functional.getModules().isSyncCase())) { + handleApiCaseData(functionalCaseList, functional, testPlan, user); + handleApiScenarioData(functionalCaseList, functional, testPlan, user); + } + } + + /** + * 处理场景用例数据 + * + * @param functionalCaseList + * @param functional + * @param testPlan + * @param user + */ + private void handleApiScenarioData(List functionalCaseList, BaseCollectionAssociateRequest functional, TestPlan testPlan, SessionUser user) { + if (StringUtils.isNotBlank(functional.getModules().getApiScenarioCollectionId()) && checkApiCollection(testPlan, functional.getModules().getApiScenarioCollectionId(), CaseType.SCENARIO_CASE.getKey())) { + List caseIds = functionalCaseList.stream().map(FunctionalCase::getId).toList(); + List scenarioList = extFunctionalCaseTestMapper.selectApiScenarioByCaseIds(caseIds); + List testPlanApiScenarioList = new ArrayList<>(); + testPlanApiScenarioService.buildTestPlanApiScenarioDTO(functional, scenarioList, testPlan, user, testPlanApiScenarioList); + if (CollectionUtils.isNotEmpty(testPlanApiScenarioList)) { + testPlanApiScenarioMapper.batchInsert(testPlanApiScenarioList); + } + } + } + + /** + * 处理接口用例数据 + * + * @param functionalCaseList + * @param functional + * @param testPlan + * @param user + */ + private void handleApiCaseData(List functionalCaseList, BaseCollectionAssociateRequest functional, TestPlan testPlan, SessionUser user) { + if (StringUtils.isNotBlank(functional.getModules().getApiCaseCollectionId()) && checkApiCollection(testPlan, functional.getModules().getApiCaseCollectionId(), CaseType.API_CASE.getKey())) { + List caseIds = functionalCaseList.stream().map(FunctionalCase::getId).toList(); + List apiTestCaseList = extFunctionalCaseTestMapper.selectApiCaseByCaseIds(caseIds); + List testPlanApiCaseList = new ArrayList<>(); + testPlanApiCaseService.buildTestPlanApiCaseDTO(functional, apiTestCaseList, testPlan, user, testPlanApiCaseList); + if (CollectionUtils.isNotEmpty(testPlanApiCaseList)) { + testPlanApiCaseMapper.batchInsert(testPlanApiCaseList); + } + } + } + + /** + * 校验测试集 + * + * @param testPlan + * @param apiCaseCollectionId + * @return + */ + private boolean checkApiCollection(TestPlan testPlan, String apiCaseCollectionId, String type) { + TestPlanCollectionExample collectionExample = new TestPlanCollectionExample(); + collectionExample.createCriteria().andIdEqualTo(apiCaseCollectionId).andTestPlanIdEqualTo(testPlan.getId()).andTypeEqualTo(type); + return testPlanCollectionMapper.countByExample(collectionExample) > 0; + } + + private void buildTestPlanFunctionalCaseDTO(BaseCollectionAssociateRequest functional, List functionalCaseList, TestPlan testPlan, SessionUser user, List testPlanFunctionalCaseList) { AtomicLong nextOrder = new AtomicLong(getNextOrder(functional.getCollectionId())); functionalCaseList.forEach(functionalCase -> { TestPlanFunctionalCase testPlanFunctionalCase = new TestPlanFunctionalCase(); diff --git a/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanCaseControllerTests.java b/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanCaseControllerTests.java index a26c78c89d..de2b3ea2a8 100644 --- a/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanCaseControllerTests.java +++ b/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanCaseControllerTests.java @@ -389,6 +389,9 @@ public class TestPlanCaseControllerTests extends BaseTest { associateDTO.setAssociateType(AssociateCaseType.FUNCTIONAL); associateDTO.setProjectId("123"); associateDTO.setModuleMaps(buildModuleMap()); + associateDTO.setSyncCase(true); + associateDTO.setApiCaseCollectionId("223"); + associateDTO.setApiScenarioCollectionId("323"); return associateDTO; } diff --git a/backend/services/test-plan/src/test/resources/dml/init_test_plan_case_relate_bug.sql b/backend/services/test-plan/src/test/resources/dml/init_test_plan_case_relate_bug.sql index e2a29d5663..a5c5b9e290 100644 --- a/backend/services/test-plan/src/test/resources/dml/init_test_plan_case_relate_bug.sql +++ b/backend/services/test-plan/src/test/resources/dml/init_test_plan_case_relate_bug.sql @@ -59,7 +59,9 @@ INSERT INTO template (id,name,remark,internal,update_time,create_time,create_use INSERT INTO `test_plan_collection`(`id`, `test_plan_id`, `name`, `type`, `environment_id`, `test_resource_pool_id`, `pos`, `create_user`, `create_time`, `parent_id`) VALUES - ('123', 'plan_1', 'coll_1', 'FUNCTIONAL', 'NONE', 'NONE', 1, 'admin', 1716370415311, '123456'); + ('123', 'plan_1', 'coll_1', 'FUNCTIONAL', 'NONE', 'NONE', 1, 'admin', 1716370415311, '123456'), + ('223', 'plan_1', 'api_coll_1', 'API', 'NONE', 'NONE', 2, 'admin', 1716370415311, '123456'), + ('323', 'plan_1', 'scenario_coll_1', 'SCENARIO', 'NONE', 'NONE', 3, 'admin', 1716370415311, '123456'); INSERT INTO `test_plan_case_execute_history`(`id`, `test_plan_case_id`, `test_plan_id`, `case_id`, `status`, `content`, `steps`, `deleted`, `notifier`, `create_user`, `create_time`) VALUES