diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiDefinitionController.java b/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiDefinitionController.java index 37cd86af7e..57b2b790fb 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiDefinitionController.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiDefinitionController.java @@ -231,5 +231,4 @@ public class ApiDefinitionController { apiDefinitionService.saveOperationHistory(request); } - } diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/controller/EnvironmentController.java b/backend/services/project-management/src/main/java/io/metersphere/project/controller/EnvironmentController.java index 8440b34bbd..93a7675139 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/controller/EnvironmentController.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/controller/EnvironmentController.java @@ -1,7 +1,9 @@ package io.metersphere.project.controller; +import io.metersphere.project.dto.environment.EnvironmentFilterRequest; +import io.metersphere.project.dto.environment.EnvironmentImportRequest; import io.metersphere.project.dto.environment.EnvironmentInfoDTO; -import io.metersphere.project.dto.environment.*; +import io.metersphere.project.dto.environment.EnvironmentRequest; import io.metersphere.project.dto.environment.datasource.DataSource; import io.metersphere.project.dto.environment.ssl.KeyStoreEntry; import io.metersphere.project.service.CommandService; @@ -11,6 +13,7 @@ import io.metersphere.sdk.constants.PermissionConstants; import io.metersphere.sdk.domain.Environment; import io.metersphere.system.dto.sdk.OptionDTO; import io.metersphere.system.dto.sdk.request.PosRequest; +import io.metersphere.system.dto.table.TableBatchProcessDTO; import io.metersphere.system.log.annotation.Log; import io.metersphere.system.log.constants.OperationLogType; import io.metersphere.system.security.CheckOwner; @@ -60,7 +63,7 @@ public class EnvironmentController { @RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ_ADD) @Log(type = OperationLogType.ADD, expression = "#msClass.addLog(#request)", msClass = EnvironmentLogService.class) public Environment add(@Validated({Created.class}) @RequestPart(value = "request") EnvironmentRequest request, - @RequestPart(value = "file", required = false) List sslFiles) { + @RequestPart(value = "file", required = false) List sslFiles) { return environmentService.add(request, SessionUtils.getUserId(), sslFiles); } @@ -70,7 +73,7 @@ public class EnvironmentController { @Log(type = OperationLogType.UPDATE, expression = "#msClass.updateLog(#request)", msClass = EnvironmentLogService.class) @CheckOwner(resourceId = "#request.id", resourceType = "environment") public Environment update(@Validated({Updated.class}) @RequestPart("request") EnvironmentRequest request, - @RequestPart(value = "file", required = false) List sslFiles) { + @RequestPart(value = "file", required = false) List sslFiles) { return environmentService.update(request, SessionUtils.getUserId(), sslFiles); } @@ -107,8 +110,8 @@ public class EnvironmentController { @PostMapping("/export") @RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ_EXPORT) @Operation(summary = "项目管理-环境-环境目录-导出") - public ResponseEntity export(@Validated @RequestBody EnvironmentExportRequest request) { - return environmentService.exportZip(request); + public ResponseEntity export(@Validated @RequestBody TableBatchProcessDTO request) { + return environmentService.exportJson(request, SessionUtils.getCurrentProjectId()); } @PostMapping(value = "/get/entry") @@ -124,5 +127,4 @@ public class EnvironmentController { environmentService.editPos(request); } - } diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/controller/GlobalParamsController.java b/backend/services/project-management/src/main/java/io/metersphere/project/controller/GlobalParamsController.java index f569331d72..3ae0c77997 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/controller/GlobalParamsController.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/controller/GlobalParamsController.java @@ -1,21 +1,24 @@ package io.metersphere.project.controller; +import io.metersphere.project.dto.environment.GlobalParamsDTO; import io.metersphere.project.dto.environment.GlobalParamsRequest; import io.metersphere.project.service.GlobalParamsLogService; import io.metersphere.project.service.GlobalParamsService; import io.metersphere.sdk.constants.PermissionConstants; - -import io.metersphere.system.utils.SessionUtils; +import io.metersphere.sdk.domain.ProjectParameters; import io.metersphere.system.log.annotation.Log; import io.metersphere.system.log.constants.OperationLogType; +import io.metersphere.system.utils.SessionUtils; import io.metersphere.validation.groups.Created; import io.metersphere.validation.groups.Updated; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; @RestController @RequestMapping("/project/global/params") @@ -29,7 +32,7 @@ public class GlobalParamsController { @Operation(summary = "项目管理-环境-全局参数-新增") @RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ_ADD) @Log(type = OperationLogType.ADD, expression = "#msClass.addLog(#request)", msClass = GlobalParamsLogService.class) - public GlobalParamsRequest add(@Validated({Created.class}) @RequestBody GlobalParamsRequest request) { + public ProjectParameters add(@Validated({Created.class}) @RequestBody GlobalParamsRequest request) { return globalParamsService.add(request, SessionUtils.getUserId()); } @@ -37,16 +40,30 @@ public class GlobalParamsController { @Operation(summary = "项目管理-环境-全局参数-修改") @RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ_UPDATE) @Log(type = OperationLogType.UPDATE, expression = "#msClass.updateLog(#request)", msClass = GlobalParamsLogService.class) - public GlobalParamsRequest update(@Validated({Updated.class}) @RequestBody GlobalParamsRequest request) { + public ProjectParameters update(@Validated({Updated.class}) @RequestBody GlobalParamsRequest request) { return globalParamsService.update(request, SessionUtils.getUserId()); } @GetMapping("/get/{projectId}") @Operation(summary = "项目管理-环境-全局参数-详情") @RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ) - public GlobalParamsRequest get(@PathVariable String projectId) { + public GlobalParamsDTO get(@PathVariable String projectId) { return globalParamsService.get(projectId); } + @GetMapping("/export/{projectId}") + @RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ_EXPORT) + @Operation(summary = "项目管理-环境-全局参数-导出") + public ResponseEntity export(@PathVariable String projectId) { + return globalParamsService.exportJson(projectId); + } + + @PostMapping(value = "/import", consumes = {"multipart/form-data"}) + @RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ_IMPORT) + @Operation(summary = "项目管理-环境-全局参数-导入") + public void create(@RequestPart(value = "file") MultipartFile file) { + globalParamsService.importData(file, SessionUtils.getUserId(), SessionUtils.getCurrentProjectId()); + } + } diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentConfig.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentConfig.java index f7f414708a..fcdc53de13 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentConfig.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentConfig.java @@ -1,13 +1,13 @@ package io.metersphere.project.dto.environment; -import io.metersphere.project.dto.environment.assertions.EnvironmentAssertions; +import io.metersphere.project.dto.environment.assertion.MsAssertionConfig; import io.metersphere.project.dto.environment.auth.AuthConfig; import io.metersphere.project.dto.environment.common.CommonParams; import io.metersphere.project.dto.environment.datasource.DataSource; import io.metersphere.project.dto.environment.host.HostConfig; import io.metersphere.project.dto.environment.http.HttpConfig; -import io.metersphere.project.dto.environment.script.post.EnvironmentPostScript; -import io.metersphere.project.dto.environment.script.pre.EnvironmentPreScript; +import io.metersphere.project.dto.environment.processors.post.EnvironmentPostScript; +import io.metersphere.project.dto.environment.processors.pre.EnvironmentPreScript; import io.metersphere.project.dto.environment.variables.CommonVariables; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -37,7 +37,7 @@ public class EnvironmentConfig implements Serializable { @Schema(description = "全局后置脚本") private EnvironmentPostScript postScript; @Schema(description = "全局断言") - private EnvironmentAssertions assertions; + private MsAssertionConfig assertions; public EnvironmentConfig() { @@ -49,7 +49,7 @@ public class EnvironmentConfig implements Serializable { this.authConfig = new AuthConfig(); this.preScript = new EnvironmentPreScript(); this.postScript = new EnvironmentPostScript(); - this.assertions = new EnvironmentAssertions(); + this.assertions = new MsAssertionConfig(); } } diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentExportRequest.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentExportRequest.java deleted file mode 100644 index 0c20bbf042..0000000000 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/EnvironmentExportRequest.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.metersphere.project.dto.environment; - -import io.metersphere.system.dto.table.TableBatchProcessDTO; -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Size; -import lombok.Data; - -@Data -public class EnvironmentExportRequest extends TableBatchProcessDTO { - - @Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED) - @NotBlank(message = "{project_application.project_id.not_blank}") - @Size(min = 1, max = 50, message = "{project_parameters.project_id.length_range}") - private String projectId; - - @Schema(description = "是否勾选全局参数", requiredMode = Schema.RequiredMode.REQUIRED) - private Boolean globalParam = false; - - @Schema(description = "是否勾选环境", requiredMode = Schema.RequiredMode.REQUIRED) - private Boolean environment = false; - -} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/GlobalParams.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/GlobalParams.java index 9560392008..eb3e4171dc 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/GlobalParams.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/GlobalParams.java @@ -12,7 +12,7 @@ import java.util.List; public class GlobalParams implements Serializable { @Schema(description = "请求头") - private List headers; + private List headers; @Schema(description = "全局变量") private List commonVariables; diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/GlobalParamsDTO.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/GlobalParamsDTO.java new file mode 100644 index 0000000000..31cc4a9796 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/GlobalParamsDTO.java @@ -0,0 +1,24 @@ +package io.metersphere.project.dto.environment; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +@Data +public class GlobalParamsDTO implements Serializable { + + @Schema(description = "ID") + private String id; + + @Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED) + private String projectId; + + @Schema(description = "全局参数") + private GlobalParams globalParams; + + + @Serial + private static final long serialVersionUID = 1L; +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/KeyValueEnableParam.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/KeyValueEnableParam.java new file mode 100644 index 0000000000..e572e73b2e --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/KeyValueEnableParam.java @@ -0,0 +1,15 @@ +package io.metersphere.project.dto.environment; + +import lombok.Data; + +@Data +public class KeyValueEnableParam extends KeyValueParam { + /** + * 是否启用 + */ + private Boolean enable = true; + /** + * 描述 + */ + private String description; +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/KeyValueParam.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/KeyValueParam.java new file mode 100644 index 0000000000..ad06d45daa --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/KeyValueParam.java @@ -0,0 +1,20 @@ +package io.metersphere.project.dto.environment; + +import lombok.Data; +import org.apache.commons.lang3.StringUtils; + +@Data +public class KeyValueParam { + /** + * 键 + */ + private String key; + /** + * 值 + */ + private String value; + + public boolean isValid() { + return StringUtils.isNotBlank(key); + } +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsAssertion.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsAssertion.java new file mode 100644 index 0000000000..1a5c1933d1 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsAssertion.java @@ -0,0 +1,29 @@ +package io.metersphere.project.dto.environment.assertion; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import lombok.Data; + +/** + * 断言 + */ +@Data +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "assertionType") +@JsonSubTypes({ + @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 { + /** + * 是否启用 + */ + private Boolean enable = true; + /** + * 断言名称 + */ + private String name; +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsAssertionConfig.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsAssertionConfig.java new file mode 100644 index 0000000000..72a43a0e8b --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsAssertionConfig.java @@ -0,0 +1,13 @@ +package io.metersphere.project.dto.environment.assertion; + +import lombok.Data; + +import java.util.List; + +@Data +public class MsAssertionConfig { + /** + * 断言列表 + */ + private List assertions; +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsResponseBodyAssertion.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsResponseBodyAssertion.java new file mode 100644 index 0000000000..dd70cc1c20 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsResponseBodyAssertion.java @@ -0,0 +1,83 @@ +package io.metersphere.project.dto.environment.assertion; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.metersphere.project.dto.environment.assertion.body.MsDocumentAssertion; +import io.metersphere.project.dto.environment.assertion.body.MsJSONPathAssertion; +import io.metersphere.project.dto.environment.assertion.body.MsRegexAssertion; +import io.metersphere.project.dto.environment.assertion.body.MsXPathAssertion; +import lombok.Data; + +import java.util.HashMap; +import java.util.Map; + +@Data +@JsonTypeName("ENV_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/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsResponseCodeAssertion.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsResponseCodeAssertion.java new file mode 100644 index 0000000000..2175ab1147 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsResponseCodeAssertion.java @@ -0,0 +1,22 @@ +package io.metersphere.project.dto.environment.assertion; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import lombok.Data; + +@Data +@JsonTypeName("ENV_RESPONSE_CODE") +public class MsResponseCodeAssertion extends MsAssertion { + /** + * 匹配条件 + * 不校验即忽略状态 + * 选择其他条件时,也忽略状态 + * 不校验可搭配其他校验使用 + * + * @see io.metersphere.sdk.constants.MsAssertionCondition + */ + private String condition; + /** + * 匹配值 + */ + private String expectedValue; +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsResponseHeaderAssertion.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsResponseHeaderAssertion.java new file mode 100644 index 0000000000..13959cd0e5 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsResponseHeaderAssertion.java @@ -0,0 +1,35 @@ +package io.metersphere.project.dto.environment.assertion; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import lombok.Data; + +import java.util.List; + +@Data +@JsonTypeName("ENV_RESPONSE_HEADER") +public class MsResponseHeaderAssertion extends MsAssertion { + + private List assertions; + + + @Data + public static class ResponseHeaderAssertionItem { + /** + * 是否启用 + */ + private Boolean enable = true; + /** + * 响应头 + */ + private String header; + /** + * 匹配条件 + * 值为 MsAssertionCondition + */ + private String condition; + /** + * 匹配值 + */ + private String expectedValue; + } +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsResponseTimeAssertion.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsResponseTimeAssertion.java new file mode 100644 index 0000000000..a425a33664 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsResponseTimeAssertion.java @@ -0,0 +1,14 @@ +package io.metersphere.project.dto.environment.assertion; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import lombok.Data; + +@Data +@JsonTypeName("ENV_RESPONSE_TIME") +public class MsResponseTimeAssertion extends MsAssertion { + /** + * 最大响应时间 + * 响应时间在xx毫秒内 + */ + private Long expectedValue; +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsScriptAssertion.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsScriptAssertion.java new file mode 100644 index 0000000000..6b2a7f89a8 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsScriptAssertion.java @@ -0,0 +1,35 @@ +package io.metersphere.project.dto.environment.assertion; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.metersphere.project.dto.environment.KeyValueParam; +import io.metersphere.project.dto.environment.processors.ScriptProcessor; +import lombok.Data; + +import java.util.List; + +@Data +@JsonTypeName("ENV_SCRIPT_ASSERTION") +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/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsVariableAssertion.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsVariableAssertion.java new file mode 100644 index 0000000000..4b8f54e453 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/MsVariableAssertion.java @@ -0,0 +1,34 @@ +package io.metersphere.project.dto.environment.assertion; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import lombok.Data; + +import java.util.List; + +@Data +@JsonTypeName("ENV_VARIABLE") +public class MsVariableAssertion extends MsAssertion { + + private List variableAssertionItems; + + @Data + public static class VariableAssertionItem { + /** + * 是否启用 + */ + private Boolean enable = true; + /** + * 变量名 + */ + private String variableName; + /** + * 匹配条件 + * 值为 MsAssertionCondition + */ + private String condition; + /** + * 匹配值 + */ + private String expectedValue; + } +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsBodyAssertionItem.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsBodyAssertionItem.java new file mode 100644 index 0000000000..af8a8bac93 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsBodyAssertionItem.java @@ -0,0 +1,8 @@ +package io.metersphere.project.dto.environment.assertion.body; + +import lombok.Data; + +@Data +public abstract class MsBodyAssertionItem { + private Boolean enable = true; +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsDocumentAssertion.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsDocumentAssertion.java new file mode 100644 index 0000000000..e8dfef5dc9 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsDocumentAssertion.java @@ -0,0 +1,36 @@ +package io.metersphere.project.dto.environment.assertion.body; + +import lombok.Data; + +@Data +public class MsDocumentAssertion extends MsBodyAssertionItem { + /** + * 跟随定义的apiId + * 传空为不跟随接口定义 + */ + private String followApiId; + /** + * 文档类型 + * json 或者 xml + * 根据文档类型,选择对应的文档 + * 这里跟前端数据结构有差异 + * 后端从设计层面支持多种文档格式,前端只支持一种 + * 同时切换可以同时持久化两种格式 + * + * @see DocumentType + */ + private String documentType; + /** + * json格式的文档断言 + */ + private MsDocumentAssertionElement jsonAssertion; + /** + * xml格式的文档断言 + */ + private MsDocumentAssertionElement xmlAssertion; + + public enum DocumentType { + JSON, + XML; + } +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsDocumentAssertionElement.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsDocumentAssertionElement.java new file mode 100644 index 0000000000..e68c183b3d --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsDocumentAssertionElement.java @@ -0,0 +1,44 @@ +package io.metersphere.project.dto.environment.assertion.body; + +import lombok.Data; + +import java.util.List; + + +@Data +public class MsDocumentAssertionElement { + private String id; + /** + * 参数名 + */ + private String paramName; + /** + * 必含 + */ + private Boolean include = false; + /** + * 类型 + */ + private String type; + /** + * 类型校验 + */ + private Boolean typeVerification = false; + /** + * 匹配条件 + */ + private String condition; + /** + * 匹配值 + * 即预期结果 + */ + private Object expectedResult; + /** + * 组内校验 + */ + private Boolean arrayVerification; + /** + * 子对象 + */ + private List children; +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsJSONPathAssertion.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsJSONPathAssertion.java new file mode 100644 index 0000000000..889c6d23d4 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsJSONPathAssertion.java @@ -0,0 +1,15 @@ +package io.metersphere.project.dto.environment.assertion.body; + +import lombok.Data; + +import java.util.List; + +@Data +public class MsJSONPathAssertion { + + /** + * 断言列表 + */ + private List assertions; +} + diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsJSONPathAssertionItem.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsJSONPathAssertionItem.java new file mode 100644 index 0000000000..20c0c85f00 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsJSONPathAssertionItem.java @@ -0,0 +1,17 @@ +package io.metersphere.project.dto.environment.assertion.body; + +import lombok.Data; +import org.apache.commons.lang3.StringUtils; + +@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/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsRegexAssertion.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsRegexAssertion.java new file mode 100644 index 0000000000..34a8712a11 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsRegexAssertion.java @@ -0,0 +1,13 @@ +package io.metersphere.project.dto.environment.assertion.body; + +import lombok.Data; + +import java.util.List; + +@Data +public class MsRegexAssertion { + /** + * 断言列表 + */ + private List assertions; +} \ No newline at end of file diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsRegexAssertionItem.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsRegexAssertionItem.java new file mode 100644 index 0000000000..f6af573401 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsRegexAssertionItem.java @@ -0,0 +1,13 @@ +package io.metersphere.project.dto.environment.assertion.body; + +import lombok.Data; +import org.apache.commons.lang3.StringUtils; + +@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/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsXPathAssertion.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsXPathAssertion.java new file mode 100644 index 0000000000..9bc258b88f --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsXPathAssertion.java @@ -0,0 +1,30 @@ +package io.metersphere.project.dto.environment.assertion.body; + + +import lombok.Data; + +import java.util.List; + +@Data +public class MsXPathAssertion { + /** + * 响应内容格式 + * xml 或者 html + */ + private String responseFormat; + /** + * xpath断言 + */ + private List assertions; + + public enum ResponseFormat { + /** + * XML + */ + XML, + /** + * HTML + */ + HTML + } +} \ No newline at end of file diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsXPathAssertionItem.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsXPathAssertionItem.java new file mode 100644 index 0000000000..ba12282d5a --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertion/body/MsXPathAssertionItem.java @@ -0,0 +1,15 @@ +package io.metersphere.project.dto.environment.assertion.body; + + +import lombok.Data; +import org.apache.commons.lang3.StringUtils; + +@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/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvAssertionDuration.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvAssertionDuration.java deleted file mode 100644 index f130a024e2..0000000000 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvAssertionDuration.java +++ /dev/null @@ -1,20 +0,0 @@ -package io.metersphere.project.dto.environment.assertions; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; - -@EqualsAndHashCode(callSuper = true) -@Data -public class EnvAssertionDuration extends EnvAssertionType { - @Schema(description = "响应时间") - private long value; - - public EnvAssertionDuration() { - setType(DURATION); - } - - public boolean isValid() { - return value > 0 && isEnable(); - } -} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvAssertionJSR223.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvAssertionJSR223.java deleted file mode 100644 index a1baa86ccb..0000000000 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvAssertionJSR223.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.metersphere.project.dto.environment.assertions; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import org.apache.commons.lang3.StringUtils; - -@EqualsAndHashCode(callSuper = true) -@Data -public class EnvAssertionJSR223 extends EnvAssertionType { - @Schema(description = "变量名") - private String variable; - @Schema(description = "操作符") - private String operator; - @Schema(description = "值") - private String value; - @Schema(description = "脚本名称") - private String name; - @Schema(description = "脚本内容") - private String script; - @Schema(description = "脚本语言") - private String scriptLanguage; - @Schema(description = "是否启用jsr223") - private Boolean jsrEnable; - - public EnvAssertionJSR223() { - setType(JSR223); - } - - public boolean isValid() { - return StringUtils.isNotBlank(script) && StringUtils.isNotBlank(scriptLanguage) && isEnable(); - } -} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvAssertionJsonPath.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvAssertionJsonPath.java deleted file mode 100644 index fb23f99d60..0000000000 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvAssertionJsonPath.java +++ /dev/null @@ -1,27 +0,0 @@ -package io.metersphere.project.dto.environment.assertions; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import org.apache.commons.lang3.StringUtils; - -@EqualsAndHashCode(callSuper = true) -@Data -public class EnvAssertionJsonPath extends EnvAssertionType { - @Schema(description = "期望值") - private String expect; - @Schema(description = "表达式") - private String expression; - @Schema(description = "描述") - private String description; - @Schema(description = "option 包含/不包含/正则/等于/不等于/大于/小于") - private String option = "REGEX"; - - public EnvAssertionJsonPath() { - setType(JSON_PATH); - } - - public boolean isValid() { - return StringUtils.isNotBlank(expression) && isEnable(); - } -} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvAssertionRegex.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvAssertionRegex.java deleted file mode 100644 index 17635836dc..0000000000 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvAssertionRegex.java +++ /dev/null @@ -1,27 +0,0 @@ -package io.metersphere.project.dto.environment.assertions; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import org.apache.commons.lang3.StringUtils; - -@EqualsAndHashCode(callSuper = true) -@Data -public class EnvAssertionRegex extends EnvAssertionType { - @Schema(description = "断言对象 Response Headers/Response Code/Response Data") - private String subject; - @Schema(description = "表达式") - private String expression; - @Schema(description = "描述") - private String description; - @Schema(description = "忽略状态") - private Boolean assumeSuccess = false; - - public EnvAssertionRegex() { - setType(EnvAssertionType.REGEX); - } - - public boolean isValid() { - return StringUtils.isNotBlank(subject) && StringUtils.isNotBlank(expression) && isEnable(); - } -} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvAssertionType.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvAssertionType.java deleted file mode 100644 index e015b7d0be..0000000000 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvAssertionType.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.metersphere.project.dto.environment.assertions; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Data -public class EnvAssertionType { - public final static String REGEX = "Regex"; - public final static String DURATION = "Duration"; - public final static String JSON_PATH = "JSONPath"; - public final static String JSR223 = "JSR223"; - public final static String TEXT = "Text"; - public final static String XPATH2 = "XPath2"; - @Schema(description = "是否启用") - private boolean enable = true; - - private String type; -} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvAssertionXPath.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvAssertionXPath.java deleted file mode 100644 index 89cc39e1eb..0000000000 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvAssertionXPath.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.metersphere.project.dto.environment.assertions; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import org.apache.commons.lang3.StringUtils; - -@EqualsAndHashCode(callSuper = true) -@Data -public class EnvAssertionXPath extends EnvAssertionType { - @Schema(description = "表达式") - private String expression; - - public EnvAssertionXPath() { - setType(XPATH2); - } - - public boolean isValid() { - return StringUtils.isNotBlank(expression) && isEnable(); - } -} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvironmentAssertions.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvironmentAssertions.java deleted file mode 100644 index 7eb641a99f..0000000000 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/EnvironmentAssertions.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.metersphere.project.dto.environment.assertions; - -import io.metersphere.project.dto.environment.assertions.document.MsAssertionDocument; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.util.List; - -@Data -public class EnvironmentAssertions { - @Schema(description = "接口测试") - private Boolean apiTest = true; - @Schema(description = "UI测试") - private Boolean uiTest = false; - @Schema(description = "xpath类型 xml/html") - private String xpathType; - @Schema(description = "正则断言") - private List regex; - @Schema(description = "jsonPath断言") - private List jsonPath; - @Schema(description = "jsr223断言") - private List jsr223; - @Schema(description = "xpath断言") - private List xpath; - @Schema(description = "响应时间断言") - private EnvAssertionDuration duration; - @Schema(description = "文档断言") - private MsAssertionDocument document; - - - -} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/document/Document.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/document/Document.java deleted file mode 100644 index 8b3bec758e..0000000000 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/document/Document.java +++ /dev/null @@ -1,25 +0,0 @@ -package io.metersphere.project.dto.environment.assertions.document; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.util.List; - -@Data -public class Document { - @Schema(description = "JSON跟随API 这里的是id") - private String jsonFollowAPI; - @Schema(description = "XML跟随API") - private String xmlFollowAPI; - @Schema(description = "JSON内容") - private List json; - @Schema(description = "XML内容") - private List xml; - @Schema(description = "是否包含") - private Boolean include = false; - @Schema(description = "是否包含类型") - private Boolean typeVerification = false; - - - -} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/document/DocumentElement.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/document/DocumentElement.java deleted file mode 100644 index 9d975bccd6..0000000000 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/document/DocumentElement.java +++ /dev/null @@ -1,36 +0,0 @@ -package io.metersphere.project.dto.environment.assertions.document; - - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.util.List; - -@Data -public class DocumentElement { - @Schema(description = "id") - private String id; - @Schema(description = "名称") - private String name; - @Schema(description = "包含") - private Boolean include = false; - @Schema(description = "状态") - private String status; - @Schema(description = "类型校验") - private boolean typeVerification; - @Schema(description = "类型 object/array/string/number/boolean/integer") - private String type; - @Schema(description = "组id") - private String groupId; - @Schema(description = "行数") - private int rowspan; - @Schema(description = "校验组内元素") - private boolean arrayVerification; - @Schema(description = "内容校验 none/value_eq/value_not_eq/value_in/length_eq/length_not_eq/length_gt/length_lt/regular") - private String contentVerification; - @Schema(description = "预期结果") - private Object expectedOutcome; - @Schema(description = "子级") - private List children; - -} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/document/MsAssertionDocument.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/document/MsAssertionDocument.java deleted file mode 100644 index 9a6ef55de0..0000000000 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/assertions/document/MsAssertionDocument.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.metersphere.project.dto.environment.assertions.document; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Data -public class MsAssertionDocument { - @Schema(description = "是否启用") - private Boolean enable = true; - @Schema(description = "断言类型 JSON/XML") - private String type; - @Schema(description = "数据") - private Document data; -} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/http/HttpConfig.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/http/HttpConfig.java index bf9528f268..b38260a242 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/http/HttpConfig.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/http/HttpConfig.java @@ -2,6 +2,7 @@ package io.metersphere.project.dto.environment.http; import io.metersphere.project.dto.environment.KeyValue; +import io.metersphere.project.dto.environment.KeyValueEnableParam; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -24,7 +25,7 @@ public class HttpConfig implements Serializable { @Schema(description = "启用条件为MODULE时,需要模块的id") private List moduleIds; @Schema(description = "请求头") - private List headers; + private List headers; @Schema(description = "浏览器 选项为chrome/firefox") private String browser; private String description; @@ -33,7 +34,7 @@ public class HttpConfig implements Serializable { private static final long serialVersionUID = 1L; public HttpConfig() { - this.headers = List.of(new KeyValue()); + this.headers = List.of(new KeyValueEnableParam()); } } diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiScript.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiScript.java new file mode 100644 index 0000000000..087bf9dcdf --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ApiScript.java @@ -0,0 +1,17 @@ +package io.metersphere.project.dto.environment.processors; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Data +public class ApiScript { + @Schema(description = "测试计划级 包括脚本和sql") + private List planProcessors; + @Schema(description = "场景级 包括脚本和sql") + private List scenarioProcessors; + @Schema(description = "步骤级 包括脚本和sql 脚本是脚本前和脚本后") + private List stepProcessors; +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/MsProcessor.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/MsProcessor.java new file mode 100644 index 0000000000..30617aa26e --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/MsProcessor.java @@ -0,0 +1,24 @@ +package io.metersphere.project.dto.environment.processors; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import lombok.Data; + +@Data +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "processorType") +@JsonSubTypes({ + @JsonSubTypes.Type(value = ScriptProcessor.class), + @JsonSubTypes.Type(value = SQLProcessor.class), + @JsonSubTypes.Type(value = ScenarioScript.class), + @JsonSubTypes.Type(value = StepScript.class), +}) +public abstract class MsProcessor { + /** + * 名称 + */ + private String name; + /** + * 是否启用 + */ + private Boolean enable = true; +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/SQLProcessor.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/SQLProcessor.java new file mode 100644 index 0000000000..3b2c3babf7 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/SQLProcessor.java @@ -0,0 +1,45 @@ +package io.metersphere.project.dto.environment.processors; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.metersphere.project.dto.environment.KeyValueEnableParam; +import io.metersphere.project.dto.environment.KeyValueParam; +import lombok.Data; + +import java.util.List; + +@Data +@JsonTypeName("ENV_SQL") +public class SQLProcessor extends MsProcessor { + /** + * 脚本内容 + */ + private String script; + /** + * 超时时间 + */ + private long queryTimeout; + /** + * 存储结果 + */ + private String resultVariable; + /** + * 按列存储 + */ + private String variableNames; + /** + * 变量列表 + */ + private List variables; + /** + * 环境ID + */ + private String environmentId; + /** + * 数据源ID + */ + private String dataSourceId; + /** + * 提取参数 + */ + private List extractParams; +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ScenarioScript.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ScenarioScript.java new file mode 100644 index 0000000000..3bd4d15e30 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ScenarioScript.java @@ -0,0 +1,15 @@ +package io.metersphere.project.dto.environment.processors; + + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@JsonTypeName("SCENARIO_SCRIPT") +public class ScenarioScript extends ScriptProcessor { + + @Schema(description = "关联场景结果 true: 是/false: 否") + private Boolean associateScenarioResults = false; +} + diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ScriptProcessor.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ScriptProcessor.java new file mode 100644 index 0000000000..a1275544c4 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/ScriptProcessor.java @@ -0,0 +1,52 @@ +package io.metersphere.project.dto.environment.processors; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.metersphere.project.dto.environment.KeyValueParam; +import lombok.Data; + +import java.util.List; + +@Data +@JsonTypeName("ENV_SCRIPT") +public class ScriptProcessor extends MsProcessor { + /** + * 脚本内容 + */ + private String script; + /** + * 脚本语言 + * + * @see ScriptLanguageType + */ + private String scriptLanguage; + /** + * 是否启用公共脚本 + */ + private Boolean enableCommonScript = false; + /** + * 脚本ID + */ + private String scriptId; + /** + * 公共脚本入参 + */ + private List params; + + public enum ScriptLanguageType { + BEANSHELL("beanshell"), + BEANSHELL_JSR233("beanshell-JSR233"), + GROOVY("groovy"), + JAVASCRIPT("javascript"), + PYTHON("python"); + + private String value; + + ScriptLanguageType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/StepScript.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/StepScript.java new file mode 100644 index 0000000000..a8f08affbe --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/StepScript.java @@ -0,0 +1,17 @@ +package io.metersphere.project.dto.environment.processors; + + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Data +@JsonTypeName("STEP_SCRIPT") +public class StepScript extends ScriptProcessor { + @Schema(description = "忽略请求") + private List filterRequestScript; + @Schema(description = "脚本执行顺序 true:先执行 false:后执行") + private Boolean scriptExecBefore = true; +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/script/post/EnvironmentPostScript.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/post/EnvironmentPostScript.java similarity index 57% rename from backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/script/post/EnvironmentPostScript.java rename to backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/post/EnvironmentPostScript.java index 7fa2e2148d..279a492b71 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/script/post/EnvironmentPostScript.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/post/EnvironmentPostScript.java @@ -1,14 +1,14 @@ -package io.metersphere.project.dto.environment.script.post; +package io.metersphere.project.dto.environment.processors.post; -import io.metersphere.project.dto.environment.script.ScriptContent; +import io.metersphere.project.dto.environment.processors.ApiScript; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @Data public class EnvironmentPostScript { @Schema(description = "接口测试") - private ScriptContent.ApiScript apiPostScript; + private ApiScript apiPostScript; @Schema(description = "UI测试") private UiPostScript uiPostScript; diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/script/post/UiPostScript.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/post/UiPostScript.java similarity index 90% rename from backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/script/post/UiPostScript.java rename to backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/post/UiPostScript.java index efe6ffa63c..605a3ec64d 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/script/post/UiPostScript.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/post/UiPostScript.java @@ -1,4 +1,4 @@ -package io.metersphere.project.dto.environment.script.post; +package io.metersphere.project.dto.environment.processors.post; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/script/pre/EnvironmentPreScript.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/pre/EnvironmentPreScript.java similarity index 57% rename from backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/script/pre/EnvironmentPreScript.java rename to backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/pre/EnvironmentPreScript.java index 60acea578c..b4af1e56d8 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/script/pre/EnvironmentPreScript.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/pre/EnvironmentPreScript.java @@ -1,14 +1,14 @@ -package io.metersphere.project.dto.environment.script.pre; +package io.metersphere.project.dto.environment.processors.pre; -import io.metersphere.project.dto.environment.script.ScriptContent; +import io.metersphere.project.dto.environment.processors.ApiScript; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @Data public class EnvironmentPreScript { @Schema(description = "接口测试") - private ScriptContent.ApiScript apiPreScript; + private ApiScript apiPreScript; @Schema(description = "UI测试") private UiPreScript uiPreScript; diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/script/pre/UiPreScript.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/pre/UiPreScript.java similarity index 90% rename from backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/script/pre/UiPreScript.java rename to backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/pre/UiPreScript.java index 1be7e9a9ab..e32ad27c6a 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/script/pre/UiPreScript.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/processors/pre/UiPreScript.java @@ -1,4 +1,4 @@ -package io.metersphere.project.dto.environment.script.pre; +package io.metersphere.project.dto.environment.processors.pre; import io.swagger.v3.oas.annotations.media.Schema; diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/script/ScriptContent.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/script/ScriptContent.java deleted file mode 100644 index dbe375e1b9..0000000000 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/script/ScriptContent.java +++ /dev/null @@ -1,50 +0,0 @@ -package io.metersphere.project.dto.environment.script; - - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.util.List; - -@Data -public class ScriptContent { - - @Schema(description = "脚本内容") - private String script; - @Schema(description = "脚本语言") - private String scriptLanguage; - @Schema(description = "是否是jsr223") - private Boolean jsrEnable; - - - @Data - @EqualsAndHashCode(callSuper = true) - public static class ScenarioScript extends ScriptContent { - - @Schema(description = "关联场景结果 true: 是/false: 否") - private Boolean associateScenarioResults = false; - } - - @Data - @EqualsAndHashCode(callSuper = true) - public static class StepScript extends ScriptContent { - @Schema(description = "忽略请求") - private List filterRequestScript; - @Schema(description = "脚本执行顺序 true:先执行 false:后执行") - private Boolean scriptExecBefore = true; - @Schema(description = "脚本内容") - private ScriptContent scriptContent; - - } - - @Data - public static class ApiScript { - @Schema(description = "测试计划级") - private ScriptContent envJSR223Script; - @Schema(description = "场景级") - private ScenarioScript scenarioJSR223Script; - @Schema(description = "步骤级 ") - private List stepJSR223Script; - } -} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/variables/CommonVariables.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/variables/CommonVariables.java index 2a065844ac..b2d7dfc4e2 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/variables/CommonVariables.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/environment/variables/CommonVariables.java @@ -8,6 +8,7 @@ import lombok.Data; import org.apache.commons.lang3.StringUtils; import java.io.Serializable; +import java.util.List; @Data public class CommonVariables implements Serializable { @@ -25,6 +26,8 @@ public class CommonVariables implements Serializable { private Boolean enable = true; @Schema(description = "描述") private String description; + @Schema(description = "标签") + private List tags; @JsonIgnore diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentService.java b/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentService.java index 263e39daa7..ee3318c0ed 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentService.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentService.java @@ -6,11 +6,15 @@ import io.metersphere.project.dto.environment.*; import io.metersphere.project.dto.environment.datasource.DataSource; import io.metersphere.project.mapper.ExtEnvironmentMapper; import io.metersphere.project.mapper.ProjectMapper; -import io.metersphere.project.utils.FileDownloadUtils; import io.metersphere.sdk.constants.DefaultRepositoryDir; import io.metersphere.sdk.constants.HttpMethodConstants; -import io.metersphere.sdk.domain.*; +import io.metersphere.sdk.domain.Environment; +import io.metersphere.sdk.domain.EnvironmentBlob; +import io.metersphere.sdk.domain.EnvironmentBlobExample; +import io.metersphere.sdk.domain.EnvironmentExample; import io.metersphere.sdk.exception.MSException; +import io.metersphere.sdk.file.FileRequest; +import io.metersphere.sdk.file.MinioRepository; import io.metersphere.sdk.mapper.EnvironmentBlobMapper; import io.metersphere.sdk.mapper.EnvironmentMapper; import io.metersphere.sdk.mapper.ProjectParametersMapper; @@ -21,8 +25,7 @@ import io.metersphere.sdk.util.Translator; import io.metersphere.system.dto.sdk.BaseSystemConfigDTO; import io.metersphere.system.dto.sdk.OptionDTO; import io.metersphere.system.dto.sdk.request.PosRequest; -import io.metersphere.sdk.file.FileRequest; -import io.metersphere.sdk.file.MinioRepository; +import io.metersphere.system.dto.table.TableBatchProcessDTO; import io.metersphere.system.log.constants.OperationLogModule; import io.metersphere.system.log.constants.OperationLogType; import io.metersphere.system.log.dto.LogDTO; @@ -187,51 +190,29 @@ public class EnvironmentService { return (pos == null ? 0 : pos) + ORDER_STEP; } - public ResponseEntity exportZip(EnvironmentExportRequest request) { + public ResponseEntity exportJson(TableBatchProcessDTO request, String projectId) { try { - byte[] bytes = this.download(request); + Project project = projectMapper.selectByPrimaryKey(projectId); + List environmentList = this.exportEnv(request, projectId); + String fileName = null; + if (CollectionUtils.isNotEmpty(environmentList)) { + if (environmentList.size() == 1) { + fileName = StringUtils.join(project.getName(), "_", environmentList.get(0).getName(), ".json"); + } else { + fileName = StringUtils.join(project.getName(), "_", Translator.get("env_info_all")); + } + } return ResponseEntity.ok() .contentType(MediaType.parseMediaType("application/octet-stream")) - .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + "files.zip") - .body(bytes); + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName) + .body(JSON.toJSONString(environmentList).getBytes()); } catch (Exception e) { return ResponseEntity.status(509).body(e.getMessage().getBytes()); } } - public byte[] download(EnvironmentExportRequest request) { - Map files = new LinkedHashMap<>(); - Project project = projectMapper.selectByPrimaryKey(request.getProjectId()); - if (BooleanUtils.isTrue(request.getGlobalParam())) { - //查询全局参数 - EnvironmentExportDTO environmentExportDTO = new EnvironmentExportDTO(); - ProjectParametersExample projectParametersExample = new ProjectParametersExample(); - projectParametersExample.createCriteria().andProjectIdEqualTo(request.getProjectId()); - List projectParameters = projectParametersMapper.selectByExampleWithBLOBs(projectParametersExample); - if (CollectionUtils.isNotEmpty(projectParameters)) { - environmentExportDTO.setGlobalParam(true); - environmentExportDTO.setData(new String(projectParameters.get(0).getParameters())); - files.put(StringUtils.join(project.getName(), "_", Translator.get("global_params")), JSON.toJSONString(environmentExportDTO).getBytes()); - } - } - if (BooleanUtils.isTrue(request.getEnvironment())) { - EnvironmentExportDTO environmentExportDTO = new EnvironmentExportDTO(); - List environmentList = this.exportEnv(request); - if (CollectionUtils.isNotEmpty(environmentList)) { - environmentExportDTO.setEnvironment(true); - environmentExportDTO.setData(JSON.toJSONString(environmentList)); - if (environmentList.size() == 1) { - files.put(StringUtils.join(project.getName(), "_", environmentList.get(0).getName(), ".json"), JSON.toJSONString(environmentList.get(0)).getBytes()); - } else { - files.put(StringUtils.join(project.getName(), "_", Translator.get("env_info_all")), JSON.toJSONString(environmentExportDTO).getBytes()); - } - } - } - return FileDownloadUtils.listFileBytesToZip(files); - } - - public List exportEnv(EnvironmentExportRequest environmentExportRequest) { - List environmentIds = this.getEnvironmentIds(environmentExportRequest); + public List exportEnv(TableBatchProcessDTO request, String projectId) { + List environmentIds = this.getEnvironmentIds(request, projectId); // 查询环境 EnvironmentExample environmentExample = new EnvironmentExample(); environmentExample.createCriteria().andIdIn(environmentIds); @@ -271,9 +252,9 @@ public class EnvironmentService { } } - private List getEnvironmentIds(EnvironmentExportRequest request) { + private List getEnvironmentIds(TableBatchProcessDTO request, String projectId) { if (request.isSelectAll()) { - List environments = extEnvironmentMapper.selectByKeyword(request.getCondition().getKeyword(), true, request.getProjectId()); + List environments = extEnvironmentMapper.selectByKeyword(request.getCondition().getKeyword(), true, projectId); List environmentIds = environments.stream().map(Environment::getId).collect(Collectors.toList()); if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(request.getExcludeIds())) { environmentIds.removeAll(request.getExcludeIds()); @@ -318,82 +299,55 @@ public class EnvironmentService { // 读取文件内容 String content = new String(inputStream.readAllBytes()); inputStream.close(); - //参数是一个对象 - EnvironmentExportDTO environmentExportDTO = JSON.parseObject(content, EnvironmentExportDTO.class); - if (environmentExportDTO != null) { - if (BooleanUtils.isTrue(environmentExportDTO.getGlobalParam())) { - String data = environmentExportDTO.getData(); - //解析出来的参数是一个对象 - if (BooleanUtils.isTrue(request.getCover())) { - ProjectParametersExample projectParametersExample = new ProjectParametersExample(); - projectParametersExample.createCriteria().andProjectIdEqualTo(currentProjectId); - if (projectParametersMapper.countByExample(projectParametersExample) > 0) { - projectParametersMapper.deleteByExample(projectParametersExample); - } - ProjectParameters projectParameters = new ProjectParameters(); - projectParameters.setId(IDGenerator.nextStr()); - projectParameters.setProjectId(currentProjectId); - projectParameters.setCreateUser(userId); - projectParameters.setUpdateUser(userId); - projectParameters.setCreateTime(System.currentTimeMillis()); - projectParameters.setUpdateTime(System.currentTimeMillis()); - projectParameters.setParameters(data.getBytes()); - projectParametersMapper.insert(projectParameters); - } - } - if (BooleanUtils.isTrue(environmentExportDTO.getEnvironment())) { - // 拿到的参数是一个list - List environmentRequests = JSON.parseArray(environmentExportDTO.getData(), EnvironmentRequest.class); - if (CollectionUtils.isNotEmpty(environmentRequests)) { - List environments = new ArrayList<>(); - List environmentBlobs = new ArrayList<>(); - List logDos = new ArrayList<>(); - Project project = projectMapper.selectByPrimaryKey(currentProjectId); - environmentRequests.forEach(environmentRequest -> { - Environment environment = new Environment(); - environment.setId(IDGenerator.nextStr()); - environment.setCreateUser(userId); - environment.setName(environmentRequest.getName()); - environment.setProjectId(currentProjectId); - environment.setUpdateUser(userId); - environment.setUpdateTime(System.currentTimeMillis()); - environment.setMock(false); - environment.setPos(getNextOrder(currentProjectId)); - Environment exitsEnv = getExitsEnv(environment); - if (exitsEnv != null && BooleanUtils.isTrue(request.getCover())) { - environmentMapper.deleteByPrimaryKey(exitsEnv.getId()); - environmentBlobMapper.deleteByPrimaryKey(exitsEnv.getId()); - } else if (exitsEnv != null && BooleanUtils.isFalse(request.getCover())) { - return; - } - environment.setCreateTime(System.currentTimeMillis()); - environment.setProjectId(currentProjectId); - environments.add(environment); - EnvironmentBlob environmentBlob = new EnvironmentBlob(); - environmentBlob.setId(environment.getId()); - environmentBlob.setConfig(JSON.toJSONBytes(environmentRequest.getConfig())); - environmentBlobs.add(environmentBlob); - LogDTO logDTO = new LogDTO( - currentProjectId, - project.getOrganizationId(), - environment.getId(), - userId, - OperationLogType.ADD.name(), - OperationLogModule.PROJECT_ENVIRONMENT_SETTING, - environment.getName()); - logDTO.setMethod(HttpMethodConstants.POST.name()); - logDTO.setOriginalValue(JSON.toJSONBytes(environmentRequest.getConfig())); - logDTO.setPath(PATH); - logDos.add(logDTO); - }); - if (CollectionUtils.isNotEmpty(environments) - && CollectionUtils.isNotEmpty(environmentBlobs) - && CollectionUtils.isNotEmpty(logDos)) { - environmentMapper.batchInsert(environments); - environmentBlobMapper.batchInsert(environmentBlobs); - operationLogService.batchAdd(logDos); - } + List environmentRequests = JSON.parseArray(content, EnvironmentRequest.class); + if (CollectionUtils.isNotEmpty(environmentRequests)) { + List environments = new ArrayList<>(); + List environmentBlobs = new ArrayList<>(); + List logDos = new ArrayList<>(); + Project project = projectMapper.selectByPrimaryKey(currentProjectId); + environmentRequests.forEach(environmentRequest -> { + Environment environment = new Environment(); + environment.setId(IDGenerator.nextStr()); + environment.setCreateUser(userId); + environment.setName(environmentRequest.getName()); + environment.setProjectId(currentProjectId); + environment.setUpdateUser(userId); + environment.setUpdateTime(System.currentTimeMillis()); + environment.setMock(false); + environment.setPos(getNextOrder(currentProjectId)); + Environment exitsEnv = getExitsEnv(environment); + if (exitsEnv != null && BooleanUtils.isTrue(request.getCover())) { + environmentMapper.deleteByPrimaryKey(exitsEnv.getId()); + environmentBlobMapper.deleteByPrimaryKey(exitsEnv.getId()); + } else if (exitsEnv != null && BooleanUtils.isFalse(request.getCover())) { + return; } + environment.setCreateTime(System.currentTimeMillis()); + environment.setProjectId(currentProjectId); + environments.add(environment); + EnvironmentBlob environmentBlob = new EnvironmentBlob(); + environmentBlob.setId(environment.getId()); + environmentBlob.setConfig(JSON.toJSONBytes(environmentRequest.getConfig())); + environmentBlobs.add(environmentBlob); + LogDTO logDTO = new LogDTO( + currentProjectId, + project.getOrganizationId(), + environment.getId(), + userId, + OperationLogType.ADD.name(), + OperationLogModule.PROJECT_ENVIRONMENT_SETTING, + environment.getName()); + logDTO.setMethod(HttpMethodConstants.POST.name()); + logDTO.setOriginalValue(JSON.toJSONBytes(environmentRequest.getConfig())); + logDTO.setPath(PATH); + logDos.add(logDTO); + }); + if (CollectionUtils.isNotEmpty(environments) + && CollectionUtils.isNotEmpty(environmentBlobs) + && CollectionUtils.isNotEmpty(logDos)) { + environmentMapper.batchInsert(environments); + environmentBlobMapper.batchInsert(environmentBlobs); + operationLogService.batchAdd(logDos); } } } catch (Exception e) { diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/service/GlobalParamsService.java b/backend/services/project-management/src/main/java/io/metersphere/project/service/GlobalParamsService.java index 89feed716c..1061daff18 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/service/GlobalParamsService.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/service/GlobalParamsService.java @@ -1,21 +1,29 @@ package io.metersphere.project.service; +import io.metersphere.project.domain.Project; import io.metersphere.project.dto.environment.GlobalParams; +import io.metersphere.project.dto.environment.GlobalParamsDTO; import io.metersphere.project.dto.environment.GlobalParamsRequest; import io.metersphere.project.mapper.ProjectMapper; import io.metersphere.sdk.domain.ProjectParameters; import io.metersphere.sdk.domain.ProjectParametersExample; import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.mapper.ProjectParametersMapper; - import io.metersphere.sdk.util.JSON; +import io.metersphere.sdk.util.LogUtils; import io.metersphere.sdk.util.Translator; import io.metersphere.system.uid.IDGenerator; import jakarta.annotation.Resource; import jakarta.transaction.Transactional; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import java.io.InputStream; import java.util.List; @@ -28,7 +36,7 @@ public class GlobalParamsService { @Resource private ProjectMapper projectMapper; - public GlobalParamsRequest add(GlobalParamsRequest globalParamsRequest, String userId) { + public ProjectParameters add(GlobalParamsRequest globalParamsRequest, String userId) { ProjectParameters projectParameters = new ProjectParameters(); projectParameters.setProjectId(globalParamsRequest.getProjectId()); checkExist(globalParamsRequest.getProjectId()); @@ -41,10 +49,10 @@ public class GlobalParamsService { projectParameters.setParameters(JSON.toJSONBytes(globalParamsRequest.getGlobalParams())); projectParametersMapper.insert(projectParameters); globalParamsRequest.setId(projectParameters.getId()); - return globalParamsRequest; + return projectParameters; } - public GlobalParamsRequest update(GlobalParamsRequest globalParamsRequest, String userId) { + public ProjectParameters update(GlobalParamsRequest globalParamsRequest, String userId) { ProjectParameters projectParameters = new ProjectParameters(); projectParameters.setProjectId(globalParamsRequest.getProjectId()); checkDataExist(globalParamsRequest.getProjectId()); @@ -54,7 +62,7 @@ public class GlobalParamsService { projectParameters.setUpdateTime(System.currentTimeMillis()); projectParameters.setParameters(JSON.toJSONBytes(globalParamsRequest.getGlobalParams())); projectParametersMapper.updateByPrimaryKeySelective(projectParameters); - return globalParamsRequest; + return projectParameters; } private void checkDataExist(String projectId) { @@ -66,16 +74,16 @@ public class GlobalParamsService { } } - public GlobalParamsRequest get(String projectId) { + public GlobalParamsDTO get(String projectId) { ProjectParametersExample example = new ProjectParametersExample(); example.createCriteria().andProjectIdEqualTo(projectId); List projectParametersList = projectParametersMapper.selectByExampleWithBLOBs(example); if (CollectionUtils.isNotEmpty(projectParametersList)) { - GlobalParamsRequest globalParamsRequest = new GlobalParamsRequest(); - globalParamsRequest.setProjectId(projectId); - globalParamsRequest.setId(projectParametersList.get(0).getId()); - globalParamsRequest.setGlobalParams(JSON.parseObject(new String(projectParametersList.get(0).getParameters()), GlobalParams.class)); - return globalParamsRequest; + GlobalParamsDTO globalParamsDTO = new GlobalParamsDTO(); + globalParamsDTO.setProjectId(projectId); + globalParamsDTO.setId(projectParametersList.get(0).getId()); + globalParamsDTO.setGlobalParams(JSON.parseObject(new String(projectParametersList.get(0).getParameters()), GlobalParams.class)); + return globalParamsDTO; } else { return null; } @@ -96,4 +104,61 @@ public class GlobalParamsService { throw new MSException(Translator.get("project_is_not_exist")); } } + + public ResponseEntity exportJson(String projectId) { + try { + Project project = projectMapper.selectByPrimaryKey(projectId); + //查询全局参数 + ProjectParametersExample projectParametersExample = new ProjectParametersExample(); + projectParametersExample.createCriteria().andProjectIdEqualTo(projectId); + List projectParameters = projectParametersMapper.selectByExampleWithBLOBs(projectParametersExample); + byte[] bytes = new byte[0]; + if (CollectionUtils.isNotEmpty(projectParameters)) { + GlobalParamsDTO globalParamsDTO = new GlobalParamsDTO(); + globalParamsDTO.setProjectId(projectId); + globalParamsDTO.setId(projectParameters.get(0).getId()); + globalParamsDTO.setGlobalParams(JSON.parseObject(new String(projectParameters.get(0).getParameters()), GlobalParams.class)); + bytes = JSON.toJSONString(globalParamsDTO).getBytes(); + } else { + throw new MSException(Translator.get("global_parameters_is_not_exist")); + } + return ResponseEntity.ok() + .contentType(MediaType.parseMediaType("application/octet-stream")) + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + StringUtils.join(project.getName(), "_", Translator.get("global_params"))) + .body(bytes); + + } catch (Exception e) { + return ResponseEntity.status(509).body(e.getMessage().getBytes()); + } + } + + public void importData(MultipartFile file, String userId, String currentProjectId) { + if (file != null) { + try { + InputStream inputStream = file.getInputStream(); + // 读取文件内容 + String content = new String(inputStream.readAllBytes()); + inputStream.close(); + //参数是一个对象 + GlobalParamsDTO globalParamsDTO = JSON.parseObject(content, GlobalParamsDTO.class); + ProjectParametersExample projectParametersExample = new ProjectParametersExample(); + projectParametersExample.createCriteria().andProjectIdEqualTo(currentProjectId); + if (projectParametersMapper.countByExample(projectParametersExample) > 0) { + projectParametersMapper.deleteByExample(projectParametersExample); + } + ProjectParameters projectParameters = new ProjectParameters(); + projectParameters.setId(IDGenerator.nextStr()); + projectParameters.setProjectId(currentProjectId); + projectParameters.setCreateUser(userId); + projectParameters.setUpdateUser(userId); + projectParameters.setCreateTime(System.currentTimeMillis()); + projectParameters.setUpdateTime(System.currentTimeMillis()); + projectParameters.setParameters(JSON.toJSONBytes(globalParamsDTO.getGlobalParams())); + projectParametersMapper.insert(projectParameters); + } catch (Exception e) { + LogUtils.error("获取文件输入流异常", e); + throw new RuntimeException("获取文件输入流异常", e); + } + } + } } diff --git a/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentControllerTests.java b/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentControllerTests.java index d69a49081b..ce508ad8de 100644 --- a/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentControllerTests.java +++ b/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentControllerTests.java @@ -1,32 +1,30 @@ package io.metersphere.project.controller; -import io.metersphere.project.dto.environment.EnvironmentInfoDTO; import io.metersphere.project.dto.environment.*; -import io.metersphere.project.dto.environment.assertions.*; +import io.metersphere.project.dto.environment.assertion.*; +import io.metersphere.project.dto.environment.assertion.body.*; import io.metersphere.project.dto.environment.auth.AuthConfig; import io.metersphere.project.dto.environment.common.CommonParams; import io.metersphere.project.dto.environment.datasource.DataSource; import io.metersphere.project.dto.environment.host.Host; import io.metersphere.project.dto.environment.host.HostConfig; import io.metersphere.project.dto.environment.http.HttpConfig; -import io.metersphere.project.dto.environment.script.ScriptContent; -import io.metersphere.project.dto.environment.script.post.EnvironmentPostScript; -import io.metersphere.project.dto.environment.script.post.UiPostScript; -import io.metersphere.project.dto.environment.script.pre.EnvironmentPreScript; -import io.metersphere.project.dto.environment.script.pre.UiPreScript; +import io.metersphere.project.dto.environment.processors.*; +import io.metersphere.project.dto.environment.processors.post.EnvironmentPostScript; +import io.metersphere.project.dto.environment.processors.post.UiPostScript; +import io.metersphere.project.dto.environment.processors.pre.EnvironmentPreScript; +import io.metersphere.project.dto.environment.processors.pre.UiPreScript; import io.metersphere.project.dto.environment.ssl.KeyStoreConfig; import io.metersphere.project.dto.environment.ssl.KeyStoreEntry; import io.metersphere.project.dto.environment.ssl.KeyStoreFile; import io.metersphere.project.dto.environment.variables.CommonVariables; -import io.metersphere.sdk.constants.DefaultRepositoryDir; -import io.metersphere.sdk.constants.PermissionConstants; -import io.metersphere.sdk.constants.SessionConstants; -import io.metersphere.sdk.constants.VariableTypeConstants; +import io.metersphere.sdk.constants.*; import io.metersphere.sdk.domain.Environment; import io.metersphere.sdk.domain.EnvironmentBlob; import io.metersphere.sdk.domain.EnvironmentExample; -import io.metersphere.sdk.domain.ProjectParametersExample; +import io.metersphere.sdk.file.FileRequest; +import io.metersphere.sdk.file.MinioRepository; import io.metersphere.sdk.mapper.EnvironmentBlobMapper; import io.metersphere.sdk.mapper.EnvironmentMapper; import io.metersphere.sdk.mapper.ProjectParametersMapper; @@ -36,8 +34,7 @@ import io.metersphere.system.base.BaseTest; import io.metersphere.system.controller.handler.ResultHolder; import io.metersphere.system.dto.sdk.OptionDTO; import io.metersphere.system.dto.sdk.request.PosRequest; -import io.metersphere.sdk.file.FileRequest; -import io.metersphere.sdk.file.MinioRepository; +import io.metersphere.system.dto.table.TableBatchProcessDTO; import io.metersphere.system.log.constants.OperationLogType; import jakarta.annotation.Resource; import org.apache.commons.lang3.StringUtils; @@ -61,6 +58,7 @@ import org.springframework.util.MultiValueMap; import java.io.File; import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -71,7 +69,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @AutoConfigureMockMvc @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class EnvironmentControllerTests extends BaseTest { @@ -214,9 +212,9 @@ public class EnvironmentControllerTests extends BaseTest { private List createHttpConfig() { List httpConfigs = new ArrayList<>(); HttpConfig httpConfig = new HttpConfig(); - List headers = new ArrayList<>(); - KeyValue keyValue = new KeyValue(); - keyValue.setName("key"); + List headers = new ArrayList<>(); + KeyValueEnableParam keyValue = new KeyValueEnableParam(); + keyValue.setKey("key"); keyValue.setValue("value"); headers.add(keyValue); httpConfig.setHeaders(headers); @@ -307,20 +305,31 @@ public class EnvironmentControllerTests extends BaseTest { return keyStoreConfig; } - private ScriptContent.ApiScript createApiScript() { - ScriptContent.ApiScript apiScript = new ScriptContent.ApiScript(); - ScriptContent scriptContent = new ScriptContent(); - scriptContent.setScript("script"); - apiScript.setEnvJSR223Script(scriptContent); - ScriptContent.ScenarioScript scenarioScript = new ScriptContent.ScenarioScript(); - scenarioScript.setAssociateScenarioResults(true); - scenarioScript.setScript("scenarioPostScript"); - apiScript.setScenarioJSR223Script(scenarioScript); - ScriptContent.StepScript stepPostScript = new ScriptContent.StepScript(); - stepPostScript.setScriptExecBefore(true); - stepPostScript.setScriptContent(scriptContent); - stepPostScript.setFilterRequestScript(new ArrayList<>()); - apiScript.setStepJSR223Script(List.of(stepPostScript)); + private ApiScript createApiScript() { + ApiScript apiScript = new ApiScript(); + ScriptProcessor scriptProcessor = new ScriptProcessor(); + scriptProcessor.setScript("script"); + scriptProcessor.setName("测试计划级别脚本"); + SQLProcessor sqlProcessor = new SQLProcessor(); + sqlProcessor.setEnvironmentId("environmentId"); + sqlProcessor.setDataSourceId("dataSourceId"); + sqlProcessor.setQueryTimeout(1000L); + apiScript.setPlanProcessors(List.of(scriptProcessor, sqlProcessor)); + ScenarioScript scenarioScript = new ScenarioScript(); + scenarioScript.setScript("script"); + scenarioScript.setName("场景级别脚本"); + apiScript.setScenarioProcessors(List.of(scenarioScript, sqlProcessor)); + StepScript stepScript = new StepScript(); + stepScript.setScript("script"); + stepScript.setName("步骤级别前置脚本前"); + stepScript.setScriptExecBefore(true); + stepScript.setFilterRequestScript(List.of("HTTP")); + StepScript stepScriptAfter = new StepScript(); + stepScriptAfter.setScript("script"); + stepScriptAfter.setName("步骤级别前置脚本后"); + stepScriptAfter.setScriptExecBefore(false); + stepScriptAfter.setFilterRequestScript(List.of("HTTP")); + apiScript.setStepProcessors(List.of(stepScript, sqlProcessor, stepScriptAfter)); return apiScript; } @@ -343,17 +352,85 @@ public class EnvironmentControllerTests extends BaseTest { return uiPostScript; } - private EnvironmentAssertions createAssertions() { - EnvironmentAssertions assertions = new EnvironmentAssertions(); - assertions.setApiTest(true); - List regex = new ArrayList<>(); - assertions.setRegex(regex); - List jsonPath = new ArrayList<>(); - assertions.setJsonPath(jsonPath); - List jsr223 = new ArrayList<>(); - assertions.setJsr223(jsr223); - List xpath = new ArrayList<>(); - assertions.setXpath(xpath); + public static List getGeneralAssertions() { + List assertions = new ArrayList<>(); + MsResponseCodeAssertion responseCodeAssertion = new MsResponseCodeAssertion(); + responseCodeAssertion.setCondition(MsAssertionCondition.EMPTY.name()); + responseCodeAssertion.setExpectedValue("value"); + responseCodeAssertion.setName("name"); + assertions.add(responseCodeAssertion); + + MsResponseHeaderAssertion responseHeaderAssertion = new MsResponseHeaderAssertion(); + MsResponseHeaderAssertion.ResponseHeaderAssertionItem responseHeaderAssertionItem = new MsResponseHeaderAssertion.ResponseHeaderAssertionItem(); + responseHeaderAssertionItem.setHeader("header"); + responseHeaderAssertionItem.setExpectedValue("value"); + responseHeaderAssertionItem.setCondition(MsAssertionCondition.EMPTY.name()); + responseHeaderAssertion.setAssertions(List.of(responseHeaderAssertionItem)); + assertions.add(responseHeaderAssertion); + + MsResponseBodyAssertion regexResponseBodyAssertion = new MsResponseBodyAssertion(); + regexResponseBodyAssertion.setAssertionBodyType(MsResponseBodyAssertion.MsBodyAssertionType.REGEX.name()); + MsRegexAssertion regexAssertion = new MsRegexAssertion(); + + 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); + + 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; + } + + private MsAssertionConfig createAssertions() { + MsAssertionConfig assertions = new MsAssertionConfig(); + assertions.setAssertions(getGeneralAssertions()); return assertions; } @@ -393,6 +470,7 @@ public class EnvironmentControllerTests extends BaseTest { envConfig.setCommonParams(createCommonParams()); request.setName("commonParams"); request.setConfig(envConfig); + paramMap.clear(); paramMap.set("request", JSON.toJSONString(request)); mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap); response = parseObjectFromMvcResult(mvcResult, Environment.class); @@ -418,6 +496,7 @@ public class EnvironmentControllerTests extends BaseTest { envConfig.setCommonVariables(createCommonVariables(1)); request.setName("commonVariables"); request.setConfig(envConfig); + paramMap.clear(); paramMap.set("request", JSON.toJSONString(request)); mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap); response = parseObjectFromMvcResult(mvcResult, Environment.class); @@ -443,6 +522,7 @@ public class EnvironmentControllerTests extends BaseTest { envConfig.setHttpConfig(createHttpConfig()); request.setName("httpConfig"); request.setConfig(envConfig); + paramMap.clear(); paramMap.set("request", JSON.toJSONString(request)); mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap); response = parseObjectFromMvcResult(mvcResult, Environment.class); @@ -468,6 +548,7 @@ public class EnvironmentControllerTests extends BaseTest { envConfig.setDataSources(createDataSources()); request.setName("dataSources"); request.setConfig(envConfig); + paramMap.clear(); paramMap.set("request", JSON.toJSONString(request)); mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap); response = parseObjectFromMvcResult(mvcResult, Environment.class); @@ -493,6 +574,7 @@ public class EnvironmentControllerTests extends BaseTest { envConfig.setHostConfig(crateHostConfig()); request.setName("hostConfig"); request.setConfig(envConfig); + paramMap.clear(); paramMap.set("request", JSON.toJSONString(request)); mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap); response = parseObjectFromMvcResult(mvcResult, Environment.class); @@ -518,6 +600,7 @@ public class EnvironmentControllerTests extends BaseTest { envConfig.setAuthConfig(createAuthConfig()); request.setName("authConfig"); request.setConfig(envConfig); + paramMap.clear(); paramMap.set("request", JSON.toJSONString(request)); mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap); response = parseObjectFromMvcResult(mvcResult, Environment.class); @@ -545,6 +628,7 @@ public class EnvironmentControllerTests extends BaseTest { envConfig.setAuthConfig(authConfig); request.setName("sslConfig"); request.setConfig(envConfig); + paramMap.clear(); paramMap.set("request", JSON.toJSONString(request)); mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap); response = parseObjectFromMvcResult(mvcResult, Environment.class); @@ -570,6 +654,7 @@ public class EnvironmentControllerTests extends BaseTest { envConfig.setPreScript(createEnvironmentPreScript()); request.setName("preScript"); request.setConfig(envConfig); + paramMap.clear(); paramMap.set("request", JSON.toJSONString(request)); mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap); response = parseObjectFromMvcResult(mvcResult, Environment.class); @@ -595,6 +680,7 @@ public class EnvironmentControllerTests extends BaseTest { envConfig.setPostScript(createEnvironmentPostScript()); request.setName("postScript"); request.setConfig(envConfig); + paramMap.clear(); paramMap.set("request", JSON.toJSONString(request)); mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap); response = parseObjectFromMvcResult(mvcResult, Environment.class); @@ -621,6 +707,7 @@ public class EnvironmentControllerTests extends BaseTest { envConfig.setAssertions(createAssertions()); request.setName("assertions"); request.setConfig(envConfig); + paramMap.clear(); paramMap.set("request", JSON.toJSONString(request)); mvcResult = this.requestMultipartWithOkAndReturn(add, paramMap); response = parseObjectFromMvcResult(mvcResult, Environment.class); @@ -788,7 +875,7 @@ public class EnvironmentControllerTests extends BaseTest { // 测试500 dataSource.setDriver("com.mysql.cj.jdbc.Driver"); dataSource.setDbUrl("jdbc:mysql://"); - this.requestPost(validate + "500", dataSource, ERROR_REQUEST_MATCHER); + this.requestPost(validate, dataSource, ERROR_REQUEST_MATCHER); } @Test @@ -903,10 +990,10 @@ public class EnvironmentControllerTests extends BaseTest { List environments = environmentMapper.selectByExample(example); posRequest.setMoveId(environments.get(0).getId()); posRequest.setMoveMode("AFTER"); - this.requestPostWithOkAndReturn(POS_URL, posRequest); + this.requestPostWithOkAndReturn(POS_URL, posRequest, DEFAULT_PROJECT_ID); posRequest.setMoveMode("BEFORE"); - this.requestPostWithOkAndReturn(POS_URL, posRequest); + this.requestPostWithOkAndReturn(POS_URL, posRequest, DEFAULT_PROJECT_ID); } @@ -964,11 +1051,11 @@ public class EnvironmentControllerTests extends BaseTest { Assertions.assertEquals(1, response.size()); environmentDTO.setProjectId(DEFAULT_PROJECT_ID); //校验权限 - requestPostPermissionTest(PermissionConstants.PROJECT_ENVIRONMENT_READ, list , environmentDTO); + requestPostPermissionTest(PermissionConstants.PROJECT_ENVIRONMENT_READ, list, environmentDTO); //项目不存在 返回内容为[] environmentDTO.setProjectId("ceshi"); - mvcResult = this.responsePost(list ,environmentDTO); + mvcResult = this.responsePost(list, environmentDTO); response = parseObjectFromMvcResult(mvcResult, List.class); Assertions.assertEquals(0, response.size()); } @@ -1041,52 +1128,50 @@ public class EnvironmentControllerTests extends BaseTest { @Order(14) public void testExport() throws Exception { //指定id - EnvironmentExportRequest environmentExportRequest = new EnvironmentExportRequest(); - environmentExportRequest.setProjectId(DEFAULT_PROJECT_ID); - environmentExportRequest.setEnvironment(true); - environmentExportRequest.setSelectIds(List.of("environmentId1")); - MvcResult mvcResult = this.requestPostDownloadFile(exportEnv, null, environmentExportRequest); + TableBatchProcessDTO request = new TableBatchProcessDTO(); + request.setSelectIds(List.of("environmentId1")); + MvcResult mvcResult = this.requestPostDownloadFile(exportEnv, null, request, DEFAULT_PROJECT_ID); byte[] fileBytes = mvcResult.getResponse().getContentAsByteArray(); Assertions.assertNotNull(fileBytes); - ProjectParametersExample projectParametersExample = new ProjectParametersExample(); - projectParametersExample.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID); - if (projectParametersMapper.countByExample(projectParametersExample) == 0) { - //全局参数 - GlobalParamsRequest request = new GlobalParamsRequest(); - request.setProjectId(DEFAULT_PROJECT_ID); - GlobalParams globalParams = new GlobalParams(); - globalParams.setHeaders(getHeaders(1)); - globalParams.setCommonVariables(getEnvVariables(1)); - request.setGlobalParams(globalParams); - this.responsePost("/project/global/params/add", request); - } - //全选 - environmentExportRequest.setGlobalParam(true); - environmentExportRequest.setSelectIds(List.of("environmentId1")); - environmentExportRequest.setSelectAll(true); - environmentExportRequest.setExcludeIds(List.of("environmentId1")); - MvcResult mvcResult1 = this.requestPostDownloadFile(exportEnv, null, environmentExportRequest); + request.setSelectIds(List.of("environmentId1")); + request.setSelectAll(true); + request.setExcludeIds(List.of("environmentId1")); + MvcResult mvcResult1 = this.requestPostDownloadFile(exportEnv, null, request, DEFAULT_PROJECT_ID); byte[] fileBytes1 = mvcResult1.getResponse().getContentAsByteArray(); + File file = new File("test.json"); + FileOutputStream fileOutputStream = new FileOutputStream(file); + fileOutputStream.write(fileBytes1); + fileOutputStream.close(); Assertions.assertNotNull(fileBytes1); - projectParametersMapper.deleteByExample(projectParametersExample); - environmentExportRequest.setSelectIds(List.of("不存在blob")); - environmentExportRequest.setSelectAll(false); - environmentExportRequest.setEnvironment(true); - mockMvc.perform(getPostRequestBuilder(exportEnv, environmentExportRequest)) + request.setSelectIds(List.of("不存在blob")); + request.setSelectAll(false); + mockMvc.perform(getPostRequestBuilder(exportEnv, request, DEFAULT_PROJECT_ID)) .andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM)) .andExpect(ERROR_REQUEST_MATCHER); } - protected MvcResult requestPostDownloadFile(String url, MediaType contentType, Object param) throws Exception { + protected MvcResult requestPostDownloadFile(String url, MediaType contentType, Object param, String projectId) throws Exception { if (contentType == null) { contentType = MediaType.APPLICATION_OCTET_STREAM; } - return mockMvc.perform(getPostRequestBuilder(url, param)) + return mockMvc.perform(getPostRequestBuilder(url, param, projectId)) .andExpect(content().contentType(contentType)) .andExpect(status().isOk()).andReturn(); } + + protected MockHttpServletRequestBuilder getPostRequestBuilder(String url, Object param, Object... uriVariables) { + MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.post(getBasePath() + url); + return requestBuilder + .header(SessionConstants.HEADER_TOKEN, sessionId) + .header(SessionConstants.CSRF_TOKEN, csrfToken) + .header(SessionConstants.CURRENT_PROJECT, uriVariables) + .header(org.apache.http.HttpHeaders.ACCEPT_LANGUAGE, "zh-CN") + .content(JSON.toJSONString(param)) + .contentType(MediaType.APPLICATION_JSON); + } + @Test @Order(15) public void testImport() throws Exception { @@ -1109,38 +1194,6 @@ public class EnvironmentControllerTests extends BaseTest { paramMap.add("request", JSON.toJSONString(request)); requestMultipartWithOk(importEnv, paramMap, DEFAULT_PROJECT_ID); - //上传全局参数 - ProjectParametersExample projectParametersExample = new ProjectParametersExample(); - projectParametersExample.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID); - if (projectParametersMapper.countByExample(projectParametersExample) == 0) { - //全局参数 - GlobalParamsRequest globalParamsRequest = new GlobalParamsRequest(); - globalParamsRequest.setProjectId(DEFAULT_PROJECT_ID); - GlobalParams globalParams = new GlobalParams(); - globalParams.setHeaders(getHeaders(1)); - globalParams.setCommonVariables(getEnvVariables(1)); - globalParamsRequest.setGlobalParams(globalParams); - this.responsePost("/project/global/params/add", globalParamsRequest); - } - - inputStream = new FileInputStream(new File( - this.getClass().getClassLoader().getResource("file/globalParam.json") - .getPath())); - file = new MockMultipartFile("file", "globalParam.json", MediaType.APPLICATION_OCTET_STREAM_VALUE, inputStream); - paramMap = new LinkedMultiValueMap<>(); - request = new EnvironmentImportRequest(); - request.setCover(true); - paramMap.add("file", List.of(file)); - paramMap.add("request", JSON.toJSONString(request)); - - requestMultipartWithOk(importEnv, paramMap, DEFAULT_PROJECT_ID); - request.setCover(false); - paramMap.clear(); - paramMap.add("file", List.of(file)); - paramMap.add("request", JSON.toJSONString(request)); - requestMultipartWithOk(importEnv, paramMap, DEFAULT_PROJECT_ID); - projectParametersMapper.deleteByExample(projectParametersExample); - inputStream = new FileInputStream(new File( this.getClass().getClassLoader().getResource("file/txtFile.txt") .getPath())); diff --git a/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentGroupControllerTests.java b/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentGroupControllerTests.java index f8af09772b..f2d2269105 100644 --- a/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentGroupControllerTests.java +++ b/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentGroupControllerTests.java @@ -107,9 +107,9 @@ public class EnvironmentGroupControllerTests extends BaseTest { private List createHttpConfig() { List httpConfigs = new ArrayList<>(); HttpConfig httpConfig = new HttpConfig(); - List headers = new ArrayList<>(); - KeyValue keyValue = new KeyValue(); - keyValue.setName("key"); + List headers = new ArrayList<>(); + KeyValueEnableParam keyValue = new KeyValueEnableParam(); + keyValue.setKey("key"); keyValue.setValue("value"); headers.add(keyValue); httpConfig.setHeaders(headers); @@ -314,6 +314,7 @@ public class EnvironmentGroupControllerTests extends BaseTest { this.requestPostWithOkAndReturn(POS_URL, posRequest); } + @Test @Order(12) public void testDeleteSuccess() throws Exception { diff --git a/backend/services/project-management/src/test/java/io/metersphere/project/controller/GlobalParamsControllerTests.java b/backend/services/project-management/src/test/java/io/metersphere/project/controller/GlobalParamsControllerTests.java index 5714964070..290f21401f 100644 --- a/backend/services/project-management/src/test/java/io/metersphere/project/controller/GlobalParamsControllerTests.java +++ b/backend/services/project-management/src/test/java/io/metersphere/project/controller/GlobalParamsControllerTests.java @@ -2,8 +2,9 @@ package io.metersphere.project.controller; import io.metersphere.project.domain.Project; import io.metersphere.project.dto.environment.GlobalParams; +import io.metersphere.project.dto.environment.GlobalParamsDTO; import io.metersphere.project.dto.environment.GlobalParamsRequest; -import io.metersphere.project.dto.environment.KeyValue; +import io.metersphere.project.dto.environment.KeyValueEnableParam; import io.metersphere.project.dto.environment.variables.CommonVariables; import io.metersphere.project.mapper.ProjectMapper; import io.metersphere.sdk.constants.PermissionConstants; @@ -18,27 +19,41 @@ import io.metersphere.system.controller.handler.ResultHolder; import io.metersphere.system.invoker.ProjectServiceInvoker; import io.metersphere.system.log.constants.OperationLogType; import jakarta.annotation.Resource; +import org.apache.http.HttpHeaders; import org.junit.jupiter.api.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; +import org.springframework.mock.web.MockMultipartFile; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.SqlConfig; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultMatcher; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; +import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.util.CollectionUtils; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.ArrayList; import java.util.List; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @AutoConfigureMockMvc @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class GlobalParamsControllerTests extends BaseTest { @@ -48,6 +63,8 @@ public class GlobalParamsControllerTests extends BaseTest { private static final String add = prefix + "/add"; private static final String get = prefix + "/get/"; private static final String update = prefix + "/update"; + private static final String export = prefix + "/export/%s"; + private static final String importUrl = prefix + "/import"; private static final ResultMatcher BAD_REQUEST_MATCHER = status().isBadRequest(); private static final ResultMatcher ERROR_REQUEST_MATCHER = status().is5xxServerError(); @@ -112,6 +129,7 @@ public class GlobalParamsControllerTests extends BaseTest { envVariable.setName("name" + i); envVariable.setValue("value" + i); envVariable.setDescription("desc" + i); + envVariable.setTags(List.of("tag" + i)); envVariable.setType(VariableTypeConstants.CONSTANT.name()); commonVariables.add(envVariable); } @@ -119,11 +137,11 @@ public class GlobalParamsControllerTests extends BaseTest { } //根据需要多长的list 生成不同的List headers - private List getHeaders(int length) { - List headers = new ArrayList<>(); + private List getHeaders(int length) { + List headers = new ArrayList<>(); for (int i = 0; i < length; i++) { - KeyValue header = new KeyValue(); - header.setName("key" + i); + KeyValueEnableParam header = new KeyValueEnableParam(); + header.setKey("key" + i); header.setValue("value" + i); headers.add(header); } @@ -242,7 +260,7 @@ public class GlobalParamsControllerTests extends BaseTest { globalParams.setCommonVariables(getEnvVariables(1)); request.setGlobalParams(globalParams); MvcResult mvcResult = this.responsePost(add, request); - GlobalParamsRequest globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsRequest.class); + ProjectParameters globalParamsRequest = parseObjectFromMvcResult(mvcResult, ProjectParameters.class); Assertions.assertNotNull(globalParamsRequest); ProjectParameters projectParameters = projectParametersMapper.selectByPrimaryKey(globalParamsRequest.getId()); Assertions.assertNotNull(projectParameters); @@ -258,7 +276,7 @@ public class GlobalParamsControllerTests extends BaseTest { globalParams.setCommonVariables(new ArrayList<>()); request.setGlobalParams(globalParams); mvcResult = this.responsePost(add, request); - globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsRequest.class); + globalParamsRequest = parseObjectFromMvcResult(mvcResult, ProjectParameters.class); Assertions.assertNotNull(globalParamsRequest); projectParameters = projectParametersMapper.selectByPrimaryKey(globalParamsRequest.getId()); Assertions.assertNotNull(projectParameters); @@ -274,7 +292,7 @@ public class GlobalParamsControllerTests extends BaseTest { globalParams.setCommonVariables(getEnvVariables(1)); request.setGlobalParams(globalParams); mvcResult = this.responsePost(add, request); - globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsRequest.class); + globalParamsRequest = parseObjectFromMvcResult(mvcResult, ProjectParameters.class); Assertions.assertNotNull(globalParamsRequest); projectParameters = projectParametersMapper.selectByPrimaryKey(globalParamsRequest.getId()); Assertions.assertNotNull(projectParameters); @@ -290,7 +308,7 @@ public class GlobalParamsControllerTests extends BaseTest { globalParams.setCommonVariables(new ArrayList<>()); request.setGlobalParams(globalParams); mvcResult = this.responsePost(add, request); - globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsRequest.class); + globalParamsRequest = parseObjectFromMvcResult(mvcResult, ProjectParameters.class); Assertions.assertNotNull(globalParamsRequest); projectParameters = projectParametersMapper.selectByPrimaryKey(globalParamsRequest.getId()); Assertions.assertNotNull(projectParameters); @@ -302,7 +320,7 @@ public class GlobalParamsControllerTests extends BaseTest { request.setProjectId("projectId5"); request.setGlobalParams(new GlobalParams()); mvcResult = this.responsePost(add, request); - globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsRequest.class); + globalParamsRequest = parseObjectFromMvcResult(mvcResult, ProjectParameters.class); Assertions.assertNotNull(globalParamsRequest); //校验日志 checkLog(globalParamsRequest.getId(), OperationLogType.ADD); @@ -315,6 +333,10 @@ public class GlobalParamsControllerTests extends BaseTest { //校验权限 request = new GlobalParamsRequest(); request.setProjectId(DEFAULT_PROJECT_ID); + GlobalParams globalParams1 = new GlobalParams(); + globalParams1.setHeaders(getHeaders(2)); + globalParams1.setCommonVariables(getEnvVariables(2)); + request.setGlobalParams(globalParams1); //权限校验 requestPostPermissionTest(PermissionConstants.PROJECT_ENVIRONMENT_READ_ADD, add, request); } @@ -352,7 +374,7 @@ public class GlobalParamsControllerTests extends BaseTest { globalParams.setCommonVariables(getEnvVariables(2)); request.setGlobalParams(globalParams); MvcResult mvcResult = this.responsePost(update, request); - GlobalParamsRequest globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsRequest.class); + ProjectParameters globalParamsRequest = parseObjectFromMvcResult(mvcResult, ProjectParameters.class); Assertions.assertNotNull(globalParamsRequest); //校验日志 checkLog(globalParamsRequest.getId(), OperationLogType.UPDATE); @@ -365,10 +387,14 @@ public class GlobalParamsControllerTests extends BaseTest { //校验权限 request = new GlobalParamsRequest(); example = new ProjectParametersExample(); - example.createCriteria().andProjectIdEqualTo("100001100001"); + example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID); projectParametersList = projectParametersMapper.selectByExample(example); - request.setProjectId("100001100001"); + request.setProjectId(DEFAULT_PROJECT_ID); request.setId(projectParametersList.get(0).getId()); + GlobalParams globalParams1 = new GlobalParams(); + globalParams1.setHeaders(getHeaders(3)); + globalParams1.setCommonVariables(getEnvVariables(4)); + request.setGlobalParams(globalParams1); //权限校验 requestPostPermissionTest(PermissionConstants.PROJECT_ENVIRONMENT_READ_UPDATE, update, request); @@ -405,7 +431,7 @@ public class GlobalParamsControllerTests extends BaseTest { public void testGetSuccess() throws Exception { //获取全局参数 MvcResult mvcResult = this.responseGet(get + "projectId1"); - GlobalParamsRequest globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsRequest.class); + GlobalParamsDTO globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsDTO.class); Assertions.assertNotNull(globalParamsRequest); Assertions.assertEquals("projectId1", globalParamsRequest.getProjectId()); Assertions.assertEquals(2, globalParamsRequest.getGlobalParams().getHeaders().size()); @@ -416,9 +442,161 @@ public class GlobalParamsControllerTests extends BaseTest { //获取全局参数 全局参数不存在 mvcResult = this.responseGet(get + "projectId2"); - globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsRequest.class); + globalParamsRequest = parseObjectFromMvcResult(mvcResult, GlobalParamsDTO.class); Assertions.assertNull(globalParamsRequest); } + @Test + @Order(6) + public void testExportSuccess() throws Exception { + //导出全局参数 + MvcResult mvcResult = this.requestGetDownloadFile(String.format(export, DEFAULT_PROJECT_ID), null); + byte[] fileBytes = mvcResult.getResponse().getContentAsByteArray(); + Assertions.assertNotNull(fileBytes); + mockMvc.perform(getRequestBuilder(String.format(export, "321"))) + .andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM)) + .andExpect(status().is5xxServerError()); + } + + @Test + @Order(7) + public void testImportSuccess() throws Exception { + //导入全局参数 + InputStream inputStream = new FileInputStream(new File( + this.getClass().getClassLoader().getResource("file/globalParams.json") + .getPath())); + MockMultipartFile file = new MockMultipartFile("file", "globalParams.json", MediaType.APPLICATION_OCTET_STREAM_VALUE, inputStream); + MultiValueMap paramMap = new LinkedMultiValueMap<>(); + paramMap.add("file", List.of(file)); + requestMultipartWithOk(importUrl, paramMap); + paramMap.clear(); + paramMap.add("file", List.of(new File( + this.getClass().getClassLoader().getResource("file/huanj.json") + .getPath()))); + + this.requestMultipart(importUrl, paramMap, status().is5xxServerError()); + + } + + protected MvcResult requestMultipart(String url, MultiValueMap paramMap, ResultMatcher resultMatcher) throws Exception { + MockMultipartHttpServletRequestBuilder requestBuilder = getMultipartRequestBuilderWithParam(url, paramMap); + MockHttpServletRequestBuilder header = requestBuilder + .header(SessionConstants.HEADER_TOKEN, sessionId) + .header(SessionConstants.CSRF_TOKEN, csrfToken) + .header(org.springframework.http.HttpHeaders.ACCEPT_LANGUAGE, "zh-CN"); + return mockMvc.perform(header) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(resultMatcher).andReturn(); + } + + private MockMultipartHttpServletRequestBuilder getMultipartRequestBuilderWithParam(String url, MultiValueMap paramMap) { + MockMultipartHttpServletRequestBuilder requestBuilder = + MockMvcRequestBuilders.multipart(getBasePath() + url); + paramMap.forEach((key, value) -> { + List list = value; + for (Object o : list) { + if (o instanceof List fileList) { + fileList.forEach(o1 -> { + if (o1 instanceof MockMultipartFile mockMultipartFile) { + try { + MockMultipartFile mockMultipartFile1 = null; + mockMultipartFile1 = new MockMultipartFile(key, mockMultipartFile.getOriginalFilename(), + MediaType.APPLICATION_OCTET_STREAM_VALUE, mockMultipartFile.getBytes()); + requestBuilder.file(mockMultipartFile1); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + }); + } else { + MockMultipartFile multipartFile = null; + multipartFile = new MockMultipartFile(key, null, + MediaType.APPLICATION_JSON_VALUE, o.toString().getBytes()); + requestBuilder.file(multipartFile); + } + } + }); + return requestBuilder; + + } + + protected ResultActions requestMultipartWithOk(String url, MultiValueMap paramMap, Object... uriVariables) throws Exception { + MockHttpServletRequestBuilder requestBuilder = getMultipartRequestBuilder(url, paramMap, uriVariables); + return mockMvc.perform(requestBuilder) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andDo(print()) + .andExpect(status().isOk()); + } + + private static MockMultipartFile getMockMultipartFile(String key, Object value) throws IOException { + MockMultipartFile multipartFile; + if (value instanceof File) { + File file = (File) value; + multipartFile = new MockMultipartFile(key, file.getName(), + MediaType.APPLICATION_OCTET_STREAM_VALUE, Files.readAllBytes(file.toPath())); + } else if (value instanceof MockMultipartFile) { + multipartFile = (MockMultipartFile) value; + // 有些地方的参数 name 写的是文件名,这里统一处理成参数名 key + multipartFile = new MockMultipartFile(key, multipartFile.getOriginalFilename(), + MediaType.APPLICATION_OCTET_STREAM_VALUE, multipartFile.getBytes()); + } else { + multipartFile = new MockMultipartFile(key, key, + MediaType.APPLICATION_JSON_VALUE, value.toString().getBytes()); + } + return multipartFile; + } + + private MockHttpServletRequestBuilder getMultipartRequestBuilder(String url, + MultiValueMap paramMap, + Object[] uriVariables) { + MockMultipartHttpServletRequestBuilder requestBuilder = getMultipartRequestBuilderWithParam(url, paramMap, uriVariables); + return requestBuilder + .header(SessionConstants.HEADER_TOKEN, sessionId) + .header(SessionConstants.CSRF_TOKEN, csrfToken) + .header(SessionConstants.CURRENT_PROJECT, DEFAULT_PROJECT_ID) + .header(HttpHeaders.ACCEPT_LANGUAGE, "zh-CN"); + } + + + private MockMultipartHttpServletRequestBuilder getMultipartRequestBuilderWithParam(String url, MultiValueMap paramMap, Object[] uriVariables) { + MockMultipartHttpServletRequestBuilder requestBuilder = + MockMvcRequestBuilders.multipart(getBasePath() + url, uriVariables); + paramMap.forEach((key, value) -> { + List list = value; + for (Object o : list) { + try { + if (o == null) { + continue; + } + MockMultipartFile multipartFile; + if (o instanceof List) { + List listObject = ((List) o); + if (CollectionUtils.isEmpty(listObject)) { + continue; + } + if (listObject.get(0) instanceof File || listObject.get(0) instanceof MockMultipartFile) { + // 参数是多个文件时,设置多个文件 + for (Object subObject : ((List) o)) { + multipartFile = getMockMultipartFile(key, subObject); + requestBuilder.file(multipartFile); + } + } else { + multipartFile = getMockMultipartFile(key, o); + requestBuilder.file(multipartFile); + } + } else { + multipartFile = getMockMultipartFile(key, o); + requestBuilder.file(multipartFile); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + + } + }); + return requestBuilder; + } + } diff --git a/backend/services/project-management/src/test/resources/file/globalParam.json b/backend/services/project-management/src/test/resources/file/globalParam.json deleted file mode 100644 index 0810d237e0..0000000000 --- a/backend/services/project-management/src/test/resources/file/globalParam.json +++ /dev/null @@ -1 +0,0 @@ -{"globalParam":true,"environment":false,"data":"{\"headers\":[{\"name\":\"key0\",\"value\":\"value0\",\"enable\":true}],\"commonVariables\":[{\"id\":null,\"name\":\"name0\",\"type\":\"CONSTANT\",\"value\":\"value0\",\"enable\":true,\"description\":\"desc0\"}]}"} diff --git a/backend/services/project-management/src/test/resources/file/globalParams.json b/backend/services/project-management/src/test/resources/file/globalParams.json new file mode 100644 index 0000000000..3df102217d --- /dev/null +++ b/backend/services/project-management/src/test/resources/file/globalParams.json @@ -0,0 +1,69 @@ +{ + "id":"1204738326536684", + "projectId":"100001100001", + "globalParams":{ + "headers":[ + { + "name":"key0", + "value":"value0", + "enable":true + }, + { + "name":"key1", + "value":"value1", + "enable":true + }, + { + "name":"key2", + "value":"value2", + "enable":true + } + ], + "commonVariables":[ + { + "id":null, + "name":"name0", + "type":"CONSTANT", + "value":"value0", + "enable":true, + "description":"desc0", + "tags":[ + "tag0" + ] + }, + { + "id":null, + "name":"name1", + "type":"CONSTANT", + "value":"value1", + "enable":true, + "description":"desc1", + "tags":[ + "tag1" + ] + }, + { + "id":null, + "name":"name2", + "type":"CONSTANT", + "value":"value2", + "enable":true, + "description":"desc2", + "tags":[ + "tag2" + ] + }, + { + "id":null, + "name":"name4", + "type":"CONSTANT", + "value":"value4", + "enable":true, + "description":"desc4", + "tags":[ + "tag4" + ] + } + ] + } +} \ No newline at end of file diff --git a/backend/services/project-management/src/test/resources/file/huanj.json b/backend/services/project-management/src/test/resources/file/huanj.json index 48859fadc4..3d2e3e7ef7 100644 --- a/backend/services/project-management/src/test/resources/file/huanj.json +++ b/backend/services/project-management/src/test/resources/file/huanj.json @@ -1 +1 @@ -{"globalParam":false,"environment":true,"data":"[{\"id\":\"1017615191384064\",\"projectId\":\"projectId\",\"name\":\"导入环境1\",\"config\":{\"commonParams\":{\"requestTimeout\":null,\"responseTimeout\":null},\"commonVariables\":[],\"httpConfig\":[],\"dataSources\":[],\"hostConfig\":{\"enable\":null,\"hosts\":null},\"authConfig\":{\"username\":null,\"password\":null,\"verification\":null,\"sslConfig\":null},\"preScript\":{\"apiPreScript\":null,\"uiPreScript\":null},\"postScript\":{\"apiPostScript\":null,\"uiPostScript\":null},\"assertions\":{\"apiTest\":true,\"uiTest\":false,\"xpathType\":null,\"regex\":null,\"jsonPath\":null,\"jsr223\":null,\"xpath\":null,\"duration\":null,\"document\":null}},\"mock\":null,\"description\":null},{\"id\":\"1017615191384065\",\"projectId\":\"projectId\",\"name\":\"导入环境2\",\"config\":{\"commonParams\":{\"requestTimeout\":6000,\"responseTimeout\":6000},\"commonVariables\":[],\"httpConfig\":[],\"dataSources\":[],\"hostConfig\":{\"enable\":null,\"hosts\":null},\"authConfig\":{\"username\":null,\"password\":null,\"verification\":null,\"sslConfig\":null},\"preScript\":{\"apiPreScript\":null,\"uiPreScript\":null},\"postScript\":{\"apiPostScript\":null,\"uiPostScript\":null},\"assertions\":{\"apiTest\":true,\"uiTest\":false,\"xpathType\":null,\"regex\":null,\"jsonPath\":null,\"jsr223\":null,\"xpath\":null,\"duration\":null,\"document\":null}},\"mock\":null,\"description\":null},{\"id\":\"1017615191384066\",\"projectId\":\"projectId\",\"name\":\"导入环境3\",\"config\":{\"commonParams\":{\"requestTimeout\":6000,\"responseTimeout\":6000},\"commonVariables\":[{\"id\":null,\"name\":\"key0\",\"type\":\"CONSTANT\",\"value\":\"value0\",\"enable\":true,\"description\":\"description0\"}],\"httpConfig\":[],\"dataSources\":[],\"hostConfig\":{\"enable\":null,\"hosts\":null},\"authConfig\":{\"username\":null,\"password\":null,\"verification\":null,\"sslConfig\":null},\"preScript\":{\"apiPreScript\":null,\"uiPreScript\":null},\"postScript\":{\"apiPostScript\":null,\"uiPostScript\":null},\"assertions\":{\"apiTest\":true,\"uiTest\":false,\"xpathType\":null,\"regex\":null,\"jsonPath\":null,\"jsr223\":null,\"xpath\":null,\"duration\":null,\"document\":null}},\"mock\":null,\"description\":null},{\"id\":\"1017615191384067\",\"projectId\":\"projectId\",\"name\":\"导入环境4\",\"config\":{\"commonParams\":{\"requestTimeout\":6000,\"responseTimeout\":6000},\"commonVariables\":[{\"id\":null,\"name\":\"key0\",\"type\":\"CONSTANT\",\"value\":\"value0\",\"enable\":true,\"description\":\"description0\"}],\"httpConfig\":[{\"url\":null,\"apiTest\":true,\"uiTest\":false,\"type\":null,\"details\":null,\"moduleIds\":null,\"headers\":[{\"name\":\"key\",\"value\":\"value\",\"enable\":true}],\"browser\":null,\"description\":null}],\"dataSources\":[],\"hostConfig\":{\"enable\":null,\"hosts\":null},\"authConfig\":{\"username\":null,\"password\":null,\"verification\":null,\"sslConfig\":null},\"preScript\":{\"apiPreScript\":null,\"uiPreScript\":null},\"postScript\":{\"apiPostScript\":null,\"uiPostScript\":null},\"assertions\":{\"apiTest\":true,\"uiTest\":false,\"xpathType\":null,\"regex\":null,\"jsonPath\":null,\"jsr223\":null,\"xpath\":null,\"duration\":null,\"document\":null}},\"mock\":null,\"description\":null},{\"id\":\"1017615191384068\",\"projectId\":\"projectId\",\"name\":\"导入环境5\",\"config\":{\"commonParams\":{\"requestTimeout\":6000,\"responseTimeout\":6000},\"commonVariables\":[{\"id\":null,\"name\":\"key0\",\"type\":\"CONSTANT\",\"value\":\"value0\",\"enable\":true,\"description\":\"description0\"}],\"httpConfig\":[{\"url\":null,\"apiTest\":true,\"uiTest\":false,\"type\":null,\"details\":null,\"moduleIds\":null,\"headers\":[{\"name\":\"key\",\"value\":\"value\",\"enable\":true}],\"browser\":null,\"description\":null}],\"dataSources\":[{\"id\":\"1\",\"dataSource\":\"mysql\",\"driver\":\"com.mysql.cj.jdbc.Driver\",\"driverId\":null,\"dbUrl\":\"jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai\",\"username\":\"root\",\"password\":\"123456\",\"poolMax\":10,\"timeout\":1000}],\"hostConfig\":{\"enable\":null,\"hosts\":null},\"authConfig\":{\"username\":null,\"password\":null,\"verification\":null,\"sslConfig\":null},\"preScript\":{\"apiPreScript\":null,\"uiPreScript\":null},\"postScript\":{\"apiPostScript\":null,\"uiPostScript\":null},\"assertions\":{\"apiTest\":true,\"uiTest\":false,\"xpathType\":null,\"regex\":null,\"jsonPath\":null,\"jsr223\":null,\"xpath\":null,\"duration\":null,\"document\":null}},\"mock\":null,\"description\":null},{\"id\":\"1017615191384069\",\"projectId\":\"projectId\",\"name\":\"导入环境6\",\"config\":{\"commonParams\":{\"requestTimeout\":6000,\"responseTimeout\":6000},\"commonVariables\":[{\"id\":null,\"name\":\"key0\",\"type\":\"CONSTANT\",\"value\":\"value0\",\"enable\":true,\"description\":\"description0\"}],\"httpConfig\":[{\"url\":null,\"apiTest\":true,\"uiTest\":false,\"type\":null,\"details\":null,\"moduleIds\":null,\"headers\":[{\"name\":\"key\",\"value\":\"value\",\"enable\":true}],\"browser\":null,\"description\":null}],\"dataSources\":[{\"id\":\"1\",\"dataSource\":\"mysql\",\"driver\":\"com.mysql.cj.jdbc.Driver\",\"driverId\":null,\"dbUrl\":\"jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai\",\"username\":\"root\",\"password\":\"123456\",\"poolMax\":10,\"timeout\":1000}],\"hostConfig\":{\"enable\":null,\"hosts\":null},\"authConfig\":{\"username\":null,\"password\":null,\"verification\":null,\"sslConfig\":null},\"preScript\":{\"apiPreScript\":null,\"uiPreScript\":null},\"postScript\":{\"apiPostScript\":null,\"uiPostScript\":null},\"assertions\":{\"apiTest\":true,\"uiTest\":false,\"xpathType\":null,\"regex\":null,\"jsonPath\":null,\"jsr223\":null,\"xpath\":null,\"duration\":null,\"document\":null}},\"mock\":null,\"description\":null},{\"id\":\"1017615191384070\",\"projectId\":\"projectId\",\"name\":\"导入环境7\",\"config\":{\"commonParams\":{\"requestTimeout\":6000,\"responseTimeout\":6000},\"commonVariables\":[{\"id\":null,\"name\":\"key0\",\"type\":\"CONSTANT\",\"value\":\"value0\",\"enable\":true,\"description\":\"description0\"}],\"httpConfig\":[{\"url\":null,\"apiTest\":true,\"uiTest\":false,\"type\":null,\"details\":null,\"moduleIds\":null,\"headers\":[{\"name\":\"key\",\"value\":\"value\",\"enable\":true}],\"browser\":null,\"description\":null}],\"dataSources\":[{\"id\":\"1\",\"dataSource\":\"mysql\",\"driver\":\"com.mysql.cj.jdbc.Driver\",\"driverId\":null,\"dbUrl\":\"jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai\",\"username\":\"root\",\"password\":\"123456\",\"poolMax\":10,\"timeout\":1000}],\"hostConfig\":{\"enable\":true,\"hosts\":[{\"ip\":\"ip\",\"domain\":\"domain\",\"description\":\"description\",\"uuid\":\"uuid\"}]},\"authConfig\":{\"username\":null,\"password\":null,\"verification\":null,\"sslConfig\":null},\"preScript\":{\"apiPreScript\":null,\"uiPreScript\":null},\"postScript\":{\"apiPostScript\":null,\"uiPostScript\":null},\"assertions\":{\"apiTest\":true,\"uiTest\":false,\"xpathType\":null,\"regex\":null,\"jsonPath\":null,\"jsr223\":null,\"xpath\":null,\"duration\":null,\"document\":null}},\"mock\":null,\"description\":null}]"} +[{"id":"1093344054747149","projectId":"100001100001","name":"校验更新权限","config":{"commonParams":{"requestTimeout":600000,"responseTimeout":600000},"commonVariables":[{"id":null,"name":null,"type":"CONSTANT","value":null,"enable":true,"description":null,"tags":null}],"httpConfig":[{"url":null,"apiTest":true,"uiTest":false,"type":"NONE","details":null,"moduleIds":null,"headers":[{"key":null,"value":null,"enable":true,"description":null,"valid":false}],"browser":null,"description":null}],"dataSources":[{"id":null,"dataSource":null,"driver":null,"driverId":null,"dbUrl":null,"username":null,"password":null,"poolMax":null,"timeout":null}],"hostConfig":{"enable":null,"hosts":null},"authConfig":{"username":null,"password":null,"verification":null,"sslConfig":null},"preScript":{"apiPreScript":null,"uiPreScript":null},"postScript":{"apiPostScript":null,"uiPostScript":null},"assertions":{"assertions":null}},"mock":null,"description":null},{"id":"1093344054747137","projectId":"100001100001","name":"commonParams","config":{"commonParams":{"requestTimeout":600000,"responseTimeout":600000},"commonVariables":[{"id":null,"name":null,"type":"CONSTANT","value":null,"enable":true,"description":null,"tags":null}],"httpConfig":[{"url":null,"apiTest":true,"uiTest":false,"type":"NONE","details":null,"moduleIds":null,"headers":[{"key":null,"value":null,"enable":true,"description":null,"valid":false}],"browser":null,"description":null}],"dataSources":[{"id":null,"dataSource":null,"driver":null,"driverId":null,"dbUrl":null,"username":null,"password":null,"poolMax":null,"timeout":null}],"hostConfig":{"enable":null,"hosts":null},"authConfig":{"username":null,"password":null,"verification":null,"sslConfig":null},"preScript":{"apiPreScript":null,"uiPreScript":null},"postScript":{"apiPostScript":null,"uiPostScript":null},"assertions":{"assertions":null}},"mock":null,"description":null},{"id":"1093344054747146","projectId":"100001100001","name":"assertions","config":{"commonParams":{"requestTimeout":6000,"responseTimeout":6000},"commonVariables":[{"id":null,"name":"key0","type":"CONSTANT","value":"value0","enable":true,"description":"description0","tags":null}],"httpConfig":[{"url":"http://www.baidu.com","apiTest":true,"uiTest":false,"type":"NONE","details":null,"moduleIds":null,"headers":[{"key":"key","value":"value","enable":true,"description":null,"valid":true}],"browser":null,"description":null}],"dataSources":[{"id":"1","dataSource":"mysql","driver":"com.mysql.cj.jdbc.Driver","driverId":null,"dbUrl":"jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai","username":"root","password":"123456","poolMax":10,"timeout":1000}],"hostConfig":{"enable":true,"hosts":[{"ip":"ip","domain":"domain","description":"description","uuid":"uuid"}]},"authConfig":{"username":"username","password":"password","verification":null,"sslConfig":{"entry":[{"id":"id","originalAsName":null,"newAsName":null,"type":null,"password":"alias","sourceName":"sourceName","sourceId":"sourceId","isDefault":true,"default":true}],"files":[{"id":"id","name":"name","type":"type","updateTime":"updateTime","password":"password","file":null}],"defaultAlias":null}},"preScript":{"apiPreScript":{"planProcessors":[{"processorType":"ENV_SCRIPT","name":"测试计划级别脚本","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null},{"processorType":"ENV_SQL","name":null,"enable":true,"script":null,"queryTimeout":1000,"resultVariable":null,"variableNames":null,"variables":null,"environmentId":"environmentId","dataSourceId":"dataSourceId","extractParams":null}],"scenarioProcessors":[{"processorType":"SCENARIO_SCRIPT","name":"场景级别脚本","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null,"associateScenarioResults":false},{"processorType":"ENV_SQL","name":null,"enable":true,"script":null,"queryTimeout":1000,"resultVariable":null,"variableNames":null,"variables":null,"environmentId":"environmentId","dataSourceId":"dataSourceId","extractParams":null}],"stepProcessors":[{"processorType":"STEP_SCRIPT","name":"步骤级别前置脚本前","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null,"filterRequestScript":["HTTP"],"scriptExecBefore":true},{"processorType":"ENV_SQL","name":null,"enable":true,"script":null,"queryTimeout":1000,"resultVariable":null,"variableNames":null,"variables":null,"environmentId":"environmentId","dataSourceId":"dataSourceId","extractParams":null},{"processorType":"STEP_SCRIPT","name":"步骤级别前置脚本后","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null,"filterRequestScript":["HTTP"],"scriptExecBefore":false}]},"uiPreScript":{"preScriptExecBefore":true,"jsrType":true,"jsrSetVariable":true,"variableName":"variableName","value":true}},"postScript":{"apiPostScript":{"planProcessors":[{"processorType":"ENV_SCRIPT","name":"测试计划级别脚本","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null},{"processorType":"ENV_SQL","name":null,"enable":true,"script":null,"queryTimeout":1000,"resultVariable":null,"variableNames":null,"variables":null,"environmentId":"environmentId","dataSourceId":"dataSourceId","extractParams":null}],"scenarioProcessors":[{"processorType":"SCENARIO_SCRIPT","name":"场景级别脚本","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null,"associateScenarioResults":false},{"processorType":"ENV_SQL","name":null,"enable":true,"script":null,"queryTimeout":1000,"resultVariable":null,"variableNames":null,"variables":null,"environmentId":"environmentId","dataSourceId":"dataSourceId","extractParams":null}],"stepProcessors":[{"processorType":"STEP_SCRIPT","name":"步骤级别前置脚本前","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null,"filterRequestScript":["HTTP"],"scriptExecBefore":true},{"processorType":"ENV_SQL","name":null,"enable":true,"script":null,"queryTimeout":1000,"resultVariable":null,"variableNames":null,"variables":null,"environmentId":"environmentId","dataSourceId":"dataSourceId","extractParams":null},{"processorType":"STEP_SCRIPT","name":"步骤级别前置脚本后","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null,"filterRequestScript":["HTTP"],"scriptExecBefore":false}]},"uiPostScript":{"postScriptExecBefore":true,"jsrType":true,"jsrSetVariable":true,"variableName":"variableName","value":true}},"assertions":{"assertions":[{"assertionType":"ENV_RESPONSE_CODE","enable":true,"name":"name","condition":"EMPTY","expectedValue":"value"},{"assertionType":"ENV_RESPONSE_HEADER","enable":true,"name":null,"assertions":[{"enable":true,"header":"header","condition":"EMPTY","expectedValue":"value"}]},{"assertionType":"ENV_RESPONSE_BODY","enable":true,"name":null,"assertionBodyType":"REGEX","jsonPathAssertion":null,"xpathAssertion":null,"documentAssertion":null,"regexAssertion":{"assertions":[{"enable":true,"expression":"^test","valid":true}]},"bodyAssertionClassByType":"io.metersphere.project.dto.environment.assertion.body.MsRegexAssertion","bodyAssertionDataByType":{"assertions":[{"enable":true,"expression":"^test","valid":true}]}},{"assertionType":"ENV_RESPONSE_BODY","enable":true,"name":null,"assertionBodyType":"DOCUMENT","jsonPathAssertion":null,"xpathAssertion":null,"documentAssertion":{"enable":true,"followApiId":null,"documentType":null,"jsonAssertion":null,"xmlAssertion":null},"regexAssertion":null,"bodyAssertionClassByType":"io.metersphere.project.dto.environment.assertion.body.MsDocumentAssertion","bodyAssertionDataByType":{"enable":true,"followApiId":null,"documentType":null,"jsonAssertion":null,"xmlAssertion":null}},{"assertionType":"ENV_RESPONSE_BODY","enable":true,"name":null,"assertionBodyType":"JSON_PATH","jsonPathAssertion":{"assertions":[{"enable":true,"expression":"^test","condition":"REGEX","expectedValue":"expectedValue","valid":true}]},"xpathAssertion":null,"documentAssertion":null,"regexAssertion":null,"bodyAssertionClassByType":"io.metersphere.project.dto.environment.assertion.body.MsJSONPathAssertion","bodyAssertionDataByType":{"assertions":[{"enable":true,"expression":"^test","condition":"REGEX","expectedValue":"expectedValue","valid":true}]}},{"assertionType":"ENV_RESPONSE_BODY","enable":true,"name":null,"assertionBodyType":"XPATH","jsonPathAssertion":null,"xpathAssertion":{"responseFormat":"XML","assertions":[{"enable":true,"expression":"^test","expectedValue":"expectedValue","valid":true}]},"documentAssertion":null,"regexAssertion":null,"bodyAssertionClassByType":"io.metersphere.project.dto.environment.assertion.body.MsXPathAssertion","bodyAssertionDataByType":{"responseFormat":"XML","assertions":[{"enable":true,"expression":"^test","expectedValue":"expectedValue","valid":true}]}},{"assertionType":"ENV_RESPONSE_TIME","enable":true,"name":"aa","expectedValue":1000},{"assertionType":"ENV_SCRIPT_ASSERTION","enable":true,"name":"1111","script":"1111","scriptLanguage":null,"enableCommonScript":null,"scriptId":"1111","params":null},{"assertionType":"ENV_VARIABLE","enable":true,"name":null,"variableAssertionItems":[{"enable":true,"variableName":"vn","condition":"GT","expectedValue":"ev"}]}]}},"mock":null,"description":null},{"id":"1093344054747145","projectId":"100001100001","name":"postScript","config":{"commonParams":{"requestTimeout":6000,"responseTimeout":6000},"commonVariables":[{"id":null,"name":"key0","type":"CONSTANT","value":"value0","enable":true,"description":"description0","tags":null}],"httpConfig":[{"url":"http://www.baidu.com","apiTest":true,"uiTest":false,"type":"NONE","details":null,"moduleIds":null,"headers":[{"key":"key","value":"value","enable":true,"description":null,"valid":true}],"browser":null,"description":null}],"dataSources":[{"id":"1","dataSource":"mysql","driver":"com.mysql.cj.jdbc.Driver","driverId":null,"dbUrl":"jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai","username":"root","password":"123456","poolMax":10,"timeout":1000}],"hostConfig":{"enable":true,"hosts":[{"ip":"ip","domain":"domain","description":"description","uuid":"uuid"}]},"authConfig":{"username":"username","password":"password","verification":null,"sslConfig":{"entry":[{"id":"id","originalAsName":null,"newAsName":null,"type":null,"password":"alias","sourceName":"sourceName","sourceId":"sourceId","isDefault":true,"default":true}],"files":[{"id":"id","name":"name","type":"type","updateTime":"updateTime","password":"password","file":null}],"defaultAlias":null}},"preScript":{"apiPreScript":{"planProcessors":[{"processorType":"ENV_SCRIPT","name":"测试计划级别脚本","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null},{"processorType":"ENV_SQL","name":null,"enable":true,"script":null,"queryTimeout":1000,"resultVariable":null,"variableNames":null,"variables":null,"environmentId":"environmentId","dataSourceId":"dataSourceId","extractParams":null}],"scenarioProcessors":[{"processorType":"SCENARIO_SCRIPT","name":"场景级别脚本","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null,"associateScenarioResults":false},{"processorType":"ENV_SQL","name":null,"enable":true,"script":null,"queryTimeout":1000,"resultVariable":null,"variableNames":null,"variables":null,"environmentId":"environmentId","dataSourceId":"dataSourceId","extractParams":null}],"stepProcessors":[{"processorType":"STEP_SCRIPT","name":"步骤级别前置脚本前","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null,"filterRequestScript":["HTTP"],"scriptExecBefore":true},{"processorType":"ENV_SQL","name":null,"enable":true,"script":null,"queryTimeout":1000,"resultVariable":null,"variableNames":null,"variables":null,"environmentId":"environmentId","dataSourceId":"dataSourceId","extractParams":null},{"processorType":"STEP_SCRIPT","name":"步骤级别前置脚本后","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null,"filterRequestScript":["HTTP"],"scriptExecBefore":false}]},"uiPreScript":{"preScriptExecBefore":true,"jsrType":true,"jsrSetVariable":true,"variableName":"variableName","value":true}},"postScript":{"apiPostScript":{"planProcessors":[{"processorType":"ENV_SCRIPT","name":"测试计划级别脚本","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null},{"processorType":"ENV_SQL","name":null,"enable":true,"script":null,"queryTimeout":1000,"resultVariable":null,"variableNames":null,"variables":null,"environmentId":"environmentId","dataSourceId":"dataSourceId","extractParams":null}],"scenarioProcessors":[{"processorType":"SCENARIO_SCRIPT","name":"场景级别脚本","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null,"associateScenarioResults":false},{"processorType":"ENV_SQL","name":null,"enable":true,"script":null,"queryTimeout":1000,"resultVariable":null,"variableNames":null,"variables":null,"environmentId":"environmentId","dataSourceId":"dataSourceId","extractParams":null}],"stepProcessors":[{"processorType":"STEP_SCRIPT","name":"步骤级别前置脚本前","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null,"filterRequestScript":["HTTP"],"scriptExecBefore":true},{"processorType":"ENV_SQL","name":null,"enable":true,"script":null,"queryTimeout":1000,"resultVariable":null,"variableNames":null,"variables":null,"environmentId":"environmentId","dataSourceId":"dataSourceId","extractParams":null},{"processorType":"STEP_SCRIPT","name":"步骤级别前置脚本后","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null,"filterRequestScript":["HTTP"],"scriptExecBefore":false}]},"uiPostScript":{"postScriptExecBefore":true,"jsrType":true,"jsrSetVariable":true,"variableName":"variableName","value":true}},"assertions":{"assertions":null}},"mock":null,"description":null},{"id":"1093344054747144","projectId":"100001100001","name":"preScript","config":{"commonParams":{"requestTimeout":6000,"responseTimeout":6000},"commonVariables":[{"id":null,"name":"key0","type":"CONSTANT","value":"value0","enable":true,"description":"description0","tags":null}],"httpConfig":[{"url":"http://www.baidu.com","apiTest":true,"uiTest":false,"type":"NONE","details":null,"moduleIds":null,"headers":[{"key":"key","value":"value","enable":true,"description":null,"valid":true}],"browser":null,"description":null}],"dataSources":[{"id":"1","dataSource":"mysql","driver":"com.mysql.cj.jdbc.Driver","driverId":null,"dbUrl":"jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai","username":"root","password":"123456","poolMax":10,"timeout":1000}],"hostConfig":{"enable":true,"hosts":[{"ip":"ip","domain":"domain","description":"description","uuid":"uuid"}]},"authConfig":{"username":"username","password":"password","verification":null,"sslConfig":{"entry":[{"id":"id","originalAsName":null,"newAsName":null,"type":null,"password":"alias","sourceName":"sourceName","sourceId":"sourceId","isDefault":true,"default":true}],"files":[{"id":"id","name":"name","type":"type","updateTime":"updateTime","password":"password","file":null}],"defaultAlias":null}},"preScript":{"apiPreScript":{"planProcessors":[{"processorType":"ENV_SCRIPT","name":"测试计划级别脚本","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null},{"processorType":"ENV_SQL","name":null,"enable":true,"script":null,"queryTimeout":1000,"resultVariable":null,"variableNames":null,"variables":null,"environmentId":"environmentId","dataSourceId":"dataSourceId","extractParams":null}],"scenarioProcessors":[{"processorType":"SCENARIO_SCRIPT","name":"场景级别脚本","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null,"associateScenarioResults":false},{"processorType":"ENV_SQL","name":null,"enable":true,"script":null,"queryTimeout":1000,"resultVariable":null,"variableNames":null,"variables":null,"environmentId":"environmentId","dataSourceId":"dataSourceId","extractParams":null}],"stepProcessors":[{"processorType":"STEP_SCRIPT","name":"步骤级别前置脚本前","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null,"filterRequestScript":["HTTP"],"scriptExecBefore":true},{"processorType":"ENV_SQL","name":null,"enable":true,"script":null,"queryTimeout":1000,"resultVariable":null,"variableNames":null,"variables":null,"environmentId":"environmentId","dataSourceId":"dataSourceId","extractParams":null},{"processorType":"STEP_SCRIPT","name":"步骤级别前置脚本后","enable":true,"script":"script","scriptLanguage":null,"enableCommonScript":false,"scriptId":null,"params":null,"filterRequestScript":["HTTP"],"scriptExecBefore":false}]},"uiPreScript":{"preScriptExecBefore":true,"jsrType":true,"jsrSetVariable":true,"variableName":"variableName","value":true}},"postScript":{"apiPostScript":null,"uiPostScript":null},"assertions":{"assertions":null}},"mock":null,"description":null},{"id":"1093344054747143","projectId":"100001100001","name":"sslConfig","config":{"commonParams":{"requestTimeout":6000,"responseTimeout":6000},"commonVariables":[{"id":null,"name":"key0","type":"CONSTANT","value":"value0","enable":true,"description":"description0","tags":null}],"httpConfig":[{"url":"http://www.baidu.com","apiTest":true,"uiTest":false,"type":"NONE","details":null,"moduleIds":null,"headers":[{"key":"key","value":"value","enable":true,"description":null,"valid":true}],"browser":null,"description":null}],"dataSources":[{"id":"1","dataSource":"mysql","driver":"com.mysql.cj.jdbc.Driver","driverId":null,"dbUrl":"jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai","username":"root","password":"123456","poolMax":10,"timeout":1000}],"hostConfig":{"enable":true,"hosts":[{"ip":"ip","domain":"domain","description":"description","uuid":"uuid"}]},"authConfig":{"username":"username","password":"password","verification":null,"sslConfig":{"entry":[{"id":"id","originalAsName":null,"newAsName":null,"type":null,"password":"alias","sourceName":"sourceName","sourceId":"sourceId","isDefault":true,"default":true}],"files":[{"id":"id","name":"name","type":"type","updateTime":"updateTime","password":"password","file":null}],"defaultAlias":null}},"preScript":{"apiPreScript":null,"uiPreScript":null},"postScript":{"apiPostScript":null,"uiPostScript":null},"assertions":{"assertions":null}},"mock":null,"description":null},{"id":"1093344054747142","projectId":"100001100001","name":"authConfig","config":{"commonParams":{"requestTimeout":6000,"responseTimeout":6000},"commonVariables":[{"id":null,"name":"key0","type":"CONSTANT","value":"value0","enable":true,"description":"description0","tags":null}],"httpConfig":[{"url":"http://www.baidu.com","apiTest":true,"uiTest":false,"type":"NONE","details":null,"moduleIds":null,"headers":[{"key":"key","value":"value","enable":true,"description":null,"valid":true}],"browser":null,"description":null}],"dataSources":[{"id":"1","dataSource":"mysql","driver":"com.mysql.cj.jdbc.Driver","driverId":null,"dbUrl":"jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai","username":"root","password":"123456","poolMax":10,"timeout":1000}],"hostConfig":{"enable":true,"hosts":[{"ip":"ip","domain":"domain","description":"description","uuid":"uuid"}]},"authConfig":{"username":"username","password":"password","verification":null,"sslConfig":null},"preScript":{"apiPreScript":null,"uiPreScript":null},"postScript":{"apiPostScript":null,"uiPostScript":null},"assertions":{"assertions":null}},"mock":null,"description":null},{"id":"1093344054747141","projectId":"100001100001","name":"hostConfig","config":{"commonParams":{"requestTimeout":6000,"responseTimeout":6000},"commonVariables":[{"id":null,"name":"key0","type":"CONSTANT","value":"value0","enable":true,"description":"description0","tags":null}],"httpConfig":[{"url":"http://www.baidu.com","apiTest":true,"uiTest":false,"type":"NONE","details":null,"moduleIds":null,"headers":[{"key":"key","value":"value","enable":true,"description":null,"valid":true}],"browser":null,"description":null}],"dataSources":[{"id":"1","dataSource":"mysql","driver":"com.mysql.cj.jdbc.Driver","driverId":null,"dbUrl":"jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai","username":"root","password":"123456","poolMax":10,"timeout":1000}],"hostConfig":{"enable":true,"hosts":[{"ip":"ip","domain":"domain","description":"description","uuid":"uuid"}]},"authConfig":{"username":null,"password":null,"verification":null,"sslConfig":null},"preScript":{"apiPreScript":null,"uiPreScript":null},"postScript":{"apiPostScript":null,"uiPostScript":null},"assertions":{"assertions":null}},"mock":null,"description":null},{"id":"1093344054747140","projectId":"100001100001","name":"dataSources","config":{"commonParams":{"requestTimeout":6000,"responseTimeout":6000},"commonVariables":[{"id":null,"name":"key0","type":"CONSTANT","value":"value0","enable":true,"description":"description0","tags":null}],"httpConfig":[{"url":"http://www.baidu.com","apiTest":true,"uiTest":false,"type":"NONE","details":null,"moduleIds":null,"headers":[{"key":"key","value":"value","enable":true,"description":null,"valid":true}],"browser":null,"description":null}],"dataSources":[{"id":"1","dataSource":"mysql","driver":"com.mysql.cj.jdbc.Driver","driverId":null,"dbUrl":"jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai","username":"root","password":"123456","poolMax":10,"timeout":1000}],"hostConfig":{"enable":null,"hosts":null},"authConfig":{"username":null,"password":null,"verification":null,"sslConfig":null},"preScript":{"apiPreScript":null,"uiPreScript":null},"postScript":{"apiPostScript":null,"uiPostScript":null},"assertions":{"assertions":null}},"mock":null,"description":null},{"id":"1093344054747139","projectId":"100001100001","name":"httpConfig","config":{"commonParams":{"requestTimeout":6000,"responseTimeout":6000},"commonVariables":[{"id":null,"name":"key0","type":"CONSTANT","value":"value0","enable":true,"description":"description0","tags":null}],"httpConfig":[{"url":"http://www.baidu.com","apiTest":true,"uiTest":false,"type":"NONE","details":null,"moduleIds":null,"headers":[{"key":"key","value":"value","enable":true,"description":null,"valid":true}],"browser":null,"description":null}],"dataSources":[{"id":null,"dataSource":null,"driver":null,"driverId":null,"dbUrl":null,"username":null,"password":null,"poolMax":null,"timeout":null}],"hostConfig":{"enable":null,"hosts":null},"authConfig":{"username":null,"password":null,"verification":null,"sslConfig":null},"preScript":{"apiPreScript":null,"uiPreScript":null},"postScript":{"apiPostScript":null,"uiPostScript":null},"assertions":{"assertions":null}},"mock":null,"description":null},{"id":"1093344054747138","projectId":"100001100001","name":"commonVariables","config":{"commonParams":{"requestTimeout":6000,"responseTimeout":6000},"commonVariables":[{"id":null,"name":"key0","type":"CONSTANT","value":"value0","enable":true,"description":"description0","tags":null}],"httpConfig":[{"url":null,"apiTest":true,"uiTest":false,"type":"NONE","details":null,"moduleIds":null,"headers":[{"key":null,"value":null,"enable":true,"description":null,"valid":false}],"browser":null,"description":null}],"dataSources":[{"id":null,"dataSource":null,"driver":null,"driverId":null,"dbUrl":null,"username":null,"password":null,"poolMax":null,"timeout":null}],"hostConfig":{"enable":null,"hosts":null},"authConfig":{"username":null,"password":null,"verification":null,"sslConfig":null},"preScript":{"apiPreScript":null,"uiPreScript":null},"postScript":{"apiPostScript":null,"uiPostScript":null},"assertions":{"assertions":null}},"mock":null,"description":null},{"id":"100663626829922680","projectId":"100001100001","name":"Mock环境","config":null,"mock":null,"description":null}] \ No newline at end of file