From b5dca1b323e7a496f4b23b4e6435e876f2d90498 Mon Sep 17 00:00:00 2001 From: AgAngle <1323481023@qq.com> Date: Thu, 25 Jan 2024 16:46:49 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95):=20?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E5=9C=BA=E6=99=AF=E6=AD=A5=E9=AA=A4=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/i18n/api.properties | 2 +- .../main/resources/i18n/api_en_US.properties | 1 + .../main/resources/i18n/api_zh_CN.properties | 1 + .../main/resources/i18n/api_zh_TW.properties | 1 + .../scenario/ApiScenarioController.java | 8 +++ .../api/parser/step/ApiCaseStepParser.java | 20 ++++++- .../parser/step/ApiScenarioStepParser.java | 29 +++++++++- .../api/parser/step/ApiStepParser.java | 54 ++++++++++++++----- .../api/parser/step/DefaultStepParser.java | 24 +++++++++ .../api/parser/step/StepParser.java | 36 ++++++++++++- .../api/parser/step/StepParserFactory.java | 4 +- .../service/scenario/ApiScenarioService.java | 14 ++++- .../ApiScenarioControllerTests.java | 30 +++++++++++ 13 files changed, 204 insertions(+), 20 deletions(-) create mode 100644 backend/services/api-test/src/main/java/io/metersphere/api/parser/step/DefaultStepParser.java diff --git a/backend/framework/sdk/src/main/resources/i18n/api.properties b/backend/framework/sdk/src/main/resources/i18n/api.properties index 33989aa8dd..07e468444d 100644 --- a/backend/framework/sdk/src/main/resources/i18n/api.properties +++ b/backend/framework/sdk/src/main/resources/i18n/api.properties @@ -380,6 +380,7 @@ schedule_not_exist=定时任务不存在 api_case_report_not_exist=用例报告不存在 api_scenario_report_not_exist=场景报告不存在 permission.api_plugin.name=接口插件 +permission.api_step.name=步骤 #module:ApiScenarioCsv api_scenario_csv.file_id.not_blank=文件ID不能为空 @@ -398,4 +399,3 @@ api_scenario_csv.ignore_first_line.not_blank=是否忽略第一行 api_scenario_csv.allow_quoted_data.not_blank=是否允许带引号 api_scenario_csv.recycle_on_eof.not_blank=是否循环 api_scenario_csv.stop_thread_on_eof.not_blank=是否停止线程 - diff --git a/backend/framework/sdk/src/main/resources/i18n/api_en_US.properties b/backend/framework/sdk/src/main/resources/i18n/api_en_US.properties index 5b62faece8..32506630fd 100644 --- a/backend/framework/sdk/src/main/resources/i18n/api_en_US.properties +++ b/backend/framework/sdk/src/main/resources/i18n/api_en_US.properties @@ -392,6 +392,7 @@ schedule_not_exist=The scheduled task does not exist api_case_report_not_exist=Api report does not exist api_scenario_report_not_exist=Scenario report does not exist permission.api_plugin.name=Api Plugin +permission.api_step.name=Step #module:ApiScenarioCsv api_scenario_csv.file_id.not_blank=File ID cannot be empty diff --git a/backend/framework/sdk/src/main/resources/i18n/api_zh_CN.properties b/backend/framework/sdk/src/main/resources/i18n/api_zh_CN.properties index 61ec88f817..6abe872047 100644 --- a/backend/framework/sdk/src/main/resources/i18n/api_zh_CN.properties +++ b/backend/framework/sdk/src/main/resources/i18n/api_zh_CN.properties @@ -361,6 +361,7 @@ schedule_not_exist=定时任务不存在 api_case_report_not_exist=用例报告不存在 api_scenario_report_not_exist=场景报告不存在 permission.api_plugin.name=接口插件 +permission.api_step.name=步骤 #module:ApiScenarioCsv api_scenario_csv.file_id.not_blank=文件ID不能为空 diff --git a/backend/framework/sdk/src/main/resources/i18n/api_zh_TW.properties b/backend/framework/sdk/src/main/resources/i18n/api_zh_TW.properties index dfb09e9fa9..c9ff6164dd 100644 --- a/backend/framework/sdk/src/main/resources/i18n/api_zh_TW.properties +++ b/backend/framework/sdk/src/main/resources/i18n/api_zh_TW.properties @@ -361,6 +361,7 @@ schedule_not_exist=定時任務不存在 api_case_report_not_exist=用例報告不存在 api_scenario_report_not_exist=場景報告不存在 permission.api_plugin.name=接口插件 +permission.api_step.name=步驟 #module:ApiScenarioCsv 繁体 api_scenario_csv.file_id.not_blank=文件ID不能為空 diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/controller/scenario/ApiScenarioController.java b/backend/services/api-test/src/main/java/io/metersphere/api/controller/scenario/ApiScenarioController.java index 4316c1055a..68c35db3a7 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/controller/scenario/ApiScenarioController.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/controller/scenario/ApiScenarioController.java @@ -114,10 +114,18 @@ public class ApiScenarioController { @GetMapping("/get/{scenarioId}") @Operation(summary = "接口测试-接口场景管理-获取场景详情") @RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_READ) + @CheckOwner(resourceId = "#scenarioId", resourceType = "api_scenario") public ApiScenarioDetail get(@PathVariable String scenarioId) { return apiScenarioService.get(scenarioId); } + @GetMapping("/step/get/{stepId}") + @Operation(summary = "接口测试-接口场景管理-获取场景步骤详情") + @RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_READ) + public Object getStepDetail(@PathVariable String stepId) { + return apiScenarioService.getStepDetail(stepId); + } + @PostMapping("/debug") @Operation(summary = "接口测试-接口场景管理-场景调试") @RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_EXECUTE) diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/ApiCaseStepParser.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/ApiCaseStepParser.java index 69f81d98e1..460b6f192a 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/ApiCaseStepParser.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/ApiCaseStepParser.java @@ -1,8 +1,12 @@ package io.metersphere.api.parser.step; +import io.metersphere.api.domain.ApiScenarioStep; +import io.metersphere.api.domain.ApiTestCaseBlob; import io.metersphere.api.dto.scenario.ApiScenarioStepCommonDTO; +import io.metersphere.api.mapper.ApiTestCaseBlobMapper; import io.metersphere.api.utils.ApiDataUtils; import io.metersphere.plugin.api.spi.AbstractMsTestElement; +import io.metersphere.sdk.util.CommonBeanFactory; import org.apache.commons.lang3.StringUtils; /** @@ -11,7 +15,7 @@ import org.apache.commons.lang3.StringUtils; */ public class ApiCaseStepParser extends StepParser { @Override - public AbstractMsTestElement parse(ApiScenarioStepCommonDTO step, String resourceBlob, String stepDetail) { + public AbstractMsTestElement parseTestElement(ApiScenarioStepCommonDTO step, String resourceBlob, String stepDetail) { if (isRef(step.getRefType())) { return StringUtils.isBlank(resourceBlob) ? null : parse2MsTestElement(resourceBlob); } else { @@ -21,4 +25,18 @@ public class ApiCaseStepParser extends StepParser { return StringUtils.isBlank(stepDetail) ? null : ApiDataUtils.parseObject(stepDetail, AbstractMsTestElement.class); } } + + @Override + public Object parseDetail(ApiScenarioStep step) { + if (isRef(step.getRefType())) { + ApiTestCaseBlobMapper apiTestCaseBlobMapper = CommonBeanFactory.getBean(ApiTestCaseBlobMapper.class); + ApiTestCaseBlob apiTestCaseBlob = apiTestCaseBlobMapper.selectByPrimaryKey(step.getResourceId()); + if (apiTestCaseBlob == null) { + return null; + } + return parse2MsTestElement(new String(apiTestCaseBlob.getRequest())); + } else { + return parse2MsTestElement(getStepBlobString(step.getId())); + } + } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/ApiScenarioStepParser.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/ApiScenarioStepParser.java index f89b25385d..e47287a0d5 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/ApiScenarioStepParser.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/ApiScenarioStepParser.java @@ -1,9 +1,13 @@ package io.metersphere.api.parser.step; +import io.metersphere.api.domain.ApiScenarioBlob; +import io.metersphere.api.domain.ApiScenarioStep; import io.metersphere.api.dto.request.MsScenario; import io.metersphere.api.dto.scenario.ApiScenarioStepCommonDTO; import io.metersphere.api.dto.scenario.ScenarioConfig; +import io.metersphere.api.mapper.ApiScenarioBlobMapper; import io.metersphere.plugin.api.spi.AbstractMsTestElement; +import io.metersphere.sdk.util.CommonBeanFactory; import io.metersphere.sdk.util.JSON; import org.apache.commons.lang3.StringUtils; @@ -13,7 +17,7 @@ import org.apache.commons.lang3.StringUtils; */ public class ApiScenarioStepParser extends StepParser { @Override - public AbstractMsTestElement parse(ApiScenarioStepCommonDTO step, String resourceBlob, String stepDetail) { + public AbstractMsTestElement parseTestElement(ApiScenarioStepCommonDTO step, String resourceBlob, String stepDetail) { MsScenario msScenario = new MsScenario(); if (isRef(step.getRefType())) { if (StringUtils.isNotBlank(resourceBlob)) { @@ -26,4 +30,27 @@ public class ApiScenarioStepParser extends StepParser { } return msScenario; } + + /** + * 获取场景配置详情 + * @param step + * @return + */ + @Override + public Object parseDetail(ApiScenarioStep step) { + if (isRef(step.getRefType())) { + ApiScenarioBlobMapper apiScenarioBlobMapper = CommonBeanFactory.getBean(ApiScenarioBlobMapper.class); + ApiScenarioBlob apiScenarioBlob = apiScenarioBlobMapper.selectByPrimaryKey(step.getResourceId()); + if (apiScenarioBlob == null || apiScenarioBlob.getConfig() == null) { + return null; + } + return JSON.parseObject(new String(apiScenarioBlob.getConfig()), ScenarioConfig.class); + } else { + String stepDetailStr= getStepBlobString(step.getId()); + if (StringUtils.isBlank(stepDetailStr)) { + return null; + } + return JSON.parseObject(stepDetailStr, ScenarioConfig.class); + } + } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/ApiStepParser.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/ApiStepParser.java index 014f7d9f9f..4f4183a94c 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/ApiStepParser.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/ApiStepParser.java @@ -1,11 +1,15 @@ package io.metersphere.api.parser.step; +import io.metersphere.api.domain.ApiDefinitionBlob; +import io.metersphere.api.domain.ApiScenarioStep; 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.ApiScenarioStepCommonDTO; +import io.metersphere.api.mapper.ApiDefinitionBlobMapper; import io.metersphere.api.utils.ApiDataUtils; import io.metersphere.plugin.api.spi.AbstractMsTestElement; +import io.metersphere.sdk.util.CommonBeanFactory; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -17,24 +21,50 @@ import java.util.List; */ public class ApiStepParser extends StepParser { @Override - public AbstractMsTestElement parse(ApiScenarioStepCommonDTO step, String resourceBlob, String stepDetail) { + public AbstractMsTestElement parseTestElement(ApiScenarioStepCommonDTO 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; - } + return parseRefTestElement(resourceBlob, stepDetail); } else { return StringUtils.isBlank(stepDetail) ? null : ApiDataUtils.parseObject(stepDetail, AbstractMsTestElement.class); } } + /** + * 处理引用的接口步骤 + * 替换修改的参数 + * @param resourceBlob 引用的接口步骤详情 + * @param stepDetail 引用之后修改的步骤详情 + * @return + */ + public AbstractMsTestElement parseRefTestElement(String resourceBlob, String stepDetail) { + if (StringUtils.isBlank(resourceBlob)) { + return null; + } + AbstractMsTestElement refResourceElement = parse2MsTestElement(resourceBlob); + if (refResourceElement instanceof MsHTTPElement && StringUtils.isNotBlank(stepDetail)) { + // 如果是 http 并且有修改请求参数,则替换请求参数 + AbstractMsTestElement stepElement = parse2MsTestElement(stepDetail); + return replaceParams((MsHTTPElement) stepElement, (MsHTTPElement) refResourceElement); + } else { + return refResourceElement; + } + } + + @Override + public Object parseDetail(ApiScenarioStep step) { + if (isRef(step.getRefType())) { + ApiDefinitionBlobMapper apiDefinitionBlobMapper = CommonBeanFactory.getBean(ApiDefinitionBlobMapper.class); + ApiDefinitionBlob apiDefinitionBlob = apiDefinitionBlobMapper.selectByPrimaryKey(step.getResourceId()); + if (apiDefinitionBlob == null) { + return null; + } + return parseRefTestElement(new String(apiDefinitionBlob.getRequest()), getStepBlobString(step.getId())); + } else { + return parse2MsTestElement(getStepBlobString(step.getId())); + } + + } + private AbstractMsTestElement replaceParams(MsHTTPElement msTestElement, MsHTTPElement refResourceElement) { replaceKvParam(msTestElement.getHeaders(), refResourceElement.getHeaders()); diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/DefaultStepParser.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/DefaultStepParser.java new file mode 100644 index 0000000000..789084ffcc --- /dev/null +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/DefaultStepParser.java @@ -0,0 +1,24 @@ +package io.metersphere.api.parser.step; + +import io.metersphere.api.domain.ApiScenarioStep; +import io.metersphere.api.dto.scenario.ApiScenarioStepCommonDTO; +import io.metersphere.plugin.api.spi.AbstractMsTestElement; + +/** + * 默认的步骤解析器 + * 逻辑控制器等步骤,直接将步骤详情解析为 MsTestElement + * @Author: jianxing + * @CreateTime: 2024-01-20 15:43 + */ +public class DefaultStepParser extends StepParser { + + @Override + public AbstractMsTestElement parseTestElement(ApiScenarioStepCommonDTO step, String resourceBlob, String stepDetail) { + return parse2MsTestElement(stepDetail); + } + + @Override + public Object parseDetail(ApiScenarioStep step) { + return parse2MsTestElement(getStepBlobString(step.getId())); + } +} diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/StepParser.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/StepParser.java index 04cb87c80f..232f0b4623 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/StepParser.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/StepParser.java @@ -1,10 +1,13 @@ package io.metersphere.api.parser.step; import io.metersphere.api.constants.ApiScenarioStepRefType; +import io.metersphere.api.domain.ApiScenarioStep; +import io.metersphere.api.domain.ApiScenarioStepBlob; import io.metersphere.api.dto.scenario.ApiScenarioStepCommonDTO; -import io.metersphere.api.dto.scenario.ApiScenarioStepRequest; +import io.metersphere.api.mapper.ApiScenarioStepBlobMapper; import io.metersphere.api.utils.ApiDataUtils; import io.metersphere.plugin.api.spi.AbstractMsTestElement; +import io.metersphere.sdk.util.CommonBeanFactory; import org.apache.commons.lang3.StringUtils; /** @@ -13,13 +16,42 @@ import org.apache.commons.lang3.StringUtils; */ public abstract class StepParser { - public abstract AbstractMsTestElement parse(ApiScenarioStepCommonDTO step, String resourceBlob, String stepDetail); + /** + * 将步骤详情解析为 MsTestElement + * @param step 步骤 + * @param resourceBlob 关联的资源详情 + * @param stepDetail 步骤详情 + * @return + */ + public abstract AbstractMsTestElement parseTestElement(ApiScenarioStepCommonDTO step, String resourceBlob, String stepDetail); + + /** + * 将步骤解析为步骤详情 + * 场景步骤,返回 ScenarioConfig + * 其余返回 MsTestElement + * @param step + * @return + */ + public abstract Object parseDetail(ApiScenarioStep step); + protected boolean isRef(String refType) { return StringUtils.equalsAny(refType, ApiScenarioStepRefType.REF.name(), ApiScenarioStepRefType.PARTIAL_REF.name()); } protected static AbstractMsTestElement parse2MsTestElement(String blobContent) { + if (StringUtils.isBlank(blobContent)) { + return null; + } return ApiDataUtils.parseObject(blobContent, AbstractMsTestElement.class); } + + protected String getStepBlobString(String stepId) { + ApiScenarioStepBlobMapper apiScenarioStepBlobMapper = CommonBeanFactory.getBean(ApiScenarioStepBlobMapper.class); + ApiScenarioStepBlob apiScenarioStepBlob = apiScenarioStepBlobMapper.selectByPrimaryKey(stepId); + if (apiScenarioStepBlob == null) { + return null; + } + return new String(apiScenarioStepBlob.getContent()); + } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/StepParserFactory.java b/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/StepParserFactory.java index f0f9904a2c..c681592e61 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/StepParserFactory.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/parser/step/StepParserFactory.java @@ -12,6 +12,7 @@ import java.util.Map; public abstract class StepParserFactory { private static Map stepParserMap = new HashMap<>(); + private static StepParser defaultStepParser = new DefaultStepParser(); static { stepParserMap.put(ApiScenarioStepType.API.name(), new ApiStepParser()); @@ -20,6 +21,7 @@ public abstract class StepParserFactory { } public static StepParser getStepParser(String stepType) { - return stepParserMap.get(stepType); + StepParser stepParser = stepParserMap.get(stepType); + return stepParser == null ? defaultStepParser : stepParser; } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioService.java index 093040292f..e5ca51df1c 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioService.java @@ -908,13 +908,13 @@ public class ApiScenarioService { } for (ApiScenarioStepCommonDTO step : steps) { StepParser stepParser = StepParserFactory.getStepParser(step.getStepType()); - if (stepParser == null || BooleanUtils.isFalse(step.getEnable())) { + if (BooleanUtils.isFalse(step.getEnable())) { continue; } setPartialRefStepEnable(step, stepDetailMap); // 将步骤详情解析生成对应的MsTestElement - AbstractMsTestElement msTestElement = stepParser.parse(step, resourceBlobMap.get(step.getResourceId()), stepDetailMap.get(step.getId())); + AbstractMsTestElement msTestElement = stepParser.parseTestElement(step, resourceBlobMap.get(step.getResourceId()), stepDetailMap.get(step.getId())); if (msTestElement != null) { parentElement.getChildren().add(msTestElement); } @@ -1261,4 +1261,14 @@ public class ApiScenarioService { } return extApiScenarioStepMapper.getStepDTOByScenarioIds(scenarioIds); } + + public Object getStepDetail(String stepId) { + ApiScenarioStep step = checkStepExist(stepId); + StepParser stepParser = StepParserFactory.getStepParser(step.getStepType()); + return stepParser.parseDetail(step); + } + + private ApiScenarioStep checkStepExist(String id) { + return ServiceUtils.checkResourceExist(apiScenarioStepMapper.selectByPrimaryKey(id), "permission.api_step.name"); + } } \ No newline at end of file diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiScenarioControllerTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiScenarioControllerTests.java index 728c984a29..315b613b35 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiScenarioControllerTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiScenarioControllerTests.java @@ -15,6 +15,7 @@ import io.metersphere.api.mapper.*; import io.metersphere.api.service.BaseResourcePoolTestService; import io.metersphere.api.service.definition.ApiDefinitionService; import io.metersphere.api.service.definition.ApiTestCaseService; +import io.metersphere.api.service.scenario.ApiScenarioService; import io.metersphere.api.utils.ApiDataUtils; import io.metersphere.project.dto.filemanagement.request.FileUploadRequest; import io.metersphere.project.mapper.ExtBaseProjectVersionMapper; @@ -65,6 +66,7 @@ public class ApiScenarioControllerTests extends BaseTest { private static final String FOLLOW = "follow/"; 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 STEP_GET = "step/get/{0}"; protected static final String DEBUG = "debug"; private static final String UPDATE_STATUS = "update-status"; private static final String UPDATE_PRIORITY = "update-priority"; @@ -100,6 +102,8 @@ public class ApiScenarioControllerTests extends BaseTest { private FileMetadataService fileMetadataService; @Resource private ApiScenarioCsvMapper apiScenarioCsvMapper; + @Resource + private ApiScenarioService apiScenarioService; private static String fileMetadataId; private static String localFileId; private static ApiScenario addApiScenario; @@ -565,6 +569,32 @@ public class ApiScenarioControllerTests extends BaseTest { requestGetPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_READ, DEFAULT_GET, addApiScenario.getId()); } + @Test + @Order(7) + public void getStepDetail() throws Exception { + ApiScenarioDetail apiScenarioDetail = apiScenarioService.get(addApiScenario.getId()); + List steps = apiScenarioDetail.getSteps(); + requestGetStepDetail(steps); + + apiScenarioDetail = apiScenarioService.get(anOtherAddApiScenario.getId()); + steps = apiScenarioDetail.getSteps(); + requestGetStepDetail(steps); + + // @@校验权限 + requestGetPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_READ, STEP_GET, addApiScenario.getId()); + } + + private void requestGetStepDetail(List steps) throws Exception { + if (CollectionUtils.isEmpty(steps)) { + return; + } + for (ApiScenarioStepCommonDTO step : steps) { + this.requestGetWithOk(STEP_GET, step.getId()); + List children = step.getChildren(); + requestGetStepDetail(children); + } + } + private void asserGetApiScenarioSteps(List addApiScenarioSteps, List steps) { if (addApiScenarioSteps == null || steps == null) { Assertions.assertEquals(addApiScenarioSteps, null);