feat(用例评审): 关联用例弹窗&评审详情展示关联用例列表接口

This commit is contained in:
WangXu10 2023-12-07 16:46:43 +08:00 committed by f2c-ci-robot[bot]
parent f933967063
commit faa17a3843
19 changed files with 603 additions and 2 deletions

View File

@ -0,0 +1,50 @@
package io.metersphere.functional.controller;
import com.alibaba.excel.util.StringUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.functional.dto.ReviewFunctionalCaseDTO;
import io.metersphere.functional.request.ReviewFunctionalCasePageRequest;
import io.metersphere.functional.service.CaseReviewFunctionalCaseService;
import io.metersphere.system.utils.PageUtils;
import io.metersphere.system.utils.Pager;
import io.metersphere.system.utils.SessionUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author wx
*/
@Tag(name = "用例管理-用例评审-评审列表-评审详情")
@RestController
@RequestMapping("/case/review/detail")
public class CaseReviewFunctionalCaseController {
@Resource
private CaseReviewFunctionalCaseService caseReviewFunctionalCaseService;
@GetMapping("/get-ids/{reviewId}")
@Operation(summary = "用例管理-功能用例-评审列表-评审详情-获取已关联用例id集合(关联用例弹窗前调用)")
public List<String> getCaseIds(@PathVariable String reviewId) {
return caseReviewFunctionalCaseService.getCaseIdsByReviewId(reviewId);
}
@PostMapping("/page")
@Operation(summary = "用例管理-功能用例-评审列表-评审详情-已关联用例列表")
public Pager<List<ReviewFunctionalCaseDTO>> page(@Validated @RequestBody ReviewFunctionalCasePageRequest request) {
String userId = StringUtils.EMPTY;
if (request.getViewFlag()) {
userId = SessionUtils.getUserId();
}
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize());
return PageUtils.setPageInfo(page, caseReviewFunctionalCaseService.page(request, false, userId));
}
}

View File

@ -11,10 +11,12 @@ import io.metersphere.project.dto.filemanagement.request.FileMetadataTableReques
import io.metersphere.project.dto.filemanagement.response.FileInformationResponse; import io.metersphere.project.dto.filemanagement.response.FileInformationResponse;
import io.metersphere.project.service.FileAssociationService; import io.metersphere.project.service.FileAssociationService;
import io.metersphere.project.service.FileMetadataService; import io.metersphere.project.service.FileMetadataService;
import io.metersphere.project.service.FileModuleService;
import io.metersphere.sdk.constants.PermissionConstants; import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.FileAssociationSourceUtil; import io.metersphere.sdk.util.FileAssociationSourceUtil;
import io.metersphere.sdk.util.Translator; import io.metersphere.sdk.util.Translator;
import io.metersphere.system.dto.sdk.BaseTreeNode;
import io.metersphere.system.log.constants.OperationLogModule; import io.metersphere.system.log.constants.OperationLogModule;
import io.metersphere.system.utils.Pager; import io.metersphere.system.utils.Pager;
import io.metersphere.system.utils.SessionUtils; import io.metersphere.system.utils.SessionUtils;
@ -46,6 +48,8 @@ public class FunctionalCaseAttachmentController {
@Resource @Resource
private FileAssociationService fileAssociationService; private FileAssociationService fileAssociationService;
@Resource
private FileModuleService fileModuleService;
@PostMapping("/page") @PostMapping("/page")
@ -120,6 +124,7 @@ public class FunctionalCaseAttachmentController {
String fileId = null; String fileId = null;
try { try {
FileAssociationDTO fileAssociationDTO = new FileAssociationDTO(attachment.getFileName(), fileByte, attachment.getCaseId(), FileAssociationSourceUtil.SOURCE_TYPE_FUNCTIONAL_CASE, fileLogRecord); FileAssociationDTO fileAssociationDTO = new FileAssociationDTO(attachment.getFileName(), fileByte, attachment.getCaseId(), FileAssociationSourceUtil.SOURCE_TYPE_FUNCTIONAL_CASE, fileLogRecord);
fileAssociationDTO.setModuleId(request.getModuleId());
fileId = fileAssociationService.transferAndAssociation(fileAssociationDTO); fileId = fileAssociationService.transferAndAssociation(fileAssociationDTO);
functionalCaseAttachmentService.deleteCaseAttachment(Arrays.asList(request.getFileId()), request.getCaseId(), request.getProjectId()); functionalCaseAttachmentService.deleteCaseAttachment(Arrays.asList(request.getFileId()), request.getCaseId(), request.getProjectId());
} catch (Exception e) { } catch (Exception e) {
@ -146,4 +151,13 @@ public class FunctionalCaseAttachmentController {
functionalCaseAttachmentService.deleteFile(request, userId); functionalCaseAttachmentService.deleteFile(request, userId);
} }
@GetMapping("/options/{projectId}")
@Operation(summary = "用例管理-功能用例-附件-转存目录下拉框")
@RequiresPermissions(PermissionConstants.FUNCTIONAL_CASE_READ)
public List<BaseTreeNode> options(@PathVariable String projectId) {
return fileModuleService.getTree(projectId);
}
} }

View File

@ -0,0 +1,46 @@
package io.metersphere.functional.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
* @author wx
*/
@Data
public class ReviewFunctionalCaseDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "用例id")
private String id;
@Schema(description = "用例名称")
private String name;
@Schema(description = "版本id")
private String versionId;
@Schema(description = "版本名称")
private String versionName;
@Schema(description = "评审人")
private List<String> reviewers;
@Schema(description = "评审人名称")
private List<String> reviewNames;
@Schema(description = "评审状态")
private String status;
@Schema(description = "所属模块")
private String moduleId;
@Schema(description = "模块名称")
private String moduleName;
}

