* fix variable patches

* add test case

* update changelog

* update snapshot
This commit is contained in:
Lei Ni 2022-08-02 10:25:32 +08:00 коммит произвёл GitHub
Родитель f37550d3cb
Коммит c1996477d6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 1354 добавлений и 192 удалений

Просмотреть файл

@ -1,6 +1,7 @@
# Change Log - oav
## 07/20/2022 3.0.4
- GenerateExamples - Support data generation in byte format
- ModelValidator - Support data validation in byte format
- API Scenario
@ -8,8 +9,10 @@
- Fix step variable unresolved in newman collection
- Fix bugs about html report
- Aggregate reports into one per scenario file
- Fix bug of object variables and patches
## 07/06/2022 3.0.3
- Generate high quality examples from API Scenario tests
## 06/30/2022 3.0.2

Просмотреть файл

@ -336,7 +336,7 @@ export class ApiScenarioLoader implements Loader<ScenarioDefinition> {
throw new Error("Invalid step");
}
} catch (error) {
throw new Error(`Failed to load step ${rawStep.step}: ${(error as any).message}`);
throw new Error(`Failed to load step ${JSON.stringify(rawStep)}: ${(error as any).message}`);
}
if (step.outputVariables) {
@ -381,28 +381,40 @@ export class ApiScenarioLoader implements Loader<ScenarioDefinition> {
ctx.stepTracking.set(step.step, step);
const getVariable = (name: string): Variable => {
const variable =
step.variables[name] ?? ctx.scenario?.variables[name] ?? ctx.scenarioDef.variables[name];
if (variable === undefined) {
const requiredVariables =
ctx.scenario?.requiredVariables ?? ctx.scenarioDef.requiredVariables;
if (
requiredVariables.includes(name) ||
(ctx.scenarioDef.scope === "ResourceGroup" &&
["subscriptionId", "resourceGroupName", "location"].indexOf(name) >= 0)
) {
const getVariable = (
name: string,
...scopes: Array<VariableScope | undefined>
): Variable | undefined => {
if (!scopes || scopes.length === 0) {
scopes = [step, ctx.scenario, ctx.scenarioDef];
}
for (const scope of scopes) {
if (scope && scope.variables[name]) {
return scope.variables[name];
}
}
for (const scope of scopes) {
if (scope && scope.requiredVariables.includes(name)) {
return {
type: "string",
value: `$(${name})`,
};
}
}
return variable;
if (
ctx.scenarioDef.scope === "ResourceGroup" &&
["subscriptionId", "resourceGroupName", "location"].includes(name)
) {
return {
type: "string",
value: `$(${name})`,
};
}
return undefined;
};
const requireVariable = (name: string) => {
if (["resourceGroupName"].includes(name)) {
if (ctx.scenarioDef.scope === "ResourceGroup" && ["resourceGroupName"].includes(name)) {
return;
}
const requiredVariables =
@ -441,7 +453,13 @@ export class ApiScenarioLoader implements Loader<ScenarioDefinition> {
if (value.type === "object" || value.type === "secureObject" || value.type === "array") {
if (value.patches) {
const obj = cloneDeep(getVariable(name));
const variable = ctx.scenario
? getVariable(name, ctx.scenario, ctx.scenarioDef)
: getVariable(name, ctx.scenarioDef);
if (!variable) {
throw new Error(`Variable ${name} not found in step ${step.step}`);
}
const obj = cloneDeep(variable);
if (typeof obj !== "object") {
// TODO dynamic json patch
throw new Error(`Can not Json Patch on ${name}, type of ${typeof obj}`);
@ -737,6 +755,11 @@ const convertVariables = (rawVariables: RawVariableScope["variables"]) => {
if (val.value === undefined && val.prefix === undefined) {
result.requiredVariables.push(key);
}
} else if (
(val.type === "object" || val.type === "secureObject" || val.type === "array") &&
val.patches !== undefined
) {
// ok
} else {
throw new Error(
`Only string and secureString type is supported in environment variables, please specify value for: ${key}`

Просмотреть файл

@ -37,7 +37,7 @@ export class TemplateGenerator {
public exampleParameterConvention(
step: Pick<StepRestCall, "parameters" | "responses" | "operation">,
variables: (name: string) => any,
getVariable: (name: string) => any,
operation: Operation
) {
const toMatch: string[] = [];
@ -45,7 +45,7 @@ export class TemplateGenerator {
const parameters = cloneDeep(step.parameters);
for (const paramName of Object.keys(parameters)) {
if (variables(paramName) === undefined) {
if (getVariable(paramName) === undefined) {
continue;
}

Просмотреть файл

@ -771,6 +771,111 @@ Object {
},
},
},
Object {
"_scenarioDef": [Circular],
"description": "",
"requiredVariables": Array [
"subscriptionId",
"location",
],
"scenario": "patchVariables",
"secretVariables": Array [],
"shareScope": true,
"steps": Array [
Object {
"description": undefined,
"operation": Object {},
"operationId": "StorageAccounts_Create",
"outputVariables": Object {},
"parameters": Object {
"accountName": "$(accountName)",
"api-version": "2021-08-01",
"parameters": Object {
"properties": Object {
"kind": "StorageV2",
"location": "$(location)",
"patches": Array [
Object {
"add": "/properties/kind",
"value": "StorageV2",
},
],
"properties": Object {
"encryption": Object {
"keySource": "Microsoft.Storage",
"services": Object {
"blob": Object {},
},
},
},
"sku": "Standard",
},
},
"resourceGroupName": "$(resourceGroupName)",
"subscriptionId": "$(subscriptionId)",
},
"requiredVariables": Array [],
"responses": Object {},
"secretVariables": Array [],
"step": "createStorageAccount",
"type": "restCall",
"variables": Object {
"parameters": Object {
"type": "object",
"value": Object {
"properties": Object {
"kind": "StorageV2",
"location": "$(location)",
"patches": Array [
Object {
"add": "/properties/kind",
"value": "StorageV2",
},
],
"properties": Object {
"encryption": Object {
"keySource": "Microsoft.Storage",
"services": Object {
"blob": Object {},
},
},
},
"sku": "Standard",
},
},
},
},
},
],
"variables": Object {
"parameters": Object {
"type": "object",
"value": Object {
"properties": Object {
"kind": "StorageV2",
"location": "$(location)",
"patches": Array [
Object {
"add": "/properties/kind",
"value": "StorageV2",
},
],
"properties": Object {
"encryption": Object {
"keySource": "Microsoft.Storage",
"services": Object {
"blob": Object {},
},
},
},
"sku": Object {
"name": "Standard_LRS",
},
},
},
},
},
},
],
"scope": "ResourceGroup",
"secretVariables": Array [],

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -28,7 +28,7 @@ scenarios:
kind: StorageV2
location: $(location)
properties:
encryption: {"services": {"blob": {}}, "keySource": "Microsoft.Storage"}
encryption: { "services": { "blob": {} }, "keySource": "Microsoft.Storage" }
- scenario: overrideVariable
variables:
accountName: $(accountName)2
@ -52,7 +52,7 @@ scenarios:
kind: StorageV2
location: $(location)
properties:
encryption: {"services": {"blob": {}}, "keySource": "Microsoft.Storage"}
encryption: { "services": { "blob": {} }, "keySource": "Microsoft.Storage" }
- scenario: primitiveParameter
variables:
accountName:
@ -78,7 +78,7 @@ scenarios:
kind: StorageV2
location: $(location)
properties:
encryption: {"services": {"blob": {}}, "keySource": "Microsoft.Storage"}
encryption: { "services": { "blob": {} }, "keySource": "Microsoft.Storage" }
- step: DeletedAccounts_Get
operationId: DeletedAccounts_Get
parameters:
@ -87,3 +87,27 @@ scenarios:
deletedAccountName:
type: string
prefix: foobar
- scenario: patchVariables
variables:
parameters:
type: object
value:
properties:
sku:
name: Standard_LRS
kind: StorageV2
location: $(location)
properties:
encryption: { "services": { "blob": {} }, "keySource": "Microsoft.Storage" }
patches:
- add: /properties/kind
value: StorageV2
steps:
- step: createStorageAccount
operationId: StorageAccounts_Create
variables:
parameters:
type: object
patches:
- replace: /properties/sku
value: Standard