feat(测试计划): 补充测试计划权限位

This commit is contained in:
song-cc-rock 2024-05-20 14:16:28 +08:00 committed by 刘瑞斌
parent 0be3a0f743
commit 57d710a2b2
23 changed files with 150 additions and 112 deletions

View File

@ -7,5 +7,30 @@ update functional_case set last_execute_result = 'SUCCESS' where last_execute_re
update functional_case set last_execute_result = 'ERROR' where last_execute_result = 'FAILED';
update functional_case set last_execute_result = 'PENDING' where last_execute_result = 'SKIPPED';
-- 初始化计划相关的权限 (删除V3.0.0_11_1测试计划模块相关的权限, 重新初始化, 模块树不单独拥有权限)
delete from user_role_permission where permission_id like 'PROJECT_TEST_PLAN_MODULE%' or permission_id like 'PROJECT_TEST_PLAN%';
-- 项目管理员(测试计划相关的权限)
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+ADD');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+UPDATE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+DELETE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+EXECUTE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+ASSOCIATION');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN_REPORT:READ');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN_REPORT:READ+UPDATE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN_REPORT:READ+SHARE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN_REPORT:READ+DELETE');
-- 项目成员(测试计划相关的权限)
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN:READ');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN:READ+ADD');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN:READ+UPDATE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN:READ+DELETE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN:READ+EXECUTE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN:READ+ASSOCIATION');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN_REPORT:READ');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN_REPORT:READ+UPDATE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN_REPORT:READ+SHARE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN_REPORT:READ+DELETE');
-- set innodb lock wait timeout to default
SET SESSION innodb_lock_wait_timeout = DEFAULT;

View File

@ -299,10 +299,6 @@ public class PermissionConstants {
//测试计划
/*------ start: TEST_PLAN ------*/
public static final String TEST_PLAN_MODULE_READ = "PROJECT_TEST_PLAN_MODULE:READ";
public static final String TEST_PLAN_MODULE_READ_ADD = "PROJECT_TEST_PLAN_MODULE:READ+ADD";
public static final String TEST_PLAN_MODULE_READ_UPDATE = "PROJECT_TEST_PLAN_MODULE:READ+UPDATE";
public static final String TEST_PLAN_MODULE_READ_DELETE = "PROJECT_TEST_PLAN_MODULE:READ+DELETE";
public static final String TEST_PLAN_READ = "PROJECT_TEST_PLAN:READ";
public static final String TEST_PLAN_READ_ADD = "PROJECT_TEST_PLAN:READ+ADD";

View File

@ -83,6 +83,9 @@ public class FilterChainUtils {
filterChainDefinitionMap.put("/api/report/case/share/**", "anon");
filterChainDefinitionMap.put("/api/report/scenario/share/**", "anon");
filterChainDefinitionMap.put("/api/report/share/get/**", "anon");
// 测试计划报告分享接口
filterChainDefinitionMap.put("/test-plan/report/share/get/detail/**", "anon");
filterChainDefinitionMap.put("/test-plan/report/share/detail/**", "anon");
return filterChainDefinitionMap;
}

View File

@ -458,6 +458,7 @@ permission.recover=恢复
permission.export=导出
permission.execute=执行
permission.debug=调试
permission.association=关联
permission.api_definition.delete_and_recover=删除/恢复
permission.service_integration.reset=重置
@ -522,7 +523,8 @@ swagger_parse_error_with_auth=Swagger 解析失败,请确认认证信息是否
swagger_parse_error=Swagger 解析失败,请确认文件格式是否正确!
#测试计划
permission.test_plan.name=测试计划
permission.test_plan_module.name=测试计划模块
permission.test_plan=计划
permission.test_plan_report=报告
#关联
relate_source_id_not_blank=关联来源ID不能为空

View File

@ -467,7 +467,7 @@ permission.recover=Recover
permission.export=Export
permission.execute=Execute
permission.debug=Debug
permission.association=Associate
file_name_illegal_error=File name is illegal
plugin_enable_error=Plugin is not enabled
plugin_permission_error=No access to this plugin
@ -536,7 +536,8 @@ swagger_parse_error_with_auth=Swagger parsing failed, please confirm whether the
swagger_parse_error=Swagger parsing failed or file format is incorrect!
#测试计划
permission.test_plan.name=Test plan
permission.test_plan_module.name=Test plan module
permission.test_plan=Plan
permission.test_plan_report=Report
excel.template.id=Non mandatory, add a new use case when the ID is empty or does not exist;
excel.template.case_edit_type=Not mandatory, fill in STEP for step description, fill in Text for text description, default to Text if not filled in

View File

@ -466,7 +466,7 @@ permission.recover=恢复
permission.export=导出
permission.execute=执行
permission.debug=调试
permission.association=关联
file_name_illegal_error=文件名不合法
plugin_enable_error=插件未启用
plugin_permission_error=没有该插件的访问权限
@ -533,7 +533,8 @@ swagger_parse_error_with_auth=Swagger 解析失败,请确认认证信息是否
swagger_parse_error=Swagger 解析失败,请确认文件格式是否正确!
#测试计划
permission.test_plan.name=测试计划
permission.test_plan_module.name=测试计划模块
permission.test_plan=计划
permission.test_plan_report=报告
excel.template.id=非必填ID为空或不存在时新增用例
excel.template.case_edit_type=非必填步骤描述填写STEP文本描述填写TEXT未填写默认为TEXT

View File

@ -464,7 +464,7 @@ permission.recover=恢復
permission.export=導出
permission.execute=執行
permission.debug=調試
permission.association=關聯
file_name_illegal_error=文件名不合法
plugin_enable_error=插件未啟用
plugin_permission_error=沒有該插件的訪問權限
@ -534,7 +534,8 @@ swagger_parse_error_with_auth=Swagger 解析失敗,請檢查 Swagger 接口是
swagger_parse_error=Swagger 解析失敗
#測試計劃
permission.test_plan.name=測試計劃
permission.test_plan_module.name=測試計劃模塊
permission.test_plan=計劃
permission.test_plan_report=報告
excel.template.id=非必填ID為空時或不存在時新增用例
excel.template.case_edit_type=非必填步驟描述填寫STEP文本描述填寫TEXT為填寫默認為TEXT

View File

@ -91,4 +91,6 @@ test_plan.batch.log={0}测试计划
test_plan_report_not_exist=测试计划报告不存在
test_plan_report_id.not_blank=测试计划报告id不能为空
test_plan_report_name.not_blank=测试计划报告名称不能为空
test_plan_not_exist=测试计划不存在
test_plan_not_exist=测试计划不存在
test_plan.report_id.not_blank=测试计划报告ID不能为空
test_plan.report.share_id.not_blank=测试计划报告分享ID不能为空

View File

@ -103,4 +103,6 @@ test_plan_report_not_exist=The test plan report does not exist
test_plan_report_id.not_blank=The test plan report id cannot be empty
test_plan_report_name.not_blank=The test plan report name cannot be empty
run_functional_case=Run functional case
test_plan_not_exist=The test plan does not exist
test_plan_not_exist=The test plan does not exist
test_plan.report_id.not_blank=The test plan report ID cannot be empty
test_plan.report.share_id.not_blank=The test plan report share ID cannot be empty

View File

@ -103,4 +103,6 @@ test_plan_report_not_exist=测试计划报告不存在
test_plan_report_id.not_blank=测试计划报告id不能为空
test_plan_report_name.not_blank=测试计划报告名称不能为空
run_functional_case=执行功能用例
test_plan_not_exist=测试计划不存在
test_plan_not_exist=测试计划不存在
test_plan.report_id.not_blank=测试计划报告ID不能为空
test_plan.report.share_id.not_blank=测试计划报告分享ID不能为空

View File

@ -103,4 +103,6 @@ test_plan_report_not_exist=測試計劃報告不存在
test_plan_report_id.not_blank=測試計劃報告id不能爲空
test_plan_report_name.not_blank=測試計劃報告名稱不能爲空
run_functional_case=執行功能用例
test_plan_not_exist=測試計劃不存在
test_plan_not_exist=測試計劃不存在
test_plan.report_id.not_blank=測試計劃報告ID不能爲空
test_plan.report.share_id.not_blank=測試計劃報告分享ID不能爲空

View File

@ -68,7 +68,6 @@ public class TestPlanController {
return testPlanManagementService.moduleCount(request);
}
@PostMapping("/add")
@Operation(summary = "测试计划-创建测试计划")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_ADD)
@ -89,7 +88,6 @@ public class TestPlanController {
return testPlanService.update(request, SessionUtils.getUserId(), "/test-plan/update", HttpMethodConstants.POST.name());
}
@GetMapping("/delete/{id}")
@Operation(summary = "测试计划-删除测试计划")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_DELETE)
@ -109,7 +107,6 @@ public class TestPlanController {
testPlanService.editFollower(request.getTestPlanId(), userId);
}
@GetMapping("/archived/{id}")
@Operation(summary = "测试计划-归档")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_UPDATE)
@ -155,7 +152,6 @@ public class TestPlanController {
testPlanService.batchCopy(request, SessionUtils.getUserId(), "/test-plan/batch-copy", HttpMethodConstants.POST.name());
}
@PostMapping("/batch-move")
@Operation(summary = "测试计划-批量移动测试计划")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_UPDATE)
@ -183,7 +179,6 @@ public class TestPlanController {
testPlanService.association(request);
}
@PostMapping("/batch-edit")
@Operation(summary = "测试计划-批量编辑")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_UPDATE)

View File

@ -107,6 +107,7 @@ public class TestPlanFunctionalCaseController {
@PostMapping("/associate/bug/page")
@Operation(summary = "测试计划-计划详情-功能用例-获取缺陷列表")
@CheckOwner(resourceId = "#request.getProjectId", resourceType = "project")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ)
public Pager<List<BugProviderDTO>> associateBugList(@Validated @RequestBody BugPageProviderRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize());
return PageUtils.setPageInfo(page, testPlanFunctionalCaseService.bugPage(request));
@ -114,6 +115,7 @@ public class TestPlanFunctionalCaseController {
@PostMapping("/associate/bug")
@Operation(summary = "测试计划-计划详情-功能用例-关联其他用例-关联缺陷")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE)
@CheckOwner(resourceId = "#request.getTestPlanCaseId()", resourceType = "test_plan_functional_case")
public void associateBug(@Validated @RequestBody TestPlanCaseAssociateBugRequest request) {
testPlanFunctionalCaseService.associateBug(request, SessionUtils.getUserId());
@ -121,6 +123,7 @@ public class TestPlanFunctionalCaseController {
@GetMapping("/disassociate/bug/{id}")
@Operation(summary = "用例管理-功能用例-关联其他用例-取消关联缺陷")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE)
@Log(type = OperationLogType.DISASSOCIATE, expression = "#msClass.disassociateBugLog(#id)", msClass = TestPlanFunctionalCaseService.class)
@CheckOwner(resourceId = "#id", resourceType = "bug_relation_case")
public void disassociateBug(@PathVariable String id) {
@ -135,7 +138,6 @@ public class TestPlanFunctionalCaseController {
testPlanFunctionalCaseService.run(request, SessionUtils.getCurrentOrganizationId(), new LogInsertModule(SessionUtils.getUserId(), "/test-plan/functional/case/run", HttpMethodConstants.POST.name()));
}
@PostMapping("/batch/run")
@Operation(summary = "测试计划-计划详情-功能用例-批量执行")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE)
@ -146,13 +148,13 @@ public class TestPlanFunctionalCaseController {
@PostMapping("/has/associate/bug/page")
@Operation(summary = "测试计划-计划详情-功能用例-获取已关联的缺陷列表")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE)
@CheckOwner(resourceId = "#request.getTestPlanCaseId()", resourceType = "test_plan_functional_case")
public Pager<List<BugProviderDTO>> getAssociateBugList(@Validated @RequestBody AssociateBugPageRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize());
return PageUtils.setPageInfo(page, testPlanFunctionalCaseService.hasAssociateBugPage(request));
}
@PostMapping("/batch/update/executor")
@Operation(summary = "测试计划-计划详情-功能用例-批量更新执行人")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_UPDATE)
@ -170,7 +172,6 @@ public class TestPlanFunctionalCaseController {
return testPlanFunctionalCaseService.getFunctionalCaseDetail(id, userId);
}
@PostMapping("/exec/history")
@Operation(summary = "测试计划-计划详情-功能用例-执行历史")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ)
@ -179,7 +180,6 @@ public class TestPlanFunctionalCaseController {
return testPlanFunctionalCaseService.getCaseExecHistory(request);
}
@PostMapping("/edit")
@Operation(summary = "测试计划-计划详情-功能用例-编辑执行结果")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE)
@ -188,7 +188,6 @@ public class TestPlanFunctionalCaseController {
testPlanFunctionalCaseService.editFunctionalCase(request, SessionUtils.getUserId());
}
@GetMapping("/user-option/{projectId}")
@Operation(summary = "测试计划-计划详情-功能用例-获取用户列表")
@RequiresPermissions(value = {PermissionConstants.TEST_PLAN_READ, PermissionConstants.TEST_PLAN_READ_UPDATE, PermissionConstants.TEST_PLAN_READ_ADD}, logical = Logical.OR)

View File

@ -33,7 +33,7 @@ public class TestPlanModuleController {
@GetMapping("/tree/{projectId}")
@Operation(summary = "测试计划管理-模块树-查找模块")
@RequiresPermissions(PermissionConstants.TEST_PLAN_MODULE_READ)
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ)
@CheckOwner(resourceId = "#projectId", resourceType = "project")
public List<BaseTreeNode> getTree(@PathVariable String projectId) {
testPlanManagementService.checkModuleIsOpen(projectId, TestPlanResourceConfig.CHECK_TYPE_PROJECT, Collections.singletonList(TestPlanResourceConfig.CHECK_TYPE_TEST_PLAN));
@ -42,7 +42,7 @@ public class TestPlanModuleController {
@PostMapping("/add")
@Operation(summary = "测试计划管理-模块树-添加模块")
@RequiresPermissions(PermissionConstants.TEST_PLAN_MODULE_READ_ADD)
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_ADD)
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
public String add(@RequestBody @Validated TestPlanModuleCreateRequest request) {
testPlanManagementService.checkModuleIsOpen(request.getProjectId(), TestPlanResourceConfig.CHECK_TYPE_PROJECT, Collections.singletonList(TestPlanResourceConfig.CHECK_TYPE_TEST_PLAN));
@ -51,7 +51,7 @@ public class TestPlanModuleController {
@PostMapping("/update")
@Operation(summary = "测试计划管理-模块树-修改模块")
@RequiresPermissions(PermissionConstants.TEST_PLAN_MODULE_READ_UPDATE)
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_UPDATE)
@CheckOwner(resourceId = "#request.getId()", resourceType = "file_module")
public boolean list(@RequestBody @Validated TestPlanModuleUpdateRequest request) {
testPlanManagementService.checkModuleIsOpen(request.getId(), TestPlanResourceConfig.CHECK_TYPE_TEST_PLAN_MODULE, Collections.singletonList(TestPlanResourceConfig.CHECK_TYPE_TEST_PLAN));
@ -61,7 +61,7 @@ public class TestPlanModuleController {
@GetMapping("/delete/{deleteId}")
@Operation(summary = "测试计划管理-模块树-删除模块")
@RequiresPermissions(PermissionConstants.TEST_PLAN_MODULE_READ_DELETE)
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_DELETE)
@CheckOwner(resourceId = "#deleteId", resourceType = "file_module")
public void deleteNode(@PathVariable String deleteId) {
testPlanManagementService.checkModuleIsOpen(deleteId, TestPlanResourceConfig.CHECK_TYPE_TEST_PLAN_MODULE, Collections.singletonList(TestPlanResourceConfig.CHECK_TYPE_TEST_PLAN));
@ -70,7 +70,7 @@ public class TestPlanModuleController {
@PostMapping("/move")
@Operation(summary = "测试计划管理-模块树-移动模块")
@RequiresPermissions(PermissionConstants.TEST_PLAN_MODULE_READ_UPDATE)
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_UPDATE)
@CheckOwner(resourceId = "#request.getDragNodeId()", resourceType = "test_plan_module")
public void moveNode(@Validated @RequestBody NodeMoveRequest request) {
testPlanManagementService.checkModuleIsOpen(request.getDragNodeId(), TestPlanResourceConfig.CHECK_TYPE_TEST_PLAN_MODULE, Collections.singletonList(TestPlanResourceConfig.CHECK_TYPE_TEST_PLAN));

View File

@ -6,10 +6,7 @@ import io.metersphere.bug.dto.response.BugDTO;
import io.metersphere.plan.constants.TestPlanResourceConfig;
import io.metersphere.plan.domain.TestPlanReport;
import io.metersphere.plan.dto.ReportDetailCasePageDTO;
import io.metersphere.plan.dto.request.TestPlanReportBatchRequest;
import io.metersphere.plan.dto.request.TestPlanReportDetailEditRequest;
import io.metersphere.plan.dto.request.TestPlanReportGenRequest;
import io.metersphere.plan.dto.request.TestPlanReportPageRequest;
import io.metersphere.plan.dto.request.*;
import io.metersphere.plan.dto.response.TestPlanReportDetailResponse;
import io.metersphere.plan.dto.response.TestPlanReportPageResponse;
import io.metersphere.plan.service.TestPlanManagementService;
@ -17,7 +14,6 @@ import io.metersphere.plan.service.TestPlanReportLogService;
import io.metersphere.plan.service.TestPlanReportNoticeService;
import io.metersphere.plan.service.TestPlanReportService;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.system.dto.sdk.BasePageRequest;
import io.metersphere.system.log.annotation.Log;
import io.metersphere.system.log.constants.OperationLogType;
import io.metersphere.system.notice.annotation.SendNotice;
@ -111,25 +107,23 @@ public class TestPlanReportController {
return testPlanReportService.edit(request);
}
@PostMapping("/detail/bug/page/{reportId}")
@PostMapping("/detail/bug/page")
@Operation(summary = "测试计划-报告-详情-缺陷分页查询")
@RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ)
@CheckOwner(resourceId = "#reportId", resourceType = "test_plan_report")
public Pager<List<BugDTO>> pageBug(@PathVariable String reportId,
@Validated @RequestBody BasePageRequest request) {
public Pager<List<BugDTO>> pageBug(@Validated @RequestBody TestPlanReportDetailPageRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "tprb.bug_num, tprb.id desc");
return PageUtils.setPageInfo(page, testPlanReportService.listReportDetailBugs(request, reportId));
return PageUtils.setPageInfo(page, testPlanReportService.listReportDetailBugs(request));
}
@PostMapping("/detail/functional/case/page/{reportId}")
@PostMapping("/detail/functional/case/page")
@Operation(summary = "测试计划-报告-详情-功能用例分页查询")
@RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ)
@CheckOwner(resourceId = "#reportId", resourceType = "test_plan_report")
public Pager<List<ReportDetailCasePageDTO>> pageFunctionalCase(@PathVariable String reportId,
@Validated @RequestBody BasePageRequest request) {
public Pager<List<ReportDetailCasePageDTO>> pageFunctionalCase(@Validated @RequestBody TestPlanReportDetailPageRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "tprfc.function_case_num, tprfc.id desc");
return PageUtils.setPageInfo(page, testPlanReportService.listReportDetailFunctionalCases(request, reportId));
return PageUtils.setPageInfo(page, testPlanReportService.listReportDetailFunctionalCases(request));
}
}

View File

@ -6,13 +6,13 @@ import io.metersphere.bug.dto.response.BugDTO;
import io.metersphere.plan.dto.ReportDetailCasePageDTO;
import io.metersphere.plan.dto.TestPlanShareInfo;
import io.metersphere.plan.dto.request.TestPlanReportShareRequest;
import io.metersphere.plan.dto.request.TestPlanShareReportDetailRequest;
import io.metersphere.plan.dto.response.TestPlanReportDetailResponse;
import io.metersphere.plan.dto.response.TestPlanShareResponse;
import io.metersphere.plan.service.TestPlanReportService;
import io.metersphere.plan.service.TestPlanReportShareService;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.sdk.domain.ShareInfo;
import io.metersphere.system.dto.sdk.BasePageRequest;
import io.metersphere.system.security.CheckOwner;
import io.metersphere.system.utils.PageUtils;
import io.metersphere.system.utils.Pager;
@ -47,21 +47,22 @@ public class TestPlanReportShareController {
@GetMapping("/get/{id}")
@Operation(summary = "测试计划-报告-获取分享链接")
@RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ_SHARE)
public TestPlanShareResponse get(@PathVariable String id) {
return testPlanReportShareService.get(id);
}
@GetMapping("/get-share-time/{id}")
@Operation(summary = "测试计划-报告-获取分享链接的有效时间")
@RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ_SHARE)
public String getShareTime(@PathVariable String id) {
return testPlanReportShareService.getShareTime(id);
}
// 分享报告详情开始
@GetMapping("/get/{shareId}/{reportId}")
@GetMapping("/get/detail/{shareId}/{reportId}")
@Operation(summary = "测试计划-报告分享-详情查看")
@RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ)
@CheckOwner(resourceId = "#id", resourceType = "test_plan_report")
public TestPlanReportDetailResponse getDetail(@PathVariable String shareId, @PathVariable String reportId) {
ShareInfo shareInfo = testPlanReportShareService.checkResource(shareId);
@ -69,29 +70,25 @@ public class TestPlanReportShareController {
return testPlanReportService.getReport(reportId);
}
@PostMapping("/detail/bug/page/{shareId}/{reportId}")
@PostMapping("/detail/bug/page")
@Operation(summary = "测试计划-报告-详情-缺陷分页查询")
@RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ)
@CheckOwner(resourceId = "#reportId", resourceType = "test_plan_report")
public Pager<List<BugDTO>> pageBug(@PathVariable String reportId, @PathVariable String shareId,
@Validated @RequestBody BasePageRequest request) {
ShareInfo shareInfo = testPlanReportShareService.checkResource(shareId);
public Pager<List<BugDTO>> pageBug(@Validated @RequestBody TestPlanShareReportDetailRequest request) {
ShareInfo shareInfo = testPlanReportShareService.checkResource(request.getShareId());
testPlanReportShareService.validateExpired(shareInfo);
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "tprb.bug_num, tprb.id desc");
return PageUtils.setPageInfo(page, testPlanReportService.listReportDetailBugs(request, reportId));
return PageUtils.setPageInfo(page, testPlanReportService.listReportDetailBugs(request));
}
@PostMapping("/detail/functional/case/page/{shareId}/{reportId}")
@PostMapping("/detail/functional/case/page")
@Operation(summary = "测试计划-报告-详情-功能用例分页查询")
@RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ)
@CheckOwner(resourceId = "#reportId", resourceType = "test_plan_report")
public Pager<List<ReportDetailCasePageDTO>> pageFunctionalCase(@PathVariable String reportId, @PathVariable String shareId,
@Validated @RequestBody BasePageRequest request) {
ShareInfo shareInfo = testPlanReportShareService.checkResource(shareId);
public Pager<List<ReportDetailCasePageDTO>> pageFunctionalCase(@Validated @RequestBody TestPlanShareReportDetailRequest request) {
ShareInfo shareInfo = testPlanReportShareService.checkResource(request.getShareId());
testPlanReportShareService.validateExpired(shareInfo);
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "tprfc.function_case_num, tprfc.id desc");
return PageUtils.setPageInfo(page, testPlanReportService.listReportDetailFunctionalCases(request, reportId));
return PageUtils.setPageInfo(page, testPlanReportService.listReportDetailFunctionalCases(request));
}
}

