feat(接口测试): 接口定义导入
This commit is contained in:
parent
4e607cfa7b
commit
b08775dbb9
|
@ -19,11 +19,15 @@ import io.metersphere.base.mapper.ext.ExtApiDefinitionMapper;
|
|||
import io.metersphere.commons.constants.APITestStatus;
|
||||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.commons.utils.ServiceUtils;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.service.FileService;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
import org.aspectj.util.FileUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
@ -55,6 +59,8 @@ public class ApiDefinitionService {
|
|||
private ExtApiDefinitionExecResultMapper extApiDefinitionExecResultMapper;
|
||||
@Resource
|
||||
private JMeterService jMeterService;
|
||||
@Resource
|
||||
private SqlSessionFactory sqlSessionFactory;
|
||||
|
||||
private static Cache cache = Cache.newHardMemoryCache(0, 3600 * 24);
|
||||
|
||||
|
@ -218,39 +224,27 @@ public class ApiDefinitionService {
|
|||
return test;
|
||||
}
|
||||
|
||||
private ApiDefinition createTest(ApiDefinitionResult request) {
|
||||
private ApiDefinition createTest(ApiDefinitionResult request, ApiDefinitionMapper batchMapper) {
|
||||
SaveApiDefinitionRequest saveReq = new SaveApiDefinitionRequest();
|
||||
BeanUtils.copyBean(saveReq, request);
|
||||
saveReq.setId(UUID.randomUUID().toString());
|
||||
saveReq.setName(request.getName());
|
||||
saveReq.setProtocol(request.getProtocol());
|
||||
saveReq.setProjectId(request.getProjectId());
|
||||
saveReq.setPath(request.getPath());
|
||||
checkNameExist(saveReq);
|
||||
final ApiDefinitionWithBLOBs test = new ApiDefinitionWithBLOBs();
|
||||
test.setId(request.getId());
|
||||
test.setName(request.getName());
|
||||
test.setProtocol(request.getProtocol());
|
||||
test.setMethod(request.getMethod());
|
||||
test.setPath(request.getPath());
|
||||
test.setModuleId(request.getModuleId());
|
||||
test.setProjectId(request.getProjectId());
|
||||
test.setRequest(request.getRequest());
|
||||
BeanUtils.copyBean(test, request);
|
||||
test.setCreateTime(System.currentTimeMillis());
|
||||
test.setUpdateTime(System.currentTimeMillis());
|
||||
test.setStatus(APITestStatus.Underway.name());
|
||||
test.setModulePath(request.getModulePath());
|
||||
test.setResponse(request.getResponse());
|
||||
test.setEnvironmentId(request.getEnvironmentId());
|
||||
if (request.getUserId() == null) {
|
||||
test.setUserId(Objects.requireNonNull(SessionUtils.getUser()).getId());
|
||||
} else {
|
||||
test.setUserId(request.getUserId());
|
||||
}
|
||||
test.setDescription(request.getDescription());
|
||||
apiDefinitionMapper.insert(test);
|
||||
batchMapper.insert(test);
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
private void deleteFileByTestId(String apiId) {
|
||||
ApiTestFileExample apiTestFileExample = new ApiTestFileExample();
|
||||
apiTestFileExample.createCriteria().andTestIdEqualTo(apiId);
|
||||
|
@ -337,15 +331,23 @@ public class ApiDefinitionService {
|
|||
}
|
||||
|
||||
private void importApiTest(ApiTestImportRequest importRequest, ApiDefinitionImport apiImport) {
|
||||
apiImport.getData().forEach(item -> {
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
ApiDefinitionMapper batchMapper = sqlSession.getMapper(ApiDefinitionMapper.class);
|
||||
List<ApiDefinitionResult> data = apiImport.getData();
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
ApiDefinitionResult item = data.get(i);
|
||||
item.setProjectId(importRequest.getProjectId());
|
||||
item.setModuleId(importRequest.getModuleId());
|
||||
item.setModulePath(importRequest.getModulePath());
|
||||
item.setEnvironmentId(importRequest.getEnvironmentId());
|
||||
item.setId(UUID.randomUUID().toString());
|
||||
item.setUserId(null);
|
||||
createTest(item);
|
||||
});
|
||||
createTest(item, batchMapper);
|
||||
if (i % 300 == 0) {
|
||||
sqlSession.flushStatements();
|
||||
}
|
||||
}
|
||||
sqlSession.flushStatements();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ CREATE TABLE IF NOT EXISTS `api_module` (
|
|||
CREATE TABLE IF NOT EXISTS `api_definition` (
|
||||
`id` varchar(50) NOT NULL COMMENT 'Test ID',
|
||||
`project_id` varchar(50) NOT NULL COMMENT 'Project ID this test belongs to',
|
||||
`name` varchar(64) NOT NULL COMMENT 'Test name',
|
||||
`name` varchar(255) NOT NULL COMMENT 'Test name',
|
||||
`method` varchar(64) NOT NULL COMMENT 'method',
|
||||
`protocol` varchar(255) NOT NULL COMMENT 'request protocol',
|
||||
`path` varchar(255) DEFAULT NULL COMMENT 'request path',
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
</el-tree>
|
||||
|
||||
<ms-add-basis-api :current-protocol="protocol" ref="basisApi"></ms-add-basis-api>
|
||||
<api-import ref="apiImport" @refresh="refresh"/>
|
||||
<api-import ref="apiImport" :project-id="currentProject.id" @refresh="refresh"/>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<template>
|
||||
<el-dialog :close-on-click-modal="false" :title="$t('api_test.api_import.title')" :visible.sync="visible" class="api-import" v-loading="result.loading" @close="close">
|
||||
<el-dialog :close-on-click-modal="false" :title="$t('api_test.api_import.title')" width="30%"
|
||||
:visible.sync="visible" class="api-import" v-loading="result.loading" @close="close">
|
||||
|
||||
<div class="header-bar">
|
||||
<div>{{$t('api_test.api_import.data_format')}}</div>
|
||||
|
@ -18,64 +19,35 @@
|
|||
</div>
|
||||
|
||||
<el-form :model="formData" :rules="rules" label-width="100px" v-loading="result.loading" ref="form">
|
||||
<el-row>
|
||||
<el-col :span="11">
|
||||
<el-form-item :label="$t('commons.name')" prop="name">
|
||||
<el-input size="small" class="name-input" v-model="formData.name" clearable show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.project')" prop="projectId">
|
||||
<el-select size="small" v-model="formData.projectId" class="project-select" clearable>
|
||||
<el-option v-for="(project, index) in projects" :key="index" :label="project.name" :value="project.id"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="useEnvironment || selectedPlatformValue == 'Swagger2'" :label="$t('api_test.environment.environment_config')" prop="environmentId">
|
||||
<el-select v-if="showEnvironmentSelect" size="small" v-model="formData.environmentId" class="environment-select" clearable>
|
||||
<el-option v-for="(environment, index) in environments" :key="index" :label="environment.name" :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 :disabled="formData.projectId == ''" class="environment-button" size="mini" type="primary" @click="openEnvironmentConfig">{{$t('api_test.environment.environment_config')}}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="selectedPlatformValue != 'Swagger2'" prop="useEnvironment">
|
||||
<el-checkbox v-model="useEnvironment">{{$t('api_test.environment.config_environment')}}</el-checkbox>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="'Swagger URL'" prop="wgerUrl" v-if="selectedPlatformValue == 'Swagger2' && swaggerUrlEable">
|
||||
<el-input size="small" v-model="formData.swaggerUrl" clearable show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-upload
|
||||
v-if="selectedPlatformValue != 'Swagger2' || (selectedPlatformValue == 'Swagger2' && !swaggerUrlEable)"
|
||||
class="api-upload"
|
||||
drag
|
||||
action=""
|
||||
:http-request="upload"
|
||||
:limit="1"
|
||||
:beforeUpload="uploadValidate"
|
||||
:on-remove="handleRemove"
|
||||
:file-list="fileList"
|
||||
:on-exceed="handleExceed"
|
||||
multiple>
|
||||
<i class="el-icon-upload"></i>
|
||||
<div class="el-upload__text" v-html="$t('load_test.upload_tips')"></div>
|
||||
<div class="el-upload__tip" slot="tip">{{$t('api_test.api_import.file_size_limit')}}</div>
|
||||
</el-upload>
|
||||
|
||||
<el-form-item v-if="selectedPlatformValue == 'Swagger2'">
|
||||
<el-switch
|
||||
v-model="swaggerUrlEable"
|
||||
:active-text="$t('api_test.api_import.swagger_url_import')">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-form-item :label="'Swagger URL'" prop="wgerUrl" v-if="isSwagger2 && swaggerUrlEable" class="swagger-url">
|
||||
<el-input size="small" v-model="formData.swaggerUrl" clearable show-word-limit/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="isSwagger2" class="swagger-enable" :class="{'swagger-url-disable': !swaggerUrlEable}">
|
||||
<el-switch
|
||||
v-model="swaggerUrlEable"
|
||||
:active-text="$t('api_test.api_import.swagger_url_import')">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
|
||||
<el-col :span="1" v-if="selectedPlatformValue != 'Swagger2' || (selectedPlatformValue == 'Swagger2' && !swaggerUrlEable)">
|
||||
<el-divider direction="vertical"/>
|
||||
</el-col>
|
||||
<el-col :span="12" v-if="selectedPlatformValue != 'Swagger2' || (selectedPlatformValue == 'Swagger2' && !swaggerUrlEable)">
|
||||
<el-upload
|
||||
class="api-upload"
|
||||
drag
|
||||
action=""
|
||||
:http-request="upload"
|
||||
:limit="1"
|
||||
:beforeUpload="uploadValidate"
|
||||
:on-remove="handleRemove"
|
||||
:file-list="fileList"
|
||||
:on-exceed="handleExceed"
|
||||
multiple>
|
||||
<i class="el-icon-upload"></i>
|
||||
<div class="el-upload__text" v-html="$t('load_test.upload_tips')"></div>
|
||||
<div class="el-upload__tip" slot="tip">{{$t('api_test.api_import.file_size_limit')}}</div>
|
||||
</el-upload>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<div class="format-tip">
|
||||
|
@ -87,19 +59,16 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<api-environment-config ref="environmentConfig" @close="getEnvironments"/>
|
||||
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsDialogFooter from "../../../../common/components/MsDialogFooter";
|
||||
import ApiEnvironmentConfig from "../environment/ApiEnvironmentConfig";
|
||||
import {listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||
|
||||
export default {
|
||||
name: "ApiImport",
|
||||
components: {ApiEnvironmentConfig, MsDialogFooter},
|
||||
components: {MsDialogFooter},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
|
@ -135,31 +104,18 @@
|
|||
environments: [],
|
||||
useEnvironment: false,
|
||||
formData: {
|
||||
name: '',
|
||||
environmentId: '',
|
||||
projectId: '',
|
||||
file: undefined,
|
||||
swaggerUrl: ''
|
||||
},
|
||||
rules: {},
|
||||
currentModule: {},
|
||||
rules: {
|
||||
name: [
|
||||
{required: true, message: this.$t('commons.input_name'), trigger: 'blur'},
|
||||
{max: 60, message: this.$t('commons.input_limit', [1, 60]), trigger: 'blur'}
|
||||
],
|
||||
environmentId: [
|
||||
{required: true, message: this.$t('api_test.environment.select_environment'), trigger: 'blur'},
|
||||
],
|
||||
projectId: [
|
||||
{required: true, message: this.$t('api_test.select_project'), trigger: 'blur'},
|
||||
]
|
||||
},
|
||||
fileList: []
|
||||
}
|
||||
},
|
||||
props: ['projectId'],
|
||||
activated() {
|
||||
this.selectedPlatform = this.platforms[0];
|
||||
this.getProjects();
|
||||
},
|
||||
watch: {
|
||||
selectedPlatformValue() {
|
||||
|
@ -170,8 +126,10 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
'formData.projectId'() {
|
||||
this.getEnvironments();
|
||||
},
|
||||
computed: {
|
||||
isSwagger2() {
|
||||
return this.selectedPlatformValue === 'Swagger2';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -195,63 +153,21 @@
|
|||
this.$warning(this.$t('api_test.api_import.suffixFormatErr'));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file.size / 1024 / 1024 > 20) {
|
||||
this.$warning(this.$t('test_track.case.import.upload_limit_size'));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
getEnvironments() {
|
||||
if (this.formData.projectId) {
|
||||
this.$get('/api/environment/list/' + this.formData.projectId, response => {
|
||||
this.environments = response.data;
|
||||
let hasEnvironmentId = false;
|
||||
this.environments.forEach(env => {
|
||||
if (env.id === this.formData.environmentId) {
|
||||
hasEnvironmentId = true;
|
||||
}
|
||||
});
|
||||
if (!hasEnvironmentId) {
|
||||
this.formData.environmentId = '';
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.environments = [];
|
||||
this.formData.environmentId = '';
|
||||
}
|
||||
},
|
||||
getProjects() {
|
||||
this.result = this.$get("/project/listAll", response => {
|
||||
this.projects = response.data;
|
||||
})
|
||||
},
|
||||
openEnvironmentConfig() {
|
||||
if (!this.formData.projectId) {
|
||||
this.$error(this.$t('api_test.select_project'));
|
||||
return;
|
||||
}
|
||||
this.showEnvironmentSelect = false;
|
||||
this.$refs.environmentConfig.open(this.formData.projectId);
|
||||
this.showEnvironmentSelect = true;
|
||||
},
|
||||
save() {
|
||||
this.$refs.form.validate(valid => {
|
||||
if (valid) {
|
||||
let param = {};
|
||||
Object.assign(param, this.formData);
|
||||
param.platform = this.selectedPlatformValue;
|
||||
param.useEnvironment = this.useEnvironment;
|
||||
param.moduleId = this.currentModule.id;
|
||||
param.modulePath = this.currentModule.path;
|
||||
if ((this.selectedPlatformValue != 'Swagger2' || (this.selectedPlatformValue == 'Swagger2' && !this.swaggerUrlEable)) && !this.formData.file) {
|
||||
this.$warning(this.$t('commons.please_upload'));
|
||||
return;
|
||||
}
|
||||
if (!this.swaggerUrlEable) {
|
||||
param.swaggerUrl = undefined;
|
||||
}
|
||||
this.result = this.$fileUpload('/api/definition/import', param.file, null, param, response => {
|
||||
let param = this.buildParam();
|
||||
this.result = this.$fileUpload('/api/definition/import', param.file, null, this.buildParam(), response => {
|
||||
let res = response.data;
|
||||
this.$success(this.$t('test_track.case.import.success'));
|
||||
this.visible = false;
|
||||
|
@ -262,11 +178,20 @@
|
|||
}
|
||||
});
|
||||
},
|
||||
buildParam() {
|
||||
let param = {};
|
||||
Object.assign(param, this.formData);
|
||||
param.platform = this.selectedPlatformValue;
|
||||
param.moduleId = this.currentModule.id;
|
||||
param.modulePath = this.currentModule.path;
|
||||
param.projectId = this.projectId;
|
||||
if (!this.swaggerUrlEable) {
|
||||
param.swaggerUrl = undefined;
|
||||
}
|
||||
return param;
|
||||
},
|
||||
close() {
|
||||
this.formData = {
|
||||
name: '',
|
||||
environmentId: '',
|
||||
projectId: '',
|
||||
file: undefined,
|
||||
swaggerUrl: ''
|
||||
};
|
||||
|
@ -280,6 +205,10 @@
|
|||
|
||||
<style scoped>
|
||||
|
||||
.api-import >>> .el-dialog {
|
||||
min-width: 700px;
|
||||
}
|
||||
|
||||
.format-tip {
|
||||
background: #EDEDED;
|
||||
}
|
||||
|
@ -325,29 +254,18 @@
|
|||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.environment-button {
|
||||
margin-left: 20px;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
.empty-environment {
|
||||
padding: 10px 0px;
|
||||
}
|
||||
|
||||
.el-form {
|
||||
padding: 30px 10px;
|
||||
}
|
||||
|
||||
.el-divider {
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.name-input {
|
||||
max-width: 195px;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.swagger-url-disable {
|
||||
margin-top: 10px;
|
||||
|
||||
margin-left: 80px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue