feat(接口管理): 新增场景导入系统参数模块多选关联接口

This commit is contained in:
guoyuqi 2024-10-09 18:17:32 +08:00 committed by Craftsman
parent c220f08010
commit c15a5881c2
10 changed files with 369 additions and 38 deletions

View File

@ -0,0 +1,35 @@
package io.metersphere.api.controller.scenario;
import io.metersphere.api.dto.scenario.ApiScenarioSelectAssociateDTO;
import io.metersphere.api.dto.scenario.ApiScenarioStepDTO;
import io.metersphere.api.service.scenario.ApiScenarioSelectAssociateService;
import io.metersphere.sdk.constants.PermissionConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping(value = "/api/scenario/associate")
@Tag(name = "接口测试-接口场景管理-场景导入系统参数")
public class ApiScenarioSelectAssociateController {
@Resource
private ApiScenarioSelectAssociateService apiScenarioSelectAssociateService;
@PostMapping("/all")
@Operation(summary = "接口场景管理-场景导入系统参数")
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_UPDATE)
public List<ApiScenarioStepDTO> getSelectDto(@Validated @RequestBody Map<String, ApiScenarioSelectAssociateDTO> requestMap) {
return apiScenarioSelectAssociateService.getSelectDto(requestMap);
}
}

View File

@ -1,5 +1,7 @@
package io.metersphere.api.dto.scenario; package io.metersphere.api.dto.scenario;
import io.metersphere.api.constants.ApiScenarioStepRefType;
import io.metersphere.sdk.valid.EnumValue;
import io.metersphere.system.dto.ModuleSelectDTO; import io.metersphere.system.dto.ModuleSelectDTO;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
@ -29,6 +31,11 @@ public class ApiScenarioSelectAssociateDTO implements Serializable {
@Schema(description = "模块下的id集合属性", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "模块下的id集合属性", requiredMode = Schema.RequiredMode.REQUIRED)
private Map<String, ModuleSelectDTO> moduleMaps; private Map<String, ModuleSelectDTO> moduleMaps;
@Schema(description = "关联类型 COPY:复制 REF:引用")
@EnumValue(enumClass = ApiScenarioStepRefType.class)
@NotBlank
private String refType;
@Schema(description = "关联关系的type(接口定义API/接口用例API_CASE/场景API_SCENARIO)", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "关联关系的type(接口定义API/接口用例API_CASE/场景API_SCENARIO)", requiredMode = Schema.RequiredMode.REQUIRED)
private String associateType; private String associateType;

View File

@ -20,6 +20,7 @@ import java.util.List;
public interface ExtApiDefinitionMapper { public interface ExtApiDefinitionMapper {
void deleteApiToGc(@Param("ids") List<String> ids, @Param("userId") String userId, @Param("time") long time); void deleteApiToGc(@Param("ids") List<String> ids, @Param("userId") String userId, @Param("time") long time);
@BaseConditionFilter @BaseConditionFilter
List<ApiDefinitionDTO> list(@Param("request") ApiDefinitionPageRequest request); List<ApiDefinitionDTO> list(@Param("request") ApiDefinitionPageRequest request);
@ -99,5 +100,5 @@ public interface ExtApiDefinitionMapper {
List<ApiDefinition> getListBySelectModules(@Param("projectId") String projectId, @Param("moduleIds") List<String> moduleIds, @Param("protocols") List<String> protocols); List<ApiDefinition> getListBySelectModules(@Param("projectId") String projectId, @Param("moduleIds") List<String> moduleIds, @Param("protocols") List<String> protocols);
List<ApiDefinition> getListBySelectIds(@Param("ids") List<String> ids, @Param("protocols") List<String> protocols); List<ApiDefinition> getListBySelectIds(@Param("projectId") String projectId, @Param("ids") List<String> ids, @Param("protocols") List<String> protocols);
} }

View File

@ -680,12 +680,14 @@
</foreach> </foreach>
</select> </select>
<select id="selectAllCase" resultType="io.metersphere.api.domain.ApiDefinition"> <select id="selectAllApi" resultType="io.metersphere.api.domain.ApiDefinition">
select select
api_definition.id, api_definition.id,
api_definition.name, api_definition.name,
api_definition.method, api_definition.method,
api_definition.num, api_definition.num,
api_definition.project_id,
api_definition.version_id,
api_definition.pos api_definition.pos
from api_definition from api_definition
where api_definition.deleted = false where api_definition.deleted = false
@ -705,6 +707,8 @@
api_definition.name, api_definition.name,
api_definition.method, api_definition.method,
api_definition.num, api_definition.num,
api_definition.project_id,
api_definition.version_id,
api_definition.pos api_definition.pos
from api_definition from api_definition
where api_definition.deleted = false where api_definition.deleted = false
@ -727,6 +731,8 @@
api_definition.name, api_definition.name,
api_definition.method, api_definition.method,
api_definition.num, api_definition.num,
api_definition.project_id,
api_definition.version_id,
api_definition.pos api_definition.pos
from api_definition from api_definition
where api_definition.deleted = false where api_definition.deleted = false

View File

@ -89,6 +89,7 @@ public interface ExtApiScenarioMapper {
List<ApiScenario> selectAllCase(@Param("isRepeat") boolean isRepeat, @Param("projectId") String projectId, @Param("testPlanId") String testPlanId); List<ApiScenario> selectAllCase(@Param("isRepeat") boolean isRepeat, @Param("projectId") String projectId, @Param("testPlanId") String testPlanId);
List<ApiScenario> selectAllCaseExcludeSelf(@Param("projectId") String projectId);
List<ApiScenario> getListBySelectModules(@Param("isRepeat") boolean isRepeat, @Param("projectId") String projectId, @Param("moduleIds") List<String> moduleIds, @Param("testPlanId") String testPlanId); List<ApiScenario> getListBySelectModules(@Param("isRepeat") boolean isRepeat, @Param("projectId") String projectId, @Param("moduleIds") List<String> moduleIds, @Param("testPlanId") String testPlanId);

View File

@ -698,6 +698,19 @@
order by api_scenario.pos asc order by api_scenario.pos asc
</select> </select>
<select id="selectAllCaseExcludeSelf" resultType="io.metersphere.api.domain.ApiScenario">
select
api_scenario.id,
api_scenario.name,
api_scenario.project_id,
api_scenario.num,
api_scenario.version_id
from api_scenario
where api_scenario.deleted = false
and api_scenario.project_id = #{projectId}
order by api_scenario.pos asc
</select>
<select id="getListBySelectModules" resultType="io.metersphere.api.domain.ApiScenario"> <select id="getListBySelectModules" resultType="io.metersphere.api.domain.ApiScenario">
select select
api_scenario.id, api_scenario.id,

View File

@ -765,7 +765,12 @@
select select
api_test_case.id, api_test_case.id,
api_test_case.create_user, api_test_case.create_user,
api_test_case.environment_id api_test_case.environment_id,
api_test_case.name,
api_test_case.project_id,
api_test_case.num,
api_test_case.version_id,
api_test_case.pos
from api_test_case from api_test_case
INNER JOIN api_definition ON api_test_case.api_definition_id = api_definition.id INNER JOIN api_definition ON api_test_case.api_definition_id = api_definition.id
where api_test_case.deleted = false where api_test_case.deleted = false
@ -790,6 +795,10 @@
api_test_case.id, api_test_case.id,
api_test_case.create_user, api_test_case.create_user,
api_test_case.environment_id, api_test_case.environment_id,
api_test_case.name,
api_test_case.project_id,
api_test_case.num,
api_test_case.version_id,
api_test_case.pos api_test_case.pos
from api_test_case from api_test_case
inner join api_definition on api_definition.id = api_test_case.api_definition_id inner join api_definition on api_definition.id = api_test_case.api_definition_id
@ -817,6 +826,10 @@
api_test_case.id, api_test_case.id,
api_test_case.create_user, api_test_case.create_user,
api_test_case.environment_id, api_test_case.environment_id,
api_test_case.name,
api_test_case.project_id,
api_test_case.num,
api_test_case.version_id,
api_test_case.pos api_test_case.pos
from api_test_case from api_test_case
inner join api_definition on api_definition.id = api_test_case.api_definition_id inner join api_definition on api_definition.id = api_test_case.api_definition_id

View File

@ -1,11 +1,28 @@
package io.metersphere.api.service.scenario; package io.metersphere.api.service.scenario;
import io.metersphere.api.constants.ApiScenarioStepType;
import io.metersphere.api.domain.ApiDefinition;
import io.metersphere.api.domain.ApiScenario;
import io.metersphere.api.domain.ApiScenarioCsvStep;
import io.metersphere.api.domain.ApiTestCase;
import io.metersphere.api.dto.scenario.ApiScenarioSelectAssociateDTO;
import io.metersphere.api.dto.scenario.ApiScenarioStepCommonDTO;
import io.metersphere.api.dto.scenario.ApiScenarioStepDTO;
import io.metersphere.api.mapper.ExtApiDefinitionMapper; import io.metersphere.api.mapper.ExtApiDefinitionMapper;
import io.metersphere.api.mapper.ExtApiScenarioMapper; import io.metersphere.api.mapper.ExtApiScenarioMapper;
import io.metersphere.api.mapper.ExtApiScenarioStepMapper;
import io.metersphere.api.mapper.ExtApiTestCaseMapper; import io.metersphere.api.mapper.ExtApiTestCaseMapper;
import io.metersphere.sdk.dto.AssociateCaseDTO;
import io.metersphere.system.dto.ModuleSelectDTO;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
@Service @Service
public class ApiScenarioSelectAssociateService { public class ApiScenarioSelectAssociateService {
@ -15,30 +32,42 @@ public class ApiScenarioSelectAssociateService {
private ExtApiTestCaseMapper extApiTestCaseMapper; private ExtApiTestCaseMapper extApiTestCaseMapper;
@Resource @Resource
private ExtApiDefinitionMapper extApiDefinitionMapper; private ExtApiDefinitionMapper extApiDefinitionMapper;
@Resource
private ApiScenarioService apiScenarioService;
@Resource
private ExtApiScenarioStepMapper extApiScenarioStepMapper;
public static final String MODULE_ALL = "all"; public static final String MODULE_ALL = "all";
/*public void getSelectDto(ApiScenarioSelectAssociateDTO request) { public List<ApiScenarioStepDTO> getSelectDto(Map<String, ApiScenarioSelectAssociateDTO> request) {
List<ApiScenarioStepDTO> steps = new ArrayList<>();
for (String key : request.keySet()) {
switch (key) {
case "SCENARIO":
List<ApiScenarioStepDTO> apiScenarioStepDTOs = handleApiScenarioData(request.get(key));
steps.addAll(apiScenarioStepDTOs);
case "CASE":
List<ApiScenarioStepDTO> apiCaseStepDTOs = handleApiCaseData(request.get(key));
steps.addAll(apiCaseStepDTOs);
default:
List<ApiScenarioStepDTO> apiStepDTOs = handleApiData(request.get(key));
steps.addAll(apiStepDTOs);
}
}
return steps;
}
private List<ApiScenarioStepDTO> handleApiData(ApiScenarioSelectAssociateDTO request) {
List<ApiScenarioStepDTO> steps = new ArrayList<>();
boolean selectAllModule = request.isSelectAllModule(); boolean selectAllModule = request.isSelectAllModule();
Map<String, ModuleSelectDTO> moduleMaps = request.getModuleMaps(); Map<String, ModuleSelectDTO> moduleMaps = request.getModuleMaps();
moduleMaps.remove(MODULE_ALL); moduleMaps.remove(MODULE_ALL);
switch (request.getAssociateType()) {
case "API_SCENARIO":
handleApiScenarioData(selectAllModule, moduleMaps, request);
case "API_CASE":
handleApiCaseData(selectAllModule, moduleMaps, request);
default:
handleApiData(selectAllModule, moduleMaps, request);
}
}
private void handleApiData(boolean selectAllModule, Map<String, ModuleSelectDTO> moduleMaps, ApiScenarioSelectAssociateDTO request) {
if (selectAllModule) { if (selectAllModule) {
// 选择了全部模块 // 选择了全部模块
List<ApiDefinition> apiDefinitionList = extApiDefinitionMapper.selectAllApi(request.getProjectId(), request.getProtocols()); List<ApiDefinition> apiDefinitionList = extApiDefinitionMapper.selectAllApi(request.getProjectId(), request.getProtocols());
getApiSteps(request, apiDefinitionList, steps);
} else { } else {
AssociateCaseDTO dto = getCaseIds(moduleMaps); AssociateCaseDTO dto = getCaseIds(moduleMaps);
List<ApiDefinition> apiDefinitionList = new ArrayList<>(); List<ApiDefinition> apiDefinitionList = new ArrayList<>();
@ -50,27 +79,46 @@ public class ApiScenarioSelectAssociateService {
if (CollectionUtils.isNotEmpty(dto.getSelectIds())) { if (CollectionUtils.isNotEmpty(dto.getSelectIds())) {
CollectionUtils.removeAll(dto.getSelectIds(), apiDefinitionList.stream().map(ApiDefinition::getId).toList()); CollectionUtils.removeAll(dto.getSelectIds(), apiDefinitionList.stream().map(ApiDefinition::getId).toList());
//获取选中的ids数据 //获取选中的ids数据
List<ApiDefinition> selectIdList = extApiDefinitionMapper.getListBySelectIds(dto.getSelectIds(), request.getProtocols()); List<ApiDefinition> selectIdList = extApiDefinitionMapper.getListBySelectIds(request.getProjectId(), dto.getSelectIds(), request.getProtocols());
apiDefinitionList.addAll(selectIdList); apiDefinitionList.addAll(selectIdList);
} }
if (CollectionUtils.isNotEmpty(dto.getExcludeIds())) { if (CollectionUtils.isNotEmpty(dto.getExcludeIds())) {
//排除的ids //排除的ids
List<String> excludeIds = dto.getExcludeIds(); List<String> excludeIds = dto.getExcludeIds();
apiDefinitionList = apiDefinitionList.stream().filter(item -> !excludeIds.contains(item.getId())).toList(); apiDefinitionList = apiDefinitionList.stream().filter(item -> !excludeIds.contains(item.getId())).toList();
} }
if (CollectionUtils.isNotEmpty(apiDefinitionList)) { if (CollectionUtils.isNotEmpty(apiDefinitionList)) {
List<ApiDefinition> list = apiDefinitionList.stream().sorted(Comparator.comparing(ApiDefinition::getPos)).toList(); List<ApiDefinition> list = apiDefinitionList.stream().sorted(Comparator.comparing(ApiDefinition::getPos)).toList();
getApiSteps(request, list, steps);
} }
} }
return steps;
} }
private void handleApiCaseData(boolean selectAllModule, Map<String, ModuleSelectDTO> moduleMaps, ApiScenarioSelectAssociateDTO request) { private static void getApiSteps(ApiScenarioSelectAssociateDTO request, List<ApiDefinition> apiDefinitionList, List<ApiScenarioStepDTO> steps) {
apiDefinitionList.forEach(item -> {
ApiScenarioStepDTO step = new ApiScenarioStepDTO();
step.setStepType(ApiScenarioStepType.API.name());
step.setName(item.getName());
step.setResourceId(item.getId());
step.setRefType(request.getRefType());
step.setProjectId(item.getProjectId());
step.setResourceNum(item.getNum().toString());
step.setVersionId(item.getVersionId());
steps.add(step);
});
}
private List<ApiScenarioStepDTO> handleApiCaseData(ApiScenarioSelectAssociateDTO request) {
List<ApiScenarioStepDTO> steps = new ArrayList<>();
boolean selectAllModule = request.isSelectAllModule();
Map<String, ModuleSelectDTO> moduleMaps = request.getModuleMaps();
moduleMaps.remove(MODULE_ALL);
if (selectAllModule) { if (selectAllModule) {
// 选择了全部模块 // 选择了全部模块
List<ApiTestCase> apiTestCaseList = extApiTestCaseMapper.selectAllApiCase(true, request.getProjectId(), null, request.getProtocols()); List<ApiTestCase> apiTestCaseList = extApiTestCaseMapper.selectAllApiCase(true, request.getProjectId(), null, request.getProtocols());
getCaseSteps(request, apiTestCaseList, steps);
} else { } else {
AssociateCaseDTO dto = getCaseIds(moduleMaps); AssociateCaseDTO dto = getCaseIds(moduleMaps);
List<ApiTestCase> apiTestCaseList = new ArrayList<>(); List<ApiTestCase> apiTestCaseList = new ArrayList<>();
@ -94,15 +142,37 @@ public class ApiScenarioSelectAssociateService {
if (CollectionUtils.isNotEmpty(apiTestCaseList)) { if (CollectionUtils.isNotEmpty(apiTestCaseList)) {
List<ApiTestCase> list = apiTestCaseList.stream().sorted(Comparator.comparing(ApiTestCase::getPos)).toList(); List<ApiTestCase> list = apiTestCaseList.stream().sorted(Comparator.comparing(ApiTestCase::getPos)).toList();
getCaseSteps(request, list, steps);
} }
} }
return steps;
} }
private void handleApiScenarioData(boolean selectAllModule, Map<String, ModuleSelectDTO> moduleMaps, ApiScenarioSelectAssociateDTO request) { private static void getCaseSteps(ApiScenarioSelectAssociateDTO request, List<ApiTestCase> apiTestCaseList, List<ApiScenarioStepDTO> steps) {
apiTestCaseList.forEach(item -> {
ApiScenarioStepDTO step = new ApiScenarioStepDTO();
step.setStepType(ApiScenarioStepType.API_CASE.name());
step.setName(item.getName());
step.setResourceId(item.getId());
step.setRefType(request.getRefType());
step.setProjectId(item.getProjectId());
step.setResourceNum(item.getNum().toString());
step.setVersionId(item.getVersionId());
steps.add(step);
});
}
private List<ApiScenarioStepDTO> handleApiScenarioData(ApiScenarioSelectAssociateDTO request) {
List<ApiScenarioStepDTO> steps = new ArrayList<>();
boolean selectAllModule = request.isSelectAllModule();
Map<String, ModuleSelectDTO> moduleMaps = request.getModuleMaps();
moduleMaps.remove(MODULE_ALL);
if (selectAllModule) { if (selectAllModule) {
// 选择了全部模块 // 选择了全部模块
List<ApiScenario> scenarioList = extApiScenarioMapper.selectAllCase(true, request.getProjectId(), null); List<ApiScenario> scenarioList = extApiScenarioMapper.selectAllCaseExcludeSelf(request.getProjectId());
getScenarioStepDto(request, scenarioList, steps);
} else { } else {
AssociateCaseDTO dto = getCaseIds(moduleMaps); AssociateCaseDTO dto = getCaseIds(moduleMaps);
List<ApiScenario> scenarioList = new ArrayList<>(); List<ApiScenario> scenarioList = new ArrayList<>();
@ -110,31 +180,76 @@ public class ApiScenarioSelectAssociateService {
if (CollectionUtils.isNotEmpty(dto.getModuleIds())) { if (CollectionUtils.isNotEmpty(dto.getModuleIds())) {
scenarioList = extApiScenarioMapper.getListBySelectModules(true, request.getProjectId(), dto.getModuleIds(), null); scenarioList = extApiScenarioMapper.getListBySelectModules(true, request.getProjectId(), dto.getModuleIds(), null);
} }
if (CollectionUtils.isNotEmpty(dto.getSelectIds())) { if (CollectionUtils.isNotEmpty(dto.getSelectIds())) {
CollectionUtils.removeAll(dto.getSelectIds(), scenarioList.stream().map(ApiScenario::getId).toList()); CollectionUtils.removeAll(dto.getSelectIds(), scenarioList.stream().map(ApiScenario::getId).toList());
//获取选中的ids数据 //获取选中的ids数据
List<ApiScenario> selectIdList = extApiScenarioMapper.getListBySelectIds(request.getProjectId(), dto.getSelectIds(), null); List<ApiScenario> selectIdList = extApiScenarioMapper.getListBySelectIds(request.getProjectId(), dto.getSelectIds(), null);
scenarioList.addAll(selectIdList); scenarioList.addAll(selectIdList);
} }
List<String> excludeIds = new ArrayList<>();
excludeIds.add(request.getScenarioId());
if (CollectionUtils.isNotEmpty(dto.getExcludeIds())) { if (CollectionUtils.isNotEmpty(dto.getExcludeIds())) {
//排除的ids //排除的ids
List<String> excludeIds = dto.getExcludeIds(); excludeIds.addAll(dto.getExcludeIds());
excludeIds.add(request.getScenarioId());
scenarioList = scenarioList.stream().filter(item -> !excludeIds.contains(item.getId())).toList(); scenarioList = scenarioList.stream().filter(item -> !excludeIds.contains(item.getId())).toList();
} }
if (CollectionUtils.isNotEmpty(scenarioList)) { if (CollectionUtils.isNotEmpty(scenarioList)) {
List<ApiScenario> list = scenarioList.stream().sorted(Comparator.comparing(ApiScenario::getPos)).toList(); List<ApiScenario> list = scenarioList.stream().sorted(Comparator.comparing(ApiScenario::getPos)).toList();
getScenarioStepDto(request, list, steps);
}
}
return steps;
} }
private void getScenarioStepDto(ApiScenarioSelectAssociateDTO request, List<ApiScenario> scenarioList, List<ApiScenarioStepDTO> steps) {
List<String> ids = scenarioList.stream().map(ApiScenario::getId).toList();
// 获取所有步骤
List<ApiScenarioStepDTO> allSteps = apiScenarioService.getAllStepsByScenarioIds(ids)
.stream()
.distinct() // 这里可能存在多次引用相同场景步骤可能会重复去重
.toList();
// 设置步骤的 csvIds
setStepCsvIds(ids, allSteps);
// 构造 mapkey 为场景IDvalue 为步骤列表
Map<String, List<ApiScenarioStepDTO>> scenarioStepMap = allSteps.stream()
.collect(Collectors.groupingBy(step -> Optional.ofNullable(step.getScenarioId()).orElse(StringUtils.EMPTY)));
// 查询步骤详情
Map<String, String> stepDetailMap = apiScenarioService.getPartialRefStepDetailMap(allSteps);
for (ApiScenario apiScenario : scenarioList) {
List<ApiScenarioStepDTO> apiScenarioStepDTOS = scenarioStepMap.get(apiScenario.getId());
List<ApiScenarioStepDTO> stepList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(apiScenarioStepDTOS)) {
Map<String, List<ApiScenarioStepDTO>> currentScenarioParentStepMap = apiScenarioStepDTOS
.stream()
.collect(Collectors.groupingBy(step -> {
if (StringUtils.equals(step.getParentId(), "NONE")) {
step.setParentId(StringUtils.EMPTY);
}
return Optional.ofNullable(step.getParentId()).orElse(StringUtils.EMPTY);
}));
stepList = apiScenarioService.buildStepTree(currentScenarioParentStepMap.get(StringUtils.EMPTY), currentScenarioParentStepMap, scenarioStepMap, new HashSet<>());
// 设置部分引用的步骤的启用状态
apiScenarioService.setPartialRefStepsEnable(stepList, stepDetailMap);
}
ApiScenarioStepDTO step = new ApiScenarioStepDTO();
step.setStepType(ApiScenarioStepType.API_SCENARIO.name());
step.setName(apiScenario.getName());
step.setResourceId(apiScenario.getId());
step.setRefType(request.getRefType());
step.setProjectId(apiScenario.getProjectId());
step.setResourceNum(apiScenario.getNum().toString());
step.setVersionId(apiScenario.getVersionId());
step.setChildren(stepList);
steps.add(step);
} }
} }
*//**
* 获取关联时的相关id数据
*//*
protected AssociateCaseDTO getCaseIds(Map<String, ModuleSelectDTO> moduleMaps) { protected AssociateCaseDTO getCaseIds(Map<String, ModuleSelectDTO> moduleMaps) {
// 排除的ids // 排除的ids
List<String> excludeIds = moduleMaps.values().stream() List<String> excludeIds = moduleMaps.values().stream()
@ -152,6 +267,27 @@ public class ApiScenarioSelectAssociateService {
.toList(); .toList();
return new AssociateCaseDTO(excludeIds, selectIds, moduleIds); return new AssociateCaseDTO(excludeIds, selectIds, moduleIds);
}*/ }
private void setStepCsvIds(List<String> scenarioIds, List<ApiScenarioStepDTO> allSteps) {
List<String> refScenarioIds = allSteps.stream()
.filter(apiScenarioService::isRefOrPartialScenario)
.map(ApiScenarioStepCommonDTO::getResourceId)
.collect(Collectors.toList());
refScenarioIds.addAll(scenarioIds);
//获取所有步骤的csv的关联关系
List<ApiScenarioCsvStep> csvSteps = extApiScenarioStepMapper.getCsvStepByScenarioIds(refScenarioIds);
// 构造 mapkey 为步骤IDvalue 为csv文件ID列表
Map<String, List<String>> stepsCsvMap = csvSteps.stream()
.collect(Collectors.groupingBy(ApiScenarioCsvStep::getStepId, Collectors.mapping(ApiScenarioCsvStep::getFileId, Collectors.toList())));
//将stepsCsvMap根据步骤id放入到allSteps中
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(allSteps)) {
allSteps.forEach(step -> step.setCsvIds(stepsCsvMap.get(step.getId())));
}
}
} }

View File

@ -1393,6 +1393,9 @@ public class ApiScenarioService extends MoveNodeService {
* 设置部分引用的步骤的启用状态 * 设置部分引用的步骤的启用状态
*/ */
private void setChildPartialRefEnable(List<? extends ApiScenarioStepCommonDTO> steps, PartialRefStepDetail partialRefStepDetail) { private void setChildPartialRefEnable(List<? extends ApiScenarioStepCommonDTO> steps, PartialRefStepDetail partialRefStepDetail) {
if (CollectionUtils.isEmpty(steps)) {
return;
}
for (ApiScenarioStepCommonDTO step : steps) { for (ApiScenarioStepCommonDTO step : steps) {
if (StringUtils.equals(step.getRefType(), ApiScenarioStepRefType.REF.name())) { if (StringUtils.equals(step.getRefType(), ApiScenarioStepRefType.REF.name())) {
// 引用的启用不修改 // 引用的启用不修改
@ -1429,7 +1432,8 @@ public class ApiScenarioService extends MoveNodeService {
* @param steps * @param steps
* @return * @return
*/ */
private Map<String, String> getPartialRefStepDetailMap(List<? extends ApiScenarioStepCommonDTO> steps) {
public Map<String, String> getPartialRefStepDetailMap(List<? extends ApiScenarioStepCommonDTO> steps) {
steps.forEach(step -> { steps.forEach(step -> {
if (isPartialRef(step)) { if (isPartialRef(step)) {
@ -1671,7 +1675,7 @@ public class ApiScenarioService extends MoveNodeService {
/** /**
* 设置部分引用的步骤的启用状态 * 设置部分引用的步骤的启用状态
*/ */
private void setPartialRefStepsEnable(List<? extends ApiScenarioStepCommonDTO> steps, Map<String, String> stepDetailMap) { public void setPartialRefStepsEnable(List<? extends ApiScenarioStepCommonDTO> steps, Map<String, String> stepDetailMap) {
if (CollectionUtils.isEmpty(steps)) { if (CollectionUtils.isEmpty(steps)) {
return; return;
} }
@ -1718,7 +1722,7 @@ public class ApiScenarioService extends MoveNodeService {
* @param parentStepMap 当前场景所有的步骤key 为父步骤IDvalue 为子步骤列表 * @param parentStepMap 当前场景所有的步骤key 为父步骤IDvalue 为子步骤列表
* @param scenarioStepMap 所有场景步骤key 为场景IDvalue 为子步骤列表 * @param scenarioStepMap 所有场景步骤key 为场景IDvalue 为子步骤列表
*/ */
private List<ApiScenarioStepDTO> buildStepTree(List<ApiScenarioStepDTO> steps, public List<ApiScenarioStepDTO> buildStepTree(List<ApiScenarioStepDTO> steps,
Map<String, List<ApiScenarioStepDTO>> parentStepMap, Map<String, List<ApiScenarioStepDTO>> parentStepMap,
Map<String, List<ApiScenarioStepDTO>> scenarioStepMap, Map<String, List<ApiScenarioStepDTO>> scenarioStepMap,
Set<String> stepIdSet) { Set<String> stepIdSet) {
@ -1779,14 +1783,14 @@ public class ApiScenarioService extends MoveNodeService {
/** /**
* 判断步骤是否是引用的场景 * 判断步骤是否是引用的场景
*/ */
private boolean isRefOrPartialScenario(ApiScenarioStepDTO step) { public boolean isRefOrPartialScenario(ApiScenarioStepDTO step) {
return isRefOrPartialRef(step.getRefType()) && isScenarioStep(step.getStepType()); return isRefOrPartialRef(step.getRefType()) && isScenarioStep(step.getStepType());
} }
/** /**
* 递归获取所有的场景步骤 * 递归获取所有的场景步骤
*/ */
private List<ApiScenarioStepDTO> getAllStepsByScenarioIds(List<String> scenarioIds) { public List<ApiScenarioStepDTO> getAllStepsByScenarioIds(List<String> scenarioIds) {
List<ApiScenarioStepDTO> steps = getStepDTOByScenarioIds(scenarioIds); List<ApiScenarioStepDTO> steps = getStepDTOByScenarioIds(scenarioIds);
if (CollectionUtils.isEmpty(steps)) { if (CollectionUtils.isEmpty(steps)) {
return steps; return steps;

View File

@ -0,0 +1,115 @@
package io.metersphere.api.controller;
import io.metersphere.api.domain.ApiDefinition;
import io.metersphere.api.domain.ApiDefinitionExample;
import io.metersphere.api.domain.ApiScenario;
import io.metersphere.api.domain.ApiScenarioExample;
import io.metersphere.api.dto.scenario.ApiScenarioSelectAssociateDTO;
import io.metersphere.api.dto.scenario.ApiScenarioStepDTO;
import io.metersphere.api.mapper.ApiDefinitionMapper;
import io.metersphere.api.mapper.ApiScenarioMapper;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.base.BaseTest;
import io.metersphere.system.controller.handler.ResultHolder;
import io.metersphere.system.dto.ModuleSelectDTO;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.junit.jupiter.api.*;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MvcResult;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@AutoConfigureMockMvc
public class ApiScenarioSelectAssociateControllerTests extends BaseTest {
private static final String URL = "/api/scenario/associate/all";
@Resource
private ApiScenarioMapper apiScenarioMapper;
@Resource
private ApiDefinitionMapper apiDefinitionMapper;
@Test
@Order(0)
public void testBatchExportReport() throws Exception {
ApiScenarioExample apiScenarioExample = new ApiScenarioExample();
apiScenarioExample.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID);
List<ApiScenario> apiScenarios = apiScenarioMapper.selectByExample(apiScenarioExample);
ApiScenario apiScenario = apiScenarios.get(0);
ApiDefinitionExample apiDefinitionExample = new ApiDefinitionExample();
apiDefinitionExample.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID);
List<ApiDefinition> apiDefinitionList = apiDefinitionMapper.selectByExample(apiDefinitionExample);
ApiDefinition apiDefinition = apiDefinitionList.get(0);
ApiDefinition apiDefinition1 = apiDefinitionList.get(1);
ApiScenarioSelectAssociateDTO apiScenarioSelectAssociateDTO = new ApiScenarioSelectAssociateDTO();
apiScenarioSelectAssociateDTO.setScenarioId(apiScenario.getId());
apiScenarioSelectAssociateDTO.setProjectId(DEFAULT_PROJECT_ID);
apiScenarioSelectAssociateDTO.setAssociateType("CASE");
apiScenarioSelectAssociateDTO.setSelectAllModule(true);
apiScenarioSelectAssociateDTO.setModuleMaps(new HashMap<>());
apiScenarioSelectAssociateDTO.setRefType("REF");
Map<String, ApiScenarioSelectAssociateDTO> requestMap = new HashMap<>();
requestMap.put("CASE", apiScenarioSelectAssociateDTO);
requestMap.put("SCENARIO",apiScenarioSelectAssociateDTO);
requestMap.put("API",apiScenarioSelectAssociateDTO);
MvcResult mvcResult = this.requestPostWithOkAndReturn(URL, requestMap);
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
List<ApiScenarioStepDTO> testCaseProviderDTOS = JSON.parseArray(JSON.toJSONString(resultHolder.getData()), ApiScenarioStepDTO.class);
Assertions.assertTrue(CollectionUtils.isNotEmpty(testCaseProviderDTOS));
Map<String, ModuleSelectDTO> moduleMaps = new HashMap<>();
ModuleSelectDTO moduleSelectDTO = new ModuleSelectDTO();
moduleSelectDTO.setSelectAll(false);
moduleSelectDTO.setSelectIds(List.of(apiScenarios.get(0).getId()));
moduleSelectDTO.setExcludeIds(List.of(apiScenarios.get(1).getId()));
moduleMaps.put(apiScenarios.get(0).getModuleId(),moduleSelectDTO);
apiScenarioSelectAssociateDTO.setSelectAllModule(false);
apiScenarioSelectAssociateDTO.setModuleMaps(moduleMaps);
apiScenarioSelectAssociateDTO.setProtocols(List.of("HTTP"));
Map<String, ModuleSelectDTO> caseModuleMaps = new HashMap<>();
ModuleSelectDTO caseModuleSelectDTO = new ModuleSelectDTO();
caseModuleSelectDTO.setSelectAll(false);
caseModuleSelectDTO.setSelectIds(List.of("sss"));
caseModuleSelectDTO.setExcludeIds(List.of("fff"));
caseModuleMaps.put(apiDefinitionList.get(3).getModuleId(),caseModuleSelectDTO);
ApiScenarioSelectAssociateDTO caseScenarioSelectAssociateDTO = new ApiScenarioSelectAssociateDTO();
caseScenarioSelectAssociateDTO.setScenarioId(apiScenario.getId());
caseScenarioSelectAssociateDTO.setProjectId(DEFAULT_PROJECT_ID);
caseScenarioSelectAssociateDTO.setAssociateType("CASE");
caseScenarioSelectAssociateDTO.setProtocols(List.of("HTTP"));
caseScenarioSelectAssociateDTO.setSelectAllModule(false);
caseScenarioSelectAssociateDTO.setModuleMaps(caseModuleMaps);
caseScenarioSelectAssociateDTO.setRefType("REF");
Map<String, ModuleSelectDTO> apiModuleMaps = new HashMap<>();
ModuleSelectDTO apiModuleSelectDTO = new ModuleSelectDTO();
apiModuleSelectDTO.setSelectAll(false);
apiModuleSelectDTO.setSelectIds(List.of(apiDefinition.getId()));
apiModuleSelectDTO.setExcludeIds(List.of(apiDefinition1.getId()));
apiModuleMaps.put(apiDefinitionList.get(3).getModuleId(),caseModuleSelectDTO);
ApiScenarioSelectAssociateDTO apiDScenarioSelectAssociateDTO = new ApiScenarioSelectAssociateDTO();
apiDScenarioSelectAssociateDTO.setScenarioId(apiScenario.getId());
apiDScenarioSelectAssociateDTO.setProtocols(List.of("HTTP"));
apiDScenarioSelectAssociateDTO.setProjectId(DEFAULT_PROJECT_ID);
apiDScenarioSelectAssociateDTO.setAssociateType("CASE");
apiDScenarioSelectAssociateDTO.setSelectAllModule(false);
apiDScenarioSelectAssociateDTO.setModuleMaps(apiModuleMaps);
apiDScenarioSelectAssociateDTO.setRefType("REF");
requestMap = new HashMap<>();
requestMap.put("CASE", apiScenarioSelectAssociateDTO);
requestMap.put("SCENARIO",caseScenarioSelectAssociateDTO);
requestMap.put("API",apiDScenarioSelectAssociateDTO);
this.requestPostWithOkAndReturn(URL, requestMap);
}
}