refactor(功能用例): 接口逻辑触发消息通知
This commit is contained in:
parent
b1c627ef3f
commit
c09f15ed11
|
@ -215,6 +215,8 @@ public class PermissionConstants {
|
||||||
public static final String FUNCTIONAL_CASE_READ_ADD = "FUNCTIONAL_CASE:READ+ADD";
|
public static final String FUNCTIONAL_CASE_READ_ADD = "FUNCTIONAL_CASE:READ+ADD";
|
||||||
public static final String FUNCTIONAL_CASE_READ_UPDATE = "FUNCTIONAL_CASE:READ+UPDATE";
|
public static final String FUNCTIONAL_CASE_READ_UPDATE = "FUNCTIONAL_CASE:READ+UPDATE";
|
||||||
public static final String FUNCTIONAL_CASE_COMMENT_READ_ADD = "FUNCTIONAL_CASE_COMMENT:READ+ADD";
|
public static final String FUNCTIONAL_CASE_COMMENT_READ_ADD = "FUNCTIONAL_CASE_COMMENT:READ+ADD";
|
||||||
|
public static final String FUNCTIONAL_CASE_COMMENT_READ_DELETE = "FUNCTIONAL_CASE_COMMENT:READ+DELETE";
|
||||||
|
|
||||||
|
|
||||||
/*------ end: FUNCTIONAL_CASE ------*/
|
/*------ end: FUNCTIONAL_CASE ------*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,3 +121,7 @@ custom_field_test_case.resource_id.not_blank=资源ID不能为空
|
||||||
custom_field_test_case.field_id.not_blank=字段ID不能为空
|
custom_field_test_case.field_id.not_blank=字段ID不能为空
|
||||||
#comment
|
#comment
|
||||||
case_comment.case_is_null=功能用例不存在
|
case_comment.case_is_null=功能用例不存在
|
||||||
|
case_comment.parent_id_is_null=当前回复的评论id为空
|
||||||
|
case_comment.parent_case_is_null=当前回复的评论不存在
|
||||||
|
case_comment.reply_user_is_null=回复的用户为空
|
||||||
|
case_comment.id_is_null=当前评论id为空
|
|
@ -138,3 +138,7 @@ custom_field_test_case.field_id.not_blank=Field ID cannot be empty
|
||||||
default_template_not_found=Default template not found
|
default_template_not_found=Default template not found
|
||||||
#comment
|
#comment
|
||||||
case_comment.case_is_null=Function use case does not exist
|
case_comment.case_is_null=Function use case does not exist
|
||||||
|
case_comment.parent_id_is_null=The comment id of the current reply is empty
|
||||||
|
case_comment.parent_case_is_null=The comment currently being replied to does not exist
|
||||||
|
case_comment.reply_user_is_null=The user who replied is empty
|
||||||
|
case_comment.id_is_null=The current comment id is empty
|
|
@ -138,3 +138,7 @@ custom_field_test_case.field_id.not_blank=字段ID不能为空
|
||||||
default_template_not_found=默认模板不存在
|
default_template_not_found=默认模板不存在
|
||||||
#comment
|
#comment
|
||||||
case_comment.case_is_null=功能用例不存在
|
case_comment.case_is_null=功能用例不存在
|
||||||
|
case_comment.parent_id_is_null=当前回复的评论id为空
|
||||||
|
case_comment.parent_case_is_null=当前回复的评论不存在
|
||||||
|
case_comment.reply_user_is_null=回复的用户为空
|
||||||
|
case_comment.id_is_null=当前评论id为空
|
|
@ -138,3 +138,7 @@ custom_field_test_case.field_id.not_blank=字段ID不能為空
|
||||||
default_template_not_found=默認模板不存在
|
default_template_not_found=默認模板不存在
|
||||||
#comment
|
#comment
|
||||||
case_comment.case_is_null=功能用例不存在
|
case_comment.case_is_null=功能用例不存在
|
||||||
|
case_comment.parent_id_is_null=目前回覆的評論id為空
|
||||||
|
case_comment.parent_case_is_null=目前回應的評論不存在
|
||||||
|
case_comment.reply_user_is_null=回覆的用戶為空
|
||||||
|
case_comment.id_is_null=目前評論id為空
|
|
@ -3,10 +3,7 @@ package io.metersphere.functional.controller;
|
||||||
import io.metersphere.functional.domain.FunctionalCaseComment;
|
import io.metersphere.functional.domain.FunctionalCaseComment;
|
||||||
import io.metersphere.functional.request.FunctionalCaseCommentRequest;
|
import io.metersphere.functional.request.FunctionalCaseCommentRequest;
|
||||||
import io.metersphere.functional.service.FunctionalCaseCommentService;
|
import io.metersphere.functional.service.FunctionalCaseCommentService;
|
||||||
import io.metersphere.functional.service.FunctionalCaseNoticeService;
|
|
||||||
import io.metersphere.sdk.constants.PermissionConstants;
|
import io.metersphere.sdk.constants.PermissionConstants;
|
||||||
import io.metersphere.system.notice.annotation.SendNotice;
|
|
||||||
import io.metersphere.system.notice.constants.NoticeConstants;
|
|
||||||
import io.metersphere.system.utils.SessionUtils;
|
import io.metersphere.system.utils.SessionUtils;
|
||||||
import io.metersphere.validation.groups.Created;
|
import io.metersphere.validation.groups.Created;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
@ -14,10 +11,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@Tag(name = "用例管理-功能用例-用例评论")
|
@Tag(name = "用例管理-功能用例-用例评论")
|
||||||
@RestController
|
@RestController
|
||||||
|
@ -30,8 +24,14 @@ public class FunctionalCaseCommentController {
|
||||||
@PostMapping("/save")
|
@PostMapping("/save")
|
||||||
@Operation(summary = "用例管理-功能用例-用例评论-创建评论")
|
@Operation(summary = "用例管理-功能用例-用例评论-创建评论")
|
||||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_COMMENT_READ_ADD)
|
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_COMMENT_READ_ADD)
|
||||||
@SendNotice(taskType = NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, event = NoticeConstants.Event.AT, target = "#targetClass.getRelatedUsers(#functionalCaseCommentRequest)", targetClass = FunctionalCaseNoticeService.class)
|
|
||||||
public FunctionalCaseComment saveComment(@Validated({Created.class}) @RequestBody FunctionalCaseCommentRequest functionalCaseCommentRequest) {
|
public FunctionalCaseComment saveComment(@Validated({Created.class}) @RequestBody FunctionalCaseCommentRequest functionalCaseCommentRequest) {
|
||||||
return functionalCaseCommentService.saveComment(functionalCaseCommentRequest, SessionUtils.getUserId());
|
return functionalCaseCommentService.saveComment(functionalCaseCommentRequest, SessionUtils.getUserId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/delete/{commentId}")
|
||||||
|
@Operation(summary = "用例管理-功能用例-用例评论-删除评论")
|
||||||
|
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_COMMENT_READ_DELETE)
|
||||||
|
public void deleteComment(@PathVariable String commentId) {
|
||||||
|
functionalCaseCommentService.deleteComment(commentId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
package io.metersphere.functional.dto;
|
package io.metersphere.functional.dto;
|
||||||
|
|
||||||
import io.metersphere.functional.domain.FunctionalCase;
|
import io.metersphere.functional.domain.FunctionalCase;
|
||||||
|
import io.metersphere.system.dto.sdk.OptionDTO;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class FunctionalCaseDTO extends FunctionalCase {
|
public class FunctionalCaseDTO extends FunctionalCase {
|
||||||
|
|
||||||
@Schema(description = "评论@的人, 多个以';'隔开")
|
@Schema(description = "评论@的人, 多个以';'隔开")
|
||||||
private String relatedUsers;
|
private String relatedUsers;
|
||||||
|
|
||||||
|
@Schema(description = "自定义字段的值")
|
||||||
|
private List<OptionDTO> fields;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ public class FunctionalCaseCommentRequest {
|
||||||
@NotBlank(message = "{functional_case_comment.case_id.not_blank}", groups = {Created.class})
|
@NotBlank(message = "{functional_case_comment.case_id.not_blank}", groups = {Created.class})
|
||||||
private String caseId;
|
private String caseId;
|
||||||
|
|
||||||
@Schema(description = "评论@的人, 多个以';'隔开")
|
@Schema(description = "评论@的人的Id, 多个以';'隔开")
|
||||||
private String notifier;
|
private String notifier;
|
||||||
|
|
||||||
@Schema(description = "回复人")
|
@Schema(description = "回复人")
|
||||||
|
@ -27,4 +27,8 @@ public class FunctionalCaseCommentRequest {
|
||||||
@NotBlank(message = "{functional_case_comment.content.not_blank}", groups = {Created.class})
|
@NotBlank(message = "{functional_case_comment.content.not_blank}", groups = {Created.class})
|
||||||
private String content;
|
private String content;
|
||||||
|
|
||||||
|
@Schema(description = "任务事件(仅评论: ’COMMENT‘; 评论并@: ’AT‘; 回复评论/回复并@: ’REPLAY‘;)", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{functional_case_comment.event.not_blank}", groups = {Created.class})
|
||||||
|
private String event;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,17 +2,29 @@ package io.metersphere.functional.service;
|
||||||
|
|
||||||
import io.metersphere.functional.domain.FunctionalCase;
|
import io.metersphere.functional.domain.FunctionalCase;
|
||||||
import io.metersphere.functional.domain.FunctionalCaseComment;
|
import io.metersphere.functional.domain.FunctionalCaseComment;
|
||||||
|
import io.metersphere.functional.domain.FunctionalCaseCommentExample;
|
||||||
import io.metersphere.functional.dto.CommentEnum;
|
import io.metersphere.functional.dto.CommentEnum;
|
||||||
|
import io.metersphere.functional.dto.FunctionalCaseDTO;
|
||||||
import io.metersphere.functional.mapper.FunctionalCaseCommentMapper;
|
import io.metersphere.functional.mapper.FunctionalCaseCommentMapper;
|
||||||
import io.metersphere.functional.mapper.FunctionalCaseMapper;
|
import io.metersphere.functional.mapper.FunctionalCaseMapper;
|
||||||
import io.metersphere.functional.request.FunctionalCaseCommentRequest;
|
import io.metersphere.functional.request.FunctionalCaseCommentRequest;
|
||||||
import io.metersphere.sdk.exception.MSException;
|
import io.metersphere.sdk.exception.MSException;
|
||||||
import io.metersphere.sdk.util.Translator;
|
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 io.metersphere.system.uid.IDGenerator;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.commons.beanutils.BeanMap;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author guoyuqi
|
* @author guoyuqi
|
||||||
*/
|
*/
|
||||||
|
@ -26,14 +38,42 @@ public class FunctionalCaseCommentService {
|
||||||
@Resource
|
@Resource
|
||||||
private FunctionalCaseMapper functionalCaseMapper;
|
private FunctionalCaseMapper functionalCaseMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private UserMapper userMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private FunctionalCaseNoticeService functionalCaseNoticeService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private NoticeSendService noticeSendService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增评论
|
* 新增评论
|
||||||
|
*
|
||||||
* @param functionalCaseCommentRequest functionalCaseCommentDTO
|
* @param functionalCaseCommentRequest functionalCaseCommentDTO
|
||||||
* @param userId 当前操作用户
|
* @param userId 当前操作用户
|
||||||
* @return FunctionalCaseComment
|
* @return FunctionalCaseComment
|
||||||
*/
|
*/
|
||||||
public FunctionalCaseComment saveComment(FunctionalCaseCommentRequest functionalCaseCommentRequest, String userId) {
|
public FunctionalCaseComment saveComment(FunctionalCaseCommentRequest functionalCaseCommentRequest, String userId) {
|
||||||
checkCase(functionalCaseCommentRequest);
|
checkCase(functionalCaseCommentRequest);
|
||||||
|
FunctionalCaseComment functionalCaseComment = getFunctionalCaseComment(functionalCaseCommentRequest, userId);
|
||||||
|
if (StringUtils.equals(functionalCaseCommentRequest.getEvent(), NoticeConstants.Event.REPLY)) {
|
||||||
|
return saveCommentWidthNotice(functionalCaseCommentRequest, functionalCaseComment, userId);
|
||||||
|
} else {
|
||||||
|
return saveCommentWidthOutNotice(functionalCaseCommentRequest, functionalCaseComment, userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 组装除通知人,被回复的id外的其他用例评论属性
|
||||||
|
*
|
||||||
|
* @param functionalCaseCommentRequest 页面参数
|
||||||
|
* @param userId 当前操作人
|
||||||
|
* @return FunctionalCaseComment
|
||||||
|
*/
|
||||||
|
private static FunctionalCaseComment getFunctionalCaseComment(FunctionalCaseCommentRequest functionalCaseCommentRequest, String userId) {
|
||||||
FunctionalCaseComment functionalCaseComment = new FunctionalCaseComment();
|
FunctionalCaseComment functionalCaseComment = new FunctionalCaseComment();
|
||||||
functionalCaseComment.setId(IDGenerator.nextStr());
|
functionalCaseComment.setId(IDGenerator.nextStr());
|
||||||
functionalCaseComment.setCaseId(functionalCaseCommentRequest.getCaseId());
|
functionalCaseComment.setCaseId(functionalCaseCommentRequest.getCaseId());
|
||||||
|
@ -42,20 +82,120 @@ public class FunctionalCaseCommentService {
|
||||||
functionalCaseComment.setCreateTime(System.currentTimeMillis());
|
functionalCaseComment.setCreateTime(System.currentTimeMillis());
|
||||||
functionalCaseComment.setUpdateTime(System.currentTimeMillis());
|
functionalCaseComment.setUpdateTime(System.currentTimeMillis());
|
||||||
functionalCaseComment.setType(CommentEnum.CASE.toString());
|
functionalCaseComment.setType(CommentEnum.CASE.toString());
|
||||||
if (StringUtils.isNotBlank(functionalCaseCommentRequest.getNotifier())) {
|
|
||||||
functionalCaseComment.setNotifier(functionalCaseCommentRequest.getNotifier());
|
|
||||||
}
|
|
||||||
if (StringUtils.isNotBlank(functionalCaseCommentRequest.getParentId())) {
|
|
||||||
functionalCaseComment.setParentId(functionalCaseCommentRequest.getParentId());
|
|
||||||
}
|
|
||||||
functionalCaseCommentMapper.insert(functionalCaseComment);
|
|
||||||
return functionalCaseComment;
|
return functionalCaseComment;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkCase(FunctionalCaseCommentRequest functionalCaseCommentRequest) {
|
private void checkCase(FunctionalCaseCommentRequest functionalCaseCommentRequest) {
|
||||||
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(functionalCaseCommentRequest.getCaseId());
|
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(functionalCaseCommentRequest.getCaseId());
|
||||||
if (functionalCase ==null) {
|
if (functionalCase == null) {
|
||||||
throw new MSException(Translator.get("case_comment.case_is_null"));
|
throw new MSException(Translator.get("case_comment.case_is_null"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 非REPLAY事件,保存
|
||||||
|
* @param functionalCaseCommentRequest 页面参数
|
||||||
|
* @param functionalCaseComment 被组装的半份数据
|
||||||
|
* @return FunctionalCaseComment
|
||||||
|
*/
|
||||||
|
public FunctionalCaseComment saveCommentWidthOutNotice(FunctionalCaseCommentRequest functionalCaseCommentRequest, FunctionalCaseComment functionalCaseComment, String userId) {
|
||||||
|
if (StringUtils.isNotBlank(functionalCaseCommentRequest.getNotifier())) {
|
||||||
|
functionalCaseComment.setNotifier(functionalCaseCommentRequest.getNotifier());
|
||||||
|
}
|
||||||
|
functionalCaseCommentMapper.insert(functionalCaseComment);
|
||||||
|
FunctionalCaseDTO functionalCaseDTO = functionalCaseNoticeService.getFunctionalCaseDTO(functionalCaseCommentRequest);
|
||||||
|
sendNotice(functionalCaseCommentRequest, userId, functionalCaseDTO);
|
||||||
|
return functionalCaseComment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果是REPLAY事件,需要再次发送回复被@的通知
|
||||||
|
* @param functionalCaseCommentRequest 页面参数
|
||||||
|
* @param functionalCaseComment 被组装的半份数据
|
||||||
|
* @return FunctionalCaseComment
|
||||||
|
*/
|
||||||
|
public FunctionalCaseComment saveCommentWidthNotice(FunctionalCaseCommentRequest functionalCaseCommentRequest, FunctionalCaseComment functionalCaseComment, String userId) {
|
||||||
|
checkParentId(functionalCaseCommentRequest, functionalCaseComment);
|
||||||
|
if (StringUtils.isBlank(functionalCaseCommentRequest.getReplyUser())) {
|
||||||
|
throw new MSException(Translator.get("case_comment.reply_user_is_null"));
|
||||||
|
}
|
||||||
|
functionalCaseCommentRequest.setReplyUser(functionalCaseCommentRequest.getReplyUser());
|
||||||
|
if (StringUtils.isNotBlank(functionalCaseCommentRequest.getNotifier())) {
|
||||||
|
functionalCaseComment.setNotifier(functionalCaseCommentRequest.getNotifier());
|
||||||
|
}
|
||||||
|
functionalCaseCommentMapper.insert(functionalCaseComment);
|
||||||
|
FunctionalCaseDTO functionalCaseDTOReply = functionalCaseNoticeService.getFunctionalCaseDTO(functionalCaseCommentRequest);
|
||||||
|
sendNotice(functionalCaseCommentRequest, userId, functionalCaseDTOReply);
|
||||||
|
functionalCaseCommentRequest.setEvent(NoticeConstants.Event.AT);
|
||||||
|
FunctionalCaseDTO functionalCaseDTO = functionalCaseNoticeService.getFunctionalCaseDTO(functionalCaseCommentRequest);
|
||||||
|
//发通知
|
||||||
|
sendNotice(functionalCaseCommentRequest, userId, functionalCaseDTO);
|
||||||
|
return functionalCaseComment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Async
|
||||||
|
public void sendNotice(FunctionalCaseCommentRequest functionalCaseCommentRequest, String userId, FunctionalCaseDTO functionalCaseDTO) {
|
||||||
|
Map<String, String> defaultTemplateMap = MessageTemplateUtils.getDefaultTemplateMap();
|
||||||
|
String template = defaultTemplateMap.get(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK + "_" + functionalCaseCommentRequest.getEvent());
|
||||||
|
Map<String, String> defaultSubjectMap = MessageTemplateUtils.getDefaultTemplateSubjectMap();
|
||||||
|
String subject = defaultSubjectMap.get(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK + "_" + functionalCaseCommentRequest.getEvent());
|
||||||
|
List<String> relatedUsers = getRelatedUsers(functionalCaseDTO.getRelatedUsers());
|
||||||
|
User user = userMapper.selectByPrimaryKey(userId);
|
||||||
|
BeanMap beanMap = new BeanMap(functionalCaseDTO);
|
||||||
|
Map paramMap = new HashMap<>(beanMap);
|
||||||
|
paramMap.put(NoticeConstants.RelatedUser.OPERATOR, user.getName());
|
||||||
|
NoticeModel noticeModel = NoticeModel.builder()
|
||||||
|
.operator(userId)
|
||||||
|
.context(template)
|
||||||
|
.subject(subject)
|
||||||
|
.paramMap(paramMap)
|
||||||
|
.event(functionalCaseCommentRequest.getEvent())
|
||||||
|
.status((String) paramMap.get("status"))
|
||||||
|
.excludeSelf(true)
|
||||||
|
.relatedUsers(relatedUsers)
|
||||||
|
.build();
|
||||||
|
noticeSendService.send(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK, noticeModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查被回复的评论是否为空
|
||||||
|
* @param functionalCaseCommentRequest 页面参数
|
||||||
|
* @param functionalCaseComment 被组装的半份数据
|
||||||
|
*/
|
||||||
|
private void checkParentId(FunctionalCaseCommentRequest functionalCaseCommentRequest, FunctionalCaseComment functionalCaseComment) {
|
||||||
|
String parentId = functionalCaseCommentRequest.getParentId();
|
||||||
|
if (StringUtils.isBlank(parentId)) {
|
||||||
|
throw new MSException(Translator.get("case_comment.parent_id_is_null"));
|
||||||
|
}
|
||||||
|
FunctionalCaseComment parentComment = functionalCaseCommentMapper.selectByPrimaryKey(parentId);
|
||||||
|
if (parentComment==null) {
|
||||||
|
throw new MSException(Translator.get("case_comment.parent_case_is_null"));
|
||||||
|
}
|
||||||
|
functionalCaseComment.setParentId(parentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> getRelatedUsers(Object relatedUsers) {
|
||||||
|
String relatedUser = (String) relatedUsers;
|
||||||
|
List<String> relatedUserList = new ArrayList<>();
|
||||||
|
if (StringUtils.isNotBlank(relatedUser)) {
|
||||||
|
relatedUserList = Arrays.asList(relatedUser.split(";"));
|
||||||
|
}
|
||||||
|
return relatedUserList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteComment(String commentId) {
|
||||||
|
FunctionalCaseComment functionalCaseComment = functionalCaseCommentMapper.selectByPrimaryKey(commentId);
|
||||||
|
if (functionalCaseComment == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//删除选中的评论下的所有回复
|
||||||
|
FunctionalCaseCommentExample functionalCaseCommentExample = new FunctionalCaseCommentExample();
|
||||||
|
functionalCaseCommentExample.createCriteria().andParentIdEqualTo(commentId);
|
||||||
|
List<FunctionalCaseComment> functionalCaseComments = functionalCaseCommentMapper.selectByExample(functionalCaseCommentExample);
|
||||||
|
List<String> commentIds = new ArrayList<>(functionalCaseComments.stream().map(FunctionalCaseComment::getId).toList());
|
||||||
|
commentIds.add(commentId);
|
||||||
|
functionalCaseCommentExample = new FunctionalCaseCommentExample();
|
||||||
|
functionalCaseCommentExample.createCriteria().andIdIn(commentIds);
|
||||||
|
functionalCaseCommentMapper.deleteByExample(functionalCaseCommentExample);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,121 @@
|
||||||
package io.metersphere.functional.service;
|
package io.metersphere.functional.service;
|
||||||
|
|
||||||
import io.metersphere.functional.domain.FunctionalCase;
|
import io.metersphere.functional.domain.FunctionalCase;
|
||||||
|
import io.metersphere.functional.domain.FunctionalCaseCustomField;
|
||||||
|
import io.metersphere.functional.domain.FunctionalCaseCustomFieldExample;
|
||||||
import io.metersphere.functional.dto.FunctionalCaseDTO;
|
import io.metersphere.functional.dto.FunctionalCaseDTO;
|
||||||
|
import io.metersphere.functional.mapper.FunctionalCaseCustomFieldMapper;
|
||||||
import io.metersphere.functional.mapper.FunctionalCaseMapper;
|
import io.metersphere.functional.mapper.FunctionalCaseMapper;
|
||||||
import io.metersphere.functional.request.FunctionalCaseCommentRequest;
|
import io.metersphere.functional.request.FunctionalCaseCommentRequest;
|
||||||
import io.metersphere.sdk.util.BeanUtils;
|
import io.metersphere.sdk.util.BeanUtils;
|
||||||
|
import io.metersphere.system.domain.CustomField;
|
||||||
|
import io.metersphere.system.domain.CustomFieldExample;
|
||||||
|
import io.metersphere.system.dto.sdk.OptionDTO;
|
||||||
|
import io.metersphere.system.mapper.CustomFieldMapper;
|
||||||
|
import io.metersphere.system.notice.constants.NoticeConstants;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class FunctionalCaseNoticeService {
|
public class FunctionalCaseNoticeService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private FunctionalCaseMapper functionalCaseMapper;
|
private FunctionalCaseMapper functionalCaseMapper;
|
||||||
|
|
||||||
public FunctionalCaseDTO getRelatedUsers(FunctionalCaseCommentRequest functionalCaseCommentRequest){
|
@Resource
|
||||||
|
private FunctionalCaseCustomFieldMapper functionalCaseCustomFieldMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CustomFieldMapper customFieldMapper;
|
||||||
|
|
||||||
|
public FunctionalCaseDTO getFunctionalCaseDTO(FunctionalCaseCommentRequest functionalCaseCommentRequest){
|
||||||
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(functionalCaseCommentRequest.getCaseId());
|
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(functionalCaseCommentRequest.getCaseId());
|
||||||
FunctionalCaseDTO functionalCaseDTO = new FunctionalCaseDTO();
|
FunctionalCaseDTO functionalCaseDTO = new FunctionalCaseDTO();
|
||||||
if (functionalCase!=null) {
|
if (functionalCase!=null) {
|
||||||
BeanUtils.copyBean(functionalCaseDTO,functionalCase);
|
BeanUtils.copyBean(functionalCaseDTO,functionalCase);
|
||||||
}
|
}
|
||||||
functionalCaseDTO.setRelatedUsers(functionalCaseCommentRequest.getNotifier());
|
setNotifier(functionalCaseCommentRequest, functionalCaseDTO);
|
||||||
|
List<OptionDTO> customFields = getCustomFields(functionalCaseCommentRequest.getCaseId());
|
||||||
|
functionalCaseDTO.setFields(customFields);
|
||||||
return functionalCaseDTO;
|
return functionalCaseDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 如果是REPLAY事件,需要判断有无@的人,如果有@的人且当前被回复的人不是同一人,这里只要被回复的人,如果是同一人,这里通知人为空,走AT事件
|
||||||
|
* 如果不是REPLAY事件,需要判断有无被回复的人,如果被回复的人不在被@人里,则用页面参数传递的通知人,如果在,则排除这个人,如果没有被回复的人,用页面数据
|
||||||
|
* @param functionalCaseCommentRequest 页面参数
|
||||||
|
* @param functionalCaseDTO 发通知需要解析字段集合
|
||||||
|
*/
|
||||||
|
private void setNotifier(FunctionalCaseCommentRequest functionalCaseCommentRequest, FunctionalCaseDTO functionalCaseDTO) {
|
||||||
|
String notifier = functionalCaseCommentRequest.getNotifier();
|
||||||
|
String replyUser = functionalCaseCommentRequest.getReplyUser();
|
||||||
|
if (StringUtils.equals(functionalCaseCommentRequest.getEvent(), NoticeConstants.Event.REPLY)) {
|
||||||
|
if (StringUtils.isNotBlank(replyUser)) {
|
||||||
|
if (StringUtils.isNotBlank(notifier)) {
|
||||||
|
List<String> notifierList = Arrays.asList(notifier.split(";"));
|
||||||
|
if (!notifierList.contains(replyUser)) {
|
||||||
|
functionalCaseDTO.setRelatedUsers(replyUser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (StringUtils.isNotBlank(replyUser)) {
|
||||||
|
StringBuilder notifierStr = new StringBuilder();
|
||||||
|
if (StringUtils.isNotBlank(notifier)) {
|
||||||
|
List<String> notifierList = Arrays.asList(notifier.split(";"));
|
||||||
|
if (notifierList.contains(replyUser)) {
|
||||||
|
for (String notifierId : notifierList) {
|
||||||
|
if (!StringUtils.equals(notifierId, replyUser)) {
|
||||||
|
notifierStr.append(notifierId).append(";");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
notifierStr = new StringBuilder(notifier);
|
||||||
|
}
|
||||||
|
functionalCaseDTO.setRelatedUsers(notifierStr.toString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
functionalCaseDTO.setRelatedUsers(notifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用例id获取当前用例在使用的自定义的字段及其值
|
||||||
|
*
|
||||||
|
* @param caseId 用例Id
|
||||||
|
* @return 返回 字段以及字段值的组合
|
||||||
|
*/
|
||||||
|
private List<OptionDTO> getCustomFields(String caseId) {
|
||||||
|
FunctionalCaseCustomFieldExample functionalCaseCustomFieldExample = new FunctionalCaseCustomFieldExample();
|
||||||
|
functionalCaseCustomFieldExample.createCriteria().andCaseIdEqualTo(caseId);
|
||||||
|
List<FunctionalCaseCustomField> functionalCaseCustomFields = functionalCaseCustomFieldMapper.selectByExample(functionalCaseCustomFieldExample);
|
||||||
|
List<OptionDTO>optionDTOList = new ArrayList<>();
|
||||||
|
if (CollectionUtils.isNotEmpty(functionalCaseCustomFields)) {
|
||||||
|
Map<String, String> fieldValueMap = functionalCaseCustomFields.stream().collect(Collectors.toMap(FunctionalCaseCustomField::getFieldId, FunctionalCaseCustomField::getValue));
|
||||||
|
List<String> fieldIds = functionalCaseCustomFields.stream().map(FunctionalCaseCustomField::getFieldId).distinct().toList();
|
||||||
|
CustomFieldExample customFieldExample = new CustomFieldExample();
|
||||||
|
customFieldExample.createCriteria().andIdIn(fieldIds);
|
||||||
|
List<CustomField> customFields = customFieldMapper.selectByExample(customFieldExample);
|
||||||
|
customFields.forEach(t->{
|
||||||
|
OptionDTO optionDTO = new OptionDTO();
|
||||||
|
optionDTO.setId(t.getName());
|
||||||
|
optionDTO.setName(fieldValueMap.get(t.getId()));
|
||||||
|
optionDTOList.add(optionDTO);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return optionDTOList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,23 @@ package io.metersphere.functional.controller;
|
||||||
|
|
||||||
import com.jayway.jsonpath.JsonPath;
|
import com.jayway.jsonpath.JsonPath;
|
||||||
import io.metersphere.functional.domain.FunctionalCaseComment;
|
import io.metersphere.functional.domain.FunctionalCaseComment;
|
||||||
|
import io.metersphere.functional.domain.FunctionalCaseCommentExample;
|
||||||
|
import io.metersphere.functional.domain.FunctionalCaseCustomField;
|
||||||
|
import io.metersphere.functional.mapper.FunctionalCaseCommentMapper;
|
||||||
|
import io.metersphere.functional.mapper.FunctionalCaseCustomFieldMapper;
|
||||||
import io.metersphere.functional.request.FunctionalCaseCommentRequest;
|
import io.metersphere.functional.request.FunctionalCaseCommentRequest;
|
||||||
import io.metersphere.project.domain.Notification;
|
import io.metersphere.project.domain.Notification;
|
||||||
import io.metersphere.project.domain.NotificationExample;
|
import io.metersphere.project.domain.NotificationExample;
|
||||||
import io.metersphere.project.mapper.NotificationMapper;
|
import io.metersphere.project.mapper.NotificationMapper;
|
||||||
|
import io.metersphere.sdk.constants.CustomFieldType;
|
||||||
import io.metersphere.sdk.constants.SessionConstants;
|
import io.metersphere.sdk.constants.SessionConstants;
|
||||||
|
import io.metersphere.sdk.constants.TemplateScene;
|
||||||
|
import io.metersphere.sdk.constants.TemplateScopeType;
|
||||||
import io.metersphere.sdk.util.JSON;
|
import io.metersphere.sdk.util.JSON;
|
||||||
|
import io.metersphere.sdk.util.Translator;
|
||||||
import io.metersphere.system.controller.handler.ResultHolder;
|
import io.metersphere.system.controller.handler.ResultHolder;
|
||||||
|
import io.metersphere.system.domain.CustomField;
|
||||||
|
import io.metersphere.system.mapper.CustomFieldMapper;
|
||||||
import io.metersphere.system.notice.constants.NoticeConstants;
|
import io.metersphere.system.notice.constants.NoticeConstants;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
@ -33,17 +43,29 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
@AutoConfigureMockMvc
|
@AutoConfigureMockMvc
|
||||||
public class FunctionalCaseCommentControllerTests {
|
public class FunctionalCaseCommentControllerTests {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private MockMvc mockMvc;
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private NotificationMapper notificationMapper;
|
private NotificationMapper notificationMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private FunctionalCaseCommentMapper functionalCaseCommentMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CustomFieldMapper customFieldMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private FunctionalCaseCustomFieldMapper functionalCaseCustomFieldMapper;
|
||||||
|
|
||||||
public static final String SAVE_URL = "/functional/case/comment/save";
|
public static final String SAVE_URL = "/functional/case/comment/save";
|
||||||
|
public static final String DELETE_URL = "/functional/case/comment/delete/";
|
||||||
|
|
||||||
|
|
||||||
private static String sessionId;
|
private static String sessionId;
|
||||||
private static String csrfToken;
|
private static String csrfToken;
|
||||||
private static String projectId = "100001100001";
|
private static final String projectId = "100001100001";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(0)
|
@Order(0)
|
||||||
|
@ -61,25 +83,17 @@ public class FunctionalCaseCommentControllerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(1)
|
@Order(1)
|
||||||
public void saveCommentSuccess() throws Exception {
|
public void saveCommentATSuccess() throws Exception {
|
||||||
FunctionalCaseCommentRequest functionalCaseCommentRequest = new FunctionalCaseCommentRequest();
|
FunctionalCaseCommentRequest functionalCaseCommentRequest = new FunctionalCaseCommentRequest();
|
||||||
functionalCaseCommentRequest.setCaseId("xiaomeinvGTest");
|
functionalCaseCommentRequest.setCaseId("xiaomeinvGTest");
|
||||||
functionalCaseCommentRequest.setNotifier("default-project-member-user-guo-1");
|
functionalCaseCommentRequest.setNotifier("default-project-member-user-guo-1");
|
||||||
functionalCaseCommentRequest.setContent("评论你好");
|
functionalCaseCommentRequest.setContent("评论你好");
|
||||||
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post(SAVE_URL).header(SessionConstants.HEADER_TOKEN, sessionId)
|
functionalCaseCommentRequest.setEvent(NoticeConstants.Event.AT);
|
||||||
.header(SessionConstants.CSRF_TOKEN, csrfToken)
|
FunctionalCaseComment functionalCaseComment = getFunctionalCaseComment(functionalCaseCommentRequest);
|
||||||
.header(SessionConstants.CURRENT_PROJECT, projectId)
|
|
||||||
.content(JSON.toJSONString(functionalCaseCommentRequest))
|
|
||||||
.contentType(MediaType.APPLICATION_JSON))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
|
|
||||||
String contentAsString = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
|
||||||
ResultHolder resultHolder = JSON.parseObject(contentAsString, ResultHolder.class);
|
|
||||||
FunctionalCaseComment functionalCaseComment = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), FunctionalCaseComment.class);
|
|
||||||
NotificationExample notificationExample = new NotificationExample();
|
NotificationExample notificationExample = new NotificationExample();
|
||||||
notificationExample.createCriteria().andResourceIdEqualTo("xiaomeinvGTest").andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK);
|
notificationExample.createCriteria().andResourceIdEqualTo("xiaomeinvGTest").andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK);
|
||||||
List<Notification> notifications = notificationMapper.selectByExampleWithBLOBs(notificationExample);
|
List<Notification> notifications = notificationMapper.selectByExampleWithBLOBs(notificationExample);
|
||||||
Assertions.assertTrue(notifications.size() > 0);
|
Assertions.assertFalse(notifications.isEmpty());
|
||||||
Assertions.assertTrue(StringUtils.equals(notifications.get(0).getReceiver(), "default-project-member-user-guo-1"));
|
Assertions.assertTrue(StringUtils.equals(notifications.get(0).getReceiver(), "default-project-member-user-guo-1"));
|
||||||
System.out.println(notifications.get(0).getContent());
|
System.out.println(notifications.get(0).getContent());
|
||||||
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getCaseId(), "xiaomeinvGTest"));
|
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getCaseId(), "xiaomeinvGTest"));
|
||||||
|
@ -89,41 +103,42 @@ public class FunctionalCaseCommentControllerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(2)
|
@Order(2)
|
||||||
public void saveCommentFalse() throws Exception {
|
public void saveCommentATFalse() throws Exception {
|
||||||
FunctionalCaseCommentRequest functionalCaseCommentRequest = new FunctionalCaseCommentRequest();
|
FunctionalCaseCommentRequest functionalCaseCommentRequest = new FunctionalCaseCommentRequest();
|
||||||
functionalCaseCommentRequest.setCaseId("xiaomeinvGTestNo");
|
functionalCaseCommentRequest.setCaseId("xiaomeinvGTestNo");
|
||||||
functionalCaseCommentRequest.setNotifier("default-project-member-user-guo-1");
|
functionalCaseCommentRequest.setNotifier("default-project-member-user-guo-1");
|
||||||
functionalCaseCommentRequest.setContent("评论你好");
|
functionalCaseCommentRequest.setContent("评论你好");
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post(SAVE_URL).header(SessionConstants.HEADER_TOKEN, sessionId)
|
functionalCaseCommentRequest.setEvent(NoticeConstants.Event.AT);
|
||||||
.header(SessionConstants.CSRF_TOKEN, csrfToken)
|
ResultHolder resultHolder = postFalse(functionalCaseCommentRequest);
|
||||||
.header(SessionConstants.CURRENT_PROJECT, projectId)
|
String jsonString = JSON.toJSONString(resultHolder.getData());
|
||||||
.content(JSON.toJSONString(functionalCaseCommentRequest))
|
System.out.println(jsonString);
|
||||||
.contentType(MediaType.APPLICATION_JSON))
|
|
||||||
.andExpect(status().is5xxServerError())
|
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
|
|
||||||
NotificationExample notificationExample = new NotificationExample();
|
NotificationExample notificationExample = new NotificationExample();
|
||||||
notificationExample.createCriteria().andResourceIdEqualTo("xiaomeinvGTestNo").andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK);
|
notificationExample.createCriteria().andResourceIdEqualTo("xiaomeinvGTestNo").andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK);
|
||||||
List<Notification> notifications = notificationMapper.selectByExample(notificationExample);
|
List<Notification> notifications = notificationMapper.selectByExample(notificationExample);
|
||||||
Assertions.assertTrue(CollectionUtils.isEmpty(notifications));
|
Assertions.assertTrue(CollectionUtils.isEmpty(notifications));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
private ResultHolder postFalse(FunctionalCaseCommentRequest functionalCaseCommentRequest) throws Exception {
|
||||||
@Order(3)
|
|
||||||
public void saveCommentExcludeSelfSuccess() throws Exception {
|
|
||||||
FunctionalCaseCommentRequest functionalCaseCommentRequest = new FunctionalCaseCommentRequest();
|
|
||||||
functionalCaseCommentRequest.setCaseId("xiaomeinvGTest");
|
|
||||||
functionalCaseCommentRequest.setNotifier("default-project-member-user-guo");
|
|
||||||
functionalCaseCommentRequest.setContent("这个好");
|
|
||||||
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post(SAVE_URL).header(SessionConstants.HEADER_TOKEN, sessionId)
|
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post(SAVE_URL).header(SessionConstants.HEADER_TOKEN, sessionId)
|
||||||
.header(SessionConstants.CSRF_TOKEN, csrfToken)
|
.header(SessionConstants.CSRF_TOKEN, csrfToken)
|
||||||
.header(SessionConstants.CURRENT_PROJECT, projectId)
|
.header(SessionConstants.CURRENT_PROJECT, projectId)
|
||||||
.content(JSON.toJSONString(functionalCaseCommentRequest))
|
.content(JSON.toJSONString(functionalCaseCommentRequest))
|
||||||
.contentType(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().is5xxServerError())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
|
||||||
String contentAsString = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
String contentAsString = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||||
ResultHolder resultHolder = JSON.parseObject(contentAsString, ResultHolder.class);
|
return JSON.parseObject(contentAsString, ResultHolder.class);
|
||||||
FunctionalCaseComment functionalCaseComment = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), FunctionalCaseComment.class);
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(3)
|
||||||
|
public void saveCommentATExcludeSelfSuccess() throws Exception {
|
||||||
|
FunctionalCaseCommentRequest functionalCaseCommentRequest = new FunctionalCaseCommentRequest();
|
||||||
|
functionalCaseCommentRequest.setCaseId("xiaomeinvGTest");
|
||||||
|
functionalCaseCommentRequest.setNotifier("default-project-member-user-guo");
|
||||||
|
functionalCaseCommentRequest.setContent("这个好");
|
||||||
|
functionalCaseCommentRequest.setEvent(NoticeConstants.Event.AT);
|
||||||
|
FunctionalCaseComment functionalCaseComment = getFunctionalCaseComment(functionalCaseCommentRequest);
|
||||||
NotificationExample notificationExample = new NotificationExample();
|
NotificationExample notificationExample = new NotificationExample();
|
||||||
notificationExample.createCriteria().andResourceIdEqualTo("xiaomeinvGTest").andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK).andReceiverEqualTo("default-project-member-user-guo");
|
notificationExample.createCriteria().andResourceIdEqualTo("xiaomeinvGTest").andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK).andReceiverEqualTo("default-project-member-user-guo");
|
||||||
List<Notification> notifications = notificationMapper.selectByExample(notificationExample);
|
List<Notification> notifications = notificationMapper.selectByExample(notificationExample);
|
||||||
|
@ -133,4 +148,260 @@ public class FunctionalCaseCommentControllerTests {
|
||||||
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getContent(), "这个好"));
|
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getContent(), "这个好"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(4)
|
||||||
|
public void saveCommentATNoNotifierSuccess() throws Exception {
|
||||||
|
FunctionalCaseCommentRequest functionalCaseCommentRequest = new FunctionalCaseCommentRequest();
|
||||||
|
functionalCaseCommentRequest.setCaseId("xiaomeinvGTestOne");
|
||||||
|
functionalCaseCommentRequest.setContent("这个好");
|
||||||
|
functionalCaseCommentRequest.setEvent(NoticeConstants.Event.AT);
|
||||||
|
FunctionalCaseComment functionalCaseComment = getFunctionalCaseComment(functionalCaseCommentRequest);
|
||||||
|
NotificationExample notificationExample = new NotificationExample();
|
||||||
|
notificationExample.createCriteria().andResourceIdEqualTo("xiaomeinvGTestOne").andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK);
|
||||||
|
List<Notification> notifications = notificationMapper.selectByExample(notificationExample);
|
||||||
|
Assertions.assertTrue(CollectionUtils.isEmpty(notifications));
|
||||||
|
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getCaseId(), "xiaomeinvGTestOne"));
|
||||||
|
Assertions.assertTrue(StringUtils.isBlank(functionalCaseComment.getNotifier()));
|
||||||
|
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getContent(), "这个好"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(5)
|
||||||
|
public void saveOnlyCommentSuccess() throws Exception {
|
||||||
|
FunctionalCaseCommentRequest functionalCaseCommentRequest = new FunctionalCaseCommentRequest();
|
||||||
|
functionalCaseCommentRequest.setCaseId("xiaomeinvGTestOne");
|
||||||
|
functionalCaseCommentRequest.setContent("评论你好");
|
||||||
|
functionalCaseCommentRequest.setEvent(NoticeConstants.Event.COMMENT);
|
||||||
|
FunctionalCaseComment functionalCaseComment = getFunctionalCaseComment(functionalCaseCommentRequest);
|
||||||
|
NotificationExample notificationExample = new NotificationExample();
|
||||||
|
notificationExample.createCriteria().andResourceIdEqualTo("xiaomeinvGTestOne").andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK);
|
||||||
|
List<Notification> notifications = notificationMapper.selectByExampleWithBLOBs(notificationExample);
|
||||||
|
Assertions.assertFalse(notifications.isEmpty());
|
||||||
|
System.out.println(JSON.toJSONString(notifications));
|
||||||
|
Assertions.assertTrue(StringUtils.equals(notifications.get(0).getReceiver(), "gyq"));
|
||||||
|
System.out.println(notifications.get(0).getContent());
|
||||||
|
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getCaseId(), "xiaomeinvGTestOne"));
|
||||||
|
Assertions.assertTrue(StringUtils.isBlank(functionalCaseComment.getNotifier()));
|
||||||
|
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getContent(), "评论你好"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(6)
|
||||||
|
public void saveCommentReplySuccess() throws Exception {
|
||||||
|
FunctionalCaseComment functionalCaseComment1 = getFunctionalCaseComment();
|
||||||
|
FunctionalCaseCommentRequest functionalCaseCommentRequest = new FunctionalCaseCommentRequest();
|
||||||
|
functionalCaseCommentRequest.setCaseId("xiaomeinvGTestOne");
|
||||||
|
functionalCaseCommentRequest.setContent("评论你好");
|
||||||
|
functionalCaseCommentRequest.setReplyUser("default-project-member-user-guo");
|
||||||
|
functionalCaseCommentRequest.setParentId(functionalCaseComment1.getId());
|
||||||
|
functionalCaseCommentRequest.setEvent(NoticeConstants.Event.REPLY);
|
||||||
|
FunctionalCaseComment functionalCaseComment = getFunctionalCaseComment(functionalCaseCommentRequest);
|
||||||
|
NotificationExample notificationExample = new NotificationExample();
|
||||||
|
notificationExample.createCriteria().andResourceIdEqualTo("xiaomeinvGTestOne").andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK);
|
||||||
|
List<Notification> notifications = notificationMapper.selectByExampleWithBLOBs(notificationExample);
|
||||||
|
Assertions.assertFalse(notifications.isEmpty());
|
||||||
|
System.out.println(JSON.toJSONString(notifications));
|
||||||
|
Assertions.assertTrue(StringUtils.equals(notifications.get(0).getReceiver(), "gyq"));
|
||||||
|
System.out.println(notifications.get(0).getContent());
|
||||||
|
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getCaseId(), "xiaomeinvGTestOne"));
|
||||||
|
Assertions.assertTrue(StringUtils.isBlank(functionalCaseComment.getNotifier()));
|
||||||
|
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getContent(), "评论你好"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(7)
|
||||||
|
public void saveCommentReplyNoParentId() throws Exception {
|
||||||
|
FunctionalCaseCommentRequest functionalCaseCommentRequest = new FunctionalCaseCommentRequest();
|
||||||
|
functionalCaseCommentRequest.setCaseId("xiaomeinvGTestOne");
|
||||||
|
functionalCaseCommentRequest.setContent("评论你好");
|
||||||
|
functionalCaseCommentRequest.setEvent(NoticeConstants.Event.REPLY);
|
||||||
|
ResultHolder resultHolder = postFalse(functionalCaseCommentRequest);
|
||||||
|
String message = resultHolder.getMessage();
|
||||||
|
Assertions.assertTrue(StringUtils.equals(message, Translator.get("case_comment.parent_id_is_null")));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(8)
|
||||||
|
public void saveCommentReplyNoParent() throws Exception {
|
||||||
|
FunctionalCaseCommentRequest functionalCaseCommentRequest = new FunctionalCaseCommentRequest();
|
||||||
|
functionalCaseCommentRequest.setCaseId("xiaomeinvGTestOne");
|
||||||
|
functionalCaseCommentRequest.setContent("评论你好");
|
||||||
|
functionalCaseCommentRequest.setParentId("noComment");
|
||||||
|
functionalCaseCommentRequest.setEvent(NoticeConstants.Event.REPLY);
|
||||||
|
ResultHolder resultHolder = postFalse(functionalCaseCommentRequest);
|
||||||
|
String message = resultHolder.getMessage();
|
||||||
|
Assertions.assertTrue(StringUtils.equals(message, Translator.get("case_comment.parent_case_is_null")));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(9)
|
||||||
|
public void saveCommentReplyNotifierSuccess() throws Exception {
|
||||||
|
FunctionalCaseComment functionalCaseComment1 = getFunctionalCaseComment();
|
||||||
|
FunctionalCaseCommentRequest functionalCaseCommentRequest = new FunctionalCaseCommentRequest();
|
||||||
|
functionalCaseCommentRequest.setCaseId("xiaomeinvGTest");
|
||||||
|
functionalCaseCommentRequest.setContent("评论你好");
|
||||||
|
functionalCaseCommentRequest.setNotifier("default-project-member-user-guo-2");
|
||||||
|
functionalCaseCommentRequest.setReplyUser("default-project-member-user-guo");
|
||||||
|
functionalCaseCommentRequest.setParentId(functionalCaseComment1.getId());
|
||||||
|
functionalCaseCommentRequest.setEvent(NoticeConstants.Event.REPLY);
|
||||||
|
FunctionalCaseComment functionalCaseComment = getFunctionalCaseComment(functionalCaseCommentRequest);
|
||||||
|
NotificationExample notificationExample = new NotificationExample();
|
||||||
|
notificationExample.createCriteria().andResourceIdEqualTo("xiaomeinvGTest").andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK);
|
||||||
|
List<Notification> notifications = notificationMapper.selectByExampleWithBLOBs(notificationExample);
|
||||||
|
Assertions.assertFalse(notifications.isEmpty());
|
||||||
|
System.out.println(JSON.toJSONString(notifications));
|
||||||
|
Assertions.assertTrue(StringUtils.equals(notifications.get(1).getReceiver(), "default-project-member-user-guo-2"));
|
||||||
|
System.out.println(notifications.get(0).getContent());
|
||||||
|
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getCaseId(), "xiaomeinvGTest"));
|
||||||
|
Assertions.assertTrue(StringUtils.isNotBlank(functionalCaseComment.getNotifier()));
|
||||||
|
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getContent(), "评论你好"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(10)
|
||||||
|
public void saveCommentReplyNoReply() throws Exception {
|
||||||
|
FunctionalCaseComment functionalCaseComment1 = getFunctionalCaseComment();
|
||||||
|
FunctionalCaseCommentRequest functionalCaseCommentRequest = new FunctionalCaseCommentRequest();
|
||||||
|
functionalCaseCommentRequest.setCaseId("xiaomeinvGTestOne");
|
||||||
|
functionalCaseCommentRequest.setContent("评论你好");
|
||||||
|
functionalCaseCommentRequest.setParentId(functionalCaseComment1.getId());
|
||||||
|
functionalCaseCommentRequest.setEvent(NoticeConstants.Event.REPLY);
|
||||||
|
ResultHolder resultHolder = postFalse(functionalCaseCommentRequest);
|
||||||
|
String message = resultHolder.getMessage();
|
||||||
|
Assertions.assertTrue(StringUtils.equals(message, Translator.get("case_comment.reply_user_is_null")));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(11)
|
||||||
|
public void saveCommentWidthCustomFields() throws Exception {
|
||||||
|
CustomField customField = new CustomField();
|
||||||
|
customField.setId("gyq_custom_field_one");
|
||||||
|
customField.setName("testLevel");
|
||||||
|
customField.setType(CustomFieldType.INPUT.toString());
|
||||||
|
customField.setScene(TemplateScene.FUNCTIONAL.name());
|
||||||
|
customField.setCreateUser("gyq");
|
||||||
|
customField.setCreateTime(System.currentTimeMillis());
|
||||||
|
customField.setUpdateTime(System.currentTimeMillis());
|
||||||
|
customField.setRefId("gyq_custom_field_one");
|
||||||
|
customField.setScopeId(projectId);
|
||||||
|
customField.setScopeType(TemplateScopeType.PROJECT.name());
|
||||||
|
customField.setInternal(false);
|
||||||
|
customField.setEnableOptionKey(false);
|
||||||
|
customField.setRemark("1");
|
||||||
|
customFieldMapper.insertSelective(customField);
|
||||||
|
FunctionalCaseCustomField functionalCaseCustomField = new FunctionalCaseCustomField();
|
||||||
|
functionalCaseCustomField.setCaseId("xiaomeinvGTest");
|
||||||
|
functionalCaseCustomField.setFieldId("gyq_custom_field_one");
|
||||||
|
functionalCaseCustomField.setValue("1");
|
||||||
|
functionalCaseCustomFieldMapper.insertSelective(functionalCaseCustomField);
|
||||||
|
|
||||||
|
FunctionalCaseComment functionalCaseComment1 = getFunctionalCaseComment();
|
||||||
|
FunctionalCaseCommentRequest functionalCaseCommentRequest = new FunctionalCaseCommentRequest();
|
||||||
|
functionalCaseCommentRequest.setCaseId("xiaomeinvGTest");
|
||||||
|
functionalCaseCommentRequest.setNotifier("default-project-member-user-guo-3;default-project-member-user-guo-4;");
|
||||||
|
functionalCaseCommentRequest.setContent("评论你好");
|
||||||
|
functionalCaseCommentRequest.setEvent(NoticeConstants.Event.REPLY);
|
||||||
|
functionalCaseCommentRequest.setReplyUser("default-project-member-user-guo");
|
||||||
|
functionalCaseCommentRequest.setParentId(functionalCaseComment1.getId());
|
||||||
|
FunctionalCaseComment functionalCaseComment = getFunctionalCaseComment(functionalCaseCommentRequest);
|
||||||
|
NotificationExample notificationExample = new NotificationExample();
|
||||||
|
notificationExample.createCriteria().andResourceIdEqualTo("xiaomeinvGTest").andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK);
|
||||||
|
List<Notification> notifications = notificationMapper.selectByExampleWithBLOBs(notificationExample);
|
||||||
|
Assertions.assertFalse(notifications.isEmpty());
|
||||||
|
// Assertions.assertTrue(StringUtils.equals(notifications.get(0).getReceiver(), "default-project-member-user-guo-1"));
|
||||||
|
System.out.println(JSON.toJSONString(notifications));
|
||||||
|
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getCaseId(), "xiaomeinvGTest"));
|
||||||
|
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getNotifier(), "default-project-member-user-guo-3;default-project-member-user-guo-4;"));
|
||||||
|
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getContent(), "评论你好"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(12)
|
||||||
|
public void saveCommentATWidthReplyUser() throws Exception {
|
||||||
|
FunctionalCaseComment functionalCaseComment1 = getFunctionalCaseComment();
|
||||||
|
FunctionalCaseCommentRequest functionalCaseCommentRequest = new FunctionalCaseCommentRequest();
|
||||||
|
functionalCaseCommentRequest.setCaseId("xiaomeinvGTest");
|
||||||
|
functionalCaseCommentRequest.setNotifier("default-project-member-user-guo;default-project-member-user-guo-4;");
|
||||||
|
functionalCaseCommentRequest.setContent("评论你好哇");
|
||||||
|
functionalCaseCommentRequest.setEvent(NoticeConstants.Event.AT);
|
||||||
|
functionalCaseCommentRequest.setReplyUser("default-project-member-user-guo");
|
||||||
|
functionalCaseCommentRequest.setParentId(functionalCaseComment1.getId());
|
||||||
|
FunctionalCaseComment functionalCaseComment = getFunctionalCaseComment(functionalCaseCommentRequest);
|
||||||
|
NotificationExample notificationExample = new NotificationExample();
|
||||||
|
notificationExample.createCriteria().andResourceIdEqualTo("xiaomeinvGTest").andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK);
|
||||||
|
List<Notification> notifications = notificationMapper.selectByExampleWithBLOBs(notificationExample);
|
||||||
|
Assertions.assertFalse(notifications.isEmpty());
|
||||||
|
// Assertions.assertTrue(StringUtils.equals(notifications.get(0).getReceiver(), "default-project-member-user-guo-1"));
|
||||||
|
System.out.println(JSON.toJSONString(notifications));
|
||||||
|
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getCaseId(), "xiaomeinvGTest"));
|
||||||
|
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getNotifier(), "default-project-member-user-guo;default-project-member-user-guo-4;"));
|
||||||
|
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getContent(), "评论你好哇"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(13)
|
||||||
|
public void deleteCommentSuccess() throws Exception {
|
||||||
|
FunctionalCaseCommentExample functionalCaseCommentExample = new FunctionalCaseCommentExample();
|
||||||
|
functionalCaseCommentExample.createCriteria().andCaseIdEqualTo("xiaomeinvGTest").andNotifierEqualTo("default-project-member-user-guo;default-project-member-user-guo-4;");
|
||||||
|
List<FunctionalCaseComment> functionalCaseComments = functionalCaseCommentMapper.selectByExample(functionalCaseCommentExample);
|
||||||
|
System.out.println(JSON.toJSONString(functionalCaseComments));
|
||||||
|
String id = functionalCaseComments.get(0).getId();
|
||||||
|
Assertions.assertFalse(functionalCaseComments.isEmpty());
|
||||||
|
delFunctionalCaseComment(id);
|
||||||
|
functionalCaseCommentExample = new FunctionalCaseCommentExample();
|
||||||
|
functionalCaseCommentExample.createCriteria().andParentIdEqualTo(id);
|
||||||
|
List<FunctionalCaseComment> functionalCaseComments1 = functionalCaseCommentMapper.selectByExample(functionalCaseCommentExample);
|
||||||
|
Assertions.assertTrue(functionalCaseComments1.isEmpty());
|
||||||
|
FunctionalCaseComment functionalCaseComment = functionalCaseCommentMapper.selectByPrimaryKey(id);
|
||||||
|
Assertions.assertNull(functionalCaseComment);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(14)
|
||||||
|
public void deleteNoCommentSuccess() throws Exception {
|
||||||
|
delFunctionalCaseComment("no_comment");
|
||||||
|
FunctionalCaseCommentExample functionalCaseCommentExample = new FunctionalCaseCommentExample();
|
||||||
|
functionalCaseCommentExample.createCriteria().andParentIdEqualTo("no_comment");
|
||||||
|
List<FunctionalCaseComment> functionalCaseComments1 = functionalCaseCommentMapper.selectByExample(functionalCaseCommentExample);
|
||||||
|
Assertions.assertTrue(functionalCaseComments1.isEmpty());
|
||||||
|
FunctionalCaseComment functionalCaseComment = functionalCaseCommentMapper.selectByPrimaryKey("no_comment");
|
||||||
|
Assertions.assertNull(functionalCaseComment);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private FunctionalCaseComment getFunctionalCaseComment(FunctionalCaseCommentRequest functionalCaseCommentRequest) throws Exception {
|
||||||
|
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post(SAVE_URL).header(SessionConstants.HEADER_TOKEN, sessionId)
|
||||||
|
.header(SessionConstants.CSRF_TOKEN, csrfToken)
|
||||||
|
.header(SessionConstants.CURRENT_PROJECT, projectId)
|
||||||
|
.content(JSON.toJSONString(functionalCaseCommentRequest))
|
||||||
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
|
||||||
|
String contentAsString = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||||
|
ResultHolder resultHolder = JSON.parseObject(contentAsString, ResultHolder.class);
|
||||||
|
return JSON.parseObject(JSON.toJSONString(resultHolder.getData()), FunctionalCaseComment.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void delFunctionalCaseComment(String commentId) throws Exception {
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.get(DELETE_URL+commentId).header(SessionConstants.HEADER_TOKEN, sessionId)
|
||||||
|
.header(SessionConstants.CSRF_TOKEN, csrfToken)
|
||||||
|
.header(SessionConstants.CURRENT_PROJECT, projectId)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
|
||||||
|
}
|
||||||
|
|
||||||
|
private FunctionalCaseComment getFunctionalCaseComment() {
|
||||||
|
FunctionalCaseCommentExample functionalCaseCommentExample = new FunctionalCaseCommentExample();
|
||||||
|
functionalCaseCommentExample.createCriteria().andCaseIdEqualTo("xiaomeinvGTest");
|
||||||
|
List<FunctionalCaseComment> functionalCaseComments = functionalCaseCommentMapper.selectByExample(functionalCaseCommentExample);
|
||||||
|
return functionalCaseComments.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos,
|
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,
|
version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user,
|
||||||
update_user, delete_user, create_time, update_time, delete_time)
|
update_user, delete_user, create_time, update_time, delete_time)
|
||||||
VALUES ('xiaomeinvGTest', 1000001, 'test_guo', '100001100001', 'test_guo', '郭雨琦测试', 'UN_REVIEWED', null, 'text',
|
VALUES ('xiaomeinvGTest', 1000001, 'test_guo', '100001100001', 'test_guo', 'gyqTest', 'UN_REVIEWED', null, 'text',
|
||||||
10001, '111', 'xiaomeinvGTest', 'success', false, false, true, 'gyq', 'gyq', null, 1698058347559, 1698058347559,
|
10001, '111', 'xiaomeinvGTest', 'success', false, false, true, 'gyq', 'gyq', null, 1698058347559, 1698058347559,
|
||||||
null);
|
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 ('xiaomeinvGTestOne', 1000001, 'test_guo', '100001100001', 'test_guo', 'gyqTest1', 'UN_REVIEWED', null, 'text',
|
||||||
|
10001, '111', 'xiaomeinvGTestOne', 'success', false, false, true, 'gyq', 'gyq', null, 1698058347559,
|
||||||
|
1698058347559,
|
||||||
|
null);
|
||||||
|
|
||||||
INSERT INTO user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source,
|
INSERT INTO user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source,
|
||||||
last_project_id, create_user, update_user, deleted)
|
last_project_id, create_user, update_user, deleted)
|
||||||
|
@ -15,15 +21,34 @@ VALUES ('default-project-member-user-guo', 'default-project-member-user1', 'proj
|
||||||
('default-project-member-user-guo-1', 'default-project-member-user2', 'project-member-guo2@metersphere.io',
|
('default-project-member-user-guo-1', 'default-project-member-user2', 'project-member-guo2@metersphere.io',
|
||||||
MD5('metersphere'), UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin',
|
MD5('metersphere'), UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin',
|
||||||
'admin', 0),
|
'admin', 0),
|
||||||
|
('default-project-member-user-guo-2', 'default-project-member-user3', 'project-member-guo3@metersphere.io',
|
||||||
|
MD5('metersphere'), UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin',
|
||||||
|
'admin', 0),
|
||||||
|
('default-project-member-user-guo-3', 'default-project-member-user4', 'project-member-guo4@metersphere.io',
|
||||||
|
MD5('metersphere'), UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin',
|
||||||
|
'admin', 0),
|
||||||
|
('default-project-member-user-guo-4', 'default-project-member-user5', 'project-member-guo5@metersphere.io',
|
||||||
|
MD5('metersphere'), UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin',
|
||||||
|
'admin', 0),
|
||||||
('default-project-member-user-guo-del', 'default-project-member-userDel',
|
('default-project-member-user-guo-del', 'default-project-member-userDel',
|
||||||
'project-member-guo-del@metersphere.io', MD5('metersphere'), UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000,
|
'project-member-guo-del@metersphere.io', MD5('metersphere'), UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000,
|
||||||
|
NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin', 1),
|
||||||
|
('gyq', 'gyq', 'gyq@metersphere.io', MD5('metersphere'), UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000,
|
||||||
NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin', 1);
|
NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin', 1);
|
||||||
|
|
||||||
INSERT INTO user_role_relation (id, user_id, role_id, source_id, organization_id, create_time, create_user)
|
INSERT INTO user_role_relation (id, user_id, role_id, source_id, organization_id, create_time, create_user)
|
||||||
VALUES (UUID(), 'default-project-member-user-guo', 'org_member', '100001', '100001', UNIX_TIMESTAMP() * 1000, 'admin'),
|
VALUES (UUID(), 'default-project-member-user-guo', 'org_member', '100001', '100001', UNIX_TIMESTAMP() * 1000, 'admin'),
|
||||||
(UUID(), 'default-project-member-user-guo-1', 'org_member', '100001', '100001', UNIX_TIMESTAMP() * 1000,
|
(UUID(), 'default-project-member-user-guo-1', 'org_member', '100001', '100001', UNIX_TIMESTAMP() * 1000,
|
||||||
'admin'),
|
'admin'),
|
||||||
|
(UUID(), 'default-project-member-user-guo-2', 'org_member', '100001', '100001', UNIX_TIMESTAMP() * 1000,
|
||||||
|
'admin'),
|
||||||
|
(UUID(), 'default-project-member-user-guo-3', 'org_member', '100001', '100001', UNIX_TIMESTAMP() * 1000,
|
||||||
|
'admin'),
|
||||||
|
(UUID(), 'default-project-member-user-guo-4', 'org_member', '100001', '100001', UNIX_TIMESTAMP() * 1000,
|
||||||
|
'admin'),
|
||||||
(UUID(), 'default-project-member-user-guo-del', 'org_member', '100001', '100001', UNIX_TIMESTAMP() * 1000,
|
(UUID(), 'default-project-member-user-guo-del', 'org_member', '100001', '100001', UNIX_TIMESTAMP() * 1000,
|
||||||
|
'admin'),
|
||||||
|
(UUID(), 'gyq', 'org_member', '100001', '100001', UNIX_TIMESTAMP() * 1000,
|
||||||
'admin');
|
'admin');
|
||||||
|
|
||||||
INSERT INTO user_role_relation (id, user_id, role_id, source_id, organization_id, create_time, create_user)
|
INSERT INTO user_role_relation (id, user_id, role_id, source_id, organization_id, create_time, create_user)
|
||||||
|
@ -31,11 +56,20 @@ VALUES (UUID(), 'default-project-member-user-guo', 'project_admin', '10000110000
|
||||||
'admin'),
|
'admin'),
|
||||||
(UUID(), 'default-project-member-user-guo-1', 'project_admin', '100001100001', '100001', UNIX_TIMESTAMP() * 1000,
|
(UUID(), 'default-project-member-user-guo-1', 'project_admin', '100001100001', '100001', UNIX_TIMESTAMP() * 1000,
|
||||||
'admin'),
|
'admin'),
|
||||||
|
(UUID(), 'default-project-member-user-guo-2', 'project_admin', '100001100001', '100001', UNIX_TIMESTAMP() * 1000,
|
||||||
|
'admin'),
|
||||||
|
(UUID(), 'default-project-member-user-guo-3', 'project_admin', '100001100001', '100001', UNIX_TIMESTAMP() * 1000,
|
||||||
|
'admin'),
|
||||||
|
(UUID(), 'default-project-member-user-guo-4', 'project_admin', '100001100001', '100001', UNIX_TIMESTAMP() * 1000,
|
||||||
|
'admin'),
|
||||||
(UUID(), 'default-project-member-user-guo-del', 'project_admin', '100001100001', '100001',
|
(UUID(), 'default-project-member-user-guo-del', 'project_admin', '100001100001', '100001',
|
||||||
UNIX_TIMESTAMP() * 1000, 'admin');
|
UNIX_TIMESTAMP() * 1000, 'admin'),
|
||||||
|
(UUID(), 'gyq', 'project_admin', '100001100001', '100001', UNIX_TIMESTAMP() * 1000,
|
||||||
|
'admin');
|
||||||
|
|
||||||
INSERT INTO user_role_permission(id, role_id, permission_id)
|
INSERT INTO user_role_permission(id, role_id, permission_id)
|
||||||
VALUES ('user_role_guo_permission1', 'project_admin', 'FUNCTIONAL_CASE_COMMENT:READ+ADD'),
|
VALUES ('user_role_guo_permission1', 'project_admin', 'FUNCTIONAL_CASE_COMMENT:READ+ADD'),
|
||||||
('user_role_guo_permission2', 'project_admin', 'FUNCTIONAL_CASE:READ+ADD');
|
('user_role_guo_permission2', 'project_admin', 'FUNCTIONAL_CASE_COMMENT:READ+DELETE'),
|
||||||
|
('user_role_guo_permission3', 'project_admin', 'FUNCTIONAL_CASE:READ+ADD');
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,9 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class CreateRobotResourceService implements CreateProjectResourceService {
|
public class CreateRobotResourceService implements CreateProjectResourceService {
|
||||||
|
@ -77,6 +79,7 @@ public class CreateRobotResourceService implements CreateProjectResourceService
|
||||||
public void setMessageTask(String projectId, String defaultRobotId) {
|
public void setMessageTask(String projectId, String defaultRobotId) {
|
||||||
StringBuilder jsonStr = new StringBuilder();
|
StringBuilder jsonStr = new StringBuilder();
|
||||||
InputStream inputStream = getClass().getResourceAsStream("/message_task.json");
|
InputStream inputStream = getClass().getResourceAsStream("/message_task.json");
|
||||||
|
assert inputStream != null;
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||||
String line;
|
String line;
|
||||||
try {
|
try {
|
||||||
|
@ -91,15 +94,21 @@ public class CreateRobotResourceService implements CreateProjectResourceService
|
||||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||||
MessageTaskMapper mapper = sqlSession.getMapper(MessageTaskMapper.class);
|
MessageTaskMapper mapper = sqlSession.getMapper(MessageTaskMapper.class);
|
||||||
MessageTaskBlobMapper blobMapper = sqlSession.getMapper(MessageTaskBlobMapper.class);
|
MessageTaskBlobMapper blobMapper = sqlSession.getMapper(MessageTaskBlobMapper.class);
|
||||||
|
//生成消息管理默认显示数据
|
||||||
|
setTemplateMessageTask(projectId, defaultRobotId, jsonStr, mapper, blobMapper);
|
||||||
|
//生成 内置at 的消息管理数据
|
||||||
|
setAtMessageTask(projectId, defaultRobotId, mapper, blobMapper);
|
||||||
|
|
||||||
|
sqlSession.flushStatements();
|
||||||
|
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setTemplateMessageTask(String projectId, String defaultRobotId, StringBuilder jsonStr, MessageTaskMapper mapper, MessageTaskBlobMapper blobMapper) {
|
||||||
List<MessageTaskDTO> messageTaskDTOList = JSON.parseArray(jsonStr.toString(), MessageTaskDTO.class);
|
List<MessageTaskDTO> messageTaskDTOList = JSON.parseArray(jsonStr.toString(), MessageTaskDTO.class);
|
||||||
for (MessageTaskDTO messageTaskDTO : messageTaskDTOList) {
|
for (MessageTaskDTO messageTaskDTO : messageTaskDTOList) {
|
||||||
List<MessageTaskTypeDTO> messageTaskTypeDTOList = messageTaskDTO.getMessageTaskTypeDTOList();
|
List<MessageTaskTypeDTO> messageTaskTypeDTOList = messageTaskDTO.getMessageTaskTypeDTOList();
|
||||||
for (MessageTaskTypeDTO messageTaskTypeDTO : messageTaskTypeDTOList) {
|
for (MessageTaskTypeDTO messageTaskTypeDTO : messageTaskTypeDTOList) {
|
||||||
String taskType = messageTaskTypeDTO.getTaskType();
|
String taskType = messageTaskTypeDTO.getTaskType();
|
||||||
if (taskType.contains("AT")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
List<MessageTaskDetailDTO> messageTaskDetailDTOList = messageTaskTypeDTO.getMessageTaskDetailDTOList();
|
List<MessageTaskDetailDTO> messageTaskDetailDTOList = messageTaskTypeDTO.getMessageTaskDetailDTOList();
|
||||||
for (MessageTaskDetailDTO messageTaskDetailDTO : messageTaskDetailDTOList) {
|
for (MessageTaskDetailDTO messageTaskDetailDTO : messageTaskDetailDTOList) {
|
||||||
String event = messageTaskDetailDTO.getEvent();
|
String event = messageTaskDetailDTO.getEvent();
|
||||||
|
@ -134,8 +143,45 @@ public class CreateRobotResourceService implements CreateProjectResourceService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sqlSession.flushStatements();
|
private static void setAtMessageTask(String projectId, String defaultRobotId, MessageTaskMapper mapper, MessageTaskBlobMapper blobMapper) {
|
||||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
Map<String,List<String>> taskTypeEventMap = new HashMap<>();
|
||||||
|
List<String>bugEventList = new ArrayList<>();
|
||||||
|
bugEventList.add(NoticeConstants.Event.AT);
|
||||||
|
bugEventList.add(NoticeConstants.Event.REPLY);
|
||||||
|
taskTypeEventMap.put(NoticeConstants.TaskType.BUG_TASK,bugEventList);
|
||||||
|
List<String>funcationalCaseEventList = new ArrayList<>();
|
||||||
|
funcationalCaseEventList.add(NoticeConstants.Event.AT);
|
||||||
|
funcationalCaseEventList.add(NoticeConstants.Event.REPLY);
|
||||||
|
funcationalCaseEventList.add(NoticeConstants.Event.REVIEW_AT);
|
||||||
|
funcationalCaseEventList.add(NoticeConstants.Event.EXECUTE_AT);
|
||||||
|
taskTypeEventMap.put(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK,funcationalCaseEventList);
|
||||||
|
taskTypeEventMap.forEach((taskType, eventList)->{
|
||||||
|
for (String event : eventList) {
|
||||||
|
String id = IDGenerator.nextStr();
|
||||||
|
MessageTask messageTask = new MessageTask();
|
||||||
|
messageTask.setId(id);
|
||||||
|
messageTask.setEvent(event);
|
||||||
|
messageTask.setTaskType(taskType);
|
||||||
|
messageTask.setReceiver("NONE");
|
||||||
|
messageTask.setProjectId(projectId);
|
||||||
|
messageTask.setProjectRobotId(defaultRobotId);
|
||||||
|
messageTask.setEnable(true);
|
||||||
|
messageTask.setTestId("NONE");
|
||||||
|
messageTask.setCreateUser("admin");
|
||||||
|
messageTask.setCreateTime(System.currentTimeMillis());
|
||||||
|
messageTask.setUpdateUser("admin");
|
||||||
|
messageTask.setUpdateTime(System.currentTimeMillis());
|
||||||
|
messageTask.setSubject("");
|
||||||
|
messageTask.setUseDefaultSubject(true);
|
||||||
|
messageTask.setUseDefaultTemplate(true);
|
||||||
|
MessageTaskBlob messageTaskBlob = new MessageTaskBlob();
|
||||||
|
messageTaskBlob.setId(id);
|
||||||
|
messageTaskBlob.setTemplate("");
|
||||||
|
mapper.insert(messageTask);
|
||||||
|
blobMapper.insert(messageTaskBlob);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
package io.metersphere.project.controller;
|
package io.metersphere.project.controller;
|
||||||
|
|
||||||
|
import io.metersphere.project.domain.MessageTask;
|
||||||
|
import io.metersphere.project.domain.MessageTaskExample;
|
||||||
import io.metersphere.project.domain.Project;
|
import io.metersphere.project.domain.Project;
|
||||||
import io.metersphere.project.domain.ProjectRobot;
|
import io.metersphere.project.domain.ProjectRobot;
|
||||||
import io.metersphere.project.dto.MessageTaskDTO;
|
import io.metersphere.project.dto.MessageTaskDTO;
|
||||||
|
import io.metersphere.project.mapper.MessageTaskMapper;
|
||||||
import io.metersphere.project.mapper.ProjectMapper;
|
import io.metersphere.project.mapper.ProjectMapper;
|
||||||
import io.metersphere.sdk.constants.SessionConstants;
|
import io.metersphere.sdk.constants.SessionConstants;
|
||||||
import io.metersphere.sdk.util.JSON;
|
import io.metersphere.sdk.util.JSON;
|
||||||
|
@ -42,6 +45,9 @@ public class CreateRobotResourceTests extends BaseTest {
|
||||||
@Resource
|
@Resource
|
||||||
private ProjectMapper projectMapper;
|
private ProjectMapper projectMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MessageTaskMapper messageTaskMapper;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(1)
|
@Order(1)
|
||||||
public void testCreateResource() throws Exception {
|
public void testCreateResource() throws Exception {
|
||||||
|
@ -60,6 +66,10 @@ public class CreateRobotResourceTests extends BaseTest {
|
||||||
List<ProjectRobot> projectRobotAfters = getList(id);
|
List<ProjectRobot> projectRobotAfters = getList(id);
|
||||||
Assertions.assertEquals(2, projectRobotAfters.size());
|
Assertions.assertEquals(2, projectRobotAfters.size());
|
||||||
List<MessageTaskDTO> messageList = getMessageList(id);
|
List<MessageTaskDTO> messageList = getMessageList(id);
|
||||||
|
MessageTaskExample messageTaskExample = new MessageTaskExample();
|
||||||
|
messageTaskExample.createCriteria().andProjectIdEqualTo(id).andEventLike("AT");
|
||||||
|
List<MessageTask> messageTasks = messageTaskMapper.selectByExample(messageTaskExample);
|
||||||
|
Assertions.assertTrue(messageTasks.size() > 0);
|
||||||
Assertions.assertTrue(messageList.size() > 0);
|
Assertions.assertTrue(messageList.size() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,7 @@ public interface NoticeConstants {
|
||||||
String AT = "AT";
|
String AT = "AT";
|
||||||
|
|
||||||
@Schema(description = "message.replay")
|
@Schema(description = "message.replay")
|
||||||
String REPLAY = "REPLAY";
|
String REPLY = "REPLY";
|
||||||
|
|
||||||
@Schema(description = "message.review_passed")
|
@Schema(description = "message.review_passed")
|
||||||
String REVIEW_PASSED = "REVIEW_PASSED";
|
String REVIEW_PASSED = "REVIEW_PASSED";
|
||||||
|
|
|
@ -21,7 +21,6 @@ import io.metersphere.plan.domain.TestPlanFollowerExample;
|
||||||
import io.metersphere.plan.mapper.TestPlanFollowerMapper;
|
import io.metersphere.plan.mapper.TestPlanFollowerMapper;
|
||||||
import io.metersphere.sdk.util.JSON;
|
import io.metersphere.sdk.util.JSON;
|
||||||
import io.metersphere.sdk.util.LogUtils;
|
import io.metersphere.sdk.util.LogUtils;
|
||||||
import io.metersphere.system.domain.CustomField;
|
|
||||||
import io.metersphere.system.domain.User;
|
import io.metersphere.system.domain.User;
|
||||||
import io.metersphere.system.domain.UserExample;
|
import io.metersphere.system.domain.UserExample;
|
||||||
import io.metersphere.system.mapper.CustomFieldMapper;
|
import io.metersphere.system.mapper.CustomFieldMapper;
|
||||||
|
@ -33,7 +32,6 @@ import io.metersphere.system.notice.constants.NoticeConstants;
|
||||||
import io.metersphere.system.notice.constants.NotificationConstants;
|
import io.metersphere.system.notice.constants.NotificationConstants;
|
||||||
import io.metersphere.system.notice.utils.MessageTemplateUtils;
|
import io.metersphere.system.notice.utils.MessageTemplateUtils;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.beanutils.BeanMap;
|
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
@ -91,16 +89,13 @@ public abstract class AbstractNoticeSender implements NoticeSender {
|
||||||
}
|
}
|
||||||
if (CollectionUtils.isNotEmpty(fields)) {
|
if (CollectionUtils.isNotEmpty(fields)) {
|
||||||
for (Object o : fields) {
|
for (Object o : fields) {
|
||||||
Map jsonObject = new BeanMap(o);
|
String jsonFields = JSON.toJSONString(o);
|
||||||
String id = (String) jsonObject.get("id");
|
Map<?, ?> jsonObject = JSON.parseObject(jsonFields, Map.class);
|
||||||
CustomField customField = customFieldMapper.selectByPrimaryKey(id);
|
String customFieldName = (String) jsonObject.get("id");
|
||||||
if (customField == null) {
|
Object value = jsonObject.get("name");
|
||||||
continue;
|
if (value instanceof String && StringUtils.isNotBlank((String) value)) {
|
||||||
}
|
|
||||||
Object value = jsonObject.get("value");
|
|
||||||
if (value instanceof String && StringUtils.isNotEmpty((String) value)) {
|
|
||||||
String v = StringUtils.unwrap((String) value, "\"");
|
String v = StringUtils.unwrap((String) value, "\"");
|
||||||
noticeModel.getParamMap().put(customField.getName(), v); // 处理人
|
noticeModel.getParamMap().put(customFieldName, v); // 处理人
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,7 +110,7 @@ public abstract class AbstractNoticeSender implements NoticeSender {
|
||||||
for (String userId : messageDetail.getReceiverIds()) {
|
for (String userId : messageDetail.getReceiverIds()) {
|
||||||
switch (userId) {
|
switch (userId) {
|
||||||
case NoticeConstants.RelatedUser.CREATE_USER -> {
|
case NoticeConstants.RelatedUser.CREATE_USER -> {
|
||||||
String createUser = (String) paramMap.get(NoticeConstants.RelatedUser.CREATE_USER);
|
String createUser = (String) paramMap.get("createUser");
|
||||||
if (StringUtils.isNotBlank(createUser)) {
|
if (StringUtils.isNotBlank(createUser)) {
|
||||||
toUsers.add(new Receiver(createUser, NotificationConstants.Type.SYSTEM_NOTICE.name()));
|
toUsers.add(new Receiver(createUser, NotificationConstants.Type.SYSTEM_NOTICE.name()));
|
||||||
}
|
}
|
||||||
|
@ -140,7 +135,7 @@ public abstract class AbstractNoticeSender implements NoticeSender {
|
||||||
|
|
||||||
}
|
}
|
||||||
//处理评论人
|
//处理评论人
|
||||||
if (event.contains(NoticeConstants.Event.AT) || event.contains(NoticeConstants.Event.REPLAY)) {
|
if (event.contains(NoticeConstants.Event.AT) || event.contains(NoticeConstants.Event.REPLY)) {
|
||||||
if (CollectionUtils.isNotEmpty(noticeModel.getRelatedUsers())) {
|
if (CollectionUtils.isNotEmpty(noticeModel.getRelatedUsers())) {
|
||||||
for (String relatedUser : noticeModel.getRelatedUsers()) {
|
for (String relatedUser : noticeModel.getRelatedUsers()) {
|
||||||
toUsers.add(new Receiver(relatedUser, NotificationConstants.Type.MENTIONED_ME.name()));
|
toUsers.add(new Receiver(relatedUser, NotificationConstants.Type.MENTIONED_ME.name()));
|
||||||
|
|
|
@ -4,7 +4,6 @@ package io.metersphere.system.notice.sender;
|
||||||
import io.metersphere.system.dto.sdk.BaseSystemConfigDTO;
|
import io.metersphere.system.dto.sdk.BaseSystemConfigDTO;
|
||||||
import io.metersphere.system.dto.sdk.SessionUser;
|
import io.metersphere.system.dto.sdk.SessionUser;
|
||||||
import io.metersphere.system.notice.NoticeModel;
|
import io.metersphere.system.notice.NoticeModel;
|
||||||
import io.metersphere.system.notice.annotation.SendNotice;
|
|
||||||
import io.metersphere.system.notice.constants.NoticeConstants;
|
import io.metersphere.system.notice.constants.NoticeConstants;
|
||||||
import io.metersphere.system.notice.utils.MessageTemplateUtils;
|
import io.metersphere.system.notice.utils.MessageTemplateUtils;
|
||||||
import io.metersphere.system.service.NoticeSendService;
|
import io.metersphere.system.service.NoticeSendService;
|
||||||
|
@ -24,7 +23,7 @@ public class AfterReturningNoticeSendService {
|
||||||
private NoticeSendService noticeSendService;
|
private NoticeSendService noticeSendService;
|
||||||
|
|
||||||
@Async
|
@Async
|
||||||
public void sendNotice(SendNotice sendNotice, List<Map> resources, SessionUser sessionUser, String currentProjectId) {
|
public void sendNotice(String taskType, String event, List<Map> resources, SessionUser sessionUser, String currentProjectId) {
|
||||||
|
|
||||||
// 有批量操作发送多次
|
// 有批量操作发送多次
|
||||||
BaseSystemConfigDTO baseSystemConfigDTO = systemParameterService.getBaseInfo();
|
BaseSystemConfigDTO baseSystemConfigDTO = systemParameterService.getBaseInfo();
|
||||||
|
@ -39,9 +38,9 @@ public class AfterReturningNoticeSendService {
|
||||||
// 占位符
|
// 占位符
|
||||||
handleDefaultValues(paramMap);
|
handleDefaultValues(paramMap);
|
||||||
|
|
||||||
String context = getContext(sendNotice);
|
String context = getContext(taskType, event);
|
||||||
|
|
||||||
String subject = getSubject(sendNotice);
|
String subject = getSubject(taskType, event);
|
||||||
|
|
||||||
List<String> relatedUsers = getRelatedUsers(resource.get("relatedUsers"));
|
List<String> relatedUsers = getRelatedUsers(resource.get("relatedUsers"));
|
||||||
|
|
||||||
|
@ -50,12 +49,12 @@ public class AfterReturningNoticeSendService {
|
||||||
.context(context)
|
.context(context)
|
||||||
.subject(subject)
|
.subject(subject)
|
||||||
.paramMap(paramMap)
|
.paramMap(paramMap)
|
||||||
.event(sendNotice.event())
|
.event(event)
|
||||||
.status((String) paramMap.get("status"))
|
.status((String) paramMap.get("status"))
|
||||||
.excludeSelf(true)
|
.excludeSelf(true)
|
||||||
.relatedUsers(relatedUsers)
|
.relatedUsers(relatedUsers)
|
||||||
.build();
|
.build();
|
||||||
noticeSendService.send(sendNotice.taskType(), noticeModel);
|
noticeSendService.send(taskType, noticeModel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,14 +62,14 @@ public class AfterReturningNoticeSendService {
|
||||||
String relatedUser = (String) relatedUsers;
|
String relatedUser = (String) relatedUsers;
|
||||||
List<String> relatedUserList = new ArrayList<>();
|
List<String> relatedUserList = new ArrayList<>();
|
||||||
if (StringUtils.isNotBlank(relatedUser)) {
|
if (StringUtils.isNotBlank(relatedUser)) {
|
||||||
relatedUserList = Arrays.asList(relatedUser.split(","));
|
relatedUserList = Arrays.asList(relatedUser.split(";"));
|
||||||
}
|
}
|
||||||
return relatedUserList;
|
return relatedUserList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getSubject(SendNotice sendNotice) {
|
private String getSubject(String taskType, String event) {
|
||||||
Map<String, String> defaultTemplateTitleMap = MessageTemplateUtils.getDefaultTemplateSubjectMap();
|
Map<String, String> defaultTemplateTitleMap = MessageTemplateUtils.getDefaultTemplateSubjectMap();
|
||||||
return defaultTemplateTitleMap.get(sendNotice.taskType() + "_" + sendNotice.event());
|
return defaultTemplateTitleMap.get(taskType + "_" + event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,8 +80,8 @@ public class AfterReturningNoticeSendService {
|
||||||
paramMap.put("planShareUrl", StringUtils.EMPTY); // 占位符
|
paramMap.put("planShareUrl", StringUtils.EMPTY); // 占位符
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getContext(SendNotice sendNotice) {
|
private String getContext(String taskType, String event) {
|
||||||
Map<String, String> defaultTemplateMap = MessageTemplateUtils.getDefaultTemplateMap();
|
Map<String, String> defaultTemplateMap = MessageTemplateUtils.getDefaultTemplateMap();
|
||||||
return defaultTemplateMap.get(sendNotice.taskType() + "_" + sendNotice.event());
|
return defaultTemplateMap.get(taskType + "_" + event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,14 +89,14 @@ public class SendNoticeAspect {
|
||||||
String[] params = discoverer.getParameterNames(method);
|
String[] params = discoverer.getParameterNames(method);
|
||||||
//获取操作
|
//获取操作
|
||||||
SendNotice sendNotice = method.getAnnotation(SendNotice.class);
|
SendNotice sendNotice = method.getAnnotation(SendNotice.class);
|
||||||
// 再次从数据库查询一次内容,方便获取最新参数
|
|
||||||
|
|
||||||
if (StringUtils.isNotEmpty(sendNotice.target())) {
|
|
||||||
//将参数纳入Spring管理
|
|
||||||
EvaluationContext context = new StandardEvaluationContext();
|
EvaluationContext context = new StandardEvaluationContext();
|
||||||
for (int len = 0; len < params.length; len++) {
|
for (int len = 0; len < params.length; len++) {
|
||||||
context.setVariable(params[len], args[len]);
|
context.setVariable(params[len], args[len]);
|
||||||
}
|
}
|
||||||
|
// 再次从数据库查询一次内容,方便获取最新参数
|
||||||
|
if (StringUtils.isNotEmpty(sendNotice.target())) {
|
||||||
|
//将参数纳入Spring管理
|
||||||
|
|
||||||
context.setVariable("targetClass", CommonBeanFactory.getBean(sendNotice.targetClass()));
|
context.setVariable("targetClass", CommonBeanFactory.getBean(sendNotice.targetClass()));
|
||||||
|
|
||||||
String target = sendNotice.target();
|
String target = sendNotice.target();
|
||||||
|
@ -124,10 +124,32 @@ public class SendNoticeAspect {
|
||||||
} else {
|
} else {
|
||||||
resources.add(new BeanMap(retValue));
|
resources.add(new BeanMap(retValue));
|
||||||
}
|
}
|
||||||
|
String taskType = sendNotice.taskType();
|
||||||
|
// taskType
|
||||||
|
if (StringUtils.isNotEmpty(sendNotice.taskType())) {
|
||||||
|
try {
|
||||||
|
Expression titleExp = parser.parseExpression(taskType);
|
||||||
|
taskType = titleExp.getValue(resources, String.class);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.info("使用原值");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String event = sendNotice.event();
|
||||||
|
// event
|
||||||
|
if (StringUtils.isNotEmpty(sendNotice.event())) {
|
||||||
|
try {
|
||||||
|
Expression titleExp = parser.parseExpression(event);
|
||||||
|
event = titleExp.getValue(context, String.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.info("使用原值");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SessionUser sessionUser = SessionUtils.getUser();
|
SessionUser sessionUser = SessionUtils.getUser();
|
||||||
String currentProjectId = SessionUtils.getCurrentProjectId();
|
String currentProjectId = SessionUtils.getCurrentProjectId();
|
||||||
afterReturningNoticeSendService.sendNotice(sendNotice, resources, sessionUser, currentProjectId);
|
LogUtils.info("event:"+event);
|
||||||
|
afterReturningNoticeSendService.sendNotice(taskType,event, resources, sessionUser, currentProjectId);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtils.error(e.getMessage(), e);
|
LogUtils.error(e.getMessage(), e);
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -111,11 +111,15 @@ public class MessageDetailService {
|
||||||
}
|
}
|
||||||
if (!messageTask.getUseDefaultSubject() && StringUtils.isNotBlank(messageTask.getSubject())) {
|
if (!messageTask.getUseDefaultSubject() && StringUtils.isNotBlank(messageTask.getSubject())) {
|
||||||
messageDetail.setSubject(messageTask.getSubject());
|
messageDetail.setSubject(messageTask.getSubject());
|
||||||
|
} else {
|
||||||
|
if (StringUtils.equals(projectRobot.getPlatform(),"MAIL")) {
|
||||||
|
String subject = getMailSubject(messageTask.getTaskType(), messageTask.getEvent());
|
||||||
|
messageDetail.setSubject(subject);
|
||||||
} else {
|
} else {
|
||||||
String subject = getSubject(messageTask.getTaskType(), messageTask.getEvent());
|
String subject = getSubject(messageTask.getTaskType(), messageTask.getEvent());
|
||||||
messageDetail.setSubject(subject);
|
messageDetail.setSubject(subject);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
MessageTaskBlob messageTaskBlob = messageTaskBlobMap.get(messageTask.getId());
|
MessageTaskBlob messageTaskBlob = messageTaskBlobMap.get(messageTask.getId());
|
||||||
if (!messageTask.getUseDefaultTemplate() && StringUtils.isNotBlank(messageTaskBlob.getTemplate())) {
|
if (!messageTask.getUseDefaultTemplate() && StringUtils.isNotBlank(messageTaskBlob.getTemplate())) {
|
||||||
messageDetail.setTemplate(messageTaskBlob.getTemplate());
|
messageDetail.setTemplate(messageTaskBlob.getTemplate());
|
||||||
|
@ -132,12 +136,15 @@ public class MessageDetailService {
|
||||||
return defaultTemplateMap.get(taskType + "_" + event);
|
return defaultTemplateMap.get(taskType + "_" + event);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getSubject(String taskType, String event) {
|
private String getMailSubject(String taskType, String event) {
|
||||||
Map<String, String> defaultTemplateTitleMap = MessageTemplateUtils.getDefaultTemplateSubjectMap();
|
Map<String, String> defaultTemplateTitleMap = MessageTemplateUtils.getDefaultTemplateSubjectMap();
|
||||||
return "MeterSphere " + defaultTemplateTitleMap.get(taskType + "_" + event);
|
return "MeterSphere " + defaultTemplateTitleMap.get(taskType + "_" + event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getSubject(String taskType, String event) {
|
||||||
|
Map<String, String> defaultTemplateTitleMap = MessageTemplateUtils.getDefaultTemplateSubjectMap();
|
||||||
|
return defaultTemplateTitleMap.get(taskType + "_" + event);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 根据用例ID获取所有该用例的定时任务的任务通知
|
* 根据用例ID获取所有该用例的定时任务的任务通知
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
package io.metersphere.system.controller;
|
||||||
|
|
||||||
|
import io.metersphere.functional.domain.FunctionalCase;
|
||||||
|
import io.metersphere.functional.domain.FunctionalCaseCustomField;
|
||||||
|
import io.metersphere.functional.domain.FunctionalCaseCustomFieldExample;
|
||||||
|
import io.metersphere.functional.mapper.FunctionalCaseCustomFieldMapper;
|
||||||
|
import io.metersphere.functional.mapper.FunctionalCaseMapper;
|
||||||
|
import io.metersphere.sdk.util.BeanUtils;
|
||||||
|
import io.metersphere.sdk.util.JSON;
|
||||||
|
import io.metersphere.system.base.BaseTest;
|
||||||
|
import io.metersphere.system.controller.dto.FunctionalCaseDTO;
|
||||||
|
import io.metersphere.system.domain.CustomField;
|
||||||
|
import io.metersphere.system.dto.sdk.OptionDTO;
|
||||||
|
import io.metersphere.system.dto.sdk.SessionUser;
|
||||||
|
import io.metersphere.system.dto.user.UserDTO;
|
||||||
|
import io.metersphere.system.mapper.CustomFieldMapper;
|
||||||
|
import io.metersphere.system.notice.constants.NoticeConstants;
|
||||||
|
import io.metersphere.system.notice.sender.AfterReturningNoticeSendService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
|
import org.junit.jupiter.api.Order;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
|
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 java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
|
@AutoConfigureMockMvc
|
||||||
|
public class AfterReturningNoticeSendServiceTests extends BaseTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AfterReturningNoticeSendService afterReturningNoticeSendService;
|
||||||
|
@Resource
|
||||||
|
private FunctionalCaseMapper functionalCaseMapper;
|
||||||
|
@Resource
|
||||||
|
private CustomFieldMapper customFieldMapper;
|
||||||
|
@Resource
|
||||||
|
private FunctionalCaseCustomFieldMapper functionalCaseCustomFieldMapper;
|
||||||
|
|
||||||
|
|
||||||
|
private ThreadLocal<String> source = new ThreadLocal<>();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(1)
|
||||||
|
@Sql(scripts = {"/dml/init_aspect.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
|
||||||
|
public void noticeSuccess() {
|
||||||
|
String taskType = NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK;
|
||||||
|
List<String>eventList = new ArrayList<>();
|
||||||
|
getTypeList(eventList);
|
||||||
|
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey("aspect_gyq_one");
|
||||||
|
FunctionalCaseCustomFieldExample functionalCaseCustomFieldExample = new FunctionalCaseCustomFieldExample();
|
||||||
|
functionalCaseCustomFieldExample.createCriteria().andCaseIdEqualTo("aspect_gyq_one");
|
||||||
|
List<FunctionalCaseCustomField> functionalCaseCustomFields = functionalCaseCustomFieldMapper.selectByExample(functionalCaseCustomFieldExample);
|
||||||
|
String fieldId = functionalCaseCustomFields.get(0).getFieldId();
|
||||||
|
CustomField customFields = customFieldMapper.selectByPrimaryKey(fieldId);
|
||||||
|
|
||||||
|
List<OptionDTO>optionDTOList = new ArrayList<>();
|
||||||
|
OptionDTO optionDTO = new OptionDTO();
|
||||||
|
optionDTO.setId(customFields.getName());
|
||||||
|
optionDTO.setName(functionalCaseCustomFields.get(0).getValue());
|
||||||
|
optionDTOList.add(optionDTO);
|
||||||
|
FunctionalCaseDTO functionalCaseDTO = new FunctionalCaseDTO();
|
||||||
|
BeanUtils.copyBean(functionalCaseDTO,functionalCase);
|
||||||
|
functionalCaseDTO.setRelatedUsers("aspect-member-user-guo");
|
||||||
|
functionalCaseDTO.setFields(optionDTOList);
|
||||||
|
|
||||||
|
String jsonObject = JSON.toJSONString(functionalCaseDTO);
|
||||||
|
if (!StringUtils.equals("{}", jsonObject) && !StringUtils.equals("[]", jsonObject)) {
|
||||||
|
source.set(JSON.toJSONString(functionalCaseDTO));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Map> resources = new ArrayList<>();
|
||||||
|
String v = source.get();
|
||||||
|
if (StringUtils.isNotBlank(v)) {
|
||||||
|
// array
|
||||||
|
if (StringUtils.startsWith(v, "[")) {
|
||||||
|
resources.addAll(JSON.parseArray(v, Map.class));
|
||||||
|
}
|
||||||
|
// map
|
||||||
|
else {
|
||||||
|
Map<?, ?> value = JSON.parseObject(v, Map.class);
|
||||||
|
resources.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UserDTO userDTO = new UserDTO();
|
||||||
|
userDTO.setId(sessionId);
|
||||||
|
userDTO.setName("admin");
|
||||||
|
SessionUser user = SessionUser.fromUser(userDTO, sessionId);
|
||||||
|
|
||||||
|
for (String event : eventList) {
|
||||||
|
afterReturningNoticeSendService.sendNotice(taskType, event,resources, user, "100001100001");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void getTypeList(List<String>eventList ) {
|
||||||
|
eventList.add(NoticeConstants.Event.CREATE);
|
||||||
|
eventList.add(NoticeConstants.Event.UPDATE);
|
||||||
|
eventList.add(NoticeConstants.Event.AT);
|
||||||
|
eventList.add(NoticeConstants.Event.REPLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package io.metersphere.system.controller.dto;
|
||||||
|
|
||||||
|
import io.metersphere.functional.domain.FunctionalCase;
|
||||||
|
import io.metersphere.system.dto.sdk.OptionDTO;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class FunctionalCaseDTO extends FunctionalCase {
|
||||||
|
|
||||||
|
@Schema(description = "评论@的人, 多个以';'隔开")
|
||||||
|
private String relatedUsers;
|
||||||
|
|
||||||
|
@Schema(description = "自定义字段的值")
|
||||||
|
private List<OptionDTO> fields;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
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 ('aspect_gyq_one', 1000001, 'test_guo', '100001100001', 'test_guo', 'gyq_test_one', 'UN_REVIEWED', null, 'text',
|
||||||
|
10001, '111', 'aspect_gyq_one', '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 ('aspect_gyq_two', 1000001, 'test_guo', '100001100001', 'test_guo', 'gyq_test_two', 'UN_REVIEWED', null, 'text',
|
||||||
|
10001, '111', 'aspect_gyq_two', 'success', false, false, true, 'gyq', 'gyq', null, 1698058347559, 1698058347559,
|
||||||
|
null);
|
||||||
|
|
||||||
|
INSERT INTO user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source,
|
||||||
|
last_project_id, create_user, update_user, deleted)
|
||||||
|
VALUES ('aspect-member-user-guo', 'aspect-member-user-guo', 'aspect-member-user-guo@metersphere.io',
|
||||||
|
MD5('metersphere'), 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(), 'aspect-member-user-guo', 'org_member', '100001', '100001', UNIX_TIMESTAMP() * 1000, 'admin');
|
||||||
|
|
||||||
|
INSERT INTO user_role_relation (id, user_id, role_id, source_id, organization_id, create_time, create_user)
|
||||||
|
VALUES (UUID(), 'aspect-member-user-guo', 'project_admin', '100001100001', '100001', UNIX_TIMESTAMP() * 1000,
|
||||||
|
'admin');
|
||||||
|
|
||||||
|
INSERT INTO user_role_permission(id, role_id, permission_id)
|
||||||
|
VALUES ('aspect_user_role_guo_permission1', 'project_admin', 'FUNCTIONAL_CASE_COMMENT:READ+ADD'),
|
||||||
|
('aspect_user_role_guo_permission2', 'project_admin', 'FUNCTIONAL_CASE:READ+ADD');
|
||||||
|
|
||||||
|
INSERT INTO custom_field(id, name, scene, type, remark, create_time, update_time, create_user, ref_id, scope_id, internal, enable_option_key, scope_type)
|
||||||
|
values ('aspect_test_one','aspect_test','FUNCTIONAL', 'INPUT','aspect_test', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin' , 'aspect_test_one', '100001100001',false, false, 'PROJECT');
|
||||||
|
|
||||||
|
INSERT INTO functional_case_custom_field(case_id, field_id, value) VALUES ('aspect_gyq_one', 'aspect_test_one', 'hello');
|
Loading…
Reference in New Issue