feat(Mock优化): #1003356 Mock服务期望及响应配置优化
【Mock服务期望及响应配置优化】 https://www.tapd.cn/55049933/prong/stories/view/1155049933001003356
This commit is contained in:
parent
5453dcdcec
commit
6392190f54
|
@ -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<String,String> 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<String,String> 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<String,String> 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<String,String> 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<String,String> 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<String,String> 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<String,String> requestHeaderMap = MockApiUtils.getHttpRequestHeader(request);
|
||||
mockConfigService.checkReturnWithMockExpectByUrlParam("HEAD", requestHeaderMap, project, request, response);
|
||||
}
|
||||
|
||||
@GetMapping("/getTcpMockPortStatus/")
|
||||
|
|
|
@ -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<MultipartFile> 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<MultipartFile> 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<Map<String, String>> apiParams = mockConfigService.getApiParamsByApiDefinitionBLOBs(apiDefinitionWithBLOBs);
|
||||
return apiParams;
|
||||
}
|
||||
|
||||
@GetMapping("/getApiResponse/{id}")
|
||||
public Map<String, String> getApiResponse(@PathVariable String id) {
|
||||
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = apiDefinitionService.getBLOBs(id);
|
||||
Map<String, String> returnMap = MockApiUtils.getApiResponse(apiDefinitionWithBLOBs.getResponse());
|
||||
return returnMap;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<String,String> getHttpRequestHeader(HttpServletRequest request){
|
||||
Map<String,String> returnMap = new HashMap<>();
|
||||
Enumeration<String> 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<String, String> requestHeaderMap) {
|
||||
Map<String,String> 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<String, String> 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<String> 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<String, String> getApiResponse(String response) {
|
||||
Map<String, String> 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<String, String> 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<String,String> 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,"<?") && !StringUtils.endsWith(xmlHeader,"?>")){
|
||||
returnStr = "<?"+xmlHeader+"?>\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<String,String> 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());
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -27,4 +27,6 @@ public class MockExpectConfigRequest {
|
|||
private Object response;
|
||||
|
||||
private String status;
|
||||
|
||||
private String copyId;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -295,6 +295,9 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
|
|||
if (StringUtils.isNotBlank(node.getId())) {
|
||||
criteria.andIdNotEqualTo(node.getId());
|
||||
}
|
||||
if(StringUtils.isNotEmpty(node.getProtocol())){
|
||||
criteria.andProtocolEqualTo(node.getProtocol());
|
||||
}
|
||||
return apiModuleMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<MockExpectConfigWithBLOBs> selectMockExpectConfigByApiId(String apiId){
|
||||
public List<MockExpectConfigWithBLOBs> selectMockExpectConfigByApiId(String apiId) {
|
||||
return extMockExpectConfigMapper.selectByApiId(apiId);
|
||||
}
|
||||
|
||||
public List<MockConfigImportDTO> selectMockExpectConfigByApiIdIn(List<String> apiIds){
|
||||
if(CollectionUtils.isNotEmpty(apiIds)){
|
||||
public List<MockConfigImportDTO> selectMockExpectConfigByApiIdIn(List<String> apiIds) {
|
||||
if (CollectionUtils.isNotEmpty(apiIds)) {
|
||||
List<MockConfigImportDTO> returnDTO = new ArrayList<>();
|
||||
for (String apiId : apiIds) {
|
||||
List<MockExpectConfigWithBLOBs> 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<MultipartFile> 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<MockExpectConfigResponse> mockExpectConfigList, JSONObject reqJsonObj) {
|
||||
public MockExpectConfigResponse findExpectConfig(Map<String, String> requestHeaderMap, List<MockExpectConfigResponse> 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<MockExpectConfigResponse> mockExpectConfigList, JSONArray reqJsonArray) {
|
||||
private boolean isRequestMockExpectMatchingByParams(Map<String, String> 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<String, String> 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<String, String> requestHeaderMap, List<MockExpectConfigResponse> 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<String, String> 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<String, String> 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<String, String> 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<String> 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<MockConfig> mockConfigList = mockConfigMapper.selectByExample(configExample);
|
||||
|
@ -644,20 +857,31 @@ public class MockConfigService {
|
|||
for (MockConfig mockConfig : mockConfigList) {
|
||||
example.clear();
|
||||
example.createCriteria().andMockConfigIdEqualTo(mockConfig.getId());
|
||||
List<MockExpectConfigWithBLOBs> 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<String> 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<String> paramNameItor = request.getParameterNames();
|
||||
while (paramNameItor.hasMoreElements()) {
|
||||
|
@ -881,29 +1106,30 @@ public class MockConfigService {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.equals(type, "BINARY")) {
|
||||
if (bodyObj.containsKey("binary")) {
|
||||
List<Map<String, String>> 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<Map<String, String>> 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<String, String> requestHeaderMap, Project project, HttpServletRequest
|
||||
request, HttpServletResponse response) {
|
||||
String returnStr = "";
|
||||
boolean isMatch = false;
|
||||
String url = request.getRequestURL().toString();
|
||||
List<ApiDefinitionWithBLOBs> 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<String, String> requestHeaderMap, Project project, HttpServletRequest
|
||||
request, HttpServletResponse response) {
|
||||
String returnStr = "";
|
||||
boolean isMatch = false;
|
||||
String url = request.getRequestURI();
|
||||
List<ApiDefinitionWithBLOBs> 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<TcpTreeTableDataStruct> tcpDataList = JSONArray.parseArray(requestJson.getString("xmlDataStruct"),TcpTreeTableDataStruct.class);
|
||||
List<TcpTreeTableDataStruct> 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<String,List<MockExpectConfigWithBLOBs>> saveMap = new HashMap<>();
|
||||
if (CollectionUtils.isNotEmpty(apiImport.getMocks())) {
|
||||
Map<String, List<MockExpectConfigWithBLOBs>> 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<MockExpectConfigWithBLOBs> list = new ArrayList<>();
|
||||
list.add(dto);
|
||||
saveMap.put(apiId,list);
|
||||
saveMap.put(apiId, list);
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String,List<MockExpectConfigWithBLOBs>> entry : saveMap.entrySet()) {
|
||||
for (Map.Entry<String, List<MockExpectConfigWithBLOBs>> entry : saveMap.entrySet()) {
|
||||
String apiId = entry.getKey();
|
||||
this.deleteMockConfigByApiId(apiId);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -74,7 +74,8 @@
|
|||
</div>
|
||||
|
||||
<div v-if="showMock && (currentProtocol === 'HTTP')" class="ms-api-div">
|
||||
<mock-config :base-mock-config-data="baseMockConfigData" type="http"/>
|
||||
<!-- <mock-config :base-mock-config-data="baseMockConfigData" type="http"/>-->
|
||||
<mock-tab :base-mock-config-data="baseMockConfigData" type="http"/>
|
||||
</div>
|
||||
<div v-if="showMock && (currentProtocol === 'TCP')" class="ms-api-div">
|
||||
<tcp-mock-config :base-mock-config-data="baseMockConfigData" type="tcp"/>
|
||||
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<i class="el-icon-plus"/>
|
||||
</div>
|
||||
<div class="upload-item" slot="file" slot-scope="{file}">
|
||||
<span>{{file.file ? file.file.name : file.name}}</span>
|
||||
<span>{{file.file && file.file.name ? file.file.name : file.name}}</span>
|
||||
<span class="el-upload-list__item-actions">
|
||||
<!--<span v-if="!disabled" class="el-upload-list__item-delete" @click="handleDownload(file)">-->
|
||||
<!--<i class="el-icon-download"/>-->
|
||||
|
|
|
@ -0,0 +1,345 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-radio-group v-model="body.type" size="mini">
|
||||
<el-radio :disabled="isReadOnly" :label="type.FORM_DATA" @change="modeChange">
|
||||
{{ $t('api_test.definition.request.body_form_data') }}
|
||||
</el-radio>
|
||||
|
||||
<el-radio :disabled="isReadOnly" :label="type.WWW_FORM" @change="modeChange">
|
||||
{{ $t('api_test.definition.request.body_x_www_from_urlencoded') }}
|
||||
</el-radio>
|
||||
|
||||
<el-radio :disabled="isReadOnly" :label="type.JSON" @change="modeChange">
|
||||
{{ $t('api_test.definition.request.body_json') }}
|
||||
</el-radio>
|
||||
|
||||
<el-radio :disabled="isReadOnly" :label="type.XML" @change="modeChange">
|
||||
{{ $t('api_test.definition.request.body_xml') }}
|
||||
</el-radio>
|
||||
|
||||
<el-radio :disabled="isReadOnly" :label="type.RAW" @change="modeChange">
|
||||
{{ $t('api_test.definition.request.body_raw') }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
<div style="min-width: 1200px;" v-if="body.type == 'Form Data' || body.type == 'WWW_FORM'">
|
||||
<el-row v-if="body.type == 'Form Data' || body.type == 'WWW_FORM'">
|
||||
<el-link class="ms-el-link" @click="batchAdd"> {{ $t("commons.batch_add") }}</el-link>
|
||||
</el-row>
|
||||
<ms-api-variable
|
||||
:with-mor-setting="true"
|
||||
:is-read-only="isReadOnly"
|
||||
:parameters="body.kvs"
|
||||
:isShowEnable="isShowEnable"
|
||||
type="body"/>
|
||||
</div>
|
||||
<div v-if="body.type == 'JSON'">
|
||||
<div style="padding: 10px">
|
||||
<el-switch active-text="JSON-SCHEMA" v-model="body.format" @change="formatChange" active-value="JSON-SCHEMA"/>
|
||||
</div>
|
||||
<ms-json-code-edit
|
||||
v-if="body.format==='JSON-SCHEMA'"
|
||||
:body="body"
|
||||
ref="jsonCodeEdit"/>
|
||||
<ms-code-edit
|
||||
v-else-if="codeEditActive"
|
||||
:read-only="isReadOnly"
|
||||
:data.sync="body.raw"
|
||||
:modes="modes"
|
||||
:mode="'json'"
|
||||
height="400px"
|
||||
ref="codeEdit"/>
|
||||
</div>
|
||||
|
||||
<div class="ms-body" v-if="body.type == 'XML'">
|
||||
<ms-code-edit
|
||||
:read-only="isReadOnly"
|
||||
:data.sync="body.raw"
|
||||
:modes="modes"
|
||||
:mode="'text'"
|
||||
ref="codeEdit"/>
|
||||
</div>
|
||||
|
||||
<div class="ms-body" v-if="body.type == 'Raw'">
|
||||
<ms-code-edit
|
||||
:read-only="isReadOnly"
|
||||
:data.sync="body.raw"
|
||||
:modes="modes"
|
||||
ref="codeEdit"/>
|
||||
</div>
|
||||
<batch-add-parameter @batchSave="batchSave" ref="batchAddParameter"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsApiKeyValue from "@/business/components/api/definition/components/ApiKeyValue";
|
||||
import {BODY_TYPE, KeyValue} from "@/business/components/api/definition/model/ApiTestModel";
|
||||
import MsCodeEdit from "@/business/components/common/components/MsCodeEdit";
|
||||
import MsJsonCodeEdit from "@/business/components/common/json-schema/JsonSchemaEditor";
|
||||
import MsDropdown from "@/business/components/common/components/MsDropdown";
|
||||
import MsApiVariable from "@/business/components/api/definition/components/ApiVariable";
|
||||
import MsApiFromUrlVariable from "@/business/components/api/definition/components/body/ApiFromUrlVariable";
|
||||
import BatchAddParameter from "@/business/components/api/definition/components/basis/BatchAddParameter";
|
||||
import Convert from "@/business/components/common/json-schema/convert/convert";
|
||||
|
||||
|
||||
export default {
|
||||
name: "MockApiBody",
|
||||
components: {
|
||||
MsApiVariable,
|
||||
MsDropdown,
|
||||
MsCodeEdit,
|
||||
MsApiKeyValue,
|
||||
MsApiFromUrlVariable,
|
||||
MsJsonCodeEdit,
|
||||
BatchAddParameter
|
||||
},
|
||||
props: {
|
||||
body: {},
|
||||
headers: Array,
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isShowEnable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
type: BODY_TYPE,
|
||||
modes: ['text', 'json', 'xml', 'html'],
|
||||
jsonSchema: "JSON",
|
||||
codeEditActive: true,
|
||||
hasOwnProperty: Object.prototype.hasOwnProperty,
|
||||
propIsEnumerable: Object.prototype.propertyIsEnumerable
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
'body.raw'() {
|
||||
if (this.body.format !== 'JSON-SCHEMA' && this.body.raw) {
|
||||
try {
|
||||
const MsConvert = new Convert();
|
||||
let data = MsConvert.format(JSON.parse(this.body.raw));
|
||||
if (this.body.jsonSchema) {
|
||||
this.body.jsonSchema = this.deepAssign(this.body.jsonSchema, data);
|
||||
}
|
||||
} catch (ex) {
|
||||
this.body.jsonSchema = "";
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
isObj(x) {
|
||||
let type = typeof x;
|
||||
return x !== null && (type === 'object' || type === 'function');
|
||||
},
|
||||
|
||||
toObject(val) {
|
||||
if (val === null || val === undefined) {
|
||||
return;
|
||||
}
|
||||
return Object(val);
|
||||
},
|
||||
|
||||
assignKey(to, from, key) {
|
||||
let val = from[key];
|
||||
if (val === undefined || val === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.hasOwnProperty.call(to, key) || !this.isObj(val)) {
|
||||
to[key] = val;
|
||||
} else {
|
||||
to[key] = this.assign(Object(to[key]), from[key]);
|
||||
}
|
||||
},
|
||||
|
||||
assign(to, from) {
|
||||
if (to === from) {
|
||||
return to;
|
||||
}
|
||||
from = Object(from);
|
||||
for (let key in from) {
|
||||
if (this.hasOwnProperty.call(from, key)) {
|
||||
this.assignKey(to, from, key);
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.getOwnPropertySymbols) {
|
||||
let symbols = Object.getOwnPropertySymbols(from);
|
||||
|
||||
for (let i = 0; i < symbols.length; i++) {
|
||||
if (this.propIsEnumerable.call(from, symbols[i])) {
|
||||
this.assignKey(to, from, symbols[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return to;
|
||||
},
|
||||
|
||||
deepAssign(target) {
|
||||
target = this.toObject(target);
|
||||
for (let s = 1; s < arguments.length; s++) {
|
||||
this.assign(target, arguments[s]);
|
||||
}
|
||||
return target;
|
||||
},
|
||||
reloadCodeEdit() {
|
||||
this.codeEditActive = false;
|
||||
this.$nextTick(() => {
|
||||
this.codeEditActive = true;
|
||||
});
|
||||
},
|
||||
formatChange() {
|
||||
const MsConvert = new Convert();
|
||||
|
||||
if (this.body.format === 'JSON-SCHEMA') {
|
||||
if (this.body.raw && !this.body.jsonSchema) {
|
||||
this.body.jsonSchema = MsConvert.format(JSON.parse(this.body.raw));
|
||||
}
|
||||
} else {
|
||||
if (this.body.jsonSchema) {
|
||||
MsConvert.schemaToJsonStr(this.body.jsonSchema, (result) => {
|
||||
this.$set(this.body, 'raw', result);
|
||||
this.reloadCodeEdit();
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
modeChange(mode) {
|
||||
switch (this.body.type) {
|
||||
case "JSON":
|
||||
this.setContentType("application/json");
|
||||
break;
|
||||
case "XML":
|
||||
this.setContentType("text/xml");
|
||||
break;
|
||||
case "WWW_FORM":
|
||||
this.setContentType("application/x-www-form-urlencoded");
|
||||
break;
|
||||
// todo from data
|
||||
// case "BINARY":
|
||||
// this.setContentType("application/octet-stream");
|
||||
// break;
|
||||
default:
|
||||
this.removeContentType();
|
||||
break;
|
||||
}
|
||||
},
|
||||
setContentType(value) {
|
||||
let isType = false;
|
||||
this.headers.forEach(item => {
|
||||
if (item.name === "Content-Type") {
|
||||
item.value = value;
|
||||
isType = true;
|
||||
}
|
||||
})
|
||||
if (!isType) {
|
||||
this.headers.unshift(new KeyValue({name: "Content-Type", value: value}));
|
||||
this.$emit('headersChange');
|
||||
}
|
||||
},
|
||||
removeContentType() {
|
||||
for (let index in this.headers) {
|
||||
if (this.headers[index].name === "Content-Type") {
|
||||
this.headers.splice(index, 1);
|
||||
this.$emit('headersChange');
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
batchAdd() {
|
||||
this.$refs.batchAddParameter.open();
|
||||
},
|
||||
format(array, obj) {
|
||||
if (array) {
|
||||
let isAdd = true;
|
||||
for (let i in array) {
|
||||
let item = array[i];
|
||||
if (item.name === obj.name) {
|
||||
item.value = obj.value;
|
||||
isAdd = false;
|
||||
}
|
||||
}
|
||||
if (isAdd) {
|
||||
this.body.kvs.unshift(obj);
|
||||
}
|
||||
}
|
||||
},
|
||||
batchSave(data) {
|
||||
if (data) {
|
||||
let params = data.split("\n");
|
||||
let keyValues = [];
|
||||
params.forEach(item => {
|
||||
let line = [];
|
||||
line[0] = item.substring(0,item.indexOf(":"));
|
||||
line[1] = item.substring(item.indexOf(":")+1,item.length);
|
||||
let required = false;
|
||||
keyValues.unshift(new KeyValue({
|
||||
name: line[0],
|
||||
required: required,
|
||||
value: line[1],
|
||||
description: line[2],
|
||||
type: "text",
|
||||
valid: false,
|
||||
file: false,
|
||||
encode: true,
|
||||
enable: true,
|
||||
contentType: "text/plain"
|
||||
}));
|
||||
})
|
||||
keyValues.forEach(item => {
|
||||
this.format(this.body.kvs, item);
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if (!this.body.type) {
|
||||
this.body.type = BODY_TYPE.FORM_DATA;
|
||||
}
|
||||
if (this.body.kvs) {
|
||||
this.body.kvs.forEach(param => {
|
||||
if (!param.type) {
|
||||
param.type = 'text';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.textarea {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.ms-body {
|
||||
padding: 15px 0;
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.el-dropdown {
|
||||
margin-left: 20px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.ace_editor {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.el-radio-group {
|
||||
margin: 10px 10px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.ms-el-link {
|
||||
float: right;
|
||||
margin-right: 45px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,396 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-radio-group v-model="body.type" size="mini">
|
||||
<el-radio :disabled="isReadOnly" :label="type.JSON" @change="modeChange">
|
||||
{{ $t('api_test.definition.request.body_json') }}
|
||||
</el-radio>
|
||||
<el-radio :disabled="isReadOnly" label="fromApi" @change="modeChange">
|
||||
<!-- {{ 跟随API定义 }}-->
|
||||
跟随API定义
|
||||
</el-radio>
|
||||
<el-radio :disabled="isReadOnly" :label="type.XML" @change="modeChange">
|
||||
{{ $t('api_test.definition.request.body_xml') }}
|
||||
</el-radio>
|
||||
<el-radio :disabled="isReadOnly" :label="type.RAW" @change="modeChange">
|
||||
{{ $t('api_test.definition.request.body_raw') }}
|
||||
</el-radio>
|
||||
<el-radio :disabled="isReadOnly" label="script" @change="modeChange">
|
||||
{{ $t('api_test.automation.customize_script') }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
<div class="ms-body" v-if="body.type == 'JSON'">
|
||||
<div style="padding: 10px">
|
||||
<el-switch active-text="JSON-SCHEMA" v-model="body.format" @change="formatChange" active-value="JSON-SCHEMA"/>
|
||||
</div>
|
||||
<ms-json-code-edit
|
||||
v-if="body.format==='JSON-SCHEMA'"
|
||||
:body="body"
|
||||
ref="jsonCodeEdit"/>
|
||||
<ms-code-edit
|
||||
v-else-if="codeEditActive && loadIsOver"
|
||||
:read-only="isReadOnly"
|
||||
:data.sync="body.raw"
|
||||
:modes="modes"
|
||||
:mode="'json'"
|
||||
height="90%"
|
||||
ref="codeEdit"/>
|
||||
</div>
|
||||
|
||||
<div class="ms-body" v-if="body.type == 'fromApi'">
|
||||
<ms-code-edit
|
||||
:read-only="true"
|
||||
:data.sync="body.apiRspRaw"
|
||||
:modes="modes"
|
||||
:mode="'text'"
|
||||
v-if="loadIsOver"
|
||||
height="90%"
|
||||
ref="fromApiCodeEdit"/>
|
||||
</div>
|
||||
|
||||
<div class="ms-body" v-if="body.type == 'XML'">
|
||||
<el-input v-model="body.xmlHeader" size="small" style="width: 400px;margin-bottom: 5px"/>
|
||||
<ms-code-edit
|
||||
:read-only="isReadOnly"
|
||||
:data.sync="body.xmlRaw"
|
||||
:modes="modes"
|
||||
:mode="'xml'"
|
||||
v-if="loadIsOver"
|
||||
height="90%"
|
||||
ref="codeEdit"/>
|
||||
</div>
|
||||
|
||||
<div class="ms-body" v-if="body.type == 'Raw'">
|
||||
<ms-code-edit
|
||||
:read-only="isReadOnly"
|
||||
:data.sync="body.raw"
|
||||
:modes="modes"
|
||||
height="90%"
|
||||
ref="codeEdit"/>
|
||||
</div>
|
||||
|
||||
<div class="ms-body" v-if="body.type == 'script'">
|
||||
<mock-api-script-editor v-if="loadIsOver"
|
||||
:jsr223-processor="body.scriptObject"/>
|
||||
</div>
|
||||
|
||||
<batch-add-parameter @batchSave="batchSave" ref="batchAddParameter"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsApiKeyValue from "@/business/components/api/definition/components/ApiKeyValue";
|
||||
import {BODY_TYPE, KeyValue} from "@/business/components/api/definition/model/ApiTestModel";
|
||||
import MsCodeEdit from "@/business/components/common/components/MsCodeEdit";
|
||||
import MsJsonCodeEdit from "@/business/components/common/json-schema/JsonSchemaEditor";
|
||||
import MsDropdown from "@/business/components/common/components/MsDropdown";
|
||||
import MsApiVariable from "@/business/components/api/definition/components/ApiVariable";
|
||||
import MsApiFromUrlVariable from "@/business/components/api/definition/components/body/ApiFromUrlVariable";
|
||||
import BatchAddParameter from "@/business/components/api/definition/components/basis/BatchAddParameter";
|
||||
import Convert from "@/business/components/common/json-schema/convert/convert";
|
||||
import MockApiScriptEditor from "@/business/components/api/definition/components/mock/Components/MockApiScriptEditor";
|
||||
|
||||
export default {
|
||||
name: "MockApiResponseBody",
|
||||
components: {
|
||||
MsApiVariable,
|
||||
MsDropdown,
|
||||
MsCodeEdit,
|
||||
MsApiKeyValue,
|
||||
MsApiFromUrlVariable,
|
||||
MsJsonCodeEdit,
|
||||
BatchAddParameter,
|
||||
MockApiScriptEditor
|
||||
},
|
||||
props: {
|
||||
apiId:String,
|
||||
body: {},
|
||||
headers: Array,
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isShowEnable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loadIsOver: true,
|
||||
type: BODY_TYPE,
|
||||
modes: ['text', 'json', 'xml', 'html'],
|
||||
jsonSchema: "JSON",
|
||||
codeEditActive: true,
|
||||
hasOwnProperty: Object.prototype.hasOwnProperty,
|
||||
propIsEnumerable: Object.prototype.propertyIsEnumerable
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
'body.raw'() {
|
||||
if (this.body.format !== 'JSON-SCHEMA' && this.body.raw) {
|
||||
try {
|
||||
const MsConvert = new Convert();
|
||||
let data = MsConvert.format(JSON.parse(this.body.raw));
|
||||
if (this.body.jsonSchema) {
|
||||
this.body.jsonSchema = this.deepAssign(this.body.jsonSchema, data);
|
||||
}
|
||||
} catch (ex) {
|
||||
this.body.jsonSchema = "";
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
'body.xmlRaw'() {
|
||||
if (!this.body.xmlRaw) {
|
||||
this.body.xmlRaw = '';
|
||||
}
|
||||
},
|
||||
|
||||
'body.scriptObject'() {
|
||||
if (!this.body.scriptObject) {
|
||||
this.body.scriptObject = {};
|
||||
}
|
||||
},
|
||||
|
||||
'body.xmlHeader'() {
|
||||
if (!this.body.xmlHeader) {
|
||||
this.body.xmlHeader = 'version="1.0" encoding="UTF-8"';
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
isObj(x) {
|
||||
let type = typeof x;
|
||||
return x !== null && (type === 'object' || type === 'function');
|
||||
},
|
||||
toObject(val) {
|
||||
if (val === null || val === undefined) {
|
||||
return;
|
||||
}
|
||||
return Object(val);
|
||||
},
|
||||
|
||||
assignKey(to, from, key) {
|
||||
let val = from[key];
|
||||
if (val === undefined || val === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.hasOwnProperty.call(to, key) || !this.isObj(val)) {
|
||||
to[key] = val;
|
||||
} else {
|
||||
to[key] = this.assign(Object(to[key]), from[key]);
|
||||
}
|
||||
},
|
||||
|
||||
assign(to, from) {
|
||||
if (to === from) {
|
||||
return to;
|
||||
}
|
||||
from = Object(from);
|
||||
for (let key in from) {
|
||||
if (this.hasOwnProperty.call(from, key)) {
|
||||
this.assignKey(to, from, key);
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.getOwnPropertySymbols) {
|
||||
let symbols = Object.getOwnPropertySymbols(from);
|
||||
|
||||
for (let i = 0; i < symbols.length; i++) {
|
||||
if (this.propIsEnumerable.call(from, symbols[i])) {
|
||||
this.assignKey(to, from, symbols[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return to;
|
||||
},
|
||||
|
||||
deepAssign(target) {
|
||||
target = this.toObject(target);
|
||||
for (let s = 1; s < arguments.length; s++) {
|
||||
this.assign(target, arguments[s]);
|
||||
}
|
||||
return target;
|
||||
},
|
||||
reloadCodeEdit() {
|
||||
this.codeEditActive = false;
|
||||
this.$nextTick(() => {
|
||||
this.codeEditActive = true;
|
||||
});
|
||||
},
|
||||
formatChange() {
|
||||
const MsConvert = new Convert();
|
||||
|
||||
if (this.body.format === 'JSON-SCHEMA') {
|
||||
if (this.body.raw && !this.body.jsonSchema) {
|
||||
this.body.jsonSchema = MsConvert.format(JSON.parse(this.body.raw));
|
||||
}
|
||||
} else {
|
||||
if (this.body.jsonSchema) {
|
||||
MsConvert.schemaToJsonStr(this.body.jsonSchema, (result) => {
|
||||
this.$set(this.body, 'raw', result);
|
||||
this.reloadCodeEdit();
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
modeChange(mode) {
|
||||
switch (this.body.type) {
|
||||
case "JSON":
|
||||
// this.setContentType("application/json");
|
||||
this.refreshMsCodeEdit();
|
||||
break;
|
||||
case "XML":
|
||||
// this.setContentType("text/xml");
|
||||
this.refreshMsCodeEdit();
|
||||
break;
|
||||
case "fromApi":
|
||||
this.selectApiResponse();
|
||||
break;
|
||||
default:
|
||||
// this.removeContentType();
|
||||
this.refreshMsCodeEdit();
|
||||
break;
|
||||
}
|
||||
},
|
||||
refreshMsCodeEdit(){
|
||||
this.loadIsOver = false;
|
||||
this.$nextTick(() => {
|
||||
this.loadIsOver = true;
|
||||
});
|
||||
},
|
||||
selectApiResponse(){
|
||||
let selectUrl = "/mockConfig/getApiResponse/" + this.apiId;
|
||||
this.$get(selectUrl, response => {
|
||||
let apiResponse = response.data;
|
||||
if(apiResponse && apiResponse.returnMsg){
|
||||
this.body.apiRspRaw = apiResponse.returnMsg;
|
||||
}
|
||||
this.refreshMsCodeEdit();
|
||||
});
|
||||
},
|
||||
setContentType(value) {
|
||||
let isType = false;
|
||||
this.headers.forEach(item => {
|
||||
if (item.name === "Content-Type") {
|
||||
item.value = value;
|
||||
isType = true;
|
||||
}
|
||||
})
|
||||
if (!isType) {
|
||||
this.headers.unshift(new KeyValue({name: "Content-Type", value: value}));
|
||||
this.$emit('headersChange');
|
||||
}
|
||||
},
|
||||
removeContentType() {
|
||||
for (let index in this.headers) {
|
||||
if (this.headers[index].name === "Content-Type") {
|
||||
this.headers.splice(index, 1);
|
||||
this.$emit('headersChange');
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
batchAdd() {
|
||||
this.$refs.batchAddParameter.open();
|
||||
},
|
||||
format(array, obj) {
|
||||
if (array) {
|
||||
let isAdd = true;
|
||||
for (let i in array) {
|
||||
let item = array[i];
|
||||
if (item.name === obj.name) {
|
||||
item.value = obj.value;
|
||||
isAdd = false;
|
||||
}
|
||||
}
|
||||
if (isAdd) {
|
||||
this.body.kvs.unshift(obj);
|
||||
}
|
||||
}
|
||||
},
|
||||
batchSave(data) {
|
||||
if (data) {
|
||||
let params = data.split("\n");
|
||||
let keyValues = [];
|
||||
params.forEach(item => {
|
||||
let line = [];
|
||||
line[0] = item.substring(0,item.indexOf(":"));
|
||||
line[1] = item.substring(item.indexOf(":")+1,item.length);
|
||||
let required = false;
|
||||
keyValues.unshift(new KeyValue({
|
||||
name: line[0],
|
||||
required: required,
|
||||
value: line[1],
|
||||
description: line[2],
|
||||
type: "text",
|
||||
valid: false,
|
||||
file: false,
|
||||
encode: true,
|
||||
enable: true,
|
||||
contentType: "text/plain"
|
||||
}));
|
||||
})
|
||||
keyValues.forEach(item => {
|
||||
this.format(this.body.kvs, item);
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if (!this.body.type) {
|
||||
this.body.type = BODY_TYPE.FORM_DATA;
|
||||
}
|
||||
if (this.body.kvs) {
|
||||
this.body.kvs.forEach(param => {
|
||||
if (!param.type) {
|
||||
param.type = 'text';
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!this.body.xmlRaw) {
|
||||
this.body.xmlRaw = '';
|
||||
}
|
||||
if (!this.body.scriptObject) {
|
||||
this.body.scriptObject = {};
|
||||
}
|
||||
|
||||
if (!this.body.xmlHeader) {
|
||||
this.body.xmlHeader = 'version="1.0" encoding="UTF-8"';
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.textarea {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.ms-body {
|
||||
padding: 15px 0;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.el-dropdown {
|
||||
margin-left: 20px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.ace_editor {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.el-radio-group {
|
||||
margin: 10px 10px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.ms-el-link {
|
||||
float: right;
|
||||
margin-right: 45px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,210 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-row type="flex" :gutter="10">
|
||||
<el-col :span="codeSpan" class="script-content">
|
||||
<ms-code-edit v-if="isCodeEditAlive" :mode="codeEditModeMap[jsr223ProcessorData.scriptLanguage]"
|
||||
:read-only="isReadOnly"
|
||||
height="90%"
|
||||
:data.sync="jsr223ProcessorData.script" theme="eclipse" :modes="['java','python']"
|
||||
ref="codeEdit"/>
|
||||
</el-col>
|
||||
<div style="width: 14px;margin-right: 5px;">
|
||||
<div style="height: 12px;width: 12px; line-height:12px;">
|
||||
<i :class="showMenu ? 'el-icon-remove-outline' : 'el-icon-circle-plus-outline'"
|
||||
class="show-menu"
|
||||
@click="switchMenu"></i>
|
||||
</div>
|
||||
</div>
|
||||
<el-col :span="menuSpan" class="script-index">
|
||||
<ms-dropdown :default-command="jsr223ProcessorData.scriptLanguage" :commands="languages" style="margin-bottom: 5px;margin-left: 15px;"
|
||||
@command="languageChange"/>
|
||||
<mock-script-nav-menu ref="scriptNavMenu" :language="jsr223ProcessorData.scriptLanguage" :menus="codeTemplates"
|
||||
@handleCode="handleCodeTemplate"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import MsCodeEdit from "@/business/components/api/definition/components/MsCodeEdit";
|
||||
import MsDropdown from "@/business/components/common/components/MsDropdown";
|
||||
import CustomFunctionRelate from "@/business/components/settings/project/function/CustomFunctionRelate";
|
||||
import ApiFuncRelevance from "@/business/components/settings/project/function/ApiFuncRelevance";
|
||||
import MockScriptNavMenu from "@/business/components/api/definition/components/mock/Components/MockScriptNavMenu";
|
||||
|
||||
export default {
|
||||
name: "MockApiScriptEditor",
|
||||
components: {MsDropdown, MsCodeEdit, CustomFunctionRelate, ApiFuncRelevance, MockScriptNavMenu},
|
||||
data() {
|
||||
return {
|
||||
jsr223ProcessorData: {},
|
||||
codeTemplates: [
|
||||
{
|
||||
title: "API"+this.$t('api_test.definition.document.request_info'),
|
||||
children: [
|
||||
{
|
||||
title: this.$t('api_test.request.address'),
|
||||
value: '\nreturnMsg.add(@address)\n',
|
||||
},
|
||||
{
|
||||
title: "Header "+this.$t('api_test.definition.document.request_param'),
|
||||
value: '\nreturnMsg.add(@header(${param}))\n',
|
||||
},
|
||||
{
|
||||
title: this.$t('api_test.request.body')+this.$t('api_test.variable'),
|
||||
value: '\nreturnMsg.add(@body(${param}))\n',
|
||||
},
|
||||
{
|
||||
title: this.$t('api_test.request.body')+this.$t('api_test.variable')+" (Raw)",
|
||||
value: '\nreturnMsg.add(@bodyRaw)\n',
|
||||
},
|
||||
{
|
||||
title: "Query "+this.$t('api_test.definition.document.request_param'),
|
||||
value: '\nreturnMsg.add(@query(${param}))\n',
|
||||
},
|
||||
{
|
||||
title: "Rest "+this.$t('api_test.definition.document.request_param'),
|
||||
value: '\nreturnMsg.add(@rest(${param}))\n',
|
||||
},
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
title: this.$t('project.code_segment.code_segment'),
|
||||
children: [
|
||||
{
|
||||
title: this.$t('project.code_segment.insert_segment'),
|
||||
command: "custom_function",
|
||||
}
|
||||
]
|
||||
},
|
||||
],
|
||||
isCodeEditAlive: true,
|
||||
languages: [
|
||||
'beanshell',"groovy"
|
||||
// , "python", "nashornScript", "rhinoScript"
|
||||
],
|
||||
codeEditModeMap: {
|
||||
beanshell: 'java',
|
||||
python: 'python',
|
||||
groovy: 'java',
|
||||
nashornScript: 'javascript',
|
||||
rhinoScript: 'javascript',
|
||||
},
|
||||
codeSpan: 20,
|
||||
menuSpan: 4,
|
||||
showMenu: true,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.jsr223ProcessorData = this.jsr223Processor;
|
||||
},
|
||||
props: {
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default:
|
||||
false
|
||||
},
|
||||
jsr223Processor: {
|
||||
type: Object,
|
||||
},
|
||||
node: {},
|
||||
},
|
||||
watch: {
|
||||
jsr223Processor() {
|
||||
this.reload();
|
||||
}
|
||||
}
|
||||
,
|
||||
methods: {
|
||||
addTemplate(template) {
|
||||
if (!this.jsr223ProcessorData.script) {
|
||||
this.jsr223ProcessorData.script = "";
|
||||
}
|
||||
this.jsr223ProcessorData.script += template.value;
|
||||
if (this.jsr223ProcessorData.scriptLanguage === 'beanshell') {
|
||||
this.jsr223ProcessorData.script += ';';
|
||||
}
|
||||
this.reload();
|
||||
},
|
||||
reload() {
|
||||
this.isCodeEditAlive = false;
|
||||
this.$nextTick(() => (this.isCodeEditAlive = true));
|
||||
},
|
||||
languageChange(language) {
|
||||
this.jsr223ProcessorData.scriptLanguage = language;
|
||||
this.$emit("languageChange");
|
||||
},
|
||||
addCustomFuncScript(script) {
|
||||
this.jsr223ProcessorData.script = this.jsr223ProcessorData.script ?
|
||||
this.jsr223ProcessorData.script + '\n\n' + script : script;
|
||||
this.reload();
|
||||
},
|
||||
switchMenu() {
|
||||
this.showMenu = !this.showMenu;
|
||||
if (this.showMenu) {
|
||||
this.codeSpan = 20;
|
||||
this.menuSpan = 4;
|
||||
} else {
|
||||
this.codeSpan = 24;
|
||||
this.menuSpan = 0;
|
||||
}
|
||||
},
|
||||
handleCodeTemplate(code) {
|
||||
if (!this.jsr223ProcessorData.script) {
|
||||
this.jsr223ProcessorData.script = code;
|
||||
} else {
|
||||
this.jsr223ProcessorData.script = this.jsr223ProcessorData.script + '\n' + code;
|
||||
}
|
||||
this.reload();
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ace_editor {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.script-content {
|
||||
/*height: calc(100vh - 570px);*/
|
||||
height: 185px;
|
||||
min-height: 170px;
|
||||
}
|
||||
|
||||
.script-index {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.template-title {
|
||||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.document-url {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.instructions-icon {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.ms-dropdown {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.show-menu {
|
||||
text-align:center;
|
||||
font-weight: bold;
|
||||
color:#935aa1;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.show-menu:hover {
|
||||
color:#935aa1;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,228 @@
|
|||
<template>
|
||||
<div style="line-height: 20px;">
|
||||
<div v-for="(menu, index) in menus" :key="index">
|
||||
<span class="link-type">
|
||||
<i class="icon el-icon-arrow-right" style="font-weight: bold; margin-right: 2px;"
|
||||
@click="active(menu)" :class="{'is-active': menu.open}"></i>
|
||||
<span @click="active(menu)" class="nav-menu-title nav-font">{{menu.title}}</span>
|
||||
</span>
|
||||
|
||||
<el-collapse-transition>
|
||||
<div v-if="menu.open">
|
||||
<div v-for="(child, key) in menu.children" :key="key" class="func-div">
|
||||
<el-link :disabled="child.disabled" @click="handleClick(child)" class="func-link nav-font">{{child.title}}</el-link>
|
||||
</div>
|
||||
</div>
|
||||
</el-collapse-transition>
|
||||
</div>
|
||||
<custom-function-relate ref="customFunctionRelate" @addCustomFuncScript="handleCodeTemplate"/>
|
||||
<!--接口列表-->
|
||||
<api-func-relevance @save="apiSave" @close="apiClose" ref="apiFuncRelevance"/>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ApiFuncRelevance from "@/business/components/settings/project/function/ApiFuncRelevance";
|
||||
import CustomFunctionRelate from "@/business/components/settings/project/function/CustomFunctionRelate";
|
||||
import {getCodeTemplate} from "@/business/components/settings/project/function/custom-function";
|
||||
import {SCRIPT_MENU} from "@/business/components/settings/project/function/script-menu";
|
||||
|
||||
export default {
|
||||
name: "MockScriptNavMenu",
|
||||
components: {
|
||||
ApiFuncRelevance,
|
||||
CustomFunctionRelate
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
value: true
|
||||
}
|
||||
},
|
||||
props: {
|
||||
language: {
|
||||
type: String,
|
||||
default() {
|
||||
return "beanshell"
|
||||
}
|
||||
},
|
||||
menus: {
|
||||
type: Array,
|
||||
default() {
|
||||
return SCRIPT_MENU
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
apiSave(data, env) {
|
||||
// data:选中的多个接口定义或多个接口用例; env: 关联页面选中的环境
|
||||
let condition = env.config.httpConfig.conditions || [];
|
||||
let protocol = "";
|
||||
let host = "";
|
||||
let domain = "";
|
||||
let port = "";
|
||||
if (condition && condition.length > 0) {
|
||||
// 如果有多个环境,取第一个
|
||||
protocol = condition[0].protocol ? condition[0].protocol : "http";
|
||||
host = condition[0].socket;
|
||||
domain = condition[0].domain;
|
||||
port = condition[0].port;
|
||||
}
|
||||
// todo
|
||||
if (data.length > 5) {
|
||||
this.$warning("最多可以选择5个接口!");
|
||||
return;
|
||||
}
|
||||
let code = "";
|
||||
if (data.length > 0) {
|
||||
for (let dt of data) {
|
||||
// 过滤非HTTP接口API
|
||||
if (dt.protocol !== "HTTP") {
|
||||
if (!dt.request) {
|
||||
continue;
|
||||
} else {
|
||||
// 是否是HTTP接口CASE
|
||||
if (dt.request) {
|
||||
let req = JSON.parse(dt.request);
|
||||
if (req.protocol !== "HTTP") {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let param = this._parseRequestObj(dt);
|
||||
param['host'] = host;
|
||||
param['domain'] = domain;
|
||||
param['port'] = port;
|
||||
param['protocol'] = protocol;
|
||||
code += '\n' + getCodeTemplate(this.language, param);
|
||||
}
|
||||
}
|
||||
this.handleCodeTemplate(code);
|
||||
this.$refs.apiFuncRelevance.close();
|
||||
},
|
||||
handleCodeTemplate(code) {
|
||||
this.$emit("handleCode", code);
|
||||
},
|
||||
_parseRequestObj(data) {
|
||||
let requestHeaders = new Map();
|
||||
let requestArguments = new Map();
|
||||
let requestMethod = "";
|
||||
let requestBody = "";
|
||||
let requestPath = "";
|
||||
let request = JSON.parse(data.request);
|
||||
// 拼接发送请求需要的参数
|
||||
requestPath = request.path;
|
||||
requestMethod = request.method;
|
||||
let headers = request.headers;
|
||||
if (headers && headers.length > 0) {
|
||||
headers.forEach(header => {
|
||||
if (header.name) {
|
||||
requestHeaders.set(header.name, header.value);
|
||||
}
|
||||
})
|
||||
}
|
||||
let args = request.arguments;
|
||||
if (args && args.length) {
|
||||
args.forEach(arg => {
|
||||
if (arg.name) {
|
||||
requestArguments.set(arg.name, arg.value);
|
||||
}
|
||||
})
|
||||
}
|
||||
let body = request.body;
|
||||
if (body.json) {
|
||||
requestBody = body.raw;
|
||||
}
|
||||
return {requestPath, requestHeaders, requestMethod, requestBody, requestArguments}
|
||||
},
|
||||
apiClose() {
|
||||
|
||||
},
|
||||
handleClick(obj) {
|
||||
let code = "";
|
||||
if (obj.command) {
|
||||
code = this._handleCommand(obj.command);
|
||||
if (!code) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// todo 优化
|
||||
if (this.language !== 'beanshell' && this.language !== 'groovy') {
|
||||
if (obj.title === this.$t('api_test.request.processor.code_add_report_length') ||
|
||||
obj.title === this.$t('api_test.request.processor.code_hide_report_length')) {
|
||||
this.$warning("无对应的 "+ this.language +" 代码模版!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
code = obj.value;
|
||||
}
|
||||
this.handleCodeTemplate(code);
|
||||
},
|
||||
_handleCommand(command) {
|
||||
switch (command) {
|
||||
case 'custom_function':
|
||||
this.$refs.customFunctionRelate.open(this.language);
|
||||
return "";
|
||||
case 'api_definition':
|
||||
this.$refs.apiFuncRelevance.open();
|
||||
return "";
|
||||
case 'new_api_request': {
|
||||
// requestObj为空则生产默认模版
|
||||
let headers = new Map();
|
||||
headers.set('Content-type', 'application/json');
|
||||
return getCodeTemplate(this.language, {requestHeaders: headers});
|
||||
}
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
},
|
||||
active(menu) {
|
||||
if (!menu.open) {
|
||||
this.$set(menu, "open", true);
|
||||
} else {
|
||||
this.$set(menu, "open", !menu.open);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.template-title {
|
||||
margin-bottom: 4px;
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.func-link {
|
||||
margin-left: 18px;
|
||||
}
|
||||
|
||||
.func-div >>> .func-link {
|
||||
color: #935aa1;
|
||||
}
|
||||
|
||||
.func-div >>> .func-link:hover {
|
||||
color: #935aa1;
|
||||
}
|
||||
|
||||
.link-type {
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.icon.is-active {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.nav-menu-title:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.nav-font {
|
||||
font-size: 13px;
|
||||
}
|
||||
</style>
|
|
@ -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;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
<template>
|
||||
<el-header style="width: 100% ;padding: 0px">
|
||||
<el-card>
|
||||
<el-row>
|
||||
<el-col :span="1">
|
||||
{{$t('commons.name')}}
|
||||
</el-col>
|
||||
<el-col :span="11">
|
||||
<el-input class="ms-http-input" style="width: 80%" size="small" v-model="mockExpectConfig.name"/>
|
||||
</el-col>
|
||||
<el-col :span="1">
|
||||
{{$t('commons.tag')}}
|
||||
</el-col>
|
||||
<el-col :span="11">
|
||||
<ms-input-tag :currentScenario="mockExpectConfig" style="width: 80%;height: 100%;white-space: nowrap;overflow: hidden" v-if="showHeadTable" ref="tag"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-header>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import MsInputTag from "@/business/components/api/automation/scenario/MsInputTag";
|
||||
|
||||
export default {
|
||||
name: "MockConfigHeader",
|
||||
components: {MsInputTag},
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
props: {
|
||||
mockExpectConfig: Object,
|
||||
showHeadTable:Boolean,
|
||||
},
|
||||
created() {
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.el-card-btn {
|
||||
float: right;
|
||||
top: 20px;
|
||||
right: 0px;
|
||||
padding: 0;
|
||||
background: 0 0;
|
||||
border: none;
|
||||
outline: 0;
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.variable-combine {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.el-col {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.ms-api-header-select {
|
||||
margin-left: 20px;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.el-col {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.api-el-tag {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.select-all {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.ms-col-name {
|
||||
display: inline-block;
|
||||
margin: 0 5px;
|
||||
overflow-x: hidden;
|
||||
padding-bottom: 0;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: middle;
|
||||
white-space: nowrap;
|
||||
width: 100px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,343 @@
|
|||
<template>
|
||||
<ms-drawer :size="60" @close="close" :visible="showDrawer" direction="bottom">
|
||||
<template v-slot:header>
|
||||
<mock-config-header
|
||||
:mock-expect-config="mockExpectConfig"
|
||||
:show-head-table="showHeadTable"
|
||||
/>
|
||||
</template>
|
||||
<el-container>
|
||||
<el-main>
|
||||
<!-- 期望详情 -->
|
||||
<p class="tip">{{ $t('api_test.mock.request_condition') }}</p>
|
||||
<el-form :model="mockExpectConfig" :rules="rule" ref="mockExpectForm" label-width="80px" label-position="right">
|
||||
|
||||
<div class="card">
|
||||
<div class="base-info">
|
||||
<el-row>
|
||||
<mock-request-param
|
||||
:isShowEnable="true"
|
||||
:referenced="true"
|
||||
:is-read-only="false"
|
||||
:request="mockExpectConfig.request.params"/>
|
||||
</el-row>
|
||||
|
||||
<el-row style="margin-top: 10px;">
|
||||
<p class="tip">{{ $t('api_test.mock.rsp_param') }}</p>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<mock-response-param :api-id="apiId"
|
||||
:response="mockExpectConfig.response.responseResult"/>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<div style="float: right;margin-right: 20px">
|
||||
<el-button type="primary" size="small" @click="saveMockExpectConfig" title="ctrl + s">{{
|
||||
$t('commons.save')
|
||||
}}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</el-form>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</ms-drawer>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
import MsDrawer from "@/business/components/common/components/MsDrawer";
|
||||
import {REQUEST_HEADERS} from "@/common/js/constants";
|
||||
import MockRowVariables from "@/business/components/api/definition/components/mock/MockRowVariables";
|
||||
import MsCodeEdit from "@/business/components/common/components/MsCodeEdit";
|
||||
import MockConfigHeader from "@/business/components/api/definition/components/mock/MockConfigHeader";
|
||||
import MockRequestParam from "@/business/components/api/definition/components/mock/MockRequestParam";
|
||||
import MockResponseParam from "@/business/components/api/definition/components/mock/MockResponseParam";
|
||||
import {getUUID} from "@/common/js/utils";
|
||||
|
||||
export default {
|
||||
name: 'MockEditDrawer',
|
||||
components: {
|
||||
MsDrawer,MockConfigHeader,MockRowVariables,MsCodeEdit,MockRequestParam,MockResponseParam
|
||||
},
|
||||
props: {
|
||||
apiParams: Array,
|
||||
apiId:String,
|
||||
mockConfigId:String,
|
||||
// mockConfigData: Object,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showDrawer: false,
|
||||
mockExpectConfig:{},
|
||||
showHeadTable: true,
|
||||
headerSuggestions: REQUEST_HEADERS,
|
||||
baseMockExpectConfig: {
|
||||
id: "",
|
||||
name: "",
|
||||
mockConfigId: "",
|
||||
request: {
|
||||
jsonParam: false,
|
||||
variables: [],
|
||||
jsonData: "{}",
|
||||
params:{
|
||||
headers:[],
|
||||
arguments:[],
|
||||
rest:[],
|
||||
body:{
|
||||
type: 'JSON',
|
||||
binary:[]
|
||||
}
|
||||
}
|
||||
},
|
||||
response: {
|
||||
httpCode: "",
|
||||
delayed: "",
|
||||
httpHeads: [],
|
||||
body: "",
|
||||
responseResult:{
|
||||
headers:[],
|
||||
arguments:[],
|
||||
rest:[],
|
||||
body:{
|
||||
type: 'JSON',
|
||||
binary:[]
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
rule: {
|
||||
name: [
|
||||
{required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'},
|
||||
{max: 100, message: this.$t('test_track.length_less_than') + '100', trigger: 'blur'}
|
||||
],
|
||||
response: {
|
||||
httpCode: [{required: true, message: this.$t('api_test.mock.rule.input_code'), trigger: 'blur'},],
|
||||
delayed: [{required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'},],
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
created() {
|
||||
this.mockExpectConfig = JSON.parse(JSON.stringify(this.baseMockExpectConfig));
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
methods: {
|
||||
uuid: function () {
|
||||
return (((1 + Math.random()) * 0x100000) | 0).toString(16).substring(1);
|
||||
},
|
||||
open(param){
|
||||
this.mockExpectConfig = JSON.parse(JSON.stringify(this.baseMockExpectConfig));
|
||||
if(param){
|
||||
this.mockExpectConfig = param;
|
||||
if(!this.mockExpectConfig.request.params){
|
||||
|
||||
let requestParamsObj = {
|
||||
rest:[],
|
||||
headers: [],
|
||||
arguments: [],
|
||||
body: {
|
||||
type: "JSON",
|
||||
raw: "",
|
||||
kvs: [],
|
||||
},
|
||||
};
|
||||
this.$set(this.mockExpectConfig.request,"params",requestParamsObj);
|
||||
|
||||
if(this.mockExpectConfig.request.jsonParam && this.mockExpectConfig.request.jsonData){
|
||||
this.mockExpectConfig.request.params.body.type = "JSON";
|
||||
this.mockExpectConfig.request.params.body.raw = this.mockExpectConfig.jsonData;
|
||||
}else if(this.mockExpectConfig.request.variables){
|
||||
this.mockExpectConfig.request.params.body.type = "Form Data";
|
||||
let headerItem = {};
|
||||
headerItem.enable = true;
|
||||
this.mockExpectConfig.request.params.headers.push(headerItem);
|
||||
this.mockExpectConfig.request.variables.forEach(item => {
|
||||
this.mockExpectConfig.request.params.arguments.push({
|
||||
description : "",
|
||||
type : "text",
|
||||
name : item.name,
|
||||
value : item.value,
|
||||
required : true,
|
||||
contentType : "text/plain",
|
||||
uuid : this.uuid(),
|
||||
});
|
||||
this.mockExpectConfig.request.params.body.kvs.push({
|
||||
description : "",
|
||||
type : "text",
|
||||
name : item.name,
|
||||
value : item.value,
|
||||
required : true,
|
||||
contentType : "text/plain",
|
||||
uuid : this.uuid(),
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
if (!this.mockExpectConfig.response.responseResult) {
|
||||
let responseResultObj = {
|
||||
headers:[],
|
||||
arguments:[],
|
||||
rest:[],
|
||||
httpCode: this.mockExpectConfig.response.httpCode,
|
||||
delayed: this.mockExpectConfig.response.delayed,
|
||||
body:{
|
||||
type: "Raw",
|
||||
raw: this.mockExpectConfig.response.body,
|
||||
binary:[]
|
||||
}
|
||||
};
|
||||
this.$set(this.mockExpectConfig.response,"responseResult",responseResultObj);
|
||||
if(this.mockExpectConfig.response.httpHeads){
|
||||
this.mockExpectConfig.response.httpHeads.forEach(item => {
|
||||
this.mockExpectConfig.response.responseResult.headers.push({
|
||||
enable:true,
|
||||
name: item.name,
|
||||
value: item.value,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
this.showDrawer = true;
|
||||
},
|
||||
close(){
|
||||
this.showDrawer = false;
|
||||
},
|
||||
saveMockExpectConfig() {
|
||||
let mockConfigId = this.mockConfigId;
|
||||
this.mockExpectConfig.mockConfigId = mockConfigId;
|
||||
let formCheckResult = this.checkMockExpectForm("mockExpectForm", true);
|
||||
},
|
||||
cleanMockExpectConfig() {
|
||||
this.showHeadTable = false;
|
||||
this.mockExpectConfig = JSON.parse(JSON.stringify(this.baseMockExpectConfig));
|
||||
this.$nextTick(function () {
|
||||
this.showHeadTable = true;
|
||||
});
|
||||
},
|
||||
updateMockExpectConfig() {
|
||||
this.checkMockExpectForm("mockExpectForm");
|
||||
},
|
||||
uploadMockExpectConfig(clearForm) {
|
||||
let url = "/mockConfig/updateMockExpectConfig";
|
||||
let param = this.mockExpectConfig;
|
||||
if(!param.request.params.id){
|
||||
param.request.params.id = getUUID();
|
||||
}
|
||||
let obj = {
|
||||
request: param.request.params,
|
||||
response: param.response.responseResult
|
||||
};
|
||||
let bodyFiles = this.getBodyUploadFiles(obj);
|
||||
|
||||
this.$fileUpload(url, null, bodyFiles, param, response => {
|
||||
let returnData = response.data;
|
||||
this.mockExpectConfig.id = returnData.id;
|
||||
this.$emit('refreshMockInfo',param.mockConfigId);
|
||||
if (clearForm) {
|
||||
this.cleanMockExpectConfig();
|
||||
}
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: this.$t('commons.save_success'),
|
||||
});
|
||||
this.close();
|
||||
});
|
||||
},
|
||||
getBodyUploadFiles(data) {
|
||||
let bodyUploadFiles = [];
|
||||
data.bodyUploadIds = [];
|
||||
let request = data.request;
|
||||
let response = data.response;
|
||||
if (request.body) {
|
||||
if (request.body.kvs) {
|
||||
request.body.kvs.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
let fileId = getUUID().substring(0, 8);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
data.bodyUploadIds.push(fileId);
|
||||
bodyUploadFiles.push(item.file);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if (request.body.binary) {
|
||||
request.body.binary.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
let fileId = getUUID().substring(0, 8);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
data.bodyUploadIds.push(fileId);
|
||||
bodyUploadFiles.push(item.file);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (response.body) {
|
||||
if (response.body.kvs) {
|
||||
response.body.kvs.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
let fileId = getUUID().substring(0, 8);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
data.bodyUploadIds.push(fileId);
|
||||
bodyUploadFiles.push(item.file);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if (response.body.binary) {
|
||||
response.body.binary.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
let fileId = getUUID().substring(0, 8);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
data.bodyUploadIds.push(fileId);
|
||||
bodyUploadFiles.push(item.file);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return bodyUploadFiles;
|
||||
},
|
||||
checkMockExpectForm(formName, clearForm) {
|
||||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
this.uploadMockExpectConfig(clearForm);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.ms-drawer >>> .ms-drawer-body {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,390 @@
|
|||
<template xmlns:v-slot="http://www.w3.org/1999/XSL/Transform">
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="spanCount">
|
||||
<!-- HTTP 请求参数 -->
|
||||
<div style="border:1px #DCDFE6 solid; height: 100%;border-radius: 4px ;width: 100%" v-loading="isReloadData">
|
||||
<el-tabs v-model="activeName" class="request-tabs">
|
||||
<!-- 请求头-->
|
||||
<el-tab-pane :label="$t('api_test.request.headers')" name="headers">
|
||||
<el-tooltip class="item-tabs" effect="dark" :content="$t('api_test.request.headers')" placement="top-start" slot="label">
|
||||
<span>{{ $t('api_test.request.headers') }}
|
||||
<div class="el-step__icon is-text ms-api-col ms-header" v-if="request.headers.length>1">
|
||||
<div class="el-step__icon-inner">{{ request.headers.length - 1 }}</div>
|
||||
</div>
|
||||
</span>
|
||||
</el-tooltip>
|
||||
<el-row>
|
||||
<el-link class="ms-el-link" @click="batchAdd" style="color: #783887"> {{ $t("commons.batch_add") }}</el-link>
|
||||
</el-row>
|
||||
<ms-api-key-value :show-desc="true" :is-read-only="isReadOnly" :isShowEnable="isShowEnable" :suggestions="headerSuggestions" :items="request.headers" :need-mock="true"/>
|
||||
</el-tab-pane>
|
||||
|
||||
<!--query 参数-->
|
||||
<el-tab-pane :label="$t('api_test.definition.request.query_param')" name="parameters">
|
||||
<el-tooltip class="item-tabs" effect="dark" :content="$t('api_test.definition.request.query_info')" placement="top-start" slot="label">
|
||||
<span>{{ $t('api_test.definition.request.query_param') }}
|
||||
<div class="el-step__icon is-text ms-api-col ms-header" v-if="request.arguments.length>1">
|
||||
<div class="el-step__icon-inner">{{ request.arguments.length - 1 }}</div>
|
||||
</div></span>
|
||||
</el-tooltip>
|
||||
<el-row>
|
||||
<el-link class="ms-el-link" @click="batchAdd" style="color: #783887"> {{ $t("commons.batch_add") }}</el-link>
|
||||
</el-row>
|
||||
<ms-api-variable :with-mor-setting="true" :is-read-only="isReadOnly" :isShowEnable="isShowEnable" :parameters="request.arguments"/>
|
||||
</el-tab-pane>
|
||||
|
||||
<!--REST 参数-->
|
||||
<el-tab-pane :label="$t('api_test.definition.request.rest_param')" name="rest">
|
||||
<el-tooltip class="item-tabs" effect="dark" :content="$t('api_test.definition.request.rest_info')" placement="top-start" slot="label">
|
||||
<span>
|
||||
{{ $t('api_test.definition.request.rest_param') }}
|
||||
<div class="el-step__icon is-text ms-api-col ms-header" v-if="request.rest.length>1">
|
||||
<div class="el-step__icon-inner">{{ request.rest.length - 1 }}</div>
|
||||
</div>
|
||||
</span>
|
||||
</el-tooltip>
|
||||
<el-row>
|
||||
<el-link class="ms-el-link" @click="batchAdd" style="color: #783887"> {{ $t("commons.batch_add") }}</el-link>
|
||||
</el-row>
|
||||
<ms-api-variable :with-mor-setting="true" :is-read-only="isReadOnly" :isShowEnable="isShowEnable" :parameters="request.rest"/>
|
||||
</el-tab-pane>
|
||||
|
||||
<!--请求体-->
|
||||
<el-tab-pane v-if="isBodyShow" :label="$t('api_test.request.body')" name="body" style="overflow: auto">
|
||||
<mock-api-body @headersChange="reloadBody" :is-read-only="isReadOnly" :isShowEnable="isShowEnable" :headers="request.headers" :body="request.body"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="create" v-if="hasPermission('PROJECT_API_DEFINITION:READ+CREATE_API') && hasLicense() && definitionTest">
|
||||
<template v-slot:label>
|
||||
<el-button size="mini" type="primary" @click.stop @click="generate">{{ $t('commons.generate_test_data') }}</el-button>
|
||||
</template>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<batch-add-parameter @batchSave="batchSave" ref="batchAddParameter"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsApiKeyValue from "@/business/components/api/definition/components/ApiKeyValue";
|
||||
import MsApiAuthConfig from "@/business/components/api/definition/components/auth/ApiAuthConfig";
|
||||
import ApiRequestMethodSelect from "@/business/components/api/definition/components/collapse/ApiRequestMethodSelect";
|
||||
import {REQUEST_HEADERS} from "@/common/js/constants";
|
||||
import MsApiVariable from "@/business/components/api/definition/components/ApiVariable";
|
||||
import MsApiAssertions from "@/business/components/api/definition/components/assertion/ApiAssertions";
|
||||
import MsApiExtract from "@/business/components/api/definition/components/extract/ApiExtract";
|
||||
import {Body, KeyValue} from "@/business/components/api/definition/model/ApiTestModel";
|
||||
import {hasLicense, getUUID} from "@/common/js/utils";
|
||||
import BatchAddParameter from "@/business/components/api/definition/components/basis/BatchAddParameter";
|
||||
import MsApiAdvancedConfig from "@/business/components/api/definition/components/request/http/ApiAdvancedConfig";
|
||||
import MsJsr233Processor from "@/business/components/api/automation/scenario/component/Jsr233Processor";
|
||||
import ApiDefinitionStepButton from "@/business/components/api/definition/components/request/components/ApiDefinitionStepButton";
|
||||
import {hasPermission} from '@/common/js/utils';
|
||||
import Convert from "@/business/components/common/json-schema/convert/convert";
|
||||
import MockApiBody from "@/business/components/api/definition/components/mock/Components/MockApiBody";
|
||||
|
||||
export default {
|
||||
name: "MockRequestParam",
|
||||
components: {
|
||||
ApiDefinitionStepButton,
|
||||
MsJsr233Processor,
|
||||
MsApiAdvancedConfig,
|
||||
BatchAddParameter,
|
||||
MsApiVariable,
|
||||
ApiRequestMethodSelect,
|
||||
MsApiExtract,
|
||||
MsApiAuthConfig,
|
||||
MockApiBody,
|
||||
MsApiKeyValue,
|
||||
MsApiAssertions
|
||||
},
|
||||
props: {
|
||||
method: String,
|
||||
request: {},
|
||||
response: {},
|
||||
definitionTest: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
showScript: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
referenced: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isShowEnable: Boolean,
|
||||
jsonPathList: Array,
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: String,
|
||||
},
|
||||
data() {
|
||||
let validateURL = (rule, value, callback) => {
|
||||
try {
|
||||
new URL(this.addProtocol(this.request.url));
|
||||
} catch (e) {
|
||||
callback(this.$t('api_test.request.url_invalid'));
|
||||
}
|
||||
};
|
||||
return {
|
||||
activeName: this.request.method === "POST" ? "body" : "parameters",
|
||||
rules: {
|
||||
name: [
|
||||
{max: 300, message: this.$t('commons.input_limit', [1, 300]), trigger: 'blur'}
|
||||
],
|
||||
url: [
|
||||
{max: 500, required: true, message: this.$t('commons.input_limit', [1, 500]), trigger: 'blur'},
|
||||
{validator: validateURL, trigger: 'blur'}
|
||||
],
|
||||
path: [
|
||||
{max: 500, message: this.$t('commons.input_limit', [0, 500]), trigger: 'blur'},
|
||||
]
|
||||
},
|
||||
spanCount: 21,
|
||||
headerSuggestions: REQUEST_HEADERS,
|
||||
isReloadData: false,
|
||||
isBodyShow: true,
|
||||
dialogVisible: false,
|
||||
hasOwnProperty: Object.prototype.hasOwnProperty,
|
||||
propIsEnumerable: Object.prototype.propertyIsEnumerable
|
||||
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (!this.referenced && this.showScript) {
|
||||
this.spanCount = 21;
|
||||
} else {
|
||||
this.spanCount = 24;
|
||||
}
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
hasPermission,
|
||||
hasLicense,
|
||||
generate() {
|
||||
if (this.request.body && (this.request.body.jsonSchema || this.request.body.raw)) {
|
||||
if (!this.request.body.jsonSchema) {
|
||||
const MsConvert = new Convert();
|
||||
this.request.body.jsonSchema = MsConvert.format(JSON.parse(this.request.body.raw));
|
||||
}
|
||||
this.$post('/api/test/data/generator', this.request.body.jsonSchema, response => {
|
||||
if (response.data) {
|
||||
if (this.request.body.format !== 'JSON-SCHEMA') {
|
||||
this.request.body.raw = response.data;
|
||||
} else {
|
||||
const MsConvert = new Convert();
|
||||
let data = MsConvert.format(JSON.parse(response.data));
|
||||
this.request.body.jsonSchema = this.deepAssign(this.request.body.jsonSchema, data);
|
||||
}
|
||||
this.reloadBody();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
remove(row) {
|
||||
let index = this.request.hashTree.indexOf(row);
|
||||
this.request.hashTree.splice(index, 1);
|
||||
this.reload();
|
||||
},
|
||||
copyRow(row) {
|
||||
let obj = JSON.parse(JSON.stringify(row));
|
||||
obj.id = getUUID();
|
||||
this.request.hashTree.push(obj);
|
||||
this.reload();
|
||||
},
|
||||
reload() {
|
||||
this.isReloadData = true
|
||||
this.$nextTick(() => {
|
||||
this.isReloadData = false
|
||||
})
|
||||
},
|
||||
init() {
|
||||
if (Object.prototype.toString.call(this.request).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object') {
|
||||
this.request = JSON.parse(this.request);
|
||||
}
|
||||
if (!this.request.body) {
|
||||
this.request.body = new Body();
|
||||
}
|
||||
if (!this.request.headers) {
|
||||
this.request.headers = [];
|
||||
}
|
||||
if (!this.request.body.kvs) {
|
||||
this.request.body.kvs = [];
|
||||
}
|
||||
if (!this.request.rest) {
|
||||
this.request.rest = [];
|
||||
}
|
||||
if (!this.request.arguments) {
|
||||
this.request.arguments = [];
|
||||
}
|
||||
},
|
||||
reloadBody() {
|
||||
// 解决修改请求头后 body 显示错位
|
||||
this.isBodyShow = false;
|
||||
this.$nextTick(() => {
|
||||
this.isBodyShow = true;
|
||||
});
|
||||
},
|
||||
batchAdd() {
|
||||
this.$refs.batchAddParameter.open();
|
||||
},
|
||||
format(array, obj) {
|
||||
if (array) {
|
||||
let isAdd = true;
|
||||
for (let i in array) {
|
||||
let item = array[i];
|
||||
if (item.name === obj.name) {
|
||||
item.value = obj.value;
|
||||
isAdd = false;
|
||||
}
|
||||
}
|
||||
if (isAdd) {
|
||||
switch (this.activeName) {
|
||||
case "parameters":
|
||||
this.request.arguments.unshift(obj);
|
||||
break;
|
||||
case "rest":
|
||||
this.request.rest.unshift(obj);
|
||||
break;
|
||||
case "headers":
|
||||
this.request.headers.unshift(obj);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
batchSave(data) {
|
||||
if (data) {
|
||||
let params = data.split("\n");
|
||||
let keyValues = [];
|
||||
params.forEach(item => {
|
||||
let line = item.split(/:|:/);
|
||||
let required = false;
|
||||
keyValues.unshift(new KeyValue({
|
||||
name: line[0],
|
||||
required: required,
|
||||
value: line[1],
|
||||
description: line[2],
|
||||
type: "text",
|
||||
valid: false,
|
||||
file: false,
|
||||
encode: true,
|
||||
enable: true,
|
||||
contentType: "text/plain"
|
||||
}));
|
||||
})
|
||||
|
||||
keyValues.forEach(item => {
|
||||
switch (this.activeName) {
|
||||
case "parameters":
|
||||
this.format(this.request.arguments, item);
|
||||
break;
|
||||
case "rest":
|
||||
this.format(this.request.rest, item);
|
||||
break;
|
||||
case "headers":
|
||||
this.format(this.request.headers, item);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
isObj(x) {
|
||||
let type = typeof x;
|
||||
return x !== null && (type === 'object' || type === 'function');
|
||||
},
|
||||
|
||||
toObject(val) {
|
||||
if (val === null || val === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
return Object(val);
|
||||
},
|
||||
|
||||
assignKey(to, from, key) {
|
||||
let val = from[key];
|
||||
|
||||
if (val === undefined || val === null) {
|
||||
return;
|
||||
}
|
||||
if (!this.hasOwnProperty.call(to, key) || !this.isObj(val)) {
|
||||
to[key] = val;
|
||||
} else {
|
||||
to[key] = this.assign(Object(to[key]), from[key]);
|
||||
}
|
||||
},
|
||||
|
||||
assign(to, from) {
|
||||
if (to === from) {
|
||||
return to;
|
||||
}
|
||||
from = Object(from);
|
||||
for (let key in from) {
|
||||
if (this.hasOwnProperty.call(from, key)) {
|
||||
this.assignKey(to, from, key);
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.getOwnPropertySymbols) {
|
||||
let symbols = Object.getOwnPropertySymbols(from);
|
||||
|
||||
for (let i = 0; i < symbols.length; i++) {
|
||||
if (this.propIsEnumerable.call(from, symbols[i])) {
|
||||
this.assignKey(to, from, symbols[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return to;
|
||||
},
|
||||
|
||||
deepAssign(target) {
|
||||
target = this.toObject(target);
|
||||
for (let s = 1; s < arguments.length; s++) {
|
||||
this.assign(target, arguments[s]);
|
||||
}
|
||||
return target;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ms-query {
|
||||
background: #783887;
|
||||
color: white;
|
||||
height: 18px;
|
||||
border-radius: 42%;
|
||||
}
|
||||
|
||||
.ms-header {
|
||||
background: #783887;
|
||||
color: white;
|
||||
height: 18px;
|
||||
border-radius: 42%;
|
||||
}
|
||||
|
||||
.request-tabs {
|
||||
margin: 20px;
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.ms-el-link {
|
||||
float: right;
|
||||
margin-right: 45px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,216 @@
|
|||
<template xmlns:v-slot="http://www.w3.org/1999/XSL/Transform">
|
||||
<div class="text-container" style="border:1px #DCDFE6 solid; height: 100%;border-radius: 4px ;width: 100%">
|
||||
<el-form :model="response" ref="response" label-width="100px">
|
||||
|
||||
<el-collapse-transition>
|
||||
<el-tabs v-model="activeName" v-show="isActive" style="margin: 20px">
|
||||
<el-tab-pane :label="$t('api_test.definition.request.response_header')" name="headers" class="pane">
|
||||
<ms-api-key-value :isShowEnable="false" :suggestions="headerSuggestions" :items="response.headers"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('api_test.definition.request.response_body')" name="body" class="pane">
|
||||
<mock-api-response-body :isReadOnly="false" :isShowEnable="false" :api-id="apiId" :body="response.body" :headers="response.headers"/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane :label="$t('api_test.definition.request.status_code')" name="status_code" class="pane">
|
||||
<el-row>
|
||||
<el-col :span="2"/>
|
||||
<el-col :span="20">
|
||||
<el-input class="ms-http-input" size="small" v-model="response.httpCode"/>
|
||||
</el-col>
|
||||
<el-col :span="2"/>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="响应延迟时间" name="delayed" class="pane">
|
||||
<el-row>
|
||||
<el-input-number v-model="response.delayed" :min="0">
|
||||
<template slot="append">ms</template>
|
||||
</el-input-number>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-collapse-transition>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MockApiResponseBody from "@/business/components/api/definition/components/mock/Components/MockApiResponseBody";
|
||||
import MsApiKeyValue from "@/business/components/api/definition/components/ApiKeyValue";
|
||||
import MsApiAuthConfig from "@/business/components/api/definition/components/auth/ApiAuthConfig";
|
||||
import ApiRequestMethodSelect from "@/business/components/api/definition/components/collapse/ApiRequestMethodSelect";
|
||||
import MsApiVariable from "@/business/components/api/definition/components/ApiVariable";
|
||||
import MsApiAssertions from "@/business/components/api/definition/components/assertion/ApiAssertions";
|
||||
import MsApiExtract from "@/business/components/api/definition/components/extract/ApiExtract";
|
||||
import BatchAddParameter from "@/business/components/api/definition/components/basis/BatchAddParameter";
|
||||
import MsApiAdvancedConfig from "@/business/components/api/definition/components/request/http/ApiAdvancedConfig";
|
||||
import MsJsr233Processor from "@/business/components/api/automation/scenario/component/Jsr233Processor";
|
||||
import ApiDefinitionStepButton
|
||||
from "@/business/components/api/definition/components/request/components/ApiDefinitionStepButton";
|
||||
import {Body, BODY_FORMAT} from "@/business/components/api/definition/model/ApiTestModel";
|
||||
import {REQUEST_HEADERS} from "@/common/js/constants";
|
||||
|
||||
export default {
|
||||
name: "MockResponseParam",
|
||||
components: {
|
||||
ApiDefinitionStepButton,
|
||||
MsJsr233Processor,
|
||||
MsApiAdvancedConfig,
|
||||
BatchAddParameter,
|
||||
MsApiVariable,
|
||||
ApiRequestMethodSelect,
|
||||
MsApiExtract,
|
||||
MsApiAuthConfig,
|
||||
MockApiResponseBody,
|
||||
MsApiKeyValue,
|
||||
MsApiAssertions
|
||||
},
|
||||
props: {
|
||||
response: {},
|
||||
apiId:String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isActive: true,
|
||||
activeName: "body",
|
||||
modes: ['text', 'json', 'xml', 'html'],
|
||||
sqlModes: ['text', 'table'],
|
||||
mode: BODY_FORMAT.TEXT,
|
||||
isMsCodeEditShow: true,
|
||||
reqMessages: "",
|
||||
headerSuggestions: REQUEST_HEADERS,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
response(){
|
||||
this.setBodyType();
|
||||
this.setReqMessage();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.setBodyType();
|
||||
this.setReqMessage();
|
||||
},
|
||||
methods: {
|
||||
modeChange(mode) {
|
||||
this.mode = mode;
|
||||
},
|
||||
sqlModeChange(mode) {
|
||||
this.mode = mode;
|
||||
},
|
||||
setBodyType() {
|
||||
if (!this.response || !this.response || !this.response.headers) {
|
||||
return;
|
||||
}
|
||||
if (Object.prototype.toString.call(this.response).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object') {
|
||||
this.response = JSON.parse(this.response);
|
||||
}
|
||||
if (!this.response.body) {
|
||||
this.response.body = new Body();
|
||||
}
|
||||
if (!this.response.headers) {
|
||||
this.response.headers = [];
|
||||
}
|
||||
if (!this.response.body.kvs) {
|
||||
this.response.body.kvs = [];
|
||||
}
|
||||
if (!this.response.rest) {
|
||||
this.response.rest = [];
|
||||
}
|
||||
if (!this.response.arguments) {
|
||||
this.response.arguments = [];
|
||||
}
|
||||
|
||||
if (this.response.headers.indexOf("Content-Type: application/json") > 0) {
|
||||
this.mode = BODY_FORMAT.JSON;
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.modeDropdown) {
|
||||
this.$refs.modeDropdown.handleCommand(BODY_FORMAT.JSON);
|
||||
this.msCodeReload();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
msCodeReload() {
|
||||
this.isMsCodeEditShow = false;
|
||||
this.$nextTick(() => {
|
||||
this.isMsCodeEditShow = true;
|
||||
});
|
||||
},
|
||||
setReqMessage() {
|
||||
if (this.response) {
|
||||
if (!this.response.url) {
|
||||
this.response.url = "";
|
||||
}
|
||||
if (!this.response.headers) {
|
||||
this.response.headers = "";
|
||||
}
|
||||
if (!this.response.cookies) {
|
||||
this.response.cookies = "";
|
||||
}
|
||||
if (!this.response.body) {
|
||||
this.response.body = "";
|
||||
}
|
||||
if (!this.response) {
|
||||
this.response = {};
|
||||
}
|
||||
if (!this.response.vars) {
|
||||
this.response.vars = "";
|
||||
}
|
||||
this.reqMessages = this.$t('api_test.request.address') + ":\n" + this.response.url + "\n" +
|
||||
this.$t('api_test.scenario.headers') + ":\n" + this.response.headers + "\n" + "Cookies :\n" +
|
||||
this.response.cookies + "\n" + "Body:" + "\n" + this.response.body;
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.setBodyType();
|
||||
this.setReqMessage();
|
||||
},
|
||||
computed: {
|
||||
responseResult() {
|
||||
return this.response && this.response ? this.response : {};
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.text-container .icon {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.text-container .collapse {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.text-container .collapse:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.text-container .icon.is-active {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.text-container .pane {
|
||||
/*background-color: #F5F5F5;*/
|
||||
padding: 1px 0;
|
||||
height: 250px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.text-container .pane.cookie {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/deep/ .el-tabs__nav-wrap::after {
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
.ms-div {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
|
@ -14,8 +14,6 @@
|
|||
<el-autocomplete :disabled="isReadOnly" :maxlength="400" v-model="item.name" size="small" style="width: 100%"
|
||||
:fetch-suggestions="querySearch"
|
||||
show-word-limit/>
|
||||
<!-- <ms-api-variable-input :show-copy="showCopy" :show-variable="showVariable" :is-read-only="isReadOnly" v-model="item.name" size="small" maxlength="200" @change="change"-->
|
||||
<!-- :placeholder="$t('api_test.variable_name')" show-word-limit/>-->
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-input :disabled="isReadOnly" v-model="item.value" size="small" @change="change"
|
||||
|
|
|
@ -0,0 +1,228 @@
|
|||
<template>
|
||||
<div>
|
||||
<div>
|
||||
<el-input :placeholder="$t('commons.search_by_name')" class="search-input" size="small"
|
||||
:clearable="true"
|
||||
v-model="tableSearch"/>
|
||||
<el-button type="primary" style="float: right;margin-right: 10px" icon="el-icon-plus" size="small"
|
||||
@click="addApiMock">{{ $t('commons.add') }}
|
||||
</el-button>
|
||||
|
||||
<ms-table
|
||||
v-loading="result.loading"
|
||||
:data="mockConfigData.mockExpectConfigList.filter(data=>!tableSearch || data.name.toLowerCase().includes(tableSearch.toLowerCase()))"
|
||||
:operators="operators"
|
||||
:screen-height="screenHeight"
|
||||
@row-click="clickRow"
|
||||
row-key="id"
|
||||
operator-width="80px"
|
||||
ref="table"
|
||||
>
|
||||
|
||||
<ms-table-column
|
||||
prop="name"
|
||||
:label="$t('api_test.mock.table.name')"
|
||||
min-width="160px">
|
||||
</ms-table-column>
|
||||
<ms-table-column prop="tags" width="200px" :label="$t('api_test.mock.table.tag')">
|
||||
<template v-slot:default="scope">
|
||||
<ms-tag v-for="(itemName,index) in scope.row.tags" :key="index" type="success" effect="plain"
|
||||
:show-tooltip="true" :content="itemName" style="margin-left: 0px; margin-right: 2px"/>
|
||||
<span/>
|
||||
</template>
|
||||
</ms-table-column>
|
||||
|
||||
<ms-table-column
|
||||
prop="createUserId"
|
||||
:label="$t('api_test.mock.table.creator')"
|
||||
min-width="160px"/>
|
||||
<ms-table-column
|
||||
sortable="updateTime"
|
||||
min-width="160px"
|
||||
:label="$t('api_test.definition.api_last_time')"
|
||||
prop="updateTime">
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</ms-table-column>
|
||||
<ms-table-column
|
||||
prop="status"
|
||||
min-width="50px"
|
||||
:label="$t('api_test.mock.table.status')">
|
||||
<template v-slot:default="scope">
|
||||
<div>
|
||||
<el-switch
|
||||
v-model="scope.row.status"
|
||||
class="captcha-img"
|
||||
@change="changeStatus(scope.row)"
|
||||
></el-switch>
|
||||
</div>
|
||||
</template>
|
||||
</ms-table-column>
|
||||
</ms-table>
|
||||
</div>
|
||||
<mock-edit-drawer :api-id="this.baseMockConfigData.mockConfig.apiId" @refreshMockInfo="refreshMockInfo" :mock-config-id="mockConfigData.mockConfig.id" ref="mockEditDrawer"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import {getCurrentProjectID, getUUID} from "@/common/js/utils";
|
||||
import MockEditDrawer from "@/business/components/api/definition/components/mock/MockEditDrawer";
|
||||
import MsTable from "@/business/components/common/components/table/MsTable";
|
||||
import MsTableColumn from "@/business/components/common/components/table/MsTableColumn";
|
||||
import MsTag from "@/business/components/common/components/MsTag";
|
||||
|
||||
export default {
|
||||
name: 'MockTab',
|
||||
components: {
|
||||
MockEditDrawer,
|
||||
MsTable,MsTableColumn,MsTag
|
||||
},
|
||||
props: {
|
||||
baseMockConfigData: {}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
visible: false,
|
||||
mockConfigData: {},
|
||||
tableSearch:"",
|
||||
apiParams: [],
|
||||
screenHeight:document.documentElement.clientHeight - 250,
|
||||
operators: [
|
||||
{
|
||||
tip: this.$t('commons.edit'), icon: "el-icon-edit",
|
||||
exec: this.clickRow,
|
||||
},
|
||||
{
|
||||
tip: this.$t('commons.copy'), icon: "el-icon-copy-document",
|
||||
exec: this.copyExpect,
|
||||
},
|
||||
{
|
||||
tip: this.$t('commons.delete'), icon: "el-icon-delete", type: "danger",
|
||||
exec: this.removeExpect,
|
||||
permissions: ['PROJECT_TRACK_REVIEW:READ+RELEVANCE_OR_CANCEL']
|
||||
}
|
||||
],
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
},
|
||||
created() {
|
||||
this.mockConfigData = this.baseMockConfigData;
|
||||
this.searchApiParams(this.mockConfigData.mockConfig.apiId);
|
||||
},
|
||||
computed: {
|
||||
projectId() {
|
||||
return getCurrentProjectID();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
searchApiParams(apiId) {
|
||||
let selectUrl = "/mockConfig/getApiParams/" + apiId;
|
||||
this.$get(selectUrl, response => {
|
||||
this.apiParams = response.data;
|
||||
});
|
||||
},
|
||||
changeStatus(row) {
|
||||
let mockParam = {};
|
||||
mockParam.id = row.id;
|
||||
mockParam.status = row.status;
|
||||
this.$post('/mockConfig/updateMockExpectConfigStatus', mockParam, response => {
|
||||
});
|
||||
},
|
||||
copyExpect(row) {
|
||||
let selectUrl = "/mockConfig/mockExpectConfig/" + row.id;
|
||||
this.$get(selectUrl, response => {
|
||||
let data = response.data;
|
||||
let mockExpectConfig = data;
|
||||
mockExpectConfig.id = "";
|
||||
mockExpectConfig.copyId = row.id;
|
||||
mockExpectConfig.name = mockExpectConfig.name + "_copy";
|
||||
if (mockExpectConfig.request == null) {
|
||||
mockExpectConfig.request = {
|
||||
jsonParam: false,
|
||||
variables: [],
|
||||
jsonData: "{}",
|
||||
};
|
||||
}
|
||||
if (mockExpectConfig.response == null) {
|
||||
mockExpectConfig.response = {
|
||||
httpCode: "",
|
||||
delayed: "",
|
||||
httpHeads: [],
|
||||
body: "",
|
||||
};
|
||||
}
|
||||
this.$refs.mockEditDrawer.open(mockExpectConfig);
|
||||
});
|
||||
},
|
||||
clickRow(row, column, event) {
|
||||
let selectUrl = "/mockConfig/mockExpectConfig/" + row.id;
|
||||
this.$get(selectUrl, response => {
|
||||
let data = response.data;
|
||||
let mockExpectConfig = data;
|
||||
if (mockExpectConfig.request == null) {
|
||||
mockExpectConfig.request = {
|
||||
jsonParam: false,
|
||||
variables: [],
|
||||
jsonData: "{}",
|
||||
};
|
||||
}
|
||||
if (mockExpectConfig.response == null) {
|
||||
mockExpectConfig.response = {
|
||||
httpCode: "",
|
||||
delayed: "",
|
||||
httpHeads: [],
|
||||
body: "",
|
||||
};
|
||||
}
|
||||
this.$refs.mockEditDrawer.open(mockExpectConfig);
|
||||
});
|
||||
},
|
||||
addApiMock(){
|
||||
this.$refs.mockEditDrawer.open();
|
||||
},
|
||||
removeExpect(row) {
|
||||
this.$confirm(this.$t('api_test.mock.delete_mock_expect'), this.$t('commons.prompt'), {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
cancelButtonText: this.$t('commons.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
let mockInfoId = row.mockConfigId;
|
||||
let selectUrl = "/mockConfig/deleteMockExpectConfig/" + row.id;
|
||||
this.$get(selectUrl, response => {
|
||||
this.refreshMockInfo(mockInfoId);
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: this.$t('commons.delete_success'),
|
||||
});
|
||||
});
|
||||
}).catch(() => {
|
||||
});
|
||||
},
|
||||
refreshMockInfo(mockConfigId) {
|
||||
let mockParam = {};
|
||||
mockParam.id = mockConfigId;
|
||||
this.$post('/mockConfig/genMockConfig', mockParam, response => {
|
||||
this.mockConfigData = response.data;
|
||||
});
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.ms-drawer >>> .ms-drawer-body {
|
||||
margin-top: 40px;
|
||||
}
|
||||
.search-input {
|
||||
float: right;
|
||||
width: 300px;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
|
@ -72,6 +72,8 @@ export default {
|
|||
this.reload();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
mounted() {
|
||||
this.reload();
|
||||
},
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -837,6 +837,7 @@ export default {
|
|||
update_time: "更新时间"
|
||||
},
|
||||
expect_detail: "期望详情",
|
||||
request_condition:"请求触发条件",
|
||||
base_info: "基本信息",
|
||||
req_param: "请求参数",
|
||||
rsp_param: "响应内容",
|
||||
|
|
|
@ -837,6 +837,7 @@ export default {
|
|||
update_time: "更新時間"
|
||||
},
|
||||
expect_detail: "期望詳情",
|
||||
request_condition:"請求觸發條件",
|
||||
base_info: "基本信息",
|
||||
req_param: "請求參數",
|
||||
rsp_param: "響應內容",
|
||||
|
|
Loading…
Reference in New Issue