fix(接口测试): 场景普通导出时数据补足
--bug=1047996 --user=宋天阳 【场景导入】-导入无引用关系的场景文件,CASE类型步骤的参数丢失 https://www.tapd.cn/55049933/s/1597504
This commit is contained in:
parent
e31dc32ec3
commit
be5ce9de72
|
@ -1,7 +1,5 @@
|
|||
package io.metersphere.api.dto.export;
|
||||
|
||||
import io.metersphere.api.constants.ApiScenarioStepRefType;
|
||||
import io.metersphere.api.constants.ApiScenarioStepType;
|
||||
import io.metersphere.api.domain.ApiScenarioCsv;
|
||||
import io.metersphere.api.dto.converter.ApiDefinitionDetail;
|
||||
import io.metersphere.api.dto.definition.ApiTestCaseDTO;
|
||||
|
@ -9,7 +7,6 @@ import io.metersphere.api.dto.scenario.ApiScenarioDetail;
|
|||
import io.metersphere.api.dto.scenario.ApiScenarioStepDTO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
@ -55,20 +52,4 @@ public class MetersphereApiScenarioExportResponse extends ApiScenarioExportRespo
|
|||
public void addExportScenario(ApiScenarioDetail apiScenarioDetail) {
|
||||
exportScenarioList.add(apiScenarioDetail);
|
||||
}
|
||||
|
||||
public void setStepTypeToCustomRequest() {
|
||||
scenarioStepList.forEach(step -> {
|
||||
if (StringUtils.equalsAnyIgnoreCase(step.getStepType(), ApiScenarioStepType.API.name(), ApiScenarioStepType.API_CASE.name())) {
|
||||
step.setStepType(ApiScenarioStepType.CUSTOM_REQUEST.name());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setRefTypeToCopy() {
|
||||
scenarioStepList.forEach(step -> {
|
||||
if (StringUtils.equalsAnyIgnoreCase(step.getStepType(), ApiScenarioStepType.API.name(), ApiScenarioStepType.API_SCENARIO.name(), ApiScenarioStepType.API_CASE.name())) {
|
||||
step.setRefType(ApiScenarioStepRefType.COPY.name());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.api.service;
|
||||
|
||||
import io.metersphere.api.constants.ApiDefinitionStatus;
|
||||
import io.metersphere.api.constants.ApiScenarioStepRefType;
|
||||
import io.metersphere.api.constants.ApiScenarioStepType;
|
||||
import io.metersphere.api.domain.*;
|
||||
import io.metersphere.api.dto.ApiFile;
|
||||
|
@ -179,7 +180,7 @@ public class ApiScenarioDataTransferService {
|
|||
}
|
||||
//解析
|
||||
ApiScenarioPreImportAnalysisResult preImportAnalysisResult = this.importAnalysis(
|
||||
parseResult, request.getOperator(), request.getProjectId(), request.getModuleId(), apiScenarioModuleService.getTree(request.getProjectId()));
|
||||
parseResult, request.getOperator(), request.getProjectId(), request.getModuleId(), apiScenarioModuleService.getImportTreeNodeList(request.getProjectId()));
|
||||
//存储
|
||||
this.save(preImportAnalysisResult, request.getProjectId(), request.getOperator(), request.isCoverData());
|
||||
}
|
||||
|
@ -938,7 +939,7 @@ public class ApiScenarioDataTransferService {
|
|||
{
|
||||
for (Map.Entry<String, List<ApiScenarioImportDetail>> entry : projectScenarioMap.entrySet()) {
|
||||
String targetProjectId = entry.getKey();
|
||||
List<BaseTreeNode> apiScenarioModules = apiScenarioModuleService.getTree(targetProjectId);
|
||||
List<BaseTreeNode> apiScenarioModules = apiScenarioModuleService.getImportTreeNodeList(targetProjectId);
|
||||
|
||||
Map<String, String> moduleIdPathMap = apiScenarioModules.stream().collect(Collectors.toMap(BaseTreeNode::getId, BaseTreeNode::getPath));
|
||||
Map<String, BaseTreeNode> modulePathMap = apiScenarioModules.stream().collect(Collectors.toMap(BaseTreeNode::getPath, k -> k, (k1, k2) -> k1));
|
||||
|
@ -1020,7 +1021,7 @@ public class ApiScenarioDataTransferService {
|
|||
if (CollectionUtils.isEmpty(ids)) {
|
||||
return null;
|
||||
}
|
||||
Map<String, String> moduleMap = this.apiScenarioModuleService.getTree(request.getProjectId()).stream().collect(Collectors.toMap(BaseTreeNode::getId, BaseTreeNode::getPath));
|
||||
Map<String, String> moduleMap = this.apiScenarioModuleService.getImportTreeNodeList(request.getProjectId()).stream().collect(Collectors.toMap(BaseTreeNode::getId, BaseTreeNode::getPath));
|
||||
|
||||
String fileFolder = tmpDir.getPath() + File.separatorChar + request.getFileId();
|
||||
AtomicInteger fileIndex = new AtomicInteger(1);
|
||||
|
@ -1150,9 +1151,47 @@ public class ApiScenarioDataTransferService {
|
|||
}
|
||||
|
||||
} else {
|
||||
|
||||
// 普通导出,所有的引用都改为复制,并且Api、ApiCase改为CUSTOM_REQUEST
|
||||
response.setRefTypeToCopy();
|
||||
response.setStepTypeToCustomRequest();
|
||||
Map<String, String> stepApiDefinitionMap = new HashMap<>();
|
||||
Map<String, String> stepApiCaseMap = new HashMap<>();
|
||||
response.getScenarioStepList().forEach(step -> {
|
||||
if (StringUtils.equalsAnyIgnoreCase(step.getStepType(), ApiScenarioStepType.API.name(), ApiScenarioStepType.API_SCENARIO.name(), ApiScenarioStepType.API_CASE.name())) {
|
||||
// 引用的api、case转换为自定义步骤时,要对应的api、case也一并导出
|
||||
if (!response.getScenarioStepBlobMap().containsKey(step.getId())) {
|
||||
if (StringUtils.equalsIgnoreCase(step.getStepType(), ApiScenarioStepType.API.name())) {
|
||||
stepApiDefinitionMap.put(step.getId(), step.getResourceId());
|
||||
} else if (StringUtils.equalsIgnoreCase(step.getStepType(), ApiScenarioStepType.API_CASE.name())) {
|
||||
stepApiCaseMap.put(step.getId(), step.getResourceId());
|
||||
}
|
||||
}
|
||||
step.setRefType(ApiScenarioStepRefType.COPY.name());
|
||||
step.setStepType(ApiScenarioStepType.CUSTOM_REQUEST.name());
|
||||
}
|
||||
});
|
||||
Map<String, String> appendBlobMap = new HashMap<>();
|
||||
if (MapUtils.isNotEmpty(stepApiDefinitionMap)) {
|
||||
List<ApiDefinitionWithBlob> apiDefinitionWithBlobs = extApiDefinitionMapper.selectApiDefinitionWithBlob(new ArrayList<>(stepApiDefinitionMap.values()));
|
||||
Map<String, ApiDefinitionWithBlob> idMap = apiDefinitionWithBlobs.stream().collect(Collectors.toMap(ApiDefinitionWithBlob::getId, Function.identity()));
|
||||
stepApiDefinitionMap.forEach((stepId, apiId) -> {
|
||||
ApiDefinitionWithBlob api = idMap.get(apiId);
|
||||
if (api != null) {
|
||||
appendBlobMap.put(stepId, new String(api.getRequest(), StandardCharsets.UTF_8));
|
||||
}
|
||||
});
|
||||
}
|
||||
if (MapUtils.isNotEmpty(stepApiCaseMap)) {
|
||||
List<ApiTestCaseWithBlob> apiTestCaseList = extApiTestCaseMapper.selectAllDetailByIds(new ArrayList<>(stepApiCaseMap.values()));
|
||||
Map<String, ApiTestCaseWithBlob> idMap = apiTestCaseList.stream().collect(Collectors.toMap(ApiTestCaseWithBlob::getId, Function.identity()));
|
||||
stepApiCaseMap.forEach((stepId, apiCaseId) -> {
|
||||
ApiTestCaseWithBlob apiTestCase = idMap.get(apiCaseId);
|
||||
if (apiTestCase != null) {
|
||||
appendBlobMap.put(stepId, new String(apiTestCase.getRequest(), StandardCharsets.UTF_8));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
response.getScenarioStepBlobMap().putAll(appendBlobMap);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -65,12 +66,36 @@ public class ApiScenarioModuleService extends ModuleTreeService {
|
|||
return super.buildTreeAndCountResource(fileModuleList, true, Translator.get(UNPLANNED_SCENARIO));
|
||||
}
|
||||
|
||||
public List<BaseTreeNode> getTree(String projectId) {
|
||||
public List<BaseTreeNode> getImportTreeNodeList(String projectId) {
|
||||
|
||||
//接口的树结构是 模块:子模块+接口 接口为非delete状态的
|
||||
List<BaseTreeNode> fileModuleList = extApiScenarioModuleMapper.selectBaseByRequest(new ApiScenarioModuleRequest() {{
|
||||
List<BaseTreeNode> traverseList = extApiScenarioModuleMapper.selectBaseByRequest(new ApiScenarioModuleRequest() {{
|
||||
this.setProjectId(projectId);
|
||||
}});
|
||||
return super.buildTreeAndCountResource(fileModuleList, true, Translator.get(UNPLANNED_SCENARIO));
|
||||
|
||||
List<BaseTreeNode> baseTreeNodeList = new ArrayList<>();
|
||||
BaseTreeNode defaultNode = new BaseTreeNode(ModuleConstants.DEFAULT_NODE_ID, Translator.get(UNPLANNED_SCENARIO), ModuleConstants.NODE_TYPE_DEFAULT, ModuleConstants.ROOT_NODE_PARENT_ID);
|
||||
defaultNode.setPath(StringUtils.join("/", defaultNode.getName()));
|
||||
baseTreeNodeList.add(defaultNode);
|
||||
int lastSize = 0;
|
||||
Map<String, BaseTreeNode> baseTreeNodeMap = new HashMap<>();
|
||||
while (CollectionUtils.isNotEmpty(traverseList) && traverseList.size() != lastSize) {
|
||||
lastSize = traverseList.size();
|
||||
List<BaseTreeNode> notMatchedList = new ArrayList<>();
|
||||
for (BaseTreeNode treeNode : traverseList) {
|
||||
if (!baseTreeNodeMap.containsKey(treeNode.getParentId()) && !StringUtils.equalsIgnoreCase(treeNode.getParentId(), ModuleConstants.ROOT_NODE_PARENT_ID)) {
|
||||
notMatchedList.add(treeNode);
|
||||
continue;
|
||||
}
|
||||
BaseTreeNode node = new BaseTreeNode(treeNode.getId(), treeNode.getName(), treeNode.getType(), treeNode.getParentId());
|
||||
node.genModulePath(baseTreeNodeMap.get(treeNode.getParentId()));
|
||||
baseTreeNodeMap.put(treeNode.getId(), node);
|
||||
|
||||
baseTreeNodeList.add(node);
|
||||
}
|
||||
traverseList = notMatchedList;
|
||||
}
|
||||
return baseTreeNodeList;
|
||||
}
|
||||
|
||||
public List<BaseTreeNode> getTreeOnlyIdsAndResourceCount(ApiScenarioModuleRequest request, List<ModuleCountDTO> moduleCountDTOList) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package io.metersphere.api.controller;
|
||||
|
||||
import io.metersphere.api.dto.definition.ApiDefinitionBatchExportRequest;
|
||||
import io.metersphere.api.dto.definition.ApiScenarioBatchExportRequest;
|
||||
import io.metersphere.api.dto.export.MetersphereApiScenarioExportResponse;
|
||||
import io.metersphere.api.dto.scenario.ApiScenarioImportRequest;
|
||||
import io.metersphere.api.utils.ApiDataUtils;
|
||||
|
@ -34,6 +34,7 @@ import org.springframework.util.MultiValueMap;
|
|||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
|
@ -62,11 +63,6 @@ public class ApiScenarioControllerImportAndExportTests extends BaseTest {
|
|||
initProject.setEnable(true);
|
||||
initProject.setUserIds(List.of("admin"));
|
||||
project = commonProjectService.add(initProject, "admin", "/organization-project/add", OperationLogModule.SETTING_ORGANIZATION_PROJECT);
|
||||
// ArrayList<String> moduleList = new ArrayList<>(List.of("workstation", "testPlan", "bugManagement", "caseManagement", "apiTest", "uiTest", "loadTest"));
|
||||
// Project updateProject = new Project();
|
||||
// updateProject.setId(importProject.getId());
|
||||
// updateProject.setModuleSetting(JSON.toJSONString(moduleList));
|
||||
// projectMapper.updateByPrimaryKeySelective(updateProject);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,13 +97,17 @@ public class ApiScenarioControllerImportAndExportTests extends BaseTest {
|
|||
public void testExport() throws Exception {
|
||||
MsFileUtils.deleteDir("/tmp/api-scenario-export/");
|
||||
|
||||
ApiDefinitionBatchExportRequest exportRequest = new ApiDefinitionBatchExportRequest();
|
||||
List<Boolean> exportAllRelatedData = new ArrayList<>() {{
|
||||
this.add(true);
|
||||
this.add(false);
|
||||
}};
|
||||
for (Boolean isAllRelatedData : exportAllRelatedData) {
|
||||
ApiScenarioBatchExportRequest exportRequest = new ApiScenarioBatchExportRequest();
|
||||
String fileId = IDGenerator.nextStr();
|
||||
exportRequest.setProjectId(project.getId());
|
||||
exportRequest.setFileId(fileId);
|
||||
exportRequest.setSelectAll(true);
|
||||
exportRequest.setExportApiCase(true);
|
||||
exportRequest.setExportApiMock(true);
|
||||
exportRequest.setExportAllRelatedData(isAllRelatedData);
|
||||
MvcResult mvcResult = this.requestPostWithOkAndReturn(URL_POST_EXPORT + "metersphere", exportRequest);
|
||||
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
|
||||
|
@ -143,6 +143,7 @@ public class ApiScenarioControllerImportAndExportTests extends BaseTest {
|
|||
|
||||
MsFileUtils.deleteDir("/tmp/api-scenario-export/");
|
||||
}
|
||||
}
|
||||
|
||||
private MvcResult download(String projectId, String fileId) throws Exception {
|
||||
return mockMvc.perform(MockMvcRequestBuilders.get("/api/scenario/download/file/" + projectId + "/" + fileId)
|
||||
|
|
Loading…
Reference in New Issue