refactor(接口测试): 优化接口详情参数

This commit is contained in:
AgAngle 2024-01-28 16:44:50 +08:00 committed by Craftsman
parent ae6fb6184a
commit de192523ea
14 changed files with 109 additions and 37 deletions

View File

@ -2,6 +2,7 @@ package io.metersphere.api.dto.debug;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
@ -44,8 +45,8 @@ public class ApiDebugAddRequest implements Serializable {
private String moduleId;
@Schema(description = "请求内容")
@NotBlank
private String request;
@NotNull
private Object request;
/**
* 新上传的文件ID
* 创建时先按ID创建目录再把文件放入目录

View File

@ -37,7 +37,7 @@ public class ApiDebugUpdateRequest implements Serializable {
private String moduleId;
@Schema(description = "请求内容")
private String request;
private Object request;
/**
* 新上传的文件ID

View File

@ -3,6 +3,7 @@ package io.metersphere.api.dto.definition;
import io.metersphere.sdk.constants.ModuleConstants;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
@ -65,12 +66,12 @@ public class ApiDefinitionAddRequest implements Serializable {
private LinkedHashSet<@NotBlank String> tags;
@Schema(description = "请求内容")
@NotBlank
private String request;
@NotNull
private Object request;
@Schema(description = "请求内容")
@NotBlank
private String response;
@NotNull
private Object response;
/**
* 新上传的文件ID

View File

@ -2,6 +2,7 @@ package io.metersphere.api.dto.definition;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
@ -50,8 +51,8 @@ public class ApiTestCaseAddRequest implements Serializable {
private String environmentId;
@Schema(description = "请求内容")
@NotBlank
private String request;
@NotNull
private Object request;
/**
* 新上传的文件ID

View File

@ -2,6 +2,7 @@ package io.metersphere.api.dto.definition;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
@ -44,8 +45,8 @@ public class ApiTestCaseUpdateRequest implements Serializable {
private String environmentId;
@Schema(description = "请求内容")
@NotBlank
private String request;
@NotNull
private Object request;
/**
* 新上传的文件ID

View File

@ -83,7 +83,7 @@ public class ApiDebugService {
apiDebugMapper.insert(apiDebug);
ApiDebugBlob apiDebugBlob = new ApiDebugBlob();
apiDebugBlob.setId(apiDebug.getId());
apiDebugBlob.setRequest(request.getRequest().getBytes());
apiDebugBlob.setRequest(getMsTestElementStr(request.getRequest()).getBytes());
apiDebugBlobMapper.insert(apiDebugBlob);
// 处理文件
@ -94,6 +94,7 @@ public class ApiDebugService {
return apiDebug;
}
private Long getNextOrder(String projectId) {
Long pos = extApiDebugMapper.getPos(projectId);
return (pos == null ? 0 : pos) + ORDER_STEP;
@ -121,10 +122,10 @@ public class ApiDebugService {
apiDebug.setUpdateTime(System.currentTimeMillis());
apiDebugMapper.updateByPrimaryKeySelective(apiDebug);
if (StringUtils.isNotBlank(request.getRequest())) {
if (request.getRequest() != null) {
ApiDebugBlob apiDebugBlob = new ApiDebugBlob();
apiDebugBlob.setId(request.getId());
apiDebugBlob.setRequest(request.getRequest().getBytes());
apiDebugBlob.setRequest(getMsTestElementStr(request.getRequest()).getBytes());
apiDebugBlobMapper.updateByPrimaryKeySelective(apiDebugBlob);
}
@ -137,6 +138,14 @@ public class ApiDebugService {
return apiDebug;
}
private String getMsTestElementStr(Object request) {
String requestStr = JSON.toJSONString(request);
AbstractMsTestElement msTestElement = ApiDataUtils.parseObject(requestStr, AbstractMsTestElement.class);
// 手动校验参数
ServiceUtils.validateParam(msTestElement);
return requestStr;
}
public void delete(String id, String operator) {
ApiDebug apiDebug = apiDebugMapper.selectByPrimaryKey(id);
checkResourceExist(id);

View File

@ -35,6 +35,7 @@ import io.metersphere.system.service.UserLoginService;
import io.metersphere.system.uid.IDGenerator;
import io.metersphere.system.uid.NumGenerator;
import io.metersphere.system.utils.CustomFieldUtils;
import io.metersphere.system.utils.ServiceUtils;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
@ -186,8 +187,8 @@ public class ApiDefinitionService {
apiDefinitionMapper.insertSelective(apiDefinition);
ApiDefinitionBlob apiDefinitionBlob = new ApiDefinitionBlob();
apiDefinitionBlob.setId(apiDefinition.getId());
apiDefinitionBlob.setRequest(request.getRequest().getBytes());
apiDefinitionBlob.setResponse(request.getResponse().getBytes());
apiDefinitionBlob.setRequest(getMsTestElementStr(request.getRequest()).getBytes());
apiDefinitionBlob.setResponse(JSON.toJSONString(request.getResponse()).getBytes());
apiDefinitionBlobMapper.insertSelective(apiDefinitionBlob);
// 处理文件
@ -207,6 +208,14 @@ public class ApiDefinitionService {
return apiDefinition;
}
private String getMsTestElementStr(Object request) {
String requestStr = JSON.toJSONString(request);
AbstractMsTestElement msTestElement = ApiDataUtils.parseObject(requestStr, AbstractMsTestElement.class);
// 手动校验参数
ServiceUtils.validateParam(msTestElement);
return requestStr;
}
private static ApiFileResourceUpdateRequest getApiFileResourceUpdateRequest(String sourceId, String projectId, String operator) {
String apiDefinitionDir = DefaultRepositoryDir.getApiDefinitionDir(projectId, sourceId);
ApiFileResourceUpdateRequest resourceUpdateRequest = new ApiFileResourceUpdateRequest();
@ -244,8 +253,14 @@ public class ApiDefinitionService {
apiDefinitionMapper.updateByPrimaryKeySelective(apiDefinition);
ApiDefinitionBlob apiDefinitionBlob = new ApiDefinitionBlob();
apiDefinitionBlob.setId(apiDefinition.getId());
apiDefinitionBlob.setRequest(request.getRequest().getBytes());
apiDefinitionBlob.setResponse(request.getResponse().getBytes());
if (request.getRequest() != null) {
apiDefinitionBlob.setRequest(getMsTestElementStr(request.getRequest()).getBytes());
}
if (request.getResponse() != null) {
apiDefinitionBlob.setResponse(JSON.toJSONString(request.getResponse()).getBytes());
}
apiDefinitionBlobMapper.updateByPrimaryKeySelective(apiDefinitionBlob);
// 自定义字段

View File

@ -156,7 +156,7 @@ public class ApiTestCaseService {
ApiTestCaseBlob caseBlob = new ApiTestCaseBlob();
caseBlob.setId(testCase.getId());
caseBlob.setRequest(request.getRequest().getBytes());
caseBlob.setRequest(getMsTestElementStr(request.getRequest()).getBytes());
apiTestCaseBlobMapper.insert(caseBlob);
// 处理文件
@ -167,6 +167,14 @@ public class ApiTestCaseService {
return testCase;
}
private String getMsTestElementStr(Object request) {
String requestStr = JSON.toJSONString(request);
AbstractMsTestElement msTestElement = ApiDataUtils.parseObject(requestStr, AbstractMsTestElement.class);
// 手动校验参数
ServiceUtils.validateParam(msTestElement);
return requestStr;
}
private ApiTestCase checkResourceExist(String id) {
ApiTestCase testCase = apiTestCaseMapper.selectByPrimaryKey(id);
if (testCase == null) {
@ -240,7 +248,7 @@ public class ApiTestCaseService {
apiTestCaseMapper.updateByPrimaryKey(testCase);
ApiTestCaseBlob apiTestCaseBlob = new ApiTestCaseBlob();
apiTestCaseBlob.setId(request.getId());
apiTestCaseBlob.setRequest(request.getRequest().getBytes());
apiTestCaseBlob.setRequest(getMsTestElementStr(request.getRequest()).getBytes());
apiTestCaseBlobMapper.updateByPrimaryKeySelective(apiTestCaseBlob);
ApiFileResourceUpdateRequest resourceUpdateRequest = getApiFileResourceUpdateRequest(testCase.getId(), testCase.getProjectId(), userId);

View File

@ -140,7 +140,7 @@ public class ApiDebugControllerTests extends BaseTest {
request.setModuleId("default");
request.setProjectId(DEFAULT_PROJECT_ID);
MsHTTPElement msHttpElement = MsHTTPElementTest.getMsHttpElement();
request.setRequest(ApiDataUtils.toJSONString(msHttpElement));
request.setRequest(getMsElementParam(msHttpElement));
uploadFileId = doUploadTempFile(getMockMultipartFile());
request.setUploadFileIds(List.of(uploadFileId));
@ -203,7 +203,7 @@ public class ApiDebugControllerTests extends BaseTest {
request.setModuleId("default1");
MsHTTPElement msHttpElement = MsHTTPElementTest.getMsHttpElement();
msHttpElement.setName("test1");
request.setRequest(ApiDataUtils.toJSONString(msHttpElement));
request.setRequest(getMsElementParam(msHttpElement));
// 不带文件的更新
request.setUnLinkRefIds(List.of(fileMetadataId));

View File

@ -192,9 +192,9 @@ public class ApiDefinitionControllerTests extends BaseTest {
// 创建测试数据
ApiDefinitionAddRequest request = createApiDefinitionAddRequest();
MsHTTPElement msHttpElement = MsHTTPElementTest.getMsHttpElement();
request.setRequest(ApiDataUtils.toJSONString(msHttpElement));
request.setRequest(getMsElementParam(msHttpElement));
List<HttpResponse> msHttpResponse = MsHTTPElementTest.getMsHttpResponse();
request.setResponse(ApiDataUtils.toJSONString(msHttpResponse));
request.setResponse(msHttpResponse);
uploadFileId = doUploadTempFile(getMockMultipartFile("file_upload.JPG"));
request.setUploadFileIds(List.of(uploadFileId));
@ -235,6 +235,10 @@ public class ApiDefinitionControllerTests extends BaseTest {
requestPostPermissionTest(PermissionConstants.PROJECT_API_DEFINITION_ADD, ADD, request);
}
private Object getMsElementParam(MsHTTPElement msHTTPElement) {
return JSON.parseObject(ApiDataUtils.toJSONString(msHTTPElement));
}
private ApiDefinitionAddRequest createApiDefinitionAddRequest() {
// 创建并返回一个 ApiDefinitionAddRequest 对象用于测试
String defaultVersion = extBaseProjectVersionMapper.getDefaultVersion(DEFAULT_PROJECT_ID);
@ -327,9 +331,9 @@ public class ApiDefinitionControllerTests extends BaseTest {
request.setCustomFields(customFieldMap);
MsHTTPElement msHttpElement = MsHTTPElementTest.getMsHttpElement();
request.setRequest(ApiDataUtils.toJSONString(msHttpElement));
request.setRequest(getMsElementParam(msHttpElement));
List<HttpResponse> msHttpResponse = MsHTTPElementTest.getMsHttpResponse();
request.setResponse(ApiDataUtils.toJSONString(msHttpResponse));
request.setResponse(msHttpResponse);
// 清除文件的更新
request.setUnLinkRefIds(List.of(fileMetadataId));
@ -410,8 +414,8 @@ public class ApiDefinitionControllerTests extends BaseTest {
addRequest.setDescription("描述内容");
addRequest.setTags(new LinkedHashSet<>(List.of("tag1", "tag2")));
addRequest.setCustomFields(new HashMap<>());
addRequest.setRequest(ApiDataUtils.toJSONString(msHttpElement));
addRequest.setResponse(ApiDataUtils.toJSONString(msHttpResponse));
addRequest.setRequest(getMsElementParam(msHttpElement));
addRequest.setResponse(msHttpResponse);
MvcResult mvcResult = this.requestPostWithOkAndReturn(ADD, addRequest);
ApiDefinition apiDefinition = getResultData(mvcResult, ApiDefinition.class);
ApiDefinition apiPathAndMethod = apiDefinitionMapper.selectByPrimaryKey(apiDefinition.getId());
@ -420,8 +424,8 @@ public class ApiDefinitionControllerTests extends BaseTest {
ApiDefinitionUpdateRequest updateRequest = new ApiDefinitionUpdateRequest();
BeanUtils.copyBean(updateRequest, apiPathAndMethod);
updateRequest.setPath("/api/test/path/method");
updateRequest.setRequest(ApiDataUtils.toJSONString(msHttpElement));
updateRequest.setResponse(ApiDataUtils.toJSONString(msHttpResponse));
updateRequest.setRequest(getMsElementParam(msHttpElement));
updateRequest.setResponse(msHttpResponse);
updateRequest.setMethod("GET");
this.requestPostWithOk(UPDATE, updateRequest);
//增加用例
@ -433,7 +437,7 @@ public class ApiDefinitionControllerTests extends BaseTest {
testCaseAddRequest.setPriority("P0");
testCaseAddRequest.setStatus(ApiDefinitionStatus.PREPARE.getValue());
testCaseAddRequest.setTags(new LinkedHashSet<>(List.of("tag1", "tag2")));
testCaseAddRequest.setRequest(ApiDataUtils.toJSONString(msHttpElement));
testCaseAddRequest.setRequest(getMsElementParam(msHttpElement));
this.requestPostWithOkAndReturn("/api/case/add", testCaseAddRequest);
}
updateRequest.setPath("/api/test/path/method/case");

View File

@ -434,7 +434,7 @@ public class ApiScenarioControllerTests extends BaseTest {
apiDefinitionAddRequest.setDescription("描述内容");
apiDefinitionAddRequest.setName("test scenario");
MsHTTPElement msHttpElement = MsHTTPElementTest.getMsHttpElement();
apiDefinitionAddRequest.setRequest(ApiDataUtils.toJSONString(msHttpElement));
apiDefinitionAddRequest.setRequest(getMsElementParam(msHttpElement));
apiDefinitionAddRequest.setResponse("{}");
apiDefinition = apiDefinitionService.create(apiDefinitionAddRequest, "admin");
@ -445,10 +445,13 @@ public class ApiScenarioControllerTests extends BaseTest {
apiTestCaseAddRequest.setPriority("P0");
apiTestCaseAddRequest.setStatus("Underway");
apiTestCaseAddRequest.setTags(new LinkedHashSet<>(List.of("tag1", "tag2")));
apiTestCaseAddRequest.setRequest(ApiDataUtils.toJSONString(msHttpElement));
apiTestCaseAddRequest.setRequest(getMsElementParam(msHttpElement));
apiTestCase = apiTestCaseService.addCase(apiTestCaseAddRequest, "admin");
}
private Object getMsElementParam(MsHTTPElement msHTTPElement) {
return JSON.parseObject(ApiDataUtils.toJSONString(msHTTPElement));
}
@Test
@Order(2)

View File

@ -324,7 +324,7 @@ public class ApiTestCaseControllerTests extends BaseTest {
request.setTags(new LinkedHashSet<>(List.of("tag1", "tag2")));
request.setEnvironmentId(environments.get(0).getId());
MsHTTPElement msHttpElement = MsHTTPElementTest.getMsHttpElement();
request.setRequest(ApiDataUtils.toJSONString(msHttpElement));
request.setRequest(getMsElementParam(msHttpElement));
uploadFileId = doUploadTempFile(getMockMultipartFile());
request.setUploadFileIds(List.of(uploadFileId));
@ -372,6 +372,10 @@ public class ApiTestCaseControllerTests extends BaseTest {
}
private Object getMsElementParam(MsHTTPElement msHTTPElement) {
return JSON.parseObject(ApiDataUtils.toJSONString(msHTTPElement));
}
@Test
@Order(3)
@ -498,7 +502,7 @@ public class ApiTestCaseControllerTests extends BaseTest {
request.setTags(List.of("tag1", "tag2"));
request.setEnvironmentId(null);
MsHTTPElement msHttpElement = MsHTTPElementTest.getMsHttpElement();
request.setRequest(ApiDataUtils.toJSONString(msHttpElement));
request.setRequest(getMsElementParam(msHttpElement));
// 不带文件的更新
request.setUnLinkRefIds(List.of(fileMetadataId));
request.setDeleteFileIds(List.of(uploadFileId));
@ -638,7 +642,7 @@ public class ApiTestCaseControllerTests extends BaseTest {
request.setStatus("Underway");
request.setTags(new LinkedHashSet<>(List.of("tag1", "tag2")));
MsHTTPElement msHttpElement = MsHTTPElementTest.getMsHttpElement();
request.setRequest(ApiDataUtils.toJSONString(msHttpElement));
request.setRequest(getMsElementParam(msHttpElement));
this.requestPost(ADD, request);
ApiTestCasePageRequest pageRequest = new ApiTestCasePageRequest();
pageRequest.setProjectId(DEFAULT_PROJECT_ID);

View File

@ -86,7 +86,7 @@ public class RestControllerExceptionHandler {
message = getNotFoundMessage(message);
}
return ResponseEntity.status(code % 1000)
.body(ResultHolder.error(code, message));
.body(ResultHolder.error(code, message, e.getMessage()));
} else {
// 响应码返回 500设置业务状态码
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)

View File

@ -1,10 +1,16 @@
package io.metersphere.system.utils;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.CommonBeanFactory;
import io.metersphere.system.controller.handler.result.MsHttpResultCode;
import io.metersphere.system.dto.sdk.enums.MoveTypeEnum;
import io.metersphere.system.dto.sdk.request.PosRequest;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validator;
import org.apache.commons.collections.CollectionUtils;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
@ -90,4 +96,23 @@ public class ServiceUtils {
throw new MSException("更新 pos 字段失败");
}
}
/**
* 校验对象的参数校验注解
* @param param
*/
public static <T> void validateParam(T param) {
Validator validator = (Validator) CommonBeanFactory.getBean("validator");
Set<ConstraintViolation<T>> errors = validator.validate(param);
if (CollectionUtils.isEmpty(errors)) {
return;
}
StringBuilder tips = new StringBuilder();
for (ConstraintViolation<T> error : errors) {
String fieldName = error.getPropertyPath().toString();
String message = error.getMessage();
tips.append(fieldName + message).append("; ");
}
throw new MSException(MsHttpResultCode.VALIDATE_FAILED, tips.toString());
}
}