Merge branch 'master' of https://github.com/metersphere/server
This commit is contained in:
commit
fdde95218d
|
@ -104,9 +104,6 @@ public class APITestService {
|
|||
}
|
||||
|
||||
private void createBodyFiles(ApiTest test, List<String> bodyUploadIds, List<MultipartFile> bodyFiles) {
|
||||
if (bodyFiles == null || bodyFiles.isEmpty()) {
|
||||
|
||||
}
|
||||
String dir = BODY_FILE_DIR + "/" + test.getId();
|
||||
File testDir = new File(dir);
|
||||
if (!testDir.exists()) {
|
||||
|
@ -115,24 +112,12 @@ public class APITestService {
|
|||
for (int i = 0; i < bodyUploadIds.size(); i++) {
|
||||
MultipartFile item = bodyFiles.get(i);
|
||||
File file = new File(testDir + "/" + bodyUploadIds.get(i) + "_" + item.getOriginalFilename());
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
try {
|
||||
try (InputStream in = item.getInputStream(); OutputStream out = new FileOutputStream(file)) {
|
||||
file.createNewFile();
|
||||
in = item.getInputStream();
|
||||
out = new FileOutputStream(file);
|
||||
FileUtil.copyStream(in, out);
|
||||
} catch (IOException e) {
|
||||
LogUtil.error(e);
|
||||
MSException.throwException(Translator.get("upload_fail"));
|
||||
} finally {
|
||||
try {
|
||||
in.close();
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
LogUtil.error(e);
|
||||
MSException.throwException(Translator.get("upload_fail"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,9 +97,7 @@
|
|||
|
||||
<select id="list" resultMap="BaseResultMap"
|
||||
parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">
|
||||
select test_plan.*, project.name as project_name
|
||||
from test_plan
|
||||
left join project on test_plan.project_id = project.id
|
||||
select test_plan.* from test_plan
|
||||
<where>
|
||||
<if test="request.combine != null">
|
||||
<include refid="combine">
|
||||
|
@ -111,10 +109,7 @@
|
|||
and test_plan.name like CONCAT('%', #{request.name},'%')
|
||||
</if>
|
||||
<if test="request.workspaceId != null">
|
||||
AND project.workspace_id = #{request.workspaceId}
|
||||
</if>
|
||||
<if test="request.projectId != null">
|
||||
AND project.id = #{request.projectId}
|
||||
AND test_plan.workspace_id = #{request.workspaceId}
|
||||
</if>
|
||||
<if test="request.id != null">
|
||||
AND test_plan.id = #{request.id}
|
||||
|
@ -150,9 +145,7 @@
|
|||
</select>
|
||||
|
||||
<select id="listRelate" resultType="io.metersphere.track.dto.TestPlanDTOWithMetric">
|
||||
select test_plan.*, project.name as project_name
|
||||
from test_plan
|
||||
left join project on test_plan.project_id = project.id
|
||||
select test_plan.* from test_plan
|
||||
where test_plan.workspace_id = #{request.workspaceId}
|
||||
and (test_plan.principal = #{request.principal}
|
||||
<if test="request.planIds != null and request.planIds.size() > 0">
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
|
|||
import io.metersphere.commons.constants.ParamConstants;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.EncryptUtils;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.controller.request.LoginRequest;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.service.SystemParameterService;
|
||||
|
@ -47,6 +48,7 @@ public class LdapService {
|
|||
// 执行登录认证
|
||||
authenticate(String.valueOf(dirContextOperations.getDn()), credentials);
|
||||
} catch (AuthenticationException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
MSException.throwException(Translator.get("authentication_failed"));
|
||||
}
|
||||
|
||||
|
@ -93,8 +95,10 @@ public class LdapService {
|
|||
return result.get(0);
|
||||
}
|
||||
} catch (NameNotFoundException | InvalidNameException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
MSException.throwException(Translator.get("login_fail_ou_error"));
|
||||
} catch (InvalidSearchFilterException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
MSException.throwException(Translator.get("login_fail_filter_error"));
|
||||
}
|
||||
}
|
||||
|
@ -161,8 +165,10 @@ public class LdapService {
|
|||
try {
|
||||
authenticate(dn, credentials, ldapTemplate);
|
||||
} catch (AuthenticationException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
MSException.throwException(Translator.get("ldap_connect_fail_user"));
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
MSException.throwException(Translator.get("ldap_connect_fail"));
|
||||
}
|
||||
|
||||
|
|
|
@ -16,13 +16,14 @@ import io.metersphere.controller.request.ProjectRequest;
|
|||
import io.metersphere.dto.ProjectDTO;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.performance.service.PerformanceTestService;
|
||||
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
|
||||
import io.metersphere.track.request.testplan.DeleteTestPlanRequest;
|
||||
import io.metersphere.track.service.TestCaseService;
|
||||
import io.metersphere.track.service.TestPlanProjectService;
|
||||
import io.metersphere.track.service.TestPlanService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
@ -54,6 +55,8 @@ public class ProjectService {
|
|||
private TestCaseService testCaseService;
|
||||
@Resource
|
||||
private APITestService apiTestService;
|
||||
@Resource
|
||||
private TestPlanProjectService testPlanProjectService;
|
||||
|
||||
public Project addProject(Project project) {
|
||||
if (StringUtils.isBlank(project.getName())) {
|
||||
|
@ -96,21 +99,22 @@ public class ProjectService {
|
|||
performanceTestService.delete(deleteTestPlanRequest);
|
||||
});
|
||||
|
||||
// TODO 删除项目下 测试跟踪 相关
|
||||
// 删除项目下 测试跟踪 相关
|
||||
deleteTrackResourceByProjectId(projectId);
|
||||
|
||||
// TODO 删除项目下 接口测试 相关
|
||||
// 删除项目下 接口测试 相关
|
||||
deleteAPIResourceByProjectId(projectId);
|
||||
// delete project
|
||||
projectMapper.deleteByPrimaryKey(projectId);
|
||||
}
|
||||
|
||||
private void deleteTrackResourceByProjectId(String projectId) {
|
||||
QueryTestPlanRequest request = new QueryTestPlanRequest();
|
||||
request.setProjectId(projectId);
|
||||
testPlanService.listTestPlan(request).forEach(testPlan -> {
|
||||
testPlanService.deleteTestPlan(testPlan.getId());
|
||||
List<String> testPlanIds = testPlanProjectService.getPlanIdByProjectId(projectId);
|
||||
if (!CollectionUtils.isEmpty(testPlanIds)) {
|
||||
testPlanIds.forEach(testPlanId -> {
|
||||
testPlanService.deleteTestPlan(testPlanId);
|
||||
});
|
||||
}
|
||||
testCaseService.deleteTestCaseByProjectId(projectId);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import io.metersphere.base.domain.TestCaseNode;
|
|||
import io.metersphere.commons.constants.RoleConstants;
|
||||
import io.metersphere.track.dto.TestCaseNodeDTO;
|
||||
import io.metersphere.track.request.testcase.DragNodeRequest;
|
||||
import io.metersphere.track.request.testcase.QueryNodeRequest;
|
||||
import io.metersphere.track.service.TestCaseNodeService;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
|
@ -26,9 +27,9 @@ public class TestCaseNodeController {
|
|||
}
|
||||
|
||||
/*模块列表列表*/
|
||||
@GetMapping("/list/all/plan/{planId}")
|
||||
public List<TestCaseNodeDTO> getAllNodeByPlanId(@PathVariable String planId) {
|
||||
return testCaseNodeService.getAllNodeByPlanId(planId);
|
||||
@PostMapping("/list/all/plan")
|
||||
public List<TestCaseNodeDTO> getAllNodeByPlanId(@RequestBody QueryNodeRequest request) {
|
||||
return testCaseNodeService.getAllNodeByPlanId(request);
|
||||
}
|
||||
|
||||
@GetMapping("/list/plan/{planId}")
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.metersphere.track.controller;
|
|||
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import io.metersphere.base.domain.Project;
|
||||
import io.metersphere.base.domain.TestPlan;
|
||||
import io.metersphere.commons.constants.RoleConstants;
|
||||
import io.metersphere.commons.utils.PageUtils;
|
||||
|
@ -12,6 +13,8 @@ import io.metersphere.track.dto.TestPlanDTO;
|
|||
import io.metersphere.track.dto.TestPlanDTOWithMetric;
|
||||
import io.metersphere.track.request.testcase.PlanCaseRelevanceRequest;
|
||||
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
|
||||
import io.metersphere.track.request.testplan.AddTestPlanRequest;
|
||||
import io.metersphere.track.service.TestPlanProjectService;
|
||||
import io.metersphere.track.service.TestPlanService;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
|
@ -26,6 +29,8 @@ public class TestPlanController {
|
|||
|
||||
@Resource
|
||||
TestPlanService testPlanService;
|
||||
@Resource
|
||||
TestPlanProjectService testPlanProjectService;
|
||||
|
||||
@PostMapping("/list/{goPage}/{pageSize}")
|
||||
public Pager<List<TestPlanDTO>> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryTestPlanRequest request) {
|
||||
|
@ -37,7 +42,7 @@ public class TestPlanController {
|
|||
|
||||
/*jenkins测试计划*/
|
||||
@GetMapping("/list/all/{projectId}/{workspaceId}")
|
||||
public List<TestPlanDTO> listByprojectId(@PathVariable String projectId, @PathVariable String workspaceId) {
|
||||
public List<TestPlanDTO> listByProjectId(@PathVariable String projectId, @PathVariable String workspaceId) {
|
||||
QueryTestPlanRequest request = new QueryTestPlanRequest();
|
||||
request.setWorkspaceId(workspaceId);
|
||||
request.setProjectId(projectId);
|
||||
|
@ -69,7 +74,7 @@ public class TestPlanController {
|
|||
|
||||
@PostMapping("/add")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||
public void addTestPlan(@RequestBody TestPlan testPlan) {
|
||||
public void addTestPlan(@RequestBody AddTestPlanRequest testPlan) {
|
||||
testPlanService.addTestPlan(testPlan);
|
||||
}
|
||||
|
||||
|
@ -100,4 +105,14 @@ public class TestPlanController {
|
|||
public TestCaseReportMetricDTO getMetric(@PathVariable String planId) {
|
||||
return testPlanService.getMetric(planId);
|
||||
}
|
||||
|
||||
@GetMapping("/project/name/{planId}")
|
||||
public String getProjectNameByPlanId(@PathVariable String planId) {
|
||||
return testPlanService.getProjectNameByPlanId(planId);
|
||||
}
|
||||
|
||||
@GetMapping("/project/{planId}")
|
||||
public List<Project> getProjectByPlanId(@PathVariable String planId) {
|
||||
return testPlanProjectService.getProjectByPlanId(planId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package io.metersphere.track.domain;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.metersphere.base.domain.Issues;
|
||||
import io.metersphere.base.domain.TestCaseNode;
|
||||
import io.metersphere.base.domain.TestCaseNodeExample;
|
||||
import io.metersphere.base.mapper.TestCaseNodeMapper;
|
||||
|
@ -11,6 +9,7 @@ import io.metersphere.commons.utils.MathUtils;
|
|||
import io.metersphere.track.dto.*;
|
||||
import io.metersphere.track.service.IssuesService;
|
||||
import io.metersphere.track.service.TestCaseNodeService;
|
||||
import io.metersphere.track.service.TestPlanProjectService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -30,8 +29,9 @@ public class ReportResultComponent extends ReportComponent {
|
|||
public void init() {
|
||||
TestCaseNodeService testCaseNodeService = (TestCaseNodeService) CommonBeanFactory.getBean("testCaseNodeService");
|
||||
TestCaseNodeMapper testCaseNodeMapper = (TestCaseNodeMapper) CommonBeanFactory.getBean("testCaseNodeMapper");
|
||||
TestPlanProjectService testPlanProjectService = (TestPlanProjectService) CommonBeanFactory.getBean("testPlanProjectService");
|
||||
TestCaseNodeExample testCaseNodeExample = new TestCaseNodeExample();
|
||||
testCaseNodeExample.createCriteria().andProjectIdEqualTo(testPlan.getProjectId());
|
||||
testCaseNodeExample.createCriteria().andProjectIdIn(testPlanProjectService.getProjectIdsByPlanId(testPlan.getId()));
|
||||
List<TestCaseNode> nodes = testCaseNodeMapper.selectByExample(testCaseNodeExample);
|
||||
nodeTrees = testCaseNodeService.getNodeTrees(nodes);
|
||||
nodeTrees.forEach(item -> {
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package io.metersphere.track.request.testcase;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class QueryNodeRequest {
|
||||
|
||||
private String testPlanId;
|
||||
private String projectId;
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package io.metersphere.track.request.testplan;
|
||||
|
||||
import io.metersphere.base.domain.TestPlan;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class AddTestPlanRequest extends TestPlan {
|
||||
private List<String> projectIds;
|
||||
}
|
|
@ -2,10 +2,7 @@ package io.metersphere.track.service;
|
|||
|
||||
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.TestCaseMapper;
|
||||
import io.metersphere.base.mapper.TestCaseNodeMapper;
|
||||
import io.metersphere.base.mapper.TestPlanMapper;
|
||||
import io.metersphere.base.mapper.TestPlanTestCaseMapper;
|
||||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.base.mapper.ext.ExtTestCaseMapper;
|
||||
import io.metersphere.commons.constants.TestCaseConstants;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
|
@ -15,6 +12,7 @@ import io.metersphere.i18n.Translator;
|
|||
import io.metersphere.track.dto.TestCaseDTO;
|
||||
import io.metersphere.track.dto.TestCaseNodeDTO;
|
||||
import io.metersphere.track.request.testcase.DragNodeRequest;
|
||||
import io.metersphere.track.request.testcase.QueryNodeRequest;
|
||||
import io.metersphere.track.request.testcase.QueryTestCaseRequest;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
|
@ -43,6 +41,10 @@ public class TestCaseNodeService {
|
|||
ExtTestCaseMapper extTestCaseMapper;
|
||||
@Resource
|
||||
SqlSessionFactory sqlSessionFactory;
|
||||
@Resource
|
||||
TestPlanProjectService testPlanProjectService;
|
||||
@Resource
|
||||
ProjectMapper projectMapper;
|
||||
|
||||
public String addNode(TestCaseNode node) {
|
||||
validateNode(node);
|
||||
|
@ -182,8 +184,22 @@ public class TestCaseNodeService {
|
|||
*/
|
||||
public List<TestCaseNodeDTO> getNodeByPlanId(String planId) {
|
||||
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(planId);
|
||||
List<TestCaseNodeDTO> list = new ArrayList<>();
|
||||
List<String> projectIds = testPlanProjectService.getProjectIdsByPlanId(planId);
|
||||
projectIds.forEach(id -> {
|
||||
String name = projectMapper.selectByPrimaryKey(id).getName();
|
||||
List<TestCaseNodeDTO> nodeList = getNodeDTO(id, planId);
|
||||
TestCaseNodeDTO testCaseNodeDTO = new TestCaseNodeDTO();
|
||||
testCaseNodeDTO.setName(name);
|
||||
testCaseNodeDTO.setLabel(name);
|
||||
testCaseNodeDTO.setChildren(nodeList);
|
||||
list.add(testCaseNodeDTO);
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<TestCaseNodeDTO> getNodeDTO(String projectId, String planId) {
|
||||
TestPlanTestCaseExample testPlanTestCaseExample = new TestPlanTestCaseExample();
|
||||
testPlanTestCaseExample.createCriteria().andPlanIdEqualTo(planId);
|
||||
List<TestPlanTestCase> testPlanTestCases = testPlanTestCaseMapper.selectByExample(testPlanTestCaseExample);
|
||||
|
@ -193,7 +209,7 @@ public class TestCaseNodeService {
|
|||
}
|
||||
|
||||
TestCaseNodeExample testCaseNodeExample = new TestCaseNodeExample();
|
||||
testCaseNodeExample.createCriteria().andProjectIdEqualTo(testPlan.getProjectId());
|
||||
testCaseNodeExample.createCriteria().andProjectIdEqualTo(projectId);
|
||||
List<TestCaseNode> nodes = testCaseNodeMapper.selectByExample(testCaseNodeExample);
|
||||
|
||||
List<String> caseIds = testPlanTestCases.stream()
|
||||
|
@ -254,12 +270,15 @@ public class TestCaseNodeService {
|
|||
return false;
|
||||
}
|
||||
|
||||
public List<TestCaseNodeDTO> getAllNodeByPlanId(String planId) {
|
||||
public List<TestCaseNodeDTO> getAllNodeByPlanId(QueryNodeRequest request) {
|
||||
String planId = request.getTestPlanId();
|
||||
String projectId = request.getProjectId();
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(planId);
|
||||
if (testPlan == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return getNodeTreeByProjectId(testPlan.getProjectId());
|
||||
|
||||
return getNodeTreeByProjectId(projectId);
|
||||
}
|
||||
|
||||
public Map<String, String> createNodeByTestCases(List<TestCaseWithBLOBs> testCases, String projectId) {
|
||||
|
|
|
@ -182,9 +182,7 @@ public class TestCaseService {
|
|||
public List<TestCase> getTestCaseNames(QueryTestCaseRequest request) {
|
||||
if (StringUtils.isNotBlank(request.getPlanId())) {
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getPlanId());
|
||||
if (testPlan != null) {
|
||||
request.setProjectId(testPlan.getProjectId());
|
||||
}
|
||||
// request 传入要查询的 projectId 切换的项目ID
|
||||
}
|
||||
|
||||
List<TestCase> testCaseNames = extTestCaseMapper.getTestCaseNames(request);
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
package io.metersphere.track.service;
|
||||
|
||||
import io.metersphere.base.domain.Project;
|
||||
import io.metersphere.base.domain.ProjectExample;
|
||||
import io.metersphere.base.domain.TestPlanProject;
|
||||
import io.metersphere.base.domain.TestPlanProjectExample;
|
||||
import io.metersphere.base.mapper.ProjectMapper;
|
||||
import io.metersphere.base.mapper.TestPlanProjectMapper;
|
||||
import org.python.antlr.ast.Str;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class TestPlanProjectService {
|
||||
|
||||
@Resource
|
||||
TestPlanProjectMapper testPlanProjectMapper;
|
||||
@Resource
|
||||
ProjectMapper projectMapper;
|
||||
|
||||
public List<String> getProjectIdsByPlanId(String planId) {
|
||||
TestPlanProjectExample example = new TestPlanProjectExample();
|
||||
example.createCriteria().andTestPlanIdEqualTo(planId);
|
||||
List<String> projectIds = testPlanProjectMapper.selectByExample(example)
|
||||
.stream()
|
||||
.map(TestPlanProject::getProjectId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (projectIds.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return projectIds;
|
||||
}
|
||||
|
||||
public List<Project> getProjectByPlanId(String planId) {
|
||||
List<String> projectIds = getProjectIdsByPlanId(planId);
|
||||
ProjectExample projectExample = new ProjectExample();
|
||||
projectExample.createCriteria().andIdIn(projectIds);
|
||||
List<Project> projects = projectMapper.selectByExample(projectExample);
|
||||
return Optional.ofNullable(projects).orElse(new ArrayList<>());
|
||||
}
|
||||
|
||||
public void deleteTestPlanProjectByPlanId(String planId) {
|
||||
TestPlanProjectExample testPlanProjectExample = new TestPlanProjectExample();
|
||||
testPlanProjectExample.createCriteria().andTestPlanIdEqualTo(planId);
|
||||
testPlanProjectMapper.deleteByExample(testPlanProjectExample);
|
||||
}
|
||||
|
||||
public List<String> getPlanIdByProjectId(String projectId) {
|
||||
TestPlanProjectExample testPlanProjectExample = new TestPlanProjectExample();
|
||||
testPlanProjectExample.createCriteria().andProjectIdEqualTo(projectId);
|
||||
List<TestPlanProject> testPlanProjects = testPlanProjectMapper.selectByExample(testPlanProjectExample);
|
||||
if (CollectionUtils.isEmpty(testPlanProjects)) {
|
||||
return null;
|
||||
}
|
||||
return testPlanProjects
|
||||
.stream()
|
||||
.map(TestPlanProject::getTestPlanId)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
|
@ -4,10 +4,7 @@ package io.metersphere.track.service;
|
|||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.TestCaseMapper;
|
||||
import io.metersphere.base.mapper.TestCaseReportMapper;
|
||||
import io.metersphere.base.mapper.TestPlanMapper;
|
||||
import io.metersphere.base.mapper.TestPlanTestCaseMapper;
|
||||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.base.mapper.ext.ExtProjectMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestPlanMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestPlanTestCaseMapper;
|
||||
|
@ -28,6 +25,7 @@ import io.metersphere.track.dto.TestPlanDTO;
|
|||
import io.metersphere.track.dto.TestPlanDTOWithMetric;
|
||||
import io.metersphere.track.request.testcase.PlanCaseRelevanceRequest;
|
||||
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
|
||||
import io.metersphere.track.request.testplan.AddTestPlanRequest;
|
||||
import io.metersphere.track.request.testplancase.QueryTestPlanCaseRequest;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
|
@ -72,12 +70,29 @@ public class TestPlanService {
|
|||
@Resource
|
||||
TestCaseReportMapper testCaseReportMapper;
|
||||
|
||||
public void addTestPlan(TestPlan testPlan) {
|
||||
@Resource
|
||||
TestPlanProjectMapper testPlanProjectMapper;
|
||||
@Resource
|
||||
TestPlanProjectService testPlanProjectService;
|
||||
@Resource
|
||||
ProjectMapper projectMapper;
|
||||
|
||||
public void addTestPlan(AddTestPlanRequest testPlan) {
|
||||
if (getTestPlanByName(testPlan.getName()).size() > 0) {
|
||||
MSException.throwException(Translator.get("plan_name_already_exists"));
|
||||
}
|
||||
;
|
||||
testPlan.setId(UUID.randomUUID().toString());
|
||||
|
||||
String testPlanId = UUID.randomUUID().toString();
|
||||
|
||||
List<String> projectIds = testPlan.getProjectIds();
|
||||
projectIds.forEach(id -> {
|
||||
TestPlanProject testPlanProject = new TestPlanProject();
|
||||
testPlanProject.setProjectId(id);
|
||||
testPlanProject.setTestPlanId(testPlanId);
|
||||
testPlanProjectMapper.insertSelective(testPlanProject);
|
||||
});
|
||||
|
||||
testPlan.setId(testPlanId);
|
||||
testPlan.setStatus(TestPlanStatus.Prepare.name());
|
||||
testPlan.setCreateTime(System.currentTimeMillis());
|
||||
testPlan.setUpdateTime(System.currentTimeMillis());
|
||||
|
@ -116,6 +131,7 @@ public class TestPlanService {
|
|||
|
||||
public int deleteTestPlan(String planId) {
|
||||
deleteTestCaseByPlanId(planId);
|
||||
testPlanProjectService.deleteTestPlanProjectByPlanId(planId);
|
||||
return testPlanMapper.deleteByPrimaryKey(planId);
|
||||
}
|
||||
|
||||
|
@ -316,4 +332,23 @@ public class TestPlanService {
|
|||
testPlan.setStatus(TestPlanStatus.Completed.name());
|
||||
testPlanMapper.updateByPrimaryKeySelective(testPlan);
|
||||
}
|
||||
|
||||
public String getProjectNameByPlanId(String testPlanId) {
|
||||
List<String> projectIds = testPlanProjectService.getProjectIdsByPlanId(testPlanId);
|
||||
ProjectExample projectExample = new ProjectExample();
|
||||
projectExample.createCriteria().andIdIn(projectIds);
|
||||
|
||||
List<Project> projects = projectMapper.selectByExample(projectExample);
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
String projectName = "";
|
||||
|
||||
if (projects.size() > 0) {
|
||||
for (Project project : projects) {
|
||||
stringBuilder.append(project.getName()).append("、");
|
||||
}
|
||||
projectName = stringBuilder.toString().substring(0, stringBuilder.length() - 1);
|
||||
}
|
||||
|
||||
return projectName;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,6 +123,9 @@
|
|||
validateDomain(domain) {
|
||||
let url = {};
|
||||
try {
|
||||
if (!domain.startsWith("http") || !domain.startsWith("https")) {
|
||||
domain += "http://";
|
||||
}
|
||||
url = new URL(domain);
|
||||
} catch (e) {
|
||||
this.$warning(this.$t('load_test.input_domain'));
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<el-container>
|
||||
<el-aside class="scenario-aside">
|
||||
<div class="scenario-list">
|
||||
<ms-api-collapse v-model="activeName" @change="handleChange" accordion>
|
||||
<ms-api-collapse v-model="activeName" @change="handleChange">
|
||||
<draggable :list="scenarios" group="Scenario" class="scenario-draggable" ghost-class="scenario-ghost">
|
||||
<ms-api-collapse-item v-for="(scenario, index) in scenarios" :key="index"
|
||||
:title="scenario.name" :name="index" :class="{'disable-scenario': !scenario.enable}">
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<div class="request-container">
|
||||
<draggable :list="this.scenario.requests" group="Request" class="request-draggable" ghost-class="request-ghost">
|
||||
<draggable :list="this.scenario.requests" group="Request" class="request-draggable" ghost-class="request-ghost"
|
||||
:disabled="isReference">
|
||||
<div class="request-item" v-for="(request, index) in this.scenario.requests" :key="index" @click="select(request)"
|
||||
:class="{'selected': isSelected(request), 'disable-request': !request.enable || !scenario.enable}">
|
||||
<el-row type="flex" align="middle">
|
||||
|
@ -23,10 +24,12 @@
|
|||
<el-dropdown-item :disabled="isReadOnly" :command="{type: 'delete', index: index}">
|
||||
{{ $t('api_test.request.delete') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="request.enable" :disabled="isReadOnly" :command="{type: 'disable', index: index}">
|
||||
<el-dropdown-item v-if="request.enable" :disabled="isReadOnly"
|
||||
:command="{type: 'disable', index: index}">
|
||||
{{ $t('api_test.scenario.disable') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="!request.enable" :disabled="isReadOnly" :command="{type: 'enable', index: index}">
|
||||
<el-dropdown-item v-if="!request.enable" :disabled="isReadOnly"
|
||||
:command="{type: 'enable', index: index}">
|
||||
{{ $t('api_test.scenario.enable') }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
|
@ -78,6 +81,9 @@
|
|||
return function (request) {
|
||||
return this.selected === request;
|
||||
}
|
||||
},
|
||||
isReference() {
|
||||
return this.scenario.isReference();
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -504,8 +504,8 @@ export class DNSCacheManager extends DefaultTestElement {
|
|||
let collectionPropHosts = this.collectionProp('DNSCacheManager.hosts');
|
||||
|
||||
hosts.forEach(host => {
|
||||
let elementProp = collectionPropHosts.elementProp('', 'StaticHost');
|
||||
if (host && host.domain.trim() === domain.trim()) {
|
||||
let elementProp = collectionPropHosts.elementProp(host.domain, 'StaticHost');
|
||||
if (host && host.domain.trim().indexOf(domain.trim()) != -1) {
|
||||
elementProp.stringProp('StaticHost.Name', host.domain);
|
||||
elementProp.stringProp('StaticHost.Address', host.ip);
|
||||
}
|
||||
|
|
|
@ -405,7 +405,7 @@ export class DubboRequest extends Request {
|
|||
this.debugReport = undefined;
|
||||
this.beanShellPreProcessor = new BeanShellProcessor(options.beanShellPreProcessor);
|
||||
this.beanShellPostProcessor = new BeanShellProcessor(options.beanShellPostProcessor);
|
||||
this.enable = options.enable == undefined ? true : options.enable;
|
||||
this.enable = options.enable === undefined ? true : options.enable;
|
||||
this.jsr223PreProcessor = new JSR223Processor(options.jsr223PreProcessor);
|
||||
this.jsr223PostProcessor = new JSR223Processor(options.jsr223PostProcessor);
|
||||
|
||||
|
@ -956,8 +956,8 @@ class JMXGenerator {
|
|||
let name = request.name + " DNSCacheManager";
|
||||
let hosts = JSON.parse(request.environment.hosts);
|
||||
if (hosts.length > 0) {
|
||||
let domain = request.environment.protocol + "://" + request.environment.domain;
|
||||
threadGroup.put(new DNSCacheManager(name, domain, hosts));
|
||||
//let domain = request.environment.protocol + "://" + request.environment.domain;
|
||||
threadGroup.put(new DNSCacheManager(name, request.environment.domain, hosts));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1038,7 +1038,7 @@ class JMXGenerator {
|
|||
this.addRequestBodyFile(httpSamplerProxy, request, testId);
|
||||
} else {
|
||||
httpSamplerProxy.boolProp('HTTPSampler.postBodyRaw', true);
|
||||
body.push({name: '', value: request.body.raw, encode: false});
|
||||
body.push({name: '', value: request.body.raw, encode: false, enable: true});
|
||||
}
|
||||
|
||||
httpSamplerProxy.add(new HTTPSamplerArguments(body));
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
<template>
|
||||
<el-dialog v-loading="result.loading"
|
||||
:visible.sync="dialogVisible"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-table
|
||||
:data="tableData"
|
||||
highlight-current-row
|
||||
@current-change="handleCurrentChange"
|
||||
style="width: 100%">
|
||||
<el-table-column prop="name" :label="$t('commons.name')" show-overflow-tooltip/>
|
||||
<el-table-column prop="description" :label="$t('commons.description')" show-overflow-tooltip>
|
||||
<template v-slot:default="scope">
|
||||
{{ scope.row.description }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
sortable
|
||||
prop="createTime"
|
||||
:label="$t('commons.create_time')"
|
||||
show-overflow-tooltip>
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
sortable
|
||||
prop="updateTime"
|
||||
:label="$t('commons.update_time')"
|
||||
show-overflow-tooltip>
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<template v-slot:footer>
|
||||
<div class="dialog-footer">
|
||||
<ms-dialog-footer
|
||||
@cancel="dialogVisible = false"
|
||||
@confirm="submit()"/>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsDialogFooter from "../../../common/components/MsDialogFooter";
|
||||
|
||||
export default {
|
||||
name: "SwitchProject",
|
||||
components: {MsDialogFooter},
|
||||
data() {
|
||||
return {
|
||||
tableData: [],
|
||||
result: {},
|
||||
dialogVisible: false,
|
||||
projectId: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
open(planId) {
|
||||
this.dialogVisible = true;
|
||||
this.initData(planId);
|
||||
},
|
||||
initData(planId) {
|
||||
this.result = this.$get("/test/plan/project/" + planId,res => {
|
||||
this.tableData = res.data;
|
||||
})
|
||||
},
|
||||
handleCurrentChange(currentRow) {
|
||||
// initData 改变表格数据会触发此方法
|
||||
if (currentRow) {
|
||||
this.projectId = currentRow.id;
|
||||
}
|
||||
},
|
||||
submit() {
|
||||
this.$emit('getProjectNode', this.projectId);
|
||||
this.dialogVisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -230,12 +230,16 @@ export default {
|
|||
this.$emit("refresh");
|
||||
},
|
||||
nodeExpand(data) {
|
||||
if (data.id) {
|
||||
this.expandedNode.push(data.id);
|
||||
}
|
||||
},
|
||||
nodeCollapse(data) {
|
||||
if (data.id) {
|
||||
this.expandedNode.splice(this.expandedNode.indexOf(data.id), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -90,6 +90,12 @@
|
|||
initTableData() {
|
||||
this.result = this.$post('/test/plan/list/all/relate', this.condition, response => {
|
||||
this.tableData = response.data;
|
||||
for (let i = 0; i < this.tableData.length; i++) {
|
||||
let path = "/test/plan/project/name/" + this.tableData[i].id;
|
||||
this.$get(path, res => {
|
||||
this.$set(this.tableData[i], "projectName", res.data);
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
intoPlan(row, event, column) {
|
||||
|
|
|
@ -22,11 +22,14 @@
|
|||
</el-col>
|
||||
|
||||
<el-col :span="11" :offset="2">
|
||||
<el-form-item :label="$t('test_track.plan.plan_project')" :label-width="formLabelWidth" prop="projectId">
|
||||
<el-form-item :label="$t('test_track.plan.plan_project')" :label-width="formLabelWidth" prop="projectIds">
|
||||
<el-select
|
||||
:disabled="(form.status == null) ? false : true"
|
||||
v-model="form.projectId"
|
||||
v-model="form.projectIds"
|
||||
:placeholder="$t('test_track.plan.input_plan_project')"
|
||||
multiple
|
||||
style="width: 100%"
|
||||
collapse-tags
|
||||
filterable>
|
||||
<el-option
|
||||
v-for="item in projects"
|
||||
|
@ -68,7 +71,7 @@
|
|||
</el-row>
|
||||
|
||||
<el-row type="flex" justify="left" style="margin-top: 10px;">
|
||||
<el-col :span="19" :offset="1">
|
||||
<el-col :span="23" :offset="1">
|
||||
<el-form-item :label="$t('commons.description')" :label-width="formLabelWidth" prop="description">
|
||||
<el-input v-model="form.description"
|
||||
type="textarea"
|
||||
|
@ -124,7 +127,7 @@ export default {
|
|||
dialogFormVisible: false,
|
||||
form: {
|
||||
name: '',
|
||||
projectId: '',
|
||||
projectIds: [],
|
||||
principal: '',
|
||||
stage: '',
|
||||
description: ''
|
||||
|
@ -134,7 +137,7 @@ export default {
|
|||
{required: true, message: this.$t('test_track.plan.input_plan_name'), trigger: 'blur'},
|
||||
{max: 30, message: this.$t('test_track.length_less_than') + '30', trigger: 'blur'}
|
||||
],
|
||||
projectId: [{required: true, message: this.$t('test_track.plan.input_plan_project'), trigger: 'change'}],
|
||||
projectIds: [{required: true, message: this.$t('test_track.plan.input_plan_project'), trigger: 'change'}],
|
||||
principal: [{required: true, message: this.$t('test_track.plan.input_plan_principal'), trigger: 'change'}],
|
||||
stage: [{required: true, message: this.$t('test_track.plan.input_plan_stage'), trigger: 'change'}],
|
||||
description: [{max: 200, message: this.$t('test_track.length_less_than') + '200', trigger: 'blur'}]
|
||||
|
@ -213,7 +216,7 @@ export default {
|
|||
this.$refs['planFrom'].validate((valid) => {
|
||||
this.$refs['planFrom'].resetFields();
|
||||
this.form.name = '';
|
||||
this.form.projectId = '';
|
||||
this.form.projectIds = [];
|
||||
this.form.principal = '';
|
||||
this.form.stage = '';
|
||||
this.form.description = '';
|
||||
|
|
|
@ -191,6 +191,16 @@ export default {
|
|||
let data = response.data;
|
||||
this.total = data.itemCount;
|
||||
this.tableData = data.listObject;
|
||||
for (let i = 0; i < this.tableData.length; i++) {
|
||||
let path = "/test/plan/project/" + this.tableData[i].id;
|
||||
this.$get(path, res => {
|
||||
let arr = res.data;
|
||||
let projectName = arr.map(data => data.name).join("、");
|
||||
let projectIds = arr.map(data => data.id);
|
||||
this.$set(this.tableData[i], "projectName", projectName);
|
||||
this.$set(this.tableData[i], "projectIds", projectIds);
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
buildPagePath(path) {
|
||||
|
|
|
@ -6,10 +6,12 @@
|
|||
:visible.sync="dialogFormVisible"
|
||||
@close="close"
|
||||
width="60%" v-loading="result.loading"
|
||||
:close-on-click-modal="false"
|
||||
top="50px">
|
||||
|
||||
<el-container class="main-content">
|
||||
<el-aside class="tree-aside" width="250px">
|
||||
<el-link type="primary" class="project-link" @click="switchProject">{{projectName ? projectName : '切换项目' }}</el-link>
|
||||
<node-tree class="node-tree"
|
||||
@nodeSelectEvent="nodeChange"
|
||||
@refresh="refresh"
|
||||
|
@ -71,6 +73,8 @@
|
|||
</template>
|
||||
|
||||
</el-dialog>
|
||||
|
||||
<switch-project ref="switchProject" @getProjectNode="getProjectNode"/>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
@ -86,6 +90,7 @@
|
|||
import MsTableAdvSearchBar from "../../../../common/components/search/MsTableAdvSearchBar";
|
||||
import MsTableHeader from "../../../../common/components/MsTableHeader";
|
||||
import {TEST_CASE_CONFIGS} from "../../../../common/components/search/search-components";
|
||||
import SwitchProject from "../../../case/components/SwitchProject";
|
||||
|
||||
export default {
|
||||
name: "TestCaseRelevance",
|
||||
|
@ -96,7 +101,8 @@
|
|||
TypeTableItem,
|
||||
MsTableSearchBar,
|
||||
MsTableAdvSearchBar,
|
||||
MsTableHeader
|
||||
MsTableHeader,
|
||||
SwitchProject
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -108,6 +114,9 @@
|
|||
treeNodes: [],
|
||||
selectNodeIds: [],
|
||||
selectNodeNames: [],
|
||||
projectId: '',
|
||||
projectName: '',
|
||||
projects: [],
|
||||
condition: {
|
||||
components: TEST_CASE_CONFIGS
|
||||
},
|
||||
|
@ -135,6 +144,9 @@
|
|||
},
|
||||
selectNodeIds() {
|
||||
this.getCaseNames();
|
||||
},
|
||||
projectId() {
|
||||
this.getProjectNode();
|
||||
}
|
||||
},
|
||||
updated() {
|
||||
|
@ -157,7 +169,6 @@
|
|||
});
|
||||
},
|
||||
getCaseNames() {
|
||||
let param = {};
|
||||
if (this.planId) {
|
||||
// param.planId = this.planId;
|
||||
this.condition.planId = this.planId;
|
||||
|
@ -168,12 +179,17 @@
|
|||
} else {
|
||||
this.condition.nodeIds = [];
|
||||
}
|
||||
|
||||
if (this.projectId) {
|
||||
this.condition.projectId = this.projectId;
|
||||
this.result = this.$post('/test/case/name', this.condition, response => {
|
||||
this.testCases = response.data;
|
||||
this.testCases.forEach(item => {
|
||||
item.checked = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
handleSelectAll(selection) {
|
||||
if (selection.length > 0) {
|
||||
|
@ -203,13 +219,18 @@
|
|||
initData() {
|
||||
this.getCaseNames();
|
||||
this.getAllNodeTreeByPlanId();
|
||||
this.getProject();
|
||||
},
|
||||
refresh() {
|
||||
this.close();
|
||||
},
|
||||
getAllNodeTreeByPlanId() {
|
||||
if (this.planId) {
|
||||
this.result = this.$get("/case/node/list/all/plan/" + this.planId, response => {
|
||||
let param = {
|
||||
testPlanId: this.planId,
|
||||
projectId: this.projectId
|
||||
};
|
||||
this.result = this.$post("/case/node/list/all/plan", param , response => {
|
||||
this.treeNodes = response.data;
|
||||
});
|
||||
}
|
||||
|
@ -233,6 +254,36 @@
|
|||
})
|
||||
})
|
||||
},
|
||||
getProject() {
|
||||
if (this.planId) {
|
||||
this.$get("/test/plan/project/" + this.planId,res => {
|
||||
let data = res.data;
|
||||
if (data) {
|
||||
this.projects = data;
|
||||
this.projectId = data[0].id;
|
||||
this.projectName = data[0].name;
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
switchProject() {
|
||||
this.$refs.switchProject.open(this.planId);
|
||||
},
|
||||
getProjectNode(projectId) {
|
||||
const index = this.projects.findIndex(project => project.id === projectId);
|
||||
if (index !== -1) {
|
||||
this.projectName = this.projects[index].name;
|
||||
}
|
||||
if (projectId) {
|
||||
this.projectId = projectId;
|
||||
}
|
||||
this.result = this.$post("/case/node/list/all/plan",
|
||||
{testPlanId: this.planId, projectId: this.projectId} , response => {
|
||||
this.treeNodes = response.data;
|
||||
});
|
||||
|
||||
this.selectNodeIds = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -281,4 +332,10 @@
|
|||
/*border: 1px solid #EBEEF5;*/
|
||||
}
|
||||
|
||||
.project-link {
|
||||
float: right;
|
||||
margin-right: 12px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue