feat(测试计划): 游离态测试计划以及测试计划组排序功能开发
This commit is contained in:
parent
4e2cac42d7
commit
f0f3f69b7a
|
@ -3,6 +3,49 @@ SET SESSION innodb_lock_wait_timeout = 7200;
|
|||
|
||||
DROP TABLE IF EXISTS functional_minder_extra_node;
|
||||
|
||||
-- 清洗测试计划表的pos数据
|
||||
DROP PROCEDURE IF EXISTS UpdatePosForNoneGroup;
|
||||
DELIMITER
|
||||
$$
|
||||
CREATE PROCEDURE UpdatePosForNoneGroup()
|
||||
BEGIN
|
||||
#声明结束标识
|
||||
DECLARE done INT DEFAULT FALSE;
|
||||
DECLARE testPlanUpdateId varchar(50);
|
||||
DECLARE testPlanProjectId varchar(50);
|
||||
DECLARE lastProjectId varchar(50) default '';
|
||||
DECLARE current_pos INT DEFAULT 4096;
|
||||
DECLARE updateRow CURSOR FOR SELECT id, project_id
|
||||
FROM test_plan
|
||||
WHERE `group_id` = 'none'
|
||||
ORDER BY project_id ASC, num ASC;
|
||||
#设置终止标志
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
|
||||
#打开游标
|
||||
OPEN updateRow;
|
||||
#获取当前游标指针记录,取出值赋给自定义的变量
|
||||
FETCH updateRow INTO testPlanUpdateId,testPlanProjectId;
|
||||
#遍历游标
|
||||
REPEAT
|
||||
#判断是否是同一个项目
|
||||
IF testPlanProjectId != lastProjectId THEN
|
||||
SET current_pos = 4096;
|
||||
SET lastProjectId = testPlanProjectId;
|
||||
END IF;
|
||||
#利用取到的值进行数据库的操作
|
||||
update test_plan set pos = current_pos where id = testPlanUpdateId;
|
||||
# 将游标中的值再赋值给变量,供下次循环使用
|
||||
FETCH updateRow INTO testPlanUpdateId,testPlanProjectId;
|
||||
SET current_pos = current_pos + 4096;
|
||||
UNTIL done END REPEAT;
|
||||
#关闭游标
|
||||
CLOSE updateRow;
|
||||
END
|
||||
$$
|
||||
DELIMITER ;
|
||||
CALL UpdatePosForNoneGroup();
|
||||
DROP PROCEDURE IF EXISTS UpdatePosForNoneGroup;
|
||||
-- 清洗测试计划表的pos数据结束
|
||||
|
||||
-- set innodb lock wait timeout to default
|
||||
SET SESSION innodb_lock_wait_timeout = DEFAULT;
|
|
@ -91,6 +91,12 @@ public abstract class MoveNodeService {
|
|||
return new MoveNodeSortDTO(sortRangeId, dragNode, previousNode, nextNode);
|
||||
}
|
||||
|
||||
//判断是否存在需要提前排序的异常数据
|
||||
public boolean needRefreshBeforeSort(DropNode previousNode, DropNode nextNode) {
|
||||
long previousPos = previousNode == null ? -1 : previousNode.getPos();
|
||||
long nextPos = nextNode == null ? -1 : nextNode.getPos();
|
||||
return nextPos - previousPos <= 1 || previousPos == 0 || nextPos == 0;
|
||||
}
|
||||
//排序
|
||||
public void sort(MoveNodeSortDTO sortDTO) {
|
||||
// 获取相邻节点
|
||||
|
|
|
@ -95,7 +95,6 @@ public class TestPlanApiCaseController {
|
|||
batchRequest.setTestPlanId(request.getTestPlanId());
|
||||
batchRequest.setSelectIds(List.of(request.getId()));
|
||||
TestPlanAssociationResponse response = testPlanApiCaseService.disassociate(batchRequest, new LogInsertModule(SessionUtils.getUserId(), "/test-plan/api/case/disassociate", HttpMethodConstants.POST.name()));
|
||||
testPlanService.refreshTestPlanStatus(request.getTestPlanId());
|
||||
return response;
|
||||
}
|
||||
|
||||
|
@ -109,7 +108,6 @@ public class TestPlanApiCaseController {
|
|||
return new TestPlanAssociationResponse();
|
||||
}
|
||||
TestPlanAssociationResponse response = testPlanApiCaseService.disassociate(request, new LogInsertModule(SessionUtils.getUserId(), "/test-plan/api/case/batch/disassociate", HttpMethodConstants.POST.name()));
|
||||
testPlanService.refreshTestPlanStatus(request.getTestPlanId());
|
||||
return response;
|
||||
}
|
||||
|
||||
|
|
|
@ -101,7 +101,6 @@ public class TestPlanApiScenarioController {
|
|||
batchRequest.setTestPlanId(request.getTestPlanId());
|
||||
batchRequest.setSelectIds(List.of(request.getId()));
|
||||
TestPlanAssociationResponse response = testPlanApiScenarioService.disassociate(batchRequest, new LogInsertModule(SessionUtils.getUserId(), "/test-plan/api/scenario/disassociate", HttpMethodConstants.POST.name()));
|
||||
testPlanService.refreshTestPlanStatus(request.getTestPlanId());
|
||||
return response;
|
||||
}
|
||||
|
||||
|
@ -112,7 +111,6 @@ public class TestPlanApiScenarioController {
|
|||
@CheckOwner(resourceId = "#request.getTestPlanId()", resourceType = "test_plan")
|
||||
public TestPlanAssociationResponse batchDisassociate(@Validated @RequestBody BasePlanCaseBatchRequest request) {
|
||||
TestPlanAssociationResponse response = testPlanApiScenarioService.disassociate(request, new LogInsertModule(SessionUtils.getUserId(), "/test-plan/api/scenario/batch/disassociate", HttpMethodConstants.POST.name()));
|
||||
testPlanService.refreshTestPlanStatus(request.getTestPlanId());
|
||||
return response;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,10 +6,7 @@ import io.metersphere.plan.constants.TestPlanResourceConfig;
|
|||
import io.metersphere.plan.domain.TestPlan;
|
||||
import io.metersphere.plan.dto.TestPlanExecuteHisDTO;
|
||||
import io.metersphere.plan.dto.request.*;
|
||||
import io.metersphere.plan.dto.response.TestPlanDetailResponse;
|
||||
import io.metersphere.plan.dto.response.TestPlanOperationResponse;
|
||||
import io.metersphere.plan.dto.response.TestPlanResponse;
|
||||
import io.metersphere.plan.dto.response.TestPlanStatisticsResponse;
|
||||
import io.metersphere.plan.dto.response.*;
|
||||
import io.metersphere.plan.service.*;
|
||||
import io.metersphere.sdk.constants.HttpMethodConstants;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
|
@ -168,11 +165,8 @@ public class TestPlanController {
|
|||
@Operation(summary = "测试计划-复制测试计划")
|
||||
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_ADD)
|
||||
@CheckOwner(resourceId = "#id", resourceType = "test_plan")
|
||||
public TestPlanOperationResponse copy(@PathVariable String id) {
|
||||
long copyCount = testPlanService.copy(id, SessionUtils.getUserId());
|
||||
//copy完成之后的刷新一下状态
|
||||
testPlanService.refreshTestPlanStatus(id);
|
||||
return new TestPlanOperationResponse(copyCount);
|
||||
public TestPlanSingleOperationResponse copy(@PathVariable String id) {
|
||||
return new TestPlanSingleOperationResponse(testPlanService.copy(id, SessionUtils.getUserId()));
|
||||
}
|
||||
|
||||
@PostMapping("/batch-copy")
|
||||
|
@ -208,17 +202,6 @@ public class TestPlanController {
|
|||
testPlanService.batchArchived(request, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
@PostMapping(value = "/association")
|
||||
@Operation(summary = "测试计划功能用例-关联功能用例")
|
||||
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_ASSOCIATION)
|
||||
@CheckOwner(resourceId = "#request.getTestPlanId()", resourceType = "test_plan")
|
||||
public void association(@Validated @RequestBody TestPlanAssociationRequest request) {
|
||||
testPlanManagementService.checkModuleIsOpen(request.getTestPlanId(), TestPlanResourceConfig.CHECK_TYPE_TEST_PLAN, Collections.singletonList(TestPlanResourceConfig.CONFIG_TEST_PLAN_FUNCTIONAL_CASE));
|
||||
testPlanService.checkTestPlanNotArchived(request.getTestPlanId());
|
||||
testPlanService.association(request, SessionUtils.getUserId());
|
||||
testPlanService.refreshTestPlanStatus(request.getTestPlanId());
|
||||
}
|
||||
|
||||
@PostMapping("/batch-edit")
|
||||
@Operation(summary = "测试计划-批量编辑")
|
||||
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_UPDATE)
|
||||
|
@ -236,7 +219,7 @@ public class TestPlanController {
|
|||
@CheckOwner(resourceId = "#request.getMoveId()", resourceType = "test_plan")
|
||||
public TestPlanOperationResponse sortTestPlan(@Validated @RequestBody PosRequest request) {
|
||||
testPlanManagementService.checkModuleIsOpen(request.getMoveId(), TestPlanResourceConfig.CHECK_TYPE_TEST_PLAN, Collections.singletonList(TestPlanResourceConfig.CONFIG_TEST_PLAN));
|
||||
return testPlanService.sortInGroup(request, new LogInsertModule(SessionUtils.getUserId(), "/test-plan/move", HttpMethodConstants.POST.name()));
|
||||
return testPlanService.sort(request, new LogInsertModule(SessionUtils.getUserId(), "/test-plan/sort", HttpMethodConstants.POST.name()));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/schedule-config")
|
||||
|
|
|
@ -97,7 +97,6 @@ public class TestPlanFunctionalCaseController {
|
|||
batchRequest.setTestPlanId(request.getTestPlanId());
|
||||
batchRequest.setSelectIds(List.of(request.getId()));
|
||||
TestPlanAssociationResponse response = testPlanFunctionalCaseService.disassociate(batchRequest, new LogInsertModule(SessionUtils.getUserId(), "/test-plan/functional/case/disassociate", HttpMethodConstants.POST.name()));
|
||||
testPlanService.refreshTestPlanStatus(request.getTestPlanId());
|
||||
return response;
|
||||
}
|
||||
|
||||
|
@ -108,7 +107,6 @@ public class TestPlanFunctionalCaseController {
|
|||
public TestPlanAssociationResponse batchDisassociate(@Validated @RequestBody BasePlanCaseBatchRequest request) {
|
||||
testPlanManagementService.checkModuleIsOpen(request.getTestPlanId(), TestPlanResourceConfig.CHECK_TYPE_TEST_PLAN, Collections.singletonList(TestPlanResourceConfig.CONFIG_TEST_PLAN_FUNCTIONAL_CASE));
|
||||
TestPlanAssociationResponse response = testPlanFunctionalCaseService.disassociate(request, new LogInsertModule(SessionUtils.getUserId(), "/test-plan/functional/case/batch/disassociate", HttpMethodConstants.POST.name()));
|
||||
testPlanService.refreshTestPlanStatus(request.getTestPlanId());
|
||||
return response;
|
||||
}
|
||||
|
||||
|
@ -144,7 +142,6 @@ public class TestPlanFunctionalCaseController {
|
|||
public void run(@Validated @RequestBody TestPlanCaseRunRequest request) {
|
||||
testPlanFunctionalCaseService.run(request, new LogInsertModule(SessionUtils.getUserId(), "/test-plan/functional/case/run", HttpMethodConstants.POST.name()));
|
||||
testPlanService.setActualStartTime(request.getTestPlanId());
|
||||
testPlanService.refreshTestPlanStatus(request.getTestPlanId());
|
||||
}
|
||||
|
||||
@PostMapping("/batch/run")
|
||||
|
@ -154,7 +151,6 @@ public class TestPlanFunctionalCaseController {
|
|||
public void batchRun(@Validated @RequestBody TestPlanCaseBatchRunRequest request) {
|
||||
testPlanFunctionalCaseService.batchRun(request, new LogInsertModule(SessionUtils.getUserId(), "/test-plan/functional/case/batch/run", HttpMethodConstants.POST.name()));
|
||||
testPlanService.setActualStartTime(request.getTestPlanId());
|
||||
testPlanService.refreshTestPlanStatus(request.getTestPlanId());
|
||||
}
|
||||
|
||||
@PostMapping("/has/associate/bug/page")
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package io.metersphere.plan.dto.response;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TestPlanSingleOperationResponse {
|
||||
@Schema(description = "处理成功的ID")
|
||||
private String operationId;
|
||||
}
|
|
@ -57,6 +57,8 @@ public interface ExtTestPlanMapper {
|
|||
|
||||
long selectMaxPosByGroupId(String groupId);
|
||||
|
||||
long selectMaxPosByProjectIdAndGroupId(@Param("projectId") String projectId, @Param("groupId") String groupId);
|
||||
|
||||
List<TestPlanResponse> selectByGroupIds(@Param("groupIds") List<String> groupIds);
|
||||
|
||||
List<String> selectRightfulIdsForExecute(@Param("ids") List<String> ids);
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
<foreach collection="groupIds" item="groupId" separator="," open="(" close=")">
|
||||
#{groupId}
|
||||
</foreach>
|
||||
ORDER BY t.pos ASC
|
||||
ORDER BY t.pos DESC
|
||||
</select>
|
||||
|
||||
<sql id="queryByTableRequest">
|
||||
|
@ -452,6 +452,12 @@
|
|||
FROM test_plan
|
||||
WHERE group_id = #{0}
|
||||
</select>
|
||||
<select id="selectMaxPosByProjectIdAndGroupId" resultType="java.lang.Long">
|
||||
SELECT IF(MAX(pos) IS NULL, 0, MAX(pos)) AS pos
|
||||
FROM test_plan
|
||||
WHERE project_id = #{projectId}
|
||||
AND group_id = #{groupId}
|
||||
</select>
|
||||
<select id="selectRightfulIdsForExecute" resultType="java.lang.String">
|
||||
SELECT id FROM test_plan WHERE id IN
|
||||
<foreach collection="ids" item="id" open="(" separator="," close=")">
|
||||
|
|
|
@ -85,7 +85,6 @@ public class TestPlanApiCaseBatchRunService {
|
|||
*/
|
||||
public void asyncBatchRun(TestPlanApiCaseBatchRunRequest request, String userId) {
|
||||
TestPlanService testPlanService = CommonBeanFactory.getBean(TestPlanService.class);
|
||||
testPlanService.setTestPlanUnderway(request.getTestPlanId());
|
||||
testPlanService.setActualStartTime(request.getTestPlanId());
|
||||
Thread.startVirtualThread(() -> batchRun(request, userId));
|
||||
}
|
||||
|
|
|
@ -683,7 +683,6 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
|
|||
public TaskRequestDTO run(String id, String reportId, String userId) {
|
||||
TestPlanApiCase testPlanApiCase = checkResourceExist(id);
|
||||
TestPlanService testPlanService = CommonBeanFactory.getBean(TestPlanService.class);
|
||||
testPlanService.setTestPlanUnderway(testPlanApiCase.getTestPlanId());
|
||||
testPlanService.setActualStartTime(testPlanApiCase.getTestPlanId());
|
||||
ApiTestCase apiTestCase = apiTestCaseService.checkResourceExist(testPlanApiCase.getApiCaseId());
|
||||
ApiRunModeConfigDTO runModeConfig = testPlanApiBatchRunBaseService.getApiRunModeConfig(testPlanApiCase.getTestPlanCollectionId());
|
||||
|
|
|
@ -85,7 +85,6 @@ public class TestPlanApiScenarioBatchRunService {
|
|||
public void asyncBatchRun(TestPlanApiScenarioBatchRunRequest request, String userId) {
|
||||
TestPlanService testPlanService = CommonBeanFactory.getBean(TestPlanService.class);
|
||||
testPlanService.setActualStartTime(request.getTestPlanId());
|
||||
testPlanService.setTestPlanUnderway(request.getTestPlanId());
|
||||
Thread.startVirtualThread(() -> batchRun(request, userId));
|
||||
}
|
||||
|
||||
|
|
|
@ -287,7 +287,6 @@ public class TestPlanApiScenarioService extends TestPlanResourceService {
|
|||
public TaskRequestDTO run(String id, String reportId, String userId) {
|
||||
TestPlanApiScenario testPlanApiScenario = checkResourceExist(id);
|
||||
TestPlanService testPlanService = CommonBeanFactory.getBean(TestPlanService.class);
|
||||
testPlanService.setTestPlanUnderway(testPlanApiScenario.getTestPlanId());
|
||||
testPlanService.setActualStartTime(testPlanApiScenario.getTestPlanId());
|
||||
ApiScenario apiScenario = apiScenarioService.checkResourceExist(testPlanApiScenario.getApiScenarioId());
|
||||
ApiRunModeConfigDTO runModeConfig = testPlanApiBatchRunBaseService.getApiRunModeConfig(testPlanApiScenario.getTestPlanCollectionId());
|
||||
|
|
|
@ -1,29 +1,17 @@
|
|||
package io.metersphere.plan.service;
|
||||
|
||||
import io.metersphere.plan.domain.TestPlan;
|
||||
import io.metersphere.plan.dto.ResourceLogInsertModule;
|
||||
import io.metersphere.plan.dto.TestPlanResourceAssociationParam;
|
||||
import io.metersphere.plan.dto.request.BaseAssociateCaseRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanAssociationRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanBatchProcessRequest;
|
||||
import io.metersphere.plan.mapper.ExtTestPlanMapper;
|
||||
import io.metersphere.plan.mapper.TestPlanMapper;
|
||||
import io.metersphere.sdk.constants.HttpMethodConstants;
|
||||
import io.metersphere.sdk.constants.ModuleConstants;
|
||||
import io.metersphere.sdk.constants.TestPlanResourceConstants;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.domain.TestPlanModuleExample;
|
||||
import io.metersphere.system.dto.LogInsertModule;
|
||||
import io.metersphere.system.mapper.TestPlanModuleMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class TestPlanBaseUtilsService {
|
||||
|
@ -35,8 +23,6 @@ public class TestPlanBaseUtilsService {
|
|||
@Resource
|
||||
private ExtTestPlanMapper extTestPlanMapper;
|
||||
@Resource
|
||||
private TestPlanCaseService testPlanCaseService;
|
||||
@Resource
|
||||
private TestPlanResourceLogService testPlanResourceLogService;
|
||||
|
||||
/**
|
||||
|
@ -54,58 +40,4 @@ public class TestPlanBaseUtilsService {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取选择的计划id集合
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public List<String> getSelectIds(TestPlanBatchProcessRequest request) {
|
||||
if (request.isSelectAll()) {
|
||||
List<String> ids = extTestPlanMapper.selectIdByConditions(request);
|
||||
if (org.apache.commons.collections.CollectionUtils.isNotEmpty(request.getExcludeIds())) {
|
||||
ids.removeAll(request.getExcludeIds());
|
||||
}
|
||||
return ids;
|
||||
} else {
|
||||
return request.getSelectIds();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联用例
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
//TODO 后续删除此方法以及调用controlle 后续改成通过计划集保存用例
|
||||
public void association(TestPlanAssociationRequest request, String operator) {
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getTestPlanId());
|
||||
handleAssociateCase(request, operator, testPlan);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理关联的用例
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public void handleAssociateCase(BaseAssociateCaseRequest request, String operator, TestPlan testPlan) {
|
||||
//关联的功能用例
|
||||
handleFunctionalCase(request.getFunctionalSelectIds(), operator, testPlan);
|
||||
//TODO 关联接口用例/接口场景用例 handleApi(request.getApiSelectIds(),request.getApiCaseSelectIds())
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联的功能用例
|
||||
*
|
||||
* @param functionalSelectIds
|
||||
*/
|
||||
private void handleFunctionalCase(List<String> functionalSelectIds, String operator, TestPlan testPlan) {
|
||||
if (CollectionUtils.isNotEmpty(functionalSelectIds)) {
|
||||
TestPlanResourceAssociationParam associationParam = new TestPlanResourceAssociationParam(functionalSelectIds, testPlan.getProjectId(), testPlan.getId(), testPlan.getNum(), testPlan.getCreateUser());
|
||||
testPlanCaseService.saveTestPlanResource(associationParam);
|
||||
testPlanResourceLogService.saveAssociateLog(testPlan, new ResourceLogInsertModule(TestPlanResourceConstants.RESOURCE_FUNCTIONAL_CASE, new LogInsertModule(operator, "/test-plan/association", HttpMethodConstants.POST.name())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ public class TestPlanBatchOperationService extends TestPlanBaseUtilsService {
|
|||
testPlanGroupService.validateGroupCapacity(targetId, copyPlanList.size());
|
||||
}
|
||||
/*
|
||||
此处不选择批量操作,原因有两点:
|
||||
此处不进行批量处理,原因有两点:
|
||||
1) 测试计划内(或者测试计划组内)数据量不可控,选择批量操作时更容易出现数据太多不走索引、数据太多内存溢出等问题。不批量操作可以减少这些问题出现的概率,代价是速度会变慢。
|
||||
2) 作为数据量不可控的操作,如果数据量少,不采用批量处理也不会消耗太多时间。如果数据量多,就会容易出现1的问题。并且本人不建议针对不可控数据量的数据支持批量操作。
|
||||
*/
|
||||
|
@ -168,15 +168,12 @@ public class TestPlanBatchOperationService extends TestPlanBaseUtilsService {
|
|||
String groupId = originalTestPlan.getGroupId();
|
||||
long pos = originalTestPlan.getPos();
|
||||
if (StringUtils.equals(targetType, TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
|
||||
if (StringUtils.equalsIgnoreCase(targetId, TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||
pos = 0L;
|
||||
} else {
|
||||
if (!StringUtils.equalsIgnoreCase(targetId, TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||
TestPlan group = testPlanMapper.selectByPrimaryKey(targetId);
|
||||
//如果目标ID是测试计划组, 需要进行容量校验
|
||||
if (!StringUtils.equalsIgnoreCase(targetType, ModuleConstants.NODE_TYPE_DEFAULT)) {
|
||||
testPlanGroupService.validateGroupCapacity(targetId, 1);
|
||||
}
|
||||
pos = testPlanGroupService.getNextOrder(targetId);
|
||||
moduleId = group.getModuleId();
|
||||
}
|
||||
groupId = targetId;
|
||||
|
@ -196,7 +193,7 @@ public class TestPlanBatchOperationService extends TestPlanBaseUtilsService {
|
|||
testPlan.setUpdateTime(operatorTime);
|
||||
testPlan.setModuleId(moduleId);
|
||||
testPlan.setGroupId(groupId);
|
||||
testPlan.setPos(pos);
|
||||
testPlan.setPos(testPlanGroupService.getNextOrder(targetId));
|
||||
testPlan.setActualEndTime(null);
|
||||
testPlan.setActualStartTime(null);
|
||||
testPlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_PREPARED);
|
||||
|
@ -286,6 +283,7 @@ public class TestPlanBatchOperationService extends TestPlanBaseUtilsService {
|
|||
testPlanGroup.setUpdateUser(operator);
|
||||
testPlanGroup.setUpdateTime(operatorTime);
|
||||
testPlanGroup.setModuleId(moduleId);
|
||||
testPlanGroup.setPos(testPlanGroupService.getNextOrder(originalGroup.getGroupId()));
|
||||
testPlanGroup.setActualEndTime(null);
|
||||
testPlanGroup.setActualStartTime(null);
|
||||
testPlanGroup.setStatus(TestPlanConstants.TEST_PLAN_STATUS_PREPARED);
|
||||
|
|
|
@ -1,110 +0,0 @@
|
|||
package io.metersphere.plan.service;
|
||||
|
||||
import io.metersphere.plan.domain.TestPlan;
|
||||
import io.metersphere.plan.domain.TestPlanFunctionalCase;
|
||||
import io.metersphere.plan.domain.TestPlanFunctionalCaseExample;
|
||||
import io.metersphere.plan.dto.TestPlanResourceAssociationParam;
|
||||
import io.metersphere.plan.mapper.ExtTestPlanFunctionalCaseMapper;
|
||||
import io.metersphere.plan.mapper.TestPlanFunctionalCaseMapper;
|
||||
import io.metersphere.sdk.constants.ExecStatus;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import io.metersphere.system.utils.ServiceUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class TestPlanCaseService {
|
||||
|
||||
@Resource
|
||||
private TestPlanFunctionalCaseMapper testPlanFunctionalCaseMapper;
|
||||
@Resource
|
||||
private ExtTestPlanFunctionalCaseMapper extTestPlanFunctionalCaseMapper;
|
||||
|
||||
|
||||
public void saveTestPlanResource(@Validated TestPlanResourceAssociationParam associationParam) {
|
||||
long pox = this.getNextOrder(associationParam.getTestPlanId());
|
||||
long now = System.currentTimeMillis();
|
||||
List<TestPlanFunctionalCase> testPlanFunctionalCaseList = new ArrayList<>();
|
||||
List<String> associationIdList = associationParam.getResourceIdList();
|
||||
// 批量添加时,按照列表顺序进行展示。所以这里将集合倒叙排列
|
||||
Collections.reverse(associationIdList);
|
||||
for (int i = 0; i < associationIdList.size(); i++) {
|
||||
TestPlanFunctionalCase testPlanFunctionalCase = new TestPlanFunctionalCase();
|
||||
testPlanFunctionalCase.setId(IDGenerator.nextStr());
|
||||
testPlanFunctionalCase.setTestPlanId(associationParam.getTestPlanId());
|
||||
testPlanFunctionalCase.setFunctionalCaseId(associationIdList.get(i));
|
||||
testPlanFunctionalCase.setPos(pox);
|
||||
testPlanFunctionalCase.setCreateTime(now);
|
||||
testPlanFunctionalCase.setCreateUser(associationParam.getOperator());
|
||||
testPlanFunctionalCase.setLastExecResult(ExecStatus.PENDING.name());
|
||||
testPlanFunctionalCase.setExecuteUser(associationParam.getOperator());
|
||||
testPlanFunctionalCaseList.add(testPlanFunctionalCase);
|
||||
// TODO 关联逻辑后续改进 默认先写死
|
||||
testPlanFunctionalCase.setTestPlanCollectionId("NONE");
|
||||
pox += ServiceUtils.POS_STEP;
|
||||
}
|
||||
testPlanFunctionalCaseMapper.batchInsert(testPlanFunctionalCaseList);
|
||||
}
|
||||
|
||||
|
||||
public long getNextOrder(String testPlanId) {
|
||||
Long maxPos = extTestPlanFunctionalCaseMapper.getMaxPosByTestPlanId(testPlanId);
|
||||
if (maxPos == null) {
|
||||
//默认返回POS_STEP,不能直接返回0, 否则无法进行“前置”排序
|
||||
return ServiceUtils.POS_STEP;
|
||||
} else {
|
||||
return maxPos + ServiceUtils.POS_STEP;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 复制计划时,复制功能用例
|
||||
*
|
||||
* @param ids
|
||||
* @param testPlan
|
||||
*/
|
||||
public void saveTestPlanByPlanId(List<String> ids, TestPlan testPlan) {
|
||||
TestPlanFunctionalCaseExample example = new TestPlanFunctionalCaseExample();
|
||||
example.createCriteria().andTestPlanIdIn(ids);
|
||||
List<TestPlanFunctionalCase> testPlanFunctionalCases = testPlanFunctionalCaseMapper.selectByExample(example);
|
||||
if (CollectionUtils.isNotEmpty(testPlanFunctionalCases)) {
|
||||
Map<String, List<TestPlanFunctionalCase>> collect = testPlanFunctionalCases.stream().collect(Collectors.groupingBy(TestPlanFunctionalCase::getTestPlanId));
|
||||
List<TestPlanFunctionalCase> associateList = new ArrayList<>();
|
||||
ids.forEach(id -> {
|
||||
if (collect.containsKey(id)) {
|
||||
saveCase(collect.get(id), associateList, testPlan, id);
|
||||
}
|
||||
});
|
||||
testPlanFunctionalCaseMapper.batchInsert(associateList);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveCase(List<TestPlanFunctionalCase> testPlanFunctionalCases, List<TestPlanFunctionalCase> associateList, TestPlan testPlan, String id) {
|
||||
AtomicLong pos = new AtomicLong(this.getNextOrder(id));
|
||||
testPlanFunctionalCases.forEach(item -> {
|
||||
TestPlanFunctionalCase functionalCase = new TestPlanFunctionalCase();
|
||||
functionalCase.setTestPlanId(testPlan.getId());
|
||||
functionalCase.setId(IDGenerator.nextStr());
|
||||
functionalCase.setCreateTime(System.currentTimeMillis());
|
||||
functionalCase.setCreateUser(testPlan.getCreateUser());
|
||||
functionalCase.setFunctionalCaseId(item.getFunctionalCaseId());
|
||||
functionalCase.setPos(pos.get());
|
||||
associateList.add(functionalCase);
|
||||
pos.updateAndGet(v -> v + ServiceUtils.POS_STEP);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -245,8 +245,6 @@ public class TestPlanCollectionMinderService {
|
|||
beansOfType.forEach((k, v) -> {
|
||||
v.associateCollection(request.getPlanId(), associateMap, user);
|
||||
});
|
||||
//更新测试计划
|
||||
testPlanService.refreshTestPlanStatus(request.getPlanId());
|
||||
}
|
||||
|
||||
private void dealEditList(TestPlanCollectionMinderEditRequest request, String userId, Map<String, List<BaseCollectionAssociateRequest>> associateMap) {
|
||||
|
|
|
@ -79,13 +79,6 @@ public class TestPlanExecuteSupportService {
|
|||
postParam.setEndTime(System.currentTimeMillis());
|
||||
postParam.setExecStatus(isStop ? ExecStatus.STOPPED.name() : ExecStatus.COMPLETED.name());
|
||||
testPlanReportService.postHandleReport(postParam, false);
|
||||
|
||||
if (!isGroupReport) {
|
||||
TestPlanReport testPlanReport = testPlanReportService.selectById(reportId);
|
||||
if (testPlanReport != null) {
|
||||
testPlanService.refreshTestPlanStatus(testPlanReport.getTestPlanId());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtils.error("测试计划报告汇总失败!reportId:" + reportId, e);
|
||||
TestPlanReport stopReport = testPlanReportService.selectById(reportId);
|
||||
|
|
|
@ -8,7 +8,6 @@ import io.metersphere.project.dto.MoveNodeSortDTO;
|
|||
import io.metersphere.sdk.constants.TestPlanConstants;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.dto.sdk.enums.MoveTypeEnum;
|
||||
import io.metersphere.system.dto.sdk.request.PosRequest;
|
||||
import io.metersphere.system.utils.ServiceUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
|
@ -44,10 +43,18 @@ public class TestPlanGroupService extends TestPlanSortService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void refreshPos(String groupId) {
|
||||
public void refreshPos(String rangeId) {
|
||||
TestPlanExample testPlanExample = new TestPlanExample();
|
||||
testPlanExample.createCriteria().andGroupIdEqualTo(groupId);
|
||||
testPlanExample.setOrderByClause("pos asc");
|
||||
if (StringUtils.contains(rangeId, "_")) {
|
||||
String[] rangeIds = rangeId.split("_");
|
||||
String projectId = rangeIds[0];
|
||||
String testPlanGroupId = rangeIds[1];
|
||||
testPlanExample.createCriteria().andProjectIdEqualTo(projectId).andGroupIdEqualTo(testPlanGroupId);
|
||||
} else {
|
||||
testPlanExample.createCriteria().andGroupIdEqualTo(rangeId);
|
||||
}
|
||||
|
||||
List<TestPlan> testPlans = testPlanMapper.selectByExample(testPlanExample);
|
||||
long pos = 1;
|
||||
for (TestPlan testPlanItem : testPlans) {
|
||||
|
@ -64,42 +71,50 @@ public class TestPlanGroupService extends TestPlanSortService {
|
|||
validateMoveRequest(dropPlan, targetPlan, request.getMoveMode());
|
||||
MoveNodeSortDTO sortDTO = super.getNodeSortDTO(
|
||||
targetPlan.getGroupId(),
|
||||
this.getNodeMoveRequest(request, false),
|
||||
this.getNodeMoveRequest(request, true),
|
||||
extTestPlanMapper::selectDragInfoById,
|
||||
extTestPlanMapper::selectNodeByPosOperator
|
||||
);
|
||||
|
||||
if (StringUtils.equalsIgnoreCase(sortDTO.getSortRangeId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||
sortDTO.setSortRangeId(request.getProjectId() + "_" + TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID);
|
||||
}
|
||||
//判断是否需要刷新排序
|
||||
if (this.needRefreshBeforeSort(sortDTO.getPreviousNode(), sortDTO.getNextNode())) {
|
||||
this.refreshPos(sortDTO.getSortRangeId());
|
||||
dropPlan = testPlanMapper.selectByPrimaryKey(request.getMoveId());
|
||||
targetPlan = testPlanMapper.selectByPrimaryKey(request.getTargetId());
|
||||
sortDTO = super.getNodeSortDTO(
|
||||
targetPlan.getGroupId(),
|
||||
this.getNodeMoveRequest(request, true),
|
||||
extTestPlanMapper::selectDragInfoById,
|
||||
extTestPlanMapper::selectNodeByPosOperator
|
||||
);
|
||||
if (StringUtils.equalsIgnoreCase(sortDTO.getSortRangeId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||
sortDTO.setSortRangeId(request.getProjectId() + "_" + TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID);
|
||||
}
|
||||
}
|
||||
this.sort(sortDTO);
|
||||
}
|
||||
|
||||
private void validateMoveRequest(TestPlan dropPlan, TestPlan targetPlan, String moveType) {
|
||||
//测试计划组不能进行移动操作
|
||||
if (dropPlan == null || StringUtils.equalsIgnoreCase(dropPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
|
||||
if (dropPlan == null) {
|
||||
throw new MSException(Translator.get("test_plan.drag.node.error"));
|
||||
}
|
||||
if (targetPlan == null || StringUtils.equalsIgnoreCase(targetPlan.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||
if (targetPlan == null) {
|
||||
throw new MSException(Translator.get("test_plan.drag.node.error"));
|
||||
}
|
||||
if (StringUtils.equalsIgnoreCase(MoveTypeEnum.APPEND.name(), moveType)) {
|
||||
if (!StringUtils.equalsIgnoreCase(targetPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
|
||||
throw new MSException(Translator.get("test_plan.drag.node.error"));
|
||||
}
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(moveType, MoveTypeEnum.BEFORE.name(), MoveTypeEnum.AFTER.name())) {
|
||||
if (StringUtils.equalsAny(TestPlanConstants.TEST_PLAN_TYPE_GROUP, dropPlan.getType())) {
|
||||
throw new MSException(Translator.get("test_plan.drag.node.error"));
|
||||
}
|
||||
} else {
|
||||
throw new MSException(Translator.get("test_plan.drag.position.error"));
|
||||
}
|
||||
}
|
||||
|
||||
public void validateGroupCapacity(String groupId, int size) {
|
||||
if (!StringUtils.equals(groupId, TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||
public TestPlan validateGroupCapacity(String groupId, int size) {
|
||||
// 判断测试计划组是否存在
|
||||
TestPlan groupPlan = testPlanMapper.selectByPrimaryKey(groupId);
|
||||
if (groupPlan == null) {
|
||||
throw new MSException(Translator.get("test_plan.group.error"));
|
||||
}
|
||||
if (!StringUtils.equalsIgnoreCase(groupPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
|
||||
throw new MSException(Translator.get("test_plan.group.error"));
|
||||
}
|
||||
//判断并未归档
|
||||
if (StringUtils.equalsIgnoreCase(groupPlan.getStatus(), TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED)) {
|
||||
throw new MSException(Translator.get("test_plan.group.error"));
|
||||
|
@ -110,6 +125,6 @@ public class TestPlanGroupService extends TestPlanSortService {
|
|||
if (testPlanMapper.countByExample(example) + size > 20) {
|
||||
throw new MSException(Translator.getWithArgs("test_plan.group.children.max", MAX_CHILDREN_COUNT));
|
||||
}
|
||||
}
|
||||
return groupPlan;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ public class TestPlanManagementService {
|
|||
public Pager<List<TestPlanResponse>> page(TestPlanTableRequest request) {
|
||||
this.initDefaultFilter(request);
|
||||
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
|
||||
MapUtils.isEmpty(request.getSort()) ? "t.num desc" : request.getSortString());
|
||||
MapUtils.isEmpty(request.getSort()) ? "t.pos desc, t.id desc" : request.getSortString("id", "t"));
|
||||
return PageUtils.setPageInfo(page, this.list(request));
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ public class TestPlanManagementService {
|
|||
public List<TestPlan> groupList(String projectId) {
|
||||
TestPlanExample example = new TestPlanExample();
|
||||
example.createCriteria().andTypeEqualTo(TestPlanConstants.TEST_PLAN_TYPE_GROUP).andProjectIdEqualTo(projectId).andStatusNotEqualTo(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED);
|
||||
example.setOrderByClause("num desc");
|
||||
example.setOrderByClause("pos desc, id desc");
|
||||
return testPlanMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,10 +34,10 @@ import io.metersphere.system.schedule.ScheduleService;
|
|||
import io.metersphere.system.uid.IDGenerator;
|
||||
import io.metersphere.system.uid.NumGenerator;
|
||||
import io.metersphere.system.utils.BatchProcessUtils;
|
||||
import io.metersphere.system.utils.ServiceUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.ListUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
|
@ -78,8 +78,6 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
@Resource
|
||||
private TestPlanStatisticsService testPlanStatisticsService;
|
||||
@Resource
|
||||
private TestPlanCaseService testPlanCaseService;
|
||||
@Resource
|
||||
private ScheduleMapper scheduleMapper;
|
||||
@Resource
|
||||
SqlSessionFactory sqlSessionFactory;
|
||||
|
@ -115,11 +113,6 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
//自动生成测试规划
|
||||
this.initDefaultPlanCollection(testPlan.getId(), operator);
|
||||
|
||||
if (!StringUtils.equalsIgnoreCase(testPlan.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||
//更新计划组状态
|
||||
this.updateTestPlanGroupStatus(testPlan.getGroupId());
|
||||
}
|
||||
|
||||
testPlanLogService.saveAddLog(testPlan, operator, requestUrl, requestMethod);
|
||||
return testPlan;
|
||||
}
|
||||
|
@ -142,11 +135,11 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
|
||||
TestPlan createTestPlan = new TestPlan();
|
||||
BeanUtils.copyBean(createTestPlan, createOrCopyRequest);
|
||||
testPlanGroupService.validateGroupCapacity(createTestPlan.getGroupId(), 1);
|
||||
|
||||
if (!StringUtils.equals(createTestPlan.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||
TestPlan groupPlan = testPlanGroupService.validateGroupCapacity(createTestPlan.getGroupId(), 1);
|
||||
// 判断测试计划组是否存在
|
||||
createTestPlan.setModuleId(testPlanMapper.selectByPrimaryKey(createTestPlan.getGroupId()).getModuleId());
|
||||
createTestPlan.setModuleId(groupPlan.getModuleId());
|
||||
}
|
||||
|
||||
initTestPlanPos(createTestPlan);
|
||||
|
@ -171,15 +164,21 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
return createTestPlan;
|
||||
}
|
||||
|
||||
|
||||
//校验测试计划
|
||||
private void initTestPlanPos(TestPlan createTestPlan) {
|
||||
if (!StringUtils.equals(createTestPlan.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||
createTestPlan.setPos(testPlanGroupService.getNextOrder(createTestPlan.getGroupId()));
|
||||
if (StringUtils.equals(createTestPlan.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||
createTestPlan.setPos(this.getNextOrder(createTestPlan.getProjectId(), createTestPlan.getGroupId()));
|
||||
} else {
|
||||
createTestPlan.setPos(0L);
|
||||
createTestPlan.setPos(testPlanGroupService.getNextOrder(createTestPlan.getGroupId()));
|
||||
}
|
||||
}
|
||||
|
||||
public long getNextOrder(String projectId, String groupId) {
|
||||
long maxPos = extTestPlanMapper.selectMaxPosByProjectIdAndGroupId(projectId, groupId);
|
||||
return maxPos + ServiceUtils.POS_STEP;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除测试计划
|
||||
*/
|
||||
|
@ -192,11 +191,6 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
//级联删除
|
||||
TestPlanReportService testPlanReportService = CommonBeanFactory.getBean(TestPlanReportService.class);
|
||||
this.cascadeDeleteTestPlanIds(Collections.singletonList(id), testPlanReportService);
|
||||
|
||||
if (!StringUtils.equalsIgnoreCase(testPlan.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||
//更新计划组状态
|
||||
this.updateTestPlanGroupStatus(testPlan.getGroupId());
|
||||
}
|
||||
}
|
||||
//记录日志
|
||||
testPlanLogService.saveDeleteLog(testPlan, operator, requestUrl, requestMethod);
|
||||
|
@ -319,43 +313,51 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
*/
|
||||
public TestPlan update(TestPlanUpdateRequest request, String userId, String requestUrl, String requestMethod) {
|
||||
this.checkTestPlanNotArchived(request.getId());
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getId());
|
||||
String testPlanGroup = testPlan.getGroupId();
|
||||
if (!ObjectUtils.allNull(request.getName(), request.getModuleId(), request.getTags(), request.getPlannedEndTime(), request.getPlannedStartTime(), request.getDescription(), request.getGroupId())) {
|
||||
TestPlan originalTestPlan = testPlanMapper.selectByPrimaryKey(request.getId());
|
||||
|
||||
TestPlan updateTestPlan = new TestPlan();
|
||||
updateTestPlan.setId(request.getId());
|
||||
if (StringUtils.isNotBlank(request.getModuleId())) {
|
||||
//检查模块的合法性
|
||||
checkModule(request.getModuleId());
|
||||
updateTestPlan.setModuleId(request.getModuleId());
|
||||
//移动模块时重置GroupId
|
||||
updateTestPlan.setGroupId(TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID);
|
||||
}
|
||||
if (StringUtils.isNotBlank(request.getGroupId()) && !StringUtils.equalsIgnoreCase(request.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||
//移动测试计划到测试计划组中,删除定时任务
|
||||
updateTestPlan.setGroupId(request.getGroupId());
|
||||
this.deleteScheduleConfig(request.getId());
|
||||
}
|
||||
if (StringUtils.isNotBlank(request.getName())) {
|
||||
updateTestPlan.setName(request.getName());
|
||||
updateTestPlan.setProjectId(testPlan.getProjectId());
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(request.getTags())) {
|
||||
updateTestPlan.setTags(new ArrayList<>(request.getTags()));
|
||||
} else {
|
||||
updateTestPlan.setTags(new ArrayList<>());
|
||||
}
|
||||
updateTestPlan.setPlannedStartTime(request.getPlannedStartTime());
|
||||
updateTestPlan.setPlannedEndTime(request.getPlannedEndTime());
|
||||
updateTestPlan.setDescription(request.getDescription());
|
||||
//判断有没有用户组的变化
|
||||
if (StringUtils.isNotBlank(request.getGroupId())) {
|
||||
if (!StringUtils.equalsIgnoreCase(originalTestPlan.getGroupId(), request.getGroupId())) {
|
||||
//用户更换了测试计划组
|
||||
TestPlan testPlanGroup = testPlanGroupService.validateGroupCapacity(request.getGroupId(), 1);
|
||||
updateTestPlan.setGroupId(testPlanGroup.getId());
|
||||
this.deleteScheduleConfig(request.getId());
|
||||
updateTestPlan.setPos(testPlanGroupService.getNextOrder(request.getGroupId()));
|
||||
updateTestPlan.setModuleId(testPlanGroup.getModuleId());
|
||||
}
|
||||
} else {
|
||||
request.setGroupId(TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID);
|
||||
if (!StringUtils.equalsIgnoreCase(originalTestPlan.getGroupId(), request.getGroupId())) {
|
||||
//移出了测试计划组
|
||||
this.deleteScheduleConfig(request.getId());
|
||||
updateTestPlan.setPos(testPlanGroupService.getNextOrder(request.getGroupId()));
|
||||
}
|
||||
}
|
||||
//判断有没有模块的变化
|
||||
if (StringUtils.isNotBlank(request.getModuleId())) {
|
||||
if (!StringUtils.equalsIgnoreCase(request.getModuleId(), originalTestPlan.getModuleId())) {
|
||||
//检查模块的合法性
|
||||
checkModule(request.getModuleId());
|
||||
updateTestPlan.setModuleId(request.getModuleId());
|
||||
}
|
||||
}
|
||||
|
||||
//判断标签的变化
|
||||
if (CollectionUtils.isNotEmpty(request.getTags())) {
|
||||
List<String> tags = new ArrayList<>(request.getTags());
|
||||
this.checkTagsLength(tags);
|
||||
updateTestPlan.setTags(tags);
|
||||
} else {
|
||||
updateTestPlan.setTags(new ArrayList<>());
|
||||
}
|
||||
updateTestPlan.setType(testPlan.getType());
|
||||
testPlanMapper.updateByPrimaryKeySelective(updateTestPlan);
|
||||
}
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(updateTestPlan.getId());
|
||||
|
||||
if (!ObjectUtils.allNull(request.getAutomaticStatusUpdate(), request.getRepeatCase(), request.getPassThreshold(), request.getTestPlanning())) {
|
||||
TestPlanConfig testPlanConfig = new TestPlanConfig();
|
||||
|
@ -366,11 +368,8 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
testPlanConfigMapper.updateByPrimaryKeySelective(testPlanConfig);
|
||||
}
|
||||
|
||||
if (!StringUtils.equalsIgnoreCase(testPlanGroup, TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||
this.updateTestPlanGroupStatus(testPlanGroup);
|
||||
}
|
||||
testPlanLogService.saveUpdateLog(testPlan, testPlanMapper.selectByPrimaryKey(request.getId()), testPlan.getProjectId(), userId, requestUrl, requestMethod);
|
||||
return testPlan;
|
||||
return updateTestPlan;
|
||||
}
|
||||
|
||||
|
||||
|
@ -466,7 +465,7 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
/**
|
||||
* 复制测试计划
|
||||
*/
|
||||
public long copy(String testPlanId, String userId) {
|
||||
public String copy(String testPlanId, String userId) {
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(testPlanId);
|
||||
TestPlan copyPlan = null;
|
||||
if (StringUtils.equalsIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
|
||||
|
@ -475,7 +474,7 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
copyPlan = testPlanBatchOperationService.copyPlan(testPlan, testPlan.getGroupId(), TestPlanConstants.TEST_PLAN_TYPE_GROUP, System.currentTimeMillis(), userId);
|
||||
}
|
||||
testPlanLogService.copyLog(copyPlan, userId);
|
||||
return 1;
|
||||
return copyPlan.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -573,15 +572,6 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
}
|
||||
|
||||
|
||||
public String getModuleName(String id) {
|
||||
if (ModuleConstants.DEFAULT_NODE_ID.equals(id)) {
|
||||
return Translator.get("unplanned.plan");
|
||||
}
|
||||
TestPlanModule module = testPlanModuleMapper.selectByPrimaryKey(id);
|
||||
return module == null ? StringUtils.EMPTY : module.getName();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量复制 (计划/计划组)
|
||||
*
|
||||
|
@ -636,7 +626,9 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
moveTestPlanList = moveTestPlanList.stream().filter(
|
||||
item -> StringUtils.equalsIgnoreCase(item.getType(), TestPlanConstants.TEST_PLAN_TYPE_PLAN) && !StringUtils.equalsIgnoreCase(item.getGroupId(), request.getTargetId())
|
||||
).collect(Collectors.toList());
|
||||
if (!StringUtils.equalsIgnoreCase(request.getTargetId(), TestPlanConstants.DEFAULT_PARENT_ID)) {
|
||||
testPlanGroupService.validateGroupCapacity(request.getTargetId(), moveTestPlanList.size());
|
||||
}
|
||||
moveCount = testPlanBatchOperationService.batchMoveGroup(moveTestPlanList, request.getTargetId(), userId);
|
||||
} else {
|
||||
moveCount = testPlanBatchOperationService.batchMoveModule(moveTestPlanList, request.getTargetId(), userId);
|
||||
|
@ -769,10 +761,6 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
public void setTestPlanUnderway(String testPlanId) {
|
||||
this.updateTestPlanStatusAndGroupStatus(testPlanId, TestPlanConstants.TEST_PLAN_STATUS_UNDERWAY);
|
||||
}
|
||||
|
||||
public void setActualStartTime(String testPlanId) {
|
||||
long actualStartTime = System.currentTimeMillis();
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(testPlanId);
|
||||
|
@ -784,92 +772,38 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
}
|
||||
}
|
||||
|
||||
private void updateTestPlanStatusAndGroupStatus(String testPlanId, String testPlanStatus) {
|
||||
TestPlan testPlan = new TestPlan();
|
||||
testPlan.setId(testPlanId);
|
||||
testPlan.setStatus(testPlanStatus);
|
||||
testPlanMapper.updateByPrimaryKeySelective(testPlan);
|
||||
|
||||
testPlan = testPlanMapper.selectByPrimaryKey(testPlanId);
|
||||
if (!StringUtils.equalsIgnoreCase(testPlan.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||
this.updateTestPlanGroupStatus(testPlan.getGroupId());
|
||||
}
|
||||
}
|
||||
// private void updateTestPlanStatus(String testPlanId) {
|
||||
// Map<String, Long> caseExecResultCount = new HashMap<>();
|
||||
// Map<String, TestPlanResourceService> beansOfType = applicationContext.getBeansOfType(TestPlanResourceService.class);
|
||||
// beansOfType.forEach((k, v) -> {
|
||||
// Map<String, Long> map = v.caseExecResultCount(testPlanId);
|
||||
// map.forEach((key, value) -> {
|
||||
// if (value != 0) {
|
||||
// caseExecResultCount.merge(key, value, Long::sum);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// String testPlanFinalStatus = TestPlanConstants.TEST_PLAN_STATUS_UNDERWAY;
|
||||
// if (MapUtils.isEmpty(caseExecResultCount)) {
|
||||
// // 没有任何执行结果: 状态是未开始
|
||||
// testPlanFinalStatus = TestPlanConstants.TEST_PLAN_STATUS_PREPARED;
|
||||
// extTestPlanMapper.clearActualEndTime(testPlanId);
|
||||
// } else if (caseExecResultCount.size() == 1 && caseExecResultCount.containsKey(ExecStatus.PENDING.name()) && caseExecResultCount.get(ExecStatus.PENDING.name()) > 0) {
|
||||
// // 执行结果只有未开始: 状态是未开始
|
||||
// testPlanFinalStatus = TestPlanConstants.TEST_PLAN_STATUS_PREPARED;
|
||||
// extTestPlanMapper.clearActualEndTime(testPlanId);
|
||||
// } else if (!caseExecResultCount.containsKey(ExecStatus.PENDING.name())) {
|
||||
// // 执行结果没有未开始: 已完成
|
||||
// testPlanFinalStatus = TestPlanConstants.TEST_PLAN_STATUS_COMPLETED;
|
||||
// extTestPlanMapper.setActualEndTime(testPlanId, System.currentTimeMillis());
|
||||
// }
|
||||
//
|
||||
// this.updateTestPlanStatusAndGroupStatus(testPlanId, testPlanFinalStatus);
|
||||
// }
|
||||
|
||||
private void updateTestPlanGroupStatus(String testPlanGroupId) {
|
||||
//该测试计划是测试计划组内的子计划, 要同步计算测试计划组的状态
|
||||
List<TestPlan> childPlan = this.selectNotArchivedChildren(testPlanGroupId);
|
||||
String groupStatus = TestPlanConstants.TEST_PLAN_STATUS_PREPARED;
|
||||
|
||||
// 未开始:计划组为空、组内所有计划都是“未开始”状态
|
||||
// 已完成:组内计划均为“已完成”状态
|
||||
// 进行中:组内计划有未完成的状态
|
||||
if (CollectionUtils.isNotEmpty(childPlan)) {
|
||||
List<String> testPlanStatus = childPlan.stream().map(TestPlan::getStatus).distinct().toList();
|
||||
if (testPlanStatus.size() == 1) {
|
||||
if (StringUtils.equals(testPlanStatus.getFirst(), TestPlanConstants.TEST_PLAN_STATUS_COMPLETED)) {
|
||||
groupStatus = TestPlanConstants.TEST_PLAN_STATUS_COMPLETED;
|
||||
} else if (StringUtils.equals(testPlanStatus.getFirst(), TestPlanConstants.TEST_PLAN_STATUS_PREPARED)) {
|
||||
groupStatus = TestPlanConstants.TEST_PLAN_STATUS_PREPARED;
|
||||
} else if (StringUtils.equals(testPlanStatus.getFirst(), TestPlanConstants.TEST_PLAN_STATUS_UNDERWAY)) {
|
||||
groupStatus = TestPlanConstants.TEST_PLAN_STATUS_UNDERWAY;
|
||||
}
|
||||
} else {
|
||||
groupStatus = TestPlanConstants.TEST_PLAN_STATUS_UNDERWAY;
|
||||
}
|
||||
}
|
||||
TestPlanExample testPlanExample = new TestPlanExample();
|
||||
testPlanExample.createCriteria().andIdEqualTo(testPlanGroupId).andStatusNotEqualTo(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED);
|
||||
TestPlan updateGroupPlan = new TestPlan();
|
||||
updateGroupPlan.setStatus(groupStatus);
|
||||
testPlanMapper.updateByExampleSelective(updateGroupPlan, testPlanExample);
|
||||
if (StringUtils.equalsIgnoreCase(updateGroupPlan.getStatus(), TestPlanConstants.TEST_PLAN_STATUS_COMPLETED)) {
|
||||
extTestPlanMapper.setActualEndTime(testPlanGroupId, System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshTestPlanStatus(String testPlanId) {
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(testPlanId);
|
||||
if (StringUtils.equalsIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_PLAN)) {
|
||||
this.updateTestPlanStatus(testPlanId);
|
||||
} else {
|
||||
if (!StringUtils.equalsIgnoreCase(testPlan.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||
this.updateTestPlanGroupStatus(testPlan.getGroupId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTestPlanStatus(String testPlanId) {
|
||||
Map<String, Long> caseExecResultCount = new HashMap<>();
|
||||
Map<String, TestPlanResourceService> beansOfType = applicationContext.getBeansOfType(TestPlanResourceService.class);
|
||||
beansOfType.forEach((k, v) -> {
|
||||
Map<String, Long> map = v.caseExecResultCount(testPlanId);
|
||||
map.forEach((key, value) -> {
|
||||
if (value != 0) {
|
||||
caseExecResultCount.merge(key, value, Long::sum);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
String testPlanFinalStatus = TestPlanConstants.TEST_PLAN_STATUS_UNDERWAY;
|
||||
if (MapUtils.isEmpty(caseExecResultCount)) {
|
||||
// 没有任何执行结果: 状态是未开始
|
||||
testPlanFinalStatus = TestPlanConstants.TEST_PLAN_STATUS_PREPARED;
|
||||
extTestPlanMapper.clearActualEndTime(testPlanId);
|
||||
} else if (caseExecResultCount.size() == 1 && caseExecResultCount.containsKey(ExecStatus.PENDING.name()) && caseExecResultCount.get(ExecStatus.PENDING.name()) > 0) {
|
||||
// 执行结果只有未开始: 状态是未开始
|
||||
testPlanFinalStatus = TestPlanConstants.TEST_PLAN_STATUS_PREPARED;
|
||||
extTestPlanMapper.clearActualEndTime(testPlanId);
|
||||
} else if (!caseExecResultCount.containsKey(ExecStatus.PENDING.name())) {
|
||||
// 执行结果没有未开始: 已完成
|
||||
testPlanFinalStatus = TestPlanConstants.TEST_PLAN_STATUS_COMPLETED;
|
||||
extTestPlanMapper.setActualEndTime(testPlanId, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
this.updateTestPlanStatusAndGroupStatus(testPlanId, testPlanFinalStatus);
|
||||
}
|
||||
|
||||
public TestPlanOperationResponse sortInGroup(PosRequest request, LogInsertModule logInsertModule) {
|
||||
public TestPlanOperationResponse sort(PosRequest request, LogInsertModule logInsertModule) {
|
||||
testPlanGroupService.sort(request);
|
||||
testPlanLogService.saveMoveLog(testPlanMapper.selectByPrimaryKey(request.getMoveId()), request.getMoveId(), logInsertModule);
|
||||
return new TestPlanOperationResponse(1);
|
||||
|
@ -920,7 +854,7 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
public List<TestPlan> selectNotArchivedChildren(String testPlanGroupId) {
|
||||
TestPlanExample example = new TestPlanExample();
|
||||
example.createCriteria().andGroupIdEqualTo(testPlanGroupId).andStatusNotEqualTo(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED);
|
||||
example.setOrderByClause("pos asc");
|
||||
example.setOrderByClause("pos desc");
|
||||
return testPlanMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
|
@ -1023,7 +957,6 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
@Transactional(rollbackFor = Exception.class, propagation = Propagation.NOT_SUPPORTED)
|
||||
public void setExecuteConfig(String testPlanId, String testPlanReportId) {
|
||||
this.setActualStartTime(testPlanId);
|
||||
this.setTestPlanUnderway(testPlanId);
|
||||
if (StringUtils.isNotBlank(testPlanReportId)) {
|
||||
testPlanReportService.updateExecuteTimeAndStatus(testPlanReportId);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,10 @@ import io.metersphere.api.domain.ApiScenario;
|
|||
import io.metersphere.api.domain.ApiTestCase;
|
||||
import io.metersphere.functional.domain.FunctionalCase;
|
||||
import io.metersphere.plan.constants.TestPlanResourceConfig;
|
||||
import io.metersphere.plan.domain.*;
|
||||
import io.metersphere.plan.domain.TestPlan;
|
||||
import io.metersphere.plan.domain.TestPlanConfig;
|
||||
import io.metersphere.plan.domain.TestPlanExample;
|
||||
import io.metersphere.plan.domain.TestPlanReport;
|
||||
import io.metersphere.plan.dto.request.*;
|
||||
import io.metersphere.plan.dto.response.TestPlanOperationResponse;
|
||||
import io.metersphere.plan.dto.response.TestPlanResponse;
|
||||
|
@ -18,8 +21,10 @@ 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.constants.ModuleConstants;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.sdk.constants.SessionConstants;
|
||||
import io.metersphere.sdk.constants.TestPlanConstants;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
|
@ -122,7 +127,6 @@ public class TestPlanTests extends BaseTest {
|
|||
private static final String URL_POST_TEST_PLAN_SCHEDULE_DELETE = "/test-plan/schedule-config-delete/%s";
|
||||
|
||||
//测试计划资源-功能用例
|
||||
private static final String URL_POST_RESOURCE_CASE_ASSOCIATION = "/test-plan/association";
|
||||
private static final String URL_POST_RESOURCE_FUNCTIONAL_CASE_SORT = "/test-plan/functional/case/sort";
|
||||
|
||||
private static final String URL_TEST_PLAN_EDIT_FOLLOWER = "/test-plan/edit/follower";
|
||||
|
@ -577,10 +581,10 @@ public class TestPlanTests extends BaseTest {
|
|||
groupTestPlanId15 = returnId;
|
||||
} else if (i == 35) {
|
||||
groupTestPlanId35 = returnId;
|
||||
} else if (i > 700 && i < 750) {
|
||||
} else if (i > 700 && i < 725) {
|
||||
// 701-749 要创建测试计划报告 每个测试计划创建250个报告
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
TestPlanReportMapper batchInsert = sqlSession.getMapper(TestPlanReportMapper.class);
|
||||
// 701-749 要创建测试计划报告 每个测试计划创建250个报告
|
||||
for (int reportCount = 0; reportCount < 250; reportCount++) {
|
||||
TestPlanReport testPlanReport = new TestPlanReport();
|
||||
testPlanReport.setId(IDGenerator.nextStr());
|
||||
|
@ -633,11 +637,6 @@ public class TestPlanTests extends BaseTest {
|
|||
testPlanTestService.checkTestPlanByAddTest();
|
||||
simpleTestPlan = testPlanTestService.selectTestPlanByName("testPlan_13");
|
||||
repeatCaseTestPlan = testPlanTestService.selectTestPlanByName("testPlan_123");
|
||||
//测试继续创建10个
|
||||
for (int i = 0; i < 10; i++) {
|
||||
request.setName("testPlan_1000_" + i);
|
||||
this.requestPost(URL_POST_TEST_PLAN_ADD, request);
|
||||
}
|
||||
|
||||
//在groupTestPlanId7、groupTestPlanId15下面各创建20条数据(并且校验第21条不能创建成功)
|
||||
for (int i = 0; i < 21; i++) {
|
||||
|
@ -702,8 +701,8 @@ public class TestPlanTests extends BaseTest {
|
|||
request.setModuleId(IDGenerator.nextStr());
|
||||
this.requestPost(URL_POST_TEST_PLAN_ADD, request).andExpect(status().is5xxServerError());
|
||||
request.setModuleId(a1Node.getId());
|
||||
request.setGroupId(testPlanTestService.selectTestPlanByName("testPlan_60").getGroupId());
|
||||
this.requestPost(URL_POST_TEST_PLAN_ADD, request);
|
||||
request.setGroupId(testPlanTestService.selectTestPlanByName("testPlan_60").getId());
|
||||
this.requestPost(URL_POST_TEST_PLAN_ADD, request).andExpect(status().is5xxServerError());
|
||||
request.setGroupId(TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID);
|
||||
request.setPassThreshold(100.11);
|
||||
this.requestPost(URL_POST_TEST_PLAN_ADD, request).andExpect(status().isBadRequest());
|
||||
|
@ -715,6 +714,7 @@ public class TestPlanTests extends BaseTest {
|
|||
request.setPassThreshold(100);
|
||||
this.requestPostPermissionTest(PermissionConstants.TEST_PLAN_READ_ADD, URL_POST_TEST_PLAN_ADD, request);
|
||||
|
||||
this.checkTestPlanSortWithOutGroup();
|
||||
this.checkTestPlanSortInGroup(groupTestPlanId7);
|
||||
this.checkTestPlanMoveToGroup();
|
||||
this.checkTestPlanGroupArchived(groupTestPlanId7);
|
||||
|
@ -729,6 +729,65 @@ public class TestPlanTests extends BaseTest {
|
|||
TestPlanResponse.class);
|
||||
}
|
||||
|
||||
|
||||
protected void checkTestPlanSortWithOutGroup() throws Exception {
|
||||
TestPlanTableRequest dataRequest = new TestPlanTableRequest();
|
||||
dataRequest.setProjectId(project.getId());
|
||||
dataRequest.setType("ALL");
|
||||
dataRequest.setPageSize(10);
|
||||
dataRequest.setCurrent(1);
|
||||
//提前校验
|
||||
List<TestPlanResponse> tableList = testPlanTestService.getTestPlanResponse(this.requestPostWithOkAndReturn(
|
||||
URL_POST_TEST_PLAN_PAGE, dataRequest).getResponse().getContentAsString(StandardCharsets.UTF_8));
|
||||
Assertions.assertTrue(tableList.get(0).getId().equals(rootPlanIds.getLast()));
|
||||
|
||||
/*
|
||||
排序校验用例设计:
|
||||
1.第一个移动到最后一个。
|
||||
2.最后一个移动到第一个(还原为原来的顺序)
|
||||
3.第三个移动到第二个
|
||||
4.修改第一个和第二个之间的pos差小于2,将第三个移动到第二个(还原为原来的顺序),并检查pos有没有初始化
|
||||
*/
|
||||
|
||||
|
||||
// 1.第一个移动到最后一个
|
||||
PosRequest posRequest = new PosRequest(project.getId(), rootPlanIds.getLast(), rootPlanIds.getFirst(), MoveTypeEnum.AFTER.name());
|
||||
this.requestPostWithOk(URL_POST_TEST_PLAN_SORT, posRequest);
|
||||
tableList = testPlanTestService.getTestPlanResponse(this.requestPostWithOkAndReturn(
|
||||
URL_POST_TEST_PLAN_PAGE, dataRequest).getResponse().getContentAsString(StandardCharsets.UTF_8));
|
||||
Assertions.assertTrue(tableList.get(0).getId().equals(rootPlanIds.get(rootPlanIds.size() - 2)));
|
||||
// 2.最后一个移动到第一个(还原为原来的顺序)
|
||||
posRequest.setTargetId(tableList.getFirst().getId());
|
||||
posRequest.setMoveMode(MoveTypeEnum.BEFORE.name());
|
||||
this.requestPostWithOk(URL_POST_TEST_PLAN_SORT, posRequest);
|
||||
tableList = testPlanTestService.getTestPlanResponse(this.requestPostWithOkAndReturn(
|
||||
URL_POST_TEST_PLAN_PAGE, dataRequest).getResponse().getContentAsString(StandardCharsets.UTF_8));
|
||||
Assertions.assertTrue(tableList.get(0).getId().equals(rootPlanIds.getLast()));
|
||||
// 3.第三个移动到第二个
|
||||
posRequest = new PosRequest(project.getId(), rootPlanIds.get(rootPlanIds.size() - 3), rootPlanIds.get(rootPlanIds.size() - 2), MoveTypeEnum.BEFORE.name());
|
||||
this.requestPostWithOk(URL_POST_TEST_PLAN_SORT, posRequest);
|
||||
tableList = testPlanTestService.getTestPlanResponse(this.requestPostWithOkAndReturn(
|
||||
URL_POST_TEST_PLAN_PAGE, dataRequest).getResponse().getContentAsString(StandardCharsets.UTF_8));
|
||||
Assertions.assertTrue(tableList.get(0).getId().equals(rootPlanIds.getLast()));
|
||||
Assertions.assertTrue(tableList.get(1).getId().equals(posRequest.getMoveId()));
|
||||
Assertions.assertTrue(tableList.get(2).getId().equals(posRequest.getTargetId()));
|
||||
|
||||
// 4.修改第一个只比第二个大1,将第三个移动到第二个(还原为原来的顺序),并检查pos有没有初始化
|
||||
TestPlan updatePlan = new TestPlan();
|
||||
updatePlan.setId(rootPlanIds.getLast());
|
||||
updatePlan.setPos(tableList.get(1).getPos() + 1);
|
||||
testPlanMapper.updateByPrimaryKeySelective(updatePlan);
|
||||
|
||||
posRequest.setMoveId(rootPlanIds.get(rootPlanIds.size() - 2));
|
||||
posRequest.setTargetId(rootPlanIds.get(rootPlanIds.size() - 3));
|
||||
posRequest.setMoveMode(MoveTypeEnum.BEFORE.name());
|
||||
this.requestPostWithOk(URL_POST_TEST_PLAN_SORT, posRequest);
|
||||
tableList = testPlanTestService.getTestPlanResponse(this.requestPostWithOkAndReturn(
|
||||
URL_POST_TEST_PLAN_PAGE, dataRequest).getResponse().getContentAsString(StandardCharsets.UTF_8));
|
||||
Assertions.assertTrue(tableList.get(0).getId().equals(rootPlanIds.getLast()));
|
||||
Assertions.assertTrue(tableList.get(1).getId().equals(posRequest.getMoveId()));
|
||||
Assertions.assertTrue(tableList.get(2).getId().equals(posRequest.getTargetId()));
|
||||
}
|
||||
protected void checkTestPlanSortInGroup(String groupId) throws Exception {
|
||||
/*
|
||||
排序校验用例设计:
|
||||
|
@ -812,7 +871,7 @@ public class TestPlanTests extends BaseTest {
|
|||
targetPlan = lastTestPlanInGroup.get(1);
|
||||
TestPlan updatePlan = new TestPlan();
|
||||
updatePlan.setId(targetPlan.getId());
|
||||
updatePlan.setPos(lastTestPlanInGroup.get(0).getPos() + 2);
|
||||
updatePlan.setPos(lastTestPlanInGroup.get(0).getPos() - 2);
|
||||
testPlanMapper.updateByPrimaryKeySelective(updatePlan);
|
||||
|
||||
posRequest = new PosRequest(project.getId(), movePlan.getId(), targetPlan.getId(), MoveTypeEnum.BEFORE.name());
|
||||
|
@ -826,11 +885,9 @@ public class TestPlanTests extends BaseTest {
|
|||
newTestPlanInGroup = this.selectByGroupId(groupId);
|
||||
Assertions.assertEquals(response.getOperationCount(), 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 + NodeSortUtils.DEFAULT_NODE_INTERVAL_POS));
|
||||
lastPos = newTestPlanInGroup.get(newListIndex).getPos();
|
||||
Assertions.assertEquals(newTestPlanInGroup.get(newListIndex).getPos(), defaultTestPlanInGroup.get(newListIndex).getPos());
|
||||
}
|
||||
|
||||
//测试权限
|
||||
|
@ -958,12 +1015,15 @@ public class TestPlanTests extends BaseTest {
|
|||
BaseTreeNode a1b1Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a1-b1");
|
||||
assert a1Node != null & a2Node != null & a3Node != null & a1a1Node != null & a1b1Node != null;
|
||||
|
||||
TestPlanExample example = new TestPlanExample();
|
||||
example.createCriteria().andProjectIdEqualTo(project.getId()).andGroupIdEqualTo("NONE").andStatusEqualTo(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED);
|
||||
long count = testPlanMapper.countByExample(example);
|
||||
//此时有一个归档的
|
||||
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
|
||||
URL_POST_TEST_PLAN_PAGE, dataRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
|
||||
dataRequest.getCurrent(),
|
||||
dataRequest.getPageSize(),
|
||||
1010 - 1);
|
||||
999 - 1);
|
||||
//查询归档的
|
||||
dataRequest.setFilter(new HashMap<>() {{
|
||||
this.put("status", Collections.singletonList(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED));
|
||||
|
@ -984,7 +1044,7 @@ public class TestPlanTests extends BaseTest {
|
|||
URL_POST_TEST_PLAN_PAGE, onlyPlanRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
|
||||
dataRequest.getCurrent(),
|
||||
dataRequest.getPageSize(),
|
||||
1007);
|
||||
996);
|
||||
|
||||
//按照名称倒叙
|
||||
dataRequest.setSort(new HashMap<>() {{
|
||||
|
@ -995,7 +1055,7 @@ public class TestPlanTests extends BaseTest {
|
|||
URL_POST_TEST_PLAN_PAGE, dataRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
|
||||
dataRequest.getCurrent(),
|
||||
dataRequest.getPageSize(),
|
||||
1010 - 1);
|
||||
999 - 1);
|
||||
|
||||
|
||||
//指定模块ID查询 (查询count时,不会因为选择了模块而更改了总量
|
||||
|
@ -1008,7 +1068,7 @@ public class TestPlanTests extends BaseTest {
|
|||
URL_POST_TEST_PLAN_PAGE, dataRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
|
||||
dataRequest.getCurrent(),
|
||||
dataRequest.getPageSize(),
|
||||
910 - 1);
|
||||
899 - 1);
|
||||
|
||||
//测试根据名称模糊查询: Plan_2 预期结果: a1Node下有11条(testPlan_2,testPlan_20~testPlan_29), a1b1Node下有100条(testPlan_200~testPlan_299)
|
||||
dataRequest.setModuleIds(null);
|
||||
|
@ -1183,11 +1243,11 @@ public class TestPlanTests extends BaseTest {
|
|||
|
||||
//修改a2节点下的数据(91,92)的所属测试计划组
|
||||
updateRequest = testPlanTestService.generateUpdateRequest(testPlanTestService.selectTestPlanByName("testPlan_91").getId());
|
||||
updateRequest.setGroupId(groupTestPlanId7);
|
||||
updateRequest.setGroupId(groupTestPlanId35);
|
||||
this.requestPostWithOk(URL_POST_TEST_PLAN_UPDATE, updateRequest);
|
||||
a2NodeCount--;
|
||||
updateRequest = testPlanTestService.generateUpdateRequest(testPlanTestService.selectTestPlanByName("testPlan_92").getId());
|
||||
updateRequest.setGroupId(groupTestPlanId7);
|
||||
updateRequest.setGroupId(groupTestPlanId35);
|
||||
this.requestPostWithOk(URL_POST_TEST_PLAN_UPDATE, updateRequest);
|
||||
a2NodeCount--;
|
||||
|
||||
|
@ -1195,7 +1255,6 @@ public class TestPlanTests extends BaseTest {
|
|||
updatePlan.setId(groupTestPlanId7);
|
||||
updatePlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_UNDERWAY);
|
||||
testPlanMapper.updateByPrimaryKeySelective(updatePlan);
|
||||
|
||||
//修改测试计划组信息
|
||||
updateRequest = testPlanTestService.generateUpdateRequest(groupTestPlanId7);
|
||||
updateRequest.setName(IDGenerator.nextStr());
|
||||
|
@ -1239,137 +1298,6 @@ public class TestPlanTests extends BaseTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(21)
|
||||
public void testPlanAssociationFunctionCase() throws Exception {
|
||||
if (ObjectUtils.anyNull(simpleTestPlan, repeatCaseTestPlan)) {
|
||||
this.testPlanAddTest();
|
||||
}
|
||||
//创建20个功能测试用例
|
||||
FUNCTIONAL_CASES.addAll(testPlanTestService.createFunctionCase(20, project.getId()));
|
||||
|
||||
//测试不开启用例重复的测试计划多次关联
|
||||
TestPlanAssociationRequest request = new TestPlanAssociationRequest();
|
||||
request.setTestPlanId(simpleTestPlan.getId());
|
||||
request.setFunctionalSelectIds(FUNCTIONAL_CASES.stream().map(FunctionalCase::getId).collect(Collectors.toList()));
|
||||
MvcResult result = this.requestPostWithOkAndReturn(URL_POST_RESOURCE_CASE_ASSOCIATION, request);
|
||||
String returnData = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
||||
Assertions.assertNotNull(resultHolder);
|
||||
|
||||
//先测试一下没有开启模块时能否使用
|
||||
testPlanTestService.removeProjectModule(project, PROJECT_MODULE, "caseManagement");
|
||||
this.requestPost(URL_POST_RESOURCE_CASE_ASSOCIATION, request).andExpect(status().is5xxServerError());
|
||||
//恢复
|
||||
testPlanTestService.resetProjectModule(project, PROJECT_MODULE);
|
||||
|
||||
result = this.requestPostWithOkAndReturn(URL_POST_RESOURCE_CASE_ASSOCIATION, request);
|
||||
returnData = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
||||
Assertions.assertNotNull(resultHolder);
|
||||
|
||||
//测试开启用例重复的测试计划多次关联
|
||||
request.setTestPlanId(repeatCaseTestPlan.getId());
|
||||
result = this.requestPostWithOkAndReturn(URL_POST_RESOURCE_CASE_ASSOCIATION, request);
|
||||
returnData = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
||||
Assertions.assertNotNull(resultHolder);
|
||||
|
||||
result = this.requestPostWithOkAndReturn(URL_POST_RESOURCE_CASE_ASSOCIATION, request);
|
||||
returnData = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
||||
Assertions.assertNotNull(resultHolder);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(22)
|
||||
public void testPlanFunctionCaseSort() throws Exception {
|
||||
if (FUNCTIONAL_CASES.isEmpty()) {
|
||||
this.testPlanAssociationFunctionCase();
|
||||
}
|
||||
String collectionId = IDGenerator.nextStr();
|
||||
List<TestPlanFunctionalCase> funcList = testPlanTestService.selectTestPlanFunctionalCaseByTestPlanId(repeatCaseTestPlan.getId());
|
||||
funcList.forEach(item -> {
|
||||
TestPlanFunctionalCase updateModel = new TestPlanFunctionalCase();
|
||||
updateModel.setId(item.getId());
|
||||
updateModel.setTestPlanCollectionId(collectionId);
|
||||
testPlanFunctionalCaseMapper.updateByPrimaryKeySelective(updateModel);
|
||||
});
|
||||
//将第30个移动到第一位之前
|
||||
ResourceSortRequest request = new ResourceSortRequest();
|
||||
request.setTestCollectionId(funcList.getFirst().getTestPlanCollectionId());
|
||||
request.setProjectId(DEFAULT_PROJECT_ID);
|
||||
request.setMoveId(funcList.get(29).getId());
|
||||
request.setTargetId(funcList.get(0).getId());
|
||||
request.setMoveMode(MoveTypeEnum.BEFORE.name());
|
||||
|
||||
//恢复
|
||||
testPlanTestService.resetProjectModule(project, PROJECT_MODULE);
|
||||
|
||||
MvcResult result = this.requestPostWithOkAndReturn(URL_POST_RESOURCE_FUNCTIONAL_CASE_SORT, request);
|
||||
ResultHolder resultHolder = JSON.parseObject(result.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class);
|
||||
TestPlanOperationResponse response = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), TestPlanOperationResponse.class);
|
||||
Assertions.assertEquals(response.getOperationCount(), 1);
|
||||
funcList = testPlanTestService.selectTestPlanFunctionalCaseByTestPlanId(repeatCaseTestPlan.getId());
|
||||
Assertions.assertEquals(funcList.get(0).getId(), request.getMoveId());
|
||||
Assertions.assertEquals(funcList.get(1).getId(), request.getTargetId());
|
||||
LOG_CHECK_LIST.add(
|
||||
new CheckLogModel(request.getMoveId(), OperationLogType.UPDATE, URL_POST_RESOURCE_FUNCTIONAL_CASE_SORT)
|
||||
);
|
||||
|
||||
//将这时的第30个放到第一位之后
|
||||
request.setMoveId(funcList.get(29).getId());
|
||||
request.setTargetId(funcList.get(0).getId());
|
||||
request.setMoveMode(MoveTypeEnum.AFTER.name());
|
||||
result = this.requestPostWithOkAndReturn(URL_POST_RESOURCE_FUNCTIONAL_CASE_SORT, request);
|
||||
resultHolder = JSON.parseObject(result.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class);
|
||||
response = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), TestPlanOperationResponse.class);
|
||||
Assertions.assertEquals(response.getOperationCount(), 1);
|
||||
funcList = testPlanTestService.selectTestPlanFunctionalCaseByTestPlanId(repeatCaseTestPlan.getId());
|
||||
Assertions.assertEquals(funcList.get(0).getId(), request.getTargetId());
|
||||
Assertions.assertEquals(funcList.get(1).getId(), request.getMoveId());
|
||||
LOG_CHECK_LIST.add(
|
||||
new CheckLogModel(request.getMoveId(), OperationLogType.UPDATE, URL_POST_RESOURCE_FUNCTIONAL_CASE_SORT)
|
||||
);
|
||||
|
||||
//再将这时的第30个放到第一位之前,但是第一个的pos为2,检查能否触发ref操作
|
||||
request.setMoveId(funcList.get(29).getId());
|
||||
request.setTargetId(funcList.get(0).getId());
|
||||
request.setMoveMode(MoveTypeEnum.BEFORE.name());
|
||||
testPlanTestService.setResourcePos(funcList.get(0).getId(), TestPlanResourceConstants.RESOURCE_FUNCTIONAL_CASE, 2);
|
||||
result = this.requestPostWithOkAndReturn(URL_POST_RESOURCE_FUNCTIONAL_CASE_SORT, request);
|
||||
resultHolder = JSON.parseObject(result.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class);
|
||||
response = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), TestPlanOperationResponse.class);
|
||||
Assertions.assertEquals(response.getOperationCount(), 1);
|
||||
funcList = testPlanTestService.selectTestPlanFunctionalCaseByTestPlanId(repeatCaseTestPlan.getId());
|
||||
Assertions.assertEquals(funcList.get(0).getId(), request.getMoveId());
|
||||
Assertions.assertEquals(funcList.get(1).getId(), request.getTargetId());
|
||||
LOG_CHECK_LIST.add(
|
||||
new CheckLogModel(request.getMoveId(), OperationLogType.UPDATE, URL_POST_RESOURCE_FUNCTIONAL_CASE_SORT)
|
||||
);
|
||||
|
||||
//反例:测试集为空
|
||||
request.setTestCollectionId(null);
|
||||
this.requestPost(URL_POST_RESOURCE_FUNCTIONAL_CASE_SORT, request).andExpect(status().isBadRequest());
|
||||
//反例:拖拽的节点不存在
|
||||
request.setTestCollectionId(funcList.getFirst().getTestPlanCollectionId());
|
||||
request.setMoveId(null);
|
||||
this.requestPost(URL_POST_RESOURCE_FUNCTIONAL_CASE_SORT, request).andExpect(status().isBadRequest());
|
||||
//反例:目标节点不存在
|
||||
request.setMoveId(funcList.get(29).getId());
|
||||
request.setTargetId(null);
|
||||
this.requestPost(URL_POST_RESOURCE_FUNCTIONAL_CASE_SORT, request).andExpect(status().isBadRequest());
|
||||
//反例: 节点重复
|
||||
request.setTargetId(request.getMoveId());
|
||||
this.requestPost(URL_POST_RESOURCE_FUNCTIONAL_CASE_SORT, request).andExpect(status().is5xxServerError());
|
||||
|
||||
//测试权限
|
||||
request.setMoveMode(MoveTypeEnum.BEFORE.name());
|
||||
this.requestPostPermissionTest(PermissionConstants.TEST_PLAN_READ_UPDATE, URL_POST_RESOURCE_FUNCTIONAL_CASE_SORT, request);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(61)
|
||||
public void scheduleTest() throws Exception {
|
||||
|
@ -2276,20 +2204,6 @@ public class TestPlanTests extends BaseTest {
|
|||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Order(305)
|
||||
public void testAssociation() throws Exception {
|
||||
TestPlanAssociationRequest request = new TestPlanAssociationRequest();
|
||||
request.setTestPlanId("wx_test_plan_id_2");
|
||||
this.requestPostWithOkAndReturn(URL_POST_RESOURCE_CASE_ASSOCIATION, request);
|
||||
request.setFunctionalSelectIds(Arrays.asList("my_test_1", "my_test_2", "my_test_3"));
|
||||
this.requestPostWithOkAndReturn(URL_POST_RESOURCE_CASE_ASSOCIATION, request);
|
||||
|
||||
//测试归档的关联会报错
|
||||
request.setTestPlanId("wx_test_plan_id_1");
|
||||
this.requestPost(URL_POST_RESOURCE_CASE_ASSOCIATION, request).andExpect(status().is5xxServerError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(306)
|
||||
public void testStatistics() throws Exception {
|
||||
|
|
|
@ -10,6 +10,7 @@ import io.metersphere.functional.domain.FunctionalCase;
|
|||
import io.metersphere.functional.mapper.FunctionalCaseMapper;
|
||||
import io.metersphere.plan.domain.*;
|
||||
import io.metersphere.plan.dto.request.TestPlanUpdateRequest;
|
||||
import io.metersphere.plan.dto.response.TestPlanResponse;
|
||||
import io.metersphere.plan.job.TestPlanScheduleJob;
|
||||
import io.metersphere.plan.mapper.*;
|
||||
import io.metersphere.project.domain.Project;
|
||||
|
@ -434,6 +435,13 @@ public class TestPlanTestService {
|
|||
});
|
||||
}
|
||||
|
||||
public List<TestPlanResponse> getTestPlanResponse(String returnData) {
|
||||
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
||||
Pager<Object> result = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), Pager.class);
|
||||
List<TestPlanResponse> returnList = JSON.parseArray(JSON.toJSONString(result.getList()), TestPlanResponse.class);
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public void checkTestPlanPage(String returnData, long current, long pageSize, long allData) {
|
||||
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
||||
Pager<Object> result = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), Pager.class);
|
||||
|
|
Loading…
Reference in New Issue