feat(接口自动化): 完成接口引用

This commit is contained in:
fit2-zhao 2020-12-10 12:46:14 +08:00
parent 1307b4d854
commit bc49f69ede
13 changed files with 60 additions and 7 deletions

View File

@ -4,6 +4,9 @@ import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.annotation.JSONType; import com.alibaba.fastjson.annotation.JSONType;
import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.api.dto.definition.request.assertions.MsAssertions; import io.metersphere.api.dto.definition.request.assertions.MsAssertions;
import io.metersphere.api.dto.definition.request.auth.MsAuthManager; import io.metersphere.api.dto.definition.request.auth.MsAuthManager;
import io.metersphere.api.dto.definition.request.configurations.MsHeaderManager; import io.metersphere.api.dto.definition.request.configurations.MsHeaderManager;
@ -16,6 +19,9 @@ import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
import io.metersphere.api.dto.definition.request.sampler.MsJDBCSampler; import io.metersphere.api.dto.definition.request.sampler.MsJDBCSampler;
import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler; import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler;
import io.metersphere.api.dto.definition.request.timer.MsConstantTimer; import io.metersphere.api.dto.definition.request.timer.MsConstantTimer;
import io.metersphere.api.service.ApiDefinitionService;
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.LogUtil;
import lombok.Data; import lombok.Data;
import org.apache.jmeter.protocol.http.control.AuthManager; import org.apache.jmeter.protocol.http.control.AuthManager;
@ -50,7 +56,7 @@ import java.util.List;
MsJSR223PreProcessor.class, MsTestPlan.class, MsThreadGroup.class, AuthManager.class, MsAssertions.class, MsJSR223PreProcessor.class, MsTestPlan.class, MsThreadGroup.class, AuthManager.class, MsAssertions.class,
MsExtract.class, MsTCPSampler.class, MsDubboSampler.class, MsJDBCSampler.class, MsConstantTimer.class, MsIfController.class, MsScenario.class}, typeKey = "type") MsExtract.class, MsTCPSampler.class, MsDubboSampler.class, MsJDBCSampler.class, MsConstantTimer.class, MsIfController.class, MsScenario.class}, typeKey = "type")
@Data @Data
public class MsTestElement { public abstract class MsTestElement {
private String type; private String type;
@JSONField(ordinal = 1) @JSONField(ordinal = 1)
private String id; private String id;
@ -106,6 +112,19 @@ public class MsTestElement {
return jmeterTestPlanHashTree; return jmeterTestPlanHashTree;
} }
public void getRefElement(MsTestElement element) {
try {
ApiDefinitionService apiDefinitionService = CommonBeanFactory.getBean(ApiDefinitionService.class);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
ApiDefinitionWithBLOBs apiDefinition = apiDefinitionService.getBLOBs(this.getId());
element = mapper.readValue(apiDefinition.getRequest(), new TypeReference<MsTestElement>() {
});
hashTree.add(element);
} catch (Exception ex) {
ex.printStackTrace();
}
}
} }

View File

@ -52,6 +52,13 @@ public class MsDubboSampler extends MsTestElement {
private List<KeyValue> attachmentArgs; private List<KeyValue> attachmentArgs;
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) { public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
if (this.getReferenced() != null && this.getReferenced().equals("Deleted")) {
return;
}
if (this.getReferenced() != null && this.getReferenced().equals("REF")) {
this.getRefElement(this);
}
final HashTree testPlanTree = new ListedHashTree(); final HashTree testPlanTree = new ListedHashTree();
testPlanTree.add(dubboConfig()); testPlanTree.add(dubboConfig());
tree.set(dubboSample(), testPlanTree); tree.set(dubboSample(), testPlanTree);

View File

@ -86,6 +86,9 @@ public class MsHTTPSamplerProxy extends MsTestElement {
private List<KeyValue> arguments; private List<KeyValue> arguments;
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) { public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
if (this.getReferenced() != null && this.getReferenced().equals("REF")) {
this.getRefElement(this);
}
HTTPSamplerProxy sampler = new HTTPSamplerProxy(); HTTPSamplerProxy sampler = new HTTPSamplerProxy();
sampler.setEnabled(true); sampler.setEnabled(true);
sampler.setName(this.getName()); sampler.setName(this.getName());

View File

@ -40,6 +40,9 @@ public class MsJDBCSampler extends MsTestElement {
private String environmentId; private String environmentId;
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) { public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
if (this.getReferenced() != null && this.getReferenced().equals("REF")) {
this.getRefElement(this);
}
final HashTree samplerHashTree = tree.add(jdbcSampler()); final HashTree samplerHashTree = tree.add(jdbcSampler());
tree.add(jdbcDataSource()); tree.add(jdbcDataSource());
tree.add(arguments(this.getName() + " Variables", this.getVariables())); tree.add(arguments(this.getName() + " Variables", this.getVariables()));

View File

@ -50,6 +50,9 @@ public class MsTCPSampler extends MsTestElement {
private String request; private String request;
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) { public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
if (this.getReferenced() != null && this.getReferenced().equals("REF")) {
this.getRefElement(this);
}
final HashTree samplerHashTree = new ListedHashTree(); final HashTree samplerHashTree = new ListedHashTree();
samplerHashTree.add(tcpConfig()); samplerHashTree.add(tcpConfig());
tree.set(tcpSampler(), samplerHashTree); tree.set(tcpSampler(), samplerHashTree);

View File

@ -105,6 +105,10 @@ public class ApiDefinitionService {
return apiDefinitionMapper.selectByPrimaryKey(id); return apiDefinitionMapper.selectByPrimaryKey(id);
} }
public ApiDefinitionWithBLOBs getBLOBs(String id) {
return apiDefinitionMapper.selectByPrimaryKey(id);
}
public void create(SaveApiDefinitionRequest request, List<MultipartFile> bodyFiles) { public void create(SaveApiDefinitionRequest request, List<MultipartFile> bodyFiles) {
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds()); List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
createTest(request); createTest(request);

View File

@ -12,7 +12,7 @@
<i class="icon el-icon-arrow-right" :class="{'is-active': request.active}" <i class="icon el-icon-arrow-right" :class="{'is-active': request.active}"
@click="active(request)" v-if="request.referenced!=undefined && request.referenced!='Deleted' && request.referenced!='REF'"/> @click="active(request)" v-if="request.referenced!=undefined && request.referenced!='Deleted' && request.referenced!='REF'"/>
<span>{{request.type!= 'create' ? request.name:''}} </span> <span>{{request.type!= 'create' ? request.name:''}} </span>
<el-tag size="mini" style="margin-left: 20px" v-if="request.referenced==='Deleted'" type="danger">引用不存在</el-tag> <el-tag size="mini" style="margin-left: 20px" v-if="request.referenced==='Deleted'" type="danger">{{$t('api_test.automation.reference_deleted')}}</el-tag>
<el-tag size="mini" style="margin-left: 20px" v-if="request.referenced ==='REF'">{{ $t('api_test.scenario.reference') }}</el-tag> <el-tag size="mini" style="margin-left: 20px" v-if="request.referenced ==='REF'">{{ $t('api_test.scenario.reference') }}</el-tag>
<el-button size="mini" type="danger" icon="el-icon-delete" circle @click="remove" style="margin-right: 20px; float: right"/> <el-button size="mini" type="danger" icon="el-icon-delete" circle @click="remove" style="margin-right: 20px; float: right"/>
@ -62,6 +62,17 @@
return {loading: false, reqOptions: REQ_METHOD,} return {loading: false, reqOptions: REQ_METHOD,}
}, },
created() { created() {
if (this.request.id && this.request.referenced === 'REF') {
this.$get("/api/definition/get/" + this.request.id, response => {
if (response.data) {
this.request.name = response.data.name;
this.reload();
} else {
this.request.referenced = "Deleted";
}
})
}
if (this.request.protocol === 'HTTP') { if (this.request.protocol === 'HTTP') {
try { try {
let urlObject = new URL(this.request.url); let urlObject = new URL(this.request.url);

View File

@ -6,7 +6,7 @@
<div class="el-step__icon-inner">{{scenario.index}}</div> <div class="el-step__icon-inner">{{scenario.index}}</div>
</div> </div>
<div style="margin-left: 20px;float: left"> {{scenario.name}}</div> <div style="margin-left: 20px;float: left"> {{scenario.name}}</div>
<el-tag size="mini" style="margin-left: 20px" v-if="scenario.referenced==='Deleted'" type="danger">引用不存在</el-tag> <el-tag size="mini" style="margin-left: 20px" v-if="scenario.referenced==='Deleted'" type="danger">{{$t('api_test.automation.reference_deleted')}}</el-tag>
<el-tag size="mini" style="margin-left: 20px" v-if="scenario.referenced==='REF'">{{ $t('api_test.scenario.reference') }}</el-tag> <el-tag size="mini" style="margin-left: 20px" v-if="scenario.referenced==='REF'">{{ $t('api_test.scenario.reference') }}</el-tag>
<el-button size="mini" type="danger" icon="el-icon-delete" circle @click="remove" style="margin-right: 20px; float: right"/> <el-button size="mini" type="danger" icon="el-icon-delete" circle @click="remove" style="margin-right: 20px; float: right"/>
</el-row> </el-row>

View File

@ -239,8 +239,8 @@
<!--接口列表--> <!--接口列表-->
<el-drawer :visible.sync="apiListVisible" :destroy-on-close="true" direction="ltr" :withHeader="false" :title="$t('api_test.automation.api_list_import')" :modal="false" size="90%"> <el-drawer :visible.sync="apiListVisible" :destroy-on-close="true" direction="ltr" :withHeader="false" :title="$t('api_test.automation.api_list_import')" :modal="false" size="90%">
<ms-api-definition :visible="true" :currentRow="currentRow"/> <ms-api-definition :visible="true" :currentRow="currentRow"/>
<!--<el-button style="float: right;margin: 20px" type="primary" @click="copyApi('REF')">{{$t('api_test.scenario.reference')}}</el-button>--> <el-button style="float: right;margin: 0px 20px 0px" type="primary" @click="copyApi('REF')">{{$t('api_test.scenario.reference')}}</el-button>
<el-button style="float: right;margin: 0px 20px 0px" type="primary" @click="copyApi('Copy')">{{ $t('commons.copy') }}</el-button> <el-button style="float: right;" type="primary" @click="copyApi('Copy')">{{ $t('commons.copy') }}</el-button>
</el-drawer> </el-drawer>
<!--自定义接口--> <!--自定义接口-->
@ -362,7 +362,7 @@
watch: {}, watch: {},
methods: { methods: {
nodeClick(e) { nodeClick(e) {
if (e.referenced != 'REF') { if (e.referenced != 'REF' && e.referenced != 'Deleted') {
this.operatingElements = ELEMENTS.get(e.type); this.operatingElements = ELEMENTS.get(e.type);
} else { } else {
this.operatingElements = []; this.operatingElements = [];

@ -1 +1 @@
Subproject commit a22a3005d9bd254793fcf634d72539cbdf31be3a Subproject commit 8a972a198775b3783ed6e4cef27197e53d1ebdc8

View File

@ -584,6 +584,7 @@ export default {
}, },
report_name_info: 'Please enter the registration name', report_name_info: 'Please enter the registration name',
save_case_info: 'Please save the use case first', save_case_info: 'Please save the use case first',
reference_deleted: 'Reference deleted',
}, },
environment: { environment: {
name: "Environment Name", name: "Environment Name",

View File

@ -583,6 +583,7 @@ export default {
}, },
report_name_info: '请输入报名名称', report_name_info: '请输入报名名称',
save_case_info: '请先保存用例', save_case_info: '请先保存用例',
reference_deleted: '引用已删除',
}, },
environment: { environment: {
name: "环境名称", name: "环境名称",

View File

@ -583,6 +583,7 @@ export default {
}, },
report_name_info: '請輸入報名名稱', report_name_info: '請輸入報名名稱',
save_case_info: '請先保存用例', save_case_info: '請先保存用例',
reference_deleted: '引用已删除',
}, },
environment: { environment: {
name: "環境名稱", name: "環境名稱",