feat(接口测试): TCP-Mock的期望设置中针对xml参数增加范围值选项

TCP-Mock的期望设置中针对xml参数增加范围值选项
This commit is contained in:
song-tianyang 2022-02-18 16:21:25 +08:00 committed by CountryBuilder
parent c0c19d214e
commit 0ea9c0b748
13 changed files with 396 additions and 137 deletions

View File

@ -1,5 +1,6 @@
package io.metersphere.api.controller; package io.metersphere.api.controller;
import io.metersphere.api.dto.automation.TcpTreeTableDataStruct;
import io.metersphere.api.dto.mock.MockParamSuggestions; import io.metersphere.api.dto.mock.MockParamSuggestions;
import io.metersphere.api.dto.mock.MockTestDataRequest; import io.metersphere.api.dto.mock.MockTestDataRequest;
import io.metersphere.api.dto.mockconfig.MockConfigRequest; import io.metersphere.api.dto.mockconfig.MockConfigRequest;
@ -82,4 +83,10 @@ public class MockConfigController {
return testDataUtil.parseTestDataByRequest(requestArray); return testDataUtil.parseTestDataByRequest(requestArray);
} }
@PostMapping("/getTcpMockTestData")
public List<TcpTreeTableDataStruct> getTcpMockTestData(@RequestBody List<TcpTreeTableDataStruct> requestArray) {
MockTestDataUtil testDataUtil = new MockTestDataUtil();
return testDataUtil.parseTestDataByTcpTreeTableData(requestArray);
}
} }

View File

@ -28,6 +28,7 @@ public class TcpTreeTableDataStruct {
private String type; private String type;
private String systemName; private String systemName;
private String contentType; private String contentType;
private String condition;
private boolean required; private boolean required;
private String description; private String description;
private List<TcpTreeTableDataStruct> children; private List<TcpTreeTableDataStruct> children;
@ -114,7 +115,6 @@ public class TcpTreeTableDataStruct {
try { try {
element = document.addElement(this.name); element = document.addElement(this.name);
if (StringUtils.equalsAnyIgnoreCase(type, "string", "array")) { if (StringUtils.equalsAnyIgnoreCase(type, "string", "array")) {
long lengthNum = Long.parseLong(this.contentType);
String attrString = ""; String attrString = "";
if (StringUtils.equalsIgnoreCase(this.type, "string")) { if (StringUtils.equalsIgnoreCase(this.type, "string")) {
attrString = "s," + contentType; attrString = "s," + contentType;
@ -153,7 +153,6 @@ public class TcpTreeTableDataStruct {
try { try {
element = document.addElement(this.name); element = document.addElement(this.name);
if (StringUtils.equalsAnyIgnoreCase(type, "string", "array")) { if (StringUtils.equalsAnyIgnoreCase(type, "string", "array")) {
long lengthNum = Long.parseLong(this.contentType);
String attrString = ""; String attrString = "";
if (StringUtils.equalsIgnoreCase(this.type, "string")) { if (StringUtils.equalsIgnoreCase(this.type, "string")) {
attrString = "s," + contentType; attrString = "s," + contentType;

View File

@ -1,12 +1,17 @@
package io.metersphere.api.dto.automation.parse; package io.metersphere.api.dto.automation.parse;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.metersphere.api.dto.automation.TcpTreeTableDataStruct; import io.metersphere.api.dto.automation.TcpTreeTableDataStruct;
import io.metersphere.api.dto.mock.MockConfigRequestParams;
import io.metersphere.api.mock.utils.MockApiUtils;
import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.LogUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.DocumentHelper; import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat; import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter; import org.dom4j.io.XMLWriter;
import org.springframework.util.CollectionUtils;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
@ -32,11 +37,11 @@ public class TcpTreeTableDataParser {
Document document = DocumentHelper.createDocument(); Document document = DocumentHelper.createDocument();
TcpTreeTableDataStruct dataStruct = null; TcpTreeTableDataStruct dataStruct = null;
if(treeDataList.size()>1){ if (treeDataList.size() > 1) {
dataStruct = new TcpTreeTableDataStruct(); dataStruct = new TcpTreeTableDataStruct();
dataStruct.setName("ROOT"); dataStruct.setName("ROOT");
dataStruct.setChildren(treeDataList); dataStruct.setChildren(treeDataList);
}else { } else {
dataStruct = treeDataList.get(0); dataStruct = treeDataList.get(0);
} }
@ -77,4 +82,60 @@ public class TcpTreeTableDataParser {
return xmlString; return xmlString;
} }
public static boolean isMatchTreeTableData(JSONObject sourceObj, List<TcpTreeTableDataStruct> tcpDataList) {
if (CollectionUtils.isEmpty(tcpDataList)) {
return true;
}
if (sourceObj == null) {
sourceObj = new JSONObject();
}
boolean isMatch = false;
for (TcpTreeTableDataStruct dataStruct : tcpDataList) {
if(isMatch){
break;
}
String key = dataStruct.getName();
if (sourceObj.containsKey(key)) {
Object sourceObjItem = sourceObj.get(key);
if (sourceObjItem instanceof JSONObject) {
if (!CollectionUtils.isEmpty(dataStruct.getChildren())) {
if (!isMatchTreeTableData((JSONObject) sourceObjItem, dataStruct.getChildren())) {
continue;
}
} else {
continue;
}
} else if (sourceObjItem instanceof JSONArray) {
if (!CollectionUtils.isEmpty(dataStruct.getChildren())) {
JSONArray jsonArray = (JSONArray) sourceObjItem;
for (int i = 0; i < jsonArray.size(); i ++){
Object itemObj = jsonArray.get(i);
if(itemObj instanceof JSONObject){
if (!isMatchTreeTableData((JSONObject) itemObj, dataStruct.getChildren())) {
continue;
}
}else {
continue;
}
}
} else {
continue;
}
} else {
String sourceValues = String.valueOf(sourceObjItem);
MockConfigRequestParams mockParams = new MockConfigRequestParams();
mockParams.setKey(dataStruct.getName());
mockParams.setValue(dataStruct.getValue());
mockParams.setCondition(dataStruct.getCondition());
if (!MockApiUtils.isValueMatch(sourceValues, mockParams)) {
continue;
}
}
}
isMatch = true;
}
return isMatch;
}
} }

View File

@ -701,7 +701,7 @@ public class MockApiUtils {
return false; return false;
} }
private static boolean isValueMatch(String requestParam, MockConfigRequestParams params) { public static boolean isValueMatch(String requestParam, MockConfigRequestParams params) {
if (StringUtils.equals(params.getCondition(), MockParamConditionEnum.VALUE_EQUALS.name())) { if (StringUtils.equals(params.getCondition(), MockParamConditionEnum.VALUE_EQUALS.name())) {
return StringUtils.equals(requestParam, params.getValue()); return StringUtils.equals(requestParam, params.getValue());
} else if (StringUtils.equals(params.getCondition(), MockParamConditionEnum.VALUE_NOT_EQUALS.name())) { } else if (StringUtils.equals(params.getCondition(), MockParamConditionEnum.VALUE_NOT_EQUALS.name())) {

View File

@ -1,11 +1,13 @@
package io.metersphere.api.mock.utils; package io.metersphere.api.mock.utils;
import com.mifmif.common.regex.Generex; import com.mifmif.common.regex.Generex;
import io.metersphere.api.dto.automation.TcpTreeTableDataStruct;
import io.metersphere.api.dto.mock.MockTestDataRequest; import io.metersphere.api.dto.mock.MockTestDataRequest;
import io.metersphere.api.mock.dto.MockParamConditionEnum; import io.metersphere.api.mock.dto.MockParamConditionEnum;
import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.LogUtil;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import java.util.List; import java.util.List;
@ -50,4 +52,49 @@ public class MockTestDataUtil {
return ""; return "";
} }
} }
public String getTestData(TcpTreeTableDataStruct condition) {
if (StringUtils.equals(MockApiUtils.parseCondition(condition.getCondition()), MockParamConditionEnum.VALUE_EQUALS.name())) {
return condition.getValue();
} else if (StringUtils.equalsAny(MockApiUtils.parseCondition(condition.getCondition()), MockParamConditionEnum.VALUE_CONTAINS.name(), MockParamConditionEnum.VALUE_NOT_EQUALS.name())) {
return condition.getValue() + "A";
} else if (StringUtils.equals(MockApiUtils.parseCondition(condition.getCondition()), MockParamConditionEnum.LENGTH_EQUALS.name())) {
int length = Integer.parseInt(condition.getValue());
return RandomStringUtils.randomAlphanumeric(length);
} else if (StringUtils.equalsAny(MockApiUtils.parseCondition(condition.getCondition()), MockParamConditionEnum.LENGTH_NOT_EQUALS.name(), MockParamConditionEnum.LENGTH_LARGE_THAN.name())) {
int length = Integer.parseInt(condition.getValue()) + 1;
return RandomStringUtils.randomAlphanumeric(length);
} else if (StringUtils.equals(MockApiUtils.parseCondition(condition.getCondition()), MockParamConditionEnum.LENGTH_SHOT_THAN.name())) {
int length = Integer.parseInt(condition.getValue());
if(length > 1){
return RandomStringUtils.randomAlphanumeric(length);
}else {
return "";
}
} else if (StringUtils.equals(MockApiUtils.parseCondition(condition.getCondition()), MockParamConditionEnum.REGULAR_MATCH.name())) {
if (StringUtils.isNotEmpty(condition.getValue())) {
Generex generex = new Generex(condition.getValue());
String randomStr = generex.random();
return randomStr;
}else {
return "";
}
} else {
return "";
}
}
public List<TcpTreeTableDataStruct> parseTestDataByTcpTreeTableData(List<TcpTreeTableDataStruct> requestArray) {
for (TcpTreeTableDataStruct request : requestArray) {
try{
request.setValue(this.getTestData(request));
if(!CollectionUtils.isEmpty(request.getChildren())){
this.parseTestDataByTcpTreeTableData(request.getChildren());
}
}catch (Exception e){
LogUtil.error(e);
}
}
return requestArray;
}
} }

View File

@ -1292,15 +1292,12 @@ public class MockConfigService {
} else if (isXMLMessage && StringUtils.equalsIgnoreCase(reportType, "xml")) { } else if (isXMLMessage && StringUtils.equalsIgnoreCase(reportType, "xml")) {
if (requestJson.containsKey("xmlDataStruct")) { if (requestJson.containsKey("xmlDataStruct")) {
JSONObject sourceObj = XMLUtils.XmlToJson(message); JSONObject sourceObj = XMLUtils.XmlToJson(message);
String xmlStr = "";
try { try {
List<TcpTreeTableDataStruct> tcpDataList = JSONArray.parseArray(requestJson.getString("xmlDataStruct"), TcpTreeTableDataStruct.class); List<TcpTreeTableDataStruct> tcpDataList = JSONArray.parseArray(requestJson.getString("xmlDataStruct"), TcpTreeTableDataStruct.class);
xmlStr = TcpTreeTableDataParser.treeTableData2Xml(tcpDataList); isMatch = TcpTreeTableDataParser.isMatchTreeTableData(sourceObj,tcpDataList);
} catch (Exception e) { } catch (Exception e) {
LogUtil.error(e); LogUtil.error(e);
} }
JSONObject matchObj = XMLUtils.XmlToJson(xmlStr);
isMatch = JsonStructUtils.checkJsonObjCompliance(sourceObj, matchObj);
} }
} else if (StringUtils.equalsIgnoreCase(reportType, "raw")) { } else if (StringUtils.equalsIgnoreCase(reportType, "raw")) {
if (requestJson.containsKey("rawDataStruct")) { if (requestJson.containsKey("rawDataStruct")) {

View File

@ -16,6 +16,7 @@ public class TCPServicer {
private InputStream is; private InputStream is;
private OutputStream os; private OutputStream os;
private int port; private int port;
public TCPServicer(Socket s, int port) { public TCPServicer(Socket s, int port) {
this.s = s; this.s = s;
this.port = port; this.port = port;
@ -29,49 +30,50 @@ public class TCPServicer {
is = s.getInputStream(); is = s.getInputStream();
os = s.getOutputStream(); os = s.getOutputStream();
int len = is.read(b); int len = is.read(b);
message = new String(b,0,len); message = new String(b, 0, len);
returnMsg = this.getReturnMsg(message); returnMsg = this.getReturnMsg(message);
os.write(returnMsg.getBytes()); os.write(returnMsg.getBytes());
} catch (Exception e) { } catch (Exception e) {
LogUtil.error(e); LogUtil.error(e);
}finally { } finally {
this.close(); this.close();
} }
} }
private String getReturnMsg(String message) { private String getReturnMsg(String message) {
LogUtil.info("TCP-Mock start. port: " + this.port + "; Message:" + message);
MockConfigService mockConfigService = CommonBeanFactory.getBean(MockConfigService.class); MockConfigService mockConfigService = CommonBeanFactory.getBean(MockConfigService.class);
MockExpectConfigWithBLOBs matchdMockExpect = mockConfigService.matchTcpMockExpect(message,this.port); MockExpectConfigWithBLOBs matchdMockExpect = mockConfigService.matchTcpMockExpect(message, this.port);
String returnMsg = ""; String returnMsg = "";
if(matchdMockExpect != null){ if (matchdMockExpect != null) {
String response = matchdMockExpect.getResponse(); String response = matchdMockExpect.getResponse();
JSONObject responseObj = JSONObject.parseObject(response); JSONObject responseObj = JSONObject.parseObject(response);
int delayed = 0; int delayed = 0;
try { try {
if(responseObj.containsKey("delayed")){ if (responseObj.containsKey("delayed")) {
delayed = responseObj.getInteger("delayed"); delayed = responseObj.getInteger("delayed");
} }
} catch (Exception e) { } catch (Exception e) {
LogUtil.error(e); LogUtil.error(e);
} }
if(responseObj.containsKey("responseResult")){ if (responseObj.containsKey("responseResult")) {
JSONObject respResultObj = responseObj.getJSONObject("responseResult"); JSONObject respResultObj = responseObj.getJSONObject("responseResult");
if(respResultObj.containsKey("body")){ if (respResultObj.containsKey("body")) {
MockApiUtils mockApiUtils = new MockApiUtils(); MockApiUtils mockApiUtils = new MockApiUtils();
boolean useScript = false; boolean useScript = false;
if(respResultObj.containsKey("usePostScript")){ if (respResultObj.containsKey("usePostScript")) {
useScript = respResultObj.getBoolean("usePostScript"); useScript = respResultObj.getBoolean("usePostScript");
} }
returnMsg = mockApiUtils.getResultByResponseResult(respResultObj.getJSONObject("body"),"",null,null,useScript); returnMsg = mockApiUtils.getResultByResponseResult(respResultObj.getJSONObject("body"), "", null, null, useScript);
} }
try { try {
if(respResultObj.containsKey("delayed")){ if (respResultObj.containsKey("delayed")) {
delayed = respResultObj.getInteger("delayed"); delayed = respResultObj.getInteger("delayed");
} }
} catch (Exception e) { } catch (Exception e) {
LogUtil.error(e); LogUtil.error(e);
} }
}else { } else {
returnMsg = responseObj.getString("body"); returnMsg = responseObj.getString("body");
} }
@ -86,16 +88,20 @@ public class TCPServicer {
public void close() { public void close() {
//关闭资源 //关闭资源
try{ try {
is.close(); is.close();
}catch (Exception e){}finally { } catch (Exception e) {
try{ LogUtil.error(e);
} finally {
try {
os.close(); os.close();
}catch (Exception e){}finally { } catch (Exception e) {
try{ LogUtil.error(e);
} finally {
try {
s.close(); s.close();
}catch (Exception e){}finally { } catch (Exception e) {
LogUtil.error(e);
} }
} }
} }

View File

@ -71,13 +71,9 @@ public class XMLUtils {
} }
xml = xml.substring(begin + 2); xml = xml.substring(begin + 2);
} // <?xml version="1.0" encoding="utf-8"?> 若存在则去除 } // <?xml version="1.0" encoding="utf-8"?> 若存在则去除
String rgex = "\\s*"; String rgex = ">";
Pattern pattern = Pattern.compile(rgex); Pattern pattern = Pattern.compile(rgex);
Matcher m = pattern.matcher(xml); Matcher m = pattern.matcher(xml);
xml = m.replaceAll("");
rgex = ">";
pattern = Pattern.compile(rgex);
m = pattern.matcher(xml);
xml = m.replaceAll("> "); xml = m.replaceAll("> ");
rgex = "\\s*</"; rgex = "\\s*</";
pattern = Pattern.compile(rgex); pattern = Pattern.compile(rgex);

View File

@ -10,7 +10,7 @@
<el-table-column prop="name" :label="$t('api_test.definition.request.esb_table.name')" width="230"> <el-table-column prop="name" :label="$t('api_test.definition.request.esb_table.name')" width="230">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-if="scope.row.status" v-model="scope.row.name" style="width: 140px"></el-input> <el-input v-if="scope.row.status" v-model="scope.row.name" style="width: 140px"></el-input>
<span v-else>{{scope.row.name}}</span> <span v-else>{{ scope.row.name }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="type" :label="$t('api_test.definition.request.esb_table.type')" width="120"> <el-table-column prop="type" :label="$t('api_test.definition.request.esb_table.type')" width="120">
@ -19,33 +19,48 @@
<el-option v-for="item in typeSelectOptions " :key="item.value" :label="item.value" :value="item.value"> <el-option v-for="item in typeSelectOptions " :key="item.value" :label="item.value" :value="item.value">
</el-option> </el-option>
</el-select> </el-select>
<span v-else>{{scope.row.type}}</span> <span v-else>{{ scope.row.type }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="length" :label="$t('api_test.definition.request.esb_table.length')" width="80"> <el-table-column prop="length" :label="$t('api_test.definition.request.esb_table.length')" width="80">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-if="scope.row.status" v-model="scope.row.contentType"></el-input> <el-input v-if="scope.row.status" v-model="scope.row.contentType"></el-input>
<span v-else>{{scope.row.contentType}}</span> <span v-else>{{ scope.row.contentType }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="description" :label="$t('api_test.definition.request.esb_table.desc')" min-width="200"> <el-table-column prop="description" :label="$t('api_test.definition.request.esb_table.desc')" min-width="200">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-if="scope.row.status" v-model="scope.row.description"></el-input> <el-input v-if="scope.row.status" v-model="scope.row.description"></el-input>
<span v-else>{{scope.row.description}}</span> <span v-else>{{ scope.row.description }}</span>
</template>
</el-table-column>
<el-table-column v-if="showOperationCol" prop="condition" :label="$t('api_test.request.range')" width="200">
<template slot-scope="scope">
<el-select v-if="scope.row.status" :maxlength="100" v-model="scope.row.condition"
size="small" style="width: 100%">
<el-option
v-for="item in rangeTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"></el-option>
</el-select>
<span v-else>{{ parseRangeType(scope.row.condition) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="value" :label="$t('api_test.definition.request.esb_table.value')" width="180"> <el-table-column prop="value" :label="$t('api_test.definition.request.esb_table.value')" width="180">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-if="scope.row.status" v-model="scope.row.value"></el-input> <el-input v-if="scope.row.status" v-model="scope.row.value"></el-input>
<span v-else>{{scope.row.value}}</span> <span v-else>{{ scope.row.value }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column v-if="showOptionsButton" :label="$t('commons.operating')" width="140" fixed="right"> <el-table-column v-if="showOptionsButton" :label="$t('commons.operating')" width="140" fixed="right">
<template v-slot:default="scope"> <template v-slot:default="scope">
<span> <span>
<el-button size="mini" p="$t('commons.next_level')" icon="el-icon-plus" type="primary" circle @click="nextRow(scope.row)" <el-button size="mini" p="$t('commons.next_level')" icon="el-icon-plus" type="primary" circle
@click="nextRow(scope.row)"
class="ht-btn-confirm"/> class="ht-btn-confirm"/>
<el-button size="mini" p="$t('commons.copy')" icon="el-icon-copy-document" type="primary" circle @click="copyDataStructConfirm(scope.row)" <el-button size="mini" p="$t('commons.copy')" icon="el-icon-copy-document" type="primary" circle
@click="copyDataStructConfirm(scope.row)"
class="ht-btn-confirm"/> class="ht-btn-confirm"/>
<el-button size="mini" p="$t('commons.remove')" icon="el-icon-close" circle @click="remove(scope.row)" <el-button size="mini" p="$t('commons.remove')" icon="el-icon-close" circle @click="remove(scope.row)"
class="ht-btn-remove"/> class="ht-btn-remove"/>
@ -54,8 +69,12 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
<div v-if="showOptionsButton"> <div v-if="showOptionsButton">
<el-button class="ht-btn-add" size="mini" p="$t('commons.add')" icon="el-icon-circle-plus-outline" @click="add">{{$t("commons.add")}}</el-button> <el-button class="ht-btn-add" size="mini" p="$t('commons.add')" icon="el-icon-circle-plus-outline" @click="add">
<el-button class="ht-btn-add" size="mini" p="$t('commons.add')" icon="el-icon-circle-plus-outline" @click="saveTableData">{{$t("commons.save")}}</el-button> {{ $t("commons.add") }}
</el-button>
<el-button class="ht-btn-add" size="mini" p="$t('commons.add')" icon="el-icon-circle-plus-outline"
@click="saveTableData">{{ $t("commons.save") }}
</el-button>
</div> </div>
</div> </div>
</template> </template>
@ -67,53 +86,134 @@ export default {
components: {}, components: {},
props: { props: {
tableData: Array, tableData: Array,
showOptionsButton:Boolean, showOptionsButton: Boolean,
showOperationCol: {
type: Boolean,
default: false
},
}, },
data() { data() {
return { return {
loading:false, loading: false,
typeSelectOptions:[ rangeTypeOptions: [
{ value: 'object', label: '[object]' }, {
{ value: 'string', label: '[string]' }, value: "",
{ value: 'array', label: '[array]' }, label: this.$t("commons.please_select"),
},
{
value: "value_eq",
label: this.$t("api_test.mock.range_type.value_eq"),
},
{
value: "value_not_eq",
label: this.$t("api_test.mock.range_type.value_not_eq"),
},
{
value: "value_contain",
label: this.$t("api_test.mock.range_type.value_contain"),
},
{
value: "length_eq",
label: this.$t("api_test.mock.range_type.length_eq"),
},
{
value: "length_not_eq",
label: this.$t("api_test.mock.range_type.length_not_eq"),
},
{
value: "length_large_than",
label: this.$t("api_test.mock.range_type.length_large_than"),
},
{
value: "length_shot_than",
label: this.$t("api_test.mock.range_type.length_shot_than"),
},
{
value: "regular_match",
label: this.$t("api_test.mock.range_type.regular_match"),
},
], ],
requiredSelectOptions:[ typeSelectOptions: [
{ value: true, label: '必填' }, {value: 'object', label: '[object]'},
{ value: false, label: '非必填' }, {value: 'string', label: '[string]'},
{value: 'array', label: '[array]'},
], ],
tableExpandRowKayArray:["name","systemName"], requiredSelectOptions: [
{value: true, label: '必填'},
{value: false, label: '非必填'},
],
tableExpandRowKayArray: ["name", "systemName"],
} }
}, },
created() { created() {
if(this.tableData && this.tableData.length>0){ if (this.tableData && this.tableData.length > 0) {
this.tableData.forEach(row => { this.tableData.forEach(row => {
if(row.name == null || row.name === ""){ if (row.name == null || row.name === "") {
this.remove(row); this.remove(row);
} }
}) })
} }
},
computed: {
}, },
methods: { methods: {
saveTableData:function(){ parseRangeType(type) {
this.$emit('saveTableData',this.tableData); if (!type) {
type = "";
}
let returnValue = null;
switch (type) {
case "value_eq":
returnValue = this.$t("api_test.mock.range_type.value_eq");
break;
case "value_not_eq":
returnValue = this.$t("api_test.mock.range_type.value_not_eq");
break;
case "value_contain":
returnValue = this.$t("api_test.mock.range_type.value_contain");
break;
case "length_eq":
returnValue = this.$t("api_test.mock.range_type.length_eq");
break;
case "length_not_eq":
returnValue = this.$t("api_test.mock.range_type.length_not_eq");
break;
case "length_large_than":
returnValue = this.$t("api_test.mock.range_type.length_large_than");
break;
case "length_shot_than":
returnValue = this.$t("api_test.mock.range_type.length_shot_than");
break;
case "regular_match":
returnValue = this.$t("api_test.mock.range_type.regular_match");
break;
default:
returnValue = "";
break;
}
return returnValue;
},
saveTableData: function () {
this.$emit('saveTableData', this.tableData);
}, },
remove: function (row) { remove: function (row) {
this.removeTableRow(row); this.removeTableRow(row);
}, },
add: function (r) { add: function (r) {
let row = this.getNewRow(null); let row = this.getNewRow(null);
this.pushTableData(row,"root"); this.pushTableData(row, "root");
}, },
nextRow:function (row) { nextRow: function (row) {
// //
let confirmRowFlag = this.confirm(row); let confirmRowFlag = this.confirm(row);
if(confirmRowFlag){ if (confirmRowFlag) {
let nextRow = this.getNewRow(null); let nextRow = this.getNewRow(null);
this.pushTableData(nextRow,row.uuid); this.pushTableData(nextRow, row.uuid);
} }
}, },
// //
copyDataStructConfirm:function (row){ copyDataStructConfirm: function (row) {
this.$alert(this.$t('api_test.definition.request.esb_copy_confirm') + " ", '', { this.$alert(this.$t('api_test.definition.request.esb_copy_confirm') + " ", '', {
confirmButtonText: this.$t('commons.confirm'), confirmButtonText: this.$t('commons.confirm'),
callback: (action) => { callback: (action) => {
@ -123,21 +223,21 @@ export default {
} }
}); });
}, },
copyDataStruct:function (row){ copyDataStruct: function (row) {
let parentRow = this.selectParentRow(this.tableData,row.uuid); let parentRow = this.selectParentRow(this.tableData, row.uuid);
let newRow = this.createNewId(row); let newRow = this.createNewId(row);
if(parentRow!=null){ if (parentRow != null) {
if(parentRow.children == null){ if (parentRow.children == null) {
parentRow.children = []; parentRow.children = [];
} }
parentRow.children.push(newRow); parentRow.children.push(newRow);
}else{ } else {
this.$emit('xmlTableDataPushRow',newRow); this.$emit('xmlTableDataPushRow', newRow);
} }
}, },
createNewId(row){ createNewId(row) {
let newRow = this.getNewRow(row); let newRow = this.getNewRow(row);
if(row.children!=null && row.children.length > 0){ if (row.children != null && row.children.length > 0) {
row.children.forEach(child => { row.children.forEach(child => {
let newChild = this.createNewId(child); let newChild = this.createNewId(child);
newRow.children.push(newChild); newRow.children.push(newChild);
@ -145,24 +245,24 @@ export default {
} }
return newRow; return newRow;
}, },
selectParentRow(dataStruct,rowId){ selectParentRow(dataStruct, rowId) {
let returnRow = null; let returnRow = null;
if(dataStruct == null || dataStruct.length === 0){ if (dataStruct == null || dataStruct.length === 0) {
return returnRow; return returnRow;
} }
dataStruct.forEach( itemData => { dataStruct.forEach(itemData => {
if(itemData.children != null && itemData.children.length > 0){ if (itemData.children != null && itemData.children.length > 0) {
itemData.children.forEach( child => { itemData.children.forEach(child => {
if(child.uuid === rowId){ if (child.uuid === rowId) {
returnRow = itemData; returnRow = itemData;
return returnRow; return returnRow;
} }
}); });
} }
if(returnRow == null ){ if (returnRow == null) {
if(itemData.children != null && itemData.children.length > 0){ if (itemData.children != null && itemData.children.length > 0) {
returnRow = this.selectParentRow(itemData.children,rowId); returnRow = this.selectParentRow(itemData.children, rowId);
if(returnRow!=null){ if (returnRow != null) {
return returnRow; return returnRow;
} }
} }
@ -177,13 +277,21 @@ export default {
} }
return false; return false;
}, },
getNewRow(param){ getNewRow(param) {
if(param == null ){ if (param == null) {
let row = { let row = {
name: '',systemName: '',status: 'edit',type: '[object]',contentType: '',required: false,description: '',uuid: this.uuid(),children: [] name: '',
systemName: '',
status: 'edit',
type: '[object]',
contentType: '',
required: false,
description: '',
uuid: this.uuid(),
children: []
} }
return row; return row;
}else{ } else {
let row = { let row = {
name: param.name, name: param.name,
systemName: param.systemName, systemName: param.systemName,
@ -199,15 +307,15 @@ export default {
} }
}, },
validateRowData(row) { validateRowData(row) {
if(row.name == null || row.name === ''){ if (row.name == null || row.name === '') {
// this.$warning(this.$t('load_test.input_ip')); // this.$warning(this.$t('load_test.input_ip'));
this.$warning("参数名"+"不能为空,且不能包含英文小数点[.]"); this.$warning("参数名" + "不能为空,且不能包含英文小数点[.]");
return false; return false;
}else if(row.name.indexOf(".")>0){ } else if (row.name.indexOf(".") > 0) {
this.$warning("参数名["+row.name+"]不合法,不能包含英文小数点\".\"!"); this.$warning("参数名[" + row.name + "]不合法,不能包含英文小数点\".\"!");
return false; return false;
}else if(row.type == null || row.type === ''){ } else if (row.type == null || row.type === '') {
this.$warning("类型"+"不能为空!"); this.$warning("类型" + "不能为空!");
return false; return false;
} }
return true; return true;
@ -218,48 +326,48 @@ export default {
uuid: function () { uuid: function () {
return (((1 + Math.random()) * 0x100000) | 0).toString(16).substring(1); return (((1 + Math.random()) * 0x100000) | 0).toString(16).substring(1);
}, },
pushTableData: function(dataRow,rowId){ pushTableData: function (dataRow, rowId) {
if(rowId === "" || rowId == null){ if (rowId === "" || rowId == null) {
if(this.tableData){ if (this.tableData) {
this.$emit("initXmlTableData"); this.$emit("initXmlTableData");
} }
this.$emit("xmlTablePushRow",dataRow); this.$emit("xmlTablePushRow", dataRow);
} else if(rowId === "root"){ } else if (rowId === "root") {
this.$emit("xmlTablePushRow",dataRow); this.$emit("xmlTablePushRow", dataRow);
}else { } else {
this.appendDataWithDeepForeach(this.tableData,rowId,dataRow); this.appendDataWithDeepForeach(this.tableData, rowId, dataRow);
} }
}, },
appendDataWithDeepForeach(datas,rowId,appendData){ appendDataWithDeepForeach(datas, rowId, appendData) {
datas.forEach( row => { datas.forEach(row => {
if(row.uuid === rowId){ if (row.uuid === rowId) {
if(row.children == null){ if (row.children == null) {
row.children = []; row.children = [];
} }
row.children.push(appendData); row.children.push(appendData);
}else if(row.children.length>0){ } else if (row.children.length > 0) {
let appendResult = this.appendDataWithDeepForeach(row.children,rowId,appendData); let appendResult = this.appendDataWithDeepForeach(row.children, rowId, appendData);
if(appendResult){ if (appendResult) {
return appendResult; return appendResult;
} }
} }
}); });
return false; return false;
}, },
removeTableRow: function (row){ removeTableRow: function (row) {
this.removeFromDataStruct(this.tableData,row); this.removeFromDataStruct(this.tableData, row);
}, },
removeFromDataStruct(dataStruct,row){ removeFromDataStruct(dataStruct, row) {
if(dataStruct == null || dataStruct.length === 0){ if (dataStruct == null || dataStruct.length === 0) {
return; return;
} }
let rowIndex = dataStruct.indexOf(row); let rowIndex = dataStruct.indexOf(row);
if(rowIndex >= 0){ if (rowIndex >= 0) {
dataStruct.splice(rowIndex,1); dataStruct.splice(rowIndex, 1);
}else { } else {
dataStruct.forEach( itemData => { dataStruct.forEach(itemData => {
if(itemData.children != null && itemData.children.length > 0){ if (itemData.children != null && itemData.children.length > 0) {
this.removeFromDataStruct(itemData.children,row); this.removeFromDataStruct(itemData.children, row);
} }
}); });
} }

View File

@ -106,6 +106,9 @@
}, },
setEnvironment(enviromentId){ setEnvironment(enviromentId){
this.currentData.environmentId = enviromentId; this.currentData.environmentId = enviromentId;
if (this.currentData.request) {
this.currentData.request.useEnvironment = enviromentId;
}
} }
} }
} }

View File

@ -16,7 +16,7 @@
<div class="base-info"> <div class="base-info">
<el-row> <el-row>
<tcp-params <tcp-params
v-if="isTcp" v-if="isTcp" :show-operation-col="true"
:request="mockExpectConfig.request" style="margin: 10px 10px;" ref="tcpParam"></tcp-params> :request="mockExpectConfig.request" style="margin: 10px 10px;" ref="tcpParam"></tcp-params>
<mock-request-param <mock-request-param
v-else v-else
@ -218,6 +218,9 @@ export default {
this.showDrawer = false; this.showDrawer = false;
}, },
saveMockExpectConfig() { saveMockExpectConfig() {
if(this.isTcp && this.$refs.tcpParam){
this.$refs.tcpParam.saveData();
}
let mockConfigId = this.mockConfigId; let mockConfigId = this.mockConfigId;
this.mockExpectConfig.mockConfigId = mockConfigId; this.mockExpectConfig.mockConfigId = mockConfigId;
let formCheckResult = this.checkMockExpectForm("mockExpectForm", true); let formCheckResult = this.checkMockExpectForm("mockExpectForm", true);

View File

@ -155,28 +155,51 @@ export default {
if (row && row.request) { if (row && row.request) {
requestParam = JSON.parse(JSON.stringify(row.request)); requestParam = JSON.parse(JSON.stringify(row.request));
} }
if(requestParam.params){ if (requestParam.xmlDataStruct) {
this.getTcpMockTestData(requestParam);
} else {
this.getHttpMockTestData(requestParam);
}
},
getTcpMockTestData(requestParam) {
if (requestParam && requestParam.xmlDataStruct) {
let selectParma = requestParam.xmlDataStruct;
//mock
this.$post("/mockConfig/getTcpMockTestData", selectParma, response => {
let returnData = response.data;
if (returnData) {
requestParam.xmlDataStruct = returnData;
}
this.$emit("redirectToTest", requestParam);
}, error => {
this.$emit("redirectToTest", requestParam);
});
}
},
getHttpMockTestData(requestParam) {
if (requestParam && requestParam.params) {
let selectParma = []; let selectParma = [];
if(requestParam.params.arguments && requestParam.params.arguments.length > 0){ if (requestParam.params.arguments && requestParam.params.arguments.length > 0) {
requestParam.params.arguments.forEach(item => { requestParam.params.arguments.forEach(item => {
if(item.rangeType && item.value &&item.uuid){ if (item.rangeType && item.value && item.uuid) {
let paramObj = {id:item.uuid,value:item.value,condition:item.rangeType}; let paramObj = {id: item.uuid, value: item.value, condition: item.rangeType};
selectParma.push(paramObj); selectParma.push(paramObj);
} }
}); });
} }
if(requestParam.params.rest && requestParam.params.rest.length > 0){ if (requestParam.params.rest && requestParam.params.rest.length > 0) {
requestParam.params.rest.forEach(item => { requestParam.params.rest.forEach(item => {
if(item.rangeType && item.value &&item.uuid){ if (item.rangeType && item.value && item.uuid) {
let paramObj = {id:item.uuid,value:item.value,condition:item.rangeType}; let paramObj = {id: item.uuid, value: item.value, condition: item.rangeType};
selectParma.push(paramObj); selectParma.push(paramObj);
} }
}); });
} }
if(requestParam.params.body.kvs && requestParam.params.body.kvs.length > 0){ if (requestParam.params.body.kvs && requestParam.params.body.kvs.length > 0) {
requestParam.params.body.kvs.forEach(item => { requestParam.params.body.kvs.forEach(item => {
if(item.rangeType && item.value &&item.uuid){ if (item.rangeType && item.value && item.uuid) {
let paramObj = {id:item.uuid,value:item.value,condition:item.rangeType}; let paramObj = {id: item.uuid, value: item.value, condition: item.rangeType};
selectParma.push(paramObj); selectParma.push(paramObj);
} }
}); });
@ -184,25 +207,25 @@ export default {
//mock //mock
this.$post("/mockConfig/getMockTestData", selectParma, response => { this.$post("/mockConfig/getMockTestData", selectParma, response => {
let returnData = response.data; let returnData = response.data;
if(returnData && returnData.length > 0){ if (returnData && returnData.length > 0) {
returnData.forEach(data => { returnData.forEach(data => {
if(requestParam.params.arguments && requestParam.params.arguments.length > 0){ if (requestParam.params.arguments && requestParam.params.arguments.length > 0) {
for(let i = 0; i < requestParam.params.arguments.length; i++){ for (let i = 0; i < requestParam.params.arguments.length; i++) {
if(requestParam.params.arguments[i].uuid === data.id){ if (requestParam.params.arguments[i].uuid === data.id) {
requestParam.params.arguments[i].value = data.value; requestParam.params.arguments[i].value = data.value;
} }
} }
} }
if(requestParam.params.rest && requestParam.params.rest.length > 0){ if (requestParam.params.rest && requestParam.params.rest.length > 0) {
for(let i = 0; i < requestParam.params.rest.length; i++){ for (let i = 0; i < requestParam.params.rest.length; i++) {
if(requestParam.params.rest[i].uuid === data.id){ if (requestParam.params.rest[i].uuid === data.id) {
requestParam.params.rest[i].value = data.value; requestParam.params.rest[i].value = data.value;
} }
} }
} }
if(requestParam.params.body.kvs && requestParam.params.body.kvs.length > 0){ if (requestParam.params.body.kvs && requestParam.params.body.kvs.length > 0) {
for(let i = 0; i < requestParam.params.body.kvs.length; i++){ for (let i = 0; i < requestParam.params.body.kvs.length; i++) {
if(requestParam.params.body.kvs[i].uuid === data.id){ if (requestParam.params.body.kvs[i].uuid === data.id) {
requestParam.params.body.kvs[i].value = data.value; requestParam.params.body.kvs[i].value = data.value;
} }
} }

View File

@ -13,7 +13,7 @@
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
<div style="min-width: 1200px;" v-if="request.reportType === 'xml'"> <div style="min-width: 1200px;" v-if="request.reportType === 'xml'">
<tcp-xml-table :table-data="request.xmlDataStruct" :show-options-button="true" <tcp-xml-table :table-data="request.xmlDataStruct" :show-options-button="true" :show-operation-col="showOperationCol"
@xmlTablePushRow="xmlTablePushRow" @xmlTablePushRow="xmlTablePushRow"
@initXmlTableData="initXmlTableData" @initXmlTableData="initXmlTableData"
@saveTableData="saveXmlTableData" ref="treeTable"></tcp-xml-table> @saveTableData="saveXmlTableData" ref="treeTable"></tcp-xml-table>
@ -74,6 +74,10 @@ export default {
type: Boolean, type: Boolean,
default: false default: false
}, },
showOperationCol: {
type: Boolean,
default: false
},
showScript: { showScript: {
type: Boolean, type: Boolean,
default: true, default: true,
@ -167,6 +171,11 @@ export default {
}); });
} }
}, },
saveData(){
if(this.request && this.request.reportType === 'xml' && this.$refs.treeTable){
this.$refs.treeTable.saveTableData();
}
},
checkXmlTableDataStructData(dataStruct){ checkXmlTableDataStructData(dataStruct){
let allCheckResult = true; let allCheckResult = true;
if(this.$refs.treeTable){ if(this.$refs.treeTable){