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;
|
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.service.MockConfigService;
|
||||||
import io.metersphere.api.tcp.TCPPool;
|
import io.metersphere.api.tcp.TCPPool;
|
||||||
import io.metersphere.base.domain.Project;
|
import io.metersphere.base.domain.Project;
|
||||||
|
@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.*;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author song.tianyang
|
* @author song.tianyang
|
||||||
|
@ -30,7 +31,8 @@ public class MockApiController {
|
||||||
@NoResultHolder
|
@NoResultHolder
|
||||||
public String postRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) {
|
public String postRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) {
|
||||||
Project project = projectService.findBySystemId(projectSystemId);
|
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;
|
return returnStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +40,8 @@ public class MockApiController {
|
||||||
@NoResultHolder
|
@NoResultHolder
|
||||||
public String getRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) {
|
public String getRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) {
|
||||||
Project project = projectService.findBySystemId(projectSystemId);
|
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;
|
return returnStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +49,8 @@ public class MockApiController {
|
||||||
@NoResultHolder
|
@NoResultHolder
|
||||||
public String putRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) {
|
public String putRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) {
|
||||||
Project project = projectService.findBySystemId(projectSystemId);
|
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;
|
return returnStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +58,8 @@ public class MockApiController {
|
||||||
@NoResultHolder
|
@NoResultHolder
|
||||||
public String patchRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) {
|
public String patchRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) {
|
||||||
Project project = projectService.findBySystemId(projectSystemId);
|
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;
|
return returnStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +67,8 @@ public class MockApiController {
|
||||||
@NoResultHolder
|
@NoResultHolder
|
||||||
public String deleteRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) {
|
public String deleteRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) {
|
||||||
Project project = projectService.findBySystemId(projectSystemId);
|
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;
|
return returnStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +76,8 @@ public class MockApiController {
|
||||||
@NoResultHolder
|
@NoResultHolder
|
||||||
public String optionsRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) {
|
public String optionsRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) {
|
||||||
Project project = projectService.findBySystemId(projectSystemId);
|
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;
|
return returnStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +85,8 @@ public class MockApiController {
|
||||||
@NoResultHolder
|
@NoResultHolder
|
||||||
public void headRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) {
|
public void headRequest(@PathVariable String projectSystemId, HttpServletRequest request, HttpServletResponse response) {
|
||||||
Project project = projectService.findBySystemId(projectSystemId);
|
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/")
|
@GetMapping("/getTcpMockPortStatus/")
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package io.metersphere.api.controller;
|
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.MockConfigRequest;
|
||||||
import io.metersphere.api.dto.mockconfig.MockExpectConfigRequest;
|
import io.metersphere.api.dto.mockconfig.MockExpectConfigRequest;
|
||||||
import io.metersphere.api.dto.mockconfig.response.MockConfigResponse;
|
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.MockExpectConfig;
|
||||||
import io.metersphere.base.domain.MockExpectConfigWithBLOBs;
|
import io.metersphere.base.domain.MockExpectConfigWithBLOBs;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -34,11 +36,25 @@ public class MockConfigController {
|
||||||
return mockConfigService.genMockConfig(request);
|
return mockConfigService.genMockConfig(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/updateMockExpectConfig")
|
@PostMapping(value ="/updateMockExpectConfig", consumes = {"multipart/form-data"})
|
||||||
public MockExpectConfig updateMockExpectConfig(@RequestBody MockExpectConfigRequest request) {
|
public MockExpectConfig updateMockExpectConfig(@RequestPart("request")MockExpectConfigRequest request, @RequestPart(value = "files", required = false) List<MultipartFile> bodyFiles) {
|
||||||
return mockConfigService.updateMockExpectConfig(request);
|
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}")
|
@GetMapping("/mockExpectConfig/{id}")
|
||||||
public MockExpectConfigResponse selectMockExpectConfig(@PathVariable String id) {
|
public MockExpectConfigResponse selectMockExpectConfig(@PathVariable String id) {
|
||||||
MockExpectConfigWithBLOBs config = mockConfigService.findMockExpectConfigById(id);
|
MockExpectConfigWithBLOBs config = mockConfigService.findMockExpectConfigById(id);
|
||||||
|
@ -58,4 +74,12 @@ public class MockConfigController {
|
||||||
List<Map<String, String>> apiParams = mockConfigService.getApiParamsByApiDefinitionBLOBs(apiDefinitionWithBLOBs);
|
List<Map<String, String>> apiParams = mockConfigService.getApiParamsByApiDefinitionBLOBs(apiDefinitionWithBLOBs);
|
||||||
return apiParams;
|
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 Object response;
|
||||||
|
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
|
private String copyId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -560,9 +560,9 @@ public class ApiDefinitionService {
|
||||||
if (CollectionUtils.isEmpty(sameRequest)) {
|
if (CollectionUtils.isEmpty(sameRequest)) {
|
||||||
//postman 可能含有前置脚本,接口定义去掉脚本
|
//postman 可能含有前置脚本,接口定义去掉脚本
|
||||||
apiDefinition.setOrder(getImportNextOrder(apiTestImportRequest.getProjectId()));
|
apiDefinition.setOrder(getImportNextOrder(apiTestImportRequest.getProjectId()));
|
||||||
batchMapper.insert(apiDefinition);
|
|
||||||
String originId = apiDefinition.getId();
|
String originId = apiDefinition.getId();
|
||||||
apiDefinition.setId(UUID.randomUUID().toString());
|
apiDefinition.setId(UUID.randomUUID().toString());
|
||||||
|
batchMapper.insert(apiDefinition);
|
||||||
String requestStr = setImportHashTree(apiDefinition);
|
String requestStr = setImportHashTree(apiDefinition);
|
||||||
reSetImportCasesApiId(cases, originId, apiDefinition.getId());
|
reSetImportCasesApiId(cases, originId, apiDefinition.getId());
|
||||||
apiDefinition.setRequest(requestStr);
|
apiDefinition.setRequest(requestStr);
|
||||||
|
@ -1014,6 +1014,7 @@ public class ApiDefinitionService {
|
||||||
if (apiImport.getEsbApiParamsMap() != null) {
|
if (apiImport.getEsbApiParamsMap() != null) {
|
||||||
String apiId = item.getId();
|
String apiId = item.getId();
|
||||||
EsbApiParamsWithBLOBs model = apiImport.getEsbApiParamsMap().get(apiId);
|
EsbApiParamsWithBLOBs model = apiImport.getEsbApiParamsMap().get(apiId);
|
||||||
|
request.setModeId("fullCoverage");//标准版ESB数据导入不区分是否覆盖,默认都为覆盖
|
||||||
importCreate(item, batchMapper, apiTestCaseMapper, request, apiImport.getCases(), apiImport.getMocks(), project.getRepeatable());
|
importCreate(item, batchMapper, apiTestCaseMapper, request, apiImport.getCases(), apiImport.getMocks(), project.getRepeatable());
|
||||||
if (model != null) {
|
if (model != null) {
|
||||||
apiImport.getEsbApiParamsMap().remove(apiId);
|
apiImport.getEsbApiParamsMap().remove(apiId);
|
||||||
|
|
|
@ -295,6 +295,9 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
|
||||||
if (StringUtils.isNotBlank(node.getId())) {
|
if (StringUtils.isNotBlank(node.getId())) {
|
||||||
criteria.andIdNotEqualTo(node.getId());
|
criteria.andIdNotEqualTo(node.getId());
|
||||||
}
|
}
|
||||||
|
if(StringUtils.isNotEmpty(node.getProtocol())){
|
||||||
|
criteria.andProtocolEqualTo(node.getProtocol());
|
||||||
|
}
|
||||||
return apiModuleMapper.selectByExample(example);
|
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.TcpTreeTableDataStruct;
|
||||||
import io.metersphere.api.dto.automation.parse.TcpTreeTableDataParser;
|
import io.metersphere.api.dto.automation.parse.TcpTreeTableDataParser;
|
||||||
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
|
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.MockConfigImportDTO;
|
||||||
import io.metersphere.api.dto.mockconfig.MockConfigRequest;
|
import io.metersphere.api.dto.mockconfig.MockConfigRequest;
|
||||||
import io.metersphere.api.dto.mockconfig.MockExpectConfigRequest;
|
import io.metersphere.api.dto.mockconfig.MockExpectConfigRequest;
|
||||||
|
@ -30,6 +32,7 @@ import org.apache.ibatis.session.SqlSession;
|
||||||
import org.json.XML;
|
import org.json.XML;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
@ -165,7 +168,21 @@ public class MockConfigService {
|
||||||
return returnRsp;
|
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;
|
boolean isSave = false;
|
||||||
if (StringUtils.isEmpty(request.getId())) {
|
if (StringUtils.isEmpty(request.getId())) {
|
||||||
isSave = true;
|
isSave = true;
|
||||||
|
@ -200,6 +217,10 @@ public class MockConfigService {
|
||||||
} else {
|
} else {
|
||||||
mockExpectConfigMapper.updateByPrimaryKeySelective(model);
|
mockExpectConfigMapper.updateByPrimaryKeySelective(model);
|
||||||
}
|
}
|
||||||
|
if (StringUtils.isNotEmpty(request.getCopyId())) {
|
||||||
|
FileUtils.copyBdyFile(request.getCopyId(), model.getId());
|
||||||
|
}
|
||||||
|
FileUtils.createBodyFiles(model.getId(), bodyFiles);
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,14 +233,268 @@ 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;
|
MockExpectConfigResponse returnModel = null;
|
||||||
|
|
||||||
if (reqJsonObj == null || reqJsonObj.isEmpty()) {
|
if (requestMockParams == null || requestMockParams.isEmpty()) {
|
||||||
|
//如果参数为空,则匹配请求为空的期望
|
||||||
for (MockExpectConfigResponse model : mockExpectConfigList) {
|
for (MockExpectConfigResponse model : mockExpectConfigList) {
|
||||||
if (!model.isStatus()) {
|
if (!model.isStatus()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
JSONObject requestObj = model.getRequest();
|
||||||
|
MockExpectConfigResponse resultModel = null;
|
||||||
|
if (requestObj.containsKey("params")) {
|
||||||
|
resultModel = this.getEmptyRequestMockExpectByParams(requestHeaderMap, model);
|
||||||
|
} else {
|
||||||
|
resultModel = this.getEmptyRequestMockExpect(model);
|
||||||
|
}
|
||||||
|
if (resultModel != null) {
|
||||||
|
return resultModel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (MockExpectConfigResponse model : mockExpectConfigList) {
|
||||||
|
try {
|
||||||
|
if (!model.isStatus()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
JSONObject mockExpectRequestObj = model.getRequest();
|
||||||
|
boolean mathing = false;
|
||||||
|
if (mockExpectRequestObj.containsKey("params")) {
|
||||||
|
mathing = this.isRequestMockExpectMatchingByParams(requestHeaderMap, mockExpectRequestObj, requestMockParams);
|
||||||
|
} else {
|
||||||
|
mathing = this.isRequestMockExpectMatching(mockExpectRequestObj, requestMockParams.getQueryParamsObj());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mathing) {
|
||||||
|
returnModel = model;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
JSONObject requestObj = model.getRequest();
|
||||||
boolean isJsonParam = requestObj.getBoolean("jsonParam");
|
boolean isJsonParam = requestObj.getBoolean("jsonParam");
|
||||||
if (isJsonParam) {
|
if (isJsonParam) {
|
||||||
|
@ -247,60 +522,10 @@ public class MockConfigService {
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return null;
|
||||||
}
|
|
||||||
for (MockExpectConfigResponse model : mockExpectConfigList) {
|
|
||||||
try {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
} 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean mathing = JsonStructUtils.checkJsonObjCompliance(reqJsonObj, mockExpectJson);
|
public MockExpectConfigResponse findExpectConfigByArrayJson(Map<String, String> requestHeaderMap, List<MockExpectConfigResponse> mockExpectConfigList, JSONArray reqJsonArray) {
|
||||||
if (mathing) {
|
|
||||||
returnModel = model;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return returnModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MockExpectConfigResponse findExpectConfig(List<MockExpectConfigResponse> mockExpectConfigList, JSONArray reqJsonArray) {
|
|
||||||
MockExpectConfigResponse returnModel = null;
|
MockExpectConfigResponse returnModel = null;
|
||||||
|
|
||||||
if (reqJsonArray == null || reqJsonArray.isEmpty()) {
|
if (reqJsonArray == null || reqJsonArray.isEmpty()) {
|
||||||
|
@ -393,12 +618,48 @@ public class MockConfigService {
|
||||||
return returnModel;
|
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 = "";
|
String returnStr = "";
|
||||||
try {
|
try {
|
||||||
//设置响应头和响应码
|
//设置响应头和响应码
|
||||||
JSONObject responseObj = finalExpectConfig.getResponse();
|
JSONObject responseObj = finalExpectConfig.getResponse();
|
||||||
String httpCode = responseObj.getString("httpCode");
|
String httpCode = responseObj.getString("httpCode");
|
||||||
|
if (StringUtils.isEmpty(httpCode)) {
|
||||||
|
httpCode = "500";
|
||||||
|
}
|
||||||
|
response.setStatus(Integer.parseInt(httpCode));
|
||||||
|
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");
|
JSONArray jsonArray = responseObj.getJSONArray("httpHeads");
|
||||||
for (int i = 0; i < jsonArray.size(); i++) {
|
for (int i = 0; i < jsonArray.size(); i++) {
|
||||||
JSONObject object = jsonArray.getJSONObject(i);
|
JSONObject object = jsonArray.getJSONObject(i);
|
||||||
|
@ -414,13 +675,16 @@ public class MockConfigService {
|
||||||
response.setHeader(name, value);
|
response.setHeader(name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
response.setStatus(Integer.parseInt(httpCode));
|
|
||||||
|
|
||||||
returnStr = String.valueOf(responseObj.get("body"));
|
returnStr = String.valueOf(responseObj.get("body"));
|
||||||
|
|
||||||
if (responseObj.containsKey("delayed")) {
|
if (responseObj.containsKey("delayed")) {
|
||||||
try {
|
try {
|
||||||
long sleepTime = Long.parseLong(String.valueOf(responseObj.get("delayed")));
|
sleepTime = Long.parseLong(String.valueOf(responseObj.get("delayed")));
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sleepTime > 0) {
|
||||||
|
try {
|
||||||
Thread.sleep(sleepTime);
|
Thread.sleep(sleepTime);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
}
|
}
|
||||||
|
@ -480,7 +744,7 @@ public class MockConfigService {
|
||||||
if (bodyObj.containsKey("jsonSchema") && bodyObj.getJSONObject("jsonSchema").containsKey("properties")) {
|
if (bodyObj.containsKey("jsonSchema") && bodyObj.getJSONObject("jsonSchema").containsKey("properties")) {
|
||||||
String bodyRetunStr = bodyObj.getJSONObject("jsonSchema").getJSONObject("properties").toJSONString();
|
String bodyRetunStr = bodyObj.getJSONObject("jsonSchema").getJSONObject("properties").toJSONString();
|
||||||
JSONObject bodyReturnObj = JSONObject.parseObject(bodyRetunStr);
|
JSONObject bodyReturnObj = JSONObject.parseObject(bodyRetunStr);
|
||||||
JSONObject returnObj = this.parseJsonSchema(bodyReturnObj);
|
JSONObject returnObj = MockApiUtils.parseJsonSchema(bodyReturnObj);
|
||||||
returnStr = returnObj.toJSONString();
|
returnStr = returnObj.toJSONString();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -515,37 +779,38 @@ public class MockConfigService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
returnStr = JSONObject.toJSONString(paramMap);
|
returnStr = JSONObject.toJSONString(paramMap);
|
||||||
} else if (StringUtils.equals(type, "BINARY")) {
|
//Binary的先不处理
|
||||||
Map<String, String> paramMap = new LinkedHashMap<>();
|
// } else if (StringUtils.equals(type, "BINARY")) {
|
||||||
if (bodyObj.containsKey("binary")) {
|
// Map<String, String> paramMap = new LinkedHashMap<>();
|
||||||
JSONArray kvsArr = bodyObj.getJSONArray("kvs");
|
// if (bodyObj.containsKey("binary")) {
|
||||||
for (int i = 0; i < kvsArr.size(); i++) {
|
// JSONArray kvsArr = bodyObj.getJSONArray("kvs");
|
||||||
JSONObject kv = kvsArr.getJSONObject(i);
|
// for (int i = 0; i < kvsArr.size(); i++) {
|
||||||
if (kv.containsKey("description") && kv.containsKey("files")) {
|
// JSONObject kv = kvsArr.getJSONObject(i);
|
||||||
String name = kv.getString("description");
|
// if (kv.containsKey("description") && kv.containsKey("files")) {
|
||||||
JSONArray fileArr = kv.getJSONArray("files");
|
// String name = kv.getString("description");
|
||||||
String allValue = "";
|
// JSONArray fileArr = kv.getJSONArray("files");
|
||||||
for (int j = 0; j < fileArr.size(); j++) {
|
// String allValue = "";
|
||||||
JSONObject fileObj = fileArr.getJSONObject(j);
|
// for (int j = 0; j < fileArr.size(); j++) {
|
||||||
if (fileObj.containsKey("name")) {
|
// JSONObject fileObj = fileArr.getJSONObject(j);
|
||||||
String values = fileObj.getString("name");
|
// if (fileObj.containsKey("name")) {
|
||||||
if (StringUtils.isEmpty(values)) {
|
// String values = fileObj.getString("name");
|
||||||
values = "";
|
// if (StringUtils.isEmpty(values)) {
|
||||||
} else {
|
// values = "";
|
||||||
try {
|
// } else {
|
||||||
values = values.startsWith("@") ? ScriptEngineUtils.buildFunctionCallString(values) : values;
|
// try {
|
||||||
} catch (Exception e) {
|
// values = values.startsWith("@") ? ScriptEngineUtils.buildFunctionCallString(values) : values;
|
||||||
}
|
// } catch (Exception e) {
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
allValue += values + " ;";
|
//
|
||||||
}
|
// allValue += values + " ;";
|
||||||
}
|
// }
|
||||||
paramMap.put(name, allValue);
|
// }
|
||||||
}
|
// paramMap.put(name, allValue);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
returnStr = JSONObject.toJSONString(paramMap);
|
// }
|
||||||
|
// returnStr = JSONObject.toJSONString(paramMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -563,78 +828,26 @@ public class MockConfigService {
|
||||||
return returnStr;
|
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) {
|
public MockExpectConfigWithBLOBs findMockExpectConfigById(String id) {
|
||||||
return mockExpectConfigMapper.selectByPrimaryKey(id);
|
return mockExpectConfigMapper.selectByPrimaryKey(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteMockExpectConfig(String id) {
|
public void deleteMockExpectConfig(String id) {
|
||||||
|
MockExpectConfigWithBLOBs mockBlobs = mockExpectConfigMapper.selectByPrimaryKey(id);
|
||||||
|
if (mockBlobs != null) {
|
||||||
|
this.deleteMockExpectFiles(mockBlobs);
|
||||||
mockExpectConfigMapper.deleteByPrimaryKey(id);
|
mockExpectConfigMapper.deleteByPrimaryKey(id);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
public void deleteMockConfigByApiId(String apiId) {
|
||||||
MockConfigExample configExample = new MockConfigExample();
|
MockConfigExample configExample = new MockConfigExample();
|
||||||
|
@ -644,20 +857,31 @@ public class MockConfigService {
|
||||||
for (MockConfig mockConfig : mockConfigList) {
|
for (MockConfig mockConfig : mockConfigList) {
|
||||||
example.clear();
|
example.clear();
|
||||||
example.createCriteria().andMockConfigIdEqualTo(mockConfig.getId());
|
example.createCriteria().andMockConfigIdEqualTo(mockConfig.getId());
|
||||||
|
List<MockExpectConfigWithBLOBs> deleteBolobs = mockExpectConfigMapper.selectByExampleWithBLOBs(example);
|
||||||
|
for (MockExpectConfigWithBLOBs model : deleteBolobs) {
|
||||||
|
this.deleteMockExpectFiles(model);
|
||||||
|
}
|
||||||
mockExpectConfigMapper.deleteByExample(example);
|
mockExpectConfigMapper.deleteByExample(example);
|
||||||
}
|
}
|
||||||
mockConfigMapper.deleteByExample(configExample);
|
mockConfigMapper.deleteByExample(configExample);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSONObject getGetParamMap(String urlParams, ApiDefinitionWithBLOBs api, HttpServletRequest request) {
|
public RequestMockParams getGetParamMap(String urlParams, ApiDefinitionWithBLOBs api, HttpServletRequest request) {
|
||||||
JSONObject paramMap = this.getSendRestParamMapByIdAndUrl(api, urlParams);
|
RequestMockParams requestMockParams = new RequestMockParams();
|
||||||
|
|
||||||
|
JSONObject urlParamsObject = this.getSendRestParamMapByIdAndUrl(api, urlParams);
|
||||||
|
|
||||||
|
JSONObject queryParamsObject = new JSONObject();
|
||||||
Enumeration<String> paramNameItor = request.getParameterNames();
|
Enumeration<String> paramNameItor = request.getParameterNames();
|
||||||
while (paramNameItor.hasMoreElements()) {
|
while (paramNameItor.hasMoreElements()) {
|
||||||
String key = paramNameItor.nextElement();
|
String key = paramNameItor.nextElement();
|
||||||
String value = request.getParameter(key);
|
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) {
|
public JSON getPostParamMap(HttpServletRequest request) {
|
||||||
|
@ -699,13 +923,14 @@ public class MockConfigService {
|
||||||
} else {
|
} else {
|
||||||
JSONObject object = new JSONObject();
|
JSONObject object = new JSONObject();
|
||||||
String bodyParam = this.readBody(request);
|
String bodyParam = this.readBody(request);
|
||||||
if (!StringUtils.isEmpty(bodyParam)) {
|
object.put("raw",bodyParam);
|
||||||
try {
|
// if (!StringUtils.isEmpty(bodyParam)) {
|
||||||
object = JSONObject.parseObject(bodyParam);
|
// try {
|
||||||
} catch (Exception e) {
|
// object = JSONObject.parseObject(bodyParam);
|
||||||
e.printStackTrace();
|
// } catch (Exception e) {
|
||||||
}
|
// object.put("raw",bodyParam);
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
Enumeration<String> paramNameItor = request.getParameterNames();
|
Enumeration<String> paramNameItor = request.getParameterNames();
|
||||||
while (paramNameItor.hasMoreElements()) {
|
while (paramNameItor.hasMoreElements()) {
|
||||||
|
@ -881,29 +1106,30 @@ public class MockConfigService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (StringUtils.equals(type, "BINARY")) {
|
//Binary的先不处理
|
||||||
if (bodyObj.containsKey("binary")) {
|
// } else if (StringUtils.equals(type, "BINARY")) {
|
||||||
List<Map<String, String>> bodyParamList = new ArrayList<>();
|
// if (bodyObj.containsKey("binary")) {
|
||||||
JSONArray kvsArr = bodyObj.getJSONArray("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);
|
// for (int i = 0; i < kvsArr.size(); i++) {
|
||||||
if (kv.containsKey("description") && kv.containsKey("files")) {
|
// JSONObject kv = kvsArr.getJSONObject(i);
|
||||||
String name = kv.getString("description");
|
// if (kv.containsKey("description") && kv.containsKey("files")) {
|
||||||
JSONArray fileArr = kv.getJSONArray("files");
|
// String name = kv.getString("description");
|
||||||
String value = "";
|
// JSONArray fileArr = kv.getJSONArray("files");
|
||||||
for (int j = 0; j < fileArr.size(); j++) {
|
// String value = "";
|
||||||
JSONObject fileObj = fileArr.getJSONObject(j);
|
// for (int j = 0; j < fileArr.size(); j++) {
|
||||||
if (fileObj.containsKey("name")) {
|
// JSONObject fileObj = fileArr.getJSONObject(j);
|
||||||
value += fileObj.getString("name") + " ;";
|
// if (fileObj.containsKey("name")) {
|
||||||
}
|
// value += fileObj.getString("name") + " ;";
|
||||||
}
|
// }
|
||||||
if (!paramNameList.contains(name)) {
|
// }
|
||||||
paramNameList.add(name);
|
// if (!paramNameList.contains(name)) {
|
||||||
}
|
// paramNameList.add(name);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -946,10 +1172,11 @@ public class MockConfigService {
|
||||||
return this.assemblyMockConfingResponse(configList);
|
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) {
|
request, HttpServletResponse response) {
|
||||||
String returnStr = "";
|
String returnStr = "";
|
||||||
boolean isMatch = false;
|
boolean isMatch = false;
|
||||||
|
String url = request.getRequestURL().toString();
|
||||||
List<ApiDefinitionWithBLOBs> aualifiedApiList = new ArrayList<>();
|
List<ApiDefinitionWithBLOBs> aualifiedApiList = new ArrayList<>();
|
||||||
if (project != null) {
|
if (project != null) {
|
||||||
String urlSuffix = this.getUrlSuffix(project.getSystemId(), request);
|
String urlSuffix = this.getUrlSuffix(project.getSystemId(), request);
|
||||||
|
@ -960,33 +1187,40 @@ public class MockConfigService {
|
||||||
if (mockConfigData != null && mockConfigData.getMockExpectConfigList() != null) {
|
if (mockConfigData != null && mockConfigData.getMockExpectConfigList() != null) {
|
||||||
JSON paramJson = this.getPostParamMap(request);
|
JSON paramJson = this.getPostParamMap(request);
|
||||||
if (paramJson instanceof JSONObject) {
|
if (paramJson instanceof JSONObject) {
|
||||||
JSONObject paramMap = (JSONObject) paramJson;
|
JSONArray paramsArray = new JSONArray();
|
||||||
MockExpectConfigResponse finalExpectConfig = this.findExpectConfig(mockConfigData.getMockExpectConfigList(), paramMap);
|
paramsArray.add(paramJson);
|
||||||
|
RequestMockParams mockParams = new RequestMockParams();
|
||||||
|
mockParams.setBodyParams(paramsArray);
|
||||||
|
MockExpectConfigResponse finalExpectConfig = this.findExpectConfig(requestHeaderMap, mockConfigData.getMockExpectConfigList(), mockParams);
|
||||||
if (finalExpectConfig != null) {
|
if (finalExpectConfig != null) {
|
||||||
isMatch = true;
|
isMatch = true;
|
||||||
returnStr = this.updateHttpServletResponse(finalExpectConfig, response);
|
returnStr = this.updateHttpServletResponse(finalExpectConfig, url, requestHeaderMap, mockParams, response);
|
||||||
}
|
}
|
||||||
} else if (paramJson instanceof JSONArray) {
|
} else if (paramJson instanceof JSONArray) {
|
||||||
JSONArray paramArray = (JSONArray) paramJson;
|
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) {
|
if (finalExpectConfig != null) {
|
||||||
isMatch = true;
|
isMatch = true;
|
||||||
returnStr = this.updateHttpServletResponse(finalExpectConfig, response);
|
returnStr = this.updateHttpServletResponse(finalExpectConfig, url, requestHeaderMap, mockParams, response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isMatch) {
|
if (!isMatch) {
|
||||||
returnStr = this.updateHttpServletResponse(aualifiedApiList, response);
|
// returnStr = this.updateHttpServletResponse(aualifiedApiList, response);
|
||||||
|
response.setStatus(404);
|
||||||
}
|
}
|
||||||
return returnStr;
|
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) {
|
request, HttpServletResponse response) {
|
||||||
String returnStr = "";
|
String returnStr = "";
|
||||||
boolean isMatch = false;
|
boolean isMatch = false;
|
||||||
|
String url = request.getRequestURI();
|
||||||
List<ApiDefinitionWithBLOBs> aualifiedApiList = new ArrayList<>();
|
List<ApiDefinitionWithBLOBs> aualifiedApiList = new ArrayList<>();
|
||||||
if (project != null) {
|
if (project != null) {
|
||||||
String urlSuffix = this.getUrlSuffix(project.getSystemId(), request);
|
String urlSuffix = this.getUrlSuffix(project.getSystemId(), request);
|
||||||
|
@ -1001,13 +1235,13 @@ public class MockConfigService {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (ApiDefinitionWithBLOBs api : aualifiedApiList) {
|
for (ApiDefinitionWithBLOBs api : aualifiedApiList) {
|
||||||
JSONObject paramMap = this.getGetParamMap(urlSuffix, api, request);
|
RequestMockParams paramMap = this.getGetParamMap(urlSuffix, api, request);
|
||||||
|
|
||||||
MockConfigResponse mockConfigData = this.findByApiId(api.getId());
|
MockConfigResponse mockConfigData = this.findByApiId(api.getId());
|
||||||
if (mockConfigData != null && mockConfigData.getMockExpectConfigList() != null) {
|
if (mockConfigData != null && mockConfigData.getMockExpectConfigList() != null) {
|
||||||
MockExpectConfigResponse finalExpectConfig = this.findExpectConfig(mockConfigData.getMockExpectConfigList(), paramMap);
|
MockExpectConfigResponse finalExpectConfig = this.findExpectConfig(requestHeaderMap, mockConfigData.getMockExpectConfigList(), paramMap);
|
||||||
if (finalExpectConfig != null) {
|
if (finalExpectConfig != null) {
|
||||||
returnStr = this.updateHttpServletResponse(finalExpectConfig, response);
|
returnStr = this.updateHttpServletResponse(finalExpectConfig, url, requestHeaderMap, paramMap, response);
|
||||||
isMatch = true;
|
isMatch = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1016,7 +1250,8 @@ public class MockConfigService {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isMatch) {
|
if (!isMatch) {
|
||||||
returnStr = this.updateHttpServletResponse(aualifiedApiList, response);
|
// returnStr = this.updateHttpServletResponse(aualifiedApiList, response);
|
||||||
|
response.setStatus(404);
|
||||||
}
|
}
|
||||||
return returnStr;
|
return returnStr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,13 @@ public class JsonStructUtils {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static boolean checkJsonObjCompliance(JSONObject sourceObj, JSONObject matchObj) {
|
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;
|
return true;
|
||||||
} else if (sourceObj != null && matchObj != null) {
|
} else if (sourceObj != null && matchObj != null) {
|
||||||
boolean lastMatchResultIsTrue = false;
|
boolean lastMatchResultIsTrue = false;
|
||||||
|
@ -55,7 +61,7 @@ public class JsonStructUtils {
|
||||||
public static boolean checkJsonArrayCompliance(JSONArray sourceArray, JSONArray matchArray) {
|
public static boolean checkJsonArrayCompliance(JSONArray sourceArray, JSONArray matchArray) {
|
||||||
if (sourceArray == null && matchArray == null) {
|
if (sourceArray == null && matchArray == null) {
|
||||||
return true;
|
return true;
|
||||||
} else if (sourceArray != null && matchArray != null && sourceArray.size() > matchArray.size()) {
|
} else if (sourceArray != null && matchArray != null && sourceArray.size() >= matchArray.size()) {
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < matchArray.size(); i++) {
|
for (int i = 0; i < matchArray.size(); i++) {
|
||||||
Object obj = matchArray.get(i);
|
Object obj = matchArray.get(i);
|
||||||
|
|
|
@ -74,7 +74,8 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="showMock && (currentProtocol === 'HTTP')" class="ms-api-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>
|
||||||
<div v-if="showMock && (currentProtocol === 'TCP')" class="ms-api-div">
|
<div v-if="showMock && (currentProtocol === 'TCP')" class="ms-api-div">
|
||||||
<tcp-mock-config :base-mock-config-data="baseMockConfigData" type="tcp"/>
|
<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 MsRunTestTcpPage from "./runtest/RunTestTCPPage";
|
||||||
import MsRunTestSqlPage from "./runtest/RunTestSQLPage";
|
import MsRunTestSqlPage from "./runtest/RunTestSQLPage";
|
||||||
import MsRunTestDubboPage from "./runtest/RunTestDubboPage";
|
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 TcpMockConfig from "@/business/components/api/definition/components/mock/TcpMockConfig";
|
||||||
import ApiCaseSimpleList from "./list/ApiCaseSimpleList";
|
import ApiCaseSimpleList from "./list/ApiCaseSimpleList";
|
||||||
import MsApiCaseList from "./case/ApiCaseList";
|
import MsApiCaseList from "./case/ApiCaseList";
|
||||||
|
@ -120,7 +121,7 @@ export default {
|
||||||
MsRunTestTcpPage,
|
MsRunTestTcpPage,
|
||||||
MsRunTestSqlPage,
|
MsRunTestSqlPage,
|
||||||
MsRunTestDubboPage,
|
MsRunTestDubboPage,
|
||||||
MockConfig,
|
MockTab,
|
||||||
TcpMockConfig,
|
TcpMockConfig,
|
||||||
ApiCaseSimpleList,
|
ApiCaseSimpleList,
|
||||||
MsApiCaseList
|
MsApiCaseList
|
||||||
|
|
|
@ -128,6 +128,7 @@ export default {
|
||||||
propIsEnumerable: Object.prototype.propertyIsEnumerable
|
propIsEnumerable: Object.prototype.propertyIsEnumerable
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
'body.raw'() {
|
'body.raw'() {
|
||||||
if (this.body.format !== 'JSON-SCHEMA' && this.body.raw) {
|
if (this.body.format !== 'JSON-SCHEMA' && this.body.raw) {
|
||||||
|
@ -141,7 +142,7 @@ export default {
|
||||||
this.body.jsonSchema = "";
|
this.body.jsonSchema = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
isObj(x) {
|
isObj(x) {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<i class="el-icon-plus"/>
|
<i class="el-icon-plus"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="upload-item" slot="file" slot-scope="{file}">
|
<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 class="el-upload-list__item-actions">
|
||||||
<!--<span v-if="!disabled" class="el-upload-list__item-delete" @click="handleDownload(file)">-->
|
<!--<span v-if="!disabled" class="el-upload-list__item-delete" @click="handleDownload(file)">-->
|
||||||
<!--<i class="el-icon-download"/>-->
|
<!--<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;
|
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) {
|
removeExpect(row) {
|
||||||
this.$confirm(this.$t('api_test.mock.delete_mock_expect'), this.$t('commons.prompt'), {
|
this.$confirm(this.$t('api_test.mock.delete_mock_expect'), this.$t('commons.prompt'), {
|
||||||
confirmButtonText: this.$t('commons.confirm'),
|
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>
|
</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%"
|
<el-autocomplete :disabled="isReadOnly" :maxlength="400" v-model="item.name" size="small" style="width: 100%"
|
||||||
:fetch-suggestions="querySearch"
|
:fetch-suggestions="querySearch"
|
||||||
show-word-limit/>
|
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-col>
|
<el-col>
|
||||||
<el-input :disabled="isReadOnly" v-model="item.value" size="small" @change="change"
|
<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();
|
this.reload();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.reload();
|
this.reload();
|
||||||
},
|
},
|
||||||
|
|
|
@ -831,6 +831,7 @@ export default {
|
||||||
update_time: "Update time"
|
update_time: "Update time"
|
||||||
},
|
},
|
||||||
expect_detail: "Expect",
|
expect_detail: "Expect",
|
||||||
|
request_condition:"Request Condition",
|
||||||
base_info: "Base info",
|
base_info: "Base info",
|
||||||
req_param: "Request params",
|
req_param: "Request params",
|
||||||
rsp_param: "Response Params",
|
rsp_param: "Response Params",
|
||||||
|
|
|
@ -837,6 +837,7 @@ export default {
|
||||||
update_time: "更新时间"
|
update_time: "更新时间"
|
||||||
},
|
},
|
||||||
expect_detail: "期望详情",
|
expect_detail: "期望详情",
|
||||||
|
request_condition:"请求触发条件",
|
||||||
base_info: "基本信息",
|
base_info: "基本信息",
|
||||||
req_param: "请求参数",
|
req_param: "请求参数",
|
||||||
rsp_param: "响应内容",
|
rsp_param: "响应内容",
|
||||||
|
|
|
@ -837,6 +837,7 @@ export default {
|
||||||
update_time: "更新時間"
|
update_time: "更新時間"
|
||||||
},
|
},
|
||||||
expect_detail: "期望詳情",
|
expect_detail: "期望詳情",
|
||||||
|
request_condition:"請求觸發條件",
|
||||||
base_info: "基本信息",
|
base_info: "基本信息",
|
||||||
req_param: "請求參數",
|
req_param: "請求參數",
|
||||||
rsp_param: "響應內容",
|
rsp_param: "響應內容",
|
||||||
|
|
Loading…
Reference in New Issue