feat(用例评审): 新增用例评审编辑获取固定权限的用户列表

This commit is contained in:
guoyuqi 2023-11-24 19:38:48 +08:00 committed by f2c-ci-robot[bot]
parent c86a192ae9
commit c940a86423
11 changed files with 433 additions and 103 deletions

View File

@ -1,22 +1,28 @@
package io.metersphere.functional.controller;
import io.metersphere.functional.request.CaseReviewAddRequest;
import io.metersphere.functional.request.CaseReviewFollowerRequest;
import io.metersphere.functional.request.CaseReviewRequest;
import io.metersphere.functional.service.CaseReviewLogService;
import io.metersphere.functional.service.CaseReviewNoticeService;
import io.metersphere.functional.service.CaseReviewService;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.system.domain.User;
import io.metersphere.system.log.annotation.Log;
import io.metersphere.system.log.constants.OperationLogType;
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.Updated;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.apache.shiro.authz.annotation.Logical;
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.*;
import java.util.List;
@Tag(name = "用例管理-用例评审")
@RestController
@ -29,11 +35,21 @@ public class CaseReviewController {
@PostMapping("/add")
@Operation(summary = "用例管理-用例评审-创建用例评审")
@Log(type = OperationLogType.ADD, expression = "#msClass.addCaseReviewLog(#request)", msClass = CaseReviewLogService.class)
@SendNotice(taskType = NoticeConstants.TaskType.CASE_REVIEW_TASK, event = NoticeConstants.Event.CREATE, target = "#targetClass.getMainCaseReview(#request)", targetClass = CaseReviewNoticeService.class)
@RequiresPermissions(PermissionConstants.CASE_REVIEW_READ_ADD)
public void addCaseReview(@Validated @RequestBody CaseReviewAddRequest request) {
public void addCaseReview(@Validated @RequestBody CaseReviewRequest request) {
caseReviewService.addCaseReview(request, SessionUtils.getUserId());
}
@PostMapping("/edit")
@Operation(summary = "用例管理-用例评审-编辑用例评审")
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateCaseReviewLog(#request)", msClass = CaseReviewLogService.class)
@SendNotice(taskType = NoticeConstants.TaskType.CASE_REVIEW_TASK, event = NoticeConstants.Event.UPDATE, target = "#targetClass.getMainCaseReview(#request)", targetClass = CaseReviewNoticeService.class)
@RequiresPermissions(PermissionConstants.CASE_REVIEW_READ_UPDATE)
public void editCaseReview(@Validated({Updated.class}) @RequestBody CaseReviewRequest request) {
caseReviewService.editCaseReview(request, SessionUtils.getUserId());
}
@PostMapping("/edit/follower")
@Operation(summary = "用例管理-用例评审-关注/取消关注用例")
@RequiresPermissions(PermissionConstants.CASE_REVIEW_READ_UPDATE)
@ -41,4 +57,12 @@ public class CaseReviewController {
caseReviewService.editFollower(request.getCaseReviewId(), SessionUtils.getUserId());
}
@GetMapping("/user-option/{projectId}")
@Operation(summary = "用例管理-用例评审-获取具有评审权限的用户")
@RequiresPermissions(value = {PermissionConstants.CASE_REVIEW_READ_ADD,PermissionConstants.CASE_REVIEW_READ_UPDATE}, logical = Logical.OR)
public List<User> getReviewUserList(@PathVariable String projectId, @Schema(description = "查询关键字,根据邮箱和用户名查询")
@RequestParam(value = "keyword", required = false) String keyword) {
return caseReviewService.getReviewUserList(projectId, keyword);
}
}

View File

@ -12,5 +12,5 @@ public interface ExtCaseReviewMapper {
List<CaseReview> checkCaseByModuleIds(@Param("moduleIds") List<String> deleteIds);
Long getPos(@Param("projectId") String projectId);
}

View File

@ -14,4 +14,16 @@
</foreach>
</select>
<select id="getPos" resultType="java.lang.Long">
SELECT
pos
FROM
case_review
WHERE
project_id = #{projectId}
ORDER BY
pos DESC
LIMIT 1;
</select>
</mapper>

View File

@ -1,5 +1,6 @@
package io.metersphere.functional.request;
import io.metersphere.validation.groups.Updated;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
@ -12,11 +13,15 @@ import java.util.List;
@Data
@EqualsAndHashCode(callSuper = false)
public class CaseReviewAddRequest implements Serializable {
public class CaseReviewRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "用例id", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{functional_case.id.not_blank}", groups = {Updated.class})
private String id;
@Schema(description = "项目id", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{case_review.project_id.not_blank}")
private String projectId;

View File

@ -1,11 +1,14 @@
package io.metersphere.functional.service;
import io.metersphere.functional.request.CaseReviewAddRequest;
import io.metersphere.functional.domain.CaseReview;
import io.metersphere.functional.mapper.CaseReviewMapper;
import io.metersphere.functional.request.CaseReviewRequest;
import io.metersphere.sdk.constants.HttpMethodConstants;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.log.constants.OperationLogModule;
import io.metersphere.system.log.constants.OperationLogType;
import io.metersphere.system.log.dto.LogDTO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -16,13 +19,16 @@ import org.springframework.transaction.annotation.Transactional;
@Transactional(rollbackFor = Exception.class)
public class CaseReviewLogService {
@Resource
private CaseReviewMapper caseReviewMapper;
/**
* 新增用例评审 日志
*
* @param requests 页面参数
* @return LogDTO
*/
public LogDTO addCaseReviewLog(CaseReviewAddRequest requests) {
public LogDTO addCaseReviewLog(CaseReviewRequest requests) {
LogDTO dto = new LogDTO(
requests.getProjectId(),
null,
@ -37,4 +43,30 @@ public class CaseReviewLogService {
dto.setOriginalValue(JSON.toJSONBytes(requests));
return dto;
}
/**
* 更新用例评审 日志
*
* @param requests 页面参数
* @return LogDTO
*/
public LogDTO updateCaseReviewLog(CaseReviewRequest requests) {
CaseReview caseReview = caseReviewMapper.selectByPrimaryKey(requests.getId());
if (caseReview ==null) {
return null;
}
LogDTO dto = new LogDTO(
caseReview.getProjectId(),
null,
caseReview.getId(),
caseReview.getCreateUser(),
OperationLogType.UPDATE.name(),
OperationLogModule.CASE_REVIEW,
caseReview.getName());
dto.setPath("/case/review/edit");
dto.setMethod(HttpMethodConstants.POST.name());
dto.setOriginalValue(JSON.toJSONBytes(caseReview));
return dto;
}
}

View File

@ -0,0 +1,56 @@
package io.metersphere.functional.service;
import io.metersphere.functional.constants.CaseReviewStatus;
import io.metersphere.functional.domain.CaseReview;
import io.metersphere.functional.mapper.CaseReviewMapper;
import io.metersphere.functional.mapper.ExtCaseReviewMapper;
import io.metersphere.functional.request.CaseReviewRequest;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.utils.SessionUtils;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
@Service
public class CaseReviewNoticeService {
@Resource
private ExtCaseReviewMapper extCaseReviewMapper;
@Resource
private CaseReviewMapper caseReviewMapper;
public CaseReview getMainCaseReview(CaseReviewRequest request){
CaseReview caseReview = null;
if (StringUtils.isNotBlank(request.getId())) {
caseReview = caseReviewMapper.selectByPrimaryKey(request.getId());
}
if (caseReview == null) {
caseReview = new CaseReview();
}
caseReview.setName(request.getName());
caseReview.setModuleId(request.getModuleId());
if (StringUtils.isBlank(request.getId())) {
caseReview.setProjectId(request.getProjectId());
caseReview.setStatus(CaseReviewStatus.PREPARED.toString());
caseReview.setReviewPassRule(request.getReviewPassRule());
caseReview.setPos(getNextPos(request.getProjectId()));
caseReview.setCreateTime(System.currentTimeMillis());
caseReview.setCreateUser(SessionUtils.getUserId());
}
if (CollectionUtils.isNotEmpty(request.getTags())) {
caseReview.setTags(JSON.toJSONString(request.getTags()));
}
caseReview.setStartTime(request.getStartTime());
caseReview.setEndTime(request.getEndTime());
caseReview.setUpdateTime(System.currentTimeMillis());
caseReview.setUpdateUser(SessionUtils.getUserId());
return caseReview;
}
public Long getNextPos(String projectId) {
Long pos = extCaseReviewMapper.getPos(projectId);
return (pos == null ? 0 : pos) + 5000;
}
}

View File

@ -5,10 +5,13 @@ import io.metersphere.functional.constants.CaseReviewStatus;
import io.metersphere.functional.constants.FunctionalCaseReviewStatus;
import io.metersphere.functional.domain.*;
import io.metersphere.functional.mapper.*;
import io.metersphere.functional.request.CaseReviewAddRequest;
import io.metersphere.functional.request.CaseReviewRequest;
import io.metersphere.functional.result.CaseManagementResultCode;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.domain.User;
import io.metersphere.system.mapper.ExtUserMapper;
import io.metersphere.system.uid.IDGenerator;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
@ -19,6 +22,8 @@ import org.mybatis.spring.SqlSessionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 用例评审表服务实现类
*
@ -28,16 +33,20 @@ import org.springframework.transaction.annotation.Transactional;
@Transactional(rollbackFor = Exception.class)
public class CaseReviewService {
public static final int ORDER_STEP = 5000;
public static final int POS_STEP = 5000;
@Resource
private ExtFunctionalCaseMapper extFunctionalCaseMapper;
private ExtCaseReviewMapper extCaseReviewMapper;
@Resource
private CaseReviewMapper caseReviewMapper;
@Resource
private CaseReviewFollowerMapper caseReviewFollowerMapper;
@Resource
SqlSessionFactory sqlSessionFactory;
@Resource
private CaseReviewUserMapper caseReviewUserMapper;
@Resource
private ExtUserMapper extUserMapper;
/**
* 添加用例评审
@ -45,7 +54,7 @@ public class CaseReviewService {
* @param request 页面参数
* @param userId 当前操作人
*/
public void addCaseReview(CaseReviewAddRequest request, String userId) {
public void addCaseReview(CaseReviewRequest request, String userId) {
String caseReviewId = IDGenerator.nextStr();
addCaseReview(request, userId, caseReviewId);
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
@ -63,69 +72,39 @@ public class CaseReviewService {
}
/**
* 保存用例评审和功能用例的关系
* @param request request
* 编辑用例评审
* @param request 页面参数
* @param userId 当前操作人
* @param caseReviewId 用例评审id
* @param caseReviewFunctionalCaseMapper caseReviewFunctionalCaseMapper
*/
private void addCaseReviewFunctionalCase(CaseReviewAddRequest request, String userId, String caseReviewId, CaseReviewFunctionalCaseMapper caseReviewFunctionalCaseMapper) {
if (CollectionUtils.isNotEmpty(request.getCaseIds())) {
request.getReviewers().forEach(caseId -> {
CaseReviewFunctionalCase caseReviewFunctionalCase = new CaseReviewFunctionalCase();
caseReviewFunctionalCase.setReviewId(caseReviewId);
caseReviewFunctionalCase.setCaseId(caseId);
caseReviewFunctionalCase.setStatus(FunctionalCaseReviewStatus.UN_REVIEWED.toString());
caseReviewFunctionalCase.setCreateUser(userId);
caseReviewFunctionalCase.setCreateTime(System.currentTimeMillis());
caseReviewFunctionalCase.setUpdateTime(System.currentTimeMillis());
caseReviewFunctionalCase.setId(IDGenerator.nextStr());
caseReviewFunctionalCase.setPos(getNextOrder(request.getProjectId()));
caseReviewFunctionalCaseMapper.insert(caseReviewFunctionalCase);
});
}
}
/**
* 保存用例评审和评审人的关系
* @param request request
* @param caseReviewId 用例评审
* @param caseReviewUserMapper caseReviewUserMapper
*/
private static void addCaseReviewUser(CaseReviewAddRequest request, String caseReviewId, CaseReviewUserMapper caseReviewUserMapper) {
request.getReviewers().forEach(user -> {
CaseReviewUser caseReviewUser = new CaseReviewUser();
caseReviewUser.setReviewId(caseReviewId);
caseReviewUser.setUserId(user);
caseReviewUserMapper.insert(caseReviewUser);
});
}
/**
* 新增用例评审
* @param request request
* @param userId 当前操作人
* @param caseReviewId 用例评审id
*/
private void addCaseReview(CaseReviewAddRequest request, String userId, String caseReviewId) {
public void editCaseReview(CaseReviewRequest request, String userId) {
String reviewId = request.getId();
checkCaseReview(reviewId);
CaseReview caseReview = new CaseReview();
caseReview.setId(caseReviewId);
caseReview.setId(reviewId);
caseReview.setProjectId(request.getProjectId());
caseReview.setName(request.getName());
caseReview.setModuleId(request.getModuleId());
caseReview.setStatus(CaseReviewStatus.PREPARED.toString());
caseReview.setReviewPassRule(request.getReviewPassRule());
caseReview.setPos(getNextOrder(request.getProjectId()));
if (CollectionUtils.isNotEmpty(request.getTags())) {
caseReview.setTags(JSON.toJSONString(request.getTags()));
}
caseReview.setStartTime(request.getStartTime());
caseReview.setEndTime(request.getEndTime());
caseReview.setCreateTime(System.currentTimeMillis());
caseReview.setUpdateTime(System.currentTimeMillis());
caseReview.setCreateUser(userId);
caseReview.setUpdateUser(userId);
caseReviewMapper.insert(caseReview);
caseReviewMapper.updateByPrimaryKeySelective(caseReview);
//删除用例评审和评审人的关系
CaseReviewUserExample caseReviewUserExample = new CaseReviewUserExample();
caseReviewUserExample.createCriteria().andReviewIdEqualTo(reviewId);
caseReviewUserMapper.deleteByExample(caseReviewUserExample);
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
CaseReviewUserMapper mapper = sqlSession.getMapper(CaseReviewUserMapper.class);
try {
//保存评审和评审人的关系
addCaseReviewUser(request, reviewId, mapper);
sqlSession.flushStatements();
} finally {
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
}
}
/**
@ -148,26 +127,105 @@ public class CaseReviewService {
}
}
/**
* 获取具有评审权限的用户
* @param projectId projectId
* @param keyword 查询关键字根据邮箱和用户名查询
* @return List<User>
*/
public List<User> getReviewUserList(String projectId, String keyword) {
return extUserMapper.getUserByPermission(projectId, keyword, PermissionConstants.CASE_REVIEW_REVIEW);
}
/**
* 新增用例评审
* @param request request
* @param userId 当前操作人
* @param caseReviewId 用例评审id
*/
private void addCaseReview(CaseReviewRequest request, String userId, String caseReviewId) {
CaseReview caseReview = new CaseReview();
caseReview.setId(caseReviewId);
caseReview.setProjectId(request.getProjectId());
caseReview.setName(request.getName());
caseReview.setModuleId(request.getModuleId());
caseReview.setStatus(CaseReviewStatus.PREPARED.toString());
caseReview.setReviewPassRule(request.getReviewPassRule());
caseReview.setPos(getNextPos(request.getProjectId()));
if (CollectionUtils.isNotEmpty(request.getTags())) {
caseReview.setTags(JSON.toJSONString(request.getTags()));
}
caseReview.setStartTime(request.getStartTime());
caseReview.setEndTime(request.getEndTime());
caseReview.setCreateTime(System.currentTimeMillis());
caseReview.setUpdateTime(System.currentTimeMillis());
caseReview.setCreateUser(userId);
caseReview.setUpdateUser(userId);
caseReviewMapper.insert(caseReview);
}
/**
* 检查用例评审是否存在
*
* @param caseReviewId 用例评审id
* @return CaseReview
*/
private CaseReview checkCaseReview(String caseReviewId) {
private void checkCaseReview(String caseReviewId) {
CaseReviewExample caseReviewExample = new CaseReviewExample();
caseReviewExample.createCriteria().andIdEqualTo(caseReviewId);
CaseReview caseReview = caseReviewMapper.selectByPrimaryKey(caseReviewId);
if (caseReview == null) {
throw new MSException(CaseManagementResultCode.CASE_REVIEW_NOT_FOUND);
}
return caseReview;
}
public Long getNextOrder(String projectId) {
Long pos = extFunctionalCaseMapper.getPos(projectId);
return (pos == null ? 0 : pos) + ORDER_STEP;
/**
*
* @param projectId 项目id
* @return pos
*/
public Long getNextPos(String projectId) {
Long pos = extCaseReviewMapper.getPos(projectId);
return (pos == null ? 0 : pos) + POS_STEP;
}
/**
* 保存用例评审和功能用例的关系
* @param request request
* @param userId 当前操作人
* @param caseReviewId 用例评审id
* @param caseReviewFunctionalCaseMapper caseReviewFunctionalCaseMapper
*/
private void addCaseReviewFunctionalCase(CaseReviewRequest request, String userId, String caseReviewId, CaseReviewFunctionalCaseMapper caseReviewFunctionalCaseMapper) {
if (CollectionUtils.isNotEmpty(request.getCaseIds())) {
request.getReviewers().forEach(caseId -> {
CaseReviewFunctionalCase caseReviewFunctionalCase = new CaseReviewFunctionalCase();
caseReviewFunctionalCase.setReviewId(caseReviewId);
caseReviewFunctionalCase.setCaseId(caseId);
caseReviewFunctionalCase.setStatus(FunctionalCaseReviewStatus.UN_REVIEWED.toString());
caseReviewFunctionalCase.setCreateUser(userId);
caseReviewFunctionalCase.setCreateTime(System.currentTimeMillis());
caseReviewFunctionalCase.setUpdateTime(System.currentTimeMillis());
caseReviewFunctionalCase.setId(IDGenerator.nextStr());
caseReviewFunctionalCase.setPos(getNextPos(request.getProjectId()));
caseReviewFunctionalCaseMapper.insert(caseReviewFunctionalCase);
});
}
}
/**
* 保存用例评审和评审人的关系
* @param request request
* @param caseReviewId 用例评审
* @param caseReviewUserMapper caseReviewUserMapper
*/
private static void addCaseReviewUser(CaseReviewRequest request, String caseReviewId, CaseReviewUserMapper caseReviewUserMapper) {
request.getReviewers().forEach(user -> {
CaseReviewUser caseReviewUser = new CaseReviewUser();
caseReviewUser.setReviewId(caseReviewId);
caseReviewUser.setUserId(user);
caseReviewUserMapper.insert(caseReviewUser);
});
}
}

View File

@ -6,9 +6,16 @@ import io.metersphere.functional.mapper.CaseReviewFollowerMapper;
import io.metersphere.functional.mapper.CaseReviewFunctionalCaseMapper;
import io.metersphere.functional.mapper.CaseReviewMapper;
import io.metersphere.functional.mapper.CaseReviewUserMapper;
import io.metersphere.functional.request.CaseReviewAddRequest;
import io.metersphere.functional.request.CaseReviewFollowerRequest;
import io.metersphere.functional.request.CaseReviewRequest;
import io.metersphere.project.domain.Notification;
import io.metersphere.project.domain.NotificationExample;
import io.metersphere.project.mapper.NotificationMapper;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.base.BaseTest;
import io.metersphere.system.controller.handler.ResultHolder;
import io.metersphere.system.domain.User;
import io.metersphere.system.notice.constants.NoticeConstants;
import jakarta.annotation.Resource;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.*;
@ -17,8 +24,10 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.SqlConfig;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.testcontainers.shaded.org.apache.commons.lang3.StringUtils;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@ -35,7 +44,10 @@ public class CaseReviewControllerTests extends BaseTest {
private static final String projectId = "project-gyq-case-review-test";
private static final String ADD_CASE_REVIEW = "/case/review/add";
private static final String EDIT_CASE_REVIEW = "/case/review/edit";
private static final String FOLLOW_CASE_REVIEW = "/case/review/edit/follower";
private static final String CASE_REVIEWER_LIST = "/case/review/user-option/";
@Resource
private CaseReviewMapper caseReviewMapper;
@ -46,16 +58,16 @@ public class CaseReviewControllerTests extends BaseTest {
private CaseReviewUserMapper caseReviewUserMapper;
@Resource
private CaseReviewFunctionalCaseMapper caseReviewFunctionalCaseMapper;
@Resource
private NotificationMapper notificationMapper;
@Test
@Order(1)
@Sql(scripts = {"/dml/init_case_review.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
public void addCaseReviewSuccess() throws Exception {
CaseReviewAddRequest caseReviewAddRequest = getCaseReviewAddRequest("创建评审1", CaseReviewPassRule.SINGLE.toString(), "CASE_REVIEW_TEST_GYQ_ID", false, true);
this.requestPostWithOk(ADD_CASE_REVIEW,caseReviewAddRequest);
CaseReviewExample caseReviewExample = new CaseReviewExample();
caseReviewExample.createCriteria().andNameEqualTo("创建评审1");
List<CaseReview> caseReviews = caseReviewMapper.selectByExample(caseReviewExample);
CaseReviewRequest caseReviewRequest = getCaseReviewAddRequest("创建评审1", CaseReviewPassRule.SINGLE.toString(), "CASE_REVIEW_TEST_GYQ_ID", false, true, null);
this.requestPostWithOk(ADD_CASE_REVIEW, caseReviewRequest);
List<CaseReview> caseReviews = getCaseReviews("创建评审1");
Assertions.assertEquals(1, caseReviews.size());
String caseReviewId = caseReviews.get(0).getId();
CaseReviewUserExample caseReviewUserExample = new CaseReviewUserExample();
@ -66,41 +78,54 @@ public class CaseReviewControllerTests extends BaseTest {
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(caseReviewId);
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
Assertions.assertEquals(1, caseReviewFunctionalCases.size());
NotificationExample notificationExample = new NotificationExample();
notificationExample.createCriteria().andResourceTypeEqualTo(NoticeConstants.TaskType.CASE_REVIEW_TASK);
List<Notification> notifications = notificationMapper.selectByExampleWithBLOBs(notificationExample);
System.out.println(JSON.toJSONString(notifications));
Assertions.assertEquals(1, notifications.size());
}
private List<CaseReview> getCaseReviews(String name) {
CaseReviewExample caseReviewExample = new CaseReviewExample();
caseReviewExample.createCriteria().andNameEqualTo(name);
return caseReviewMapper.selectByExample(caseReviewExample);
}
@NotNull
private static CaseReviewAddRequest getCaseReviewAddRequest(String name, String reviewPassRule, String caseId, boolean tag, boolean reviewer) {
CaseReviewAddRequest caseReviewAddRequest = new CaseReviewAddRequest();
caseReviewAddRequest.setProjectId(projectId);
caseReviewAddRequest.setName(name);
caseReviewAddRequest.setModuleId("CASE_REVIEW_REAL_MODULE_ID");
caseReviewAddRequest.setReviewPassRule(reviewPassRule);
private static CaseReviewRequest getCaseReviewAddRequest(String name, String reviewPassRule, String caseId, boolean tag, boolean reviewer, String id) {
CaseReviewRequest caseReviewRequest = new CaseReviewRequest();
if (StringUtils.isNotBlank(id)) {
caseReviewRequest.setId(id);
}
caseReviewRequest.setProjectId(projectId);
caseReviewRequest.setName(name);
caseReviewRequest.setModuleId("CASE_REVIEW_REAL_MODULE_ID");
caseReviewRequest.setReviewPassRule(reviewPassRule);
List<String> reviewers = new ArrayList<>();
reviewers.add("admin");
if (reviewer) {
caseReviewAddRequest.setReviewers(reviewers);
caseReviewRequest.setReviewers(reviewers);
}
if (StringUtils.isNotBlank(caseId)) {
List<String> caseIds = new ArrayList<>();
caseIds.add(caseId);
caseReviewAddRequest.setCaseIds(caseIds);
caseReviewRequest.setCaseIds(caseIds);
}
if (tag) {
List<String> tags = new ArrayList<>();
tags.add("11");
caseReviewAddRequest.setTags(tags);
caseReviewRequest.setTags(tags);
}
return caseReviewAddRequest;
return caseReviewRequest;
}
@Test
@Order(2)
public void addCaseReviewWidthOutCaseIdsSuccess() throws Exception {
CaseReviewAddRequest caseReviewAddRequest = getCaseReviewAddRequest("创建评审2", CaseReviewPassRule.SINGLE.toString(), null, false, true);
this.requestPostWithOk(ADD_CASE_REVIEW,caseReviewAddRequest);
CaseReviewExample caseReviewExample = new CaseReviewExample();
caseReviewExample.createCriteria().andNameEqualTo("创建评审2");
List<CaseReview> caseReviews = caseReviewMapper.selectByExample(caseReviewExample);
CaseReviewRequest caseReviewRequest = getCaseReviewAddRequest("创建评审2", CaseReviewPassRule.SINGLE.toString(), null, false, true, null);
this.requestPostWithOk(ADD_CASE_REVIEW, caseReviewRequest);
List<CaseReview> caseReviews = getCaseReviews("创建评审2");
Assertions.assertEquals(1, caseReviews.size());
String caseReviewId = caseReviews.get(0).getId();
CaseReviewUserExample caseReviewUserExample = new CaseReviewUserExample();
@ -113,14 +138,13 @@ public class CaseReviewControllerTests extends BaseTest {
Assertions.assertEquals(0, caseReviewFunctionalCases.size());
}
@Test
@Order(3)
public void addCaseReviewWidthTagsSuccess() throws Exception {
CaseReviewAddRequest caseReviewAddRequest = getCaseReviewAddRequest("创建评审3", CaseReviewPassRule.SINGLE.toString(), null, true, true);
this.requestPostWithOk(ADD_CASE_REVIEW,caseReviewAddRequest);
CaseReviewExample caseReviewExample = new CaseReviewExample();
caseReviewExample.createCriteria().andNameEqualTo("创建评审3");
List<CaseReview> caseReviews = caseReviewMapper.selectByExample(caseReviewExample);
CaseReviewRequest caseReviewRequest = getCaseReviewAddRequest("创建评审3", CaseReviewPassRule.SINGLE.toString(), null, true, true, null);
this.requestPostWithOk(ADD_CASE_REVIEW, caseReviewRequest);
List<CaseReview> caseReviews = getCaseReviews("创建评审3");
Assertions.assertEquals(1, caseReviews.size());
String caseReviewId = caseReviews.get(0).getId();
Assertions.assertNotNull(caseReviews.get(0).getTags());
@ -137,18 +161,16 @@ public class CaseReviewControllerTests extends BaseTest {
@Test
@Order(4)
public void addCaseReviewFalse() throws Exception {
CaseReviewAddRequest caseReviewAddRequestNoReviewer= getCaseReviewAddRequest("创建评审4", CaseReviewPassRule.SINGLE.toString(), null, true, false);
this.requestPost(ADD_CASE_REVIEW, caseReviewAddRequestNoReviewer).andExpect(status().is4xxClientError());
CaseReviewAddRequest caseReviewAddRequestNoName = getCaseReviewAddRequest(null, CaseReviewPassRule.SINGLE.toString(), null, true, true);
this.requestPost(ADD_CASE_REVIEW, caseReviewAddRequestNoName).andExpect(status().is4xxClientError());
CaseReviewRequest caseReviewRequestNoReviewer = getCaseReviewAddRequest("创建评审4", CaseReviewPassRule.SINGLE.toString(), null, true, false, null);
this.requestPost(ADD_CASE_REVIEW, caseReviewRequestNoReviewer).andExpect(status().is4xxClientError());
CaseReviewRequest caseReviewRequestNoName = getCaseReviewAddRequest(null, CaseReviewPassRule.SINGLE.toString(), null, true, true, null);
this.requestPost(ADD_CASE_REVIEW, caseReviewRequestNoName).andExpect(status().is4xxClientError());
}
@Test
@Order(5)
public void followCaseReview() throws Exception {
CaseReviewExample caseReviewExample = new CaseReviewExample();
caseReviewExample.createCriteria().andNameEqualTo("创建评审1");
List<CaseReview> caseReviews = caseReviewMapper.selectByExample(caseReviewExample);
List<CaseReview> caseReviews = getCaseReviews("创建评审1");
CaseReview caseReview = caseReviews.get(0);
CaseReviewFollowerRequest caseReviewFollowerRequest = new CaseReviewFollowerRequest();
caseReviewFollowerRequest.setCaseReviewId(caseReview.getId());
@ -176,5 +198,49 @@ public class CaseReviewControllerTests extends BaseTest {
this.requestPost(FOLLOW_CASE_REVIEW, caseReviewFollowerRequest).andExpect(status().is5xxServerError());
}
@Test
@Order(7)
public void editCaseReviewSuccess() throws Exception {
List<CaseReview> caseReviews = getCaseReviews("创建评审1");
CaseReview caseReview = caseReviews.get(0);
CaseReviewRequest caseReviewRequest = getCaseReviewAddRequest("创建评审更新1", CaseReviewPassRule.SINGLE.toString(), null, true, true, caseReview.getId());
this.requestPostWithOk(EDIT_CASE_REVIEW, caseReviewRequest);
List<CaseReview> updateCaseReviews = getCaseReviews("创建评审更新1");
Assertions.assertEquals(1, updateCaseReviews.size());
List<CaseReview> caseReviews2 = getCaseReviews("创建评审2");
CaseReview caseReview2 = caseReviews2.get(0);
CaseReviewRequest caseReviewRequest2 = getCaseReviewAddRequest("创建评审更新2", CaseReviewPassRule.SINGLE.toString(), null, false, true, caseReview2.getId());
this.requestPostWithOk(EDIT_CASE_REVIEW, caseReviewRequest2);
List<CaseReview> updateCaseReviews2 = getCaseReviews("创建评审更新2");
Assertions.assertEquals(1, updateCaseReviews2.size());
NotificationExample notificationExample = new NotificationExample();
notificationExample.createCriteria().andResourceTypeEqualTo(NoticeConstants.TaskType.CASE_REVIEW_TASK).andReceiverEqualTo("gyq_review_test2");
List<Notification> notifications = notificationMapper.selectByExampleWithBLOBs(notificationExample);
System.out.println(JSON.toJSONString(notifications));
Assertions.assertTrue(notifications.size()>0);
}
@Test
@Order(8)
public void editCaseReviewFalse() throws Exception {
CaseReviewRequest caseReviewRequest = getCaseReviewAddRequest("创建评审更新1", CaseReviewPassRule.SINGLE.toString(), null, true, true, null);
this.requestPost(EDIT_CASE_REVIEW, caseReviewRequest).andExpect(status().is4xxClientError());
caseReviewRequest = getCaseReviewAddRequest("创建评审更新1", CaseReviewPassRule.SINGLE.toString(), null, true, true, "XXX");
this.requestPost(EDIT_CASE_REVIEW, caseReviewRequest).andExpect(status().is5xxServerError());
}
@Test
@Order(9)
public void getUserList() throws Exception {
MvcResult mvcResult = this.requestGetWithOkAndReturn(CASE_REVIEWER_LIST + projectId);
String contentAsString = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder resultHolder = JSON.parseObject(contentAsString, ResultHolder.class);
List<User> list = JSON.parseArray(JSON.toJSONString(resultHolder.getData()), User.class);
Assertions.assertFalse(list.isEmpty());
}
}

View File

@ -29,3 +29,56 @@ INSERT INTO functional_case_module(id, project_id, name, parent_id, pos, create_
INSERT INTO case_review_module(id, project_id, name, parent_id, pos, create_time, update_time, create_user, update_user) VALUES ('CASE_REVIEW_REAL_MODULE_ID', 'project-gyq-case-review-test', '用例评审所属模块', 'NONE', 0, 1669174143999, 1669174143999, 'admin', 'admin');
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 ('gyq_review_test', 'gyq_review_test', 'PROJECT@fit2cloud.com', MD5('metersphere'),UNIX_TIMESTAMP() * 1000,UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin', false),
('gyq_review_test2', 'default-Administrator-1', 'admin-default-user@metersphere.io', MD5('metersphere'), UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin', false);
INSERT INTO user_role(id, name, description, internal, type, create_time, update_time, create_user, scope_id) VALUE
('review-case-role-id-1', 'review-case-role-1', 'XXX', FALSE, 'PROJECT', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'project-gyq-case-review-test');
INSERT INTO user_role(id, name, description, internal, type, create_time, update_time, create_user, scope_id) VALUE
('review-case-role-id-2', 'review-case-role-2', 'XXX', FALSE, 'PROJECT', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'project-gyq-case-review-test');
INSERT INTO user_role(id, name, description, internal, type, create_time, update_time, create_user, scope_id) VALUE
('review-case-role-id-3', 'review-case-role-3', 'XXX', FALSE, 'PROJECT', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'project-gyq-case-review-test');
INSERT INTO user_role(id, name, description, internal, type, create_time, update_time, create_user, scope_id) VALUE
('review-case-role-id-4', 'review-case-role-4', 'XXX', FALSE, 'PROJECT', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'project-gyq-case-review-test');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUE
(uuid(), 'review-case-role-id-3', 'CASE_REVIEW:READ+REVIEW');
INSERT INTO user_role_relation (id, user_id, role_id, source_id, organization_id, create_time, create_user) VALUE
(UUID(), 'gyq_review_test', 'review-case-role-id-3', 'project-gyq-case-review-test', 'organization-gyq-case-review-test', UNIX_TIMESTAMP() * 1000, 'admin');
INSERT INTO user_role_relation (id, user_id, role_id, source_id, organization_id, create_time, create_user) VALUE
(UUID(), 'gyq_review_test2', 'review-case-role-id-3', 'project-gyq-case-review-test', 'organization-gyq-case-review-test', UNIX_TIMESTAMP() * 1000, 'admin');
INSERT INTO project_robot(id, project_id, name, platform, webhook, type, app_key, app_secret, enable, create_user, create_time, update_user, update_time, description) VALUES ('test_case_review_message_robot1', 'project-gyq-case-review-test', '测试机器人1', 'IN_SITE', 'NONE', null, null, null, true, 'admin', unix_timestamp() * 1000,'admin', unix_timestamp() * 1000, null);
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user, create_time, update_user, update_time, use_default_template, use_default_subject, subject)
VALUES ('case-review_message0', 'CREATE', 'gyq_review_test', 'test_case_review_message_robot1', 'CASE_REVIEW_TASK', 'NONE', 'project-gyq-case-review-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true, true, 'message.title.case_review_task_create');
INSERT INTO message_task_blob(id, template) VALUES ('case-review_message0', 'message.case_review_task_create');
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user, create_time, update_user, update_time, use_default_template, use_default_subject, subject)
VALUES ('case-review_message1', 'UPDATE', 'CREATE_USER', 'test_case_review_message_robot1', 'CASE_REVIEW_TASK', 'NONE', 'project-gyq-case-review-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true, true, 'message.title.case_review_task_update');
INSERT INTO message_task_blob(id, template) VALUES ('case-review_message1', 'message.case_review_task_update');
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user, create_time, update_user, update_time, use_default_template, use_default_subject, subject)
VALUES ('case-review_message2', 'UPDATE', 'FOLLOW_PEOPLE', 'test_case_review_message_robot1', 'CASE_REVIEW_TASK', 'NONE', 'project-gyq-case-review-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true, true, 'message.title.case_review_task_update');
INSERT INTO message_task_blob(id, template) VALUES ('case-review_message2', 'message.case_review_task_update');
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user, create_time, update_user, update_time, use_default_template, use_default_subject, subject)
VALUES ('case-review_message5', 'UPDATE', 'gyq_review_test2', 'test_case_review_message_robot1', 'CASE_REVIEW_TASK', 'NONE', 'project-gyq-case-review-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true, true, 'message.title.case_review_task_update');
INSERT INTO message_task_blob(id, template) VALUES ('case-review_message5', 'message.case_review_task_update');
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user, create_time, update_user, update_time, use_default_template, use_default_subject, subject)
VALUES ('case-review_message3', 'DELETE', 'CREATE_USER', 'test_case_review_message_robot1', 'CASE_REVIEW_TASK', 'NONE', 'project-gyq-case-review-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true, true, 'message.title.case_review_task_delete');
INSERT INTO message_task_blob(id, template) VALUES ('case-review_message3', 'message.case_review_task_delete');
Insert into message_task(id, event, receiver, project_robot_id, task_type, test_id, project_id, enable, create_user, create_time, update_user, update_time, use_default_template, use_default_subject, subject)
VALUES ('case-review_message4', 'REVIEW_COMPLETED', 'CREATE_USER', 'test_case_review_message_robot1', 'CASE_REVIEW_TASK', 'NONE', 'project-gyq-case-review-test', true, 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true, true, 'message.title.case_review_task_review_completed');
INSERT INTO message_task_blob(id, template) VALUES ('case-review_message4', 'message.case_review_task_review_completed');

View File

@ -22,4 +22,13 @@ public interface ExtUserMapper {
* @return 用户列表
*/
List<User> getRoleUserByParam(@Param("ids") List<String> ids, @Param("keyword") String keyword);
/**
* 获取某个项目下的固定权限的用户列表
* @param projectId 项目ID
* @param keyword 关键字
* @param permission 权限
* @return 用户列表
*/
List<User>getUserByPermission(@Param("projectId") String projectId, @Param("keyword") String keyword, @Param("permission") String permission);
}

View File

@ -56,4 +56,19 @@
</if>
limit 100
</select>
<select id="getUserByPermission" resultType="io.metersphere.system.domain.User">
SELECT u.id, u.name, u.email
FROM user u
LEFT JOIN user_role_relation urr ON u.id = urr.user_id
WHERE urr.role_id IN (SELECT urp.role_id FROM user_role_permission urp WHERE urp.permission_id = #{permission})
AND urr.source_id = #{projectId}
<if test="keyword != null and keyword != ''">
AND (name LIKE concat('%', #{keyword}, '%') OR email LIKE concat('%', #{keyword}, '%'))
</if>
GROUP BY urr.user_id
limit 100
</select>
</mapper>