feat(接口测试): 处理执行时引用公共脚本
This commit is contained in:
parent
03fde1b4a3
commit
7a453643ad
|
@ -0,0 +1,42 @@
|
|||
package io.metersphere.api.dto;
|
||||
|
||||
import io.metersphere.api.dto.request.MsCommonElement;
|
||||
import io.metersphere.api.dto.request.http.MsHTTPElement;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 执行场景解析参数时的临时参数
|
||||
*
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2024-02-22 11:27
|
||||
*/
|
||||
@Data
|
||||
public class ApiScenarioParseParam {
|
||||
/**
|
||||
* 步骤详情 Map
|
||||
* key 为步骤ID
|
||||
* value 为步骤详情字符串
|
||||
*/
|
||||
private Map<String, String> stepDetailMap;
|
||||
/**
|
||||
* 资源的请求内容 Map
|
||||
* key 为资源ID
|
||||
* value 为请求详情字符串
|
||||
*/
|
||||
private Map<String, String> resourceDetailMap;
|
||||
/**
|
||||
* MsHTTPElement Map
|
||||
* key 为 stepType
|
||||
* value 为 MsHTTPElement
|
||||
*/
|
||||
private Map<String, List<MsHTTPElement>> stepTypeHttpElementMap = new HashMap<>();
|
||||
/**
|
||||
* 场景中所有的 MsCommonElement 列表
|
||||
*/
|
||||
private List<MsCommonElement> commonElements = new ArrayList<>();
|
||||
}
|
|
@ -16,6 +16,7 @@ import org.apache.jorphan.collections.HashTree;
|
|||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.USER_PARAMETERS_GUI;
|
||||
|
@ -53,6 +54,9 @@ public class MsCommentScriptElementConverter extends AbstractJmeterElementConver
|
|||
scriptElement = new BeanShellSampler();
|
||||
}
|
||||
ScriptProcessorConverter.parse(scriptElement, scriptProcessor);
|
||||
// 添加公共脚本的参数
|
||||
Optional.ofNullable(ScriptProcessorConverter.getScriptArguments(scriptProcessor))
|
||||
.ifPresent(hashTree::add);
|
||||
hashTree.add(scriptElement);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,4 +20,5 @@ public class JmeterAlias {
|
|||
public static final String COOKIE_PANEL = "CookiePanel";
|
||||
public static final String HEADER_PANEL = "HeaderPanel";
|
||||
public static final String AUTH_PANEL = "AuthPanel";
|
||||
public static final String ARGUMENTS_PANEL = "ArgumentsPanel";
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ import org.apache.jmeter.protocol.java.sampler.JSR223Sampler;
|
|||
import org.apache.jmeter.testelement.TestElement;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 环境场景级前置处理器处理
|
||||
*
|
||||
|
@ -31,6 +33,11 @@ public class ScenarioScriptProcessorConverter extends ScriptProcessorConverter {
|
|||
}
|
||||
|
||||
parse(processor, scriptProcessor);
|
||||
|
||||
// 添加公共脚本的参数
|
||||
Optional.ofNullable(getScriptArguments(scriptProcessor))
|
||||
.ifPresent(hashTree::add);
|
||||
|
||||
// 标记当前处理器是否关联场景结果
|
||||
processor.setName("ASSOCIATE_RESULT_PROCESSOR_" + associateScenarioResult);
|
||||
hashTree.add(processor);
|
||||
|
|
|
@ -7,6 +7,8 @@ import org.apache.jmeter.extractor.JSR223PostProcessor;
|
|||
import org.apache.jmeter.testelement.TestElement;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-12-26 14:49
|
||||
|
@ -17,7 +19,6 @@ public class ScriptPostProcessorConverter extends ScriptProcessorConverter {
|
|||
if (!needParse(scriptProcessor, config) || !scriptProcessor.isValid()) {
|
||||
return;
|
||||
}
|
||||
// todo 处理公共脚本
|
||||
TestElement processor;
|
||||
if (isJSR233(scriptProcessor)) {
|
||||
processor = new JSR223PostProcessor();
|
||||
|
@ -25,6 +26,11 @@ public class ScriptPostProcessorConverter extends ScriptProcessorConverter {
|
|||
processor = new BeanShellPostProcessor();
|
||||
}
|
||||
parse(processor, scriptProcessor);
|
||||
|
||||
// 添加公共脚本的参数
|
||||
Optional.ofNullable(getScriptArguments(scriptProcessor))
|
||||
.ifPresent(hashTree::add);
|
||||
|
||||
hashTree.add(processor);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
package io.metersphere.api.parser.jmeter.processor;
|
||||
|
||||
import io.metersphere.project.api.processor.ScriptProcessor;
|
||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||
import io.metersphere.project.api.processor.ScriptProcessor;
|
||||
import org.apache.jmeter.modifiers.BeanShellPreProcessor;
|
||||
import org.apache.jmeter.modifiers.JSR223PreProcessor;
|
||||
import org.apache.jmeter.testelement.TestElement;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-12-26 14:49
|
||||
|
@ -17,7 +19,6 @@ public class ScriptPreProcessorConverter extends ScriptProcessorConverter {
|
|||
if (!needParse(scriptProcessor, config) || !scriptProcessor.isValid()) {
|
||||
return;
|
||||
}
|
||||
// todo 处理公共脚本
|
||||
TestElement processor;
|
||||
if (isJSR233(scriptProcessor)) {
|
||||
processor = new JSR223PreProcessor();
|
||||
|
@ -25,6 +26,11 @@ public class ScriptPreProcessorConverter extends ScriptProcessorConverter {
|
|||
processor = new BeanShellPreProcessor();
|
||||
}
|
||||
parse(processor, scriptProcessor);
|
||||
|
||||
// 添加公共脚本的参数
|
||||
Optional.ofNullable(getScriptArguments(scriptProcessor))
|
||||
.ifPresent(hashTree::add);
|
||||
|
||||
hashTree.add(processor);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
package io.metersphere.api.parser.jmeter.processor;
|
||||
|
||||
import io.metersphere.plugin.api.constants.ElementProperty;
|
||||
import io.metersphere.project.constants.ScriptLanguageType;
|
||||
import io.metersphere.project.api.processor.ScriptProcessor;
|
||||
import io.metersphere.api.parser.jmeter.constants.JmeterAlias;
|
||||
import io.metersphere.api.parser.jmeter.constants.JmeterProperty;
|
||||
import io.metersphere.plugin.api.constants.ElementProperty;
|
||||
import io.metersphere.project.api.KeyValueParam;
|
||||
import io.metersphere.project.api.processor.ScriptProcessor;
|
||||
import io.metersphere.project.constants.ScriptLanguageType;
|
||||
import io.metersphere.project.dto.CommonScriptInfo;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.config.Arguments;
|
||||
import org.apache.jmeter.save.SaveService;
|
||||
import org.apache.jmeter.testelement.TestElement;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.ARGUMENTS_PANEL;
|
||||
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
|
@ -38,9 +46,48 @@ public abstract class ScriptProcessorConverter extends MsProcessorConverter<Scri
|
|||
testElement.setProperty(JmeterProperty.CACHE_KEY, cacheKey);
|
||||
testElement.setProperty(TestElement.TEST_CLASS, testElement.getClass().getSimpleName());
|
||||
testElement.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass(JmeterAlias.TEST_BEAN_GUI));
|
||||
testElement.setProperty(JmeterProperty.SCRIPT_LANGUAGE, scriptProcessor.getScriptLanguage());
|
||||
testElement.setProperty(JmeterProperty.SCRIPT, scriptProcessor.getScript());
|
||||
testElement.setProperty(ElementProperty.PROJECT_ID.name(), scriptProcessor.getProjectId());
|
||||
String scriptLanguage = scriptProcessor.getScriptLanguage();
|
||||
String script = scriptProcessor.getScript();
|
||||
if (scriptProcessor.isEnableCommonScript()) {
|
||||
scriptLanguage = scriptProcessor.getCommonScriptInfo().getScriptLanguage();
|
||||
script = scriptProcessor.getCommonScriptInfo().getScript();
|
||||
}
|
||||
if (scriptLanguage == null) {
|
||||
scriptLanguage = ScriptLanguageType.BEANSHELL.name();
|
||||
}
|
||||
testElement.setProperty(JmeterProperty.SCRIPT, script);
|
||||
testElement.setProperty(JmeterProperty.SCRIPT_LANGUAGE, scriptLanguage.toLowerCase());
|
||||
}
|
||||
|
||||
public static Arguments getScriptArguments(ScriptProcessor scriptProcessor) {
|
||||
if (scriptProcessor == null || !scriptProcessor.isEnableCommonScript() || !scriptProcessor.isValid()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CommonScriptInfo commonScriptInfo = scriptProcessor.getCommonScriptInfo();
|
||||
if (CollectionUtils.isEmpty(commonScriptInfo.getParams())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<KeyValueParam> params = commonScriptInfo.getParams()
|
||||
.stream()
|
||||
.filter(KeyValueParam::isValid)
|
||||
.toList();
|
||||
|
||||
if (CollectionUtils.isEmpty(commonScriptInfo.getParams())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Arguments arguments = new Arguments();
|
||||
arguments.setEnabled(true);
|
||||
arguments.setName(scriptProcessor.getName() + "_Arguments");
|
||||
arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName());
|
||||
arguments.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass(ARGUMENTS_PANEL));
|
||||
for (KeyValueParam param : params) {
|
||||
arguments.addArgument(param.getKey(), param.getValue(), "=");
|
||||
}
|
||||
return arguments;
|
||||
}
|
||||
|
||||
public static boolean isJSR233(ScriptProcessor scriptProcessor) {
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
package io.metersphere.api.parser.jmeter.processor.assertion;
|
||||
|
||||
import io.metersphere.project.api.assertion.MsScriptAssertion;
|
||||
import io.metersphere.project.api.processor.ScriptProcessor;
|
||||
import io.metersphere.api.parser.jmeter.processor.ScriptProcessorConverter;
|
||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||
import io.metersphere.project.api.assertion.MsScriptAssertion;
|
||||
import io.metersphere.project.api.processor.ScriptProcessor;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.assertions.JSR223Assertion;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-12-27 21:01
|
||||
|
@ -16,17 +17,18 @@ import org.apache.jorphan.collections.HashTree;
|
|||
public class ScriptAssertionConverter extends AssertionConverter<MsScriptAssertion> {
|
||||
@Override
|
||||
public void parse(HashTree hashTree, MsScriptAssertion msAssertion, ParameterConfig config, boolean isIgnoreStatus) {
|
||||
if (!needParse(msAssertion, config) || !isValid(msAssertion)) {
|
||||
if (!needParse(msAssertion, config) || !msAssertion.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
JSR223Assertion jsr223Assertion = new JSR223Assertion();
|
||||
ScriptProcessorConverter.parse(jsr223Assertion, BeanUtils.copyBean(new ScriptProcessor(), msAssertion));
|
||||
ScriptProcessor scriptProcessor = BeanUtils.copyBean(new ScriptProcessor(), msAssertion);
|
||||
ScriptProcessorConverter.parse(jsr223Assertion, scriptProcessor);
|
||||
|
||||
// 添加公共脚本的参数
|
||||
Optional.ofNullable(ScriptProcessorConverter.getScriptArguments(scriptProcessor))
|
||||
.ifPresent(hashTree::add);
|
||||
|
||||
hashTree.add(jsr223Assertion);
|
||||
}
|
||||
|
||||
public boolean isValid(MsScriptAssertion msAssertion) {
|
||||
// todo 公共脚本库
|
||||
return StringUtils.isNotBlank(msAssertion.getScript());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,16 +3,25 @@ package io.metersphere.api.service;
|
|||
import io.metersphere.api.dto.ApiFile;
|
||||
import io.metersphere.api.dto.definition.ResponseBinaryBody;
|
||||
import io.metersphere.api.dto.definition.ResponseBody;
|
||||
import io.metersphere.api.dto.request.MsCommonElement;
|
||||
import io.metersphere.api.dto.request.http.MsHTTPElement;
|
||||
import io.metersphere.api.dto.request.http.body.BinaryBody;
|
||||
import io.metersphere.api.dto.request.http.body.Body;
|
||||
import io.metersphere.api.dto.request.http.body.FormDataBody;
|
||||
import io.metersphere.api.dto.request.http.body.FormDataKV;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.project.api.KeyValueParam;
|
||||
import io.metersphere.project.api.processor.MsProcessor;
|
||||
import io.metersphere.project.api.processor.ScriptProcessor;
|
||||
import io.metersphere.project.domain.CustomFunction;
|
||||
import io.metersphere.project.domain.CustomFunctionBlob;
|
||||
import io.metersphere.project.domain.FileAssociation;
|
||||
import io.metersphere.project.domain.FileMetadata;
|
||||
import io.metersphere.project.dto.CommonScriptInfo;
|
||||
import io.metersphere.project.service.CustomFunctionService;
|
||||
import io.metersphere.project.service.FileAssociationService;
|
||||
import io.metersphere.project.service.FileMetadataService;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -22,6 +31,8 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
@ -35,8 +46,12 @@ public class ApiCommonService {
|
|||
private FileAssociationService fileAssociationService;
|
||||
@Resource
|
||||
private FileMetadataService fileMetadataService;
|
||||
@Resource
|
||||
private CustomFunctionService customFunctionService;
|
||||
|
||||
/**
|
||||
* 根据 fileId 查找 MsHTTPElement 中的 ApiFile
|
||||
*
|
||||
* @param fileId
|
||||
* @param msTestElement
|
||||
* @return
|
||||
|
@ -63,24 +78,26 @@ public class ApiCommonService {
|
|||
/**
|
||||
* 设置关联的文件的最新信息
|
||||
* 包括文件别名和是否被删除
|
||||
*
|
||||
* @param resourceId
|
||||
* @param msTestElement
|
||||
*/
|
||||
public void updateLinkFileInfo(String resourceId, AbstractMsTestElement msTestElement) {
|
||||
updateLinkFileInfo(resourceId, getApiFiles(msTestElement));
|
||||
public void setLinkFileInfo(String resourceId, AbstractMsTestElement msTestElement) {
|
||||
setLinkFileInfo(resourceId, getApiFiles(msTestElement));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置关联的文件的最新信息
|
||||
* 包括文件别名和是否被删除
|
||||
*
|
||||
* @param resourceId
|
||||
* @param responseBody
|
||||
*/
|
||||
public void updateLinkFileInfo(String resourceId, ResponseBody responseBody) {
|
||||
updateLinkFileInfo(resourceId, getApiBodyFiles(responseBody));
|
||||
public void setLinkFileInfo(String resourceId, ResponseBody responseBody) {
|
||||
setLinkFileInfo(resourceId, getApiBodyFiles(responseBody));
|
||||
}
|
||||
|
||||
private void updateLinkFileInfo(String resourceId, List<ApiFile> apiFiles) {
|
||||
private void setLinkFileInfo(String resourceId, List<ApiFile> apiFiles) {
|
||||
List<ApiFile> linkFiles = apiFiles.stream()
|
||||
.filter(file -> !file.getLocal() && !file.getDelete())
|
||||
.toList();
|
||||
|
@ -114,7 +131,6 @@ public class ApiCommonService {
|
|||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param body
|
||||
* @return
|
||||
*/
|
||||
|
@ -155,8 +171,96 @@ public class ApiCommonService {
|
|||
public void replaceApiFileInfo(List<ApiFile> updateFiles, FileMetadata newFileMetadata) {
|
||||
for (ApiFile updateFile : updateFiles) {
|
||||
updateFile.setFileId(newFileMetadata.getId());
|
||||
// todo 重新设置文件名
|
||||
// updateFile.setFileName();
|
||||
updateFile.setFileName(newFileMetadata.getOriginalName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置使用脚本前后置的公共脚本信息
|
||||
* @param msTestElement
|
||||
*/
|
||||
public void setEnableCommonScriptProcessorInfo(AbstractMsTestElement msTestElement) {
|
||||
MsCommonElement msCommonElement = getMsCommonElement(msTestElement);
|
||||
Optional.ofNullable(msCommonElement).ifPresent(item -> setEnableCommonScriptProcessorInfo(List.of(item)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置使用脚本前后置的公共脚本信息
|
||||
*
|
||||
* @param commonElements
|
||||
*/
|
||||
public void setEnableCommonScriptProcessorInfo(List<MsCommonElement> commonElements) {
|
||||
List<ScriptProcessor> scriptsProcessors = getEnableCommonScriptProcessors(commonElements);
|
||||
|
||||
List<String> commonScriptIds = scriptsProcessors.stream()
|
||||
.map(processor -> processor.getCommonScriptInfo().getId())
|
||||
.toList();
|
||||
|
||||
Map<String, CustomFunctionBlob> customFunctionBlobMap = customFunctionService.getBlobByIds(commonScriptIds).stream()
|
||||
.collect(Collectors.toMap(CustomFunctionBlob::getId, Function.identity()));
|
||||
|
||||
Map<String, CustomFunction> customFunctionMap = customFunctionService.getByIds(commonScriptIds).stream()
|
||||
.collect(Collectors.toMap(CustomFunction::getId, Function.identity()));
|
||||
|
||||
for (ScriptProcessor processor : scriptsProcessors) {
|
||||
CommonScriptInfo commonScriptInfo = processor.getCommonScriptInfo();
|
||||
CustomFunctionBlob customFunctionBlob = customFunctionBlobMap.get(commonScriptInfo.getId());
|
||||
CustomFunction customFunction = customFunctionMap.get(commonScriptInfo.getId());
|
||||
|
||||
// 设置公共脚本信息
|
||||
Optional.ofNullable(customFunctionBlob.getParams()).ifPresent(paramsBlob -> {
|
||||
List<KeyValueParam> commonParams = JSON.parseArray(new String(paramsBlob), KeyValueParam.class);
|
||||
// 替换用户输入值
|
||||
commonParams.forEach(commonParam ->
|
||||
Optional.ofNullable(commonScriptInfo.getParams()).ifPresent(params ->
|
||||
params.stream()
|
||||
.filter(param -> StringUtils.equals(commonParam.getKey(), param.getKey()))
|
||||
.findFirst()
|
||||
.ifPresent(param -> commonParam.setValue(param.getValue()))
|
||||
)
|
||||
);
|
||||
commonScriptInfo.setParams(commonParams);
|
||||
});
|
||||
Optional.ofNullable(customFunctionBlob.getScript()).ifPresent(script ->
|
||||
commonScriptInfo.setScript(new String(script)));
|
||||
commonScriptInfo.setScriptLanguage(customFunction.getType());
|
||||
commonScriptInfo.setName(customFunction.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取使用公共脚本的前后置
|
||||
*
|
||||
* @param commonElements
|
||||
* @return
|
||||
*/
|
||||
private List<ScriptProcessor> getEnableCommonScriptProcessors(List<MsCommonElement> commonElements) {
|
||||
List<MsProcessor> processors = new ArrayList<>();
|
||||
|
||||
for (MsCommonElement commonElement : commonElements) {
|
||||
processors.addAll(commonElement.getPreProcessorConfig().getProcessors());
|
||||
processors.addAll(commonElement.getPostProcessorConfig().getProcessors());
|
||||
}
|
||||
|
||||
// 获取使用公共脚本的前后置
|
||||
List<ScriptProcessor> scriptsProcessors = processors.stream()
|
||||
.filter(processor -> processor instanceof ScriptProcessor)
|
||||
.map(processor -> (ScriptProcessor) processor)
|
||||
.filter(ScriptProcessor::getEnable)
|
||||
.filter(ScriptProcessor::isEnableCommonScript)
|
||||
.filter(ScriptProcessor::isValid)
|
||||
.collect(Collectors.toList());
|
||||
return scriptsProcessors;
|
||||
}
|
||||
|
||||
public MsCommonElement getMsCommonElement(AbstractMsTestElement msTestElement) {
|
||||
if (CollectionUtils.isNotEmpty(msTestElement.getChildren())) {
|
||||
for (AbstractMsTestElement child : msTestElement.getChildren()) {
|
||||
if (child instanceof MsCommonElement msCommonElement) {
|
||||
return msCommonElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,9 +132,6 @@ public class ApiExecuteService {
|
|||
|
||||
parameterConfig.setGlobalParams(getGlobalParam(request));
|
||||
|
||||
// todo 获取接口插件和jar包
|
||||
// todo 处理公共脚本
|
||||
// todo 接口用例 method 获取定义中的数据库字段
|
||||
String executeScript = parseExecuteScript(request.getTestElement(), parameterConfig);
|
||||
|
||||
doDebug(reportId, testId, taskRequest, executeScript, request.getProjectId());
|
||||
|
@ -318,7 +315,7 @@ public class ApiExecuteService {
|
|||
List<FileMetadata> fileMetadataList = fileManagementService.findJarByProjectId(List.of(taskRequest.getProjectId()));
|
||||
taskRequest.setFuncJars(fileMetadataList.stream()
|
||||
.map(file -> {
|
||||
String fileName = file.getName() + "." + file.getType();
|
||||
String fileName = file.getOriginalName();
|
||||
ApiExecuteFileInfo tempFileInfo = getApiExecuteFileInfo(file.getId(), fileName, file.getProjectId(), file.getStorage());
|
||||
if (StorageType.isGit(file.getStorage())) {
|
||||
// 设置Git信息
|
||||
|
|
|
@ -78,7 +78,8 @@ public class ApiDebugService {
|
|||
ApiDebugDTO apiDebugDTO = new ApiDebugDTO();
|
||||
BeanUtils.copyBean(apiDebugDTO, apiDebug);
|
||||
AbstractMsTestElement msTestElement = ApiDataUtils.parseObject(new String(apiDebugBlob.getRequest()), AbstractMsTestElement.class);
|
||||
apiCommonService.updateLinkFileInfo(id, msTestElement);
|
||||
apiCommonService.setLinkFileInfo(id, msTestElement);
|
||||
apiCommonService.setEnableCommonScriptProcessorInfo(msTestElement);
|
||||
apiDebugDTO.setRequest(msTestElement);
|
||||
apiDebugDTO.setResponse(apiDebugDTO.getResponse());
|
||||
return apiDebugDTO;
|
||||
|
@ -218,6 +219,10 @@ public class ApiDebugService {
|
|||
paramConfig.setTestElementClassPluginIdMap(apiPluginService.getTestElementPluginMap());
|
||||
paramConfig.setTestElementClassProtocalMap(apiPluginService.getTestElementProtocolMap());
|
||||
paramConfig.setReportId(reportId);
|
||||
|
||||
// 设置使用脚本前后置的公共脚本信息
|
||||
apiCommonService.setEnableCommonScriptProcessorInfo(runRequest.getTestElement());
|
||||
|
||||
apiExecuteService.debug(runRequest, paramConfig);
|
||||
return runRequest.getReportId();
|
||||
}
|
||||
|
|
|
@ -872,13 +872,14 @@ public class ApiDefinitionService {
|
|||
Optional<ApiDefinitionBlob> apiDefinitionBlobOptional = Optional.ofNullable(apiDefinitionBlobMapper.selectByPrimaryKey(id));
|
||||
apiDefinitionBlobOptional.ifPresent(blob -> {
|
||||
AbstractMsTestElement msTestElement = ApiDataUtils.parseObject(new String(blob.getRequest()), AbstractMsTestElement.class);
|
||||
apiCommonService.updateLinkFileInfo(id, msTestElement);
|
||||
apiCommonService.setLinkFileInfo(id, msTestElement);
|
||||
apiCommonService.setEnableCommonScriptProcessorInfo(msTestElement);
|
||||
apiDefinitionDTO.setRequest(msTestElement);
|
||||
// blob.getResponse() 为 null 时不进行转换
|
||||
if (blob.getResponse() != null) {
|
||||
List<HttpResponse> httpResponses = ApiDataUtils.parseArray(new String(blob.getResponse()), HttpResponse.class);
|
||||
for (HttpResponse httpResponse : httpResponses) {
|
||||
apiCommonService.updateLinkFileInfo(id, httpResponse.getBody());
|
||||
apiCommonService.setLinkFileInfo(id, httpResponse.getBody());
|
||||
}
|
||||
apiDefinitionDTO.setResponse(httpResponses);
|
||||
}
|
||||
|
|
|
@ -210,7 +210,10 @@ public class ApiTestCaseService {
|
|||
example.createCriteria().andCaseIdEqualTo(id).andUserIdEqualTo(userId);
|
||||
List<ApiTestCaseFollower> followers = apiTestCaseFollowerMapper.selectByExample(example);
|
||||
apiTestCaseDTO.setFollow(CollectionUtils.isNotEmpty(followers));
|
||||
apiTestCaseDTO.setRequest(ApiDataUtils.parseObject(new String(testCaseBlob.getRequest()), AbstractMsTestElement.class));
|
||||
AbstractMsTestElement msTestElement = ApiDataUtils.parseObject(new String(testCaseBlob.getRequest()), AbstractMsTestElement.class);
|
||||
apiCommonService.setLinkFileInfo(id, msTestElement);
|
||||
apiCommonService.setEnableCommonScriptProcessorInfo(msTestElement);
|
||||
apiTestCaseDTO.setRequest(msTestElement);
|
||||
return apiTestCaseDTO;
|
||||
}
|
||||
|
||||
|
|
|
@ -1054,11 +1054,11 @@ public class ApiScenarioService {
|
|||
Map<String, List<String>> refResourceMap = new HashMap<>();
|
||||
buildRefResourceIdMap(steps, refResourceMap);
|
||||
|
||||
ApiScenarioParseParam parseParam = new ApiScenarioParseParam();
|
||||
// 查询引用的资源详情
|
||||
Map<String, String> resourceBlobMap = getResourceBlobMap(refResourceMap);
|
||||
|
||||
parseParam.setResourceDetailMap(getResourceDetailMap(refResourceMap));
|
||||
// 查询复制的步骤详情
|
||||
Map<String, String> detailMap = getStepDetailMap(steps, request.getStepDetails());
|
||||
parseParam.setStepDetailMap(getStepDetailMap(steps, request.getStepDetails()));
|
||||
|
||||
// 解析生成待执行的场景树
|
||||
MsScenario msScenario = new MsScenario();
|
||||
|
@ -1068,10 +1068,11 @@ public class ApiScenarioService {
|
|||
|
||||
// 获取场景环境相关配置
|
||||
ApiScenarioParseEnvInfo scenarioParseEnvInfo = getScenarioParseEnvInfo(refResourceMap, request.getEnvironmentId(), request.getGrouped());
|
||||
Map<String, List<MsHTTPElement>> stepTypeHttpElementMap = new HashMap<>();
|
||||
parseStep2MsElement(msScenario, steps, resourceBlobMap, detailMap, stepTypeHttpElementMap, scenarioParseEnvInfo);
|
||||
parseStep2MsElement(msScenario, steps, parseParam, scenarioParseEnvInfo);
|
||||
// 设置 HttpElement 的模块信息
|
||||
setHttpElementModuleId(stepTypeHttpElementMap);
|
||||
setHttpElementModuleId(parseParam.getStepTypeHttpElementMap());
|
||||
// 设置使用脚本前后置的公共脚本信息
|
||||
apiCommonService.setEnableCommonScriptProcessorInfo(parseParam.getCommonElements());
|
||||
|
||||
ApiResourceRunRequest runRequest = BeanUtils.copyBean(new ApiResourceRunRequest(), request);
|
||||
runRequest.setProjectId(request.getProjectId());
|
||||
|
@ -1230,13 +1231,15 @@ public class ApiScenarioService {
|
|||
*/
|
||||
private void parseStep2MsElement(AbstractMsTestElement parentElement,
|
||||
List<? extends ApiScenarioStepCommonDTO> steps,
|
||||
Map<String, String> resourceBlobMap,
|
||||
Map<String, String> stepDetailMap,
|
||||
Map<String, List<MsHTTPElement>> stepTypeHttpElementMap,
|
||||
ApiScenarioParseParam parseParam,
|
||||
ApiScenarioParseEnvInfo scenarioParseEnvInfo) {
|
||||
if (CollectionUtils.isNotEmpty(steps)) {
|
||||
parentElement.setChildren(new LinkedList<>());
|
||||
}
|
||||
|
||||
Map<String, String> stepDetailMap = parseParam.getStepDetailMap();
|
||||
Map<String, String> resourceDetailMap = parseParam.getResourceDetailMap();
|
||||
Map<String, List<MsHTTPElement>> stepTypeHttpElementMap = parseParam.getStepTypeHttpElementMap();
|
||||
for (ApiScenarioStepCommonDTO step : steps) {
|
||||
StepParser stepParser = StepParserFactory.getStepParser(step.getStepType());
|
||||
if (BooleanUtils.isFalse(step.getEnable())) {
|
||||
|
@ -1245,7 +1248,7 @@ public class ApiScenarioService {
|
|||
setPartialRefStepEnable(step, stepDetailMap);
|
||||
|
||||
// 将步骤详情解析生成对应的MsTestElement
|
||||
AbstractMsTestElement msTestElement = stepParser.parseTestElement(step, resourceBlobMap.get(step.getResourceId()), stepDetailMap.get(step.getId()));
|
||||
AbstractMsTestElement msTestElement = stepParser.parseTestElement(step, resourceDetailMap.get(step.getResourceId()), stepDetailMap.get(step.getId()));
|
||||
if (msTestElement != null) {
|
||||
if (msTestElement instanceof MsHTTPElement msHTTPElement) {
|
||||
// 暂存http类型的步骤
|
||||
|
@ -1255,11 +1258,13 @@ public class ApiScenarioService {
|
|||
msTestElement.setProjectId(step.getProjectId());
|
||||
msTestElement.setResourceId(step.getResourceId());
|
||||
setMsScenarioParam(scenarioParseEnvInfo, step, msTestElement);
|
||||
// 记录 msCommonElement
|
||||
Optional.ofNullable(apiCommonService.getMsCommonElement(msTestElement))
|
||||
.ifPresent(msCommonElement -> parseParam.getCommonElements().add(msCommonElement));
|
||||
parentElement.getChildren().add(msTestElement);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(step.getChildren())) {
|
||||
parseStep2MsElement(msTestElement, step.getChildren(), resourceBlobMap,
|
||||
stepDetailMap, stepTypeHttpElementMap, scenarioParseEnvInfo);
|
||||
parseStep2MsElement(msTestElement, step.getChildren(), parseParam, scenarioParseEnvInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1383,7 +1388,7 @@ public class ApiScenarioService {
|
|||
return stepDetails;
|
||||
}
|
||||
|
||||
private Map<String, String> getResourceBlobMap(Map<String, List<String>> refResourceMap) {
|
||||
private Map<String, String> getResourceDetailMap(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);
|
||||
|
@ -1645,13 +1650,14 @@ public class ApiScenarioService {
|
|||
}
|
||||
StepParser stepParser = StepParserFactory.getStepParser(step.getStepType());
|
||||
Object stepDetail = stepParser.parseDetail(step);
|
||||
if (stepDetail instanceof MsHTTPElement msHTTPElement) {
|
||||
if (stepDetail instanceof AbstractMsTestElement msTestElement) {
|
||||
// 设置关联的文件的最新信息
|
||||
if (isRef(step.getRefType())) {
|
||||
apiCommonService.updateLinkFileInfo(step.getResourceId(), msHTTPElement);
|
||||
apiCommonService.setLinkFileInfo(step.getResourceId(), msTestElement);
|
||||
} else {
|
||||
apiCommonService.updateLinkFileInfo(step.getScenarioId(), msHTTPElement);
|
||||
apiCommonService.setLinkFileInfo(step.getScenarioId(), msTestElement);
|
||||
}
|
||||
apiCommonService.setEnableCommonScriptProcessorInfo(msTestElement);
|
||||
}
|
||||
return stepDetail;
|
||||
}
|
||||
|
|
|
@ -28,10 +28,18 @@ import io.metersphere.api.service.BaseFileManagementTestService;
|
|||
import io.metersphere.api.service.BaseResourcePoolTestService;
|
||||
import io.metersphere.api.utils.ApiDataUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.project.api.KeyValueEnableParam;
|
||||
import io.metersphere.project.api.KeyValueParam;
|
||||
import io.metersphere.project.api.processor.ScriptProcessor;
|
||||
import io.metersphere.project.constants.ScriptLanguageType;
|
||||
import io.metersphere.project.domain.CustomFunction;
|
||||
import io.metersphere.project.domain.ProjectTestResourcePool;
|
||||
import io.metersphere.project.domain.ProjectTestResourcePoolExample;
|
||||
import io.metersphere.project.dto.CommonScriptInfo;
|
||||
import io.metersphere.project.dto.customfunction.request.CustomFunctionRequest;
|
||||
import io.metersphere.project.dto.filemanagement.FileInfo;
|
||||
import io.metersphere.project.mapper.ProjectTestResourcePoolMapper;
|
||||
import io.metersphere.project.service.CustomFunctionService;
|
||||
import io.metersphere.project.service.FileAssociationService;
|
||||
import io.metersphere.sdk.constants.DefaultRepositoryDir;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
|
@ -93,6 +101,8 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||
private ProjectTestResourcePoolMapper projectTestResourcePoolMapper;
|
||||
@Resource
|
||||
private TestResourcePoolMapper testResourcePoolMapper;
|
||||
@Resource
|
||||
private CustomFunctionService customFunctionService;
|
||||
private static ApiDebug addApiDebug;
|
||||
private static ApiDebug anotherAddApiDebug;
|
||||
private static String fileMetadataId;
|
||||
|
@ -363,7 +373,7 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||
ApiDebugDTO copyApiDebugDTO = BeanUtils.copyBean(new ApiDebugDTO(), apiDebugMapper.selectByPrimaryKey(addApiDebug.getId()));
|
||||
ApiDebugBlob apiDebugBlob = apiDebugBlobMapper.selectByPrimaryKey(addApiDebug.getId());
|
||||
AbstractMsTestElement msTestElement = ApiDataUtils.parseObject(new String(apiDebugBlob.getRequest()), AbstractMsTestElement.class);
|
||||
apiCommonService.updateLinkFileInfo(addApiDebug.getId(), msTestElement);
|
||||
apiCommonService.setLinkFileInfo(addApiDebug.getId(), msTestElement);
|
||||
copyApiDebugDTO.setRequest(msTestElement);
|
||||
Assertions.assertEquals(apiDebugDTO, copyApiDebugDTO);
|
||||
|
||||
|
@ -477,6 +487,22 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||
msAssertionConfig.setAssertions(MsHTTPElementTest.getGeneralXmlAssertions());
|
||||
msCommonElement = new MsCommonElement();
|
||||
msCommonElement.setAssertionConfig(msAssertionConfig);
|
||||
|
||||
// 测试公共脚本
|
||||
ScriptProcessor scriptProcessor = new ScriptProcessor();
|
||||
scriptProcessor.setEnable(true);
|
||||
scriptProcessor.setName("test");
|
||||
scriptProcessor.setScriptLanguage(ScriptLanguageType.JAVASCRIPT.name());
|
||||
CustomFunction customFunction = addCustomFunction();
|
||||
scriptProcessor.setCommonScriptInfo(new CommonScriptInfo());
|
||||
scriptProcessor.getCommonScriptInfo().setId(customFunction.getId());
|
||||
scriptProcessor.setEnableCommonScript(true);
|
||||
KeyValueParam keyValueParam = new KeyValueParam();
|
||||
keyValueParam.setKey("a");
|
||||
keyValueParam.setValue("bb");
|
||||
scriptProcessor.getCommonScriptInfo().setParams(List.of(keyValueParam));
|
||||
msCommonElement.getPostProcessorConfig().getProcessors().add(scriptProcessor);
|
||||
|
||||
linkedList = new LinkedList();
|
||||
linkedList.add(msCommonElement);
|
||||
msHTTPElement = MsHTTPElementTest.getMsHttpElement();
|
||||
|
@ -485,7 +511,6 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||
request.setRequest(getMsElementParam(msHTTPElement));
|
||||
this.requestPostWithOk(DEBUG, request);
|
||||
|
||||
|
||||
// 测试请求体
|
||||
MockMultipartFile file = getMockMultipartFile();
|
||||
String fileId = doUploadTempFile(file);
|
||||
|
@ -513,6 +538,19 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||
requestPostPermissionTest(PermissionConstants.PROJECT_API_DEBUG_EXECUTE, DEBUG, request);
|
||||
}
|
||||
|
||||
private CustomFunction addCustomFunction() {
|
||||
CustomFunctionRequest request = new CustomFunctionRequest();
|
||||
request.setScript("aaa");
|
||||
KeyValueEnableParam keyValueEnableParam = new KeyValueEnableParam();
|
||||
keyValueEnableParam.setKey("a");
|
||||
keyValueEnableParam.setValue("b");
|
||||
request.setParams(JSON.toJSONString(keyValueEnableParam));
|
||||
request.setProjectId(DEFAULT_PROJECT_ID);
|
||||
request.setType(ScriptLanguageType.BEANSHELL.name());
|
||||
request.setName(IDGenerator.nextStr());
|
||||
return customFunctionService.add(request, "admin");
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试关联的文件更新
|
||||
*
|
||||
|
|
|
@ -348,11 +348,11 @@ public class ApiDefinitionControllerTests extends BaseTest {
|
|||
}
|
||||
if (apiDefinitionBlob != null) {
|
||||
AbstractMsTestElement msTestElement = ApiDataUtils.parseObject(new String(apiDefinitionBlob.getRequest()), AbstractMsTestElement.class);
|
||||
apiCommonService.updateLinkFileInfo(apiDefinition.getId(), msTestElement);
|
||||
apiCommonService.setLinkFileInfo(apiDefinition.getId(), msTestElement);
|
||||
copyApiDefinitionDTO.setRequest(msTestElement);
|
||||
List<HttpResponse> httpResponses = ApiDataUtils.parseArray(new String(apiDefinitionBlob.getResponse()), HttpResponse.class);
|
||||
for (HttpResponse httpResponse : httpResponses) {
|
||||
apiCommonService.updateLinkFileInfo(apiDefinition.getId(), httpResponse.getBody());
|
||||
apiCommonService.setLinkFileInfo(apiDefinition.getId(), httpResponse.getBody());
|
||||
}
|
||||
copyApiDefinitionDTO.setResponse(httpResponses);
|
||||
}
|
||||
|
|
|
@ -415,12 +415,14 @@ public class ApiTestCaseControllerTests extends BaseTest {
|
|||
ApiDefinition apiDefinition = apiDefinitionMapper.selectByPrimaryKey(apiTestCase.getApiDefinitionId());
|
||||
copyApiDebugDTO.setMethod(apiDefinition.getMethod());
|
||||
copyApiDebugDTO.setPath(apiDefinition.getPath());
|
||||
ApiTestCaseBlob apiDebugBlob = apiTestCaseBlobMapper.selectByPrimaryKey(apiTestCase.getId());
|
||||
ApiTestCaseBlob apiTestCaseBlob = apiTestCaseBlobMapper.selectByPrimaryKey(apiTestCase.getId());
|
||||
ApiTestCaseFollowerExample example = new ApiTestCaseFollowerExample();
|
||||
example.createCriteria().andCaseIdEqualTo(apiTestCase.getId()).andUserIdEqualTo("admin");
|
||||
List<ApiTestCaseFollower> followers = apiTestCaseFollowerMapper.selectByExample(example);
|
||||
copyApiDebugDTO.setFollow(CollectionUtils.isNotEmpty(followers));
|
||||
copyApiDebugDTO.setRequest(ApiDataUtils.parseObject(new String(apiDebugBlob.getRequest()), AbstractMsTestElement.class));
|
||||
AbstractMsTestElement msTestElement = ApiDataUtils.parseObject(new String(apiTestCaseBlob.getRequest()), AbstractMsTestElement.class);
|
||||
apiCommonService.setLinkFileInfo(apiTestCase.getId(), msTestElement);
|
||||
copyApiDebugDTO.setRequest(msTestElement);
|
||||
Assertions.assertEquals(apiDebugDTO, copyApiDebugDTO);
|
||||
this.requestGetWithOk(GET + anotherApiTestCase.getId())
|
||||
.andReturn();
|
||||
|
|
|
@ -27,6 +27,7 @@ import io.metersphere.project.api.processor.extract.RegexExtract;
|
|||
import io.metersphere.project.api.processor.extract.ResultMatchingExtract;
|
||||
import io.metersphere.project.api.processor.extract.XPathExtract;
|
||||
import io.metersphere.project.constants.ScriptLanguageType;
|
||||
import io.metersphere.project.dto.CommonScriptInfo;
|
||||
import io.metersphere.sdk.constants.MsAssertionCondition;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
|
@ -363,7 +364,8 @@ public class MsHTTPElementTest {
|
|||
assertions.add(responseTimeAssertion);
|
||||
|
||||
MsScriptAssertion scriptAssertion = new MsScriptAssertion();
|
||||
scriptAssertion.setScriptId("1111");
|
||||
scriptAssertion.setCommonScriptInfo(new CommonScriptInfo());
|
||||
scriptAssertion.getCommonScriptInfo().setId("1111");
|
||||
scriptAssertion.setScript("1111");
|
||||
scriptAssertion.setName("1111");
|
||||
assertions.add(scriptAssertion);
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
package io.metersphere.project.api.assertion;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.metersphere.project.api.KeyValueParam;
|
||||
import io.metersphere.project.constants.ScriptLanguageType;
|
||||
import io.metersphere.project.dto.CommonScriptInfo;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* 变量断言
|
||||
|
@ -27,13 +28,23 @@ public class MsScriptAssertion extends MsAssertion {
|
|||
/**
|
||||
* 是否启用公共脚本
|
||||
*/
|
||||
private Boolean enableCommonScript;
|
||||
private Boolean enableCommonScript = false;
|
||||
/**
|
||||
* 脚本ID
|
||||
* 公共脚本信息
|
||||
* {@link CommonScriptInfo}
|
||||
*/
|
||||
private String scriptId;
|
||||
/**
|
||||
* 公共脚本入参
|
||||
*/
|
||||
private List<KeyValueParam> params;
|
||||
@Valid
|
||||
private CommonScriptInfo commonScriptInfo;
|
||||
|
||||
public boolean isValid() {
|
||||
if (isEnableCommonScript()) {
|
||||
return commonScriptInfo != null && StringUtils.isNotBlank(commonScriptInfo.getId());
|
||||
} else {
|
||||
return StringUtils.isNotBlank(script);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnableCommonScript() {
|
||||
return BooleanUtils.isTrue(enableCommonScript);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,16 +2,15 @@ package io.metersphere.project.api.processor;
|
|||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.metersphere.project.constants.ScriptLanguageType;
|
||||
import io.metersphere.project.api.KeyValueParam;
|
||||
import io.metersphere.project.dto.CommonScriptInfo;
|
||||
import io.metersphere.system.valid.EnumValue;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
|
@ -29,6 +28,7 @@ public class ScriptProcessor extends MsProcessor {
|
|||
* {@link ScriptLanguageType}
|
||||
*/
|
||||
@Size(max = 20)
|
||||
@NotBlank
|
||||
@EnumValue(enumClass = ScriptLanguageType.class)
|
||||
private String scriptLanguage;
|
||||
/**
|
||||
|
@ -38,20 +38,22 @@ public class ScriptProcessor extends MsProcessor {
|
|||
*/
|
||||
private Boolean enableCommonScript = false;
|
||||
/**
|
||||
* 公共脚本ID
|
||||
*/
|
||||
@Size(max = 50)
|
||||
private String scriptId;
|
||||
/**
|
||||
* 公共脚本入参
|
||||
* 公共脚本信息
|
||||
* {@link CommonScriptInfo}
|
||||
*/
|
||||
@Valid
|
||||
private List<KeyValueParam> params;
|
||||
private CommonScriptInfo commonScriptInfo;
|
||||
|
||||
|
||||
public boolean isValid() {
|
||||
if (BooleanUtils.isTrue(enableCommonScript) && StringUtils.isBlank(scriptId)) {
|
||||
return false;
|
||||
if (isEnableCommonScript()) {
|
||||
return commonScriptInfo != null && StringUtils.isNotBlank(commonScriptInfo.getId());
|
||||
} else {
|
||||
return StringUtils.isNotBlank(script);
|
||||
}
|
||||
return StringUtils.isNotBlank(script);
|
||||
}
|
||||
|
||||
public boolean isEnableCommonScript() {
|
||||
return BooleanUtils.isTrue(enableCommonScript);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package io.metersphere.project.dto;
|
||||
|
||||
import io.metersphere.project.api.KeyValueParam;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2024-02-23 13:34
|
||||
*/
|
||||
@Data
|
||||
public class CommonScriptInfo {
|
||||
/**
|
||||
* 公共脚本ID
|
||||
*/
|
||||
@Size(min = 1, max = 50)
|
||||
private String id;
|
||||
/**
|
||||
* 公共脚本的名字
|
||||
* 页面展示需要
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 公共脚本的内容
|
||||
* 执行时设置
|
||||
*/
|
||||
private String script;
|
||||
/**
|
||||
* 脚本语言
|
||||
*/
|
||||
private String scriptLanguage;
|
||||
/**
|
||||
* 公共脚本入参
|
||||
*/
|
||||
@Valid
|
||||
private List<KeyValueParam> params;
|
||||
}
|
|
@ -2,6 +2,7 @@ package io.metersphere.project.service;
|
|||
|
||||
import io.metersphere.project.domain.CustomFunction;
|
||||
import io.metersphere.project.domain.CustomFunctionBlob;
|
||||
import io.metersphere.project.domain.CustomFunctionBlobExample;
|
||||
import io.metersphere.project.domain.CustomFunctionExample;
|
||||
import io.metersphere.project.dto.customfunction.CustomFunctionDTO;
|
||||
import io.metersphere.project.dto.customfunction.request.CustomFunctionPageRequest;
|
||||
|
@ -162,4 +163,23 @@ public class CustomFunctionService {
|
|||
}
|
||||
}
|
||||
|
||||
public List<CustomFunctionBlob> getBlobByIds(List<String> commonScriptIds) {
|
||||
if (CollectionUtils.isEmpty(commonScriptIds)) {
|
||||
return List.of();
|
||||
}
|
||||
CustomFunctionBlobExample example = new CustomFunctionBlobExample();
|
||||
example.createCriteria()
|
||||
.andIdIn(commonScriptIds);
|
||||
return customFunctionBlobMapper.selectByExampleWithBLOBs(example);
|
||||
}
|
||||
|
||||
public List<CustomFunction> getByIds(List<String> commonScriptIds) {
|
||||
if (CollectionUtils.isEmpty(commonScriptIds)) {
|
||||
return List.of();
|
||||
}
|
||||
CustomFunctionExample example = new CustomFunctionExample();
|
||||
example.createCriteria()
|
||||
.andIdIn(commonScriptIds);
|
||||
return customFunctionMapper.selectByExample(example);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import io.metersphere.project.dto.customfunction.request.CustomFunctionUpdateReq
|
|||
import io.metersphere.project.enums.result.ProjectResultCode;
|
||||
import io.metersphere.project.mapper.CustomFunctionBlobMapper;
|
||||
import io.metersphere.project.mapper.CustomFunctionMapper;
|
||||
import io.metersphere.project.service.CustomFunctionService;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
|
@ -29,6 +30,8 @@ import java.util.HashMap;
|
|||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author: LAN
|
||||
|
@ -54,7 +57,8 @@ public class CustomFunctionControllerTests extends BaseTest {
|
|||
|
||||
@Resource
|
||||
private CustomFunctionBlobMapper customFunctionBlobMapper;
|
||||
|
||||
@Resource
|
||||
private CustomFunctionService customFunctionService;
|
||||
|
||||
@Test
|
||||
@Order(1)
|
||||
|
@ -328,6 +332,16 @@ public class CustomFunctionControllerTests extends BaseTest {
|
|||
request.setFilter(filters);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(11)
|
||||
public void testUncoveredFunc() {
|
||||
// 在项目管理模块没有调用,手动调用
|
||||
customFunctionService.getBlobByIds(List.of());
|
||||
customFunctionService.getByIds(List.of());
|
||||
Assertions.assertEquals(customFunctionService.getBlobByIds(List.of(customFunction.getId())).size(), 1);
|
||||
Assertions.assertEquals(customFunctionService.getByIds(List.of(customFunction.getId())).size(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(12)
|
||||
public void testDel() throws Exception {
|
||||
|
@ -348,5 +362,4 @@ public class CustomFunctionControllerTests extends BaseTest {
|
|||
requestGetPermissionTest(PermissionConstants.PROJECT_CUSTOM_FUNCTION_DELETE, DELETE + "222");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import io.metersphere.project.api.assertion.*;
|
|||
import io.metersphere.project.api.assertion.body.*;
|
||||
import io.metersphere.project.api.processor.SQLProcessor;
|
||||
import io.metersphere.project.api.processor.ScriptProcessor;
|
||||
import io.metersphere.project.dto.CommonScriptInfo;
|
||||
import io.metersphere.project.dto.environment.*;
|
||||
import io.metersphere.project.dto.environment.auth.AuthConfig;
|
||||
import io.metersphere.project.dto.environment.common.CommonParams;
|
||||
|
@ -409,7 +410,8 @@ public class EnvironmentControllerTests extends BaseTest {
|
|||
assertions.add(responseTimeAssertion);
|
||||
|
||||
MsScriptAssertion scriptAssertion = new MsScriptAssertion();
|
||||
scriptAssertion.setScriptId("1111");
|
||||
scriptAssertion.setCommonScriptInfo(new CommonScriptInfo());
|
||||
scriptAssertion.getCommonScriptInfo().setId("1111");
|
||||
scriptAssertion.setScript("1111");
|
||||
scriptAssertion.setName("1111");
|
||||
assertions.add(scriptAssertion);
|
||||
|
@ -671,7 +673,7 @@ public class EnvironmentControllerTests extends BaseTest {
|
|||
//校验日志
|
||||
checkLog(response.getId(), OperationLogType.ADD);
|
||||
|
||||
//后置脚本 todo
|
||||
//后置脚本
|
||||
envConfig.setPostProcessorConfig(createEnvironmentProcessorConfig());
|
||||
request.setName("postScript");
|
||||
request.setConfig(envConfig);
|
||||
|
|
Loading…
Reference in New Issue