diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiTestCaseController.java b/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiTestCaseController.java index bb3d3b32ca..d139f0fa7b 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiTestCaseController.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiTestCaseController.java @@ -8,6 +8,7 @@ import io.metersphere.api.service.definition.ApiTestCaseLogService; import io.metersphere.api.service.definition.ApiTestCaseNoticeService; import io.metersphere.api.service.definition.ApiTestCaseService; import io.metersphere.sdk.constants.PermissionConstants; +import io.metersphere.system.dto.sdk.request.PosRequest; import io.metersphere.system.log.annotation.Log; import io.metersphere.system.log.constants.OperationLogType; import io.metersphere.system.notice.annotation.SendNotice; @@ -28,7 +29,7 @@ import java.util.List; @RestController -@RequestMapping(value = "/api/testCase") +@RequestMapping(value = "/api/case") @Tag(name = "接口测试-接口管理-接口用例") public class ApiTestCaseController { @Resource @@ -142,4 +143,12 @@ public class ApiTestCaseController { return PageUtils.setPageInfo(page, apiTestCaseService.page(request, true)); } + @PostMapping("edit/pos") + @Operation(summary = "接口测试-接口管理-接口用例-拖拽排序") + @RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_CASE_UPDATE) + public void editPos(@Validated @RequestBody PosRequest request) { + apiTestCaseService.editPos(request); + } + + } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiDefinitionBatchRequest.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiDefinitionBatchRequest.java index 8f4fc5853e..48d4ff5664 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiDefinitionBatchRequest.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiDefinitionBatchRequest.java @@ -33,7 +33,7 @@ public class ApiDefinitionBatchRequest extends TableBatchProcessDTO implements S private String protocol = ModuleConstants.NODE_PROTOCOL_HTTP; @Schema(description = "模块ID(根据模块树查询时要把当前节点以及子节点都放在这里。)") - private List moduleIds; + private List<@NotBlank String> moduleIds; @Schema(description = "删除列表版本/删除全部版本") private Boolean deleteAll = false; diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiDefinitionPageRequest.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiDefinitionPageRequest.java index 36c369b5b3..4c82aabfb8 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiDefinitionPageRequest.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiDefinitionPageRequest.java @@ -44,7 +44,7 @@ public class ApiDefinitionPageRequest extends BasePageRequest { private String refId; @Schema(description = "模块ID(根据模块树查询时要把当前节点以及子节点都放在这里。)") - private List moduleIds; + private List<@NotBlank String> moduleIds; @Schema(description = "删除状态(状态为 1 时为回收站数据)") private Boolean deleted = false; diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiModuleRequest.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiModuleRequest.java index b9cd0eda44..9d1728f6d1 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiModuleRequest.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiModuleRequest.java @@ -11,7 +11,7 @@ import java.util.List; @Data public class ApiModuleRequest { @Schema(description = "模块ID(根据模块树查询时要把当前节点以及子节点都放在这里。)") - private List moduleIds; + private List<@NotBlank String> moduleIds; @Schema(description = "协议", requiredMode = Schema.RequiredMode.REQUIRED) @NotBlank(message = "{api_definition_module.protocol.not_blank}") diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiTestCaseBatchRequest.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiTestCaseBatchRequest.java index 156650adf6..01e9325d4f 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiTestCaseBatchRequest.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiTestCaseBatchRequest.java @@ -31,7 +31,7 @@ public class ApiTestCaseBatchRequest extends TableBatchProcessDTO implements Ser private String protocol = ModuleConstants.NODE_PROTOCOL_HTTP; @Schema(description = "模块ID") - private List moduleIds; + private List<@NotBlank String> moduleIds; @Schema(description = "版本fk") private String versionId; diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiTestCaseLogDTO.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiTestCaseLogDTO.java new file mode 100644 index 0000000000..6962a54eab --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiTestCaseLogDTO.java @@ -0,0 +1,13 @@ +package io.metersphere.api.dto.definition; + +import io.metersphere.api.domain.ApiTestCase; +import io.metersphere.plugin.api.spi.AbstractMsTestElement; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class ApiTestCaseLogDTO extends ApiTestCase { + + @Schema(description = "请求内容") + private AbstractMsTestElement request; +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiTestCasePageRequest.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiTestCasePageRequest.java index c7a9b7e7dc..978286f921 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiTestCasePageRequest.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiTestCasePageRequest.java @@ -33,7 +33,7 @@ public class ApiTestCasePageRequest extends BasePageRequest { private String protocol = ModuleConstants.NODE_PROTOCOL_HTTP; @Schema(description = "模块ID") - private List moduleIds; + private List<@NotBlank String> moduleIds; @Schema(description = "版本fk") private String versionId; diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiTestCaseMapper.java b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiTestCaseMapper.java index afa03daaeb..7de7086ee4 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiTestCaseMapper.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiTestCaseMapper.java @@ -29,4 +29,8 @@ public interface ExtApiTestCaseMapper { List getCaseInfoByApiIds(@Param("ids") List apiIds, @Param("deleted") boolean deleted); List getCaseInfoByIds(@Param("ids") List caseIds, @Param("deleted") boolean deleted); + + Long getPrePos(@Param("projectId") String projectId, @Param("basePos") Long basePos); + + Long getLastPos(@Param("projectId") String projectId, @Param("basePos") Long basePos); } \ No newline at end of file diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiTestCaseMapper.xml b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiTestCaseMapper.xml index 3f86843863..54211a1832 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiTestCaseMapper.xml +++ b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiTestCaseMapper.xml @@ -75,6 +75,23 @@ + + + + + and a.protocol = #{request.protocol} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseLogService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseLogService.java index f586bb33eb..93cb15c982 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseLogService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseLogService.java @@ -1,12 +1,20 @@ package io.metersphere.api.service.definition; import io.metersphere.api.domain.ApiTestCase; +import io.metersphere.api.domain.ApiTestCaseBlob; +import io.metersphere.api.domain.ApiTestCaseBlobExample; +import io.metersphere.api.domain.ApiTestCaseExample; import io.metersphere.api.dto.definition.ApiTestCaseAddRequest; +import io.metersphere.api.dto.definition.ApiTestCaseLogDTO; import io.metersphere.api.dto.definition.ApiTestCaseUpdateRequest; +import io.metersphere.api.mapper.ApiTestCaseBlobMapper; import io.metersphere.api.mapper.ApiTestCaseMapper; +import io.metersphere.api.util.ApiDataUtils; +import io.metersphere.plugin.api.spi.AbstractMsTestElement; import io.metersphere.project.domain.Project; import io.metersphere.project.mapper.ProjectMapper; import io.metersphere.sdk.constants.HttpMethodConstants; +import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.Translator; import io.metersphere.system.dto.builder.LogDTOBuilder; @@ -19,6 +27,8 @@ import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; @Service public class ApiTestCaseLogService { @@ -29,6 +39,8 @@ public class ApiTestCaseLogService { private ProjectMapper projectMapper; @Resource private OperationLogService operationLogService; + @Resource + private ApiTestCaseBlobMapper apiTestCaseBlobMapper; /** * 添加接口日志 @@ -47,7 +59,7 @@ public class ApiTestCaseLogService { OperationLogModule.API_DEFINITION_CASE, request.getName()); - dto.setPath("/api/testCase/add"); + dto.setPath("/api/case/add"); dto.setMethod(HttpMethodConstants.POST.name()); dto.setOriginalValue(JSON.toJSONBytes(request)); return dto; @@ -65,7 +77,7 @@ public class ApiTestCaseLogService { OperationLogModule.API_DEFINITION_CASE, apiTestCase.getName()); - dto.setPath("/api/testCase/delete/" + id); + dto.setPath("/api/case/delete/" + id); dto.setMethod(HttpMethodConstants.GET.name()); dto.setOriginalValue(JSON.toJSONBytes(apiTestCase)); return dto; @@ -83,7 +95,7 @@ public class ApiTestCaseLogService { OperationLogModule.API_DEFINITION_CASE, apiTestCase.getName()); - dto.setPath("/api/testCase/move-gc/" + id); + dto.setPath("/api/case/move-gc/" + id); dto.setMethod(HttpMethodConstants.GET.name()); dto.setOriginalValue(JSON.toJSONBytes(apiTestCase)); return dto; @@ -101,7 +113,7 @@ public class ApiTestCaseLogService { OperationLogModule.API_DEFINITION_CASE, apiTestCase.getName()); - dto.setPath("/api/testCase/recover/" + id); + dto.setPath("/api/case/recover/" + id); dto.setMethod(HttpMethodConstants.GET.name()); dto.setOriginalValue(JSON.toJSONBytes(apiTestCase)); return dto; @@ -119,7 +131,7 @@ public class ApiTestCaseLogService { OperationLogModule.API_DEFINITION_CASE, Translator.get("follow") + apiTestCase.getName()); - dto.setPath("/api/testCase/follow/" + id); + dto.setPath("/api/case/follow/" + id); dto.setMethod(HttpMethodConstants.GET.name()); dto.setOriginalValue(JSON.toJSONBytes(apiTestCase)); return dto; @@ -137,7 +149,7 @@ public class ApiTestCaseLogService { OperationLogModule.API_DEFINITION_CASE, Translator.get("unfollow") + apiTestCase.getName()); - dto.setPath("/api/testCase/unfollow/" + id); + dto.setPath("/api/case/unfollow/" + id); dto.setMethod(HttpMethodConstants.GET.name()); dto.setOriginalValue(JSON.toJSONBytes(apiTestCase)); return dto; @@ -145,6 +157,7 @@ public class ApiTestCaseLogService { public LogDTO updateLog(ApiTestCaseUpdateRequest request) { ApiTestCase apiTestCase = apiTestCaseMapper.selectByPrimaryKey(request.getId()); + ApiTestCaseBlob apiTestCaseBlob = apiTestCaseBlobMapper.selectByPrimaryKey(request.getId()); Project project = projectMapper.selectByPrimaryKey(apiTestCase.getProjectId()); LogDTO dto = new LogDTO( apiTestCase.getProjectId(), @@ -155,14 +168,18 @@ public class ApiTestCaseLogService { OperationLogModule.API_DEFINITION_CASE, request.getName()); - dto.setPath("/api/testCase/update"); + dto.setPath("/api/case/update"); dto.setMethod(HttpMethodConstants.POST.name()); - dto.setOriginalValue(JSON.toJSONBytes(request)); + ApiTestCaseLogDTO apiTestCaseDTO = new ApiTestCaseLogDTO(); + BeanUtils.copyBean(apiTestCaseDTO, apiTestCase); + apiTestCaseDTO.setRequest(ApiDataUtils.parseObject(new String(apiTestCaseBlob.getRequest()), AbstractMsTestElement.class)); + dto.setOriginalValue(JSON.toJSONBytes(apiTestCaseDTO)); return dto; } public LogDTO updateLog(String id) { ApiTestCase apiTestCase = apiTestCaseMapper.selectByPrimaryKey(id); + ApiTestCaseBlob apiTestCaseBlob = apiTestCaseBlobMapper.selectByPrimaryKey(id); Project project = projectMapper.selectByPrimaryKey(apiTestCase.getProjectId()); LogDTO dto = new LogDTO( apiTestCase.getProjectId(), @@ -173,9 +190,12 @@ public class ApiTestCaseLogService { OperationLogModule.API_DEFINITION_CASE, apiTestCase.getName()); - dto.setPath("/api/testCase/update"); + dto.setPath("/api/case/update"); dto.setMethod(HttpMethodConstants.POST.name()); - dto.setOriginalValue(JSON.toJSONBytes(apiTestCase)); + ApiTestCaseLogDTO apiTestCaseDTO = new ApiTestCaseLogDTO(); + BeanUtils.copyBean(apiTestCaseDTO, apiTestCase); + apiTestCaseDTO.setRequest(ApiDataUtils.parseObject(new String(apiTestCaseBlob.getRequest()), AbstractMsTestElement.class)); + dto.setOriginalValue(JSON.toJSONBytes(apiTestCaseDTO)); return dto; } @@ -189,7 +209,7 @@ public class ApiTestCaseLogService { .type(OperationLogType.DELETE.name()) .module(OperationLogModule.API_DEFINITION_CASE) .method(HttpMethodConstants.POST.name()) - .path("/api/testCase/batch/delete") + .path("/api/case/batch/delete") .sourceId(item.getId()) .content(item.getName()) .createUser(operator) @@ -210,7 +230,7 @@ public class ApiTestCaseLogService { .type(OperationLogType.DELETE.name()) .module(OperationLogModule.API_DEFINITION_CASE) .method(HttpMethodConstants.POST.name()) - .path("/api/testCase/batch/move-gc") + .path("/api/case/batch/move-gc") .sourceId(item.getId()) .content(item.getName()) .createUser(operator) @@ -223,18 +243,36 @@ public class ApiTestCaseLogService { public void batchEditLog(List apiTestCases, String operator, String projectId) { Project project = projectMapper.selectByPrimaryKey(projectId); + //取出apiTestCases所有的id为新的list + List caseId = apiTestCases.stream().map(ApiTestCase::getId).distinct().toList(); + ApiTestCaseExample example = new ApiTestCaseExample(); + example.createCriteria().andIdIn(caseId); + List apiTestCaseList = apiTestCaseMapper.selectByExample(example); + //apiTestCaseList按id生成新的map key为id value为ApiTestCase + Map caseMap = apiTestCaseList.stream().collect(Collectors.toMap(ApiTestCase::getId, a -> a)); + ApiTestCaseBlobExample blobExample = new ApiTestCaseBlobExample(); + blobExample.createCriteria().andIdIn(caseId); + List blobList = apiTestCaseBlobMapper.selectByExampleWithBLOBs(blobExample); + //blobList按id生成新的map key为id value为ApiTestCaseBlob + Map blobMap = blobList.stream().collect(Collectors.toMap(ApiTestCaseBlob::getId, a -> a)); List logs = new ArrayList<>(); apiTestCases.forEach(item -> { - LogDTO dto = LogDTOBuilder.builder() + ApiTestCaseLogDTO apiTestCaseDTO = new ApiTestCaseLogDTO(); + BeanUtils.copyBean(apiTestCaseDTO, caseMap.get(item.getId())); + if (blobMap.get(item.getId()) != null) { + apiTestCaseDTO.setRequest(ApiDataUtils.parseObject(new String(blobMap.get(item.getId()).getRequest()), AbstractMsTestElement.class)); + } + LogDTO dto = LogDTOBuilder.builder() .projectId(project.getId()) .organizationId(project.getOrganizationId()) .type(OperationLogType.DELETE.name()) .module(OperationLogModule.API_DEFINITION_CASE) .method(HttpMethodConstants.POST.name()) - .path("/api/testCase/batch/move-gc") + .path("/api/case/batch/edit") .sourceId(item.getId()) .content(item.getName()) .createUser(operator) + .originalValue(JSON.toJSONBytes(apiTestCaseDTO)) .build().getLogDTO(); logs.add(dto); } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseService.java index c61221e074..7ed00b2c5b 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseService.java @@ -18,11 +18,13 @@ import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.mapper.EnvironmentMapper; import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.JSON; +import io.metersphere.sdk.util.SubListUtils; import io.metersphere.sdk.util.Translator; -import io.metersphere.system.file.MinioRepository; +import io.metersphere.system.dto.sdk.request.PosRequest; import io.metersphere.system.service.UserLoginService; import io.metersphere.system.uid.IDGenerator; import io.metersphere.system.uid.NumGenerator; +import io.metersphere.system.utils.ServiceUtils; import jakarta.annotation.Resource; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; @@ -65,8 +67,6 @@ public class ApiTestCaseService { @Resource private ApiTestCaseFollowerMapper apiTestCaseFollowerMapper; @Resource - private MinioRepository minioRepository; - @Resource private UserLoginService userLoginService; @Resource private EnvironmentMapper environmentMapper; @@ -315,15 +315,9 @@ public class ApiTestCaseService { if (CollectionUtils.isEmpty(ids)) { return; } - while (!ids.isEmpty()) { - if (ids.size() <= 2000) { - deleteResourceByIds(ids, request.getProjectId(), userId); - break; - } - List subList = ids.subList(0, 2000); + SubListUtils.dealForSubList(ids, 2000, subList -> { deleteResourceByIds(subList, request.getProjectId(), userId); - ids.removeAll(subList); - } + }); } public void deleteResourceByIds(List ids, String projectId, String userId) { @@ -374,15 +368,9 @@ public class ApiTestCaseService { if (CollectionUtils.isEmpty(ids)) { return; } - while (!ids.isEmpty()) { - if (ids.size() <= 2000) { - batchMoveToGc(ids, userId, projectId, saveLog); - break; - } - List subList = ids.subList(0, 2000); + SubListUtils.dealForSubList(ids, 2000, subList -> { batchMoveToGc(subList, userId, projectId, saveLog); - ids.removeAll(subList); - } + }); } private void batchMoveToGc(List ids, String userId, String projectId, boolean saveLog) { @@ -398,15 +386,9 @@ public class ApiTestCaseService { if (CollectionUtils.isEmpty(ids)) { return; } - while (!ids.isEmpty()) { - if (ids.size() <= 2000) { - batchEditByType(request, ids, userId, request.getProjectId()); - break; - } - List subList = ids.subList(0, 2000); + SubListUtils.dealForSubList(ids, 2000, subList -> { batchEditByType(request, subList, userId, request.getProjectId()); - ids.removeAll(subList); - } + }); } private void batchEditByType(ApiCaseBatchEditRequest request, List ids, String userId, String projectId) { @@ -487,4 +469,13 @@ public class ApiTestCaseService { updateCase.setPriority(priority); apiTestCaseMapper.updateByExampleSelective(updateCase, example); } + + public void editPos(PosRequest request) { + ServiceUtils.updatePosField(request, + ApiTestCase.class, + apiTestCaseMapper::selectByPrimaryKey, + extApiTestCaseMapper::getPrePos, + extApiTestCaseMapper::getLastPos, + apiTestCaseMapper::updateByPrimaryKeySelective); + } } diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionModuleControllerTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionModuleControllerTests.java index f288491c75..46288d2aa2 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionModuleControllerTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionModuleControllerTests.java @@ -5,16 +5,14 @@ import io.metersphere.api.dto.debug.ApiDebugRequest; import io.metersphere.api.dto.debug.ModuleCreateRequest; import io.metersphere.api.dto.debug.ModuleUpdateRequest; import io.metersphere.api.dto.definition.ApiModuleRequest; -import io.metersphere.api.mapper.ApiDefinitionBlobMapper; -import io.metersphere.api.mapper.ApiDefinitionMapper; -import io.metersphere.api.mapper.ApiDefinitionModuleMapper; -import io.metersphere.api.mapper.ApiTestCaseMapper; +import io.metersphere.api.mapper.*; import io.metersphere.api.service.definition.ApiDefinitionModuleService; import io.metersphere.project.domain.Project; import io.metersphere.project.mapper.ProjectMapper; import io.metersphere.sdk.constants.ApplicationNumScope; import io.metersphere.sdk.constants.ModuleConstants; import io.metersphere.sdk.constants.PermissionConstants; +import io.metersphere.sdk.dto.api.request.http.MsHTTPElement; import io.metersphere.sdk.util.JSON; import io.metersphere.system.base.BaseTest; import io.metersphere.system.controller.handler.ResultHolder; @@ -26,7 +24,11 @@ import io.metersphere.system.uid.IDGenerator; import io.metersphere.system.uid.NumGenerator; import jakarta.annotation.Resource; import org.apache.commons.collections4.CollectionUtils; +import org.apache.ibatis.session.ExecutorType; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; import org.junit.jupiter.api.*; +import org.mybatis.spring.SqlSessionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; @@ -70,7 +72,7 @@ public class ApiDefinitionModuleControllerTests extends BaseTest { @Resource private ApiDefinitionModuleService apiDefinitionModuleService; @Resource - private ApiTestCaseMapper apiTestCaseMapper; + private SqlSessionFactory sqlSessionFactory; @Autowired public ApiDefinitionModuleControllerTests(ProjectServiceInvoker serviceInvoker) { @@ -148,7 +150,10 @@ public class ApiDefinitionModuleControllerTests extends BaseTest { apiDefinitionBlob.setResponse(new byte[0]); apiDefinitionBlobMapper.insertSelective(apiDefinitionBlob); - List apiTestCasesList = new ArrayList<>(); + MsHTTPElement msHttpElement = MsHTTPElementTest.getMsHttpElement(); + SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); + ApiTestCaseMapper caseMapper = sqlSession.getMapper(ApiTestCaseMapper.class); + ApiTestCaseBlobMapper caseBlobMapper = sqlSession.getMapper(ApiTestCaseBlobMapper.class); for (int i = 0; i < 100; i++) { ApiTestCase apiTestCase = new ApiTestCase(); apiTestCase.setId(IDGenerator.nextStr()); @@ -165,9 +170,14 @@ public class ApiDefinitionModuleControllerTests extends BaseTest { apiTestCase.setUpdateUser("admin"); apiTestCase.setVersionId("1.0"); apiTestCase.setDeleted(false); - apiTestCasesList.add(apiTestCase); + caseMapper.insert(apiTestCase); + ApiTestCaseBlob apiTestCaseBlob = new ApiTestCaseBlob(); + apiTestCaseBlob.setId(apiTestCase.getId()); + apiTestCaseBlob.setRequest(JSON.toJSONBytes(msHttpElement)); + caseBlobMapper.insert(apiTestCaseBlob); } - apiTestCaseMapper.batchInsert(apiTestCasesList); + sqlSession.flushStatements(); + SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); } @Test diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiTestCaseControllerTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiTestCaseControllerTests.java index c8a0d5e468..fadbb42b23 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiTestCaseControllerTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiTestCaseControllerTests.java @@ -20,14 +20,20 @@ import io.metersphere.sdk.util.CommonBeanFactory; import io.metersphere.sdk.util.JSON; import io.metersphere.system.base.BaseTest; import io.metersphere.system.controller.handler.ResultHolder; +import io.metersphere.system.dto.sdk.request.PosRequest; import io.metersphere.system.file.FileRequest; import io.metersphere.system.file.MinioRepository; import io.metersphere.system.log.constants.OperationLogType; import io.metersphere.system.uid.NumGenerator; import io.metersphere.system.utils.Pager; +import io.metersphere.system.utils.ServiceUtils; import jakarta.annotation.Resource; import org.apache.commons.collections.CollectionUtils; +import org.apache.ibatis.session.ExecutorType; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; import org.junit.jupiter.api.*; +import org.mybatis.spring.SqlSessionUtils; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; @@ -53,7 +59,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @AutoConfigureMockMvc @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class ApiTestCaseControllerTests extends BaseTest { - private static final String BASE_PATH = "/api/testCase/"; + private static final String BASE_PATH = "/api/case/"; private static final String ADD = BASE_PATH + "add"; private static final String GET = BASE_PATH + "get-detail/"; private static final String MOVE_TO_GC = BASE_PATH + "move-gc/"; @@ -68,6 +74,7 @@ public class ApiTestCaseControllerTests extends BaseTest { private static final String BATCH_EDIT = BASE_PATH + "batch/edit"; private static final String BATCH_DELETE = BASE_PATH + "batch/delete"; private static final String BATCH_MOVE_GC = BASE_PATH + "batch/move-gc"; + private static final String POS_URL = BASE_PATH + "/edit/pos"; private static final ResultMatcher ERROR_REQUEST_MATCHER = status().is5xxServerError(); private static ApiTestCase apiTestCase; @@ -87,6 +94,10 @@ public class ApiTestCaseControllerTests extends BaseTest { private EnvironmentMapper environmentMapper; @Resource private ApiFileResourceService apiFileResourceService; + @Resource + private SqlSessionFactory sqlSessionFactory; + @Resource + private ExtApiTestCaseMapper extApiTestCaseMapper; public static T parseObjectFromMvcResult(MvcResult mvcResult, Class parseClass) { try { @@ -142,7 +153,10 @@ public class ApiTestCaseControllerTests extends BaseTest { public void initCaseData() { //2000条数据 - List apiTestCasesList = new ArrayList<>(); + MsHTTPElement msHttpElement = MsHTTPElementTest.getMsHttpElement(); + SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); + ApiTestCaseMapper caseMapper = sqlSession.getMapper(ApiTestCaseMapper.class); + ApiTestCaseBlobMapper caseBlobMapper = sqlSession.getMapper(ApiTestCaseBlobMapper.class); for (int i = 0; i < 2100; i++) { ApiTestCase apiTestCase = new ApiTestCase(); apiTestCase.setId("apiTestCaseId" + i); @@ -159,10 +173,14 @@ public class ApiTestCaseControllerTests extends BaseTest { apiTestCase.setUpdateUser("admin"); apiTestCase.setVersionId("1.0"); apiTestCase.setDeleted(false); - apiTestCasesList.add(apiTestCase); + caseMapper.insert(apiTestCase); + ApiTestCaseBlob apiTestCaseBlob = new ApiTestCaseBlob(); + apiTestCaseBlob.setId(apiTestCase.getId()); + apiTestCaseBlob.setRequest(JSON.toJSONBytes(msHttpElement)); + caseBlobMapper.insert(apiTestCaseBlob); } - apiTestCaseMapper.batchInsert(apiTestCasesList); - + sqlSession.flushStatements(); + SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); } @@ -408,6 +426,38 @@ public class ApiTestCaseControllerTests extends BaseTest { @Test @Order(8) + public void testPos() throws Exception { + PosRequest posRequest = new PosRequest(); + posRequest.setProjectId(DEFAULT_PROJECT_ID); + posRequest.setTargetId(apiTestCase.getId()); + posRequest.setMoveId(anotherApiTestCase.getId()); + posRequest.setMoveMode("AFTER"); + this.requestPostWithOkAndReturn(POS_URL, posRequest); + + posRequest.setMoveMode("BEFORE"); + this.requestPostWithOkAndReturn(POS_URL, posRequest); + + } + + @Test + @Order(9) + public void test() throws Exception { + PosRequest request = new PosRequest(); + request.setProjectId(DEFAULT_PROJECT_ID); + request.setTargetId(apiTestCase.getId()); + request.setMoveId(anotherApiTestCase.getId()); + request.setMoveMode("AFTER"); + + ServiceUtils.updatePosField(request, + ApiTestCase.class, + apiTestCaseMapper::selectByPrimaryKey, + extApiTestCaseMapper::getPrePos, + extApiTestCaseMapper::getLastPos, + apiTestCaseMapper::updateByPrimaryKeySelective); + } + + @Test + @Order(10) public void page() throws Exception { // @@请求成功 ApiTestCaseAddRequest request = new ApiTestCaseAddRequest(); @@ -469,7 +519,7 @@ public class ApiTestCaseControllerTests extends BaseTest { } @Test - @Order(9) + @Order(11) public void updateStatus() throws Exception { // @@请求成功 this.requestGetWithOk(UPDATE_STATUS + "/" + apiTestCase.getId() + "/Underway"); @@ -483,7 +533,7 @@ public class ApiTestCaseControllerTests extends BaseTest { } @Test - @Order(10) + @Order(12) public void batchEdit() throws Exception { // 追加标签 ApiCaseBatchEditRequest request = new ApiCaseBatchEditRequest(); @@ -586,7 +636,7 @@ public class ApiTestCaseControllerTests extends BaseTest { } @Test - @Order(11) + @Order(13) public void batchMoveGc() throws Exception { // @@请求成功 ApiTestCaseBatchRequest request = new ApiTestCaseBatchRequest(); @@ -616,7 +666,7 @@ public class ApiTestCaseControllerTests extends BaseTest { } @Test - @Order(12) + @Order(14) public void trashPage() throws Exception { // @@请求成功 ApiTestCasePageRequest pageRequest = new ApiTestCasePageRequest(); diff --git a/backend/services/api-test/src/test/resources/application.properties b/backend/services/api-test/src/test/resources/application.properties index 063627b5c4..dd57bbbe17 100644 --- a/backend/services/api-test/src/test/resources/application.properties +++ b/backend/services/api-test/src/test/resources/application.properties @@ -85,6 +85,6 @@ minio.endpoint=http://${embedded.minio.host}:${embedded.minio.port} minio.access-key=${embedded.minio.accessKey} minio.secret-key=${embedded.minio.secretKey} -logging.level.org.springframework.jdbc.core=info -logging.level.io.metersphere.sdk.mapper=info -logging.level.io.metersphere.project.mapper=info \ No newline at end of file +logging.level.org.springframework.jdbc.core=debug +logging.level.io.metersphere.sdk.mapper=debug +logging.level.io.metersphere.project.mapper=debug \ No newline at end of file diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/ExtGetPosService.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/ExtGetPosService.java new file mode 100644 index 0000000000..0aee065e1a --- /dev/null +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/ExtGetPosService.java @@ -0,0 +1,17 @@ +package io.metersphere.system.controller; + + +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Service; + +@Service +public class ExtGetPosService { + + public Long getPrePos(@Param("projectId") String projectId, @Param("basePos") Long basePos) { + return 100L; + } + + public Long getLastPos(@Param("projectId") String projectId, @Param("basePos") Long basePos) { + return 120L; + } +} \ No newline at end of file diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/SystemProjectControllerTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/SystemProjectControllerTests.java index 0be847e8f1..962e6a31fa 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/SystemProjectControllerTests.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/SystemProjectControllerTests.java @@ -1,5 +1,7 @@ package io.metersphere.system.controller; +import io.metersphere.api.domain.ApiTestCase; +import io.metersphere.api.mapper.ApiTestCaseMapper; import io.metersphere.project.domain.Project; import io.metersphere.project.domain.ProjectExample; import io.metersphere.project.domain.ProjectTestResourcePool; @@ -18,6 +20,7 @@ import io.metersphere.system.dto.request.ProjectAddMemberRequest; import io.metersphere.system.dto.request.ProjectMemberRequest; import io.metersphere.system.dto.request.ProjectRequest; import io.metersphere.system.dto.sdk.request.CustomFieldOptionRequest; +import io.metersphere.system.dto.sdk.request.PosRequest; import io.metersphere.system.dto.sdk.request.TemplateCustomFieldRequest; import io.metersphere.system.dto.sdk.request.TemplateUpdateRequest; import io.metersphere.system.dto.user.UserExtendDTO; @@ -28,7 +31,9 @@ import io.metersphere.system.mapper.OrganizationParameterMapper; import io.metersphere.system.mapper.UserMapper; import io.metersphere.system.mapper.UserRoleRelationMapper; import io.metersphere.system.service.*; +import io.metersphere.system.uid.NumGenerator; import io.metersphere.system.utils.Pager; +import io.metersphere.system.utils.ServiceUtils; import jakarta.annotation.Resource; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; @@ -109,6 +114,10 @@ public class SystemProjectControllerTests extends BaseTest { @Resource private CleanProjectJob cleanProjectJob; private final ProjectServiceInvoker serviceInvoker; + @Resource + private ApiTestCaseMapper apiTestCaseMapper; + @Resource + private ExtGetPosService extGetPosService; @Autowired public SystemProjectControllerTests(ProjectServiceInvoker serviceInvoker) { @@ -1147,4 +1156,64 @@ public class SystemProjectControllerTests extends BaseTest { this.requestPost(updateName, project, ERROR_REQUEST_MATCHER); } + + @Test + @Order(26) + public void test() throws Exception { + ApiTestCase apiTestCase = new ApiTestCase(); + apiTestCase.setId("test-apiTestCaseId"); + apiTestCase.setApiDefinitionId("apiDefinitionId"); + apiTestCase.setProjectId(DEFAULT_PROJECT_ID); + apiTestCase.setName("test-apiTestCaseName"); + apiTestCase.setPriority("P0"); + apiTestCase.setStatus("Underway"); + apiTestCase.setNum(NumGenerator.nextNum(DEFAULT_PROJECT_ID + "_" + "100001", ApplicationNumScope.API_TEST_CASE)); + apiTestCase.setPos(100L); + apiTestCase.setCreateTime(System.currentTimeMillis()); + apiTestCase.setUpdateTime(System.currentTimeMillis()); + apiTestCase.setCreateUser("admin"); + apiTestCase.setUpdateUser("admin"); + apiTestCase.setVersionId("1.0"); + apiTestCase.setDeleted(false); + apiTestCaseMapper.insert(apiTestCase); + ApiTestCase anotherCase = new ApiTestCase(); + anotherCase.setId("test-apiTestCaseId1"); + anotherCase.setApiDefinitionId("apiDefinitionId"); + anotherCase.setProjectId(DEFAULT_PROJECT_ID); + anotherCase.setName("test-apiTestCaseName1"); + anotherCase.setPriority("P0"); + anotherCase.setStatus("Underway"); + anotherCase.setNum(NumGenerator.nextNum(DEFAULT_PROJECT_ID + "_" + "100001", ApplicationNumScope.API_TEST_CASE)); + anotherCase.setPos(120L); + anotherCase.setCreateTime(System.currentTimeMillis()); + anotherCase.setUpdateTime(System.currentTimeMillis()); + anotherCase.setCreateUser("admin"); + anotherCase.setUpdateUser("admin"); + anotherCase.setVersionId("1.0"); + anotherCase.setDeleted(false); + apiTestCaseMapper.insert(anotherCase); + PosRequest request = new PosRequest(); + request.setProjectId(DEFAULT_PROJECT_ID); + request.setTargetId(apiTestCase.getId()); + request.setMoveId(anotherCase.getId()); + request.setMoveMode("AFTER"); + + ServiceUtils.updatePosField(request, + ApiTestCase.class, + apiTestCaseMapper::selectByPrimaryKey, + extGetPosService::getPrePos, + extGetPosService::getLastPos, + apiTestCaseMapper::updateByPrimaryKeySelective); + + request.setMoveMode("BEFORE"); + ServiceUtils.updatePosField(request, + ApiTestCase.class, + apiTestCaseMapper::selectByPrimaryKey, + extGetPosService::getPrePos, + extGetPosService::getLastPos, + apiTestCaseMapper::updateByPrimaryKeySelective); + apiTestCaseMapper.deleteByPrimaryKey(apiTestCase.getId()); + apiTestCaseMapper.deleteByPrimaryKey(anotherCase.getId()); + } + }