feat(功能用例): 关联用例评审表
This commit is contained in:
parent
106800e6cd
commit
25a957cabe
|
@ -1,12 +1,16 @@
|
||||||
package io.metersphere.functional.domain;
|
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 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.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class CaseReviewFunctionalCase implements Serializable {
|
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})
|
@Size(min = 1, max = 50, message = "{case_review_functional_case.case_id.length_range}", groups = {Created.class, Updated.class})
|
||||||
private String caseId;
|
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})
|
@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})
|
@Size(min = 1, max = 64, message = "{case_review_functional_case.status.length_range}", groups = {Created.class, Updated.class})
|
||||||
private String status;
|
private String status;
|
||||||
|
|
|
@ -9,7 +9,7 @@ CREATE TABLE IF NOT EXISTS functional_case
|
||||||
`project_id` VARCHAR(50) NOT NULL COMMENT '项目ID',
|
`project_id` VARCHAR(50) NOT NULL COMMENT '项目ID',
|
||||||
`template_id` VARCHAR(50) NOT NULL COMMENT '模板ID',
|
`template_id` VARCHAR(50) NOT NULL COMMENT '模板ID',
|
||||||
`name` VARCHAR(255) NOT NULL COMMENT '名称',
|
`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)',
|
`tags` VARCHAR(1000) COMMENT '标签(JSON)',
|
||||||
`case_edit_type` VARCHAR(50) NOT NULL DEFAULT 'STEP' COMMENT '编辑模式:步骤模式/文本模式',
|
`case_edit_type` VARCHAR(50) NOT NULL DEFAULT 'STEP' COMMENT '编辑模式:步骤模式/文本模式',
|
||||||
`pos` BIGINT NOT NULL DEFAULT 0 COMMENT '自定义排序,间隔5000',
|
`pos` BIGINT NOT NULL DEFAULT 0 COMMENT '自定义排序,间隔5000',
|
||||||
|
|
|
@ -1,26 +1,6 @@
|
||||||
package io.metersphere.functional.constants;
|
package io.metersphere.functional.constants;
|
||||||
|
|
||||||
import io.metersphere.sdk.util.Translator;
|
|
||||||
|
|
||||||
public enum CaseReviewPassRule {
|
public enum CaseReviewPassRule {
|
||||||
SINGLE("case_review.single"),
|
SINGLE,
|
||||||
MULTIPLE("case_review.multiple");
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,9 @@
|
||||||
package io.metersphere.functional.constants;
|
package io.metersphere.functional.constants;
|
||||||
|
|
||||||
import io.metersphere.sdk.util.Translator;
|
|
||||||
|
|
||||||
public enum CaseReviewStatus {
|
public enum CaseReviewStatus {
|
||||||
|
|
||||||
|
PREPARED,
|
||||||
PREPARED("case_review.prepared"),
|
UNDERWAY,
|
||||||
UNDERWAY("case_review.underway"),
|
COMPLETED,
|
||||||
COMPLETED("case_review.completed"),
|
ARCHIVED
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -27,9 +27,6 @@ public class CaseReviewDTO extends CaseReview {
|
||||||
@Schema(description = "已评审过得用例数")
|
@Schema(description = "已评审过得用例数")
|
||||||
private int reviewedCount;
|
private int reviewedCount;
|
||||||
|
|
||||||
@Schema(description = "评审状态名称")
|
|
||||||
private String statusName;
|
|
||||||
|
|
||||||
@Schema(description = "关注标识")
|
@Schema(description = "关注标识")
|
||||||
private Boolean followFlag;
|
private Boolean followFlag;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
||||||
|
}
|
|
@ -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>
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
|
@ -113,8 +113,6 @@ public class CaseReviewService {
|
||||||
}
|
}
|
||||||
|
|
||||||
buildReviewers(caseReviewDTO, reviewUserMap);
|
buildReviewers(caseReviewDTO, reviewUserMap);
|
||||||
|
|
||||||
caseReviewDTO.setStatusName(CaseReviewStatus.valueOf(caseReviewDTO.getStatus()).getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void buildReviewers(CaseReviewDTO caseReviewDTO, Map<String, List<CaseReviewUserDTO>> reviewUserMap) {
|
private static void buildReviewers(CaseReviewDTO caseReviewDTO, Map<String, List<CaseReviewUserDTO>> reviewUserMap) {
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +0,0 @@
|
||||||
package io.metersphere.functional.service;
|
|
||||||
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 功能用例和其他用例的中间表服务实现类
|
|
||||||
*
|
|
||||||
* @date : 2023-5-17
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class FunctionalCaseTestService {
|
|
||||||
|
|
||||||
}
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue