mirror of
https://gitee.com/fit2cloud-feizhiyun/MeterSphere.git
synced 2024-12-02 20:19:16 +08:00
feat(接口测试): 场景执行接口
This commit is contained in:
parent
31562ac774
commit
26f9f6726e
@ -283,7 +283,7 @@ CREATE TABLE IF NOT EXISTS api_scenario_step(
|
|||||||
`project_id` VARCHAR(50) COMMENT '项目fk' ,
|
`project_id` VARCHAR(50) COMMENT '项目fk' ,
|
||||||
`parent_id` VARCHAR(50) DEFAULT 'NONE' COMMENT '父级fk' ,
|
`parent_id` VARCHAR(50) DEFAULT 'NONE' COMMENT '父级fk' ,
|
||||||
`version_id` VARCHAR(50) COMMENT '版本号' ,
|
`version_id` VARCHAR(50) COMMENT '版本号' ,
|
||||||
`ref_type` VARCHAR(10) COMMENT '引用/复制/自定义' ,
|
`ref_type` VARCHAR(20) COMMENT '引用/复制/自定义' ,
|
||||||
`config` VARCHAR(500) COMMENT '循环等组件基础数据' ,
|
`config` VARCHAR(500) COMMENT '循环等组件基础数据' ,
|
||||||
PRIMARY KEY (id)
|
PRIMARY KEY (id)
|
||||||
) ENGINE = InnoDB
|
) ENGINE = InnoDB
|
||||||
|
@ -11,13 +11,13 @@ public enum ApiScenarioStepRefType {
|
|||||||
*/
|
*/
|
||||||
DIRECT,
|
DIRECT,
|
||||||
/**
|
/**
|
||||||
* 引用
|
* 完全引用
|
||||||
*/
|
*/
|
||||||
REF,
|
REF,
|
||||||
/**
|
/**
|
||||||
* 步骤引用
|
* 部分引用
|
||||||
*/
|
*/
|
||||||
STEP_REF,
|
PARTIAL_REF,
|
||||||
/**
|
/**
|
||||||
* 复制
|
* 复制
|
||||||
*/
|
*/
|
||||||
|
@ -70,7 +70,7 @@ public class ApiScenarioController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
@Operation(summary = "创建场景")
|
@Operation(summary = "接口测试-接口场景管理-创建场景")
|
||||||
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_ADD)
|
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_ADD)
|
||||||
@Log(type = OperationLogType.ADD, expression = "#msClass.addLog(#request)", msClass = ApiScenarioLogService.class)
|
@Log(type = OperationLogType.ADD, expression = "#msClass.addLog(#request)", msClass = ApiScenarioLogService.class)
|
||||||
public ApiScenario add(@Validated @RequestBody ApiScenarioAddRequest request) {
|
public ApiScenario add(@Validated @RequestBody ApiScenarioAddRequest request) {
|
||||||
@ -78,14 +78,14 @@ public class ApiScenarioController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/upload/temp/file")
|
@PostMapping("/upload/temp/file")
|
||||||
@Operation(summary = "上传场景所需的文件资源,并返回文件ID")
|
@Operation(summary = "接口测试-接口场景管理-上传场景所需的文件资源,并返回文件ID")
|
||||||
@RequiresPermissions(logical = Logical.OR, value = {PermissionConstants.PROJECT_API_SCENARIO_ADD, PermissionConstants.PROJECT_API_SCENARIO_UPDATE})
|
@RequiresPermissions(logical = Logical.OR, value = {PermissionConstants.PROJECT_API_SCENARIO_ADD, PermissionConstants.PROJECT_API_SCENARIO_UPDATE})
|
||||||
public String uploadTempFile(@RequestParam("file") MultipartFile file) {
|
public String uploadTempFile(@RequestParam("file") MultipartFile file) {
|
||||||
return apiScenarioService.uploadTempFile(file);
|
return apiScenarioService.uploadTempFile(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/update")
|
@PostMapping("/update")
|
||||||
@Operation(summary = "更新场景")
|
@Operation(summary = "接口测试-接口场景管理-更新场景")
|
||||||
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_UPDATE)
|
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_UPDATE)
|
||||||
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateLog(#request)", msClass = ApiScenarioLogService.class)
|
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateLog(#request)", msClass = ApiScenarioLogService.class)
|
||||||
public ApiScenario update(@Validated @RequestBody ApiScenarioUpdateRequest request) {
|
public ApiScenario update(@Validated @RequestBody ApiScenarioUpdateRequest request) {
|
||||||
@ -93,7 +93,7 @@ public class ApiScenarioController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/delete/{id}")
|
@GetMapping("/delete/{id}")
|
||||||
@Operation(summary = "删除场景")
|
@Operation(summary = "接口测试-接口场景管理-删除场景")
|
||||||
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_DELETE)
|
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_DELETE)
|
||||||
@Log(type = OperationLogType.DELETE, expression = "#msClass.deleteLog(#id)", msClass = ApiScenarioLogService.class)
|
@Log(type = OperationLogType.DELETE, expression = "#msClass.deleteLog(#id)", msClass = ApiScenarioLogService.class)
|
||||||
public void delete(@PathVariable String id) {
|
public void delete(@PathVariable String id) {
|
||||||
@ -101,10 +101,17 @@ public class ApiScenarioController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/delete-to-gc/{id}")
|
@GetMapping("/delete-to-gc/{id}")
|
||||||
@Operation(summary = "删除场景到回收站")
|
@Operation(summary = "接口测试-接口场景管理-删除场景到回收站")
|
||||||
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_DELETE)
|
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_DELETE)
|
||||||
@Log(type = OperationLogType.DELETE, expression = "#msClass.deleteLog(#id)", msClass = ApiScenarioLogService.class)
|
@Log(type = OperationLogType.DELETE, expression = "#msClass.deleteLog(#id)", msClass = ApiScenarioLogService.class)
|
||||||
public void deleteToGc(@PathVariable String id) {
|
public void deleteToGc(@PathVariable String id) {
|
||||||
apiScenarioService.deleteToGc(id);
|
apiScenarioService.deleteToGc(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/debug")
|
||||||
|
@Operation(summary = "接口测试-接口场景管理-场景调试")
|
||||||
|
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_EXECUTE)
|
||||||
|
public String debug(@RequestBody ApiScenarioDebugRequest request) {
|
||||||
|
return apiScenarioService.debug(request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,5 +18,5 @@ public class ApiDebugRunRequest {
|
|||||||
private List<String> tempFileIds;
|
private List<String> tempFileIds;
|
||||||
@NotNull
|
@NotNull
|
||||||
@Schema(description = "请求内容")
|
@Schema(description = "请求内容")
|
||||||
private String request;
|
private Object request;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package io.metersphere.api.dto.debug;
|
package io.metersphere.api.dto.debug;
|
||||||
|
|
||||||
|
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -20,7 +21,11 @@ public class ApiResourceRunRequest {
|
|||||||
*/
|
*/
|
||||||
private String reportId;
|
private String reportId;
|
||||||
/**
|
/**
|
||||||
* 环境ID
|
* 是否为环境组
|
||||||
|
*/
|
||||||
|
private Boolean grouped = false;
|
||||||
|
/**
|
||||||
|
* 环境或者环境组ID
|
||||||
*/
|
*/
|
||||||
private String environmentId;
|
private String environmentId;
|
||||||
/**
|
/**
|
||||||
@ -33,9 +38,9 @@ public class ApiResourceRunRequest {
|
|||||||
*/
|
*/
|
||||||
private String resourceType;
|
private String resourceType;
|
||||||
/**
|
/**
|
||||||
* 请求内容
|
* 执行组件
|
||||||
*/
|
*/
|
||||||
private String request;
|
private AbstractMsTestElement testElement;
|
||||||
/**
|
/**
|
||||||
* 点击调试时尚未保存的文件列表
|
* 点击调试时尚未保存的文件列表
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package io.metersphere.api.dto.request;
|
package io.metersphere.api.dto.request;
|
||||||
|
|
||||||
|
import io.metersphere.api.dto.scenario.ScenarioConfig;
|
||||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@ -7,4 +8,5 @@ import lombok.EqualsAndHashCode;
|
|||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class MsScenario extends AbstractMsTestElement {
|
public class MsScenario extends AbstractMsTestElement {
|
||||||
|
private ScenarioConfig scenarioConfig;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
package io.metersphere.api.dto.scenario;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-10 11:24
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ApiScenarioDebugRequest {
|
||||||
|
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_scenario.id.not_blank}")
|
||||||
|
@Size(max = 50, message = "{api_scenario.id.length_range}")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "是否为环境组")
|
||||||
|
private Boolean grouped = false;
|
||||||
|
|
||||||
|
@Schema(description = "环境或者环境组ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank
|
||||||
|
private String environmentId;
|
||||||
|
|
||||||
|
@Schema(description = "场景的通用配置")
|
||||||
|
private ScenarioConfig scenarioConfig;
|
||||||
|
|
||||||
|
@Schema(description = "步骤集合")
|
||||||
|
private List<ApiScenarioStepRequest> steps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 步骤详情
|
||||||
|
* key 为步骤ID
|
||||||
|
* 值 为详情
|
||||||
|
*/
|
||||||
|
@Schema(description = "步骤详情")
|
||||||
|
private Map<String, Object> stepDetails;
|
||||||
|
|
||||||
|
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank
|
||||||
|
private String projectId;
|
||||||
|
@Schema(description = "点击调试时尚未保存的文件ID列表")
|
||||||
|
private List<String> tempFileIds;
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package io.metersphere.api.dto.scenario;
|
||||||
|
|
||||||
|
import io.metersphere.api.domain.ApiScenario;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class ApiScenarioDetail extends ApiScenario {
|
||||||
|
@Schema(description = "场景的通用配置")
|
||||||
|
private ScenarioConfig scenarioConfig;
|
||||||
|
}
|
@ -50,7 +50,8 @@ public class ApiScenarioStepRequest {
|
|||||||
/**
|
/**
|
||||||
* 引用模式:默认完全引用
|
* 引用模式:默认完全引用
|
||||||
* - 完全引用:步骤状态不可调整
|
* - 完全引用:步骤状态不可调整
|
||||||
* - 步骤引用:步骤状态可调整
|
* - 部分引用:步骤状态可调整
|
||||||
|
* @see io.metersphere.api.constants.ApiScenarioStepRefType
|
||||||
*/
|
*/
|
||||||
@Schema(description = "引用/复制/自定义")
|
@Schema(description = "引用/复制/自定义")
|
||||||
private String refType;
|
private String refType;
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package io.metersphere.api.dto.scenario;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-22 15:17
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class PartialRefStepDetail {
|
||||||
|
/**
|
||||||
|
* 记录子步骤中启用的步骤ID
|
||||||
|
* 不包含,部分引用的子步骤
|
||||||
|
* 部分引用的子步骤也会自行保存子步骤的启用状态
|
||||||
|
*/
|
||||||
|
private Set<String> enableStepIds;
|
||||||
|
// 预留保存其他信息
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package io.metersphere.api.parser.step;
|
||||||
|
|
||||||
|
import io.metersphere.api.dto.scenario.ApiScenarioStepRequest;
|
||||||
|
import io.metersphere.api.utils.ApiDataUtils;
|
||||||
|
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-20 15:43
|
||||||
|
*/
|
||||||
|
public class ApiCaseStepParser extends StepParser {
|
||||||
|
@Override
|
||||||
|
public AbstractMsTestElement parse(ApiScenarioStepRequest step, String resourceBlob, String stepDetail) {
|
||||||
|
if (isRef(step.getRefType())) {
|
||||||
|
return StringUtils.isBlank(resourceBlob) ? null : parse2MsTestElement(resourceBlob);
|
||||||
|
} else {
|
||||||
|
if (StringUtils.isBlank(stepDetail)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return StringUtils.isBlank(stepDetail) ? null : ApiDataUtils.parseObject(stepDetail, AbstractMsTestElement.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package io.metersphere.api.parser.step;
|
||||||
|
|
||||||
|
import io.metersphere.api.dto.request.MsScenario;
|
||||||
|
import io.metersphere.api.dto.scenario.ApiScenarioStepRequest;
|
||||||
|
import io.metersphere.api.dto.scenario.ScenarioConfig;
|
||||||
|
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||||
|
import io.metersphere.sdk.util.JSON;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-20 15:43
|
||||||
|
*/
|
||||||
|
public class ApiScenarioStepParser extends StepParser {
|
||||||
|
@Override
|
||||||
|
public AbstractMsTestElement parse(ApiScenarioStepRequest step, String resourceBlob, String stepDetail) {
|
||||||
|
MsScenario msScenario = new MsScenario();
|
||||||
|
if (isRef(step.getRefType())) {
|
||||||
|
if (StringUtils.isNotBlank(resourceBlob)) {
|
||||||
|
msScenario.setScenarioConfig(JSON.parseObject(resourceBlob, ScenarioConfig.class));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (StringUtils.isNotBlank(stepDetail)) {
|
||||||
|
msScenario.setScenarioConfig(JSON.parseObject(stepDetail, ScenarioConfig.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return msScenario;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
package io.metersphere.api.parser.step;
|
||||||
|
|
||||||
|
import io.metersphere.api.dto.request.http.KeyValueParam;
|
||||||
|
import io.metersphere.api.dto.request.http.MsHTTPElement;
|
||||||
|
import io.metersphere.api.dto.request.http.body.Body;
|
||||||
|
import io.metersphere.api.dto.scenario.ApiScenarioStepRequest;
|
||||||
|
import io.metersphere.api.utils.ApiDataUtils;
|
||||||
|
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-20 15:43
|
||||||
|
*/
|
||||||
|
public class ApiStepParser extends StepParser {
|
||||||
|
@Override
|
||||||
|
public AbstractMsTestElement parse(ApiScenarioStepRequest step, String resourceBlob, String stepDetail) {
|
||||||
|
if (isRef(step.getRefType())) {
|
||||||
|
if (StringUtils.isBlank(resourceBlob)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
AbstractMsTestElement refResourceElement = parse2MsTestElement(resourceBlob);
|
||||||
|
if (refResourceElement instanceof MsHTTPElement && StringUtils.isNotBlank(stepDetail)) {
|
||||||
|
// 如果是 http 并且有修改请求参数,则替换请求参数
|
||||||
|
AbstractMsTestElement msTestElement = ApiDataUtils.parseObject(stepDetail, AbstractMsTestElement.class);
|
||||||
|
return replaceParams((MsHTTPElement) msTestElement, (MsHTTPElement) refResourceElement);
|
||||||
|
} else {
|
||||||
|
return refResourceElement;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return StringUtils.isBlank(stepDetail) ? null : ApiDataUtils.parseObject(stepDetail, AbstractMsTestElement.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private AbstractMsTestElement replaceParams(MsHTTPElement msTestElement, MsHTTPElement refResourceElement) {
|
||||||
|
replaceKvParam(msTestElement.getHeaders(), refResourceElement.getHeaders());
|
||||||
|
replaceKvParam(msTestElement.getQuery(), refResourceElement.getQuery());
|
||||||
|
replaceKvParam(msTestElement.getRest(), refResourceElement.getRest());
|
||||||
|
replaceBodyParams(msTestElement.getBody(), refResourceElement.getBody());
|
||||||
|
return refResourceElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换请求体中的参数
|
||||||
|
*
|
||||||
|
* @param valueBody
|
||||||
|
* @param refBody
|
||||||
|
*/
|
||||||
|
private void replaceBodyParams(Body valueBody, Body refBody) {
|
||||||
|
if (refBody == null || valueBody == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (StringUtils.equals(refBody.getBodyType(), Body.BodyType.FORM_DATA.name()) &&
|
||||||
|
valueBody.getFormDataBody() != null && refBody.getFormDataBody() != null) {
|
||||||
|
replaceKvParam(valueBody.getFormDataBody().getFromValues(), valueBody.getFormDataBody().getFromValues());
|
||||||
|
}
|
||||||
|
if (StringUtils.equals(refBody.getBodyType(), Body.BodyType.WWW_FORM.name()) &&
|
||||||
|
valueBody.getWwwFormBody() != null && refBody.getWwwFormBody() != null) {
|
||||||
|
replaceKvParam(valueBody.getWwwFormBody().getFromValues(), valueBody.getWwwFormBody().getFromValues());
|
||||||
|
}
|
||||||
|
// todo JsonSchema body
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换参数
|
||||||
|
*
|
||||||
|
* @param valueList
|
||||||
|
* @param refList
|
||||||
|
*/
|
||||||
|
private void replaceKvParam(List valueList, List refList) {
|
||||||
|
if (CollectionUtils.isEmpty(refList) || CollectionUtils.isEmpty(valueList)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
refList.forEach(item -> {
|
||||||
|
KeyValueParam keyValueParam = (KeyValueParam) item;
|
||||||
|
for (Object valueItem : valueList) {
|
||||||
|
KeyValueParam valueParam = (KeyValueParam) valueItem;
|
||||||
|
if (StringUtils.equals(keyValueParam.getKey(), valueParam.getKey())) {
|
||||||
|
keyValueParam.setValue(valueParam.getValue());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package io.metersphere.api.parser.step;
|
||||||
|
|
||||||
|
import io.metersphere.api.constants.ApiScenarioStepRefType;
|
||||||
|
import io.metersphere.api.dto.scenario.ApiScenarioStepRequest;
|
||||||
|
import io.metersphere.api.utils.ApiDataUtils;
|
||||||
|
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-20 15:43
|
||||||
|
*/
|
||||||
|
public abstract class StepParser {
|
||||||
|
|
||||||
|
public abstract AbstractMsTestElement parse(ApiScenarioStepRequest step, String resourceBlob, String stepDetail);
|
||||||
|
|
||||||
|
protected boolean isRef(String refType) {
|
||||||
|
return StringUtils.equalsAny(refType, ApiScenarioStepRefType.REF.name(), ApiScenarioStepRefType.PARTIAL_REF.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static AbstractMsTestElement parse2MsTestElement(String blobContent) {
|
||||||
|
return ApiDataUtils.parseObject(blobContent, AbstractMsTestElement.class);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package io.metersphere.api.parser.step;
|
||||||
|
|
||||||
|
import io.metersphere.api.constants.ApiScenarioStepType;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-20 15:43
|
||||||
|
*/
|
||||||
|
public abstract class StepParserFactory {
|
||||||
|
|
||||||
|
private static Map<String, StepParser> stepParserMap = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
stepParserMap.put(ApiScenarioStepType.API.name(), new ApiStepParser());
|
||||||
|
stepParserMap.put(ApiScenarioStepType.API_CASE.name(), new ApiCaseStepParser());
|
||||||
|
stepParserMap.put(ApiScenarioStepType.API_SCENARIO.name(), new ApiScenarioStepParser());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StepParser getStepParser(String stepType) {
|
||||||
|
return stepParserMap.get(stepType);
|
||||||
|
}
|
||||||
|
}
|
@ -131,7 +131,7 @@ public class ApiExecuteService {
|
|||||||
// todo 接口用例 method 获取定义中的数据库字段
|
// todo 接口用例 method 获取定义中的数据库字段
|
||||||
ParameterConfig parameterConfig = new ParameterConfig();
|
ParameterConfig parameterConfig = new ParameterConfig();
|
||||||
parameterConfig.setReportId(reportId);
|
parameterConfig.setReportId(reportId);
|
||||||
String executeScript = parseExecuteScript(request.getRequest(), parameterConfig);
|
String executeScript = parseExecuteScript(request.getTestElement(), parameterConfig);
|
||||||
|
|
||||||
TestResourceNodeDTO testResourceNodeDTO = getProjectExecuteNode(request.getProjectId());
|
TestResourceNodeDTO testResourceNodeDTO = getProjectExecuteNode(request.getProjectId());
|
||||||
|
|
||||||
@ -306,15 +306,10 @@ public class ApiExecuteService {
|
|||||||
/**
|
/**
|
||||||
* 生成执行脚本
|
* 生成执行脚本
|
||||||
*
|
*
|
||||||
* @param testElementStr
|
* @param msTestElement
|
||||||
* @param config
|
* @param config
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private static String parseExecuteScript(String testElementStr, ParameterConfig config) {
|
|
||||||
// 解析生成脚本
|
|
||||||
return parseExecuteScript(ApiDataUtils.parseObject(testElementStr, AbstractMsTestElement.class), config);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String parseExecuteScript(AbstractMsTestElement msTestElement, ParameterConfig config) {
|
private static String parseExecuteScript(AbstractMsTestElement msTestElement, ParameterConfig config) {
|
||||||
// 解析生成脚本
|
// 解析生成脚本
|
||||||
TestElementParser defaultParser = TestElementParserFactory.getDefaultParser();
|
TestElementParser defaultParser = TestElementParserFactory.getDefaultParser();
|
||||||
|
@ -18,6 +18,7 @@ import io.metersphere.sdk.constants.DefaultRepositoryDir;
|
|||||||
import io.metersphere.sdk.exception.MSException;
|
import io.metersphere.sdk.exception.MSException;
|
||||||
import io.metersphere.sdk.util.BeanUtils;
|
import io.metersphere.sdk.util.BeanUtils;
|
||||||
import io.metersphere.sdk.util.FileAssociationSourceUtil;
|
import io.metersphere.sdk.util.FileAssociationSourceUtil;
|
||||||
|
import io.metersphere.sdk.util.JSON;
|
||||||
import io.metersphere.system.log.constants.OperationLogModule;
|
import io.metersphere.system.log.constants.OperationLogModule;
|
||||||
import io.metersphere.system.uid.IDGenerator;
|
import io.metersphere.system.uid.IDGenerator;
|
||||||
import io.metersphere.system.utils.ServiceUtils;
|
import io.metersphere.system.utils.ServiceUtils;
|
||||||
@ -187,6 +188,8 @@ public class ApiDebugService {
|
|||||||
runRequest.setReportId(id);
|
runRequest.setReportId(id);
|
||||||
runRequest.setResourceType(ApiResourceType.API_DEBUG.name());
|
runRequest.setResourceType(ApiResourceType.API_DEBUG.name());
|
||||||
runRequest.setRunMode(ApiExecuteRunMode.BACKEND_DEBUG.name());
|
runRequest.setRunMode(ApiExecuteRunMode.BACKEND_DEBUG.name());
|
||||||
|
runRequest.setEnvironmentId(request.getEnvironmentId());
|
||||||
|
runRequest.setTestElement(ApiDataUtils.parseObject(JSON.toJSONString(request.getRequest()), AbstractMsTestElement.class));
|
||||||
|
|
||||||
apiExecuteService.debug(runRequest);
|
apiExecuteService.debug(runRequest);
|
||||||
|
|
||||||
|
@ -1011,4 +1011,13 @@ public class ApiDefinitionService {
|
|||||||
// 记录操作日志
|
// 记录操作日志
|
||||||
return apiDefinitionLogService.recoverOperationHistoryLog(apiDefinitionDTO, apiDefinition.getCreateUser(), apiDefinition.getProjectId());
|
return apiDefinitionLogService.recoverOperationHistoryLog(apiDefinitionDTO, apiDefinition.getCreateUser(), apiDefinition.getProjectId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<ApiDefinitionBlob> getBlobByIds(List<String> apiIds) {
|
||||||
|
if (CollectionUtils.isEmpty(apiIds)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
ApiDefinitionBlobExample apiDefinitionBlobExample = new ApiDefinitionBlobExample();
|
||||||
|
apiDefinitionBlobExample.createCriteria().andIdIn(apiIds);
|
||||||
|
return apiDefinitionBlobMapper.selectByExampleWithBLOBs(apiDefinitionBlobExample);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@ -529,4 +530,13 @@ public class ApiTestCaseService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<ApiTestCaseBlob> getBlobByIds(List<String> apiCaseIds) {
|
||||||
|
if (CollectionUtils.isEmpty(apiCaseIds)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
ApiTestCaseBlobExample example = new ApiTestCaseBlobExample();
|
||||||
|
example.createCriteria().andIdIn(apiCaseIds);
|
||||||
|
return apiTestCaseBlobMapper.selectByExampleWithBLOBs(example);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,20 @@ import io.metersphere.api.constants.ApiScenarioStepRefType;
|
|||||||
import io.metersphere.api.constants.ApiScenarioStepType;
|
import io.metersphere.api.constants.ApiScenarioStepType;
|
||||||
import io.metersphere.api.domain.*;
|
import io.metersphere.api.domain.*;
|
||||||
import io.metersphere.api.dto.debug.ApiFileResourceUpdateRequest;
|
import io.metersphere.api.dto.debug.ApiFileResourceUpdateRequest;
|
||||||
|
import io.metersphere.api.dto.debug.ApiResourceRunRequest;
|
||||||
|
import io.metersphere.api.dto.request.MsScenario;
|
||||||
import io.metersphere.api.dto.scenario.*;
|
import io.metersphere.api.dto.scenario.*;
|
||||||
import io.metersphere.api.mapper.*;
|
import io.metersphere.api.mapper.*;
|
||||||
|
import io.metersphere.api.parser.step.StepParser;
|
||||||
|
import io.metersphere.api.parser.step.StepParserFactory;
|
||||||
|
import io.metersphere.api.service.ApiExecuteService;
|
||||||
import io.metersphere.api.service.ApiFileResourceService;
|
import io.metersphere.api.service.ApiFileResourceService;
|
||||||
|
import io.metersphere.api.service.definition.ApiDefinitionService;
|
||||||
|
import io.metersphere.api.service.definition.ApiTestCaseService;
|
||||||
|
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||||
import io.metersphere.project.mapper.ExtBaseProjectVersionMapper;
|
import io.metersphere.project.mapper.ExtBaseProjectVersionMapper;
|
||||||
import io.metersphere.project.service.ProjectService;
|
import io.metersphere.project.service.ProjectService;
|
||||||
|
import io.metersphere.sdk.constants.ApiExecuteRunMode;
|
||||||
import io.metersphere.sdk.constants.ApplicationNumScope;
|
import io.metersphere.sdk.constants.ApplicationNumScope;
|
||||||
import io.metersphere.sdk.constants.DefaultRepositoryDir;
|
import io.metersphere.sdk.constants.DefaultRepositoryDir;
|
||||||
import io.metersphere.sdk.domain.Environment;
|
import io.metersphere.sdk.domain.Environment;
|
||||||
@ -45,6 +54,7 @@ import java.util.stream.Collectors;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static io.metersphere.api.controller.result.ApiResultCode.API_SCENARIO_EXIST;
|
import static io.metersphere.api.controller.result.ApiResultCode.API_SCENARIO_EXIST;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public class ApiScenarioService {
|
public class ApiScenarioService {
|
||||||
@ -84,6 +94,12 @@ public class ApiScenarioService {
|
|||||||
private ApiScenarioStepBlobMapper apiScenarioStepBlobMapper;
|
private ApiScenarioStepBlobMapper apiScenarioStepBlobMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiScenarioBlobMapper apiScenarioBlobMapper;
|
private ApiScenarioBlobMapper apiScenarioBlobMapper;
|
||||||
|
@Resource
|
||||||
|
private ApiExecuteService apiExecuteService;
|
||||||
|
@Resource
|
||||||
|
private ApiDefinitionService apiDefinitionService;
|
||||||
|
@Resource
|
||||||
|
private ApiTestCaseService apiTestCaseService;
|
||||||
public static final String PRIORITY = "Priority";
|
public static final String PRIORITY = "Priority";
|
||||||
public static final String STATUS = "Status";
|
public static final String STATUS = "Status";
|
||||||
public static final String TAGS = "Tags";
|
public static final String TAGS = "Tags";
|
||||||
@ -284,13 +300,16 @@ public class ApiScenarioService {
|
|||||||
|
|
||||||
// 插入步骤
|
// 插入步骤
|
||||||
if (CollectionUtils.isNotEmpty(request.getSteps())) {
|
if (CollectionUtils.isNotEmpty(request.getSteps())) {
|
||||||
List<ApiScenarioStepBlob> apiScenarioStepsDetails = new ArrayList<>();
|
// 获取待添加的步骤
|
||||||
List<ApiScenarioStep> apiScenarioSteps = getUpdateApiScenarioSteps(null, request.getSteps(), apiScenarioStepsDetails);
|
List<ApiScenarioStep> steps = getApiScenarioSteps(null, request.getSteps());
|
||||||
apiScenarioStepsDetails.addAll(getUpdateStepDetails(apiScenarioSteps, request.getStepDetails()));
|
steps.forEach(step -> step.setScenarioId(scenario.getId()));
|
||||||
apiScenarioSteps.forEach(step -> step.setScenarioId(scenario.getId()));
|
// 获取待添加的步骤详情
|
||||||
|
List<ApiScenarioStepBlob> apiScenarioStepsDetails = getPartialRefStepDetails(request.getSteps());
|
||||||
|
apiScenarioStepsDetails.addAll(getUpdateStepDetails(steps, request.getStepDetails()));
|
||||||
apiScenarioStepsDetails.forEach(step -> step.setScenarioId(scenario.getId()));
|
apiScenarioStepsDetails.forEach(step -> step.setScenarioId(scenario.getId()));
|
||||||
if (CollectionUtils.isNotEmpty(apiScenarioSteps)) {
|
|
||||||
apiScenarioStepMapper.batchInsert(apiScenarioSteps);
|
if (CollectionUtils.isNotEmpty(steps)) {
|
||||||
|
apiScenarioStepMapper.batchInsert(steps);
|
||||||
}
|
}
|
||||||
if (CollectionUtils.isNotEmpty(apiScenarioStepsDetails)) {
|
if (CollectionUtils.isNotEmpty(apiScenarioStepsDetails)) {
|
||||||
apiScenarioStepBlobMapper.batchInsert(apiScenarioStepsDetails);
|
apiScenarioStepBlobMapper.batchInsert(apiScenarioStepsDetails);
|
||||||
@ -359,6 +378,7 @@ public class ApiScenarioService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新场景步骤
|
* 更新场景步骤
|
||||||
|
*
|
||||||
* @param request
|
* @param request
|
||||||
* @param scenario
|
* @param scenario
|
||||||
*/
|
*/
|
||||||
@ -372,10 +392,13 @@ public class ApiScenarioService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ApiScenarioStepBlob> apiScenarioStepsDetails = new ArrayList<>();
|
// 获取待更新的步骤
|
||||||
List<ApiScenarioStep> apiScenarioSteps = getUpdateApiScenarioSteps(null, request.getSteps(), apiScenarioStepsDetails);
|
List<ApiScenarioStep> apiScenarioSteps = getApiScenarioSteps(null, request.getSteps());
|
||||||
apiScenarioStepsDetails.addAll(getUpdateStepDetails(apiScenarioSteps, request.getStepDetails()));
|
|
||||||
apiScenarioSteps.forEach(step -> step.setScenarioId(scenario.getId()));
|
apiScenarioSteps.forEach(step -> step.setScenarioId(scenario.getId()));
|
||||||
|
|
||||||
|
// 获取待更新的步骤详情
|
||||||
|
List<ApiScenarioStepBlob> apiScenarioStepsDetails = getPartialRefStepDetails(request.getSteps());
|
||||||
|
apiScenarioStepsDetails.addAll(getUpdateStepDetails(apiScenarioSteps, request.getStepDetails()));
|
||||||
apiScenarioStepsDetails.forEach(step -> step.setScenarioId(scenario.getId()));
|
apiScenarioStepsDetails.forEach(step -> step.setScenarioId(scenario.getId()));
|
||||||
|
|
||||||
List<String> stepIds = apiScenarioSteps.stream().map(ApiScenarioStep::getId).collect(Collectors.toList());
|
List<String> stepIds = apiScenarioSteps.stream().map(ApiScenarioStep::getId).collect(Collectors.toList());
|
||||||
@ -439,6 +462,7 @@ public class ApiScenarioService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取待更新的 ApiScenarioStepBlob 列表
|
* 获取待更新的 ApiScenarioStepBlob 列表
|
||||||
|
*
|
||||||
* @param apiScenarioSteps
|
* @param apiScenarioSteps
|
||||||
* @param stepDetails
|
* @param stepDetails
|
||||||
* @return
|
* @return
|
||||||
@ -457,8 +481,7 @@ public class ApiScenarioService {
|
|||||||
if (step == null) {
|
if (step == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean isRef = StringUtils.equalsAny(step.getRefType(), ApiScenarioStepRefType.REF.name(), ApiScenarioStepRefType.STEP_REF.name());
|
if (!isRef(step.getRefType()) || StringUtils.equals(step.getRefType(), ApiScenarioStepType.API.name())) {
|
||||||
if (!isRef || StringUtils.equals(step.getRefType(), ApiScenarioStepType.API.name())) {
|
|
||||||
// 非引用的步骤,如果有编辑内容,保存到blob表
|
// 非引用的步骤,如果有编辑内容,保存到blob表
|
||||||
// 如果引用的是接口定义,也保存详情,因为应用接口定义允许修改参数值
|
// 如果引用的是接口定义,也保存详情,因为应用接口定义允许修改参数值
|
||||||
ApiScenarioStepBlob apiScenarioStepBlob = new ApiScenarioStepBlob();
|
ApiScenarioStepBlob apiScenarioStepBlob = new ApiScenarioStepBlob();
|
||||||
@ -470,17 +493,20 @@ public class ApiScenarioService {
|
|||||||
return apiScenarioStepsDetails;
|
return apiScenarioStepsDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isRef(String refType) {
|
||||||
|
return StringUtils.equalsAny(refType, ApiScenarioStepRefType.REF.name(), ApiScenarioStepRefType.PARTIAL_REF.name());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析步骤树结构
|
* 解析步骤树结构
|
||||||
* 获取待更新的 ApiScenarioStep 列表
|
* 获取待更新的 ApiScenarioStep 列表
|
||||||
|
*
|
||||||
* @param parent
|
* @param parent
|
||||||
* @param steps
|
* @param steps
|
||||||
* @param apiScenarioStepsDetails
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private List<ApiScenarioStep> getUpdateApiScenarioSteps(ApiScenarioStepRequest parent,
|
private List<ApiScenarioStep> getApiScenarioSteps(ApiScenarioStepRequest parent,
|
||||||
List<ApiScenarioStepRequest> steps,
|
List<ApiScenarioStepRequest> steps) {
|
||||||
List<ApiScenarioStepBlob> apiScenarioStepsDetails) {
|
|
||||||
|
|
||||||
if (CollectionUtils.isEmpty(steps)) {
|
if (CollectionUtils.isEmpty(steps)) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
@ -499,25 +525,49 @@ public class ApiScenarioService {
|
|||||||
}
|
}
|
||||||
apiScenarioSteps.add(apiScenarioStep);
|
apiScenarioSteps.add(apiScenarioStep);
|
||||||
|
|
||||||
if (StringUtils.equals(step.getRefType(), ApiScenarioStepRefType.STEP_REF.name())) {
|
if (StringUtils.equalsAny(step.getRefType(), ApiScenarioStepRefType.REF.name(), ApiScenarioStepRefType.PARTIAL_REF.name())) {
|
||||||
// 如果是步骤引用,blob表保存启用的子步骤ID
|
|
||||||
Set<String> enableStepSet = getEnableStepSet(step.getChildren());
|
|
||||||
ApiScenarioStepBlob apiScenarioStepBlob = new ApiScenarioStepBlob();
|
|
||||||
apiScenarioStepBlob.setId(apiScenarioStep.getId());
|
|
||||||
apiScenarioStepBlob.setContent(JSON.toJSONString(enableStepSet).getBytes());
|
|
||||||
apiScenarioStepsDetails.add(apiScenarioStepBlob);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StringUtils.equalsAny(step.getRefType(), ApiScenarioStepRefType.REF.name(), ApiScenarioStepRefType.STEP_REF.name())) {
|
|
||||||
// 引用的步骤不解析子步骤
|
// 引用的步骤不解析子步骤
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 解析子步骤
|
// 解析子步骤
|
||||||
apiScenarioSteps.addAll(getUpdateApiScenarioSteps(step, step.getChildren(), apiScenarioStepsDetails));
|
apiScenarioSteps.addAll(getApiScenarioSteps(step, step.getChildren()));
|
||||||
}
|
}
|
||||||
return apiScenarioSteps;
|
return apiScenarioSteps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析步骤树结构
|
||||||
|
* 获取待更新的 ApiScenarioStep 列表
|
||||||
|
*
|
||||||
|
* @param steps
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private List<ApiScenarioStepBlob> getPartialRefStepDetails(List<ApiScenarioStepRequest> steps) {
|
||||||
|
if (CollectionUtils.isEmpty(steps)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
List<ApiScenarioStepBlob> apiScenarioStepsDetails = new ArrayList<>();
|
||||||
|
|
||||||
|
for (ApiScenarioStepRequest step : steps) {
|
||||||
|
if (StringUtils.equals(step.getRefType(), ApiScenarioStepRefType.REF.name())) {
|
||||||
|
// 引用的步骤不解析子步骤
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (StringUtils.equals(step.getRefType(), ApiScenarioStepRefType.PARTIAL_REF.name())) {
|
||||||
|
// 如果是部分引用,blob表保存启用的子步骤ID
|
||||||
|
Set<String> enableStepSet = getEnableStepSet(step.getChildren());
|
||||||
|
PartialRefStepDetail stepDetail = new PartialRefStepDetail();
|
||||||
|
stepDetail.setEnableStepIds(enableStepSet);
|
||||||
|
ApiScenarioStepBlob apiScenarioStepBlob = new ApiScenarioStepBlob();
|
||||||
|
apiScenarioStepBlob.setId(step.getId());
|
||||||
|
apiScenarioStepBlob.setContent(JSON.toJSONString(stepDetail).getBytes());
|
||||||
|
apiScenarioStepsDetails.add(apiScenarioStepBlob);
|
||||||
|
}
|
||||||
|
apiScenarioStepsDetails.addAll(getPartialRefStepDetails(step.getChildren()));
|
||||||
|
}
|
||||||
|
return apiScenarioStepsDetails;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取步骤及子步骤中 enable 的步骤ID
|
* 获取步骤及子步骤中 enable 的步骤ID
|
||||||
*
|
*
|
||||||
@ -533,8 +583,11 @@ public class ApiScenarioService {
|
|||||||
if (BooleanUtils.isTrue(step.getEnable())) {
|
if (BooleanUtils.isTrue(step.getEnable())) {
|
||||||
enableSteps.add(step.getId());
|
enableSteps.add(step.getId());
|
||||||
}
|
}
|
||||||
// 获取子步骤中 enable = true 的步骤
|
// 完全引用和部分引用不解析子步骤
|
||||||
enableSteps.addAll(getEnableStepSet(step.getChildren()));
|
if (!isRef(step.getRefType())) {
|
||||||
|
// 获取子步骤中 enable 的步骤
|
||||||
|
enableSteps.addAll(getEnableStepSet(step.getChildren()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return enableSteps;
|
return enableSteps;
|
||||||
}
|
}
|
||||||
@ -609,4 +662,210 @@ public class ApiScenarioService {
|
|||||||
public String uploadTempFile(MultipartFile file) {
|
public String uploadTempFile(MultipartFile file) {
|
||||||
return apiFileResourceService.uploadTempFile(file);
|
return apiFileResourceService.uploadTempFile(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String debug(ApiScenarioDebugRequest request) {
|
||||||
|
ApiScenario apiScenario = apiScenarioMapper.selectByPrimaryKey(request.getId());
|
||||||
|
boolean hasSave = apiScenario != null;
|
||||||
|
String reportId = IDGenerator.nextStr();
|
||||||
|
|
||||||
|
List<ApiScenarioStepRequest> steps = request.getSteps();
|
||||||
|
|
||||||
|
// 记录引用的资源ID
|
||||||
|
Map<String, List<String>> refResourceMap = new HashMap<>();
|
||||||
|
buildRefResourceIdMap(steps, refResourceMap);
|
||||||
|
|
||||||
|
// 查询引用的资源详情
|
||||||
|
Map<String, String> resourceBlobMap = getResourceBlobMap(refResourceMap);
|
||||||
|
|
||||||
|
// 查询复制的步骤详情
|
||||||
|
Map<String, String> detailMap = getStepDetailMap(steps, request.getStepDetails());
|
||||||
|
|
||||||
|
// 解析生成待执行的场景树
|
||||||
|
MsScenario msScenario = new MsScenario();
|
||||||
|
msScenario.setScenarioConfig(getScenarioConfig(request, hasSave));
|
||||||
|
parseStep2MsElement(msScenario, steps, resourceBlobMap, detailMap);
|
||||||
|
|
||||||
|
ApiResourceRunRequest runRequest = BeanUtils.copyBean(new ApiResourceRunRequest(), request);
|
||||||
|
runRequest.setProjectId(request.getProjectId());
|
||||||
|
runRequest.setTestId(request.getId());
|
||||||
|
runRequest.setReportId(reportId);
|
||||||
|
runRequest.setResourceType(ApiResourceType.API_SCENARIO.name());
|
||||||
|
runRequest.setRunMode(ApiExecuteRunMode.BACKEND_DEBUG.name());
|
||||||
|
runRequest.setTempFileIds(request.getTempFileIds());
|
||||||
|
runRequest.setGrouped(request.getGrouped());
|
||||||
|
runRequest.setEnvironmentId(request.getEnvironmentId());
|
||||||
|
runRequest.setTestElement(msScenario);
|
||||||
|
|
||||||
|
apiExecuteService.debug(runRequest);
|
||||||
|
|
||||||
|
return reportId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将步骤解析成 MsTestElement 树结构
|
||||||
|
*
|
||||||
|
* @param parentElement
|
||||||
|
* @param steps
|
||||||
|
* @param resourceBlobMap
|
||||||
|
* @param stepDetailMap
|
||||||
|
*/
|
||||||
|
private void parseStep2MsElement(AbstractMsTestElement parentElement,
|
||||||
|
List<ApiScenarioStepRequest> steps,
|
||||||
|
Map<String, String> resourceBlobMap,
|
||||||
|
Map<String, String> stepDetailMap) {
|
||||||
|
if (CollectionUtils.isNotEmpty(steps)) {
|
||||||
|
parentElement.setChildren(new LinkedList<>());
|
||||||
|
}
|
||||||
|
for (ApiScenarioStepRequest step : steps) {
|
||||||
|
StepParser stepParser = StepParserFactory.getStepParser(step.getStepType());
|
||||||
|
if (stepParser == null || BooleanUtils.isFalse(step.getEnable())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (StringUtils.equals(step.getStepType(), ApiScenarioStepRefType.PARTIAL_REF.name())) {
|
||||||
|
setPartialRefStepEnable(step, stepDetailMap);
|
||||||
|
}
|
||||||
|
// 将步骤详情解析生成对应的MsTestElement
|
||||||
|
AbstractMsTestElement msTestElement = stepParser.parse(step, resourceBlobMap.get(step.getResourceId()), stepDetailMap.get(step.getId()));
|
||||||
|
if (msTestElement != null) {
|
||||||
|
parentElement.getChildren().add(msTestElement);
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(step.getChildren())) {
|
||||||
|
parseStep2MsElement(msTestElement, step.getChildren(), resourceBlobMap, stepDetailMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置部分引用的步骤的启用状态
|
||||||
|
* @param step
|
||||||
|
* @param stepDetailMap
|
||||||
|
*/
|
||||||
|
private void setPartialRefStepEnable(ApiScenarioStepRequest step, Map<String, String> stepDetailMap) {
|
||||||
|
String stepDetail = stepDetailMap.get(step.getId());
|
||||||
|
if (StringUtils.isBlank(stepDetail)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PartialRefStepDetail partialRefStepDetail = JSON.parseObject(stepDetail, PartialRefStepDetail.class);
|
||||||
|
setChildPartialRefEnable(step.getChildren(), partialRefStepDetail.getEnableStepIds(), stepDetailMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置部分引用的步骤的启用状态
|
||||||
|
* @param steps
|
||||||
|
* @param enableStepIds
|
||||||
|
* @param stepDetailMap
|
||||||
|
*/
|
||||||
|
private void setChildPartialRefEnable(List<ApiScenarioStepRequest> steps, Set<String> enableStepIds, Map<String, String> stepDetailMap) {
|
||||||
|
for (ApiScenarioStepRequest step : steps) {
|
||||||
|
if (StringUtils.equals(step.getRefType(), ApiScenarioStepRefType.REF.name())) {
|
||||||
|
// 引用的启用不修改
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 非完全引用的步骤,使用当前场景配置的启用状态
|
||||||
|
step.setEnable(enableStepIds.contains(step.getId()));
|
||||||
|
if (StringUtils.equals(step.getRefType(), ApiScenarioStepRefType.PARTIAL_REF.name())) {
|
||||||
|
// 如果是部分引用的场景,重新获取详情再解析
|
||||||
|
setPartialRefStepEnable(step, stepDetailMap);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 非完全引用和部分引用的步骤,递归设置子步骤
|
||||||
|
if (CollectionUtils.isNotEmpty(step.getChildren())) {
|
||||||
|
setChildPartialRefEnable(step.getChildren(), enableStepIds, stepDetailMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> getStepDetailMap(List<ApiScenarioStepRequest> steps, Map<String, Object> stepDetailsParam) {
|
||||||
|
List<String> needBlobStepIds = new ArrayList<>();
|
||||||
|
for (ApiScenarioStepRequest step : steps) {
|
||||||
|
if (BooleanUtils.isFalse(step.getEnable())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (StringUtils.equalsAny(step.getStepType(), ApiScenarioStepRefType.REF.name())
|
||||||
|
&& !StringUtils.equals(step.getRefType(), ApiScenarioStepType.API.name())) {
|
||||||
|
// 非完全引用的步骤和接口定义的步骤,才需要查blob
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (stepDetailsParam != null && stepDetailsParam.keySet().contains(step.getId())) {
|
||||||
|
// 前端传了blob,不需要再查
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
needBlobStepIds.add(step.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> stepDetails = getStepBlobByIds(needBlobStepIds).stream()
|
||||||
|
.collect(Collectors.toMap(ApiScenarioStepBlob::getId, blob -> new String(blob.getContent())));
|
||||||
|
// 前端有传,就用前端传的
|
||||||
|
if (stepDetailsParam != null) {
|
||||||
|
stepDetailsParam.forEach((stepId, detail) -> stepDetails.put(stepId, JSON.toJSONString(detail)));
|
||||||
|
}
|
||||||
|
return stepDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> getResourceBlobMap(Map<String, List<String>> refResourceMap) {
|
||||||
|
Map<String, String> resourceBlobMap = new HashMap<>();
|
||||||
|
List<String> apiIds = refResourceMap.get(ApiScenarioStepType.API.name());
|
||||||
|
List<ApiDefinitionBlob> apiDefinitionBlobs = apiDefinitionService.getBlobByIds(apiIds);
|
||||||
|
apiDefinitionBlobs.forEach(blob -> resourceBlobMap.put(blob.getId(), new String(blob.getRequest())));
|
||||||
|
|
||||||
|
List<String> apiCaseIds = refResourceMap.get(ApiScenarioStepType.API_CASE.name());
|
||||||
|
List<ApiTestCaseBlob> apiTestCaseBlobs = apiTestCaseService.getBlobByIds(apiCaseIds);
|
||||||
|
apiTestCaseBlobs.forEach(blob -> resourceBlobMap.put(blob.getId(), new String(blob.getRequest())));
|
||||||
|
|
||||||
|
List<String> apiScenarioIds = refResourceMap.get(ApiScenarioStepType.API_SCENARIO.name());
|
||||||
|
List<ApiScenarioBlob> apiScenarioBlobs = getBlobByIds(apiScenarioIds);
|
||||||
|
apiScenarioBlobs.forEach(blob -> resourceBlobMap.put(blob.getId(), new String(blob.getConfig())));
|
||||||
|
return resourceBlobMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ApiScenarioStepBlob> getStepBlobByIds(List<String> stepIds) {
|
||||||
|
if (CollectionUtils.isEmpty(stepIds)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
ApiScenarioStepBlobExample example = new ApiScenarioStepBlobExample();
|
||||||
|
example.createCriteria().andIdIn(stepIds);
|
||||||
|
return apiScenarioStepBlobMapper.selectByExampleWithBLOBs(example);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ApiScenarioBlob> getBlobByIds(List<String> apiScenarioIds) {
|
||||||
|
if (CollectionUtils.isEmpty(apiScenarioIds)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
ApiScenarioBlobExample example = new ApiScenarioBlobExample();
|
||||||
|
example.createCriteria().andIdIn(apiScenarioIds);
|
||||||
|
return apiScenarioBlobMapper.selectByExampleWithBLOBs(example);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildRefResourceIdMap(List<ApiScenarioStepRequest> steps, Map<String, List<String>> refResourceIdMap) {
|
||||||
|
for (ApiScenarioStepRequest step : steps) {
|
||||||
|
if (isRef(step.getRefType()) && BooleanUtils.isTrue(step.getEnable())) {
|
||||||
|
// 记录引用的步骤ID
|
||||||
|
List<String> resourceIds = refResourceIdMap.get(step.getStepType());
|
||||||
|
if (resourceIds == null) {
|
||||||
|
resourceIds = new ArrayList<>();
|
||||||
|
refResourceIdMap.put(step.getStepType(), resourceIds);
|
||||||
|
}
|
||||||
|
resourceIds.add(step.getResourceId());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CollectionUtils.isNotEmpty(step.getChildren())) {
|
||||||
|
buildRefResourceIdMap(step.getChildren(), refResourceIdMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScenarioConfig getScenarioConfig(ApiScenarioDebugRequest request, boolean hasSave) {
|
||||||
|
ScenarioConfig scenarioConfig = null;
|
||||||
|
if (request.getScenarioConfig() != null) {
|
||||||
|
// 优先使用前端传的配置
|
||||||
|
scenarioConfig = request.getScenarioConfig();
|
||||||
|
} else if (hasSave) {
|
||||||
|
// 没传并且保存过,则从数据库获取
|
||||||
|
ApiScenarioBlob apiScenarioBlob = apiScenarioBlobMapper.selectByPrimaryKey(request.getId());
|
||||||
|
if (apiScenarioBlob != null) {
|
||||||
|
scenarioConfig = JSON.parseObject(new String(apiScenarioBlob.getConfig()), ScenarioConfig.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return scenarioConfig;
|
||||||
|
}
|
||||||
}
|
}
|
@ -3,6 +3,7 @@ package io.metersphere.api.utils;
|
|||||||
import io.metersphere.api.parser.jmeter.MsCommentScriptElementConverter;
|
import io.metersphere.api.parser.jmeter.MsCommentScriptElementConverter;
|
||||||
import io.metersphere.api.parser.jmeter.MsCommonElementConverter;
|
import io.metersphere.api.parser.jmeter.MsCommonElementConverter;
|
||||||
import io.metersphere.api.parser.jmeter.MsHTTPElementConverter;
|
import io.metersphere.api.parser.jmeter.MsHTTPElementConverter;
|
||||||
|
import io.metersphere.api.parser.jmeter.MsScenarioConverter;
|
||||||
import io.metersphere.plugin.api.spi.AbstractJmeterElementConverter;
|
import io.metersphere.plugin.api.spi.AbstractJmeterElementConverter;
|
||||||
import io.metersphere.plugin.api.spi.MsTestElement;
|
import io.metersphere.plugin.api.spi.MsTestElement;
|
||||||
import io.metersphere.plugin.sdk.util.PluginLogUtils;
|
import io.metersphere.plugin.sdk.util.PluginLogUtils;
|
||||||
@ -30,6 +31,7 @@ public class JmeterElementConverterRegister {
|
|||||||
register(MsHTTPElementConverter.class);
|
register(MsHTTPElementConverter.class);
|
||||||
register(MsCommonElementConverter.class);
|
register(MsCommonElementConverter.class);
|
||||||
register(MsCommentScriptElementConverter.class);
|
register(MsCommentScriptElementConverter.class);
|
||||||
|
register(MsScenarioConverter.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -363,7 +363,7 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||||||
MsHTTPElement msHTTPElement = new MsHTTPElement();
|
MsHTTPElement msHTTPElement = new MsHTTPElement();
|
||||||
msHTTPElement.setPath("/test");
|
msHTTPElement.setPath("/test");
|
||||||
msHTTPElement.setMethod("GET");
|
msHTTPElement.setMethod("GET");
|
||||||
request.setRequest(ApiDataUtils.toJSONString(msHTTPElement));
|
request.setRequest(JSON.parseObject(ApiDataUtils.toJSONString(msHTTPElement)));
|
||||||
|
|
||||||
// @校验组织没有资源池权限异常
|
// @校验组织没有资源池权限异常
|
||||||
assertErrorCode(this.requestPost(DEBUG, request), ApiResultCode.EXECUTE_RESOURCE_POOL_NOT_CONFIG);
|
assertErrorCode(this.requestPost(DEBUG, request), ApiResultCode.EXECUTE_RESOURCE_POOL_NOT_CONFIG);
|
||||||
@ -392,7 +392,7 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||||||
msHTTPElement = MsHTTPElementTest.getMsHttpElement();
|
msHTTPElement = MsHTTPElementTest.getMsHttpElement();
|
||||||
msHTTPElement.setChildren(linkedList);
|
msHTTPElement.setChildren(linkedList);
|
||||||
msHTTPElement.setEnable(true);
|
msHTTPElement.setEnable(true);
|
||||||
request.setRequest(ApiDataUtils.toJSONString(msHTTPElement));
|
request.setRequest(getMsElementParam(msHTTPElement));
|
||||||
this.requestPostWithOk(DEBUG, request);
|
this.requestPostWithOk(DEBUG, request);
|
||||||
|
|
||||||
// 测试请求体
|
// 测试请求体
|
||||||
@ -407,10 +407,10 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||||||
|
|
||||||
// 增加覆盖率
|
// 增加覆盖率
|
||||||
msHTTPElement.setMethod("GET");
|
msHTTPElement.setMethod("GET");
|
||||||
request.setRequest(ApiDataUtils.toJSONString(msHTTPElement));
|
request.setRequest(getMsElementParam(msHTTPElement));
|
||||||
this.requestPostWithOk(DEBUG, request);
|
this.requestPostWithOk(DEBUG, request);
|
||||||
msHTTPElement.setEnable(false);
|
msHTTPElement.setEnable(false);
|
||||||
request.setRequest(ApiDataUtils.toJSONString(msHTTPElement));
|
request.setRequest(getMsElementParam(msHTTPElement));
|
||||||
this.requestPostWithOk(DEBUG, request);
|
this.requestPostWithOk(DEBUG, request);
|
||||||
|
|
||||||
// 增加覆盖率
|
// 增加覆盖率
|
||||||
@ -426,35 +426,39 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||||||
private void testBodyParse(ApiDebugRunRequest request, MsHTTPElement msHTTPElement, Body generalBody) throws Exception {
|
private void testBodyParse(ApiDebugRunRequest request, MsHTTPElement msHTTPElement, Body generalBody) throws Exception {
|
||||||
// 测试 FORM_DATA
|
// 测试 FORM_DATA
|
||||||
generalBody.setBodyType(Body.BodyType.FORM_DATA.name());
|
generalBody.setBodyType(Body.BodyType.FORM_DATA.name());
|
||||||
request.setRequest(ApiDataUtils.toJSONString(msHTTPElement));
|
request.setRequest(getMsElementParam(msHTTPElement));
|
||||||
this.requestPostWithOk(DEBUG, request);
|
this.requestPostWithOk(DEBUG, request);
|
||||||
|
|
||||||
// 测试 WWW_FORM
|
// 测试 WWW_FORM
|
||||||
generalBody.setBodyType(Body.BodyType.WWW_FORM.name());
|
generalBody.setBodyType(Body.BodyType.WWW_FORM.name());
|
||||||
request.setRequest(ApiDataUtils.toJSONString(msHTTPElement));
|
request.setRequest(getMsElementParam(msHTTPElement));
|
||||||
this.requestPostWithOk(DEBUG, request);
|
this.requestPostWithOk(DEBUG, request);
|
||||||
|
|
||||||
// 测试 BINARY
|
// 测试 BINARY
|
||||||
generalBody.setBodyType(Body.BodyType.BINARY.name());
|
generalBody.setBodyType(Body.BodyType.BINARY.name());
|
||||||
request.setRequest(ApiDataUtils.toJSONString(msHTTPElement));
|
request.setRequest(getMsElementParam(msHTTPElement));
|
||||||
this.requestPostWithOk(DEBUG, request);
|
this.requestPostWithOk(DEBUG, request);
|
||||||
|
|
||||||
// 测试 JSON
|
// 测试 JSON
|
||||||
generalBody.setBodyType(Body.BodyType.JSON.name());
|
generalBody.setBodyType(Body.BodyType.JSON.name());
|
||||||
request.setRequest(ApiDataUtils.toJSONString(msHTTPElement));
|
request.setRequest(getMsElementParam(msHTTPElement));
|
||||||
this.requestPostWithOk(DEBUG, request);
|
this.requestPostWithOk(DEBUG, request);
|
||||||
|
|
||||||
// 测试 XML
|
// 测试 XML
|
||||||
generalBody.setBodyType(Body.BodyType.XML.name());
|
generalBody.setBodyType(Body.BodyType.XML.name());
|
||||||
request.setRequest(ApiDataUtils.toJSONString(msHTTPElement));
|
request.setRequest(getMsElementParam(msHTTPElement));
|
||||||
this.requestPostWithOk(DEBUG, request);
|
this.requestPostWithOk(DEBUG, request);
|
||||||
|
|
||||||
// 测试 RAW
|
// 测试 RAW
|
||||||
generalBody.setBodyType(Body.BodyType.RAW.name());
|
generalBody.setBodyType(Body.BodyType.RAW.name());
|
||||||
request.setRequest(ApiDataUtils.toJSONString(msHTTPElement));
|
request.setRequest(getMsElementParam(msHTTPElement));
|
||||||
this.requestPostWithOk(DEBUG, request);
|
this.requestPostWithOk(DEBUG, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Object getMsElementParam(MsHTTPElement msHTTPElement) {
|
||||||
|
return JSON.parseObject(ApiDataUtils.toJSONString(msHTTPElement));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(7)
|
@Order(7)
|
||||||
public void delete() throws Exception {
|
public void delete() throws Exception {
|
||||||
|
@ -3,6 +3,7 @@ package io.metersphere.api.controller;
|
|||||||
import io.metersphere.api.constants.ApiDefinitionStatus;
|
import io.metersphere.api.constants.ApiDefinitionStatus;
|
||||||
import io.metersphere.api.constants.ApiScenarioStatus;
|
import io.metersphere.api.constants.ApiScenarioStatus;
|
||||||
import io.metersphere.api.constants.ApiScenarioStepRefType;
|
import io.metersphere.api.constants.ApiScenarioStepRefType;
|
||||||
|
import io.metersphere.api.constants.ApiScenarioStepType;
|
||||||
import io.metersphere.api.domain.*;
|
import io.metersphere.api.domain.*;
|
||||||
import io.metersphere.api.dto.definition.ApiDefinitionAddRequest;
|
import io.metersphere.api.dto.definition.ApiDefinitionAddRequest;
|
||||||
import io.metersphere.api.dto.definition.ApiTestCaseAddRequest;
|
import io.metersphere.api.dto.definition.ApiTestCaseAddRequest;
|
||||||
@ -11,6 +12,7 @@ import io.metersphere.api.dto.request.assertion.MsScriptAssertion;
|
|||||||
import io.metersphere.api.dto.request.http.MsHTTPElement;
|
import io.metersphere.api.dto.request.http.MsHTTPElement;
|
||||||
import io.metersphere.api.dto.scenario.*;
|
import io.metersphere.api.dto.scenario.*;
|
||||||
import io.metersphere.api.mapper.*;
|
import io.metersphere.api.mapper.*;
|
||||||
|
import io.metersphere.api.service.BaseResourcePoolTestService;
|
||||||
import io.metersphere.api.service.definition.ApiDefinitionService;
|
import io.metersphere.api.service.definition.ApiDefinitionService;
|
||||||
import io.metersphere.api.service.definition.ApiTestCaseService;
|
import io.metersphere.api.service.definition.ApiTestCaseService;
|
||||||
import io.metersphere.api.utils.ApiDataUtils;
|
import io.metersphere.api.utils.ApiDataUtils;
|
||||||
@ -60,6 +62,7 @@ public class ApiScenarioControllerTests extends BaseTest {
|
|||||||
private static final String FOLLOW = "follow/";
|
private static final String FOLLOW = "follow/";
|
||||||
protected static final String UPLOAD_TEMP_FILE = "upload/temp/file";
|
protected static final String UPLOAD_TEMP_FILE = "upload/temp/file";
|
||||||
protected static final String DELETE_TO_GC = "delete-to-gc/{0}";
|
protected static final String DELETE_TO_GC = "delete-to-gc/{0}";
|
||||||
|
protected static final String DEBUG = "debug";
|
||||||
|
|
||||||
private static final ResultMatcher ERROR_REQUEST_MATCHER = status().is5xxServerError();
|
private static final ResultMatcher ERROR_REQUEST_MATCHER = status().is5xxServerError();
|
||||||
@Resource
|
@Resource
|
||||||
@ -86,6 +89,8 @@ public class ApiScenarioControllerTests extends BaseTest {
|
|||||||
private ApiDefinitionService apiDefinitionService;
|
private ApiDefinitionService apiDefinitionService;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiTestCaseService apiTestCaseService;
|
private ApiTestCaseService apiTestCaseService;
|
||||||
|
@Resource
|
||||||
|
private BaseResourcePoolTestService baseResourcePoolTestService;
|
||||||
private static ApiScenario addApiScenario;
|
private static ApiScenario addApiScenario;
|
||||||
private static ApiScenario anOtherAddApiScenario;
|
private static ApiScenario anOtherAddApiScenario;
|
||||||
private static ApiDefinition apiDefinition;
|
private static ApiDefinition apiDefinition;
|
||||||
@ -227,7 +232,7 @@ public class ApiScenarioControllerTests extends BaseTest {
|
|||||||
stepRequest2.setId(IDGenerator.nextStr());
|
stepRequest2.setId(IDGenerator.nextStr());
|
||||||
stepRequest2.setName(addApiScenario.getName());
|
stepRequest2.setName(addApiScenario.getName());
|
||||||
stepRequest2.setResourceId(addApiScenario.getId());
|
stepRequest2.setResourceId(addApiScenario.getId());
|
||||||
stepRequest2.setRefType(ApiScenarioStepRefType.STEP_REF.name());
|
stepRequest2.setRefType(ApiScenarioStepRefType.PARTIAL_REF.name());
|
||||||
stepRequest2.setChildren(List.of(stepRequest));
|
stepRequest2.setChildren(List.of(stepRequest));
|
||||||
steps = List.of(stepRequest, stepRequest2);
|
steps = List.of(stepRequest, stepRequest2);
|
||||||
request.setSteps(steps);
|
request.setSteps(steps);
|
||||||
@ -326,8 +331,11 @@ public class ApiScenarioControllerTests extends BaseTest {
|
|||||||
stepRequest3.setResourceId(apiDefinition.getId());
|
stepRequest3.setResourceId(apiDefinition.getId());
|
||||||
stepRequest.setName(apiDefinition.getName() + "3");
|
stepRequest.setName(apiDefinition.getName() + "3");
|
||||||
stepRequest3.setRefType(ApiScenarioStepRefType.REF.name());
|
stepRequest3.setRefType(ApiScenarioStepRefType.REF.name());
|
||||||
|
return new ArrayList<>() {{
|
||||||
return List.of(stepRequest, stepRequest2);
|
add(stepRequest);
|
||||||
|
add(stepRequest2);
|
||||||
|
add(stepRequest3);
|
||||||
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initTestData() {
|
private void initTestData() {
|
||||||
@ -409,30 +417,6 @@ public class ApiScenarioControllerTests extends BaseTest {
|
|||||||
requestPostPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_UPDATE, DEFAULT_UPDATE, request);
|
requestPostPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_UPDATE, DEFAULT_UPDATE, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@Order(3)
|
|
||||||
public void deleteToGc() throws Exception {
|
|
||||||
// @@请求成功
|
|
||||||
this.requestGetWithOk(DELETE_TO_GC, addApiScenario.getId());
|
|
||||||
// todo 校验请求成功数据
|
|
||||||
// @@校验日志
|
|
||||||
checkLog(addApiScenario.getId(), OperationLogType.DELETE);
|
|
||||||
// @@校验权限
|
|
||||||
requestGetPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_DELETE, DELETE_TO_GC, addApiScenario.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Order(4)
|
|
||||||
public void delete() throws Exception {
|
|
||||||
// @@请求成功
|
|
||||||
this.requestGetWithOk(DEFAULT_DELETE, addApiScenario.getId());
|
|
||||||
// todo 校验请求成功数据
|
|
||||||
// @@校验日志
|
|
||||||
checkLog(addApiScenario.getId(), OperationLogType.DELETE);
|
|
||||||
// @@校验权限
|
|
||||||
requestGetPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_DELETE, DEFAULT_DELETE, addApiScenario.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(5)
|
@Order(5)
|
||||||
public void uploadTempFile() throws Exception {
|
public void uploadTempFile() throws Exception {
|
||||||
@ -450,6 +434,45 @@ public class ApiScenarioControllerTests extends BaseTest {
|
|||||||
requestUploadPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_UPDATE, UPLOAD_TEMP_FILE, file);
|
requestUploadPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_UPDATE, UPLOAD_TEMP_FILE, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(6)
|
||||||
|
public void debug() throws Exception {
|
||||||
|
mockPost("/api/debug", "");
|
||||||
|
baseResourcePoolTestService.initProjectResourcePool();
|
||||||
|
// @@请求成功
|
||||||
|
ApiScenarioDebugRequest request = new ApiScenarioDebugRequest();
|
||||||
|
request.setProjectId(DEFAULT_PROJECT_ID);
|
||||||
|
request.setScenarioConfig(new ScenarioConfig());
|
||||||
|
request.setEnvironmentId("environmentId");
|
||||||
|
|
||||||
|
List<ApiScenarioStepRequest> steps = getApiScenarioStepRequests();
|
||||||
|
ApiScenarioStepRequest stepRequest = new ApiScenarioStepRequest();
|
||||||
|
stepRequest.setName("test step");
|
||||||
|
stepRequest.setId(IDGenerator.nextStr());
|
||||||
|
stepRequest.setRefType(ApiScenarioStepRefType.REF.name());
|
||||||
|
stepRequest.setResourceId(addApiScenario.getId());
|
||||||
|
stepRequest.setResourceNum(addApiScenario.getNum().toString());
|
||||||
|
stepRequest.setName(addApiScenario.getName());
|
||||||
|
stepRequest.setStepType(ApiScenarioStepType.API_SCENARIO.name());
|
||||||
|
stepRequest.setChildren(getApiScenarioStepRequests());
|
||||||
|
steps.add(stepRequest);
|
||||||
|
ApiScenarioStepRequest copyScenarioStep = BeanUtils.copyBean(new ApiScenarioStepRequest(), stepRequest);
|
||||||
|
copyScenarioStep.setRefType(ApiScenarioStepRefType.COPY.name());
|
||||||
|
copyScenarioStep.setChildren(getApiScenarioStepRequests());
|
||||||
|
steps.add(stepRequest);
|
||||||
|
ApiScenarioStepRequest partialScenarioStep = BeanUtils.copyBean(new ApiScenarioStepRequest(), stepRequest);
|
||||||
|
partialScenarioStep.setRefType(ApiScenarioStepRefType.PARTIAL_REF.name());
|
||||||
|
partialScenarioStep.setChildren(getApiScenarioStepRequests());
|
||||||
|
steps.add(partialScenarioStep);
|
||||||
|
request.setId(addApiScenario.getId());
|
||||||
|
request.setSteps(steps);
|
||||||
|
request.setStepDetails(new HashMap<>());
|
||||||
|
this.requestPostWithOk(DEBUG, request);
|
||||||
|
|
||||||
|
// @@校验权限
|
||||||
|
requestPostPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_EXECUTE, DEBUG, request);
|
||||||
|
}
|
||||||
|
|
||||||
private String doUploadTempFile(MockMultipartFile file) throws Exception {
|
private String doUploadTempFile(MockMultipartFile file) throws Exception {
|
||||||
return JSON.parseObject(requestUploadFileWithOkAndReturn(UPLOAD_TEMP_FILE, file)
|
return JSON.parseObject(requestUploadFileWithOkAndReturn(UPLOAD_TEMP_FILE, file)
|
||||||
.getResponse()
|
.getResponse()
|
||||||
@ -467,6 +490,30 @@ public class ApiScenarioControllerTests extends BaseTest {
|
|||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(9)
|
||||||
|
public void deleteToGc() throws Exception {
|
||||||
|
// @@请求成功
|
||||||
|
this.requestGetWithOk(DELETE_TO_GC, addApiScenario.getId());
|
||||||
|
// todo 校验请求成功数据
|
||||||
|
// @@校验日志
|
||||||
|
checkLog(addApiScenario.getId(), OperationLogType.DELETE);
|
||||||
|
// @@校验权限
|
||||||
|
requestGetPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_DELETE, DELETE_TO_GC, addApiScenario.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(10)
|
||||||
|
public void delete() throws Exception {
|
||||||
|
// @@请求成功
|
||||||
|
this.requestGetWithOk(DEFAULT_DELETE, addApiScenario.getId());
|
||||||
|
// todo 校验请求成功数据
|
||||||
|
// @@校验日志
|
||||||
|
checkLog(addApiScenario.getId(), OperationLogType.DELETE);
|
||||||
|
// @@校验权限
|
||||||
|
requestGetPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_DELETE, DEFAULT_DELETE, addApiScenario.getId());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(11)
|
@Order(11)
|
||||||
public void page() throws Exception {
|
public void page() throws Exception {
|
||||||
|
Loading…
Reference in New Issue
Block a user