feat(功能用例): 关联用例评审表

This commit is contained in:
guoyuqi 2023-12-04 19:36:57 +08:00 committed by 刘瑞斌
parent 106800e6cd
commit 25a957cabe
15 changed files with 221 additions and 72 deletions

View File

@ -1,12 +1,16 @@
package io.metersphere.functional.domain;
import io.metersphere.validation.groups.*;
import io.metersphere.validation.groups.Created;
import io.metersphere.validation.groups.Updated;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import lombok.Data;
@Data
public class CaseReviewFunctionalCase implements Serializable {
@ -25,7 +29,7 @@ public class CaseReviewFunctionalCase implements Serializable {
@Size(min = 1, max = 50, message = "{case_review_functional_case.case_id.length_range}", groups = {Created.class, Updated.class})
private String caseId;
@Schema(description = "评审状态:进行中/通过/不通过/重新提审", requiredMode = Schema.RequiredMode.REQUIRED)
@Schema(description = "评审结果:进行中/通过/不通过/重新提审", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{case_review_functional_case.status.not_blank}", groups = {Created.class})
@Size(min = 1, max = 64, message = "{case_review_functional_case.status.length_range}", groups = {Created.class, Updated.class})
private String status;

View File

@ -9,7 +9,7 @@ CREATE TABLE IF NOT EXISTS functional_case
`project_id` VARCHAR(50) NOT NULL COMMENT '项目ID',
`template_id` VARCHAR(50) NOT NULL COMMENT '模板ID',
`name` VARCHAR(255) NOT NULL COMMENT '名称',
`review_status` VARCHAR(64) NOT NULL DEFAULT 'UN_REVIEWED' COMMENT '评审状态:未评审/评审中/通过/不通过/重新提审',
`review_status` VARCHAR(64) NOT NULL DEFAULT 'UN_REVIEWED' COMMENT '评审结果:未评审/评审中/通过/不通过/重新提审',
`tags` VARCHAR(1000) COMMENT '标签JSON)',
`case_edit_type` VARCHAR(50) NOT NULL DEFAULT 'STEP' COMMENT '编辑模式:步骤模式/文本模式',
`pos` BIGINT NOT NULL DEFAULT 0 COMMENT '自定义排序间隔5000',

View File

@ -1,26 +1,6 @@
package io.metersphere.functional.constants;
import io.metersphere.sdk.util.Translator;
public enum CaseReviewPassRule {
SINGLE("case_review.single"),
MULTIPLE("case_review.multiple");
private final String name;
CaseReviewPassRule(String name) {
this.name = name;
}
public String getName() {
return getTranslationName(this.name);
}
/**
* 返回国际化后的规则信息
* 如果没有匹配则返回原文
*/
String getTranslationName(String name) {
return Translator.get(name, name);
}
SINGLE,
MULTIPLE
}

View File

@ -1,30 +1,9 @@
package io.metersphere.functional.constants;
import io.metersphere.sdk.util.Translator;
public enum CaseReviewStatus {
PREPARED("case_review.prepared"),
UNDERWAY("case_review.underway"),
COMPLETED("case_review.completed"),
ARCHIVED("case_review.archived");
private final String name;
CaseReviewStatus(String name) {
this.name = name;
}
public String getName() {
return getTranslationName(this.name);
}
/**
* 返回国际化后的状态信息
* 如果没有匹配则返回原文
*/
String getTranslationName(String name) {
return Translator.get(name, name);
}
PREPARED,
UNDERWAY,
COMPLETED,
ARCHIVED
}

View File

@ -0,0 +1,39 @@
package io.metersphere.functional.controller;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.functional.dto.FunctionalCaseReviewDTO;
import io.metersphere.functional.request.FunctionalCaseReviewListRequest;
import io.metersphere.functional.service.FunctionalCaseReviewService;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.system.utils.PageUtils;
import io.metersphere.system.utils.Pager;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Tag(name = "用例管理-功能用例-用例评审")
@RestController
@RequestMapping("/functional/case/review")
public class FunctionalCaseReviewController {
@Resource
private FunctionalCaseReviewService functionalCaseReviewService;
@PostMapping("/page")
@Operation(summary = "用例管理-功能用例-用例评审-列表")
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ)
public Pager<List<FunctionalCaseReviewDTO>> getFunctionalCasePage(@Validated @RequestBody FunctionalCaseReviewListRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(), "update_time desc");
return PageUtils.setPageInfo(page, functionalCaseReviewService.getFunctionalCaseReviewPage(request));
}
}

View File

@ -27,9 +27,6 @@ public class CaseReviewDTO extends CaseReview {
@Schema(description = "已评审过得用例数")
private int reviewedCount;
@Schema(description = "评审状态名称")
private String statusName;
@Schema(description = "关注标识")
private Boolean followFlag;
}

View File

@ -0,0 +1,23 @@
package io.metersphere.functional.dto;
import io.metersphere.functional.domain.CaseReviewFunctionalCase;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class FunctionalCaseReviewDTO extends CaseReviewFunctionalCase {
@Schema(description = "评审Id", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{case_review_functional_case.review_name.not_blank}")
private String reviewNum;
@Schema(description = "评审名称", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{case_review_functional_case.review_name.not_blank}")
private String reviewName;
@Schema(description = "用例评审状态", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{case_review_functional_case.review_status.not_blank}")
private String reviewStatus;
}

View File

@ -0,0 +1,16 @@
package io.metersphere.functional.mapper;
import io.metersphere.functional.dto.FunctionalCaseReviewDTO;
import io.metersphere.functional.request.FunctionalCaseReviewListRequest;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author guoyuqi
*/
public interface ExtCaseReviewFunctionalCaseMapper {
List<FunctionalCaseReviewDTO> list(@Param("request") FunctionalCaseReviewListRequest request);
}

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.metersphere.functional.mapper.ExtCaseReviewFunctionalCaseMapper">
<select id="list" resultType="io.metersphere.functional.dto.FunctionalCaseReviewDTO">
SELECT
cr.num as reviewNum, cr.name as reviewName, cr.status as reviewStatus, cf.status, cf.update_time
FROM
case_review_functional_case cf left join case_review cr on cf.review_id = cr.id
where cf.case_id = #{request.caseId}
<if test="request.keyword != null and request.keyword != ''">
and (
cr.num like concat('%', #{request.keyword},'%')
or cr.name like concat('%', #{request.keyword},'%')
)
</if>
</select>
</mapper>

View File

@ -0,0 +1,14 @@
package io.metersphere.functional.request;
import io.metersphere.system.dto.sdk.BasePageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class FunctionalCaseReviewListRequest extends BasePageRequest {
@Schema(description = "功能用例id")
private String caseId;
}

View File

@ -113,8 +113,6 @@ public class CaseReviewService {
}
buildReviewers(caseReviewDTO, reviewUserMap);
caseReviewDTO.setStatusName(CaseReviewStatus.valueOf(caseReviewDTO.getStatus()).getName());
}
private static void buildReviewers(CaseReviewDTO caseReviewDTO, Map<String, List<CaseReviewUserDTO>> reviewUserMap) {

View File

@ -0,0 +1,29 @@
package io.metersphere.functional.service;
import io.metersphere.functional.dto.FunctionalCaseReviewDTO;
import io.metersphere.functional.mapper.ExtCaseReviewFunctionalCaseMapper;
import io.metersphere.functional.request.FunctionalCaseReviewListRequest;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 功能用例和其他用例的中间表服务实现类
*
* @date : 2023-5-17
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class FunctionalCaseReviewService {
@Resource
private ExtCaseReviewFunctionalCaseMapper extCaseReviewFunctionalCaseMapper;
public List<FunctionalCaseReviewDTO> getFunctionalCaseReviewPage(FunctionalCaseReviewListRequest request) {
return extCaseReviewFunctionalCaseMapper.list(request);
}
}

View File

@ -1,15 +0,0 @@
package io.metersphere.functional.service;
import org.springframework.stereotype.Service;
/**
* 功能用例和其他用例的中间表服务实现类
*
* @date : 2023-5-17
*/
@Service
public class FunctionalCaseTestService {
}

View File

@ -0,0 +1,49 @@
package io.metersphere.functional.controller;
import io.metersphere.functional.dto.FunctionalCaseReviewDTO;
import io.metersphere.functional.request.FunctionalCaseReviewListRequest;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.base.BaseTest;
import io.metersphere.system.controller.handler.ResultHolder;
import io.metersphere.system.utils.Pager;
import org.junit.jupiter.api.*;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.SqlConfig;
import org.springframework.test.web.servlet.MvcResult;
import java.nio.charset.StandardCharsets;
import java.util.List;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@AutoConfigureMockMvc
public class FunctionalCaseReviewControllerTests extends BaseTest {
private static final String URL_CASE_REVIEW_PAGE = "/functional/case/review/page";
@Test
@Order(1)
@Sql(scripts = {"/dml/init_case_review_functional_case.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
public void testGetPageList() throws Exception {
FunctionalCaseReviewListRequest functionalCaseReviewListRequest = new FunctionalCaseReviewListRequest();
functionalCaseReviewListRequest.setCaseId("associate_case_gyq_id");
functionalCaseReviewListRequest.setCurrent(1);
functionalCaseReviewListRequest.setPageSize(10);
MvcResult mvcResult = this.requestPostWithOkAndReturn(URL_CASE_REVIEW_PAGE, functionalCaseReviewListRequest);
Pager<List<FunctionalCaseReviewDTO>> tableData = JSON.parseObject(JSON.toJSONString(
JSON.parseObject(mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class).getData()),
Pager.class);
//返回值的页码和当前页码相同
Assertions.assertEquals(tableData.getCurrent(), functionalCaseReviewListRequest.getCurrent());
//返回的数据量不超过规定要返回的数据量相同
Assertions.assertTrue(JSON.parseArray(JSON.toJSONString(tableData.getList())).size() <= functionalCaseReviewListRequest.getPageSize());
List<FunctionalCaseReviewDTO> fileList = JSON.parseArray(JSON.toJSONString(tableData.getList()), FunctionalCaseReviewDTO.class);
String jsonString = JSON.toJSONString(fileList);
System.out.println(jsonString);
}
}

View File

@ -0,0 +1,17 @@
INSERT INTO case_review(id, num, name, module_id, project_id, status, review_pass_rule, pos, start_time, end_time, case_count, pass_rate, tags, description, create_time, create_user, update_time, update_user)
VALUES ('case_review_associate_Id',10001,'用例关系名称1', 'test_module_one', 'case_review_relevence_project_gyq', 'COMPLETED', 'SINGLE', 001, null, null, 1,100.00,null,null,1698058347559,'admin',1698058347559,'admin'),
('case_review_associate_Id2',10002,'用例关系名称2', 'test_module_one', 'case_review_relevence_project_gyq', 'COMPLETED', 'SINGLE', 001, null, null, 1,100.00,null,null,1698058347559,'admin',1698058347559,'admin');
INSERT INTO case_review_functional_case(id, review_id, case_id, status, create_time, create_user, update_time)
VALUES ('associate_id1', 'case_review_associate_Id', 'associate_case_gyq_id', 'PASS', 1698058347559,'admin',1698058347559),
('associate_id2', 'case_review_associate_Id2', 'associate_case_gyq_id', 'PASS', 1698058347559,'admin',1698058347559);