View File

@ -0,0 +1,27 @@
package io.metersphere.functional.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* @author wx
*/
@Data
public class ReviewsDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "用例id")
private String caseId;
@Schema(description = "用例评审人id字符串集合")
private String userIds;
@Schema(description = "用例评审人名称字符集合")
private String userNames;
}

View File

@ -1,7 +1,9 @@
package io.metersphere.functional.mapper; package io.metersphere.functional.mapper;
import io.metersphere.functional.dto.FunctionalCaseReviewDTO; import io.metersphere.functional.dto.FunctionalCaseReviewDTO;
import io.metersphere.functional.dto.ReviewFunctionalCaseDTO;
import io.metersphere.functional.request.FunctionalCaseReviewListRequest; import io.metersphere.functional.request.FunctionalCaseReviewListRequest;
import io.metersphere.functional.request.ReviewFunctionalCasePageRequest;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
@ -16,4 +18,8 @@ public interface ExtCaseReviewFunctionalCaseMapper {
void updateStatus(@Param("caseId") String caseId, @Param("reviewId") String reviewId, @Param("status") String status); void updateStatus(@Param("caseId") String caseId, @Param("reviewId") String reviewId, @Param("status") String status);
Long getUnCompletedCaseCount(@Param("reviewId") String reviewId, @Param("statusList") List<String> statusList); Long getUnCompletedCaseCount(@Param("reviewId") String reviewId, @Param("statusList") List<String> statusList);
List<String> getCaseIdsByReviewId(@Param("reviewId") String reviewId);
List<ReviewFunctionalCaseDTO> page(@Param("request") ReviewFunctionalCasePageRequest request, @Param("deleted") boolean deleted, @Param("userId") String userId, @Param("sort") String sort);
} }

View File

