fix(接口定义): 部分缺陷修复

This commit is contained in:
fit2-zhao 2020-12-14 12:19:35 +08:00
parent 0bd4675886
commit 469802030c
14 changed files with 112 additions and 92 deletions

View File

@ -17,6 +17,7 @@ import io.metersphere.commons.utils.CommonBeanFactory;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.jmeter.save.SaveService; import org.apache.jmeter.save.SaveService;
import org.apache.jmeter.testelement.TestElement; import org.apache.jmeter.testelement.TestElement;
import org.apache.jorphan.collections.HashTree; import org.apache.jorphan.collections.HashTree;
@ -47,7 +48,7 @@ public class MsScenario extends MsTestElement {
if (!this.isEnable()) { if (!this.isEnable()) {
return; return;
} }
if (environmentId != null) { if (StringUtils.isNotEmpty(environmentId)) {
ApiTestEnvironmentService environmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class); ApiTestEnvironmentService environmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class);
ApiTestEnvironmentWithBLOBs environment = environmentService.get(environmentId); ApiTestEnvironmentWithBLOBs environment = environmentService.get(environmentId);
config.setConfig(JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class)); config.setConfig(JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class));

View File

@ -124,7 +124,7 @@ public class ApiAutomationService {
scenario.setDescription(request.getDescription()); scenario.setDescription(request.getDescription());
apiScenarioMapper.insert(scenario); apiScenarioMapper.insert(scenario);
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds()); List<String> bodyUploadIds = request.getBodyUploadIds();
apiDefinitionService.createBodyFiles(bodyUploadIds, bodyFiles); apiDefinitionService.createBodyFiles(bodyUploadIds, bodyFiles);
} }

View File

@ -21,11 +21,10 @@ import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.Resource;
@Service @Service
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public class ApiScenarioModuleService { public class ApiScenarioModuleService {

View File

@ -57,74 +57,75 @@
</template> </template>
<script> <script>
import {WORKSPACE_ID} from '@/common/js/constants'; import {WORKSPACE_ID} from '@/common/js/constants';
import {getCurrentUser, getUUID,getCurrentProjectID} from "@/common/js/utils"; import {getCurrentUser, getUUID, getCurrentProjectID} from "@/common/js/utils";
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter"; import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
export default {
name: "MsAddBasisScenario", export default {
components: {MsDialogFooter}, name: "MsAddBasisScenario",
props: {}, components: {MsDialogFooter},
data() { props: {},
return { data() {
scenarioForm: {}, return {
visible: false, scenarioForm: {},
currentModule: {}, visible: false,
userOptions: [], currentModule: {},
rule: { userOptions: [],
name: [ rule: {
{required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'}, name: [
{max: 50, message: this.$t('test_track.length_less_than') + '50', trigger: 'blur'} {required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'},
], {max: 50, message: this.$t('test_track.length_less_than') + '50', trigger: 'blur'}
principal: [{ ],
required: true, principal: [{
message: this.$t('api_test.automation.scenario.select_principal'), required: true,
trigger: 'change' message: this.$t('api_test.automation.scenario.select_principal'),
}], trigger: 'change'
}, }],
} },
} }
, }
methods: { ,
saveScenario(saveAs) { methods: {
this.$refs['scenarioForm'].validate((valid) => { saveScenario(saveAs) {
if (valid) { this.$refs['scenarioForm'].validate((valid) => {
let path = "/api/automation/create"; if (valid) {
this.setParameter(); let path = "/api/automation/create";
this.result = this.$post(path, this.scenarioForm, () => { this.setParameter();
this.visible = false; this.$fileUpload(path, null, [], this.scenarioForm, () => {
if (saveAs) { this.visible = false;
this.scenarioForm.request = JSON.stringify(this.scenarioForm.request); if (saveAs) {
this.$parent.saveAsEdit(this.scenarioForm); this.scenarioForm.request = JSON.stringify(this.scenarioForm.request);
} else { this.$parent.saveAsEdit(this.scenarioForm);
this.$parent.refresh(this.currentModule); } else {
} this.$parent.refresh(this.currentModule);
}); }
} else { });
return false; } else {
} return false;
}) }
}, })
setParameter() { },
this.scenarioForm.projectId = getCurrentProjectID(); setParameter() {
this.scenarioForm.id = getUUID().substring(0, 8); this.scenarioForm.projectId = getCurrentProjectID();
this.scenarioForm.protocol = this.currentProtocol; this.scenarioForm.id = getUUID().substring(0, 8);
if (this.currentModule != null) { this.scenarioForm.protocol = this.currentProtocol;
this.scenarioForm.modulePath = this.currentModule.method !== undefined ? this.currentModule.method : null; if (this.currentModule != null && this.currentModule != "newId") {
this.scenarioForm.apiScenarioModuleId = this.currentModule.id; this.scenarioForm.modulePath = this.currentModule.method !== undefined ? this.currentModule.method : null;
this.scenarioForm.apiScenarioModuleId = this.currentModule.id;
}
},
getMaintainerOptions() {
let workspaceId = localStorage.getItem(WORKSPACE_ID);
this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {
this.userOptions = response.data;
});
},
open(currentModule) {
this.scenarioForm = {principal: getCurrentUser().id};
this.currentModule = currentModule;
this.getMaintainerOptions();
this.visible = true;
} }
},
getMaintainerOptions() {
let workspaceId = localStorage.getItem(WORKSPACE_ID);
this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {
this.userOptions = response.data;
});
},
open(currentModule) {
this.scenarioForm = {principal: getCurrentUser().id};
this.currentModule = currentModule;
this.getMaintainerOptions();
this.visible = true;
} }
} }
}
</script> </script>

View File

@ -41,7 +41,7 @@
</el-input> </el-input>
</div> </div>
<p class="tip">{{$t('api_test.definition.request.req_param')}} </p> <p class="tip">{{$t('api_test.definition.request.req_param')}} </p>
<ms-api-request-form :headers="request.headers " :request="request" v-if="request.protocol==='HTTP'"/> <ms-api-request-form :referenced="true" :headers="request.headers " :request="request" v-if="request.protocol==='HTTP'"/>
<ms-tcp-basis-parameters :request="request" v-if="request.protocol==='TCP'"/> <ms-tcp-basis-parameters :request="request" v-if="request.protocol==='TCP'"/>
<ms-sql-basis-parameters :request="request" v-if="request.protocol==='SQL'"/> <ms-sql-basis-parameters :request="request" v-if="request.protocol==='SQL'"/>
<ms-dubbo-basis-parameters :request="request" v-if="request.protocol==='DUBBO' || request.protocol==='dubbo://'"/> <ms-dubbo-basis-parameters :request="request" v-if="request.protocol==='DUBBO' || request.protocol==='dubbo://'"/>

View File

@ -265,6 +265,7 @@
const children = parent.data.children || parent.data const children = parent.data.children || parent.data
const index = children.findIndex(d => d.id !== undefined && data.id !== undefined && d.id === data.id) const index = children.findIndex(d => d.id !== undefined && data.id !== undefined && d.id === data.id)
children.splice(index, 1); children.splice(index, 1);
this.getApiModuleTree();
}); });
}, },

View File

@ -476,7 +476,7 @@
request.enable === undefined ? request.enable = true : request.enable; request.enable === undefined ? request.enable = true : request.enable;
request.active = false; request.active = false;
request.resourceId = getUUID(); request.resourceId = getUUID();
if (referenced === 'REF') { if (referenced === 'REF' || !request.hashTree) {
request.hashTree = []; request.hashTree = [];
} }
if (this.selectedTreeNode != undefined) { if (this.selectedTreeNode != undefined) {
@ -496,7 +496,7 @@
request.enable === undefined ? request.enable = true : request.enable; request.enable === undefined ? request.enable = true : request.enable;
request.active = false; request.active = false;
request.resourceId = getUUID(); request.resourceId = getUUID();
if (referenced === 'REF') { if (referenced === 'REF' || !request.hashTree) {
request.hashTree = []; request.hashTree = [];
} }
if (this.selectedTreeNode != undefined) { if (this.selectedTreeNode != undefined) {
@ -506,6 +506,8 @@
} }
}) })
this.apiListVisible = false; this.apiListVisible = false;
this.currentRow.cases = [];
this.currentRow.apis = [];
this.sort(); this.sort();
this.reload(); this.reload();
}, },
@ -861,7 +863,8 @@
/deep/ .el-step__icon.is-text { /deep/ .el-step__icon.is-text {
border: 1px solid; border: 1px solid;
} }
/deep/.el-drawer__header{
/deep/ .el-drawer__header {
margin-bottom: 0px; margin-bottom: 0px;
} }
</style> </style>

View File

@ -193,6 +193,7 @@
this.total = response.data.itemCount; this.total = response.data.itemCount;
this.tableData = response.data.listObject; this.tableData = response.data.listObject;
}); });
this.selectRows = new Set();
}, },
handleSelect(selection, row) { handleSelect(selection, row) {
row.hashTree = []; row.hashTree = [];

View File

@ -335,6 +335,9 @@
for (let index in response.data) { for (let index in response.data) {
let test = response.data[index]; let test = response.data[index];
test.request = JSON.parse(test.request); test.request = JSON.parse(test.request);
if (!test.request.hashTree) {
test.request.hashTree = [];
}
} }
this.apiCaseList = response.data; this.apiCaseList = response.data;
if (this.apiCaseList.length == 0) { if (this.apiCaseList.length == 0) {

View File

@ -77,6 +77,9 @@
} else { } else {
this.reqUrl = "/api/definition/create"; this.reqUrl = "/api/definition/create";
} }
if (!this.request.hashTree) {
this.request.hashTree = [];
}
}, },
methods: { methods: {
runTest(data) { runTest(data) {

View File

@ -275,6 +275,9 @@
handleTestCase(api) { handleTestCase(api) {
this.selectApi = api; this.selectApi = api;
let request = JSON.parse(api.request); let request = JSON.parse(api.request);
if (!request.hashTree) {
request.hashTree = [];
}
this.selectApi.url = request.path; this.selectApi.url = request.path;
this.$refs.caseList.open(this.selectApi); this.$refs.caseList.open(this.selectApi);
}, },

View File

@ -2,7 +2,7 @@
<el-row> <el-row>
<el-col :span="21"> <el-col :span="21">
<!-- HTTP 请求参数 --> <!-- HTTP 请求参数 -->
<div style="border:1px #DCDFE6 solid; height: 100%;border-radius: 4px ;width: 100%"> <div style="border:1px #DCDFE6 solid; height: 100%;border-radius: 4px ;width: 100%" v-loading="isReloadData">
<el-tabs v-model="activeName" class="request-tabs"> <el-tabs v-model="activeName" class="request-tabs">
<!-- 请求头--> <!-- 请求头-->
<el-tab-pane :label="$t('api_test.request.headers')" name="headers"> <el-tab-pane :label="$t('api_test.request.headers')" name="headers">
@ -58,23 +58,23 @@
</el-tabs> </el-tabs>
</div> </div>
<div v-if="!referenced">
<div v-for="row in request.hashTree" :key="row.id" v-loading="isReloadData"> <div v-for="row in request.hashTree" :key="row.id">
<!-- 前置脚本 --> <!-- 前置脚本 -->
<ms-jsr233-processor v-if="row.label ==='JSR223 PreProcessor'" @copyRow="copyRow" @remove="remove" :is-read-only="false" :title="$t('api_test.definition.request.pre_script')" style-type="color: #B8741A;background-color: #F9F1EA" <ms-jsr233-processor v-if="row.label ==='JSR223 PreProcessor'" @copyRow="copyRow" @remove="remove" :is-read-only="false" :title="$t('api_test.definition.request.pre_script')" style-type="color: #B8741A;background-color: #F9F1EA"
:jsr223-processor="row"/> :jsr223-processor="row"/>
<!--后置脚本--> <!--后置脚本-->
<ms-jsr233-processor v-if="row.label ==='JSR223 PostProcessor'" @copyRow="copyRow" @remove="remove" :is-read-only="false" :title="$t('api_test.definition.request.post_script')" style-type="color: #783887;background-color: #F2ECF3" <ms-jsr233-processor v-if="row.label ==='JSR223 PostProcessor'" @copyRow="copyRow" @remove="remove" :is-read-only="false" :title="$t('api_test.definition.request.post_script')" style-type="color: #783887;background-color: #F2ECF3"
:jsr223-processor="row"/> :jsr223-processor="row"/>
<!--断言规则--> <!--断言规则-->
<ms-api-assertions v-if="row.type==='Assertions'" @copyRow="copyRow" @remove="remove" :is-read-only="isReadOnly" :assertions="row"/> <ms-api-assertions v-if="row.type==='Assertions'" @copyRow="copyRow" @remove="remove" :is-read-only="isReadOnly" :assertions="row"/>
<!--提取规则--> <!--提取规则-->
<ms-api-extract :is-read-only="isReadOnly" @copyRow="copyRow" @remove="remove" v-if="row.type==='Extract'" :extract="row"/> <ms-api-extract :is-read-only="isReadOnly" @copyRow="copyRow" @remove="remove" v-if="row.type==='Extract'" :extract="row"/>
</div>
</div> </div>
</el-col> </el-col>
<!--操作按钮--> <!--操作按钮-->
<el-col :span="3" class="ms-left-cell"> <el-col :span="3" class="ms-left-cell" v-if="!referenced">
<el-button class="ms-left-buttion" size="small" @click="addPre">+{{$t('api_test.definition.request.pre_script')}}</el-button> <el-button class="ms-left-buttion" size="small" @click="addPre">+{{$t('api_test.definition.request.pre_script')}}</el-button>
<br/> <br/>
<el-button class="ms-left-buttion" size="small" @click="addPost">+{{$t('api_test.definition.request.post_script')}}</el-button> <el-button class="ms-left-buttion" size="small" @click="addPost">+{{$t('api_test.definition.request.post_script')}}</el-button>
@ -116,6 +116,7 @@
return []; return [];
} }
}, },
referenced: Boolean,
isShowEnable: Boolean, isShowEnable: Boolean,
jsonPathList: Array, jsonPathList: Array,
isReadOnly: { isReadOnly: {

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="request-form"> <div class="request-form">
<component :is="component" :is-read-only="isReadOnly" :request="request" :headers="headers" :isShowEnable="isShowEnable"/> <component :is="component" :is-read-only="isReadOnly" :referenced="referenced" :request="request" :headers="headers" :isShowEnable="isShowEnable"/>
</div> </div>
</template> </template>
@ -17,6 +17,10 @@
type: Boolean, type: Boolean,
default: true default: true
}, },
referenced: {
type: Boolean,
default: false
},
isReadOnly: { isReadOnly: {
type: Boolean, type: Boolean,
default: false default: false

@ -1 +1 @@
Subproject commit a22a3005d9bd254793fcf634d72539cbdf31be3a Subproject commit 29a8fc09602fde5708af06582ac972d98eb69836