feat(用例评审): 新增单独取消关联功能用例获取评审模块数量接口
This commit is contained in:
parent
a236a424bb
commit
18fce82f90
|
@ -29,6 +29,7 @@ import org.springframework.validation.annotation.Validated;
|
|||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Tag(name = "用例管理-用例评审")
|
||||
@RestController
|
||||
|
@ -39,14 +40,21 @@ public class CaseReviewController {
|
|||
private CaseReviewService caseReviewService;
|
||||
|
||||
@PostMapping("/page")
|
||||
@Operation(summary = "用例管理-功能用例-用例列表查询")
|
||||
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ)
|
||||
@Operation(summary = "用例管理-用例评审-用例列表查询")
|
||||
@RequiresPermissions(PermissionConstants.CASE_REVIEW_READ)
|
||||
public Pager<List<CaseReviewDTO>> getFunctionalCasePage(@Validated @RequestBody CaseReviewPageRequest request) {
|
||||
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
|
||||
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "pos desc");
|
||||
return PageUtils.setPageInfo(page, caseReviewService.getCaseReviewPage(request));
|
||||
}
|
||||
|
||||
@PostMapping("/module/count")
|
||||
@Operation(summary = "用例管理-用例评审-表格分页查询文件")
|
||||
@RequiresPermissions(PermissionConstants.CASE_REVIEW_READ)
|
||||
public Map<String, Long> moduleCount(@Validated @RequestBody CaseReviewPageRequest request) {
|
||||
return caseReviewService.moduleCount(request);
|
||||
}
|
||||
|
||||
@PostMapping("/add")
|
||||
@Operation(summary = "用例管理-用例评审-创建用例评审")
|
||||
@Log(type = OperationLogType.ADD, expression = "#msClass.addCaseReviewLog(#request)", msClass = CaseReviewLogService.class)
|
||||
|
@ -97,6 +105,14 @@ public class CaseReviewController {
|
|||
caseReviewService.associateCase(request, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
@GetMapping("disassociate/{reviewId}/{caseId}")
|
||||
@Operation(summary = "用例管理-用例评审-取消关联用例")
|
||||
@Log(type = OperationLogType.DISASSOCIATE, expression = "#msClass.disAssociateCaseLog(#reviewId, #caseId)", msClass = CaseReviewLogService.class)
|
||||
@RequiresPermissions(PermissionConstants.CASE_REVIEW_RELEVANCE)
|
||||
public void disassociate(@PathVariable String reviewId, @PathVariable String caseId) {
|
||||
caseReviewService.disassociate(reviewId, caseId);
|
||||
}
|
||||
|
||||
@PostMapping("/edit/pos")
|
||||
@Operation(summary = "用例管理-用例评审-拖拽排序")
|
||||
@RequiresPermissions(PermissionConstants.CASE_REVIEW_READ_UPDATE)
|
||||
|
|
|
@ -4,6 +4,7 @@ import io.metersphere.functional.domain.CaseReview;
|
|||
import io.metersphere.functional.dto.CaseReviewDTO;
|
||||
import io.metersphere.functional.request.CaseReviewBatchRequest;
|
||||
import io.metersphere.functional.request.CaseReviewPageRequest;
|
||||
import io.metersphere.project.dto.ModuleCountDTO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -26,4 +27,10 @@ public interface ExtCaseReviewMapper {
|
|||
List<String> getIds(@Param("request") CaseReviewBatchRequest request, @Param("projectId") String projectId);
|
||||
|
||||
void batchMoveModule(@Param("request") CaseReviewBatchRequest request, @Param("ids") List<String> ids, @Param("userId") String userId);
|
||||
|
||||
List<ModuleCountDTO> countModuleIdByKeywordAndFileType(@Param("request") CaseReviewPageRequest request);
|
||||
|
||||
long caseCount(@Param("request") CaseReviewPageRequest request);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -116,6 +116,21 @@
|
|||
<property name="searchMode" value="request.searchMode"/>
|
||||
</include>
|
||||
</if>
|
||||
<if test="request.createByMe != null">
|
||||
case_review.create_user = #{request.createByMe}
|
||||
<include refid="queryType">
|
||||
<property name="searchMode" value="request.searchMode"/>
|
||||
</include>
|
||||
</if>
|
||||
<if test="request.reviewByMe != null">
|
||||
case_review.id in
|
||||
(
|
||||
select case_review_user.review_id from case_review_user where case_review_user.user_id = #{request.reviewByMe}
|
||||
)
|
||||
<include refid="queryType">
|
||||
<property name="searchMode" value="request.searchMode"/>
|
||||
</include>
|
||||
</if>
|
||||
<include refid="filters">
|
||||
<property name="filter" value="request.filter"/>
|
||||
</include>
|
||||
|
@ -373,4 +388,40 @@
|
|||
</foreach>
|
||||
</update>
|
||||
|
||||
<select id="countModuleIdByKeywordAndFileType" resultType="io.metersphere.project.dto.ModuleCountDTO">
|
||||
SELECT module_id AS moduleId, count(id) AS dataCount
|
||||
FROM case_review
|
||||
WHERE project_id = #{request.projectId}
|
||||
<choose>
|
||||
<when test='request.searchMode == "AND"'>
|
||||
AND <include refid="queryWhereCondition"/>
|
||||
</when>
|
||||
<when test='request.searchMode == "OR"'>
|
||||
AND (
|
||||
<include refid="queryWhereCondition"/>
|
||||
)
|
||||
</when>
|
||||
</choose>
|
||||
1 = 1
|
||||
GROUP BY moduleId
|
||||
</select>
|
||||
|
||||
<select id="caseCount"
|
||||
resultType="java.lang.Long">
|
||||
SELECT count(id)
|
||||
FROM case_review
|
||||
WHERE project_id = #{request.projectId}
|
||||
<choose>
|
||||
<when test='request.searchMode == "AND"'>
|
||||
AND <include refid="queryWhereCondition"/>
|
||||
</when>
|
||||
<when test='request.searchMode == "OR"'>
|
||||
and (
|
||||
<include refid="queryWhereCondition"/>
|
||||
)
|
||||
</when>
|
||||
</choose>
|
||||
1 = 1
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -22,4 +22,12 @@ public class CaseReviewPageRequest extends BasePageRequest implements Serializab
|
|||
@Schema(description = "模块id")
|
||||
private List<String> moduleIds;
|
||||
|
||||
@Schema(description = "我评审的")
|
||||
private String reviewByMe;
|
||||
|
||||
@Schema(description = "我创建的")
|
||||
private String createByMe;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -164,11 +164,36 @@ public class CaseReviewLogService {
|
|||
dto.setPath("/case/review/associate");
|
||||
dto.setMethod(HttpMethodConstants.POST.name());
|
||||
dto.setOriginalValue(JSON.toJSONBytes(functionalCase));
|
||||
dtoList.add(dto);
|
||||
}
|
||||
|
||||
return dtoList;
|
||||
}
|
||||
|
||||
public LogDTO disAssociateCaseLog(String reviewId, String caseId) {
|
||||
CaseReview caseReview = caseReviewMapper.selectByPrimaryKey(reviewId);
|
||||
if (caseReview == null) {
|
||||
return null;
|
||||
}
|
||||
FunctionalCase functionalCase = functionalCaseMapper.selectByPrimaryKey(caseId);
|
||||
if (functionalCase == null) {
|
||||
return null;
|
||||
}
|
||||
LogDTO dto = new LogDTO(
|
||||
caseReview.getProjectId(),
|
||||
null,
|
||||
caseReview.getId(),
|
||||
null,
|
||||
OperationLogType.DISASSOCIATE.name(),
|
||||
OperationLogModule.CASE_REVIEW,
|
||||
functionalCase.getName());
|
||||
|
||||
dto.setPath("/case/review/disassociate");
|
||||
dto.setMethod(HttpMethodConstants.GET.name());
|
||||
dto.setOriginalValue(JSON.toJSONBytes(functionalCase));
|
||||
return dto;
|
||||
}
|
||||
|
||||
|
||||
public List<LogDTO> batchDisassociateCaseLog(BaseReviewCaseBatchRequest request) {
|
||||
List<String> ids = caseReviewFunctionalCaseService.doSelectIds(request);
|
||||
|
|
|
@ -12,6 +12,7 @@ import io.metersphere.functional.request.CaseReviewBatchRequest;
|
|||
import io.metersphere.functional.request.CaseReviewPageRequest;
|
||||
import io.metersphere.functional.request.CaseReviewRequest;
|
||||
import io.metersphere.functional.result.CaseManagementResultCode;
|
||||
import io.metersphere.project.dto.ModuleCountDTO;
|
||||
import io.metersphere.sdk.constants.ApplicationNumScope;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
|
@ -71,8 +72,14 @@ public class CaseReviewService {
|
|||
private FunctionalCaseMapper functionalCaseMapper;
|
||||
@Resource
|
||||
private DeleteCaseReviewService deleteCaseReviewService;
|
||||
@Resource
|
||||
private CaseReviewFunctionalCaseUserMapper caseReviewFunctionalCaseUserMapper;
|
||||
@Resource
|
||||
private CaseReviewModuleService caseReviewModuleService;
|
||||
|
||||
|
||||
private static final String CASE_MODULE_COUNT_ALL = "all";
|
||||
|
||||
/**
|
||||
* 获取用例评审列表
|
||||
*
|
||||
|
@ -523,4 +530,45 @@ public class CaseReviewService {
|
|||
deleteCaseReviewService.deleteCaseReviewResource(List.of(reviewId), projectId, false);
|
||||
|
||||
}
|
||||
|
||||
public void disassociate(String reviewId, String caseId) {
|
||||
//1.刪除评审与功能用例关联关系
|
||||
CaseReviewFunctionalCaseExample caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
||||
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(reviewId).andCaseIdEqualTo(caseId);
|
||||
caseReviewFunctionalCaseMapper.deleteByExample(caseReviewFunctionalCaseExample);
|
||||
//2.删除用例和用例评审人的关系
|
||||
CaseReviewFunctionalCaseUserExample caseReviewFunctionalCaseUserExample = new CaseReviewFunctionalCaseUserExample();
|
||||
caseReviewFunctionalCaseUserExample.createCriteria().andCaseIdEqualTo(caseId).andReviewIdEqualTo(reviewId);
|
||||
caseReviewFunctionalCaseUserMapper.deleteByExample(caseReviewFunctionalCaseUserExample);
|
||||
|
||||
caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
||||
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(reviewId);
|
||||
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
|
||||
List<CaseReviewFunctionalCase> passList = caseReviewFunctionalCases.stream().filter(t -> StringUtils.equalsIgnoreCase(t.getStatus(), FunctionalCaseReviewStatus.PASS.toString())).toList();
|
||||
CaseReview caseReview = new CaseReview();
|
||||
caseReview.setId(reviewId);
|
||||
//更新用例数量
|
||||
caseReview.setCaseCount(caseReviewFunctionalCases.size());
|
||||
//通过率
|
||||
BigDecimal passCount = BigDecimal.valueOf(passList.size());
|
||||
BigDecimal totalCount = BigDecimal.valueOf(caseReview.getCaseCount());
|
||||
BigDecimal passRate;
|
||||
if (totalCount.compareTo(BigDecimal.ZERO)==0) {
|
||||
passRate = BigDecimal.ZERO;
|
||||
} else {
|
||||
passRate = passCount.divide(totalCount, 2, RoundingMode.HALF_UP);
|
||||
}
|
||||
caseReview.setPassRate(passRate);
|
||||
caseReviewMapper.updateByPrimaryKeySelective(caseReview);
|
||||
}
|
||||
|
||||
public Map<String, Long> moduleCount(CaseReviewPageRequest request) {
|
||||
//查出每个模块节点下的资源数量。 不需要按照模块进行筛选
|
||||
List<ModuleCountDTO> moduleCountDTOList = extCaseReviewMapper.countModuleIdByKeywordAndFileType(request);
|
||||
Map<String, Long> moduleCountMap = caseReviewModuleService.getModuleCountMap(request.getProjectId(), moduleCountDTOList);
|
||||
//查出全部用例数量
|
||||
long allCount = extCaseReviewMapper.caseCount(request);
|
||||
moduleCountMap.put(CASE_MODULE_COUNT_ALL, allCount);
|
||||
return moduleCountMap;
|
||||
}
|
||||
}
|
|
@ -32,6 +32,7 @@ import org.springframework.test.web.servlet.MvcResult;
|
|||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.testcontainers.shaded.org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -54,7 +55,9 @@ public class CaseReviewControllerTests extends BaseTest {
|
|||
private static final String BATCH_MOVE_CASE_REVIEW = "/case/review/batch/move";
|
||||
private static final String EDIT_CASE_REVIEW = "/case/review/edit";
|
||||
private static final String PAGE_CASE_REVIEW = "/case/review/page";
|
||||
private static final String MODULE_COUNT_CASE_REVIEW = "/case/review/module/count";
|
||||
private static final String ASSOCIATE_CASE_REVIEW = "/case/review/associate";
|
||||
private static final String DISASSOCIATE_CASE_REVIEW = "/case/review/disassociate/";
|
||||
private static final String EDIT_POS_CASE_REVIEW_URL = "/case/review/edit/pos";
|
||||
private static final String FOLLOW_CASE_REVIEW = "/case/review/edit/follower";
|
||||
private static final String CASE_REVIEWER_LIST = "/case/review/user-option/";
|
||||
|
@ -339,9 +342,19 @@ public class CaseReviewControllerTests extends BaseTest {
|
|||
request.setCombine(caseReviewCombine);
|
||||
request.setProjectId(projectId);
|
||||
request.setKeyword("评审更新");
|
||||
request.setReviewByMe("admin");
|
||||
request.setCurrent(1);
|
||||
request.setPageSize(10);
|
||||
MvcResult mvcResult = this.requestPostWithOkAndReturn(PAGE_CASE_REVIEW, request);
|
||||
Pager<List<CaseReviewDTO>> tableData = JSON.parseObject(JSON.toJSONString(
|
||||
JSON.parseObject(mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class).getData()),
|
||||
Pager.class);
|
||||
|
||||
MvcResult moduleCountMvcResult = this.requestPostWithOkAndReturn(MODULE_COUNT_CASE_REVIEW, request);
|
||||
Map<String, Integer> moduleCount = JSON.parseObject(JSON.toJSONString(
|
||||
JSON.parseObject(moduleCountMvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class).getData()),
|
||||
Map.class);
|
||||
|
||||
// 获取返回值
|
||||
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
||||
|
@ -355,6 +368,21 @@ public class CaseReviewControllerTests extends BaseTest {
|
|||
// 返回的数据量不超过规定要返回的数据量相同
|
||||
Assertions.assertTrue(JSON.parseArray(JSON.toJSONString(pageData.getList())).size() <= request.getPageSize());
|
||||
|
||||
//如果没有数据,则返回的模块节点也不应该有数据
|
||||
boolean moduleHaveResource = false;
|
||||
for (int countByModuleId : moduleCount.values()) {
|
||||
if (countByModuleId > 0) {
|
||||
moduleHaveResource = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Assertions.assertEquals(request.getPageSize(), tableData.getPageSize());
|
||||
if (tableData.getTotal() > 0) {
|
||||
Assertions.assertTrue(moduleHaveResource);
|
||||
}
|
||||
|
||||
Assertions.assertTrue(moduleCount.containsKey("all"));
|
||||
|
||||
CaseReviewFunctionalCaseExample caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
||||
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(caseReviews.get(0).getId());
|
||||
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
|
||||
|
@ -507,6 +535,75 @@ public class CaseReviewControllerTests extends BaseTest {
|
|||
Assertions.assertEquals(1, notifications.size());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Order(17)
|
||||
public void testDisassociate() throws Exception {
|
||||
List<CaseReview> caseReviews = getCaseReviews("创建评审更新1");
|
||||
Assertions.assertEquals(1, caseReviews.size());
|
||||
String caseReviewId = caseReviews.get(0).getId();
|
||||
CaseReviewFunctionalCaseExample caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
||||
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(caseReviewId).andCaseIdEqualTo("CASE_REVIEW_TEST_GYQ_ID6");
|
||||
List<CaseReviewFunctionalCase> caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
|
||||
Assertions.assertEquals(1, caseReviewFunctionalCases.size());
|
||||
mockMvc.perform(MockMvcRequestBuilders.get(DISASSOCIATE_CASE_REVIEW+caseReviewId+"/CASE_REVIEW_TEST_GYQ_ID6").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();
|
||||
caseReviewFunctionalCaseExample = new CaseReviewFunctionalCaseExample();
|
||||
caseReviewFunctionalCaseExample.createCriteria().andReviewIdEqualTo(caseReviewId).andCaseIdEqualTo("CASE_REVIEW_TEST_GYQ_ID6");
|
||||
caseReviewFunctionalCases = caseReviewFunctionalCaseMapper.selectByExample(caseReviewFunctionalCaseExample);
|
||||
Assertions.assertEquals(0, caseReviewFunctionalCases.size());
|
||||
|
||||
caseReviews = getCaseReviews("创建评审3");
|
||||
Assertions.assertEquals(1, caseReviews.size());
|
||||
caseReviewId = caseReviews.get(0).getId();
|
||||
CaseReviewAssociateRequest caseReviewAssociateRequest = new CaseReviewAssociateRequest();
|
||||
caseReviewAssociateRequest.setProjectId(projectId);
|
||||
caseReviewAssociateRequest.setReviewId(caseReviewId);
|
||||
List<String> caseIds = new ArrayList<>();
|
||||
caseIds.add("CASE_REVIEW_TEST_GYQ_ID2");
|
||||
caseReviewAssociateRequest.setCaseIds(caseIds);
|
||||
List<String> userIds = new ArrayList<>();
|
||||
userIds.add("gyq_review_test");
|
||||
userIds.add("gyq_review_test2");
|
||||
caseReviewAssociateRequest.setReviewers(userIds);
|
||||
this.requestPostWithOk(ASSOCIATE_CASE_REVIEW, caseReviewAssociateRequest);
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get(DISASSOCIATE_CASE_REVIEW+caseReviewId+"/CASE_REVIEW_TEST_GYQ_ID2").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();
|
||||
CaseReview caseReview = caseReviewMapper.selectByPrimaryKey(caseReviewId);
|
||||
Assertions.assertEquals(0, caseReview.getPassRate().compareTo(BigDecimal.ZERO));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(18)
|
||||
public void testDisassociateFalse() throws Exception {
|
||||
List<CaseReview> caseReviews = getCaseReviews("创建评审更新1");
|
||||
mockMvc.perform(MockMvcRequestBuilders.get(DISASSOCIATE_CASE_REVIEW+"caseReviewIdX"+"/CASE_REVIEW_TEST_GYQ_ID6").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();
|
||||
|
||||
String caseReviewId = caseReviews.get(0).getId();
|
||||
mockMvc.perform(MockMvcRequestBuilders.get(DISASSOCIATE_CASE_REVIEW+caseReviewId+"/CASE_REVIEW_TEST_GYQ_IDXX").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();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成高级搜索参数
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue