feat(测试计划): 获取组内测试计划接口的开发

This commit is contained in:
Jianguo-Genius 2024-06-03 17:05:29 +08:00 committed by 刘瑞斌
parent 86eee33ee9
commit 536185bdca
6 changed files with 107 additions and 65 deletions

View File

@ -54,6 +54,15 @@ public class TestPlanController {
return testPlanManagementService.page(request);
}
@GetMapping("/list-in-group/{groupId}")
@Operation(summary = "测试计划-表格分页查询")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ)
@CheckOwner(resourceId = "#groupId", resourceType = "test_plan")
public List<TestPlanResponse> listInGroup(@NotBlank @PathVariable String groupId) {
testPlanManagementService.checkModuleIsOpen(groupId, TestPlanResourceConfig.CHECK_TYPE_TEST_PLAN, Collections.singletonList(TestPlanResourceConfig.CONFIG_TEST_PLAN));
return testPlanManagementService.selectByGroupId(groupId);
}
@PostMapping("/statistics")
@Operation(summary = "测试计划-获取计划详情统计{通过率, 执行进度}")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ)

View File

@ -41,4 +41,6 @@ public class TestPlanResponse extends TestPlanStatisticsResponse {
@Schema(description = "描述")
private String description;
private long pos;
}

View File

@ -13,11 +13,11 @@ import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ExtTestPlanMapper {
List<String> selectByGroupId(String parentId);
List<String> selectIdByGroupId(String parentId);
List<String> selectByGroupIdList(@Param("list") List<String> parentTestPlanId);
List<TestPlanResponse> selectByConditions(@Param("request") TestPlanTableRequest request,@Param("groupIds") List<String> groupIds);
List<TestPlanResponse> selectByConditions(@Param("request") TestPlanTableRequest request);
List<String> selectIdByConditions(@Param("request") TestPlanBatchProcessRequest request);
@ -48,4 +48,6 @@ public interface ExtTestPlanMapper {
DropNode selectNodeByPosOperator(NodeSortQueryParam nodeSortQueryParam);
long selectMaxPosByGroupId(String groupId);
List<TestPlanResponse> selectByGroupIds(@Param("groupIds") List<String> groupIds);
}

View File

@ -32,7 +32,7 @@
</foreach>
</update>
<select id="selectByGroupId" resultType="java.lang.String">
<select id="selectIdByGroupId" resultType="java.lang.String">
SELECT id FROM test_plan WHERE group_id = #{parentId}
</select>
<select id="selectByGroupIdList" resultType="java.lang.String">
@ -57,23 +57,32 @@
FROM test_plan t
INNER JOIN user createUser ON t.create_user = createUser.id
WHERE t.project_id = #{request.projectId}
<if test="groupIds != null and groupIds.size() > 0">
and t.group_id IN
<foreach collection="groupIds" item="groupId" separator="," open="(" close=")">
#{groupId}
<include refid="queryByTableRequest"/>
</select>
<select id="selectByGroupIds"
resultMap="BaseResultMapDTO">
SELECT
t.id,t.num,t.name,t.status,t.group_id,
t.create_user AS createUser,
createUser.name AS createUserName,
t.create_time as createTime,
t.module_id as moduleId,
t.type,
t.description,
t.pos,
t.tags
FROM test_plan t
INNER JOIN user createUser ON t.create_user = createUser.id
WHERE t.group_id IN
<foreach collection="groupIds" item="groupId" separator="," open="(" close=")">
#{groupId}
</foreach>
</if>
<include refid="queryWhereCondition"/>
ORDER BY t.pos ASC
</select>
<sql id="queryWhereCondition">
<if test="request.moduleIds != null and request.moduleIds.size() > 0">
and t.module_id in
<foreach collection="request.moduleIds" item="moduleId" separator="," open="(" close=")">
#{moduleId}
</foreach>
</if>
<sql id="queryByTableRequest">
<include refid="baseConditionQuery"/>
<if test="request.keyword != null and request.keyword != ''">
and (
t.name like concat('%', #{request.keyword},'%')
@ -96,9 +105,6 @@
</when>
</choose>
</if>
<include refid="filters">
<property name="filter" value="request.filter"/>
</include>
<choose>
<when test='request.searchMode == "AND"'>
AND <include refid="queryCombine"/>
@ -109,6 +115,10 @@
)
</when>
</choose>
<include refid="filters">
<property name="filter" value="request.filter"/>
</include>
</sql>
@ -249,7 +259,7 @@
FROM test_plan t
INNER JOIN user createUser ON t.create_user = createUser.id
WHERE t.project_id = #{request.projectId}
<include refid="queryWhereCondition"/>
<include refid="queryByTableRequest"/>
GROUP BY t.module_id
</select>
<select id="selectIdByConditions"
@ -259,23 +269,15 @@
t.id
FROM test_plan t
WHERE t.project_id = #{request.projectId}
<include refid="queryWhereConditionByBaseQueryRequest"/>
<include refid="queryByTestPlanQueryConditions"/>
</select>
<sql id="queryWhereConditionByBaseQueryRequest">
<sql id="baseConditionQuery">
<if test="request.moduleIds != null and request.moduleIds.size() > 0">
and t.module_id in
<foreach collection="request.moduleIds" item="moduleId" separator="," open="(" close=")">
#{moduleId}
</foreach>
</if>
<if test="request.condition.keyword != null and request.condition.keyword != ''">
and (
t.name like concat('%', #{request.condition.keyword},'%')
or t.num like concat('%', #{request.condition.keyword},'%')
or t.tags like concat('%', #{request.condition.keyword}, '%')
)
</if>
<if test="request.type != null and request.type != ''">
<choose>
<when test="request.type == 'ALL'">
@ -287,13 +289,20 @@
</when>
<when test="request.type == 'GROUP'">
and t.group_id = 'NONE'
and t.type = 'GTOUP'
and t.type = 'GROUP'
</when>
</choose>
</if>
<include refid="filters">
<property name="filter" value="request.condition.filter"/>
</include>
</sql>
<sql id="queryByTestPlanQueryConditions">
<include refid="baseConditionQuery"/>
<if test="request.condition.keyword != null and request.condition.keyword != ''">
and (
t.name like concat('%', #{request.condition.keyword},'%')
or t.num like concat('%', #{request.condition.keyword},'%')
or t.tags like concat('%', #{request.condition.keyword}, '%')
)
</if>
<choose>
<when test='request.condition.searchMode == "AND"'>
AND <include refid="baseQueryCombine"/>
@ -304,6 +313,9 @@
)
</when>
</choose>
<include refid="filters">
<property name="filter" value="request.condition.filter"/>
</include>
</sql>
<sql id="baseQueryCombine">

View File

@ -17,6 +17,7 @@ import io.metersphere.sdk.util.Translator;
import io.metersphere.system.utils.PageUtils;
import io.metersphere.system.utils.Pager;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
@ -63,8 +64,8 @@ public class TestPlanManagementService {
}
private List<TestPlanResponse> getTableList(TestPlanTableRequest request) {
List<TestPlanResponse> testPlanResponses = extTestPlanMapper.selectByConditions(request, null);
handChildren(testPlanResponses, request.getProjectId());
List<TestPlanResponse> testPlanResponses = extTestPlanMapper.selectByConditions(request);
handChildren(testPlanResponses,request.getProjectId());
return testPlanResponses;
}
@ -73,20 +74,20 @@ public class TestPlanManagementService {
*/
private void handChildren(List<TestPlanResponse> testPlanResponses, String projectId) {
List<String> groupIds = testPlanResponses.stream().filter(item -> StringUtils.equals(item.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)).map(TestPlanResponse::getId).toList();
TestPlanTableRequest request = new TestPlanTableRequest();
request.setProjectId(projectId);
List<TestPlanResponse> childrenList = extTestPlanMapper.selectByConditions(request, groupIds);
Map<String, List<TestPlanResponse>> collect = childrenList.stream().collect(Collectors.groupingBy(TestPlanResponse::getGroupId));
testPlanResponses.forEach(item -> {
if (collect.containsKey(item.getId())) {
//存在子节点
List<TestPlanResponse> list = collect.get(item.getId());
testPlanStatisticsService.calculateCaseCount(list);
item.setChildren(list);
item.setChildrenCount(list.size());
}
testPlanStatisticsService.calculateCaseCount(List.of(item));
});
if (CollectionUtils.isNotEmpty(groupIds)) {
List<TestPlanResponse> childrenList = extTestPlanMapper.selectByGroupIds(groupIds);
Map<String, List<TestPlanResponse>> collect = childrenList.stream().collect(Collectors.groupingBy(TestPlanResponse::getGroupId));
testPlanResponses.forEach(item -> {
if (collect.containsKey(item.getId())) {
//存在子节点
List<TestPlanResponse> list = collect.get(item.getId());
testPlanStatisticsService.calculateCaseCount(list);
item.setChildren(list);
item.setChildrenCount(list.size());
}
testPlanStatisticsService.calculateCaseCount(List.of(item));
});
}
}
public void checkModuleIsOpen(String resourceId, String resourceType, List<String> moduleMenus) {
@ -111,6 +112,10 @@ public class TestPlanManagementService {
}
}
public List<TestPlanResponse> selectByGroupId(String groupId) {
return extTestPlanMapper.selectByGroupIds(List.of(groupId));
}
/**
* 根据项目id检查模块是否开启

View File

@ -7,6 +7,7 @@ import io.metersphere.plan.constants.TestPlanResourceConfig;
import io.metersphere.plan.domain.*;
import io.metersphere.plan.dto.request.*;
import io.metersphere.plan.dto.response.TestPlanResourceSortResponse;
import io.metersphere.plan.dto.response.TestPlanResponse;
import io.metersphere.plan.mapper.ExtTestPlanMapper;
import io.metersphere.plan.mapper.TestPlanMapper;
import io.metersphere.plan.mapper.TestPlanReportMapper;
@ -15,6 +16,7 @@ import io.metersphere.plan.utils.TestPlanTestUtils;
import io.metersphere.project.domain.Project;
import io.metersphere.project.dto.filemanagement.request.FileModuleCreateRequest;
import io.metersphere.project.dto.filemanagement.request.FileModuleUpdateRequest;
import io.metersphere.project.utils.NodeSortUtils;
import io.metersphere.sdk.constants.*;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.CommonBeanFactory;
@ -107,6 +109,7 @@ public class TestPlanTests extends BaseTest {
private static final String URL_POST_TEST_PLAN_PAGE = "/test-plan/page";
private static final String URL_POST_TEST_PLAN_STATISTICS = "/test-plan/statistics";
private static final String URL_POST_TEST_PLAN_MODULE_COUNT = "/test-plan/module/count";
private static final String URL_GET_TEST_PLAN_LIST_IN_GROUP = "/test-plan/list-in-group/%s";
private static final String URL_POST_TEST_PLAN_ADD = "/test-plan/add";
private static final String URL_POST_TEST_PLAN_SORT = "/test-plan/sort";
private static final String URL_POST_TEST_PLAN_UPDATE = "/test-plan/update";
@ -687,7 +690,16 @@ public class TestPlanTests extends BaseTest {
this.checkTestPlanSortInGroup(groupTestPlanId7);
}
protected void checkTestPlanSortInGroup(String groupTestPlanId7) throws Exception {
private List<TestPlanResponse> selectByGroupId(String groupId) throws Exception {
return JSON.parseArray(
JSON.toJSONString(
JSON.parseObject(
this.requestGetWithOkAndReturn(String.format(URL_GET_TEST_PLAN_LIST_IN_GROUP, groupId))
.getResponse().getContentAsString(), ResultHolder.class).getData()),
TestPlanResponse.class);
}
protected void checkTestPlanSortInGroup(String groupId) throws Exception {
/*
排序校验用例设计
1.第一个移动到最后一个
@ -695,13 +707,9 @@ public class TestPlanTests extends BaseTest {
3.第三个移动到第二个
4.修改第一个和第二个之间的pos差小于2将第三个移动到第二个还原为原来的顺序并检查pos有没有初始化
*/
TestPlanExample example = new TestPlanExample();
example.createCriteria().andGroupIdEqualTo(groupTestPlanId7);
example.setOrderByClause("pos asc");
List<TestPlan> defaultTestPlanInGroup = testPlanMapper.selectByExample(example);
List<TestPlan> lastTestPlanInGroup = defaultTestPlanInGroup;
TestPlan movePlan, targetPlan = null;
List<TestPlanResponse> defaultTestPlanInGroup = this.selectByGroupId(groupId);
List<TestPlanResponse> lastTestPlanInGroup = defaultTestPlanInGroup;
TestPlanResponse movePlan, targetPlan = null;
PosRequest posRequest = null;
TestPlanResourceSortResponse response = null;
@ -716,7 +724,7 @@ public class TestPlanTests extends BaseTest {
.getResponse().getContentAsString(), ResultHolder.class).getData()),
TestPlanResourceSortResponse.class);
//位置校验
List<TestPlan> newTestPlanInGroup = testPlanMapper.selectByExample(example);
List<TestPlanResponse> newTestPlanInGroup = this.selectByGroupId(groupId);
Assertions.assertEquals(response.getSortNodeNum(), 1);
Assertions.assertEquals(newTestPlanInGroup.size(), lastTestPlanInGroup.size());
for (int newListIndex = 0; newListIndex < newTestPlanInGroup.size(); newListIndex++) {
@ -736,7 +744,7 @@ public class TestPlanTests extends BaseTest {
.getResponse().getContentAsString(), ResultHolder.class).getData()),
TestPlanResourceSortResponse.class);
//位置校验
newTestPlanInGroup = testPlanMapper.selectByExample(example);
newTestPlanInGroup = this.selectByGroupId(groupId);
Assertions.assertEquals(response.getSortNodeNum(), 1);
Assertions.assertEquals(newTestPlanInGroup.size(), lastTestPlanInGroup.size());
for (int newListIndex = 0; newListIndex < newTestPlanInGroup.size(); newListIndex++) {
@ -755,7 +763,7 @@ public class TestPlanTests extends BaseTest {
.getResponse().getContentAsString(), ResultHolder.class).getData()),
TestPlanResourceSortResponse.class);
//位置校验
newTestPlanInGroup = testPlanMapper.selectByExample(example);
newTestPlanInGroup = this.selectByGroupId(groupId);
Assertions.assertEquals(response.getSortNodeNum(), 1);
Assertions.assertEquals(newTestPlanInGroup.size(), lastTestPlanInGroup.size());
for (int newListIndex = 0; newListIndex < newTestPlanInGroup.size(); newListIndex++) {
@ -772,8 +780,10 @@ public class TestPlanTests extends BaseTest {
// 修改第一个和第二个之间的pos差为2(拖拽的最小pos差将第三个移动到第二个换回来然后检查pos有没有变化
movePlan = lastTestPlanInGroup.get(2);
targetPlan = lastTestPlanInGroup.get(1);
targetPlan.setPos(lastTestPlanInGroup.get(0).getPos() + 2);
testPlanMapper.updateByPrimaryKey(targetPlan);
TestPlan updatePlan = new TestPlan();
updatePlan.setId(targetPlan.getId());
updatePlan.setPos(lastTestPlanInGroup.get(0).getPos() + 2);
testPlanMapper.updateByPrimaryKeySelective(updatePlan);
posRequest = new PosRequest(project.getId(), movePlan.getId(), targetPlan.getId(), MoveTypeEnum.BEFORE.name());
response = JSON.parseObject(
@ -783,13 +793,13 @@ public class TestPlanTests extends BaseTest {
.getResponse().getContentAsString(), ResultHolder.class).getData()),
TestPlanResourceSortResponse.class);
//位置校验
newTestPlanInGroup = testPlanMapper.selectByExample(example);
newTestPlanInGroup = this.selectByGroupId(groupId);
Assertions.assertEquals(response.getSortNodeNum(), 1);
Assertions.assertEquals(newTestPlanInGroup.size(), lastTestPlanInGroup.size());
long lastPos = 0;
for (int newListIndex = 0; newListIndex < newTestPlanInGroup.size(); newListIndex++) {
Assertions.assertEquals(newTestPlanInGroup.get(newListIndex).getId(), defaultTestPlanInGroup.get(newListIndex).getId());
Assertions.assertTrue(newTestPlanInGroup.get(newListIndex).getPos() > (lastPos + 1));
Assertions.assertTrue(newTestPlanInGroup.get(newListIndex).getPos() == (lastPos + NodeSortUtils.DEFAULT_NODE_INTERVAL_POS));
lastPos = newTestPlanInGroup.get(newListIndex).getPos();
}
}
@ -847,11 +857,13 @@ public class TestPlanTests extends BaseTest {
dataRequest.getCurrent(),
dataRequest.getPageSize(),
1010);
//只查询组
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
URL_POST_TEST_PLAN_PAGE, groupRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
dataRequest.getCurrent(),
dataRequest.getPageSize(),
2);
//只查询计划
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
URL_POST_TEST_PLAN_PAGE, onlyPlanRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
dataRequest.getCurrent(),