Merge remote-tracking branch 'origin/v1.7' into v1.7

This commit is contained in:
song.tianyang 2021-02-01 15:03:14 +08:00
commit 32f734a445
15 changed files with 138 additions and 37 deletions

View File

@ -272,10 +272,14 @@ public class MsHTTPSamplerProxy extends MsTestElement {
StringBuffer stringBuffer = new StringBuffer(); StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(path); stringBuffer.append(path);
stringBuffer.append("?"); stringBuffer.append("?");
this.getArguments().stream().filter(KeyValue::isEnable).filter(KeyValue::isValid).forEach(keyValue -> this.getArguments().stream().filter(KeyValue::isEnable).filter(KeyValue::isValid).forEach(keyValue -> {
stringBuffer.append(keyValue.getName()).append("=").append(keyValue.getValue() != null && keyValue.getValue().startsWith("@") ? stringBuffer.append(keyValue.getName());
ScriptEngineUtils.calculate(keyValue.getValue()) : keyValue.getValue()).append("&") if (keyValue.getValue() != null) {
); stringBuffer.append("=").append(keyValue.getValue().startsWith("@") ?
ScriptEngineUtils.calculate(keyValue.getValue()) : keyValue.getValue());
}
stringBuffer.append("&");
});
return stringBuffer.substring(0, stringBuffer.length() - 1); return stringBuffer.substring(0, stringBuffer.length() - 1);
} }

View File

@ -0,0 +1,8 @@
package io.metersphere.api.dto.parse.postman;
import lombok.Data;
@Data
public class PostmanEvent {
private String listen;
private PostmanScript script;
}

View File

@ -7,6 +7,7 @@ import java.util.List;
@Data @Data
public class PostmanItem { public class PostmanItem {
private String name; private String name;
private List<PostmanEvent> event;
private PostmanRequest request; private PostmanRequest request;
private List<PostmanItem> item; private List<PostmanItem> item;
} }

View File

@ -0,0 +1,11 @@
package io.metersphere.api.dto.parse.postman;
import lombok.Data;
import java.util.List;
@Data
public class PostmanScript {
private List<String> exec;
private String type;
}

View File

@ -57,7 +57,7 @@ public class KeyValue {
} }
public boolean isValid() { public boolean isValid() {
return ((StringUtils.isNotBlank(name) && StringUtils.isNotBlank(value)) || "JSON-SCHEMA".equals(type)) && !StringUtils.equalsIgnoreCase(type, "file"); return (StringUtils.isNotBlank(name) || "JSON-SCHEMA".equals(type)) && !StringUtils.equalsIgnoreCase(type, "file");
} }
public boolean isFile() { public boolean isFile() {

View File

@ -13,6 +13,7 @@ import io.metersphere.api.dto.scenario.KeyValue;
import io.metersphere.api.dto.scenario.request.RequestType; import io.metersphere.api.dto.scenario.request.RequestType;
import io.metersphere.api.service.ApiModuleService; import io.metersphere.api.service.ApiModuleService;
import io.metersphere.base.domain.ApiModule; import io.metersphere.base.domain.ApiModule;
import io.metersphere.commons.constants.ApiImportPlatform;
import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.LogUtil;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
@ -34,6 +35,7 @@ public class MsParser extends ApiImportAbstractParser {
if (testObject.get("projectName") != null) { if (testObject.get("projectName") != null) {
return parseMsFormat(testStr, request); return parseMsFormat(testStr, request);
} else { } else {
request.setPlatform(ApiImportPlatform.Plugin.name());
return parsePluginFormat(testObject, request); return parsePluginFormat(testObject, request);
} }
} }

View File

@ -5,6 +5,8 @@ import com.alibaba.fastjson.JSONObject;
import io.metersphere.api.dto.ApiTestImportRequest; import io.metersphere.api.dto.ApiTestImportRequest;
import io.metersphere.api.dto.definition.ApiDefinitionResult; import io.metersphere.api.dto.definition.ApiDefinitionResult;
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport; import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
import io.metersphere.api.dto.definition.request.MsTestElement;
import io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor;
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy; import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
import io.metersphere.api.dto.parse.postman.*; import io.metersphere.api.dto.parse.postman.*;
import io.metersphere.api.dto.scenario.Body; import io.metersphere.api.dto.scenario.Body;
@ -12,11 +14,14 @@ import io.metersphere.api.dto.scenario.KeyValue;
import io.metersphere.base.domain.ApiModule; import io.metersphere.base.domain.ApiModule;
import io.metersphere.commons.constants.MsRequestBodyType; import io.metersphere.commons.constants.MsRequestBodyType;
import io.metersphere.commons.constants.PostmanRequestBodyMode; import io.metersphere.commons.constants.PostmanRequestBodyMode;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
public class PostmanParser extends ApiImportAbstractParser { public class PostmanParser extends ApiImportAbstractParser {
@ -75,10 +80,37 @@ public class PostmanParser extends ApiImportAbstractParser {
request.setArguments(parseKeyValue(url.getQuery())); request.setArguments(parseKeyValue(url.getQuery()));
request.setHeaders(parseKeyValue(requestDesc.getHeader())); request.setHeaders(parseKeyValue(requestDesc.getHeader()));
addBodyHeader(request); addBodyHeader(request);
addPreScript(request, requestItem.getEvent());
apiDefinition.setRequest(JSON.toJSONString(request)); apiDefinition.setRequest(JSON.toJSONString(request));
return apiDefinition; return apiDefinition;
} }
private void addPreScript(MsHTTPSamplerProxy request, List<PostmanEvent> event) {
if (CollectionUtils.isNotEmpty(event)) {
StringBuilder scriptStr = new StringBuilder();
event = event.stream()
.filter(item -> item.getScript() != null)
.collect(Collectors.toList());
event.forEach(item -> {
PostmanScript script = item.getScript();
List<String> exec = script.getExec();
if (CollectionUtils.isNotEmpty(exec)) {
exec.forEach(col -> {
scriptStr.append(col + "/n");
});
}
});
if (StringUtils.isNotBlank(scriptStr)) {
MsJSR223PreProcessor jsr223PreProcessor = new MsJSR223PreProcessor();
jsr223PreProcessor.setScriptLanguage("javascript");
jsr223PreProcessor.setScript(scriptStr.toString());
LinkedList<MsTestElement> hashTree = new LinkedList<>();
hashTree.add(jsr223PreProcessor);
request.setHashTree(hashTree);
}
}
}
private List<KeyValue> parseKeyValue(List<PostmanKeyValue> postmanKeyValues) { private List<KeyValue> parseKeyValue(List<PostmanKeyValue> postmanKeyValues) {
if (postmanKeyValues == null) { if (postmanKeyValues == null) {
return null; return null;

View File

@ -10,6 +10,7 @@ import io.metersphere.api.dto.datacount.ApiDataCountResult;
import io.metersphere.api.dto.definition.*; import io.metersphere.api.dto.definition.*;
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport; import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
import io.metersphere.api.dto.definition.request.ScheduleInfoSwaggerUrlRequest; import io.metersphere.api.dto.definition.request.ScheduleInfoSwaggerUrlRequest;
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
import io.metersphere.api.dto.scenario.request.RequestType; import io.metersphere.api.dto.scenario.request.RequestType;
import io.metersphere.api.dto.swaggerurl.SwaggerTaskResult; import io.metersphere.api.dto.swaggerurl.SwaggerTaskResult;
import io.metersphere.api.dto.swaggerurl.SwaggerUrlRequest; import io.metersphere.api.dto.swaggerurl.SwaggerUrlRequest;
@ -21,10 +22,7 @@ import io.metersphere.api.parse.ApiImportParserFactory;
import io.metersphere.base.domain.*; import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*; import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.ext.*; import io.metersphere.base.mapper.ext.*;
import io.metersphere.commons.constants.APITestStatus; import io.metersphere.commons.constants.*;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.ScheduleGroup;
import io.metersphere.commons.constants.ScheduleType;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.*; import io.metersphere.commons.utils.*;
import io.metersphere.i18n.Translator; import io.metersphere.i18n.Translator;
@ -300,7 +298,7 @@ public class ApiDefinitionService {
} }
} }
private ApiDefinition importCreate(ApiDefinitionResult request, ApiDefinitionMapper batchMapper, ApiTestImportRequest apiTestImportRequest) { private ApiDefinition importCreate(ApiDefinitionResult request, ApiDefinitionMapper batchMapper, ApiTestCaseMapper apiTestCaseMapper, ApiTestImportRequest apiTestImportRequest) {
SaveApiDefinitionRequest saveReq = new SaveApiDefinitionRequest(); SaveApiDefinitionRequest saveReq = new SaveApiDefinitionRequest();
BeanUtils.copyBean(saveReq, request); BeanUtils.copyBean(saveReq, request);
final ApiDefinitionWithBLOBs apiDefinition = new ApiDefinitionWithBLOBs(); final ApiDefinitionWithBLOBs apiDefinition = new ApiDefinitionWithBLOBs();
@ -317,30 +315,72 @@ public class ApiDefinitionService {
List<ApiDefinition> sameRequest = getSameRequest(saveReq); List<ApiDefinition> sameRequest = getSameRequest(saveReq);
if (StringUtils.equals("fullCoverage", apiTestImportRequest.getModeId())) { if (StringUtils.equals("fullCoverage", apiTestImportRequest.getModeId())) {
if (CollectionUtils.isEmpty(sameRequest)) { _importCreate(sameRequest, batchMapper, apiDefinition, apiTestCaseMapper, apiTestImportRequest);
batchMapper.insert(apiDefinition);
} else {
//如果存在则修改
apiDefinition.setId(sameRequest.get(0).getId());
apiDefinitionMapper.updateByPrimaryKeyWithBLOBs(apiDefinition);
}
} else if (StringUtils.equals("incrementalMerge", apiTestImportRequest.getModeId())) { } else if (StringUtils.equals("incrementalMerge", apiTestImportRequest.getModeId())) {
if (CollectionUtils.isEmpty(sameRequest)) { if (CollectionUtils.isEmpty(sameRequest)) {
//postman 可能含有前置脚本接口定义去掉脚本
String requestStr = setImportHashTree(apiDefinition);
batchMapper.insert(apiDefinition); batchMapper.insert(apiDefinition);
apiDefinition.setRequest(requestStr);
importApiCase(apiDefinition, apiTestCaseMapper, apiTestImportRequest, true);
} }
} else { } else {
if (CollectionUtils.isEmpty(sameRequest)) { _importCreate(sameRequest, batchMapper, apiDefinition, apiTestCaseMapper, apiTestImportRequest);
batchMapper.insert(apiDefinition);
} else {
//如果存在则修改
apiDefinition.setId(sameRequest.get(0).getId());
apiDefinitionMapper.updateByPrimaryKeyWithBLOBs(apiDefinition);
}
} }
return apiDefinition; return apiDefinition;
} }
private void _importCreate(List<ApiDefinition> sameRequest, ApiDefinitionMapper batchMapper, ApiDefinitionWithBLOBs apiDefinition,
ApiTestCaseMapper apiTestCaseMapper, ApiTestImportRequest apiTestImportRequest) {
if (CollectionUtils.isEmpty(sameRequest)) {
String request = setImportHashTree(apiDefinition);
batchMapper.insert(apiDefinition);
apiDefinition.setRequest(request);
importApiCase(apiDefinition, apiTestCaseMapper, apiTestImportRequest, true);
} else {
//如果存在则修改
apiDefinition.setId(sameRequest.get(0).getId());
String request = setImportHashTree(apiDefinition);
apiDefinitionMapper.updateByPrimaryKeyWithBLOBs(apiDefinition);
apiDefinition.setRequest(request);
importApiCase(apiDefinition, apiTestCaseMapper, apiTestImportRequest, false);
}
}
private String setImportHashTree(ApiDefinitionWithBLOBs apiDefinition) {
String request = apiDefinition.getRequest();
MsHTTPSamplerProxy msHTTPSamplerProxy = JSONObject.parseObject(request, MsHTTPSamplerProxy.class);
msHTTPSamplerProxy.setHashTree(null);
apiDefinition.setRequest(JSONObject.toJSONString(msHTTPSamplerProxy));
return request;
}
/**
* 导入是插件或者postman时创建用例
* postman考虑是否有前置脚本
*/
private void importApiCase(ApiDefinitionWithBLOBs apiDefinition, ApiTestCaseMapper apiTestCaseMapper,
ApiTestImportRequest apiTestImportRequest, Boolean isInsert) {
try {
if (StringUtils.equalsAnyIgnoreCase(apiTestImportRequest.getPlatform(), ApiImportPlatform.Plugin.name(), ApiImportPlatform.Postman.name())) {
ApiTestCaseWithBLOBs apiTestCase = new ApiTestCaseWithBLOBs();
BeanUtils.copyBean(apiTestCase, apiDefinition);
apiTestCase.setId(UUID.randomUUID().toString());
apiTestCase.setApiDefinitionId(apiDefinition.getId());
apiTestCase.setCreateTime(System.currentTimeMillis());
apiTestCase.setUpdateTime(System.currentTimeMillis());
apiTestCase.setCreateUserId(SessionUtils.getUserId());
apiTestCase.setUpdateUserId(SessionUtils.getUserId());
apiTestCase.setPriority("P0");
if (!isInsert) {
apiTestCase.setName(apiTestCase.getName() + "_" + apiTestCase.getId().substring(0, 5));
}
apiTestCaseMapper.insert(apiTestCase);
}
} catch (Exception e) {
LogUtil.error("导入创建用例异常", e);
}
}
private void deleteFileByTestId(String apiId) { private void deleteFileByTestId(String apiId) {
ApiTestFileExample apiTestFileExample = new ApiTestFileExample(); ApiTestFileExample apiTestFileExample = new ApiTestFileExample();
@ -457,6 +497,7 @@ public class ApiDefinitionService {
private void importApi(ApiTestImportRequest request, ApiDefinitionImport apiImport) { private void importApi(ApiTestImportRequest request, ApiDefinitionImport apiImport) {
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
ApiDefinitionMapper batchMapper = sqlSession.getMapper(ApiDefinitionMapper.class); ApiDefinitionMapper batchMapper = sqlSession.getMapper(ApiDefinitionMapper.class);
ApiTestCaseMapper apiTestCaseMapper = sqlSession.getMapper(ApiTestCaseMapper.class);
List<ApiDefinitionResult> data = apiImport.getData(); List<ApiDefinitionResult> data = apiImport.getData();
int num = 0; int num = 0;
if (!CollectionUtils.isEmpty(data) && data.get(0) != null && data.get(0).getProjectId() != null) { if (!CollectionUtils.isEmpty(data) && data.get(0) != null && data.get(0).getProjectId() != null) {
@ -468,7 +509,7 @@ public class ApiDefinitionService {
item.setName(item.getName().substring(0, 255)); item.setName(item.getName().substring(0, 255));
} }
item.setNum(num++); item.setNum(num++);
importCreate(item, batchMapper, request); importCreate(item, batchMapper, apiTestCaseMapper, request);
if (i % 300 == 0) { if (i % 300 == 0) {
sqlSession.flushStatements(); sqlSession.flushStatements();
} }

View File

@ -1,5 +1,5 @@
package io.metersphere.commons.constants; package io.metersphere.commons.constants;
public enum ApiImportPlatform { public enum ApiImportPlatform {
Metersphere, Postman, Swagger2 Metersphere, Postman, Swagger2, Plugin
} }

View File

@ -37,6 +37,7 @@
<el-button size="mini" icon="el-icon-delete" type="danger" circle @click="remove"/> <el-button size="mini" icon="el-icon-delete" type="danger" circle @click="remove"/>
</el-tooltip> </el-tooltip>
</div> </div>
</div> </div>
<div class="header"> <div class="header">
<fieldset :disabled="data.disabled" class="ms-fieldset"> <fieldset :disabled="data.disabled" class="ms-fieldset">

@ -1 +1 @@
Subproject commit 53bd821bee65be3374f1ccc9a299cef9ac44b985 Subproject commit a3d469fd18f663d11e5c1c49f71ced6e3e4b292f

View File

@ -208,8 +208,8 @@ export default {
display: { display: {
title: 'Theme', title: 'Theme',
logo: 'System LOGO', logo: 'System LOGO',
loginLogo: 'Picture on the right side of the login page', loginLogo: 'Login page upper left corner LOGO',
loginImage: 'Login page upper left corner LOGO', loginImage: 'Picture on the right side of the login page',
loginTitle: 'Login page prompt information', loginTitle: 'Login page prompt information',
pageTitle: 'Page Title', pageTitle: 'Page Title',
}, },

View File

@ -209,8 +209,8 @@ export default {
display: { display: {
title: '显示设置', title: '显示设置',
logo: '系统 LOGO', logo: '系统 LOGO',
loginLogo: '登陆页面右侧图片', loginLogo: '登录页左上角 LOGO',
loginImage: '登录页左上角 LOGO', loginImage: '登陆页面右侧图片',
loginTitle: '登陆页面提示信息', loginTitle: '登陆页面提示信息',
pageTitle: '页面 Title', pageTitle: '页面 Title',
}, },

View File

@ -209,8 +209,8 @@ export default {
display: { display: {
title: '顯示設置', title: '顯示設置',
logo: '系統 LOGO', logo: '系統 LOGO',
loginLogo: '登陸頁面右側圖片', loginLogo: '登錄頁左上角 LOGO',
loginImage: '登錄頁左上角 LOGO', loginImage: '登陸頁面右側圖片',
loginTitle: '登陸頁面提示信息', loginTitle: '登陸頁面提示信息',
pageTitle: '頁面 Title', pageTitle: '頁面 Title',
}, },

View File

@ -8,7 +8,7 @@
<img :src="'/display/file/loginLogo'" alt=""> <img :src="'/display/file/loginLogo'" alt="">
</div> </div>
<div class="welcome"> <div class="welcome">
<span>{{ $t('commons.welcome') }}</span> <span>{{ loginTitle }}</span>
</div> </div>
</div> </div>
@ -46,7 +46,7 @@
<div class="divider"/> <div class="divider"/>
<el-col :span="12"> <el-col :span="12">
<img class="login-image" :src="'/display/file/loginImage'"> <img class="login-image" :src="'/display/file/loginImage'" alt="">
</el-col> </el-col>
</el-row> </el-row>
@ -85,7 +85,7 @@ export default {
msg: '', msg: '',
ready: false, ready: false,
openLdap: false, openLdap: false,
loginTitle: this.$t("commons.login") + " MeterSphere", loginTitle: this.$t("commons.welcome"),
authSources: [], authSources: [],
loginUrl: 'signin', loginUrl: 'signin',
} }
@ -200,6 +200,7 @@ export default {
.title img { .title img {
width: 293px; width: 293px;
max-height: 60px;
margin-top: 165px; margin-top: 165px;
} }