Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
4a22ef3224
|
@ -167,6 +167,11 @@ curl -sSL https://github.com/metersphere/metersphere/releases/latest/download/qu
|
|||
- 基础设施: [Docker](https://www.docker.com/), [Kubernetes](https://kubernetes.io/)
|
||||
- 测试引擎: [JMeter](https://jmeter.apache.org/)
|
||||
|
||||
## 加入 MeterSphere 团队
|
||||
我们正在招聘 MeterSphere 技术布道师,一起打造开源明星项目,请发简历到 metersphere@fit2cloud.com
|
||||
|
||||
点击查看 [岗位详情](https://www.zhipin.com/job_detail/b151c4b3d594688733Ny3dy1GFI~.html)
|
||||
|
||||
## 微信群
|
||||
|
||||
![wechat-group](https://metersphere.io/images/contact/wechat-group.png)
|
||||
|
|
|
@ -190,6 +190,13 @@
|
|||
<artifactId>spring-boot-starter-data-ldap</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- swagger 解析 -->
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-parser</artifactId>
|
||||
<version>1.0.51</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -14,4 +14,5 @@ public class SwaggerApi {
|
|||
private List<String> schemes;
|
||||
private List<SwaggerTag> tags;
|
||||
private JSONObject paths;
|
||||
private JSONObject definitions;
|
||||
}
|
||||
|
|
|
@ -12,5 +12,5 @@ public class SwaggerRequest {
|
|||
private String operationId;
|
||||
private List<String> consumes;
|
||||
private List<String> produces;
|
||||
private SwaggerParameter parameters;
|
||||
private List<SwaggerParameter> parameters;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import lombok.Data;
|
|||
public class KeyValue {
|
||||
private String name;
|
||||
private String value;
|
||||
private String description;
|
||||
|
||||
public KeyValue() {
|
||||
}
|
||||
|
@ -14,4 +15,10 @@ public class KeyValue {
|
|||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public KeyValue(String name, String value, String description) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.description = description;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,30 @@
|
|||
package io.metersphere.api.parse;
|
||||
|
||||
import io.metersphere.api.dto.scenario.KeyValue;
|
||||
import io.metersphere.api.dto.scenario.Request;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public abstract class ApiImportAbstractParser implements ApiImportParser {
|
||||
|
||||
protected String getApiTestStr(InputStream source) {
|
||||
BufferedReader bufferedReader = null;
|
||||
BufferedReader bufferedReader;
|
||||
StringBuilder testStr = null;
|
||||
try {
|
||||
bufferedReader = new BufferedReader(new InputStreamReader(source, "UTF-8"));
|
||||
bufferedReader = new BufferedReader(new InputStreamReader(source, StandardCharsets.UTF_8));
|
||||
testStr = new StringBuilder();
|
||||
String inputStr = null;
|
||||
String inputStr;
|
||||
while ((inputStr = bufferedReader.readLine()) != null) {
|
||||
testStr.append(inputStr);
|
||||
}
|
||||
|
@ -34,4 +42,36 @@ public abstract class ApiImportAbstractParser implements ApiImportParser {
|
|||
return testStr.toString();
|
||||
}
|
||||
|
||||
protected void addContentType(Request request, String contentType) {
|
||||
addHeader(request, HttpHeader.CONTENT_TYPE.toString(), contentType);
|
||||
}
|
||||
|
||||
protected void addCookie(Request request, String key, String value) {
|
||||
List<KeyValue> headers = Optional.ofNullable(request.getHeaders()).orElse(new ArrayList<>());
|
||||
boolean hasCookie = false;
|
||||
for (KeyValue header : headers) {
|
||||
if (StringUtils.equalsIgnoreCase(HttpHeader.COOKIE.name(), header.getName())) {
|
||||
hasCookie = true;
|
||||
String cookies = Optional.ofNullable(header.getValue()).orElse("");
|
||||
header.setValue(cookies + key + "=" + value + ";");
|
||||
}
|
||||
}
|
||||
if (!hasCookie) {
|
||||
addHeader(request, HttpHeader.COOKIE.name(), key + "=" + value + ";");
|
||||
}
|
||||
}
|
||||
|
||||
protected void addHeader(Request request, String key, String value) {
|
||||
List<KeyValue> headers = Optional.ofNullable(request.getHeaders()).orElse(new ArrayList<>());
|
||||
boolean hasContentType = false;
|
||||
for (KeyValue header : headers) {
|
||||
if (StringUtils.equalsIgnoreCase(header.getName(), key)) {
|
||||
hasContentType = true;
|
||||
}
|
||||
}
|
||||
if (!hasContentType) {
|
||||
headers.add(new KeyValue(key, value));
|
||||
}
|
||||
request.setHeaders(headers);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ public class ApiImportParserFactory {
|
|||
return new MsParser();
|
||||
} else if (StringUtils.equals(ApiImportPlatform.Postman.name(), platform)) {
|
||||
return new PostmanParser();
|
||||
} else if (StringUtils.equals(ApiImportPlatform.Swagger2.name(), platform)) {
|
||||
return new Swagger2Parser();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -2,17 +2,15 @@ package io.metersphere.api.parse;
|
|||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.metersphere.api.dto.parse.ApiImport;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class MsParser extends ApiImportAbstractParser {
|
||||
|
||||
@Override
|
||||
public ApiImport parse(InputStream source) {
|
||||
String testStr = getApiTestStr(source);
|
||||
return JSON.parseObject(testStr.toString(), ApiImport.class);
|
||||
return JSON.parseObject(testStr, ApiImport.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package io.metersphere.api.parse;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.api.dto.parse.ApiImport;
|
||||
import io.metersphere.api.dto.parse.postman.*;
|
||||
|
@ -11,14 +10,9 @@ import io.metersphere.api.dto.scenario.Request;
|
|||
import io.metersphere.api.dto.scenario.Scenario;
|
||||
import io.metersphere.commons.constants.MsRequestBodyType;
|
||||
import io.metersphere.commons.constants.PostmanRequestBodyMode;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -27,7 +21,7 @@ public class PostmanParser extends ApiImportAbstractParser {
|
|||
@Override
|
||||
public ApiImport parse(InputStream source) {
|
||||
String testStr = getApiTestStr(source);
|
||||
PostmanCollection postmanCollection = JSON.parseObject(testStr.toString(), PostmanCollection.class);
|
||||
PostmanCollection postmanCollection = JSON.parseObject(testStr, PostmanCollection.class);
|
||||
PostmanCollectionInfo info = postmanCollection.getInfo();
|
||||
List<Request> requests = parseRequests(postmanCollection);
|
||||
ApiImport apiImport = new ApiImport();
|
||||
|
@ -45,9 +39,7 @@ public class PostmanParser extends ApiImportAbstractParser {
|
|||
return null;
|
||||
}
|
||||
List<KeyValue> keyValues = new ArrayList<>();
|
||||
postmanKeyValues.forEach(item -> {
|
||||
keyValues.add(new KeyValue(item.getKey(), item.getValue()));
|
||||
});
|
||||
postmanKeyValues.forEach(item -> keyValues.add(new KeyValue(item.getKey(), item.getValue())));
|
||||
return keyValues;
|
||||
}
|
||||
|
||||
|
@ -64,32 +56,27 @@ public class PostmanParser extends ApiImportAbstractParser {
|
|||
request.setMethod(requestDesc.getMethod());
|
||||
request.setHeaders(parseKeyValue(requestDesc.getHeader()));
|
||||
request.setParameters(parseKeyValue(url.getQuery()));
|
||||
Body body = new Body();
|
||||
JSONObject postmanBody = requestDesc.getBody();
|
||||
String bodyMode = postmanBody.getString("mode");
|
||||
if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.RAW.value())) {
|
||||
body.setRaw(postmanBody.getString(bodyMode));
|
||||
body.setType(MsRequestBodyType.RAW.value());
|
||||
String contentType = postmanBody.getJSONObject("options").getJSONObject("raw").getString("language");
|
||||
List<KeyValue> headers = request.getHeaders();
|
||||
boolean hasContentType = false;
|
||||
for (KeyValue header : headers) {
|
||||
if (StringUtils.equalsIgnoreCase(header.getName(), "Content-Type")) {
|
||||
hasContentType = true;
|
||||
}
|
||||
}
|
||||
if (!hasContentType) {
|
||||
headers.add(new KeyValue("Content-Type", contentType));
|
||||
}
|
||||
} else if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.FORM_DATA.value()) || StringUtils.equals(bodyMode, PostmanRequestBodyMode.URLENCODED.value())) {
|
||||
List<PostmanKeyValue> postmanKeyValues = JSON.parseArray(postmanBody.getString(bodyMode), PostmanKeyValue.class);
|
||||
body.setType(MsRequestBodyType.KV.value());
|
||||
body.setKvs(parseKeyValue(postmanKeyValues));
|
||||
}
|
||||
request.setBody(body);
|
||||
request.setBody(parseBody(requestDesc, request));
|
||||
requests.add(request);
|
||||
}
|
||||
return requests;
|
||||
}
|
||||
|
||||
private Body parseBody(PostmanRequest requestDesc, Request request) {
|
||||
Body body = new Body();
|
||||
JSONObject postmanBody = requestDesc.getBody();
|
||||
String bodyMode = postmanBody.getString("mode");
|
||||
if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.RAW.value())) {
|
||||
body.setRaw(postmanBody.getString(bodyMode));
|
||||
body.setType(MsRequestBodyType.RAW.value());
|
||||
String contentType = postmanBody.getJSONObject("options").getJSONObject("raw").getString("language");
|
||||
addContentType(request, contentType);
|
||||
} else if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.FORM_DATA.value()) || StringUtils.equals(bodyMode, PostmanRequestBodyMode.URLENCODED.value())) {
|
||||
List<PostmanKeyValue> postmanKeyValues = JSON.parseArray(postmanBody.getString(bodyMode), PostmanKeyValue.class);
|
||||
body.setType(MsRequestBodyType.KV.value());
|
||||
body.setKvs(parseKeyValue(postmanKeyValues));
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,185 @@
|
|||
package io.metersphere.api.parse;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.api.dto.parse.ApiImport;
|
||||
import io.metersphere.api.dto.scenario.Body;
|
||||
import io.metersphere.api.dto.scenario.KeyValue;
|
||||
import io.metersphere.api.dto.scenario.Request;
|
||||
import io.metersphere.api.dto.scenario.Scenario;
|
||||
import io.metersphere.commons.constants.MsRequestBodyType;
|
||||
import io.metersphere.commons.constants.SwaggerParameterType;
|
||||
import io.swagger.models.*;
|
||||
import io.swagger.models.parameters.*;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.ObjectProperty;
|
||||
import io.swagger.models.properties.Property;
|
||||
import io.swagger.models.properties.RefProperty;
|
||||
import io.swagger.parser.SwaggerParser;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
|
||||
public class Swagger2Parser extends ApiImportAbstractParser {
|
||||
|
||||
@Override
|
||||
public ApiImport parse(InputStream source) {
|
||||
String testStr = getApiTestStr(source);
|
||||
// Swagger swagger = new SwaggerParser().read("http://petstore.swagger.io/v2/swagger.json");
|
||||
Swagger swagger = new SwaggerParser().readWithInfo(testStr).getSwagger();
|
||||
ApiImport apiImport = new ApiImport();
|
||||
apiImport.setScenarios(parseRequests(swagger));
|
||||
return apiImport;
|
||||
}
|
||||
|
||||
private List<Scenario> parseRequests(Swagger swagger) {
|
||||
Map<String, Path> paths = swagger.getPaths();
|
||||
Set<String> pathNames = paths.keySet();
|
||||
Map<String, Scenario> scenarioMap = new HashMap<>();
|
||||
List<Scenario> scenarios = new ArrayList<>();
|
||||
for (String pathName : pathNames) {
|
||||
Path path = paths.get(pathName);
|
||||
Map<HttpMethod, Operation> operationMap = path.getOperationMap();
|
||||
Set<HttpMethod> httpMethods = operationMap.keySet();
|
||||
for (HttpMethod method : httpMethods) {
|
||||
Operation operation = operationMap.get(method);
|
||||
Request request = new Request();
|
||||
request.setName(operation.getOperationId());
|
||||
request.setPath(pathName);
|
||||
request.setUseEnvironment(true);
|
||||
request.setMethod(method.name());
|
||||
parseParameters(operation, swagger.getDefinitions(), request);
|
||||
List<String> tags = operation.getTags();
|
||||
if (tags != null) {
|
||||
tags.forEach(tag -> {
|
||||
Scenario scenario = Optional.ofNullable(scenarioMap.get(tag)).orElse(new Scenario());
|
||||
List<Request> requests = Optional.ofNullable(scenario.getRequests()).orElse(new ArrayList<>());
|
||||
requests.add(request);
|
||||
scenario.setRequests(requests);scenario.setName(tag);
|
||||
scenarioMap.put(tag, scenario);
|
||||
});
|
||||
} else {
|
||||
Scenario scenario = Optional.ofNullable(scenarioMap.get("default")).orElse(new Scenario());
|
||||
List<Request> requests = Optional.ofNullable(scenario.getRequests()).orElse(new ArrayList<>());
|
||||
requests.add(request);
|
||||
scenario.setRequests(requests);
|
||||
scenarioMap.put("default", scenario);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
scenarioMap.values().forEach(scenario -> {
|
||||
scenarios.add(scenario);
|
||||
});
|
||||
return scenarios;
|
||||
}
|
||||
|
||||
private void parseParameters(Operation operation, Map<String, Model> definitions, Request request) {
|
||||
|
||||
List<Parameter> parameters = operation.getParameters();
|
||||
|
||||
for (Parameter parameter : parameters) {
|
||||
switch (parameter.getIn()){
|
||||
// case SwaggerParameterType.PATH:
|
||||
// parsePathParameters(parameter, request);
|
||||
// break;
|
||||
case SwaggerParameterType.QUERY:
|
||||
parseQueryParameters(parameter, request);
|
||||
break;
|
||||
case SwaggerParameterType.FORM_DATA:
|
||||
parseFormDataParameters(parameter, request);
|
||||
break;
|
||||
case SwaggerParameterType.BODY:
|
||||
parseBodyParameters(parameter, request, definitions);
|
||||
break;
|
||||
case SwaggerParameterType.HEADER:
|
||||
parseHeaderParameters(parameter, request);
|
||||
break;
|
||||
case SwaggerParameterType.COOKIE:
|
||||
parseCookieParameters(parameter, request);
|
||||
break;
|
||||
// case SwaggerParameterType.FILE:
|
||||
// parsePathParameters(parameter, request);
|
||||
// break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseCookieParameters(Parameter parameter, Request request) {
|
||||
CookieParameter cookieParameter = (CookieParameter) parameter;
|
||||
addCookie(request, cookieParameter.getName(), cookieParameter.getDescription());
|
||||
}
|
||||
|
||||
private void parseHeaderParameters(Parameter parameter, Request request) {
|
||||
HeaderParameter headerParameter = (HeaderParameter) parameter;
|
||||
addHeader(request, headerParameter.getName(), headerParameter.getDescription());
|
||||
}
|
||||
|
||||
private void parseBodyParameters(Parameter parameter, Request request, Map<String, Model> definitions) {
|
||||
BodyParameter bodyParameter = (BodyParameter) parameter;
|
||||
Body body = Optional.ofNullable(request.getBody()).orElse(new Body());
|
||||
body.setType(MsRequestBodyType.RAW.value());
|
||||
Model schema = bodyParameter.getSchema();
|
||||
|
||||
if (schema instanceof RefModel) {
|
||||
RefModel refModel = (RefModel) bodyParameter.getSchema();
|
||||
Model model = definitions.get(refModel.getSimpleRef());
|
||||
JSONObject bodyParameters = getBodyJSONObjectParameters(model.getProperties(), definitions);
|
||||
body.setRaw(bodyParameters.toJSONString());
|
||||
} else if (schema instanceof ArrayModel) {
|
||||
ArrayModel arrayModel = (ArrayModel) bodyParameter.getSchema();
|
||||
Property items = arrayModel.getItems();
|
||||
if (items instanceof RefProperty) {
|
||||
RefProperty refProperty = (RefProperty) items;
|
||||
Model model = definitions.get(refProperty.getSimpleRef());
|
||||
JSONArray propertyList = new JSONArray();
|
||||
propertyList.add(getBodyJSONObjectParameters(model.getProperties(), definitions));
|
||||
body.setRaw(propertyList.toString());
|
||||
}
|
||||
}
|
||||
request.setBody(body);
|
||||
addContentType(request, "application/json");
|
||||
|
||||
}
|
||||
|
||||
private JSONObject getBodyJSONObjectParameters(Map<String, Property> properties, Map<String, Model> definitions) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
properties.forEach((key, value) -> {
|
||||
if (value instanceof ObjectProperty) {
|
||||
ObjectProperty objectProperty = (ObjectProperty) value;
|
||||
jsonObject.put(key, getBodyJSONObjectParameters(objectProperty.getProperties(), definitions));
|
||||
} else if (value instanceof ArrayProperty) {
|
||||
ArrayProperty arrayProperty = (ArrayProperty) value;
|
||||
Property items = arrayProperty.getItems();
|
||||
if (items instanceof RefProperty) {
|
||||
RefProperty refProperty = (RefProperty) items;
|
||||
Model model = definitions.get(refProperty.getSimpleRef());
|
||||
JSONArray propertyList = new JSONArray();
|
||||
propertyList.add(getBodyJSONObjectParameters(model.getProperties(), definitions));
|
||||
jsonObject.put(key, propertyList);
|
||||
} else {
|
||||
jsonObject.put(key, new ArrayList<>());
|
||||
}
|
||||
} else {
|
||||
jsonObject.put(key, Optional.ofNullable(value.getDescription()).orElse(""));
|
||||
}
|
||||
});
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
private void parseFormDataParameters(Parameter parameter, Request request) {
|
||||
Body body = Optional.ofNullable(request.getBody()).orElse(new Body());
|
||||
body.setType(MsRequestBodyType.FORM_DATA.value());
|
||||
List<KeyValue> keyValues = Optional.ofNullable(body.getKvs()).orElse(new ArrayList<>());
|
||||
keyValues.add(new KeyValue(parameter.getName(), "", parameter.getDescription()));
|
||||
body.setKvs(keyValues);
|
||||
request.setBody(body);
|
||||
}
|
||||
|
||||
private void parseQueryParameters(Parameter parameter, Request request) {
|
||||
QueryParameter queryParameter = (QueryParameter) parameter;
|
||||
List<KeyValue> parameters = Optional.ofNullable(request.getParameters()).orElse(new ArrayList<>());
|
||||
parameters.add(new KeyValue(queryParameter.getName(), "", queryParameter.getDescription()));
|
||||
request.setParameters(parameters);
|
||||
}
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
package io.metersphere.api.parse;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.api.dto.parse.ApiImport;
|
||||
import io.metersphere.api.dto.parse.postman.PostmanItem;
|
||||
import io.metersphere.api.dto.parse.postman.PostmanRequest;
|
||||
import io.metersphere.api.dto.parse.postman.PostmanUrl;
|
||||
import io.metersphere.api.dto.parse.swagger.SwaggerApi;
|
||||
import io.metersphere.api.dto.parse.swagger.SwaggerInfo;
|
||||
import io.metersphere.api.dto.parse.swagger.SwaggerRequest;
|
||||
import io.metersphere.api.dto.scenario.Request;
|
||||
import io.metersphere.api.dto.scenario.Scenario;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class SwaggerParser extends ApiImportAbstractParser {
|
||||
|
||||
@Override
|
||||
public ApiImport parse(InputStream source) {
|
||||
String testStr = getApiTestStr(source);
|
||||
|
||||
SwaggerApi swaggerApi = JSON.parseObject(testStr.toString(), SwaggerApi.class);
|
||||
|
||||
SwaggerInfo info = swaggerApi.getInfo();
|
||||
|
||||
String title = info.getTitle();
|
||||
|
||||
|
||||
// List<Request> requests = parseRequests(swaggerApi);
|
||||
// ApiImport apiImport = new ApiImport();
|
||||
// List<Scenario> scenarios = new ArrayList<>();
|
||||
// Scenario scenario = new Scenario();
|
||||
// scenario.setRequests(requests);
|
||||
// scenario.setName(info.getName());
|
||||
// scenarios.add(scenario);
|
||||
// apiImport.setScenarios(scenarios);
|
||||
// return apiImport;
|
||||
return null;
|
||||
}
|
||||
|
||||
// private List<Request> parseRequests(SwaggerApi swaggerApi) {
|
||||
// JSONObject paths = swaggerApi.getPaths();
|
||||
//
|
||||
// Set<String> pathNames = paths.keySet();
|
||||
//
|
||||
// for (String path : pathNames) {
|
||||
// JSONObject pathObject = paths.getJSONObject(path);
|
||||
// Set<String> methods = pathObject.keySet();
|
||||
// for (String method : methods) {
|
||||
// SwaggerRequest swaggerRequest = JSON.parseObject(pathObject.getJSONObject(method).toJSONString(), SwaggerRequest.class);
|
||||
// Request request = new Request();
|
||||
// request.setName(swaggerRequest.getOperationId());
|
||||
// request.setUrl(url.getRaw());
|
||||
// request.setPath(.getRaw());
|
||||
// request.setUseEnvironment(false);
|
||||
// request.setMethod(requestDesc.getMethod());
|
||||
// request.setHeaders(parseKeyValue(requestDesc.getHeader()));
|
||||
// request.setParameters(parseKeyValue(url.getQuery()));
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// List<PostmanItem> item = postmanCollection.getItem();
|
||||
// List<Request> requests = new ArrayList<>();
|
||||
// for (PostmanItem requestItem : item) {
|
||||
// Request request = new Request();
|
||||
// PostmanRequest requestDesc = requestItem.getRequest();
|
||||
// PostmanUrl url = requestDesc.getUrl();
|
||||
// request.setName(requestItem.getName());
|
||||
// request.setUrl(url.getRaw());
|
||||
// request.setUseEnvironment(false);
|
||||
// request.setMethod(requestDesc.getMethod());
|
||||
// request.setHeaders(parseKeyValue(requestDesc.getHeader()));
|
||||
// request.setParameters(parseKeyValue(url.getQuery()));
|
||||
// Body body = new Body();
|
||||
// JSONObject postmanBody = requestDesc.getBody();
|
||||
// String bodyMode = postmanBody.getString("mode");
|
||||
// if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.RAW.value())) {
|
||||
// body.setRaw(postmanBody.getString(bodyMode));
|
||||
// body.setType(MsRequestBodyType.RAW.value());
|
||||
// String contentType = postmanBody.getJSONObject("options").getJSONObject("raw").getString("language");
|
||||
// List<KeyValue> headers = request.getHeaders();
|
||||
// boolean hasContentType = false;
|
||||
// for (KeyValue header : headers) {
|
||||
// if (StringUtils.equalsIgnoreCase(header.getName(), "Content-Type")) {
|
||||
// hasContentType = true;
|
||||
// }
|
||||
// }
|
||||
// if (!hasContentType) {
|
||||
// headers.add(new KeyValue("Content-Type", contentType));
|
||||
// }
|
||||
// } else if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.FORM_DATA.value()) || StringUtils.equals(bodyMode, PostmanRequestBodyMode.URLENCODED.value())) {
|
||||
// List<PostmanKeyValue> postmanKeyValues = JSON.parseArray(postmanBody.getString(bodyMode), PostmanKeyValue.class);
|
||||
// body.setType(MsRequestBodyType.KV.value());
|
||||
// body.setKvs(parseKeyValue(postmanKeyValues));
|
||||
// }
|
||||
// request.setBody(body);
|
||||
// requests.add(request);
|
||||
// }
|
||||
// return requests;
|
||||
// }
|
||||
}
|
|
@ -33,5 +33,7 @@ public class TestCase implements Serializable {
|
|||
|
||||
private Integer sort;
|
||||
|
||||
private Integer num;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
|
@ -1053,6 +1053,66 @@ public class TestCaseExample {
|
|||
addCriterion("sort not between", value1, value2, "sort");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNumIsNull() {
|
||||
addCriterion("num is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNumIsNotNull() {
|
||||
addCriterion("num is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNumEqualTo(Integer value) {
|
||||
addCriterion("num =", value, "num");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNumNotEqualTo(Integer value) {
|
||||
addCriterion("num <>", value, "num");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNumGreaterThan(Integer value) {
|
||||
addCriterion("num >", value, "num");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNumGreaterThanOrEqualTo(Integer value) {
|
||||
addCriterion("num >=", value, "num");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNumLessThan(Integer value) {
|
||||
addCriterion("num <", value, "num");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNumLessThanOrEqualTo(Integer value) {
|
||||
addCriterion("num <=", value, "num");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNumIn(List<Integer> values) {
|
||||
addCriterion("num in", values, "num");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNumNotIn(List<Integer> values) {
|
||||
addCriterion("num not in", values, "num");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNumBetween(Integer value1, Integer value2) {
|
||||
addCriterion("num between", value1, value2, "num");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andNumNotBetween(Integer value1, Integer value2) {
|
||||
addCriterion("num not between", value1, value2, "num");
|
||||
return (Criteria) this;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Criteria extends GeneratedCriteria {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
|
||||
<result column="test_id" jdbcType="VARCHAR" property="testId" />
|
||||
<result column="sort" jdbcType="INTEGER" property="sort" />
|
||||
<result column="num" jdbcType="INTEGER" property="num" />
|
||||
</resultMap>
|
||||
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.TestCaseWithBLOBs">
|
||||
<result column="remark" jdbcType="LONGVARCHAR" property="remark" />
|
||||
|
@ -81,7 +82,7 @@
|
|||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
id, node_id, node_path, project_id, `name`, `type`, maintainer, priority, `method`,
|
||||
prerequisite, create_time, update_time, test_id, sort
|
||||
prerequisite, create_time, update_time, test_id, sort, num
|
||||
</sql>
|
||||
<sql id="Blob_Column_List">
|
||||
remark, steps
|
||||
|
@ -139,14 +140,14 @@
|
|||
project_id, `name`, `type`,
|
||||
maintainer, priority, `method`,
|
||||
prerequisite, create_time, update_time,
|
||||
test_id, sort, remark,
|
||||
steps)
|
||||
test_id, sort, num,
|
||||
remark, steps)
|
||||
values (#{id,jdbcType=VARCHAR}, #{nodeId,jdbcType=VARCHAR}, #{nodePath,jdbcType=VARCHAR},
|
||||
#{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR},
|
||||
#{maintainer,jdbcType=VARCHAR}, #{priority,jdbcType=VARCHAR}, #{method,jdbcType=VARCHAR},
|
||||
#{prerequisite,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
|
||||
#{testId,jdbcType=VARCHAR}, #{sort,jdbcType=INTEGER}, #{remark,jdbcType=LONGVARCHAR},
|
||||
#{steps,jdbcType=LONGVARCHAR})
|
||||
#{testId,jdbcType=VARCHAR}, #{sort,jdbcType=INTEGER}, #{num,jdbcType=INTEGER},
|
||||
#{remark,jdbcType=LONGVARCHAR}, #{steps,jdbcType=LONGVARCHAR})
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestCaseWithBLOBs">
|
||||
insert into test_case
|
||||
|
@ -193,6 +194,9 @@
|
|||
<if test="sort != null">
|
||||
sort,
|
||||
</if>
|
||||
<if test="num != null">
|
||||
num,
|
||||
</if>
|
||||
<if test="remark != null">
|
||||
remark,
|
||||
</if>
|
||||
|
@ -243,6 +247,9 @@
|
|||
<if test="sort != null">
|
||||
#{sort,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="num != null">
|
||||
#{num,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="remark != null">
|
||||
#{remark,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
|
@ -302,6 +309,9 @@
|
|||
<if test="record.sort != null">
|
||||
sort = #{record.sort,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="record.num != null">
|
||||
num = #{record.num,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="record.remark != null">
|
||||
remark = #{record.remark,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
|
@ -329,6 +339,7 @@
|
|||
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||
test_id = #{record.testId,jdbcType=VARCHAR},
|
||||
sort = #{record.sort,jdbcType=INTEGER},
|
||||
num = #{record.num,jdbcType=INTEGER},
|
||||
remark = #{record.remark,jdbcType=LONGVARCHAR},
|
||||
steps = #{record.steps,jdbcType=LONGVARCHAR}
|
||||
<if test="_parameter != null">
|
||||
|
@ -350,7 +361,8 @@
|
|||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||
test_id = #{record.testId,jdbcType=VARCHAR},
|
||||
sort = #{record.sort,jdbcType=INTEGER}
|
||||
sort = #{record.sort,jdbcType=INTEGER},
|
||||
num = #{record.num,jdbcType=INTEGER}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
|
@ -397,6 +409,9 @@
|
|||
<if test="sort != null">
|
||||
sort = #{sort,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="num != null">
|
||||
num = #{num,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="remark != null">
|
||||
remark = #{remark,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
|
@ -421,6 +436,7 @@
|
|||
update_time = #{updateTime,jdbcType=BIGINT},
|
||||
test_id = #{testId,jdbcType=VARCHAR},
|
||||
sort = #{sort,jdbcType=INTEGER},
|
||||
num = #{num,jdbcType=INTEGER},
|
||||
remark = #{remark,jdbcType=LONGVARCHAR},
|
||||
steps = #{steps,jdbcType=LONGVARCHAR}
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
|
@ -439,7 +455,8 @@
|
|||
create_time = #{createTime,jdbcType=BIGINT},
|
||||
update_time = #{updateTime,jdbcType=BIGINT},
|
||||
test_id = #{testId,jdbcType=VARCHAR},
|
||||
sort = #{sort,jdbcType=INTEGER}
|
||||
sort = #{sort,jdbcType=INTEGER},
|
||||
num = #{num,jdbcType=INTEGER}
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
</mapper>
|
|
@ -17,4 +17,6 @@ public interface ExtTestCaseMapper {
|
|||
|
||||
List<TestCaseDTO> listBytestCaseIds(@Param("request") QueryTestCaseRequest request);
|
||||
|
||||
TestCase getMaxNumByProjectId(@Param("projectId") String projectId);
|
||||
|
||||
}
|
||||
|
|
|
@ -188,7 +188,8 @@
|
|||
</where>
|
||||
</select>
|
||||
<select id="listBytestCaseIds" resultType="io.metersphere.track.dto.TestCaseDTO">
|
||||
select test_case.*,api_test.name as apiName,load_test.name AS performName from test_case left join api_test on test_case.test_id=api_test.id left join load_test on test_case.test_id=load_test.id
|
||||
select test_case.*,api_test.name as apiName,load_test.name AS performName from test_case left join api_test on
|
||||
test_case.test_id=api_test.id left join load_test on test_case.test_id=load_test.id
|
||||
<where>
|
||||
<if test="request.testCaseIds!=null and request.testCaseIds.size() > 0">
|
||||
and test_case.id in
|
||||
|
@ -198,4 +199,8 @@
|
|||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="getMaxNumByProjectId" resultType="io.metersphere.base.domain.TestCase">
|
||||
select * from test_case where test_case.project_id = #{projectId} order by num desc limit 1;
|
||||
</select>
|
||||
</mapper>
|
|
@ -1,5 +1,5 @@
|
|||
package io.metersphere.commons.constants;
|
||||
|
||||
public enum ApiImportPlatform {
|
||||
Metersphere, Postman
|
||||
Metersphere, Postman, Swagger2
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package io.metersphere.commons.constants;
|
||||
|
||||
public class SwaggerParameterType {
|
||||
|
||||
public static final String PATH = "path";
|
||||
public static final String FORM_DATA = "formData";
|
||||
public static final String FILE = "file";
|
||||
public static final String HEADER = "header";
|
||||
public static final String BODY = "body";
|
||||
public static final String COOKIE = "cookie";
|
||||
public static final String QUERY = "query";
|
||||
}
|
|
@ -2,11 +2,13 @@ package io.metersphere.track.request.testcase;
|
|||
|
||||
import io.metersphere.base.domain.TestCaseNode;
|
||||
import io.metersphere.track.dto.TestCaseNodeDTO;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Getter
|
||||
@Setter
|
||||
public class DragNodeRequest extends TestCaseNode {
|
||||
|
||||
List<String> nodeIds;
|
||||
|
|
|
@ -84,6 +84,7 @@ public class TestCaseService {
|
|||
testCase.setId(UUID.randomUUID().toString());
|
||||
testCase.setCreateTime(System.currentTimeMillis());
|
||||
testCase.setUpdateTime(System.currentTimeMillis());
|
||||
testCase.setNum(getNextNum(testCase.getProjectId()));
|
||||
testCaseMapper.insert(testCase);
|
||||
}
|
||||
|
||||
|
@ -253,9 +254,12 @@ public class TestCaseService {
|
|||
TestCaseMapper mapper = sqlSession.getMapper(TestCaseMapper.class);
|
||||
if (!testCases.isEmpty()) {
|
||||
AtomicInteger sort = new AtomicInteger();
|
||||
AtomicInteger num = new AtomicInteger();
|
||||
num.set(getNextNum(projectId)+testCases.size());
|
||||
testCases.forEach(testcase -> {
|
||||
testcase.setNodeId(nodePathMap.get(testcase.getNodePath()));
|
||||
testcase.setSort(sort.getAndIncrement());
|
||||
testcase.setNum(num.decrementAndGet());
|
||||
mapper.insert(testcase);
|
||||
});
|
||||
}
|
||||
|
@ -429,4 +433,17 @@ public class TestCaseService {
|
|||
MSException.throwException(Translator.get("related_case_del_fail_prefix") + " " + str + " " + Translator.get("related_case_del_fail_suffix"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目下一个num (页面展示的ID)
|
||||
* @return
|
||||
*/
|
||||
private int getNextNum(String projectId) {
|
||||
TestCase testCase = extTestCaseMapper.getMaxNumByProjectId(projectId);
|
||||
if (testCase == null) {
|
||||
return 100001;
|
||||
} else {
|
||||
return Optional.ofNullable(testCase.getNum()+1).orElse(100001);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
alter table test_case add num int null comment 'Manually controlled growth identifier';
|
||||
|
||||
DROP PROCEDURE IF EXISTS test_cursor;
|
||||
DELIMITER //
|
||||
CREATE PROCEDURE test_cursor()
|
||||
BEGIN
|
||||
DECLARE projectId VARCHAR(64);
|
||||
DECLARE caseId VARCHAR(64);
|
||||
DECLARE num INT;
|
||||
DECLARE done INT DEFAULT 0;
|
||||
DECLARE cursor1 CURSOR FOR (SELECT DISTINCT project_id
|
||||
FROM test_case
|
||||
WHERE num IS NULL);
|
||||
DECLARE cursor2 CURSOR FOR (SELECT id
|
||||
FROM test_case
|
||||
WHERE project_id = projectId
|
||||
ORDER BY create_time);
|
||||
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
|
||||
OPEN cursor1;
|
||||
outer_loop:
|
||||
LOOP
|
||||
FETCH cursor1 INTO projectId;
|
||||
IF done
|
||||
THEN
|
||||
LEAVE outer_loop;
|
||||
END IF;
|
||||
SET num = 100001;
|
||||
OPEN cursor2;
|
||||
inner_loop:
|
||||
LOOP
|
||||
FETCH cursor2 INTO caseId;
|
||||
IF done
|
||||
THEN
|
||||
LEAVE inner_loop;
|
||||
END IF;
|
||||
UPDATE test_case
|
||||
SET num = num
|
||||
WHERE id = caseId;
|
||||
SET num = num + 1;
|
||||
END LOOP;
|
||||
SET done = 0;
|
||||
CLOSE cursor2;
|
||||
END LOOP;
|
||||
CLOSE cursor1;
|
||||
END //
|
||||
DELIMITER ;
|
||||
|
||||
CALL test_cursor();
|
||||
DROP PROCEDURE IF EXISTS test_cursor;
|
|
@ -39,8 +39,8 @@
|
|||
<!-- jdbc连接信息 --> <!-- EduLoanManage EduTestDataBase -->
|
||||
<!--<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://192.168.20.180:3306/fit2cloud"-->
|
||||
<!--userId="root" password="Fit2cloud2015!" />-->
|
||||
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
|
||||
connectionURL="${spring.datasource.url}"
|
||||
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
|
||||
connectionURL="${spring.datasource.url}&nullCatalogMeansCurrent=true"
|
||||
userId="${spring.datasource.username}" password="${spring.datasource.password}"/>
|
||||
|
||||
<!-- javaTypeResolver式类型转换的信息 -->
|
||||
|
@ -64,7 +64,7 @@
|
|||
|
||||
<!--要生成的数据库表 -->
|
||||
|
||||
<table tableName="load_test"/>
|
||||
<table tableName="test_case"/>
|
||||
|
||||
|
||||
</context>
|
||||
|
|
1159
backend/tree.txt
1159
backend/tree.txt
File diff suppressed because one or more lines are too long
|
@ -255,7 +255,7 @@
|
|||
return this.test.isValid() && !this.change;
|
||||
},
|
||||
isDisabled() {
|
||||
return !(this.test.isValid() && this.change)
|
||||
return !(this.test.isValid())
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -90,14 +90,14 @@
|
|||
activeName: "parameters",
|
||||
rules: {
|
||||
name: [
|
||||
{max: 100, message: this.$t('commons.input_limit', [0, 100]), trigger: 'blur'}
|
||||
{max: 100, message: this.$t('commons.input_limit', [1, 100]), trigger: 'blur'}
|
||||
],
|
||||
url: [
|
||||
{max: 500, required: true, message: this.$t('commons.input_limit', [0, 500]), trigger: 'blur'},
|
||||
{max: 500, required: true, message: this.$t('commons.input_limit', [1, 500]), trigger: 'blur'},
|
||||
{validator: validateURL, trigger: 'blur'}
|
||||
],
|
||||
path: [
|
||||
{max: 500, required: true, message: this.$t('commons.input_limit', [0, 500]), trigger: 'blur'},
|
||||
{max: 500, required: true, message: this.$t('commons.input_limit', [1, 500]), trigger: 'blur'},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -143,6 +143,7 @@
|
|||
this.$error(this.$t('api_test.request.please_add_environment_to_scenario'), 2000);
|
||||
this.request.useEnvironment = false;
|
||||
}
|
||||
this.$refs["request"].clearValidate();
|
||||
},
|
||||
addProtocol(url) {
|
||||
if (url) {
|
||||
|
|
|
@ -8,6 +8,11 @@
|
|||
<el-select :disabled="isReadOnly" v-model="scenario.environmentId" class="environment-select" @change="environmentChange" clearable>
|
||||
<el-option v-for="(environment, index) in environments" :key="index" :label="environment.name + ': ' + environment.protocol + '://' + environment.socket" :value="environment.id"/>
|
||||
<el-button class="environment-button" size="mini" type="primary" @click="openEnvironmentConfig">{{$t('api_test.environment.environment_config')}}</el-button>
|
||||
<template v-slot:empty>
|
||||
<div class="empty-environment">
|
||||
<el-button class="environment-button" size="mini" type="primary" @click="openEnvironmentConfig">{{$t('api_test.environment.environment_config')}}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
|
@ -65,18 +70,32 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
projectId() {
|
||||
this.getEnvironments();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getEnvironments() {
|
||||
if (this.projectId) {
|
||||
this.result = this.$get('/api/environment/list/' + this.projectId, response => {
|
||||
this.environments = response.data;
|
||||
let hasEnvironment = false;
|
||||
for (let i in this.environments) {
|
||||
if (this.environments[i].id === this.scenario.environmentId) {
|
||||
this.scenario.environment = this.environments[i];
|
||||
hasEnvironment = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasEnvironment) {
|
||||
this.scenario.environmentId = '';
|
||||
this.scenario.environment = undefined;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.scenario.environmentId = '';
|
||||
this.scenario.environment = undefined;
|
||||
}
|
||||
},
|
||||
environmentChange(value) {
|
||||
|
@ -97,6 +116,10 @@
|
|||
}
|
||||
},
|
||||
openEnvironmentConfig() {
|
||||
if (!this.projectId) {
|
||||
this.$error(this.$t('api_test.select_project'));
|
||||
return;
|
||||
}
|
||||
this.$refs.environmentConfig.open(this.projectId);
|
||||
},
|
||||
environmentConfigClose() {
|
||||
|
@ -117,4 +140,8 @@
|
|||
padding: 7px;
|
||||
}
|
||||
|
||||
.empty-environment {
|
||||
padding: 10px 0px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -61,7 +61,10 @@
|
|||
return {
|
||||
result: {},
|
||||
rules: {
|
||||
name :[{required: true, message: this.$t('commons.input_name'), trigger: 'blur'}],
|
||||
name :[
|
||||
{required: true, message: this.$t('commons.input_name'), trigger: 'blur'},
|
||||
{max: 64, message: this.$t('commons.input_limit', [1, 64]), trigger: 'blur'}
|
||||
],
|
||||
socket :[{required: true, validator: socketValidator, trigger: 'blur'}],
|
||||
},
|
||||
}
|
||||
|
@ -83,7 +86,9 @@
|
|||
url = '/api/environment/update';
|
||||
}
|
||||
this.result = this.$post(url, param, response => {
|
||||
this.environment.id = response.data;
|
||||
if (!param.id) {
|
||||
this.environment.id = response.data;
|
||||
}
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
});
|
||||
},
|
||||
|
|
|
@ -56,7 +56,14 @@
|
|||
name: 'Postman',
|
||||
value: 'Postman',
|
||||
tip: this.$t('api_test.api_import.postman_tip'),
|
||||
exportTip: this.$t('api_test.api_import.post_man_export_tip'),
|
||||
exportTip: this.$t('api_test.api_import.post_export_tip'),
|
||||
suffixes: new Set(['json'])
|
||||
},
|
||||
{
|
||||
name: 'Swagger',
|
||||
value: 'Swagger2',
|
||||
tip: this.$t('api_test.api_import.swagger_tip'),
|
||||
exportTip: this.$t('api_test.api_import.swagger_export_tip'),
|
||||
suffixes: new Set(['json'])
|
||||
}
|
||||
],
|
||||
|
|
|
@ -169,9 +169,6 @@ export class Scenario extends BaseConfig {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (!this.name) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -394,27 +391,37 @@ const JMX_ASSERTION_CONDITION = {
|
|||
|
||||
class JMXRequest {
|
||||
constructor(request) {
|
||||
if (request && request instanceof Request && request.url) {
|
||||
let url = new URL(request.url);
|
||||
this.method = request.method;
|
||||
this.hostname = decodeURIComponent(url.hostname);
|
||||
this.pathname = decodeURIComponent(url.pathname);
|
||||
this.path = decodeURIComponent(request.path);
|
||||
if (request && request instanceof Request && (request.url || request.path)) {
|
||||
this.useEnvironment = request.useEnvironment;
|
||||
this.environment = request.environment;
|
||||
this.port = url.port;
|
||||
this.protocol = url.protocol.split(":")[0];
|
||||
if (this.method.toUpperCase() !== "GET") {
|
||||
// this.pathname += url.search.replace('&', '&');
|
||||
this.pathname += '?';
|
||||
request.parameters.forEach(parameter => {
|
||||
if (parameter.name) {
|
||||
this.pathname += (parameter.name + '=' + parameter.value + '&');
|
||||
}
|
||||
});
|
||||
this.method = request.method;
|
||||
if (!request.useEnvironment) {
|
||||
let url = new URL(request.url);
|
||||
this.hostname = decodeURIComponent(url.hostname);
|
||||
this.pathname = decodeURIComponent(url.pathname);
|
||||
this.port = url.port;
|
||||
this.protocol = url.protocol.split(":")[0];
|
||||
this.pathname = this.getPostQueryParameters(request, this.pathname);
|
||||
} else {
|
||||
this.environment = request.environment;
|
||||
this.port = request.environment.port;
|
||||
this.path = decodeURIComponent(request.path);
|
||||
this.path = this.getPostQueryParameters(request, this.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getPostQueryParameters(request, path) {
|
||||
if (this.method.toUpperCase() !== "GET") {
|
||||
path += '?';
|
||||
request.parameters.forEach(parameter => {
|
||||
if (parameter.name) {
|
||||
path += (parameter.name + '=' + parameter.value + '&');
|
||||
}
|
||||
});
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class JMeterTestPlan extends Element {
|
||||
|
|
|
@ -4,11 +4,6 @@
|
|||
<el-dialog :title="$t('commons.adv_search.combine')" :visible.sync="visible" custom-class="adv-dialog"
|
||||
:append-to-body="true">
|
||||
<div>
|
||||
<!-- 如果有需求再加上-->
|
||||
<!-- <div class="search-label">{{$t('commons.adv_search.combine')}}: </div>-->
|
||||
<!-- <el-select v-model="logic" :placeholder="$t('commons.please_select')" size="small" class="search-combine">-->
|
||||
<!-- <el-option v-for="o in options" :key="o.value" :label="o.label" :value="o.value"/>-->
|
||||
<!-- </el-select>-->
|
||||
<div class="search-items">
|
||||
<component class="search-item" v-for="(component, index) in config.components" :key="index"
|
||||
:is="component.name" :component="component"/>
|
||||
|
@ -26,7 +21,7 @@
|
|||
|
||||
<script>
|
||||
import components from "./search-components";
|
||||
import _ from "lodash";
|
||||
import {cloneDeep} from "lodash";
|
||||
|
||||
export default {
|
||||
components: {...components},
|
||||
|
@ -37,20 +32,12 @@
|
|||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
config: this.init(),
|
||||
options: [{
|
||||
label: this.$t("commons.adv_search.and"),
|
||||
value: "and"
|
||||
}, {
|
||||
label: this.$t("commons.adv_search.or"),
|
||||
value: "or"
|
||||
}],
|
||||
logic: this.condition.logic || "and"
|
||||
config: this.init()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init() { // 设置默认值
|
||||
let config = _.cloneDeep(this.condition);
|
||||
init() {
|
||||
let config = cloneDeep(this.condition);
|
||||
config.components.forEach(component => {
|
||||
let operator = component.operator.value;
|
||||
component.operator.value = operator === undefined ? component.operator.options[0].value : operator;
|
||||
|
@ -58,21 +45,19 @@
|
|||
return config;
|
||||
},
|
||||
search() {
|
||||
let condition = {
|
||||
// logic: this.logic // 如果有需求再加上
|
||||
}
|
||||
let condition = {}
|
||||
this.config.components.forEach(component => {
|
||||
let operator = component.operator.value;
|
||||
let value = component.value;
|
||||
if (Array.isArray(component.value)) {
|
||||
if (component.value.length > 0) {
|
||||
if (Array.isArray(value)) {
|
||||
if (value.length > 0) {
|
||||
condition[component.key] = {
|
||||
operator: operator,
|
||||
value: value
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (component.value !== undefined && component.value !== null && component.value !== "") {
|
||||
if (value !== undefined && value !== null && value !== "") {
|
||||
condition[component.key] = {
|
||||
operator: operator,
|
||||
value: value
|
||||
|
@ -135,17 +120,6 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.search-label {
|
||||
display: inline-block;
|
||||
width: 80px;
|
||||
box-sizing: border-box;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.search-combine {
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
.search-items {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,12 @@
|
|||
class="test-content">
|
||||
<el-table-column
|
||||
type="selection"/>
|
||||
<el-table-column
|
||||
prop="num"
|
||||
sortable="custom"
|
||||
:label="$t('commons.id')"
|
||||
show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
:label="$t('commons.name')"
|
||||
|
@ -310,6 +316,10 @@
|
|||
this.initTableData();
|
||||
},
|
||||
sort(column) {
|
||||
// 每次只对一个字段排序
|
||||
if (this.condition.orders) {
|
||||
this.condition.orders = [];
|
||||
}
|
||||
_sort(column, this.condition);
|
||||
this.initTableData();
|
||||
}
|
||||
|
|
|
@ -33,7 +33,11 @@
|
|||
|
||||
<el-table-column
|
||||
type="selection"></el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="num"
|
||||
:label="$t('commons.id')"
|
||||
show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
:label="$t('commons.name')"
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
<el-table
|
||||
row-key="id"
|
||||
:data="failureTestCases">
|
||||
<el-table-column
|
||||
prop="num"
|
||||
:label="$t('commons.id')"
|
||||
show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
:label="$t('commons.name')"
|
||||
|
|
|
@ -103,6 +103,7 @@ export default {
|
|||
input_login_username: 'Please input the user ID or email',
|
||||
input_name: 'Please enter name',
|
||||
formatErr: 'Format Error',
|
||||
id: 'ID',
|
||||
date: {
|
||||
select_date: 'Select date',
|
||||
start_date: 'Start date',
|
||||
|
@ -411,8 +412,10 @@ export default {
|
|||
export_tip: "Export Tip",
|
||||
ms_tip: "Support for Metersphere JSON format",
|
||||
ms_export_tip: "Export jSON-formatted files via Metersphere website or browser plug-ins",
|
||||
swagger_tip: "Only Swagger2.x json files are supported",
|
||||
postman_tip: "Only Postman Collection V2.1 json files are supported",
|
||||
post_man_export_tip: "Export the test collection by Postman",
|
||||
postman_export_tip: "Export the test collection by Postman",
|
||||
swagger_export_tip: "Export jSON-formatted files via Swagger website",
|
||||
suffixFormatErr: "The file format does not meet the requirements",
|
||||
}
|
||||
},
|
||||
|
|
|
@ -103,6 +103,7 @@ export default {
|
|||
input_login_username: '请输入用户 ID 或 邮箱',
|
||||
input_name: '请输入名称',
|
||||
formatErr: '格式错误',
|
||||
id: 'ID',
|
||||
date: {
|
||||
select_date: '选择日期',
|
||||
start_date: '开始日期',
|
||||
|
@ -411,7 +412,9 @@ export default {
|
|||
ms_tip: "支持 Metersphere json 格式",
|
||||
ms_export_tip: "通过 Metersphere Api 测试页面或者浏览器插件导出 json 格式文件",
|
||||
postman_tip: "只支持 Postman Collection v2.1 格式的 json 文件",
|
||||
post_man_export_tip: "通过 Postman 导出测试集合",
|
||||
swagger_tip: "只支持 Swagger2.x 版本的 json 文件",
|
||||
post_export_tip: "通过 Postman 导出测试集合",
|
||||
swagger_export_tip: "通过 Swagger 页面导出",
|
||||
suffixFormatErr: "文件格式不符合要求",
|
||||
}
|
||||
},
|
||||
|
|
|
@ -101,6 +101,7 @@ export default {
|
|||
delete_confirm: '請輸入以下內容,確認刪除:',
|
||||
input_name: '請輸入名稱',
|
||||
formatErr: '格式錯誤',
|
||||
id: 'ID',
|
||||
date: {
|
||||
select_date: '選擇日期',
|
||||
start_date: '開始日期',
|
||||
|
@ -411,7 +412,9 @@ export default {
|
|||
ms_tip: "支持 Metersphere json 格式",
|
||||
ms_export_tip: "通過 Metersphere Api 測試頁面或者瀏覽器插件導出 json 格式文件",
|
||||
postman_tip: "只支持 Postman Collection v2.1 格式的 json 文件",
|
||||
post_man_export_tip: "通過 Postman 導出測試集合",
|
||||
swagger_tip: "只支持 Swagger2.x 版本的 json 文件",
|
||||
post_export_tip: "通過 Postman 導出測試集合",
|
||||
swagger_export_tip: "通過 Swagger 頁面導出",
|
||||
suffixFormatErr: "文件格式不符合要求",
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue