feat(测试计划): 测试计划详情用例批量创建缺陷
This commit is contained in:
parent
bd4d0f02e9
commit
6294eb6f47
|
@ -2,6 +2,9 @@ package io.metersphere.plan.controller;
|
|||
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import io.metersphere.bug.domain.Bug;
|
||||
import io.metersphere.bug.dto.request.BugEditRequest;
|
||||
import io.metersphere.bug.service.BugService;
|
||||
import io.metersphere.dto.BugProviderDTO;
|
||||
import io.metersphere.plan.constants.TestPlanResourceConfig;
|
||||
import io.metersphere.plan.dto.request.*;
|
||||
|
@ -14,6 +17,7 @@ import io.metersphere.request.AssociateBugPageRequest;
|
|||
import io.metersphere.request.BugPageProviderRequest;
|
||||
import io.metersphere.sdk.constants.HttpMethodConstants;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.system.dto.LogInsertModule;
|
||||
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
||||
import io.metersphere.system.dto.user.UserDTO;
|
||||
|
@ -32,6 +36,7 @@ import org.apache.shiro.authz.annotation.Logical;
|
|||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -48,6 +53,8 @@ public class TestPlanFunctionalCaseController {
|
|||
private TestPlanManagementService testPlanManagementService;
|
||||
@Resource
|
||||
private TestPlanFunctionalCaseService testPlanFunctionalCaseService;
|
||||
@Resource
|
||||
private BugService bugService;
|
||||
|
||||
@PostMapping(value = "/sort")
|
||||
@Operation(summary = "测试计划功能用例-功能用例拖拽排序")
|
||||
|
@ -201,4 +208,19 @@ public class TestPlanFunctionalCaseController {
|
|||
public void batchMove(@Validated @RequestBody BaseBatchMoveRequest request) {
|
||||
testPlanFunctionalCaseService.batchMove(request);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/batch/add-bug")
|
||||
@Operation(summary = "测试计划-计划详情-功能用例-批量添加缺陷")
|
||||
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE)
|
||||
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
||||
public void batchAddBug(@Validated @RequestPart("request") TestPlanCaseBatchAddBugRequest request,
|
||||
@RequestPart(value = "files", required = false) List<MultipartFile> files) {
|
||||
BugEditRequest bugEditRequest = new BugEditRequest();
|
||||
BeanUtils.copyBean(bugEditRequest, request);
|
||||
Bug bug = bugService.addOrUpdate(bugEditRequest, files, SessionUtils.getUserId(), SessionUtils.getCurrentOrganizationId(), false);
|
||||
testPlanFunctionalCaseService.batchAssociateBug(request, bug.getId(), SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
package io.metersphere.plan.dto.request;
|
||||
|
||||
import io.metersphere.bug.dto.response.BugCustomFieldDTO;
|
||||
import io.metersphere.bug.dto.response.BugFileDTO;
|
||||
import io.metersphere.validation.groups.Created;
|
||||
import io.metersphere.validation.groups.Updated;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* @author wx
|
||||
*/
|
||||
@Data
|
||||
public class TestPlanCaseBatchAddBugRequest extends BasePlanCaseBatchRequest {
|
||||
|
||||
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{bug.id.not_blank}", groups = {Updated.class})
|
||||
@Size(min = 1, max = 50, message = "{bug.id.length_range}", groups = {Created.class, Updated.class})
|
||||
private String id;
|
||||
|
||||
@Schema(description = "缺陷标题")
|
||||
@Size(min = 1, max = 255, message = "{bug.title.length_range}", groups = {Created.class, Updated.class})
|
||||
private String title;
|
||||
|
||||
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{bug.project_id.not_blank}", groups = {Created.class, Updated.class})
|
||||
@Size(min = 1, max = 50, message = "{bug.project_id.length_range}", groups = {Created.class, Updated.class})
|
||||
private String projectId;
|
||||
|
||||
@Schema(description = "模板ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{bug.template_id.not_blank}", groups = {Created.class, Updated.class})
|
||||
@Size(min = 1, max = 50, message = "{bug.template_id.length_range}", groups = {Created.class, Updated.class})
|
||||
private String templateId;
|
||||
|
||||
@Schema(description = "标签")
|
||||
private List<String> tags;
|
||||
|
||||
@Schema(description = "缺陷内容")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "自定义字段集合")
|
||||
private List<BugCustomFieldDTO> customFields;
|
||||
|
||||
@Schema(description = "删除的本地附件集合, {文件ID")
|
||||
private List<String> deleteLocalFileIds;
|
||||
|
||||
@Schema(description = "取消关联附件关系ID集合, 关联关系ID")
|
||||
private List<String> unLinkRefIds;
|
||||
|
||||
@Schema(description = "关联附件集合, 文件ID")
|
||||
private List<String> linkFileIds;
|
||||
|
||||
@Schema(description = "复制的附件")
|
||||
private List<BugFileDTO> copyFiles;
|
||||
|
||||
@Schema(description = "富文本临时文件ID")
|
||||
private List<String> richTextTmpFileIds;
|
||||
}
|
|
@ -723,7 +723,7 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService {
|
|||
|
||||
public TestPlanCaseDetailResponse getFunctionalCaseDetail(String id, String userId) {
|
||||
TestPlanFunctionalCase planFunctionalCase = testPlanFunctionalCaseMapper.selectByPrimaryKey(id);
|
||||
if(planFunctionalCase == null){
|
||||
if (planFunctionalCase == null) {
|
||||
throw new MSException(Translator.get("resource_not_exist"));
|
||||
}
|
||||
String caseId = planFunctionalCase.getFunctionalCaseId();
|
||||
|
@ -996,6 +996,7 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService {
|
|||
|
||||
/**
|
||||
* 处理执行人为空过滤参数
|
||||
*
|
||||
* @param request 请求参数
|
||||
*/
|
||||
protected void filterCaseRequest(TestPlanCaseRequest request) {
|
||||
|
@ -1008,4 +1009,29 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void batchAssociateBug(TestPlanCaseBatchAddBugRequest request, String bugId, String userId) {
|
||||
List<String> ids = doSelectIds(request);
|
||||
if (CollectionUtils.isNotEmpty(ids)) {
|
||||
TestPlanFunctionalCaseExample example = new TestPlanFunctionalCaseExample();
|
||||
example.createCriteria().andIdIn(ids);
|
||||
List<TestPlanFunctionalCase> caseList = testPlanFunctionalCaseMapper.selectByExample(example);
|
||||
Map<String, String> caseMap = caseList.stream().collect(Collectors.toMap(TestPlanFunctionalCase::getId, TestPlanFunctionalCase::getFunctionalCaseId));
|
||||
List<BugRelationCase> list = new ArrayList<>();
|
||||
ids.forEach(id -> {
|
||||
BugRelationCase bugRelationCase = new BugRelationCase();
|
||||
bugRelationCase.setId(IDGenerator.nextStr());
|
||||
bugRelationCase.setBugId(bugId);
|
||||
bugRelationCase.setCaseId(caseMap.get(id));
|
||||
bugRelationCase.setCaseType(CaseType.FUNCTIONAL_CASE.getKey());
|
||||
bugRelationCase.setCreateUser(userId);
|
||||
bugRelationCase.setCreateTime(System.currentTimeMillis());
|
||||
bugRelationCase.setUpdateTime(System.currentTimeMillis());
|
||||
bugRelationCase.setTestPlanCaseId(id);
|
||||
bugRelationCase.setTestPlanId(request.getTestPlanId());
|
||||
list.add(bugRelationCase);
|
||||
});
|
||||
bugRelationCaseMapper.batchInsert(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.metersphere.plan.controller;
|
|||
|
||||
import io.metersphere.bug.domain.BugRelationCase;
|
||||
import io.metersphere.bug.domain.BugRelationCaseExample;
|
||||
import io.metersphere.bug.dto.response.BugCustomFieldDTO;
|
||||
import io.metersphere.bug.mapper.BugRelationCaseMapper;
|
||||
import io.metersphere.dto.BugProviderDTO;
|
||||
import io.metersphere.functional.domain.FunctionalCaseBlob;
|
||||
|
@ -33,9 +34,11 @@ import org.junit.jupiter.api.*;
|
|||
import org.mockito.Mockito;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
import org.springframework.test.context.jdbc.SqlConfig;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
@ -63,6 +66,7 @@ public class TestPlanCaseControllerTests extends BaseTest {
|
|||
public static final String FUNCTIONAL_CASE_EXEC_HISTORY_URL = "/test-plan/functional/case/exec/history";
|
||||
public static final String USER_URL = "/test-plan/functional/case/user-option/";
|
||||
public static final String FUNCTIONAL_CASE_BATCH_MOVE_URL = "/test-plan/functional/case/batch/move";
|
||||
public static final String FUNCTIONAL_CASE_BATCH_ADD_BUG_URL = "/test-plan/functional/case/batch/add-bug";
|
||||
@Resource
|
||||
private TestPlanFunctionalCaseMapper testPlanFunctionalCaseMapper;
|
||||
@Resource
|
||||
|
@ -284,7 +288,7 @@ public class TestPlanCaseControllerTests extends BaseTest {
|
|||
functionalCaseStepDTO.setNum(1);
|
||||
functionalCaseStepDTO.setDesc("步骤描述");
|
||||
functionalCaseStepDTO.setResult("结果");
|
||||
List<FunctionalCaseStepDTO>list = new ArrayList<>();
|
||||
List<FunctionalCaseStepDTO> list = new ArrayList<>();
|
||||
list.add(functionalCaseStepDTO);
|
||||
testPlanCaseExecuteHistory.setSteps(JSON.toJSONString(list).getBytes());
|
||||
testPlanCaseExecuteHistoryMapper.updateByPrimaryKeySelective(testPlanCaseExecuteHistory);
|
||||
|
@ -438,4 +442,53 @@ public class TestPlanCaseControllerTests extends BaseTest {
|
|||
this.requestPostWithOk(FUNCTIONAL_CASE_BATCH_MOVE_URL, request);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(19)
|
||||
public void testBatchAddBug() throws Exception {
|
||||
TestPlanCaseBatchAddBugRequest request = buildRequest(false);
|
||||
List<MockMultipartFile> files = new ArrayList<>();
|
||||
LinkedMultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>();
|
||||
paramMap.add("request", JSON.toJSONString(request));
|
||||
paramMap.add("files", files);
|
||||
this.requestMultipartWithOkAndReturn(FUNCTIONAL_CASE_BATCH_ADD_BUG_URL, paramMap);
|
||||
|
||||
request.setSelectAll(true);
|
||||
paramMap = new LinkedMultiValueMap<>();
|
||||
paramMap.add("request", JSON.toJSONString(request));
|
||||
paramMap.add("files", files);
|
||||
this.requestMultipartWithOkAndReturn(FUNCTIONAL_CASE_BATCH_ADD_BUG_URL, paramMap);
|
||||
}
|
||||
|
||||
private TestPlanCaseBatchAddBugRequest buildRequest(boolean isUpdate) {
|
||||
TestPlanCaseBatchAddBugRequest request = new TestPlanCaseBatchAddBugRequest();
|
||||
request.setTestPlanId("plan_1");
|
||||
request.setProjectId("123");
|
||||
request.setTitle("default-bug-title");
|
||||
request.setDescription("default-bug-description");
|
||||
request.setTemplateId("default-bug-template");
|
||||
request.setLinkFileIds(List.of("default-bug-file-id-1"));
|
||||
if (isUpdate) {
|
||||
request.setId("default-bug-id");
|
||||
request.setUnLinkRefIds(List.of("default-file-association-id"));
|
||||
request.setDeleteLocalFileIds(List.of("default-bug-file-id"));
|
||||
request.setLinkFileIds(List.of("default-bug-file-id-2"));
|
||||
}
|
||||
BugCustomFieldDTO fieldDTO1 = new BugCustomFieldDTO();
|
||||
fieldDTO1.setId("custom-field");
|
||||
fieldDTO1.setName("oasis");
|
||||
BugCustomFieldDTO fieldDTO2 = new BugCustomFieldDTO();
|
||||
fieldDTO2.setId("test_field");
|
||||
fieldDTO2.setName(JSON.toJSONString(List.of("test")));
|
||||
BugCustomFieldDTO handleUserField = new BugCustomFieldDTO();
|
||||
handleUserField.setId("handleUser");
|
||||
handleUserField.setName("处理人");
|
||||
handleUserField.setValue("admin");
|
||||
BugCustomFieldDTO statusField = new BugCustomFieldDTO();
|
||||
statusField.setId("status");
|
||||
statusField.setName("状态");
|
||||
statusField.setValue("1");
|
||||
request.setCustomFields(List.of(fieldDTO1, fieldDTO2, handleUserField, statusField));
|
||||
return request;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -74,3 +74,21 @@ VALUES
|
|||
|
||||
INSERT INTO `test_plan_config`(`test_plan_id`, `automatic_status_update`, `repeat_case`, `pass_threshold`, `case_run_mode`)
|
||||
VALUES ('plan_1', b'0', b'0', 100.00, 'PARALLEL');
|
||||
|
||||
|
||||
INSERT INTO project_application (project_id, type, type_value) VALUES
|
||||
('123', 'BUG_DEFAULT_TEMPLATE', 'default-bug-template-id'),
|
||||
('123', 'BUG_SYNC_BUG_PLATFORM_CONFIG', '{"jiraKey":"TES","jiraBugTypeId":"10009"}'),
|
||||
('123', 'BUG_SYNC_CRON_EXPRESSION', '0 0 0/1 * * ?'),
|
||||
('123', 'BUG_SYNC_MECHANISM', 'increment'),
|
||||
('123', 'BUG_SYNC_PLATFORM_KEY', 'jira'),
|
||||
('123-integration', 'BUG_SYNC_PLATFORM_KEY', 'jira'),
|
||||
('123', 'BUG_SYNC_SYNC_ENABLE', 'true'),
|
||||
('123', 'CASE_RELATED_CASE_ENABLE', 'false'),
|
||||
('123', 'CASE_RELATED_DEMAND_PLATFORM_CONFIG', '{"jiraKey":"TES","jiraDemandTypeId":"10007"}'),
|
||||
('123', 'CASE_RELATED_PLATFORM_KEY', 'jira');
|
||||
|
||||
|
||||
INSERT INTO service_integration(`id`, `plugin_id`, `enable`, `configuration`, `organization_id`) VALUES
|
||||
('621103810617343', 'jira', true, 0x504B0304140008080800BC517657000000000000000000000000030000007A6970258DC10EC2201044FF65CF06D2C498D89347B5574FBD6D8158222CD85D6268E3BF4BE3F5CDBC990DD0DAC531430FB348E65EEBE06B41AAA9289480CC1E4991130D07C022F3A366D7DA13B2373B32261592469AF1572FCF883E289362CB735BF8A4C5EE073474C3CB8E59A6F85EEFF12AE676EC4E67F8FE00504B0708384DA4307800000087000000504B01021400140008080800BC517657384DA43078000000870000000300000000000000000000000000000000007A6970504B0506000000000100010031000000A90000000000, '1'),
|
||||
('652096294625284', 'zentao', true, 0x504B030414000808080093756458000000000000000000000000030000007A6970AB564A4C49294A2D2E56B252CA282929B0D2D7373437D23334D3333230D033B3B4B230B0B050D2514A4C4ECE2FCD2B01AA4A4CC9CDCC038A1424161797E717A500859C1373F2F3D21D8C0C0C4D811245A985A5A9C525219505A940B900C7108F784F3F377FA55A00504B07088A813510680000006C000000504B01021400140008080800937564588A813510680000006C0000000300000000000000000000000000000000007A6970504B0506000000000100010031000000990000000000, '1');
|
||||
|
|
Loading…
Reference in New Issue