fix(测试计划): 测试计划细节一揽子优化
This commit is contained in:
parent
1cf7f454d9
commit
a65ad3a598
|
@ -42,6 +42,29 @@ public class BasePageRequest extends BaseCondition {
|
|||
return sb.substring(0, sb.length() - 1);
|
||||
}
|
||||
|
||||
public String getSortString(String defaultColumn, String tableAliseName) {
|
||||
if (sort == null || sort.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Map.Entry<String, String> entry : sort.entrySet()) {
|
||||
String column = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, entry.getKey());
|
||||
sb.append(tableAliseName)
|
||||
.append(".")
|
||||
.append(column)
|
||||
.append(StringUtils.SPACE)
|
||||
.append(StringUtils.equalsIgnoreCase(entry.getValue(), "DESC") ? "DESC" : "ASC")
|
||||
.append(",")
|
||||
.append(tableAliseName)
|
||||
.append(".")
|
||||
.append(defaultColumn)
|
||||
.append(StringUtils.SPACE)
|
||||
.append(StringUtils.equalsIgnoreCase(entry.getValue(), "DESC") ? "DESC" : "ASC");
|
||||
return sb.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getSortString(String defaultColumn) {
|
||||
if (sort == null || sort.isEmpty()) {
|
||||
return null;
|
||||
|
|
|
@ -5,7 +5,6 @@ import com.github.pagehelper.PageHelper;
|
|||
import io.metersphere.api.dto.definition.ApiReportDTO;
|
||||
import io.metersphere.api.dto.definition.ApiReportDetailDTO;
|
||||
import io.metersphere.api.service.definition.ApiReportService;
|
||||
import io.metersphere.plan.constants.TestPlanResourceConfig;
|
||||
import io.metersphere.plan.dto.request.*;
|
||||
import io.metersphere.plan.dto.response.TestPlanApiCasePageResponse;
|
||||
import io.metersphere.plan.dto.response.TestPlanAssociationResponse;
|
||||
|
@ -32,7 +31,6 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
|
|||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
|
|
@ -53,4 +53,5 @@ public class TestPlanExecuteController {
|
|||
testPlanManagementService.checkModuleIsOpen(request.getProjectId(), TestPlanResourceConfig.CHECK_TYPE_PROJECT, Collections.singletonList(TestPlanResourceConfig.CONFIG_TEST_PLAN));
|
||||
testPlanExecuteService.batchExecuteTestPlan(request, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
@ -61,7 +62,9 @@ public class TestPlanFunctionalCaseController {
|
|||
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ)
|
||||
@CheckOwner(resourceId = "#request.getTestPlanId()", resourceType = "test_plan")
|
||||
public Pager<List<TestPlanCasePageResponse>> page(@Validated @RequestBody TestPlanCaseRequest request) {
|
||||
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize());
|
||||
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
|
||||
StringUtils.isNotBlank(request.getSortString("id", "test_plan_functional_case")) ? request.getSortString("id", "test_plan_functional_case") : "test_plan_functional_case.pos asc");
|
||||
|
||||
return PageUtils.setPageInfo(page, testPlanFunctionalCaseService.getFunctionalCasePage(request, false));
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package io.metersphere.plan.dto.request;
|
||||
|
||||
import io.metersphere.system.dto.sdk.BasePageRequest;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class TestPlanHistoryPageRequest extends BasePageRequest {
|
||||
|
||||
@Schema(description = "测试计划ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{test_plan.id.not_blank}")
|
||||
private String testPlanId;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package io.metersphere.plan.dto.response;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class TestPlanHistoryResponse {
|
||||
|
||||
@Schema(description = "报告ID")
|
||||
private String id;
|
||||
@Schema(description = "触发方式/执行方式")
|
||||
private String triggerMode;
|
||||
@Schema(description = "执行结果")
|
||||
private String resultStatus;
|
||||
@Schema(description = "操作人")
|
||||
private String operator;
|
||||
@Schema(description = "开始时间")
|
||||
private Long startTime;
|
||||
@Schema(description = "结束时间")
|
||||
private Long endTime;
|
||||
@Schema(description = "是否还能查看执行报告")
|
||||
private boolean reportDeleted;
|
||||
}
|
|
@ -61,7 +61,7 @@
|
|||
resultType="io.metersphere.project.dto.DropNode">
|
||||
SELECT id, pos
|
||||
FROM test_plan_api_case
|
||||
WHERE test_plan_id = #{parentId}
|
||||
WHERE test_plan_collection_id = #{parentId}
|
||||
<if test="operator == 'moreThan'">
|
||||
AND pos > #{pos}
|
||||
</if>
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
resultType="io.metersphere.project.dto.DropNode">
|
||||
SELECT id, pos
|
||||
FROM test_plan_api_scenario
|
||||
WHERE test_plan_id = #{parentId}
|
||||
WHERE test_plan_collection_id = #{parentId}
|
||||
<if test="operator == 'moreThan'">
|
||||
AND pos > #{pos}
|
||||
</if>
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
resultType="io.metersphere.project.dto.DropNode">
|
||||
SELECT id, pos
|
||||
FROM test_plan_functional_case
|
||||
WHERE test_plan_id = #{parentId}
|
||||
WHERE test_plan_collection_id = #{parentId}
|
||||
<if test="operator == 'moreThan'">
|
||||
AND pos > #{pos}
|
||||
</if>
|
||||
|
|
|
@ -581,7 +581,7 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
|
|||
TestPlanOperationResponse response = new TestPlanOperationResponse();
|
||||
MoveNodeSortDTO sortDTO = super.getNodeSortDTO(
|
||||
request.getTestCollectionId(),
|
||||
super.getNodeMoveRequest(request, true),
|
||||
super.getNodeMoveRequest(request, false),
|
||||
extTestPlanApiCaseMapper::selectDragInfoById,
|
||||
extTestPlanApiCaseMapper::selectNodeByPosOperator
|
||||
);
|
||||
|
|
|
@ -245,7 +245,7 @@ public class TestPlanApiScenarioService extends TestPlanResourceService {
|
|||
TestPlanOperationResponse response = new TestPlanOperationResponse();
|
||||
MoveNodeSortDTO sortDTO = super.getNodeSortDTO(
|
||||
request.getTestCollectionId(),
|
||||
super.getNodeMoveRequest(request, true),
|
||||
super.getNodeMoveRequest(request, false),
|
||||
extTestPlanApiScenarioMapper::selectDragInfoById,
|
||||
extTestPlanApiScenarioMapper::selectNodeByPosOperator
|
||||
);
|
||||
|
@ -604,9 +604,8 @@ public class TestPlanApiScenarioService extends TestPlanResourceService {
|
|||
ids.forEach(id -> {
|
||||
TestPlanApiScenario testPlanApiScenario = new TestPlanApiScenario();
|
||||
testPlanApiScenario.setId(id);
|
||||
testPlanApiScenario.setPos(nextOrder.get());
|
||||
testPlanApiScenario.setPos(nextOrder.getAndAdd(DEFAULT_NODE_INTERVAL_POS));
|
||||
testPlanApiScenario.setTestPlanCollectionId(targetCollectionId);
|
||||
nextOrder.addAndGet(DEFAULT_NODE_INTERVAL_POS);
|
||||
testPlanApiScenarioMapper.updateByPrimaryKeySelective(testPlanApiScenario);
|
||||
});
|
||||
sqlSession.flushStatements();
|
||||
|
|
|
@ -205,7 +205,7 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService {
|
|||
TestPlanOperationResponse response = new TestPlanOperationResponse();
|
||||
MoveNodeSortDTO sortDTO = super.getNodeSortDTO(
|
||||
request.getTestCollectionId(),
|
||||
super.getNodeMoveRequest(request, true),
|
||||
super.getNodeMoveRequest(request, false),
|
||||
extTestPlanFunctionalCaseMapper::selectDragInfoById,
|
||||
extTestPlanFunctionalCaseMapper::selectNodeByPosOperator
|
||||
);
|
||||
|
|
|
@ -16,6 +16,7 @@ import io.metersphere.sdk.constants.*;
|
|||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.*;
|
||||
import io.metersphere.system.domain.ScheduleExample;
|
||||
import io.metersphere.system.domain.TestPlanModule;
|
||||
import io.metersphere.system.domain.TestPlanModuleExample;
|
||||
import io.metersphere.system.domain.User;
|
||||
import io.metersphere.system.dto.LogInsertModule;
|
||||
|
@ -126,6 +127,11 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
private TestPlan savePlanDTO(TestPlanCreateRequest createOrCopyRequest, String operator) {
|
||||
//检查模块的合法性
|
||||
checkModule(createOrCopyRequest.getModuleId());
|
||||
if (StringUtils.equalsIgnoreCase(createOrCopyRequest.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)
|
||||
&& !StringUtils.equalsIgnoreCase(createOrCopyRequest.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||
throw new MSException(Translator.get("test_plan.group.error"));
|
||||
}
|
||||
|
||||
TestPlan createTestPlan = new TestPlan();
|
||||
BeanUtils.copyBean(createTestPlan, createOrCopyRequest);
|
||||
validateTestPlanGroup(createTestPlan.getGroupId(), 1);
|
||||
|
@ -468,14 +474,20 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
public TestPlanDetailResponse detail(String id, String userId) {
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(id);
|
||||
TestPlanDetailResponse response = new TestPlanDetailResponse();
|
||||
String moduleName = getModuleName(testPlan.getModuleId());
|
||||
|
||||
String moduleName = Translator.get("unplanned.plan");
|
||||
if (!ModuleConstants.DEFAULT_NODE_ID.equals(id)) {
|
||||
TestPlanModule module = testPlanModuleMapper.selectByPrimaryKey(id);
|
||||
moduleName = module == null ? Translator.get("unplanned.plan") : module.getName();
|
||||
response.setModuleId(module == null ? ModuleConstants.DEFAULT_NODE_ID : module.getId());
|
||||
}
|
||||
|
||||
//计划组只有几个参数
|
||||
response.setId(testPlan.getId());
|
||||
response.setNum(testPlan.getNum());
|
||||
response.setStatus(testPlan.getStatus());
|
||||
response.setName(testPlan.getName());
|
||||
response.setTags(testPlan.getTags());
|
||||
response.setModuleId(testPlan.getModuleId());
|
||||
response.setModuleName(moduleName);
|
||||
response.setDescription(testPlan.getDescription());
|
||||
response.setType(testPlan.getType());
|
||||
|
@ -547,9 +559,10 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
|||
|
||||
public String getModuleName(String id) {
|
||||
if (ModuleConstants.DEFAULT_NODE_ID.equals(id)) {
|
||||
return Translator.get("functional_case.module.default.name");
|
||||
return Translator.get("unplanned.plan");
|
||||
}
|
||||
return testPlanModuleMapper.selectByPrimaryKey(id).getName();
|
||||
TestPlanModule module = testPlanModuleMapper.selectByPrimaryKey(id);
|
||||
return module == null ? StringUtils.EMPTY : module.getName();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ public class TestPlanApiCaseControllerTests extends BaseTest {
|
|||
request.setProjectId("wxx_1234");
|
||||
request.setMoveId(apiList.getLast().getId());
|
||||
request.setTargetId(apiList.getFirst().getId());
|
||||
request.setMoveMode(MoveTypeEnum.AFTER.name());
|
||||
request.setMoveMode(MoveTypeEnum.BEFORE.name());
|
||||
|
||||
MvcResult result = this.requestPostWithOkAndReturn(URL_POST_RESOURCE_API_CASE_SORT, request);
|
||||
ResultHolder resultHolder = JSON.parseObject(result.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class);
|
||||
|
@ -164,7 +164,7 @@ public class TestPlanApiCaseControllerTests extends BaseTest {
|
|||
//将这时的第30个放到第一位之后
|
||||
request.setTargetId(apiList.getLast().getId());
|
||||
request.setMoveId(apiList.getFirst().getId());
|
||||
request.setMoveMode(MoveTypeEnum.BEFORE.name());
|
||||
request.setMoveMode(MoveTypeEnum.AFTER.name());
|
||||
result = this.requestPostWithOkAndReturn(URL_POST_RESOURCE_API_CASE_SORT, request);
|
||||
resultHolder = JSON.parseObject(result.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class);
|
||||
response = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), TestPlanOperationResponse.class);
|
||||
|
|
|
@ -24,7 +24,6 @@ import io.metersphere.plan.domain.TestPlanApiScenarioExample;
|
|||
import io.metersphere.plan.dto.request.*;
|
||||
import io.metersphere.plan.dto.response.TestPlanOperationResponse;
|
||||
import io.metersphere.plan.mapper.TestPlanApiScenarioMapper;
|
||||
import io.metersphere.plan.service.TestPlanApiScenarioLogService;
|
||||
import io.metersphere.plan.service.TestPlanApiScenarioService;
|
||||
import io.metersphere.project.api.assertion.MsResponseCodeAssertion;
|
||||
import io.metersphere.project.api.assertion.MsScriptAssertion;
|
||||
|
@ -316,7 +315,7 @@ public class TestPlanApiScenarioControllerTests extends BaseTest {
|
|||
request.setProjectId("wxx_project_1234");
|
||||
request.setMoveId(scenarioList.getLast().getId());
|
||||
request.setTargetId(scenarioList.getFirst().getId());
|
||||
request.setMoveMode(MoveTypeEnum.AFTER.name());
|
||||
request.setMoveMode(MoveTypeEnum.BEFORE.name());
|
||||
|
||||
MvcResult result = this.requestPostWithOkAndReturn(URL_POST_RESOURCE_API_SCENARIO_SORT, request);
|
||||
ResultHolder resultHolder = JSON.parseObject(result.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class);
|
||||
|
@ -329,7 +328,7 @@ public class TestPlanApiScenarioControllerTests extends BaseTest {
|
|||
//将这时的第30个放到第一位之后
|
||||
request.setTargetId(scenarioList.getLast().getId());
|
||||
request.setMoveId(scenarioList.getFirst().getId());
|
||||
request.setMoveMode(MoveTypeEnum.BEFORE.name());
|
||||
request.setMoveMode(MoveTypeEnum.AFTER.name());
|
||||
result = this.requestPostWithOkAndReturn(URL_POST_RESOURCE_API_SCENARIO_SORT, request);
|
||||
resultHolder = JSON.parseObject(result.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class);
|
||||
response = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), TestPlanOperationResponse.class);
|
||||
|
|
|
@ -10,6 +10,7 @@ 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.mapper.ExtTestPlanMapper;
|
||||
import io.metersphere.plan.mapper.TestPlanFunctionalCaseMapper;
|
||||
import io.metersphere.plan.mapper.TestPlanMapper;
|
||||
import io.metersphere.plan.mapper.TestPlanReportMapper;
|
||||
import io.metersphere.plan.service.*;
|
||||
|
@ -147,6 +148,8 @@ public class TestPlanTests extends BaseTest {
|
|||
private static final String[] PROJECT_MODULE = new String[]{"workstation", "testPlan", "bugManagement", "caseManagement", "apiTest", "uiTest", "loadTest"};
|
||||
@Resource
|
||||
private ExtTestPlanMapper extTestPlanMapper;
|
||||
@Resource
|
||||
private TestPlanFunctionalCaseMapper testPlanFunctionalCaseMapper;
|
||||
|
||||
@BeforeEach
|
||||
public void initTestData() {
|
||||
|
@ -1264,14 +1267,21 @@ public class TestPlanTests extends BaseTest {
|
|||
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(repeatCaseTestPlan.getId());
|
||||
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.AFTER.name());
|
||||
request.setMoveMode(MoveTypeEnum.BEFORE.name());
|
||||
|
||||
//恢复
|
||||
testPlanTestService.resetProjectModule(project, PROJECT_MODULE);
|
||||
|
@ -1290,7 +1300,7 @@ public class TestPlanTests extends BaseTest {
|
|||
//将这时的第30个放到第一位之后
|
||||
request.setMoveId(funcList.get(29).getId());
|
||||
request.setTargetId(funcList.get(0).getId());
|
||||
request.setMoveMode(MoveTypeEnum.BEFORE.name());
|
||||
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);
|
||||
|
@ -1302,11 +1312,10 @@ public class TestPlanTests extends BaseTest {
|
|||
new CheckLogModel(request.getMoveId(), OperationLogType.UPDATE, URL_POST_RESOURCE_FUNCTIONAL_CASE_SORT)
|
||||
);
|
||||
|
||||
|
||||
//再将这时的第30个放到第一位之后,但是第一个的pos为2,检查能否触发ref操作
|
||||
//再将这时的第30个放到第一位之前,但是第一个的pos为2,检查能否触发ref操作
|
||||
request.setMoveId(funcList.get(29).getId());
|
||||
request.setTargetId(funcList.get(0).getId());
|
||||
request.setMoveMode(MoveTypeEnum.AFTER.name());
|
||||
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);
|
||||
|
@ -1319,11 +1328,11 @@ public class TestPlanTests extends BaseTest {
|
|||
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(repeatCaseTestPlan.getId());
|
||||
request.setTestCollectionId(funcList.getFirst().getTestPlanCollectionId());
|
||||
request.setMoveId(null);
|
||||
this.requestPost(URL_POST_RESOURCE_FUNCTIONAL_CASE_SORT, request).andExpect(status().isBadRequest());
|
||||
//反例:目标节点不存在
|
||||
|
|
Loading…
Reference in New Issue