feat(用例评审): 新增评审功能
This commit is contained in:
parent
25b374a286
commit
0bb49654df
|
@ -25,7 +25,9 @@ public class CaseReviewHistory implements Serializable {
|
|||
@Size(min = 1, max = 50, message = "{case_review_history.case_id.length_range}", groups = {Created.class, Updated.class})
|
||||
private String caseId;
|
||||
|
||||
@Schema(description = "评审结果:通过/不通过")
|
||||
@Schema(description = "评审结果:通过/不通过/建议", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{case_review_history.status.not_blank}", groups = {Created.class})
|
||||
@Size(min = 1, max = 64, message = "{case_review_history.status.length_range}", groups = {Created.class, Updated.class})
|
||||
private String status;
|
||||
|
||||
@Schema(description = "通知人")
|
||||
|
@ -37,8 +39,7 @@ public class CaseReviewHistory implements Serializable {
|
|||
@Schema(description = "操作时间")
|
||||
private Long createTime;
|
||||
|
||||
@Schema(description = "评审意见", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "{case_review_history.content.not_blank}", groups = {Created.class})
|
||||
@Schema(description = "评审意见")
|
||||
private byte[] content;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
|
|
@ -40,7 +40,7 @@ CREATE INDEX idx_delete_time ON functional_case (delete_time desc);
|
|||
CREATE INDEX idx_update_time ON functional_case (update_time desc);
|
||||
CREATE INDEX idx_num ON functional_case (num);
|
||||
CREATE INDEX idx_project_id ON functional_case (project_id);
|
||||
CREATE INDEX idx_pos ON functional_case(pos);
|
||||
CREATE INDEX idx_pos ON functional_case (pos);
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS functional_case_blob
|
||||
|
@ -182,25 +182,25 @@ CREATE INDEX idx_source_id ON functional_case_test (source_id);
|
|||
|
||||
CREATE TABLE IF NOT EXISTS functional_case_demand
|
||||
(
|
||||
`id` VARCHAR(50) NOT NULL COMMENT 'ID' ,
|
||||
`case_id` VARCHAR(50) NOT NULL COMMENT '功能用例ID' ,
|
||||
`parent` VARCHAR(50) NOT NULL DEFAULT 'NONE' COMMENT '父需求id' ,
|
||||
`demand_id` VARCHAR(50) COMMENT '需求ID' ,
|
||||
`demand_name` VARCHAR(64) NOT NULL DEFAULT 'NONE' COMMENT '需求标题' ,
|
||||
`demand_url` VARCHAR(255) COMMENT '需求地址' ,
|
||||
`demand_platform` VARCHAR(64) NOT NULL DEFAULT 'LOCAL' COMMENT '需求所属平台' ,
|
||||
`create_time` BIGINT NOT NULL COMMENT '创建时间' ,
|
||||
`update_time` BIGINT NOT NULL COMMENT '更新时间' ,
|
||||
`create_user` VARCHAR(50) NOT NULL COMMENT '创建人' ,
|
||||
`update_user` VARCHAR(50) NOT NULL COMMENT '更新人' ,
|
||||
PRIMARY KEY (id)
|
||||
`id` VARCHAR(50) NOT NULL COMMENT 'ID',
|
||||
`case_id` VARCHAR(50) NOT NULL COMMENT '功能用例ID',
|
||||
`parent` VARCHAR(50) NOT NULL DEFAULT 'NONE' COMMENT '父需求id',
|
||||
`demand_id` VARCHAR(50) COMMENT '需求ID',
|
||||
`demand_name` VARCHAR(64) NOT NULL DEFAULT 'NONE' COMMENT '需求标题',
|
||||
`demand_url` VARCHAR(255) COMMENT '需求地址',
|
||||
`demand_platform` VARCHAR(64) NOT NULL DEFAULT 'LOCAL' COMMENT '需求所属平台',
|
||||
`create_time` BIGINT NOT NULL COMMENT '创建时间',
|
||||
`update_time` BIGINT NOT NULL COMMENT '更新时间',
|
||||
`create_user` VARCHAR(50) NOT NULL COMMENT '创建人',
|
||||
`update_user` VARCHAR(50) NOT NULL COMMENT '更新人',
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT = '功能用例和需求的中间表';
|
||||
COLLATE = utf8mb4_general_ci COMMENT = '功能用例和需求的中间表';
|
||||
|
||||
|
||||
CREATE INDEX idx_case_id ON functional_case_demand(case_id);
|
||||
CREATE INDEX idx_demand_platform ON functional_case_demand(demand_platform);
|
||||
CREATE INDEX idx_case_id ON functional_case_demand (case_id);
|
||||
CREATE INDEX idx_demand_platform ON functional_case_demand (demand_platform);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS functional_minder_extra_node
|
||||
(
|
||||
|
@ -230,43 +230,43 @@ CREATE TABLE IF NOT EXISTS functional_case_custom_field
|
|||
|
||||
CREATE TABLE IF NOT EXISTS case_review
|
||||
(
|
||||
`id` VARCHAR(50) NOT NULL COMMENT 'ID' ,
|
||||
`num` BIGINT NOT NULL COMMENT '业务ID' ,
|
||||
`name` VARCHAR(255) NOT NULL COMMENT '名称' ,
|
||||
`module_id` VARCHAR(50) NOT NULL COMMENT '模块id' ,
|
||||
`project_id` VARCHAR(50) NOT NULL COMMENT '项目ID' ,
|
||||
`status` VARCHAR(64) NOT NULL DEFAULT 'PREPARE' COMMENT '评审状态:未开始/进行中/已完成/已结束/已归档' ,
|
||||
`review_pass_rule` VARCHAR(64) NOT NULL DEFAULT 'SINGLE' COMMENT '通过标准:单人通过/全部通过' ,
|
||||
`pos` BIGINT NOT NULL DEFAULT 0 COMMENT '自定义排序,间隔5000' ,
|
||||
`start_time` BIGINT COMMENT '评审开始时间' ,
|
||||
`end_time` BIGINT COMMENT '评审结束时间' ,
|
||||
`case_count` INT NOT NULL DEFAULT 0 COMMENT '用例数' ,
|
||||
`pass_rate` DECIMAL(5,2) NOT NULL DEFAULT 0.00 COMMENT '通过率(保留两位小数)' ,
|
||||
`tags` VARCHAR(1000) COMMENT '标签' ,
|
||||
`description` VARCHAR(1000) COMMENT '描述' ,
|
||||
`create_time` BIGINT NOT NULL COMMENT '创建时间' ,
|
||||
`create_user` VARCHAR(50) NOT NULL COMMENT '创建人' ,
|
||||
`update_time` BIGINT NOT NULL COMMENT '更新时间' ,
|
||||
`update_user` VARCHAR(50) NOT NULL COMMENT '更新人' ,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT = '用例评审';
|
||||
`id` VARCHAR(50) NOT NULL COMMENT 'ID',
|
||||
`num` BIGINT NOT NULL COMMENT '业务ID',
|
||||
`name` VARCHAR(255) NOT NULL COMMENT '名称',
|
||||
`module_id` VARCHAR(50) NOT NULL COMMENT '模块id',
|
||||
`project_id` VARCHAR(50) NOT NULL COMMENT '项目ID',
|
||||
`status` VARCHAR(64) NOT NULL DEFAULT 'PREPARE' COMMENT '评审状态:未开始/进行中/已完成/已结束/已归档',
|
||||
`review_pass_rule` VARCHAR(64) NOT NULL DEFAULT 'SINGLE' COMMENT '通过标准:单人通过/全部通过',
|
||||
`pos` BIGINT NOT NULL DEFAULT 0 COMMENT '自定义排序,间隔5000',
|
||||
`start_time` BIGINT COMMENT '评审开始时间',
|
||||
`end_time` BIGINT COMMENT '评审结束时间',
|
||||
`case_count` INT NOT NULL DEFAULT 0 COMMENT '用例数',
|
||||
`pass_rate` DECIMAL(5, 2) NOT NULL DEFAULT 0.00 COMMENT '通过率(保留两位小数)',
|
||||
`tags` VARCHAR(1000) COMMENT '标签',
|
||||
`description` VARCHAR(1000) COMMENT '描述',
|
||||
`create_time` BIGINT NOT NULL COMMENT '创建时间',
|
||||
`create_user` VARCHAR(50) NOT NULL COMMENT '创建人',
|
||||
`update_time` BIGINT NOT NULL COMMENT '更新时间',
|
||||
`update_user` VARCHAR(50) NOT NULL COMMENT '更新人',
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT = '用例评审';
|
||||
|
||||
|
||||
CREATE INDEX idx_create_user ON case_review(create_user);
|
||||
CREATE INDEX idx_project_id ON case_review(project_id);
|
||||
CREATE INDEX idx_name ON case_review(name);
|
||||
CREATE INDEX idx_status ON case_review(status);
|
||||
CREATE INDEX idx_review_pass_rule ON case_review(review_pass_rule);
|
||||
CREATE INDEX idx_create_time ON case_review(create_time desc);
|
||||
CREATE INDEX idx_update_time ON case_review(update_time desc);
|
||||
CREATE INDEX idx_update_user ON case_review(update_user);
|
||||
CREATE INDEX idx_module_id ON case_review(module_id);
|
||||
CREATE INDEX idx_pos ON case_review(pos);
|
||||
CREATE INDEX idx_case_count ON case_review(case_count);
|
||||
CREATE INDEX idx_pass_rate ON case_review(pass_rate);
|
||||
CREATE INDEX idx_num ON case_review(num);
|
||||
CREATE INDEX idx_create_user ON case_review (create_user);
|
||||
CREATE INDEX idx_project_id ON case_review (project_id);
|
||||
CREATE INDEX idx_name ON case_review (name);
|
||||
CREATE INDEX idx_status ON case_review (status);
|
||||
CREATE INDEX idx_review_pass_rule ON case_review (review_pass_rule);
|
||||
CREATE INDEX idx_create_time ON case_review (create_time desc);
|
||||
CREATE INDEX idx_update_time ON case_review (update_time desc);
|
||||
CREATE INDEX idx_update_user ON case_review (update_user);
|
||||
CREATE INDEX idx_module_id ON case_review (module_id);
|
||||
CREATE INDEX idx_pos ON case_review (pos);
|
||||
CREATE INDEX idx_case_count ON case_review (case_count);
|
||||
CREATE INDEX idx_pass_rate ON case_review (pass_rate);
|
||||
CREATE INDEX idx_num ON case_review (num);
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS case_review_user
|
||||
|
@ -298,13 +298,14 @@ CREATE TABLE IF NOT EXISTS case_review_functional_case
|
|||
CREATE INDEX idx_case_id ON case_review_functional_case (case_id);
|
||||
CREATE INDEX idx_review_id ON case_review_functional_case (review_id);
|
||||
CREATE INDEX idx_status ON case_review_functional_case (status);
|
||||
CREATE INDEX idx_pos ON case_review_functional_case(pos);
|
||||
CREATE INDEX idx_pos ON case_review_functional_case (pos);
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS case_review_functional_case_archive(
|
||||
CREATE TABLE IF NOT EXISTS case_review_functional_case_archive
|
||||
(
|
||||
`review_id` VARCHAR(50) NOT NULL COMMENT '用例评审ID',
|
||||
`case_id` VARCHAR(50) NOT NULL COMMENT '功能用例ID',
|
||||
`content` LONGBLOB COMMENT '功能用例快照(JSON)'
|
||||
`content` LONGBLOB COMMENT '功能用例快照(JSON)'
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT = '用例评审归档表';
|
||||
|
@ -346,20 +347,22 @@ CREATE TABLE IF NOT EXISTS case_review_history
|
|||
`id` VARCHAR(50) NOT NULL COMMENT 'ID',
|
||||
`review_id` VARCHAR(50) NOT NULL COMMENT '评审ID',
|
||||
`case_id` VARCHAR(50) NOT NULL COMMENT '用例ID',
|
||||
`content` BLOB NOT NULL COMMENT '评审意见',
|
||||
`status` VARCHAR(64) COMMENT '评审结果:通过/不通过',
|
||||
`content` LONGBLOB COMMENT '评审意见',
|
||||
`status` VARCHAR(64) NOT NULL COMMENT '评审结果:通过/不通过/建议',
|
||||
`notifier` VARCHAR(1000) COMMENT '通知人',
|
||||
`create_user` VARCHAR(50) NOT NULL COMMENT '操作人',
|
||||
`create_time` BIGINT NOT NULL COMMENT '操作时间',
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT = '评审变更记录';
|
||||
COLLATE = utf8mb4_general_ci COMMENT = '评审历史表';
|
||||
|
||||
|
||||
CREATE INDEX idx_case_id ON case_review_history (case_id);
|
||||
CREATE INDEX idx_review_id ON case_review_history (review_id);
|
||||
CREATE INDEX idx_review_id_case_id ON case_review_history (review_id, case_id);
|
||||
CREATE INDEX idx_status ON case_review_history (status);
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS case_review_module
|
||||
(
|
||||
|
|
|
@ -145,3 +145,4 @@ case_review.archived=已归档
|
|||
case_review.single=单人评审
|
||||
case_review.multiple=多人评审
|
||||
case_review.not.exist=用例评审不存在
|
||||
case_review_content.not.exist = 评审意见不能为空
|
||||
|
|
|
@ -162,3 +162,5 @@ case_review.archived=Archived
|
|||
case_review.single=Single person review
|
||||
case_review.multiple=Multiple reviewers
|
||||
case_review.not.exist=Case review does not exist
|
||||
case_review_content.not.exist = Review comments cannot be empty
|
||||
|
||||
|
|
|
@ -161,3 +161,5 @@ case_review.archived=已归档
|
|||
case_review.single=单人评审
|
||||
case_review.multiple=多人评审
|
||||
case_review.not.exist=用例评审不存在
|
||||
case_review_content.not.exist = 评审意见不能为空
|
||||
|
||||
|
|
|
@ -162,4 +162,5 @@ case_review.archived=已歸檔
|
|||
case_review.single=單人評審
|
||||
case_review.multiple=多人評審
|
||||
case_review.not.exist=用例評審不存在
|
||||
case_review_content.not.exist = 評審意見不能為空
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package io.metersphere.functional.controller;
|
||||
|
||||
import io.metersphere.functional.request.ReviewFunctionalCaseRequest;
|
||||
import io.metersphere.functional.service.ReviewFunctionalCaseService;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
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.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Tag(name = "用例管理-用例评审-评审功能用例")
|
||||
@RestController
|
||||
@RequestMapping("/review/functional/case")
|
||||
public class ReviewFunctionalCaseController {
|
||||
|
||||
@Resource
|
||||
private ReviewFunctionalCaseService reviewFunctionalCaseService;
|
||||
|
||||
@PostMapping("/save")
|
||||
@Operation(summary = "用例管理-用例评审-评审功能用例-提交评审")
|
||||
@RequiresPermissions(PermissionConstants.CASE_REVIEW_REVIEW)
|
||||
public void saveReview(@Validated @RequestBody ReviewFunctionalCaseRequest request) {
|
||||
reviewFunctionalCaseService.saveReview(request, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -13,4 +13,7 @@ public interface ExtCaseReviewFunctionalCaseMapper {
|
|||
|
||||
List<FunctionalCaseReviewDTO> list(@Param("request") FunctionalCaseReviewListRequest request);
|
||||
|
||||
void updateStatus(@Param("caseId") String caseId, @Param("reviewId") String reviewId, @Param("status") String status);
|
||||
|
||||
Long getUnCompletedCaseCount(@Param("reviewId") String reviewId, @Param("statusList") List<String> statusList);
|
||||
}
|
||||
|
|
|
@ -16,4 +16,23 @@
|
|||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getUnCompletedCaseCount" resultType="java.lang.Long">
|
||||
SELECT
|
||||
count(1)
|
||||
FROM
|
||||
case_review_functional_case
|
||||
where review_id = #{reviewId}
|
||||
and status in
|
||||
<foreach collection="statusList" item="status" open="(" separator="," close=")">
|
||||
#{status}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<update id="updateStatus">
|
||||
update case_review_functional_case
|
||||
set status = #{status},
|
||||
update_time = UNIX_TIMESTAMP()*1000
|
||||
where review_id = #{reviewId} and case_id = #{caseId}
|
||||
</update>
|
||||
|
||||
</mapper>
|
|
@ -0,0 +1,35 @@
|
|||
package io.metersphere.functional.request;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ReviewFunctionalCaseRequest {
|
||||
|
||||
@Schema(description = "项目Id")
|
||||
@NotBlank(message = "{case_review.project_id.not_blank}")
|
||||
private String projectId;
|
||||
|
||||
@Schema(description = "用例评审Id")
|
||||
@NotBlank(message = "{case_review.review_id.not_blank}")
|
||||
private String reviewId;
|
||||
|
||||
@Schema(description = "功能用例id")
|
||||
@NotBlank(message = "{functional_case.case_id.not_blank}")
|
||||
private String caseId;
|
||||
|
||||
@Schema(description = "评审规则")
|
||||
@NotBlank(message = "{case_review.review_pass_rule.not_blank}")
|
||||
private String reviewPassRule;
|
||||
|
||||
@Schema(description = "评审结果")
|
||||
@NotBlank(message = "{functional_case.status.not_blank}")
|
||||
private String status;
|
||||
|
||||
@Schema(description = "评审规则")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "评论@的人的Id, 多个以';'隔开")
|
||||
private String notifier;
|
||||
}
|
|
@ -0,0 +1,215 @@
|
|||
package io.metersphere.functional.service;
|
||||
|
||||
import io.metersphere.functional.constants.CaseReviewPassRule;
|
||||
import io.metersphere.functional.constants.CaseReviewStatus;
|
||||
import io.metersphere.functional.constants.FunctionalCaseReviewStatus;
|
||||
import io.metersphere.functional.domain.*;
|
||||
import io.metersphere.functional.mapper.*;
|
||||
import io.metersphere.functional.request.ReviewFunctionalCaseRequest;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.domain.User;
|
||||
import io.metersphere.system.mapper.UserMapper;
|
||||
import io.metersphere.system.notice.NoticeModel;
|
||||
import io.metersphere.system.notice.constants.NoticeConstants;
|
||||
import io.metersphere.system.notice.utils.MessageTemplateUtils;
|
||||
import io.metersphere.system.service.NoticeSendService;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.beanutils.BeanMap;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class ReviewFunctionalCaseService {
|
||||
|
||||
@Resource
|
||||
private CaseReviewHistoryMapper caseReviewHistoryMapper;
|
||||
@Resource
|
||||
private ExtCaseReviewFunctionalCaseMapper extCaseReviewFunctionalCaseMapper;
|
||||
@Resource
|
||||
private CaseReviewFunctionalCaseUserMapper caseReviewFunctionalCaseUserMapper;
|
||||
@Resource
|
||||
private CaseReviewMapper caseReviewMapper;
|
||||
@Resource
|
||||
private UserMapper userMapper;
|
||||
@Resource
|
||||
private NoticeSendService noticeSendService;
|
||||
@Resource
|
||||
private FunctionalCaseMapper functionalCaseMapper;
|
||||
|
||||
|
||||
/**
|
||||
* 评审功能用例
|
||||
*
|
||||
* @param request 页面参数
|
||||
* @param userId 当前操作人
|
||||
*/
|
||||
public void saveReview(ReviewFunctionalCaseRequest request, String userId) {
|
||||
//保存评审历史
|
||||
CaseReviewHistory caseReviewHistory = buildReviewHistory(request, userId);
|
||||
caseReviewHistoryMapper.insert(caseReviewHistory);
|
||||
//根据评审规则更新用例评审和功能用例关系表中的状态 1.单人评审直接更新评审结果 2.多人评审需要计算
|
||||
String functionalCaseStatus = getFunctionalCaseStatus(request);
|
||||
extCaseReviewFunctionalCaseMapper.updateStatus(request.getCaseId(), request.getReviewId(), functionalCaseStatus);
|
||||
//更新用例评审状态(判断所有用例是否结束,false:进行中,true:已完成)
|
||||
boolean completed = updateCaseReviewStatus(request.getCaseId(), request.getReviewId());
|
||||
//检查是否有@,发送@通知
|
||||
if (StringUtils.isNotBlank(request.getNotifier())) {
|
||||
List<String> relatedUsers = Arrays.asList(request.getNotifier().split(";"));
|
||||
sendNotice(relatedUsers, userId, request,NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, NoticeConstants.Event.REVIEW_AT);
|
||||
}
|
||||
//发送评审通过不通过通知(评审中不发)
|
||||
if (StringUtils.equalsIgnoreCase(request.getStatus(), FunctionalCaseReviewStatus.UN_PASS.toString())) {
|
||||
sendNotice(new ArrayList<>(), userId, request,NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, NoticeConstants.Event.REVIEW_FAIL);
|
||||
}
|
||||
if (StringUtils.equalsIgnoreCase(request.getStatus(), FunctionalCaseReviewStatus.PASS.toString())) {
|
||||
sendNotice(new ArrayList<>(), userId, request,NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, NoticeConstants.Event.REVIEW_PASSED);
|
||||
}
|
||||
//检查用例评审是否结束发送通知
|
||||
if (completed) {
|
||||
sendNotice(new ArrayList<>(), userId, request,NoticeConstants.TaskType.CASE_REVIEW_TASK, NoticeConstants.Event.REVIEW_COMPLETED);
|
||||
}
|
||||
}
|
||||
|
||||
@Async
|
||||
public void sendNotice(List<String> relatedUsers, String userId,ReviewFunctionalCaseRequest request, String task, String event) {
|
||||
CaseReview caseReview = caseReviewMapper.selectByPrimaryKey(request.getReviewId());
|
||||
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(request.getCaseId());
|
||||
Map<String, String> defaultTemplateMap = MessageTemplateUtils.getDefaultTemplateMap();
|
||||
String template = defaultTemplateMap.get(task + "_" + event);
|
||||
Map<String, String> defaultSubjectMap = MessageTemplateUtils.getDefaultTemplateSubjectMap();
|
||||
String subject = defaultSubjectMap.get(task + "_" + event);
|
||||
User user = userMapper.selectByPrimaryKey(userId);
|
||||
Map paramMap;
|
||||
if (StringUtils.equalsIgnoreCase(task,NoticeConstants.TaskType.CASE_REVIEW_TASK)) {
|
||||
BeanMap beanMap = new BeanMap(caseReview);
|
||||
paramMap = new HashMap<>(beanMap);
|
||||
} else {
|
||||
BeanMap beanMap = new BeanMap(functionalCase);
|
||||
paramMap = new HashMap<>(beanMap);
|
||||
paramMap.put("reviewName", caseReview.getName());
|
||||
}
|
||||
paramMap.put(NoticeConstants.RelatedUser.OPERATOR, user.getName());
|
||||
NoticeModel noticeModel = NoticeModel.builder()
|
||||
.operator(userId)
|
||||
.context(template)
|
||||
.subject(subject)
|
||||
.paramMap(paramMap)
|
||||
.event(event)
|
||||
.status((String) paramMap.get("status"))
|
||||
.excludeSelf(true)
|
||||
.relatedUsers(relatedUsers)
|
||||
.build();
|
||||
noticeSendService.send(task, noticeModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用例评审自身的状态
|
||||
*
|
||||
* @param caseId 功能用例Id
|
||||
* @param reviewId 用例评审Id
|
||||
* @return completed
|
||||
*/
|
||||
private boolean updateCaseReviewStatus(String caseId, String reviewId) {
|
||||
boolean completed = false;
|
||||
List<String> statusList = new ArrayList<>();
|
||||
statusList.add(FunctionalCaseReviewStatus.UN_REVIEWED.toString());
|
||||
statusList.add(FunctionalCaseReviewStatus.UNDER_REVIEWED.toString());
|
||||
statusList.add(FunctionalCaseReviewStatus.RE_REVIEWED.toString());
|
||||
Long unCompletedCaseCount = extCaseReviewFunctionalCaseMapper.getUnCompletedCaseCount(reviewId, statusList);
|
||||
CaseReview caseReview = new CaseReview();
|
||||
caseReview.setId(reviewId);
|
||||
if (unCompletedCaseCount > 0L) {
|
||||
caseReview.setStatus(CaseReviewStatus.UNDERWAY.toString());
|
||||
} else {
|
||||
completed = true;
|
||||
caseReview.setStatus(CaseReviewStatus.COMPLETED.toString());
|
||||
}
|
||||
caseReviewMapper.updateByPrimaryKeySelective(caseReview);
|
||||
return completed;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算当前评审的功能用例的评审结果
|
||||
*
|
||||
* @param request 评审规则
|
||||
* @return 功能用例的评审结果
|
||||
*/
|
||||
private String getFunctionalCaseStatus(ReviewFunctionalCaseRequest request) {
|
||||
String functionalCaseStatus;
|
||||
if (StringUtils.equals(request.getReviewPassRule(), CaseReviewPassRule.SINGLE.toString())) {
|
||||
functionalCaseStatus = request.getStatus();
|
||||
} else {
|
||||
//根据用例ID 查询所有评审人 再查所有评审人最后一次的评审结果(只有通过/不通过算结果)
|
||||
CaseReviewHistoryExample caseReviewHistoryExample = new CaseReviewHistoryExample();
|
||||
caseReviewHistoryExample.createCriteria().andCaseIdEqualTo(request.getCaseId()).andReviewIdEqualTo(request.getReviewId());
|
||||
List<CaseReviewHistory> caseReviewHistories = caseReviewHistoryMapper.selectByExample(caseReviewHistoryExample);
|
||||
Map<String, List<CaseReviewHistory>> hasReviewedUserMap = caseReviewHistories.stream().sorted(Comparator.comparingLong(CaseReviewHistory::getCreateTime).reversed()).collect(Collectors.groupingBy(CaseReviewHistory::getCreateUser, Collectors.toList()));
|
||||
CaseReviewFunctionalCaseUserExample caseReviewFunctionalCaseUserExample = new CaseReviewFunctionalCaseUserExample();
|
||||
caseReviewFunctionalCaseUserExample.createCriteria().andReviewIdEqualTo(request.getReviewId()).andCaseIdEqualTo(request.getCaseId());
|
||||
long reviewerNum = caseReviewFunctionalCaseUserMapper.countByExample(caseReviewFunctionalCaseUserExample);
|
||||
if ((int) reviewerNum > hasReviewedUserMap.size()) {
|
||||
functionalCaseStatus = FunctionalCaseReviewStatus.UNDER_REVIEWED.toString();
|
||||
} else {
|
||||
AtomicBoolean hasUnPass = new AtomicBoolean(false);
|
||||
AtomicInteger passCount = new AtomicInteger();
|
||||
hasReviewedUserMap.forEach((k, v) -> {
|
||||
if (StringUtils.equalsIgnoreCase(v.get(0).getStatus(), FunctionalCaseReviewStatus.UN_PASS.toString())) {
|
||||
hasUnPass.set(true);
|
||||
}
|
||||
if (StringUtils.equalsIgnoreCase(v.get(0).getStatus(), FunctionalCaseReviewStatus.PASS.toString())) {
|
||||
passCount.set(passCount.get() + 1);
|
||||
}
|
||||
});
|
||||
if (hasUnPass.get()) {
|
||||
functionalCaseStatus = FunctionalCaseReviewStatus.UN_PASS.toString();
|
||||
} else {
|
||||
//检查是否全部是通过,全是才是PASS,否则是评审中
|
||||
if (passCount.get() == hasReviewedUserMap.size()) {
|
||||
functionalCaseStatus = FunctionalCaseReviewStatus.PASS.toString();
|
||||
} else {
|
||||
functionalCaseStatus = FunctionalCaseReviewStatus.UNDER_REVIEWED.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return functionalCaseStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建评审历史表
|
||||
*
|
||||
* @param request request
|
||||
* @param userId 当前操作人
|
||||
* @return CaseReviewHistory
|
||||
*/
|
||||
private static CaseReviewHistory buildReviewHistory(ReviewFunctionalCaseRequest request, String userId) {
|
||||
CaseReviewHistory caseReviewHistory = new CaseReviewHistory();
|
||||
caseReviewHistory.setId(IDGenerator.nextStr());
|
||||
caseReviewHistory.setReviewId(request.getReviewId());
|
||||
caseReviewHistory.setCaseId(request.getCaseId());
|
||||
caseReviewHistory.setStatus(request.getStatus());
|
||||
if (StringUtils.equalsIgnoreCase(request.getStatus(), FunctionalCaseReviewStatus.UN_PASS.toString())) {
|
||||
if (StringUtils.isBlank(request.getContent())) {
|
||||
throw new MSException(Translator.get("case_review_content.not.exist"));
|
||||
}
|
||||
} else {
|
||||
if (StringUtils.isNotBlank(request.getContent())) {
|
||||
caseReviewHistory.setContent(request.getContent().getBytes());
|
||||
}
|
||||
}
|
||||
caseReviewHistory.setNotifier(request.getNotifier());
|
||||
caseReviewHistory.setCreateUser(userId);
|
||||
caseReviewHistory.setCreateTime(System.currentTimeMillis());
|
||||
return caseReviewHistory;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,240 @@
|
|||
package io.metersphere.functional.controller;
|
||||
|
||||
import io.metersphere.functional.constants.CaseReviewPassRule;
|
||||
import io.metersphere.functional.constants.CaseReviewStatus;
|
||||
import io.metersphere.functional.constants.FunctionalCaseReviewStatus;
|
||||
import io.metersphere.functional.domain.*;
|
||||
import io.metersphere.functional.mapper.CaseReviewFunctionalCaseMapper;
|
||||
import io.metersphere.functional.mapper.CaseReviewHistoryMapper;
|
||||
import io.metersphere.functional.mapper.CaseReviewMapper;
|
||||
import io.metersphere.functional.request.CaseReviewRequest;
|
||||
import io.metersphere.functional.request.ReviewFunctionalCaseRequest;
|
||||
import io.metersphere.project.domain.Notification;
|
||||
import io.metersphere.project.domain.NotificationExample;
|
||||
import io.metersphere.project.mapper.NotificationMapper;
|
||||
import io.metersphere.system.base.BaseTest;
|
||||
import io.metersphere.system.notice.constants.NoticeConstants;
|
||||
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;
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
import org.springframework.test.context.jdbc.SqlConfig;
|
||||
|
||||
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
|
||||
public class ReviewFunctionalCaseControllerTests extends BaseTest {
|
||||
|
||||
private static final String projectId = "project-review-case-test";
|
||||
|
||||
private static final String SAVE_REVIEW = "/review/functional/case/save";
|
||||
private static final String ADD_CASE_REVIEW = "/case/review/add";
|
||||
|
||||
@Resource
|
||||
private CaseReviewMapper caseReviewMapper;
|
||||
@Resource
|
||||
private CaseReviewHistoryMapper caseReviewHistoryMapper;
|
||||
@Resource
|
||||
private NotificationMapper notificationMapper;
|
||||
@Resource
|
||||
private CaseReviewFunctionalCaseMapper caseReviewFunctionalCaseMapper;
|
||||
|
||||
|
||||
@Test
|
||||
@Order(0)
|
||||
@Sql(scripts = {"/dml/init_review_case.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
|
||||
public void saveReviewSuccess() throws Exception {
|
||||
//单人评审通过
|
||||
List<String> caseIds = new ArrayList<>();
|
||||
caseIds.add("gyqReviewCaseTest");
|
||||
caseIds.add("gyqReviewCaseTestOne");
|
||||
List<String> reviewers = new ArrayList<>();
|
||||
reviewers.add("admin");
|
||||
reviewers.add("default-project-member-user-gyq");
|
||||
List<CaseReview> caseReviews = addReview("创建用例评审1", caseIds, reviewers);
|
||||
String reviewId = caseReviews.get(0).getId();
|
||||
ReviewFunctionalCaseRequest reviewFunctionalCaseRequest = new ReviewFunctionalCaseRequest();
|
||||
reviewFunctionalCaseRequest.setReviewId(reviewId);
|
||||
reviewFunctionalCaseRequest.setCaseId("gyqReviewCaseTest");
|
||||
reviewFunctionalCaseRequest.setProjectId(projectId);
|
||||
reviewFunctionalCaseRequest.setStatus(FunctionalCaseReviewStatus.PASS.toString());
|
||||
reviewFunctionalCaseRequest.setContent("通过了");
|
||||
reviewFunctionalCaseRequest.setNotifier("default-project-member-user-gyq-2;");
|
||||
reviewFunctionalCaseRequest.setReviewPassRule(CaseReviewPassRule.SINGLE.toString());
|
||||
this.requestPostWithOk(SAVE_REVIEW, reviewFunctionalCaseRequest);
|
||||
CaseReviewHistoryExample caseReviewHistoryExample = new CaseReviewHistoryExample();
|
||||
caseReviewHistoryExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTest");
|
||||
List<CaseReviewHistory> caseReviewHistories = caseReviewHistoryMapper.selectByExample(caseReviewHistoryExample);
|
||||
Assertions.assertEquals(1, caseReviewHistories.size());
|
||||
CaseReviewFunctionalCaseExample caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
||||
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTest");
|
||||
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
|
||||
Assertions.assertTrue(StringUtils.equalsIgnoreCase(caseReviewFunctionalCases.get(0).getStatus(),FunctionalCaseReviewStatus.PASS.toString()));
|
||||
List<CaseReview> caseReviews1 = getCaseReviews("创建用例评审1");
|
||||
Assertions.assertTrue(StringUtils.equals(caseReviews1.get(0).getStatus(), CaseReviewStatus.UNDERWAY.toString()));
|
||||
//单人评审不通过
|
||||
reviewFunctionalCaseRequest = new ReviewFunctionalCaseRequest();
|
||||
reviewFunctionalCaseRequest.setReviewId(reviewId);
|
||||
reviewFunctionalCaseRequest.setCaseId("gyqReviewCaseTestOne");
|
||||
reviewFunctionalCaseRequest.setProjectId(projectId);
|
||||
reviewFunctionalCaseRequest.setStatus(FunctionalCaseReviewStatus.UN_PASS.toString());
|
||||
reviewFunctionalCaseRequest.setContent("不通过");
|
||||
reviewFunctionalCaseRequest.setNotifier("default-project-member-user-gyq-2;");
|
||||
reviewFunctionalCaseRequest.setReviewPassRule(CaseReviewPassRule.SINGLE.toString());
|
||||
this.requestPostWithOk(SAVE_REVIEW, reviewFunctionalCaseRequest);
|
||||
caseReviewHistoryExample = new CaseReviewHistoryExample();
|
||||
caseReviewHistoryExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTestOne");
|
||||
caseReviewHistories = caseReviewHistoryMapper.selectByExample(caseReviewHistoryExample);
|
||||
Assertions.assertEquals(1, caseReviewHistories.size());
|
||||
caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
||||
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTestOne");
|
||||
caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
|
||||
Assertions.assertTrue(StringUtils.equalsIgnoreCase(caseReviewFunctionalCases.get(0).getStatus(),FunctionalCaseReviewStatus.UN_PASS.toString()));
|
||||
caseReviews1 = getCaseReviews("创建用例评审1");
|
||||
Assertions.assertTrue(StringUtils.equals(caseReviews1.get(0).getStatus(), CaseReviewStatus.COMPLETED.toString()));
|
||||
NotificationExample notificationExample = new NotificationExample();
|
||||
notificationExample.createCriteria().andResourceTypeEqualTo(NoticeConstants.TaskType.CASE_REVIEW_TASK);
|
||||
List<Notification> notifications = notificationMapper.selectByExampleWithBLOBs(notificationExample);
|
||||
Assertions.assertFalse(notifications.isEmpty());
|
||||
notificationExample = new NotificationExample();
|
||||
notificationExample.createCriteria().andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK);
|
||||
notifications = notificationMapper.selectByExampleWithBLOBs(notificationExample);
|
||||
Assertions.assertFalse(notifications.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(1)
|
||||
public void saveReviewMultipleSuccess() throws Exception {
|
||||
//多人评审部分通过
|
||||
List<String> caseIds = new ArrayList<>();
|
||||
caseIds.add("gyqReviewCaseTestTwo");
|
||||
List<String> reviewers = new ArrayList<>();
|
||||
reviewers.add("admin");
|
||||
reviewers.add("default-project-member-user-gyq");
|
||||
List<CaseReview> caseReviews = addReview("创建用例评审2", caseIds, reviewers);
|
||||
String reviewId = caseReviews.get(0).getId();
|
||||
ReviewFunctionalCaseRequest reviewFunctionalCaseRequest = new ReviewFunctionalCaseRequest();
|
||||
reviewFunctionalCaseRequest.setReviewId(reviewId);
|
||||
reviewFunctionalCaseRequest.setCaseId("gyqReviewCaseTestTwo");
|
||||
reviewFunctionalCaseRequest.setProjectId(projectId);
|
||||
reviewFunctionalCaseRequest.setStatus(FunctionalCaseReviewStatus.PASS.toString());
|
||||
reviewFunctionalCaseRequest.setContent("通过了");
|
||||
reviewFunctionalCaseRequest.setNotifier("default-project-member-user-gyq-2");
|
||||
reviewFunctionalCaseRequest.setReviewPassRule(CaseReviewPassRule.MULTIPLE.toString());
|
||||
this.requestPostWithOk(SAVE_REVIEW, reviewFunctionalCaseRequest);
|
||||
CaseReviewHistoryExample caseReviewHistoryExample = new CaseReviewHistoryExample();
|
||||
caseReviewHistoryExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTestTwo");
|
||||
List<CaseReviewHistory> caseReviewHistories = caseReviewHistoryMapper.selectByExample(caseReviewHistoryExample);
|
||||
Assertions.assertEquals(1, caseReviewHistories.size());
|
||||
CaseReviewFunctionalCaseExample caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
||||
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTestTwo");
|
||||
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
|
||||
Assertions.assertTrue(StringUtils.equalsIgnoreCase(caseReviewFunctionalCases.get(0).getStatus(),FunctionalCaseReviewStatus.UNDER_REVIEWED.toString()));
|
||||
List<CaseReview> caseReviews1 = getCaseReviews("创建用例评审2");
|
||||
Assertions.assertTrue(StringUtils.equals(caseReviews1.get(0).getStatus(), CaseReviewStatus.UNDERWAY.toString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(2)
|
||||
public void saveReviewMultipleAllSuccess() throws Exception {
|
||||
//多人评审部分通过
|
||||
List<String> caseIds = new ArrayList<>();
|
||||
caseIds.add("gyqReviewCaseTestThree");
|
||||
caseIds.add("gyqReviewCaseTestFour");
|
||||
List<String> reviewers = new ArrayList<>();
|
||||
reviewers.add("admin");
|
||||
List<CaseReview> caseReviews = addReview("创建用例评审3", caseIds, reviewers);
|
||||
String reviewId = caseReviews.get(0).getId();
|
||||
ReviewFunctionalCaseRequest reviewFunctionalCaseRequest = new ReviewFunctionalCaseRequest();
|
||||
reviewFunctionalCaseRequest.setReviewId(reviewId);
|
||||
reviewFunctionalCaseRequest.setCaseId("gyqReviewCaseTestThree");
|
||||
reviewFunctionalCaseRequest.setProjectId(projectId);
|
||||
reviewFunctionalCaseRequest.setStatus(FunctionalCaseReviewStatus.PASS.toString());
|
||||
reviewFunctionalCaseRequest.setContent("通过了");
|
||||
reviewFunctionalCaseRequest.setNotifier("default-project-member-user-gyq-2");
|
||||
reviewFunctionalCaseRequest.setReviewPassRule(CaseReviewPassRule.MULTIPLE.toString());
|
||||
this.requestPostWithOk(SAVE_REVIEW, reviewFunctionalCaseRequest);
|
||||
CaseReviewHistoryExample caseReviewHistoryExample = new CaseReviewHistoryExample();
|
||||
caseReviewHistoryExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTestThree");
|
||||
List<CaseReviewHistory> caseReviewHistories = caseReviewHistoryMapper.selectByExample(caseReviewHistoryExample);
|
||||
Assertions.assertEquals(1, caseReviewHistories.size());
|
||||
CaseReviewFunctionalCaseExample caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
||||
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTestThree");
|
||||
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
|
||||
Assertions.assertTrue(StringUtils.equalsIgnoreCase(caseReviewFunctionalCases.get(0).getStatus(),FunctionalCaseReviewStatus.PASS.toString()));
|
||||
List<CaseReview> caseReviews1 = getCaseReviews("创建用例评审3");
|
||||
Assertions.assertTrue(StringUtils.equals(caseReviews1.get(0).getStatus(), CaseReviewStatus.UNDERWAY.toString()));
|
||||
|
||||
reviewFunctionalCaseRequest = new ReviewFunctionalCaseRequest();
|
||||
reviewFunctionalCaseRequest.setReviewId(reviewId);
|
||||
reviewFunctionalCaseRequest.setCaseId("gyqReviewCaseTestFour");
|
||||
reviewFunctionalCaseRequest.setProjectId(projectId);
|
||||
reviewFunctionalCaseRequest.setStatus(FunctionalCaseReviewStatus.UN_PASS.toString());
|
||||
reviewFunctionalCaseRequest.setContent("不通过");
|
||||
reviewFunctionalCaseRequest.setNotifier("default-project-member-user-gyq-2");
|
||||
reviewFunctionalCaseRequest.setReviewPassRule(CaseReviewPassRule.MULTIPLE.toString());
|
||||
this.requestPostWithOk(SAVE_REVIEW, reviewFunctionalCaseRequest);
|
||||
caseReviewHistoryExample = new CaseReviewHistoryExample();
|
||||
caseReviewHistoryExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTestFour");
|
||||
caseReviewHistories = caseReviewHistoryMapper.selectByExample(caseReviewHistoryExample);
|
||||
Assertions.assertEquals(1, caseReviewHistories.size());
|
||||
caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
||||
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo("gyqReviewCaseTestFour");
|
||||
caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
|
||||
Assertions.assertTrue(StringUtils.equalsIgnoreCase(caseReviewFunctionalCases.get(0).getStatus(),FunctionalCaseReviewStatus.UN_PASS.toString()));
|
||||
caseReviews1 = getCaseReviews("创建用例评审3");
|
||||
Assertions.assertTrue(StringUtils.equals(caseReviews1.get(0).getStatus(), CaseReviewStatus.COMPLETED.toString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(3)
|
||||
public void saveReviewFalse() throws Exception {
|
||||
//多人评审部分通过
|
||||
List<String> caseIds = new ArrayList<>();
|
||||
caseIds.add("gyqReviewCaseTestThree");
|
||||
caseIds.add("gyqReviewCaseTestFour");
|
||||
List<String> reviewers = new ArrayList<>();
|
||||
reviewers.add("admin");
|
||||
List<CaseReview> caseReviews = addReview("创建用例评审4", caseIds, reviewers);
|
||||
String reviewId = caseReviews.get(0).getId();
|
||||
ReviewFunctionalCaseRequest reviewFunctionalCaseRequest = new ReviewFunctionalCaseRequest();
|
||||
reviewFunctionalCaseRequest.setReviewId(reviewId);
|
||||
reviewFunctionalCaseRequest.setCaseId("gyqReviewCaseTestFour");
|
||||
reviewFunctionalCaseRequest.setProjectId(projectId);
|
||||
reviewFunctionalCaseRequest.setStatus(FunctionalCaseReviewStatus.UN_PASS.toString());
|
||||
reviewFunctionalCaseRequest.setNotifier("default-project-member-user-gyq-2");
|
||||
reviewFunctionalCaseRequest.setReviewPassRule(CaseReviewPassRule.SINGLE.toString());
|
||||
this.requestPost(SAVE_REVIEW, reviewFunctionalCaseRequest).andExpect(status().is5xxServerError());
|
||||
|
||||
}
|
||||
|
||||
private List<CaseReview> addReview(String name, List<String> caseIds, List<String> reviewers) throws Exception {
|
||||
CaseReviewRequest caseReviewRequest = new CaseReviewRequest();
|
||||
caseReviewRequest.setProjectId(projectId);
|
||||
caseReviewRequest.setName(name);
|
||||
caseReviewRequest.setModuleId("CASE_REVIEW_REAL_MODULE_ID");
|
||||
caseReviewRequest.setReviewPassRule(CaseReviewPassRule.SINGLE.toString());
|
||||
caseReviewRequest.setReviewers(reviewers);
|
||||
caseReviewRequest.setCaseIds(caseIds);
|
||||
List<String> tags = new ArrayList<>();
|
||||
tags.add("11");
|
||||
caseReviewRequest.setTags(tags);
|
||||
this.requestPostWithOk(ADD_CASE_REVIEW, caseReviewRequest);
|
||||
return getCaseReviews(name);
|
||||
}
|
||||
|
||||
private List<CaseReview> getCaseReviews(String name) {
|
||||
CaseReviewExample caseReviewExample = new CaseReviewExample();
|
||||
caseReviewExample.createCriteria().andNameEqualTo(name);
|
||||
return caseReviewMapper.selectByExample(caseReviewExample);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
INSERT INTO organization(id, num, name, description, create_time, update_time, create_user, update_user, deleted,
|
||||
delete_user, delete_time) VALUE
|
||||
('organization-review-case-test', null, 'organization-review-case-test', 'organization-review-case-test',
|
||||
UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'admin', 0, null, null);
|
||||
|
||||
INSERT INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time)
|
||||
VALUES ('project-review-case-test', null, 'organization-review-case-test', '用例评论项目', '系统默认创建的项目',
|
||||
'admin', 'admin', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000),
|
||||
('project-review-case-test-1', null, 'organization-review-case-test', '用例评论项目1', '系统默认创建的项目1',
|
||||
'admin', 'admin', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000),
|
||||
('project-review-case-test-2', null, 'organization-review-case-test', '用例评论项目2', '系统默认创建的项目2',
|
||||
'admin', 'admin', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000),
|
||||
('project-review-case-test-3', null, 'organization-review-case-test', '用例评论项目3', '系统默认创建的项目3',
|
||||
'admin', 'admin', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000);
|
||||
|
||||
INSERT INTO project_robot(id, project_id, name, platform, webhook, type, app_key, app_secret, enable, create_user,
|
||||
create_time, update_user, update_time, description)
|
||||
VALUES ('test_review_case_message_robot1', 'project-review-case-test', '测试机器人1', 'IN_SITE', 'NONE', null, null,
|
||||
null, true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, null);
|
||||
|
||||
|
||||
|
||||
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
|
||||
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
|
||||
VALUES ('review-case_messageOne', 'UPDATE', 'CREATE_USER', 'test_review_case_message_robot1', 'CASE_REVIEW_TASK',
|
||||
'NONE', 'project-review-case-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000,
|
||||
true, true, 'message.title.case_review_task_update');
|
||||
INSERT INTO message_task_blob(id, template)
|
||||
VALUES ('review-case_messageOne', 'message.case_review_task_update');
|
||||
|
||||
|
||||
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
|
||||
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
|
||||
VALUES ('review-case_message2', 'UPDATE', 'FOLLOW_PEOPLE', 'test_review_case_message_robot1', 'CASE_REVIEW_TASK',
|
||||
'NONE', 'project-review-case-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000,
|
||||
true, true, 'message.title.case_review_task_update');
|
||||
INSERT INTO message_task_blob(id, template)
|
||||
VALUES ('review-case_message2', 'message.case_review_task_update');
|
||||
|
||||
|
||||
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
|
||||
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
|
||||
VALUES ('review-case_message3', 'DELETE', 'CREATE_USER', 'test_review_case_message_robot1', 'CASE_REVIEW_TASK', 'NONE',
|
||||
'project-review-case-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true,
|
||||
true, 'message.title.case_review_task_delete');
|
||||
INSERT INTO message_task_blob(id, template)
|
||||
VALUES ('review-case_message3', 'message.case_review_task_delete');
|
||||
|
||||
|
||||
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
|
||||
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
|
||||
VALUES ('review-case_message4', 'REVIEW_COMPLETED', 'CREATE_USER', 'test_review_case_message_robot1',
|
||||
'CASE_REVIEW_TASK', 'NONE', 'project-review-case-test', true, 'admin', unix_timestamp() * 1000, 'admin',
|
||||
unix_timestamp() * 1000, true, true, 'message.title.case_review_task_review_completed');
|
||||
INSERT INTO message_task_blob(id, template)
|
||||
VALUES ('review-case_message4', 'message.case_review_task_review_completed');
|
||||
|
||||
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
|
||||
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
|
||||
VALUES ('review-case_messageA', 'REVIEW_COMPLETED', 'default-project-member-user-gyq',
|
||||
'test_review_case_message_robot1', 'CASE_REVIEW_TASK', 'NONE', 'project-review-case-test', true, 'admin',
|
||||
unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true, true,
|
||||
'message.title.case_review_task_review_completed');
|
||||
INSERT INTO message_task_blob(id, template)
|
||||
VALUES ('review-case_messageA', 'message.case_review_task_review_completed');
|
||||
|
||||
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
|
||||
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
|
||||
VALUES ('review-case_message5', 'CREATE', 'CREATE_USER', 'test_review_case_message_robot1', 'CASE_REVIEW_TASK', 'NONE',
|
||||
'project-review-case-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true,
|
||||
true, 'message.title.case_review_task_create');
|
||||
INSERT INTO message_task_blob(id, template)
|
||||
VALUES ('review-case_message5', 'message.case_review_task_create');
|
||||
|
||||
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
|
||||
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
|
||||
VALUES ('review-case_message6', 'CREATE', 'default-project-member-user-gyq', 'test_review_case_message_robot1',
|
||||
'CASE_REVIEW_TASK', 'NONE', 'project-review-case-test', true, 'admin', unix_timestamp() * 1000, 'admin',
|
||||
unix_timestamp() * 1000, true, true, 'message.title.case_review_task_create');
|
||||
INSERT INTO message_task_blob(id, template)
|
||||
VALUES ('review-case_message6', 'message.case_review_task_create');
|
||||
|
||||
|
||||
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
|
||||
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
|
||||
VALUES ('review-case_message7', 'REVIEW_AT', 'NONE', 'test_review_case_message_robot1', 'FUNCTIONAL_CASE_TASK', 'NONE',
|
||||
'project-review-case-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true,
|
||||
true, 'message.title.functional_case_task_review_at');
|
||||
INSERT INTO message_task_blob(id, template)
|
||||
VALUES ('review-case_message7', 'message.functional_case_task_review_at');
|
||||
|
||||
|
||||
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
|
||||
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
|
||||
VALUES ('review-case_message8', 'REVIEW_PASSED', 'default-project-member-user-gyq-2', 'test_review_case_message_robot1',
|
||||
'FUNCTIONAL_CASE_TASK', 'NONE', 'project-review-case-test', true, 'admin', unix_timestamp() * 1000, 'admin',
|
||||
unix_timestamp() * 1000, true, true, 'message.title.functional_case_task_review_passed');
|
||||
INSERT INTO message_task_blob(id, template)
|
||||
VALUES ('review-case_message8', 'message.functional_case_task_review');
|
||||
|
||||
|
||||
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user,
|
||||
create_time, update_user, update_time, use_default_template, use_default_subject, subject)
|
||||
VALUES ('review-case_message9', 'REVIEW_FAIL', 'default-project-member-user-gyq-2', 'test_review_case_message_robot1',
|
||||
'FUNCTIONAL_CASE_TASK', 'NONE', 'project-review-case-test', true, 'admin', unix_timestamp() * 1000, 'admin',
|
||||
unix_timestamp() * 1000, true, true, 'message.title.functional_case_task_review_fail');
|
||||
INSERT INTO message_task_blob(id, template)
|
||||
VALUES ('review-case_message9', 'message.functional_case_task_review');
|
||||
|
||||
|
||||
|
||||
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 ('gyqReviewCaseTest', 1000001, 'test_guo', 'project-review-case-test', 'test_guo', 'gyqTest', 'UN_REVIEWED',
|
||||
null, 'text',
|
||||
10001, '111', 'gyqReviewCaseTest', 'success', false, false, true, 'gyq', 'gyq', null, 1698058347559,
|
||||
1698058347559,
|
||||
null);
|
||||
|
||||
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 ('gyqReviewCaseTestTwo', 1000001, 'test_guo', 'project-review-case-test', 'test_guo', 'gyqTest', 'UN_REVIEWED',
|
||||
null, 'text',
|
||||
10001, '111', 'gyqReviewCaseTestTwo', 'success', false, false, true, 'gyq', 'gyq', null, 1698058347559,
|
||||
1698058347559,
|
||||
null);
|
||||
|
||||
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 ('gyqReviewCaseTestThree', 1000001, 'test_guo', 'project-review-case-test', 'test_guo', 'gyqTest', 'UN_REVIEWED',
|
||||
null, 'text',
|
||||
10001, '111', 'gyqReviewCaseTestThree', 'success', false, false, true, 'gyq', 'gyq', null, 1698058347559,
|
||||
1698058347559,
|
||||
null);
|
||||
|
||||
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 ('gyqReviewCaseTestFour', 1000001, 'test_guo', 'project-review-case-test', 'test_guo', 'gyqTest', 'UN_REVIEWED',
|
||||
null, 'text',
|
||||
10001, '111', 'gyqReviewCaseTestFour', 'success', false, false, true, 'gyq', 'gyq', null, 1698058347559,
|
||||
1698058347559,
|
||||
null);
|
||||
|
||||
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 ('gyqReviewCaseTestOne', 1000001, 'test_guo', 'project-review-case-test', 'test_guo', 'gyqTest1', 'UN_REVIEWED',
|
||||
null, 'text',
|
||||
10001, '111', 'gyqReviewCaseTestOne', 'success', false, false, true, 'gyq', 'gyq', null, 1698058347559,
|
||||
1698058347559,
|
||||
null);
|
||||
|
||||
INSERT INTO user(id, name, email, password, enable, create_time, update_time, language, last_organization_id, phone,
|
||||
source,
|
||||
last_project_id, create_user, update_user, deleted)
|
||||
VALUES ('default-project-member-user-gyq', 'default-project-member-user1', 'project-member-gyq1@metersphere.io',
|
||||
MD5('metersphere'),
|
||||
true, UNIX_TIMESTAMP() * 1000,
|
||||
UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin', false),
|
||||
('default-project-member-user-gyq-1', 'default-project-member-user2', 'project-member-gyq2@metersphere.io',
|
||||
MD5('metersphere'), true, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL,
|
||||
'admin',
|
||||
'admin', 0),
|
||||
('default-project-member-user-gyq-2', 'default-project-member-user3', 'project-member-gyq3@metersphere.io',
|
||||
MD5('metersphere'), true, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL,
|
||||
'admin',
|
||||
'admin', 0),
|
||||
('default-project-member-user-gyq-3', 'default-project-member-user4', 'project-member-gyq4@metersphere.io',
|
||||
MD5('metersphere'), true, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL,
|
||||
'admin',
|
||||
'admin', 0);
|
||||
|
||||
|
||||
|
||||
INSERT INTO user_role_relation (id, user_id, role_id, source_id, organization_id, create_time, create_user)
|
||||
VALUES (UUID(), 'default-project-member-user-gyq', 'org_member', 'organization-review-case-test',
|
||||
'organization-review-case-test', UNIX_TIMESTAMP() * 1000, 'admin'),
|
||||
(UUID(), 'default-project-member-user-gyq-1', 'org_member', 'organization-review-case-test',
|
||||
'organization-review-case-test', UNIX_TIMESTAMP() * 1000,
|
||||
'admin'),
|
||||
(UUID(), 'default-project-member-user-gyq-2', 'org_member', 'organization-review-case-test',
|
||||
'organization-review-case-test', UNIX_TIMESTAMP() * 1000,
|
||||
'admin'),
|
||||
(UUID(), 'default-project-member-user-gyq-3', 'org_member', 'organization-review-case-test',
|
||||
'organization-review-case-test', UNIX_TIMESTAMP() * 1000,
|
||||
'admin');
|
||||
|
||||
INSERT INTO user_role_relation (id, user_id, role_id, source_id, organization_id, create_time, create_user)
|
||||
VALUES (UUID(), 'default-project-member-user-gyq', 'project_admin', 'project-review-case-test',
|
||||
'organization-review-case-test', UNIX_TIMESTAMP() * 1000,
|
||||
'admin'),
|
||||
(UUID(), 'default-project-member-user-gyq-1', 'project_admin', 'project-review-case-test',
|
||||
'organization-review-case-test', UNIX_TIMESTAMP() * 1000,
|
||||
'admin'),
|
||||
(UUID(), 'default-project-member-user-gyq-2', 'project_admin', 'project-review-case-test',
|
||||
'organization-review-case-test', UNIX_TIMESTAMP() * 1000,
|
||||
'admin'),
|
||||
(UUID(), 'default-project-member-user-gyq-3', 'project_admin', 'project-review-case-test',
|
||||
'organization-review-case-test', UNIX_TIMESTAMP() * 1000,
|
||||
'admin');
|
||||
|
||||
INSERT INTO user_role_permission(id, role_id, permission_id)
|
||||
VALUES ('user_role_gyq_permission1', 'project_admin', 'FUNCTIONAL_CASE:READ+COMMENT');
|
||||
|
||||
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.system.config.interceptor;
|
||||
|
||||
import io.metersphere.functional.domain.CaseReviewFunctionalCaseArchive;
|
||||
import io.metersphere.functional.domain.CaseReviewHistory;
|
||||
import io.metersphere.functional.domain.FunctionalCaseBlob;
|
||||
import io.metersphere.sdk.util.CompressUtils;
|
||||
import io.metersphere.system.utils.MybatisInterceptorConfig;
|
||||
|
@ -22,6 +23,8 @@ public class FunctionalCaseInterceptor {
|
|||
configList.add(new MybatisInterceptorConfig(FunctionalCaseBlob.class, "expectedResult", CompressUtils.class, "zip", "unzip"));
|
||||
configList.add(new MybatisInterceptorConfig(FunctionalCaseBlob.class, "prerequisite", CompressUtils.class, "zip", "unzip"));
|
||||
configList.add(new MybatisInterceptorConfig(FunctionalCaseBlob.class, "description", CompressUtils.class, "zip", "unzip"));
|
||||
configList.add(new MybatisInterceptorConfig(CaseReviewHistory.class, "content", CompressUtils.class, "zip", "unzip"));
|
||||
|
||||
return configList;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue