feat(功能用例): 获取关联的测试计划
This commit is contained in:
parent
e9f234978a
commit
c8ed17ff7e
|
@ -5,7 +5,9 @@ import com.github.pagehelper.PageHelper;
|
|||
import io.metersphere.dto.BugProviderDTO;
|
||||
import io.metersphere.dto.TestCaseProviderDTO;
|
||||
import io.metersphere.functional.dto.FunctionalCaseTestDTO;
|
||||
import io.metersphere.functional.dto.FunctionalCaseTestPlanDTO;
|
||||
import io.metersphere.functional.request.AssociateCaseModuleRequest;
|
||||
import io.metersphere.functional.request.AssociatePlanPageRequest;
|
||||
import io.metersphere.functional.request.DisassociateOtherCaseRequest;
|
||||
import io.metersphere.functional.request.FunctionalCaseTestRequest;
|
||||
import io.metersphere.functional.service.FunctionalCaseLogService;
|
||||
|
@ -51,7 +53,7 @@ public class FunctionalTestCaseController {
|
|||
|
||||
@PostMapping("/associate/case/module/count")
|
||||
@Operation(summary = "用例管理-功能用例-关联其他用例-统计需要关联用例模块数量")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ)
|
||||
@RequiresPermissions(value = {PermissionConstants.FUNCTIONAL_CASE_READ_ADD, PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE, PermissionConstants.FUNCTIONAL_CASE_READ_DELETE}, logical = Logical.OR)
|
||||
@CheckOwner(resourceId = "#request.projectId", resourceType = "project")
|
||||
public Map<String, Long> moduleCount(@Validated @RequestBody TestCasePageProviderRequest request) {
|
||||
return functionalTestCaseService.moduleCount(request, false);
|
||||
|
@ -59,7 +61,7 @@ public class FunctionalTestCaseController {
|
|||
|
||||
@PostMapping("/associate/case/module/tree")
|
||||
@Operation(summary = "用例管理-功能用例-关联其他用例-获取需要关联的用例模块树")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ)
|
||||
@RequiresPermissions(value = {PermissionConstants.FUNCTIONAL_CASE_READ_ADD, PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE, PermissionConstants.FUNCTIONAL_CASE_READ_DELETE}, logical = Logical.OR)
|
||||
@CheckOwner(resourceId = "#request.projectId", resourceType = "project")
|
||||
public List<BaseTreeNode> getTree(@RequestBody @Validated AssociateCaseModuleRequest request) {
|
||||
return functionalTestCaseService.getTree(request);
|
||||
|
@ -67,7 +69,7 @@ public class FunctionalTestCaseController {
|
|||
|
||||
@PostMapping("/associate/case")
|
||||
@Operation(summary = "用例管理-功能用例-关联其他用例-关联用例")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ)
|
||||
@RequiresPermissions(value = {PermissionConstants.FUNCTIONAL_CASE_READ_ADD, PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE, PermissionConstants.FUNCTIONAL_CASE_READ_DELETE}, logical = Logical.OR)
|
||||
@CheckOwner(resourceId = "#request.sourceId", resourceType = "functional_case")
|
||||
public void associateCase(@Validated @RequestBody AssociateOtherCaseRequest request) {
|
||||
functionalTestCaseService.associateCase(request, false, SessionUtils.getUserId());
|
||||
|
@ -76,7 +78,7 @@ public class FunctionalTestCaseController {
|
|||
@PostMapping("/disassociate/case")
|
||||
@Operation(summary = "用例管理-功能用例-关联其他用例-取消关联用例")
|
||||
@Log(type = OperationLogType.DISASSOCIATE, expression = "#msClass.disassociateCaseLog(#request)", msClass = FunctionalCaseLogService.class)
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ)
|
||||
@RequiresPermissions(value = {PermissionConstants.FUNCTIONAL_CASE_READ_ADD, PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE, PermissionConstants.FUNCTIONAL_CASE_READ_DELETE}, logical = Logical.OR)
|
||||
@CheckOwner(resourceId = "#request.projectId", resourceType = "project")
|
||||
public void disassociateCase(@Validated @RequestBody DisassociateOtherCaseRequest request) {
|
||||
functionalTestCaseService.disassociateCase(request);
|
||||
|
@ -129,4 +131,14 @@ public class FunctionalTestCaseController {
|
|||
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize());
|
||||
return PageUtils.setPageInfo(page, functionalTestCaseService.hasAssociateBugPage(request));
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/has/associate/plan/page")
|
||||
@Operation(summary = "用例管理-功能用例-关联其他用例-获取已关联的测试计划列表")
|
||||
@RequiresPermissions(value = {PermissionConstants.FUNCTIONAL_CASE_READ_ADD, PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE, PermissionConstants.FUNCTIONAL_CASE_READ_DELETE}, logical = Logical.OR)
|
||||
@CheckOwner(resourceId = "#request.caseId", resourceType = "functional_case")
|
||||
public Pager<List<FunctionalCaseTestPlanDTO>> getAssociateOtherPlanList(@Validated @RequestBody AssociatePlanPageRequest request) {
|
||||
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize());
|
||||
return PageUtils.setPageInfo(page, functionalTestCaseService.hasAssociatePlanPage(request));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package io.metersphere.functional.dto;
|
||||
|
||||
import io.metersphere.plan.domain.TestPlanFunctionalCase;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FunctionalCaseTestPlanDTO extends TestPlanFunctionalCase {
|
||||
|
||||
@Schema(description = "测试计划ID")
|
||||
private String num;
|
||||
|
||||
@Schema(description = "所属项目")
|
||||
private String projectName;
|
||||
|
||||
@Schema(description = "计划状态")
|
||||
private String planStatus;
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package io.metersphere.functional.mapper;
|
||||
|
||||
import io.metersphere.functional.dto.FunctionalCaseTestDTO;
|
||||
import io.metersphere.functional.dto.FunctionalCaseTestPlanDTO;
|
||||
import io.metersphere.functional.request.AssociatePlanPageRequest;
|
||||
import io.metersphere.functional.request.DisassociateOtherCaseRequest;
|
||||
import io.metersphere.functional.request.FunctionalCaseTestRequest;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
@ -12,4 +14,7 @@ public interface ExtFunctionalCaseTestMapper {
|
|||
List<String> getIds(@Param("request") DisassociateOtherCaseRequest request);
|
||||
|
||||
List<FunctionalCaseTestDTO> getList(@Param("request") FunctionalCaseTestRequest request);
|
||||
|
||||
List<FunctionalCaseTestPlanDTO> getPlanList(@Param("request") AssociatePlanPageRequest request);
|
||||
|
||||
}
|
||||
|
|
|
@ -56,6 +56,23 @@
|
|||
order by fct.create_time desc
|
||||
</select>
|
||||
|
||||
<select id="getPlanList" parameterType="io.metersphere.functional.request.AssociatePlanPageRequest" resultType="io.metersphere.functional.dto.FunctionalCaseTestPlanDTO">
|
||||
SELECT
|
||||
tpfc.*, tp.num as num, tp.status as planStatus, p.name as projectName
|
||||
FROM
|
||||
test_plan_functional_case tpfc
|
||||
LEFT JOIN test_plan tp ON tpfc.test_plan_id = tp.id
|
||||
LEFT JOIN project p ON tp.project_id = p.id
|
||||
WHERE tpfc.functional_case_id = #{request.caseId}
|
||||
<if test="request.keyword != null">
|
||||
AND
|
||||
(
|
||||
tp.name LIKE concat('%', #{request.keyword},'%')
|
||||
OR tp.num LIKE concat('%', #{request.keyword},'%')
|
||||
)
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<sql id="queryWhereConditionByBaseQueryRequest">
|
||||
<if test="request.condition.keyword != null and request.sourceType == 'API'">
|
||||
functional_case_test.source_id not in
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package io.metersphere.functional.request;
|
||||
|
||||
import io.metersphere.request.BaseProviderCondition;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class AssociatePlanPageRequest extends BaseProviderCondition {
|
||||
|
||||
|
||||
@Schema(description = "功能用例id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{associate_plan_page_request.case_id.not_blank}")
|
||||
private String caseId;
|
||||
|
||||
|
||||
@Min(value = 1, message = "当前页码必须大于0")
|
||||
@Schema(description = "当前页码")
|
||||
private int current;
|
||||
|
||||
@Min(value = 5, message = "每页显示条数必须不小于5")
|
||||
@Max(value = 500, message = "每页显示条数不能大于500")
|
||||
@Schema(description = "每页显示条数")
|
||||
private int pageSize;
|
||||
}
|
|
@ -7,10 +7,12 @@ import io.metersphere.functional.constants.AssociateCaseType;
|
|||
import io.metersphere.functional.domain.FunctionalCaseTest;
|
||||
import io.metersphere.functional.domain.FunctionalCaseTestExample;
|
||||
import io.metersphere.functional.dto.FunctionalCaseTestDTO;
|
||||
import io.metersphere.functional.dto.FunctionalCaseTestPlanDTO;
|
||||
import io.metersphere.functional.mapper.ExtFunctionalCaseModuleMapper;
|
||||
import io.metersphere.functional.mapper.ExtFunctionalCaseTestMapper;
|
||||
import io.metersphere.functional.mapper.FunctionalCaseTestMapper;
|
||||
import io.metersphere.functional.request.AssociateCaseModuleRequest;
|
||||
import io.metersphere.functional.request.AssociatePlanPageRequest;
|
||||
import io.metersphere.functional.request.DisassociateOtherCaseRequest;
|
||||
import io.metersphere.functional.request.FunctionalCaseTestRequest;
|
||||
import io.metersphere.provider.BaseAssociateApiProvider;
|
||||
|
@ -207,4 +209,13 @@ public class FunctionalTestCaseService {
|
|||
public List<BugProviderDTO> hasAssociateBugPage(AssociateBugPageRequest request) {
|
||||
return baseAssociateBugProvider.hasAssociateBugPage(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询已关联的测试计划列表
|
||||
* @param request request
|
||||
* @return List<FunctionalCaseTestPlanDTO>
|
||||
*/
|
||||
public List<FunctionalCaseTestPlanDTO> hasAssociatePlanPage(AssociatePlanPageRequest request) {
|
||||
return extFunctionalCaseTestMapper.getPlanList(request);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package io.metersphere.functional.controller;
|
|||
import io.metersphere.api.domain.ApiDefinitionModule;
|
||||
import io.metersphere.api.domain.ApiTestCase;
|
||||
import io.metersphere.api.mapper.ApiDefinitionModuleMapper;
|
||||
import io.metersphere.bug.mapper.BugRelationCaseMapper;
|
||||
import io.metersphere.dto.BugProviderDTO;
|
||||
import io.metersphere.dto.TestCaseProviderDTO;
|
||||
import io.metersphere.functional.constants.AssociateCaseType;
|
||||
|
@ -11,11 +10,15 @@ import io.metersphere.functional.constants.FunctionalCaseReviewStatus;
|
|||
import io.metersphere.functional.domain.FunctionalCase;
|
||||
import io.metersphere.functional.domain.FunctionalCaseTest;
|
||||
import io.metersphere.functional.dto.FunctionalCaseTestDTO;
|
||||
import io.metersphere.functional.dto.FunctionalCaseTestPlanDTO;
|
||||
import io.metersphere.functional.mapper.FunctionalCaseMapper;
|
||||
import io.metersphere.functional.mapper.FunctionalCaseTestMapper;
|
||||
import io.metersphere.functional.request.AssociateCaseModuleRequest;
|
||||
import io.metersphere.functional.request.AssociatePlanPageRequest;
|
||||
import io.metersphere.functional.request.DisassociateOtherCaseRequest;
|
||||
import io.metersphere.functional.request.FunctionalCaseTestRequest;
|
||||
import io.metersphere.plan.mapper.TestPlanFunctionalCaseMapper;
|
||||
import io.metersphere.plan.mapper.TestPlanMapper;
|
||||
import io.metersphere.provider.BaseAssociateApiProvider;
|
||||
import io.metersphere.provider.BaseAssociateBugProvider;
|
||||
import io.metersphere.request.*;
|
||||
|
@ -62,6 +65,9 @@ public class FunctionalTestCaseControllerTests extends BaseTest {
|
|||
private static final String URL_DISASSOCIATE_BUG = "/functional/case/test/disassociate/bug/";
|
||||
private static final String URL_ASSOCIATE_BUG_PAGE = "/functional/case/test/has/associate/bug/page";
|
||||
|
||||
private static final String URL_ASSOCIATE_TEST_PLAN_PAGE = "/functional/case/test/has/associate/plan/page";
|
||||
|
||||
|
||||
|
||||
@Resource
|
||||
BaseAssociateApiProvider provider;
|
||||
|
@ -76,12 +82,15 @@ public class FunctionalTestCaseControllerTests extends BaseTest {
|
|||
private ApiDefinitionModuleMapper apiDefinitionModuleMapper;
|
||||
@Resource
|
||||
BaseAssociateBugProvider baseAssociateBugProvider;
|
||||
@Resource
|
||||
private BugRelationCaseMapper bugRelationCaseMapper;
|
||||
@Resource
|
||||
TestPlanFunctionalCaseMapper testPlanFunctionalCaseMapper;
|
||||
@Resource
|
||||
TestPlanMapper testPlanMapper;
|
||||
|
||||
|
||||
@Test
|
||||
@Order(1)
|
||||
@Sql(scripts = {"/dml/init_test_plan_case.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
|
||||
public void getPageSuccess() throws Exception {
|
||||
TestCasePageProviderRequest request = new TestCasePageProviderRequest();
|
||||
request.setSourceType(AssociateCaseType.API);
|
||||
|
@ -389,4 +398,21 @@ public class FunctionalTestCaseControllerTests extends BaseTest {
|
|||
}});
|
||||
this.requestPostWithOkAndReturn(URL_ASSOCIATE_BUG_PAGE, request);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(12)
|
||||
public void testAssociatePlanPage() throws Exception {
|
||||
AssociatePlanPageRequest request = new AssociatePlanPageRequest();
|
||||
request.setCurrent(1);
|
||||
request.setPageSize(10);
|
||||
request.setCaseId("gyq_associate_function_case");
|
||||
request.setKeyword("name");
|
||||
MvcResult mvcResult = this.requestPostWithOkAndReturn(URL_ASSOCIATE_TEST_PLAN_PAGE, request);
|
||||
Pager<List<FunctionalCaseTestPlanDTO>> tableData = JSON.parseObject(JSON.toJSONString(
|
||||
JSON.parseObject(mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class).getData()),
|
||||
Pager.class);
|
||||
Assertions.assertNotNull(tableData);
|
||||
List<FunctionalCaseTestPlanDTO> list = tableData.getList();
|
||||
Assertions.assertEquals(2, list.size());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
INSERT INTO test_plan(id, num, project_id, group_id, module_id, name, status, type, tags, create_time, create_user, update_time, update_user, planned_start_time, planned_end_time, actual_start_time, actual_end_time, description)
|
||||
VALUE ('test_plan_associate_case_gyq_three', 500, 'test_plan_associate_case_project', 'NONE', 'case_plan_module', 'test_plan_associate_case_name_three', 'PREPARED', 'TEST_PLAN', null, UNIX_TIMESTAMP() * 1000,'admin',
|
||||
UNIX_TIMESTAMP() * 1000,'admin',UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, null);
|
||||
|
||||
|
||||
INSERT INTO test_plan(id, num, project_id, group_id, module_id, name, status, type, tags, create_time, create_user, update_time, update_user, planned_start_time, planned_end_time, actual_start_time, actual_end_time, description)
|
||||
VALUES ('test_plan_associate_case_gyq_one', 500, 'test_plan_associate_case_project', 'NONE', 'case_plan_module', 'test_plan_associate_case_name_one', 'PREPARED', 'TEST_PLAN', null, UNIX_TIMESTAMP() * 1000,'admin',
|
||||
UNIX_TIMESTAMP() * 1000,'admin',UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, null),
|
||||
('test_plan_associate_case_gyq_two', 500, 'test_plan_associate_case_project', 'NONE', 'case_plan_module', 'test_plan_associate_case_name_two', 'PREPARED', 'TEST_PLAN', null, UNIX_TIMESTAMP() * 1000,'admin',
|
||||
UNIX_TIMESTAMP() * 1000,'admin',UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, null);
|
||||
|
||||
|
||||
INSERT INTO project(id, num, organization_id, name, description, create_time, update_time, update_user, create_user, delete_time, deleted, delete_user, enable, module_setting)
|
||||
VALUE ('test_plan_associate_case_project', null, 'organization_plan_associate_case_project', 'test_plan_associate_case_name', null,
|
||||
UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'admin', null, false, null, true, null);
|
||||
|
||||
|
||||
INSERT INTO test_plan_functional_case(id, test_plan_id, functional_case_id, create_time, create_user, last_exec_time, last_exec_result, pos)
|
||||
VALUES ('associate_case_plan_gyq_one', 'test_plan_associate_case_gyq_one', 'gyq_associate_function_case', UNIX_TIMESTAMP() * 1000, 'admin', UNIX_TIMESTAMP() * 1000, 'SUCCESS', 200),
|
||||
('associate_case_plan_gyq_two', 'test_plan_associate_case_gyq_two', 'gyq_associate_function_case', UNIX_TIMESTAMP() * 1000, 'admin', UNIX_TIMESTAMP() * 1000, 'SUCCESS', 200);
|
Loading…
Reference in New Issue