diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/BatchRunDefinitionRequest.java b/backend/src/main/java/io/metersphere/api/dto/definition/BatchRunDefinitionRequest.java index e9365139b9..396b922bf8 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/BatchRunDefinitionRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/BatchRunDefinitionRequest.java @@ -19,4 +19,6 @@ public class BatchRunDefinitionRequest { //测试计划报告ID。 测试计划执行时使用 private String planReportId; + + private String userId; } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/document/Document.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/document/Document.java index 0f6bef997f..c8b02b3e69 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/document/Document.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/document/Document.java @@ -81,7 +81,16 @@ public class Document { if (StringUtils.isEmpty(item.getGroupId())) { if (!item.getId().equals("root")) { if (parentNode != null) { - item.setJsonPath(parentNode.getJsonPath() + "." + item.getName()); + if (parentNode.getType().equals("array") && item.getType().equals("string")) { + try { + int index = StringUtils.isNotEmpty(item.getName()) ? Integer.parseInt(item.getName()) : 0; + item.setJsonPath(parentNode.getJsonPath() + "[" + index + "]"); + } catch (Exception e) { + item.setJsonPath(parentNode.getJsonPath() + "." + item.getName()); + } + } else { + item.setJsonPath(parentNode.getJsonPath() + "." + item.getName()); + } } else { item.setJsonPath("$." + item.getName()); } @@ -107,7 +116,16 @@ public class Document { for (DocumentElement item : dataList) { if (StringUtils.isEmpty(item.getGroupId())) { if (parentNode != null) { - item.setJsonPath(parentNode.getJsonPath() + "." + item.getName()); + if (StringUtils.equals(parentNode.getType(), "array") && item.getType().equals("string")) { + try { + int index = StringUtils.isNotEmpty(item.getName()) ? Integer.parseInt(item.getName()) : 0; + item.setJsonPath(parentNode.getJsonPath() + "[" + index + "]"); + } catch (Exception e) { + item.setJsonPath(parentNode.getJsonPath() + "." + item.getName()); + } + } else { + item.setJsonPath(parentNode.getJsonPath() + "." + item.getName()); + } } else { item.setJsonPath("$." + item.getName()); } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/document/DocumentElement.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/document/DocumentElement.java index 0f6a4ec0ba..8f0a02cca6 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/document/DocumentElement.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/document/DocumentElement.java @@ -46,12 +46,12 @@ public class DocumentElement { } } - public DocumentElement(String name, String type, Object expectedOutcome, boolean typeVerification, Listchildren) { + public DocumentElement(String name, String type, Object expectedOutcome, boolean include, List children) { this.id = UUID.randomUUID().toString(); this.name = name; this.expectedOutcome = expectedOutcome; this.type = type; - this.typeVerification = typeVerification; + this.include = include; this.children = children == null ? this.children = new LinkedList<>() : children; this.rowspan = 1; this.contentVerification = "value_eq"; @@ -62,6 +62,25 @@ public class DocumentElement { } } + + public DocumentElement(String name, String type, Object expectedOutcome, boolean typeVerification, boolean arrayVerification, List children) { + this.id = UUID.randomUUID().toString(); + this.name = name; + this.expectedOutcome = expectedOutcome; + this.type = type; + this.typeVerification = typeVerification; + this.arrayVerification = arrayVerification; + this.children = children == null ? this.children = new LinkedList<>() : children; + this.rowspan = 1; + this.contentVerification = "value_eq"; + if (StringUtils.equalsAny(type, "object", "array")) { + this.contentVerification = "none"; + } else if (expectedOutcome == null || StringUtils.isEmpty(expectedOutcome.toString())) { + this.contentVerification = "none"; + } + } + + public DocumentElement(String id, String name, String type, Object expectedOutcome, List children) { this.id = id; this.name = name; diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java index 1cfd86c207..3eca2e7a45 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java @@ -125,6 +125,7 @@ public class MsExtract extends MsTestElement { extractor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("JSONPostProcessorGui")); extractor.setRefNames(extractJSONPath.getVariable()); extractor.setJsonPathExpressions(extractJSONPath.getExpression()); + extractor.setComputeConcatenation(true); if (extractJSONPath.isMultipleMatching()) { extractor.setMatchNumbers("-1"); } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java index d8e3fffcc8..7ce147b894 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java @@ -677,7 +677,7 @@ public class MsHTTPSamplerProxy extends MsTestElement { try { String value = keyValue.getValue() != null && keyValue.getValue().startsWith("@") ? ScriptEngineUtils.buildFunctionCallString(keyValue.getValue()) : keyValue.getValue(); - value = keyValue.isUrlEncode() ? URLEncoder.encode(value, "utf-8") : value; + value = keyValue.isUrlEncode() ? "${__urlencode(" + value + ")}" : value; keyValueMap.put(keyValue.getName(), value); } catch (Exception e) { LogUtil.error(e); @@ -708,7 +708,7 @@ public class MsHTTPSamplerProxy extends MsTestElement { if (keyValue.getValue() != null) { try { String value = keyValue.getValue().startsWith("@") ? ScriptEngineUtils.buildFunctionCallString(keyValue.getValue()) : keyValue.getValue(); - value = keyValue.isUrlEncode() ? URLEncoder.encode(value, "utf-8") : value; + value = keyValue.isUrlEncode() ? "${__urlencode(" + value + ")}" : value; stringBuffer.append("=").append(value); } catch (Exception e) { LogUtil.error(e); @@ -726,7 +726,6 @@ public class MsHTTPSamplerProxy extends MsTestElement { filter(KeyValue::isEnable).forEach(keyValue -> { try { String value = StringUtils.isNotEmpty(keyValue.getValue()) && keyValue.getValue().startsWith("@") ? ScriptEngineUtils.buildFunctionCallString(keyValue.getValue()) : keyValue.getValue(); - value = keyValue.isUrlEncode() ? URLEncoder.encode(value, "utf-8") : value; HTTPArgument httpArgument = new HTTPArgument(keyValue.getName(), value); if (keyValue.getValue() == null) { httpArgument.setValue(""); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java index 7148d353f2..82cf1125ec 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java @@ -84,14 +84,14 @@ public class MsJDBCSampler extends MsTestElement { public void toHashTree(HashTree tree, List hashTree, MsParameter msParameter) { ParameterConfig config = (ParameterConfig) msParameter; // 非导出操作,且不是启用状态则跳过执行 - if (!config.isOperating() && !this.isEnable()) { + if (config != null && !config.isOperating() && !this.isEnable()) { return; } if (this.getReferenced() != null && MsTestElementConstants.REF.name().equals(this.getReferenced())) { this.setRefElement(); hashTree = this.getHashTree(); } - if (config.getConfig() == null) { + if (config != null && config.getConfig() == null) { // 单独接口执行 this.setProjectId(config.getProjectId()); config.setConfig(ElementUtil.getEnvironmentConfig(StringUtils.isNotEmpty(useEnvironment) ? useEnvironment : environmentId, this.getProjectId(), this.isMockEnvironment())); @@ -100,7 +100,7 @@ public class MsJDBCSampler extends MsTestElement { // 数据兼容处理 if (config.getConfig() != null && StringUtils.isNotEmpty(this.getProjectId()) && config.getConfig().containsKey(this.getProjectId())) { // 1.8 之后 当前正常数据 - } else if (config.getConfig() != null && config.getConfig().containsKey(getParentProjectId())) { + } else if ( config.getConfig() != null && config.getConfig().containsKey(getParentProjectId())) { // 1.8 前后 混合数据 this.setProjectId(getParentProjectId()); } else { @@ -153,62 +153,80 @@ public class MsJDBCSampler extends MsTestElement { tree.add(arguments); } - MsJSR223PreProcessor preProcessor = null; - MsJSR223PostProcessor postProcessor = null; - GlobalScriptConfig globalScriptConfig = null; - if(envConfig != null){ - preProcessor = envConfig.getPreProcessor(); - postProcessor = envConfig.getPostProcessor(); - globalScriptConfig = envConfig.getGlobalScriptConfig(); - } - boolean isPreScriptExecAfterPrivateScript = globalScriptConfig == null? false : globalScriptConfig.isPreScriptExecAfterPrivateScript(); - boolean isPostScriptExecAfterPrivateScript = globalScriptConfig == null? false : globalScriptConfig.isPostScriptExecAfterPrivateScript(); - boolean globalPreScriptIsFilter = false; - boolean globalPostScriptIsFilter = false; - List preFilterProtocal = globalScriptConfig == null? new ArrayList<>() : globalScriptConfig.getFilterRequestPreScript(); - List postFilterProtocal = globalScriptConfig == null? new ArrayList<>() : globalScriptConfig.getFilterRequestPostScript(); - if(preFilterProtocal.contains(GlobalScriptFilterRequest.JDBC.name())){ - globalPreScriptIsFilter = true; - } - if(postFilterProtocal.contains(GlobalScriptFilterRequest.JDBC.name())){ - globalPostScriptIsFilter = true; + // 环境通用请求头 + Arguments envArguments = getConfigArguments(config); + if (envArguments != null) { + tree.add(envArguments); } - if(!isPreScriptExecAfterPrivateScript && !globalPreScriptIsFilter){ - this.addItemHashTree(preProcessor,samplerHashTree,config); - } - if(!isPostScriptExecAfterPrivateScript && !globalPostScriptIsFilter){ - this.addItemHashTree(postProcessor,samplerHashTree,config); - } + MsJSR223PreProcessor preProcessor = envConfig != null ? envConfig.getPreProcessor() : null; + MsJSR223PostProcessor postProcessor = envConfig != null ? envConfig.getPostProcessor() : null; + GlobalScriptConfig globalScriptConfig = envConfig != null ? envConfig.getGlobalScriptConfig() : null; + if (globalScriptConfig != null) { + boolean isPreScriptExecAfterPrivateScript = globalScriptConfig.isPreScriptExecAfterPrivateScript(); + boolean isPostScriptExecAfterPrivateScript = globalScriptConfig.isPostScriptExecAfterPrivateScript(); + List preFilters = globalScriptConfig == null ? new ArrayList<>() : globalScriptConfig.getFilterRequestPreScript(); + List postFilters = globalScriptConfig == null ? new ArrayList<>() : globalScriptConfig.getFilterRequestPostScript(); + boolean globalPreScriptIsFilter = preFilters.contains(GlobalScriptFilterRequest.JDBC.name()); + boolean globalPostScriptIsFilter = postFilters.contains(GlobalScriptFilterRequest.JDBC.name()); + if (!isPreScriptExecAfterPrivateScript && !globalPreScriptIsFilter) { + this.addItemHashTree(preProcessor, samplerHashTree, config); + } + if (!isPostScriptExecAfterPrivateScript && !globalPostScriptIsFilter) { + this.addItemHashTree(postProcessor, samplerHashTree, config); + } + + if (isPreScriptExecAfterPrivateScript && !globalPreScriptIsFilter) { + this.addItemHashTree(preProcessor, samplerHashTree, config); + } + if (isPostScriptExecAfterPrivateScript && !globalPostScriptIsFilter) { + this.addItemHashTree(postProcessor, samplerHashTree, config); + } + } if (CollectionUtils.isNotEmpty(hashTree)) { hashTree.forEach(el -> { el.toHashTree(samplerHashTree, el.getHashTree(), config); }); } - if(isPreScriptExecAfterPrivateScript && !globalPreScriptIsFilter){ - this.addItemHashTree(preProcessor,samplerHashTree,config); - } - if(isPostScriptExecAfterPrivateScript && !globalPostScriptIsFilter){ - this.addItemHashTree(postProcessor,samplerHashTree,config); - } - } - private void addItemHashTree(MsTestElement element, HashTree samplerHashTree,ParameterConfig config){ - if(element != null){ - if (element.getEnvironmentId() == null) { - if (this.getEnvironmentId() == null) { - element.setEnvironmentId(useEnvironment); - } else { - element.setEnvironmentId(this.getEnvironmentId()); - } + private void addItemHashTree(MsTestElement element, HashTree samplerHashTree, ParameterConfig config) { + if (element != null && element.getEnvironmentId() == null) { + if (this.getEnvironmentId() == null) { + element.setEnvironmentId(useEnvironment); + } else { + element.setEnvironmentId(this.getEnvironmentId()); } element.toHashTree(samplerHashTree, element.getHashTree(), config); } } + /** + * 环境通用变量 + */ + private Arguments getConfigArguments(ParameterConfig config) { + Arguments arguments = new Arguments(); + arguments.setEnabled(true); + arguments.setName(StringUtils.isNotEmpty(this.getName()) ? this.getName() : "Arguments"); + arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName()); + arguments.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("ArgumentsPanel")); + // 环境通用变量 + if (config.isEffective(this.getProjectId()) && config.getConfig().get(this.getProjectId()).getCommonConfig() != null + && CollectionUtils.isNotEmpty(config.getConfig().get(this.getProjectId()).getCommonConfig().getVariables())) { + config.getConfig().get(this.getProjectId()).getCommonConfig().getVariables().stream().filter(KeyValue::isValid).filter(KeyValue::isEnable).forEach(keyValue -> + arguments.addArgument(keyValue.getName(), keyValue.getValue(), "=") + ); + // 清空变量,防止重复添加 + config.getConfig().get(this.getProjectId()).getCommonConfig().getVariables().clear(); + } + if (arguments.getArguments() != null && arguments.getArguments().size() > 0) { + return arguments; + } + return null; + } + private boolean isDataSource(List databaseConfigs) { List ids = databaseConfigs.stream().map(DatabaseConfig::getId).collect(Collectors.toList()); if (StringUtils.isNotEmpty(this.dataSourceId) && ids.contains(this.dataSourceId)) { diff --git a/backend/src/main/java/io/metersphere/api/dto/mock/MockApiUtils.java b/backend/src/main/java/io/metersphere/api/dto/mock/MockApiUtils.java index 195e74224d..8c75206225 100644 --- a/backend/src/main/java/io/metersphere/api/dto/mock/MockApiUtils.java +++ b/backend/src/main/java/io/metersphere/api/dto/mock/MockApiUtils.java @@ -26,36 +26,36 @@ import java.util.*; * @Date 2021/10/14 3:00 下午 */ public class MockApiUtils { - public static Map getHttpRequestHeader(HttpServletRequest request){ - Map returnMap = new HashMap<>(); + public static Map getHttpRequestHeader(HttpServletRequest request) { + Map returnMap = new HashMap<>(); Enumeration headers = request.getHeaderNames(); - while (headers.hasMoreElements()){ + while (headers.hasMoreElements()) { String header = headers.nextElement(); String headerValue = request.getHeader(header); - returnMap.put(header,headerValue); + returnMap.put(header, headerValue); } return returnMap; } public static boolean matchRequestHeader(JSONArray mockExpectHeaderArray, Map requestHeaderMap) { - Map mockExpectHeaders = new HashMap<>(); - for(int i = 0; i < mockExpectHeaderArray.size(); i++){ + Map mockExpectHeaders = new HashMap<>(); + for (int i = 0; i < mockExpectHeaderArray.size(); i++) { JSONObject obj = mockExpectHeaderArray.getJSONObject(i); - if(obj.containsKey("name") && obj.containsKey("value")){ - mockExpectHeaders.put(obj.getString("name"),obj.getString("value")); + if (obj.containsKey("name") && obj.containsKey("value")) { + mockExpectHeaders.put(obj.getString("name"), obj.getString("value")); } } - if(MapUtils.isEmpty(requestHeaderMap) && MapUtils.isNotEmpty(mockExpectHeaders)){ + if (MapUtils.isEmpty(requestHeaderMap) && MapUtils.isNotEmpty(mockExpectHeaders)) { return false; - }else { - for (Map.Entry entry: mockExpectHeaders.entrySet()){ + } else { + for (Map.Entry entry : mockExpectHeaders.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); - if(!requestHeaderMap.containsKey(key)){ + if (!requestHeaderMap.containsKey(key)) { return false; - }else { - if(!StringUtils.equals(value,requestHeaderMap.get(key))){ + } else { + if (!StringUtils.equals(value, requestHeaderMap.get(key))) { return false; } } @@ -81,8 +81,8 @@ public class MockApiUtils { String jsonString = ""; if (isJsonSchema) { - if (bodyObj.containsKey("jsonSchema") && bodyObj.getJSONObject("jsonSchema").containsKey("properties")) { - String bodyRetunStr = bodyObj.getJSONObject("jsonSchema").getJSONObject("properties").toJSONString(); + if (bodyObj.containsKey("jsonSchema")) { + String bodyRetunStr = bodyObj.getJSONObject("jsonSchema").toJSONString(); jsonString = JSONSchemaGenerator.getJson(bodyRetunStr); } } else { @@ -102,15 +102,15 @@ public class MockApiUtils { if (bodyObj.containsKey("raw")) { String xmlStr = bodyObj.getString("raw"); JSONObject matchObj = XMLUtils.XmlToJson(xmlStr); - returnJson = matchObj; + returnJson = matchObj; } - } else if (StringUtils.equalsIgnoreCase(type, "Raw")) { + } else if (StringUtils.equalsIgnoreCase(type, "Raw")) { if (bodyObj.containsKey("raw")) { String raw = bodyObj.getString("raw"); - if(StringUtils.isNotEmpty(raw)){ + if (StringUtils.isNotEmpty(raw)) { JSONObject rawObject = new JSONObject(); - rawObject.put("raw",raw); - returnJson = rawObject; + rawObject.put("raw", raw); + returnJson = rawObject; } } } else if (StringUtils.equalsAnyIgnoreCase(type, "Form Data", "WWW_FORM")) { @@ -132,13 +132,14 @@ public class MockApiUtils { bodyParamArr.put(kv.getString("name"), values); } } - returnJson = bodyParamArr; + returnJson = bodyParamArr; } } - }catch (Exception e){} + } catch (Exception e) { + } - return returnJson; + return returnJson; } public static JSONObject parseJsonSchema(JSONObject bodyReturnObj) { @@ -208,10 +209,10 @@ public class MockApiUtils { public static JSONObject getParamsByJSONArray(JSONArray array) { JSONObject returnObject = new JSONObject(); - for(int i = 0; i < array.size();i ++){ + for (int i = 0; i < array.size(); i++) { JSONObject obj = array.getJSONObject(i); - if(obj.containsKey("name") && obj.containsKey("value")){ - returnObject.put(obj.getString("name"),obj.getString("value")); + if (obj.containsKey("name") && obj.containsKey("value")) { + returnObject.put(obj.getString("name"), obj.getString("value")); } } return returnObject; @@ -220,7 +221,7 @@ public class MockApiUtils { public static Map getApiResponse(String response) { Map returnMap = new HashMap<>(); String returnStr = ""; - if(StringUtils.isNotEmpty(response)){ + if (StringUtils.isNotEmpty(response)) { try { JSONObject respObj = JSONObject.parseObject(response); if (respObj.containsKey("body")) { @@ -278,26 +279,26 @@ public class MockApiUtils { } } } - }catch (Exception e){ + } catch (Exception e) { MSException.throwException(e); } } - returnMap.put("returnMsg",returnStr); + returnMap.put("returnMsg", returnStr); return returnMap; } - public static String getResultByResponseResult(JSONObject bodyObj,String url, Map headerMap,RequestMockParams requestMockParams) { - if(headerMap == null){ + public static String getResultByResponseResult(JSONObject bodyObj, String url, Map headerMap, RequestMockParams requestMockParams) { + if (headerMap == null) { headerMap = new HashMap<>(); } - if(requestMockParams == null){ + if (requestMockParams == null) { requestMockParams = new RequestMockParams(); } - if(bodyObj == null && bodyObj.isEmpty()){ + if (bodyObj == null && bodyObj.isEmpty()) { return ""; - }else { + } else { String returnStr = ""; - if(bodyObj.containsKey("type")){ + if (bodyObj.containsKey("type")) { String type = bodyObj.getString("type"); if (StringUtils.equals(type, "JSON")) { //判断是否是JsonSchema @@ -320,17 +321,17 @@ public class MockApiUtils { returnStr = bodyObj.getString("raw"); } } - } else if(StringUtils.equalsAnyIgnoreCase(type,"Raw")){ + } else if (StringUtils.equalsAnyIgnoreCase(type, "Raw")) { if (bodyObj.containsKey("raw")) { String raw = bodyObj.getString("raw"); returnStr = raw; } - } else if(StringUtils.equalsAnyIgnoreCase(type,"XML")){ + } else if (StringUtils.equalsAnyIgnoreCase(type, "XML")) { if (bodyObj.containsKey("xmlHeader")) { String xmlHeader = bodyObj.getString("xmlHeader"); - if(!StringUtils.startsWith(xmlHeader,"")){ - returnStr = "\r\n"; - }else { + if (!StringUtils.startsWith(xmlHeader, "")) { + returnStr = "\r\n"; + } else { returnStr = xmlHeader; } } @@ -338,25 +339,25 @@ public class MockApiUtils { String raw = bodyObj.getString("xmlRaw"); returnStr = returnStr + raw; } - } else if(StringUtils.equalsAnyIgnoreCase(type,"fromApi")){ + } else if (StringUtils.equalsAnyIgnoreCase(type, "fromApi")) { if (bodyObj.containsKey("apiRspRaw")) { String raw = bodyObj.getString("apiRspRaw"); returnStr = raw; } - } else if(StringUtils.equalsAnyIgnoreCase(type,"script")){ + } else if (StringUtils.equalsAnyIgnoreCase(type, "script")) { if (bodyObj.containsKey("scriptObject")) { JSONObject scriptObj = bodyObj.getJSONObject("scriptObject"); String script = scriptObj.getString("script"); - String scriptLanguage =scriptObj.getString("scriptLanguage"); + String scriptLanguage = scriptObj.getString("scriptLanguage"); - String baseScript = parseScript(url,headerMap,requestMockParams); + String baseScript = parseScript(url, headerMap, requestMockParams); try { script = baseScript + script; - if(StringUtils.isEmpty(scriptLanguage)){ + if (StringUtils.isEmpty(scriptLanguage)) { scriptLanguage = "beanshell"; } - returnStr = runScript(script,scriptLanguage); - }catch (Exception e){ + returnStr = runScript(script, scriptLanguage); + } catch (Exception e) { LogUtil.error(e); } } @@ -367,58 +368,59 @@ public class MockApiUtils { } } - private static String parseScript(String url,Map headerMap,RequestMockParams requestMockParams) { + private static String parseScript(String url, Map headerMap, RequestMockParams requestMockParams) { StringBuffer scriptStringBuffer = new StringBuffer(); scriptStringBuffer.append("import java.util.HashMap;\n\n"); scriptStringBuffer.append("HashMap requestParams = new HashMap();\n"); - scriptStringBuffer.append("requestParams.put(\"address\",\""+url+"\");\n"); + scriptStringBuffer.append("requestParams.put(\"address\",\"" + url + "\");\n"); //写入请求头 - for (Map.Entry headEntry: headerMap.entrySet()){ + for (Map.Entry headEntry : headerMap.entrySet()) { String headerKey = headEntry.getKey(); String headerValue = headEntry.getValue(); - scriptStringBuffer.append("requestParams.put(\"header."+headerKey+"\",\""+headerValue+"\");\n"); + scriptStringBuffer.append("requestParams.put(\"header." + headerKey + "\",\"" + headerValue + "\");\n"); } //写入body参数 - if(requestMockParams.getBodyParams() != null){ - if(requestMockParams.getBodyParams().size() == 1){ + if (requestMockParams.getBodyParams() != null) { + if (requestMockParams.getBodyParams().size() == 1) { //参数是jsonObject JSONObject bodyParamObj = requestMockParams.getBodyParams().getJSONObject(0); - for(String key : bodyParamObj.keySet()){ + for (String key : bodyParamObj.keySet()) { String value = String.valueOf(bodyParamObj.get(key)); - value = StringUtils.replace(value,"\\","\\\\"); - value = StringUtils.replace(value,"\"","\\\""); - scriptStringBuffer.append("requestParams.put(\"body."+key+"\",\""+value+"\");\n"); - if(StringUtils.equalsIgnoreCase(key,"raw")){ - scriptStringBuffer.append("requestParams.put(\"bodyRaw\",\""+value+"\");\n"); + value = StringUtils.replace(value, "\\", "\\\\"); + value = StringUtils.replace(value, "\"", "\\\""); + scriptStringBuffer.append("requestParams.put(\"body." + key + "\",\"" + value + "\");\n"); + if (StringUtils.equalsIgnoreCase(key, "raw")) { + scriptStringBuffer.append("requestParams.put(\"bodyRaw\",\"" + value + "\");\n"); } } String jsonBody = bodyParamObj.toJSONString(); - jsonBody = StringUtils.replace(jsonBody,"\\","\\\\"); - jsonBody = StringUtils.replace(jsonBody,"\"","\\\""); - scriptStringBuffer.append("requestParams.put(\"body.json\",\""+jsonBody+"\");\n"); - }else { - scriptStringBuffer.append("requestParams.put(\"bodyRaw\",\""+requestMockParams.getBodyParams().toJSONString()+"\");\n"); + jsonBody = StringUtils.replace(jsonBody, "\\", "\\\\"); + jsonBody = StringUtils.replace(jsonBody, "\"", "\\\""); + scriptStringBuffer.append("requestParams.put(\"body.json\",\"" + jsonBody + "\");\n"); + } else { + scriptStringBuffer.append("requestParams.put(\"bodyRaw\",\"" + requestMockParams.getBodyParams().toJSONString() + "\");\n"); } } //写入query参数 - if(requestMockParams.getQueryParamsObj() != null){ + if (requestMockParams.getQueryParamsObj() != null) { JSONObject queryParamsObj = requestMockParams.getQueryParamsObj(); - for(String key : queryParamsObj.keySet()){ + for (String key : queryParamsObj.keySet()) { String value = String.valueOf(queryParamsObj.get(key)); - scriptStringBuffer.append("requestParams.put(\"query."+key+"\",\""+value+"\");\n"); + scriptStringBuffer.append("requestParams.put(\"query." + key + "\",\"" + value + "\");\n"); } } //写入rest参数 - if(requestMockParams.getRestParamsObj() != null){ + if (requestMockParams.getRestParamsObj() != null) { JSONObject restParamsObj = requestMockParams.getRestParamsObj(); - for(String key : restParamsObj.keySet()){ + for (String key : restParamsObj.keySet()) { String value = String.valueOf(restParamsObj.get(key)); - scriptStringBuffer.append("requestParams.put(\"rest."+key+"\",\""+value+"\");\n"); + scriptStringBuffer.append("requestParams.put(\"rest." + key + "\",\"" + value + "\");\n"); } } return scriptStringBuffer.toString(); } + private static String runScript(String script, String scriptLanguage) throws ScriptException { JSR223Sampler jmeterScriptSampler = new JSR223Sampler(); jmeterScriptSampler.setScriptLanguage(scriptLanguage); @@ -428,18 +430,18 @@ public class MockApiUtils { } - public static RequestMockParams getParams(String urlParams, String apiPath, JSONObject queryParamsObject,JSON paramJson){ - RequestMockParams returnParams = getGetParamMap(urlParams,apiPath,queryParamsObject); - if(paramJson != null){ + public static RequestMockParams getParams(String urlParams, String apiPath, JSONObject queryParamsObject, JSON paramJson) { + RequestMockParams returnParams = getGetParamMap(urlParams, apiPath, queryParamsObject); + if (paramJson != null) { if (paramJson instanceof JSONObject) { - if(!((JSONObject) paramJson).isEmpty()){ + if (!((JSONObject) paramJson).isEmpty()) { JSONArray paramsArray = new JSONArray(); paramsArray.add(paramJson); returnParams.setBodyParams(paramsArray); } } else if (paramJson instanceof JSONArray) { JSONArray paramArray = (JSONArray) paramJson; - if(!paramArray.isEmpty()){ + if (!paramArray.isEmpty()) { returnParams.setBodyParams(paramArray); } } @@ -447,7 +449,7 @@ public class MockApiUtils { return returnParams; } - public static JSONObject getParameterJsonObject(HttpServletRequest request){ + public static JSONObject getParameterJsonObject(HttpServletRequest request) { JSONObject queryParamsObject = new JSONObject(); Enumeration paramNameItor = request.getParameterNames(); while (paramNameItor.hasMoreElements()) { @@ -469,11 +471,11 @@ public class MockApiUtils { } public static JSON getPostParamMap(HttpServletRequest request) { - if (StringUtils.startsWithIgnoreCase(request.getContentType(),"application/JSON")) { + if (StringUtils.startsWithIgnoreCase(request.getContentType(), "application/JSON")) { JSON returnJson = null; try { String param = getRequestPostStr(request); - if(StringUtils.isNotEmpty(param)){ + if (StringUtils.isNotEmpty(param)) { JSONValidator jsonValidator = JSONValidator.from(param); if (StringUtils.equalsIgnoreCase("Array", jsonValidator.getType().name())) { returnJson = JSONArray.parseArray(param); @@ -485,7 +487,7 @@ public class MockApiUtils { LogUtil.error(e); } return returnJson; - } else if (StringUtils.startsWithIgnoreCase(request.getContentType(),"text/xml")) { + } else if (StringUtils.startsWithIgnoreCase(request.getContentType(), "text/xml")) { String xmlString = readXml(request); org.json.JSONObject xmlJSONObj = XML.toJSONObject(xmlString); @@ -496,7 +498,7 @@ public class MockApiUtils { } catch (Exception e) { } return object; - } else if (StringUtils.startsWithIgnoreCase( request.getContentType(),"application/x-www-form-urlencoded")) { + } else if (StringUtils.startsWithIgnoreCase(request.getContentType(), "application/x-www-form-urlencoded")) { JSONObject object = new JSONObject(); Enumeration paramNameItor = request.getParameterNames(); while (paramNameItor.hasMoreElements()) { @@ -505,19 +507,19 @@ public class MockApiUtils { object.put(key, value); } return object; - } else if (StringUtils.startsWithIgnoreCase(request.getContentType(),"text/plain")) { + } else if (StringUtils.startsWithIgnoreCase(request.getContentType(), "text/plain")) { JSONObject object = new JSONObject(); String bodyParam = readBody(request); - if(StringUtils.isNotEmpty(bodyParam)){ - object.put("raw",bodyParam); + if (StringUtils.isNotEmpty(bodyParam)) { + object.put("raw", bodyParam); } return object; } else { JSONObject object = new JSONObject(); String bodyParam = readBody(request); - if(StringUtils.isNotEmpty(bodyParam)){ - object.put("raw",bodyParam); + if (StringUtils.isNotEmpty(bodyParam)) { + object.put("raw", bodyParam); } return object; } @@ -548,6 +550,7 @@ public class MockApiUtils { } return returnJson; } + private static String readBody(HttpServletRequest request) { String result = ""; try { diff --git a/backend/src/main/java/io/metersphere/api/dto/scenario/Body.java b/backend/src/main/java/io/metersphere/api/dto/scenario/Body.java index 13e67872de..9ba783caa6 100644 --- a/backend/src/main/java/io/metersphere/api/dto/scenario/Body.java +++ b/backend/src/main/java/io/metersphere/api/dto/scenario/Body.java @@ -3,7 +3,7 @@ package io.metersphere.api.dto.scenario; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFeature; import io.metersphere.api.dto.scenario.request.BodyFile; -import io.metersphere.commons.json.JSONSchemaGenerator; +import io.metersphere.commons.json.JSONSchemaRunTest; import io.metersphere.commons.utils.FileUtils; import io.metersphere.jmeter.utils.ScriptEngineUtils; import lombok.Data; @@ -87,7 +87,7 @@ public class Body { if (StringUtils.isNotBlank(this.type) && StringUtils.equals(this.type, "JSON")) { if(StringUtils.isNotEmpty(this.format) && this.getJsonSchema() != null && "JSON-SCHEMA".equals(this.format)) { - this.raw = JSONSchemaGenerator.getJson(com.alibaba.fastjson.JSON.toJSONString(this.getJsonSchema())); + this.raw = JSONSchemaRunTest.getJson(com.alibaba.fastjson.JSON.toJSONString(this.getJsonSchema())); } else { // json 文本也支持 mock 参数 try { JSONObject jsonObject = com.alibaba.fastjson.JSON.parseObject(this.getRaw()); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiJmeterFileService.java b/backend/src/main/java/io/metersphere/api/service/ApiJmeterFileService.java index 308e381555..8e66039ea7 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiJmeterFileService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiJmeterFileService.java @@ -61,7 +61,7 @@ public class ApiJmeterFileService { if (StringUtils.isNotEmpty(testPlanScenarioId)) { // 获取场景用例单独的执行环境 TestPlanApiScenario planApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(testPlanScenarioId); - if(planApiScenario != null){ + if (planApiScenario != null) { String envType = planApiScenario.getEnvironmentType(); String environmentGroupId = planApiScenario.getEnvironmentGroupId(); String environment = planApiScenario.getEnvironment(); @@ -73,9 +73,9 @@ public class ApiJmeterFileService { } } HashTree hashTree; - if (ApiRunMode.DEFINITION.name().equals(runMode) || ApiRunMode.API_PLAN.name().equals(runMode) || ApiRunMode.MANUAL_PLAN.name().equals(runMode)) { + if (StringUtils.equalsAnyIgnoreCase(runMode, ApiRunMode.DEFINITION.name(), ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.MANUAL_PLAN.name())) { String testId = remoteTestId; - if(remoteTestId.contains(":")){ + if (remoteTestId.contains(":")) { //执行测试计划案例时会有拼接ID,ID为 planTestCaseId:测试计划报告ID testId = remoteTestId.split(":")[0]; } @@ -85,13 +85,15 @@ public class ApiJmeterFileService { if (item == null) { MSException.throwException("未找到执行场景。"); } - String envType = item.getEnvironmentType(); - String envJson = item.getEnvironmentJson(); - String envGroupId = item.getEnvironmentGroupId(); - if (StringUtils.equals(envType, EnvironmentType.JSON.name()) && StringUtils.isNotBlank(envJson)) { - planEnvMap = JSON.parseObject(envJson, Map.class); - } else if (StringUtils.equals(envType, EnvironmentType.GROUP.name()) && StringUtils.isNotBlank(envGroupId)) { - planEnvMap = environmentGroupProjectService.getEnvMap(envGroupId); + if (StringUtils.isBlank(testPlanScenarioId)) { + String envType = item.getEnvironmentType(); + String envJson = item.getEnvironmentJson(); + String envGroupId = item.getEnvironmentGroupId(); + if (StringUtils.equals(envType, EnvironmentType.JSON.name()) && StringUtils.isNotBlank(envJson)) { + planEnvMap = JSON.parseObject(envJson, Map.class); + } else if (StringUtils.equals(envType, EnvironmentType.GROUP.name()) && StringUtils.isNotBlank(envGroupId)) { + planEnvMap = environmentGroupProjectService.getEnvMap(envGroupId); + } } hashTree = apiAutomationService.generateHashTree(item, reportId, planEnvMap); } diff --git a/backend/src/main/java/io/metersphere/api/service/MockConfigService.java b/backend/src/main/java/io/metersphere/api/service/MockConfigService.java index 7f492c998f..4bcf49b976 100644 --- a/backend/src/main/java/io/metersphere/api/service/MockConfigService.java +++ b/backend/src/main/java/io/metersphere/api/service/MockConfigService.java @@ -116,25 +116,25 @@ public class MockConfigService { } } - public void initExpectNum(){ + public void initExpectNum() { MockExpectConfigExample example = new MockExpectConfigExample(); example.createCriteria().andExpectNumIsNull(); List mockExpectConfigList = mockExpectConfigMapper.selectByExampleWithBLOBs(example); - Map> mockConfigIdMap = mockExpectConfigList.stream().collect(Collectors.groupingBy(MockExpectConfig::getMockConfigId)); + Map> mockConfigIdMap = mockExpectConfigList.stream().collect(Collectors.groupingBy(MockExpectConfig::getMockConfigId)); for (Map.Entry> entry : mockConfigIdMap.entrySet()) { String mockConfigId = entry.getKey(); List list = entry.getValue(); String apiNum = extMockExpectConfigMapper.selectApiNumberByMockConfigId(mockConfigId); - if(StringUtils.isEmpty(apiNum) || StringUtils.equalsIgnoreCase(apiNum,"null")){ + if (StringUtils.isEmpty(apiNum) || StringUtils.equalsIgnoreCase(apiNum, "null")) { continue; } - int expectNumIndex = this.getMockExpectNumIndex(mockConfigId,apiNum); + int expectNumIndex = this.getMockExpectNumIndex(mockConfigId, apiNum); for (MockExpectConfigWithBLOBs config : list) { - config.setExpectNum(apiNum+"_"+expectNumIndex); + config.setExpectNum(apiNum + "_" + expectNumIndex); mockExpectConfigMapper.updateByPrimaryKeySelective(config); - expectNumIndex ++; + expectNumIndex++; } } @@ -211,17 +211,18 @@ public class MockConfigService { isSave = true; request.setId(UUID.randomUUID().toString()); } - //检查名称是否存在 if (request.getName() != null) { this.checkNameIsExists(request); } long timeStmp = System.currentTimeMillis(); - - String expectNum = this.getMockExpectId(request.getMockConfigId()); MockExpectConfigWithBLOBs model = new MockExpectConfigWithBLOBs(); + if (isSave) { + String expectNum = this.getMockExpectId(request.getMockConfigId()); + model.setExpectNum(expectNum); + } model.setId(request.getId()); - model.setExpectNum(expectNum); + model.setMockConfigId(request.getMockConfigId()); model.setUpdateTime(timeStmp); model.setStatus(request.getStatus()); @@ -253,46 +254,48 @@ public class MockConfigService { private String getMockExpectId(String mockConfigId) { List savedExpectNumber = extMockExpectConfigMapper.selectExlectNumByMockConfigId(mockConfigId); String apiNum = extMockExpectConfigMapper.selectApiNumberByMockConfigId(mockConfigId); - if(StringUtils.isEmpty(apiNum)){ + if (StringUtils.isEmpty(apiNum)) { apiNum = ""; - }else { + } else { apiNum = apiNum + "_"; } int index = 1; - for(String expectNum : savedExpectNumber){ - if(StringUtils.startsWith(expectNum,apiNum)){ - String numStr = StringUtils.substringAfter(expectNum,apiNum); - try{ + for (String expectNum : savedExpectNumber) { + if (StringUtils.startsWith(expectNum, apiNum)) { + String numStr = StringUtils.substringAfter(expectNum, apiNum); + try { int savedIndex = Integer.parseInt(numStr); - if(index <= savedIndex){ - index = savedIndex+1; + if (index <= savedIndex) { + index = savedIndex + 1; } - }catch (Exception ignored){} + } catch (Exception ignored) { + } } } return apiNum + index; } - private int getMockExpectNumIndex(String mockConfigId,String apiNumber) { + private int getMockExpectNumIndex(String mockConfigId, String apiNumber) { List savedExpectNumber = extMockExpectConfigMapper.selectExlectNumByMockConfigId(mockConfigId); String apiNum = apiNumber; - if(StringUtils.isEmpty(apiNum)){ + if (StringUtils.isEmpty(apiNum)) { apiNum = ""; - }else { + } else { apiNum = apiNum + "_"; } int index = 1; - for(String expectNum : savedExpectNumber){ - if(StringUtils.startsWith(expectNum,apiNum)){ - String numStr = StringUtils.substringAfter(expectNum,apiNum); - try{ + for (String expectNum : savedExpectNumber) { + if (StringUtils.startsWith(expectNum, apiNum)) { + String numStr = StringUtils.substringAfter(expectNum, apiNum); + try { int savedIndex = Integer.parseInt(numStr); - if(index <= savedIndex){ - index = savedIndex+1; + if (index <= savedIndex) { + index = savedIndex + 1; } - }catch (Exception ignored ){} + } catch (Exception ignored) { + } } } return index; @@ -369,34 +372,34 @@ public class MockConfigService { } } - if(expectParamsObj.containsKey("body")){ + if (expectParamsObj.containsKey("body")) { JSONObject expectBodyObject = expectParamsObj.getJSONObject("body"); JSON mockExpectJsonArray = MockApiUtils.getExpectBodyParams(expectBodyObject); JSONArray jsonArray = requestMockParams.getBodyParams(); if (mockExpectJsonArray instanceof JSONObject) { - if(!JsonStructUtils.checkJsonArrayCompliance(jsonArray, (JSONObject) mockExpectJsonArray)){ + if (!JsonStructUtils.checkJsonArrayCompliance(jsonArray, (JSONObject) mockExpectJsonArray)) { return false; } - }else if (mockExpectJsonArray instanceof JSONArray) { - if(!JsonStructUtils.checkJsonArrayCompliance(jsonArray, (JSONArray)mockExpectJsonArray)){ + } else if (mockExpectJsonArray instanceof JSONArray) { + if (!JsonStructUtils.checkJsonArrayCompliance(jsonArray, (JSONArray) mockExpectJsonArray)) { return false; } } } - if(expectParamsObj.containsKey("arguments")){ + if (expectParamsObj.containsKey("arguments")) { JSONArray argumentsArray = expectParamsObj.getJSONArray("arguments"); JSONObject urlRequestParamObj = MockApiUtils.getParamsByJSONArray(argumentsArray); - if(!JsonStructUtils.checkJsonObjCompliance(requestMockParams.getQueryParamsObj(), urlRequestParamObj)){ + if (!JsonStructUtils.checkJsonObjCompliance(requestMockParams.getQueryParamsObj(), urlRequestParamObj)) { return false; } } - if(expectParamsObj.containsKey("rest")){ + if (expectParamsObj.containsKey("rest")) { JSONArray restArray = expectParamsObj.getJSONArray("rest"); JSONObject restRequestParamObj = MockApiUtils.getParamsByJSONArray(restArray); - if(!JsonStructUtils.checkJsonObjCompliance(requestMockParams.getRestParamsObj(), restRequestParamObj)){ + if (!JsonStructUtils.checkJsonObjCompliance(requestMockParams.getRestParamsObj(), restRequestParamObj)) { return false; } } @@ -500,17 +503,17 @@ public class MockConfigService { boolean matchQuery = false; boolean matchBody = false; - if(requestMockParams.getQueryParamsObj() != null){ + if (requestMockParams.getQueryParamsObj() != null) { matchQuery = JsonStructUtils.checkJsonObjCompliance(requestMockParams.getQueryParamsObj(), mockExpectJson); } - if(requestMockParams.getRestParamsObj() != null){ + if (requestMockParams.getRestParamsObj() != null) { matchRest = JsonStructUtils.checkJsonObjCompliance(requestMockParams.getRestParamsObj(), mockExpectJson); } - if(requestMockParams.getBodyParams() != null){ - for (int i = 0;i < requestMockParams.getBodyParams().size(); i ++) { + if (requestMockParams.getBodyParams() != null) { + for (int i = 0; i < requestMockParams.getBodyParams().size(); i++) { JSONObject reqJsonObj = requestMockParams.getBodyParams().getJSONObject(i); matchBody = JsonStructUtils.checkJsonObjCompliance(reqJsonObj, mockExpectJson); - if(matchBody){ + if (matchBody) { break; } } @@ -764,7 +767,8 @@ public class MockConfigService { int httpCodeNum = 500; try { httpCodeNum = Integer.parseInt(responseJsonObj.getString("httpCode")); - }catch (Exception e){} + } catch (Exception e) { + } response.setStatus(httpCodeNum); } if (responseJsonObj.containsKey("delayed")) { @@ -979,6 +983,7 @@ public class MockConfigService { } mockConfigMapper.deleteByExample(configExample); } + public Map> getApiParamsByApiDefinitionBLOBs(ApiDefinitionWithBLOBs apiModel) { if (apiModel == null) { return new HashMap<>(); @@ -1016,7 +1021,7 @@ public class MockConfigService { model.setValue(item); list.add(model); }); - returnMap.put("value",list); + returnMap.put("value", list); return returnMap; } @@ -1085,32 +1090,32 @@ public class MockConfigService { } } - if(CollectionUtils.isNotEmpty(queryParamList)){ + if (CollectionUtils.isNotEmpty(queryParamList)) { List list = new ArrayList<>(); queryParamList.forEach(item -> { MockParamSuggestions model = new MockParamSuggestions(); model.setValue(item); list.add(model); }); - returnMap.put("query",list); + returnMap.put("query", list); } - if(CollectionUtils.isNotEmpty(restParamList)){ + if (CollectionUtils.isNotEmpty(restParamList)) { List list = new ArrayList<>(); restParamList.forEach(item -> { MockParamSuggestions model = new MockParamSuggestions(); model.setValue(item); list.add(model); }); - returnMap.put("rest",list); + returnMap.put("rest", list); } - if(CollectionUtils.isNotEmpty(formDataList)){ + if (CollectionUtils.isNotEmpty(formDataList)) { List list = new ArrayList<>(); formDataList.forEach(item -> { MockParamSuggestions model = new MockParamSuggestions(); model.setValue(item); list.add(model); }); - returnMap.put("form",list); + returnMap.put("form", list); } return returnMap; } @@ -1153,7 +1158,7 @@ public class MockConfigService { JSONObject parameterObject = MockApiUtils.getParameterJsonObject(request); for (ApiDefinitionWithBLOBs api : aualifiedApiList) { - RequestMockParams mockParams = MockApiUtils.getParams(urlSuffix, api.getPath(), parameterObject,paramJson); + RequestMockParams mockParams = MockApiUtils.getParams(urlSuffix, api.getPath(), parameterObject, paramJson); MockConfigResponse mockConfigData = this.findByApiId(api.getId()); MockExpectConfigResponse finalExpectConfig = this.findExpectConfig(requestHeaderMap, mockConfigData.getMockExpectConfigList(), mockParams); @@ -1223,7 +1228,7 @@ public class MockConfigService { JSONObject parameterObject = MockApiUtils.getParameterJsonObject(request); for (ApiDefinitionWithBLOBs api : aualifiedApiList) { - RequestMockParams paramMap = MockApiUtils.getParams(urlSuffix, api.getPath(), parameterObject,paramJson); + RequestMockParams paramMap = MockApiUtils.getParams(urlSuffix, api.getPath(), parameterObject, paramJson); MockConfigResponse mockConfigData = this.findByApiId(api.getId()); if (mockConfigData != null && mockConfigData.getMockExpectConfigList() != null) { @@ -1451,29 +1456,30 @@ public class MockConfigService { } public void updateMockReturnMsgByApi(ApiDefinitionWithBLOBs apiDefinitionWithBLOBs) { - if(apiDefinitionWithBLOBs == null){ + if (apiDefinitionWithBLOBs == null) { return; } Map returnMap = MockApiUtils.getApiResponse(apiDefinitionWithBLOBs.getResponse()); - if(MapUtils.isEmpty(returnMap) || !returnMap.containsKey("returnMsg")){ + if (MapUtils.isEmpty(returnMap) || !returnMap.containsKey("returnMsg")) { return; } List updateList = this.selectMockExpectConfigByApiId(apiDefinitionWithBLOBs.getId()); - if(CollectionUtils.isNotEmpty(updateList)){ - for (MockExpectConfigWithBLOBs model: updateList) { - if(StringUtils.isNotEmpty(model.getResponse())){ + if (CollectionUtils.isNotEmpty(updateList)) { + for (MockExpectConfigWithBLOBs model : updateList) { + if (StringUtils.isNotEmpty(model.getResponse())) { try { JSONObject responseObj = JSONObject.parseObject(model.getResponse()); - if(responseObj.containsKey("responseResult")){ + if (responseObj.containsKey("responseResult")) { JSONObject responseResultObject = responseObj.getJSONObject("responseResult"); - if(responseResultObject.containsKey("body")){ - responseResultObject.getJSONObject("body").put("apiRspRaw",returnMap.get("returnMsg")); + if (responseResultObject.containsKey("body")) { + responseResultObject.getJSONObject("body").put("apiRspRaw", returnMap.get("returnMsg")); model.setResponse(responseObj.toJSONString()); mockExpectConfigMapper.updateByPrimaryKeySelective(model); } } - }catch (Exception e){} + } catch (Exception e) { + } } } } diff --git a/backend/src/main/java/io/metersphere/commons/json/JSONSchemaGenerator.java b/backend/src/main/java/io/metersphere/commons/json/JSONSchemaGenerator.java index 59896093b8..fd423fb09d 100644 --- a/backend/src/main/java/io/metersphere/commons/json/JSONSchemaGenerator.java +++ b/backend/src/main/java/io/metersphere/commons/json/JSONSchemaGenerator.java @@ -172,11 +172,13 @@ public class JSONSchemaGenerator { List array = new LinkedList<>(); JsonArray jsonArray = new JsonArray(); - if (object.has("items") && object.get("items").isJsonArray()) { - jsonArray = object.get("items").getAsJsonArray(); - } else { - JsonObject itemsObject = object.get("items").getAsJsonObject(); - array.add(itemsObject); + if (object.has("items")) { + if(object.get("items").isJsonArray()){ + jsonArray = object.get("items").getAsJsonArray(); + }else { + JsonObject itemsObject = object.get("items").getAsJsonObject(); + array.add(itemsObject); + } } for (int i = 0; i < jsonArray.size(); i++) { diff --git a/backend/src/main/java/io/metersphere/commons/json/JSONSchemaRunTest.java b/backend/src/main/java/io/metersphere/commons/json/JSONSchemaRunTest.java new file mode 100644 index 0000000000..25cfc4e82f --- /dev/null +++ b/backend/src/main/java/io/metersphere/commons/json/JSONSchemaRunTest.java @@ -0,0 +1,229 @@ +package io.metersphere.commons.json; + +import com.alibaba.fastjson.JSONObject; +import com.google.gson.*; +import io.metersphere.commons.utils.LogUtil; +import io.metersphere.jmeter.utils.ScriptEngineUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.LinkedList; +import java.util.List; +import java.util.Map.Entry; + +public class JSONSchemaRunTest { + + private static void generator(String json, JSONObject obj) { + analyzeSchema(json, obj); + } + + private static void analyzeSchema(String json, JSONObject rootObj) { + try { + Gson gson = new Gson(); + JsonElement element = gson.fromJson(json, JsonElement.class); + JsonObject rootElement = element.getAsJsonObject(); + analyzeRootSchemaElement(rootElement, rootObj); + } catch (Exception e) { + LogUtil.error(e); + } + + } + + private static void analyzeRootSchemaElement(JsonObject rootElement, JSONObject rootObj) { + if (rootElement.has("type") || rootElement.has("allOf")) { + analyzeObject(rootElement, rootObj); + } + if (rootElement.has("definitions")) { + analyzeDefinitions(rootElement); + } + } + + private static void analyzeObject(JsonObject object, JSONObject rootObj) { + if (object.has("allOf")) { + JsonArray allOfArray = object.get("allOf").getAsJsonArray(); + for (JsonElement allOfElement : allOfArray) { + JsonObject allOfElementObj = allOfElement.getAsJsonObject(); + if (allOfElementObj.has("properties")) { + JsonObject propertiesObj = allOfElementObj.get("properties").getAsJsonObject(); + for (Entry entry : propertiesObj.entrySet()) { + String propertyKey = entry.getKey(); + JsonObject propertyObj = propertiesObj.get(propertyKey).getAsJsonObject(); + analyzeProperty(rootObj, propertyKey, propertyObj); + } + } + } + } else if (object.has("properties")) { + JsonObject propertiesObj = object.get("properties").getAsJsonObject(); + for (Entry entry : propertiesObj.entrySet()) { + String propertyKey = entry.getKey(); + JsonObject propertyObj = propertiesObj.get(propertyKey).getAsJsonObject(); + analyzeProperty(rootObj, propertyKey, propertyObj); + } + } else if (object.has("type") && object.get("type").getAsString().equals("array")) { + analyzeProperty(rootObj, "MS-OBJECT", object); + } else if (object.has("type") && !object.get("type").getAsString().equals("object")) { + analyzeProperty(rootObj, object.getAsString(), object); + } + } + + private static void analyzeProperty(JSONObject concept, String propertyName, JsonObject object) { + if (object.has("type")) { + String propertyObjType = null; + if (object.get("type") instanceof JsonPrimitive) { + propertyObjType = object.get("type").getAsString(); + } else if (object.get("type") instanceof JsonArray) { + JsonArray typeArray = (JsonArray) object.get("type").getAsJsonArray(); + propertyObjType = typeArray.get(0).getAsString(); + if (typeArray.size() > 1) { + if (typeArray.get(1).getAsString().equals("null")) { + // 暂不处理,后续使用时再加 + } + } + } + if (propertyObjType.equals("string") || propertyObjType.equals("enum")) { + concept.put(propertyName, getValue(object)); + } else if (propertyObjType.equals("integer") || propertyObjType.equals("number")) { + // 先设置空值 + concept.put(propertyName, 0); + try { + if (object.has("mock") && object.get("mock").getAsJsonObject() != null && StringUtils.isNotEmpty(object.get("mock").getAsJsonObject().get("mock").getAsString())) { + Number value = object.get("mock").getAsJsonObject().get("mock").getAsNumber(); + if (value.toString().indexOf(".") == -1) { + concept.put(propertyName, value.intValue()); + } else { + concept.put(propertyName, value.floatValue()); + } + } + } catch (Exception e) { + String value = ScriptEngineUtils.buildFunctionCallString(object.get("mock").getAsJsonObject().get("mock").getAsString()); + concept.put(propertyName, value); + } + } else if (propertyObjType.equals("boolean")) { + // 先设置空值 + concept.put(propertyName, false); + try { + if (object.has("mock") && object.get("mock").getAsJsonObject() != null && StringUtils.isNotEmpty(object.get("mock").getAsJsonObject().get("mock").getAsString())) { + String value = ScriptEngineUtils.buildFunctionCallString(object.get("mock").getAsJsonObject().get("mock").toString()); + if (StringUtils.isNotEmpty(value)) { + if (value.indexOf("\"") != -1) { + value = value.replaceAll("\"", ""); + } + concept.put(propertyName, Boolean.valueOf(value)); + } + } + } catch (Exception e) { + concept.put(propertyName, false); + } + } else if (propertyObjType.equals("array")) { + // 先设置空值 + List array = new LinkedList<>(); + + JsonArray jsonArray = new JsonArray(); + if (object.has("items")) { + if (object.get("items").isJsonArray()) { + jsonArray = object.get("items").getAsJsonArray(); + } else { + JsonObject itemsObject = object.get("items").getAsJsonObject(); + array.add(itemsObject); + } + } + + for (int i = 0; i < jsonArray.size(); i++) { + JsonObject itemsObject = jsonArray.get(i).getAsJsonObject(); + if (object.has("items")) { + if (itemsObject.has("mock") && itemsObject.get("mock").getAsJsonObject() != null && StringUtils.isNotEmpty(itemsObject.get("mock").getAsJsonObject().get("mock").getAsString())) { + try { + int value = itemsObject.get("mock").getAsJsonObject().get("mock").getAsInt(); + array.add(value); + } catch (Exception e) { + String value = ScriptEngineUtils.buildFunctionCallString(itemsObject.get("mock").getAsJsonObject().get("mock").getAsString()); + array.add(value); + } + } else if (itemsObject.has("type") && (itemsObject.has("enum") || itemsObject.get("type").getAsString().equals("string"))) { + array.add(getValue(itemsObject)); + } else if (itemsObject.has("type") && itemsObject.get("type").getAsString().equals("number")) { + if (itemsObject.has("mock") && itemsObject.get("mock").getAsJsonObject() != null && StringUtils.isNotEmpty(itemsObject.get("mock").getAsJsonObject().get("mock").getAsString())) { + String value = ScriptEngineUtils.buildFunctionCallString(itemsObject.get("mock").getAsJsonObject().get("mock").getAsString()); + array.add(value); + } else { + array.add(0); + } + } else if (itemsObject.has("properties")) { + JSONObject propertyConcept = new JSONObject(true); + JsonObject propertiesObj = itemsObject.get("properties").getAsJsonObject(); + for (Entry entry : propertiesObj.entrySet()) { + String propertyKey = entry.getKey(); + JsonObject propertyObj = propertiesObj.get(propertyKey).getAsJsonObject(); + analyzeProperty(propertyConcept, propertyKey, propertyObj); + } + array.add(propertyConcept); + + } else if (itemsObject.has("type") && itemsObject.get("type") instanceof JsonPrimitive) { + JSONObject newJsonObj = new JSONObject(); + analyzeProperty(newJsonObj, propertyName + "_item", itemsObject); + array.add(newJsonObj.get(propertyName + "_item")); + } + } else if (object.has("items") && object.get("items").isJsonArray()) { + JsonArray itemsObjectArray = object.get("items").getAsJsonArray(); + array.add(itemsObjectArray); + } + } + concept.put(propertyName, array); + } else if (propertyObjType.equals("object")) { + JSONObject obj = new JSONObject(); + concept.put(propertyName, obj); + analyzeObject(object, obj); + } else if (StringUtils.equalsIgnoreCase(propertyObjType, "null")) { + concept.put(propertyName, null); + } + } + } + + private static Object getValue(JsonObject object) { + try { + if (object.has("mock") && object.get("mock").getAsJsonObject() != null && StringUtils.isNotEmpty(object.get("mock").getAsJsonObject().get("mock").getAsString()) && StringUtils.isNotEmpty(object.get("mock").getAsJsonObject().get("mock").getAsString())) { + String value = ScriptEngineUtils.buildFunctionCallString(object.get("mock").getAsJsonObject().get("mock").getAsString()); + return value; + } + } catch (Exception e) { + return object.get("mock").getAsJsonObject().get("mock"); + } + return ""; + } + + private static void analyzeDefinitions(JsonObject object) { + JsonObject definitionsObj = object.get("definitions").getAsJsonObject(); + for (Entry entry : definitionsObj.entrySet()) { + String definitionKey = entry.getKey(); + JsonObject definitionObj = definitionsObj.get(definitionKey).getAsJsonObject(); + JSONObject obj = new JSONObject(); + analyzeRootSchemaElement(definitionObj, obj); + } + } + + + private static String formerJson(String jsonSchema) { + try { + JSONObject root = new JSONObject(true); + generator(jsonSchema, root); + // 格式化返回 + Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().disableHtmlEscaping().create(); + if (root.get("MS-OBJECT") != null) { + return gson.toJson(root.get("MS-OBJECT")); + } + return gson.toJson(root); + } catch (Exception e) { + return jsonSchema; + } + } + + public static String getJson(String jsonSchema) { + try { + if (StringUtils.isEmpty(jsonSchema)) { + return null; + } + return formerJson(jsonSchema); + } catch (Exception ex) { + return jsonSchema; + } + } +} diff --git a/backend/src/main/java/io/metersphere/commons/json/JSONSchemaToDocumentUtils.java b/backend/src/main/java/io/metersphere/commons/json/JSONSchemaToDocumentUtils.java index a80d424cd1..985e7bfc57 100644 --- a/backend/src/main/java/io/metersphere/commons/json/JSONSchemaToDocumentUtils.java +++ b/backend/src/main/java/io/metersphere/commons/json/JSONSchemaToDocumentUtils.java @@ -74,7 +74,7 @@ public class JSONSchemaToDocumentUtils { Object value = null; boolean required = requiredList.contains(propertyName); if (object.has("default")) { - value = object.get("default") != null ? object.get("default").toString() : ""; + value = object.get("default") != null ? object.get("default").getAsString() : ""; concept.add(new DocumentElement(propertyName, propertyObjType, value, required, null)); } else if (object.has("enum")) { try { @@ -97,7 +97,7 @@ public class JSONSchemaToDocumentUtils { } else if (propertyObjType.equals("string")) { // 先设置空值 if (object.has("default")) { - value = object.get("default") != null ? object.get("default").toString() : ""; + value = object.get("default") != null ? object.get("default").getAsString() : ""; } if (object.has("mock") && object.get("mock").getAsJsonObject() != null && StringUtils.isNotEmpty(object.get("mock").getAsJsonObject().get("mock").getAsString()) && StringUtils.isNotEmpty(object.get("mock").getAsJsonObject().get("mock").getAsString())) { value = ScriptEngineUtils.buildFunctionCallString(object.get("mock").getAsJsonObject().get("mock").getAsString()); @@ -140,7 +140,7 @@ public class JSONSchemaToDocumentUtils { concept.add(new DocumentElement(propertyName, propertyObjType, value, required, null)); } else if (propertyObjType.equals("array")) { List elements = new LinkedList<>(); - concept.add(new DocumentElement(propertyName, propertyObjType, "", requiredList.contains(propertyName), elements)); + concept.add(new DocumentElement(propertyName, propertyObjType, "", requiredList.contains(propertyName), true, elements)); JsonArray jsonArray = object.get("items").getAsJsonArray(); analyzeArray(propertyName, jsonArray, elements, requiredList); } else if (propertyObjType.equals("object")) { diff --git a/backend/src/main/java/io/metersphere/commons/utils/JsonStructUtils.java b/backend/src/main/java/io/metersphere/commons/utils/JsonStructUtils.java index a787ba7eaf..7a5980d20e 100644 --- a/backend/src/main/java/io/metersphere/commons/utils/JsonStructUtils.java +++ b/backend/src/main/java/io/metersphere/commons/utils/JsonStructUtils.java @@ -167,14 +167,19 @@ public class JsonStructUtils { return false; } else { for (int i = 0; i < matchArr.size(); i++) { - for (int j = i; j < sourceArr.size(); j++) { + boolean finalChack = false; + sourceForeach:for (int j = i; j < sourceArr.size(); j++) { Object matchItemObj = matchArr.get(i); Object sourceItemObj = sourceArr.get(j); boolean check = checkObjCompliance(sourceItemObj, matchItemObj); - if (!check) { - return check; + if (check) { + finalChack = true; + break; } } + if(!finalChack){ + return false; + } } return true; } diff --git a/backend/src/main/java/io/metersphere/controller/request/MdUploadRequest.java b/backend/src/main/java/io/metersphere/controller/request/MdUploadRequest.java index de2609fdcd..d91500bbb1 100644 --- a/backend/src/main/java/io/metersphere/controller/request/MdUploadRequest.java +++ b/backend/src/main/java/io/metersphere/controller/request/MdUploadRequest.java @@ -7,4 +7,5 @@ import lombok.Setter; @Setter public class MdUploadRequest { private String id; + private String fileName; } diff --git a/backend/src/main/java/io/metersphere/service/ResourceService.java b/backend/src/main/java/io/metersphere/service/ResourceService.java index 5bd34eb452..ebe96360dd 100644 --- a/backend/src/main/java/io/metersphere/service/ResourceService.java +++ b/backend/src/main/java/io/metersphere/service/ResourceService.java @@ -11,6 +11,8 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; import java.util.Date; @Service @@ -18,14 +20,20 @@ import java.util.Date; public class ResourceService { public void mdUpload(MdUploadRequest request, MultipartFile file) { - FileUtils.uploadFile(file, FileUtils.MD_IMAGE_DIR, request.getId() + "_" + file.getOriginalFilename()); + FileUtils.uploadFile(file, FileUtils.MD_IMAGE_DIR, request.getId() + "_" + request.getFileName()); } public ResponseEntity getMdImage(String name) { File file = new File(FileUtils.MD_IMAGE_DIR + "/" + name); HttpHeaders headers = new HttpHeaders(); + String fileName = ""; + try { + fileName = URLEncoder.encode(file.getName(), "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } headers.add("Cache-Control", "no-cache, no-store, must-revalidate"); - headers.add("Content-Disposition", "attachment; filename=" + file.getName()); + headers.add("Content-Disposition", "attachment; filename=" + fileName); headers.add("Pragma", "no-cache"); headers.add("Expires", "0"); headers.add("Last-Modified", new Date().toString()); diff --git a/backend/src/main/java/io/metersphere/track/issue/AbstractIssuePlatform.java b/backend/src/main/java/io/metersphere/track/issue/AbstractIssuePlatform.java index 37d0310ae2..b124e0e206 100644 --- a/backend/src/main/java/io/metersphere/track/issue/AbstractIssuePlatform.java +++ b/backend/src/main/java/io/metersphere/track/issue/AbstractIssuePlatform.java @@ -175,7 +175,6 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform { } protected void handleTestCaseIssues(IssuesUpdateRequest issuesRequest) { - if (!issuesRequest.isWithCaseId()) return; String issuesId = issuesRequest.getId(); if (StringUtils.isNotBlank(issuesRequest.getTestCaseId())) { insertTestCaseIssues(issuesId, issuesRequest.getTestCaseId()); diff --git a/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java b/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java index dcf99a56fa..8a1c750cc4 100644 --- a/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java +++ b/backend/src/main/java/io/metersphere/track/issue/ZentaoPlatform.java @@ -172,6 +172,8 @@ public class ZentaoPlatform extends AbstractIssuePlatform { // 用例与第三方缺陷平台中的缺陷关联 handleTestCaseIssues(issuesRequest); + } else { + MSException.throwException("请确认该Zentao账号是否开启超级modle调用接口权限"); } return issues; } @@ -235,7 +237,7 @@ public class ZentaoPlatform extends AbstractIssuePlatform { @Override public void userAuth(UserDTO.PlatformInfo userInfo) { - setUserConfig(); + setUserConfig(userInfo); zentaoClient.login(); } diff --git a/backend/src/main/java/io/metersphere/track/request/testcase/IssuesUpdateRequest.java b/backend/src/main/java/io/metersphere/track/request/testcase/IssuesUpdateRequest.java index 95bac724f1..8c1c145e84 100644 --- a/backend/src/main/java/io/metersphere/track/request/testcase/IssuesUpdateRequest.java +++ b/backend/src/main/java/io/metersphere/track/request/testcase/IssuesUpdateRequest.java @@ -12,8 +12,6 @@ public class IssuesUpdateRequest extends IssuesWithBLOBs { private String content; private String testCaseId; private String workspaceId; - // 带caseId的更新, 默认更新是同时保存用例的关联关系,脑图保存缺陷,不带caseId - private boolean withCaseId = true; private List tapdUsers; /** diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java index 32def2db8f..63389507d3 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java @@ -396,9 +396,14 @@ public class TestPlanApiCaseService { if (request.getConfig() != null && StringUtils.isNotEmpty(request.getConfig().getResourcePoolId())) { apiResult.setActuator(request.getConfig().getResourcePoolId()); } - if (SessionUtils.getUser() != null) { - apiResult.setUserId(SessionUtils.getUser().getId()); + if(StringUtils.isEmpty(request.getUserId())){ + if (SessionUtils.getUser() != null) { + apiResult.setUserId(SessionUtils.getUser().getId()); + } + }else { + apiResult.setUserId(request.getUserId()); } + apiResult.setResourceId(key.getApiCaseId()); apiResult.setStartTime(System.currentTimeMillis()); apiResult.setType(ApiRunMode.API_PLAN.name()); diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanLoadCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanLoadCaseService.java index e5581e0505..c8b94cf828 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanLoadCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanLoadCaseService.java @@ -80,7 +80,8 @@ public class TestPlanLoadCaseService { public List list(LoadCaseRequest request) { request.setOrders(ServiceUtils.getDefaultSortOrder(request.getOrders())); - return extTestPlanLoadCaseMapper.selectTestPlanLoadCaseList(request); + List testPlanLoadCaseDTOList = extTestPlanLoadCaseMapper.selectTestPlanLoadCaseList(request); + return testPlanLoadCaseDTOList; } public List selectTestPlanLoadCaseIds(LoadCaseRequest request) { @@ -155,7 +156,7 @@ public class TestPlanLoadCaseService { if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) { serialRun(request); } else { - ExecutorService executorService = Executors.newFixedThreadPool(request.getRequests().size(),new NamedThreadFactory("TestPlanLoadCaseService")); + ExecutorService executorService = Executors.newFixedThreadPool(request.getRequests().size(), new NamedThreadFactory("TestPlanLoadCaseService")); request.getRequests().forEach(item -> { executorService.submit(new ParallelExecTask(performanceTestService, testPlanLoadCaseMapper, item)); }); @@ -170,7 +171,7 @@ public class TestPlanLoadCaseService { } private void serialRun(RunBatchTestPlanRequest request) throws Exception { - ExecutorService executorService = Executors.newFixedThreadPool(request.getRequests().size(),new NamedThreadFactory("TestPlanLoadCaseService-serial")); + ExecutorService executorService = Executors.newFixedThreadPool(request.getRequests().size(), new NamedThreadFactory("TestPlanLoadCaseService-serial")); for (RunTestPlanRequest runTestPlanRequest : request.getRequests()) { Future future = executorService.submit(new SerialExecTask(performanceTestService, testPlanLoadCaseMapper, loadTestReportMapper, runTestPlanRequest, request.getConfig())); LoadTestReportWithBLOBs report = future.get(); @@ -378,8 +379,8 @@ public class TestPlanLoadCaseService { return buildCases(cases); } - public List getAllCases(Collection ids,String planId,String status) { - List cases = extTestPlanLoadCaseMapper.getCasesByIds(ids,planId, status); + public List getAllCases(Collection ids, String planId, String status) { + List cases = extTestPlanLoadCaseMapper.getCasesByIds(ids, planId, status); return buildCases(cases); } @@ -438,6 +439,7 @@ public class TestPlanLoadCaseService { /** * 用例自定义排序 + * * @param request */ public void updateOrder(ResetOrderRequest request) { @@ -450,7 +452,7 @@ public class TestPlanLoadCaseService { public void checkStatusByDeleteLoadCaseReportId(String reportId) { List updatedId = extTestPlanLoadCaseMapper.selectIdByLoadCaseReportIdAndStatusIsRun(reportId); - if(CollectionUtils.isNotEmpty(updatedId)){ + if (CollectionUtils.isNotEmpty(updatedId)) { for (String id : updatedId) { extTestPlanLoadCaseMapper.updateStatusNullById(id); } diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java index 8277059df0..f229abd377 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java @@ -1171,13 +1171,17 @@ public class TestPlanReportService { if (StringUtils.isNotBlank(testPlanReportContent.getScenarioAllCases())) { List allCases = JSONObject.parseArray(testPlanReportContent.getScenarioAllCases(), TestPlanFailureScenarioDTO.class); for (TestPlanFailureScenarioDTO dto : allCases) { - if (StringUtils.equalsIgnoreCase(dto.getLastResult(), "Underway")) { + if (StringUtils.equalsAnyIgnoreCase("Underway",dto.getStatus(), dto.getLastResult())) { isUpdate = true; ApiScenarioReport apiReport = apiScenarioReportMapper.selectByPrimaryKey(dto.getReportId()); if (apiReport != null) { dto.setLastResult(apiReport.getStatus()); dto.setStatus(apiReport.getStatus()); } + }else if (StringUtils.equalsAnyIgnoreCase("Error",dto.getStatus(), dto.getLastResult())) { + isUpdate = true; + dto.setLastResult("Fail"); + dto.setStatus("Fail"); } } testPlanReportContent.setScenarioAllCases(JSONArray.toJSONString(allCases)); diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanScenarioCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanScenarioCaseService.java index 13583b72cc..0e90809af0 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanScenarioCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanScenarioCaseService.java @@ -500,7 +500,7 @@ public class TestPlanScenarioCaseService { String defaultStatus = "Running"; if(isFinish){ - defaultStatus = "Error"; + defaultStatus = "Fail"; } Map reportStatus = apiScenarioReportService.getReportStatusByReportIds(idMap.values()); for (TestPlanFailureScenarioDTO dto: apiTestCases) { @@ -510,10 +510,14 @@ public class TestPlanScenarioCaseService { String status = reportStatus.get(reportId); if(status == null ){ status = defaultStatus; + }else { + if(StringUtils.equalsIgnoreCase(status,"Error")){ + status = "Fail"; + } } dto.setLastResult(status); + dto.setStatus(status); } - } return buildCases(apiTestCases); } diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java index 5bb028631a..cdf9484473 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java @@ -1087,7 +1087,7 @@ public class TestPlanService { } @Transactional(propagation = Propagation.NOT_SUPPORTED) - TestPlanScheduleReportInfoDTO genTestPlanReport(String projectID, String planId, String userId, String triggerMode){ + TestPlanScheduleReportInfoDTO genTestPlanReport(String projectID, String planId, String userId, String triggerMode) { TestPlanScheduleReportInfoDTO reportInfoDTO = testPlanReportService.genTestPlanReportBySchedule(projectID, planId, userId, triggerMode); return reportInfoDTO; } @@ -1181,14 +1181,14 @@ public class TestPlanService { } catch (Exception e) { LogUtil.error(e); } - performaneThreadIDMap.put(performanceRequest.getTestPlanLoadId(),reportId); + performaneThreadIDMap.put(performanceRequest.getTestPlanLoadId(), reportId); if (StringUtils.isNotEmpty(reportId)) { executePerformanceIdMap.put(caseID, TestPlanApiExecuteStatus.RUNNING.name()); } else { executePerformanceIdMap.put(caseID, TestPlanApiExecuteStatus.PREPARE.name()); } } - TestPlanReportExecuteCatch.updateTestPlanThreadInfo(planReportId,null,null,performaneThreadIDMap); + TestPlanReportExecuteCatch.updateTestPlanThreadInfo(planReportId, null, null, performaneThreadIDMap); if (!performaneReportIDMap.isEmpty()) { //性能测试时保存性能测试报告ID,在结果返回时用于捕捉并进行 testPlanReportService.updatePerformanceInfo(testPlanReport, performaneReportIDMap, triggerMode); @@ -1205,7 +1205,7 @@ public class TestPlanService { testPlanLog.info("ReportId[" + planReportId + "] start run. TestPlanID:[" + testPlanID + "]. Execute api :" + JSONObject.toJSONString(executeApiCaseIdMap) + "; Execute scenario:" + JSONObject.toJSONString(executeScenarioCaseIdMap) + "; Execute performance:" + JSONObject.toJSONString(executePerformanceIdMap)); TestPlanReportExecuteCatch.updateApiTestPlanExecuteInfo(planReportId, executeApiCaseIdMap, executeScenarioCaseIdMap, executePerformanceIdMap); //执行接口案例任务 - this.executeApiTestCase(triggerMode, planReportId, new ArrayList<>(planApiCaseMap.keySet()), runModeConfig); + this.executeApiTestCase(triggerMode, planReportId, userId, new ArrayList<>(planApiCaseMap.keySet()), runModeConfig); //执行场景执行任务 this.executeScenarioCase(planReportId, testPlanID, projectID, runModeConfig, triggerMode, userId, planScenarioIdsMap); this.listenTaskExecuteStatus(planReportId); @@ -1227,11 +1227,9 @@ public class TestPlanService { }); } - private void executeApiTestCase(String triggerMode, String planReportId, List planCaseIds, RunModeConfig runModeConfig) { + private void executeApiTestCase(String triggerMode, String planReportId, String userId, List planCaseIds, RunModeConfig runModeConfig) { executorService.submit(() -> { BatchRunDefinitionRequest request = new BatchRunDefinitionRequest(); -// List planIdList = new ArrayList<>(1); -// planIdList.add(testPlanId); if (StringUtils.equals(triggerMode, ReportTriggerMode.API.name())) { request.setTriggerMode(ApiRunMode.JENKINS_API_PLAN.name()); } else if (StringUtils.equals(triggerMode, ReportTriggerMode.MANUAL.name())) { @@ -1239,10 +1237,10 @@ public class TestPlanService { } else { request.setTriggerMode(ApiRunMode.SCHEDULE_API_PLAN.name()); } - request.setPlanIds(planCaseIds); request.setPlanReportId(planReportId); request.setConfig(runModeConfig); + request.setUserId(userId); testPlanApiCaseService.run(request); }); } @@ -1502,7 +1500,7 @@ public class TestPlanService { continue; } if ((StringUtils.equals(envType, EnvironmentType.JSON.name()) && StringUtils.isBlank(env)) - || StringUtils.equals(envType, EnvironmentType.GROUP.name()) && StringUtils.isBlank(envGroupId)) { + || StringUtils.equals(envType, EnvironmentType.GROUP.name()) && StringUtils.isBlank(envGroupId)) { continue; } Map map = new HashMap<>(); @@ -1746,7 +1744,7 @@ public class TestPlanService { } } - public void buildApiReport(TestPlanSimpleReportDTO report, JSONObject config, TestPlanExecuteInfo executeInfo,boolean isFinish) { + public void buildApiReport(TestPlanSimpleReportDTO report, JSONObject config, TestPlanExecuteInfo executeInfo, boolean isFinish) { if (MapUtils.isEmpty(executeInfo.getApiCaseExecInfo()) && MapUtils.isEmpty(executeInfo.getApiScenarioCaseExecInfo())) { return; } @@ -1756,12 +1754,12 @@ public class TestPlanService { if (checkReportConfig(config, "api", "all")) { if (MapUtils.isNotEmpty(executeInfo.getApiCaseExecInfo())) { // 接口 - apiAllCases = testPlanApiCaseService.getByApiExecReportIds(executeInfo.getApiCaseExecuteThreadMap(),isFinish); + apiAllCases = testPlanApiCaseService.getByApiExecReportIds(executeInfo.getApiCaseExecuteThreadMap(), isFinish); report.setApiAllCases(apiAllCases); } if (MapUtils.isNotEmpty(executeInfo.getApiScenarioCaseExecInfo())) { //场景 - scenarioAllCases = testPlanScenarioCaseService.getAllCases(executeInfo.getApiScenarioThreadMap(),isFinish); + scenarioAllCases = testPlanScenarioCaseService.getAllCases(executeInfo.getApiScenarioThreadMap(), isFinish); report.setScenarioAllCases(scenarioAllCases); } } diff --git a/frontend/src/business/components/api/automation/report/SysnApiReportDetail.vue b/frontend/src/business/components/api/automation/report/SysnApiReportDetail.vue index 8362ad3084..c2ec7beb30 100644 --- a/frontend/src/business/components/api/automation/report/SysnApiReportDetail.vue +++ b/frontend/src/business/components/api/automation/report/SysnApiReportDetail.vue @@ -132,6 +132,13 @@ export default { this.formatContent(this.scenario.scenarioDefinition.hashTree, obj); this.fullTreeNodes.push(obj); }, + compare(){ + return function(a,b){ + let v1 = a.value.sort; + let v2 = b.value.sort; + return v1 - v2; + } + }, setTreeValue(arr) { arr.forEach(item => { if (this.debugResult && this.debugResult.get(item.resId)) { @@ -161,6 +168,7 @@ export default { this.setTreeValue(item.children); } }) + arr.sort(this.compare()); }, getType(type) { switch (type) { @@ -301,7 +309,9 @@ export default { this.content.passAssertions += item.passAssertions this.content.totalAssertions += item.totalAssertions; if (item && item.requestResults) { - item.requestResults.forEach(req => { + for(let index in item.requestResults){ + let req = item.requestResults[index]; + req.sort = index; req.responseResult.console = res.console; if (req.method === 'Request' && req.subRequestResults && req.subRequestResults.length > 0) { this.getTransaction(req.subRequestResults, resMap); @@ -327,7 +337,7 @@ export default { this.endTime = req.endTime; } } - }) + } } }) } diff --git a/frontend/src/business/components/api/automation/scenario/variable/VariableList.vue b/frontend/src/business/components/api/automation/scenario/variable/VariableList.vue index a5c929310c..da7d4afd83 100644 --- a/frontend/src/business/components/api/automation/scenario/variable/VariableList.vue +++ b/frontend/src/business/components/api/automation/scenario/variable/VariableList.vue @@ -272,8 +272,6 @@ export default { this.headers = headers; } this.visible = true; - this.editData = {type: "CONSTANT"}; - this.addParameters(this.editData); this.disabled = disabled; }, save() { diff --git a/frontend/src/business/components/api/definition/components/MsCodeEdit.vue b/frontend/src/business/components/api/definition/components/MsCodeEdit.vue index 09655cb806..704523a513 100644 --- a/frontend/src/business/components/api/definition/components/MsCodeEdit.vue +++ b/frontend/src/business/components/api/definition/components/MsCodeEdit.vue @@ -1,5 +1,5 @@