refactor(功能用例): 接口逻辑触发消息通知

This commit is contained in:
guoyuqi 2023-10-26 13:57:59 +08:00 committed by Craftsman
parent b1c627ef3f
commit c09f15ed11
22 changed files with 913 additions and 100 deletions

View File

@ -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_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_DELETE = "FUNCTIONAL_CASE_COMMENT:READ+DELETE";
/*------ end: FUNCTIONAL_CASE ------*/
}

View File

@ -120,4 +120,8 @@ case_review_follow.follow_id.not_blank=关注人不能为空
custom_field_test_case.resource_id.not_blank=资源ID不能为空
custom_field_test_case.field_id.not_blank=字段ID不能为空
#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为空

View File

@ -137,4 +137,8 @@ custom_field_test_case.resource_id.not_blank=Resource ID cannot be empty
custom_field_test_case.field_id.not_blank=Field ID cannot be empty
default_template_not_found=Default template not found
#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

View File

@ -137,4 +137,8 @@ custom_field_test_case.resource_id.not_blank=资源ID不能为空
custom_field_test_case.field_id.not_blank=字段ID不能为空
default_template_not_found=默认模板不存在
#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为空

View File

@ -137,4 +137,8 @@ custom_field_test_case.resource_id.not_blank=資源ID不能為空
custom_field_test_case.field_id.not_blank=字段ID不能為空
default_template_not_found=默認模板不存在
#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為空

View File

@ -3,10 +3,7 @@ package io.metersphere.functional.controller;
import io.metersphere.functional.domain.FunctionalCaseComment;
import io.metersphere.functional.request.FunctionalCaseCommentRequest;
import io.metersphere.functional.service.FunctionalCaseCommentService;
import io.metersphere.functional.service.FunctionalCaseNoticeService;
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.validation.groups.Created;
import io.swagger.v3.oas.annotations.Operation;
@ -14,10 +11,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
@Tag(name = "用例管理-功能用例-用例评论")
@RestController
@ -30,8 +24,14 @@ public class FunctionalCaseCommentController {
@PostMapping("/save")
@Operation(summary = "用例管理-功能用例-用例评论-创建评论")
@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) {
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);
}
}

View File

@ -1,13 +1,19 @@
package io.metersphere.functional.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;
}

View File

@ -14,7 +14,7 @@ public class FunctionalCaseCommentRequest {
@NotBlank(message = "{functional_case_comment.case_id.not_blank}", groups = {Created.class})
private String caseId;
@Schema(description = "评论@的人, 多个以';'隔开")
@Schema(description = "评论@的人的Id, 多个以';'隔开")
private String notifier;
@Schema(description = "回复人")
@ -27,4 +27,8 @@ public class FunctionalCaseCommentRequest {
@NotBlank(message = "{functional_case_comment.content.not_blank}", groups = {Created.class})
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;
}

View File

@ -2,17 +2,29 @@ package io.metersphere.functional.service;
import io.metersphere.functional.domain.FunctionalCase;
import io.metersphere.functional.domain.FunctionalCaseComment;
import io.metersphere.functional.domain.FunctionalCaseCommentExample;
import io.metersphere.functional.dto.CommentEnum;
import io.metersphere.functional.dto.FunctionalCaseDTO;
import io.metersphere.functional.mapper.FunctionalCaseCommentMapper;
import io.metersphere.functional.mapper.FunctionalCaseMapper;
import io.metersphere.functional.request.FunctionalCaseCommentRequest;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.domain.User;
import io.metersphere.system.mapper.UserMapper;
import io.metersphere.system.notice.NoticeModel;
import io.metersphere.system.notice.constants.NoticeConstants;
import io.metersphere.system.notice.utils.MessageTemplateUtils;
import io.metersphere.system.service.NoticeSendService;
import io.metersphere.system.uid.IDGenerator;
import jakarta.annotation.Resource;
import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* @author guoyuqi
*/
@ -26,14 +38,42 @@ public class FunctionalCaseCommentService {
@Resource
private FunctionalCaseMapper functionalCaseMapper;
@Resource
private UserMapper userMapper;
@Resource
private FunctionalCaseNoticeService functionalCaseNoticeService;
@Resource
private NoticeSendService noticeSendService;
/**
* 新增评论
*
* @param functionalCaseCommentRequest functionalCaseCommentDTO
* @param userId 当前操作用户
* @param userId 当前操作用户
* @return FunctionalCaseComment
*/
public FunctionalCaseComment saveComment(FunctionalCaseCommentRequest functionalCaseCommentRequest, String userId) {
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.setId(IDGenerator.nextStr());
functionalCaseComment.setCaseId(functionalCaseCommentRequest.getCaseId());
@ -42,20 +82,120 @@ public class FunctionalCaseCommentService {
functionalCaseComment.setCreateTime(System.currentTimeMillis());
functionalCaseComment.setUpdateTime(System.currentTimeMillis());
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;
}
private void checkCase(FunctionalCaseCommentRequest functionalCaseCommentRequest) {
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(functionalCaseCommentRequest.getCaseId());
if (functionalCase ==null) {
if (functionalCase == 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);
}
}

View File

@ -1,29 +1,121 @@
package io.metersphere.functional.service;
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.mapper.FunctionalCaseCustomFieldMapper;
import io.metersphere.functional.mapper.FunctionalCaseMapper;
import io.metersphere.functional.request.FunctionalCaseCommentRequest;
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 org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
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
public class FunctionalCaseNoticeService {
@Resource
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());
FunctionalCaseDTO functionalCaseDTO = new FunctionalCaseDTO();
if (functionalCase!=null) {
BeanUtils.copyBean(functionalCaseDTO,functionalCase);
}
functionalCaseDTO.setRelatedUsers(functionalCaseCommentRequest.getNotifier());
setNotifier(functionalCaseCommentRequest, functionalCaseDTO);
List<OptionDTO> customFields = getCustomFields(functionalCaseCommentRequest.getCaseId());
functionalCaseDTO.setFields(customFields);
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;
}
}

View File

@ -2,13 +2,23 @@ package io.metersphere.functional.controller;
import com.jayway.jsonpath.JsonPath;
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.project.domain.Notification;
import io.metersphere.project.domain.NotificationExample;
import io.metersphere.project.mapper.NotificationMapper;
import io.metersphere.sdk.constants.CustomFieldType;
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.Translator;
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 jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
@ -33,17 +43,29 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@AutoConfigureMockMvc
public class FunctionalCaseCommentControllerTests {
@Resource
private MockMvc mockMvc;
@Resource
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 DELETE_URL = "/functional/case/comment/delete/";
private static String sessionId;
private static String csrfToken;
private static String projectId = "100001100001";
private static final String projectId = "100001100001";
@Test
@Order(0)
@ -61,25 +83,17 @@ public class FunctionalCaseCommentControllerTests {
@Test
@Order(1)
public void saveCommentSuccess() throws Exception {
public void saveCommentATSuccess() throws Exception {
FunctionalCaseCommentRequest functionalCaseCommentRequest = new FunctionalCaseCommentRequest();
functionalCaseCommentRequest.setCaseId("xiaomeinvGTest");
functionalCaseCommentRequest.setNotifier("default-project-member-user-guo-1");
functionalCaseCommentRequest.setContent("评论你好");
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);
FunctionalCaseComment functionalCaseComment = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), FunctionalCaseComment.class);
functionalCaseCommentRequest.setEvent(NoticeConstants.Event.AT);
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.assertTrue(notifications.size() > 0);
Assertions.assertFalse(notifications.isEmpty());
Assertions.assertTrue(StringUtils.equals(notifications.get(0).getReceiver(), "default-project-member-user-guo-1"));
System.out.println(notifications.get(0).getContent());
Assertions.assertTrue(StringUtils.equals(functionalCaseComment.getCaseId(), "xiaomeinvGTest"));
@ -89,41 +103,42 @@ public class FunctionalCaseCommentControllerTests {
@Test
@Order(2)
public void saveCommentFalse() throws Exception {
public void saveCommentATFalse() throws Exception {
FunctionalCaseCommentRequest functionalCaseCommentRequest = new FunctionalCaseCommentRequest();
functionalCaseCommentRequest.setCaseId("xiaomeinvGTestNo");
functionalCaseCommentRequest.setNotifier("default-project-member-user-guo-1");
functionalCaseCommentRequest.setContent("评论你好");
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().is5xxServerError())
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
functionalCaseCommentRequest.setEvent(NoticeConstants.Event.AT);
ResultHolder resultHolder = postFalse(functionalCaseCommentRequest);
String jsonString = JSON.toJSONString(resultHolder.getData());
System.out.println(jsonString);
NotificationExample notificationExample = new NotificationExample();
notificationExample.createCriteria().andResourceIdEqualTo("xiaomeinvGTestNo").andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK);
List<Notification> notifications = notificationMapper.selectByExample(notificationExample);
Assertions.assertTrue(CollectionUtils.isEmpty(notifications));
}
@Test
@Order(3)
public void saveCommentExcludeSelfSuccess() throws Exception {
FunctionalCaseCommentRequest functionalCaseCommentRequest = new FunctionalCaseCommentRequest();
functionalCaseCommentRequest.setCaseId("xiaomeinvGTest");
functionalCaseCommentRequest.setNotifier("default-project-member-user-guo");
functionalCaseCommentRequest.setContent("这个好");
private ResultHolder postFalse(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(status().is5xxServerError())
.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);
return JSON.parseObject(contentAsString, ResultHolder.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.createCriteria().andResourceIdEqualTo("xiaomeinvGTest").andResourceTypeEqualTo(NoticeConstants.TaskType.FUNCTIONAL_CASE_TASK).andReceiverEqualTo("default-project-member-user-guo");
List<Notification> notifications = notificationMapper.selectByExample(notificationExample);
@ -133,4 +148,260 @@ public class FunctionalCaseCommentControllerTests {
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);
}
}

View File

@ -1,11 +1,17 @@
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 ('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,
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,
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',
MD5('metersphere'), UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin',
'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',
'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);
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'),
(UUID(), 'default-project-member-user-guo-1', 'org_member', '100001', '100001', UNIX_TIMESTAMP() * 1000,
'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,
'admin'),
(UUID(), 'gyq', '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)
@ -31,11 +56,20 @@ VALUES (UUID(), 'default-project-member-user-guo', 'project_admin', '10000110000
'admin'),
(UUID(), 'default-project-member-user-guo-1', 'project_admin', '100001100001', '100001', UNIX_TIMESTAMP() * 1000,
'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',
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)
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');

View File

@ -29,7 +29,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class CreateRobotResourceService implements CreateProjectResourceService {
@ -77,6 +79,7 @@ public class CreateRobotResourceService implements CreateProjectResourceService
public void setMessageTask(String projectId, String defaultRobotId) {
StringBuilder jsonStr = new StringBuilder();
InputStream inputStream = getClass().getResourceAsStream("/message_task.json");
assert inputStream != null;
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
try {
@ -91,15 +94,21 @@ public class CreateRobotResourceService implements CreateProjectResourceService
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
MessageTaskMapper mapper = sqlSession.getMapper(MessageTaskMapper.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);
for (MessageTaskDTO messageTaskDTO : messageTaskDTOList) {
List<MessageTaskTypeDTO> messageTaskTypeDTOList = messageTaskDTO.getMessageTaskTypeDTOList();
for (MessageTaskTypeDTO messageTaskTypeDTO : messageTaskTypeDTOList) {
String taskType = messageTaskTypeDTO.getTaskType();
if (taskType.contains("AT")) {
continue;
}
List<MessageTaskDetailDTO> messageTaskDetailDTOList = messageTaskTypeDTO.getMessageTaskDetailDTOList();
for (MessageTaskDetailDTO messageTaskDetailDTO : messageTaskDetailDTOList) {
String event = messageTaskDetailDTO.getEvent();
@ -134,8 +143,45 @@ public class CreateRobotResourceService implements CreateProjectResourceService
}
}
}
}
sqlSession.flushStatements();
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
private static void setAtMessageTask(String projectId, String defaultRobotId, MessageTaskMapper mapper, MessageTaskBlobMapper blobMapper) {
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);
}
});
}
}

View File

@ -1,8 +1,11 @@
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.ProjectRobot;
import io.metersphere.project.dto.MessageTaskDTO;
import io.metersphere.project.mapper.MessageTaskMapper;
import io.metersphere.project.mapper.ProjectMapper;
import io.metersphere.sdk.constants.SessionConstants;
import io.metersphere.sdk.util.JSON;
@ -42,6 +45,9 @@ public class CreateRobotResourceTests extends BaseTest {
@Resource
private ProjectMapper projectMapper;
@Resource
private MessageTaskMapper messageTaskMapper;
@Test
@Order(1)
public void testCreateResource() throws Exception {
@ -60,6 +66,10 @@ public class CreateRobotResourceTests extends BaseTest {
List<ProjectRobot> projectRobotAfters = getList(id);
Assertions.assertEquals(2, projectRobotAfters.size());
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);
}

View File

@ -139,7 +139,7 @@ public interface NoticeConstants {
String AT = "AT";
@Schema(description = "message.replay")
String REPLAY = "REPLAY";
String REPLY = "REPLY";
@Schema(description = "message.review_passed")
String REVIEW_PASSED = "REVIEW_PASSED";

View File

@ -21,7 +21,6 @@ import io.metersphere.plan.domain.TestPlanFollowerExample;
import io.metersphere.plan.mapper.TestPlanFollowerMapper;
import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.LogUtils;
import io.metersphere.system.domain.CustomField;
import io.metersphere.system.domain.User;
import io.metersphere.system.domain.UserExample;
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.utils.MessageTemplateUtils;
import jakarta.annotation.Resource;
import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
@ -91,16 +89,13 @@ public abstract class AbstractNoticeSender implements NoticeSender {
}
if (CollectionUtils.isNotEmpty(fields)) {
for (Object o : fields) {
Map jsonObject = new BeanMap(o);
String id = (String) jsonObject.get("id");
CustomField customField = customFieldMapper.selectByPrimaryKey(id);
if (customField == null) {
continue;
}
Object value = jsonObject.get("value");
if (value instanceof String && StringUtils.isNotEmpty((String) value)) {
String jsonFields = JSON.toJSONString(o);
Map<?, ?> jsonObject = JSON.parseObject(jsonFields, Map.class);
String customFieldName = (String) jsonObject.get("id");
Object value = jsonObject.get("name");
if (value instanceof String && StringUtils.isNotBlank((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()) {
switch (userId) {
case NoticeConstants.RelatedUser.CREATE_USER -> {
String createUser = (String) paramMap.get(NoticeConstants.RelatedUser.CREATE_USER);
String createUser = (String) paramMap.get("createUser");
if (StringUtils.isNotBlank(createUser)) {
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())) {
for (String relatedUser : noticeModel.getRelatedUsers()) {
toUsers.add(new Receiver(relatedUser, NotificationConstants.Type.MENTIONED_ME.name()));

View File

@ -4,7 +4,6 @@ package io.metersphere.system.notice.sender;
import io.metersphere.system.dto.sdk.BaseSystemConfigDTO;
import io.metersphere.system.dto.sdk.SessionUser;
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.utils.MessageTemplateUtils;
import io.metersphere.system.service.NoticeSendService;
@ -24,7 +23,7 @@ public class AfterReturningNoticeSendService {
private NoticeSendService noticeSendService;
@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();
@ -39,9 +38,9 @@ public class AfterReturningNoticeSendService {
// 占位符
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"));
@ -50,12 +49,12 @@ public class AfterReturningNoticeSendService {
.context(context)
.subject(subject)
.paramMap(paramMap)
.event(sendNotice.event())
.event(event)
.status((String) paramMap.get("status"))
.excludeSelf(true)
.relatedUsers(relatedUsers)
.build();
noticeSendService.send(sendNotice.taskType(), noticeModel);
noticeSendService.send(taskType, noticeModel);
}
}
@ -63,14 +62,14 @@ public class AfterReturningNoticeSendService {
String relatedUser = (String) relatedUsers;
List<String> relatedUserList = new ArrayList<>();
if (StringUtils.isNotBlank(relatedUser)) {
relatedUserList = Arrays.asList(relatedUser.split(","));
relatedUserList = Arrays.asList(relatedUser.split(";"));
}
return relatedUserList;
}
private String getSubject(SendNotice sendNotice) {
private String getSubject(String taskType, String event) {
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); // 占位符
}
private String getContext(SendNotice sendNotice) {
private String getContext(String taskType, String event) {
Map<String, String> defaultTemplateMap = MessageTemplateUtils.getDefaultTemplateMap();
return defaultTemplateMap.get(sendNotice.taskType() + "_" + sendNotice.event());
return defaultTemplateMap.get(taskType + "_" + event);
}
}

View File

@ -89,14 +89,14 @@ public class SendNoticeAspect {
String[] params = discoverer.getParameterNames(method);
//获取操作
SendNotice sendNotice = method.getAnnotation(SendNotice.class);
EvaluationContext context = new StandardEvaluationContext();
for (int len = 0; len < params.length; len++) {
context.setVariable(params[len], args[len]);
}
// 再次从数据库查询一次内容方便获取最新参数
if (StringUtils.isNotEmpty(sendNotice.target())) {
//将参数纳入Spring管理
EvaluationContext context = new StandardEvaluationContext();
for (int len = 0; len < params.length; len++) {
context.setVariable(params[len], args[len]);
}
context.setVariable("targetClass", CommonBeanFactory.getBean(sendNotice.targetClass()));
String target = sendNotice.target();
@ -124,10 +124,32 @@ public class SendNoticeAspect {
} else {
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();
String currentProjectId = SessionUtils.getCurrentProjectId();
afterReturningNoticeSendService.sendNotice(sendNotice, resources, sessionUser, currentProjectId);
LogUtils.info("event:"+event);
afterReturningNoticeSendService.sendNotice(taskType,event, resources, sessionUser, currentProjectId);
} catch (Exception e) {
LogUtils.error(e.getMessage(), e);
} finally {

View File

@ -112,10 +112,14 @@ public class MessageDetailService {
if (!messageTask.getUseDefaultSubject() && StringUtils.isNotBlank(messageTask.getSubject())) {
messageDetail.setSubject(messageTask.getSubject());
} else {
String subject = getSubject(messageTask.getTaskType(), messageTask.getEvent());
messageDetail.setSubject(subject);
if (StringUtils.equals(projectRobot.getPlatform(),"MAIL")) {
String subject = getMailSubject(messageTask.getTaskType(), messageTask.getEvent());
messageDetail.setSubject(subject);
} else {
String subject = getSubject(messageTask.getTaskType(), messageTask.getEvent());
messageDetail.setSubject(subject);
}
}
MessageTaskBlob messageTaskBlob = messageTaskBlobMap.get(messageTask.getId());
if (!messageTask.getUseDefaultTemplate() && StringUtils.isNotBlank(messageTaskBlob.getTemplate())) {
messageDetail.setTemplate(messageTaskBlob.getTemplate());
@ -132,12 +136,15 @@ public class MessageDetailService {
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();
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获取所有该用例的定时任务的任务通知
*

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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');