View File

@ -0,0 +1,15 @@
package io.metersphere.plan.dto.request;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class TestPlanShareReportDetailRequest extends TestPlanReportDetailPageRequest{
@Schema(description = "分享ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{test_plan.report.share_id.not_blank}")
private String shareId;
}

View File

@ -4,12 +4,13 @@
<select id="getPlanExecuteCases" resultType="io.metersphere.plan.domain.TestPlanReportFunctionCase">
select tpfc.id as testPlanFunctionCaseId, fc.id as functionCaseId, fc.num as functionCaseNum, fc.name as functionCaseName,
fcm.name as functionCaseModule, tpfc.execute_user as functionCaseExecuteUser,
if(fc.module_id = 'root','未规划用例', fcm.name) as functionCaseModule, tpfc.execute_user as functionCaseExecuteUser,
count(brc.id) as functionCaseBugCount, ifnull(tpfc.last_exec_result, 'PENDING') as functionCaseExecuteResult
from test_plan_functional_case tpfc join functional_case fc on tpfc.functional_case_id = fc.id
left join functional_case_module fcm on fcm.id = fc.module_id
left join bug_relation_case brc on brc.test_plan_case_id = tpfc.id
where tpfc.test_plan_id = #{id}
group by tpfc.id
</select>
<select id="getCasePriorityByIds" resultType="io.metersphere.plugin.platform.dto.SelectOption">

View File

@ -20,7 +20,6 @@ import io.metersphere.sdk.util.DateUtils;
import io.metersphere.sdk.util.SubListUtils;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.domain.User;
import io.metersphere.system.dto.sdk.BasePageRequest;
import io.metersphere.system.mapper.UserMapper;
import io.metersphere.system.notice.constants.NoticeConstants;
import io.metersphere.system.service.UserService;
@ -369,11 +368,8 @@ public class TestPlanReportService {
* @param request 请求参数
* @return 缺陷分页数据
*/
public List<BugDTO> listReportDetailBugs(BasePageRequest request, String reportId) {
TestPlanReportDetailPageRequest reportRequest = new TestPlanReportDetailPageRequest();
BeanUtils.copyBean(reportRequest, request);
reportRequest.setReportId(reportId);
return extTestPlanReportBugMapper.list(reportRequest);
public List<BugDTO> listReportDetailBugs(TestPlanReportDetailPageRequest request) {
return extTestPlanReportBugMapper.list(request);
}
/**
@ -381,11 +377,8 @@ public class TestPlanReportService {
* @param request 请求参数
* @return 缺陷分页数据
*/
public List<ReportDetailCasePageDTO> listReportDetailFunctionalCases(BasePageRequest request, String reportId) {
TestPlanReportDetailPageRequest reportRequest = new TestPlanReportDetailPageRequest();
BeanUtils.copyBean(reportRequest, request);
reportRequest.setReportId(reportId);
return extTestPlanReportFunctionalCaseMapper.list(reportRequest);
public List<ReportDetailCasePageDTO> listReportDetailFunctionalCases(TestPlanReportDetailPageRequest request) {
return extTestPlanReportFunctionalCaseMapper.list(request);
}

View File

@ -2,29 +2,11 @@
{
"id": "TEST_PLAN",
"name": "permission.test_plan.name",
"type": "TEST_PLAN",
"type": "PROJECT",
"children": [
{
"id": "TEST_PLAN_MODULE",
"name": "permission.test_plan_module.name",
"permissions": [
{
"id": "PROJECT_TEST_PLAN_MODULE:READ"
},
{
"id": "PROJECT_TEST_PLAN_MODULE:READ+ADD"
},
{
"id": "PROJECT_TEST_PLAN_MODULE:READ+UPDATE"
},
{
"id": "PROJECT_TEST_PLAN_MODULE:READ+DELETE"
}
]
},
{
"id": "TEST_PLAN",
"name": "permission.test_plan.name",
"id": "PROJECT_TEST_PLAN",
"name": "permission.test_plan",
"permissions": [
{
"id": "PROJECT_TEST_PLAN:READ"
@ -39,12 +21,32 @@
"id": "PROJECT_TEST_PLAN:READ+DELETE"
},
{
"id": "PROJECT_TEST_PLAN:READ+ASSOCIATION"
"id": "PROJECT_TEST_PLAN:READ+ASSOCIATION",
"name": "permission.association"
},
{
"id": "PROJECT_TEST_PLAN:READ+EXECUTE"
}
]
},
{
"id": "PROJECT_TEST_PLAN_REPORT",
"name": "permission.test_plan_report",
"permissions": [
{
"id": "PROJECT_TEST_PLAN_REPORT:READ"
},
{
"id": "PROJECT_TEST_PLAN_REPORT:READ+UPDATE"
},
{
"id": "PROJECT_TEST_PLAN_REPORT:READ+SHARE",
"name": "permission.api_doc.share"
},
{
"id": "PROJECT_TEST_PLAN_REPORT:READ+DELETE"
}
]
}
]
}

View File

@ -18,7 +18,6 @@ import io.metersphere.sdk.util.CommonBeanFactory;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.base.BaseTest;
import io.metersphere.system.controller.handler.ResultHolder;
import io.metersphere.system.dto.sdk.BasePageRequest;
import io.metersphere.system.utils.Pager;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
@ -55,7 +54,7 @@ public class TestPlanReportControllerTests extends BaseTest {
private static final String GEN_AND_SHARE = "/test-plan/report/share/gen";
private static final String GET_SHARE_INFO = "/test-plan/report/share/get";
private static final String GET_SHARE_TIME = "/test-plan/report/share/get-share-time";
private static final String GET_SHARE_REPORT = "/test-plan/report/share/get";
private static final String GET_SHARE_REPORT = "/test-plan/report/share/get/detail";
private static final String GET_SHARE_REPORT_BUG_LIST = "/test-plan/report/share/detail/bug/page";
private static final String GET_SHARE_REPORT_FUNCTIONAL_LIST = "/test-plan/report/share/detail/functional/case/page";
@ -172,15 +171,17 @@ public class TestPlanReportControllerTests extends BaseTest {
@Test
@Order(8)
void testGetShareReportTableList() throws Exception{
BasePageRequest request = new BasePageRequest();
TestPlanShareReportDetailRequest request = new TestPlanShareReportDetailRequest();
request.setCurrent(1);
request.setPageSize(10);
request.setReportId("test-plan-report-id-1");
request.setShareId(GEN_SHARE_ID);
// 获取分享的报告的列表明细
this.requestPostWithOk(GET_SHARE_REPORT_BUG_LIST + "/" + GEN_SHARE_ID + "/test-plan-report-id-1", request);
this.requestPostWithOk(GET_SHARE_REPORT_FUNCTIONAL_LIST + "/" + GEN_SHARE_ID + "/test-plan-report-id-1", request);
this.requestPostWithOk(GET_SHARE_REPORT_BUG_LIST, request);
this.requestPostWithOk(GET_SHARE_REPORT_FUNCTIONAL_LIST, request);
request.setSort(Map.of("num", "asc"));
this.requestPostWithOk(GET_SHARE_REPORT_BUG_LIST + "/" + GEN_SHARE_ID + "/test-plan-report-id-1", request);
this.requestPostWithOk(GET_SHARE_REPORT_FUNCTIONAL_LIST + "/" + GEN_SHARE_ID + "/test-plan-report-id-1", request);
this.requestPostWithOk(GET_SHARE_REPORT_BUG_LIST, request);
this.requestPostWithOk(GET_SHARE_REPORT_FUNCTIONAL_LIST, request);
}
@Test
@ -262,23 +263,25 @@ public class TestPlanReportControllerTests extends BaseTest {
@Test
@Order(15)
void testPageReportDetailBugSuccess() throws Exception {
BasePageRequest request = new BasePageRequest();
TestPlanReportDetailPageRequest request = new TestPlanReportDetailPageRequest();
request.setCurrent(1);
request.setPageSize(10);
this.requestPostWithOk(GET_PLAN_REPORT_DETAIL_BUG_PAGE + "/" + GEN_REPORT_ID, request);
request.setReportId(GEN_REPORT_ID);
this.requestPostWithOk(GET_PLAN_REPORT_DETAIL_BUG_PAGE, request);
request.setSort(Map.of("num", "asc"));
this.requestPostWithOk(GET_PLAN_REPORT_DETAIL_BUG_PAGE + "/" + GEN_REPORT_ID, request);
this.requestPostWithOk(GET_PLAN_REPORT_DETAIL_BUG_PAGE, request);
}
@Test
@Order(16)
void testPageReportDetailFunctionalCaseSuccess() throws Exception {
BasePageRequest request = new BasePageRequest();
TestPlanReportDetailPageRequest request = new TestPlanReportDetailPageRequest();
request.setCurrent(1);
request.setPageSize(10);
this.requestPostWithOk(GET_PLAN_REPORT_DETAIL_FUNCTIONAL_PAGE + "/" + GEN_REPORT_ID, request);
request.setReportId(GEN_REPORT_ID);
this.requestPostWithOk(GET_PLAN_REPORT_DETAIL_FUNCTIONAL_PAGE, request);
request.setSort(Map.of("num", "asc"));
this.requestPostWithOk(GET_PLAN_REPORT_DETAIL_FUNCTIONAL_PAGE + "/" + GEN_REPORT_ID, request);
this.requestPostWithOk(GET_PLAN_REPORT_DETAIL_FUNCTIONAL_PAGE, request);
}
@Test

View File

@ -206,7 +206,7 @@ public class TestPlanTests extends BaseTest {
Assertions.assertTrue(JSON.parseArray(JSON.toJSONString(result.getList())).size() <= testPlanTableRequest.getPageSize());
//判断权限
this.requestGetPermissionTest(PermissionConstants.TEST_PLAN_MODULE_READ, String.format(URL_GET_MODULE_TREE, DEFAULT_PROJECT_ID));
this.requestGetPermissionTest(PermissionConstants.TEST_PLAN_READ, String.format(URL_GET_MODULE_TREE, DEFAULT_PROJECT_ID));
testPlanTableRequest.setProjectId(DEFAULT_PROJECT_ID);
this.requestPostPermissionTest(PermissionConstants.TEST_PLAN_READ, URL_POST_TEST_PLAN_PAGE, testPlanTableRequest);
}
@ -439,7 +439,7 @@ public class TestPlanTests extends BaseTest {
this.requestPost(URL_POST_MODULE_ADD, request).andExpect(status().is5xxServerError());
//判断权限
this.requestPostPermissionTest(PermissionConstants.TEST_PLAN_MODULE_READ_ADD, URL_POST_MODULE_ADD, request);
this.requestPostPermissionTest(PermissionConstants.TEST_PLAN_READ_ADD, URL_POST_MODULE_ADD, request);
}
@Test
@ -496,7 +496,7 @@ public class TestPlanTests extends BaseTest {
this.requestPost(URL_POST_MODULE_UPDATE, updateRequest).andExpect(status().is5xxServerError());
//判断权限
this.requestPostPermissionTest(PermissionConstants.TEST_PLAN_MODULE_READ_UPDATE, URL_POST_MODULE_UPDATE, updateRequest);
this.requestPostPermissionTest(PermissionConstants.TEST_PLAN_READ_UPDATE, URL_POST_MODULE_UPDATE, updateRequest);
}
@Resource
@ -1387,7 +1387,7 @@ public class TestPlanTests extends BaseTest {
);
//判断权限
this.requestPostPermissionTest(PermissionConstants.TEST_PLAN_MODULE_READ_UPDATE, URL_POST_MODULE_MOVE, request);
this.requestPostPermissionTest(PermissionConstants.TEST_PLAN_READ_UPDATE, URL_POST_MODULE_MOVE, request);
}
@Test
@ -1522,7 +1522,7 @@ public class TestPlanTests extends BaseTest {
testPlanModuleService.deleteModule(new ArrayList<>(), project.getId(), null, null, null);
//判断权限
this.requestGetPermissionTest(PermissionConstants.TEST_PLAN_MODULE_READ_DELETE, (String.format(URL_GET_MODULE_DELETE, IDGenerator.nextNum())));
this.requestGetPermissionTest(PermissionConstants.TEST_PLAN_READ_DELETE, (String.format(URL_GET_MODULE_DELETE, IDGenerator.nextNum())));
//删除当前项目下的所有测试计划相关的数据
CleanupPlanResourceService cleanupPlanResourceService = CommonBeanFactory.getBean(CleanupPlanResourceService.class);

View File

@ -103,6 +103,9 @@
<template #status="{ record }">
<MsStatusTag :status="record.status" />
</template>
<template #createUserName="{ record }">
<span type="text" class="px-0">{{ record.createUserName || '-' }}</span>
</template>
<template #moduleId="{ record }">
<a-tooltip :content="getModules(record.moduleId, props.moduleTree)" position="top">
<span class="one-line-text inline-block">
@ -298,7 +301,6 @@
import { characterLimit } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import type { TableQueryParams } from '@/models/common';
import { ModuleTreeNode } from '@/models/common';
import type { PassRateCountDetail, planStatusType, TestPlanItem } from '@/models/testPlan/testPlan';
import { TestPlanRouteEnum } from '@/enums/routeEnum';
@ -374,7 +376,7 @@
{
title: 'common.creator',
slotName: 'createUser',
dataIndex: 'createUser',
dataIndex: 'createUserName',
showInTable: true,
width: 200,
showDrag: true,