From 6392190f54a2bda4c10ccee36bc9f7a2c48c5179 Mon Sep 17 00:00:00 2001 From: song-tianyang Date: Wed, 20 Oct 2021 19:44:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(Mock=E4=BC=98=E5=8C=96):=20#1003356=20Mock?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E6=9C=9F=E6=9C=9B=E5=8F=8A=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 【Mock服务期望及响应配置优化】 https://www.tapd.cn/55049933/prong/stories/view/1155049933001003356 --- .../api/controller/MockApiController.java | 24 +- .../api/controller/MockConfigController.java | 30 +- .../api/dto/mock/MockApiUtils.java | 418 ++++++++++ .../api/dto/mock/RequestMockParams.java | 42 + .../mockconfig/MockExpectConfigRequest.java | 2 + .../api/service/ApiDefinitionService.java | 3 +- .../api/service/ApiModuleService.java | 3 + .../api/service/MockConfigService.java | 719 ++++++++++++------ .../commons/utils/JsonStructUtils.java | 10 +- .../components/EditCompleteContainer.vue | 7 +- .../definition/components/body/ApiBody.vue | 3 +- .../components/body/ApiBodyFileUpload.vue | 2 +- .../mock/Components/MockApiBody.vue | 345 +++++++++ .../mock/Components/MockApiResponseBody.vue | 396 ++++++++++ .../mock/Components/MockApiScriptEditor.vue | 210 +++++ .../mock/Components/MockScriptNavMenu.vue | 228 ++++++ .../definition/components/mock/MockConfig.vue | 64 +- .../components/mock/MockConfigHeader.vue | 101 +++ .../components/mock/MockEditDrawer.vue | 343 +++++++++ .../components/mock/MockRequestParam.vue | 390 ++++++++++ .../components/mock/MockResponseParam.vue | 216 ++++++ .../components/mock/MockRowVariables.vue | 2 - .../definition/components/mock/MockTab.vue | 228 ++++++ .../common/components/MsDoughnutPieChart.vue | 2 + frontend/src/i18n/en-US.js | 1 + frontend/src/i18n/zh-CN.js | 1 + frontend/src/i18n/zh-TW.js | 1 + 27 files changed, 3465 insertions(+), 326 deletions(-) create mode 100644 backend/src/main/java/io/metersphere/api/dto/mock/MockApiUtils.java create mode 100644 backend/src/main/java/io/metersphere/api/dto/mock/RequestMockParams.java create mode 100644 frontend/src/business/components/api/definition/components/mock/Components/MockApiBody.vue create mode 100644 frontend/src/business/components/api/definition/components/mock/Components/MockApiResponseBody.vue create mode 100644 frontend/src/business/components/api/definition/components/mock/Components/MockApiScriptEditor.vue create mode 100644 frontend/src/business/components/api/definition/components/mock/Components/MockScriptNavMenu.vue create mode 100644 frontend/src/business/components/api/definition/components/mock/MockConfigHeader.vue create mode 100644 frontend/src/business/components/api/definition/components/mock/MockEditDrawer.vue create mode 100644 frontend/src/business/components/api/definition/components/mock/MockRequestParam.vue create mode 100644 frontend/src/business/components/api/definition/components/mock/MockResponseParam.vue create mode 100644 frontend/src/business/components/api/definition/components/mock/MockTab.vue diff --git a/backend/src/main/java/io/metersphere/api/controller/MockApiController.java b/backend/src/main/java/io/metersphere/api/controller/MockApiController.java index 453a42b928..f5844ee2c3 100644 --- a/backend/src/main/java/io/metersphere/api/controller/MockApiController.java +++ b/backend/src/main/java/io/metersphere/api/controller/MockApiController.java @@ -1,6 +1,6 @@ package io.metersphere.api.controller; -import io.metersphere.api.service.ApiDefinitionService; +import io.metersphere.api.dto.mock.MockApiUtils; import io.metersphere.api.service.MockConfigService; import io.metersphere.api.tcp.TCPPool; import io.metersphere.base.domain.Project; @@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.util.Map; /** * @author song.tianyang @@ -30,7 +31,8 @@ public class MockApiController { @NoResultHolder public String postRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) { Project project = projectService.findBySystemId(projectSystemId); - String returnStr = mockConfigService.checkReturnWithMockExpectByBodyParam("POST", project, request, response); + Map requestHeaderMap = MockApiUtils.getHttpRequestHeader(request); + String returnStr = mockConfigService.checkReturnWithMockExpectByBodyParam("POST", requestHeaderMap,project, request, response); return returnStr; } @@ -38,7 +40,8 @@ public class MockApiController { @NoResultHolder public String getRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) { Project project = projectService.findBySystemId(projectSystemId); - String returnStr = mockConfigService.checkReturnWithMockExpectByUrlParam("GET", project, request, response); + Map requestHeaderMap = MockApiUtils.getHttpRequestHeader(request); + String returnStr = mockConfigService.checkReturnWithMockExpectByUrlParam("GET", requestHeaderMap, project, request, response); return returnStr; } @@ -46,7 +49,8 @@ public class MockApiController { @NoResultHolder public String putRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) { Project project = projectService.findBySystemId(projectSystemId); - String returnStr = mockConfigService.checkReturnWithMockExpectByBodyParam("PUT", project, request, response); + Map requestHeaderMap = MockApiUtils.getHttpRequestHeader(request); + String returnStr = mockConfigService.checkReturnWithMockExpectByBodyParam("PUT", requestHeaderMap, project, request, response); return returnStr; } @@ -54,7 +58,8 @@ public class MockApiController { @NoResultHolder public String patchRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) { Project project = projectService.findBySystemId(projectSystemId); - String returnStr = mockConfigService.checkReturnWithMockExpectByBodyParam("PATCH", project, request, response); + Map requestHeaderMap = MockApiUtils.getHttpRequestHeader(request); + String returnStr = mockConfigService.checkReturnWithMockExpectByBodyParam("PATCH", requestHeaderMap, project, request, response); return returnStr; } @@ -62,7 +67,8 @@ public class MockApiController { @NoResultHolder public String deleteRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) { Project project = projectService.findBySystemId(projectSystemId); - String returnStr = mockConfigService.checkReturnWithMockExpectByUrlParam("DELETE", project, request, response); + Map requestHeaderMap = MockApiUtils.getHttpRequestHeader(request); + String returnStr = mockConfigService.checkReturnWithMockExpectByUrlParam("DELETE", requestHeaderMap, project, request, response); return returnStr; } @@ -70,7 +76,8 @@ public class MockApiController { @NoResultHolder public String optionsRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) { Project project = projectService.findBySystemId(projectSystemId); - String returnStr = mockConfigService.checkReturnWithMockExpectByUrlParam("OPTIONS", project, request, response); + Map requestHeaderMap = MockApiUtils.getHttpRequestHeader(request); + String returnStr = mockConfigService.checkReturnWithMockExpectByUrlParam("OPTIONS", requestHeaderMap, project, request, response); return returnStr; } @@ -78,7 +85,8 @@ public class MockApiController { @NoResultHolder public void headRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) { Project project = projectService.findBySystemId(projectSystemId); - mockConfigService.checkReturnWithMockExpectByUrlParam("HEAD", project, request, response); + Map requestHeaderMap = MockApiUtils.getHttpRequestHeader(request); + mockConfigService.checkReturnWithMockExpectByUrlParam("HEAD", requestHeaderMap, project, request, response); } @GetMapping("/getTcpMockPortStatus/") diff --git a/backend/src/main/java/io/metersphere/api/controller/MockConfigController.java b/backend/src/main/java/io/metersphere/api/controller/MockConfigController.java index 826909163b..b0976073f5 100644 --- a/backend/src/main/java/io/metersphere/api/controller/MockConfigController.java +++ b/backend/src/main/java/io/metersphere/api/controller/MockConfigController.java @@ -1,5 +1,6 @@ package io.metersphere.api.controller; +import io.metersphere.api.dto.mock.MockApiUtils; import io.metersphere.api.dto.mockconfig.MockConfigRequest; import io.metersphere.api.dto.mockconfig.MockExpectConfigRequest; import io.metersphere.api.dto.mockconfig.response.MockConfigResponse; @@ -10,6 +11,7 @@ import io.metersphere.base.domain.ApiDefinitionWithBLOBs; import io.metersphere.base.domain.MockExpectConfig; import io.metersphere.base.domain.MockExpectConfigWithBLOBs; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.util.List; @@ -34,11 +36,25 @@ public class MockConfigController { return mockConfigService.genMockConfig(request); } - @PostMapping("/updateMockExpectConfig") - public MockExpectConfig updateMockExpectConfig(@RequestBody MockExpectConfigRequest request) { - return mockConfigService.updateMockExpectConfig(request); + @PostMapping(value ="/updateMockExpectConfig", consumes = {"multipart/form-data"}) + public MockExpectConfig updateMockExpectConfig(@RequestPart("request")MockExpectConfigRequest request, @RequestPart(value = "files", required = false) List bodyFiles) { + return mockConfigService.updateMockExpectConfig(request,bodyFiles); } + @PostMapping(value ="/updateMockExpectConfigStatus") + public MockExpectConfig updateMockExpectConfig(@RequestBody MockExpectConfigRequest request) { + return mockConfigService.updateMockExpectConfigStatus(request); + } + +// @PostMapping(value = "/create", consumes = {"multipart/form-data"}) +// @RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ_CREATE_API) +// @MsAuditLog(module = "api_definition", type = OperLogConstants.CREATE, title = "#request.name", content = "#msClass.getLogDetails(#request.id)", msClass = ApiDefinitionService.class) +// @SendNotice(taskType = NoticeConstants.TaskType.API_DEFINITION_TASK, event = NoticeConstants.Event.CREATE, mailTemplate = "api/DefinitionCreate", subject = "接口定义通知") +// public ApiDefinitionWithBLOBs create(@RequestPart("request") SaveApiDefinitionRequest request, @RequestPart(value = "files", required = false) List bodyFiles) { +// checkPermissionService.checkProjectOwner(request.getProjectId()); +// return apiDefinitionService.create(request, bodyFiles); +// } + @GetMapping("/mockExpectConfig/{id}") public MockExpectConfigResponse selectMockExpectConfig(@PathVariable String id) { MockExpectConfigWithBLOBs config = mockConfigService.findMockExpectConfigById(id); @@ -58,4 +74,12 @@ public class MockConfigController { List> apiParams = mockConfigService.getApiParamsByApiDefinitionBLOBs(apiDefinitionWithBLOBs); return apiParams; } + + @GetMapping("/getApiResponse/{id}") + public Map getApiResponse(@PathVariable String id) { + ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = apiDefinitionService.getBLOBs(id); + Map returnMap = MockApiUtils.getApiResponse(apiDefinitionWithBLOBs.getResponse()); + return returnMap; + } + } 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 new file mode 100644 index 0000000000..93f84377a1 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/mock/MockApiUtils.java @@ -0,0 +1,418 @@ +package io.metersphere.api.dto.mock; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONValidator; +import io.metersphere.api.dto.mockconfig.response.JsonSchemaReturnObj; +import io.metersphere.commons.exception.MSException; +import io.metersphere.commons.json.JSONSchemaGenerator; +import io.metersphere.commons.utils.XMLUtils; +import io.metersphere.jmeter.utils.ScriptEngineUtils; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.jmeter.protocol.java.sampler.JSR223Sampler; +import org.apache.jmeter.samplers.SampleResult; + +import javax.servlet.http.HttpServletRequest; +import java.util.*; + +/** + * @author song.tianyang + * @Date 2021/10/14 3:00 下午 + */ +public class MockApiUtils { + public static Map getHttpRequestHeader(HttpServletRequest request){ + Map returnMap = new HashMap<>(); + Enumeration headers = request.getHeaderNames(); + while (headers.hasMoreElements()){ + String header = headers.nextElement(); + String headerValue = request.getHeader(header); + 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++){ + JSONObject obj = mockExpectHeaderArray.getJSONObject(i); + if(obj.containsKey("name") && obj.containsKey("value") && obj.containsKey("enable")){ + boolean enable = obj.getBoolean("enable"); + if(enable){ + mockExpectHeaders.put(obj.getString("name"),obj.getString("value")); + } + } + } + if(MapUtils.isEmpty(requestHeaderMap) && MapUtils.isNotEmpty(mockExpectHeaders)){ + return false; + }else { + for (Map.Entry entry: mockExpectHeaders.entrySet()){ + String key = entry.getKey(); + String value = entry.getValue(); + + if(!requestHeaderMap.containsKey(key)){ + return false; + }else { + if(!StringUtils.equals(value,requestHeaderMap.get(key))){ + return false; + } + } + } + return true; + } + } + + public static JSONArray getExpectBodyParams(JSONObject bodyObj) { + JSONArray returnJsonArray = new JSONArray(); + + try { + String type = bodyObj.getString("type"); + if (StringUtils.equalsIgnoreCase(type, "JSON")) { + //判断是否是JsonSchema + boolean isJsonSchema = false; + if (bodyObj.containsKey("format")) { + String foramtValue = String.valueOf(bodyObj.get("format")); + if (StringUtils.equals("JSON-SCHEMA", foramtValue)) { + isJsonSchema = true; + } + } + + String jsonString = ""; + if (isJsonSchema) { + if (bodyObj.containsKey("jsonSchema") && bodyObj.getJSONObject("jsonSchema").containsKey("properties")) { + String bodyRetunStr = bodyObj.getJSONObject("jsonSchema").getJSONObject("properties").toJSONString(); + jsonString = JSONSchemaGenerator.getJson(bodyRetunStr); +// JSONObject bodyReturnObj = JSONObject.parseObject(bodyRetunStr); +// JSONObject returnObj = parseJsonSchema(bodyReturnObj); +// returnStr = returnObj.toJSONString(); + } + } else { + if (bodyObj.containsKey("raw")) { + jsonString = bodyObj.getString("raw"); + } + } + JSONValidator jsonValidator = JSONValidator.from(jsonString); + if (StringUtils.equalsIgnoreCase("Array", jsonValidator.getType().name())) { + returnJsonArray = JSONArray.parseArray(jsonString); + } else if (StringUtils.equalsIgnoreCase("Object", jsonValidator.getType().name())) { + JSONObject jsonObject = JSONObject.parseObject(jsonString); + returnJsonArray.add(jsonObject); + } + + } else if (StringUtils.equalsIgnoreCase(type, "XML")) { + if (bodyObj.containsKey("raw")) { + String xmlStr = bodyObj.getString("raw"); + JSONObject matchObj = XMLUtils.XmlToJson(xmlStr); + returnJsonArray.add(matchObj); + } + } else if (StringUtils.equalsIgnoreCase(type, "Raw")) { + if (bodyObj.containsKey("raw")) { + String raw = bodyObj.getString("raw"); + JSONObject rawObject = new JSONObject(); + rawObject.put("raw",raw); + returnJsonArray.add(rawObject); + } + } else if (StringUtils.equalsAnyIgnoreCase(type, "Form Data", "WWW_FORM")) { + if (bodyObj.containsKey("kvs")) { + JSONObject bodyParamArr = new JSONObject(); + JSONArray kvsArr = bodyObj.getJSONArray("kvs"); + for (int i = 0; i < kvsArr.size(); i++) { + JSONObject kv = kvsArr.getJSONObject(i); + if (kv.containsKey("name")) { + String values = kv.getString("value"); + if (StringUtils.isEmpty(values)) { + values = ""; + } else { + try { + values = values.startsWith("@") ? ScriptEngineUtils.buildFunctionCallString(values) : values; + } catch (Exception e) { + } + } + bodyParamArr.put(kv.getString("name"), values); + } + } + returnJsonArray.add(bodyParamArr); + } + } + }catch (Exception e){} + + + return returnJsonArray; + } + + public static JSONObject parseJsonSchema(JSONObject bodyReturnObj) { + JSONObject returnObj = new JSONObject(); + if (bodyReturnObj == null) { + return returnObj; + } + + Set keySet = bodyReturnObj.keySet(); + for (String key : keySet) { + try { + JsonSchemaReturnObj obj = bodyReturnObj.getObject(key, JsonSchemaReturnObj.class); + if (StringUtils.equals("object", obj.getType())) { + JSONObject itemObj = parseJsonSchema(obj.getProperties()); + if (!itemObj.isEmpty()) { + returnObj.put(key, itemObj); + } + } else if (StringUtils.equals("array", obj.getType())) { + if (obj.getItems() != null) { + JSONObject itemObj = obj.getItems(); + if (itemObj.containsKey("type")) { + if (StringUtils.equals("object", itemObj.getString("type")) && itemObj.containsKey("properties")) { + JSONObject arrayObj = itemObj.getJSONObject("properties"); + JSONObject parseObj = parseJsonSchema(arrayObj); + JSONArray array = new JSONArray(); + array.add(parseObj); + returnObj.put(key, array); + } else if (StringUtils.equals("string", itemObj.getString("type")) && itemObj.containsKey("mock")) { + JsonSchemaReturnObj arrayObj = JSONObject.toJavaObject(itemObj, JsonSchemaReturnObj.class); + String value = getMockValues(arrayObj.getMockValue()); + JSONArray array = new JSONArray(); + array.add(value); + returnObj.put(key, array); + } + } + } + } else { + String values = obj.getMockValue(); + if (StringUtils.isEmpty(values)) { + values = ""; + } else { + try { + values = values.startsWith("@") ? ScriptEngineUtils.buildFunctionCallString(values) : values; + } catch (Exception e) { + } + } + returnObj.put(key, values); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + return returnObj; + } + + private static String getMockValues(String values) { + if (StringUtils.isEmpty(values)) { + values = ""; + } else { + try { + values = values.startsWith("@") ? ScriptEngineUtils.buildFunctionCallString(values) : values; + } catch (Exception e) { + } + } + return values; + } + + public static JSONObject getParams(JSONArray array) { + JSONObject returnObject = new JSONObject(); + for(int i = 0; i < array.size();i ++){ + JSONObject obj = array.getJSONObject(i); + if(obj.containsKey("name") && obj.containsKey("value") && obj.containsKey("enable")){ + boolean isEnable = obj.getBoolean("enable"); + if(isEnable){ + returnObject.put(obj.getString("name"),obj.getString("value")); + } + } + } + return returnObject; + } + + public static Map getApiResponse(String response) { + Map returnMap = new HashMap<>(); + String returnStr = ""; + if(StringUtils.isNotEmpty(response)){ + try { + JSONObject respObj = JSONObject.parseObject(response); + if (respObj.containsKey("body")) { + JSONObject bodyObj = respObj.getJSONObject("body"); + if (bodyObj.containsKey("type")) { + String type = bodyObj.getString("type"); + if (StringUtils.equals(type, "JSON")) { + //判断是否是JsonSchema + boolean isJsonSchema = false; + if (bodyObj.containsKey("format")) { + String foramtValue = String.valueOf(bodyObj.get("format")); + if (StringUtils.equals("JSON-SCHEMA", foramtValue)) { + isJsonSchema = true; + } + } + if (isJsonSchema) { + if (bodyObj.containsKey("jsonSchema") && bodyObj.getJSONObject("jsonSchema").containsKey("properties")) { + String bodyRetunStr = bodyObj.getJSONObject("jsonSchema").getJSONObject("properties").toJSONString(); + JSONObject bodyReturnObj = JSONObject.parseObject(bodyRetunStr); + JSONObject returnObj = MockApiUtils.parseJsonSchema(bodyReturnObj); + returnStr = returnObj.toJSONString(); + } + } else { + if (bodyObj.containsKey("raw")) { + returnStr = bodyObj.getString("raw"); + } + } + } else if (StringUtils.equalsAny(type, "XML", "Raw")) { + if (bodyObj.containsKey("raw")) { + String raw = bodyObj.getString("raw"); + returnStr = raw; + } + } else if (StringUtils.equalsAny(type, "Form Data", "WWW_FORM")) { + Map paramMap = new LinkedHashMap<>(); + if (bodyObj.containsKey("kvs")) { + JSONArray bodyParamArr = new JSONArray(); + JSONArray kvsArr = bodyObj.getJSONArray("kvs"); + for (int i = 0; i < kvsArr.size(); i++) { + JSONObject kv = kvsArr.getJSONObject(i); + if (kv.containsKey("name")) { + String values = kv.getString("value"); + if (StringUtils.isEmpty(values)) { + values = ""; + } else { + try { + values = values.startsWith("@") ? ScriptEngineUtils.buildFunctionCallString(values) : values; + } catch (Exception e) { + } + } + paramMap.put(kv.getString("name"), values); + } + } + } + returnStr = JSONObject.toJSONString(paramMap); + } + } + } + }catch (Exception e){ + MSException.throwException(e); + } + } + returnMap.put("returnMsg",returnStr); + return returnMap; + } + + public static String getResultByResponseResult(JSONObject bodyObj,String url, Map headerMap,RequestMockParams requestMockParams) { + if(bodyObj == null && bodyObj.isEmpty()){ + return ""; + }else { + String returnStr = ""; + if(bodyObj.containsKey("type")){ + String type = bodyObj.getString("type"); + if (StringUtils.equals(type, "JSON")) { + //判断是否是JsonSchema + boolean isJsonSchema = false; + if (bodyObj.containsKey("format")) { + String foramtValue = String.valueOf(bodyObj.get("format")); + if (StringUtils.equals("JSON-SCHEMA", foramtValue)) { + isJsonSchema = true; + } + } + if (isJsonSchema) { + if (bodyObj.containsKey("jsonSchema") && bodyObj.getJSONObject("jsonSchema").containsKey("properties")) { + String bodyRetunStr = bodyObj.getJSONObject("jsonSchema").getJSONObject("properties").toJSONString(); + JSONObject bodyReturnObj = JSONObject.parseObject(bodyRetunStr); + JSONObject returnObj = MockApiUtils.parseJsonSchema(bodyReturnObj); + returnStr = returnObj.toJSONString(); + } + } else { + if (bodyObj.containsKey("raw")) { + returnStr = bodyObj.getString("raw"); + } + } + } else if(StringUtils.equalsAnyIgnoreCase(type,"Raw")){ + if (bodyObj.containsKey("raw")) { + String raw = bodyObj.getString("raw"); + returnStr = raw; + } + } else if(StringUtils.equalsAnyIgnoreCase(type,"XML")){ + if (bodyObj.containsKey("xmlHeader")) { + String xmlHeader = bodyObj.getString("xmlHeader"); + if(!StringUtils.startsWith(xmlHeader,"")){ + returnStr = "\r\n"; + }else { + returnStr = xmlHeader; + } + } + if (bodyObj.containsKey("xmlRaw")) { + String raw = bodyObj.getString("xmlRaw"); + returnStr = returnStr + raw; + } + } else if(StringUtils.equalsAnyIgnoreCase(type,"fromApi")){ + if (bodyObj.containsKey("apiRspRaw")) { + String raw = bodyObj.getString("apiRspRaw"); + returnStr = raw; + } + } 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"); + + returnStr = parseScript(script,url,headerMap,requestMockParams); + + + + runScript(script,scriptLanguage); + } + } + + } + return returnStr; + } + } + + private static String parseScript(String script,String url,Map headerMap,RequestMockParams requestMockParams) { + String returnMsg = ""; + if(StringUtils.isNotEmpty(script)){ + String [] scriptRowArr = StringUtils.split(script,"\n"); + for (String scriptRow : scriptRowArr) { + scriptRow = scriptRow.trim(); + if(StringUtils.startsWith(scriptRow,"returnMsg.add(") && StringUtils.endsWith(scriptRow,")")){ + scriptRow = scriptRow.substring(14,scriptRow.length()-1).trim(); + if(StringUtils.equalsIgnoreCase(scriptRow,"@address")){ + returnMsg += url; + }else if(StringUtils.startsWith(scriptRow,"@header(${") && StringUtils.endsWith(scriptRow,"})")){ + String paramName = scriptRow.substring(10,scriptRow.length()-2); + if(headerMap.containsKey(paramName)){ + returnMsg += headerMap.get(paramName); + } + }else if(StringUtils.startsWith(scriptRow,"@body(${") && StringUtils.endsWith(scriptRow,"})")){ + String paramName = scriptRow.substring(8,scriptRow.length()-2); + if(requestMockParams.getBodyParams() != null && requestMockParams.getBodyParams().size() > 0){ + JSONObject bodyParamObj = requestMockParams.getBodyParams().getJSONObject(0); + if(bodyParamObj.containsKey(paramName)){ + returnMsg += String.valueOf(bodyParamObj.get(paramName)); + } + } + }else if(StringUtils.equalsIgnoreCase(scriptRow,"@bodyRaw")){ + if(requestMockParams.getBodyParams() != null && requestMockParams.getBodyParams().size() > 0){ + JSONObject bodyParamObj = requestMockParams.getBodyParams().getJSONObject(0); + if(bodyParamObj.containsKey("raw")){ + returnMsg += String.valueOf(bodyParamObj.get("raw")); + } + } + }else if(StringUtils.startsWith(scriptRow,"@query(${") && StringUtils.endsWith(scriptRow,"})")){ + String paramName = scriptRow.substring(9,scriptRow.length()-2); + if(requestMockParams.getQueryParamsObj() != null && requestMockParams.getQueryParamsObj().containsKey(paramName)){ + returnMsg += String.valueOf(requestMockParams.getQueryParamsObj().get(paramName)); + } + }else if(StringUtils.startsWith(scriptRow,"@rest(${") && StringUtils.endsWith(scriptRow,"})")){ + String paramName = scriptRow.substring(8,scriptRow.length()-2); + if(requestMockParams.getRestParamsObj() != null && requestMockParams.getRestParamsObj().containsKey(paramName)){ + returnMsg += String.valueOf(requestMockParams.getRestParamsObj().get(paramName)); + } + }else { + returnMsg += scriptRow; + } + } + + } + } + return returnMsg; + } + + private static void runScript(String script, String scriptLanguage) { + JSR223Sampler jmeterScriptSampler = new JSR223Sampler(); + jmeterScriptSampler.setScriptLanguage(scriptLanguage); + jmeterScriptSampler.setScript(script); + SampleResult result = jmeterScriptSampler.sample(null); + System.out.println(result.getResponseData()); + } +} diff --git a/backend/src/main/java/io/metersphere/api/dto/mock/RequestMockParams.java b/backend/src/main/java/io/metersphere/api/dto/mock/RequestMockParams.java new file mode 100644 index 0000000000..2516ed2b6e --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/mock/RequestMockParams.java @@ -0,0 +1,42 @@ +package io.metersphere.api.dto.mock; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.Getter; +import lombok.Setter; + +/** + * @author song.tianyang + * @Date 2021/10/14 4:32 下午 + */ +@Getter +@Setter +public class RequestMockParams { + private JSONObject restParamsObj; + private JSONObject queryParamsObj; + private JSONArray bodyParams; + + public JSONObject getParamsObj(){ + JSONObject returnObj = new JSONObject(); + if(restParamsObj != null){ + for (String key : restParamsObj.keySet()) { + Object value = restParamsObj.get(key); + returnObj.put(key,value); + } + } + if(queryParamsObj != null){ + for (String key : queryParamsObj.keySet()) { + Object value = queryParamsObj.get(key); + returnObj.put(key,value); + } + } + return returnObj; + } + + public boolean isEmpty() { + + return (restParamsObj == null || restParamsObj.isEmpty()) && + (queryParamsObj == null || queryParamsObj.isEmpty())&& + (bodyParams == null || bodyParams.isEmpty()); + } +} diff --git a/backend/src/main/java/io/metersphere/api/dto/mockconfig/MockExpectConfigRequest.java b/backend/src/main/java/io/metersphere/api/dto/mockconfig/MockExpectConfigRequest.java index a2fbb632c0..8efa095a6e 100644 --- a/backend/src/main/java/io/metersphere/api/dto/mockconfig/MockExpectConfigRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/mockconfig/MockExpectConfigRequest.java @@ -27,4 +27,6 @@ public class MockExpectConfigRequest { private Object response; private String status; + + private String copyId; } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java index 1630dfb5a5..bb0c230fc5 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -560,9 +560,9 @@ public class ApiDefinitionService { if (CollectionUtils.isEmpty(sameRequest)) { //postman 可能含有前置脚本,接口定义去掉脚本 apiDefinition.setOrder(getImportNextOrder(apiTestImportRequest.getProjectId())); - batchMapper.insert(apiDefinition); String originId = apiDefinition.getId(); apiDefinition.setId(UUID.randomUUID().toString()); + batchMapper.insert(apiDefinition); String requestStr = setImportHashTree(apiDefinition); reSetImportCasesApiId(cases, originId, apiDefinition.getId()); apiDefinition.setRequest(requestStr); @@ -1014,6 +1014,7 @@ public class ApiDefinitionService { if (apiImport.getEsbApiParamsMap() != null) { String apiId = item.getId(); EsbApiParamsWithBLOBs model = apiImport.getEsbApiParamsMap().get(apiId); + request.setModeId("fullCoverage");//标准版ESB数据导入不区分是否覆盖,默认都为覆盖 importCreate(item, batchMapper, apiTestCaseMapper, request, apiImport.getCases(), apiImport.getMocks(), project.getRepeatable()); if (model != null) { apiImport.getEsbApiParamsMap().remove(apiId); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java b/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java index 5aae6559d6..d4b8b1afc4 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java @@ -295,6 +295,9 @@ public class ApiModuleService extends NodeTreeService { if (StringUtils.isNotBlank(node.getId())) { criteria.andIdNotEqualTo(node.getId()); } + if(StringUtils.isNotEmpty(node.getProtocol())){ + criteria.andProtocolEqualTo(node.getProtocol()); + } return apiModuleMapper.selectByExample(example); } 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 f3b8ca06ca..72bdfcf92e 100644 --- a/backend/src/main/java/io/metersphere/api/service/MockConfigService.java +++ b/backend/src/main/java/io/metersphere/api/service/MockConfigService.java @@ -9,6 +9,8 @@ import io.metersphere.api.dto.automation.EsbDataStruct; import io.metersphere.api.dto.automation.TcpTreeTableDataStruct; import io.metersphere.api.dto.automation.parse.TcpTreeTableDataParser; import io.metersphere.api.dto.definition.parse.ApiDefinitionImport; +import io.metersphere.api.dto.mock.MockApiUtils; +import io.metersphere.api.dto.mock.RequestMockParams; import io.metersphere.api.dto.mockconfig.MockConfigImportDTO; import io.metersphere.api.dto.mockconfig.MockConfigRequest; import io.metersphere.api.dto.mockconfig.MockExpectConfigRequest; @@ -30,6 +32,7 @@ import org.apache.ibatis.session.SqlSession; import org.json.XML; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; import org.xml.sax.InputSource; import javax.annotation.Resource; @@ -69,12 +72,12 @@ public class MockConfigService { return this.assemblyMockConfingResponse(configList); } - public List selectMockExpectConfigByApiId(String apiId){ + public List selectMockExpectConfigByApiId(String apiId) { return extMockExpectConfigMapper.selectByApiId(apiId); } - public List selectMockExpectConfigByApiIdIn(List apiIds){ - if(CollectionUtils.isNotEmpty(apiIds)){ + public List selectMockExpectConfigByApiIdIn(List apiIds) { + if (CollectionUtils.isNotEmpty(apiIds)) { List returnDTO = new ArrayList<>(); for (String apiId : apiIds) { List mockExpectConfigWithBLOBsList = extMockExpectConfigMapper.selectByApiId(apiId); @@ -86,7 +89,7 @@ public class MockConfigService { } } return returnDTO; - }else { + } else { return new ArrayList<>(); } } @@ -139,7 +142,7 @@ public class MockConfigService { config.setCreateUserId(SessionUtils.getUserId()); config.setCreateTime(createTimeStmp); config.setUpdateTime(createTimeStmp); - if(request.getApiId() != null){ + if (request.getApiId() != null) { config.setApiId(request.getApiId()); mockConfigMapper.insert(config); } @@ -165,7 +168,21 @@ public class MockConfigService { return returnRsp; } - public MockExpectConfig updateMockExpectConfig(MockExpectConfigRequest request) { + public MockExpectConfig updateMockExpectConfigStatus(MockExpectConfigRequest request) { + if (StringUtils.isNotEmpty(request.getId()) && StringUtils.isNotEmpty(request.getStatus())) { + MockExpectConfigWithBLOBs model = new MockExpectConfigWithBLOBs(); + long timeStmp = System.currentTimeMillis(); + model.setId(request.getId()); + model.setUpdateTime(timeStmp); + model.setStatus(request.getStatus()); + mockExpectConfigMapper.updateByPrimaryKeySelective(model); + return model; + } else { + return null; + } + } + + public MockExpectConfig updateMockExpectConfig(MockExpectConfigRequest request, List bodyFiles) { boolean isSave = false; if (StringUtils.isEmpty(request.getId())) { isSave = true; @@ -200,6 +217,10 @@ public class MockConfigService { } else { mockExpectConfigMapper.updateByPrimaryKeySelective(model); } + if (StringUtils.isNotEmpty(request.getCopyId())) { + FileUtils.copyBdyFile(request.getCopyId(), model.getId()); + } + FileUtils.createBodyFiles(model.getId(), bodyFiles); return model; } @@ -212,40 +233,24 @@ public class MockConfigService { } } - public MockExpectConfigResponse findExpectConfig(List mockExpectConfigList, JSONObject reqJsonObj) { + public MockExpectConfigResponse findExpectConfig(Map requestHeaderMap, List mockExpectConfigList, RequestMockParams requestMockParams) { MockExpectConfigResponse returnModel = null; - if (reqJsonObj == null || reqJsonObj.isEmpty()) { + if (requestMockParams == null || requestMockParams.isEmpty()) { + //如果参数为空,则匹配请求为空的期望 for (MockExpectConfigResponse model : mockExpectConfigList) { if (!model.isStatus()) { continue; } JSONObject requestObj = model.getRequest(); - boolean isJsonParam = requestObj.getBoolean("jsonParam"); - if (isJsonParam) { - if (StringUtils.isEmpty(requestObj.getString("jsonData"))) { - return model; - } + MockExpectConfigResponse resultModel = null; + if (requestObj.containsKey("params")) { + resultModel = this.getEmptyRequestMockExpectByParams(requestHeaderMap, model); } else { - JSONObject mockExpectJson = new JSONObject(); - JSONArray jsonArray = requestObj.getJSONArray("variables"); - for (int i = 0; i < jsonArray.size(); i++) { - JSONObject object = jsonArray.getJSONObject(i); - String name = ""; - String value = ""; - if (object.containsKey("name")) { - name = String.valueOf(object.get("name")).trim(); - } - if (object.containsKey("value")) { - value = String.valueOf(object.get("value")).trim(); - } - if (StringUtils.isNotEmpty(name)) { - mockExpectJson.put(name, value); - } - } - if (mockExpectJson.isEmpty()) { - return model; - } + resultModel = this.getEmptyRequestMockExpect(model); + } + if (resultModel != null) { + return resultModel; } } } @@ -254,41 +259,14 @@ public class MockConfigService { if (!model.isStatus()) { continue; } - JSONObject requestObj = model.getRequest(); - boolean isJsonParam = requestObj.getBoolean("jsonParam"); - JSONObject mockExpectJson = new JSONObject(); - if (isJsonParam) { - String jsonParams = requestObj.getString("jsonData"); - JSONValidator jsonValidator = JSONValidator.from(jsonParams); - if (StringUtils.equalsIgnoreCase("Array", jsonValidator.getType().name())) { - JSONArray mockExpectArr = JSONArray.parseArray(jsonParams); - for (int expectIndex = 0; expectIndex < mockExpectArr.size(); expectIndex++) { - JSONObject itemObj = mockExpectArr.getJSONObject(expectIndex); - mockExpectJson = itemObj; - } - } else if (StringUtils.equalsIgnoreCase("Object", jsonValidator.getType().name())) { - JSONObject mockExpectJsonItem = JSONObject.parseObject(jsonParams); - mockExpectJson = mockExpectJsonItem; - } + JSONObject mockExpectRequestObj = model.getRequest(); + boolean mathing = false; + if (mockExpectRequestObj.containsKey("params")) { + mathing = this.isRequestMockExpectMatchingByParams(requestHeaderMap, mockExpectRequestObj, requestMockParams); } else { - JSONArray jsonArray = requestObj.getJSONArray("variables"); - for (int i = 0; i < jsonArray.size(); i++) { - JSONObject object = jsonArray.getJSONObject(i); - String name = ""; - String value = ""; - if (object.containsKey("name")) { - name = String.valueOf(object.get("name")).trim(); - } - if (object.containsKey("value")) { - value = String.valueOf(object.get("value")).trim(); - } - if (StringUtils.isNotEmpty(name)) { - mockExpectJson.put(name, value); - } - } + mathing = this.isRequestMockExpectMatching(mockExpectRequestObj, requestMockParams.getQueryParamsObj()); } - boolean mathing = JsonStructUtils.checkJsonObjCompliance(reqJsonObj, mockExpectJson); if (mathing) { returnModel = model; break; @@ -300,7 +278,254 @@ public class MockConfigService { return returnModel; } - public MockExpectConfigResponse findExpectConfig(List mockExpectConfigList, JSONArray reqJsonArray) { + private boolean isRequestMockExpectMatchingByParams(Map requestHeaderMap, JSONObject mockExpectRequestObj, RequestMockParams requestMockParams) { + JSONObject expectParamsObj = mockExpectRequestObj.getJSONObject("params"); + if (expectParamsObj.containsKey("headers")) { + //检测headers + JSONArray headerArr = expectParamsObj.getJSONArray("headers"); + for (int i = 0; i < headerArr.size(); i++) { + JSONObject jsonObject = headerArr.getJSONObject(i); + if (jsonObject.containsKey("enable") && jsonObject.containsKey("name") && jsonObject.containsKey("value")) { + boolean isEnable = jsonObject.getBoolean("enable"); + if (isEnable) { + String headerName = jsonObject.getString("name"); + String headerValue = jsonObject.getString("value"); + if (!requestHeaderMap.containsKey(headerName) || !StringUtils.equals(requestHeaderMap.get(headerName), headerValue)) { + return false; + } + } + } + } + } + + JSONArray jsonArray = requestMockParams.getBodyParams(); + if (jsonArray == null) { + //url or get 参数 + JSONArray argumentsArray = expectParamsObj.getJSONArray("arguments"); + JSONArray restArray = expectParamsObj.getJSONArray("rest"); + + JSONObject urlRequestParamObj = MockApiUtils.getParams(argumentsArray); + JSONObject restRequestParamObj = MockApiUtils.getParams(restArray); + + if (requestMockParams.getQueryParamsObj() == null || requestMockParams.getQueryParamsObj().isEmpty()) { + return JsonStructUtils.checkJsonObjCompliance(requestMockParams.getRestParamsObj(), restRequestParamObj); + } else if (requestMockParams.getRestParamsObj() == null || requestMockParams.getRestParamsObj().isEmpty()) { + return JsonStructUtils.checkJsonObjCompliance(requestMockParams.getQueryParamsObj(), urlRequestParamObj); + } else { + return JsonStructUtils.checkJsonObjCompliance(requestMockParams.getQueryParamsObj(), urlRequestParamObj) + && JsonStructUtils.checkJsonObjCompliance(requestMockParams.getRestParamsObj(), restRequestParamObj); + } + + } else { + // body参数 + JSONObject expectBodyObject = expectParamsObj.getJSONObject("body"); + JSONArray mockExpectJsonArray = MockApiUtils.getExpectBodyParams(expectBodyObject); + + return JsonStructUtils.checkJsonArrayCompliance(jsonArray, mockExpectJsonArray); + } + +// JSONObject mockExpectJson = new JSONObject(); +// if (isJsonParam) { +// String jsonParams = mockExpectRequestObj.getString("jsonData"); +// JSONValidator jsonValidator = JSONValidator.from(jsonParams); +// if (StringUtils.equalsIgnoreCase("Array", jsonValidator.getType().name())) { +// JSONArray mockExpectArr = JSONArray.parseArray(jsonParams); +// for (int expectIndex = 0; expectIndex < mockExpectArr.size(); expectIndex++) { +// JSONObject itemObj = mockExpectArr.getJSONObject(expectIndex); +// mockExpectJson = itemObj; +// } +// } else if (StringUtils.equalsIgnoreCase("Object", jsonValidator.getType().name())) { +// JSONObject mockExpectJsonItem = JSONObject.parseObject(jsonParams); +// mockExpectJson = mockExpectJsonItem; +// } +// } else { +// JSONArray jsonArray = mockExpectRequestObj.getJSONArray("variables"); +// for (int i = 0; i < jsonArray.size(); i++) { +// JSONObject object = jsonArray.getJSONObject(i); +// String name = ""; +// String value = ""; +// if (object.containsKey("name")) { +// name = String.valueOf(object.get("name")).trim(); +// } +// if (object.containsKey("value")) { +// value = String.valueOf(object.get("value")).trim(); +// } +// if (StringUtils.isNotEmpty(name)) { +// mockExpectJson.put(name, value); +// } +// } +// } + +// boolean isMatching = JsonStructUtils.checkJsonObjCompliance(mockExpectRequestObj, mockExpectJson); +// return isMatching; + } + + private boolean isRequestMockExpectMatching(JSONObject mockExpectRequestObj, JSONObject reqJsonObj) { + boolean isJsonParam = mockExpectRequestObj.getBoolean("jsonParam"); + JSONObject mockExpectJson = new JSONObject(); + if (isJsonParam) { + String jsonParams = mockExpectRequestObj.getString("jsonData"); + JSONValidator jsonValidator = JSONValidator.from(jsonParams); + if (StringUtils.equalsIgnoreCase("Array", jsonValidator.getType().name())) { + JSONArray mockExpectArr = JSONArray.parseArray(jsonParams); + for (int expectIndex = 0; expectIndex < mockExpectArr.size(); expectIndex++) { + JSONObject itemObj = mockExpectArr.getJSONObject(expectIndex); + mockExpectJson = itemObj; + } + } else if (StringUtils.equalsIgnoreCase("Object", jsonValidator.getType().name())) { + JSONObject mockExpectJsonItem = JSONObject.parseObject(jsonParams); + mockExpectJson = mockExpectJsonItem; + } + } else { + JSONArray jsonArray = mockExpectRequestObj.getJSONArray("variables"); + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject object = jsonArray.getJSONObject(i); + String name = ""; + String value = ""; + if (object.containsKey("name")) { + name = String.valueOf(object.get("name")).trim(); + } + if (object.containsKey("value")) { + value = String.valueOf(object.get("value")).trim(); + } + if (StringUtils.isNotEmpty(name)) { + mockExpectJson.put(name, value); + } + } + } + + boolean isMatching = JsonStructUtils.checkJsonObjCompliance(reqJsonObj, mockExpectJson); + return isMatching; + } + + private MockExpectConfigResponse getEmptyRequestMockExpectByParams(Map requestHeaderMap, MockExpectConfigResponse model) { + JSONObject requestObj = model.getRequest(); + if (requestObj.containsKey("params")) { + JSONObject paramsObj = requestObj.getJSONObject("params"); + if (paramsObj.containsKey("headers")) { + JSONArray headArray = paramsObj.getJSONArray("headers"); + boolean isHeadMatch = MockApiUtils.matchRequestHeader(headArray, requestHeaderMap); + if (!isHeadMatch) { + return null; + } + //判断rest为空 + if (paramsObj.containsKey("rest")) { + JSONArray restArray = paramsObj.getJSONArray("rest"); + for (int i = 0; i < restArray.size(); i++) { + JSONObject restObj = restArray.getJSONObject(i); + if (restObj.containsKey("enable") && restObj.containsKey("name") && restObj.containsKey("value")) { + boolean isEnable = restObj.getBoolean("enable"); + if (isEnable) { + return null; + } + } + } + } + //判断arguments为空 + if (paramsObj.containsKey("arguments")) { + JSONArray argumentsArray = paramsObj.getJSONArray("arguments"); + for (int i = 0; i < argumentsArray.size(); i++) { + JSONObject argumentsObj = argumentsArray.getJSONObject(i); + if (argumentsObj.containsKey("enable") && argumentsObj.containsKey("name") && argumentsObj.containsKey("value")) { + boolean isEnable = argumentsObj.getBoolean("enable"); + if (isEnable) { + return null; + } + } + } + } + //判断请求体为空 + if (paramsObj.containsKey("body")) { + JSONObject bodyObj = paramsObj.getJSONObject("body"); + if (bodyObj.containsKey("type")) { + String type = bodyObj.getString("type"); + if (StringUtils.equalsIgnoreCase(type, "json")) { + if (bodyObj.containsKey("format") && StringUtils.equalsIgnoreCase(bodyObj.getString("format"), "json-schema") && bodyObj.containsKey("jsonSchema") && bodyObj.get("jsonSchema") != null) { + return null; + } else { + if (bodyObj.containsKey("raw")) { + String raw = bodyObj.getString("raw"); + if (StringUtils.isNotEmpty(raw)) { + return null; + } + } + } + //Binary的先不处理 +// }else if(StringUtils.equalsIgnoreCase(type,"binary")){ +// if(bodyObj.containsKey("binary")){ +// JSONArray binaryArray = bodyObj.getJSONArray("binary"); +// for(int i = 0; i < binaryArray.size(); i ++){ +// JSONObject binarObj = binaryArray.getJSONObject(i); +// if(binarObj.containsKey("enable") && binarObj.containsKey("description")){ +// boolean isEnable = binarObj.getBoolean("enable"); +// if(isEnable){ +// return null; +// } +// } +// } +// } + } else if (StringUtils.equalsAnyIgnoreCase(type, "KeyValue", "Form Data", "WWW_FORM")) { + if (bodyObj.containsKey("kvs")) { + JSONArray kvsArray = bodyObj.getJSONArray("kvs"); + for (int i = 0; i < kvsArray.size(); i++) { + JSONObject kvsObj = kvsArray.getJSONObject(i); + if (kvsObj.containsKey("enable") && kvsObj.containsKey("name") && kvsObj.containsKey("value")) { + boolean isEnable = kvsObj.getBoolean("enable"); + if (isEnable) { + return null; + } + } + } + } + } else if (StringUtils.equalsAnyIgnoreCase(type, "XML", "Raw")) { + String raw = bodyObj.getString("raw"); + if (StringUtils.isNotEmpty(raw)) { + return null; + } + } + } + } + return model; + } else { + return null; + } + } else { + return null; + } + } + + private MockExpectConfigResponse getEmptyRequestMockExpect(MockExpectConfigResponse model) { + JSONObject requestObj = model.getRequest(); + boolean isJsonParam = requestObj.getBoolean("jsonParam"); + if (isJsonParam) { + if (StringUtils.isEmpty(requestObj.getString("jsonData"))) { + return model; + } + } else { + JSONObject mockExpectJson = new JSONObject(); + JSONArray jsonArray = requestObj.getJSONArray("variables"); + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject object = jsonArray.getJSONObject(i); + String name = ""; + String value = ""; + if (object.containsKey("name")) { + name = String.valueOf(object.get("name")).trim(); + } + if (object.containsKey("value")) { + value = String.valueOf(object.get("value")).trim(); + } + if (StringUtils.isNotEmpty(name)) { + mockExpectJson.put(name, value); + } + } + if (mockExpectJson.isEmpty()) { + return model; + } + } + return null; + } + + public MockExpectConfigResponse findExpectConfigByArrayJson(Map requestHeaderMap, List mockExpectConfigList, JSONArray reqJsonArray) { MockExpectConfigResponse returnModel = null; if (reqJsonArray == null || reqJsonArray.isEmpty()) { @@ -393,34 +618,73 @@ public class MockConfigService { return returnModel; } - public String updateHttpServletResponse(MockExpectConfigResponse finalExpectConfig, HttpServletResponse response) { + public String updateHttpServletResponse(MockExpectConfigResponse finalExpectConfig, String url, Map headerMap, RequestMockParams requestMockParams, HttpServletResponse response) { String returnStr = ""; try { //设置响应头和响应码 JSONObject responseObj = finalExpectConfig.getResponse(); String httpCode = responseObj.getString("httpCode"); - JSONArray jsonArray = responseObj.getJSONArray("httpHeads"); - for (int i = 0; i < jsonArray.size(); i++) { - JSONObject object = jsonArray.getJSONObject(i); - String name = null; - String value = ""; - if (object.containsKey("name")) { - name = String.valueOf(object.get("name")).trim(); - } - if (object.containsKey("value")) { - value = String.valueOf(object.get("value")).trim(); - } - if (StringUtils.isNotEmpty(name)) { - response.setHeader(name, value); - } + if (StringUtils.isEmpty(httpCode)) { + httpCode = "500"; } response.setStatus(Integer.parseInt(httpCode)); - - returnStr = String.valueOf(responseObj.get("body")); - - if (responseObj.containsKey("delayed")) { + long sleepTime = 0; + if (responseObj.containsKey("responseResult")) { + JSONObject responseJsonObj = responseObj.getJSONObject("responseResult"); + if (responseJsonObj.containsKey("headers")) { + JSONArray jsonArray = responseJsonObj.getJSONArray("headers"); + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject object = jsonArray.getJSONObject(i); + if (object.containsKey("name") && object.containsKey("enable") && object.containsKey("value")) { + boolean isEnable = object.getBoolean("enable"); + if (isEnable) { + String name = String.valueOf(object.get("name")).trim(); + String value = String.valueOf(object.get("value")).trim(); + if (StringUtils.isNotEmpty(name)) { + response.setHeader(name, value); + } + } + } + } + } + if (responseJsonObj.containsKey("body")) { + returnStr = MockApiUtils.getResultByResponseResult(responseJsonObj.getJSONObject("body"), url, headerMap, requestMockParams); + } + if (responseJsonObj.containsKey("httpCode")) { + response.setStatus(Integer.parseInt(responseJsonObj.getString("httpCode"))); + } + if (responseJsonObj.containsKey("delayed")) { + try { + sleepTime = Long.parseLong(String.valueOf(responseJsonObj.get("delayed"))); + } catch (Exception e) { + } + } + } else { + JSONArray jsonArray = responseObj.getJSONArray("httpHeads"); + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject object = jsonArray.getJSONObject(i); + String name = null; + String value = ""; + if (object.containsKey("name")) { + name = String.valueOf(object.get("name")).trim(); + } + if (object.containsKey("value")) { + value = String.valueOf(object.get("value")).trim(); + } + if (StringUtils.isNotEmpty(name)) { + response.setHeader(name, value); + } + } + returnStr = String.valueOf(responseObj.get("body")); + if (responseObj.containsKey("delayed")) { + try { + sleepTime = Long.parseLong(String.valueOf(responseObj.get("delayed"))); + } catch (Exception e) { + } + } + } + if (sleepTime > 0) { try { - long sleepTime = Long.parseLong(String.valueOf(responseObj.get("delayed"))); Thread.sleep(sleepTime); } catch (Exception e) { } @@ -480,7 +744,7 @@ public class MockConfigService { if (bodyObj.containsKey("jsonSchema") && bodyObj.getJSONObject("jsonSchema").containsKey("properties")) { String bodyRetunStr = bodyObj.getJSONObject("jsonSchema").getJSONObject("properties").toJSONString(); JSONObject bodyReturnObj = JSONObject.parseObject(bodyRetunStr); - JSONObject returnObj = this.parseJsonSchema(bodyReturnObj); + JSONObject returnObj = MockApiUtils.parseJsonSchema(bodyReturnObj); returnStr = returnObj.toJSONString(); } } else { @@ -515,37 +779,38 @@ public class MockConfigService { } } returnStr = JSONObject.toJSONString(paramMap); - } else if (StringUtils.equals(type, "BINARY")) { - Map paramMap = new LinkedHashMap<>(); - if (bodyObj.containsKey("binary")) { - JSONArray kvsArr = bodyObj.getJSONArray("kvs"); - for (int i = 0; i < kvsArr.size(); i++) { - JSONObject kv = kvsArr.getJSONObject(i); - if (kv.containsKey("description") && kv.containsKey("files")) { - String name = kv.getString("description"); - JSONArray fileArr = kv.getJSONArray("files"); - String allValue = ""; - for (int j = 0; j < fileArr.size(); j++) { - JSONObject fileObj = fileArr.getJSONObject(j); - if (fileObj.containsKey("name")) { - String values = fileObj.getString("name"); - if (StringUtils.isEmpty(values)) { - values = ""; - } else { - try { - values = values.startsWith("@") ? ScriptEngineUtils.buildFunctionCallString(values) : values; - } catch (Exception e) { - } - } - - allValue += values + " ;"; - } - } - paramMap.put(name, allValue); - } - } - } - returnStr = JSONObject.toJSONString(paramMap); + //Binary的先不处理 +// } else if (StringUtils.equals(type, "BINARY")) { +// Map paramMap = new LinkedHashMap<>(); +// if (bodyObj.containsKey("binary")) { +// JSONArray kvsArr = bodyObj.getJSONArray("kvs"); +// for (int i = 0; i < kvsArr.size(); i++) { +// JSONObject kv = kvsArr.getJSONObject(i); +// if (kv.containsKey("description") && kv.containsKey("files")) { +// String name = kv.getString("description"); +// JSONArray fileArr = kv.getJSONArray("files"); +// String allValue = ""; +// for (int j = 0; j < fileArr.size(); j++) { +// JSONObject fileObj = fileArr.getJSONObject(j); +// if (fileObj.containsKey("name")) { +// String values = fileObj.getString("name"); +// if (StringUtils.isEmpty(values)) { +// values = ""; +// } else { +// try { +// values = values.startsWith("@") ? ScriptEngineUtils.buildFunctionCallString(values) : values; +// } catch (Exception e) { +// } +// } +// +// allValue += values + " ;"; +// } +// } +// paramMap.put(name, allValue); +// } +// } +// } +// returnStr = JSONObject.toJSONString(paramMap); } } } @@ -563,80 +828,28 @@ public class MockConfigService { return returnStr; } - private JSONObject parseJsonSchema(JSONObject bodyReturnObj) { - JSONObject returnObj = new JSONObject(); - if (bodyReturnObj == null) { - return returnObj; - } - - Set keySet = bodyReturnObj.keySet(); - for (String key : keySet) { - try { - JsonSchemaReturnObj obj = bodyReturnObj.getObject(key, JsonSchemaReturnObj.class); - if (StringUtils.equals("object", obj.getType())) { - JSONObject itemObj = this.parseJsonSchema(obj.getProperties()); - if (!itemObj.isEmpty()) { - returnObj.put(key, itemObj); - } - } else if (StringUtils.equals("array", obj.getType())) { - if (obj.getItems() != null) { - JSONObject itemObj = obj.getItems(); - if (itemObj.containsKey("type")) { - if (StringUtils.equals("object", itemObj.getString("type")) && itemObj.containsKey("properties")) { - JSONObject arrayObj = itemObj.getJSONObject("properties"); - JSONObject parseObj = this.parseJsonSchema(arrayObj); - JSONArray array = new JSONArray(); - array.add(parseObj); - returnObj.put(key, array); - } else if (StringUtils.equals("string", itemObj.getString("type")) && itemObj.containsKey("mock")) { - JsonSchemaReturnObj arrayObj = JSONObject.toJavaObject(itemObj, JsonSchemaReturnObj.class); - String value = this.getMockValues(arrayObj.getMockValue()); - JSONArray array = new JSONArray(); - array.add(value); - returnObj.put(key, array); - } - } - } - } else { - String values = obj.getMockValue(); - if (StringUtils.isEmpty(values)) { - values = ""; - } else { - try { - values = values.startsWith("@") ? ScriptEngineUtils.buildFunctionCallString(values) : values; - } catch (Exception e) { - } - } - returnObj.put(key, values); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - return returnObj; - } - - private String getMockValues(String values) { - if (StringUtils.isEmpty(values)) { - values = ""; - } else { - try { - values = values.startsWith("@") ? ScriptEngineUtils.buildFunctionCallString(values) : values; - } catch (Exception e) { - } - } - return values; - } - public MockExpectConfigWithBLOBs findMockExpectConfigById(String id) { return mockExpectConfigMapper.selectByPrimaryKey(id); } public void deleteMockExpectConfig(String id) { - mockExpectConfigMapper.deleteByPrimaryKey(id); + MockExpectConfigWithBLOBs mockBlobs = mockExpectConfigMapper.selectByPrimaryKey(id); + if (mockBlobs != null) { + this.deleteMockExpectFiles(mockBlobs); + mockExpectConfigMapper.deleteByPrimaryKey(id); + } } - public void deleteMockConfigByApiId(String apiId){ + private void deleteMockExpectFiles(MockExpectConfigWithBLOBs mockExpectConfigWithBLOBs) { + if (mockExpectConfigWithBLOBs != null && StringUtils.isNotEmpty(mockExpectConfigWithBLOBs.getRequest())) { + try { + FileUtils.deleteBodyFiles(mockExpectConfigWithBLOBs.getId()); + } catch (Exception e) { + } + } + } + + public void deleteMockConfigByApiId(String apiId) { MockConfigExample configExample = new MockConfigExample(); configExample.createCriteria().andApiIdEqualTo(apiId); List mockConfigList = mockConfigMapper.selectByExample(configExample); @@ -644,20 +857,31 @@ public class MockConfigService { for (MockConfig mockConfig : mockConfigList) { example.clear(); example.createCriteria().andMockConfigIdEqualTo(mockConfig.getId()); + List deleteBolobs = mockExpectConfigMapper.selectByExampleWithBLOBs(example); + for (MockExpectConfigWithBLOBs model : deleteBolobs) { + this.deleteMockExpectFiles(model); + } mockExpectConfigMapper.deleteByExample(example); } mockConfigMapper.deleteByExample(configExample); } - public JSONObject getGetParamMap(String urlParams, ApiDefinitionWithBLOBs api, HttpServletRequest request) { - JSONObject paramMap = this.getSendRestParamMapByIdAndUrl(api, urlParams); + public RequestMockParams getGetParamMap(String urlParams, ApiDefinitionWithBLOBs api, HttpServletRequest request) { + RequestMockParams requestMockParams = new RequestMockParams(); + + JSONObject urlParamsObject = this.getSendRestParamMapByIdAndUrl(api, urlParams); + + JSONObject queryParamsObject = new JSONObject(); Enumeration paramNameItor = request.getParameterNames(); while (paramNameItor.hasMoreElements()) { String key = paramNameItor.nextElement(); String value = request.getParameter(key); - paramMap.put(key, value); + queryParamsObject.put(key, value); } - return paramMap; + + requestMockParams.setRestParamsObj(urlParamsObject); + requestMockParams.setQueryParamsObj(queryParamsObject); + return requestMockParams; } public JSON getPostParamMap(HttpServletRequest request) { @@ -699,13 +923,14 @@ public class MockConfigService { } else { JSONObject object = new JSONObject(); String bodyParam = this.readBody(request); - if (!StringUtils.isEmpty(bodyParam)) { - try { - object = JSONObject.parseObject(bodyParam); - } catch (Exception e) { - e.printStackTrace(); - } - } + object.put("raw",bodyParam); +// if (!StringUtils.isEmpty(bodyParam)) { +// try { +// object = JSONObject.parseObject(bodyParam); +// } catch (Exception e) { +// object.put("raw",bodyParam); +// } +// } Enumeration paramNameItor = request.getParameterNames(); while (paramNameItor.hasMoreElements()) { @@ -881,29 +1106,30 @@ public class MockConfigService { } } } - } else if (StringUtils.equals(type, "BINARY")) { - if (bodyObj.containsKey("binary")) { - List> bodyParamList = new ArrayList<>(); - JSONArray kvsArr = bodyObj.getJSONArray("binary"); - - for (int i = 0; i < kvsArr.size(); i++) { - JSONObject kv = kvsArr.getJSONObject(i); - if (kv.containsKey("description") && kv.containsKey("files")) { - String name = kv.getString("description"); - JSONArray fileArr = kv.getJSONArray("files"); - String value = ""; - for (int j = 0; j < fileArr.size(); j++) { - JSONObject fileObj = fileArr.getJSONObject(j); - if (fileObj.containsKey("name")) { - value += fileObj.getString("name") + " ;"; - } - } - if (!paramNameList.contains(name)) { - paramNameList.add(name); - } - } - } - } + //Binary的先不处理 +// } else if (StringUtils.equals(type, "BINARY")) { +// if (bodyObj.containsKey("binary")) { +// List> bodyParamList = new ArrayList<>(); +// JSONArray kvsArr = bodyObj.getJSONArray("binary"); +// +// for (int i = 0; i < kvsArr.size(); i++) { +// JSONObject kv = kvsArr.getJSONObject(i); +// if (kv.containsKey("description") && kv.containsKey("files")) { +// String name = kv.getString("description"); +// JSONArray fileArr = kv.getJSONArray("files"); +// String value = ""; +// for (int j = 0; j < fileArr.size(); j++) { +// JSONObject fileObj = fileArr.getJSONObject(j); +// if (fileObj.containsKey("name")) { +// value += fileObj.getString("name") + " ;"; +// } +// } +// if (!paramNameList.contains(name)) { +// paramNameList.add(name); +// } +// } +// } +// } } } } catch (Exception e) { @@ -946,10 +1172,11 @@ public class MockConfigService { return this.assemblyMockConfingResponse(configList); } - public String checkReturnWithMockExpectByBodyParam(String method, Project project, HttpServletRequest + public String checkReturnWithMockExpectByBodyParam(String method, Map requestHeaderMap, Project project, HttpServletRequest request, HttpServletResponse response) { String returnStr = ""; boolean isMatch = false; + String url = request.getRequestURL().toString(); List aualifiedApiList = new ArrayList<>(); if (project != null) { String urlSuffix = this.getUrlSuffix(project.getSystemId(), request); @@ -960,33 +1187,40 @@ public class MockConfigService { if (mockConfigData != null && mockConfigData.getMockExpectConfigList() != null) { JSON paramJson = this.getPostParamMap(request); if (paramJson instanceof JSONObject) { - JSONObject paramMap = (JSONObject) paramJson; - MockExpectConfigResponse finalExpectConfig = this.findExpectConfig(mockConfigData.getMockExpectConfigList(), paramMap); + JSONArray paramsArray = new JSONArray(); + paramsArray.add(paramJson); + RequestMockParams mockParams = new RequestMockParams(); + mockParams.setBodyParams(paramsArray); + MockExpectConfigResponse finalExpectConfig = this.findExpectConfig(requestHeaderMap, mockConfigData.getMockExpectConfigList(), mockParams); if (finalExpectConfig != null) { isMatch = true; - returnStr = this.updateHttpServletResponse(finalExpectConfig, response); + returnStr = this.updateHttpServletResponse(finalExpectConfig, url, requestHeaderMap, mockParams, response); } } else if (paramJson instanceof JSONArray) { JSONArray paramArray = (JSONArray) paramJson; - MockExpectConfigResponse finalExpectConfig = this.findExpectConfig(mockConfigData.getMockExpectConfigList(), paramArray); + RequestMockParams mockParams = new RequestMockParams(); + mockParams.setBodyParams(paramArray); + MockExpectConfigResponse finalExpectConfig = this.findExpectConfig(requestHeaderMap, mockConfigData.getMockExpectConfigList(), mockParams); if (finalExpectConfig != null) { isMatch = true; - returnStr = this.updateHttpServletResponse(finalExpectConfig, response); + returnStr = this.updateHttpServletResponse(finalExpectConfig, url, requestHeaderMap, mockParams, response); } } } } if (!isMatch) { - returnStr = this.updateHttpServletResponse(aualifiedApiList, response); +// returnStr = this.updateHttpServletResponse(aualifiedApiList, response); + response.setStatus(404); } return returnStr; } - public String checkReturnWithMockExpectByUrlParam(String method, Project project, HttpServletRequest + public String checkReturnWithMockExpectByUrlParam(String method, Map requestHeaderMap, Project project, HttpServletRequest request, HttpServletResponse response) { String returnStr = ""; boolean isMatch = false; + String url = request.getRequestURI(); List aualifiedApiList = new ArrayList<>(); if (project != null) { String urlSuffix = this.getUrlSuffix(project.getSystemId(), request); @@ -1001,13 +1235,13 @@ public class MockConfigService { */ for (ApiDefinitionWithBLOBs api : aualifiedApiList) { - JSONObject paramMap = this.getGetParamMap(urlSuffix, api, request); + RequestMockParams paramMap = this.getGetParamMap(urlSuffix, api, request); MockConfigResponse mockConfigData = this.findByApiId(api.getId()); if (mockConfigData != null && mockConfigData.getMockExpectConfigList() != null) { - MockExpectConfigResponse finalExpectConfig = this.findExpectConfig(mockConfigData.getMockExpectConfigList(), paramMap); + MockExpectConfigResponse finalExpectConfig = this.findExpectConfig(requestHeaderMap, mockConfigData.getMockExpectConfigList(), paramMap); if (finalExpectConfig != null) { - returnStr = this.updateHttpServletResponse(finalExpectConfig, response); + returnStr = this.updateHttpServletResponse(finalExpectConfig, url, requestHeaderMap, paramMap, response); isMatch = true; break; } @@ -1016,7 +1250,8 @@ public class MockConfigService { } if (!isMatch) { - returnStr = this.updateHttpServletResponse(aualifiedApiList, response); +// returnStr = this.updateHttpServletResponse(aualifiedApiList, response); + response.setStatus(404); } return returnStr; } @@ -1149,9 +1384,9 @@ public class MockConfigService { JSONObject sourceObj = XMLUtils.XmlToJson(message); String xmlStr = ""; try { - List tcpDataList = JSONArray.parseArray(requestJson.getString("xmlDataStruct"),TcpTreeTableDataStruct.class); + List tcpDataList = JSONArray.parseArray(requestJson.getString("xmlDataStruct"), TcpTreeTableDataStruct.class); xmlStr = TcpTreeTableDataParser.treeTableData2Xml(tcpDataList); - }catch (Exception e){ + } catch (Exception e) { } JSONObject matchObj = XMLUtils.XmlToJson(xmlStr); @@ -1191,12 +1426,12 @@ public class MockConfigService { } } //优先返回结构匹配的数据 - if(!structResult.isEmpty()){ + if (!structResult.isEmpty()) { return structResult.get(0); - }else { - if(!rawResult.isEmpty()){ + } else { + if (!rawResult.isEmpty()) { return rawResult.get(0); - }else { + } else { return null; } } @@ -1228,20 +1463,20 @@ public class MockConfigService { } public void importMock(ApiDefinitionImport apiImport, SqlSession sqlSession, ApiTestImportRequest request) { - if(CollectionUtils.isNotEmpty(apiImport.getMocks())){ - Map> saveMap = new HashMap<>(); + if (CollectionUtils.isNotEmpty(apiImport.getMocks())) { + Map> saveMap = new HashMap<>(); for (MockConfigImportDTO dto : apiImport.getMocks()) { String apiId = dto.getApiId();//de33108c-26e2-4d4f-826a-a5f8e017d2f4 - if(saveMap.containsKey(apiId)){ + if (saveMap.containsKey(apiId)) { saveMap.get(apiId).add(dto); - }else { + } else { List list = new ArrayList<>(); list.add(dto); - saveMap.put(apiId,list); + saveMap.put(apiId, list); } } - for (Map.Entry> entry : saveMap.entrySet()) { + for (Map.Entry> entry : saveMap.entrySet()) { String apiId = entry.getKey(); this.deleteMockConfigByApiId(apiId); 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 214a98fb48..4f0bb742e3 100644 --- a/backend/src/main/java/io/metersphere/commons/utils/JsonStructUtils.java +++ b/backend/src/main/java/io/metersphere/commons/utils/JsonStructUtils.java @@ -24,7 +24,13 @@ public class JsonStructUtils { * @return */ public static boolean checkJsonObjCompliance(JSONObject sourceObj, JSONObject matchObj) { - if (sourceObj == null && matchObj == null) { + if(sourceObj == null){ + sourceObj = new JSONObject(); + } + if(matchObj == null){ + matchObj = new JSONObject(); + } + if (sourceObj .isEmpty() && matchObj.isEmpty()) { return true; } else if (sourceObj != null && matchObj != null) { boolean lastMatchResultIsTrue = false; @@ -55,7 +61,7 @@ public class JsonStructUtils { public static boolean checkJsonArrayCompliance(JSONArray sourceArray, JSONArray matchArray) { if (sourceArray == null && matchArray == null) { return true; - } else if (sourceArray != null && matchArray != null && sourceArray.size() > matchArray.size()) { + } else if (sourceArray != null && matchArray != null && sourceArray.size() >= matchArray.size()) { try { for (int i = 0; i < matchArray.size(); i++) { Object obj = matchArray.get(i); diff --git a/frontend/src/business/components/api/definition/components/EditCompleteContainer.vue b/frontend/src/business/components/api/definition/components/EditCompleteContainer.vue index 9d930aa566..faa21f3a00 100644 --- a/frontend/src/business/components/api/definition/components/EditCompleteContainer.vue +++ b/frontend/src/business/components/api/definition/components/EditCompleteContainer.vue @@ -74,7 +74,8 @@
- + +
@@ -104,7 +105,7 @@ import MsRunTestHttpPage from "./runtest/RunTestHTTPPage"; import MsRunTestTcpPage from "./runtest/RunTestTCPPage"; import MsRunTestSqlPage from "./runtest/RunTestSQLPage"; import MsRunTestDubboPage from "./runtest/RunTestDubboPage"; -import MockConfig from "@/business/components/api/definition/components/mock/MockConfig"; +import MockTab from "@/business/components/api/definition/components/mock/MockTab"; import TcpMockConfig from "@/business/components/api/definition/components/mock/TcpMockConfig"; import ApiCaseSimpleList from "./list/ApiCaseSimpleList"; import MsApiCaseList from "./case/ApiCaseList"; @@ -120,7 +121,7 @@ export default { MsRunTestTcpPage, MsRunTestSqlPage, MsRunTestDubboPage, - MockConfig, + MockTab, TcpMockConfig, ApiCaseSimpleList, MsApiCaseList diff --git a/frontend/src/business/components/api/definition/components/body/ApiBody.vue b/frontend/src/business/components/api/definition/components/body/ApiBody.vue index bd00d8731c..cfafc13fcb 100644 --- a/frontend/src/business/components/api/definition/components/body/ApiBody.vue +++ b/frontend/src/business/components/api/definition/components/body/ApiBody.vue @@ -128,6 +128,7 @@ export default { propIsEnumerable: Object.prototype.propertyIsEnumerable }; }, + watch: { 'body.raw'() { if (this.body.format !== 'JSON-SCHEMA' && this.body.raw) { @@ -141,7 +142,7 @@ export default { this.body.jsonSchema = ""; } } - } + }, }, methods: { isObj(x) { diff --git a/frontend/src/business/components/api/definition/components/body/ApiBodyFileUpload.vue b/frontend/src/business/components/api/definition/components/body/ApiBodyFileUpload.vue index e226346057..cf8f244d3f 100644 --- a/frontend/src/business/components/api/definition/components/body/ApiBodyFileUpload.vue +++ b/frontend/src/business/components/api/definition/components/body/ApiBodyFileUpload.vue @@ -13,7 +13,7 @@
- {{file.file ? file.file.name : file.name}} + {{file.file && file.file.name ? file.file.name : file.name}} diff --git a/frontend/src/business/components/api/definition/components/mock/Components/MockApiBody.vue b/frontend/src/business/components/api/definition/components/mock/Components/MockApiBody.vue new file mode 100644 index 0000000000..c955e92fc7 --- /dev/null +++ b/frontend/src/business/components/api/definition/components/mock/Components/MockApiBody.vue @@ -0,0 +1,345 @@ + + + + + diff --git a/frontend/src/business/components/api/definition/components/mock/Components/MockApiResponseBody.vue b/frontend/src/business/components/api/definition/components/mock/Components/MockApiResponseBody.vue new file mode 100644 index 0000000000..e40a1ee802 --- /dev/null +++ b/frontend/src/business/components/api/definition/components/mock/Components/MockApiResponseBody.vue @@ -0,0 +1,396 @@ + + + + + diff --git a/frontend/src/business/components/api/definition/components/mock/Components/MockApiScriptEditor.vue b/frontend/src/business/components/api/definition/components/mock/Components/MockApiScriptEditor.vue new file mode 100644 index 0000000000..06962109d3 --- /dev/null +++ b/frontend/src/business/components/api/definition/components/mock/Components/MockApiScriptEditor.vue @@ -0,0 +1,210 @@ + + + + + diff --git a/frontend/src/business/components/api/definition/components/mock/Components/MockScriptNavMenu.vue b/frontend/src/business/components/api/definition/components/mock/Components/MockScriptNavMenu.vue new file mode 100644 index 0000000000..dfd92e5a92 --- /dev/null +++ b/frontend/src/business/components/api/definition/components/mock/Components/MockScriptNavMenu.vue @@ -0,0 +1,228 @@ + + + + + diff --git a/frontend/src/business/components/api/definition/components/mock/MockConfig.vue b/frontend/src/business/components/api/definition/components/mock/MockConfig.vue index 319a48f9c4..c0bcb93683 100644 --- a/frontend/src/business/components/api/definition/components/mock/MockConfig.vue +++ b/frontend/src/business/components/api/definition/components/mock/MockConfig.vue @@ -219,35 +219,7 @@ export default { this.apiParams = response.data; }); }, - copyExpect(row) { - let selectUrl = "/mockConfig/mockExpectConfig/" + row.id; - this.$get(selectUrl, response => { - let data = response.data; - this.showHeadTable = false; - this.mockExpectConfig = data; - this.mockExpectConfig.id = ""; - this.mockExpectConfig.name = this.mockExpectConfig.name + "_copy"; - if (this.mockExpectConfig.request == null) { - this.mockExpectConfig.request = { - jsonParam: false, - variables: [], - jsonData: "{}", - }; - } - if (this.mockExpectConfig.response == null) { - this.mockExpectConfig.response = { - httpCode: "", - delayed: "", - httpHeads: [], - body: "", - }; - } - this.$nextTick(function () { - this.showHeadTable = true; - this.saveMockExpectConfig(); - }); - }); - }, + removeExpect(row) { this.$confirm(this.$t('api_test.mock.delete_mock_expect'), this.$t('commons.prompt'), { confirmButtonText: this.$t('commons.confirm'), @@ -332,40 +304,6 @@ export default { } }); }, - changeStatus(row) { - let mockParam = {}; - mockParam.id = row.id; - mockParam.status = row.status; - this.$post('/mockConfig/updateMockExpectConfig', mockParam, response => { - }); - }, - clickRow(row, column, event) { - this.cleanMockExpectConfig(); - let selectUrl = "/mockConfig/mockExpectConfig/" + row.id; - this.$get(selectUrl, response => { - let data = response.data; - this.showHeadTable = false; - this.mockExpectConfig = data; - if (this.mockExpectConfig.request == null) { - this.mockExpectConfig.request = { - jsonParam: false, - variables: [], - jsonData: "{}", - }; - } - if (this.mockExpectConfig.response == null) { - this.mockExpectConfig.response = { - httpCode: "", - delayed: "", - httpHeads: [], - body: "", - }; - } - this.$nextTick(function () { - this.showHeadTable = true; - }); - }); - } } }; diff --git a/frontend/src/business/components/api/definition/components/mock/MockConfigHeader.vue b/frontend/src/business/components/api/definition/components/mock/MockConfigHeader.vue new file mode 100644 index 0000000000..aae676b742 --- /dev/null +++ b/frontend/src/business/components/api/definition/components/mock/MockConfigHeader.vue @@ -0,0 +1,101 @@ + + + + + diff --git a/frontend/src/business/components/api/definition/components/mock/MockEditDrawer.vue b/frontend/src/business/components/api/definition/components/mock/MockEditDrawer.vue new file mode 100644 index 0000000000..5bb713ec8c --- /dev/null +++ b/frontend/src/business/components/api/definition/components/mock/MockEditDrawer.vue @@ -0,0 +1,343 @@ + + + + diff --git a/frontend/src/business/components/api/definition/components/mock/MockRequestParam.vue b/frontend/src/business/components/api/definition/components/mock/MockRequestParam.vue new file mode 100644 index 0000000000..f7a328fb1a --- /dev/null +++ b/frontend/src/business/components/api/definition/components/mock/MockRequestParam.vue @@ -0,0 +1,390 @@ + + + + + diff --git a/frontend/src/business/components/api/definition/components/mock/MockResponseParam.vue b/frontend/src/business/components/api/definition/components/mock/MockResponseParam.vue new file mode 100644 index 0000000000..01069cc34e --- /dev/null +++ b/frontend/src/business/components/api/definition/components/mock/MockResponseParam.vue @@ -0,0 +1,216 @@ + + + + + diff --git a/frontend/src/business/components/api/definition/components/mock/MockRowVariables.vue b/frontend/src/business/components/api/definition/components/mock/MockRowVariables.vue index cef3a9b69d..26a76a23e7 100644 --- a/frontend/src/business/components/api/definition/components/mock/MockRowVariables.vue +++ b/frontend/src/business/components/api/definition/components/mock/MockRowVariables.vue @@ -14,8 +14,6 @@ - - +
+
+ + {{ $t('commons.add') }} + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + diff --git a/frontend/src/business/components/common/components/MsDoughnutPieChart.vue b/frontend/src/business/components/common/components/MsDoughnutPieChart.vue index f4a13e19d9..a0825ce371 100644 --- a/frontend/src/business/components/common/components/MsDoughnutPieChart.vue +++ b/frontend/src/business/components/common/components/MsDoughnutPieChart.vue @@ -72,6 +72,8 @@ export default { this.reload(); } }, + created() { + }, mounted() { this.reload(); }, diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index 7546e6508f..53356ffd00 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -831,6 +831,7 @@ export default { update_time: "Update time" }, expect_detail: "Expect", + request_condition:"Request Condition", base_info: "Base info", req_param: "Request params", rsp_param: "Response Params", diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index 60b1f1d99f..94679c173d 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -837,6 +837,7 @@ export default { update_time: "更新时间" }, expect_detail: "期望详情", + request_condition:"请求触发条件", base_info: "基本信息", req_param: "请求参数", rsp_param: "响应内容", diff --git a/frontend/src/i18n/zh-TW.js b/frontend/src/i18n/zh-TW.js index fc7e0b6c86..f12447d808 100644 --- a/frontend/src/i18n/zh-TW.js +++ b/frontend/src/i18n/zh-TW.js @@ -837,6 +837,7 @@ export default { update_time: "更新時間" }, expect_detail: "期望詳情", + request_condition:"請求觸發條件", base_info: "基本信息", req_param: "請求參數", rsp_param: "響應內容",