fix(接口测试): 修复引用的case无法添加断言的缺陷
--bug=1027145 --user=王孝刚 【接口测试】场景详情-引用的场景和case-无法添加断言 https://www.tapd.cn/55049933/s/1383491
This commit is contained in:
parent
25b515c16a
commit
f3df278755
|
@ -11,6 +11,7 @@ public class MsAssertionType {
|
|||
public final static String TEXT = "Text";
|
||||
public final static String XPATH2 = "XPath2";
|
||||
private boolean enable = true;
|
||||
public String label;
|
||||
|
||||
private String type;
|
||||
}
|
||||
|
|
|
@ -98,6 +98,15 @@ public class MsHashTreeService {
|
|||
private static final String RESULT_VARIABLE = "resultVariable";
|
||||
private static final String ENV_Id = "environmentId";
|
||||
|
||||
private final static String JSON_PATH="jsonPath";
|
||||
private final static String JSR223="jsr223";
|
||||
private final static String XPATH="xpath2";
|
||||
private final static String REGEX="regex";
|
||||
private final static String DURATION="duration";
|
||||
private final static String DOCUMENT="document";
|
||||
private final static String LABEL="label";
|
||||
private final static String SCENARIO_REF="SCENARIO-REF-STEP";
|
||||
|
||||
public void setHashTree(JSONArray hashTree) {
|
||||
// 将引用转成复制
|
||||
if (hashTree == null) {
|
||||
|
@ -191,7 +200,7 @@ public class MsHashTreeService {
|
|||
|
||||
List<JSONObject> pre = ElementUtil.mergeHashTree(groupMap.get(PRE), targetGroupMap.get(PRE));
|
||||
List<JSONObject> post = ElementUtil.mergeHashTree(groupMap.get(POST), targetGroupMap.get(POST));
|
||||
List<JSONObject> rules = ElementUtil.mergeHashTree(groupMap.get(ASSERTIONS), targetGroupMap.get(ASSERTIONS));
|
||||
List<JSONObject> rules = mergeAssertions(groupMap.get(ASSERTIONS), targetGroupMap.get(ASSERTIONS));
|
||||
List<JSONObject> step = new LinkedList<>();
|
||||
if (CollectionUtils.isNotEmpty(pre)) {
|
||||
step.addAll(pre);
|
||||
|
@ -232,6 +241,68 @@ public class MsHashTreeService {
|
|||
return element;
|
||||
}
|
||||
|
||||
public List<JSONObject> mergeAssertions(List<JSONObject> sourceHashTree, List<JSONObject> targetHashTree) {
|
||||
try {
|
||||
if (CollectionUtils.isNotEmpty(targetHashTree)) {
|
||||
JSONObject target = targetHashTree.get(0);
|
||||
|
||||
if (CollectionUtils.isNotEmpty(sourceHashTree)) {
|
||||
JSONObject source = sourceHashTree.get(0);
|
||||
//jsonPath
|
||||
JSONArray jsonPathTar = target.optJSONArray(JSON_PATH);
|
||||
JSONArray jsonPathSource = source.optJSONArray(JSON_PATH);
|
||||
mergeArray(target, jsonPathTar, jsonPathSource, JSON_PATH);
|
||||
//jsr223
|
||||
JSONArray jsr223Tar = target.optJSONArray(JSR223);
|
||||
JSONArray jsr223Source = source.optJSONArray(JSR223);
|
||||
mergeArray(target, jsr223Tar, jsr223Source, JSR223);
|
||||
//xpath
|
||||
JSONArray xpathTar = target.optJSONArray(XPATH);
|
||||
JSONArray xpathSource = source.optJSONArray(XPATH);
|
||||
mergeArray(target, xpathTar, xpathSource, XPATH);
|
||||
//regex
|
||||
JSONArray regexTar = target.optJSONArray(REGEX);
|
||||
JSONArray regexSource = source.optJSONArray(REGEX);
|
||||
mergeArray(target, regexTar, regexSource, REGEX);
|
||||
//duration
|
||||
JSONObject durationTar = target.optJSONObject(DURATION);
|
||||
JSONObject durationSource = source.optJSONObject(DURATION);
|
||||
mergeObject(target, durationTar, durationSource, DURATION);
|
||||
//document
|
||||
JSONObject documentTar = target.optJSONObject(DOCUMENT);
|
||||
JSONObject documentSource = source.optJSONObject(DOCUMENT);
|
||||
mergeObject(target, documentTar, documentSource, DOCUMENT);
|
||||
sourceHashTree.remove(0);
|
||||
sourceHashTree.add(target);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("mergeAssertions error", e);
|
||||
}
|
||||
return sourceHashTree;
|
||||
}
|
||||
|
||||
private static void mergeObject(JSONObject target, JSONObject durationTar, JSONObject durationSource, String type) {
|
||||
if (durationSource != null && durationSource.has(LABEL) &&
|
||||
StringUtils.equals(durationSource.optString(LABEL), SCENARIO_REF)) {
|
||||
durationTar = durationSource;
|
||||
}
|
||||
target.remove(type);
|
||||
target.put(type, durationTar);
|
||||
}
|
||||
|
||||
private static void mergeArray(JSONObject target, JSONArray jsonArray, JSONArray source, String type) {
|
||||
if (!source.isEmpty()) {
|
||||
source.forEach(obj -> {
|
||||
JSONObject jsonObject = (JSONObject) obj;
|
||||
if (StringUtils.equals(jsonObject.optString(LABEL), SCENARIO_REF)) {
|
||||
jsonArray.put(jsonObject);
|
||||
}
|
||||
});
|
||||
}
|
||||
target.remove(type);
|
||||
target.put(type, jsonArray);
|
||||
}
|
||||
|
||||
private void getCaseIds(JSONObject element, List<String> caseIds) {
|
||||
if (StringUtils.equalsIgnoreCase(element.optString(REF_TYPE), CASE) && element.has(ID)) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<el-row :gutter="10" type="flex" justify="space-between" align="middle">
|
||||
<el-col>
|
||||
<el-input
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !duration.label"
|
||||
:value="value"
|
||||
v-bind="$attrs"
|
||||
step="100"
|
||||
|
@ -21,18 +21,18 @@
|
|||
v-model="duration.enable"
|
||||
class="enable-switch"
|
||||
size="mini"
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !duration.label"
|
||||
style="width: 30px; margin-right: 10px" />
|
||||
</el-tooltip>
|
||||
<el-button
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !duration.label"
|
||||
type="danger"
|
||||
size="mini"
|
||||
icon="el-icon-delete"
|
||||
circle
|
||||
@click="remove"
|
||||
v-if="edit" />
|
||||
<el-button :disabled="isReadOnly" type="primary" size="mini" @click="add" v-else>
|
||||
<el-button :disabled="isReadOnly && !duration.label" type="primary" size="mini" @click="add" v-else>
|
||||
{{ $t('api_test.request.assertions.add') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
|
@ -55,6 +55,11 @@ export default {
|
|||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.duration && !this.duration.valid && this.duration.value === 0 && this.isReadOnly) {
|
||||
this.duration.label = "SCENARIO-REF-STEP";
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
add() {
|
||||
if (this.validate()) {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<el-col>
|
||||
<el-tooltip :disabled="showTip" placement="top" :content="jsonPath.expression">
|
||||
<el-input
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !jsonPath.label"
|
||||
v-model="jsonPath.expression"
|
||||
maxlength="500"
|
||||
size="small"
|
||||
|
@ -14,7 +14,7 @@
|
|||
</el-col>
|
||||
<el-col>
|
||||
<el-select
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !jsonPath.label"
|
||||
v-model="jsonPath.option"
|
||||
class="ms-col-type"
|
||||
size="small"
|
||||
|
@ -29,7 +29,7 @@
|
|||
<el-option :label="$t('api_test.request.assertions.regular_match')" value="REGEX"/>
|
||||
</el-select>
|
||||
<el-input
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !jsonPath.label"
|
||||
v-model="jsonPath.expect"
|
||||
size="small"
|
||||
show-word-limit
|
||||
|
@ -48,25 +48,25 @@
|
|||
v-model="jsonPath.enable"
|
||||
class="enable-switch"
|
||||
size="mini"
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !jsonPath.label"
|
||||
style="width: 30px; margin-right: 10px"/>
|
||||
</el-tooltip>
|
||||
<el-button
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !jsonPath.label"
|
||||
size="mini"
|
||||
icon="el-icon-copy-document"
|
||||
circle
|
||||
@click="copyRow"
|
||||
v-if="edit"/>
|
||||
<el-button
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !jsonPath.label"
|
||||
type="danger"
|
||||
size="mini"
|
||||
icon="el-icon-delete"
|
||||
circle
|
||||
@click="remove"
|
||||
v-if="edit"/>
|
||||
<el-button :disabled="isReadOnly" type="primary" size="mini" @click="add" v-else>
|
||||
<el-button :disabled="isReadOnly && !jsonPath.label" type="primary" size="mini" @click="add" v-else>
|
||||
{{ $t('api_test.request.assertions.add') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
|
@ -102,6 +102,9 @@ export default {
|
|||
created() {
|
||||
if (!this.jsonPath.option) {
|
||||
this.jsonPath.option = 'REGEX';
|
||||
if (this.jsonPath && this.isReadOnly) {
|
||||
this.jsonPath.label = "SCENARIO-REF-STEP";
|
||||
}
|
||||
}
|
||||
this.showTip = !this.jsonPath || !this.jsonPath.expression || this.jsonPath.expression.length < 50;
|
||||
},
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
{{ assertion.desc }}
|
||||
</div>
|
||||
<div class="assertion-item btn">
|
||||
<el-button :disabled="isReadOnly" type="success" size="mini" @click="detail">
|
||||
<el-button :disabled="isReadOnly && !assertion.label" type="success" size="mini" @click="detail">
|
||||
{{ $t('commons.edit') }}
|
||||
</el-button>
|
||||
<el-button :disabled="isReadOnly" type="primary" size="mini" @click="add">
|
||||
<el-button :disabled="isReadOnly && !assertion.label" type="primary" size="mini" @click="add">
|
||||
{{ $t('api_test.request.assertions.add') }}
|
||||
</el-button>
|
||||
</div>
|
||||
|
@ -19,16 +19,16 @@
|
|||
</div>
|
||||
<div class="assertion-item btn circle">
|
||||
<i class="el-icon-view el-button el-button--primary el-button--mini is-circle" circle @click="showPage" />
|
||||
<el-button :disabled="isReadOnly" type="success" size="mini" icon="el-icon-edit" circle @click="detail" />
|
||||
<el-button :disabled="isReadOnly && !assertion.label" type="success" size="mini" icon="el-icon-edit" circle @click="detail" />
|
||||
<el-tooltip :content="$t('test_resource_pool.enable_disable')" placement="top">
|
||||
<el-switch
|
||||
v-model="assertion.enable"
|
||||
class="enable-switch"
|
||||
size="mini"
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !assertion.label"
|
||||
style="width: 30px; margin: 0px 10px 0px 10px" />
|
||||
</el-tooltip>
|
||||
<el-button :disabled="isReadOnly" type="danger" size="mini" icon="el-icon-delete" circle @click="remove" />
|
||||
<el-button :disabled="isReadOnly && !assertion.label" type="danger" size="mini" icon="el-icon-delete" circle @click="remove" />
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
|
@ -167,6 +167,11 @@ export default {
|
|||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.assertion.valid === undefined && this.isReadOnly) {
|
||||
this.assertion.label = "SCENARIO-REF-STEP";
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
add() {
|
||||
this.list.push(new AssertionJSR223(this.assertion));
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<el-row :gutter="10" type="flex" justify="space-between" align="middle">
|
||||
<el-col class="assertion-select">
|
||||
<el-select
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !regex.label"
|
||||
class="assertion-item"
|
||||
v-model="regex.subject"
|
||||
size="small"
|
||||
|
@ -16,7 +16,7 @@
|
|||
<el-col>
|
||||
<el-tooltip :disabled="showTip" placement="top" :content="regex.expression">
|
||||
<el-input
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !regex.label"
|
||||
v-model="regex.expression"
|
||||
size="small"
|
||||
show-word-limit
|
||||
|
@ -24,7 +24,7 @@
|
|||
</el-tooltip>
|
||||
</el-col>
|
||||
<el-col class="assertion-checkbox">
|
||||
<el-checkbox v-model="regex.assumeSuccess" :disabled="isReadOnly">
|
||||
<el-checkbox v-model="regex.assumeSuccess" :disabled="isReadOnly && !regex.label">
|
||||
{{ $t('api_test.request.assertions.ignore_status') }}
|
||||
</el-checkbox>
|
||||
</el-col>
|
||||
|
@ -34,26 +34,26 @@
|
|||
v-model="regex.enable"
|
||||
class="enable-switch"
|
||||
size="mini"
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !regex.label"
|
||||
style="width: 30px; margin-right: 10px" />
|
||||
</el-tooltip>
|
||||
|
||||
<el-button
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !regex.label"
|
||||
size="mini"
|
||||
icon="el-icon-copy-document"
|
||||
circle
|
||||
@click="copyRow"
|
||||
v-if="edit" />
|
||||
<el-button
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !regex.label"
|
||||
type="danger"
|
||||
size="mini"
|
||||
icon="el-icon-delete"
|
||||
circle
|
||||
@click="remove"
|
||||
v-if="edit" />
|
||||
<el-button :disabled="isReadOnly" type="primary" size="mini" @click="add" v-else>
|
||||
<el-button :disabled="isReadOnly && !regex.label" type="primary" size="mini" @click="add" v-else>
|
||||
{{ $t('api_test.request.assertions.add') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
|
@ -102,6 +102,9 @@ export default {
|
|||
},
|
||||
},
|
||||
created() {
|
||||
if (!this.regex.description && this.isReadOnly) {
|
||||
this.regex.label = "SCENARIO-REF-STEP";
|
||||
}
|
||||
this.showTip = !this.regex || !this.regex.description || this.regex.description.length < 80;
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<el-row :gutter="10" type="flex" justify="space-between" align="middle">
|
||||
<el-col class="assertion-select">
|
||||
<el-select
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !label"
|
||||
class="assertion-item"
|
||||
v-model="subject"
|
||||
size="small"
|
||||
|
@ -15,7 +15,7 @@
|
|||
</el-col>
|
||||
<el-col class="assertion-select">
|
||||
<el-select
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !label"
|
||||
class="assertion-item"
|
||||
v-model="condition"
|
||||
size="small"
|
||||
|
@ -29,7 +29,7 @@
|
|||
</el-col>
|
||||
<el-col>
|
||||
<el-input
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !label"
|
||||
v-model="value"
|
||||
maxlength="500"
|
||||
size="small"
|
||||
|
@ -37,12 +37,12 @@
|
|||
:placeholder="$t('api_test.request.assertions.value')" />
|
||||
</el-col>
|
||||
<el-col class="assertion-checkbox">
|
||||
<el-checkbox v-model="assumeSuccess" :disabled="isReadOnly">
|
||||
<el-checkbox v-model="assumeSuccess" :disabled="isReadOnly && !label">
|
||||
{{ $t('api_test.request.assertions.ignore_status') }}
|
||||
</el-checkbox>
|
||||
</el-col>
|
||||
<el-col class="assertion-btn">
|
||||
<el-button :disabled="isReadOnly" type="primary" size="mini" @click="add">
|
||||
<el-button :disabled="isReadOnly && !label" type="primary" size="mini" @click="add">
|
||||
{{ $t('api_test.request.assertions.add') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
|
@ -72,8 +72,14 @@ export default {
|
|||
condition: '',
|
||||
assumeSuccess: false,
|
||||
value: '',
|
||||
label: '',
|
||||
};
|
||||
},
|
||||
created() {
|
||||
if (this.isReadOnly) {
|
||||
this.label = 'SCENARIO-REF-STEP';
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
add: function () {
|
||||
|
@ -110,6 +116,7 @@ export default {
|
|||
expression: expression,
|
||||
description: description,
|
||||
assumeSuccess: this.assumeSuccess,
|
||||
label: this.label,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<el-row :gutter="10" type="flex" justify="space-between" align="middle">
|
||||
<el-col>
|
||||
<el-input
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !xPath2.label"
|
||||
v-model="xPath2.expression"
|
||||
maxlength="500"
|
||||
size="small"
|
||||
|
@ -16,25 +16,25 @@
|
|||
v-model="xPath2.enable"
|
||||
class="enable-switch"
|
||||
size="mini"
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !xPath2.label"
|
||||
style="width: 30px; margin-right: 10px" />
|
||||
</el-tooltip>
|
||||
<el-button
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !xPath2.label"
|
||||
size="mini"
|
||||
icon="el-icon-copy-document"
|
||||
circle
|
||||
@click="copyRow"
|
||||
v-if="edit" />
|
||||
<el-button
|
||||
:disabled="isReadOnly"
|
||||
:disabled="isReadOnly && !xPath2.label"
|
||||
type="danger"
|
||||
size="mini"
|
||||
icon="el-icon-delete"
|
||||
circle
|
||||
@click="remove"
|
||||
v-if="edit" />
|
||||
<el-button :disabled="isReadOnly" type="primary" size="mini" @click="add" v-else>
|
||||
<el-button :disabled="isReadOnly && !xPath2.label" type="primary" size="mini" @click="add" v-else>
|
||||
{{ $t('api_test.request.assertions.add') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
|
@ -67,6 +67,12 @@ export default {
|
|||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.xPath2.valid === undefined && this.isReadOnly) {
|
||||
this.xPath2.label = "SCENARIO-REF-STEP";
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
add: function () {
|
||||
this.list.push(this.getXPath2());
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
<api-json-path-suggest-button
|
||||
:open-tip="$t('api_test.request.assertions.json_path_suggest')"
|
||||
:clear-tip="$t('api_test.request.assertions.json_path_clear')"
|
||||
:isReadOnly="isReadOnly"
|
||||
@open="suggestJsonOpen"
|
||||
@clear="clearJson" />
|
||||
</span>
|
||||
|
@ -15,7 +14,6 @@
|
|||
<el-row :gutter="10">
|
||||
<el-col :span="4">
|
||||
<el-select
|
||||
:disabled="isReadOnly"
|
||||
class="assertion-item"
|
||||
v-model="type"
|
||||
:placeholder="$t('api_test.request.assertions.select_type')"
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
v-model="assertions.document.enable"
|
||||
class="enable-switch"
|
||||
size="mini"
|
||||
:disabled="assertions.disabled"
|
||||
:disabled="isReadOnly && !assertions.document.label"
|
||||
style="width: 30px; margin-right: 10px" />
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="dark" :content="$t('commons.remove')" placement="top-start">
|
||||
|
@ -78,12 +78,12 @@
|
|||
size="mini"
|
||||
circle
|
||||
@click="remove()"
|
||||
:disabled="assertions.disabled && !assertions.root" />
|
||||
:disabled="isReadOnly && !assertions.document.label && !assertions.root" />
|
||||
</el-tooltip>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<ms-document-body :document="assertions.document" :apiId="apiId" :isReadOnly="isReadOnly" @remove="remove" />
|
||||
<ms-document-body :document="assertions.document" :apiId="apiId" :isReadOnly="isReadOnly && !assertions.document.label" @remove="remove" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
</el-select>
|
||||
</el-col>
|
||||
<el-col class="assertion-btn">
|
||||
<el-button :disabled="isReadOnly" type="primary" size="mini" @click="add">
|
||||
<el-button :disabled="isReadOnly && !document.label" type="primary" size="mini" @click="add">
|
||||
{{ $t('api_test.request.assertions.add') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
|
@ -32,6 +32,11 @@ export default {
|
|||
default: false,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if (this.document && !this.document.originalData && !this.document.rootData && this.isReadOnly) {
|
||||
this.document.label = "SCENARIO-REF-STEP";
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
add() {
|
||||
|
|
|
@ -114,7 +114,7 @@
|
|||
:request="request"
|
||||
:apiId="apiId"
|
||||
:draggable="true"
|
||||
:is-read-only="data.disabled"
|
||||
:is-read-only="request.disabled"
|
||||
:assertions="data" />
|
||||
</div>
|
||||
</span>
|
||||
|
|
Loading…
Reference in New Issue