feat(用例管理): 查询的脑图结构只到用例节点

This commit is contained in:
guoyuqi 2024-01-24 10:17:04 +08:00 committed by Yuki Guo
parent 3ced8a7c18
commit 7d2376b84e
2 changed files with 10 additions and 169 deletions

View File

@ -4,15 +4,11 @@ import io.metersphere.functional.constants.CaseReviewPassRule;
import io.metersphere.functional.constants.MinderLabel;
import io.metersphere.functional.domain.CaseReview;
import io.metersphere.functional.domain.FunctionalCase;
import io.metersphere.functional.domain.FunctionalCaseBlob;
import io.metersphere.functional.domain.FunctionalCaseBlobExample;
import io.metersphere.functional.dto.*;
import io.metersphere.functional.mapper.CaseReviewMapper;
import io.metersphere.functional.mapper.FunctionalCaseBlobMapper;
import io.metersphere.functional.request.FunctionalCasePageRequest;
import io.metersphere.functional.request.MinderReviewFunctionalCasePageRequest;
import io.metersphere.sdk.constants.ModuleConstants;
import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.dto.sdk.BaseTreeNode;
import jakarta.annotation.Resource;
@ -21,7 +17,6 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -41,8 +36,6 @@ public class FunctionalCaseMinderService {
@Resource
private FunctionalCaseModuleService functionalCaseModuleService;
@Resource
private FunctionalCaseBlobMapper functionalCaseBlobMapper;
@Resource
private CaseReviewFunctionalCaseService caseReviewFunctionalCaseService;
@Resource
private CaseReviewMapper caseReviewMapper;
@ -57,8 +50,6 @@ public class FunctionalCaseMinderService {
public FunctionalMinderTreeDTO getFunctionalCasePage(FunctionalCasePageRequest request, boolean deleted) {
//根据查询条件查询出所有符合的功能用例
List<FunctionalCasePageDTO> functionalCasePage = functionalCaseService.getFunctionalCasePage(request, deleted);
List<String> caseIds = functionalCasePage.stream().map(FunctionalCase::getId).distinct().toList();
Map<String, FunctionalCaseBlob> blobMap = getStringFunctionalCaseBlobMap(caseIds);
//根据功能用例的模块ID查出每个模块id父级直到根节点
List<String> moduleIds = functionalCasePage.stream().map(FunctionalCase::getModuleId).distinct().toList();
Map<String, List<FunctionalCasePageDTO>> moduleCaseMap = functionalCasePage.stream().collect(Collectors.groupingBy(FunctionalCasePageDTO::getModuleId));
@ -69,7 +60,7 @@ public class FunctionalCaseMinderService {
}
//构建返回数据主层级应与模块树层级相同
List<FunctionalMinderTreeDTO> functionalMinderTreeNodeDTOs = new ArrayList<>();
buildCaseTree(baseTreeNodes, moduleCaseMap, functionalMinderTreeNodeDTOs, blobMap);
buildCaseTree(baseTreeNodes, moduleCaseMap, functionalMinderTreeNodeDTOs);
return getRoot(functionalMinderTreeNodeDTOs);
}
@ -89,14 +80,7 @@ public class FunctionalCaseMinderService {
return functionalCaseModuleService.buildTreeAndCountResource(nodeByNodeIds, true, Translator.get("default.module"));
}
private Map<String, FunctionalCaseBlob> getStringFunctionalCaseBlobMap(List<String> caseIds) {
FunctionalCaseBlobExample functionalCaseBlobExample = new FunctionalCaseBlobExample();
functionalCaseBlobExample.createCriteria().andIdIn(caseIds);
List<FunctionalCaseBlob> functionalCaseBlobs = functionalCaseBlobMapper.selectByExampleWithBLOBs(functionalCaseBlobExample);
return functionalCaseBlobs.stream().collect(Collectors.toMap(FunctionalCaseBlob::getId, t -> t));
}
private static void buildCaseTree(List<BaseTreeNode> baseTreeNodes, Map<String, List<FunctionalCasePageDTO>> moduleCaseMap, List<FunctionalMinderTreeDTO> functionalMinderTreeNodeDTOs, Map<String, FunctionalCaseBlob> blobMap) {
private static void buildCaseTree(List<BaseTreeNode> baseTreeNodes, Map<String, List<FunctionalCasePageDTO>> moduleCaseMap, List<FunctionalMinderTreeDTO> functionalMinderTreeNodeDTOs) {
baseTreeNodes.forEach(t -> {
//构建根节点
FunctionalMinderTreeDTO functionalMinderTreeDTO = new FunctionalMinderTreeDTO();
@ -105,9 +89,9 @@ public class FunctionalCaseMinderService {
List<FunctionalMinderTreeDTO> children = new ArrayList<>();
//如果当前节点有用例则用例是他的子节点
buildCaseChild(moduleCaseMap, blobMap, t, children);
buildCaseChild(moduleCaseMap, t, children);
//查询当前节点下的子模块节点
buildModuleChild(moduleCaseMap, blobMap, t, children);
buildModuleChild(moduleCaseMap,t, children);
functionalMinderTreeDTO.setChildren(children);
functionalMinderTreeNodeDTOs.add(functionalMinderTreeDTO);
});
@ -121,7 +105,7 @@ public class FunctionalCaseMinderService {
return functionalMinderTreeNodeDTO;
}
private static void buildCaseChild(Map<String, List<FunctionalCasePageDTO>> moduleCaseMap, Map<String, FunctionalCaseBlob> blobMap, BaseTreeNode t, List<FunctionalMinderTreeDTO> children) {
private static void buildCaseChild(Map<String, List<FunctionalCasePageDTO>> moduleCaseMap, BaseTreeNode t, List<FunctionalMinderTreeDTO> children) {
if (moduleCaseMap.get(t.getId()) != null && CollectionUtils.isNotEmpty(moduleCaseMap.get(t.getId()))) {
List<FunctionalCasePageDTO> functionalCasePageDTOS = moduleCaseMap.get(t.getId());
functionalCasePageDTOS.forEach(functionalCasePageDTO -> {
@ -139,13 +123,12 @@ public class FunctionalCaseMinderService {
functionalMinderTreeNodeChild.setResource(List.of(MinderLabel.CASE.toString()));
functionalMinderTreeChild.setData(functionalMinderTreeNodeChild);
//将用例的blob记为Case的children
setBlobInfo(blobMap, functionalCasePageDTO.getId(), functionalCasePageDTO.getCaseEditType(), functionalMinderTreeChild);
children.add(functionalMinderTreeChild);
});
}
}
private static void buildModuleChild(Map<String, List<FunctionalCasePageDTO>> moduleCaseMap, Map<String, FunctionalCaseBlob> blobMap, BaseTreeNode t, List<FunctionalMinderTreeDTO> children) {
private static void buildModuleChild(Map<String, List<FunctionalCasePageDTO>> moduleCaseMap, BaseTreeNode t, List<FunctionalMinderTreeDTO> children) {
if (CollectionUtils.isNotEmpty(t.getChildren())) {
t.getChildren().forEach(child->{
FunctionalMinderTreeDTO functionalMinderTreeDTOChild = new FunctionalMinderTreeDTO();
@ -153,10 +136,10 @@ public class FunctionalCaseMinderService {
functionalMinderTreeDTOChild.setData(functionalMinderTreeNodeDTOChild);
List<FunctionalMinderTreeDTO> childChildren = new ArrayList<>();
buildCaseChild(moduleCaseMap, blobMap, child, childChildren);
buildCaseChild(moduleCaseMap, child, childChildren);
functionalMinderTreeDTOChild.setChildren(childChildren);
children.add(functionalMinderTreeDTOChild);
buildModuleChild(moduleCaseMap, blobMap, child, childChildren);
buildModuleChild(moduleCaseMap,child, childChildren);
});
}
@ -173,7 +156,6 @@ public class FunctionalCaseMinderService {
CaseReview caseReview = caseReviewMapper.selectByPrimaryKey(request.getReviewId());
List<ReviewFunctionalCaseDTO> page = caseReviewFunctionalCaseService.page(request, deleted, userId);
List<String> caseIds = page.stream().map(ReviewFunctionalCaseDTO::getCaseId).toList();
Map<String, FunctionalCaseBlob> blobMap = getStringFunctionalCaseBlobMap(caseIds);
List<String> moduleIds = page.stream().map(ReviewFunctionalCaseDTO::getModuleId).toList();
List<BaseTreeNode> baseTreeNodes = getBaseTreeNodes(moduleIds);
//判断虚拟节点有无数据
@ -187,7 +169,6 @@ public class FunctionalCaseMinderService {
MinderSearchDTO minderSearchDTO = new MinderSearchDTO();
minderSearchDTO.setBaseTreeNodes(baseTreeNodes);
minderSearchDTO.setModuleCaseMap(moduleCaseMap);
minderSearchDTO.setBlobMap(blobMap);
minderSearchDTO.setCustomFieldMap(caseCustomFiledMap);
minderSearchDTO.setReviewPassRule(caseReview.getReviewPassRule());
minderSearchDTO.setViewFlag(request.isViewFlag());
@ -258,85 +239,8 @@ public class FunctionalCaseMinderService {
}
functionalMinderTreeNodeChild.setResource(List.of(MinderLabel.CASE.toString()));
functionalMinderTreeChild.setData(functionalMinderTreeNodeChild);
setBlobInfo(minderSearchDTO.getBlobMap(), reviewFunctionalCaseDTO.getCaseId(), reviewFunctionalCaseDTO.getCaseEditType(), functionalMinderTreeChild);
children.add(functionalMinderTreeChild);
});
}
}
private static void setBlobInfo(Map<String, FunctionalCaseBlob> blobMap, String caseId, String caseEditType, FunctionalMinderTreeDTO functionalMinderTreeChild) {
//将用例的blob记为Case的children
List<FunctionalMinderTreeDTO> functionalMinderTreeNodeChildChild = new ArrayList<>();
FunctionalCaseBlob functionalCaseBlob = blobMap.get(caseId);
if (functionalCaseBlob != null) {
if (functionalCaseBlob.getPrerequisite() != null) {
FunctionalMinderTreeDTO functionalMinderTreeDTOPre = new FunctionalMinderTreeDTO();
//前置条件
FunctionalMinderTreeNodeDTO functionalMinderTreeNodeChildPre = new FunctionalMinderTreeNodeDTO();
String prerequisite = new String(functionalCaseBlob.getPrerequisite(), StandardCharsets.UTF_8);
functionalMinderTreeNodeChildPre.setText(prerequisite);
functionalMinderTreeNodeChildPre.setResource(List.of(MinderLabel.PREREQUISITE.toString()));
functionalMinderTreeDTOPre.setData(functionalMinderTreeNodeChildPre);
functionalMinderTreeNodeChildChild.add(functionalMinderTreeDTOPre);
}
//步骤描述
if (StringUtils.equalsIgnoreCase(caseEditType, "TEXT")) {
if (functionalCaseBlob.getTextDescription() != null) {
//1.文本描述(一个)
FunctionalMinderTreeDTO functionalMinderTreeDTOText = new FunctionalMinderTreeDTO();
FunctionalMinderTreeNodeDTO functionalMinderTreeNodeChildText = new FunctionalMinderTreeNodeDTO();
String textDescription = new String(functionalCaseBlob.getTextDescription(), StandardCharsets.UTF_8);
functionalMinderTreeNodeChildText.setText(textDescription);
functionalMinderTreeNodeChildText.setResource(List.of(MinderLabel.TEXT_DESCRIPTION.toString()));
functionalMinderTreeDTOText.setData(functionalMinderTreeNodeChildText);
List<FunctionalMinderTreeDTO> functionalMinderTreeNodeChildTextChildren = new ArrayList<>();
FunctionalMinderTreeDTO functionalMinderTreeNodeChildTextChild = new FunctionalMinderTreeDTO();
FunctionalMinderTreeNodeDTO functionalMinderTreeNodeDTOChildTextChild = new FunctionalMinderTreeNodeDTO();
String expectedResult = new String(functionalCaseBlob.getExpectedResult(), StandardCharsets.UTF_8);
functionalMinderTreeNodeDTOChildTextChild.setText(expectedResult);
functionalMinderTreeNodeDTOChildTextChild.setResource(List.of(MinderLabel.EXPECTED_RESULT.toString()));
functionalMinderTreeNodeChildTextChild.setData(functionalMinderTreeNodeDTOChildTextChild);
functionalMinderTreeNodeChildTextChildren.add(functionalMinderTreeNodeChildTextChild);
functionalMinderTreeDTOText.setChildren(functionalMinderTreeNodeChildTextChildren);
}
} else {
if (functionalCaseBlob.getSteps() != null) {
//2.步骤描述(多个)
String steps = new String(functionalCaseBlob.getSteps(), StandardCharsets.UTF_8);
List<FunctionalCaseStepDTO> functionalCaseStepDTOS = JSON.parseArray(steps, FunctionalCaseStepDTO.class);
for (FunctionalCaseStepDTO functionalCaseStepDTO : functionalCaseStepDTOS) {
FunctionalMinderTreeDTO functionalMinderTreeDTOText = new FunctionalMinderTreeDTO();
FunctionalMinderTreeNodeDTO functionalMinderTreeNodeChildStep = new FunctionalMinderTreeNodeDTO();
functionalMinderTreeNodeChildStep.setText(functionalCaseStepDTO.getDesc());
functionalMinderTreeNodeChildStep.setResource(List.of(MinderLabel.TEXT_DESCRIPTION.toString()));
List<FunctionalMinderTreeDTO> functionalMinderTreeNodeChildTextChildren = new ArrayList<>();
FunctionalMinderTreeDTO functionalMinderTreeNodeChildTextChild = new FunctionalMinderTreeDTO();
FunctionalMinderTreeNodeDTO functionalMinderTreeNodeDTOChildTextChild = new FunctionalMinderTreeNodeDTO();
functionalMinderTreeNodeDTOChildTextChild.setText(functionalCaseStepDTO.getResult());
functionalMinderTreeNodeDTOChildTextChild.setResource(List.of(MinderLabel.EXPECTED_RESULT.toString()));
functionalMinderTreeNodeChildTextChild.setData(functionalMinderTreeNodeDTOChildTextChild);
functionalMinderTreeNodeChildTextChildren.add(functionalMinderTreeNodeChildTextChild);
functionalMinderTreeDTOText.setData(functionalMinderTreeNodeChildStep);
functionalMinderTreeDTOText.setChildren(functionalMinderTreeNodeChildTextChildren);
functionalMinderTreeNodeChildChild.add(functionalMinderTreeDTOText);
}
}
}
//备注
if (functionalCaseBlob.getDescription() != null) {
FunctionalMinderTreeDTO functionalMinderTreeDTORemark = new FunctionalMinderTreeDTO();
FunctionalMinderTreeNodeDTO functionalMinderTreeNodeChildRemark = new FunctionalMinderTreeNodeDTO();
String description = new String(functionalCaseBlob.getDescription(), StandardCharsets.UTF_8);
functionalMinderTreeNodeChildRemark.setText(description);
functionalMinderTreeNodeChildRemark.setResource(List.of(MinderLabel.DESCRIPTION.toString()));
functionalMinderTreeDTORemark.setData(functionalMinderTreeNodeChildRemark);
functionalMinderTreeNodeChildChild.add(functionalMinderTreeDTORemark);
}
}
functionalMinderTreeChild.setChildren(functionalMinderTreeNodeChildChild);
}
}

View File

@ -1,15 +1,11 @@
package io.metersphere.functional.controller;
import io.metersphere.functional.domain.FunctionalCaseBlob;
import io.metersphere.functional.dto.FunctionalCaseStepDTO;
import io.metersphere.functional.dto.FunctionalMinderTreeDTO;
import io.metersphere.functional.mapper.FunctionalCaseBlobMapper;
import io.metersphere.functional.request.FunctionalCasePageRequest;
import io.metersphere.functional.request.MinderReviewFunctionalCasePageRequest;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.base.BaseTest;
import io.metersphere.system.controller.handler.ResultHolder;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.*;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
@ -18,9 +14,7 @@ import org.springframework.test.context.jdbc.SqlConfig;
import org.springframework.test.web.servlet.MvcResult;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@ -31,69 +25,12 @@ public class FunctionalCaseMinderControllerTest extends BaseTest {
public static final String FUNCTIONAL_CASE_LIST_URL = "/functional/mind/case/list";
public static final String REViEW_FUNCTIONAL_CASE_LIST_URL = "/functional/mind/case/review/list";
@Resource
private FunctionalCaseBlobMapper functionalCaseBlobMapper;
public void initPartBlob() {
List<FunctionalCaseBlob>blobs = new ArrayList<>();
FunctionalCaseBlob blob = new FunctionalCaseBlob();
blob.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_4");
List<FunctionalCaseStepDTO> stepDTOList = new ArrayList<>();
FunctionalCaseStepDTO functionalCaseStepDTO = new FunctionalCaseStepDTO();
functionalCaseStepDTO.setNum(1);
functionalCaseStepDTO.setDesc("用例4的步骤描述");
functionalCaseStepDTO.setResult("用例4的步骤预期");
stepDTOList.add(functionalCaseStepDTO);
FunctionalCaseStepDTO functionalCaseStepDTOTwo = new FunctionalCaseStepDTO();
functionalCaseStepDTOTwo.setNum(2);
functionalCaseStepDTOTwo.setDesc("用例4的步骤描述2");
functionalCaseStepDTOTwo.setResult("用例4的步骤预期1");
stepDTOList.add(functionalCaseStepDTOTwo);
blob.setSteps(JSON.toJSONString(stepDTOList).getBytes(StandardCharsets.UTF_8));
String prerequisite = "用例4的前置";
blob.setPrerequisite(prerequisite.getBytes(StandardCharsets.UTF_8));
String description = "用例4的备注";
blob.setDescription(description.getBytes(StandardCharsets.UTF_8));
blobs.add(blob);
FunctionalCaseBlob blob5 = new FunctionalCaseBlob();
blob5.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_5");
List<FunctionalCaseStepDTO> stepDTOList5 = new ArrayList<>();
FunctionalCaseStepDTO functionalCaseStepDTO5 = new FunctionalCaseStepDTO();
functionalCaseStepDTO5.setNum(1);
functionalCaseStepDTO5.setDesc("用例5的步骤描述");
functionalCaseStepDTO5.setResult("用例5的步骤预期");
stepDTOList5.add(functionalCaseStepDTO5);
FunctionalCaseStepDTO functionalCaseStepDTOTwo5= new FunctionalCaseStepDTO();
functionalCaseStepDTOTwo5.setNum(2);
functionalCaseStepDTOTwo5.setDesc("用例5的步骤描述2");
functionalCaseStepDTOTwo5.setResult("用例5的步骤预期1");
stepDTOList5.add(functionalCaseStepDTOTwo5);
blob5.setSteps(JSON.toJSONString(stepDTOList5).getBytes(StandardCharsets.UTF_8));
String prerequisite5 = "用例5的前置";
blob5.setPrerequisite(prerequisite5.getBytes(StandardCharsets.UTF_8));
String description5 = "用例5的备注";
blob5.setDescription(description5.getBytes(StandardCharsets.UTF_8));
blobs.add(blob5);
FunctionalCaseBlob blob6 = new FunctionalCaseBlob();
blob6.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6");
String textDescription = "用例6的步骤描述";
blob6.setTextDescription(textDescription.getBytes(StandardCharsets.UTF_8));
String expectedResult = "用例6的步骤预期";
blob6.setExpectedResult(expectedResult.getBytes(StandardCharsets.UTF_8));
String prerequisite6 = "用例6的前置";
blob6.setPrerequisite(prerequisite6.getBytes(StandardCharsets.UTF_8));
String description6 = "用例6的备注";
blob6.setDescription(description6.getBytes(StandardCharsets.UTF_8));
blobs.add(blob6);
functionalCaseBlobMapper.batchInsert(blobs);
}
@Test
@Order(1)
@Sql(scripts = {"/dml/init_file_minder_test.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
public void testGetPageList() throws Exception {
initPartBlob();
FunctionalCasePageRequest request = new FunctionalCasePageRequest();
request.setProjectId("project-case-minder-test");
request.setCurrent(1);
@ -106,8 +43,8 @@ public class FunctionalCaseMinderControllerTest extends BaseTest {
ResultHolder resultHolder = JSON.parseObject(contentAsString, ResultHolder.class);
FunctionalMinderTreeDTO baseTreeNodes = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), FunctionalMinderTreeDTO.class);
Assertions.assertNotNull(baseTreeNodes);
// String jsonString = JSON.toJSONString(baseTreeNodes);
//System.out.println(jsonString);
String jsonString = JSON.toJSONString(baseTreeNodes);
System.out.println(jsonString);
}