feat(用例管理): 脑图新增批量删除和拖拽接口

This commit is contained in:
guoyuqi 2024-05-08 18:30:43 +08:00 committed by Craftsman
parent 48b3b44ee5
commit f1411f87ca
23 changed files with 828 additions and 123 deletions

View File

@ -22,6 +22,7 @@ functional_case.project_id.length_range=项目ID长度必须在1-50之间
functional_case.project_id.not_blank=项目ID不能为空
functional_case.name.length_range=名称长度必须在1-255之间
functional_case.name.not_blank=名称不能为空
functional_case.pos.not_blank=顺序不能为空
functional_case.review_status.length_range=评审状态长度必须在1-64之间
functional_case.review_status.not_blank=评审状态不能为空
functional_case.step_model.length_range=编辑模式长度必须在1-64之间

View File

@ -23,6 +23,7 @@ functional_case.project_id.not_blank=Project ID cannot be empty
functional_case.template_id.not_blank=Template ID cannot be empty
functional_case.name.length_range=The name length must be between 1 and 255
functional_case.name.not_blank=Name cannot be empty
functional_case.pos.not_blank=Pos cannot be empty
functional_case.review_status.length_range=The length of the review status must be between 1 and 64
functional_case.review_status.not_blank=Review status cannot be empty
functional_case.case_edit_type.length_range=The length of the editing type must be between 1 and 64

View File

@ -22,6 +22,7 @@ functional_case.project_id.not_blank=项目ID不能为空
functional_case.template_id.not_blank=模板ID不能为空
functional_case.name.length_range=名称长度必须在1-255之间
functional_case.name.not_blank=名称不能为空
functional_case.pos.not_blank=顺序不能为空
functional_case.review_status.length_range=评审状态长度必须在1-64之间
functional_case.review_status.not_blank=评审状态不能为空
functional_case.case_edit_type.length_range=编辑模式长度必须在1-64之间

View File

@ -23,6 +23,7 @@ functional_case.project_id.not_blank=項目ID不能為空
functional_case.template_id.not_blank=模板ID不能為空
functional_case.name.length_range=名稱長度必須在1-255之間
functional_case.name.not_blank=名稱不能為空
functional_case.pos.not_blank=順序不能為空
functional_case.review_status.length_range=評審狀態長度必須在1-64之間
functional_case.review_status.not_blank=評審狀態不能為空
functional_case.case_edit_type.length_range=編輯模式長度必須在1-64之間

View File

@ -18,15 +18,18 @@ public enum MinderLabel {
* 步骤描述标签
*/
STEPS,
/**
* 步骤描述预期结果标签
*/
STEPS_EXPECTED_RESULT,
/**
* 文本描述标签
*/
TEXT_DESCRIPTION,
/**
* 预期结果标签
* 文本描述预期结果标签
*/
EXPECTED_RESULT,
TEXT_EXPECTED_RESULT,
/**
* 备注标签
*/

View File

@ -1,9 +1,10 @@
package io.metersphere.functional.controller;
import io.metersphere.functional.domain.FunctionalCase;
import io.metersphere.functional.dto.FunctionalMinderTreeDTO;
import io.metersphere.functional.dto.MinderOptionDTO;
import io.metersphere.functional.request.FunctionalCaseMindRequest;
import io.metersphere.functional.request.FunctionalCaseMinderEditRequest;
import io.metersphere.functional.request.FunctionalCaseMinderRemoveRequest;
import io.metersphere.functional.service.FunctionalCaseLogService;
import io.metersphere.functional.service.FunctionalCaseMinderService;
import io.metersphere.functional.service.FunctionalCaseNoticeService;
@ -15,6 +16,7 @@ import io.metersphere.system.notice.constants.NoticeConstants;
import io.metersphere.system.security.CheckOwner;
import io.metersphere.system.utils.SessionUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.apache.shiro.authz.annotation.RequiresPermissions;
@ -48,20 +50,37 @@ public class FunctionalCaseMinderController {
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateMinderFunctionalCaseLog(#request)", msClass = FunctionalCaseLogService.class)
@SendNotice(taskType = NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, event = NoticeConstants.Event.UPDATE, target = "#targetClass.getMainFunctionalCaseMinderDTO(#request)", targetClass = FunctionalCaseNoticeService.class)
@CheckOwner(resourceId = "#request.getId()", resourceType = "functional_case")
public FunctionalCase updateFunctionalCaseName(@Validated @RequestBody FunctionalCaseMinderEditRequest request) {
public void updateFunctionalCaseName(@Validated @RequestBody FunctionalCaseMinderEditRequest request) {
String userId = SessionUtils.getUserId();
return functionalCaseMinderService.updateFunctionalCase(request, userId);
functionalCaseMinderService.updateFunctionalCase(request, userId);
}
@PostMapping("/update/source/priority")
@Operation(summary = "脑图更新资源名称")
@Operation(summary = "脑图更新用例等级")
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE)
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateMinderFunctionalCaseLog(#request)", msClass = FunctionalCaseLogService.class)
@SendNotice(taskType = NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, event = NoticeConstants.Event.UPDATE, target = "#targetClass.getMainFunctionalCaseMinderDTO(#request)", targetClass = FunctionalCaseNoticeService.class)
@CheckOwner(resourceId = "#request.getId()", resourceType = "functional_case")
public FunctionalCase updateFunctionalCasePriority(@Validated @RequestBody FunctionalCaseMinderEditRequest request) {
public void updateFunctionalCasePriority(@Validated @RequestBody FunctionalCaseMinderEditRequest request) {
String userId = SessionUtils.getUserId();
return functionalCaseMinderService.updateFunctionalCase(request, userId);
functionalCaseMinderService.updateFunctionalCase(request, userId);
}
@PostMapping("/batch/remove")
@Operation(summary = "脑图批量移动(移动到某个节点下或者移动排序)")
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE)
public void removeFunctionalCaseBatch(@Validated @RequestBody FunctionalCaseMinderRemoveRequest request) {
String userId = SessionUtils.getUserId();
functionalCaseMinderService.removeFunctionalCaseBatch(request, userId);
}
@PostMapping("/batch/delete/{projectId}")
@Operation(summary = "脑图批量删除")
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ_DELETE)
@Log(type = OperationLogType.DELETE, expression = "#msClass.deleteBatchMinderFunctionalCaseLog(#resourceList)", msClass = FunctionalCaseLogService.class)
public void deleteFunctionalCaseBatch(@PathVariable String projectId, @Validated @RequestBody @Schema(description = "节点和节点类型的集合", requiredMode = Schema.RequiredMode.REQUIRED) List<MinderOptionDTO> resourceList) {
String userId = SessionUtils.getUserId();
functionalCaseMinderService.deleteFunctionalCaseBatch(projectId, resourceList, userId);
}
}

View File

@ -50,6 +50,11 @@ public class FunctionalCaseMindDTO {
@NotNull(message = "{functional_case.pos.not_blank}", groups = {Created.class})
private Long pos;
@Schema(description = "编辑模式:步骤模式/文本模式", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{functional_case.case_edit_type.not_blank}", groups = {Created.class})
@Size(min = 1, max = 50, message = "{functional_case.case_edit_type.length_range}", groups = {Created.class, Updated.class})
private String caseEditType;
@Schema(description = "用例步骤JSON)step_model 为 Step 时启用")
private byte[] steps;

View File

@ -0,0 +1,28 @@
package io.metersphere.functional.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author guoyuqi
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MinderOptionDTO {
@Schema(description = "节点ID如果是用例的子节点比如 前置条件步骤描述等传其父节点ID")
@NotBlank(message = "{functional_case.id.not_blank}")
private String id;
@Schema(description = "节点类型")
@NotBlank(message = "{functional_case_test.test_type.not_blank}")
private String type;
@Schema(description = "节点顺序")
@NotBlank(message = "{functional_case.pos.not_blank}")
private Long pos;
}

View File

@ -0,0 +1,21 @@
package io.metersphere.functional.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author guoyuqi
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MinderTargetDTO {
@Schema(description = "移动排序的目标id", requiredMode = Schema.RequiredMode.REQUIRED)
private String targetId;
@Schema(description = "移动方式(BEFORE AFTER)", requiredMode = Schema.RequiredMode.REQUIRED)
private String moveMode;
}

View File

@ -0,0 +1,13 @@
package io.metersphere.functional.mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author guoyuqi
*/
public interface ExtFunctionalCaseBlobMapper {
void batchUpdateColumn(@Param("column") String column, @Param("ids") List<String> ids, @Param("value") byte[] value);
}

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.metersphere.functional.mapper.ExtFunctionalCaseBlobMapper">
<resultMap id="BaseResultMap" type="io.metersphere.functional.domain.FunctionalCaseBlob">
<id column="id" jdbcType="VARCHAR" property="id" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.functional.domain.FunctionalCaseBlob">
<result column="steps" jdbcType="LONGVARBINARY" property="steps" />
<result column="text_description" jdbcType="LONGVARBINARY" property="textDescription" />
<result column="expected_result" jdbcType="LONGVARBINARY" property="expectedResult" />
<result column="prerequisite" jdbcType="LONGVARBINARY" property="prerequisite" />
<result column="description" jdbcType="LONGVARBINARY" property="description" />
</resultMap>
<update id="batchUpdateColumn">
update functional_case_blob
set ${column} = #{value,jdbcType=LONGVARBINARY}
where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</update>
</mapper>

View File

@ -782,7 +782,7 @@
<select id="getMinderCaseList" resultType="io.metersphere.functional.dto.FunctionalCaseMindDTO">
SELECT
fc.id, fc.name, fc.project_id, fc.module_id, fc.template_id, fc.review_status, fc.pos,
fc.id, fc.name, fc.project_id, fc.module_id, fc.template_id, fc.review_status, fc.pos, fc.case_edit_type,
fcb.steps, fcb.text_description, fcb.expected_result, fcb.prerequisite, fcb.description, fccf.value as priority
FROM
functional_case fc

View File

@ -36,4 +36,6 @@ public interface ExtFunctionalCaseModuleMapper {
List<BaseTreeNode> selectApiScenarioModuleByRequest(@Param("request") AssociateCaseModuleRequest request);
List<String> selectIdByProjectIdAndReviewId(@Param("projectId")String projectId, @Param("reviewId")String reviewId);
void batchUpdateStringColumn(@Param("column") String column, @Param("ids") List<String> ids, @Param("value") String value);
}

View File

@ -127,4 +127,13 @@
</where>
</sql>
<update id="batchUpdateStringColumn">
update functional_case_module
set ${column} = #{value}
where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</update>
</mapper>

View File

@ -1,5 +1,6 @@
package io.metersphere.functional.request;
import io.metersphere.functional.constants.MinderLabel;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@ -10,7 +11,7 @@ import lombok.Data;
@Data
public class FunctionalCaseMinderEditRequest{
@Schema(description = "用例id", requiredMode = Schema.RequiredMode.REQUIRED)
@Schema(description = "用例id/模块ID其他类型比如前置给用例ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{functional_case.id.not_blank}")
private String id;
@ -18,16 +19,16 @@ public class FunctionalCaseMinderEditRequest{
@NotBlank(message = "{functional_case.project_id.not_blank}")
private String projectId;
@Schema(description = "资源名称")
@Schema(description = "资源名称(更新节点的名称包括前置的编辑)")
private String name;
@Schema(description = "用例等级")
@Schema(description = "步骤描述及其预期结果的排序(更新步骤描述时必填)")
private Long pos;
@Schema(description = "资源类型")
private MinderLabel type;
@Schema(description = "用例等级(只更新用例的等级时传)")
private String priority;
@Schema(description = "评审结果")
private String reviewStatus;
@Schema(description = "执行结果")
private String executeStatus;
}

View File

@ -0,0 +1,33 @@
package io.metersphere.functional.request;
import io.metersphere.functional.dto.MinderOptionDTO;
import io.metersphere.functional.dto.MinderTargetDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.util.List;
@Data
public class FunctionalCaseMinderRemoveRequest {
@Schema(description = "项目id", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{functional_case.project_id.not_blank}")
private String projectId;
@Schema(description = "成为移动节点的父节点的目标id", requiredMode = Schema.RequiredMode.REQUIRED)
private String parentTargetId;
@Schema(description = "成为移动节点拖拽目标的用例对象", requiredMode = Schema.RequiredMode.REQUIRED)
private MinderTargetDTO caseMinderTargetDTO;
@Schema(description = "成为移动节点拖拽目标的模块对象", requiredMode = Schema.RequiredMode.REQUIRED)
private MinderTargetDTO moduleMinderTargetDTO;
@Schema(description = "节点和节点类型的集合", requiredMode = Schema.RequiredMode.REQUIRED)
private List<MinderOptionDTO> resourceList;
@Schema(description = "如果是修改步骤描述的顺序将修改后的json赋值到这里")
private String steps;
}

View File

@ -4,6 +4,7 @@ import io.metersphere.bug.domain.Bug;
import io.metersphere.bug.domain.BugRelationCase;
import io.metersphere.bug.mapper.BugMapper;
import io.metersphere.bug.mapper.BugRelationCaseMapper;
import io.metersphere.functional.constants.MinderLabel;
import io.metersphere.functional.domain.*;
import io.metersphere.functional.dto.BaseFunctionalCaseBatchDTO;
import io.metersphere.functional.dto.FunctionalCaseHistoryLogDTO;
@ -17,6 +18,7 @@ import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.domain.CustomField;
import io.metersphere.system.domain.CustomFieldExample;
import io.metersphere.system.dto.sdk.OptionDTO;
import io.metersphere.system.log.constants.OperationLogModule;
import io.metersphere.system.log.constants.OperationLogType;
import io.metersphere.system.log.dto.LogDTO;
@ -31,6 +33,8 @@ import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author wx
@ -162,6 +166,10 @@ public class FunctionalCaseLogService {
public List<LogDTO> batchDeleteFunctionalCaseLog(FunctionalCaseBatchRequest request) {
List<String> ids = functionalCaseService.doSelectIds(request, request.getProjectId());
return batchDeleteFunctionalCaseLogByIds(ids);
}
public List<LogDTO> batchDeleteFunctionalCaseLogByIds(List<String> ids) {
List<LogDTO> dtoList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(ids)) {
List<FunctionalCase> functionalCases = extFunctionalCaseMapper.getLogInfo(ids, false);
@ -184,6 +192,19 @@ public class FunctionalCaseLogService {
return dtoList;
}
public List<LogDTO> deleteBatchMinderFunctionalCaseLog(List<OptionDTO> resourceList) {
if (CollectionUtils.isEmpty(resourceList)) {
return new ArrayList<>();
}
Map<String, List<OptionDTO>> resourceMap = resourceList.stream().collect(Collectors.groupingBy(OptionDTO::getName));
List<OptionDTO> caseOptionDTOS = resourceMap.get(MinderLabel.CASE.toString());
if (CollectionUtils.isEmpty(caseOptionDTOS)) {
return new ArrayList<>();
}
List<String> caseIds = caseOptionDTOS.stream().map(OptionDTO::getId).toList();
return batchDeleteFunctionalCaseLogByIds(caseIds);
}
/**
* 恢复项目
*
@ -416,6 +437,9 @@ public class FunctionalCaseLogService {
}
public LogDTO updateMinderFunctionalCaseLog(FunctionalCaseMinderEditRequest request) {
if (request.getType() == MinderLabel.MODULE) {
return null;
}
FunctionalCaseHistoryLogDTO historyLogDTO = getOriginalValue(request.getId());
LogDTO dto = getUpdateLogDTO(request.getProjectId(), request.getId(), request.getName(), "/functional/case/update");
dto.setOriginalValue(JSON.toJSONBytes(historyLogDTO));

View File

@ -1,30 +1,38 @@
package io.metersphere.functional.service;
import io.metersphere.functional.constants.FunctionalCaseTypeConstants;
import io.metersphere.functional.constants.MinderLabel;
import io.metersphere.functional.domain.FunctionalCase;
import io.metersphere.functional.domain.FunctionalCaseCustomField;
import io.metersphere.functional.dto.FunctionalCaseMindDTO;
import io.metersphere.functional.dto.FunctionalCaseStepDTO;
import io.metersphere.functional.dto.FunctionalMinderTreeDTO;
import io.metersphere.functional.dto.FunctionalMinderTreeNodeDTO;
import io.metersphere.functional.mapper.ExtFunctionalCaseMapper;
import io.metersphere.functional.mapper.FunctionalCaseCustomFieldMapper;
import io.metersphere.functional.mapper.FunctionalCaseMapper;
import io.metersphere.functional.domain.*;
import io.metersphere.functional.dto.*;
import io.metersphere.functional.mapper.*;
import io.metersphere.functional.request.FunctionalCaseBatchMoveRequest;
import io.metersphere.functional.request.FunctionalCaseMindRequest;
import io.metersphere.functional.request.FunctionalCaseMinderEditRequest;
import io.metersphere.functional.request.FunctionalCaseMinderRemoveRequest;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.domain.CustomField;
import io.metersphere.system.domain.CustomFieldExample;
import io.metersphere.system.dto.sdk.enums.MoveTypeEnum;
import io.metersphere.system.mapper.CustomFieldMapper;
import io.metersphere.system.mapper.ExtCheckOwnerMapper;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.jetbrains.annotations.NotNull;
import org.mybatis.spring.SqlSessionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 功能用例脑图
@ -35,11 +43,24 @@ import java.util.List;
@Transactional(rollbackFor = Exception.class)
public class FunctionalCaseMinderService {
@Resource
private FunctionalCaseMapper functionalCaseMapper;
@Resource
private ExtFunctionalCaseMapper extFunctionalCaseMapper;
@Resource
private FunctionalCaseMapper functionalCaseMapper;
private FunctionalCaseBlobMapper functionalCaseBlobMapper;
@Resource
private ExtFunctionalCaseBlobMapper extFunctionalCaseBlobMapper;
@Resource
private FunctionalCaseModuleMapper functionalCaseModuleMapper;
@Resource
private ExtFunctionalCaseModuleMapper extFunctionalCaseModuleMapper;
@Resource
private CustomFieldMapper customFieldMapper;
@ -47,6 +68,21 @@ public class FunctionalCaseMinderService {
@Resource
private FunctionalCaseCustomFieldMapper functionalCaseCustomFieldMapper;
@Resource
private ExtCheckOwnerMapper extCheckOwnerMapper;
@Resource
private FunctionalCaseService functionalCaseService;
@Resource
private FunctionalCaseModuleService functionalCaseModuleService;
@Resource
SqlSessionFactory sqlSessionFactory;
private static final String FUNCTIONAL_CASE = "functional_case";
private static final String FUNCTIONAL_CASE_MODULE = "functional_case_module";
private static final String CHECK_OWNER_CASE = "check_owner_case";
/**
* 功能用例-脑图用例列表查询
*
@ -77,38 +113,49 @@ public class FunctionalCaseMinderService {
private List<FunctionalMinderTreeDTO> buildChildren(FunctionalCaseMindDTO functionalCaseMindDTO) {
List<FunctionalMinderTreeDTO> children = new ArrayList<>();
if (functionalCaseMindDTO.getTextDescription() != null) {
String textDescription = new String(functionalCaseMindDTO.getTextDescription(), StandardCharsets.UTF_8);
FunctionalMinderTreeDTO stepFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(textDescription, MinderLabel.TEXT_DESCRIPTION.toString(), 0L);
if (functionalCaseMindDTO.getExpectedResult() != null) {
String expectedResultText = new String(functionalCaseMindDTO.getExpectedResult(), StandardCharsets.UTF_8);
FunctionalMinderTreeDTO expectedResultFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(expectedResultText, MinderLabel.EXPECTED_RESULT.toString(), 0L);
stepFunctionalMinderTreeDTO.getChildren().add(expectedResultFunctionalMinderTreeDTO);
}
children.add(stepFunctionalMinderTreeDTO);
}
if (functionalCaseMindDTO.getSteps() != null) {
String stepText = new String(functionalCaseMindDTO.getSteps(), StandardCharsets.UTF_8);
List<FunctionalCaseStepDTO> functionalCaseStepDTOS = JSON.parseArray(stepText, FunctionalCaseStepDTO.class);
for (FunctionalCaseStepDTO functionalCaseStepDTO : functionalCaseStepDTOS) {
FunctionalMinderTreeDTO stepFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(functionalCaseStepDTO.getDesc(), MinderLabel.STEPS.toString(), Long.valueOf(functionalCaseStepDTO.getNum()));
if (functionalCaseMindDTO.getExpectedResult() != null) {
FunctionalMinderTreeDTO expectedResultFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(functionalCaseStepDTO.getResult(), MinderLabel.EXPECTED_RESULT.toString(), 0L);
stepFunctionalMinderTreeDTO.getChildren().add(expectedResultFunctionalMinderTreeDTO);
}
children.add(stepFunctionalMinderTreeDTO);
}
}
if (functionalCaseMindDTO.getPrerequisite() != null) {
String prerequisiteText = new String(functionalCaseMindDTO.getPrerequisite(), StandardCharsets.UTF_8);
FunctionalMinderTreeDTO prerequisiteFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(prerequisiteText, MinderLabel.PREREQUISITE.toString(), 0L);
children.add(prerequisiteFunctionalMinderTreeDTO);
}
if (StringUtils.equalsIgnoreCase(functionalCaseMindDTO.getCaseEditType(), FunctionalCaseTypeConstants.CaseEditType.TEXT.name()) && functionalCaseMindDTO.getTextDescription() != null) {
String textDescription = new String(functionalCaseMindDTO.getTextDescription(), StandardCharsets.UTF_8);
FunctionalMinderTreeDTO stepFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(textDescription, MinderLabel.TEXT_DESCRIPTION.toString(), 1L);
if (functionalCaseMindDTO.getExpectedResult() != null) {
String expectedResultText = new String(functionalCaseMindDTO.getExpectedResult(), StandardCharsets.UTF_8);
FunctionalMinderTreeDTO expectedResultFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(expectedResultText, MinderLabel.TEXT_EXPECTED_RESULT.toString(), 1L);
stepFunctionalMinderTreeDTO.getChildren().add(expectedResultFunctionalMinderTreeDTO);
} else {
FunctionalMinderTreeDTO expectedResultFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO("", MinderLabel.TEXT_EXPECTED_RESULT.toString(), 1L);
stepFunctionalMinderTreeDTO.getChildren().add(expectedResultFunctionalMinderTreeDTO);
}
children.add(stepFunctionalMinderTreeDTO);
}
int i = 1;
if (StringUtils.equalsIgnoreCase(functionalCaseMindDTO.getCaseEditType(), FunctionalCaseTypeConstants.CaseEditType.STEP.name()) && functionalCaseMindDTO.getSteps() != null) {
String stepText = new String(functionalCaseMindDTO.getSteps(), StandardCharsets.UTF_8);
List<FunctionalCaseStepDTO> functionalCaseStepDTOS = JSON.parseArray(stepText, FunctionalCaseStepDTO.class);
for (FunctionalCaseStepDTO functionalCaseStepDTO : functionalCaseStepDTOS) {
i = i + 1;
FunctionalMinderTreeDTO stepFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(functionalCaseStepDTO.getDesc(), MinderLabel.STEPS.toString(), Long.valueOf(functionalCaseStepDTO.getNum()));
stepFunctionalMinderTreeDTO.getData().setId(functionalCaseStepDTO.getId());
FunctionalMinderTreeDTO expectedResultFunctionalMinderTreeDTO;
if (functionalCaseMindDTO.getExpectedResult() != null) {
expectedResultFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(functionalCaseStepDTO.getResult(), MinderLabel.STEPS_EXPECTED_RESULT.toString(), Long.valueOf(functionalCaseStepDTO.getNum()));
} else {
expectedResultFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO("", MinderLabel.STEPS_EXPECTED_RESULT.toString(), Long.valueOf(functionalCaseStepDTO.getNum()));
}
stepFunctionalMinderTreeDTO.getChildren().add(expectedResultFunctionalMinderTreeDTO);
children.add(stepFunctionalMinderTreeDTO);
}
}
if (functionalCaseMindDTO.getDescription() != null) {
String descriptionText = new String(functionalCaseMindDTO.getDescription(), StandardCharsets.UTF_8);
FunctionalMinderTreeDTO descriptionFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(descriptionText, MinderLabel.DESCRIPTION.toString(), 0L);
FunctionalMinderTreeDTO descriptionFunctionalMinderTreeDTO = getFunctionalMinderTreeDTO(descriptionText, MinderLabel.DESCRIPTION.toString(), (long) (i + 1));
children.add(descriptionFunctionalMinderTreeDTO);
}
return children;
@ -126,13 +173,56 @@ public class FunctionalCaseMinderService {
return functionalMinderTreeDTO;
}
public FunctionalCase updateFunctionalCase(FunctionalCaseMinderEditRequest request, String userId) {
public void updateFunctionalCase(FunctionalCaseMinderEditRequest request, String userId) {
if (StringUtils.isNotBlank(request.getName())) {
FunctionalCase functionalCase = new FunctionalCase();
functionalCase.setName(request.getName());
buildUpdateCaseParam(request, userId, functionalCase);
functionalCaseMapper.updateByPrimaryKeySelective(functionalCase);
return functionalCase;
switch (request.getType()) {
case CASE -> {
FunctionalCase functionalCase = new FunctionalCase();
functionalCase.setName(request.getName());
buildUpdateCaseParam(request.getId(), userId, functionalCase);
functionalCaseMapper.updateByPrimaryKeySelective(functionalCase);
}
case MODULE -> {
FunctionalCaseModule functionalCaseModule = new FunctionalCaseModule();
functionalCaseModule.setName(request.getName());
buildUpdateCaseModuleParam(request.getId(), userId, functionalCaseModule);
functionalCaseModuleMapper.updateByPrimaryKeySelective(functionalCaseModule);
}
case PREREQUISITE -> {
FunctionalCaseBlob functionalCaseBlob = new FunctionalCaseBlob();
functionalCaseBlob.setId(request.getId());
functionalCaseBlob.setPrerequisite(StringUtils.defaultIfBlank(request.getName(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8));
functionalCaseBlobMapper.updateByPrimaryKeySelective(functionalCaseBlob);
}
case STEPS -> {
FunctionalCaseBlob functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey(request.getId());
updateSteps(request, functionalCaseBlob);
}
case STEPS_EXPECTED_RESULT -> {
FunctionalCaseBlob functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey(request.getId());
updateStepResult(request, functionalCaseBlob);
}
case TEXT_DESCRIPTION -> {
FunctionalCaseBlob functionalCaseBlob = new FunctionalCaseBlob();
functionalCaseBlob.setId(request.getId());
functionalCaseBlob.setTextDescription(StringUtils.defaultIfBlank(request.getName(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8));
functionalCaseBlobMapper.updateByPrimaryKeySelective(functionalCaseBlob);
}
case TEXT_EXPECTED_RESULT -> {
FunctionalCaseBlob functionalCaseBlob = new FunctionalCaseBlob();
functionalCaseBlob.setId(request.getId());
functionalCaseBlob.setExpectedResult(StringUtils.defaultIfBlank(request.getName(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8));
functionalCaseBlobMapper.updateByPrimaryKeySelective(functionalCaseBlob);
}
case DESCRIPTION -> {
FunctionalCaseBlob functionalCaseBlob = new FunctionalCaseBlob();
functionalCaseBlob.setId(request.getId());
functionalCaseBlob.setDescription(StringUtils.defaultIfBlank(request.getName(), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8));
functionalCaseBlobMapper.updateByPrimaryKeySelective(functionalCaseBlob);
}
default -> {
}
}
}
if (StringUtils.isNotBlank(request.getPriority())) {
CustomFieldExample example = new CustomFieldExample();
@ -145,16 +235,236 @@ public class FunctionalCaseMinderService {
customField.setValue(request.getPriority());
functionalCaseCustomFieldMapper.updateByPrimaryKeySelective(customField);
FunctionalCase functionalCase = new FunctionalCase();
buildUpdateCaseParam(request, userId, functionalCase);
buildUpdateCaseParam(request.getId(), userId, functionalCase);
functionalCaseMapper.updateByPrimaryKeySelective(functionalCase);
return functionalCase;
}
return new FunctionalCase();
}
private static void buildUpdateCaseParam(FunctionalCaseMinderEditRequest request, String userId, FunctionalCase functionalCase) {
functionalCase.setId(request.getId());
private void updateStepResult(FunctionalCaseMinderEditRequest request, FunctionalCaseBlob functionalCaseBlob) {
String stepText = new String(functionalCaseBlob.getSteps(), StandardCharsets.UTF_8);
List<FunctionalCaseStepDTO> functionalCaseStepDTOS = JSON.parseArray(stepText, FunctionalCaseStepDTO.class);
for (FunctionalCaseStepDTO functionalCaseStepDTO : functionalCaseStepDTOS) {
if (functionalCaseStepDTO.getNum() == request.getPos().intValue()) {
functionalCaseStepDTO.setResult(request.getName());
}
}
functionalCaseBlob.setSteps(StringUtils.defaultIfBlank(JSON.toJSONString(functionalCaseStepDTOS), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8));
functionalCaseBlobMapper.updateByPrimaryKeySelective(functionalCaseBlob);
}
private void updateSteps(FunctionalCaseMinderEditRequest request, FunctionalCaseBlob functionalCaseBlob) {
if (functionalCaseBlob.getSteps() != null) {
String stepText = new String(functionalCaseBlob.getSteps(), StandardCharsets.UTF_8);
List<FunctionalCaseStepDTO> functionalCaseStepDTOS = JSON.parseArray(stepText, FunctionalCaseStepDTO.class);
for (FunctionalCaseStepDTO functionalCaseStepDTO : functionalCaseStepDTOS) {
if (functionalCaseStepDTO.getNum() == request.getPos().intValue()) {
functionalCaseStepDTO.setDesc(request.getName());
}
}
functionalCaseBlob.setSteps(StringUtils.defaultIfBlank(JSON.toJSONString(functionalCaseStepDTOS), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8));
functionalCaseBlobMapper.updateByPrimaryKeySelective(functionalCaseBlob);
}
}
private void buildUpdateCaseModuleParam(String id, String userId, FunctionalCaseModule functionalCaseModule) {
functionalCaseModule.setId(id);
functionalCaseModule.setUpdateUser(userId);
functionalCaseModule.setUpdateTime(System.currentTimeMillis());
}
private void buildUpdateCaseParam(String id, String userId, FunctionalCase functionalCase) {
functionalCase.setId(id);
functionalCase.setUpdateUser(userId);
functionalCase.setUpdateTime(System.currentTimeMillis());
}
public void removeFunctionalCaseBatch(FunctionalCaseMinderRemoveRequest request, String userId) {
List<MinderOptionDTO> resourceList = request.getResourceList();
if (CollectionUtils.isEmpty(resourceList)) {
throw new MSException(Translator.get("node.not_blank"));
}
Map<String, List<MinderOptionDTO>> resourceMap = resourceList.stream().collect(Collectors.groupingBy(MinderOptionDTO::getType));
MinderTargetDTO caseMinderTargetDTO = request.getCaseMinderTargetDTO();
MinderTargetDTO moduleMinderTargetDTO = request.getModuleMinderTargetDTO();
List<MinderOptionDTO> caseOptionDTOS = resourceMap.get(MinderLabel.CASE.toString());
List<String> caseIds = new ArrayList<>();
if (CollectionUtils.isNotEmpty(caseOptionDTOS)) {
caseIds = caseOptionDTOS.stream().map(MinderOptionDTO::getId).toList();
if (!extCheckOwnerMapper.checkoutOwner(FUNCTIONAL_CASE, userId, caseIds)) {
throw new MSException(Translator.get(CHECK_OWNER_CASE));
}
}
List<String> moduleIds = new ArrayList<>();
List<MinderOptionDTO> moduleOptionDTOS = resourceMap.get(MinderLabel.MODULE.toString());
if (CollectionUtils.isNotEmpty(moduleOptionDTOS)) {
moduleIds = moduleOptionDTOS.stream().map(MinderOptionDTO::getId).toList();
if (!extCheckOwnerMapper.checkoutOwner(FUNCTIONAL_CASE_MODULE, userId, moduleIds)) {
throw new MSException(Translator.get(CHECK_OWNER_CASE));
}
}
if (StringUtils.isNotBlank(request.getParentTargetId()) ) {
//移动到某节点下
if (!extCheckOwnerMapper.checkoutOwner(FUNCTIONAL_CASE_MODULE, userId, List.of(request.getParentTargetId()))) {
throw new MSException(Translator.get(CHECK_OWNER_CASE));
}
if (CollectionUtils.isNotEmpty(caseIds)) {
//拖拽到别的节点
FunctionalCaseBatchMoveRequest functionalCaseBatchMoveRequest = new FunctionalCaseBatchMoveRequest();
functionalCaseBatchMoveRequest.setModuleId(request.getParentTargetId());
functionalCaseBatchMoveRequest.setProjectId(request.getProjectId());
functionalCaseService.batchMoveFunctionalCaseByIds(functionalCaseBatchMoveRequest, userId, caseIds);
moveSortCase(userId, caseMinderTargetDTO, caseIds);
}
if (CollectionUtils.isNotEmpty(moduleIds)) {
//处理模块拖拽以及移动
//拖拽到别的节点
extFunctionalCaseModuleMapper.batchUpdateStringColumn("parent_id", moduleIds, request.getParentTargetId());
moveSortModule(request.getProjectId(), userId, moduleMinderTargetDTO, moduleIds);
}
} else if ( CollectionUtils.isNotEmpty(caseIds)) {
//直接给用例排序
moveSortCase(userId, caseMinderTargetDTO, caseIds);
} else if (CollectionUtils.isNotEmpty(moduleIds)) {
//直接给模块排序
moveSortModule(request.getProjectId(), userId, moduleMinderTargetDTO, moduleIds);
}
updateSteps(request, resourceList);
}
private void moveSortModule(String projectId, String userId, MinderTargetDTO moduleMinderTargetDTO, List<String> moduleIds) {
if (moduleMinderTargetDTO != null && StringUtils.isNotBlank(moduleMinderTargetDTO.getTargetId())) {
//排序
String targetId = moduleMinderTargetDTO.getTargetId();
FunctionalCaseModule functionalCaseModule = functionalCaseModuleMapper.selectByPrimaryKey(targetId);
if (functionalCaseModule != null){
FunctionalCaseModuleExample functionalCaseModuleExample = new FunctionalCaseModuleExample();
functionalCaseModuleExample.createCriteria().andProjectIdEqualTo(projectId);
List<FunctionalCaseModule> functionalCaseModules = functionalCaseModuleMapper.selectByExample(functionalCaseModuleExample);
List<String> ids = new ArrayList<>(functionalCaseModules.stream().map(FunctionalCaseModule::getId).toList());
List<String> finalIds = getFinalIds(moduleMinderTargetDTO, moduleIds, ids, targetId);
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
FunctionalCaseModuleMapper moduleMapper = sqlSession.getMapper(FunctionalCaseModuleMapper.class);
for (int i = 0; i < finalIds.size(); i++) {
FunctionalCaseModule updateModule = new FunctionalCaseModule();
updateModule.setId(finalIds.get(i));
updateModule.setPos(5000L * i);
updateModule.setUpdateUser(userId);
updateModule.setUpdateTime(System.currentTimeMillis());
moduleMapper.updateByPrimaryKeySelective(updateModule);
}
sqlSession.flushStatements();
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
}
}
}
private void moveSortCase(String userId, MinderTargetDTO caseMinderTargetDTO, List<String> caseIds) {
if (caseMinderTargetDTO != null && StringUtils.isNotBlank(caseMinderTargetDTO.getTargetId())) {
String targetId = caseMinderTargetDTO.getTargetId();
//排序
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(targetId);
if (functionalCase != null && !functionalCase.getDeleted()) {
FunctionalCaseExample functionalCaseExample = new FunctionalCaseExample();
functionalCaseExample.createCriteria().andDeletedEqualTo(false).andModuleIdEqualTo(functionalCase.getModuleId()).andProjectIdEqualTo(functionalCase.getProjectId());
List<FunctionalCase> functionalCases = functionalCaseMapper.selectByExample(functionalCaseExample);
List<String> ids = new ArrayList<>(functionalCases.stream().map(FunctionalCase::getId).toList());
List<String> finalIds = getFinalIds(caseMinderTargetDTO, caseIds, ids, targetId);
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
FunctionalCaseMapper caseMapper = sqlSession.getMapper(FunctionalCaseMapper.class);
for (int i = 0; i < finalIds.size(); i++) {
FunctionalCase updateCase = new FunctionalCase();
updateCase.setId(finalIds.get(i));
updateCase.setPos(5000L * i);
updateCase.setUpdateUser(userId);
updateCase.setUpdateTime(System.currentTimeMillis());
caseMapper.updateByPrimaryKeySelective(updateCase);
}
sqlSession.flushStatements();
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
}
}
}
@NotNull
private static List<String> getFinalIds(MinderTargetDTO minderTargetDTO, List<String> paramIds, List<String> selectIds, String targetId) {
List<String> finalIds = new ArrayList<>();
int i1 = selectIds.indexOf(targetId);
List<String> beforeIds;
List<String> afterIds;
if (StringUtils.equals(minderTargetDTO.getMoveMode(), MoveTypeEnum.AFTER.name())) {
beforeIds = selectIds.subList(0, i1 + 1);
afterIds = selectIds.subList(i1 + 1, selectIds.size());
} else {
beforeIds = selectIds.subList(0, i1);
afterIds = selectIds.subList(i1, selectIds.size());
}
finalIds.addAll(beforeIds);
finalIds.addAll(paramIds);
finalIds.addAll(afterIds);
return finalIds;
}
private void updateSteps(FunctionalCaseMinderRemoveRequest request, List<MinderOptionDTO> resourceList) {
if (StringUtils.isNotBlank(request.getSteps())) {
List<FunctionalCaseStepDTO> functionalCaseStepDTOS = JSON.parseArray(request.getSteps(), FunctionalCaseStepDTO.class);
for (int i = 0; i < functionalCaseStepDTOS.size(); i++) {
functionalCaseStepDTOS.get(i).setNum(i + 1);
}
byte[] bytes = StringUtils.defaultIfBlank(JSON.toJSONString(functionalCaseStepDTOS), StringUtils.EMPTY).getBytes(StandardCharsets.UTF_8);
extFunctionalCaseBlobMapper.batchUpdateColumn("steps", List.of(resourceList.get(0).getId()), bytes);
}
}
public void deleteFunctionalCaseBatch(String projectId, List<MinderOptionDTO> resourceList, String userId) {
if (CollectionUtils.isEmpty(resourceList)) {
throw new MSException(Translator.get("node.not_blank"));
}
Map<String, List<MinderOptionDTO>> resourceMap = resourceList.stream().collect(Collectors.groupingBy(MinderOptionDTO::getType));
List<MinderOptionDTO> caseOptionDTOS = resourceMap.get(MinderLabel.CASE.toString());
if (CollectionUtils.isNotEmpty(caseOptionDTOS)) {
List<String> caseIds = caseOptionDTOS.stream().map(MinderOptionDTO::getId).toList();
if (!extCheckOwnerMapper.checkoutOwner(FUNCTIONAL_CASE, userId, caseIds)) {
throw new MSException(Translator.get(CHECK_OWNER_CASE));
}
functionalCaseService.handDeleteFunctionalCase(caseIds, false, userId, projectId);
}
List<MinderOptionDTO> caseModuleOptionDTOS = resourceMap.get(MinderLabel.MODULE.toString());
if (CollectionUtils.isNotEmpty(caseModuleOptionDTOS)) {
List<String> moduleIds = caseModuleOptionDTOS.stream().map(MinderOptionDTO::getId).toList();
if (!extCheckOwnerMapper.checkoutOwner(FUNCTIONAL_CASE_MODULE, userId, moduleIds)) {
throw new MSException(Translator.get(CHECK_OWNER_CASE));
}
List<FunctionalCase> functionalCases = functionalCaseModuleService.deleteModuleByIds(moduleIds, new ArrayList<>(), userId);
functionalCaseModuleService.batchDelLog(functionalCases, projectId);
}
List<MinderOptionDTO> prerequisiteOptionDTOS = resourceMap.get(MinderLabel.PREREQUISITE.toString());
updateBlob(userId, "prerequisite", prerequisiteOptionDTOS);
List<MinderOptionDTO> descriptionOptionDTOS = resourceMap.get(MinderLabel.DESCRIPTION.toString());
updateBlob(userId, "description", descriptionOptionDTOS);
List<MinderOptionDTO> stepOptionDTOS = resourceMap.get(MinderLabel.STEPS.toString());
if (CollectionUtils.isNotEmpty(stepOptionDTOS)) {
List<MinderOptionDTO> stepResultOptionDTOS = resourceMap.get(MinderLabel.STEPS_EXPECTED_RESULT.toString());
stepOptionDTOS.addAll(stepResultOptionDTOS);
updateBlob(userId, "steps", stepOptionDTOS);
}
List<MinderOptionDTO> textOptionDTOS = resourceMap.get(MinderLabel.TEXT_DESCRIPTION.toString());
updateBlob(userId, "text_description", textOptionDTOS);
List<MinderOptionDTO> resultOptionDTOS = resourceMap.get(MinderLabel.TEXT_EXPECTED_RESULT.toString());
updateBlob(userId, "expected_result", resultOptionDTOS);
}
private void updateBlob(String userId, String column, List<MinderOptionDTO> preRequisiteOptionDTOS) {
if (CollectionUtils.isNotEmpty(preRequisiteOptionDTOS)) {
List<String> caseIds = preRequisiteOptionDTOS.stream().map(MinderOptionDTO::getId).distinct().toList();
if (!extCheckOwnerMapper.checkoutOwner(FUNCTIONAL_CASE, userId, caseIds)) {
throw new MSException(Translator.get(CHECK_OWNER_CASE));
}
extFunctionalCaseBlobMapper.batchUpdateColumn(column, caseIds, null);
}
}
}

View File

@ -22,12 +22,15 @@ import io.metersphere.sdk.constants.ModuleConstants;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.domain.User;
import io.metersphere.system.dto.sdk.BaseTreeNode;
import io.metersphere.system.dto.sdk.request.NodeMoveRequest;
import io.metersphere.system.log.constants.OperationLogModule;
import io.metersphere.system.log.constants.OperationLogType;
import io.metersphere.system.log.dto.LogDTO;
import io.metersphere.system.log.service.OperationLogService;
import io.metersphere.system.mapper.UserMapper;
import io.metersphere.system.notice.constants.NoticeConstants;
import io.metersphere.system.uid.IDGenerator;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
@ -58,6 +61,11 @@ public class FunctionalCaseModuleService extends ModuleTreeService {
private FunctionalCaseMapper functionalCaseMapper;
@Resource
private OperationLogService operationLogService;
@Resource
private UserMapper userMapper;
@Resource
private FunctionalCaseNoticeService functionalCaseNoticeService;
public List<BaseTreeNode> getTree(String projectId) {
List<BaseTreeNode> functionalModuleList = extFunctionalCaseModuleMapper.selectBaseByProjectId(projectId);
@ -122,6 +130,9 @@ public class FunctionalCaseModuleService extends ModuleTreeService {
if (deleteModule != null) {
List<FunctionalCase> functionalCases = this.deleteModuleByIds(Collections.singletonList(moduleId), new ArrayList<>(), userId);
batchDelLog(functionalCases, deleteModule.getProjectId());
List<String> ids = functionalCases.stream().map(FunctionalCase::getId).toList();
User user = userMapper.selectByPrimaryKey(userId);
functionalCaseNoticeService.batchSendNotice(deleteModule.getProjectId(), ids, user, NoticeConstants.Event.UPDATE);
}
}

View File

@ -1,5 +1,6 @@
package io.metersphere.functional.service;
import io.metersphere.functional.constants.MinderLabel;
import io.metersphere.functional.domain.*;
import io.metersphere.functional.dto.CaseCustomFieldDTO;
import io.metersphere.functional.dto.FunctionalCaseDTO;
@ -12,12 +13,15 @@ import io.metersphere.functional.request.FunctionalCaseCommentRequest;
import io.metersphere.functional.request.FunctionalCaseEditRequest;
import io.metersphere.functional.request.FunctionalCaseMinderEditRequest;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.domain.CustomField;
import io.metersphere.system.domain.CustomFieldExample;
import io.metersphere.system.domain.User;
import io.metersphere.system.dto.sdk.OptionDTO;
import io.metersphere.system.mapper.CustomFieldMapper;
import io.metersphere.system.mapper.ExtOrganizationCustomFieldMapper;
import io.metersphere.system.notice.constants.NoticeConstants;
import io.metersphere.system.service.CommonNoticeSendService;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
@ -50,6 +54,9 @@ public class FunctionalCaseNoticeService {
@Resource
private CaseReviewMapper caseReviewMapper;
@Resource
private CommonNoticeSendService commonNoticeSendService;
public FunctionalCaseDTO getFunctionalCaseDTO(FunctionalCaseCommentRequest functionalCaseCommentRequest) {
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(functionalCaseCommentRequest.getCaseId());
@ -254,6 +261,9 @@ public class FunctionalCaseNoticeService {
public FunctionalCaseDTO getMainFunctionalCaseMinderDTO(FunctionalCaseMinderEditRequest request) {
FunctionalCaseDTO functionalCaseDTO = new FunctionalCaseDTO();
if (request.getType() == MinderLabel.MODULE) {
return functionalCaseDTO;
}
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(request.getId());
BeanUtils.copyBean(functionalCaseDTO, functionalCase);
setReviewName(request.getId(), functionalCaseDTO);
@ -289,4 +299,21 @@ public class FunctionalCaseNoticeService {
}
public void batchSendNotice(String projectId, List<String> ids, User user, String event) {
int amount = 100;//每次读取的条数
long roundTimes = Double.valueOf(Math.ceil((double) ids.size() / amount)).longValue();//循环的次数
for (int i = 0; i < (int) roundTimes; i++) {
int fromIndex = (i * amount);
int toIndex = ((i + 1) * amount);
if (i == roundTimes - 1 || toIndex > ids.size()) {//最后一次遍历
toIndex = ids.size();
}
List<String> subList = ids.subList(fromIndex, toIndex);
List<FunctionalCaseDTO> functionalCaseDTOS = handleBatchNotice(projectId, subList);
List<Map> resources = new ArrayList<>();
resources.addAll(JSON.parseArray(JSON.toJSONString(functionalCaseDTOS), Map.class));
commonNoticeSendService.sendNotice(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, event, resources, user, projectId);
}
}
}

View File

@ -615,7 +615,7 @@ public class FunctionalCaseService {
handDeleteFunctionalCase(Collections.singletonList(request.getId()), request.getDeleteAll(), userId, request.getProjectId());
}
private void handDeleteFunctionalCase(List<String> ids, Boolean deleteAll, String userId, String projectId) {
public void handDeleteFunctionalCase(List<String> ids, Boolean deleteAll, String userId, String projectId) {
Map<String, Object> param = new HashMap<>();
if (deleteAll) {
//全部删除 进入回收站
@ -631,7 +631,7 @@ public class FunctionalCaseService {
doDelete(ids, userId);
}
User user = userMapper.selectByPrimaryKey(userId);
batchSendNotice(projectId, ids, user, NoticeConstants.Event.DELETE);
functionalCaseNoticeService.batchSendNotice(projectId, ids, user, NoticeConstants.Event.DELETE);
param.put(CaseEvent.Param.USER_ID, userId);
param.put(CaseEvent.Param.EVENT_NAME, CaseEvent.Event.DELETE_FUNCTIONAL_CASE);
provider.updateCaseReview(param);
@ -750,31 +750,16 @@ public class FunctionalCaseService {
* @param userId userId
*/
public void batchMoveFunctionalCase(FunctionalCaseBatchMoveRequest request, String userId) {
User user = userMapper.selectByPrimaryKey(userId);
List<String> ids = doSelectIds(request, request.getProjectId());
if (CollectionUtils.isNotEmpty(ids)) {
List<String> refId = extFunctionalCaseMapper.getRefIds(ids, false);
extFunctionalCaseMapper.batchMoveModule(request, refId, userId);
batchSendNotice(request.getProjectId(), ids, user, NoticeConstants.Event.UPDATE);
}
batchMoveFunctionalCaseByIds(request, userId, ids);
}
private void batchSendNotice(String projectId, List<String> ids, User user, String event) {
int amount = 100;//每次读取的条数
long roundTimes = Double.valueOf(Math.ceil((double) ids.size() / amount)).longValue();//循环的次数
for (int i = 0; i < (int) roundTimes; i++) {
int fromIndex = (i * amount);
int toIndex = ((i + 1) * amount);
if (i == roundTimes - 1) {//最后一次遍历
toIndex = ids.size();
} else if (toIndex > ids.size()) {
toIndex = ids.size();
}
List<String> subList = ids.subList(fromIndex, toIndex);
List<FunctionalCaseDTO> functionalCaseDTOS = functionalCaseNoticeService.handleBatchNotice(projectId, subList);
List<Map> resources = new ArrayList<>();
resources.addAll(JSON.parseArray(JSON.toJSONString(functionalCaseDTOS), Map.class));
commonNoticeSendService.sendNotice(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, event, resources, user, projectId);
public void batchMoveFunctionalCaseByIds(FunctionalCaseBatchMoveRequest request, String userId, List<String> ids) {
if (CollectionUtils.isNotEmpty(ids)) {
User user = userMapper.selectByPrimaryKey(userId);
List<String> refId = extFunctionalCaseMapper.getRefIds(ids, false);
extFunctionalCaseMapper.batchMoveModule(request, refId, userId);
functionalCaseNoticeService.batchSendNotice(request.getProjectId(), ids, user, NoticeConstants.Event.UPDATE);
}
}
@ -862,7 +847,7 @@ public class FunctionalCaseService {
saveAddDataLog(functionalCase, new FunctionalCaseHistoryLogDTO(), historyLogDTO, userId, organizationId, OperationLogType.ADD.name(), OperationLogModule.FUNCTIONAL_CASE);
}
User user = userMapper.selectByPrimaryKey(userId);
batchSendNotice(request.getProjectId(), ids, user, NoticeConstants.Event.CREATE);
functionalCaseNoticeService.batchSendNotice(request.getProjectId(), ids, user, NoticeConstants.Event.CREATE);
}
@ -918,7 +903,7 @@ public class FunctionalCaseService {
functionalCase.setUpdateTime(System.currentTimeMillis());
functionalCase.setUpdateUser(userId);
extFunctionalCaseMapper.batchUpdate(functionalCase, ids);
batchSendNotice(request.getProjectId(), ids, user, NoticeConstants.Event.UPDATE);
functionalCaseNoticeService.batchSendNotice(request.getProjectId(), ids, user, NoticeConstants.Event.UPDATE);
}
}

View File

@ -1,20 +1,20 @@
package io.metersphere.functional.controller;
import io.metersphere.functional.domain.FunctionalCase;
import io.metersphere.functional.domain.FunctionalCaseBlob;
import io.metersphere.functional.domain.FunctionalCaseCustomField;
import io.metersphere.functional.domain.FunctionalCaseCustomFieldExample;
import io.metersphere.functional.constants.MinderLabel;
import io.metersphere.functional.domain.*;
import io.metersphere.functional.dto.FunctionalCaseStepDTO;
import io.metersphere.functional.dto.FunctionalMinderTreeDTO;
import io.metersphere.functional.mapper.FunctionalCaseBlobMapper;
import io.metersphere.functional.mapper.FunctionalCaseCustomFieldMapper;
import io.metersphere.functional.dto.MinderOptionDTO;
import io.metersphere.functional.dto.MinderTargetDTO;
import io.metersphere.functional.mapper.*;
import io.metersphere.functional.request.FunctionalCaseMindRequest;
import io.metersphere.functional.request.FunctionalCaseMinderEditRequest;
import io.metersphere.functional.request.FunctionalCaseMinderRemoveRequest;
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.enums.MoveTypeEnum;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.*;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
@ -26,6 +26,8 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@AutoConfigureMockMvc
@ -37,9 +39,19 @@ public class FunctionalCaseMinderControllerTest extends BaseTest {
public static final String FUNCTIONAL_CASE_UPDATE_PRIORITY_URL = "/functional/mind/case/update/source/priority";
public static final String FUNCTIONAL_CASE_BATCH_DELETE = "/functional/mind/case/batch/delete/";
public static final String FUNCTIONAL_CASE_BATCH_MOVE = "/functional/mind/case/batch/remove";
@Resource
private FunctionalCaseBlobMapper functionalCaseBlobMapper;
@Resource
private FunctionalCaseMapper functionalCaseMapper;
@Resource
private FunctionalCaseModuleMapper functionalCaseModuleMapper;
@Resource
private FunctionalCaseCustomFieldMapper functionalCaseCustomFieldMapper;
@Test
@ -72,6 +84,14 @@ public class FunctionalCaseMinderControllerTest extends BaseTest {
functionalCaseBlob.setPrerequisite(prerequisite.getBytes(StandardCharsets.UTF_8));
functionalCaseBlob.setDescription(description.getBytes(StandardCharsets.UTF_8));
functionalCaseBlobMapper.insert(functionalCaseBlob);
FunctionalCaseBlob functionalCaseBlob6 = new FunctionalCaseBlob();
functionalCaseBlob6.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_1");
functionalCaseBlob.setSteps(JSON.toJSONString(list).getBytes(StandardCharsets.UTF_8));
functionalCaseBlob.setTextDescription(textDescription.getBytes(StandardCharsets.UTF_8));
functionalCaseBlob.setExpectedResult(expectedResult.getBytes(StandardCharsets.UTF_8));
functionalCaseBlob.setPrerequisite(prerequisite.getBytes(StandardCharsets.UTF_8));
functionalCaseBlob.setDescription(description.getBytes(StandardCharsets.UTF_8));
functionalCaseBlobMapper.updateByPrimaryKeyWithBLOBs(functionalCaseBlob);
FunctionalCaseMindRequest request = new FunctionalCaseMindRequest();
request.setProjectId("project-case-minder-test");
@ -95,39 +115,189 @@ public class FunctionalCaseMinderControllerTest extends BaseTest {
request.setProjectId("project-case-minder-test");
request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6");
request.setName("TEST_FUNCTIONAL_MINDER_CASE_ID_Change_Name");
MvcResult mvcResultPage = this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request);
String contentAsString = mvcResultPage.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder resultHolder = JSON.parseObject(contentAsString, ResultHolder.class);
FunctionalCase baseTreeNodes = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), FunctionalCase.class);
Assertions.assertNotNull(baseTreeNodes);
String jsonString = JSON.toJSONString(baseTreeNodes);
System.out.println(jsonString);
Assertions.assertEquals(baseTreeNodes.getName(), "TEST_FUNCTIONAL_MINDER_CASE_ID_Change_Name");
request.setType(MinderLabel.CASE);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request);
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6");
Assertions.assertEquals(functionalCase.getName(), "TEST_FUNCTIONAL_MINDER_CASE_ID_Change_Name");
request.setName("TEST_MINDER_MODULE_ID_GYQ5_Change_Name");
request.setId("TEST_MINDER_MODULE_ID_GYQ5");
request.setType(MinderLabel.MODULE);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request);
FunctionalCaseModule functionalCaseModule = functionalCaseModuleMapper.selectByPrimaryKey("TEST_MINDER_MODULE_ID_GYQ5");
Assertions.assertEquals(functionalCaseModule.getName(), "TEST_MINDER_MODULE_ID_GYQ5_Change_Name");
request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6");
request.setName("前置哈哈哈");
request.setType(MinderLabel.PREREQUISITE);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request);
FunctionalCaseBlob functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6");
Assertions.assertEquals(new String(functionalCaseBlob.getPrerequisite(), StandardCharsets.UTF_8), "前置哈哈哈");
FunctionalCaseBlob functionalCaseBlobInDB = new FunctionalCaseBlob();
functionalCaseBlobInDB.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6");
String steps = "[{\"id\":\"aa159262-baf9-4a11-91b9-0ab50a9f199e\",\"num\":0,\"desc\":\"点点滴滴\",\"result\":\"点点滴滴的\"},{\"id\":\"2bf16247-96a2-44c4-92c8-f620f85eb351\",\"num\":1,\"desc\":\"d d d\",\"result\":\" 得到的\"}]";
functionalCaseBlobInDB.setSteps(steps.getBytes(StandardCharsets.UTF_8));
functionalCaseBlobMapper.updateByPrimaryKeySelective(functionalCaseBlobInDB);
request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6");
request.setName("步骤哈哈哈");
request.setType(MinderLabel.STEPS);
request.setPos(1L);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request);
functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6");
List<FunctionalCaseStepDTO> functionalCaseStepDTOS = JSON.parseArray(new String(functionalCaseBlob.getSteps(), StandardCharsets.UTF_8), FunctionalCaseStepDTO.class);
functionalCaseStepDTOS.forEach(t->{
if (t.getNum()==1) {
Assertions.assertEquals(t.getDesc(), "步骤哈哈哈");
}
});
request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6");
request.setName("步骤结果哈哈哈");
request.setType(MinderLabel.STEPS_EXPECTED_RESULT);
request.setPos(1L);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request);
functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6");
functionalCaseStepDTOS = JSON.parseArray(new String(functionalCaseBlob.getSteps(), StandardCharsets.UTF_8), FunctionalCaseStepDTO.class);
functionalCaseStepDTOS.forEach(t->{
if (t.getNum()==1) {
Assertions.assertEquals(t.getResult(), "步骤结果哈哈哈");
}
});
request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6");
request.setName("文本哈哈哈");
request.setType(MinderLabel.TEXT_DESCRIPTION);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request);
functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6");
Assertions.assertEquals(new String(functionalCaseBlob.getTextDescription(), StandardCharsets.UTF_8), "文本哈哈哈");request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6");
request.setName("预期哈哈哈");
request.setType(MinderLabel.TEXT_EXPECTED_RESULT);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request);
functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6");
Assertions.assertEquals(new String(functionalCaseBlob.getExpectedResult(), StandardCharsets.UTF_8), "预期哈哈哈");
request.setName("备注哈哈哈");
request.setType(MinderLabel.DESCRIPTION);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_NAME_URL, request);
functionalCaseBlob = functionalCaseBlobMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6");
Assertions.assertEquals(new String(functionalCaseBlob.getDescription(), StandardCharsets.UTF_8), "备注哈哈哈");
request = new FunctionalCaseMinderEditRequest();
request.setProjectId("project-case-minder-test");
request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6");
request.setPriority("P0");
mvcResultPage = this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_PRIORITY_URL, request);
contentAsString = mvcResultPage.getResponse().getContentAsString(StandardCharsets.UTF_8);
resultHolder = JSON.parseObject(contentAsString, ResultHolder.class);
baseTreeNodes = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), FunctionalCase.class);
Assertions.assertNotNull(baseTreeNodes);
jsonString = JSON.toJSONString(baseTreeNodes);
System.out.println(jsonString);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_PRIORITY_URL, request);
FunctionalCaseCustomFieldExample customField = new FunctionalCaseCustomFieldExample();
customField.createCriteria().andCaseIdEqualTo(request.getId()).andFieldIdEqualTo("custom_field_minder_gyq_id_3");
List<FunctionalCaseCustomField> functionalCaseCustomFields = functionalCaseCustomFieldMapper.selectByExample(customField);
Assertions.assertEquals(functionalCaseCustomFields.get(0).getValue(), "P0");
request = new FunctionalCaseMinderEditRequest();
request.setProjectId("project-case-minder-test");
request.setId("TEST_FUNCTIONAL_MINDER_CASE_ID_6");
mvcResultPage = this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_PRIORITY_URL, request);
contentAsString = mvcResultPage.getResponse().getContentAsString(StandardCharsets.UTF_8);
resultHolder = JSON.parseObject(contentAsString, ResultHolder.class);
baseTreeNodes = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), FunctionalCase.class);
Assertions.assertTrue(StringUtils.isBlank(baseTreeNodes.getName()));
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_UPDATE_PRIORITY_URL, request);
}
@Test
@Order(3)
public void testDeleteCase() throws Exception{
List<MinderOptionDTO> resourceList = new ArrayList<>();
this.requestPost(FUNCTIONAL_CASE_BATCH_DELETE+"/project-case-minder-test", resourceList).andExpect(status().is5xxServerError());
MinderOptionDTO optionDTO = new MinderOptionDTO("TEST_MINDER_MODULE_ID_GYQ6", MinderLabel.MODULE.name(), 5000L);
resourceList.add(optionDTO);
this.requestPost(FUNCTIONAL_CASE_BATCH_DELETE+"/project-case-minder-test-xxx", resourceList).andExpect(status().is5xxServerError());
resourceList = new ArrayList<>();
optionDTO = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_7", MinderLabel.CASE.name(), 1000L);
resourceList.add(optionDTO);
this.requestPost(FUNCTIONAL_CASE_BATCH_DELETE+"/project-case-minder-test-xxx", resourceList).andExpect(status().is5xxServerError());
resourceList = new ArrayList<>();
MinderOptionDTO optionDTOCase = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_6", MinderLabel.CASE.name(), 600L);
MinderOptionDTO optionDTOModule = new MinderOptionDTO("TEST_MINDER_MODULE_ID_GYQ", MinderLabel.MODULE.name(), 1200L);
resourceList.add(optionDTOModule);
resourceList.add(optionDTOCase);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_DELETE+"/project-case-minder-test", resourceList);
FunctionalCase functionalCaseOne = functionalCaseMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_2");
Assertions.assertTrue(functionalCaseOne.getDeleted());
FunctionalCase functionalCaseTwo = functionalCaseMapper.selectByPrimaryKey("TEST_FUNCTIONAL_MINDER_CASE_ID_6");
Assertions.assertTrue(functionalCaseTwo.getDeleted());
resourceList = new ArrayList<>();
optionDTOCase = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_3", MinderLabel.CASE.name(), 600L);
resourceList.add(optionDTOCase);
MinderOptionDTO optionDTOPrerequisite = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_3", MinderLabel.PREREQUISITE.toString(), 0L);
MinderOptionDTO optionDTODescription = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_3", MinderLabel.DESCRIPTION.toString(), 3L);
MinderOptionDTO optionDTOStep = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_3", MinderLabel.STEPS.toString(), 2L);
MinderOptionDTO optionDTOStepExpectedResult = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_3", MinderLabel.STEPS_EXPECTED_RESULT.toString(), 2L);
MinderOptionDTO optionDTOText = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_3", MinderLabel.TEXT_DESCRIPTION.toString(), 2L);
MinderOptionDTO optionDTOTextExpectedResult = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_3", MinderLabel.TEXT_EXPECTED_RESULT.toString(), 2L);
resourceList.add(optionDTOPrerequisite);
resourceList.add(optionDTODescription);
resourceList.add(optionDTOStep);
resourceList.add(optionDTOStepExpectedResult);
resourceList.add(optionDTOText);
resourceList.add(optionDTOTextExpectedResult);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_DELETE+"/project-case-minder-test", resourceList);
resourceList = new ArrayList<>();
optionDTOText = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_7", MinderLabel.TEXT_DESCRIPTION.toString(), 2L);
resourceList.add(optionDTOText);
optionDTOTextExpectedResult = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_7", MinderLabel.TEXT_EXPECTED_RESULT.toString(), 2L);
resourceList.add(optionDTOTextExpectedResult);
this.requestPost(FUNCTIONAL_CASE_BATCH_DELETE+"/project-case-minder-test", resourceList).andExpect(status().is5xxServerError());
}
@Test
@Order(4)
public void testRemoveCase() throws Exception{
FunctionalCaseMinderRemoveRequest functionalCaseMinderRemoveRequest = new FunctionalCaseMinderRemoveRequest();
functionalCaseMinderRemoveRequest.setProjectId("project-case-minder-test");
functionalCaseMinderRemoveRequest.setParentTargetId("TEST_MINDER_MODULE_ID_GYQ2");
MinderTargetDTO caseMinderTargetDTO = new MinderTargetDTO();
caseMinderTargetDTO.setTargetId("TEST_FUNCTIONAL_MINDER_CASE_ID_8");
caseMinderTargetDTO.setMoveMode(MoveTypeEnum.AFTER.name());
functionalCaseMinderRemoveRequest.setCaseMinderTargetDTO(caseMinderTargetDTO);
MinderTargetDTO moduleMinderTargetDTO = new MinderTargetDTO();
moduleMinderTargetDTO.setTargetId("TEST_MINDER_MODULE_ID_GYQ2");
moduleMinderTargetDTO.setMoveMode(MoveTypeEnum.AFTER.name());
functionalCaseMinderRemoveRequest.setModuleMinderTargetDTO(moduleMinderTargetDTO);
functionalCaseMinderRemoveRequest.setResourceList(new ArrayList<>());
this.requestPost(FUNCTIONAL_CASE_BATCH_MOVE, functionalCaseMinderRemoveRequest).andExpect(status().is5xxServerError());
List<MinderOptionDTO> resourceList = new ArrayList<>();
MinderOptionDTO optionDTOCase = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_8", MinderLabel.CASE.name(), 600L);
resourceList.add(optionDTOCase);
MinderOptionDTO optionDTOModule = new MinderOptionDTO("TEST_MINDER_MODULE_ID_GYQ5", MinderLabel.MODULE.name(), 600L);
resourceList.add(optionDTOModule);
functionalCaseMinderRemoveRequest.setResourceList(resourceList);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_MOVE, functionalCaseMinderRemoveRequest);
FunctionalCaseModule functionalCaseModule = functionalCaseModuleMapper.selectByPrimaryKey("TEST_MINDER_MODULE_ID_GYQ5");
Assertions.assertTrue(functionalCaseModule.getPos() !=0);
functionalCaseMinderRemoveRequest.setParentTargetId(null);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_MOVE, functionalCaseMinderRemoveRequest);
functionalCaseModule = functionalCaseModuleMapper.selectByPrimaryKey("TEST_MINDER_MODULE_ID_GYQ5");
Assertions.assertTrue(functionalCaseModule.getPos() !=0);
caseMinderTargetDTO = new MinderTargetDTO();
caseMinderTargetDTO.setTargetId("TEST_FUNCTIONAL_MINDER_CASE_ID_2");
caseMinderTargetDTO.setMoveMode(MoveTypeEnum.BEFORE.name());
functionalCaseMinderRemoveRequest.setCaseMinderTargetDTO(caseMinderTargetDTO);
moduleMinderTargetDTO = new MinderTargetDTO();
moduleMinderTargetDTO.setTargetId("TEST_MINDER_MODULE_ID_GYQ2");
moduleMinderTargetDTO.setMoveMode(MoveTypeEnum.BEFORE.name());
functionalCaseMinderRemoveRequest.setModuleMinderTargetDTO(moduleMinderTargetDTO);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_MOVE, functionalCaseMinderRemoveRequest);
functionalCaseModule = functionalCaseModuleMapper.selectByPrimaryKey("TEST_MINDER_MODULE_ID_GYQ5");
Assertions.assertTrue(functionalCaseModule.getPos()==20000);
functionalCaseMinderRemoveRequest.setCaseMinderTargetDTO(null);
functionalCaseMinderRemoveRequest.setModuleMinderTargetDTO(null);
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_BATCH_MOVE, functionalCaseMinderRemoveRequest);
functionalCaseModule = functionalCaseModuleMapper.selectByPrimaryKey("TEST_MINDER_MODULE_ID_GYQ5");
Assertions.assertTrue(functionalCaseModule.getPos()==20000);
functionalCaseMinderRemoveRequest.setParentTargetId("TEST_MINDER_MODULE_ID_GYQ6");
this.requestPost(FUNCTIONAL_CASE_BATCH_MOVE, functionalCaseMinderRemoveRequest).andExpect(status().is5xxServerError());
resourceList = new ArrayList<>();
optionDTOCase = new MinderOptionDTO("TEST_FUNCTIONAL_MINDER_CASE_ID_7", MinderLabel.CASE.name(), 600L);
resourceList.add(optionDTOCase);
this.requestPost(FUNCTIONAL_CASE_BATCH_MOVE, functionalCaseMinderRemoveRequest).andExpect(status().is5xxServerError());
optionDTOModule = new MinderOptionDTO("TEST_MINDER_MODULE_ID_GYQ6", MinderLabel.MODULE.name(), 600L);
resourceList = new ArrayList<>();
resourceList.add(optionDTOModule);
functionalCaseMinderRemoveRequest.setResourceList(resourceList);
this.requestPost(FUNCTIONAL_CASE_BATCH_MOVE, functionalCaseMinderRemoveRequest).andExpect(status().is5xxServerError());
}

View File

@ -1,17 +1,28 @@
INSERT INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time) VALUES
('project-case-minder-test', null, '100001', '用例脑图项目', '系统默认创建的项目', 'admin', 'admin', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000);
('project-case-minder-test', null, '100001', '用例脑图项目', '系统默认创建的项目', 'admin', 'admin', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000),
('project-case-minder-test-xx', null, '100001', '用例脑图项目权限', '系统默认创建的项目', 'admin', 'admin', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000);
INSERT INTO user_role_relation (id, user_id, role_id, source_id, organization_id, create_time, create_user)
VALUES (UUID(), 'admin', 'project_admin', 'project-case-minder-test', '100001', UNIX_TIMESTAMP() * 1000,
'admin');
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
VALUES ('TEST_FUNCTIONAL_MINDER_CASE_ID_1', 1, 'TEST_MINDER_MODULE_ID_GYQ', 'project-case-minder-test', '100001', '测试', 'UN_REVIEWED', NULL, 'STEP', 0, 'v1.0.0', 'TEST_FUNCTIONAL_MINDER_CASE_ID_1', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL),
('TEST_FUNCTIONAL_MINDER_CASE_ID_2', 2, 'TEST_MINDER_MODULE_ID_GYQ', 'project-case-minder-test', '100001', '测试多版本', 'UN_REVIEWED', '["测试标签_1"]', 'STEP', 5000, 'v1.0.0', 'TEST_FUNCTIONAL_MINDER_CASE_ID_2', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL),
('TEST_FUNCTIONAL_MINDER_CASE_ID_2', 2, 'TEST_MINDER_MODULE_ID_GYQ', 'project-case-minder-test', '100001', '测试多版本', 'UN_REVIEWED', '["测试标签_1"]', 'TEXT', 5000, 'v1.0.0', 'TEST_FUNCTIONAL_MINDER_CASE_ID_2', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL),
('TEST_FUNCTIONAL_MINDER_CASE_ID_3', 3, 'TEST_MINDER_MODULE_ID_GYQ2', 'project-case-minder-test', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 25000, 'v3.0.0', 'TEST_FUNCTIONAL_MINDER_CASE_ID_3', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL),
('TEST_FUNCTIONAL_MINDER_CASE_ID_4', 4, 'TEST_MINDER_MODULE_ID_GYQ3', 'project-case-minder-test', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 40000, 'v3.0.0', 'TEST_FUNCTIONAL_MINDER_CASE_ID_4', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL),
('TEST_FUNCTIONAL_MINDER_CASE_ID_5', 5, 'TEST_MINDER_MODULE_ID_GYQ4', 'project-case-minder-test', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 45000, 'v3.0.0', 'TEST_FUNCTIONAL_MINDER_CASE_ID_5', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL),
('TEST_FUNCTIONAL_MINDER_CASE_ID_6', 6, 'TEST_MINDER_MODULE_ID_GYQ5', 'project-case-minder-test', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'TEXT', 55000, 'v3.0.0', 'TEST_FUNCTIONAL_MINDER_CASE_ID_6', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
('TEST_FUNCTIONAL_MINDER_CASE_ID_6', 6, 'TEST_MINDER_MODULE_ID_GYQ5', 'project-case-minder-test', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'TEXT', 55000, 'v3.0.0', 'TEST_FUNCTIONAL_MINDER_CASE_ID_6', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL),
('TEST_FUNCTIONAL_MINDER_CASE_ID_8', 3, 'TEST_MINDER_MODULE_ID_GYQ2', 'project-case-minder-test', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'STEP', 25000, 'v3.0.0', 'TEST_FUNCTIONAL_MINDER_CASE_ID_8', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL),
('TEST_FUNCTIONAL_MINDER_CASE_ID_7', 7, 'TEST_MINDER_MODULE_ID_GYQ6', 'project-case-minder-test-xx', '100001', 'copy_测试多版本', 'UN_REVIEWED', NULL, 'TEXT', 55000, 'v3.0.0', 'TEST_FUNCTIONAL_MINDER_CASE_ID_7', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('TEST_FUNCTIONAL_MINDER_CASE_ID_1', NULL, NULL, NULL, NULL, NULL);
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('TEST_FUNCTIONAL_MINDER_CASE_ID_3', NULL, NULL, NULL, NULL, NULL);
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('TEST_FUNCTIONAL_MINDER_CASE_ID_6', NULL, NULL, NULL, NULL, NULL);
INSERT INTO functional_case_custom_field(case_id, field_id, value) VALUES ('TEST_FUNCTIONAL_MINDER_CASE_ID_1', 'custom_field_minder_gyq_id_3', 'P0');
@ -26,7 +37,11 @@ VALUES
('TEST_MINDER_MODULE_ID_GYQ2', 'project-case-minder-test', '测试所属模块2', 'NONE', 0, 1669174143999, 1669174143999, 'admin', 'admin'),
('TEST_MINDER_MODULE_ID_GYQ3', 'project-case-minder-test', '测试所属模块3', 'TEST_MINDER_MODULE_ID_GYQ2', 0, 1669174143999, 1669174143999, 'admin', 'admin'),
('TEST_MINDER_MODULE_ID_GYQ4', 'project-case-minder-test', '测试所属模块4', 'TEST_MINDER_MODULE_ID_GYQ3', 0, 1669174143999, 1669174143999, 'admin', 'admin'),
('TEST_MINDER_MODULE_ID_GYQ5', 'project-case-minder-test', '测试所属模块5', 'TEST_MINDER_MODULE_ID_GYQ4', 0, 1669174143999, 1669174143999, 'admin', 'admin');
('TEST_MINDER_MODULE_ID_GYQ5', 'project-case-minder-test', '测试所属模块5', 'TEST_MINDER_MODULE_ID_GYQ4', 0, 1669174143999, 1669174143999, 'admin', 'admin'),
('TEST_MINDER_MODULE_ID_GYQ7', 'project-case-minder-test', '测试所属模块7', 'TEST_MINDER_MODULE_ID_GYQ', 0, 1669174143999, 1669174143999, 'admin', 'admin'),
('TEST_MINDER_MODULE_ID_GYQ8', 'project-case-minder-test', '测试所属模块8', 'TEST_MINDER_MODULE_ID_GYQ', 0, 1669174143999, 1669174143999, 'admin', 'admin'),
('TEST_MINDER_MODULE_ID_GYQ6', 'project-case-minder-test-xx', '测试所属模块1', 'NONE', 0, 1669174143999, 1669174143999, 'admin', 'admin');
INSERT INTO custom_field (id, name, scene, type, remark, internal, scope_type, create_time, update_time, create_user, scope_id) VALUES