From 781d27453a9fb8414fdbfd50c598a3cbcd2e894e Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Wed, 23 Dec 2020 11:41:17 +0800 Subject: [PATCH 01/22] =?UTF-8?q?fix:=20=E5=8F=AA=E8=AF=BB=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=B8=8D=E8=83=BD=E6=89=A7=E8=A1=8C=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E3=80=81=E4=BF=AE=E6=94=B9=E3=80=81=E5=88=A0=E9=99=A4=E7=AD=89?= =?UTF-8?q?=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/controller/APIReportController.java | 6 ++-- .../api/controller/APITestController.java | 11 +++---- .../controller/ApiDefinitionController.java | 6 ++++ .../api/controller/ApiModuleController.java | 8 ++--- .../ApiScenarioModuleController.java | 11 ++++--- .../ApiTestEnvironmentController.java | 6 ++-- .../controller/ProjectController.java | 6 ++-- .../controller/PerformanceTestController.java | 25 +++++++++------- ...rvice.java => CheckPermissionService.java} | 29 ++++++++++++++----- .../track/controller/TestCaseController.java | 14 ++++----- .../controller/TestCaseNodeController.java | 10 +++---- .../controller/TestCaseReviewController.java | 10 +++---- .../track/controller/TestPlanController.java | 10 +++---- .../resources/i18n/messages_en_US.properties | 1 + .../resources/i18n/messages_zh_CN.properties | 1 + .../resources/i18n/messages_zh_TW.properties | 1 + 16 files changed, 90 insertions(+), 65 deletions(-) rename backend/src/main/java/io/metersphere/service/{CheckOwnerService.java => CheckPermissionService.java} (76%) diff --git a/backend/src/main/java/io/metersphere/api/controller/APIReportController.java b/backend/src/main/java/io/metersphere/api/controller/APIReportController.java index 8ad8af9d20..5f41294711 100644 --- a/backend/src/main/java/io/metersphere/api/controller/APIReportController.java +++ b/backend/src/main/java/io/metersphere/api/controller/APIReportController.java @@ -11,7 +11,7 @@ import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.Pager; import io.metersphere.commons.utils.SessionUtils; import io.metersphere.dto.DashboardTestDTO; -import io.metersphere.service.CheckOwnerService; +import io.metersphere.service.CheckPermissionService; import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresRoles; import org.springframework.web.bind.annotation.*; @@ -27,7 +27,7 @@ public class APIReportController { @Resource private APIReportService apiReportService; @Resource - private CheckOwnerService checkOwnerService; + private CheckPermissionService checkPermissionService; @GetMapping("recent/{count}") public List recentTest(@PathVariable int count) { @@ -41,7 +41,7 @@ public class APIReportController { @GetMapping("/list/{testId}/{goPage}/{pageSize}") public Pager> listByTestId(@PathVariable String testId, @PathVariable int goPage, @PathVariable int pageSize) { - checkOwnerService.checkApiTestOwner(testId); + checkPermissionService.checkApiTestOwner(testId); Page page = PageHelper.startPage(goPage, pageSize, true); return PageUtils.setPageInfo(page, apiReportService.listByTestId(testId)); diff --git a/backend/src/main/java/io/metersphere/api/controller/APITestController.java b/backend/src/main/java/io/metersphere/api/controller/APITestController.java index ba511fa454..21150523d3 100644 --- a/backend/src/main/java/io/metersphere/api/controller/APITestController.java +++ b/backend/src/main/java/io/metersphere/api/controller/APITestController.java @@ -15,11 +15,13 @@ import io.metersphere.base.domain.ApiTest; import io.metersphere.base.domain.Schedule; import io.metersphere.commons.constants.RoleConstants; import io.metersphere.commons.constants.ScheduleGroup; -import io.metersphere.commons.utils.*; +import io.metersphere.commons.utils.CronUtils; +import io.metersphere.commons.utils.PageUtils; +import io.metersphere.commons.utils.Pager; +import io.metersphere.commons.utils.SessionUtils; import io.metersphere.controller.request.QueryScheduleRequest; import io.metersphere.dto.ScheduleDao; -import io.metersphere.service.CheckOwnerService; - +import io.metersphere.service.CheckPermissionService; import io.metersphere.service.ScheduleService; import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresRoles; @@ -27,7 +29,6 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; - import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Date; @@ -46,7 +47,7 @@ public class APITestController { @Resource private ApiDefinitionService apiDefinitionService; @Resource - private CheckOwnerService checkownerService; + private CheckPermissionService checkownerService; @Resource private ApiTestCaseService apiTestCaseService; @Resource 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 23a7a8c2b5..2fe060e97f 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java @@ -14,6 +14,7 @@ import io.metersphere.commons.constants.RoleConstants; import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.Pager; import io.metersphere.commons.utils.SessionUtils; +import io.metersphere.service.CheckPermissionService; import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest; import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresRoles; @@ -30,6 +31,8 @@ import java.util.List; public class ApiDefinitionController { @Resource private ApiDefinitionService apiDefinitionService; + @Resource + private CheckPermissionService checkPermissionService; @PostMapping("/list/{goPage}/{pageSize}") public Pager> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody ApiDefinitionRequest request) { @@ -41,18 +44,21 @@ public class ApiDefinitionController { @PostMapping(value = "/create", consumes = {"multipart/form-data"}) @RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER}, logical = Logical.OR) public void create(@RequestPart("request") SaveApiDefinitionRequest request, @RequestPart(value = "files") List bodyFiles) { + checkPermissionService.checkReadOnlyUser(); apiDefinitionService.create(request, bodyFiles); } @PostMapping(value = "/update", consumes = {"multipart/form-data"}) @RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER}, logical = Logical.OR) public void update(@RequestPart("request") SaveApiDefinitionRequest request, @RequestPart(value = "files") List bodyFiles) { + checkPermissionService.checkReadOnlyUser(); apiDefinitionService.update(request, bodyFiles); } @GetMapping("/delete/{id}") @RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER}, logical = Logical.OR) public void delete(@PathVariable String id) { + checkPermissionService.checkReadOnlyUser(); apiDefinitionService.delete(id); } diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiModuleController.java b/backend/src/main/java/io/metersphere/api/controller/ApiModuleController.java index 9730e9cd86..69742559ef 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiModuleController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiModuleController.java @@ -5,7 +5,7 @@ import io.metersphere.api.dto.definition.DragModuleRequest; import io.metersphere.api.service.ApiModuleService; import io.metersphere.base.domain.ApiModule; import io.metersphere.commons.constants.RoleConstants; -import io.metersphere.service.CheckOwnerService; +import io.metersphere.service.CheckPermissionService; import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresRoles; import org.springframework.web.bind.annotation.*; @@ -21,17 +21,17 @@ public class ApiModuleController { @Resource ApiModuleService apiModuleService; @Resource - private CheckOwnerService checkOwnerService; + private CheckPermissionService checkPermissionService; @GetMapping("/list/{projectId}/{protocol}") public List getNodeByProjectId(@PathVariable String projectId,@PathVariable String protocol) { - checkOwnerService.checkProjectOwner(projectId); + checkPermissionService.checkProjectOwner(projectId); return apiModuleService.getNodeTreeByProjectId(projectId,protocol); } @GetMapping("/list/plan/{planId}/{protocol}") public List getNodeByPlanId(@PathVariable String planId, @PathVariable String protocol) { - checkOwnerService.checkTestPlanOwner(planId); + checkPermissionService.checkTestPlanOwner(planId); return apiModuleService.getNodeByPlanId(planId, protocol); } diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiScenarioModuleController.java b/backend/src/main/java/io/metersphere/api/controller/ApiScenarioModuleController.java index b51bc9aa4e..abcd2d86a5 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiScenarioModuleController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiScenarioModuleController.java @@ -5,14 +5,13 @@ import io.metersphere.api.dto.automation.DragApiScenarioModuleRequest; import io.metersphere.api.service.ApiScenarioModuleService; import io.metersphere.base.domain.ApiScenarioModule; import io.metersphere.commons.constants.RoleConstants; -import io.metersphere.service.CheckOwnerService; +import io.metersphere.service.CheckPermissionService; import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresRoles; import org.springframework.web.bind.annotation.*; -import java.util.List; - import javax.annotation.Resource; +import java.util.List; @RequestMapping("/api/automation/module") @RestController @@ -22,11 +21,11 @@ public class ApiScenarioModuleController { @Resource ApiScenarioModuleService apiScenarioModuleService; @Resource - private CheckOwnerService checkOwnerService; + private CheckPermissionService checkPermissionService; @GetMapping("/list/{projectId}") public List getNodeByProjectId(@PathVariable String projectId) { - checkOwnerService.checkProjectOwner(projectId); + checkPermissionService.checkProjectOwner(projectId); return apiScenarioModuleService.getNodeTreeByProjectId(projectId); } @@ -44,7 +43,7 @@ public class ApiScenarioModuleController { @GetMapping("/list/plan/{planId}") public List getNodeByPlanId(@PathVariable String planId) { - checkOwnerService.checkTestPlanOwner(planId); + checkPermissionService.checkTestPlanOwner(planId); return apiScenarioModuleService.getNodeByPlanId(planId); } diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiTestEnvironmentController.java b/backend/src/main/java/io/metersphere/api/controller/ApiTestEnvironmentController.java index ae274c383e..87d6e618ce 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiTestEnvironmentController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiTestEnvironmentController.java @@ -3,7 +3,7 @@ package io.metersphere.api.controller; import io.metersphere.api.service.ApiTestEnvironmentService; import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs; import io.metersphere.commons.constants.RoleConstants; -import io.metersphere.service.CheckOwnerService; +import io.metersphere.service.CheckPermissionService; import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresRoles; import org.springframework.web.bind.annotation.*; @@ -19,11 +19,11 @@ public class ApiTestEnvironmentController { @Resource ApiTestEnvironmentService apiTestEnvironmentService; @Resource - private CheckOwnerService checkOwnerService; + private CheckPermissionService checkPermissionService; @GetMapping("/list/{projectId}") public List list(@PathVariable String projectId) { - checkOwnerService.checkProjectOwner(projectId); + checkPermissionService.checkProjectOwner(projectId); return apiTestEnvironmentService.list(projectId); } diff --git a/backend/src/main/java/io/metersphere/controller/ProjectController.java b/backend/src/main/java/io/metersphere/controller/ProjectController.java index 2ce466d0d9..edf0d20024 100644 --- a/backend/src/main/java/io/metersphere/controller/ProjectController.java +++ b/backend/src/main/java/io/metersphere/controller/ProjectController.java @@ -9,7 +9,7 @@ import io.metersphere.commons.utils.Pager; import io.metersphere.commons.utils.SessionUtils; import io.metersphere.controller.request.ProjectRequest; import io.metersphere.dto.ProjectDTO; -import io.metersphere.service.CheckOwnerService; +import io.metersphere.service.CheckPermissionService; import io.metersphere.service.ProjectService; import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresRoles; @@ -24,7 +24,7 @@ public class ProjectController { @Resource private ProjectService projectService; @Resource - private CheckOwnerService checkOwnerService; + private CheckPermissionService checkPermissionService; @GetMapping("/listAll") public List listAll() { @@ -74,7 +74,7 @@ public class ProjectController { @GetMapping("/delete/{projectId}") @RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER,}, logical = Logical.OR) public void deleteProject(@PathVariable(value = "projectId") String projectId) { - checkOwnerService.checkProjectOwner(projectId); + checkPermissionService.checkProjectOwner(projectId); projectService.deleteProject(projectId); } diff --git a/backend/src/main/java/io/metersphere/performance/controller/PerformanceTestController.java b/backend/src/main/java/io/metersphere/performance/controller/PerformanceTestController.java index 9f49ebdacc..893ece5c87 100644 --- a/backend/src/main/java/io/metersphere/performance/controller/PerformanceTestController.java +++ b/backend/src/main/java/io/metersphere/performance/controller/PerformanceTestController.java @@ -14,7 +14,7 @@ import io.metersphere.dto.DashboardTestDTO; import io.metersphere.dto.LoadTestDTO; import io.metersphere.dto.ScheduleDao; import io.metersphere.performance.service.PerformanceTestService; -import io.metersphere.service.CheckOwnerService; +import io.metersphere.service.CheckPermissionService; import io.metersphere.service.FileService; import io.metersphere.track.request.testplan.*; import org.apache.shiro.authz.annotation.Logical; @@ -37,7 +37,7 @@ public class PerformanceTestController { @Resource private FileService fileService; @Resource - private CheckOwnerService checkOwnerService; + private CheckPermissionService checkPermissionService; @GetMapping("recent/{count}") public List recentTestPlans(@PathVariable int count) { @@ -59,14 +59,14 @@ public class PerformanceTestController { @GetMapping("/list/{projectId}") public List list(@PathVariable String projectId) { - checkOwnerService.checkProjectOwner(projectId); + checkPermissionService.checkProjectOwner(projectId); return performanceTestService.getLoadTestByProjectId(projectId); } @GetMapping("/state/get/{testId}") public LoadTest listByTestId(@PathVariable String testId) { - checkOwnerService.checkPerformanceTestOwner(testId); + checkPermissionService.checkPerformanceTestOwner(testId); return performanceTestService.getLoadTestBytestId(testId); } @@ -75,6 +75,7 @@ public class PerformanceTestController { @RequestPart("request") SaveTestPlanRequest request, @RequestPart(value = "file") List files ) { + checkPermissionService.checkReadOnlyUser(); return performanceTestService.save(request, files); } @@ -83,37 +84,39 @@ public class PerformanceTestController { @RequestPart("request") EditTestPlanRequest request, @RequestPart(value = "file", required = false) List files ) { - checkOwnerService.checkPerformanceTestOwner(request.getId()); + checkPermissionService.checkReadOnlyUser(); + checkPermissionService.checkPerformanceTestOwner(request.getId()); return performanceTestService.edit(request, files); } @GetMapping("/get/{testId}") public LoadTestDTO get(@PathVariable String testId) { - checkOwnerService.checkPerformanceTestOwner(testId); + checkPermissionService.checkPerformanceTestOwner(testId); return performanceTestService.get(testId); } @GetMapping("/get-advanced-config/{testId}") public String getAdvancedConfiguration(@PathVariable String testId) { - checkOwnerService.checkPerformanceTestOwner(testId); + checkPermissionService.checkPerformanceTestOwner(testId); return performanceTestService.getAdvancedConfiguration(testId); } @GetMapping("/get-load-config/{testId}") public String getLoadConfiguration(@PathVariable String testId) { - checkOwnerService.checkPerformanceTestOwner(testId); + checkPermissionService.checkPerformanceTestOwner(testId); return performanceTestService.getLoadConfiguration(testId); } @GetMapping("/get-jmx-content/{testId}") public String getJmxContent(@PathVariable String testId) { - checkOwnerService.checkPerformanceTestOwner(testId); + checkPermissionService.checkPerformanceTestOwner(testId); return performanceTestService.getJmxContent(testId); } @PostMapping("/delete") public void delete(@RequestBody DeleteTestPlanRequest request) { - checkOwnerService.checkPerformanceTestOwner(request.getId()); + checkPermissionService.checkReadOnlyUser(); + checkPermissionService.checkPerformanceTestOwner(request.getId()); performanceTestService.delete(request); } @@ -129,7 +132,7 @@ public class PerformanceTestController { @GetMapping("/file/metadata/{testId}") public List getFileMetadata(@PathVariable String testId) { - checkOwnerService.checkPerformanceTestOwner(testId); + checkPermissionService.checkPerformanceTestOwner(testId); return fileService.getFileMetadataByTestId(testId); } diff --git a/backend/src/main/java/io/metersphere/service/CheckOwnerService.java b/backend/src/main/java/io/metersphere/service/CheckPermissionService.java similarity index 76% rename from backend/src/main/java/io/metersphere/service/CheckOwnerService.java rename to backend/src/main/java/io/metersphere/service/CheckPermissionService.java index 84a100406a..cf7d210370 100644 --- a/backend/src/main/java/io/metersphere/service/CheckOwnerService.java +++ b/backend/src/main/java/io/metersphere/service/CheckPermissionService.java @@ -9,7 +9,6 @@ import io.metersphere.commons.utils.SessionUtils; import io.metersphere.i18n.Translator; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.shiro.authz.UnauthorizedException; import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -18,7 +17,7 @@ import java.util.Set; import java.util.stream.Collectors; @Service -public class CheckOwnerService { +public class CheckPermissionService { @Resource private ProjectMapper projectMapper; @Resource @@ -32,6 +31,20 @@ public class CheckOwnerService { @Resource private ExtTestCaseReviewMapper extTestCaseReviewMapper; + + public void checkReadOnlyUser() { + String currentWorkspaceId = SessionUtils.getCurrentWorkspaceId(); + Set collect = Objects.requireNonNull(SessionUtils.getUser()).getUserRoles().stream() + .filter(ur -> + StringUtils.equals(ur.getRoleId(), RoleConstants.TEST_VIEWER)) + .map(UserRole::getSourceId) + .filter(sourceId -> StringUtils.equals(currentWorkspaceId, sourceId)) + .collect(Collectors.toSet()); + if (CollectionUtils.isNotEmpty(collect)) { + throw new RuntimeException(Translator.get("check_owner_read_only")); + } + } + public void checkProjectOwner(String projectId) { Set workspaceIds = getUserRelatedWorkspaceIds(); Project project = projectMapper.selectByPrimaryKey(projectId); @@ -42,7 +55,7 @@ public class CheckOwnerService { return; } if (!workspaceIds.contains(project.getWorkspaceId())) { - throw new UnauthorizedException(Translator.get("check_owner_project")); + throw new RuntimeException(Translator.get("check_owner_project")); } } @@ -67,7 +80,7 @@ public class CheckOwnerService { int result = extApiTestMapper.checkApiTestOwner(testId, workspaceIds); if (result == 0) { - throw new UnauthorizedException(Translator.get("check_owner_test")); + throw new RuntimeException(Translator.get("check_owner_test")); } } @@ -83,7 +96,7 @@ public class CheckOwnerService { int result = extLoadTestMapper.checkLoadTestOwner(testId, workspaceIds); if (result == 0) { - throw new UnauthorizedException(Translator.get("check_owner_test")); + throw new RuntimeException(Translator.get("check_owner_test")); } } @@ -95,7 +108,7 @@ public class CheckOwnerService { int result = extTestCaseMapper.checkIsHave(caseId, workspaceIds); if (result == 0) { - throw new UnauthorizedException(Translator.get("check_owner_case")); + throw new RuntimeException(Translator.get("check_owner_case")); } } @@ -106,7 +119,7 @@ public class CheckOwnerService { } int result = extTestPlanMapper.checkIsHave(planId, workspaceIds); if (result == 0) { - throw new UnauthorizedException(Translator.get("check_owner_plan")); + throw new RuntimeException(Translator.get("check_owner_plan")); } } @@ -117,7 +130,7 @@ public class CheckOwnerService { } int result = extTestCaseReviewMapper.checkIsHave(reviewId, workspaceIds); if (result == 0) { - throw new UnauthorizedException(Translator.get("check_owner_review")); + throw new RuntimeException(Translator.get("check_owner_review")); } } } diff --git a/backend/src/main/java/io/metersphere/track/controller/TestCaseController.java b/backend/src/main/java/io/metersphere/track/controller/TestCaseController.java index 5a5643202d..e87d9cd916 100644 --- a/backend/src/main/java/io/metersphere/track/controller/TestCaseController.java +++ b/backend/src/main/java/io/metersphere/track/controller/TestCaseController.java @@ -11,7 +11,7 @@ import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.Pager; import io.metersphere.commons.utils.SessionUtils; import io.metersphere.excel.domain.ExcelResponse; -import io.metersphere.service.CheckOwnerService; +import io.metersphere.service.CheckPermissionService; import io.metersphere.service.FileService; import io.metersphere.track.dto.TestCaseDTO; import io.metersphere.track.request.testcase.EditTestCaseRequest; @@ -39,7 +39,7 @@ public class TestCaseController { @Resource TestCaseService testCaseService; @Resource - private CheckOwnerService checkOwnerService; + private CheckPermissionService checkPermissionService; @Resource private FileService fileService; @@ -51,7 +51,7 @@ public class TestCaseController { @GetMapping("/list/{projectId}") public List list(@PathVariable String projectId) { - checkOwnerService.checkProjectOwner(projectId); + checkPermissionService.checkProjectOwner(projectId); QueryTestCaseRequest request = new QueryTestCaseRequest(); request.setProjectId(projectId); return testCaseService.listTestCase(request); @@ -94,13 +94,13 @@ public class TestCaseController { @GetMapping("/get/{testCaseId}") public TestCaseWithBLOBs getTestCase(@PathVariable String testCaseId) { - checkOwnerService.checkTestCaseOwner(testCaseId); + checkPermissionService.checkTestCaseOwner(testCaseId); return testCaseService.getTestCase(testCaseId); } @GetMapping("/project/{testCaseId}") public Project getProjectByTestCaseId(@PathVariable String testCaseId) { - checkOwnerService.checkTestCaseOwner(testCaseId); + checkPermissionService.checkTestCaseOwner(testCaseId); return testCaseService.getProjectByTestCaseId(testCaseId); } @@ -119,14 +119,14 @@ public class TestCaseController { @PostMapping("/delete/{testCaseId}") @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR) public int deleteTestCase(@PathVariable String testCaseId) { - checkOwnerService.checkTestCaseOwner(testCaseId); + checkPermissionService.checkTestCaseOwner(testCaseId); return testCaseService.deleteTestCase(testCaseId); } @PostMapping("/import/{projectId}/{userId}") @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR) public ExcelResponse testCaseImport(MultipartFile file, @PathVariable String projectId, @PathVariable String userId) { - checkOwnerService.checkProjectOwner(projectId); + checkPermissionService.checkProjectOwner(projectId); return testCaseService.testCaseImport(file, projectId, userId); } diff --git a/backend/src/main/java/io/metersphere/track/controller/TestCaseNodeController.java b/backend/src/main/java/io/metersphere/track/controller/TestCaseNodeController.java index 0a7f52ee72..e651e58aee 100644 --- a/backend/src/main/java/io/metersphere/track/controller/TestCaseNodeController.java +++ b/backend/src/main/java/io/metersphere/track/controller/TestCaseNodeController.java @@ -2,7 +2,7 @@ package io.metersphere.track.controller; import io.metersphere.base.domain.TestCaseNode; import io.metersphere.commons.constants.RoleConstants; -import io.metersphere.service.CheckOwnerService; +import io.metersphere.service.CheckPermissionService; import io.metersphere.track.dto.TestCaseNodeDTO; import io.metersphere.track.request.testcase.DragNodeRequest; import io.metersphere.track.request.testcase.QueryNodeRequest; @@ -22,11 +22,11 @@ public class TestCaseNodeController { @Resource TestCaseNodeService testCaseNodeService; @Resource - private CheckOwnerService checkOwnerService; + private CheckPermissionService checkPermissionService; @GetMapping("/list/{projectId}") public List getNodeByProjectId(@PathVariable String projectId) { - checkOwnerService.checkProjectOwner(projectId); + checkPermissionService.checkProjectOwner(projectId); return testCaseNodeService.getNodeTreeByProjectId(projectId); } @@ -43,13 +43,13 @@ public class TestCaseNodeController { @GetMapping("/list/plan/{planId}") public List getNodeByPlanId(@PathVariable String planId) { - checkOwnerService.checkTestPlanOwner(planId); + checkPermissionService.checkTestPlanOwner(planId); return testCaseNodeService.getNodeByPlanId(planId); } @GetMapping("/list/review/{reviewId}") public List getNodeByReviewId(@PathVariable String reviewId) { - checkOwnerService.checkTestReviewOwner(reviewId); + checkPermissionService.checkTestReviewOwner(reviewId); return testCaseNodeService.getNodeByReviewId(reviewId); } diff --git a/backend/src/main/java/io/metersphere/track/controller/TestCaseReviewController.java b/backend/src/main/java/io/metersphere/track/controller/TestCaseReviewController.java index d9a755d0f9..84d9b809ef 100644 --- a/backend/src/main/java/io/metersphere/track/controller/TestCaseReviewController.java +++ b/backend/src/main/java/io/metersphere/track/controller/TestCaseReviewController.java @@ -9,7 +9,7 @@ import io.metersphere.commons.constants.RoleConstants; import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.Pager; import io.metersphere.commons.utils.SessionUtils; -import io.metersphere.service.CheckOwnerService; +import io.metersphere.service.CheckPermissionService; import io.metersphere.track.dto.TestCaseReviewDTO; import io.metersphere.track.dto.TestReviewDTOWithMetric; import io.metersphere.track.request.testreview.QueryCaseReviewRequest; @@ -35,7 +35,7 @@ public class TestCaseReviewController { @Resource TestReviewProjectService testReviewProjectService; @Resource - CheckOwnerService checkOwnerService; + CheckPermissionService checkPermissionService; @PostMapping("/list/{goPage}/{pageSize}") public Pager> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryCaseReviewRequest request) { @@ -75,7 +75,7 @@ public class TestCaseReviewController { @GetMapping("/delete/{reviewId}") @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR) public void deleteCaseReview(@PathVariable String reviewId) { - checkOwnerService.checkTestReviewOwner(reviewId); + checkPermissionService.checkTestReviewOwner(reviewId); testCaseReviewService.deleteCaseReview(reviewId); } @@ -107,14 +107,14 @@ public class TestCaseReviewController { @GetMapping("/get/{reviewId}") public TestCaseReview getTestReview(@PathVariable String reviewId) { - checkOwnerService.checkTestReviewOwner(reviewId); + checkPermissionService.checkTestReviewOwner(reviewId); return testCaseReviewService.getTestReview(reviewId); } @PostMapping("/edit/status/{reviewId}") @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR) public void editTestPlanStatus(@PathVariable String reviewId) { - checkOwnerService.checkTestReviewOwner(reviewId); + checkPermissionService.checkTestReviewOwner(reviewId); testCaseReviewService.editTestReviewStatus(reviewId); } diff --git a/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java b/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java index 5e633c46f3..5730ace884 100644 --- a/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java +++ b/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java @@ -8,7 +8,7 @@ import io.metersphere.commons.constants.RoleConstants; import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.Pager; import io.metersphere.commons.utils.SessionUtils; -import io.metersphere.service.CheckOwnerService; +import io.metersphere.service.CheckPermissionService; import io.metersphere.track.dto.TestCaseReportMetricDTO; import io.metersphere.track.dto.TestPlanDTO; import io.metersphere.track.dto.TestPlanDTOWithMetric; @@ -34,7 +34,7 @@ public class TestPlanController { @Resource TestPlanProjectService testPlanProjectService; @Resource - CheckOwnerService checkOwnerService; + CheckPermissionService checkPermissionService; @PostMapping("/list/{goPage}/{pageSize}") public Pager> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryTestPlanRequest request) { @@ -73,7 +73,7 @@ public class TestPlanController { @PostMapping("/get/{testPlanId}") public TestPlan getTestPlan(@PathVariable String testPlanId) { - checkOwnerService.checkTestPlanOwner(testPlanId); + checkPermissionService.checkTestPlanOwner(testPlanId); return testPlanService.getTestPlan(testPlanId); } @@ -92,14 +92,14 @@ public class TestPlanController { @PostMapping("/edit/status/{planId}") @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR) public void editTestPlanStatus(@PathVariable String planId) { - checkOwnerService.checkTestPlanOwner(planId); + checkPermissionService.checkTestPlanOwner(planId); testPlanService.editTestPlanStatus(planId); } @PostMapping("/delete/{testPlanId}") @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR) public int deleteTestPlan(@PathVariable String testPlanId) { - checkOwnerService.checkTestPlanOwner(testPlanId); + checkPermissionService.checkTestPlanOwner(testPlanId); return testPlanService.deleteTestPlan(testPlanId); } diff --git a/backend/src/main/resources/i18n/messages_en_US.properties b/backend/src/main/resources/i18n/messages_en_US.properties index b627fe4fb5..5ce5011793 100644 --- a/backend/src/main/resources/i18n/messages_en_US.properties +++ b/backend/src/main/resources/i18n/messages_en_US.properties @@ -164,6 +164,7 @@ check_owner_case=The current user does not have permission to operate this use c check_owner_plan=The current user does not have permission to operate this plan check_owner_review=The current user does not have permission to operate this review check_owner_comment=The current user does not have permission to manipulate this comment +check_owner_read_only=The current user in this workspace is a read-only user upload_content_is_null=Imported content is empty test_plan_notification=Test plan notification task_defect_notification=Task defect notification diff --git a/backend/src/main/resources/i18n/messages_zh_CN.properties b/backend/src/main/resources/i18n/messages_zh_CN.properties index 89c8359ead..a9824e3984 100644 --- a/backend/src/main/resources/i18n/messages_zh_CN.properties +++ b/backend/src/main/resources/i18n/messages_zh_CN.properties @@ -165,6 +165,7 @@ check_owner_case=当前用户没有操作此用例的权限 check_owner_plan=当前用户没有操作此计划的权限 check_owner_review=当前用户没有操作此评审的权限 check_owner_comment=当前用户没有操作此评论的权限 +check_owner_read_only=当前用户在此工作空间为只读用户 upload_content_is_null=导入内容为空 test_plan_notification=测试计划通知 task_defect_notification=缺陷任务通知 diff --git a/backend/src/main/resources/i18n/messages_zh_TW.properties b/backend/src/main/resources/i18n/messages_zh_TW.properties index ddd705a53e..f6e5762210 100644 --- a/backend/src/main/resources/i18n/messages_zh_TW.properties +++ b/backend/src/main/resources/i18n/messages_zh_TW.properties @@ -166,6 +166,7 @@ check_owner_case=當前用戶沒有操作此用例的權限 check_owner_plan=當前用戶沒有操作此計劃的權限 check_owner_review=當前用戶沒有操作此評審的權限 check_owner_comment=當前用戶沒有操作此評論的權限 +check_owner_read_only=當前用戶在此工作空間為只讀用戶 upload_content_is_null=導入內容為空 test_plan_notification=測試計畫通知 task_defect_notification=缺陷任務通知 From b9afa3c2983f1f90e9b09d02846a7f65eea523a5 Mon Sep 17 00:00:00 2001 From: "song.tianyang" Date: Wed, 23 Dec 2020 12:33:23 +0800 Subject: [PATCH 02/22] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1=E5=BC=B9?= =?UTF-8?q?=E6=A1=86=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复接口自动化定时任务弹框报错的问题 --- .../api/automation/schedule/ScheduleNotification.vue | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/src/business/components/api/automation/schedule/ScheduleNotification.vue b/frontend/src/business/components/api/automation/schedule/ScheduleNotification.vue index 09da062150..074ff9c691 100644 --- a/frontend/src/business/components/api/automation/schedule/ScheduleNotification.vue +++ b/frontend/src/business/components/api/automation/schedule/ScheduleNotification.vue @@ -110,16 +110,19 @@ - + + + diff --git a/frontend/src/business/components/track/plan/view/comonents/report/statistics/TestCaseStatisticsReportView.vue b/frontend/src/business/components/track/plan/view/comonents/report/statistics/TestCaseStatisticsReportView.vue new file mode 100644 index 0000000000..27bdee8af1 --- /dev/null +++ b/frontend/src/business/components/track/plan/view/comonents/report/statistics/TestCaseStatisticsReportView.vue @@ -0,0 +1,252 @@ + + +cd + + diff --git a/frontend/src/business/components/xpack b/frontend/src/business/components/xpack index a22a3005d9..010ad7a5f0 160000 --- a/frontend/src/business/components/xpack +++ b/frontend/src/business/components/xpack @@ -1 +1 @@ -Subproject commit a22a3005d9bd254793fcf634d72539cbdf31be3a +Subproject commit 010ad7a5f072a5e9d368c756a2473bbd20781433 From 847585e427a8a619aad93fc2496dbd60e23c4d14 Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 23 Dec 2020 14:40:31 +0800 Subject: [PATCH 07/22] =?UTF-8?q?feat:=20=E6=B5=8B=E8=AF=95=E8=AE=A1?= =?UTF-8?q?=E5=88=92-=E6=8A=A5=E5=91=8A=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../track/Factory/ReportComponentFactory.java | 3 +- .../track/controller/TestPlanController.java | 5 + .../ReportResultAdvancedChartComponent.java | 95 ++++++++++---- .../domain/ReportResultChartComponent.java | 2 +- .../TestCaseReportAdvanceStatusResultDTO.java | 9 +- .../track/dto/TestCaseReportMetricDTO.java | 3 +- .../track/service/TestPlanService.java | 117 ++++++++++++++---- 7 files changed, 179 insertions(+), 55 deletions(-) diff --git a/backend/src/main/java/io/metersphere/track/Factory/ReportComponentFactory.java b/backend/src/main/java/io/metersphere/track/Factory/ReportComponentFactory.java index cf0f0e83a7..15793efd0a 100644 --- a/backend/src/main/java/io/metersphere/track/Factory/ReportComponentFactory.java +++ b/backend/src/main/java/io/metersphere/track/Factory/ReportComponentFactory.java @@ -15,7 +15,8 @@ public class ReportComponentFactory { } else if (StringUtils.equals("2", componentId)) { return new ReportResultComponent(testPlan); } else if (StringUtils.equals("3", componentId)) { - return new ReportResultChartComponent(testPlan); + return new ReportResultAdvancedChartComponent(testPlan); +// return new ReportResultChartComponent(testPlan); } else if (StringUtils.equals("4", componentId)) { return new ReportFailureResultComponent(testPlan); } diff --git a/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java b/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java index 5e633c46f3..f6dba70cdd 100644 --- a/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java +++ b/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java @@ -113,6 +113,11 @@ public class TestPlanController { return testPlanService.getMetric(planId); } + @GetMapping("/get/statistics/metric/{planId}") + public TestCaseReportMetricDTO getStatisticsMetric(@PathVariable String planId) { + return testPlanService.getStatisticsMetric(planId); + } + @GetMapping("/project/name/{planId}") public String getProjectNameByPlanId(@PathVariable String planId) { return testPlanService.getProjectNameByPlanId(planId); diff --git a/backend/src/main/java/io/metersphere/track/domain/ReportResultAdvancedChartComponent.java b/backend/src/main/java/io/metersphere/track/domain/ReportResultAdvancedChartComponent.java index 1a0817ce65..e81697ce3d 100644 --- a/backend/src/main/java/io/metersphere/track/domain/ReportResultAdvancedChartComponent.java +++ b/backend/src/main/java/io/metersphere/track/domain/ReportResultAdvancedChartComponent.java @@ -1,28 +1,48 @@ package io.metersphere.track.domain; +import io.metersphere.api.dto.automation.ApiScenarioDTO; +import io.metersphere.api.dto.definition.TestPlanApiCaseDTO; +import io.metersphere.commons.constants.APITestStatus; import io.metersphere.commons.constants.TestPlanTestCaseStatus; -import io.metersphere.track.dto.TestCaseReportMetricDTO; -import io.metersphere.track.dto.TestCaseReportStatusResultDTO; -import io.metersphere.track.dto.TestPlanCaseDTO; -import io.metersphere.track.dto.TestPlanDTO; +import io.metersphere.track.dto.*; +import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -public class ReportResultChartComponent extends ReportComponent { - Map reportStatusResultMap = new HashMap<>(); +public class ReportResultAdvancedChartComponent extends ReportComponent { + Map functionalStatusResultMap = new HashMap<>(); + Map apiStatusResultMap = new HashMap<>(); + Map scenarioStatusResultMap = new HashMap<>(); - public ReportResultChartComponent(TestPlanDTO testPlan) { + private static Map apiResultMap = new HashMap<>(); + private static Map scenarioResultMap = new HashMap<>(); + + static { + apiResultMap.put("success", TestPlanTestCaseStatus.Pass.name()); + apiResultMap.put("error", TestPlanTestCaseStatus.Failure.name()); + scenarioResultMap.put(APITestStatus.Success.name(), TestPlanTestCaseStatus.Pass.name()); + scenarioResultMap.put(APITestStatus.Error.name(), TestPlanTestCaseStatus.Failure.name()); + } + + public ReportResultAdvancedChartComponent(TestPlanDTO testPlan) { super(testPlan); componentId = "3"; } - @Override public void readRecord(TestPlanCaseDTO testCase) { - getStatusResultMap(reportStatusResultMap, testCase); + getStatusResultMap(functionalStatusResultMap, testCase.getStatus()); + } + + public void readRecord(TestPlanApiCaseDTO testCase) { + getStatusResultMap(apiStatusResultMap, apiResultMap.get(testCase.getExecResult())); + } + + public void readRecord(ApiScenarioDTO testCase) { + getStatusResultMap(scenarioStatusResultMap, scenarioResultMap.get(testCase.getLastResult())); } @Override @@ -30,31 +50,58 @@ public class ReportResultChartComponent extends ReportComponent { testCaseReportMetric.setExecuteResult(getReportStatusResult()); } - private List getReportStatusResult() { - List reportStatusResult = new ArrayList<>(); - addToReportStatusResultList(reportStatusResult, TestPlanTestCaseStatus.Pass.name()); - addToReportStatusResultList(reportStatusResult, TestPlanTestCaseStatus.Failure.name()); - addToReportStatusResultList(reportStatusResult, TestPlanTestCaseStatus.Blocking.name()); - addToReportStatusResultList(reportStatusResult, TestPlanTestCaseStatus.Skip.name()); - addToReportStatusResultList(reportStatusResult, TestPlanTestCaseStatus.Underway.name()); - addToReportStatusResultList(reportStatusResult, TestPlanTestCaseStatus.Prepare.name()); + private TestCaseReportAdvanceStatusResultDTO getReportStatusResult() { + TestCaseReportAdvanceStatusResultDTO reportStatusResult = new TestCaseReportAdvanceStatusResultDTO(); + buildFunctionalStatusResult(reportStatusResult); + buildApiStatusResult(reportStatusResult); + buildScenarioStatusResult(reportStatusResult); return reportStatusResult; } - private void addToReportStatusResultList(List reportStatusResultList, String status) { - if (reportStatusResultMap.get(status) != null) { - reportStatusResultList.add(reportStatusResultMap.get(status)); + private void buildFunctionalStatusResult(TestCaseReportAdvanceStatusResultDTO reportStatusResult) { + List functionalStatusResult = new ArrayList<>(); + addToReportStatusResultList(functionalStatusResultMap, functionalStatusResult, TestPlanTestCaseStatus.Pass.name()); + addToReportStatusResultList(functionalStatusResultMap, functionalStatusResult, TestPlanTestCaseStatus.Failure.name()); + addToReportStatusResultList(functionalStatusResultMap, functionalStatusResult, TestPlanTestCaseStatus.Blocking.name()); + addToReportStatusResultList(functionalStatusResultMap, functionalStatusResult, TestPlanTestCaseStatus.Skip.name()); + addToReportStatusResultList(functionalStatusResultMap, functionalStatusResult, TestPlanTestCaseStatus.Underway.name()); + addToReportStatusResultList(functionalStatusResultMap, functionalStatusResult, TestPlanTestCaseStatus.Prepare.name()); + reportStatusResult.setFunctionalResult(functionalStatusResult); + } + + private void buildApiStatusResult(TestCaseReportAdvanceStatusResultDTO reportStatusResult) { + List apiStatusResult = new ArrayList<>(); + addToReportStatusResultList(apiStatusResultMap, apiStatusResult, TestPlanTestCaseStatus.Pass.name()); + addToReportStatusResultList(apiStatusResultMap, apiStatusResult, TestPlanTestCaseStatus.Failure.name()); + addToReportStatusResultList(apiStatusResultMap, apiStatusResult, TestPlanTestCaseStatus.Underway.name()); + reportStatusResult.setApiResult(apiStatusResult); + } + + private void buildScenarioStatusResult(TestCaseReportAdvanceStatusResultDTO reportStatusResult) { + List scenarioStatusResult = new ArrayList<>(); + addToReportStatusResultList(scenarioStatusResultMap, scenarioStatusResult, TestPlanTestCaseStatus.Pass.name()); + addToReportStatusResultList(scenarioStatusResultMap, scenarioStatusResult, TestPlanTestCaseStatus.Failure.name()); + addToReportStatusResultList(scenarioStatusResultMap, scenarioStatusResult, TestPlanTestCaseStatus.Underway.name()); + reportStatusResult.setScenarioResult(scenarioStatusResult); + } + + private void addToReportStatusResultList(Map resultMap, List reportStatusResultList, String status) { + if (resultMap.get(status) != null) { + reportStatusResultList.add(resultMap.get(status)); } } - private void getStatusResultMap(Map reportStatusResultMap, TestPlanCaseDTO testCase) { - TestCaseReportStatusResultDTO statusResult = reportStatusResultMap.get(testCase.getStatus()); + private void getStatusResultMap(Map reportStatusResultMap, String result) { + if (StringUtils.isBlank(result)) { + result = TestPlanTestCaseStatus.Underway.name(); + } + TestCaseReportStatusResultDTO statusResult = reportStatusResultMap.get(result); if (statusResult == null) { statusResult = new TestCaseReportStatusResultDTO(); - statusResult.setStatus(testCase.getStatus()); + statusResult.setStatus(result); statusResult.setCount(0); } statusResult.setCount(statusResult.getCount() + 1); - reportStatusResultMap.put(testCase.getStatus(), statusResult); + reportStatusResultMap.put(result, statusResult); } } diff --git a/backend/src/main/java/io/metersphere/track/domain/ReportResultChartComponent.java b/backend/src/main/java/io/metersphere/track/domain/ReportResultChartComponent.java index 1a0817ce65..778182938c 100644 --- a/backend/src/main/java/io/metersphere/track/domain/ReportResultChartComponent.java +++ b/backend/src/main/java/io/metersphere/track/domain/ReportResultChartComponent.java @@ -27,7 +27,7 @@ public class ReportResultChartComponent extends ReportComponent { @Override public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) { - testCaseReportMetric.setExecuteResult(getReportStatusResult()); +// testCaseReportMetric.setExecuteResult(getReportStatusResult()); } private List getReportStatusResult() { diff --git a/backend/src/main/java/io/metersphere/track/dto/TestCaseReportAdvanceStatusResultDTO.java b/backend/src/main/java/io/metersphere/track/dto/TestCaseReportAdvanceStatusResultDTO.java index ea29555e7c..a092ebd190 100644 --- a/backend/src/main/java/io/metersphere/track/dto/TestCaseReportAdvanceStatusResultDTO.java +++ b/backend/src/main/java/io/metersphere/track/dto/TestCaseReportAdvanceStatusResultDTO.java @@ -3,10 +3,13 @@ package io.metersphere.track.dto; import lombok.Getter; import lombok.Setter; +import java.util.List; + @Getter @Setter -public class TestCaseReportStatusResultDTO { - private String status; - private Integer count; +public class TestCaseReportAdvanceStatusResultDTO { + private List functionalResult; + private List apiResult; + private List scenarioResult; } diff --git a/backend/src/main/java/io/metersphere/track/dto/TestCaseReportMetricDTO.java b/backend/src/main/java/io/metersphere/track/dto/TestCaseReportMetricDTO.java index b1b4e8fcd9..1469213ac3 100644 --- a/backend/src/main/java/io/metersphere/track/dto/TestCaseReportMetricDTO.java +++ b/backend/src/main/java/io/metersphere/track/dto/TestCaseReportMetricDTO.java @@ -10,7 +10,8 @@ import java.util.List; @Setter public class TestCaseReportMetricDTO { - private List executeResult; +// private List executeResult; + private TestCaseReportAdvanceStatusResultDTO executeResult; private List moduleExecuteResult; private List failureTestCases; private List Issues; diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java index c218d0e95b..aa759b85e6 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java @@ -3,6 +3,10 @@ package io.metersphere.track.service; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import io.metersphere.api.dto.automation.ApiScenarioDTO; +import io.metersphere.api.dto.automation.TestPlanScenarioRequest; +import io.metersphere.api.dto.definition.ApiTestCaseRequest; +import io.metersphere.api.dto.definition.TestPlanApiCaseDTO; import io.metersphere.base.domain.*; import io.metersphere.base.mapper.*; import io.metersphere.base.mapper.ext.ExtProjectMapper; @@ -22,6 +26,7 @@ import io.metersphere.notice.service.NoticeSendService; import io.metersphere.service.SystemParameterService; import io.metersphere.track.Factory.ReportComponentFactory; import io.metersphere.track.domain.ReportComponent; +import io.metersphere.track.domain.ReportResultAdvancedChartComponent; import io.metersphere.track.dto.TestCaseReportMetricDTO; import io.metersphere.track.dto.TestPlanCaseDTO; import io.metersphere.track.dto.TestPlanDTO; @@ -80,6 +85,10 @@ public class TestPlanService { private NoticeSendService noticeSendService; @Resource private SystemParameterService systemParameterService; + @Resource + private TestPlanApiCaseService testPlanApiCaseService; + @Resource + private TestPlanScenarioCaseService testPlanScenarioCaseService; public synchronized void addTestPlan(AddTestPlanRequest testPlan) { if (getTestPlanByName(testPlan.getName()).size() > 0) { @@ -459,7 +468,6 @@ public class TestPlanService { } public TestCaseReportMetricDTO getMetric(String planId) { - IssuesService issuesService = (IssuesService) CommonBeanFactory.getBean("issuesService"); QueryTestPlanRequest queryTestPlanRequest = new QueryTestPlanRequest(); queryTestPlanRequest.setId(planId); @@ -472,31 +480,8 @@ public class TestPlanService { JSONArray componentIds = content.getJSONArray("components"); List components = ReportComponentFactory.createComponents(componentIds.toJavaList(String.class), testPlan); + List issues = buildFunctionalCaseReport(planId, components); - List testPlanTestCases = listTestCaseByPlanId(planId); - List issues = new ArrayList<>(); - for (TestPlanCaseDTO testCase : testPlanTestCases) { - List issue = issuesService.getIssues(testCase.getCaseId()); - if (issue.size() > 0) { - for (Issues i : issue) { - i.setModel(testCase.getNodePath()); - i.setProjectName(testCase.getProjectName()); - String des = i.getDescription().replaceAll("

", "").replaceAll("

", ""); - i.setDescription(des); - if (i.getLastmodify() == null || i.getLastmodify() == "") { - if (i.getReporter() != null || i.getReporter() != "") { - i.setLastmodify(i.getReporter()); - } - } - } - issues.addAll(issue); - Collections.sort(issues, Comparator.comparing(Issues::getCreateTime, (t1, t2) -> t2.compareTo(t1))); - } - - components.forEach(component -> { - component.readRecord(testCase); - }); - } TestCaseReportMetricDTO testCaseReportMetricDTO = new TestCaseReportMetricDTO(); components.forEach(component -> { component.afterBuild(testCaseReportMetricDTO); @@ -609,4 +594,86 @@ public class TestPlanService { return context; } + public TestCaseReportMetricDTO getStatisticsMetric(String planId) { + QueryTestPlanRequest queryTestPlanRequest = new QueryTestPlanRequest(); + queryTestPlanRequest.setId(planId); + + TestPlanDTO testPlan = extTestPlanMapper.list(queryTestPlanRequest).get(0); + String projectName = getProjectNameByPlanId(planId); + testPlan.setProjectName(projectName); + + TestCaseReport testCaseReport = testCaseReportMapper.selectByPrimaryKey(testPlan.getReportId()); + JSONObject content = JSONObject.parseObject(testCaseReport.getContent()); + JSONArray componentIds = content.getJSONArray("components"); + + List components = ReportComponentFactory.createComponents(componentIds.toJavaList(String.class), testPlan); + List issues = buildFunctionalCaseReport(planId, components); + buildApiCaseReport(planId, components); + buildScenarioCaseReport(planId, components); + + TestCaseReportMetricDTO testCaseReportMetricDTO = new TestCaseReportMetricDTO(); + components.forEach(component -> { + component.afterBuild(testCaseReportMetricDTO); + }); + testCaseReportMetricDTO.setIssues(issues); + return testCaseReportMetricDTO; + } + + public void buildApiCaseReport(String planId, List components) { + ApiTestCaseRequest request = new ApiTestCaseRequest(); + request.setPlanId(planId); + List apiCaseDTOS = testPlanApiCaseService.list(request); + ReportResultAdvancedChartComponent chartComponent = null; + for (TestPlanApiCaseDTO item : apiCaseDTOS) { + for (ReportComponent component : components) { + if (component instanceof ReportResultAdvancedChartComponent) { + chartComponent = (ReportResultAdvancedChartComponent) component; + chartComponent.readRecord(item); + } + } + } + } + + public void buildScenarioCaseReport(String planId, List components) { + TestPlanScenarioRequest request = new TestPlanScenarioRequest(); + request.setPlanId(planId); + List scenarioDTOS = testPlanScenarioCaseService.list(request); + ReportResultAdvancedChartComponent chartComponent = null; + for (ApiScenarioDTO item : scenarioDTOS) { + for (ReportComponent component : components) { + if (component instanceof ReportResultAdvancedChartComponent) { + chartComponent = (ReportResultAdvancedChartComponent) component; + chartComponent.readRecord(item); + } + } + } + } + + public List buildFunctionalCaseReport(String planId, List components) { + IssuesService issuesService = (IssuesService) CommonBeanFactory.getBean("issuesService"); + List testPlanTestCases = listTestCaseByPlanId(planId); + List issues = new ArrayList<>(); + for (TestPlanCaseDTO testCase : testPlanTestCases) { + List issue = issuesService.getIssues(testCase.getCaseId()); + if (issue.size() > 0) { + for (Issues i : issue) { + i.setModel(testCase.getNodePath()); + i.setProjectName(testCase.getProjectName()); + String des = i.getDescription().replaceAll("

", "").replaceAll("

", ""); + i.setDescription(des); + if (i.getLastmodify() == null || i.getLastmodify() == "") { + if (i.getReporter() != null || i.getReporter() != "") { + i.setLastmodify(i.getReporter()); + } + } + } + issues.addAll(issue); + Collections.sort(issues, Comparator.comparing(Issues::getCreateTime, (t1, t2) -> t2.compareTo(t1))); + } + components.forEach(component -> { + component.readRecord(testCase); + }); + } + return issues; + } } From b99e219d7c92a28320bb0013ecf0e9cd8b24cc60 Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Wed, 23 Dec 2020 15:00:51 +0800 Subject: [PATCH 08/22] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E8=B5=84?= =?UTF-8?q?=E6=BA=90=E6=B1=A0=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../settings/system/TestResourcePool.vue | 132 +++--------------- 1 file changed, 20 insertions(+), 112 deletions(-) diff --git a/frontend/src/business/components/settings/system/TestResourcePool.vue b/frontend/src/business/components/settings/system/TestResourcePool.vue index e01d094084..645396711c 100644 --- a/frontend/src/business/components/settings/system/TestResourcePool.vue +++ b/frontend/src/business/components/settings/system/TestResourcePool.vue @@ -47,14 +47,14 @@ + ref="testResourcePoolForm"> @@ -137,105 +137,15 @@ - - - - - - - - - - - - - - - - Node - Kubernetes - - -
-
- - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
- @@ -245,7 +155,7 @@ import MsTablePagination from "../../common/pagination/TablePagination"; import MsTableHeader from "../../common/components/MsTableHeader"; import MsTableOperator from "../../common/components/MsTableOperator"; import MsDialogFooter from "../../common/components/MsDialogFooter"; -import {listenGoBack, removeGoBackListener} from "../../../../common/js/utils"; +import {listenGoBack, removeGoBackListener} from "@/common/js/utils"; export default { name: "MsTestResourcePool", @@ -253,9 +163,8 @@ export default { data() { return { result: {}, - createVisible: false, + dialogVisible: false, infoList: [], - updateVisible: false, queryPath: "testresourcepool/list", condition: {}, items: [], @@ -340,11 +249,11 @@ export default { this.initTableData(); }, create() { - this.createVisible = true; + this.dialogVisible = true; listenGoBack(this.closeFunc); }, edit(row) { - this.updateVisible = true; + this.dialogVisible = true; this.form = JSON.parse(JSON.stringify(row)); this.convertResources(); listenGoBack(this.closeFunc); @@ -374,8 +283,8 @@ export default { this.$info(this.$t('commons.delete_cancel')); }); }, - createTestResourcePool(createTestResourcePoolForm) { - this.$refs[createTestResourcePoolForm].validate(valid => { + createTestResourcePool() { + this.$refs.testResourcePoolForm.validate(valid => { if (valid) { let vri = this.validateResourceInfo(); if (vri.validate) { @@ -385,7 +294,7 @@ export default { type: 'success', message: this.$t('commons.save_success') }, - this.createVisible = false, + this.dialogVisible = false, this.initTableData()); }); } else { @@ -411,8 +320,8 @@ export default { }); this.form.resources = resources; }, - updateTestResourcePool(updateTestResourcePoolForm) { - this.$refs[updateTestResourcePoolForm].validate(valid => { + updateTestResourcePool() { + this.$refs.testResourcePoolForm.validate(valid => { if (valid) { let vri = this.validateResourceInfo(); if (vri.validate) { @@ -422,7 +331,7 @@ export default { type: 'success', message: this.$t('commons.modify_success') }, - this.updateVisible = false, + this.dialogVisible = false, this.initTableData(), self.loading = false); }); @@ -437,8 +346,7 @@ export default { }, closeFunc() { this.form = {}; - this.updateVisible = false; - this.createVisible = false; + this.dialogVisible = false; removeGoBackListener(this.closeFunc); }, changeSwitch(row) { From d4ec0c44ec1ade1dbb94310e21a77c17c873b795 Mon Sep 17 00:00:00 2001 From: shiziyuan9527 Date: Wed, 23 Dec 2020 15:09:48 +0800 Subject: [PATCH 09/22] =?UTF-8?q?fix(=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B)?= =?UTF-8?q?:=20=E4=BF=AE=E5=A4=8D=E5=AF=BC=E5=85=A5=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=94=A8=E4=BE=8B=E6=9C=AA=E5=88=B7=E6=96=B0=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E6=A0=91=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/business/components/track/case/TestCase.vue | 5 +++++ .../components/track/case/components/TestCaseImport.vue | 4 ++-- .../components/track/case/components/TestCaseList.vue | 6 +++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/frontend/src/business/components/track/case/TestCase.vue b/frontend/src/business/components/track/case/TestCase.vue index c3d5e3d94f..4ff0576e9e 100644 --- a/frontend/src/business/components/track/case/TestCase.vue +++ b/frontend/src/business/components/track/case/TestCase.vue @@ -19,6 +19,7 @@ @testCaseDetail="showTestCaseDetail" @batchMove="batchMove" @refresh="refresh" + @refreshAll="refreshAll" @moveToNode="moveToNode" ref="testCaseList"> @@ -131,6 +132,10 @@ export default { this.selectNode = {}; this.refreshTable(); }, + refreshAll() { + this.$refs.nodeTree.list(); + this.refresh(); + }, openRecentTestCaseEditDialog(caseId) { if (caseId) { // this.getProjectByCaseId(caseId); diff --git a/frontend/src/business/components/track/case/components/TestCaseImport.vue b/frontend/src/business/components/track/case/components/TestCaseImport.vue index 8688c52489..a82195348f 100644 --- a/frontend/src/business/components/track/case/components/TestCaseImport.vue +++ b/frontend/src/business/components/track/case/components/TestCaseImport.vue @@ -204,7 +204,7 @@ if (res.success) { this.$success(this.$t('test_track.case.import.success')); this.dialogVisible = false; - this.$emit("refresh"); + this.$emit("refreshAll"); } else { this.errList = res.errList; } @@ -223,7 +223,7 @@ if (res.success) { this.$success(this.$t('test_track.case.import.success')); this.dialogVisible = false; - this.$emit("refresh"); + this.$emit("refreshAll"); } else { this.xmindErrList = res.errList; } diff --git a/frontend/src/business/components/track/case/components/TestCaseList.vue b/frontend/src/business/components/track/case/components/TestCaseList.vue index 7062407e14..c55742624d 100644 --- a/frontend/src/business/components/track/case/components/TestCaseList.vue +++ b/frontend/src/business/components/track/case/components/TestCaseList.vue @@ -25,7 +25,7 @@ - + Date: Wed, 23 Dec 2020 15:15:39 +0800 Subject: [PATCH 10/22] =?UTF-8?q?fix:=20=E6=8E=A5=E5=8F=A3=E5=85=B3?= =?UTF-8?q?=E8=81=94=E6=B5=8B=E8=AF=95=E8=AE=A1=E5=88=92=E3=80=81=E5=9C=BA?= =?UTF-8?q?=E6=99=AF=E5=85=B3=E8=81=94=E6=B5=8B=E8=AF=95=E8=AE=A1=E5=88=92?= =?UTF-8?q?=E6=97=A0=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复接口关联测试计划、场景关联测试计划无效,测试计划里找不到数据的问题 --- .../api/service/ApiAutomationService.java | 132 ++++++++++++++---- .../api/service/ApiDefinitionService.java | 2 +- .../api/service/ApiTestCaseService.java | 10 ++ .../base/mapper/ext/ExtTestPlanMapper.java | 7 + .../base/mapper/ext/ExtTestPlanMapper.xml | 12 ++ .../ext/ExtTestPlanScenarioCaseMapper.java | 3 + .../mapper/ext/ExtTestPlanTestCaseMapper.java | 1 + .../mapper/ext/ExtTestPlanTestCaseMapper.xml | 4 + 8 files changed, 140 insertions(+), 31 deletions(-) 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 8089c6f4d7..4d14e5a803 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -14,7 +14,9 @@ import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; import io.metersphere.api.jmeter.JMeterService; import io.metersphere.base.domain.*; import io.metersphere.base.mapper.ApiScenarioMapper; +import io.metersphere.base.mapper.TestPlanApiScenarioMapper; import io.metersphere.base.mapper.ext.ExtApiScenarioMapper; +import io.metersphere.base.mapper.ext.ExtTestPlanApiCaseMapper; import io.metersphere.base.mapper.ext.ExtTestPlanMapper; import io.metersphere.base.mapper.ext.ExtTestPlanScenarioCaseMapper; import io.metersphere.commons.constants.*; @@ -28,6 +30,9 @@ import io.metersphere.service.ScheduleService; import io.metersphere.track.dto.TestPlanDTO; import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest; import io.metersphere.track.request.testcase.QueryTestPlanRequest; +import io.metersphere.track.request.testcase.TestPlanApiCaseBatchRequest; +import io.metersphere.track.service.TestPlanApiCaseService; +import io.metersphere.track.service.TestPlanScenarioCaseService; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.ibatis.session.ExecutorType; @@ -53,8 +58,8 @@ public class ApiAutomationService { private ApiDefinitionService apiDefinitionService; @Resource private ExtApiScenarioMapper extApiScenarioMapper; -// @Resource -// private ApiTagMapper apiTagMapper; + @Resource + private TestPlanApiScenarioMapper testPlanApiScenarioMapper; @Resource private JMeterService jMeterService; @Resource @@ -150,10 +155,48 @@ public class ApiAutomationService { } public void delete(String id) { + //及连删除外键表 + this.preDelete(id); apiScenarioMapper.deleteByPrimaryKey(id); } + public void preDelete(String scenarioID){ + + TestPlanApiScenarioExample example = new TestPlanApiScenarioExample(); + example.createCriteria().andApiScenarioIdEqualTo(scenarioID); + List testPlanApiScenarioList = testPlanApiScenarioMapper.selectByExample(example); + + List idList = new ArrayList<>(testPlanApiScenarioList.size()); + for (TestPlanApiScenario api : + testPlanApiScenarioList) { + idList.add(api.getId()); + } + example = new TestPlanApiScenarioExample(); + example.createCriteria() + .andIdIn(idList); + testPlanApiScenarioMapper.deleteByExample(example); + } + public void preDelete(List scenarioIDList){ + List idList = new ArrayList<>(); + for (String id :scenarioIDList) { + TestPlanApiScenarioExample example = new TestPlanApiScenarioExample(); + example.createCriteria().andApiScenarioIdEqualTo(id); + List testPlanApiScenarioList = testPlanApiScenarioMapper.selectByExample(example); + + for (TestPlanApiScenario api :testPlanApiScenarioList) { + if(!idList.contains(api.getId())){ + idList.add(api.getId()); + } + } + } + TestPlanApiScenarioExample example = new TestPlanApiScenarioExample(); + example.createCriteria() + .andIdIn(idList); + testPlanApiScenarioMapper.deleteByExample(example); + } public void deleteBatch(List ids) { + //及连删除外键表 + preDelete(ids);; ApiScenarioExample example = new ApiScenarioExample(); example.createCriteria().andIdIn(ids); apiScenarioMapper.deleteByExample(example); @@ -301,7 +344,7 @@ public class ApiAutomationService { QueryTestPlanRequest planRequest = new QueryTestPlanRequest(); planRequest.setScenarioId(request.getId()); planRequest.setProjectId(request.getProjectId()); - dto.setTestPlanList(extTestPlanMapper.selectReference(planRequest)); + dto.setTestPlanList(extTestPlanMapper.selectTestPlanByRelevancy(planRequest)); return dto; } @@ -312,37 +355,66 @@ public class ApiAutomationService { List list = extTestPlanMapper.selectByIds(request.getPlanIds()); SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); ExtTestPlanMapper mapper = sqlSession.getMapper(ExtTestPlanMapper.class); - list.forEach(item -> { - if (CollectionUtils.isNotEmpty(request.getApiIds())) { - if (CollectionUtils.isNotEmpty(request.getApiIds())) { - if (StringUtils.isEmpty(item.getApiIds())) { - item.setApiIds(JSON.toJSONString(request.getApiIds())); - } else { - // 合并api - List dbApiIDs = JSON.parseArray(item.getApiIds(), String.class); - List result = Stream.of(request.getApiIds(), dbApiIDs) - .flatMap(Collection::stream).distinct().collect(Collectors.toList()); - item.setApiIds(JSON.toJSONString(result)); - } - item.setScenarioIds(null); + ExtTestPlanScenarioCaseMapper scenarioBatchMapper = sqlSession.getMapper(ExtTestPlanScenarioCaseMapper.class); + ExtTestPlanApiCaseMapper apiCaseBatchMapper = sqlSession.getMapper(ExtTestPlanApiCaseMapper.class); + + for (TestPlanDTO testPlan:list) { + if(request.getScenarioIds()!=null){ + for (String scenarioId : request.getScenarioIds()) { + TestPlanApiScenario testPlanApiScenario = new TestPlanApiScenario(); + testPlanApiScenario.setId(UUID.randomUUID().toString()); + testPlanApiScenario.setApiScenarioId(scenarioId); + testPlanApiScenario.setTestPlanId(testPlan.getId()); + testPlanApiScenario.setCreateTime(System.currentTimeMillis()); + testPlanApiScenario.setUpdateTime(System.currentTimeMillis()); + scenarioBatchMapper.insertIfNotExists(testPlanApiScenario); } } - if (CollectionUtils.isNotEmpty(request.getScenarioIds())) { - if (CollectionUtils.isNotEmpty(request.getScenarioIds())) { - if (StringUtils.isEmpty(item.getScenarioIds())) { - item.setScenarioIds(JSON.toJSONString(request.getScenarioIds())); - } else { - // 合并场景ID - List dbScenarioIDs = JSON.parseArray(item.getScenarioIds(), String.class); - List result = Stream.of(request.getScenarioIds(), dbScenarioIDs) - .flatMap(Collection::stream).distinct().collect(Collectors.toList()); - item.setScenarioIds(JSON.toJSONString(result)); - } - item.setApiIds(null); + if(request.getApiIds()!=null){ + for (String caseId : request.getApiIds()) { + TestPlanApiCase testPlanApiCase = new TestPlanApiCase(); + testPlanApiCase.setId(UUID.randomUUID().toString()); + testPlanApiCase.setApiCaseId(caseId); + testPlanApiCase.setTestPlanId(testPlan.getId()); + testPlanApiCase.setCreateTime(System.currentTimeMillis()); + testPlanApiCase.setUpdateTime(System.currentTimeMillis()); + apiCaseBatchMapper.insertIfNotExists(testPlanApiCase); } } - mapper.updatePlan(item); - }); + + } +// testPlan的ID先不存储 +// list.forEach(item -> { +// if (CollectionUtils.isNotEmpty(request.getApiIds())) { +// if (CollectionUtils.isNotEmpty(request.getApiIds())) { +// if (StringUtils.isEmpty(item.getApiIds())) { +// item.setApiIds(JSON.toJSONString(request.getApiIds())); +// } else { +// // 合并api +// List dbApiIDs = JSON.parseArray(item.getApiIds(), String.class); +// List result = Stream.of(request.getApiIds(), dbApiIDs) +// .flatMap(Collection::stream).distinct().collect(Collectors.toList()); +// item.setApiIds(JSON.toJSONString(result)); +// } +// item.setScenarioIds(null); +// } +// } +// if (CollectionUtils.isNotEmpty(request.getScenarioIds())) { +// if (CollectionUtils.isNotEmpty(request.getScenarioIds())) { +// if (StringUtils.isEmpty(item.getScenarioIds())) { +// item.setScenarioIds(JSON.toJSONString(request.getScenarioIds())); +// } else { +// // 合并场景ID +// List dbScenarioIDs = JSON.parseArray(item.getScenarioIds(), String.class); +// List result = Stream.of(request.getScenarioIds(), dbScenarioIDs) +// .flatMap(Collection::stream).distinct().collect(Collectors.toList()); +// item.setScenarioIds(JSON.toJSONString(result)); +// } +// item.setApiIds(null); +// } +// } +// mapper.updatePlan(item); +// }); sqlSession.flushStatements(); return "success"; } 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 e90df7ce74..06ed0e92da 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -392,7 +392,7 @@ public class ApiDefinitionService { QueryTestPlanRequest planRequest = new QueryTestPlanRequest(); planRequest.setApiId(request.getId()); planRequest.setProjectId(request.getProjectId()); - dto.setTestPlanList(extTestPlanMapper.selectReference(planRequest)); + dto.setTestPlanList(extTestPlanMapper.selectTestPlanByRelevancy(planRequest)); return dto; } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java index 7e6241ae5e..42a46d2eaa 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java @@ -13,6 +13,7 @@ import io.metersphere.base.mapper.ApiTestFileMapper; import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper; import io.metersphere.base.mapper.ext.ExtApiTestCaseMapper; import io.metersphere.base.mapper.ext.ExtTestPlanApiCaseMapper; +import io.metersphere.base.mapper.ext.ExtTestPlanTestCaseMapper; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.*; import io.metersphere.i18n.Translator; @@ -48,6 +49,8 @@ public class ApiTestCaseService { @Resource private ApiTestFileMapper apiTestFileMapper; @Resource + private ExtTestPlanTestCaseMapper extTestPlanTestCaseMapper; + @Resource private FileService fileService; @Resource private ExtApiDefinitionExecResultMapper extApiDefinitionExecResultMapper; @@ -131,8 +134,12 @@ public class ApiTestCaseService { } public void delete(String testId) { + + extTestPlanTestCaseMapper.deleteByTestCaseID(testId); + deleteFileByTestId(testId); extApiDefinitionExecResultMapper.deleteByResourceId(testId); + apiTestCaseMapper.deleteByPrimaryKey(testId); deleteBodyFiles(testId); } @@ -253,6 +260,9 @@ public class ApiTestCaseService { } public void deleteBatch(List ids) { + for (String testId:ids) { + extTestPlanTestCaseMapper.deleteByTestCaseID(testId); + } ApiTestCaseExample example = new ApiTestCaseExample(); example.createCriteria().andIdIn(ids); apiTestCaseMapper.deleteByExample(example); diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanMapper.java index 4cadad7073..ea1768cc89 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanMapper.java @@ -21,5 +21,12 @@ public interface ExtTestPlanMapper { List selectReference(@Param("request") QueryTestPlanRequest params); + /** + * 通过关联表(test_plan_api_case/test_plan_api_scenario)查询testPlan + * @param params + * @return + */ + List selectTestPlanByRelevancy(@Param("request") QueryTestPlanRequest params); + int checkIsHave(@Param("planId") String planId, @Param("workspaceIds") Set workspaceIds); } diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanMapper.xml index eecf98dc66..e3dbb2b706 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanMapper.xml @@ -227,4 +227,16 @@ + + \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanScenarioCaseMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanScenarioCaseMapper.java index ad4f6e42bc..670ae1b37d 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanScenarioCaseMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanScenarioCaseMapper.java @@ -7,6 +7,8 @@ import io.metersphere.api.dto.definition.ApiTestCaseRequest; import io.metersphere.api.dto.definition.TestPlanApiCaseDTO; import io.metersphere.base.domain.TestPlanApiCase; import io.metersphere.base.domain.TestPlanApiScenario; +import io.metersphere.track.dto.TestPlanDTO; +import io.metersphere.track.request.testcase.QueryTestPlanRequest; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -15,4 +17,5 @@ public interface ExtTestPlanScenarioCaseMapper { void insertIfNotExists(@Param("request") TestPlanApiScenario request); List list(@Param("request") TestPlanScenarioRequest request); + } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanTestCaseMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanTestCaseMapper.java index 3911f21c76..bd23bcfbf3 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanTestCaseMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanTestCaseMapper.java @@ -40,4 +40,5 @@ public interface ExtTestPlanTestCaseMapper { TestPlanCaseDTO get(String testPlanTestCaseId); + void deleteByTestCaseID(String id); } diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanTestCaseMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanTestCaseMapper.xml index 199b6ccb45..de4d698114 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanTestCaseMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanTestCaseMapper.xml @@ -342,4 +342,8 @@ #{id} + + + delete from test_plan_api_case where api_case_id = #{id,jdbcType=VARCHAR} + \ No newline at end of file From 8009ed294535e6b29e0260e98cc8289c3ac1d499 Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Wed, 23 Dec 2020 15:17:54 +0800 Subject: [PATCH 11/22] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E9=83=A8=E5=88=86=E7=BC=BA=E9=99=B7=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/definition/RunDefinitionRequest.java | 2 + .../api/service/ApiAutomationService.java | 1 + .../api/service/ApiScenarioReportService.java | 19 ++- .../job/sechedule/ApiScenarioTestJob.java | 4 +- .../api/automation/report/ApiReportList.vue | 3 +- .../report/components/RequestResultTail.vue | 11 +- .../report/components/RequestSubResult.vue | 13 +- .../report/components/ResponseText.vue | 142 ++++++++++-------- .../api/automation/scenario/ApiComponent.vue | 28 +++- .../automation/scenario/EditApiScenario.vue | 2 +- .../api/definition/ApiDefinition.vue | 8 +- .../components/case/ApiCaseList.vue | 6 +- .../complete/EditCompleteDubboApi.vue | 2 +- .../complete/EditCompleteHTTPApi.vue | 2 +- .../complete/EditCompleteSQLApi.vue | 2 +- .../request/database/BasisParameters.vue | 8 +- .../request/dubbo/BasisParameters.vue | 8 +- .../request/http/ApiHttpRequestForm.vue | 3 +- .../request/http/ApiRequestForm.vue | 6 +- .../components/runtest/RunTestDubboPage.vue | 5 +- .../components/runtest/RunTestHTTPPage.vue | 5 +- .../components/runtest/RunTestSQLPage.vue | 5 +- .../components/runtest/RunTestTCPPage.vue | 5 +- 23 files changed, 186 insertions(+), 104 deletions(-) diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/RunDefinitionRequest.java b/backend/src/main/java/io/metersphere/api/dto/definition/RunDefinitionRequest.java index 592e9ad0c9..b329cfcffa 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/RunDefinitionRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/RunDefinitionRequest.java @@ -15,6 +15,8 @@ public class RunDefinitionRequest { private String reportId; + private String name; + private String type; 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 8089c6f4d7..47c77263df 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -246,6 +246,7 @@ public class ApiAutomationService { }); scenario.setVariables(variables); } + group.setEnableCookieShare(scenario.isEnableCookieShare()); LinkedList scenarios = new LinkedList<>(); scenarios.add(scenario); group.setHashTree(scenarios); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java index 907b610bb0..5275448ee0 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java @@ -16,10 +16,13 @@ import io.metersphere.base.mapper.TestPlanApiScenarioMapper; import io.metersphere.base.mapper.ext.ExtApiScenarioReportMapper; 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.DateUtils; +import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.ServiceUtils; import io.metersphere.i18n.Translator; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -28,10 +31,7 @@ import sun.security.util.Cache; import javax.annotation.Resource; import java.nio.charset.StandardCharsets; import java.text.DecimalFormat; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.*; @Service @Transactional(rollbackFor = Exception.class) @@ -55,6 +55,13 @@ public class ApiScenarioReportService { MSException.throwException(Translator.get("api_report_is_null")); } APIScenarioReportResult report = (APIScenarioReportResult) obj; + if (CollectionUtils.isNotEmpty(result.getScenarios())) { + try { + report.setName(result.getScenarios().get(0).getName() + "-" + DateUtils.getTimeString(System.currentTimeMillis())); + } catch (Exception e) { + LogUtil.error(e.getMessage()); + } + } // report detail ApiScenarioReportDetail detail = new ApiScenarioReportDetail(); detail.setReportId(result.getTestId()); @@ -72,7 +79,9 @@ public class ApiScenarioReportService { } report.setContent(new String(detail.getContent(), StandardCharsets.UTF_8)); this.save(report, runMode); - cache.put(report.getId(), report); + if (!report.getTriggerMode().equals(ReportTriggerMode.SCHEDULE.name())) { + cache.put(report.getId(), report); + } } /** diff --git a/backend/src/main/java/io/metersphere/job/sechedule/ApiScenarioTestJob.java b/backend/src/main/java/io/metersphere/job/sechedule/ApiScenarioTestJob.java index 42e8b70f81..cb6be7bdaa 100644 --- a/backend/src/main/java/io/metersphere/job/sechedule/ApiScenarioTestJob.java +++ b/backend/src/main/java/io/metersphere/job/sechedule/ApiScenarioTestJob.java @@ -1,9 +1,7 @@ package io.metersphere.job.sechedule; -import io.metersphere.api.dto.SaveAPITestRequest; import io.metersphere.api.dto.automation.ExecuteType; import io.metersphere.api.dto.automation.RunScenarioRequest; -import io.metersphere.api.service.APITestService; import io.metersphere.api.service.ApiAutomationService; import io.metersphere.commons.constants.ReportTriggerMode; import io.metersphere.commons.constants.ScheduleGroup; @@ -56,7 +54,7 @@ public class ApiScenarioTestJob extends MsScheduleJob { request.setId(id); request.setReportId(id); request.setProjectId(projectID); - request.setTriggerMode(ReportTriggerMode.MANUAL.name()); + request.setTriggerMode(ReportTriggerMode.SCHEDULE.name()); request.setExecuteType(ExecuteType.Completed.name()); request.setScenarioIds(this.scenarioIds); request.setReportUserID(this.userId); diff --git a/frontend/src/business/components/api/automation/report/ApiReportList.vue b/frontend/src/business/components/api/automation/report/ApiReportList.vue index 6919193a43..c26086dcd2 100644 --- a/frontend/src/business/components/api/automation/report/ApiReportList.vue +++ b/frontend/src/business/components/api/automation/report/ApiReportList.vue @@ -69,7 +69,7 @@ import MsContainer from "../../../common/components/MsContainer"; import MsMainContainer from "../../../common/components/MsMainContainer"; import MsApiReportStatus from "./ApiReportStatus"; - import {_filter, _sort} from "@/common/js/utils"; + import {_filter, _sort,getCurrentProjectID} from "@/common/js/utils"; import MsTableOperatorButton from "../../../common/components/MsTableOperatorButton"; import ReportTriggerModeItem from "../../../common/tableItem/ReportTriggerModeItem"; import {REPORT_CONFIGS} from "../../../common/components/search/search-components"; @@ -130,6 +130,7 @@ if (this.testId !== 'all') { this.condition.testId = this.testId; } + this.condition.projectId = getCurrentProjectID(); let url = "/api/scenario/report/list/" + this.currentPage + "/" + this.pageSize; this.result = this.$post(url, this.condition, response => { let data = response.data; diff --git a/frontend/src/business/components/api/automation/report/components/RequestResultTail.vue b/frontend/src/business/components/api/automation/report/components/RequestResultTail.vue index 500eaa2f1c..7c1ccaf628 100644 --- a/frontend/src/business/components/api/automation/report/components/RequestResultTail.vue +++ b/frontend/src/business/components/api/automation/report/components/RequestResultTail.vue @@ -19,19 +19,14 @@ + :key="index" :indexNumber="index" :request="sub"/> - - -
- +
- -
- +
diff --git a/frontend/src/business/components/api/automation/report/components/RequestSubResult.vue b/frontend/src/business/components/api/automation/report/components/RequestSubResult.vue index 53e26c0c27..fa258162ac 100644 --- a/frontend/src/business/components/api/automation/report/components/RequestSubResult.vue +++ b/frontend/src/business/components/api/automation/report/components/RequestSubResult.vue @@ -3,7 +3,7 @@

- +
{{ indexNumber+1 }}
@@ -14,7 +14,16 @@ {{ request.name }}
- + +
+ {{ request.method }} +
+
+ +
+ {{ request.url }} +
+
{{ request.responseResult.responseCode }}
diff --git a/frontend/src/business/components/api/automation/report/components/ResponseText.vue b/frontend/src/business/components/api/automation/report/components/ResponseText.vue index d07d044d00..5d10582ba0 100644 --- a/frontend/src/business/components/api/automation/report/components/ResponseText.vue +++ b/frontend/src/business/components/api/automation/report/components/ResponseText.vue @@ -1,18 +1,19 @@ diff --git a/frontend/src/business/components/api/automation/scenario/ApiComponent.vue b/frontend/src/business/components/api/automation/scenario/ApiComponent.vue index 895c4f66c5..70acb87907 100644 --- a/frontend/src/business/components/api/automation/scenario/ApiComponent.vue +++ b/frontend/src/business/components/api/automation/scenario/ApiComponent.vue @@ -5,15 +5,22 @@
{{request.index}}
+
+
{{request.index}}
+
{{request.index}}
- + {{$t('api_test.automation.api_list_import')}} - + + {{$t('api_test.automation.external_import')}} + + + {{$t('api_test.automation.customize_req')}} @@ -196,7 +203,7 @@ color: #F56C6C; } - .ms-left-buttion { + .ms-left-button { color: #F56C6C; background-color: #FCF1F1; margin-right: 20px; @@ -209,6 +216,19 @@ color: #008080; } + .ms-api-col-ot-import { + background-color: #EEF5FE; + border-color: #409EFF; + margin-right: 10px; + color: #409EFF; + } + + .ms-api-col-ot-import-button { + background-color: #EEF5FE; + margin-right: 20px; + color: #409EFF; + } + /deep/ .el-card__body { padding: 15px; } @@ -217,7 +237,7 @@ transform: rotate(90deg); } - .ms-create-buttion { + .ms-create-button { color: #008080; background-color: #EBF2F2; margin-right: 20px; diff --git a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue index 04c37fa135..e215b76665 100644 --- a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue +++ b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue @@ -782,7 +782,7 @@ apiImport(importData) { if (importData && importData.data) { importData.data.forEach(item => { - this.setApiParameter(item, "API", "Copy"); + this.setApiParameter(item, "API", "OT_IMPORT"); }) this.sort(); this.reload(); diff --git a/frontend/src/business/components/api/definition/ApiDefinition.vue b/frontend/src/business/components/api/definition/ApiDefinition.vue index 5f0719a8a3..07edcab884 100644 --- a/frontend/src/business/components/api/definition/ApiDefinition.vue +++ b/frontend/src/business/components/api/definition/ApiDefinition.vue @@ -78,10 +78,10 @@
- - - - + + + +
diff --git a/frontend/src/business/components/api/definition/components/case/ApiCaseList.vue b/frontend/src/business/components/api/definition/components/case/ApiCaseList.vue index 8ecfbe2067..64f0acbc46 100644 --- a/frontend/src/business/components/api/definition/components/case/ApiCaseList.vue +++ b/frontend/src/business/components/api/definition/components/case/ApiCaseList.vue @@ -172,9 +172,9 @@ } } this.apiCaseList = response.data; - // if (this.apiCaseList.length == 0) { - // this.addCase(); - // } + if (this.apiCaseList.length == 0 && !this.loaded) { + this.addCase(); + } }); } }, diff --git a/frontend/src/business/components/api/definition/components/complete/EditCompleteDubboApi.vue b/frontend/src/business/components/api/definition/components/complete/EditCompleteDubboApi.vue index b6b9c0f58a..84380d6fa3 100644 --- a/frontend/src/business/components/api/definition/components/complete/EditCompleteDubboApi.vue +++ b/frontend/src/business/components/api/definition/components/complete/EditCompleteDubboApi.vue @@ -22,7 +22,7 @@

{{$t('api_test.definition.request.req_param')}}

- +
diff --git a/frontend/src/business/components/api/definition/components/complete/EditCompleteHTTPApi.vue b/frontend/src/business/components/api/definition/components/complete/EditCompleteHTTPApi.vue index 0ceffaca5b..9648a9bbb3 100644 --- a/frontend/src/business/components/api/definition/components/complete/EditCompleteHTTPApi.vue +++ b/frontend/src/business/components/api/definition/components/complete/EditCompleteHTTPApi.vue @@ -77,7 +77,7 @@

{{$t('api_test.definition.request.req_param')}}

- +
diff --git a/frontend/src/business/components/api/definition/components/complete/EditCompleteSQLApi.vue b/frontend/src/business/components/api/definition/components/complete/EditCompleteSQLApi.vue index 8ffbd2e577..54bc58ea4e 100644 --- a/frontend/src/business/components/api/definition/components/complete/EditCompleteSQLApi.vue +++ b/frontend/src/business/components/api/definition/components/complete/EditCompleteSQLApi.vue @@ -21,7 +21,7 @@

{{$t('api_test.definition.request.req_param')}}

- +
diff --git a/frontend/src/business/components/api/definition/components/request/database/BasisParameters.vue b/frontend/src/business/components/api/definition/components/request/database/BasisParameters.vue index 63fb764d8d..a58ad0ae54 100644 --- a/frontend/src/business/components/api/definition/components/request/database/BasisParameters.vue +++ b/frontend/src/business/components/api/definition/components/request/database/BasisParameters.vue @@ -77,7 +77,7 @@ - + +{{$t('api_test.definition.request.pre_script')}}
@@ -120,6 +120,10 @@ request: {}, basisData: {}, moduleOptions: Array, + showScript: { + type: Boolean, + default: true, + }, isReadOnly: { type: Boolean, default: false @@ -172,7 +176,7 @@ this.reload(); }, copyRow(row) { - let obj =JSON.parse(JSON.stringify(row)); + let obj = JSON.parse(JSON.stringify(row)); obj.id = getUUID(); this.request.hashTree.push(obj); this.reload(); diff --git a/frontend/src/business/components/api/definition/components/request/dubbo/BasisParameters.vue b/frontend/src/business/components/api/definition/components/request/dubbo/BasisParameters.vue index 64a4065e72..9e3057827b 100644 --- a/frontend/src/business/components/api/definition/components/request/dubbo/BasisParameters.vue +++ b/frontend/src/business/components/api/definition/components/request/dubbo/BasisParameters.vue @@ -57,7 +57,7 @@
- + +{{$t('api_test.definition.request.pre_script')}}
+{{$t('api_test.definition.request.post_script')}} @@ -105,6 +105,10 @@ type: Boolean, default: false }, + showScript: { + type: Boolean, + default: true, + } }, data() { return { @@ -141,7 +145,7 @@ this.reload(); }, copyRow(row) { - let obj =JSON.parse(JSON.stringify(row)); + let obj = JSON.parse(JSON.stringify(row)); obj.id = getUUID(); this.request.hashTree.push(obj); this.reload(); diff --git a/frontend/src/business/components/api/definition/components/request/http/ApiHttpRequestForm.vue b/frontend/src/business/components/api/definition/components/request/http/ApiHttpRequestForm.vue index 47301e9c71..ef886a900d 100644 --- a/frontend/src/business/components/api/definition/components/request/http/ApiHttpRequestForm.vue +++ b/frontend/src/business/components/api/definition/components/request/http/ApiHttpRequestForm.vue @@ -85,7 +85,7 @@
- + +{{$t('api_test.definition.request.pre_script')}}
+{{$t('api_test.definition.request.post_script')}} @@ -131,6 +131,7 @@ }, props: { request: {}, + showScript: Boolean, headers: { type: Array, default() { diff --git a/frontend/src/business/components/api/definition/components/request/http/ApiRequestForm.vue b/frontend/src/business/components/api/definition/components/request/http/ApiRequestForm.vue index de97afb499..0f2274df8a 100644 --- a/frontend/src/business/components/api/definition/components/request/http/ApiRequestForm.vue +++ b/frontend/src/business/components/api/definition/components/request/http/ApiRequestForm.vue @@ -1,6 +1,6 @@ @@ -17,6 +17,10 @@ type: Boolean, default: true }, + showScript: { + type: Boolean, + default: true, + }, referenced: { type: Boolean, default: false diff --git a/frontend/src/business/components/api/definition/components/runtest/RunTestDubboPage.vue b/frontend/src/business/components/api/definition/components/runtest/RunTestDubboPage.vue index 8d1f43638d..4179a65ab4 100644 --- a/frontend/src/business/components/api/definition/components/runtest/RunTestDubboPage.vue +++ b/frontend/src/business/components/api/definition/components/runtest/RunTestDubboPage.vue @@ -29,7 +29,7 @@ - @@ -104,6 +104,9 @@ return this.runTest(); } }, + refresh(){ + this.$emit('refresh'); + }, runTest() { this.loading = true; this.api.request.name = this.api.id; diff --git a/frontend/src/business/components/api/definition/components/runtest/RunTestHTTPPage.vue b/frontend/src/business/components/api/definition/components/runtest/RunTestHTTPPage.vue index e3c2b2ddfd..861047c291 100644 --- a/frontend/src/business/components/api/definition/components/runtest/RunTestHTTPPage.vue +++ b/frontend/src/business/components/api/definition/components/runtest/RunTestHTTPPage.vue @@ -70,7 +70,7 @@ - { diff --git a/frontend/src/business/components/api/definition/components/runtest/RunTestSQLPage.vue b/frontend/src/business/components/api/definition/components/runtest/RunTestSQLPage.vue index c6094c3108..3a52f408dc 100644 --- a/frontend/src/business/components/api/definition/components/runtest/RunTestSQLPage.vue +++ b/frontend/src/business/components/api/definition/components/runtest/RunTestSQLPage.vue @@ -28,7 +28,7 @@ - @@ -103,6 +103,9 @@ return this.$refs['requestForm'].validate(); } }, + refresh(){ + this.$emit('refresh'); + }, runTest() { this.loading = true; this.api.request.name = this.api.id; diff --git a/frontend/src/business/components/api/definition/components/runtest/RunTestTCPPage.vue b/frontend/src/business/components/api/definition/components/runtest/RunTestTCPPage.vue index a9afdda538..687083ad33 100644 --- a/frontend/src/business/components/api/definition/components/runtest/RunTestTCPPage.vue +++ b/frontend/src/business/components/api/definition/components/runtest/RunTestTCPPage.vue @@ -29,7 +29,7 @@ - @@ -103,6 +103,9 @@ return this.$refs['requestForm'].validate(); } }, + refresh(){ + this.$emit('refresh'); + }, runTest() { this.loading = true; this.api.request.name = this.api.id; From 4d7b794436bffbea59761fbff5922cb31d0bc8cb Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 23 Dec 2020 16:25:01 +0800 Subject: [PATCH 12/22] =?UTF-8?q?feat:=20=E6=B5=8B=E8=AF=95=E8=AE=A1?= =?UTF-8?q?=E5=88=92-=E5=A4=B1=E8=B4=A5=E8=AE=A1=E5=88=92=E5=88=97?= =?UTF-8?q?=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../track/Factory/ReportComponentFactory.java | 3 +- .../track/domain/ReportComponent.java | 11 ++ .../ReportFailureAdvanceResultComponent.java | 55 +++++++++ .../domain/ReportFailureResultComponent.java | 2 +- .../ReportResultAdvancedChartComponent.java | 8 +- .../track/dto/FailureTestCasesAdvanceDTO.java | 16 +++ .../track/dto/TestCaseReportMetricDTO.java | 3 +- .../track/service/TestPlanService.java | 14 +-- .../FailureResultAdvanceComponent.vue | 104 +++++++++++++++++ .../TemplateComponent/TemplateComponent.vue | 8 +- .../component/ApiFailureCasesList.vue | 73 ++++++++++++ .../component/FunctionalFailureCasesList.vue | 108 ++++++++++++++++++ .../component/ScenarioFailureCasesList.vue | 77 +++++++++++++ 13 files changed, 463 insertions(+), 19 deletions(-) create mode 100644 backend/src/main/java/io/metersphere/track/domain/ReportFailureAdvanceResultComponent.java create mode 100644 backend/src/main/java/io/metersphere/track/dto/FailureTestCasesAdvanceDTO.java create mode 100644 frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/FailureResultAdvanceComponent.vue create mode 100644 frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/component/ApiFailureCasesList.vue create mode 100644 frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/component/FunctionalFailureCasesList.vue create mode 100644 frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/component/ScenarioFailureCasesList.vue diff --git a/backend/src/main/java/io/metersphere/track/Factory/ReportComponentFactory.java b/backend/src/main/java/io/metersphere/track/Factory/ReportComponentFactory.java index 15793efd0a..537396745e 100644 --- a/backend/src/main/java/io/metersphere/track/Factory/ReportComponentFactory.java +++ b/backend/src/main/java/io/metersphere/track/Factory/ReportComponentFactory.java @@ -18,7 +18,8 @@ public class ReportComponentFactory { return new ReportResultAdvancedChartComponent(testPlan); // return new ReportResultChartComponent(testPlan); } else if (StringUtils.equals("4", componentId)) { - return new ReportFailureResultComponent(testPlan); +// return new ReportFailureResultComponent(testPlan); + return new ReportFailureAdvanceResultComponent(testPlan); } return null; } diff --git a/backend/src/main/java/io/metersphere/track/domain/ReportComponent.java b/backend/src/main/java/io/metersphere/track/domain/ReportComponent.java index 22677500d3..8f734dfa3d 100644 --- a/backend/src/main/java/io/metersphere/track/domain/ReportComponent.java +++ b/backend/src/main/java/io/metersphere/track/domain/ReportComponent.java @@ -1,8 +1,12 @@ package io.metersphere.track.domain; +import io.metersphere.api.dto.automation.ApiScenarioDTO; +import io.metersphere.api.dto.definition.TestPlanApiCaseDTO; +import io.metersphere.commons.constants.APITestStatus; import io.metersphere.track.dto.TestCaseReportMetricDTO; import io.metersphere.track.dto.TestPlanCaseDTO; import io.metersphere.track.dto.TestPlanDTO; +import org.apache.commons.lang3.StringUtils; public abstract class ReportComponent { protected String componentId; @@ -15,4 +19,11 @@ public abstract class ReportComponent { public abstract void readRecord(TestPlanCaseDTO testCase); public abstract void afterBuild(TestCaseReportMetricDTO testCaseReportMetric); + + public void readRecord(TestPlanApiCaseDTO testCase) { + } + + public void readRecord(ApiScenarioDTO testCase) { + } + } diff --git a/backend/src/main/java/io/metersphere/track/domain/ReportFailureAdvanceResultComponent.java b/backend/src/main/java/io/metersphere/track/domain/ReportFailureAdvanceResultComponent.java new file mode 100644 index 0000000000..180f2c0001 --- /dev/null +++ b/backend/src/main/java/io/metersphere/track/domain/ReportFailureAdvanceResultComponent.java @@ -0,0 +1,55 @@ +package io.metersphere.track.domain; + +import io.metersphere.api.dto.automation.ApiScenarioDTO; +import io.metersphere.api.dto.automation.ScenarioStatus; +import io.metersphere.api.dto.definition.TestPlanApiCaseDTO; +import io.metersphere.commons.constants.TestPlanTestCaseStatus; +import io.metersphere.track.dto.FailureTestCasesAdvanceDTO; +import io.metersphere.track.dto.TestCaseReportMetricDTO; +import io.metersphere.track.dto.TestPlanCaseDTO; +import io.metersphere.track.dto.TestPlanDTO; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +public class ReportFailureAdvanceResultComponent extends ReportComponent { + private List functionalTestCases = new ArrayList<>(); + private List apiTestCases = new ArrayList<>(); + private List scenarioTestCases = new ArrayList<>(); + + public ReportFailureAdvanceResultComponent(TestPlanDTO testPlan) { + super(testPlan); + componentId = "4"; + } + + @Override + public void readRecord(TestPlanCaseDTO testCase) { + if (StringUtils.equals(testCase.getStatus(), TestPlanTestCaseStatus.Failure.name())) { + this.functionalTestCases.add(testCase); + } + } + + @Override + public void readRecord(TestPlanApiCaseDTO testCase) { + if (StringUtils.equals(testCase.getExecResult(), "error")) { + this.apiTestCases.add(testCase); + } + } + + @Override + public void readRecord(ApiScenarioDTO testCase) { + if (StringUtils.equals(testCase.getLastResult(), ScenarioStatus.Fail.name())) { + this.scenarioTestCases.add(testCase); + } + } + + @Override + public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) { + FailureTestCasesAdvanceDTO failureTestCasesAdvanceDTO = new FailureTestCasesAdvanceDTO(); + failureTestCasesAdvanceDTO.setFunctionalTestCases(functionalTestCases); + failureTestCasesAdvanceDTO.setApiTestCases(apiTestCases); + failureTestCasesAdvanceDTO.setScenarioTestCases(scenarioTestCases); + testCaseReportMetric.setFailureTestCases(failureTestCasesAdvanceDTO); + } +} diff --git a/backend/src/main/java/io/metersphere/track/domain/ReportFailureResultComponent.java b/backend/src/main/java/io/metersphere/track/domain/ReportFailureResultComponent.java index 469575717c..50595c824a 100644 --- a/backend/src/main/java/io/metersphere/track/domain/ReportFailureResultComponent.java +++ b/backend/src/main/java/io/metersphere/track/domain/ReportFailureResultComponent.java @@ -26,6 +26,6 @@ public class ReportFailureResultComponent extends ReportComponent { @Override public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) { - testCaseReportMetric.setFailureTestCases(failureTestCases); +// testCaseReportMetric.setFailureTestCases(failureTestCases); } } diff --git a/backend/src/main/java/io/metersphere/track/domain/ReportResultAdvancedChartComponent.java b/backend/src/main/java/io/metersphere/track/domain/ReportResultAdvancedChartComponent.java index e81697ce3d..3c465d9079 100644 --- a/backend/src/main/java/io/metersphere/track/domain/ReportResultAdvancedChartComponent.java +++ b/backend/src/main/java/io/metersphere/track/domain/ReportResultAdvancedChartComponent.java @@ -1,8 +1,8 @@ package io.metersphere.track.domain; import io.metersphere.api.dto.automation.ApiScenarioDTO; +import io.metersphere.api.dto.automation.ScenarioStatus; import io.metersphere.api.dto.definition.TestPlanApiCaseDTO; -import io.metersphere.commons.constants.APITestStatus; import io.metersphere.commons.constants.TestPlanTestCaseStatus; import io.metersphere.track.dto.*; import org.apache.commons.lang3.StringUtils; @@ -23,8 +23,8 @@ public class ReportResultAdvancedChartComponent extends ReportComponent { static { apiResultMap.put("success", TestPlanTestCaseStatus.Pass.name()); apiResultMap.put("error", TestPlanTestCaseStatus.Failure.name()); - scenarioResultMap.put(APITestStatus.Success.name(), TestPlanTestCaseStatus.Pass.name()); - scenarioResultMap.put(APITestStatus.Error.name(), TestPlanTestCaseStatus.Failure.name()); + scenarioResultMap.put(ScenarioStatus.Success.name(), TestPlanTestCaseStatus.Pass.name()); + scenarioResultMap.put(ScenarioStatus.Fail.name(), TestPlanTestCaseStatus.Failure.name()); } public ReportResultAdvancedChartComponent(TestPlanDTO testPlan) { @@ -37,10 +37,12 @@ public class ReportResultAdvancedChartComponent extends ReportComponent { getStatusResultMap(functionalStatusResultMap, testCase.getStatus()); } + @Override public void readRecord(TestPlanApiCaseDTO testCase) { getStatusResultMap(apiStatusResultMap, apiResultMap.get(testCase.getExecResult())); } + @Override public void readRecord(ApiScenarioDTO testCase) { getStatusResultMap(scenarioStatusResultMap, scenarioResultMap.get(testCase.getLastResult())); } diff --git a/backend/src/main/java/io/metersphere/track/dto/FailureTestCasesAdvanceDTO.java b/backend/src/main/java/io/metersphere/track/dto/FailureTestCasesAdvanceDTO.java new file mode 100644 index 0000000000..ba39267353 --- /dev/null +++ b/backend/src/main/java/io/metersphere/track/dto/FailureTestCasesAdvanceDTO.java @@ -0,0 +1,16 @@ +package io.metersphere.track.dto; + +import io.metersphere.api.dto.automation.ApiScenarioDTO; +import io.metersphere.api.dto.definition.TestPlanApiCaseDTO; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class FailureTestCasesAdvanceDTO { + private List functionalTestCases; + private List apiTestCases; + private List scenarioTestCases; +} diff --git a/backend/src/main/java/io/metersphere/track/dto/TestCaseReportMetricDTO.java b/backend/src/main/java/io/metersphere/track/dto/TestCaseReportMetricDTO.java index 1469213ac3..bd8f4c84a1 100644 --- a/backend/src/main/java/io/metersphere/track/dto/TestCaseReportMetricDTO.java +++ b/backend/src/main/java/io/metersphere/track/dto/TestCaseReportMetricDTO.java @@ -13,7 +13,8 @@ public class TestCaseReportMetricDTO { // private List executeResult; private TestCaseReportAdvanceStatusResultDTO executeResult; private List moduleExecuteResult; - private List failureTestCases; + private FailureTestCasesAdvanceDTO failureTestCases; +// private List failureTestCases; private List Issues; private List executors; private String principal; diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java index aa759b85e6..cd0e35302b 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java @@ -26,7 +26,7 @@ import io.metersphere.notice.service.NoticeSendService; import io.metersphere.service.SystemParameterService; import io.metersphere.track.Factory.ReportComponentFactory; import io.metersphere.track.domain.ReportComponent; -import io.metersphere.track.domain.ReportResultAdvancedChartComponent; + import io.metersphere.track.dto.TestCaseReportMetricDTO; import io.metersphere.track.dto.TestPlanCaseDTO; import io.metersphere.track.dto.TestPlanDTO; @@ -623,13 +623,9 @@ public class TestPlanService { ApiTestCaseRequest request = new ApiTestCaseRequest(); request.setPlanId(planId); List apiCaseDTOS = testPlanApiCaseService.list(request); - ReportResultAdvancedChartComponent chartComponent = null; for (TestPlanApiCaseDTO item : apiCaseDTOS) { for (ReportComponent component : components) { - if (component instanceof ReportResultAdvancedChartComponent) { - chartComponent = (ReportResultAdvancedChartComponent) component; - chartComponent.readRecord(item); - } + component.readRecord(item); } } } @@ -638,13 +634,9 @@ public class TestPlanService { TestPlanScenarioRequest request = new TestPlanScenarioRequest(); request.setPlanId(planId); List scenarioDTOS = testPlanScenarioCaseService.list(request); - ReportResultAdvancedChartComponent chartComponent = null; for (ApiScenarioDTO item : scenarioDTOS) { for (ReportComponent component : components) { - if (component instanceof ReportResultAdvancedChartComponent) { - chartComponent = (ReportResultAdvancedChartComponent) component; - chartComponent.readRecord(item); - } + component.readRecord(item); } } } diff --git a/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/FailureResultAdvanceComponent.vue b/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/FailureResultAdvanceComponent.vue new file mode 100644 index 0000000000..5a7971e6e4 --- /dev/null +++ b/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/FailureResultAdvanceComponent.vue @@ -0,0 +1,104 @@ + + + + + diff --git a/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/TemplateComponent.vue b/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/TemplateComponent.vue index 114fc20ca9..79fedc9753 100644 --- a/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/TemplateComponent.vue +++ b/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/TemplateComponent.vue @@ -7,7 +7,8 @@ - + + @@ -18,7 +19,8 @@ - + + @@ -35,10 +37,12 @@ import DefectListComponent from "./DefectListComponent"; import html2canvas from 'html2canvas'; import TestResultAdvanceChartComponent from "./TestResultAdvanceChartComponent"; + import FailureResultAdvanceComponent from "./FailureResultAdvanceComponent"; export default { name: "TemplateComponent", components: { + FailureResultAdvanceComponent, TestResultAdvanceChartComponent, FailureResultComponent,DefectListComponent, RichTextComponent, TestResultChartComponent, TestResultComponent, BaseInfoComponent}, diff --git a/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/component/ApiFailureCasesList.vue b/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/component/ApiFailureCasesList.vue new file mode 100644 index 0000000000..e8ee8e8118 --- /dev/null +++ b/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/component/ApiFailureCasesList.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/component/FunctionalFailureCasesList.vue b/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/component/FunctionalFailureCasesList.vue new file mode 100644 index 0000000000..14f1e24d21 --- /dev/null +++ b/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/component/FunctionalFailureCasesList.vue @@ -0,0 +1,108 @@ + + + + + diff --git a/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/component/ScenarioFailureCasesList.vue b/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/component/ScenarioFailureCasesList.vue new file mode 100644 index 0000000000..7370bcbedd --- /dev/null +++ b/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/component/ScenarioFailureCasesList.vue @@ -0,0 +1,77 @@ + + + + + From 20a79f28703cd204bbcb2bbe6068f45b122d0178 Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Wed, 23 Dec 2020 16:25:18 +0800 Subject: [PATCH 13/22] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E5=AE=9A=E4=B9=89)?= =?UTF-8?q?:=20=E4=BF=AE=E6=94=B9=E6=89=A7=E8=A1=8C=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../metersphere/api/service/ApiDefinitionExecResultService.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionExecResultService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionExecResultService.java index 7c00ff765c..8ec808f47c 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionExecResultService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionExecResultService.java @@ -29,8 +29,6 @@ public class ApiDefinitionExecResultService { public void saveApiResult(TestResult result, String type) { result.getScenarios().get(0).getRequestResults().forEach(item -> { - // 清理原始资源,每个执行 保留一条结果 - extApiDefinitionExecResultMapper.deleteByResourceId(item.getName()); ApiDefinitionExecResult saveResult = new ApiDefinitionExecResult(); saveResult.setId(UUID.randomUUID().toString()); saveResult.setCreateTime(System.currentTimeMillis()); From cae9c24e4f6a38977cc23d91b7ae6a88b1244b90 Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 23 Dec 2020 16:58:56 +0800 Subject: [PATCH 14/22] =?UTF-8?q?refactor:=20=E6=B5=8B=E8=AF=95=E8=AE=A1?= =?UTF-8?q?=E5=88=92=E6=8A=A5=E5=91=8A=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FailureResultAdvanceComponent.vue | 22 +++-- .../TestResultAdvanceChartComponent.vue | 38 +++++++-- .../TestCaseStatisticsReportView.vue | 81 +++++++++++-------- 3 files changed, 95 insertions(+), 46 deletions(-) diff --git a/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/FailureResultAdvanceComponent.vue b/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/FailureResultAdvanceComponent.vue index 5a7971e6e4..f2d1156cb2 100644 --- a/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/FailureResultAdvanceComponent.vue +++ b/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/FailureResultAdvanceComponent.vue @@ -1,12 +1,9 @@ @@ -81,6 +78,17 @@ } } }, + computed: { + showFunctional() { + return this.failureTestCases.functionalTestCases.length > 0 || (this.failureTestCases.apiTestCases.length <= 0 && this.failureTestCases.scenarioTestCases.length <= 0); + }, + showApi() { + return this.failureTestCases.apiTestCases.length > 0; + }, + showScenario() { + return this.failureTestCases.scenarioTestCases.length > 0; + } + }, methods: { goFailureTestCase(row) { hub.$emit("openFailureTestCase", row); @@ -98,7 +106,7 @@ } .failure-cases-list { - margin-bottom: 30px; + margin-bottom: 40px; } diff --git a/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/TestResultAdvanceChartComponent.vue b/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/TestResultAdvanceChartComponent.vue index a913852b38..1412d990a7 100644 --- a/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/TestResultAdvanceChartComponent.vue +++ b/frontend/src/business/components/track/plan/view/comonents/report/TemplateComponent/TestResultAdvanceChartComponent.vue @@ -2,25 +2,25 @@ - + @@ -76,6 +76,30 @@ } } }, + computed: { + showFunctional() { + return this.executeResult.functionalResult.length > 0 || (this.executeResult.apiResult.length <= 0 && this.executeResult.scenarioResult.length <= 0); + }, + showApi() { + return this.executeResult.apiResult.length > 0; + }, + showScenario() { + return this.executeResult.scenarioResult.length > 0; + }, + isShowOne() { + let count = 0; + if (this.showFunctional) { + count++; + } + if (this.showApi) { + count++; + } + if (this.showScenario) { + count++; + } + return count === 1; + } + }, watch: { executeResult() { this.getCharData(); @@ -141,4 +165,8 @@ display: inline-block; } + .show-one .char-item { + display: block; + } + diff --git a/frontend/src/business/components/track/plan/view/comonents/report/statistics/TestCaseStatisticsReportView.vue b/frontend/src/business/components/track/plan/view/comonents/report/statistics/TestCaseStatisticsReportView.vue index 27bdee8af1..fa8a85e64b 100644 --- a/frontend/src/business/components/track/plan/view/comonents/report/statistics/TestCaseStatisticsReportView.vue +++ b/frontend/src/business/components/track/plan/view/comonents/report/statistics/TestCaseStatisticsReportView.vue @@ -1,36 +1,35 @@