diff --git a/backend/framework/sdk/src/main/resources/i18n/case.properties b/backend/framework/sdk/src/main/resources/i18n/case.properties index 011c857ce4..9fde88b38c 100644 --- a/backend/framework/sdk/src/main/resources/i18n/case.properties +++ b/backend/framework/sdk/src/main/resources/i18n/case.properties @@ -131,3 +131,6 @@ case_comment.reply_user_is_null=回复的用户为空 case_comment.id_is_null=当前评论id为空 #module case_module.not.exist=用例模块不存在 +#case +case.demand.not.exist=需求不存在 +case.demand.name.not.exist=需求名称不能为空 \ No newline at end of file diff --git a/backend/framework/sdk/src/main/resources/i18n/case_en_US.properties b/backend/framework/sdk/src/main/resources/i18n/case_en_US.properties index 91bf98061d..9abeb694c6 100644 --- a/backend/framework/sdk/src/main/resources/i18n/case_en_US.properties +++ b/backend/framework/sdk/src/main/resources/i18n/case_en_US.properties @@ -150,4 +150,7 @@ un_follow_functional_case=unfollow functional case follow_functional_case=followed functional case #module case_module.not.exist=Case module does not exist -file.transfer.failed=File transfer FAILED \ No newline at end of file +file.transfer.failed=File transfer FAILED +#case +case.demand.not.exist=Demand does not exist +case.demand.name.not.exist=Demand name cannot be empty \ No newline at end of file diff --git a/backend/framework/sdk/src/main/resources/i18n/case_zh_CN.properties b/backend/framework/sdk/src/main/resources/i18n/case_zh_CN.properties index 08267e1b67..16ff0d88f6 100644 --- a/backend/framework/sdk/src/main/resources/i18n/case_zh_CN.properties +++ b/backend/framework/sdk/src/main/resources/i18n/case_zh_CN.properties @@ -150,4 +150,7 @@ un_follow_functional_case=取消关注用例 follow_functional_case=关注用例 #module case_module.not.exist=用例模块不存在 -file.transfer.failed=文件转存失败 \ No newline at end of file +file.transfer.failed=文件转存失败 +#case +case.demand.not.exist=需求不存在 +case.demand.name.not.exist=需求名称不能为空 \ No newline at end of file diff --git a/backend/framework/sdk/src/main/resources/i18n/case_zh_TW.properties b/backend/framework/sdk/src/main/resources/i18n/case_zh_TW.properties index 13cb5a0bd8..6df4e421e3 100644 --- a/backend/framework/sdk/src/main/resources/i18n/case_zh_TW.properties +++ b/backend/framework/sdk/src/main/resources/i18n/case_zh_TW.properties @@ -150,4 +150,7 @@ un_follow_functional_case=取消關注用例 follow_functional_case=關注用例 #module case_module.not.exist=用例模組不存在 -file.transfer.failed=文件轉存失敗 \ No newline at end of file +file.transfer.failed=文件轉存失敗 +#case +case.demand.not.exist=需求不存在 +case.demand.name.not.exist=需求名稱不能為空 diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseDemandController.java b/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseDemandController.java new file mode 100644 index 0000000000..f8da968ad0 --- /dev/null +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/controller/FunctionalCaseDemandController.java @@ -0,0 +1,67 @@ +package io.metersphere.functional.controller; + +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import io.metersphere.functional.domain.FunctionalCaseDemand; +import io.metersphere.functional.request.FunctionalCaseDemandRequest; +import io.metersphere.functional.request.QueryDemandListRequest; +import io.metersphere.functional.service.FunctionalCaseDemandService; +import io.metersphere.sdk.constants.PermissionConstants; +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 jakarta.validation.constraints.NotBlank; +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.*; + +import java.util.List; + +@Tag(name = "用例管理-功能用例-关联需求") +@RestController +@RequestMapping("/functional/case/demand") +public class FunctionalCaseDemandController { + + @Resource + private FunctionalCaseDemandService functionalCaseDemandService; + + @PostMapping("/page") + @Operation(summary = "用例管理-功能用例-关联需求-获取已关联的需求列表") + @RequiresPermissions(value = {PermissionConstants.FUNCTIONAL_CASE_READ,PermissionConstants.FUNCTIONAL_CASE_READ_ADD, PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE, PermissionConstants.FUNCTIONAL_CASE_READ_DELETE}, logical = Logical.OR) + public Pager> listFunctionalCaseDemands(@Validated @RequestBody QueryDemandListRequest request) { + Page page = PageHelper.startPage(request.getCurrent(), request.getPageSize(), true); + return PageUtils.setPageInfo(page, functionalCaseDemandService.listFunctionalCaseDemands(request)); + } + + @PostMapping("/add") + @Operation(summary = "用例管理-功能用例-关联需求-新增需求") + @RequiresPermissions(value = {PermissionConstants.FUNCTIONAL_CASE_READ_ADD, PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE, PermissionConstants.FUNCTIONAL_CASE_READ_DELETE}, logical = Logical.OR) + public void addDemand(@RequestBody @Validated FunctionalCaseDemandRequest request) { + functionalCaseDemandService.addDemand(request, SessionUtils.getUserId()); + } + + @PostMapping("/update") + @Operation(summary = "用例管理-功能用例-关联需求-更新需求") + @RequiresPermissions(value = {PermissionConstants.FUNCTIONAL_CASE_READ_ADD, PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE, PermissionConstants.FUNCTIONAL_CASE_READ_DELETE}, logical = Logical.OR) + public void updateDemand(@RequestBody @Validated FunctionalCaseDemandRequest request) { + functionalCaseDemandService.updateDemand(request, SessionUtils.getUserId()); + } + + @GetMapping("/cancel/{id}") + @Operation(summary = "用例管理-功能用例-关联需求-取消关联需求") + @RequiresPermissions(value = {PermissionConstants.FUNCTIONAL_CASE_READ_ADD, PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE, PermissionConstants.FUNCTIONAL_CASE_READ_DELETE}, logical = Logical.OR) + public void deleteDemand(@PathVariable @NotBlank(message = "{functional_case.id.not_blank}") String id) { + functionalCaseDemandService.deleteDemand(id); + } + + @PostMapping("/batch/relevance") + @Operation(summary = "用例管理-功能用例-关联需求-批量关联需求") + @RequiresPermissions(value = {PermissionConstants.FUNCTIONAL_CASE_READ_ADD, PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE, PermissionConstants.FUNCTIONAL_CASE_READ_DELETE}, logical = Logical.OR) + public void batchRelevance(@RequestBody @Validated FunctionalCaseDemandRequest request) { + functionalCaseDemandService.batchRelevance(request, SessionUtils.getUserId()); + } +} diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/dto/DemandDTO.java b/backend/services/case-management/src/main/java/io/metersphere/functional/dto/DemandDTO.java new file mode 100644 index 0000000000..e1235af56c --- /dev/null +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/dto/DemandDTO.java @@ -0,0 +1,26 @@ +package io.metersphere.functional.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; + +/** + * @author guoyuqi + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class DemandDTO implements Serializable { + + @Schema(description = "需求ID") + private String demandId; + + @Schema(description = "需求标题", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "{functional_case_demand.demand_name.not_blank}") + private String demandName; + + @Schema(description = "需求地址") + private String demandUrl; +} diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseDemandMapper.java b/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseDemandMapper.java new file mode 100644 index 0000000000..12b6ca5f91 --- /dev/null +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseDemandMapper.java @@ -0,0 +1,15 @@ +package io.metersphere.functional.mapper; + +import io.metersphere.functional.domain.FunctionalCaseDemand; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @author guoyuqi + */ +public interface ExtFunctionalCaseDemandMapper { + + List selectByKeyword(@Param("keyword") String keyword, @Param("caseId") String caseId); + +} diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseDemandMapper.xml b/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseDemandMapper.xml new file mode 100644 index 0000000000..7ec9753234 --- /dev/null +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/mapper/ExtFunctionalCaseDemandMapper.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseDemandRequest.java b/backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseDemandRequest.java new file mode 100644 index 0000000000..76b1822998 --- /dev/null +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/request/FunctionalCaseDemandRequest.java @@ -0,0 +1,33 @@ +package io.metersphere.functional.request; + +import io.metersphere.functional.dto.DemandDTO; +import io.metersphere.validation.groups.Updated; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.List; + +/** + * @author guoyuqi + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class FunctionalCaseDemandRequest { + + @Schema(description = "功能用例需求关系ID") + @NotBlank(message = "{functional_case_demand.case_id.not_blank}", groups = {Updated.class}) + private String id; + + @Schema(description = "功能用例ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "{functional_case_demand.case_id.not_blank}") + private String caseId; + + @Schema(description = "需求所属平台(默认是LOCAL)") + @NotBlank(message = "{functional_case_demand.demand_platform.not_blank}") + private String demandPlatform; + + @Schema(description = "需求集合") + private List demandList; +} diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/request/QueryDemandListRequest.java b/backend/services/case-management/src/main/java/io/metersphere/functional/request/QueryDemandListRequest.java new file mode 100644 index 0000000000..4ab5aedf64 --- /dev/null +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/request/QueryDemandListRequest.java @@ -0,0 +1,13 @@ +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 QueryDemandListRequest extends BasePageRequest { + @Schema(description = "功能用例id") + private String caseId; +} diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/result/DemandPlatform.java b/backend/services/case-management/src/main/java/io/metersphere/functional/result/DemandPlatform.java new file mode 100644 index 0000000000..0f3deebda3 --- /dev/null +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/result/DemandPlatform.java @@ -0,0 +1,5 @@ +package io.metersphere.functional.result; + +public enum DemandPlatform { + LOCAL; +} diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseDemandService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseDemandService.java new file mode 100644 index 0000000000..9afb55e78c --- /dev/null +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseDemandService.java @@ -0,0 +1,136 @@ +package io.metersphere.functional.service; + +import io.metersphere.functional.domain.FunctionalCaseDemand; +import io.metersphere.functional.dto.DemandDTO; +import io.metersphere.functional.mapper.ExtFunctionalCaseDemandMapper; +import io.metersphere.functional.mapper.FunctionalCaseDemandMapper; +import io.metersphere.functional.request.FunctionalCaseDemandRequest; +import io.metersphere.functional.request.QueryDemandListRequest; +import io.metersphere.sdk.exception.MSException; +import io.metersphere.sdk.util.Translator; +import io.metersphere.system.uid.IDGenerator; +import jakarta.annotation.Resource; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.ibatis.session.ExecutorType; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * @author guoyuqi + */ +@Service +@Transactional(rollbackFor = Exception.class) +public class FunctionalCaseDemandService { + + @Resource + private FunctionalCaseDemandMapper functionalCaseDemandMapper; + @Resource + private ExtFunctionalCaseDemandMapper extFunctionalCaseDemandMapper; + @Resource + private SqlSessionFactory sqlSessionFactory; + + /** + * 获取需求列表 + * @param request QueryDemandListRequest + * @return List + */ + public List listFunctionalCaseDemands(QueryDemandListRequest request) { + return extFunctionalCaseDemandMapper.selectByKeyword(request.getKeyword(), request.getCaseId()); + } + + /** + * 新增本地需求 + * @param request 页面参数 + * @param userId 当前操作人 + */ + public void addDemand(FunctionalCaseDemandRequest request, String userId) { + if (checkDemandList(request)) return; + FunctionalCaseDemand functionalCaseDemand = buildFunctionalCaseDemand(request, userId, request.getDemandList().get(0)); + functionalCaseDemandMapper.insert(functionalCaseDemand); + } + + private static FunctionalCaseDemand buildFunctionalCaseDemand(FunctionalCaseDemandRequest request, String userId, DemandDTO demandDTO) { + FunctionalCaseDemand functionalCaseDemand = new FunctionalCaseDemand(); + functionalCaseDemand.setId(IDGenerator.nextStr()); + functionalCaseDemand.setCaseId(request.getCaseId()); + functionalCaseDemand.setDemandPlatform(request.getDemandPlatform()); + functionalCaseDemand.setCreateTime(System.currentTimeMillis()); + functionalCaseDemand.setCreateUser(userId); + functionalCaseDemand.setUpdateTime(System.currentTimeMillis()); + functionalCaseDemand.setUpdateUser(userId); + dealWithDemand(demandDTO, functionalCaseDemand); + return functionalCaseDemand; + } + + private static boolean checkDemandList(FunctionalCaseDemandRequest request) { + return CollectionUtils.isEmpty(request.getDemandList()); + } + + /** + * 处理单个需求 + * @param demandDTO 需求参数 + * @param functionalCaseDemand functionalCaseDemand + */ + private static void dealWithDemand(DemandDTO demandDTO, FunctionalCaseDemand functionalCaseDemand) { + if (StringUtils.isNotBlank(demandDTO.getDemandId())) { + functionalCaseDemand.setDemandId(demandDTO.getDemandId()); + } + if (StringUtils.isBlank(demandDTO.getDemandName())) { + throw new MSException(Translator.get("case.demand.name.not.exist")); + } + functionalCaseDemand.setDemandName(demandDTO.getDemandName()); + if (StringUtils.isNotBlank(demandDTO.getDemandUrl())) { + functionalCaseDemand.setDemandUrl(demandDTO.getDemandUrl()); + } + } + + /** + * 更新本地需求 + * @param request 页面参数 + * @param userId 当前操作人 + */ + public void updateDemand(FunctionalCaseDemandRequest request, String userId) { + if (checkDemandList(request)) return; + FunctionalCaseDemand functionalCaseDemand = functionalCaseDemandMapper.selectByPrimaryKey(request.getId()); + if (functionalCaseDemand == null) { + throw new MSException(Translator.get("case.demand.not.exist")); + } + dealWithDemand(request.getDemandList().get(0), functionalCaseDemand); + functionalCaseDemand.setCreateTime(null); + functionalCaseDemand.setCreateUser(null); + functionalCaseDemand.setUpdateUser(userId); + functionalCaseDemand.setUpdateTime(System.currentTimeMillis()); + functionalCaseDemandMapper.updateByPrimaryKeySelective(functionalCaseDemand); + } + + /** + * 取消关联需求 就是将该需求关系删除 + * @param id 需求关系ID + */ + public void deleteDemand(String id) { + functionalCaseDemandMapper.deleteByPrimaryKey(id); + } + + /** + * 批量关联第三方需求 需要带有所属平台 + * @param request 页面参数 + * @param userId 当前操作人 + */ + public void batchRelevance(FunctionalCaseDemandRequest request, String userId) { + if (checkDemandList(request)) return; + SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); + FunctionalCaseDemandMapper functionalCaseDemandMapper = sqlSession.getMapper(FunctionalCaseDemandMapper.class); + for (DemandDTO demandDTO : request.getDemandList()) { + FunctionalCaseDemand functionalCaseDemand = buildFunctionalCaseDemand(request, userId, demandDTO); + functionalCaseDemandMapper.insert(functionalCaseDemand); + } + sqlSession.flushStatements(); + SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); + } +} diff --git a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseService.java b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseService.java index 386e85e8c9..30debfc33a 100644 --- a/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseService.java +++ b/backend/services/case-management/src/main/java/io/metersphere/functional/service/FunctionalCaseService.java @@ -616,7 +616,7 @@ public class FunctionalCaseService { //查出每个模块节点下的资源数量。 不需要按照模块进行筛选 List moduleCountDTOList = extFunctionalCaseMapper.countModuleIdByKeywordAndFileType(request, delete); Map moduleCountMap = functionalCaseModuleService.getModuleCountMap(request.getProjectId(), moduleCountDTOList); - //查出全部文件和我的文件的数量 + //查出全部用例数量 long allCount = extFunctionalCaseMapper.caseCount(request, delete); moduleCountMap.put(CASE_MODULE_COUNT_ALL, allCount); return moduleCountMap; diff --git a/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseDemandControllerTests.java b/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseDemandControllerTests.java new file mode 100644 index 0000000000..8db8fbd57b --- /dev/null +++ b/backend/services/case-management/src/test/java/io/metersphere/functional/controller/FunctionalCaseDemandControllerTests.java @@ -0,0 +1,303 @@ +package io.metersphere.functional.controller; + +import io.metersphere.functional.domain.FunctionalCaseDemand; +import io.metersphere.functional.domain.FunctionalCaseDemandExample; +import io.metersphere.functional.dto.DemandDTO; +import io.metersphere.functional.mapper.FunctionalCaseDemandMapper; +import io.metersphere.functional.request.FunctionalCaseDemandRequest; +import io.metersphere.functional.request.QueryDemandListRequest; +import io.metersphere.sdk.constants.SessionConstants; +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 jakarta.annotation.Resource; +import org.apache.commons.collections4.CollectionUtils; +import org.junit.jupiter.api.*; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.test.context.jdbc.SqlConfig; +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.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +@AutoConfigureMockMvc +public class FunctionalCaseDemandControllerTests extends BaseTest { + + @Resource + private FunctionalCaseDemandMapper functionalCaseDemandMapper; + + + private static final String URL_DEMAND_PAGE = "/functional/case/demand/page"; + private static final String URL_DEMAND_ADD = "/functional/case/demand/add"; + private static final String URL_DEMAND_UPDATE = "/functional/case/demand/update"; + private static final String URL_DEMAND_CANCEL = "/functional/case/demand/cancel/"; + private static final String URL_DEMAND_BATCH_RELEVANCE = "/functional/case/demand/batch/relevance"; + + + @Test + @Order(1) + @Sql(scripts = {"/dml/init_case_demand.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED)) + public void addDemandSuccess() throws Exception { + FunctionalCaseDemandRequest functionalCaseDemandRequest = new FunctionalCaseDemandRequest(); + functionalCaseDemandRequest.setCaseId("DEMAND_TEST_FUNCTIONAL_CASE_ID"); + functionalCaseDemandRequest.setDemandPlatform("LOCAL"); + List demandList = new ArrayList<>(); + DemandDTO demandDTO = new DemandDTO(); + demandDTO.setDemandName("手动加入1"); + demandList.add(demandDTO); + functionalCaseDemandRequest.setDemandList(demandList); + this.requestPostWithOkAndReturn(URL_DEMAND_ADD, functionalCaseDemandRequest); + FunctionalCaseDemandExample functionalCaseDemandExample = new FunctionalCaseDemandExample(); + functionalCaseDemandExample.createCriteria().andCaseIdEqualTo("DEMAND_TEST_FUNCTIONAL_CASE_ID"); + List functionalCaseDemands = functionalCaseDemandMapper.selectByExample(functionalCaseDemandExample); + Assertions.assertFalse(functionalCaseDemands.isEmpty()); + } + + @Test + @Order(2) + public void addDemandEmpty() throws Exception { + FunctionalCaseDemandRequest functionalCaseDemandRequest = new FunctionalCaseDemandRequest(); + functionalCaseDemandRequest.setCaseId("DEMAND_TEST_FUNCTIONAL_CASE_ID2"); + functionalCaseDemandRequest.setDemandPlatform("LOCAL"); + List demandList = new ArrayList<>(); + functionalCaseDemandRequest.setDemandList(demandList); + this.requestPostWithOkAndReturn(URL_DEMAND_ADD, functionalCaseDemandRequest); + FunctionalCaseDemandExample functionalCaseDemandExample = new FunctionalCaseDemandExample(); + functionalCaseDemandExample.createCriteria().andCaseIdEqualTo("DEMAND_TEST_FUNCTIONAL_CASE_ID2"); + List functionalCaseDemands = functionalCaseDemandMapper.selectByExample(functionalCaseDemandExample); + Assertions.assertTrue(functionalCaseDemands.isEmpty()); + } + + @Test + @Order(3) + public void addDemandFalse() throws Exception { + FunctionalCaseDemandRequest functionalCaseDemandRequest = new FunctionalCaseDemandRequest(); + functionalCaseDemandRequest.setCaseId("DEMAND_TEST_FUNCTIONAL_CASE_ID2"); + functionalCaseDemandRequest.setDemandPlatform("LOCAL"); + List demandList = new ArrayList<>(); + DemandDTO demandDTO = new DemandDTO(); + demandDTO.setDemandId("111"); + demandList.add(demandDTO); + functionalCaseDemandRequest.setDemandList(demandList); + this.requestPost(URL_DEMAND_ADD, functionalCaseDemandRequest).andExpect(status().is5xxServerError()); + FunctionalCaseDemandExample functionalCaseDemandExample = new FunctionalCaseDemandExample(); + functionalCaseDemandExample.createCriteria().andCaseIdEqualTo("DEMAND_TEST_FUNCTIONAL_CASE_ID2"); + List functionalCaseDemands = functionalCaseDemandMapper.selectByExample(functionalCaseDemandExample); + Assertions.assertTrue(functionalCaseDemands.isEmpty()); + + functionalCaseDemandRequest = new FunctionalCaseDemandRequest(); + functionalCaseDemandRequest.setDemandPlatform("LOCAL"); + demandList = new ArrayList<>(); + demandDTO = new DemandDTO(); + demandDTO.setDemandId("111"); + demandList.add(demandDTO); + functionalCaseDemandRequest.setDemandList(demandList); + this.requestPost(URL_DEMAND_ADD, functionalCaseDemandRequest).andExpect(status().is4xxClientError()); + } + + @Test + @Order(4) + public void updateDemandSuccess() throws Exception { + String id = getId("DEMAND_TEST_FUNCTIONAL_CASE_ID"); + FunctionalCaseDemandExample functionalCaseDemandExample; + List functionalCaseDemands; + FunctionalCaseDemandRequest functionalCaseDemandRequest = new FunctionalCaseDemandRequest(); + functionalCaseDemandRequest.setId(id); + functionalCaseDemandRequest.setCaseId("DEMAND_TEST_FUNCTIONAL_CASE_ID"); + functionalCaseDemandRequest.setDemandPlatform("LOCAL"); + List demandList = new ArrayList<>(); + DemandDTO demandDTO = new DemandDTO(); + demandDTO.setDemandName("手动加入2"); + demandList.add(demandDTO); + functionalCaseDemandRequest.setDemandList(demandList); + this.requestPostWithOkAndReturn(URL_DEMAND_UPDATE, functionalCaseDemandRequest); + functionalCaseDemandExample = new FunctionalCaseDemandExample(); + functionalCaseDemandExample.createCriteria().andCaseIdEqualTo("DEMAND_TEST_FUNCTIONAL_CASE_ID"); + functionalCaseDemands = functionalCaseDemandMapper.selectByExample(functionalCaseDemandExample); + Assertions.assertTrue(StringUtils.equals(functionalCaseDemands.get(0).getDemandName(), "手动加入2")); + } + + @Test + @Order(5) + public void updateDemandEmpty() throws Exception { + String id = getId("DEMAND_TEST_FUNCTIONAL_CASE_ID"); + FunctionalCaseDemandExample functionalCaseDemandExample; + List functionalCaseDemands; + FunctionalCaseDemandRequest functionalCaseDemandRequest = new FunctionalCaseDemandRequest(); + functionalCaseDemandRequest.setId(id); + functionalCaseDemandRequest.setCaseId("DEMAND_TEST_FUNCTIONAL_CASE_ID"); + functionalCaseDemandRequest.setDemandPlatform("LOCAL"); + List demandList = new ArrayList<>(); + functionalCaseDemandRequest.setDemandList(demandList); + this.requestPostWithOkAndReturn(URL_DEMAND_UPDATE, functionalCaseDemandRequest); + functionalCaseDemandExample = new FunctionalCaseDemandExample(); + functionalCaseDemandExample.createCriteria().andCaseIdEqualTo("DEMAND_TEST_FUNCTIONAL_CASE_ID"); + functionalCaseDemands = functionalCaseDemandMapper.selectByExample(functionalCaseDemandExample); + Assertions.assertTrue(StringUtils.equals(functionalCaseDemands.get(0).getDemandName(), "手动加入2")); + } + + @Test + @Order(6) + public void updateDemandFalse() throws Exception { + String id = getId("DEMAND_TEST_FUNCTIONAL_CASE_ID"); + FunctionalCaseDemandExample functionalCaseDemandExample; + List functionalCaseDemands; + FunctionalCaseDemandRequest functionalCaseDemandRequest = new FunctionalCaseDemandRequest(); + functionalCaseDemandRequest.setId(id); + functionalCaseDemandRequest.setCaseId("DEMAND_TEST_FUNCTIONAL_CASE_ID"); + functionalCaseDemandRequest.setDemandPlatform("LOCAL"); + List demandList = new ArrayList<>(); + DemandDTO demandDTO = new DemandDTO(); + demandDTO.setDemandId("111"); + demandList.add(demandDTO); + functionalCaseDemandRequest.setDemandList(demandList); + this.requestPost(URL_DEMAND_UPDATE, functionalCaseDemandRequest).andExpect(status().is5xxServerError()); + functionalCaseDemandExample = new FunctionalCaseDemandExample(); + functionalCaseDemandExample.createCriteria().andCaseIdEqualTo("DEMAND_TEST_FUNCTIONAL_CASE_ID"); + functionalCaseDemands = functionalCaseDemandMapper.selectByExample(functionalCaseDemandExample); + Assertions.assertNull(functionalCaseDemands.get(0).getDemandId()); + + functionalCaseDemandRequest = new FunctionalCaseDemandRequest(); + functionalCaseDemandRequest.setId("hehe"); + functionalCaseDemandRequest.setCaseId("DEMAND_TEST_FUNCTIONAL_CASE_ID"); + functionalCaseDemandRequest.setDemandPlatform("LOCAL"); + demandList = new ArrayList<>(); + demandDTO = new DemandDTO(); + demandDTO.setDemandId("111"); + demandDTO.setDemandName("手动执行2"); + demandList.add(demandDTO); + functionalCaseDemandRequest.setDemandList(demandList); + this.requestPost(URL_DEMAND_UPDATE, functionalCaseDemandRequest).andExpect(status().is5xxServerError()); + + } + + private String getId(String caseId) { + FunctionalCaseDemandExample functionalCaseDemandExample = new FunctionalCaseDemandExample(); + functionalCaseDemandExample.createCriteria().andCaseIdEqualTo(caseId); + List functionalCaseDemands = functionalCaseDemandMapper.selectByExample(functionalCaseDemandExample); + return functionalCaseDemands.get(0).getId(); + } + + @Test + @Order(7) + public void getDemandList() throws Exception { + QueryDemandListRequest queryDemandListRequest = new QueryDemandListRequest(); + queryDemandListRequest.setCurrent(1); + queryDemandListRequest.setPageSize(5); + queryDemandListRequest.setCaseId("DEMAND_TEST_FUNCTIONAL_CASE_ID"); + MvcResult mvcResult = this.requestPostWithOkAndReturn(URL_DEMAND_PAGE, queryDemandListRequest); + Pager> tableData = JSON.parseObject(JSON.toJSONString( + JSON.parseObject(mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class).getData()), + Pager.class); + //返回值的页码和当前页码相同 + Assertions.assertEquals(tableData.getCurrent(), queryDemandListRequest.getCurrent()); + //返回的数据量不超过规定要返回的数据量相同 + Assertions.assertTrue(JSON.parseArray(JSON.toJSONString(tableData.getList())).size() <= queryDemandListRequest.getPageSize()); + + queryDemandListRequest = new QueryDemandListRequest(); + queryDemandListRequest.setCaseId("DEMAND_TEST_FUNCTIONAL_CASE_ID2"); + queryDemandListRequest.setCurrent(1); + queryDemandListRequest.setPageSize(5); + mvcResult = this.requestPostWithOkAndReturn(URL_DEMAND_PAGE, queryDemandListRequest); + tableData = JSON.parseObject(JSON.toJSONString( + JSON.parseObject(mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class).getData()), + Pager.class); + //返回值的页码和当前页码相同 + Assertions.assertEquals(tableData.getCurrent(), queryDemandListRequest.getCurrent()); + //返回的数据量为空 + Assertions.assertTrue(CollectionUtils.isEmpty(tableData.getList())); + } + + @Test + @Order(8) + public void cancelDemand() throws Exception { + String id = getId("DEMAND_TEST_FUNCTIONAL_CASE_ID"); + mockMvc.perform(MockMvcRequestBuilders.get(URL_DEMAND_CANCEL+id).header(SessionConstants.HEADER_TOKEN, sessionId) + .header(SessionConstants.CSRF_TOKEN, csrfToken) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + FunctionalCaseDemandExample functionalCaseDemandExample = new FunctionalCaseDemandExample(); + functionalCaseDemandExample.createCriteria().andCaseIdEqualTo("DEMAND_TEST_FUNCTIONAL_CASE_ID"); + List functionalCaseDemands = functionalCaseDemandMapper.selectByExample(functionalCaseDemandExample); + Assertions.assertTrue(CollectionUtils.isEmpty(functionalCaseDemands)); + } + + @Test + @Order(9) + public void batchRelevanceSuccess() throws Exception { + FunctionalCaseDemandRequest functionalCaseDemandRequest = new FunctionalCaseDemandRequest(); + functionalCaseDemandRequest.setCaseId("DEMAND_TEST_FUNCTIONAL_CASE_ID2"); + functionalCaseDemandRequest.setDemandPlatform("TAPD"); + List demandList = new ArrayList<>(); + DemandDTO demandDTO = new DemandDTO(); + demandDTO.setDemandId("100001"); + demandDTO.setDemandName("手动加入Tapd"); + demandList.add(demandDTO); + DemandDTO demandDTO2 = new DemandDTO(); + demandDTO2.setDemandId("100002"); + demandDTO2.setDemandName("手动加入Tapd1"); + demandList.add(demandDTO2); + DemandDTO demandDTO3 = new DemandDTO(); + demandDTO3.setDemandId("100003"); + demandDTO3.setDemandName("手动加入Tapd2"); + demandList.add(demandDTO3); + functionalCaseDemandRequest.setDemandList(demandList); + this.requestPostWithOkAndReturn(URL_DEMAND_BATCH_RELEVANCE, functionalCaseDemandRequest); + FunctionalCaseDemandExample functionalCaseDemandExample = new FunctionalCaseDemandExample(); + functionalCaseDemandExample.createCriteria().andCaseIdEqualTo("DEMAND_TEST_FUNCTIONAL_CASE_ID2"); + List functionalCaseDemands = functionalCaseDemandMapper.selectByExample(functionalCaseDemandExample); + Assertions.assertEquals(functionalCaseDemands.size(), demandList.size()); + } + + @Test + @Order(10) + public void batchRelevanceEmpty() throws Exception { + FunctionalCaseDemandRequest functionalCaseDemandRequest = new FunctionalCaseDemandRequest(); + functionalCaseDemandRequest.setCaseId("DEMAND_TEST_FUNCTIONAL_CASE_ID2"); + functionalCaseDemandRequest.setDemandPlatform("ZanDao"); + List demandList = new ArrayList<>(); + functionalCaseDemandRequest.setDemandList(demandList); + this.requestPostWithOkAndReturn(URL_DEMAND_BATCH_RELEVANCE, functionalCaseDemandRequest); + FunctionalCaseDemandExample functionalCaseDemandExample = new FunctionalCaseDemandExample(); + functionalCaseDemandExample.createCriteria().andCaseIdEqualTo("DEMAND_TEST_FUNCTIONAL_CASE_ID2").andDemandPlatformEqualTo("ZanDao"); + List functionalCaseDemands = functionalCaseDemandMapper.selectByExample(functionalCaseDemandExample); + Assertions.assertTrue(CollectionUtils.isEmpty(functionalCaseDemands)); + } + + @Test + @Order(11) + public void batchRelevanceFalse() throws Exception { + FunctionalCaseDemandRequest functionalCaseDemandRequest = new FunctionalCaseDemandRequest(); + functionalCaseDemandRequest.setCaseId("DEMAND_TEST_FUNCTIONAL_CASE_ID2"); + functionalCaseDemandRequest.setDemandPlatform("jira"); + List demandList = new ArrayList<>(); + DemandDTO demandDTO = new DemandDTO(); + demandDTO.setDemandId("100005"); + demandDTO.setDemandName("手动加入jira"); + demandList.add(demandDTO); + DemandDTO demandDTO2 = new DemandDTO(); + demandDTO2.setDemandId("100006"); + demandList.add(demandDTO2); + DemandDTO demandDTO3 = new DemandDTO(); + demandDTO3.setDemandId("100007"); + demandDTO3.setDemandName("手动加入jira2"); + demandList.add(demandDTO3); + functionalCaseDemandRequest.setDemandList(demandList); + this.requestPost(URL_DEMAND_BATCH_RELEVANCE, functionalCaseDemandRequest).andExpect(status().is5xxServerError()); + FunctionalCaseDemandExample functionalCaseDemandExample = new FunctionalCaseDemandExample(); + functionalCaseDemandExample.createCriteria().andCaseIdEqualTo("DEMAND_TEST_FUNCTIONAL_CASE_ID2").andDemandPlatformEqualTo("jira"); + List functionalCaseDemands = functionalCaseDemandMapper.selectByExample(functionalCaseDemandExample); + Assertions.assertTrue(CollectionUtils.isEmpty(functionalCaseDemands)); + } +} diff --git a/backend/services/case-management/src/test/resources/dml/init_case_demand.sql b/backend/services/case-management/src/test/resources/dml/init_case_demand.sql new file mode 100644 index 0000000000..3d9b5a4f69 --- /dev/null +++ b/backend/services/case-management/src/test/resources/dml/init_case_demand.sql @@ -0,0 +1,28 @@ + +INSERT INTO organization(id, num, name, description, create_time, update_time, create_user, update_user, deleted, delete_user, delete_time) VALUE + ('organization-case-demand-test', null, 'organization-case-demand-test', 'organization-case-demand-test', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'admin', 0, null, null); +INSERT INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time) VALUES + ('project-case-demand-test', null, 'organization-case-demand-test', '用例需求项目', '系统默认创建的项目', 'admin', 'admin', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000); + + +INSERT INTO template (id, name, remark, internal, update_time, create_time, create_user, scope_type, scope_id, enable_third_part, ref_id, scene) +VALUES ('test_template_case_demand_id', 'functional_case_demand_default', '', b'0', 1696992836000, 1696992836000, 'admin', 'PROJECT', 'project-case-demand-test', b'0', NULL, 'FUNCTIONAL'); + +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 ('DEMAND_TEST_FUNCTIONAL_CASE_ID', 1, 'DEMAND_TEST_MODULE_ID', 'project-case-demand-test', '100001', '关联需求测试', 'UN_REVIEWED', NULL, 'STEP', 0, 'v1.0.0', 'DEMAND_TEST_FUNCTIONAL_CASE_ID', 'UN_EXECUTED', true, b'0', b'0', 'gyq', 'gyq', '', 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 ('DEMAND_TEST_FUNCTIONAL_CASE_ID2', 1, 'DEMAND_TEST_MODULE_ID', 'project-case-demand-test', '100001', '关联需求测试', 'UN_REVIEWED', NULL, 'STEP', 0, 'v1.0.0', 'DEMAND_TEST_FUNCTIONAL_CASE_ID2', 'UN_EXECUTED', true, b'0', b'0', 'gyq', 'gyq', '', 1698058347559, 1698058347559, NULL); + +INSERT INTO functional_case_custom_field(case_id, field_id, value) VALUES ('DEMAND_TEST_FUNCTIONAL_CASE_ID', 'gyq_custom_id_demand1', '22'); +INSERT INTO functional_case_custom_field(case_id, field_id, value) VALUES ('DEMAND_TEST_FUNCTIONAL_CASE_ID', 'gyq_custom_id_demand2', '33'); + + + +INSERT INTO custom_field(id, name, scene, `type`, remark, internal, scope_type, create_time, update_time, create_user, scope_id) +VALUES('gyq_custom_id_demand1', 'functional_priority', 'FUNCTIONAL', 'SELECT', '', 1, 'ORGANIZATION', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'test_template_case_demand_id'); + +INSERT INTO custom_field(id, name, scene, `type`, remark, internal, scope_type, create_time, update_time, create_user, scope_id) +VALUES('gyq_custom_id_demand2', 'level', 'FUNCTIONAL', 'SELECT', '', 1, 'ORGANIZATION', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'test_template_case_demand_id'); + +INSERT INTO functional_case_module(id, project_id, name, parent_id, pos, create_time, update_time, create_user, update_user) VALUES ('DEMAND_TEST_MODULE_ID', 'project-case-demand-test', '测试需求所属模块', 'NONE', 0, 1669174143999, 1669174143999, 'admin', 'admin');