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

This commit is contained in:
Captain.B 2020-07-22 13:58:12 +08:00
commit c3176d1a6e
10 changed files with 54 additions and 15 deletions

View File

@ -95,7 +95,7 @@ public class APITestController {
@PostMapping(value = "/import", consumes = {"multipart/form-data"}) @PostMapping(value = "/import", consumes = {"multipart/form-data"})
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR) @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
public ApiTest testCaseImport(@RequestPart(value = "file") MultipartFile file, @RequestPart("request") ApiTestImportRequest request) { public ApiTest testCaseImport(@RequestPart(value = "file", required = false) MultipartFile file, @RequestPart("request") ApiTestImportRequest request) {
return apiTestService.apiTestImport(file, request); return apiTestService.apiTestImport(file, request);
} }

View File

@ -35,6 +35,7 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -263,7 +264,7 @@ public class APITestService {
ApiImportParser apiImportParser = ApiImportParserFactory.getApiImportParser(request.getPlatform()); ApiImportParser apiImportParser = ApiImportParserFactory.getApiImportParser(request.getPlatform());
ApiImport apiImport = null; ApiImport apiImport = null;
try { try {
apiImport = apiImportParser.parse(file.getInputStream(), request); apiImport = apiImportParser.parse(file == null ? null : file.getInputStream(), request);
} catch (Exception e) { } catch (Exception e) {
LogUtil.error(e.getMessage(), e); LogUtil.error(e.getMessage(), e);
MSException.throwException(Translator.get("parse_data_error")); MSException.throwException(Translator.get("parse_data_error"));

View File

@ -5,6 +5,7 @@ import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
import io.metersphere.base.mapper.ApiTestEnvironmentMapper; import io.metersphere.base.mapper.ApiTestEnvironmentMapper;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.i18n.Translator; import io.metersphere.i18n.Translator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -34,6 +35,7 @@ public class ApiTestEnvironmentService {
} }
public void update(ApiTestEnvironmentWithBLOBs apiTestEnvironment) { public void update(ApiTestEnvironmentWithBLOBs apiTestEnvironment) {
checkEnvironmentExist(apiTestEnvironment);
apiTestEnvironmentMapper.updateByPrimaryKeyWithBLOBs(apiTestEnvironment); apiTestEnvironmentMapper.updateByPrimaryKeyWithBLOBs(apiTestEnvironment);
} }
@ -47,9 +49,12 @@ public class ApiTestEnvironmentService {
private void checkEnvironmentExist (ApiTestEnvironmentWithBLOBs environment) { private void checkEnvironmentExist (ApiTestEnvironmentWithBLOBs environment) {
if (environment.getName() != null) { if (environment.getName() != null) {
ApiTestEnvironmentExample example = new ApiTestEnvironmentExample(); ApiTestEnvironmentExample example = new ApiTestEnvironmentExample();
example.createCriteria() ApiTestEnvironmentExample.Criteria criteria = example.createCriteria();
.andNameEqualTo(environment.getName()) criteria.andNameEqualTo(environment.getName())
.andProjectIdEqualTo(environment.getProjectId()); .andProjectIdEqualTo(environment.getProjectId());
if (StringUtils.isNotBlank(environment.getId())) {
criteria.andIdNotEqualTo(environment.getId());
}
if (apiTestEnvironmentMapper.selectByExample(example).size() > 0) { if (apiTestEnvironmentMapper.selectByExample(example).size() > 0) {
MSException.throwException(Translator.get("api_test_environment_already_exists")); MSException.throwException(Translator.get("api_test_environment_already_exists"));
} }

View File

@ -49,13 +49,16 @@
this.projectId = projectId; this.projectId = projectId;
this.getEnvironments(); this.getEnvironments();
}, },
deleteEnvironment(environment) { deleteEnvironment(environment, index) {
if (environment.id) { if (environment.id) {
this.result = this.$get('/api/environment/delete/' + environment.id, () => { this.result = this.$get('/api/environment/delete/' + environment.id, () => {
this.$success(this.$t('commons.delete_success')); this.$success(this.$t('commons.delete_success'));
this.getEnvironments(); this.getEnvironments();
}); });
} }
else {
this.environments.splice(index, 1);
}
}, },
copyEnvironment(environment) { copyEnvironment(environment) {
if (!environment.id) { if (!environment.id) {
@ -149,4 +152,5 @@
height: 100%; height: 100%;
position: absolute; position: absolute;
} }
</style> </style>

View File

@ -29,7 +29,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item v-if="(selectedPlatformValue != 'Postman' && useEnvironment) || selectedPlatformValue == 'Swagger2'" :label="$t('api_test.environment.environment_config')" prop="environmentId"> <el-form-item v-if="(selectedPlatformValue != 'Postman' && useEnvironment) || selectedPlatformValue == 'Swagger2'" :label="$t('api_test.environment.environment_config')" prop="environmentId">
<el-select size="small" v-model="formData.environmentId" class="environment-select" clearable> <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 + ': ' + environment.protocol + '://' + environment.socket" :value="environment.id"/> <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> <el-button class="environment-button" size="mini" type="primary" @click="openEnvironmentConfig">{{$t('api_test.environment.environment_config')}}</el-button>
<template v-slot:empty> <template v-slot:empty>
@ -42,11 +42,23 @@
<el-form-item v-if="selectedPlatformValue == 'Metersphere'" prop="useEnvironment"> <el-form-item v-if="selectedPlatformValue == 'Metersphere'" prop="useEnvironment">
<el-checkbox v-model="useEnvironment">{{$t('api_test.environment.config_environment')}}</el-checkbox> <el-checkbox v-model="useEnvironment">{{$t('api_test.environment.config_environment')}}</el-checkbox>
</el-form-item> </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-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-col>
<el-col :span="1">
<el-col :span="1" v-if="selectedPlatformValue != 'Swagger2' || (selectedPlatformValue == 'Swagger2' && !swaggerUrlEable)">
<el-divider direction="vertical"/> <el-divider direction="vertical"/>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12" v-if="selectedPlatformValue != 'Swagger2' || (selectedPlatformValue == 'Swagger2' && !swaggerUrlEable)">
<el-upload <el-upload
class="api-upload" class="api-upload"
drag drag
@ -89,6 +101,8 @@
data() { data() {
return { return {
visible: false, visible: false,
swaggerUrlEable: false,
showEnvironmentSelect: true,
platforms: [ platforms: [
{ {
name: 'Metersphere', name: 'Metersphere',
@ -122,7 +136,8 @@
name: '', name: '',
environmentId: '', environmentId: '',
projectId: '', projectId: '',
file: undefined file: undefined,
swaggerUrl: ''
}, },
rules: { rules: {
name: [ name: [
@ -202,7 +217,9 @@
this.$error(this.$t('api_test.select_project')); this.$error(this.$t('api_test.select_project'));
return; return;
} }
this.showEnvironmentSelect = false;
this.$refs.environmentConfig.open(this.formData.projectId); this.$refs.environmentConfig.open(this.formData.projectId);
this.showEnvironmentSelect = true;
}, },
save() { save() {
this.$refs.form.validate(valid => { this.$refs.form.validate(valid => {
@ -211,10 +228,13 @@
Object.assign(param, this.formData); Object.assign(param, this.formData);
param.platform = this.selectedPlatformValue; param.platform = this.selectedPlatformValue;
param.useEnvironment = this.useEnvironment; param.useEnvironment = this.useEnvironment;
if (!this.formData.file) { if ((this.selectedPlatformValue != 'Swagger2' || (this.selectedPlatformValue == 'Swagger2' && !this.swaggerUrlEable)) && !this.formData.file) {
this.$warning(this.$t('commons.please_upload')); this.$warning(this.$t('commons.please_upload'));
return ; return ;
} }
if (!this.swaggerUrlEable) {
param.swaggerUrl = undefined;
}
this.result = this.$fileUpload('/api/import', param.file, param,response => { this.result = this.$fileUpload('/api/import', param.file, param,response => {
let res = response.data; let res = response.data;
this.$success(this.$t('test_track.case.import.success')); this.$success(this.$t('test_track.case.import.success'));
@ -231,7 +251,8 @@
name: '', name: '',
environmentId: '', environmentId: '',
projectId: '', projectId: '',
file: undefined file: undefined,
swaggerUrl: ''
}; };
this.fileList = []; this.fileList = [];
} }
@ -252,6 +273,7 @@
.api-upload >>> .el-upload { .api-upload >>> .el-upload {
width: 100%; width: 100%;
max-width: 350px;
} }
.api-upload >>> .el-upload-dragger { .api-upload >>> .el-upload-dragger {

View File

@ -13,7 +13,7 @@
<div :style="{'height': itemBarHeight + 'px'}" v-for="(item, index) in data" :key="index" class="item-bar" @click="itemSelected(index, item)" :class="{'item-selected' : index == selectIndex}"> <div :style="{'height': itemBarHeight + 'px'}" v-for="(item, index) in data" :key="index" class="item-bar" @click="itemSelected(index, item)" :class="{'item-selected' : index == selectIndex}">
<input class="item-input" :style="{'height': itemBarHeight - 12 + 'px', 'line-height': itemBarHeight - 12 + 'px', 'width': width - 90 + 'px'}" v-model="item.name" :placeholder="$t('commons.input_content')"/> <input class="item-input" :style="{'height': itemBarHeight - 12 + 'px', 'line-height': itemBarHeight - 12 + 'px', 'width': width - 90 + 'px'}" v-model="item.name" :placeholder="$t('commons.input_content')"/>
<span :style="{'line-height': itemBarHeight - 10 + 'px'}" class="item-right"> <span :style="{'line-height': itemBarHeight - 10 + 'px'}" class="item-right">
<i v-for="(operator, index) in itemOperators" :key="index" :class="operator.icon" @click.stop="operator.func(item)"/> <i v-for="(operator, operatorIndex) in itemOperators" :key="operatorIndex" :class="operator.icon" @click.stop="operator.func(item, index)"/>
</span> </span>
</div> </div>
</ms-aside-container> </ms-aside-container>

View File

@ -32,6 +32,7 @@
<span>{{ scope.row.createTime | timestampFormatDate }}</span> <span>{{ scope.row.createTime | timestampFormatDate }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="source" :label="$t('user.source')"/>
<el-table-column :label="$t('commons.operating')"> <el-table-column :label="$t('commons.operating')">
<template v-slot:default="scope"> <template v-slot:default="scope">
<ms-table-operator @editClick="edit(scope.row)" @deleteClick="del(scope.row)"> <ms-table-operator @editClick="edit(scope.row)" @deleteClick="del(scope.row)">

View File

@ -224,7 +224,8 @@ export default {
email_format_is_incorrect: 'Email format is incorrect', email_format_is_incorrect: 'Email format is incorrect',
delete_confirm: 'Are you sure you want to delete this User?', delete_confirm: 'Are you sure you want to delete this User?',
apikey_delete_confirm: 'Are you sure you want to delete this API Key?', apikey_delete_confirm: 'Are you sure you want to delete this API Key?',
input_id_placeholder: 'Please enter ID (only supports numbers and English letters)' input_id_placeholder: 'Please enter ID (only supports numbers and English letters)',
source: 'Source'
}, },
role: { role: {
please_choose_role: 'Please Choose Role', please_choose_role: 'Please Choose Role',
@ -435,6 +436,7 @@ export default {
postman_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", swagger_export_tip: "Export jSON-formatted files via Swagger website",
suffixFormatErr: "The file format does not meet the requirements", suffixFormatErr: "The file format does not meet the requirements",
swagger_url_import: "Import using URL",
} }
}, },
api_report: { api_report: {

View File

@ -222,7 +222,8 @@ export default {
email_format_is_incorrect: '邮箱格式不正确', email_format_is_incorrect: '邮箱格式不正确',
delete_confirm: '这个用户确定要删除吗?', delete_confirm: '这个用户确定要删除吗?',
apikey_delete_confirm: '这个 API Key 确定要删除吗?', apikey_delete_confirm: '这个 API Key 确定要删除吗?',
input_id_placeholder: '请输入ID (只支持数字、英文字母)' input_id_placeholder: '请输入ID (只支持数字、英文字母)',
source: '用户来源'
}, },
role: { role: {
please_choose_role: '请选择角色', please_choose_role: '请选择角色',
@ -435,6 +436,7 @@ export default {
post_export_tip: "通过 Postman 导出测试集合", post_export_tip: "通过 Postman 导出测试集合",
swagger_export_tip: "通过 Swagger 页面导出", swagger_export_tip: "通过 Swagger 页面导出",
suffixFormatErr: "文件格式不符合要求", suffixFormatErr: "文件格式不符合要求",
swagger_url_import: "使用URL导入",
} }
}, },
api_report: { api_report: {

View File

@ -221,7 +221,8 @@ export default {
email_format_is_incorrect: '郵箱格式不正確', email_format_is_incorrect: '郵箱格式不正確',
delete_confirm: '這個用戶確定要刪除嗎?', delete_confirm: '這個用戶確定要刪除嗎?',
apikey_delete_confirm: '這個 API Key 確定要刪除嗎?', apikey_delete_confirm: '這個 API Key 確定要刪除嗎?',
input_id_placeholder: '請輸入ID (只支持數字、英文字母)' input_id_placeholder: '請輸入ID (只支持數字、英文字母)',
source: '用戶來源'
}, },
role: { role: {
please_choose_role: '請選擇角色', please_choose_role: '請選擇角色',
@ -434,6 +435,7 @@ export default {
post_export_tip: "通過 Postman 導出測試集合", post_export_tip: "通過 Postman 導出測試集合",
swagger_export_tip: "通過 Swagger 頁面導出", swagger_export_tip: "通過 Swagger 頁面導出",
suffixFormatErr: "文件格式不符合要求", suffixFormatErr: "文件格式不符合要求",
swagger_url_import: "使用URL導入",
} }
}, },
api_report: { api_report: {