From ae6fb6184a7edc80caeb3ef1fd7e3675588f9750 Mon Sep 17 00:00:00 2001 From: AgAngle <1323481023@qq.com> Date: Sun, 28 Jan 2024 11:55:31 +0800 Subject: [PATCH] =?UTF-8?q?refactor(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95):?= =?UTF-8?q?=20=E5=AE=8C=E5=96=84=E8=AF=B7=E6=B1=82=E8=AF=A6=E6=83=85java?= =?UTF-8?q?=20doc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/metersphere/api/dto/ApiFile.java | 13 +++- .../api/dto/request/MsCommonElement.java | 6 ++ .../dto/request/assertion/MsAssertion.java | 16 +++++ .../request/assertion/MsAssertionConfig.java | 3 +- .../assertion/MsResponseBodyAssertion.java | 12 +++- .../assertion/MsResponseCodeAssertion.java | 4 +- .../assertion/MsResponseHeaderAssertion.java | 14 +++- .../assertion/body/MsBodyAssertionItem.java | 4 ++ .../assertion/body/MsDocumentAssertion.java | 12 +++- .../body/MsDocumentAssertionElement.java | 34 +++++++++ .../body/MsJSONPathAssertionItem.java | 13 +++- .../assertion/body/MsRegexAssertion.java | 2 + .../assertion/body/MsRegexAssertionItem.java | 3 + .../assertion/body/MsXPathAssertion.java | 6 +- .../assertion/body/MsXPathAssertionItem.java | 6 ++ .../api/dto/request/http/Header.java | 1 + .../dto/request/http/KeyValueEnableParam.java | 4 ++ .../api/dto/request/http/KeyValueParam.java | 4 ++ .../dto/request/http/KeyValueParamType.java | 43 +++++++++++ .../api/dto/request/http/MsHTTPConfig.java | 21 ++++++ .../api/dto/request/http/MsHTTPElement.java | 23 +++++- .../api/dto/request/http/QueryParam.java | 10 ++- .../api/dto/request/http/RestParam.java | 9 ++- .../api/dto/request/http/auth/HTTPAuth.java | 8 +++ .../api/dto/request/http/body/BinaryBody.java | 7 +- .../api/dto/request/http/body/Body.java | 70 +++++++++++++++++- .../dto/request/http/body/BodyParamType.java | 57 +++++++++++++++ .../dto/request/http/body/FormDataBody.java | 3 + .../api/dto/request/http/body/FormDataKV.java | 10 ++- .../api/dto/request/http/body/JsonBody.java | 14 ++-- .../api/dto/request/http/body/RawBody.java | 4 ++ .../dto/request/http/body/WWWFormBody.java | 3 + .../api/dto/request/http/body/WWWFormKV.java | 43 ++++++----- .../api/dto/request/http/body/XmlBody.java | 4 ++ .../processors/ExtractPostProcessor.java | 1 + .../dto/request/processors/MsProcessor.java | 13 ++++ .../request/processors/MsProcessorConfig.java | 8 ++- .../dto/request/processors/SQLProcessor.java | 11 +++ .../request/processors/ScriptProcessor.java | 10 ++- .../processors/TimeWaitingProcessor.java | 5 ++ .../request/processors/extract/MsExtract.java | 32 +++++++++ .../processors/extract/RegexExtract.java | 56 ++++++--------- .../extract/ResultMatchingExtract.java | 12 +++- .../processors/extract/XPathExtract.java | 6 ++ .../api/dto/schema/JsonSchemaItem.java | 72 ++++++++++++++++++- .../jmeter/body/MsBinaryBodyConverter.java | 3 +- .../extract/RegexExtractConverter.java | 44 +++++++++--- .../api/controller/MsHTTPElementTest.java | 6 +- 48 files changed, 664 insertions(+), 101 deletions(-) create mode 100644 backend/services/api-test/src/main/java/io/metersphere/api/dto/request/http/KeyValueParamType.java create mode 100644 backend/services/api-test/src/main/java/io/metersphere/api/dto/request/http/body/BodyParamType.java diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/ApiFile.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/ApiFile.java index 32b18a2c5f..76000a6fd6 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/ApiFile.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/ApiFile.java @@ -1,16 +1,25 @@ package io.metersphere.api.dto; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; import lombok.Data; +/** + * 接口执行所需要的文件 + */ @Data public class ApiFile { /** * 记录文件的ID,防止重名 - * 生成脚本时,通过 fileId + value(文件名) 获取文件路径 + * 生成脚本时,通过 fileId + fileName(文件名) 获取文件路径 */ + @NotBlank + @Size(max = 50) private String fileId; /** - * 文件名称 + * 文件名 */ + @NotBlank + @Size(max = 200) private String fileName; } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/MsCommonElement.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/MsCommonElement.java index c5d8a1ce42..ec29fb5e4d 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/MsCommonElement.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/MsCommonElement.java @@ -3,12 +3,15 @@ package io.metersphere.api.dto.request; import io.metersphere.api.dto.request.assertion.MsAssertionConfig; import io.metersphere.api.dto.request.processors.MsProcessorConfig; import io.metersphere.plugin.api.spi.AbstractMsTestElement; +import jakarta.validation.Valid; import lombok.Data; import lombok.EqualsAndHashCode; /** * 协议插件中通用的配置 + *
* 添加到对应元素的 children 属性中 + ** @Author: jianxing * @CreateTime: 2023-12-25 10:50 */ @@ -18,13 +21,16 @@ public class MsCommonElement extends AbstractMsTestElement { /** * 前置处理器配置 */ + @Valid private MsProcessorConfig preProcessorConfig; /** * 后置处理器配置 */ + @Valid private MsProcessorConfig postProcessorConfig; /** * 断言配置 */ + @Valid private MsAssertionConfig assertionConfig; } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsAssertion.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsAssertion.java index f57681080b..c84212dec2 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsAssertion.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsAssertion.java @@ -2,10 +2,24 @@ package io.metersphere.api.dto.request.assertion; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import io.metersphere.api.dto.request.processors.extract.JSONPathExtract; +import io.metersphere.api.dto.request.processors.extract.RegexExtract; +import io.metersphere.api.dto.request.processors.extract.XPathExtract; +import jakarta.validation.constraints.Size; import lombok.Data; /** * 断言 + *
+ * 该参数传参时,需要传入 assertionType 字段,用于区分是哪种断言 + * assertionType 取值为: + * RESPONSE_CODE {@link MsResponseCodeAssertion} + * RESPONSE_HEADER {@link MsResponseHeaderAssertion} + * RESPONSE_BODY {@link MsResponseBodyAssertion} + * RESPONSE_TIME {@link MsResponseTimeAssertion} + * SCRIPT {@link MsScriptAssertion} + * VARIABLE {@link MsVariableAssertion} + **/ @Data @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "assertionType") @@ -20,10 +34,12 @@ import lombok.Data; public abstract class MsAssertion { /** * 是否启用 + * 默认启用 */ private Boolean enable = true; /** * 断言名称 */ + @Size(max = 100) private String name; } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsAssertionConfig.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsAssertionConfig.java index 7ca3c4e782..657e4285af 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsAssertionConfig.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsAssertionConfig.java @@ -13,8 +13,9 @@ import java.util.List; public class MsAssertionConfig { /** * 是否启用全局断言 + * 默认为 false */ - private Boolean enableGlobal; + private Boolean enableGlobal = false; /** * 断言列表 */ diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsResponseBodyAssertion.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsResponseBodyAssertion.java index d8ff0e6683..0a9f977161 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsResponseBodyAssertion.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsResponseBodyAssertion.java @@ -5,6 +5,8 @@ import io.metersphere.api.dto.request.assertion.body.MsDocumentAssertion; import io.metersphere.api.dto.request.assertion.body.MsJSONPathAssertion; import io.metersphere.api.dto.request.assertion.body.MsRegexAssertion; import io.metersphere.api.dto.request.assertion.body.MsXPathAssertion; +import io.metersphere.system.valid.EnumValue; +import jakarta.validation.Valid; import lombok.Data; import java.util.HashMap; @@ -26,24 +28,29 @@ public class MsResponseBodyAssertion extends MsAssertion { * 后端从设计层面支持多种断言,前端只支持一种 * 同时切换可以同时持久化两种类型 * - * @see MsBodyAssertionType + * 取值参考 {@link MsBodyAssertionType} */ + @EnumValue(enumClass = MsBodyAssertionType.class) private String assertionBodyType; /** * jsonPath断言 */ + @Valid private MsJSONPathAssertion jsonPathAssertion; /** * xpath断言 */ + @Valid private MsXPathAssertion xpathAssertion; /** * 文档断言 */ + @Valid private MsDocumentAssertion documentAssertion; /** * 正则断言 */ + @Valid private MsRegexAssertion regexAssertion; private static Map
+ * 其中包括:接口调试、接口定义、接口用例、场景的自定义请求 的详情 + * 接口协议插件的接口详情也类似 + *+ */ @Data @EqualsAndHashCode(callSuper = true) public class MsHTTPElement extends AbstractMsTestElement { - // todo 完善字段校验 /** * 完整请求地址 + * 自定义请求时,使用该字段 */ + @Size(max = 500) private String url; /** * 接口定义和用例的请求路径 */ + @Size(max = 500) private String path; /** * 请求方法 */ + @NotBlank + @Size(max = 10) private String method; /** * 请求体 */ + @Valid private Body body; /** * 请求头 */ + @Valid private List
+ * 该参数传参时,需要传入 authType 字段,用于区分是哪种认证方式 + * authType 取值为: + * BASIC ({@link BasicAuth}) + * DIGEST ({@link DigestAuth}) + * NONE ({@link NoAuth}) + ** @Author: jianxing * @CreateTime: 2023-11-07 11:00 */ diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/http/body/BinaryBody.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/http/body/BinaryBody.java index eff6557b3a..6558b883a2 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/http/body/BinaryBody.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/http/body/BinaryBody.java @@ -4,11 +4,14 @@ import io.metersphere.api.dto.ApiFile; import lombok.Data; /** + * binary 请求体 * @Author: jianxing * @CreateTime: 2023-11-06 18:25 */ @Data -public class BinaryBody { - private ApiFile bodyFile; +public class BinaryBody extends ApiFile{ + /** + * 描述 + */ private String description; } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/http/body/Body.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/http/body/Body.java index b48a2f5419..eacc722d2a 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/http/body/Body.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/http/body/Body.java @@ -1,11 +1,15 @@ package io.metersphere.api.dto.request.http.body; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; import lombok.Data; import java.util.HashMap; import java.util.Map; /** + * 请求体 * @Author: jianxing * @CreateTime: 2023-11-06 16:59 */ @@ -13,18 +17,58 @@ import java.util.Map; public class Body { /** * 当前选择的请求体类型 - * @see BodyType + * 可选值为 {@link BodyType} * 同时持久化多个类型的请求体 */ + @NotBlank + @Size(max = 20) private String bodyType; + /** + * None 请求体 + * 当 bodyType 为 NONE 时,使用该字段 + */ private NoneBody noneBody; + /** + * form-data 请求体 + * 当 bodyType 为 FORM_DATA 时,使用该字段 + */ + @Valid private FormDataBody formDataBody; + /** + * x-www-form-urlencoded 请求体 + * 当 bodyType 为 WWW_FORM 时,使用该字段 + */ + @Valid private WWWFormBody wwwFormBody; + /** + * json 请求体 + * 当 bodyType 为 JSON 时,使用该字段 + */ + @Valid private JsonBody jsonBody; + /** + * xml 请求体 + * 当 bodyType 为 XML 时,使用该字段 + */ + @Valid private XmlBody xmlBody; + /** + * raw 请求体 + * 当 bodyType 为 RAW 时,使用该字段 + */ + @Valid private RawBody rawBody; + /** + * binary 请求体 + * 当 bodyType 为 BINARY 时,使用该字段 + */ + @Valid private BinaryBody binaryBody; + /** + * 请求体类型与请求体类的映射 + * 不需要传惨 + */ private static Map
+ * 该参数传参时,需要传入 processorType 字段,用于区分是哪种认证处理器 + * processorType 取值为: + * SCRIPT {@link ScriptProcessor} + * SQL {@link SQLProcessor} + * TIME_WAITING {@link TimeWaitingProcessor} + * EXTRACT {@link ExtractPostProcessor} + ** @Author: jianxing * @CreateTime: 2023-11-07 10:17 */ @@ -20,6 +31,8 @@ public abstract class MsProcessor { /** * 名称 */ + @NotBlank + @Size(max = 100) private String name; /** * 是否启用 diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/MsProcessorConfig.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/MsProcessorConfig.java index 27a35b8a29..b6b2866d2f 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/MsProcessorConfig.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/MsProcessorConfig.java @@ -1,10 +1,12 @@ package io.metersphere.api.dto.request.processors; +import jakarta.validation.Valid; import lombok.Data; import java.util.List; /** + * 前后置处理器配置 * @Author: jianxing * @CreateTime: 2023-11-07 10:17 */ @@ -12,10 +14,12 @@ import java.util.List; public class MsProcessorConfig { /** * 是否启用全局前置 + * 默认为 false */ - private Boolean enableGlobal; + private Boolean enableGlobal = false; /** - * 处理器 + * 处理器列表 */ + @Valid private Listprocessors; } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/SQLProcessor.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/SQLProcessor.java index 8a4b647805..8b13f372e1 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/SQLProcessor.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/SQLProcessor.java @@ -3,11 +3,15 @@ package io.metersphere.api.dto.request.processors; import com.fasterxml.jackson.annotation.JsonTypeName; import io.metersphere.api.dto.request.http.KeyValueEnableParam; import io.metersphere.api.dto.request.http.KeyValueParam; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; import lombok.Data; import java.util.List; /** + * SQL 处理器 * @Author: jianxing * @CreateTime: 2023-11-06 21:12 */ @@ -25,25 +29,32 @@ public class SQLProcessor extends MsProcessor { /** * 存储结果 */ + @Size(max = 200) private String resultVariable; /** * 按列存储 */ + @Size(max = 200) private String variableNames; /** * 变量列表 */ + @Valid private List variables; /** * 环境ID */ + @Size(max = 50) private String environmentId; /** * 数据源ID */ + @NotBlank + @Size(max = 50) private String dataSourceId; /** * 提取参数 */ + @Valid private List extractParams; } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/ScriptProcessor.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/ScriptProcessor.java index 7807899d82..e76787a3d3 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/ScriptProcessor.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/ScriptProcessor.java @@ -3,6 +3,8 @@ package io.metersphere.api.dto.request.processors; import com.fasterxml.jackson.annotation.JsonTypeName; import io.metersphere.api.dto.request.http.KeyValueParam; import io.metersphere.project.constants.ScriptLanguageType; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; import lombok.Data; import java.util.List; @@ -20,19 +22,23 @@ public class ScriptProcessor extends MsProcessor { private String script; /** * 脚本语言 - * @see ScriptLanguageType + * {@link ScriptLanguageType} */ + @Size(max = 20) private String scriptLanguage; /** * 是否启用公共脚本 + * 默认为 false */ private Boolean enableCommonScript = false; /** - * 脚本ID + * 公共脚本ID */ + @Size(max = 50) private String scriptId; /** * 公共脚本入参 */ + @Valid private List params; } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/TimeWaitingProcessor.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/TimeWaitingProcessor.java index 881892550f..972e414334 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/TimeWaitingProcessor.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/TimeWaitingProcessor.java @@ -4,11 +4,16 @@ import com.fasterxml.jackson.annotation.JsonTypeName; import lombok.Data; /** + * 等待时间处理器 * @Author: jianxing * @CreateTime: 2023-11-07 09:59 */ @Data @JsonTypeName("TIME_WAITING") public class TimeWaitingProcessor extends MsProcessor { + /** + * 等待时间 + * 单位:毫秒 + */ private Integer delay; } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/extract/MsExtract.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/extract/MsExtract.java index 16d7155b2a..9ea7926bca 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/extract/MsExtract.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/extract/MsExtract.java @@ -2,9 +2,21 @@ package io.metersphere.api.dto.request.processors.extract; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import io.metersphere.system.valid.EnumValue; +import jakarta.validation.constraints.Size; import lombok.Data; import org.apache.commons.lang3.StringUtils; +/** + * 提取处理器 + * + * 该参数传参时,需要传入 extractType 字段,用于区分是哪种提取 + * extractType 取值为: + * REGEX {@link RegexExtract} + * JSON_PATH {@link JSONPathExtract} + * X_PATH {@link XPathExtract} + *+ */ @Data @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "extractType") @JsonSubTypes({ @@ -16,14 +28,19 @@ public abstract class MsExtract { /** * 变量名 */ + @Size(max = 100) private String variableName; /** * 参数类型 + * 取值参考 {@link MsExtractType} */ + @Size(max = 100) + @EnumValue(enumClass = MsExtractType.class) private String variableType; /** * 表达式 */ + @Size(max = 200) private String expression; /** * 是否启用 @@ -33,4 +50,19 @@ public abstract class MsExtract { public boolean isValid() { return StringUtils.isNotBlank(variableName) && StringUtils.isNotBlank(expression); } + + public enum MsExtractType { + /** + * 临时参数 + */ + TEMPORARY, + /** + * 环境参数 + */ + ENVIRONMENT, + /** + * 全局参数 + */ + GLOBAL; + } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/extract/RegexExtract.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/extract/RegexExtract.java index c1e15354a4..fb58122c98 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/extract/RegexExtract.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/extract/RegexExtract.java @@ -1,6 +1,7 @@ package io.metersphere.api.dto.request.processors.extract; import com.fasterxml.jackson.annotation.JsonTypeName; +import io.metersphere.system.valid.EnumValue; import lombok.Data; @Data @@ -8,54 +9,43 @@ import lombok.Data; public class RegexExtract extends ResultMatchingExtract { /** * 表达式匹配规则 - * @see ExpressionRuleType + * 取值参考 {@link ExpressionRuleType} 中的 value + * 默认为表达式匹配 */ - private String expressionMatchingRule; + @EnumValue(enumClass = ExpressionRuleType.class) + private String expressionMatchingRule = ExpressionRuleType.EXPRESSION.name(); /** * 提取范围 - * @see ExtractScope + * 取值参考 {@link ExtractScope} */ + @EnumValue(enumClass = ExtractScope.class) private String extractScope; + /** + * 表达式匹配规则 + */ public enum ExpressionRuleType { /** * 匹配表达式 */ - EXPRESSION("$1$"), + EXPRESSION, /** * 匹配组 */ - GROUP("$0$"); - - private String value; - - ExpressionRuleType(String value) { - this.value = value; - } - - public String getValue() { - return value; - } + GROUP; } + /** + * 提取对象 + */ public enum ExtractScope { - BODY("false"), - REQUEST_HEADERS("request_headers"), - UNESCAPED_BODY("unescaped"), - BODY_AS_DOCUMENT("as_document"), - RESPONSE_HEADERS("true"), - URL("URL"), - RESPONSE_CODE("code"), - RESPONSE_MESSAGE("message"); - - private String value; - - ExtractScope(String value) { - this.value = value; - } - - public String getValue() { - return value; - } + BODY, + REQUEST_HEADERS, + UNESCAPED_BODY, + BODY_AS_DOCUMENT, + RESPONSE_HEADERS, + URL, + RESPONSE_CODE, + RESPONSE_MESSAGE; } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/extract/ResultMatchingExtract.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/extract/ResultMatchingExtract.java index ab2bfa7bf2..4df858bdbb 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/extract/ResultMatchingExtract.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/extract/ResultMatchingExtract.java @@ -1,19 +1,27 @@ package io.metersphere.api.dto.request.processors.extract; +import io.metersphere.system.valid.EnumValue; +import jakarta.validation.constraints.Size; import lombok.Data; @Data public abstract class ResultMatchingExtract extends MsExtract { /** * 结果匹配规则 - * 值为 ResultMatchingRuleType + * 取值参考 {@link ResultMatchingRuleType} + * 默认随机匹配 */ - private String resultMatchingRule; + @Size(max = 100) + @EnumValue(enumClass = ResultMatchingRuleType.class) + private String resultMatchingRule = ResultMatchingRuleType.RANDOM.name(); /** * 匹配第几条结果 */ private Integer resultMatchingRuleNum; + /** + * 结果匹配规则 + */ public enum ResultMatchingRuleType { /** * 随机匹配 diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/extract/XPathExtract.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/extract/XPathExtract.java index ce920a7741..649499351e 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/extract/XPathExtract.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/processors/extract/XPathExtract.java @@ -1,6 +1,7 @@ package io.metersphere.api.dto.request.processors.extract; import com.fasterxml.jackson.annotation.JsonTypeName; +import io.metersphere.system.valid.EnumValue; import lombok.Data; /** @@ -9,6 +10,11 @@ import lombok.Data; @Data @JsonTypeName("X_PATH") public class XPathExtract extends ResultMatchingExtract { + /** + * 提取范围 + * 取值参考 {@link ResponseFormat} + */ + @EnumValue(enumClass = ResponseFormat.class) private String responseFormat; public enum ResponseFormat { diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/schema/JsonSchemaItem.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/schema/JsonSchemaItem.java index 6fd5c16f60..5afeaa4cfa 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/schema/JsonSchemaItem.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/schema/JsonSchemaItem.java @@ -1,6 +1,11 @@ package io.metersphere.api.dto.schema; +import io.metersphere.sdk.constants.ValueEnum; +import io.metersphere.system.valid.EnumValue; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; import lombok.Data; import java.math.BigDecimal; @@ -8,22 +13,63 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +/** + * json-schema 参数项 + */ @Data public class JsonSchemaItem { + /** + * 示例 + */ private Object example; + /** + * 参数ID + */ + @NotBlank + @Size(max = 50) private String id; + /** + * 参数名称 + */ + @Size(max = 200) private String title; - private String type = "string"; + /** + * 参数类型 + * 取值范围,参考 {@link JsonSchemaItemType} + * 默认为 string + */ + @EnumValue(enumClass = JsonSchemaItemType.class) + private String type = JsonSchemaItemType.STRING.value; + /** + * 参数描述 + */ private String description; + /** + * 子级参数 + * 当 type 为 object 或者 array 时,使用该值 + */ + @Valid private JsonSchemaItem items; private Mapmock; private Map properties; private JsonSchemaItem additionalProperties; private List required; private String pattern; + /** + * 最大长度 + */ private Integer maxLength; + /** + * 最小长度 + */ private Integer minLength; + /** + * 最小值 + */ private BigDecimal minimum; + /** + * 最大值 + */ private BigDecimal maximum; private String schema; private String format; @@ -55,4 +101,28 @@ public class JsonSchemaItem { this.items = new JsonSchemaItem(); } } + + /** + * json-schema 参数类型 + */ + enum JsonSchemaItemType implements ValueEnum { + STRING("string"), + NUMBER("number"), + INTEGER("integer"), + BOOLEAN("boolean"), + OBJECT("object"), + ARRAY("array"), + NULL("null"); + + private String value; + + JsonSchemaItemType(String value) { + this.value = value; + } + + @Override + public String getValue() { + return value; + } + } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/body/MsBinaryBodyConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/body/MsBinaryBodyConverter.java index 4a331cbc68..83886f49c7 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/body/MsBinaryBodyConverter.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/body/MsBinaryBodyConverter.java @@ -14,8 +14,7 @@ import org.apache.jmeter.protocol.http.util.HTTPFileArg; public class MsBinaryBodyConverter extends MsBodyConverter { @Override public void parse(HTTPSamplerProxy sampler, BinaryBody body, ParameterConfig config) { - ApiFile bodyFile = body.getBodyFile(); - HTTPFileArg httpFileArg = getHttpFileArg(bodyFile); + HTTPFileArg httpFileArg = getHttpFileArg(body); sampler.setHTTPFiles(new HTTPFileArg[]{httpFileArg}); } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/extract/RegexExtractConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/extract/RegexExtractConverter.java index 540f091bc6..11e0d83284 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/extract/RegexExtractConverter.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/extract/RegexExtractConverter.java @@ -8,6 +8,8 @@ import org.apache.jmeter.save.SaveService; import org.apache.jmeter.testelement.TestElement; import org.apache.jorphan.collections.HashTree; +import java.util.HashMap; + import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.REGEX_EXTRACTOR_GUI; /** @@ -23,18 +25,42 @@ public class RegexExtractConverter extends ExtractConverter { extractor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass(REGEX_EXTRACTOR_GUI)); extractor.setRefName(msExtract.getVariableName()); extractor.setRegex(msExtract.getExpression()); - extractor.setUseField(msExtract.getExtractScope()); extractor.setEnabled(msExtract.getEnable()); - + extractor.setUseField(getUseField(msExtract.getExtractScope())); + extractor.setTemplate(getTemplate(msExtract.getExpressionMatchingRule())); // 处理匹配多条等匹配规则 extractor.setMatchNumber(parseResultMatchingRule(msExtract)); - - // $1$提取 JSON 响应中的第一个匹配项 $0$用于提取整个 JSON 响应 - if (StringUtils.isBlank(msExtract.getExpressionMatchingRule())) { - extractor.setTemplate(RegexExtract.ExpressionRuleType.EXPRESSION.getValue()); - } else { - extractor.setTemplate(msExtract.getExpressionMatchingRule()); - } hashTree.add(extractor); } + + private String getTemplate(String expressionMatchingRule) { + // $1$提取 JSON 响应中的第一个匹配项 $0$用于提取整个 JSON 响应 + HashMap ruleValueMap = new HashMap<>() {{ + put(RegexExtract.ExpressionRuleType.EXPRESSION.name(), "$1$"); + put(RegexExtract.ExpressionRuleType.GROUP.name(), "$0$"); + }}; + if (StringUtils.isBlank(expressionMatchingRule)) { + return ruleValueMap.get(RegexExtract.ExpressionRuleType.EXPRESSION.name()); + } else { + return ruleValueMap.get(expressionMatchingRule); + } + } + + private String getUseField(String extractScope) { + HashMap extractScopeMap = new HashMap<>() {{ + put(RegexExtract.ExtractScope.BODY.name(), "false"); + put(RegexExtract.ExtractScope.REQUEST_HEADERS.name(), "request_headers"); + put(RegexExtract.ExtractScope.UNESCAPED_BODY.name(), "unescaped"); + put(RegexExtract.ExtractScope.BODY_AS_DOCUMENT.name(), "as_document"); + put(RegexExtract.ExtractScope.RESPONSE_HEADERS.name(), "true"); + put(RegexExtract.ExtractScope.URL.name(), "URL"); + put(RegexExtract.ExtractScope.RESPONSE_CODE.name(), "code"); + put(RegexExtract.ExtractScope.RESPONSE_MESSAGE.name(), "message"); + }}; + if (StringUtils.isNotBlank(extractScope)) { + return extractScopeMap.get(extractScope); + } else { + return RegexExtract.ExtractScope.BODY.name(); + } + } } diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/MsHTTPElementTest.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/MsHTTPElementTest.java index e00a30ec0e..d00944de6a 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/MsHTTPElementTest.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/MsHTTPElementTest.java @@ -24,6 +24,7 @@ import io.metersphere.plugin.api.dto.ParameterConfig; import io.metersphere.plugin.api.spi.AbstractMsTestElement; import io.metersphere.project.constants.ScriptLanguageType; import io.metersphere.sdk.constants.MsAssertionCondition; +import io.metersphere.sdk.util.BeanUtils; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -93,10 +94,7 @@ public class MsHTTPElementTest { xmlBody.setValue(""); body.setXmlBody(xmlBody); - BinaryBody binaryBody = new BinaryBody(); - binaryBody.setBodyFile(bodyFile); - body.setBinaryBody(binaryBody); - + body.setBinaryBody(BeanUtils.copyBean(new BinaryBody(), bodyFile)); return body; }