@ -35,4 +35,189 @@
where review_id = #{reviewId} and case_id = #{caseId} where review_id = #{reviewId} and case_id = #{caseId}
</update> </update>
<select id="getCaseIdsByReviewId" parameterType="java.lang.String" resultType="java.lang.String">
select case_id from case_review_functional_case where review_id = #{reviewId}
</select>
<select id="page" resultType="io.metersphere.functional.dto.ReviewFunctionalCaseDTO">
SELECT
crfc.id as id,
crfc.review_id as reviewId,
crfc.case_id as caseId,
crfc.`status` as status,
crfc.create_time as createTime,
functional_case.version_id as versionId,
functional_case.module_id as moduleId,
functional_case.name as name
FROM
case_review_functional_case crfc
LEFT JOIN functional_case ON crfc.case_id = functional_case.id
WHERE
review_id = #{request.reviewId}
AND functional_case.deleted = #{deleted}
<if test="userId != null and userId != ''">
AND crfc.case_id in (select case_id from case_review_functional_case_user crfcu where crfcu.review_id = #{request.reviewId} and crfcu.user_id = #{userId})
</if>
<choose>
<when test='request.searchMode == "AND"'>
AND <include refid="queryWhereCondition"/>
</when>
<when test='request.searchMode == "OR"'>
and (
<include refid="queryWhereCondition"/>
)
</when>
</choose>
order by
<if test="sort != null and sort != ''">
crfc.${sort}
</if>
<if test="sort == null or sort == ''">
crfc.pos desc
</if>
</select>
<sql id="queryWhereCondition">
<if test="request.keyword != null">
(
functional_case.name like concat('%', #{request.keyword},'%')
or functional_case.num like concat('%', #{request.keyword},'%')
or JSON_CONTAINS(tags, concat('["',#{request.keyword},'"]'))
)
<include refid="queryType">
<property name="searchMode" value="request.searchMode"/>
</include>
</if>
<include refid="filters">
<property name="filter" value="request.filter"/>
</include>
<include refid="combine">
<property name="condition" value="request.combine"/>
</include>
1=1
</sql>
<sql id="filters">
<if test="${filter} != null and ${filter}.size() > 0">
<foreach collection="${filter}.entrySet()" index="key" item="values">
<if test="values != null and values.size() > 0">
<choose>
<when test="key=='review_status'">
case_review_functional_case.review_status in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
<include refid="queryType">
<property name="searchMode" value="request.searchMode"/>
</include>
</when>
<when test="key=='last_execute_result'">
functional_case.last_execute_result in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
<include refid="queryType">
<property name="searchMode" value="request.searchMode"/>
</include>
</when>
<when test="key=='version_id'">
functional_case.version_id in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
<include refid="queryType">
<property name="searchMode" value="request.searchMode"/>
</include>
</when>
<when test="key.startsWith('custom_single')">
test_case.id in (
select resource_id from custom_field_test_case where concat('custom_single-',field_id) =
#{key}
and trim(both '"' from `value`) in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
)
<include refid="queryType">
<property name="searchMode" value="request.searchMode"/>
</include>
</when>
<when test="key.startsWith('custom_multiple')">
test_case.id in (
select resource_id from custom_field_test_case where concat('custom_multiple-',field_id) =
#{key}
and JSON_CONTAINS(`value`, json_array(#{value}))
<include refid="queryType">
<property name="searchMode" value="request.searchMode"/>
</include>
</when>
<when test="key=='create_user'">
functional_case.create_user in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
<include refid="queryType">
<property name="searchMode" value="request.searchMode"/>
</include>
</when>
</choose>
</if>
</foreach>
</if>
</sql>
<sql id="combine">
<if test="request.combine != null">
<if test='${condition}.name != null'>
functional_case.name
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.name"/>
</include>
<include refid="queryType">
<property name="searchMode" value="request.searchMode"/>
</include>
</if>
<if test='${condition}.id != null'>
functional_case.num
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="${condition}.id"/>
</include>
<include refid="queryType">
<property name="searchMode" value="request.searchMode"/>
</include>
</if>
<if test="${condition}.customs != null and ${condition}.customs.size() > 0">
<foreach collection="${condition}.customs" item="custom" separator="" open="" close="">
functional_case.id ${custom.operator} (
select case_id from functional_case_custom_field where field_id = #{custom.id}
<choose>
<when test="custom.type == 'List'">
and JSON_CONTAINS(`value`, json_array(#{custom.value}))
</when>
<when test="custom.type == 'date' or custom.type == 'datetime'">
and `value`
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="custom"/>
</include>
</when>
<otherwise>
and trim(both '"' from `value`)
<include refid="io.metersphere.system.mapper.BaseMapper.condition">
<property name="object" value="custom"/>
</include>
</otherwise>
</choose>
)
<include refid="queryType">
<property name="searchMode" value="request.searchMode"/>
</include>
</foreach>
</if>
</if>
</sql>
<sql id="queryType">
<choose>
<when test='${searchMode} == "AND"'>
AND
</when>
<when test='${searchMode} == "OR"'>
OR
</when>
</choose>
</sql>
</mapper> </mapper>

View File

@ -0,0 +1,13 @@
package io.metersphere.functional.mapper;
import io.metersphere.functional.dto.ReviewsDTO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author wx
*/
public interface ExtCaseReviewFunctionalCaseUserMapper {
List<ReviewsDTO> selectReviewers(@Param("ids") List<String> ids, @Param("reviewId") String reviewId);
}

View File

@ -0,0 +1,23 @@
<?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.ExtCaseReviewFunctionalCaseUserMapper">
<select id="selectReviewers" resultType="io.metersphere.functional.dto.ReviewsDTO">
SELECT
case_id,
GROUP_CONCAT( user_id ),
GROUP_CONCAT( `user`.NAME )
FROM
case_review_functional_case_user crfcu
LEFT JOIN `user` ON crfcu.user_id = `user`.id
WHERE
crfcu.review_id = #{reviewId}
AND crfcu.case_id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
GROUP BY
crfcu.case_id
</select>
</mapper>

View File

@ -95,7 +95,12 @@
) )
</when> </when>
</choose> </choose>
<if test="request.excludeIds != null and request.excludeIds.size() > 0">
AND functional_case.id not in
<foreach collection="request.excludeIds" item="excludeId" separator="," open="(" close=")">
#{excludeId}
</foreach>
</if>
</select> </select>
<update id="recoverCase"> <update id="recoverCase">

View File

@ -27,4 +27,7 @@ public class FunctionalCaseFileRequest implements Serializable {
@Schema(description = "是否本地",requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "是否本地",requiredMode = Schema.RequiredMode.REQUIRED)
private Boolean local; private Boolean local;
@Schema(description = "转存的模块id",requiredMode = Schema.RequiredMode.REQUIRED)
private String moduleId;
} }

View File

@ -41,4 +41,7 @@ public class FunctionalCasePageRequest extends BasePageRequest implements Serial
@Schema(description = "关联缺陷") @Schema(description = "关联缺陷")
private AssociationDTO associationBug; private AssociationDTO associationBug;
@Schema(description = "排除ids")
private List<String> excludeIds;
} }

View File

@ -0,0 +1,24 @@
package io.metersphere.functional.request;
import io.metersphere.system.dto.sdk.BasePageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* @author wx
*/
@Data
public class ReviewFunctionalCasePageRequest extends BasePageRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "评审id", requiredMode = Schema.RequiredMode.REQUIRED)
private String reviewId;
@Schema(description = "是否只看我的", requiredMode = Schema.RequiredMode.REQUIRED)
private Boolean viewFlag;
}

View File

@ -1,7 +1,24 @@
package io.metersphere.functional.service; package io.metersphere.functional.service;
import io.metersphere.functional.dto.ReviewFunctionalCaseDTO;
import io.metersphere.functional.dto.ReviewsDTO;
import io.metersphere.functional.mapper.ExtCaseReviewFunctionalCaseMapper;
import io.metersphere.functional.mapper.ExtCaseReviewFunctionalCaseUserMapper;
import io.metersphere.functional.mapper.ExtFunctionalCaseModuleMapper;
import io.metersphere.functional.request.ReviewFunctionalCasePageRequest;
import io.metersphere.project.domain.ProjectVersion;
import io.metersphere.project.mapper.ExtBaseProjectVersionMapper;
import io.metersphere.system.dto.sdk.BaseTreeNode;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/** /**
* 用例评审和功能用例的中间表服务实现类 * 用例评审和功能用例的中间表服务实现类
@ -9,6 +26,63 @@ import org.springframework.stereotype.Service;
* @date : 2023-5-17 * @date : 2023-5-17
*/ */
@Service @Service
@Transactional(rollbackFor = Exception.class)
public class CaseReviewFunctionalCaseService { public class CaseReviewFunctionalCaseService {
@Resource
private ExtCaseReviewFunctionalCaseMapper extCaseReviewFunctionalCaseMapper;
@Resource
private ExtFunctionalCaseModuleMapper extFunctionalCaseModuleMapper;
@Resource
private ExtBaseProjectVersionMapper extBaseProjectVersionMapper;
@Resource
private ExtCaseReviewFunctionalCaseUserMapper extCaseReviewFunctionalCaseUserMapper;
/**
* 通过评审id获取关联的用例id集合
*
* @param reviewId reviewId
* @return String
*/
public List<String> getCaseIdsByReviewId(String reviewId) {
return extCaseReviewFunctionalCaseMapper.getCaseIdsByReviewId(reviewId);
}
/**
* 评审详情分页列表查询
*
* @param request request
* @param deleted deleted
* @return ReviewFunctionalCaseDTO
*/
public List<ReviewFunctionalCaseDTO> page(ReviewFunctionalCasePageRequest request, boolean deleted, String userId) {
List<ReviewFunctionalCaseDTO> list = extCaseReviewFunctionalCaseMapper.page(request, deleted, userId, request.getSortString());
return doHandleDTO(list, request.getReviewId());
}
private List<ReviewFunctionalCaseDTO> doHandleDTO(List<ReviewFunctionalCaseDTO> list, String reviewId) {
if (CollectionUtils.isNotEmpty(list)) {
List<String> ids = list.stream().map(ReviewFunctionalCaseDTO::getId).toList();
List<BaseTreeNode> modules = extFunctionalCaseModuleMapper.selectBaseByIds(ids);
Map<String, String> moduleMap = modules.stream().collect(Collectors.toMap(BaseTreeNode::getId, BaseTreeNode::getName));
List<String> versionIds = list.stream().map(ReviewFunctionalCaseDTO::getVersionId).toList();
List<ProjectVersion> versions = extBaseProjectVersionMapper.getVersionByIds(versionIds);
Map<String, String> versionMap = versions.stream().collect(Collectors.toMap(ProjectVersion::getId, ProjectVersion::getName));
List<ReviewsDTO> reviewers = extCaseReviewFunctionalCaseUserMapper.selectReviewers(ids, reviewId);
Map<String, String> userIdMap = reviewers.stream().collect(Collectors.toMap(ReviewsDTO::getCaseId, ReviewsDTO::getUserIds));
Map<String, String> userNameMap = reviewers.stream().collect(Collectors.toMap(ReviewsDTO::getCaseId, ReviewsDTO::getUserNames));
list.forEach(item -> {
item.setModuleName(moduleMap.get(item.getModuleId()));
item.setVersionName(versionMap.get(item.getVersionId()));
item.setReviewers(Arrays.asList(userIdMap.get(item.getId())));
item.setReviewNames(Arrays.asList(userNameMap.get(item.getId())));
});
}
return list;
}
} }

View File

@ -0,0 +1,82 @@
package io.metersphere.functional.controller;
import io.metersphere.functional.request.FunctionalCasePageRequest;
import io.metersphere.functional.request.ReviewFunctionalCasePageRequest;
import io.metersphere.system.base.BaseTest;
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.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@AutoConfigureMockMvc
public class CaseReviewFunctionalCaseControllerTests extends BaseTest {
public static final String GET_CASE_IDS = "/case/review/detail/get-ids/";
public static final String FUNCTIONAL_CASE_LIST_URL = "/functional/case/page";
public static final String REVIEW_CASE_PAGE = "/case/review/detail/page";
@Test
@Order(1)
public void testGetCaseIds() throws Exception {
this.requestGet(GET_CASE_IDS + "test_review_id");
}
@Test
@Order(2)
public void testPage() throws Exception {
FunctionalCasePageRequest request = new FunctionalCasePageRequest();
request.setProjectId("100001100001");
request.setCurrent(1);
request.setPageSize(10);
request.setExcludeIds(Arrays.asList("TEST_FUNCTIONAL_CASE_ID_1"));
Map<String, Object> map = new HashMap<>();
map.put("customs", Arrays.asList(new LinkedHashMap() {{
put("id", "TEST_FIELD_ID");
put("operator", "in");
put("value", "222");
put("type", "List");
}}));
request.setCombine(map);
this.requestPost(FUNCTIONAL_CASE_LIST_URL, request);
}
@Test
@Order(3)
@Sql(scripts = {"/dml/init_review_functional_case_test.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
public void testReviewCasePage() throws Exception {
ReviewFunctionalCasePageRequest request = new ReviewFunctionalCasePageRequest();
request.setReviewId("wx_review_id_1");
request.setCurrent(1);
request.setPageSize(10);
Map<String, Object> map = new HashMap<>();
map.put("customs", Arrays.asList(new LinkedHashMap() {{
put("id", "TEST_FIELD_ID");
put("operator", "in");
put("value", "222");
put("type", "List");
}}));
request.setCombine(map);
request.setViewFlag(false);
this.requestPostWithOkAndReturn(REVIEW_CASE_PAGE, request);
request.setSort(new HashMap<>() {{
put("createTime", "desc");
}});
this.requestPostWithOkAndReturn(REVIEW_CASE_PAGE, request);
}
}

View File

@ -14,7 +14,7 @@ import org.springframework.test.context.jdbc.SqlConfig;
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT) @SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class) @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@AutoConfigureMockMvc @AutoConfigureMockMvc
public class CleanupFunctionalCaseResourceTest { public class CleanupFunctionalCaseResourceTests {
@Resource @Resource
private CleanupFunctionalCaseResourceService cleanupFunctionalCaseResourceService; private CleanupFunctionalCaseResourceService cleanupFunctionalCaseResourceService;

View File

@ -55,6 +55,7 @@ public class FunctionalCaseAttachmentControllerTests extends BaseTest {
public static final String ATTACHMENT_TRANSFER_URL = "/attachment/transfer"; public static final String ATTACHMENT_TRANSFER_URL = "/attachment/transfer";
public static final String UPLOAD_FILE_URL = "/attachment/upload/file"; public static final String UPLOAD_FILE_URL = "/attachment/upload/file";
public static final String DELETE_FILE_URL = "/attachment/delete/file"; public static final String DELETE_FILE_URL = "/attachment/delete/file";
public static final String OPTIONS_URL = "/attachment/options/";
@Test @Test
@ -216,4 +217,11 @@ public class FunctionalCaseAttachmentControllerTests extends BaseTest {
} }
@Test
@Order(9)
public void testOptions() throws Exception {
//覆盖controller方法
this.requestGet(OPTIONS_URL + DEFAULT_PROJECT_ID);
}
} }

View File

@ -0,0 +1,26 @@
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 ('wx_case_id_1', 100, 'TEST_MODULE_ID', 'wx_test_project', '100001', '测试', 'UN_REVIEWED', NULL, 'STEP', 0, 'v1.0.0', 'v1.0.0', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 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 ('wx_case_id_2', 101, 'TEST_MODULE_ID', 'wx_test_project', '100001', '测试多版本', 'UN_REVIEWED', '["测试标签_1"]', 'STEP', 0, 'v1.0.0', 'TEST_REF_ID', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('wx_case_id_1', 'STEP', '1111', '', '', 'TEST');
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('wx_case_id_2', 'STEP', '1111', '', '', '1111');
INSERT INTO functional_case_custom_field(case_id, field_id, value) VALUES ('wx_case_id_1', '100548878725546079', '22');
INSERT INTO functional_case_custom_field(case_id, field_id, value) VALUES ('wx_case_id_1', 'TEST_FIELD_ID', '["222","333"]');
INSERT INTO functional_case_custom_field(case_id, field_id, value) VALUES ('wx_case_id_2', 'TEST_FIELD_ID_1', '["222","333"]');
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 ('wx_review_id_1',10001,'wx1', 'wx_module_1', 'wx_test_project', 'COMPLETED', 'SINGLE', 001, null, null, 1,100.00,null,null,1698058347559,'admin',1698058347559,'admin'),
('wx_review_id_2',10002,'wx2', 'wx_module_2', 'wx_test_project', '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 ('wx_test_1', 'wx_review_id_1', 'wx_case_id_1', 'PASS', 1698058347559,'admin',1698058347559),
('wx_test_2', 'wx_review_id_2', 'wx_case_id_2', 'PASS', 1698058347559,'admin',1698058347559);
INSERT INTO functional_case_module(id, project_id, name, parent_id, pos, create_time, update_time, create_user, update_user) VALUES ('wx_module_1', 'wx_test_project', '测试所属模块', 'NONE', 0, 1669174143999, 1669174143999, 'admin', 'admin');

View File

@ -1,8 +1,14 @@
package io.metersphere.project.mapper; package io.metersphere.project.mapper;
import io.metersphere.project.domain.ProjectVersion;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ExtBaseProjectVersionMapper { public interface ExtBaseProjectVersionMapper {
String getDefaultVersion(@Param("projectId") String projectId); String getDefaultVersion(@Param("projectId") String projectId);
List<ProjectVersion> getVersionByIds(@Param("ids") List<String> ids);
} }

View File

@ -6,4 +6,10 @@
select id from project_version where project_id = #{projectId} and status = 'open' and latest = TRUE LIMIT 1 select id from project_version where project_id = #{projectId} and status = 'open' and latest = TRUE LIMIT 1
</select> </select>
<select id="getVersionByIds" resultType="io.metersphere.project.domain.ProjectVersion">
select id, name from project_version where id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
</mapper> </mapper>