diff --git a/ROADMAP.md b/ROADMAP.md index a6d51bbbb4..440f6fdbc5 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -55,11 +55,17 @@ - [x] 测试跟踪:支持对接禅道同步缺陷 - [x] 其他:Jenkins 插件支持 pipeline 方式调用 +## v1.6 (开发中) +- [ ] 新增接口管理功能 +- [ ] 全新接口自动化使用方式 +- [ ] 测试跟踪测试计划分类型展示 +- [ ] 优化消息通知配置及实现方式 + ## 规划中 - [ ] 接口测试支持添加 WebSocket 协议请求 -- [ ] 接口管理功能 - [ ] 集成云平台动态管理测试资源池 -- [ ] 支持 K8s 集群作为测试资源池 +- [ ] 测试跟踪测试用例及接口测试增加版本管理 +- [ ] 测试跟踪测试用例增加思维导图展示形式 - [ ] 移动端测试支持 - [ ] UI 功能测试支持 diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java b/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java index f4452ed120..710f2d3aa3 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java @@ -58,6 +58,11 @@ public class ApiAutomationController { apiAutomationService.removeToGc(ids); } + @PostMapping("/reduction") + public void reduction(@RequestBody List ids) { + apiAutomationService.reduction(ids); + } + @GetMapping("/getApiScenario/{id}") public ApiScenario getScenarioDefinition(@PathVariable String id) { return apiAutomationService.getApiScenario(id); diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java b/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java index b27b4737b6..9aa8fea318 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java @@ -6,10 +6,7 @@ import io.metersphere.api.dto.APIReportResult; import io.metersphere.api.dto.ApiTestImportRequest; import io.metersphere.api.dto.automation.ApiScenarioRequest; import io.metersphere.api.dto.automation.ReferenceDTO; -import io.metersphere.api.dto.definition.ApiDefinitionRequest; -import io.metersphere.api.dto.definition.ApiDefinitionResult; -import io.metersphere.api.dto.definition.RunDefinitionRequest; -import io.metersphere.api.dto.definition.SaveApiDefinitionRequest; +import io.metersphere.api.dto.definition.*; import io.metersphere.api.service.ApiDefinitionService; import io.metersphere.base.domain.ApiDefinition; import io.metersphere.commons.constants.RoleConstants; @@ -64,6 +61,11 @@ public class ApiDefinitionController { apiDefinitionService.removeToGc(ids); } + @PostMapping("/reduction") + public void reduction(@RequestBody List ids) { + apiDefinitionService.reduction(ids); + } + @GetMapping("/get/{id}") public ApiDefinition get(@PathVariable String id) { return apiDefinitionService.get(id); @@ -100,4 +102,10 @@ public class ApiDefinitionController { return apiDefinitionService.getReference(request); } + @PostMapping("/batch/edit") + @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR) + public void editApiBath(@RequestBody ApiBatchRequest request) { + apiDefinitionService.editApiBath(request); + } + } diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/ApiScenarioDTO.java b/backend/src/main/java/io/metersphere/api/dto/automation/ApiScenarioDTO.java index 173f7897da..efecbd4e2b 100644 --- a/backend/src/main/java/io/metersphere/api/dto/automation/ApiScenarioDTO.java +++ b/backend/src/main/java/io/metersphere/api/dto/automation/ApiScenarioDTO.java @@ -4,11 +4,13 @@ import io.metersphere.base.domain.ApiScenario; import lombok.Getter; import lombok.Setter; +import java.util.List; + @Getter @Setter public class ApiScenarioDTO extends ApiScenario { private String projectName; private String userName; - private String tagName; + private List tagNames; } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/ApiBatchRequest.java b/backend/src/main/java/io/metersphere/api/dto/definition/ApiBatchRequest.java new file mode 100644 index 0000000000..e69f300944 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/definition/ApiBatchRequest.java @@ -0,0 +1,16 @@ +package io.metersphere.api.dto.definition; + +import io.metersphere.base.domain.ApiDefinitionWithBLOBs; +import io.metersphere.controller.request.OrderRequest; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class ApiBatchRequest extends ApiDefinitionWithBLOBs { + private List ids; + private List orders; + private String projectId; +} diff --git a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java index 70145ccad2..90c436f519 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -22,6 +22,7 @@ import io.metersphere.commons.constants.APITestStatus; import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.ReportTriggerMode; import io.metersphere.commons.exception.MSException; +import io.metersphere.commons.utils.ServiceUtils; import io.metersphere.commons.utils.SessionUtils; import io.metersphere.i18n.Translator; import io.metersphere.track.dto.TestPlanDTO; @@ -67,11 +68,12 @@ public class ApiAutomationService { private static final String BODY_FILE_DIR = "/opt/metersphere/data/body"; public List list(ApiScenarioRequest request) { + request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders())); + List list = extApiScenarioMapper.list(request); ApiTagExample example = new ApiTagExample(); example.createCriteria().andProjectIdEqualTo(request.getProjectId()); List tags = apiTagMapper.selectByExample(example); Map tagMap = tags.stream().collect(Collectors.toMap(ApiTag::getId, ApiTag::getName)); - List list = extApiScenarioMapper.list(request); Gson gs = new Gson(); list.forEach(item -> { if (item.getTagId() != null) { @@ -81,7 +83,11 @@ public class ApiAutomationService { buf.append(","); }); if (buf != null && buf.length() > 0) { - item.setTagName(buf.toString().substring(0, buf.toString().length() - 1)); + String tagNames = buf.toString().substring(0, buf.toString().length() - 1); + List tagList = Arrays.asList(tagNames.split(",")); + item.setTagNames(tagList); + } else { + item.setTagNames(new ArrayList<>()); } } }); @@ -166,12 +172,12 @@ public class ApiAutomationService { apiScenarioMapper.deleteByExample(example); } - public void removeToGc(List ids) { - ApiScenario record = new ApiScenario(); - record.setStatus(ScenarioStatus.Trash.name()); - ApiScenarioExample example = new ApiScenarioExample(); - example.createCriteria().andIdIn(ids); - apiScenarioMapper.updateByExampleSelective(record, example); + public void removeToGc(List apiIds) { + extApiScenarioMapper.removeToGc(apiIds); + } + + public void reduction(List apiIds) { + extApiScenarioMapper.reduction(apiIds); } private void checkNameExist(SaveApiScenarioRequest request) { @@ -242,14 +248,16 @@ public class ApiAutomationService { JSONObject element = JSON.parseObject(item.getScenarioDefinition()); MsScenario scenario = JSONObject.parseObject(item.getScenarioDefinition(), MsScenario.class); // 多态JSON普通转换会丢失内容,需要通过 ObjectMapper 获取 - if (StringUtils.isNotEmpty(element.getString("hashTree"))) { + if (element!= null && StringUtils.isNotEmpty(element.getString("hashTree"))) { LinkedList elements = mapper.readValue(element.getString("hashTree"), - new TypeReference>() {}); + new TypeReference>() { + }); scenario.setHashTree(elements); } if (StringUtils.isNotEmpty(element.getString("variables"))) { LinkedList variables = mapper.readValue(element.getString("variables"), - new TypeReference>() {}); + new TypeReference>() { + }); scenario.setVariables(variables); } LinkedList scenarios = new LinkedList<>(); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java index 5851ca24ec..789009212a 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -163,6 +163,10 @@ public class ApiDefinitionService { extApiDefinitionMapper.removeToGc(apiIds); } + public void reduction(List apiIds) { + extApiDefinitionMapper.reduction(apiIds); + } + public void deleteBodyFiles(String apiId) { File file = new File(BODY_FILE_DIR + "/" + apiId); FileUtil.deleteContents(file); @@ -371,4 +375,15 @@ public class ApiDefinitionService { dto.setTestPlanList(extTestPlanMapper.selectReference(planRequest)); return dto; } + + public void editApiBath(ApiBatchRequest request) { + ApiDefinitionExample definitionExample = new ApiDefinitionExample(); + definitionExample.createCriteria().andIdIn(request.getIds()); + + ApiDefinitionWithBLOBs definitionWithBLOBs = new ApiDefinitionWithBLOBs(); + BeanUtils.copyBean(definitionWithBLOBs, request); + definitionWithBLOBs.setUpdateTime(System.currentTimeMillis()); + apiDefinitionMapper.updateByExampleSelective(definitionWithBLOBs, definitionExample); + } + } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java b/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java index 24d2c3412b..374f6a8c58 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java @@ -123,16 +123,17 @@ public class ApiScenarioModuleService { } } - private List queryByModuleIds(List nodeIds) { + private List queryByModuleIds(DragApiScenarioModuleRequest request) { ApiScenarioRequest apiScenarioRequest = new ApiScenarioRequest(); - apiScenarioRequest.setModuleIds(nodeIds); + apiScenarioRequest.setProjectId(request.getProjectId()); + apiScenarioRequest.setModuleIds(request.getNodeIds()); return apiAutomationService.list(apiScenarioRequest); } public int editNode(DragApiScenarioModuleRequest request) { request.setUpdateTime(System.currentTimeMillis()); checkApiScenarioModuleExist(request); - List apiScenarios = queryByModuleIds(request.getNodeIds()); + List apiScenarios = queryByModuleIds(request); apiScenarios.forEach(apiScenario -> { StringBuilder path = new StringBuilder(apiScenario.getModulePath()); @@ -171,7 +172,7 @@ public class ApiScenarioModuleService { List nodeIds = request.getNodeIds(); - List apiScenarios = queryByModuleIds(nodeIds); + List apiScenarios = queryByModuleIds(request); ApiScenarioModuleDTO nodeTree = request.getNodeTree(); diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.java index 320d5b4664..ba560aeebe 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.java @@ -15,4 +15,6 @@ public interface ExtApiDefinitionMapper { int removeToGc(@Param("ids") List ids); + int reduction(@Param("ids") List ids); + } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml index ab5b4dac15..545bc9b71a 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml @@ -255,4 +255,15 @@ #{v} + + + update api_definition + set + status = 'Underway' + where id in + + #{v} + + + \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java index bec0fbde89..fce72e2e7b 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java @@ -16,4 +16,7 @@ public interface ExtApiScenarioMapper { List selectReference(@Param("request") ApiScenarioRequest request); + int removeToGc(@Param("ids") List ids); + + int reduction(@Param("ids") List ids); } diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml index da36ff4df5..e7c638e10c 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml @@ -88,5 +88,25 @@ + + update api_scenario + set + status = 'Trash' + where id in + + #{v} + + + + + update api_scenario + set + status = 'Underway' + where id in + + #{v} + + + \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestMapper.xml index 032229be0a..3ee03e4735 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestMapper.xml @@ -106,7 +106,7 @@