feat(接口测试): 定义分享详情补充插件脚本接口

This commit is contained in:
song-cc-rock 2024-10-24 14:32:12 +08:00 committed by Craftsman
parent 7b13836e80
commit 675b9c88ec
5 changed files with 60 additions and 2 deletions

View File

@ -112,6 +112,7 @@ public class FilterChainUtils {
filterChainDefinitionMap.put("/api/doc/share/export/**", "anon"); filterChainDefinitionMap.put("/api/doc/share/export/**", "anon");
filterChainDefinitionMap.put("/api/doc/share/stop/**", "anon"); filterChainDefinitionMap.put("/api/doc/share/stop/**", "anon");
filterChainDefinitionMap.put("/api/doc/share/download/file/**", "anon"); filterChainDefinitionMap.put("/api/doc/share/download/file/**", "anon");
filterChainDefinitionMap.put("/api/doc/share/plugin/script/**", "anon");
return filterChainDefinitionMap; return filterChainDefinitionMap;
} }

View File

@ -25,6 +25,7 @@ import io.metersphere.validation.groups.Created;
import io.metersphere.validation.groups.Updated; import io.metersphere.validation.groups.Updated;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@ -125,26 +126,43 @@ public class ApiDocShareController {
@PostMapping("/export/{type}") @PostMapping("/export/{type}")
@Operation(summary = "接口测试-定义-分享-导出") @Operation(summary = "接口测试-定义-分享-导出")
@Parameter(name = "type", description = "导出类型", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED))
public String export(@RequestBody ApiDocShareExportRequest request, @PathVariable String type) { public String export(@RequestBody ApiDocShareExportRequest request, @PathVariable String type) {
return apiDocShareService.export(request, type, SessionUtils.getUserId()); return apiDocShareService.export(request, type, SessionUtils.getUserId());
} }
@GetMapping("/stop/{taskId}") @GetMapping("/stop/{taskId}")
@Operation(summary = "接口测试-定义-分享-导出-停止导出") @Operation(summary = "接口测试-定义-分享-导出-停止导出")
@Parameter(name = "taskId", description = "导出任务ID", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED))
public void caseStopExport(@PathVariable String taskId) { public void caseStopExport(@PathVariable String taskId) {
apiDefinitionExportService.stopExport(taskId, SessionUtils.getUserId()); apiDefinitionExportService.stopExport(taskId, SessionUtils.getUserId());
} }
@GetMapping(value = "/download/file/{projectId}/{fileId}") @GetMapping(value = "/download/file/{projectId}/{fileId}")
@Operation(summary = "接口测试-定义-分享-导出-下载文件") @Operation(summary = "接口测试-定义-分享-导出-下载文件")
@Parameters({
@Parameter(name = "projectId", description = "项目ID", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED)),
@Parameter(name = "fileId", description = "文件ID", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED))
})
public void downloadImgById(@PathVariable String projectId, @PathVariable String fileId, HttpServletResponse httpServletResponse) { public void downloadImgById(@PathVariable String projectId, @PathVariable String fileId, HttpServletResponse httpServletResponse) {
apiDefinitionExportService.downloadFile(projectId, fileId, SessionUtils.getUserId(), httpServletResponse); apiDefinitionExportService.downloadFile(projectId, fileId, SessionUtils.getUserId(), httpServletResponse);
} }
@GetMapping(value = "/get-detail/{id}") @GetMapping(value = "/get-detail/{id}")
@Operation(summary = "接口测试-接口管理-获取接口详情") @Operation(summary = "接口测试-接口管理-获取接口详情")
@Parameter(name = "id", description = "接口定义ID", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED))
public ApiDefinitionDTO get(@PathVariable String id) { public ApiDefinitionDTO get(@PathVariable String id) {
return apiDefinitionService.get(id, "admin"); return apiDefinitionService.get(id, "admin");
} }
@GetMapping("/plugin/script/{id}/{orgId}")
@Operation(summary = "获取定义的插件脚本")
@Parameters({
@Parameter(name = "id", description = "接口定义ID", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED)),
@Parameter(name = "orgId", description = "组织ID", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED))
})
public Object getApiProtocolScript(@PathVariable String id, @PathVariable String orgId) {
return apiDocShareService.getApiProtocolScript(id, orgId);
}
} }

View File

@ -2,18 +2,21 @@ package io.metersphere.api.service.definition;
import io.metersphere.api.domain.ApiDocShare; import io.metersphere.api.domain.ApiDocShare;
import io.metersphere.api.domain.ApiDocShareExample; import io.metersphere.api.domain.ApiDocShareExample;
import io.metersphere.api.dto.definition.ApiDefinitionDTO;
import io.metersphere.api.dto.definition.ApiDocShareDTO; import io.metersphere.api.dto.definition.ApiDocShareDTO;
import io.metersphere.api.dto.definition.ApiDocShareDetail; import io.metersphere.api.dto.definition.ApiDocShareDetail;
import io.metersphere.api.dto.definition.request.*; import io.metersphere.api.dto.definition.request.*;
import io.metersphere.api.mapper.ApiDocShareMapper; import io.metersphere.api.mapper.ApiDocShareMapper;
import io.metersphere.api.mapper.ExtApiDefinitionMapper; import io.metersphere.api.mapper.ExtApiDefinitionMapper;
import io.metersphere.api.mapper.ExtApiDocShareMapper; import io.metersphere.api.mapper.ExtApiDocShareMapper;
import io.metersphere.api.service.ApiTestService;
import io.metersphere.sdk.constants.MsAssertionCondition; import io.metersphere.sdk.constants.MsAssertionCondition;
import io.metersphere.sdk.dto.CombineCondition; import io.metersphere.sdk.dto.CombineCondition;
import io.metersphere.sdk.dto.CombineSearch; import io.metersphere.sdk.dto.CombineSearch;
import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.Translator; import io.metersphere.sdk.util.Translator;
import io.metersphere.system.dto.ProtocolDTO;
import io.metersphere.system.dto.sdk.BaseTreeNode; import io.metersphere.system.dto.sdk.BaseTreeNode;
import io.metersphere.system.service.UserToolService; import io.metersphere.system.service.UserToolService;
import io.metersphere.system.uid.IDGenerator; import io.metersphere.system.uid.IDGenerator;
@ -28,6 +31,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
/** /**
* @author song-cc-rock * @author song-cc-rock
@ -49,6 +53,10 @@ public class ApiDocShareService {
private ApiDefinitionModuleService apiDefinitionModuleService; private ApiDefinitionModuleService apiDefinitionModuleService;
@Resource @Resource
private ApiDefinitionExportService apiDefinitionExportService; private ApiDefinitionExportService apiDefinitionExportService;
@Resource
private ApiDefinitionService apiDefinitionService;
@Resource
private ApiTestService apiTestService;
public static final String RANGE_ALL = "ALL"; public static final String RANGE_ALL = "ALL";
@ -175,6 +183,23 @@ public class ApiDocShareService {
return apiDefinitionExportService.exportApiDefinition(request, type, currentUser); return apiDefinitionExportService.exportApiDefinition(request, type, currentUser);
} }
/**
* 获取接口定义的协议脚本
* @param id 接口定义ID
* @param orgId 组织ID
* @return 协议脚本
*/
public Object getApiProtocolScript(String id, String orgId) {
ApiDefinitionDTO apiDefinitionDTO = apiDefinitionService.get(id, "admin");
List<ProtocolDTO> protocols = apiTestService.getProtocols(orgId);
List<ProtocolDTO> noHttpProtocols = protocols.stream().filter(protocol -> !StringUtils.equals(protocol.getProtocol(), "HTTP")).toList();
Map<String, String> protocolMap = noHttpProtocols.stream().collect(Collectors.toMap(ProtocolDTO::getProtocol, ProtocolDTO::getPluginId));
if (!protocolMap.containsKey(apiDefinitionDTO.getProtocol())) {
return null;
}
return apiTestService.getApiProtocolScript(protocolMap.get(apiDefinitionDTO.getProtocol()));
}
/** /**
* 构建分享额外信息 * 构建分享额外信息
* @param docShares 分享列表 * @param docShares 分享列表

View File

@ -14,6 +14,8 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.api.TestMethodOrder;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.SqlConfig;
import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
@ -38,10 +40,12 @@ public class ApiDocShareControllerTests extends BaseTest {
private final static String MODULE_COUNT = BASE_PATH + "module/count"; private final static String MODULE_COUNT = BASE_PATH + "module/count";
private final static String EXPORT = BASE_PATH + "export/Swagger"; private final static String EXPORT = BASE_PATH + "export/Swagger";
private final static String DOWNLOAD = BASE_PATH + "download/file/"; private final static String DOWNLOAD = BASE_PATH + "download/file/";
private final static String GET_DETAIL = BASE_PATH + "/get-detail/"; private final static String GET_DETAIL = BASE_PATH + "get-detail/";
private final static String GET_PLUGIN_SCRIPT = BASE_PATH + "plugin/script/";
@Order(1) @Order(1)
@Test @Test
@Sql(scripts = {"/dml/init_api_doc_share.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
public void addOrUpdate() throws Exception { public void addOrUpdate() throws Exception {
ApiDocShareEditRequest request = new ApiDocShareEditRequest(); ApiDocShareEditRequest request = new ApiDocShareEditRequest();
request.setName("share-1"); request.setName("share-1");
@ -87,7 +91,8 @@ public class ApiDocShareControllerTests extends BaseTest {
this.requestGetWithOk(DELETE + docShare.getId()); this.requestGetWithOk(DELETE + docShare.getId());
// 不存在的ID // 不存在的ID
this.requestGet(DELETE + "not-exist-id").andExpect(status().is5xxServerError()); this.requestGet(DELETE + "not-exist-id").andExpect(status().is5xxServerError());
this.requestGet(GET_DETAIL + "not-exist-id").andExpect(status().is5xxServerError()); this.requestGetWithOk(GET_DETAIL + "doc-share-id");
getPluginScript("doc-share-id", DEFAULT_ORGANIZATION_ID);
} }
@Order(2) @Order(2)
@ -149,4 +154,10 @@ public class ApiDocShareControllerTests extends BaseTest {
.header(SessionConstants.HEADER_TOKEN, sessionId) .header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)).andReturn(); .header(SessionConstants.CSRF_TOKEN, csrfToken)).andReturn();
} }
private MvcResult getPluginScript(String id, String orgId) throws Exception {
return mockMvc.perform(MockMvcRequestBuilders.get(GET_PLUGIN_SCRIPT + id + "/" + orgId)
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)).andReturn();
}
} }

View File

@ -0,0 +1,3 @@
-- 插入测试数据
INSERT INTO `api_definition` (`id`, `name`, `protocol`, `method`, `path`, `status`, `num`, `tags`, `pos`, `project_id`, `module_id`, `latest`, `version_id`, `ref_id`, `description`, `create_time`, `create_user`, `update_time`, `update_user`, `delete_user`, `delete_time`, `deleted`) VALUES
('doc-share-id', 'test1', 'HTTP', 'POST', '/api/admin/1', 'PROCESSING', 1001, '[\"test3\",\"te\"]', 1, '100001100001', 'root', b'1', '100570499574136985', '1001', NULL, 1699500298164, 'admin', 1699500298162, 'admin', NULL, NULL, b'0');