fix(用例管理): 修复关联第三方需求全选失效问题

--bug=1036165  --user=郭雨琦 https://www.tapd.cn/55049933/bugtrace/bugs/view/1155049933001036165
This commit is contained in:
guoyuqi 2024-02-26 18:03:41 +08:00 committed by 刘瑞斌
parent 3795b45ceb
commit fad9764753
6 changed files with 161 additions and 38 deletions

View File

@ -22,6 +22,11 @@ public class FunctionalCaseDemandBatchRequest extends BaseFunctionalCaseBatchDTO
@NotBlank(message = "{functional_case_demand.demand_platform.not_blank}")
private String demandPlatform;
@Schema(description = "需求集合")
@Schema(description = "需求集合(全选时可为空)")
private List<DemandDTO> demandList;
@Schema(description = "全选需求时的过滤条件")
private FunctionalDemandBatchRequest functionalDemandBatchRequest;
}

View File

@ -28,4 +28,8 @@ public class FunctionalCaseDemandRequest {
@Schema(description = "需求集合")
private List<DemandDTO> demandList;
@Schema(description = "全选需求时的过滤条件")
private FunctionalDemandBatchRequest functionalDemandBatchRequest;
}

View File

@ -0,0 +1,23 @@
package io.metersphere.functional.request;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* @author guoyuqi
*/
@Data
public class FunctionalDemandBatchRequest{
@Schema(description = "关键字")
private String keyword;
@Schema(description = "取消勾选的需求ID(关联全选需求时传参)")
List<String> excludeIds = new ArrayList<>();
@Schema(description = "是否选择所有(关联全选需求时传参)")
private boolean selectAll;
}

View File

@ -1,5 +1,6 @@
package io.metersphere.functional.service;
import io.metersphere.functional.domain.FunctionalCase;
import io.metersphere.functional.domain.FunctionalCaseDemand;
import io.metersphere.functional.domain.FunctionalCaseDemandExample;
import io.metersphere.functional.dto.DemandDTO;
@ -7,10 +8,8 @@ import io.metersphere.functional.dto.FunctionalDemandDTO;
import io.metersphere.functional.mapper.ExtFunctionalCaseDemandMapper;
import io.metersphere.functional.mapper.ExtFunctionalCaseMapper;
import io.metersphere.functional.mapper.FunctionalCaseDemandMapper;
import io.metersphere.functional.request.FunctionalCaseDemandBatchRequest;
import io.metersphere.functional.request.FunctionalCaseDemandRequest;
import io.metersphere.functional.request.FunctionalThirdDemandPageRequest;
import io.metersphere.functional.request.QueryDemandListRequest;
import io.metersphere.functional.mapper.FunctionalCaseMapper;
import io.metersphere.functional.request.*;
import io.metersphere.plugin.platform.dto.reponse.PlatformDemandDTO;
import io.metersphere.plugin.platform.dto.request.DemandPageRequest;
import io.metersphere.plugin.platform.spi.Platform;
@ -32,7 +31,9 @@ import org.mybatis.spring.SqlSessionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
@ -54,6 +55,8 @@ public class FunctionalCaseDemandService {
private ProjectApplicationService projectApplicationService;
@Resource
private ExtFunctionalCaseMapper extFunctionalCaseMapper;
@Resource
private FunctionalCaseMapper functionalCaseMapper;
/**
* 获取需求列表
@ -120,10 +123,10 @@ public class FunctionalCaseDemandService {
String demandId = functionalDemandDTO.getDemandId();
//当前数据例是否有父亲的这个数据就把当前这个map数据放入父亲下(相同平台的)
List<FunctionalDemandDTO> list = new ArrayList<>();
if (parentNotMatchedMap.get(demandId)!=null) {
list= parentNotMatchedMap.get(demandId).stream().filter(t -> StringUtils.equalsIgnoreCase(t.getDemandPlatform(), functionalDemandDTO.getDemandPlatform())).toList();
if (parentNotMatchedMap.get(demandId) != null) {
list = parentNotMatchedMap.get(demandId).stream().filter(t -> StringUtils.equalsIgnoreCase(t.getDemandPlatform(), functionalDemandDTO.getDemandPlatform())).toList();
}
if(CollectionUtils.isEmpty(list)) {
if (CollectionUtils.isEmpty(list)) {
continue;
}
delChild(functionalDemandDTO, list, parentNotMatchedMap, copyFunctionalDemandDTOS);
@ -156,10 +159,10 @@ public class FunctionalCaseDemandService {
}
for (FunctionalDemandDTO demandDTO : list) {
String demandId1 = demandDTO.getDemandId();
if (parentNotMatchedMap.get(demandId1)!=null){
if (parentNotMatchedMap.get(demandId1) != null) {
List<FunctionalDemandDTO> list1 = parentNotMatchedMap.get(demandId1).stream().filter(t -> StringUtils.equalsIgnoreCase(t.getDemandPlatform(), functionalDemandDTO.getDemandPlatform())).toList();
demandDTO.setChildren(list1);
delChild(demandDTO,list1, parentNotMatchedMap, copyFunctionalDemandDTOS);
delChild(demandDTO, list1, parentNotMatchedMap, copyFunctionalDemandDTOS);
}
copyFunctionalDemandDTOS.remove(demandDTO);
}
@ -172,13 +175,15 @@ public class FunctionalCaseDemandService {
* @param userId 当前操作人
*/
public void addDemand(FunctionalCaseDemandRequest request, String userId) {
if (checkDemandList(request.getDemandList())) return;
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(request.getCaseId());
List<DemandDTO> demandDTOList = doSelectDemandList(request.getFunctionalDemandBatchRequest(), request.getDemandList(), functionalCase.getProjectId());
if (checkDemandList(demandDTOList)) return;
FunctionalCaseDemandExample functionalCaseDemandExample = new FunctionalCaseDemandExample();
functionalCaseDemandExample.createCriteria().andCaseIdEqualTo(request.getCaseId()).andDemandPlatformEqualTo(request.getDemandPlatform());
List<FunctionalCaseDemand> existDemands = functionalCaseDemandMapper.selectByExample(functionalCaseDemandExample);
try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)){
try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
FunctionalCaseDemandMapper functionalCaseDemandMapper = sqlSession.getMapper(FunctionalCaseDemandMapper.class);
for (DemandDTO demandDTO : request.getDemandList()) {
for (DemandDTO demandDTO : demandDTOList) {
FunctionalCaseDemand functionalCaseDemand = buildFunctionalCaseDemand(request.getCaseId(), request.getDemandPlatform(), userId, demandDTO);
List<FunctionalCaseDemand> list = existDemands.stream().filter(t -> StringUtils.equalsIgnoreCase(t.getDemandId(), functionalCaseDemand.getDemandId()) && StringUtils.equalsIgnoreCase(t.getParent(), functionalCaseDemand.getParent())
&& StringUtils.equalsIgnoreCase(t.getDemandName(), functionalCaseDemand.getDemandName()) && StringUtils.equalsIgnoreCase(t.getDemandUrl(), functionalCaseDemand.getDemandUrl())).toList();
@ -283,18 +288,19 @@ public class FunctionalCaseDemandService {
* @param userId 当前操作人
*/
public void batchRelevance(FunctionalCaseDemandBatchRequest request, String userId) {
if (checkDemandList(request.getDemandList())) return;
List<DemandDTO> demandDTOList = doSelectDemandList(request.getFunctionalDemandBatchRequest(), request.getDemandList(), request.getProjectId());
if (checkDemandList(demandDTOList)) return;
List<String> caseIds = doSelectIds(request, request.getProjectId());
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
FunctionalCaseDemandMapper functionalCaseDemandMapper = sqlSession.getMapper(FunctionalCaseDemandMapper.class);
List<String> demandIds = request.getDemandList().stream().map(DemandDTO::getDemandId).toList();
List<String> demandIds = demandDTOList.stream().map(DemandDTO::getDemandId).toList();
String demandPlatform = request.getDemandPlatform();
//查询当前平台所有已关联的需求
FunctionalCaseDemandExample functionalCaseDemandExample = new FunctionalCaseDemandExample();
functionalCaseDemandExample.createCriteria().andDemandPlatformEqualTo(demandPlatform);
List<FunctionalCaseDemand> existPlatformDemands = functionalCaseDemandMapper.selectByExample(functionalCaseDemandExample);
Map<String, List<FunctionalCaseDemand>> caseDemandMap = existPlatformDemands.stream().collect(Collectors.groupingBy(FunctionalCaseDemand::getCaseId));
Map<String, DemandDTO> demandDTOMap = request.getDemandList().stream().collect(Collectors.toMap(DemandDTO::getDemandId, t -> t));
Map<String, DemandDTO> demandDTOMap = demandDTOList.stream().collect(Collectors.toMap(DemandDTO::getDemandId, t -> t));
caseIds.forEach(t -> {
List<String> existDemandIds = new ArrayList<>();
List<FunctionalCaseDemand> functionalCaseDemands = caseDemandMap.get(t);
@ -314,6 +320,43 @@ public class FunctionalCaseDemandService {
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
}
private List<DemandDTO> doSelectDemandList(FunctionalDemandBatchRequest functionalDemandBatchRequest, List<DemandDTO> demandList, String projectId) {
if (functionalDemandBatchRequest != null && functionalDemandBatchRequest.isSelectAll()) {
DemandPageRequest demandPageRequest = new DemandPageRequest();
demandPageRequest.setQuery(functionalDemandBatchRequest.getKeyword());
demandPageRequest.setSelectAll(functionalDemandBatchRequest.isSelectAll());
demandPageRequest.setExcludeIds(functionalDemandBatchRequest.getExcludeIds());
demandPageRequest.setProjectConfig(projectApplicationService.getProjectDemandThirdPartConfig(projectId));
Platform platform = projectApplicationService.getPlatform(projectId, false);
PluginPager<PlatformDemandDTO> platformDemandDTOPluginPager = platform.pageDemand(demandPageRequest);
return getDemandDTOS(platformDemandDTOPluginPager);
} else {
return demandList;
}
}
public List<DemandDTO> getDemandDTOS(PluginPager<PlatformDemandDTO> platformDemandDTOPluginPager) {
if (platformDemandDTOPluginPager.getData()!=null) {
List<PlatformDemandDTO.Demand> list = platformDemandDTOPluginPager.getData().getList();
List<DemandDTO> demandDTOList = new ArrayList<>();
setDemandDTOList(list, demandDTOList);
return demandDTOList;
} else {
return new ArrayList<>();
}
}
public void setDemandDTOList(List<PlatformDemandDTO.Demand> list, List<DemandDTO> demandDTOList) {
for (PlatformDemandDTO.Demand demand : list) {
DemandDTO demandDTO = new DemandDTO();
BeanUtils.copyBean(demand, demandDTO);
if (CollectionUtils.isNotEmpty(demand.getChildren())) {
setDemandDTOList(demand.getChildren(), demandDTOList);
}
demandDTOList.add(demandDTO);
}
}
public <T> List<String> doSelectIds(T dto, String projectId) {
FunctionalCaseDemandBatchRequest request = (FunctionalCaseDemandBatchRequest) dto;
if (request.isSelectAll()) {

View File

@ -5,10 +5,8 @@ import io.metersphere.functional.domain.FunctionalCaseDemandExample;
import io.metersphere.functional.dto.DemandDTO;
import io.metersphere.functional.dto.FunctionalDemandDTO;
import io.metersphere.functional.mapper.FunctionalCaseDemandMapper;
import io.metersphere.functional.request.FunctionalCaseDemandBatchRequest;
import io.metersphere.functional.request.FunctionalCaseDemandRequest;
import io.metersphere.functional.request.FunctionalThirdDemandPageRequest;
import io.metersphere.functional.request.QueryDemandListRequest;
import io.metersphere.functional.request.*;
import io.metersphere.functional.service.FunctionalCaseDemandService;
import io.metersphere.plugin.platform.dto.reponse.PlatformDemandDTO;
import io.metersphere.plugin.platform.utils.PluginPager;
import io.metersphere.sdk.constants.SessionConstants;
@ -25,6 +23,7 @@ import io.metersphere.system.mapper.SystemParameterMapper;
import io.metersphere.system.utils.Pager;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.*;
import org.mockserver.client.MockServerClient;
@ -37,7 +36,6 @@ import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.SqlConfig;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.apache.commons.lang3.StringUtils;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@ -55,6 +53,8 @@ public class FunctionalCaseDemandControllerTests extends BaseTest {
@Resource
private FunctionalCaseDemandMapper functionalCaseDemandMapper;
@Resource
private FunctionalCaseDemandService functionalCaseDemandService;
@Resource
private OperationLogMapper operationLogMapper;
@Resource
private SystemParameterMapper systemParameterMapper;
@ -80,6 +80,24 @@ public class FunctionalCaseDemandControllerTests extends BaseTest {
@Order(1)
@Sql(scripts = {"/dml/init_case_demand.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
public void addDemandSuccess() throws Exception {
basePluginTestService.addJiraPlugin();
basePluginTestService.addServiceIntegration(DEFAULT_ORGANIZATION_ID);
mockServerClient
.when(
request()
.withMethod("GET")
.withPath("/rest/api/2/search"))
.respond(
response()
.withStatusCode(200)
.withHeaders(
new Header("Content-Type", "application/json; charset=utf-8"),
new Header("Cache-Control", "public, max-age=86400"))
.withBody("{\"id\":\"123456\",\"name\":\"test\"}")
);
FunctionalDemandBatchRequest functionalDemandBatchRequest = new FunctionalDemandBatchRequest();
functionalDemandBatchRequest.setSelectAll(false);
FunctionalCaseDemandRequest functionalCaseDemandRequest = new FunctionalCaseDemandRequest();
functionalCaseDemandRequest.setCaseId("DEMAND_TEST_FUNCTIONAL_CASE_ID");
functionalCaseDemandRequest.setDemandPlatform("Metersphere");
@ -124,6 +142,38 @@ public class FunctionalCaseDemandControllerTests extends BaseTest {
functionalCaseDemandExample.createCriteria().andCaseIdEqualTo("DEMAND_TEST_FUNCTIONAL_CASE_ID").andDemandNameLike("%手动加入孩子超长名字%");
functionalCaseDemands = functionalCaseDemandMapper.selectByExample(functionalCaseDemandExample);
Assertions.assertFalse(functionalCaseDemands.isEmpty());
functionalCaseDemandRequest = new FunctionalCaseDemandRequest();
functionalCaseDemandRequest.setFunctionalDemandBatchRequest(functionalDemandBatchRequest);
functionalCaseDemandRequest.setCaseId("DEMAND_TEST_FUNCTIONAL_CASE_ID5");
functionalCaseDemandRequest.setDemandPlatform("Metersphere");
functionalDemandBatchRequest.setSelectAll(true);
functionalCaseDemandRequest.setFunctionalDemandBatchRequest(functionalDemandBatchRequest);
this.requestPostWithOkAndReturn(URL_DEMAND_ADD, functionalCaseDemandRequest);
PluginPager<PlatformDemandDTO> platformDemandDTOPluginPager = new PluginPager<>();
platformDemandDTOPluginPager.setCurrent(1);
platformDemandDTOPluginPager.setPageSize(500);
platformDemandDTOPluginPager.setTotal(1);
PlatformDemandDTO platformDemandDTO = new PlatformDemandDTO();
platformDemandDTO.setCustomHeaders(new ArrayList<>());
List<PlatformDemandDTO.Demand> demands = new ArrayList<>();
PlatformDemandDTO.Demand demand = new PlatformDemandDTO.Demand();
demand.setDemandUrl("https://www.baidu.com/");
demand.setDemandId("10233");
demand.setDemandName("白度需求");
List<PlatformDemandDTO.Demand> children = new ArrayList<>();
PlatformDemandDTO.Demand child = new PlatformDemandDTO.Demand();
child.setDemandUrl("https://www.baidu.com/");
child.setDemandId("10234");
child.setDemandName("白度需求");
child.setParent("10233");
children.add(child);
demand.setChildren(children);
demands.add(demand);
platformDemandDTO.setList(demands);
platformDemandDTOPluginPager.setData(platformDemandDTO);
functionalCaseDemandService.getDemandDTOS(platformDemandDTOPluginPager);
}
@Test
@ -505,6 +555,16 @@ public class FunctionalCaseDemandControllerTests extends BaseTest {
System.out.println(jsonString);
functionalCaseDemandBatchRequest.setDemandList(new ArrayList<>());
this.requestPostWithOkAndReturn(URL_DEMAND_BATCH_RELEVANCE, functionalCaseDemandBatchRequest);
functionalCaseDemandBatchRequest = new FunctionalCaseDemandBatchRequest();
functionalCaseDemandBatchRequest.setSelectAll(true);
functionalCaseDemandBatchRequest.setProjectId("gyq_project-case-demand-test");
functionalCaseDemandBatchRequest.setDemandPlatform("jira");
FunctionalDemandBatchRequest functionalDemandBatchRequest = new FunctionalDemandBatchRequest();
functionalDemandBatchRequest.setSelectAll(true);
functionalCaseDemandBatchRequest.setFunctionalDemandBatchRequest(functionalDemandBatchRequest);
this.requestPostWithOkAndReturn(URL_DEMAND_BATCH_RELEVANCE, functionalCaseDemandBatchRequest);
}
@Test
@ -589,22 +649,6 @@ public class FunctionalCaseDemandControllerTests extends BaseTest {
@Test
@Order(15)
public void pageDemandSuccess() throws Exception {
basePluginTestService.addJiraPlugin();
basePluginTestService.addServiceIntegration(DEFAULT_ORGANIZATION_ID);
mockServerClient
.when(
request()
.withMethod("GET")
.withPath("/rest/api/2/search"))
.respond(
response()
.withStatusCode(200)
.withHeaders(
new Header("Content-Type", "application/json; charset=utf-8"),
new Header("Cache-Control", "public, max-age=86400"))
.withBody("{\"id\":\"123456\",\"name\":\"test\"}")
);
FunctionalThirdDemandPageRequest functionalThirdDemandPageRequest = new FunctionalThirdDemandPageRequest();
functionalThirdDemandPageRequest.setProjectId("gyq_project-case-demand-test");
functionalThirdDemandPageRequest.setPageSize(10);

View File

@ -22,6 +22,10 @@ VALUES ('DEMAND_TEST_FUNCTIONAL_CASE_ID3', 1, 'DEMAND_TEST_MODULE_ID', 'project-
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
VALUES ('DEMAND_TEST_FUNCTIONAL_CASE_ID4', 1, 'DEMAND_TEST_MODULE_ID', 'project-case-demand-test', '100001', '关联需求测试', 'UN_REVIEWED', NULL, 'STEP', 0, 'v1.0.0', 'DEMAND_TEST_FUNCTIONAL_CASE_ID4', 'UN_EXECUTED', false, b'0', b'1', 'gyq', 'gyq', '', 1698058347559, 1698058347559, NULL);
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
VALUES ('DEMAND_TEST_FUNCTIONAL_CASE_ID5', 1, 'DEMAND_TEST_MODULE_ID', 'gyq_project-case-demand-test', '100001', '关联需求测试', 'UN_REVIEWED', NULL, 'STEP', 0, 'v1.0.0', 'DEMAND_TEST_FUNCTIONAL_CASE_ID5', 'UN_EXECUTED', false, b'0', b'1', 'gyq', 'gyq', '', 1698058347559, 1698058347559, NULL);
INSERT INTO functional_case_custom_field(case_id, field_id, value) VALUES ('DEMAND_TEST_FUNCTIONAL_CASE_ID', 'gyq_custom_id_demand1', '22');
INSERT INTO functional_case_custom_field(case_id, field_id, value) VALUES ('DEMAND_TEST_FUNCTIONAL_CASE_ID', 'gyq_custom_id_demand2', '33');