fix(接口测试): 场景步骤的 schema 执行报错修复

This commit is contained in:
baiqi 2024-07-16 14:27:07 +08:00 committed by 刘瑞斌
parent 3db5da7499
commit d516ffa1f1
3 changed files with 48 additions and 34 deletions

View File

@ -8,11 +8,16 @@ import useAppStore from '@/store/modules/app';
import { findNodeByKey, getGenerateId, mapTree, traverseTree } from '@/utils';
import type { RequestResult } from '@/models/apiTest/common';
import type { ApiScenarioDebugRequest, Scenario, ScenarioStepItem } from '@/models/apiTest/scenario';
import type {
ApiScenarioDebugRequest,
Scenario,
ScenarioStepDetails,
ScenarioStepItem,
} from '@/models/apiTest/scenario';
import { ScenarioExecuteStatus, ScenarioStepRefType, ScenarioStepType } from '@/enums/apiEnum';
import type { RequestParam } from '../common/customApiDrawer.vue';
import updateStepStatus, { getScenarioFileParams } from '../utils';
import updateStepStatus, { getScenarioFileParams, getStepDetails } from '../utils';
/**
*
@ -27,7 +32,7 @@ export default function useStepExecute({
}: {
scenario: Ref<Scenario>;
steps: Ref<ScenarioStepItem[]>;
stepDetails: Ref<Record<string, any>>;
stepDetails: Ref<Record<string, ScenarioStepDetails>>;
activeStep: Ref<ScenarioStepItem | undefined>;
isPriorityLocalExec: Ref<boolean> | undefined;
localExecuteUrl: Ref<string> | undefined;
@ -89,6 +94,7 @@ export default function useStepExecute({
...getScenarioFileParams(scenario.value),
},
...executeParams,
stepDetails: getStepDetails(executeParams.steps, executeParams.stepDetails),
steps: mapTree(executeParams.steps, (node) => {
return {
...node,

View File

@ -1,7 +1,9 @@
import { RequestResult } from '@/models/apiTest/common';
import { type Scenario, ScenarioStepItem } from '@/models/apiTest/scenario';
import { type Scenario, type ScenarioStepDetails, ScenarioStepItem } from '@/models/apiTest/scenario';
import { ScenarioExecuteStatus, ScenarioStepType } from '@/enums/apiEnum';
import type { RequestParam } from './common/customApiDrawer.vue';
/**
*
* @param steps
@ -114,3 +116,34 @@ export function getScenarioFileParams(scenario: Scenario) {
uploadFileIds: Array.from(uploadFileIds),
};
}
/**
*
* @param details
*/
export function getStepDetails(steps: ScenarioStepItem[], details: Record<string, ScenarioStepDetails>) {
const newStepDetails: Record<string, ScenarioStepDetails> = {};
steps.forEach((step) => {
const currentDetail = details[step.id] as RequestParam;
if (
currentDetail &&
[ScenarioStepType.API, ScenarioStepType.API_CASE, ScenarioStepType.CUSTOM_REQUEST].includes(step.stepType)
) {
// 接口类型需要处理 json-schema 的循环引用
newStepDetails[step.id] = {
...currentDetail,
body: {
...currentDetail.body,
jsonBody: {
...currentDetail.body.jsonBody,
jsonSchema: currentDetail.body.jsonBody.jsonSchema,
jsonSchemaTableData: [], // 原树形结构存在循环引用,这里要去掉以免 axios 序列化失败
},
},
};
} else {
newStepDetails[step.id] = details[step.id];
}
});
return newStepDetails;
}

View File

@ -112,7 +112,6 @@
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
import MsSplitBox from '@/components/pure/ms-split-box/index.vue';
import MsEnvironmentSelect from '@/components/business/ms-environment-select/index.vue';
import { RequestParam } from './components/common/customApiDrawer.vue';
import scenarioModuleTree from './components/scenarioModuleTree.vue';
import executeButton from '@/views/api-test/components/executeButton.vue';
import ScenarioTable from '@/views/api-test/scenario/components/scenarioTable.vue';
@ -148,7 +147,7 @@
import { ApiTestRouteEnum } from '@/enums/routeEnum';
import { defaultCsvParamItem, defaultNormalParamItem, defaultScenario } from './components/config';
import updateStepStatus, { getScenarioFileParams } from './components/utils';
import updateStepStatus, { getScenarioFileParams, getStepDetails } from './components/utils';
import {
filterAssertions,
filterConditionsSqlValidParams,
@ -262,6 +261,7 @@
projectId: appStore.currentProjectId,
scenarioConfig: activeScenarioTab.value.scenarioConfig,
...executeParams,
stepDetails: getStepDetails(executeParams.steps, executeParams.stepDetails),
stepFileParam: activeScenarioTab.value.stepFileParam,
fileParam: {
...getScenarioFileParams(activeScenarioTab.value),
@ -286,6 +286,7 @@
},
frontendDebug: executeType === 'localExec',
...executeParams,
stepDetails: getStepDetails(executeParams.steps, executeParams.stepDetails),
steps: mapTree(executeParams.steps, (node) => {
return {
...node,
@ -531,33 +532,6 @@
apiTableRef.value?.loadScenarioList();
}
function getStepDetails() {
const stepDetails: Record<string, ScenarioStepDetails> = {};
activeScenarioTab.value.steps.forEach((step) => {
const currentDetail = activeScenarioTab.value.stepDetails[step.id] as RequestParam;
if (
currentDetail &&
[ScenarioStepType.API, ScenarioStepType.API_CASE, ScenarioStepType.CUSTOM_REQUEST].includes(step.stepType)
) {
// json-schema
stepDetails[step.id] = {
...currentDetail,
body: {
...currentDetail.body,
jsonBody: {
...currentDetail.body.jsonBody,
jsonSchema: currentDetail.body.jsonBody.jsonSchema,
jsonSchemaTableData: [], // axios
},
},
};
} else {
stepDetails[step.id] = activeScenarioTab.value.stepDetails[step.id];
}
});
return stepDetails;
}
async function realSaveScenario() {
try {
saveLoading.value = true;
@ -565,7 +539,7 @@
if (activeScenarioTab.value.isNew) {
const res = await addScenario({
...activeScenarioTab.value,
stepDetails: getStepDetails(),
stepDetails: getStepDetails(activeScenarioTab.value.steps, activeScenarioTab.value.stepDetails),
steps: mapTree(activeScenarioTab.value.steps, (node) => {
return {
...node,
@ -635,6 +609,7 @@
} else {
await updateScenario({
...activeScenarioTab.value,
stepDetails: getStepDetails(activeScenarioTab.value.steps, activeScenarioTab.value.stepDetails),
scenarioConfig: {
...activeScenarioTab.value.scenarioConfig,
assertionConfig: { ...assertionConfig, assertions: filterAssertions(assertionConfig) },