diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/MsAssertionCondition.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/MsAssertionCondition.java index 90e2a78c44..7aae35e92b 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/MsAssertionCondition.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/MsAssertionCondition.java @@ -12,11 +12,11 @@ public enum MsAssertionCondition { /** * 包含 */ - INCLUDE, + CONTAINS, /** * 不包含 */ - NOT_INCLUDE, + NOT_CONTAINS, /** * 等于 */ 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 425eeddede..f57681080b 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 @@ -10,11 +10,12 @@ import lombok.Data; @Data @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "assertionType") @JsonSubTypes({ - @JsonSubTypes.Type(value = ResponseCodeAssertion.class), - @JsonSubTypes.Type(value = ResponseHeaderAssertion.class), - @JsonSubTypes.Type(value = ResponseBodyAssertion.class), - @JsonSubTypes.Type(value = ResponseTimeAssertion.class), - @JsonSubTypes.Type(value = ScriptAssertion.class), + @JsonSubTypes.Type(value = MsResponseCodeAssertion.class), + @JsonSubTypes.Type(value = MsResponseHeaderAssertion.class), + @JsonSubTypes.Type(value = MsResponseBodyAssertion.class), + @JsonSubTypes.Type(value = MsResponseTimeAssertion.class), + @JsonSubTypes.Type(value = MsScriptAssertion.class), + @JsonSubTypes.Type(value = MsVariableAssertion.class), }) public abstract class MsAssertion { /** diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsBodyAssertionType.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsBodyAssertionType.java deleted file mode 100644 index a92a4268e1..0000000000 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsBodyAssertionType.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.metersphere.api.dto.request.assertion; - -/** - * body断言中的断言类型 - */ -public enum MsBodyAssertionType { - /** - * 正则断言 - */ - REGEX, - /** - * XPath断言 - */ - XPATH, - /** - * JSONPath断言 - */ - JSON_PATH, - /** - * 文档断言 - */ - DOCUMENT -} 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 new file mode 100644 index 0000000000..d8ff0e6683 --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsResponseBodyAssertion.java @@ -0,0 +1,89 @@ +package io.metersphere.api.dto.request.assertion; + +import com.fasterxml.jackson.annotation.JsonTypeName; +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 lombok.Data; + +import java.util.HashMap; +import java.util.Map; + +/** + * 请求体断言 + * + * @Author: jianxing + * @CreateTime: 2023-11-22 15:33 + */ +@Data +@JsonTypeName("RESPONSE_BODY") +public class MsResponseBodyAssertion extends MsAssertion { + /** + * 断言类型 + * 根据断言类型,选择对应的断言 + * 这里跟前端数据结构有差异 + * 后端从设计层面支持多种断言,前端只支持一种 + * 同时切换可以同时持久化两种类型 + * + * @see MsBodyAssertionType + */ + private String assertionBodyType; + /** + * jsonPath断言 + */ + private MsJSONPathAssertion jsonPathAssertion; + /** + * xpath断言 + */ + private MsXPathAssertion xpathAssertion; + /** + * 文档断言 + */ + private MsDocumentAssertion documentAssertion; + /** + * 正则断言 + */ + private MsRegexAssertion regexAssertion; + + private static Map bodyAssertionClassMap = new HashMap<>(); + + static { + bodyAssertionClassMap.put(MsBodyAssertionType.JSON_PATH, MsJSONPathAssertion.class); + bodyAssertionClassMap.put(MsBodyAssertionType.DOCUMENT, MsDocumentAssertion.class); + bodyAssertionClassMap.put(MsBodyAssertionType.REGEX, MsRegexAssertion.class); + bodyAssertionClassMap.put(MsBodyAssertionType.XPATH, MsXPathAssertion.class); + } + + public Class getBodyAssertionClassByType() { + return bodyAssertionClassMap.get(MsBodyAssertionType.valueOf(assertionBodyType)); + } + + public Object getBodyAssertionDataByType() { + Map boadyAssertionMap = new HashMap<>(); + boadyAssertionMap.put(MsBodyAssertionType.JSON_PATH, jsonPathAssertion); + boadyAssertionMap.put(MsBodyAssertionType.DOCUMENT, documentAssertion); + boadyAssertionMap.put(MsBodyAssertionType.REGEX, regexAssertion); + boadyAssertionMap.put(MsBodyAssertionType.XPATH, xpathAssertion); + return boadyAssertionMap.get(MsBodyAssertionType.valueOf(assertionBodyType)); + } + + public enum MsBodyAssertionType { + /** + * 正则断言 + */ + REGEX, + /** + * XPath断言 + */ + XPATH, + /** + * JSONPath断言 + */ + JSON_PATH, + /** + * 文档断言 + */ + DOCUMENT + } +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/ResponseCodeAssertion.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsResponseCodeAssertion.java similarity index 74% rename from backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/ResponseCodeAssertion.java rename to backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsResponseCodeAssertion.java index 6d9774d622..571d67ebf0 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/ResponseCodeAssertion.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsResponseCodeAssertion.java @@ -9,17 +9,17 @@ import lombok.Data; */ @Data @JsonTypeName("RESPONSE_CODE") -public class ResponseCodeAssertion extends MsAssertion { +public class MsResponseCodeAssertion extends MsAssertion { /** * 匹配条件 * 不校验即忽略状态 * 选择其他条件时,也忽略状态 * 不校验可搭配其他校验使用 - * 值为 MsAssertionCondition + * @see io.metersphere.sdk.constants.MsAssertionCondition */ private String condition; /** * 匹配值 */ - private String value; + private String expectedValue; } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/ResponseHeaderAssertion.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsResponseHeaderAssertion.java similarity index 88% rename from backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/ResponseHeaderAssertion.java rename to backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsResponseHeaderAssertion.java index a58d58553f..c583271ea5 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/ResponseHeaderAssertion.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsResponseHeaderAssertion.java @@ -12,7 +12,7 @@ import java.util.List; */ @Data @JsonTypeName("RESPONSE_HEADER") -public class ResponseHeaderAssertion extends MsAssertion { +public class MsResponseHeaderAssertion extends MsAssertion { private List assertions; @@ -35,6 +35,6 @@ public class ResponseHeaderAssertion extends MsAssertion { /** * 匹配值 */ - private String value; + private String expectedValue; } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/ResponseTimeAssertion.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsResponseTimeAssertion.java similarity index 78% rename from backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/ResponseTimeAssertion.java rename to backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsResponseTimeAssertion.java index 8305d395a7..3124cde58c 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/ResponseTimeAssertion.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsResponseTimeAssertion.java @@ -10,10 +10,10 @@ import lombok.Data; */ @Data @JsonTypeName("RESPONSE_TIME") -public class ResponseTimeAssertion extends MsAssertion { +public class MsResponseTimeAssertion extends MsAssertion { /** * 最大响应时间 * 响应时间在xx毫秒内 */ - private Long maxResponseTime; + private Long expectedValue; } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsScriptAssertion.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsScriptAssertion.java new file mode 100644 index 0000000000..9a1ffbcaf7 --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsScriptAssertion.java @@ -0,0 +1,39 @@ +package io.metersphere.api.dto.request.assertion; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.metersphere.api.dto.request.http.KeyValueParam; +import io.metersphere.api.dto.request.processors.ScriptProcessor; +import lombok.Data; + +import java.util.List; + +/** + * 变量断言 + * @Author: jianxing + * @CreateTime: 2023-11-22 15:33 + */ +@Data +@JsonTypeName("SCRIPT") +public class MsScriptAssertion extends MsAssertion { + /** + * 脚本内容 + */ + private String script; + /** + * 脚本语言 + * @see ScriptProcessor.ScriptLanguageType + */ + private String scriptLanguage; + /** + * 是否启用公共脚本 + */ + private Boolean enableCommonScript; + /** + * 脚本ID + */ + private String scriptId; + /** + * 公共脚本入参 + */ + private List params; +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/VariableAssertion.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsVariableAssertion.java similarity index 76% rename from backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/VariableAssertion.java rename to backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsVariableAssertion.java index d2096a3ad6..b36b1aea73 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/VariableAssertion.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/MsVariableAssertion.java @@ -12,9 +12,9 @@ import java.util.List; */ @Data @JsonTypeName("VARIABLE") -public class VariableAssertion { +public class MsVariableAssertion extends MsAssertion { - private List variableAssertionItem; + private List variableAssertionItems; @Data public static class VariableAssertionItem { /** @@ -24,7 +24,7 @@ public class VariableAssertion { /** * 变量名 */ - private String name; + private String variableName; /** * 匹配条件 * 值为 MsAssertionCondition @@ -33,6 +33,6 @@ public class VariableAssertion { /** * 匹配值 */ - private String value; + private String expectedValue; } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/ResponseBodyAssertion.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/ResponseBodyAssertion.java deleted file mode 100644 index d6468aa1a7..0000000000 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/ResponseBodyAssertion.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.metersphere.api.dto.request.assertion; - -import com.fasterxml.jackson.annotation.JsonTypeName; -import io.metersphere.api.dto.request.assertion.body.DocumentAssertion; -import io.metersphere.api.dto.request.assertion.body.JSONPathAssertion; -import io.metersphere.api.dto.request.assertion.body.RegexAssertion; -import io.metersphere.api.dto.request.assertion.body.XPathAssertion; -import lombok.Data; - -/** - * 请求体断言 - * @Author: jianxing - * @CreateTime: 2023-11-22 15:33 - */ -@Data -@JsonTypeName("RESPONSE_BODY") -public class ResponseBodyAssertion extends MsAssertion { - /** - * 断言类型 - * 根据断言类型,选择对应的断言 - * 这里跟前端数据结构有差异 - * 后端从设计层面支持多种断言,前端只支持一种 - * 同时切换可以同时持久化两种类型 - * 值为 MsBodyAssertionType - */ - private String assertionType; - /** - * jsonPath断言 - */ - private JSONPathAssertion jsonPathAssertion; - /** - * xpath断言 - */ - private XPathAssertion xpathAssertion; - /** - * 文档断言 - */ - private DocumentAssertion documentAssertion; - /** - * 正则断言 - */ - private RegexAssertion regexAssertion; -} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/ScriptAssertion.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/ScriptAssertion.java deleted file mode 100644 index e4fec4c4d9..0000000000 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/ScriptAssertion.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.metersphere.api.dto.request.assertion; - -import com.fasterxml.jackson.annotation.JsonTypeName; -import lombok.Data; - -/** - * 变量断言 - * @Author: jianxing - * @CreateTime: 2023-11-22 15:33 - */ -@Data -@JsonTypeName("SCRIPT") -public class ScriptAssertion extends MsAssertion { - /** - * 脚本描述 - */ - private String description; - /** - * 脚本内容 - */ - private String content; - /** - * 是否使用功能脚本 - * 公共脚本和手动录入脚本只能二选一 - */ - private Boolean enableCommonScript; - /** - * 引用公共脚本的ID - */ - private String commonScriptId; -} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/JSONPathAssertionItem.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/JSONPathAssertionItem.java deleted file mode 100644 index 151c634b6a..0000000000 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/JSONPathAssertionItem.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.metersphere.api.dto.request.assertion.body; - -import lombok.Data; - -/** - * - * JSONPath断言 - * @Author: jianxing - * @CreateTime: 2023-11-23 14:04 - */ -@Data -public class JSONPathAssertionItem extends BodyAssertionItem { - private String expression; - private String condition; - private String value; -} - diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/BodyAssertionItem.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsBodyAssertionItem.java similarity index 82% rename from backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/BodyAssertionItem.java rename to backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsBodyAssertionItem.java index d52e770dc4..7fba37263c 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/BodyAssertionItem.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsBodyAssertionItem.java @@ -8,6 +8,6 @@ import lombok.Data; * @CreateTime: 2023-11-23 14:25 */ @Data -public abstract class BodyAssertionItem { +public abstract class MsBodyAssertionItem { private Boolean enable = true; } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/DocumentAssertion.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsDocumentAssertion.java similarity index 72% rename from backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/DocumentAssertion.java rename to backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsDocumentAssertion.java index cd62b0cfb9..3803c80a98 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/DocumentAssertion.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsDocumentAssertion.java @@ -8,7 +8,7 @@ import lombok.Data; * @CreateTime: 2023-11-23 14:19 */ @Data -public class DocumentAssertion extends BodyAssertionItem { +public class MsDocumentAssertion extends MsBodyAssertionItem { /** * 跟随定义的apiId * 传空为不跟随接口定义 @@ -21,14 +21,20 @@ public class DocumentAssertion extends BodyAssertionItem { * 这里跟前端数据结构有差异 * 后端从设计层面支持多种文档格式,前端只支持一种 * 同时切换可以同时持久化两种格式 + * @see DocumentType */ private String documentType; /** * json格式的文档断言 */ - private DocumentAssertionElement jsonAssertion; + private MsDocumentAssertionElement jsonAssertion; /** * xml格式的文档断言 */ - private DocumentAssertionElement xmlAssertion; + private MsDocumentAssertionElement xmlAssertion; + + public enum DocumentType { + JSON, + XML; + } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/DocumentAssertionElement.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsDocumentAssertionElement.java similarity index 88% rename from backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/DocumentAssertionElement.java rename to backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsDocumentAssertionElement.java index 4717a2e6d0..a3e3f2d3cf 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/DocumentAssertionElement.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsDocumentAssertionElement.java @@ -9,7 +9,7 @@ import java.util.List; * @CreateTime: 2023-11-23 11:43 */ @Data -public class DocumentAssertionElement { +public class MsDocumentAssertionElement { private String id; /** * 参数名 @@ -43,5 +43,5 @@ public class DocumentAssertionElement { /** * 子对象 */ - private List children; + private List children; } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/JSONPathAssertion.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsJSONPathAssertion.java similarity index 72% rename from backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/JSONPathAssertion.java rename to backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsJSONPathAssertion.java index 94351dd498..d4479d8ae2 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/JSONPathAssertion.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsJSONPathAssertion.java @@ -11,11 +11,11 @@ import java.util.List; * @CreateTime: 2023-11-23 14:04 */ @Data -public class JSONPathAssertion { +public class MsJSONPathAssertion { /** * 断言列表 */ - private List assertions; + private List assertions; } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsJSONPathAssertionItem.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsJSONPathAssertionItem.java new file mode 100644 index 0000000000..93bccc82b5 --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsJSONPathAssertionItem.java @@ -0,0 +1,23 @@ +package io.metersphere.api.dto.request.assertion.body; + +import lombok.Data; +import org.apache.commons.lang3.StringUtils; + +/** + * + * JSONPath断言 + * @Author: jianxing + * @CreateTime: 2023-11-23 14:04 + */ +@Data +public class MsJSONPathAssertionItem extends MsBodyAssertionItem { + private String expression; + private String condition; + private String expectedValue; + + + public boolean isValid() { + return StringUtils.isNotBlank(expression) && StringUtils.isNotBlank(condition) && StringUtils.isNotBlank(expectedValue); + } +} + diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/RegexAssertion.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsRegexAssertion.java similarity index 72% rename from backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/RegexAssertion.java rename to backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsRegexAssertion.java index 8ff151e340..6dedf8d041 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/RegexAssertion.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsRegexAssertion.java @@ -10,9 +10,9 @@ import java.util.List; * @CreateTime: 2023-11-23 14:03 */ @Data -public class RegexAssertion { +public class MsRegexAssertion { /** * 断言列表 */ - private List assertions; + private List assertions; } \ No newline at end of file diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsRegexAssertionItem.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsRegexAssertionItem.java new file mode 100644 index 0000000000..2c66ee2bd3 --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsRegexAssertionItem.java @@ -0,0 +1,18 @@ +package io.metersphere.api.dto.request.assertion.body; + +import lombok.Data; +import org.apache.commons.lang3.StringUtils; + +/** + * 正则断言 + * @Author: jianxing + * @CreateTime: 2023-11-23 14:03 + */ +@Data +public class MsRegexAssertionItem extends MsBodyAssertionItem { + private String expression; + + public boolean isValid() { + return StringUtils.isNotBlank(expression); + } +} \ No newline at end of file diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/XPathAssertion.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsXPathAssertion.java similarity index 52% rename from backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/XPathAssertion.java rename to backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsXPathAssertion.java index fdacbb8171..c8360199d6 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/XPathAssertion.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsXPathAssertion.java @@ -11,14 +11,25 @@ import java.util.List; * @CreateTime: 2023-11-23 14:18 */ @Data -public class XPathAssertion { +public class MsXPathAssertion { /** * 响应内容格式 * xml 或者 html */ - private String format; + private String responseFormat; /** * xpath断言 */ - private List assertions; + private List assertions; + + public enum ResponseFormat { + /** + * XML + */ + XML, + /** + * HTML + */ + HTML + } } \ No newline at end of file diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsXPathAssertionItem.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsXPathAssertionItem.java new file mode 100644 index 0000000000..317a7609a5 --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/MsXPathAssertionItem.java @@ -0,0 +1,20 @@ +package io.metersphere.api.dto.request.assertion.body; + + +import lombok.Data; +import org.apache.commons.lang3.StringUtils; + +/** + * XPath断言 + * @Author: jianxing + * @CreateTime: 2023-11-23 14:18 + */ +@Data +public class MsXPathAssertionItem extends MsBodyAssertionItem { + private String expression; + private String expectedValue; + + public boolean isValid() { + return StringUtils.isNotBlank(expression) && StringUtils.isNotBlank(expectedValue); + } +} \ No newline at end of file diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/RegexAssertionItem.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/RegexAssertionItem.java deleted file mode 100644 index 4011494e99..0000000000 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/RegexAssertionItem.java +++ /dev/null @@ -1,13 +0,0 @@ -package io.metersphere.api.dto.request.assertion.body; - -import lombok.Data; - -/** - * 正则断言 - * @Author: jianxing - * @CreateTime: 2023-11-23 14:03 - */ -@Data -public class RegexAssertionItem extends BodyAssertionItem { - private String expression; -} \ No newline at end of file diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/XPathAssertionItem.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/XPathAssertionItem.java deleted file mode 100644 index ed5d9f7e6a..0000000000 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/request/assertion/body/XPathAssertionItem.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.metersphere.api.dto.request.assertion.body; - - -import lombok.Data; -/** - * XPath断言 - * @Author: jianxing - * @CreateTime: 2023-11-23 14:18 - */ -@Data -public class XPathAssertionItem extends BodyAssertionItem { - private String expression; - private String condition; - private String value; -} \ No newline at end of file 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 163e76e9c6..b0349c7c13 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 @@ -25,7 +25,7 @@ public class ScriptProcessor extends MsProcessor { /** * 是否启用公共脚本 */ - private Boolean enableCommonScript; + private Boolean enableCommonScript = false; /** * 脚本ID */ 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 fe8a8595c6..16d7155b2a 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 @@ -25,6 +25,10 @@ public abstract class MsExtract { * 表达式 */ private String expression; + /** + * 是否启用 + */ + private Boolean enable = true; public boolean isValid() { return StringUtils.isNotBlank(variableName) && StringUtils.isNotBlank(expression); diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsCommonElementConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsCommonElementConverter.java index c5fd7904e8..423bcd4792 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsCommonElementConverter.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsCommonElementConverter.java @@ -2,10 +2,16 @@ package io.metersphere.api.parser.jmeter; import io.metersphere.api.dto.request.MsCommonElement; +import io.metersphere.api.dto.request.assertion.MsAssertion; +import io.metersphere.api.dto.request.assertion.MsAssertionConfig; +import io.metersphere.api.dto.request.assertion.MsResponseCodeAssertion; import io.metersphere.api.dto.request.processors.MsProcessorConfig; import io.metersphere.api.parser.jmeter.processor.MsProcessorConverterFactory; +import io.metersphere.api.parser.jmeter.processor.assertion.AssertionConverterFactory; import io.metersphere.plugin.api.dto.ParameterConfig; import io.metersphere.plugin.api.spi.AbstractJmeterElementConverter; +import io.metersphere.sdk.constants.MsAssertionCondition; +import org.apache.commons.lang3.StringUtils; import org.apache.jorphan.collections.HashTree; /** @@ -26,6 +32,29 @@ public class MsCommonElementConverter extends AbstractJmeterElementConverter AssertionConverterFactory.getConverter(assertion.getClass()).parse(tree, assertion, config, finalIsIgnoreStatus)); } private void handlePreProcessor(HashTree tree, MsProcessorConfig preProcessorConfig, ParameterConfig config) { diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsHTTPElementConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsHTTPElementConverter.java index 19e2210b3f..62ce37e750 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsHTTPElementConverter.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/MsHTTPElementConverter.java @@ -18,6 +18,8 @@ import org.apache.jmeter.testelement.TestElement; import org.apache.jorphan.collections.HashTree; import org.springframework.http.HttpMethod; +import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.HTTP_TEST_SAMPLE_GUI; + /** * @Author: jianxing * @CreateTime: 2023-10-27 10:07 @@ -38,7 +40,7 @@ public class MsHTTPElementConverter extends AbstractJmeterElementConverter - ExtractConverterFactory.getConverter(extract.getClass()) - .parse(hashTree, extract, config)); + .forEach(extract -> { + // 单调提取器的 enable 跟随整体的 enable + extract.setEnable(processor.getEnable()); + ExtractConverterFactory.getConverter(extract.getClass()) + .parse(hashTree, extract, config); + }); } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/ScriptProcessorConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/ScriptProcessorConverter.java index 521e2fa8da..97e00f257a 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/ScriptProcessorConverter.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/ScriptProcessorConverter.java @@ -16,7 +16,7 @@ public abstract class ScriptProcessorConverter extends MsProcessorConverter { + /** + * 解析对应的提取器 + * @param hashTree + * @param extract + * @param config + */ + public abstract void parse(HashTree hashTree, T extract, ParameterConfig config, boolean isIgnoreStatus); + + protected boolean needParse(MsAssertion msAssertion, ParameterConfig config) { + // 如果组件是启用的,或者设置了解析禁用的组件,则返回 true + if (BooleanUtils.isTrue(msAssertion.getEnable()) || config.getParseDisabledElement()) { + return true; + } + return false; + } + + public static ResponseAssertion createResponseAssertion() { + ResponseAssertion assertion = new ResponseAssertion(); + assertion.setProperty(TestElement.TEST_CLASS, ResponseAssertion.class.getName()); + assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass(ASSERTION_GUI)); + return assertion; + } + + protected String generateRegexExpression(String condition, String text) { + Map> regexgenerateMap = new HashMap<>(); + // 只支持以下条件 + regexgenerateMap.put(MsAssertionCondition.CONTAINS, value -> StringUtils.join(".*", value, ".*")); + regexgenerateMap.put(MsAssertionCondition.NOT_CONTAINS, value -> StringUtils.join("(?s)^((?!", value, ").)*$")); + regexgenerateMap.put(MsAssertionCondition.END_WITH, value -> StringUtils.join(value, "$")); + regexgenerateMap.put(MsAssertionCondition.START_WITH, value -> StringUtils.join("^", value)); + regexgenerateMap.put(MsAssertionCondition.EQUALS, value -> StringUtils.join("^", value, "$")); + regexgenerateMap.put(MsAssertionCondition.NOT_EQUALS, value -> StringUtils.join("^(?!", value, "$).*$")); + regexgenerateMap.put(MsAssertionCondition.EMPTY, value -> StringUtils.join("^$", value)); + regexgenerateMap.put(MsAssertionCondition.NOT_EMPTY, value -> StringUtils.join("^(?!^$).*$", value)); + regexgenerateMap.put(MsAssertionCondition.REGEX, value -> value); + MsAssertionCondition msAssertionCondition = MsAssertionCondition.valueOf(condition); + if (msAssertionCondition != null && regexgenerateMap.get(msAssertionCondition) != null) { + return regexgenerateMap.get(msAssertionCondition).apply(text); + } + return text; + } +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/AssertionConverterFactory.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/AssertionConverterFactory.java new file mode 100644 index 0000000000..2ffaff98fe --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/AssertionConverterFactory.java @@ -0,0 +1,27 @@ +package io.metersphere.api.parser.jmeter.processor.assertion; + +import io.metersphere.api.dto.request.assertion.*; + +import java.util.HashMap; +import java.util.Map; + +/** + * @Author: jianxing + * @CreateTime: 2023-12-27 10:31 + */ +public class AssertionConverterFactory { + private static Map converterMap = new HashMap<>(); + + static { + converterMap.put(MsResponseCodeAssertion.class, new ResponseCodeAssertionConverter()); + converterMap.put(MsResponseHeaderAssertion.class, new ResponseHeaderAssertionConverter()); + converterMap.put(MsResponseBodyAssertion.class, new ResponseBodyAssertionConverter()); + converterMap.put(MsResponseTimeAssertion.class, new ResponseTimeAssertionConverter()); + converterMap.put(MsScriptAssertion.class, new ScriptAssertionConverter()); + converterMap.put(MsVariableAssertion.class, new VariableAssertionConverter()); + } + + public static AssertionConverter getConverter(Class processorClass) { + return converterMap.get(processorClass); + } +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/ResponseBodyAssertionConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/ResponseBodyAssertionConverter.java new file mode 100644 index 0000000000..a2f9d3c000 --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/ResponseBodyAssertionConverter.java @@ -0,0 +1,22 @@ +package io.metersphere.api.parser.jmeter.processor.assertion; + +import io.metersphere.api.dto.request.assertion.MsResponseBodyAssertion; +import io.metersphere.api.parser.jmeter.processor.assertion.body.ResponseBodyTypeAssertionConverter; +import io.metersphere.api.parser.jmeter.processor.assertion.body.ResponseBodyTypeAssertionFactory; +import io.metersphere.plugin.api.dto.ParameterConfig; +import org.apache.jorphan.collections.HashTree; + +/** + * @Author: jianxing + * @CreateTime: 2023-12-27 21:01 + */ +public class ResponseBodyAssertionConverter extends AssertionConverter { + @Override + public void parse(HashTree hashTree, MsResponseBodyAssertion msAssertion, ParameterConfig config, boolean isIgnoreStatus) { + if (!needParse(msAssertion, config)) { + return; + } + ResponseBodyTypeAssertionConverter converter = ResponseBodyTypeAssertionFactory.getConverter(msAssertion.getBodyAssertionClassByType()); + converter.parse(hashTree, msAssertion.getBodyAssertionDataByType(), config, isIgnoreStatus, msAssertion.getEnable()); + } +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/ResponseCodeAssertionConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/ResponseCodeAssertionConverter.java new file mode 100644 index 0000000000..74a334fda4 --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/ResponseCodeAssertionConverter.java @@ -0,0 +1,48 @@ +package io.metersphere.api.parser.jmeter.processor.assertion; + +import io.metersphere.api.dto.request.assertion.MsResponseCodeAssertion; +import io.metersphere.plugin.api.dto.ParameterConfig; +import io.metersphere.sdk.constants.MsAssertionCondition; +import org.apache.commons.lang3.StringUtils; +import org.apache.jmeter.assertions.ResponseAssertion; +import org.apache.jorphan.collections.HashTree; + +/** + * @Author: jianxing + * @CreateTime: 2023-12-27 21:01 + */ +public class ResponseCodeAssertionConverter extends AssertionConverter { + @Override + public void parse(HashTree hashTree, MsResponseCodeAssertion msAssertion, ParameterConfig config, boolean isIgnoreStatus) { + if (!needParse(msAssertion, config) || !isValid(msAssertion)) { + return; + } + hashTree.add(parse2ResponseAssertion(msAssertion, isIgnoreStatus)); + } + + public boolean isValid(MsResponseCodeAssertion msAssertion) { + return StringUtils.isNotBlank(msAssertion.getExpectedValue()) && StringUtils.isNotBlank(msAssertion.getCondition()); + } + + private ResponseAssertion parse2ResponseAssertion(MsResponseCodeAssertion msAssertion, boolean isIgnoreStatus) { + ResponseAssertion assertion = createResponseAssertion(); + String expectedValue = msAssertion.getExpectedValue(); + assertion.setEnabled(msAssertion.getEnable()); + + assertion.setAssumeSuccess(false); + assertion.setAssumeSuccess(isIgnoreStatus); + assertion.setEnabled(msAssertion.getEnable()); + + String condition = msAssertion.getCondition(); + assertion.setName(String.format("Response code %s %s", condition.toLowerCase().replace("_", ""), expectedValue)); + MsAssertionCondition msAssertionCondition = MsAssertionCondition.valueOf(condition); + if (msAssertionCondition!= null) { + assertion.addTestString(generateRegexExpression(condition, expectedValue)); + } else { + assertion.addTestString(expectedValue); + } + assertion.setToContainsType(); + assertion.setTestFieldResponseCode(); + return assertion; + } +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/ResponseHeaderAssertionConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/ResponseHeaderAssertionConverter.java new file mode 100644 index 0000000000..27c5ef60aa --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/ResponseHeaderAssertionConverter.java @@ -0,0 +1,61 @@ +package io.metersphere.api.parser.jmeter.processor.assertion; + +import io.metersphere.api.dto.request.assertion.MsResponseHeaderAssertion; +import io.metersphere.plugin.api.dto.ParameterConfig; +import io.metersphere.sdk.constants.MsAssertionCondition; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.jmeter.assertions.ResponseAssertion; +import org.apache.jorphan.collections.HashTree; + +/** + * @Author: jianxing + * @CreateTime: 2023-12-27 21:01 + */ +public class ResponseHeaderAssertionConverter extends AssertionConverter { + @Override + public void parse(HashTree hashTree, MsResponseHeaderAssertion msAssertion, ParameterConfig config, boolean isIgnoreStatus) { + if (!needParse(msAssertion, config)) { + return; + } + Boolean globalEnable = msAssertion.getEnable(); + msAssertion.getAssertions() + .stream() + .filter(this::isHeaderAssertionValid) + .forEach(headerAssertionItem -> { + ResponseAssertion responseAssertion = parse2ResponseAssertion(headerAssertionItem, globalEnable); + responseAssertion.setAssumeSuccess(isIgnoreStatus); + hashTree.add(responseAssertion); + }); + } + + + public boolean isHeaderAssertionValid(MsResponseHeaderAssertion.ResponseHeaderAssertionItem headerAssertionItem) { + return StringUtils.isNotBlank(headerAssertionItem.getHeader()) + && StringUtils.isNotBlank(headerAssertionItem.getCondition()) + && StringUtils.isNotBlank(headerAssertionItem.getExpectedValue()); + } + + private ResponseAssertion parse2ResponseAssertion(MsResponseHeaderAssertion.ResponseHeaderAssertionItem msAssertion, + Boolean globalEnable) { + ResponseAssertion assertion = createResponseAssertion(); + assertion.setEnabled(msAssertion.getEnable()); + if (BooleanUtils.isFalse(globalEnable)) { + // 如果整体禁用,则禁用 + assertion.setEnabled(false); + } + String expectedValue = msAssertion.getExpectedValue(); + String condition = msAssertion.getCondition(); + assertion.setName(String.format("Response header %s %s", condition.toLowerCase().replace("_", ""), expectedValue)); + MsAssertionCondition msAssertionCondition = MsAssertionCondition.valueOf(condition); + if (msAssertionCondition!= null) { + assertion.addTestString(generateRegexExpression(condition, expectedValue)); + } else { + assertion.addTestString(expectedValue); + } + assertion.setToContainsType(); + + assertion.setTestFieldResponseHeaders(); + return assertion; + } +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/ResponseTimeAssertionConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/ResponseTimeAssertionConverter.java new file mode 100644 index 0000000000..41f36f1776 --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/ResponseTimeAssertionConverter.java @@ -0,0 +1,42 @@ +package io.metersphere.api.parser.jmeter.processor.assertion; + +import io.metersphere.api.dto.request.assertion.MsResponseTimeAssertion; +import io.metersphere.plugin.api.dto.ParameterConfig; +import org.apache.jmeter.assertions.DurationAssertion; +import org.apache.jmeter.save.SaveService; +import org.apache.jmeter.testelement.TestElement; +import org.apache.jorphan.collections.HashTree; + +import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.DURATION_ASSERTION_GUI; + +/** + * @Author: jianxing + * @CreateTime: 2023-12-27 21:01 + */ +public class ResponseTimeAssertionConverter extends AssertionConverter { + + + @Override + public void parse(HashTree hashTree, MsResponseTimeAssertion msAssertion, ParameterConfig config, boolean isIgnoreStatus) { + if (!needParse(msAssertion, config) || !isValid(msAssertion)) { + return; + } + hashTree.add(parse2DurationAssertion(msAssertion)); + } + + private DurationAssertion parse2DurationAssertion(MsResponseTimeAssertion msAssertion) { + DurationAssertion assertion = new DurationAssertion(); + assertion.setEnabled(msAssertion.getEnable()); + assertion.setName("Response In Time: " + msAssertion.getExpectedValue()); + assertion.setProperty(TestElement.TEST_CLASS, DurationAssertion.class.getName()); + assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass(DURATION_ASSERTION_GUI)); + assertion.setAllowedDuration(msAssertion.getExpectedValue()); + return assertion; + } + + public boolean isValid(MsResponseTimeAssertion msAssertion) { + return msAssertion.getExpectedValue() != null && msAssertion.getExpectedValue() > 0; + } + + +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/ScriptAssertionConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/ScriptAssertionConverter.java new file mode 100644 index 0000000000..1359b45cea --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/ScriptAssertionConverter.java @@ -0,0 +1,32 @@ +package io.metersphere.api.parser.jmeter.processor.assertion; + +import io.metersphere.api.dto.request.assertion.MsScriptAssertion; +import io.metersphere.api.dto.request.processors.ScriptProcessor; +import io.metersphere.api.parser.jmeter.processor.ScriptProcessorConverter; +import io.metersphere.plugin.api.dto.ParameterConfig; +import io.metersphere.sdk.util.BeanUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.jmeter.assertions.JSR223Assertion; +import org.apache.jorphan.collections.HashTree; + +/** + * @Author: jianxing + * @CreateTime: 2023-12-27 21:01 + */ +public class ScriptAssertionConverter extends AssertionConverter { + @Override + public void parse(HashTree hashTree, MsScriptAssertion msAssertion, ParameterConfig config, boolean isIgnoreStatus) { + if (!needParse(msAssertion, config) || !isValid(msAssertion)) { + return; + } + + JSR223Assertion jsr223Assertion = new JSR223Assertion(); + ScriptProcessorConverter.parse(jsr223Assertion, BeanUtils.copyBean(new ScriptProcessor(), msAssertion)); + hashTree.add(jsr223Assertion); + } + + public boolean isValid(MsScriptAssertion msAssertion) { + // todo 公共脚本库 + return StringUtils.isNotBlank(msAssertion.getScript()); + } +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/VariableAssertionConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/VariableAssertionConverter.java new file mode 100644 index 0000000000..6b8b3ea080 --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/VariableAssertionConverter.java @@ -0,0 +1,210 @@ +package io.metersphere.api.parser.jmeter.processor.assertion; + +import io.metersphere.api.dto.request.assertion.MsVariableAssertion; +import io.metersphere.api.dto.request.processors.ScriptProcessor; +import io.metersphere.api.parser.jmeter.processor.ScriptProcessorConverter; +import io.metersphere.plugin.api.dto.ParameterConfig; +import io.metersphere.sdk.constants.MsAssertionCondition; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.jmeter.assertions.JSR223Assertion; +import org.apache.jorphan.collections.HashTree; + +import java.util.HashMap; + +/** + * @Author: jianxing + * @CreateTime: 2023-12-27 21:01 + */ +public class VariableAssertionConverter extends AssertionConverter { + @Override + public void parse(HashTree hashTree, MsVariableAssertion msAssertion, ParameterConfig config, boolean isIgnoreStatus) { + if (!needParse(msAssertion, config)) { + return; + } + Boolean globalEnable = msAssertion.getEnable(); + msAssertion.getVariableAssertionItems() + .stream() + .filter(this::isValid) + .forEach(variableAssertionItem -> { + if (needParse(variableAssertionItem, config)) { + JSR223Assertion jsr223Assertion = parse2JSR233Assertion(variableAssertionItem); + jsr223Assertion.setEnabled(variableAssertionItem.getEnable()); + if (BooleanUtils.isFalse(globalEnable)) { + // 如果整体禁用,则禁用 + jsr223Assertion.setEnabled(false); + } + hashTree.add(jsr223Assertion); + } + }); + } + + protected boolean needParse(MsVariableAssertion.VariableAssertionItem variableAssertionItem, ParameterConfig config) { + // 如果组件是启用的,或者设置了解析禁用的组件,则返回 true + if (BooleanUtils.isTrue(variableAssertionItem.getEnable()) || config.getParseDisabledElement()) { + return true; + } + return false; + } + + private static JSR223Assertion parse2JSR233Assertion(MsVariableAssertion.VariableAssertionItem variableAssertionItem) { + ScriptProcessor scriptProcessor = new ScriptProcessor(); + scriptProcessor.setScript(parse2BeanshellJSR233Script(variableAssertionItem)); + + String variableName = variableAssertionItem.getVariableName(); + String condition = variableAssertionItem.getCondition(); + String expectedValue = variableAssertionItem.getExpectedValue(); + String name = String.format("Variable '%s' expect %s %s", variableName, condition.toLowerCase().replace("_", ""), expectedValue); + scriptProcessor.setName(name); + + scriptProcessor.setScriptLanguage(ScriptProcessor.ScriptLanguageType.BEANSHELL_JSR233.getValue()); + JSR223Assertion jsr223Assertion = new JSR223Assertion(); + ScriptProcessorConverter.parse(jsr223Assertion, scriptProcessor); + return jsr223Assertion; + } + + public boolean isValid(MsVariableAssertion.VariableAssertionItem variableAssertionItem) { + return StringUtils.isNotBlank(variableAssertionItem.getVariableName()) && StringUtils.isNotBlank(variableAssertionItem.getExpectedValue()) + && StringUtils.isNotBlank(variableAssertionItem.getCondition()); + } + + private static String parse2BeanshellJSR233Script(MsVariableAssertion.VariableAssertionItem variableAssertionItem) { + HashMap handleMap = new HashMap<>(); + String script = String.format( + """ + variableValue = vars.get("%s"); + expectation = "%s"; + flag = true; + """, variableAssertionItem.getVariableName(), variableAssertionItem.getExpectedValue()); + + handleMap.put(MsAssertionCondition.EQUALS.name(), + """ + result = expectation.equals(variableValue);" + msg = "value == " + expectation; + """); + + handleMap.put(MsAssertionCondition.NOT_EQUALS.name(), + """ + result = !expectation.equals(variableValue); + msg = "value != " + expectation; + """); + + handleMap.put(MsAssertionCondition.CONTAINS.name(), + """ + result = expectation.contains(variableValue); + msg = "value contains " + expectation; + """); + + handleMap.put(MsAssertionCondition.NOT_CONTAINS.name(), + """ + result = !expectation.contains(variableValue); + msg = "value not contains " + expectation; + """); + + handleMap.put(MsAssertionCondition.GT.name(), + """ + number = Integer.parseInt(expectation); + result = number > expectation; + msg = "value > " + expectation; + """); + + handleMap.put(MsAssertionCondition.GT_OR_EQUALS.name(), + """ + number = Integer.parseInt(expectation); + result = number >= expectation; + msg = "value >= " + expectation; + """); + + handleMap.put(MsAssertionCondition.LT.name(), + """ + number = Integer.parseInt(expectation); + result = number < expectation; + msg = "value < " + expectation; + """); + + handleMap.put(MsAssertionCondition.LT_OR_EQUALS.name(), + """ + number = Integer.parseInt(expectation); + result = number <= expectation; + msg = "value <= " + expectation; + """); + + handleMap.put(MsAssertionCondition.START_WITH.name(), + """ + result = expectation.startsWith(variableValue); + msg = "value start with " + expectation; + """); + + handleMap.put(MsAssertionCondition.END_WITH.name(), + """ + result = expectation.endWith(variableValue); + msg = "value end with " + expectation; + """); + + handleMap.put(MsAssertionCondition.LENGTH_EQUALS.name(), + """ + number = Integer.parseInt(expectation); + result = variableValue.length() == number; + msg = "value length == " + expectation; + """); + + handleMap.put(MsAssertionCondition.LENGTH_GT.name(), + """ + number = Integer.parseInt(expectation); + result = variableValue.length() > number; + msg = "value length > " + expectation; + """); + + handleMap.put(MsAssertionCondition.LENGTH_GT.name(), + """ + number = Integer.parseInt(expectation); + result = variableValue.length() >= number; + msg = "value length >= " + expectation; + """); + + handleMap.put(MsAssertionCondition.LENGTH_LT.name(), + """ + number = Integer.parseInt(expectation); + result = variableValue.length() < number; + msg = "value length < " + expectation; + """); + + handleMap.put(MsAssertionCondition.LENGTH_LT_OR_EQUALS.name(), + """ + number = Integer.parseInt(expectation); + result = variableValue.length() <= number; + msg = "value length <= " + expectation; + """); + + handleMap.put(MsAssertionCondition.EMPTY.name(), + """ + result = variableValue == void || variableValue.length() == 0; + msg = "value is empty"; + flag = false; + """); + + handleMap.put(MsAssertionCondition.NOT_EMPTY.name(), + """ + result = variableValue != void && variableValue.length() > 0; + msg = "value is not empty"; + flag = false; + """); + + String condition = variableAssertionItem.getCondition(); + String handleScript = handleMap.get(condition); + if (StringUtils.isNotBlank(handleScript)) { + script += handleMap.get(MsAssertionCondition.EQUALS.name()); + } + + script += """ + if (!result) { + if (flag) { + msg = "assertion [" + msg + "]: false;"; + } + AssertionResult.setFailureMessage(msg); + AssertionResult.setFailure(true); + } + """; + return script; + } +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/body/DocumentAssertionConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/body/DocumentAssertionConverter.java new file mode 100644 index 0000000000..db6386113e --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/body/DocumentAssertionConverter.java @@ -0,0 +1,28 @@ +package io.metersphere.api.parser.jmeter.processor.assertion.body; + +import io.metersphere.api.dto.request.assertion.body.MsDocumentAssertion; +import io.metersphere.plugin.api.dto.ParameterConfig; +import org.apache.jorphan.collections.HashTree; + +/** + * @Author: jianxing + * @CreateTime: 2024-01-03 10:05 + */ +public class DocumentAssertionConverter extends ResponseBodyTypeAssertionConverter { + @Override + public void parse(HashTree hashTree, MsDocumentAssertion msAssertion, ParameterConfig config, boolean isIgnoreStatus, boolean globalEnable) { + if (msAssertion == null) { + return; + } + // todo 定义好 jsonschema 再补充 +// String documentType = msAssertion.getDocumentType(); +// MsDocumentAssertionElement documentAssertionElement; +// if (StringUtils.equals(documentType, MsDocumentAssertion.DocumentType.XML.name())) { +// documentAssertionElement = msAssertion.getXmlAssertion(); +// } else { +// documentAssertionElement = msAssertion.getJsonAssertion(); +// } + } + + +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/body/JSONPathAssertionConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/body/JSONPathAssertionConverter.java new file mode 100644 index 0000000000..1079e1102b --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/body/JSONPathAssertionConverter.java @@ -0,0 +1,51 @@ +package io.metersphere.api.parser.jmeter.processor.assertion.body; + +import io.metersphere.api.dto.request.assertion.body.MsJSONPathAssertion; +import io.metersphere.api.dto.request.assertion.body.MsJSONPathAssertionItem; +import io.metersphere.assertions.JSONPathAssertion; +import io.metersphere.plugin.api.dto.ParameterConfig; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.jmeter.testelement.TestElement; +import org.apache.jorphan.collections.HashTree; + +/** + * @Author: jianxing + * @CreateTime: 2024-01-03 10:05 + */ +public class JSONPathAssertionConverter extends ResponseBodyTypeAssertionConverter { + @Override + public void parse(HashTree hashTree, MsJSONPathAssertion msAssertion, ParameterConfig config, boolean isIgnoreStatus, boolean globalEnable) { + if (msAssertion == null || msAssertion.getAssertions() == null) { + return; + } + msAssertion.getAssertions().stream() + .filter(MsJSONPathAssertionItem::isValid) + .forEach(msJSONPathAssertionItem -> { + if (needParse(msJSONPathAssertionItem, config)) { + hashTree.add(parse2JSONPathAssertion(msJSONPathAssertionItem, globalEnable)); + } + }); + } + + private JSONPathAssertion parse2JSONPathAssertion(MsJSONPathAssertionItem msAssertion, Boolean globalEnable) { + // 使用定制的 JSONPath 断言组件 + JSONPathAssertion assertion = new JSONPathAssertion(); + assertion.setEnabled(msAssertion.getEnable()); + String condition = msAssertion.getCondition(); + String expression = msAssertion.getExpression(); + String expectedValue = msAssertion.getExpectedValue(); + assertion.setName(String.format("Response date JSONPath expect %s %s %s", expression, condition.toLowerCase().replace("_", ""), expectedValue)); + if (BooleanUtils.isFalse(globalEnable)) { + // 如果整体禁用,则禁用 + assertion.setEnabled(false); + } + assertion.setProperty(TestElement.TEST_CLASS, JSONPathAssertion.class.getName()); + assertion.setProperty(TestElement.GUI_CLASS, "io.metersphere.assertions.gui.JSONPathAssertionGui"); + assertion.setJsonValidationBool(true); + assertion.setCondition(condition); + assertion.setJsonPath(expression); + assertion.setExpectedValue(expectedValue); + return assertion; + } + +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/body/RegexAssertionConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/body/RegexAssertionConverter.java new file mode 100644 index 0000000000..e8b44f2449 --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/body/RegexAssertionConverter.java @@ -0,0 +1,46 @@ +package io.metersphere.api.parser.jmeter.processor.assertion.body; + +import io.metersphere.api.dto.request.assertion.body.MsRegexAssertion; +import io.metersphere.api.dto.request.assertion.body.MsRegexAssertionItem; +import io.metersphere.api.parser.jmeter.processor.assertion.AssertionConverter; +import io.metersphere.plugin.api.dto.ParameterConfig; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.jmeter.assertions.ResponseAssertion; +import org.apache.jorphan.collections.HashTree; + +/** + * @Author: jianxing + * @CreateTime: 2024-01-03 10:05 + */ +public class RegexAssertionConverter extends ResponseBodyTypeAssertionConverter { + @Override + public void parse(HashTree hashTree, MsRegexAssertion msAssertion, ParameterConfig config, boolean isIgnoreStatus, boolean globalEnable) { + if (msAssertion == null || msAssertion.getAssertions() == null) { + return; + } + msAssertion.getAssertions().stream() + .filter(MsRegexAssertionItem::isValid) + .forEach(regexAssertionItem -> { + if (needParse(regexAssertionItem, config)) { + ResponseAssertion responseAssertion = parse2RegexResponseAssertion(regexAssertionItem, globalEnable); + responseAssertion.setAssumeSuccess(isIgnoreStatus); + hashTree.add(responseAssertion); + } + }); + } + + private ResponseAssertion parse2RegexResponseAssertion(MsRegexAssertionItem msAssertion, Boolean globalEnable) { + ResponseAssertion assertion = AssertionConverter.createResponseAssertion(); + assertion.setEnabled(msAssertion.getEnable()); + assertion.setName("Response date expect regex " + msAssertion.getExpression()); + assertion.addTestString(msAssertion.getExpression()); + assertion.setTestFieldResponseData(); + if (BooleanUtils.isFalse(globalEnable)) { + // 如果整体禁用,则禁用 + assertion.setEnabled(false); + } + assertion.setToContainsType(); + + return assertion; + } +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/body/ResponseBodyTypeAssertionConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/body/ResponseBodyTypeAssertionConverter.java new file mode 100644 index 0000000000..9c222c058d --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/body/ResponseBodyTypeAssertionConverter.java @@ -0,0 +1,29 @@ +package io.metersphere.api.parser.jmeter.processor.assertion.body; + +import io.metersphere.api.dto.request.assertion.body.MsBodyAssertionItem; +import io.metersphere.plugin.api.dto.ParameterConfig; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.jorphan.collections.HashTree; + +/** + * @Author: jianxing + * @CreateTime: 2024-01-02 21:40 + */ +public abstract class ResponseBodyTypeAssertionConverter { + /** + * 解析对应的提取器 + * + * @param hashTree + * @param extract + * @param config + */ + public abstract void parse(HashTree hashTree, T extract, ParameterConfig config, boolean isIgnoreStatus, boolean globalEnable); + + protected boolean needParse(MsBodyAssertionItem msAssertion, ParameterConfig config) { + // 如果组件是启用的,或者设置了解析禁用的组件,则返回 true + if (BooleanUtils.isTrue(msAssertion.getEnable()) || config.getParseDisabledElement()) { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/body/ResponseBodyTypeAssertionFactory.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/body/ResponseBodyTypeAssertionFactory.java new file mode 100644 index 0000000000..9c1877499d --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/body/ResponseBodyTypeAssertionFactory.java @@ -0,0 +1,29 @@ +package io.metersphere.api.parser.jmeter.processor.assertion.body; + +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 java.util.HashMap; +import java.util.Map; + +/** + * @Author: jianxing + * @CreateTime: 2024-01-03 09:42 + */ +public class ResponseBodyTypeAssertionFactory { + + private static Map converterMap = new HashMap<>(); + + static { + converterMap.put(MsJSONPathAssertion.class, new JSONPathAssertionConverter()); + converterMap.put(MsXPathAssertion.class, new XPathAssertionConverter()); + converterMap.put(MsDocumentAssertion.class, new DocumentAssertionConverter()); + converterMap.put(MsRegexAssertion.class, new RegexAssertionConverter()); + } + + public static ResponseBodyTypeAssertionConverter getConverter(Class processorClass) { + return converterMap.get(processorClass); + } +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/body/XPathAssertionConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/body/XPathAssertionConverter.java new file mode 100644 index 0000000000..2898af8539 --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/assertion/body/XPathAssertionConverter.java @@ -0,0 +1,75 @@ +package io.metersphere.api.parser.jmeter.processor.assertion.body; + +import io.metersphere.api.dto.request.assertion.body.MsXPathAssertion; +import io.metersphere.api.dto.request.assertion.body.MsXPathAssertionItem; +import io.metersphere.api.dto.request.processors.extract.XPathExtract; +import io.metersphere.plugin.api.dto.ParameterConfig; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.jmeter.assertions.XPath2Assertion; +import org.apache.jmeter.assertions.XPathAssertion; +import org.apache.jmeter.save.SaveService; +import org.apache.jmeter.testelement.TestElement; +import org.apache.jorphan.collections.HashTree; + +import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.XPATH_ASSERTION_GUI; +import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.X_PATH_2_ASSERTION_GUI; + +/** + * @Author: jianxing + * @CreateTime: 2024-01-03 10:05 + */ +public class XPathAssertionConverter extends ResponseBodyTypeAssertionConverter { + @Override + public void parse(HashTree hashTree, MsXPathAssertion msAssertion, ParameterConfig config, boolean isIgnoreStatus, boolean globalEnable) { + if (msAssertion == null || msAssertion.getAssertions() == null) { + return; + } + String responseFormat = msAssertion.getResponseFormat(); + msAssertion.getAssertions().stream() + .filter(MsXPathAssertionItem::isValid) + .forEach(msXPathAssertionItem -> { + if (needParse(msXPathAssertionItem, config)) { + if (StringUtils.equals(responseFormat, XPathExtract.ResponseFormat.HTML.name())) { + XPathAssertion xPathAssertion = parse2XPathAssertion(msXPathAssertionItem, globalEnable); + hashTree.add(xPathAssertion); + } else { + XPath2Assertion xPath2Assertion = parse2XPath2Assertion(msXPathAssertionItem, globalEnable); + hashTree.add(xPath2Assertion); + } + } + }); + } + + private XPathAssertion parse2XPathAssertion(MsXPathAssertionItem msAssertion, Boolean globalEnable) { + XPathAssertion assertion = new XPathAssertion(); + assertion.setEnabled(msAssertion.getEnable()); + assertion.setTolerant(true); + assertion.setValidating(false); + assertion.setName("Response date expect xpath " + msAssertion.getExpression()); + assertion.setProperty(TestElement.TEST_CLASS, XPathAssertion.class.getName()); + assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass(XPATH_ASSERTION_GUI)); + assertion.setXPathString(msAssertion.getExpression()); + assertion.setNegated(false); + if (BooleanUtils.isFalse(globalEnable)) { + // 如果整体禁用,则禁用 + assertion.setEnabled(false); + } + return assertion; + } + + private XPath2Assertion parse2XPath2Assertion(MsXPathAssertionItem msAssertion, Boolean globalEnable) { + XPath2Assertion assertion = new XPath2Assertion(); + assertion.setEnabled(msAssertion.getEnable()); + assertion.setName("Response date expect xpath " + msAssertion.getExpression()); + assertion.setProperty(TestElement.TEST_CLASS, XPath2Assertion.class.getName()); + assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass(X_PATH_2_ASSERTION_GUI)); + assertion.setXPathString(msAssertion.getExpression()); + assertion.setNegated(false); + if (BooleanUtils.isFalse(globalEnable)) { + // 如果整体禁用,则禁用 + assertion.setEnabled(false); + } + return assertion; + } +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/extract/JSONPathExtractConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/extract/JSONPathExtractConverter.java index 57bfe1fa70..f18a6106de 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/extract/JSONPathExtractConverter.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/extract/JSONPathExtractConverter.java @@ -25,6 +25,7 @@ public class JSONPathExtractConverter extends ExtractConverter extractor.setJsonPathExpressions(msExtract.getExpression()); // 处理匹配多条等匹配规则 extractor.setMatchNumbers(parseResultMatchingRule(msExtract).toString()); + extractor.setEnabled(msExtract.getEnable()); hashTree.add(extractor); } } 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 eb2ec3e990..540f091bc6 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 @@ -24,6 +24,7 @@ public class RegexExtractConverter extends ExtractConverter { extractor.setRefName(msExtract.getVariableName()); extractor.setRegex(msExtract.getExpression()); extractor.setUseField(msExtract.getExtractScope()); + extractor.setEnabled(msExtract.getEnable()); // 处理匹配多条等匹配规则 extractor.setMatchNumber(parseResultMatchingRule(msExtract)); diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/extract/XPathExtractConverter.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/extract/XPathExtractConverter.java index 6d6110f490..447bc74085 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/extract/XPathExtractConverter.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/jmeter/processor/extract/XPathExtractConverter.java @@ -35,6 +35,7 @@ public class XPathExtractConverter extends ExtractConverter { extractor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass(X_PATH_EXTRACTOR_GUI)); extractor.setRefName(msExtract.getVariableName()); extractor.setXPathQuery(msExtract.getExpression()); + extractor.setEnabled(msExtract.getEnable()); // 处理匹配多条等匹配规则 extractor.setMatchNumber(parseResultMatchingRule(msExtract)); return extractor; @@ -47,6 +48,7 @@ public class XPathExtractConverter extends ExtractConverter { extractor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass(X_PATH2_EXTRACTOR_GUI)); extractor.setRefName(msExtract.getVariableName()); extractor.setXPathQuery(msExtract.getExpression()); + extractor.setEnabled(msExtract.getEnable()); // 处理匹配多条等匹配规则 extractor.setMatchNumber(parseResultMatchingRule(msExtract)); return extractor; 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 c64eb52924..49f492e1f7 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 @@ -244,46 +244,88 @@ public class MsHTTPElementTest { String json = ApiDataUtils.toJSONString(msHTTPElement); Assertions.assertNotNull(json); Assertions.assertEquals(ApiDataUtils.parseObject(json, AbstractMsTestElement.class), msHTTPElement); + + // 测试脚本解析 + ParameterConfig parameterConfig = new ParameterConfig(); + parameterConfig.setReportId("reportId"); + TestElementParser defaultParser = TestElementParserFactory.getDefaultParser(); + AbstractMsTestElement msTestElement = ApiDataUtils.parseObject(json, AbstractMsTestElement.class); + defaultParser.parse(msTestElement, parameterConfig); } public static List getGeneralAssertions() { List assertions = new ArrayList<>(); - ResponseCodeAssertion responseCodeAssertion = new ResponseCodeAssertion(); + MsResponseCodeAssertion responseCodeAssertion = new MsResponseCodeAssertion(); responseCodeAssertion.setCondition(MsAssertionCondition.EMPTY.name()); - responseCodeAssertion.setValue("value"); + responseCodeAssertion.setExpectedValue("value"); responseCodeAssertion.setName("name"); assertions.add(responseCodeAssertion); - ResponseHeaderAssertion responseHeaderAssertion = new ResponseHeaderAssertion(); - ResponseHeaderAssertion.ResponseHeaderAssertionItem responseHeaderAssertionItem = new ResponseHeaderAssertion.ResponseHeaderAssertionItem(); + MsResponseHeaderAssertion responseHeaderAssertion = new MsResponseHeaderAssertion(); + MsResponseHeaderAssertion.ResponseHeaderAssertionItem responseHeaderAssertionItem = new MsResponseHeaderAssertion.ResponseHeaderAssertionItem(); responseHeaderAssertionItem.setHeader("header"); - responseHeaderAssertionItem.setValue("value"); + responseHeaderAssertionItem.setExpectedValue("value"); responseHeaderAssertionItem.setCondition(MsAssertionCondition.EMPTY.name()); responseHeaderAssertion.setAssertions(List.of(responseHeaderAssertionItem)); assertions.add(responseHeaderAssertion); - ResponseBodyAssertion responseBodyAssertion = new ResponseBodyAssertion(); - responseBodyAssertion.setAssertionType(MsBodyAssertionType.JSON_PATH.name()); - RegexAssertion regexAssertion = new RegexAssertion(); - regexAssertion.setAssertions(List.of(new RegexAssertionItem())); - responseBodyAssertion.setRegexAssertion(regexAssertion); - responseBodyAssertion.setDocumentAssertion(new DocumentAssertion()); - responseBodyAssertion.setJsonPathAssertion(new JSONPathAssertion()); - responseBodyAssertion.setXpathAssertion(new XPathAssertion()); - assertions.add(responseBodyAssertion); + MsResponseBodyAssertion regexResponseBodyAssertion = new MsResponseBodyAssertion(); + regexResponseBodyAssertion.setAssertionBodyType(MsResponseBodyAssertion.MsBodyAssertionType.REGEX.name()); + MsRegexAssertion regexAssertion = new MsRegexAssertion(); - ResponseTimeAssertion responseTimeAssertion = new ResponseTimeAssertion(); - responseTimeAssertion.setMaxResponseTime(1000L); + MsRegexAssertionItem msRegexAssertionItem = new MsRegexAssertionItem(); + msRegexAssertionItem.setExpression("^test"); + regexAssertion.setAssertions(List.of(msRegexAssertionItem)); + regexResponseBodyAssertion.setRegexAssertion(regexAssertion); + assertions.add(regexResponseBodyAssertion); + + MsResponseBodyAssertion documentResponseBodyAssertion = new MsResponseBodyAssertion(); + documentResponseBodyAssertion.setAssertionBodyType(MsResponseBodyAssertion.MsBodyAssertionType.DOCUMENT.name()); + MsDocumentAssertion msDocumentAssertion = new MsDocumentAssertion(); + documentResponseBodyAssertion.setDocumentAssertion(msDocumentAssertion); + assertions.add(documentResponseBodyAssertion); + + MsResponseBodyAssertion jsonPathResponseBodyAssertion = new MsResponseBodyAssertion(); + jsonPathResponseBodyAssertion.setAssertionBodyType(MsResponseBodyAssertion.MsBodyAssertionType.JSON_PATH.name()); + MsJSONPathAssertion msJSONPathAssertion = new MsJSONPathAssertion(); + MsJSONPathAssertionItem msJSONPathAssertionItem = new MsJSONPathAssertionItem(); + msJSONPathAssertionItem.setExpression("^test"); + msJSONPathAssertionItem.setCondition(MsAssertionCondition.REGEX.name()); + msJSONPathAssertionItem.setExpectedValue("expectedValue"); + msJSONPathAssertion.setAssertions(List.of(msJSONPathAssertionItem)); + jsonPathResponseBodyAssertion.setJsonPathAssertion(msJSONPathAssertion); + assertions.add(jsonPathResponseBodyAssertion); + + MsResponseBodyAssertion xpathPathResponseBodyAssertion = new MsResponseBodyAssertion(); + xpathPathResponseBodyAssertion.setAssertionBodyType(MsResponseBodyAssertion.MsBodyAssertionType.XPATH.name()); + MsXPathAssertion xPathPathAssertion = new MsXPathAssertion(); + xPathPathAssertion.setResponseFormat(MsXPathAssertion.ResponseFormat.XML.name()); + MsXPathAssertionItem xPathAssertionItem = new MsXPathAssertionItem(); + xPathAssertionItem.setExpression("^test"); + xPathAssertionItem.setExpectedValue("expectedValue"); + xPathPathAssertion.setAssertions(List.of(xPathAssertionItem)); + xpathPathResponseBodyAssertion.setXpathAssertion(xPathPathAssertion); + assertions.add(xpathPathResponseBodyAssertion); + + MsResponseTimeAssertion responseTimeAssertion = new MsResponseTimeAssertion(); + responseTimeAssertion.setExpectedValue(1000L); responseTimeAssertion.setEnable(true); responseTimeAssertion.setName("aa"); assertions.add(responseTimeAssertion); - ScriptAssertion scriptAssertion = new ScriptAssertion(); - scriptAssertion.setCommonScriptId("1111"); - scriptAssertion.setContent("1111"); - scriptAssertion.setDescription("1111"); + MsScriptAssertion scriptAssertion = new MsScriptAssertion(); + scriptAssertion.setScriptId("1111"); + scriptAssertion.setScript("1111"); scriptAssertion.setName("1111"); assertions.add(scriptAssertion); + + MsVariableAssertion msVariableAssertion = new MsVariableAssertion(); + MsVariableAssertion.VariableAssertionItem variableAssertionItem = new MsVariableAssertion.VariableAssertionItem(); + variableAssertionItem.setCondition(MsAssertionCondition.GT.name()); + variableAssertionItem.setExpectedValue("ev"); + variableAssertionItem.setVariableName("vn"); + msVariableAssertion.setVariableAssertionItems(List.of(variableAssertionItem)); + assertions.add(msVariableAssertion); return assertions; }