feat(用例评审): 新增用例评审模块功能
This commit is contained in:
parent
25acb2b894
commit
2a51b922c6
|
@ -218,6 +218,19 @@ public class PermissionConstants {
|
|||
|
||||
|
||||
|
||||
/*------ end: FUNCTIONAL_CASE ------*/
|
||||
|
||||
/*------ start: CASE_REVIEW ------*/
|
||||
public static final String CASE_REVIEW_READ = "CASE_REVIEW:READ";
|
||||
public static final String CASE_REVIEW_READ_ADD = "CASE_REVIEW:READ+ADD";
|
||||
public static final String CASE_REVIEW_READ_UPDATE = "CASE_REVIEW:READ+UPDATE";
|
||||
public static final String CASE_REVIEW_READ_DELETE = "CASE_REVIEW:READ+DELETE";
|
||||
public static final String CASE_REVIEW_READ_COMMENT = "CASE_REVIEW:READ+COMMENT";
|
||||
public static final String CASE_REVIEW_READ_EXPORT = "CASE_REVIEW:READ+EXPORT";
|
||||
public static final String CASE_REVIEW_READ_IMPORT = "CASE_REVIEW:READ+IMPORT";
|
||||
|
||||
|
||||
|
||||
/*------ end: FUNCTIONAL_CASE ------*/
|
||||
|
||||
/*------ start: API_DEBUG ------*/
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package io.metersphere.functional.constants;
|
||||
|
||||
public enum CaseReviewPassRule {
|
||||
SINGLE,
|
||||
MULTIPLE
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package io.metersphere.functional.constants;
|
||||
|
||||
public enum CaseReviewStatus {
|
||||
PREPARED,
|
||||
UNDERWAY,
|
||||
COMPLETED,
|
||||
ARCHIVED;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package io.metersphere.functional.constants;
|
||||
|
||||
public enum DemandPlatform {
|
||||
LOCAL;
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package io.metersphere.functional.controller;
|
||||
|
||||
import io.metersphere.functional.request.CaseReviewModuleCreateRequest;
|
||||
import io.metersphere.functional.request.CaseReviewModuleUpdateRequest;
|
||||
import io.metersphere.functional.service.CaseReviewModuleService;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
||||
import io.metersphere.system.dto.sdk.request.NodeMoveRequest;
|
||||
import io.metersphere.system.utils.SessionUtils;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Tag(name = "用例管理-用例评审-模块")
|
||||
@RestController
|
||||
@RequestMapping("/case/review/module")
|
||||
public class CaseReviewModuleController {
|
||||
|
||||
@Resource
|
||||
private CaseReviewModuleService caseReviewModuleService;
|
||||
|
||||
@GetMapping("/tree/{projectId}")
|
||||
@Operation(summary = "用例管理-用例评审-模块-获取模块树")
|
||||
@RequiresPermissions(PermissionConstants.CASE_REVIEW_READ)
|
||||
public List<BaseTreeNode> getTree(@PathVariable String projectId) {
|
||||
return caseReviewModuleService.getTree(projectId);
|
||||
}
|
||||
|
||||
@PostMapping("/add")
|
||||
@Operation(summary = "用例管理-用例评审-模块-添加模块")
|
||||
@RequiresPermissions(PermissionConstants.CASE_REVIEW_READ_ADD)
|
||||
public void add(@RequestBody @Validated CaseReviewModuleCreateRequest request) {
|
||||
caseReviewModuleService.add(request, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
@Operation(summary = "用例管理-用例评审-模块-修改模块")
|
||||
@RequiresPermissions(PermissionConstants.CASE_REVIEW_READ_UPDATE)
|
||||
public void list(@RequestBody @Validated CaseReviewModuleUpdateRequest request) {
|
||||
caseReviewModuleService.update(request, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
@PostMapping("/move")
|
||||
@Operation(summary = "用例管理-用例评审-模块-移动模块")
|
||||
@RequiresPermissions(PermissionConstants.CASE_REVIEW_READ_UPDATE)
|
||||
public void moveNode(@Validated @RequestBody NodeMoveRequest request) {
|
||||
caseReviewModuleService.moveNode(request, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
@GetMapping("/delete/{moduleId}")
|
||||
@Operation(summary = "用例管理-用例评审-模块-删除模块")
|
||||
@RequiresPermissions(PermissionConstants.CASE_REVIEW_READ_DELETE)
|
||||
public void deleteNode(@PathVariable String moduleId) {
|
||||
caseReviewModuleService.deleteModule(moduleId);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package io.metersphere.functional.mapper;
|
||||
|
||||
import io.metersphere.functional.domain.CaseReview;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wx
|
||||
*/
|
||||
public interface ExtCaseReviewMapper {
|
||||
|
||||
List<CaseReview> checkCaseByModuleIds(@Param("moduleIds") List<String> deleteIds);
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?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.ExtCaseReviewMapper">
|
||||
|
||||
<select id="checkCaseByModuleIds" resultType="io.metersphere.functional.domain.CaseReview">
|
||||
SELECT
|
||||
id, name, module_id, create_user
|
||||
FROM
|
||||
case_review
|
||||
WHERE
|
||||
module_id IN
|
||||
<foreach collection="moduleIds" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -0,0 +1,27 @@
|
|||
package io.metersphere.functional.mapper;
|
||||
|
||||
import io.metersphere.project.dto.NodeSortQueryParam;
|
||||
import io.metersphere.system.dto.sdk.BaseModule;
|
||||
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ExtCaseReviewModuleMapper {
|
||||
List<BaseTreeNode> selectBaseByProjectId(@Param("projectId")String projectId);
|
||||
|
||||
List<BaseTreeNode> selectBaseByIds(@Param("ids") List<String> ids);
|
||||
|
||||
List<String> selectChildrenIdsByParentIds(@Param("ids") List<String> deleteIds);
|
||||
|
||||
List<String> selectChildrenIdsSortByPos(String parentId);
|
||||
|
||||
Long getMaxPosByParentId(String parentId);
|
||||
|
||||
BaseModule selectBaseModuleById(String dragNodeId);
|
||||
|
||||
BaseModule selectModuleByParentIdAndPosOperator(NodeSortQueryParam nodeSortQueryParam);
|
||||
|
||||
List<BaseTreeNode> selectIdAndParentIdByProjectId(String projectId);
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
<?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.ExtCaseReviewModuleMapper">
|
||||
<select id="selectBaseByProjectId" resultType="io.metersphere.system.dto.sdk.BaseTreeNode">
|
||||
SELECT id, name, parent_id AS parentId, 'module' AS type
|
||||
FROM case_review_module
|
||||
WHERE project_id = #{projectId}
|
||||
ORDER BY pos
|
||||
</select>
|
||||
<select id="selectBaseByIds" resultType="io.metersphere.system.dto.sdk.BaseTreeNode">
|
||||
SELECT id, name, parent_id AS parentId, 'module' AS type
|
||||
FROM case_review_module
|
||||
WHERE id IN
|
||||
<foreach collection="ids" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
ORDER BY pos
|
||||
</select>
|
||||
<select id="selectModuleByParentIdAndPosOperator"
|
||||
parameterType="io.metersphere.project.dto.NodeSortQueryParam"
|
||||
resultType="io.metersphere.system.dto.sdk.BaseModule">
|
||||
SELECT id, name, pos, project_Id, parent_id
|
||||
FROM case_review_module
|
||||
WHERE parent_id = #{parentId}
|
||||
<if test="operator == 'moreThan'">
|
||||
AND pos > #{pos}
|
||||
</if>
|
||||
<if test="operator == 'lessThan'">
|
||||
AND pos < #{pos}
|
||||
</if>
|
||||
ORDER BY pos
|
||||
<if test="operator == 'lessThan' or operator == 'latest'">
|
||||
DESC
|
||||
</if>
|
||||
LIMIT 1
|
||||
</select>
|
||||
<select id="selectChildrenIdsByParentIds" resultType="java.lang.String">
|
||||
SELECT id FROM case_review_module WHERE parent_id IN
|
||||
<foreach collection="ids" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
<select id="getMaxPosByParentId" resultType="java.lang.Long">
|
||||
SELECT max(pos)
|
||||
FROM case_review_module
|
||||
WHERE parent_id = #{0}
|
||||
</select>
|
||||
<select id="selectChildrenIdsSortByPos" resultType="java.lang.String">
|
||||
SELECT id FROM case_review_module WHERE parent_id = #{0}
|
||||
ORDER BY pos ASC
|
||||
</select>
|
||||
|
||||
<select id="selectBaseModuleById" resultType="io.metersphere.system.dto.sdk.BaseModule">
|
||||
SELECT id, name, pos, project_Id, parent_id
|
||||
FROM case_review_module
|
||||
WHERE id = #{0}
|
||||
</select>
|
||||
|
||||
<select id="selectIdAndParentIdByProjectId" resultType="io.metersphere.system.dto.sdk.BaseTreeNode">
|
||||
SELECT id, parent_id AS parentId
|
||||
FROM case_review_module
|
||||
WHERE project_id = #{0}
|
||||
</select>
|
||||
</mapper>
|
|
@ -0,0 +1,33 @@
|
|||
package io.metersphere.functional.request;
|
||||
|
||||
import io.metersphere.sdk.constants.ModuleConstants;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author guoyuqi
|
||||
*/
|
||||
@Data
|
||||
public class CaseReviewModuleCreateRequest implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{project.id.not_blank}")
|
||||
private String projectId;
|
||||
|
||||
@Schema(description = "模块名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotEmpty(message = "{file_module.name.not_blank}")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "父模块ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotEmpty(message = "{parent.node.not_blank}")
|
||||
private String parentId = ModuleConstants.ROOT_NODE_PARENT_ID;
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package io.metersphere.functional.request;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author guoyuqi
|
||||
*/
|
||||
@Data
|
||||
public class CaseReviewModuleUpdateRequest implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "模块ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{file_module.id.not_blank}")
|
||||
private String id;
|
||||
|
||||
@Schema(description = "模块名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotEmpty(message = "{file_module.name.not_blank}")
|
||||
private String name;
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
package io.metersphere.functional.result;
|
||||
|
||||
public enum DemandPlatform {
|
||||
LOCAL;
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
/**
|
||||
* @filename:CaseReviewModuleServiceImpl 2023年5月17日
|
||||
* @project ms V3.x
|
||||
* Copyright(c) 2018 wx Co. Ltd.
|
||||
* All right reserved.
|
||||
*/
|
||||
package io.metersphere.functional.service;
|
||||
|
||||
|
||||
import io.metersphere.functional.domain.*;
|
||||
import io.metersphere.functional.mapper.*;
|
||||
import io.metersphere.functional.request.CaseReviewModuleCreateRequest;
|
||||
import io.metersphere.functional.request.CaseReviewModuleUpdateRequest;
|
||||
import io.metersphere.project.dto.ModuleCountDTO;
|
||||
import io.metersphere.project.dto.NodeSortDTO;
|
||||
import io.metersphere.project.service.ModuleTreeService;
|
||||
import io.metersphere.sdk.constants.HttpMethodConstants;
|
||||
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.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.uid.IDGenerator;
|
||||
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.mybatis.spring.SqlSessionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class CaseReviewModuleService extends ModuleTreeService {
|
||||
@Resource
|
||||
private CaseReviewModuleMapper caseReviewModuleMapper;
|
||||
@Resource
|
||||
private SqlSessionFactory sqlSessionFactory;
|
||||
@Resource
|
||||
private ExtCaseReviewModuleMapper extCaseReviewModuleMapper;
|
||||
@Resource
|
||||
private ExtCaseReviewMapper extCaseReviewMapper;
|
||||
@Resource
|
||||
private DeleteCaseReviewService deleteCaseReviewService;
|
||||
|
||||
|
||||
@Resource
|
||||
private OperationLogService operationLogService;
|
||||
|
||||
public List<BaseTreeNode> getTree(String projectId) {
|
||||
List<BaseTreeNode> fileModuleList = extCaseReviewModuleMapper.selectBaseByProjectId(projectId);
|
||||
return super.buildTreeAndCountResource(fileModuleList, true, Translator.get("default.module"));
|
||||
}
|
||||
|
||||
public void add(CaseReviewModuleCreateRequest request, String userId) {
|
||||
CaseReviewModule caseReviewModule = new CaseReviewModule();
|
||||
caseReviewModule.setId(IDGenerator.nextStr());
|
||||
caseReviewModule.setName(request.getName());
|
||||
caseReviewModule.setParentId(request.getParentId());
|
||||
caseReviewModule.setProjectId(request.getProjectId());
|
||||
this.checkDataValidity(caseReviewModule);
|
||||
caseReviewModule.setCreateTime(System.currentTimeMillis());
|
||||
caseReviewModule.setUpdateTime(caseReviewModule.getCreateTime());
|
||||
caseReviewModule.setPos(this.countPos(request.getParentId()));
|
||||
caseReviewModule.setCreateUser(userId);
|
||||
caseReviewModule.setUpdateUser(userId);
|
||||
caseReviewModuleMapper.insert(caseReviewModule);
|
||||
}
|
||||
|
||||
public void update(CaseReviewModuleUpdateRequest request, String userId) {
|
||||
CaseReviewModule updateModule = caseReviewModuleMapper.selectByPrimaryKey(request.getId());
|
||||
if (updateModule == null) {
|
||||
throw new MSException(Translator.get("case_module.not.exist"));
|
||||
}
|
||||
updateModule.setName(request.getName());
|
||||
this.checkDataValidity(updateModule);
|
||||
updateModule.setUpdateTime(System.currentTimeMillis());
|
||||
updateModule.setUpdateUser(userId);
|
||||
updateModule.setCreateUser(null);
|
||||
updateModule.setCreateTime(null);
|
||||
caseReviewModuleMapper.updateByPrimaryKeySelective(updateModule);
|
||||
}
|
||||
|
||||
public void moveNode(NodeMoveRequest request, String userId) {
|
||||
NodeSortDTO nodeSortDTO = super.getNodeSortDTO(request,
|
||||
extCaseReviewModuleMapper::selectBaseModuleById,
|
||||
extCaseReviewModuleMapper::selectModuleByParentIdAndPosOperator);
|
||||
|
||||
CaseReviewModuleExample example = new CaseReviewModuleExample();
|
||||
example.createCriteria().andParentIdEqualTo(nodeSortDTO.getParent().getId()).andIdEqualTo(request.getDragNodeId());
|
||||
//节点换到了别的节点下,要先更新parent节点再计算sort
|
||||
if (caseReviewModuleMapper.countByExample(example) == 0) {
|
||||
CaseReviewModule caseReviewModule = new CaseReviewModule();
|
||||
caseReviewModule.setId(request.getDragNodeId());
|
||||
caseReviewModule.setParentId(nodeSortDTO.getParent().getId());
|
||||
caseReviewModule.setUpdateUser(userId);
|
||||
caseReviewModule.setUpdateTime(System.currentTimeMillis());
|
||||
caseReviewModuleMapper.updateByPrimaryKeySelective(caseReviewModule);
|
||||
}
|
||||
super.sort(nodeSortDTO);
|
||||
}
|
||||
|
||||
public void deleteModule(String moduleId) {
|
||||
CaseReviewModule deleteModule = caseReviewModuleMapper.selectByPrimaryKey(moduleId);
|
||||
if (deleteModule != null) {
|
||||
List<CaseReview> caseReviews = this.deleteModuleByIds(Collections.singletonList(moduleId), new ArrayList<>(), deleteModule.getProjectId());
|
||||
batchDelLog(caseReviews, deleteModule.getProjectId());
|
||||
}
|
||||
}
|
||||
|
||||
public void batchDelLog(List<CaseReview> caseReviews, String projectId) {
|
||||
List<LogDTO> dtoList = new ArrayList<>();
|
||||
caseReviews.forEach(item -> {
|
||||
LogDTO dto = new LogDTO(
|
||||
projectId,
|
||||
"",
|
||||
item.getId(),
|
||||
item.getCreateUser(),
|
||||
OperationLogType.DELETE.name(),
|
||||
OperationLogModule.CASE_REVIEW,
|
||||
item.getName());
|
||||
|
||||
dto.setPath("/case/review/module/delete/");
|
||||
dto.setMethod(HttpMethodConstants.GET.name());
|
||||
dto.setOriginalValue(JSON.toJSONBytes(item));
|
||||
dtoList.add(dto);
|
||||
});
|
||||
operationLogService.batchAdd(dtoList);
|
||||
}
|
||||
|
||||
public List<CaseReview> deleteModuleByIds(List<String>deleteIds, List<CaseReview>caseReviews, String projectId){
|
||||
if (CollectionUtils.isEmpty(deleteIds)) {
|
||||
return caseReviews;
|
||||
}
|
||||
CaseReviewModuleExample caseReviewModuleExample = new CaseReviewModuleExample();
|
||||
caseReviewModuleExample.createCriteria().andIdIn(deleteIds);
|
||||
caseReviewModuleMapper.deleteByExample(caseReviewModuleExample);
|
||||
List<CaseReview> caseReviewList = extCaseReviewMapper.checkCaseByModuleIds(deleteIds);
|
||||
if (CollectionUtils.isNotEmpty(caseReviewList)) {
|
||||
caseReviews.addAll(caseReviewList);
|
||||
}
|
||||
deleteCaseReviewService.deleteCaseReviewResource(deleteIds, projectId);
|
||||
List<String> childrenIds = extCaseReviewModuleMapper.selectChildrenIdsByParentIds(deleteIds);
|
||||
if (CollectionUtils.isNotEmpty(childrenIds)) {
|
||||
deleteModuleByIds(childrenIds, caseReviews, projectId);
|
||||
}
|
||||
return caseReviews;
|
||||
}
|
||||
|
||||
private Long countPos(String parentId) {
|
||||
Long maxPos = extCaseReviewModuleMapper.getMaxPosByParentId(parentId);
|
||||
if (maxPos == null) {
|
||||
return LIMIT_POS;
|
||||
} else {
|
||||
return maxPos + LIMIT_POS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找当前项目下模块每个节点对应的资源统计
|
||||
*
|
||||
*/
|
||||
public Map<String, Long> getModuleCountMap(String projectId, List<ModuleCountDTO> moduleCountDTOList) {
|
||||
|
||||
//构建模块树,并计算每个节点下的所有数量(包含子节点)
|
||||
List<BaseTreeNode> treeNodeList = this.getTreeOnlyIdsAndResourceCount(projectId, moduleCountDTOList);
|
||||
//通过广度遍历的方式构建返回值
|
||||
return super.getIdCountMapByBreadth(treeNodeList);
|
||||
}
|
||||
|
||||
public List<BaseTreeNode> getTreeOnlyIdsAndResourceCount(String projectId, List<ModuleCountDTO> moduleCountDTOList) {
|
||||
//节点内容只有Id和parentId
|
||||
List<BaseTreeNode> fileModuleList = extCaseReviewModuleMapper.selectIdAndParentIdByProjectId(projectId);
|
||||
return super.buildTreeAndCountResource(fileModuleList, moduleCountDTOList, true, Translator.get("default.module"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查数据的合法性
|
||||
*/
|
||||
private void checkDataValidity(CaseReviewModule caseReviewModule) {
|
||||
CaseReviewModuleExample example = new CaseReviewModuleExample();
|
||||
if (!StringUtils.equals(caseReviewModule.getParentId(), ModuleConstants.ROOT_NODE_PARENT_ID)) {
|
||||
//检查父ID是否存在
|
||||
example.createCriteria().andIdEqualTo(caseReviewModule.getParentId());
|
||||
if (caseReviewModuleMapper.countByExample(example) == 0) {
|
||||
throw new MSException(Translator.get("parent.node.not_blank"));
|
||||
}
|
||||
example.clear();
|
||||
|
||||
if (StringUtils.isNotBlank(caseReviewModule.getProjectId())) {
|
||||
//检查项目ID是否和父节点ID一致
|
||||
example.createCriteria().andProjectIdEqualTo(caseReviewModule.getProjectId()).andIdEqualTo(caseReviewModule.getParentId());
|
||||
if (caseReviewModuleMapper.countByExample(example) == 0) {
|
||||
throw new MSException(Translator.get("project.cannot.match.parent"));
|
||||
}
|
||||
example.clear();
|
||||
}
|
||||
}
|
||||
example.createCriteria().andParentIdEqualTo(caseReviewModule.getParentId()).andNameEqualTo(caseReviewModule.getName()).andIdNotEqualTo(caseReviewModule.getId());
|
||||
if (caseReviewModuleMapper.countByExample(example) > 0) {
|
||||
throw new MSException(Translator.get("node.name.repeat"));
|
||||
}
|
||||
example.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePos(String id, long pos) {
|
||||
CaseReviewModule updateModule = new CaseReviewModule();
|
||||
updateModule.setPos(pos);
|
||||
updateModule.setId(id);
|
||||
caseReviewModuleMapper.updateByPrimaryKeySelective(updateModule);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshPos(String parentId) {
|
||||
List<String> childrenIdSortByPos = extCaseReviewModuleMapper.selectChildrenIdsSortByPos(parentId);
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
CaseReviewModuleMapper batchUpdateMapper = sqlSession.getMapper(CaseReviewModuleMapper.class);
|
||||
for (int i = 0; i < childrenIdSortByPos.size(); i++) {
|
||||
String nodeId = childrenIdSortByPos.get(i);
|
||||
CaseReviewModule updateModule = new CaseReviewModule();
|
||||
updateModule.setId(nodeId);
|
||||
updateModule.setPos((i + 1) * LIMIT_POS);
|
||||
batchUpdateMapper.updateByPrimaryKeySelective(updateModule);
|
||||
}
|
||||
sqlSession.flushStatements();
|
||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package io.metersphere.functional.service;
|
||||
|
||||
import io.metersphere.functional.domain.*;
|
||||
import io.metersphere.functional.mapper.*;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author guoyuqi
|
||||
*/
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class DeleteCaseReviewService {
|
||||
|
||||
@Resource
|
||||
private CaseReviewMapper caseReviewMapper;
|
||||
@Resource
|
||||
private CaseReviewUserMapper caseReviewUserMapper;
|
||||
@Resource
|
||||
private CaseReviewFunctionalCaseMapper caseReviewFunctionalCaseMapper;
|
||||
@Resource
|
||||
private CaseReviewFunctionalCaseArchiveMapper caseReviewFunctionalCaseArchiveMapper;
|
||||
@Resource
|
||||
private CaseReviewFollowerMapper caseReviewFollowerMapper;
|
||||
@Resource
|
||||
private CaseReviewHistoryMapper caseReviewHistoryMapper;
|
||||
|
||||
public void deleteCaseReviewResource(List<String> ids, String projectId) {
|
||||
//TODO 删除各种关联关系? 1.关联用例(功能/接口/场景/ui/性能)? 2.评审和评审人 3. 归档的用例 4. 关注人 5.评审历史 6. 操作记录
|
||||
//1.刪除评审与功能用例关联关系
|
||||
CaseReviewFunctionalCaseExample caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
||||
caseReviewFunctionalCaseExample.createCriteria().andReviewIdIn(ids);
|
||||
caseReviewFunctionalCaseMapper.deleteByExample(caseReviewFunctionalCaseExample);
|
||||
//2. 删除评审和评审人
|
||||
CaseReviewUserExample caseReviewUserExample = new CaseReviewUserExample();
|
||||
caseReviewUserExample.createCriteria().andReviewIdIn(ids);
|
||||
caseReviewUserMapper.deleteByExample(caseReviewUserExample);
|
||||
//3. 删除归档的用例
|
||||
CaseReviewFunctionalCaseArchiveExample archiveExample = new CaseReviewFunctionalCaseArchiveExample();
|
||||
archiveExample.createCriteria().andReviewIdIn(ids);
|
||||
caseReviewFunctionalCaseArchiveMapper.deleteByExample(archiveExample);
|
||||
//4.删除关注人
|
||||
CaseReviewFollowerExample caseReviewFollowerExample = new CaseReviewFollowerExample();
|
||||
caseReviewFollowerExample.createCriteria().andReviewIdIn(ids);
|
||||
caseReviewFollowerMapper.deleteByExample(caseReviewFollowerExample);
|
||||
//5.删除评审历史
|
||||
CaseReviewHistoryExample caseReviewHistoryExample = new CaseReviewHistoryExample();
|
||||
caseReviewHistoryExample.createCriteria().andReviewIdIn(ids);
|
||||
caseReviewHistoryMapper.deleteByExample(caseReviewHistoryExample);
|
||||
//TODO: 6.删除操作记录
|
||||
//删除评审
|
||||
CaseReviewExample caseReviewExample = new CaseReviewExample();
|
||||
caseReviewExample.createCriteria().andIdIn(ids).andProjectIdEqualTo(projectId);
|
||||
caseReviewMapper.deleteByExample(caseReviewExample);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,764 @@
|
|||
package io.metersphere.functional.controller;
|
||||
|
||||
import io.metersphere.functional.constants.CaseReviewPassRule;
|
||||
import io.metersphere.functional.constants.CaseReviewStatus;
|
||||
import io.metersphere.functional.domain.CaseReview;
|
||||
import io.metersphere.functional.domain.CaseReviewModule;
|
||||
import io.metersphere.functional.domain.CaseReviewModuleExample;
|
||||
import io.metersphere.functional.mapper.CaseReviewMapper;
|
||||
import io.metersphere.functional.mapper.CaseReviewModuleMapper;
|
||||
import io.metersphere.functional.request.CaseReviewModuleCreateRequest;
|
||||
import io.metersphere.functional.request.CaseReviewModuleUpdateRequest;
|
||||
import io.metersphere.functional.service.CaseReviewModuleService;
|
||||
import io.metersphere.project.domain.Project;
|
||||
import io.metersphere.project.mapper.ProjectMapper;
|
||||
import io.metersphere.sdk.constants.ModuleConstants;
|
||||
import io.metersphere.sdk.constants.SessionConstants;
|
||||
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.BaseTreeNode;
|
||||
import io.metersphere.system.dto.sdk.request.NodeMoveRequest;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.testcontainers.shaded.org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
@AutoConfigureMockMvc
|
||||
public class CaseReviewModuleControllerTests extends BaseTest {
|
||||
|
||||
private static Project project;
|
||||
private static final String URL_MODULE_TREE = "/case/review/module/tree/";
|
||||
private static final String URL_MODULE_TREE_ADD = "/case/review/module/add";
|
||||
private static final String URL_MODULE_TREE_UPDATE = "/case/review/module/update";
|
||||
|
||||
private static List<BaseTreeNode> preliminaryTreeNodes = new ArrayList<>();
|
||||
|
||||
private static final String URL_MODULE_TREE_MOVE = "/case/review/module/move";
|
||||
private static final String URL_MODULE_TREE_DELETE = "/case/review/module/delete/";
|
||||
|
||||
|
||||
@Resource
|
||||
private CaseReviewModuleService caseReviewModuleService;
|
||||
@Resource
|
||||
private CaseReviewModuleMapper caseReviewModuleMapper;
|
||||
@Resource
|
||||
private CaseReviewMapper caseReviewMapper;
|
||||
@Resource
|
||||
private ProjectMapper projectMapper;
|
||||
|
||||
@BeforeEach
|
||||
public void initTestData() {
|
||||
if (project == null) {
|
||||
Project initProject = new Project();
|
||||
initProject.setId(IDGenerator.nextStr());
|
||||
initProject.setNum(null);
|
||||
initProject.setOrganizationId("100001");
|
||||
initProject.setName("caseReviewModuleTestProject");
|
||||
initProject.setDescription("caseReviewModuleTestProject");
|
||||
initProject.setCreateUser("admin");
|
||||
initProject.setUpdateUser("admin");
|
||||
initProject.setCreateTime(System.currentTimeMillis());
|
||||
initProject.setUpdateTime(System.currentTimeMillis());
|
||||
initProject.setEnable(true);
|
||||
initProject.setModuleSetting("[\"apiTest\",\"uiTest\"]");
|
||||
projectMapper.insertSelective(initProject);
|
||||
project = projectMapper.selectByPrimaryKey(initProject.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(1)
|
||||
public void emptyDataTest() throws Exception {
|
||||
//空数据下,检查模块树
|
||||
List<BaseTreeNode> treeNodes = this.getCaseReviewModuleTreeNode();
|
||||
//检查有没有默认节点
|
||||
boolean hasNode = false;
|
||||
for (BaseTreeNode baseTreeNode : treeNodes) {
|
||||
if (StringUtils.equals(baseTreeNode.getId(), ModuleConstants.DEFAULT_NODE_ID)) {
|
||||
hasNode = true;
|
||||
}
|
||||
Assertions.assertNotNull(baseTreeNode.getParentId());
|
||||
}
|
||||
Assertions.assertTrue(hasNode);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(2)
|
||||
public void addModuleTestSuccess() throws Exception {
|
||||
//根目录下创建节点(a1)
|
||||
CaseReviewModuleCreateRequest request = new CaseReviewModuleCreateRequest();
|
||||
request.setProjectId(project.getId());
|
||||
request.setName("a1");
|
||||
MvcResult mvcResult = this.requestPostWithOkAndReturn(URL_MODULE_TREE_ADD, request);
|
||||
String returnId = mvcResult.getResponse().getContentAsString();
|
||||
Assertions.assertNotNull(returnId);
|
||||
List<BaseTreeNode> treeNodes = this.getCaseReviewModuleTreeNode();
|
||||
BaseTreeNode a1Node = null;
|
||||
for (BaseTreeNode baseTreeNode : treeNodes) {
|
||||
if (StringUtils.equals(baseTreeNode.getName(), request.getName())) {
|
||||
a1Node = baseTreeNode;
|
||||
}
|
||||
Assertions.assertNotNull(baseTreeNode.getParentId());
|
||||
}
|
||||
Assertions.assertNotNull(a1Node);
|
||||
|
||||
//根目录下创建节点a2和a3,在a1下创建子节点a1-b1
|
||||
request = new CaseReviewModuleCreateRequest();
|
||||
request.setProjectId(project.getId());
|
||||
request.setName("a2");
|
||||
this.requestPostWithOkAndReturn(URL_MODULE_TREE_ADD, request);
|
||||
|
||||
request.setName("a3");
|
||||
this.requestPostWithOkAndReturn(URL_MODULE_TREE_ADD, request);
|
||||
|
||||
request = new CaseReviewModuleCreateRequest();
|
||||
request.setProjectId(project.getId());
|
||||
request.setName("a1-b1");
|
||||
request.setParentId(a1Node.getId());
|
||||
this.requestPostWithOkAndReturn(URL_MODULE_TREE_ADD, request);
|
||||
|
||||
treeNodes = this.getCaseReviewModuleTreeNode();
|
||||
BaseTreeNode a1b1Node = null;
|
||||
BaseTreeNode a2Node = null;
|
||||
for (BaseTreeNode baseTreeNode : treeNodes) {
|
||||
Assertions.assertNotNull(baseTreeNode.getParentId());
|
||||
if (StringUtils.equals(baseTreeNode.getName(), "a1") && CollectionUtils.isNotEmpty(baseTreeNode.getChildren())) {
|
||||
for (BaseTreeNode childNode : baseTreeNode.getChildren()) {
|
||||
if (StringUtils.equals(childNode.getName(), "a1-b1")) {
|
||||
a1b1Node = childNode;
|
||||
}
|
||||
Assertions.assertNotNull(childNode.getParentId());
|
||||
}
|
||||
} else if (StringUtils.equals(baseTreeNode.getName(), "a2")) {
|
||||
a2Node = baseTreeNode;
|
||||
}
|
||||
}
|
||||
Assertions.assertNotNull(a2Node);
|
||||
Assertions.assertNotNull(a1b1Node);
|
||||
|
||||
//a1节点下可以继续添加a1节点
|
||||
request = new CaseReviewModuleCreateRequest();
|
||||
request.setProjectId(project.getId());
|
||||
request.setName("a1");
|
||||
request.setParentId(a1Node.getId());
|
||||
this.requestPostWithOkAndReturn(URL_MODULE_TREE_ADD, request);
|
||||
|
||||
//继续创建a1下继续创建a1-a1-b1,
|
||||
treeNodes = this.getCaseReviewModuleTreeNode();
|
||||
BaseTreeNode a1ChildNode = null;
|
||||
for (BaseTreeNode baseTreeNode : treeNodes) {
|
||||
Assertions.assertNotNull(baseTreeNode.getParentId());
|
||||
if (StringUtils.equals(baseTreeNode.getName(), "a1") && CollectionUtils.isNotEmpty(baseTreeNode.getChildren())) {
|
||||
for (BaseTreeNode childNode : baseTreeNode.getChildren()) {
|
||||
Assertions.assertNotNull(childNode.getParentId());
|
||||
if (StringUtils.equals(childNode.getName(), "a1")) {
|
||||
a1ChildNode = childNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Assertions.assertNotNull(a1ChildNode);
|
||||
|
||||
//a1的子节点a1下继续创建节点a1-a1-c1
|
||||
request = new CaseReviewModuleCreateRequest();
|
||||
request.setProjectId(project.getId());
|
||||
request.setName("a1-a1-c1");
|
||||
request.setParentId(a1ChildNode.getId());
|
||||
this.requestPostWithOkAndReturn(URL_MODULE_TREE_ADD, request);
|
||||
treeNodes = this.getCaseReviewModuleTreeNode();
|
||||
BaseTreeNode a1a1c1Node = null;
|
||||
for (BaseTreeNode baseTreeNode : treeNodes) {
|
||||
Assertions.assertNotNull(baseTreeNode.getParentId());
|
||||
if (StringUtils.equals(baseTreeNode.getName(), "a1") && CollectionUtils.isNotEmpty(baseTreeNode.getChildren())) {
|
||||
for (BaseTreeNode secondNode : baseTreeNode.getChildren()) {
|
||||
Assertions.assertNotNull(secondNode.getParentId());
|
||||
if (StringUtils.equals(secondNode.getName(), "a1") && CollectionUtils.isNotEmpty(secondNode.getChildren())) {
|
||||
for (BaseTreeNode thirdNode : secondNode.getChildren()) {
|
||||
Assertions.assertNotNull(thirdNode.getParentId());
|
||||
if (StringUtils.equals(thirdNode.getName(), "a1-a1-c1")) {
|
||||
a1a1c1Node = thirdNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Assertions.assertNotNull(a1a1c1Node);
|
||||
|
||||
//子节点a1-b1下继续创建节点a1-b1-c1
|
||||
request = new CaseReviewModuleCreateRequest();
|
||||
request.setProjectId(project.getId());
|
||||
request.setName("a1-b1-c1");
|
||||
request.setParentId(a1b1Node.getId());
|
||||
this.requestPostWithOkAndReturn(URL_MODULE_TREE_ADD, request);
|
||||
treeNodes = this.getCaseReviewModuleTreeNode();
|
||||
BaseTreeNode a1b1c1Node = null;
|
||||
for (BaseTreeNode baseTreeNode : treeNodes) {
|
||||
if (StringUtils.equals(baseTreeNode.getName(), "a1") && CollectionUtils.isNotEmpty(baseTreeNode.getChildren())) {
|
||||
for (BaseTreeNode secondNode : baseTreeNode.getChildren()) {
|
||||
if (StringUtils.equals(secondNode.getName(), "a1-b1") && CollectionUtils.isNotEmpty(secondNode.getChildren())) {
|
||||
for (BaseTreeNode thirdNode : secondNode.getChildren()) {
|
||||
if (StringUtils.equals(thirdNode.getName(), "a1-b1-c1")) {
|
||||
a1b1c1Node = thirdNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Assertions.assertNotNull(a1b1c1Node);
|
||||
preliminaryTreeNodes = treeNodes;
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(3)
|
||||
public void addModuleTestError() throws Exception {
|
||||
this.preliminaryData();
|
||||
|
||||
BaseTreeNode a1Node = getNodeByName(preliminaryTreeNodes, "a1");
|
||||
assert a1Node != null;
|
||||
|
||||
//参数校验
|
||||
CaseReviewModuleCreateRequest request = new CaseReviewModuleCreateRequest();
|
||||
request.setProjectId(project.getId());
|
||||
this.requestPost(URL_MODULE_TREE_ADD, request).andExpect(status().isBadRequest());
|
||||
request = new CaseReviewModuleCreateRequest();
|
||||
request.setName("none");
|
||||
this.requestPost(URL_MODULE_TREE_ADD, request).andExpect(status().isBadRequest());
|
||||
request = new CaseReviewModuleCreateRequest();
|
||||
this.requestPost(URL_MODULE_TREE_ADD, request).andExpect(status().isBadRequest());
|
||||
request = new CaseReviewModuleCreateRequest();
|
||||
request.setParentId(null);
|
||||
this.requestPost(URL_MODULE_TREE_ADD, request).andExpect(status().isBadRequest());
|
||||
|
||||
//父节点ID不存在的
|
||||
request = new CaseReviewModuleCreateRequest();
|
||||
request.setProjectId(project.getId());
|
||||
request.setName("ParentIsUUID");
|
||||
request.setParentId(IDGenerator.nextStr());
|
||||
this.requestPost(URL_MODULE_TREE_ADD, request).andExpect(status().is5xxServerError());
|
||||
|
||||
//添加重复的a1节点
|
||||
request = new CaseReviewModuleCreateRequest();
|
||||
request.setProjectId(project.getId());
|
||||
request.setName("a1");
|
||||
this.requestPost(URL_MODULE_TREE_ADD, request).andExpect(status().is5xxServerError());
|
||||
|
||||
//a1节点下添加重复的a1-b1节点
|
||||
request = new CaseReviewModuleCreateRequest();
|
||||
request.setProjectId(project.getId());
|
||||
request.setName("a1-b1");
|
||||
request.setParentId(a1Node.getId());
|
||||
this.requestPost(URL_MODULE_TREE_ADD, request).andExpect(status().is5xxServerError());
|
||||
|
||||
//子节点的项目ID和父节点的不匹配
|
||||
request = new CaseReviewModuleCreateRequest();
|
||||
request.setProjectId(IDGenerator.nextStr());
|
||||
request.setName("RandomUUID");
|
||||
request.setParentId(a1Node.getId());
|
||||
this.requestPost(URL_MODULE_TREE_ADD, request).andExpect(status().is5xxServerError());
|
||||
|
||||
//项目ID和父节点的不匹配
|
||||
request = new CaseReviewModuleCreateRequest();
|
||||
request.setProjectId("100001100001");
|
||||
request.setName("RandomUUID");
|
||||
request.setParentId(a1Node.getId());
|
||||
this.requestPost(URL_MODULE_TREE_ADD, request).andExpect(status().is5xxServerError());
|
||||
}
|
||||
|
||||
public static BaseTreeNode getNodeByName(List<BaseTreeNode> preliminaryTreeNodes, String nodeName) {
|
||||
for (BaseTreeNode firstLevelNode : preliminaryTreeNodes) {
|
||||
if (StringUtils.equals(firstLevelNode.getName(), nodeName)) {
|
||||
return firstLevelNode;
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(firstLevelNode.getChildren())) {
|
||||
for (BaseTreeNode secondLevelNode : firstLevelNode.getChildren()) {
|
||||
if (StringUtils.equals(secondLevelNode.getName(), nodeName)) {
|
||||
return secondLevelNode;
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(secondLevelNode.getChildren())) {
|
||||
for (BaseTreeNode thirdLevelNode : secondLevelNode.getChildren()) {
|
||||
if (StringUtils.equals(thirdLevelNode.getName(), nodeName)) {
|
||||
return thirdLevelNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(4)
|
||||
public void updateModuleTestSuccess() throws Exception {
|
||||
if (CollectionUtils.isEmpty(preliminaryTreeNodes)) {
|
||||
this.addModuleTestSuccess();
|
||||
}
|
||||
//更改名称
|
||||
BaseTreeNode a1Node = null;
|
||||
for (BaseTreeNode node : preliminaryTreeNodes) {
|
||||
if (StringUtils.equals(node.getName(), "a1")) {
|
||||
for (BaseTreeNode a1ChildrenNode : node.getChildren()) {
|
||||
if (StringUtils.equals(a1ChildrenNode.getName(), "a1")) {
|
||||
a1Node = a1ChildrenNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert a1Node != null;
|
||||
CaseReviewModuleUpdateRequest updateRequest = new CaseReviewModuleUpdateRequest();
|
||||
updateRequest.setId(a1Node.getId());
|
||||
updateRequest.setName("a1-a1");
|
||||
this.requestPostWithOkAndReturn(URL_MODULE_TREE_UPDATE, updateRequest);
|
||||
|
||||
preliminaryTreeNodes = this.getCaseReviewModuleTreeNode();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(5)
|
||||
public void updateModuleTestError() throws Exception {
|
||||
BaseTreeNode a1Node = getNodeByName(preliminaryTreeNodes, "a1-a1");
|
||||
assert a1Node != null;
|
||||
//反例-参数校验
|
||||
CaseReviewModuleUpdateRequest updateRequest = new CaseReviewModuleUpdateRequest();
|
||||
this.requestPost(URL_MODULE_TREE_UPDATE, updateRequest).andExpect(status().isBadRequest());
|
||||
|
||||
//id不存在
|
||||
updateRequest = new CaseReviewModuleUpdateRequest();
|
||||
updateRequest.setId(IDGenerator.nextStr());
|
||||
updateRequest.setName(IDGenerator.nextStr());
|
||||
this.requestPost(URL_MODULE_TREE_UPDATE, updateRequest).andExpect(status().is5xxServerError());
|
||||
|
||||
//名称重复 a1-a1改为a1-b1
|
||||
updateRequest = new CaseReviewModuleUpdateRequest();
|
||||
updateRequest.setId(a1Node.getId());
|
||||
updateRequest.setName("a1-b1");
|
||||
this.requestPost(URL_MODULE_TREE_UPDATE, updateRequest).andExpect(status().is5xxServerError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void moveTest() throws Exception {
|
||||
this.preliminaryData();
|
||||
/*
|
||||
*默认节点
|
||||
|
|
||||
·a1 +
|
||||
| |
|
||||
| ·a1-b1 +
|
||||
| | |
|
||||
| | ·a1-b1-c1
|
||||
| |
|
||||
| *a1-a1 +(创建的时候是a1,通过修改改为a1-a1)
|
||||
| |
|
||||
| ·a1-a1-c1
|
||||
|
|
||||
·a2
|
||||
|
|
||||
·a3
|
||||
*/
|
||||
BaseTreeNode a1Node = getNodeByName(preliminaryTreeNodes, "a1");
|
||||
BaseTreeNode a2Node = getNodeByName(preliminaryTreeNodes, "a2");
|
||||
BaseTreeNode a3Node = getNodeByName(preliminaryTreeNodes, "a3");
|
||||
BaseTreeNode a1a1Node = getNodeByName(preliminaryTreeNodes, "a1-a1");
|
||||
BaseTreeNode a1b1Node = getNodeByName(preliminaryTreeNodes, "a1-b1");
|
||||
|
||||
//父节点内移动-移动到首位 a1挪到a3后面
|
||||
NodeMoveRequest request = new NodeMoveRequest();
|
||||
{
|
||||
request.setDragNodeId(a1Node.getId());
|
||||
request.setDropNodeId(a3Node.getId());
|
||||
request.setDropPosition(1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a3Node.getId(), a1Node.getId(), null, false);
|
||||
}
|
||||
//父节点内移动-移动到末位 在上面的基础上,a1挪到a2上面
|
||||
{
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a1Node.getId());
|
||||
request.setDropNodeId(a2Node.getId());
|
||||
request.setDropPosition(-1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a1Node.getId(), a2Node.getId(), null, false);
|
||||
}
|
||||
|
||||
//父节点内移动-移动到中位 a1移动到a2-a3中间
|
||||
{
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a1Node.getId());
|
||||
request.setDropNodeId(a2Node.getId());
|
||||
request.setDropPosition(1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a2Node.getId(), a1Node.getId(), a3Node.getId(), false);
|
||||
//移动回去
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a1Node.getId());
|
||||
request.setDropNodeId(a2Node.getId());
|
||||
request.setDropPosition(-1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a1Node.getId(), a2Node.getId(), null, false);
|
||||
}
|
||||
|
||||
//跨节点移动-移动到首位 a3移动到a1-b1前面,然后移动回来;
|
||||
{
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a3Node.getId());
|
||||
request.setDropNodeId(a1b1Node.getId());
|
||||
request.setDropPosition(-1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a3Node.getId(), a1b1Node.getId(), null, false);
|
||||
//移动回去
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a3Node.getId());
|
||||
request.setDropNodeId(a2Node.getId());
|
||||
request.setDropPosition(1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a2Node.getId(), a3Node.getId(), null, false);
|
||||
}
|
||||
|
||||
//跨节点移动-移动到末尾 a3移动到a1-a1后面,然后移动回来;
|
||||
{
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a3Node.getId());
|
||||
request.setDropNodeId(a1a1Node.getId());
|
||||
request.setDropPosition(1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a1a1Node.getId(), a3Node.getId(), null, false);
|
||||
//移动回去
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a3Node.getId());
|
||||
request.setDropNodeId(a2Node.getId());
|
||||
request.setDropPosition(1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a2Node.getId(), a3Node.getId(), null, false);
|
||||
}
|
||||
|
||||
//跨节点移动-移动到中位 a3移动到a1-b1和a1-a1中间,然后移动回来;
|
||||
{
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a3Node.getId());
|
||||
request.setDropNodeId(a1b1Node.getId());
|
||||
request.setDropPosition(1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a1b1Node.getId(), a3Node.getId(), a1a1Node.getId(), false);
|
||||
//移动回去
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a3Node.getId());
|
||||
request.setDropNodeId(a2Node.getId());
|
||||
request.setDropPosition(1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a2Node.getId(), a3Node.getId(), null, false);
|
||||
}
|
||||
|
||||
//父节点内移动-a3移动到首位pos小于2,是否触发计算函数 (先手动更改a1的pos为2,然后移动a3到a1前面)
|
||||
{
|
||||
//更改pos
|
||||
CaseReviewModule updateModule = new CaseReviewModule();
|
||||
updateModule.setId(a1Node.getId());
|
||||
updateModule.setPos(2L);
|
||||
caseReviewModuleMapper.updateByPrimaryKeySelective(updateModule);
|
||||
|
||||
//开始移动
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a3Node.getId());
|
||||
request.setDropNodeId(a1Node.getId());
|
||||
request.setDropPosition(-1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a3Node.getId(), a1Node.getId(), null, true);
|
||||
|
||||
//移动回去
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a3Node.getId());
|
||||
request.setDropNodeId(a2Node.getId());
|
||||
request.setDropPosition(1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a2Node.getId(), a3Node.getId(), null, false);
|
||||
}
|
||||
|
||||
//父节点内移动-移动到中位,前后节点pos差不大于2,是否触发计算函数(在上面的 a3-a1-a2的基础上, 先手动更改a1pos为3*64,a2的pos为3*64+2,然后移动a3到a1和a2中间)
|
||||
{
|
||||
//更改pos
|
||||
CaseReviewModule updateModule = new CaseReviewModule();
|
||||
updateModule.setId(a1Node.getId());
|
||||
updateModule.setPos(3 * 64L);
|
||||
caseReviewModuleMapper.updateByPrimaryKeySelective(updateModule);
|
||||
updateModule.setId(a2Node.getId());
|
||||
updateModule.setPos(3 * 64 + 2L);
|
||||
caseReviewModuleMapper.updateByPrimaryKeySelective(updateModule);
|
||||
|
||||
//开始移动
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a3Node.getId());
|
||||
request.setDropNodeId(a1Node.getId());
|
||||
request.setDropPosition(1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a1Node.getId(), a3Node.getId(), a2Node.getId(), true);
|
||||
|
||||
//移动回去
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a3Node.getId());
|
||||
request.setDropNodeId(a2Node.getId());
|
||||
request.setDropPosition(1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a2Node.getId(), a3Node.getId(), null, false);
|
||||
}
|
||||
//跨节点移动-移动到首位pos小于2,是否触发计算函数(先手动更改a1-b1的pos为2,然后移动a3到a1-b1前面,最后再移动回来)
|
||||
{
|
||||
//更改pos
|
||||
CaseReviewModule updateModule = new CaseReviewModule();
|
||||
updateModule.setId(a1b1Node.getId());
|
||||
updateModule.setPos(2L);
|
||||
caseReviewModuleMapper.updateByPrimaryKeySelective(updateModule);
|
||||
|
||||
//开始移动
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a3Node.getId());
|
||||
request.setDropNodeId(a1b1Node.getId());
|
||||
request.setDropPosition(-1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a3Node.getId(), a1b1Node.getId(), null, true);
|
||||
|
||||
//移动回去
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a3Node.getId());
|
||||
request.setDropNodeId(a2Node.getId());
|
||||
request.setDropPosition(1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a2Node.getId(), a3Node.getId(), null, false);
|
||||
}
|
||||
//跨节点移动-移动到中位,前后节点pos差不大于2,是否触发计算函数先手动更改a1-a1的pos为a1-b1+2,然后移动a3到a1-a1前面,最后再移动回来)
|
||||
{
|
||||
//更改pos
|
||||
CaseReviewModule updateModule = new CaseReviewModule();
|
||||
updateModule.setId(a1b1Node.getId());
|
||||
updateModule.setPos(3 * 64L);
|
||||
caseReviewModuleMapper.updateByPrimaryKeySelective(updateModule);
|
||||
updateModule.setId(a1a1Node.getId());
|
||||
updateModule.setPos(3 * 64 + 2L);
|
||||
caseReviewModuleMapper.updateByPrimaryKeySelective(updateModule);
|
||||
|
||||
//开始移动
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a3Node.getId());
|
||||
request.setDropNodeId(a1a1Node.getId());
|
||||
request.setDropPosition(-1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a1b1Node.getId(), a3Node.getId(), a1a1Node.getId(), true);
|
||||
|
||||
//移动回去
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a3Node.getId());
|
||||
request.setDropNodeId(a2Node.getId());
|
||||
request.setDropPosition(1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a2Node.getId(), a3Node.getId(), null, false);
|
||||
}
|
||||
//移动到没有子节点的节点下 a3移动到a2下
|
||||
{
|
||||
//开始移动
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a3Node.getId());
|
||||
request.setDropNodeId(a2Node.getId());
|
||||
request.setDropPosition(0);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
CaseReviewModule a3Module = caseReviewModuleMapper.selectByPrimaryKey(a3Node.getId());
|
||||
Assertions.assertEquals(a3Module.getParentId(), a2Node.getId());
|
||||
|
||||
//移动回去
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a3Node.getId());
|
||||
request.setDropNodeId(a2Node.getId());
|
||||
request.setDropPosition(1);
|
||||
this.requestPostWithOk(URL_MODULE_TREE_MOVE, request);
|
||||
this.checkModulePos(a2Node.getId(), a3Node.getId(), null, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(7)
|
||||
public void moveTestError() throws Exception {
|
||||
this.preliminaryData();
|
||||
BaseTreeNode a1Node = getNodeByName(preliminaryTreeNodes, "a1");
|
||||
BaseTreeNode a2Node = getNodeByName(preliminaryTreeNodes, "a2");
|
||||
//drag节点为空
|
||||
NodeMoveRequest request = new NodeMoveRequest();
|
||||
request.setDragNodeId(null);
|
||||
request.setDropNodeId(a1Node.getId());
|
||||
request.setDropPosition(1);
|
||||
this.requestPost(URL_MODULE_TREE_MOVE, request).andExpect(status().isBadRequest());
|
||||
//drag节点不存在
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(IDGenerator.nextStr());
|
||||
request.setDropNodeId(a1Node.getId());
|
||||
request.setDropPosition(1);
|
||||
this.requestPost(URL_MODULE_TREE_MOVE, request).andExpect(status().is5xxServerError());
|
||||
|
||||
//drop节点为空
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a1Node.getId());
|
||||
request.setDropNodeId(null);
|
||||
request.setDropPosition(1);
|
||||
this.requestPost(URL_MODULE_TREE_MOVE, request).andExpect(status().isBadRequest());
|
||||
|
||||
//drop节点不存在
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a1Node.getId());
|
||||
request.setDropNodeId(IDGenerator.nextStr());
|
||||
request.setDropPosition(1);
|
||||
this.requestPost(URL_MODULE_TREE_MOVE, request).andExpect(status().is5xxServerError());
|
||||
|
||||
//position为0的时候节点不存在
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a1Node.getId());
|
||||
request.setDropNodeId(IDGenerator.nextStr());
|
||||
request.setDropPosition(0);
|
||||
this.requestPost(URL_MODULE_TREE_MOVE, request).andExpect(status().is5xxServerError());
|
||||
|
||||
//dragNode和dropNode一样
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a1Node.getId());
|
||||
request.setDropNodeId(a1Node.getId());
|
||||
request.setDropPosition(1);
|
||||
this.requestPost(URL_MODULE_TREE_MOVE, request).andExpect(status().is5xxServerError());
|
||||
|
||||
//position不是-1 0 1
|
||||
request = new NodeMoveRequest();
|
||||
request.setDragNodeId(a1Node.getId());
|
||||
request.setDropNodeId(a2Node.getId());
|
||||
request.setDropPosition(4);
|
||||
this.requestPost(URL_MODULE_TREE_MOVE, request).andExpect(status().is5xxServerError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(8)
|
||||
public void deleteModuleTestSuccess() throws Exception {
|
||||
this.preliminaryData();
|
||||
|
||||
// 删除没有用例的节点a1-b1-c1 检查是否级联删除根节点
|
||||
BaseTreeNode a1b1Node = getNodeByName(this.getCaseReviewModuleTreeNode(), "a1-b1");
|
||||
assert a1b1Node != null;
|
||||
this.requestGetWithOk(URL_MODULE_TREE_DELETE+a1b1Node.getId());
|
||||
this.checkModuleIsEmpty(a1b1Node.getId());
|
||||
|
||||
// 删除有用例的节点 a1-a1 检查是否级联删除根节点
|
||||
//创建数据
|
||||
BaseTreeNode a1a1Node = getNodeByName(this.getCaseReviewModuleTreeNode(), "a1-a1");
|
||||
CaseReview name = createCaseReview(a1a1Node, "name");
|
||||
CaseReview caseReview = caseReviewMapper.selectByPrimaryKey(name.getId());
|
||||
Assertions.assertNotNull(caseReview);
|
||||
this.requestGetWithOk(URL_MODULE_TREE_DELETE+a1a1Node.getId());
|
||||
this.checkModuleIsEmpty(a1a1Node.getId());
|
||||
CaseReview caseReviewDel = caseReviewMapper.selectByPrimaryKey(name.getId());
|
||||
Assertions.assertNotNull(caseReviewDel);
|
||||
|
||||
//删除不存在的节点
|
||||
this.requestGetWithOk(URL_MODULE_TREE_DELETE+IDGenerator.nextNum());
|
||||
// 测试删除根节点
|
||||
this.requestGetWithOk(URL_MODULE_TREE_DELETE+ModuleConstants.DEFAULT_NODE_ID);
|
||||
|
||||
//service层判断:测试删除空集合
|
||||
caseReviewModuleService.deleteModuleByIds(new ArrayList<>(),new ArrayList<>(), project.getId());
|
||||
|
||||
checkLog(caseReview.getId(), OperationLogType.DELETE, URL_MODULE_TREE_DELETE);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private CaseReview createCaseReview(BaseTreeNode a1a1Node, String name) {
|
||||
CaseReview caseReview = new CaseReview();
|
||||
caseReview.setId(IDGenerator.nextStr());
|
||||
caseReview.setName(name);
|
||||
caseReview.setModuleId(a1a1Node.getId());
|
||||
caseReview.setProjectId(project.getId());
|
||||
caseReview.setStatus(CaseReviewStatus.PREPARED.toString());
|
||||
caseReview.setReviewPassRule(CaseReviewPassRule.SINGLE.toString());
|
||||
caseReview.setCreateUser("gyq");
|
||||
caseReview.setCreateTime(System.currentTimeMillis());
|
||||
caseReview.setUpdateUser("gyq");
|
||||
caseReview.setUpdateTime(System.currentTimeMillis());
|
||||
caseReviewMapper.insertSelective(caseReview);
|
||||
return caseReview;
|
||||
}
|
||||
|
||||
private void checkModuleIsEmpty(String id) {
|
||||
CaseReviewModuleExample example = new CaseReviewModuleExample();
|
||||
example.createCriteria().andParentIdEqualTo(id);
|
||||
Assertions.assertEquals(caseReviewModuleMapper.countByExample(example), 0);
|
||||
}
|
||||
|
||||
private List<BaseTreeNode> getCaseReviewModuleTreeNode() throws Exception {
|
||||
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get(URL_MODULE_TREE+"/"+project.getId()).header(SessionConstants.HEADER_TOKEN, sessionId)
|
||||
.header(SessionConstants.CSRF_TOKEN, csrfToken)
|
||||
.header(SessionConstants.CURRENT_PROJECT, project.getId())
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
|
||||
String returnData = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
||||
return JSON.parseArray(JSON.toJSONString(resultHolder.getData()), BaseTreeNode.class);
|
||||
}
|
||||
|
||||
private void preliminaryData() throws Exception {
|
||||
if (CollectionUtils.isEmpty(preliminaryTreeNodes)) {
|
||||
/*
|
||||
这里需要获取修改过的树的结构。期望的最终结构是这样的(*为测试用例中挂载文件的节点, · 为空节点):
|
||||
|
||||
*默认节点
|
||||
|
|
||||
·a1 +
|
||||
| |
|
||||
| ·a1-b1 +
|
||||
| | |
|
||||
| | ·a1-b1-c1
|
||||
| |
|
||||
| *a1-a1 +(创建的时候是a1,通过修改改为a1-a1)
|
||||
| | |
|
||||
| | ·a1-a1-c1(用于测试文件移动)
|
||||
|
|
||||
·a2
|
||||
|
|
||||
·a3
|
||||
*/
|
||||
this.updateModuleTestSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkModulePos(String firstNode, String secondNode, String thirdNode, boolean isRecalculate) {
|
||||
CaseReviewModule firstModule = caseReviewModuleMapper.selectByPrimaryKey(firstNode);
|
||||
CaseReviewModule secondModule = caseReviewModuleMapper.selectByPrimaryKey(secondNode);
|
||||
CaseReviewModule thirdModule = null;
|
||||
Assertions.assertTrue(firstModule.getPos() < secondModule.getPos());
|
||||
if (StringUtils.isNotBlank(thirdNode)) {
|
||||
thirdModule = caseReviewModuleMapper.selectByPrimaryKey(thirdNode);
|
||||
Assertions.assertTrue(secondModule.getPos() < thirdModule.getPos());
|
||||
}
|
||||
if (isRecalculate) {
|
||||
int limitPos = 64;
|
||||
Assertions.assertEquals(0, firstModule.getPos() % limitPos);
|
||||
Assertions.assertEquals(0, secondModule.getPos() % limitPos);
|
||||
if (thirdModule != null) {
|
||||
Assertions.assertEquals(0, thirdModule.getPos() % limitPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -247,6 +247,7 @@ public class FunctionalCaseDemandControllerTests extends BaseTest {
|
|||
DemandDTO demandDTO2 = new DemandDTO();
|
||||
demandDTO2.setDemandId("100002");
|
||||
demandDTO2.setDemandName("手动加入Tapd1");
|
||||
demandDTO2.setDemandUrl("https://www.tapd.cn/55049933/prong/stories/view/1155049933001012783");
|
||||
demandList.add(demandDTO2);
|
||||
DemandDTO demandDTO3 = new DemandDTO();
|
||||
demandDTO3.setDemandId("100003");
|
||||
|
|
|
@ -100,6 +100,9 @@ public class OperationLogModule {
|
|||
//用例
|
||||
public static final String FUNCTIONAL_CASE = "FUNCTIONAL_CASE";
|
||||
|
||||
public static final String CASE_REVIEW = "CASE_REVIEW";
|
||||
|
||||
|
||||
//接口调试
|
||||
public static final String API_DEBUG = "API_DEBUG";
|
||||
//接口管理-环境
|
||||
|
|
Loading…
Reference in New Issue