From c1996477d64bde3a7ee02e3c26969083f1c0c52e Mon Sep 17 00:00:00 2001 From: Lei Ni <7233663+leni-msft@users.noreply.github.com> Date: Tue, 2 Aug 2022 10:25:32 +0800 Subject: [PATCH] fix variable patches (#841) * fix variable patches * add test case * update changelog * update snapshot --- ChangeLog.md | 3 + lib/apiScenario/apiScenarioLoader.ts | 53 +- lib/apiScenario/templateGenerator.ts | 4 +- .../apiScenarioLoaderTest.ts.snap | 105 ++ .../postmanCollectionGeneratorTest.ts.snap | 1351 ++++++++++++++--- .../scenarios/storageQuickStart.yaml | 30 +- 6 files changed, 1354 insertions(+), 192 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 7b11e8c4..2da935db 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -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 diff --git a/lib/apiScenario/apiScenarioLoader.ts b/lib/apiScenario/apiScenarioLoader.ts index 98e6b4be..4c0ae678 100644 --- a/lib/apiScenario/apiScenarioLoader.ts +++ b/lib/apiScenario/apiScenarioLoader.ts @@ -336,7 +336,7 @@ export class ApiScenarioLoader implements Loader { 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 { 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 + ): 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 { 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}` diff --git a/lib/apiScenario/templateGenerator.ts b/lib/apiScenario/templateGenerator.ts index 45bb3664..6f3fdf5f 100644 --- a/lib/apiScenario/templateGenerator.ts +++ b/lib/apiScenario/templateGenerator.ts @@ -37,7 +37,7 @@ export class TemplateGenerator { public exampleParameterConvention( step: Pick, - 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; } diff --git a/test/apiScenario/__snapshots__/apiScenarioLoaderTest.ts.snap b/test/apiScenario/__snapshots__/apiScenarioLoaderTest.ts.snap index e270f964..096b74f5 100644 --- a/test/apiScenario/__snapshots__/apiScenarioLoaderTest.ts.snap +++ b/test/apiScenario/__snapshots__/apiScenarioLoaderTest.ts.snap @@ -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 [], diff --git a/test/apiScenario/__snapshots__/postmanCollectionGeneratorTest.ts.snap b/test/apiScenario/__snapshots__/postmanCollectionGeneratorTest.ts.snap index b73fac01..05b858ad 100644 --- a/test/apiScenario/__snapshots__/postmanCollectionGeneratorTest.ts.snap +++ b/test/apiScenario/__snapshots__/postmanCollectionGeneratorTest.ts.snap @@ -1612,7 +1612,7 @@ Array [ " postman.setNextRequest('_createStorageAccount_generated_get')", "}", ], - "id": "col7eq", + "id": "d9yng9", "type": "text/javascript", }, }, @@ -1863,16 +1863,261 @@ Array [ "listen": "test", "script": Object { "exec": Array [ - "pm.test(\\"response code should be 2xx\\", function() {", - "pm.response.to.be.success;", + "", + "pm.test(\\"Stopped TestProxy recording\\", function() {", + " pm.response.to.be.success;", "});", + "", ], "id": "gsyqal", "type": "text/javascript", }, }, + ], + "id": "c9wzyn", + "name": "stopTestProxyRecording", + "request": Object { + "header": Array [ + Object { + "key": "x-recording-id", + "value": "{{x_recording_id}}", + }, + ], + "method": "POST", + "url": Object { + "host": Array [ + "localhost", + ], + "path": Array [ + "record", + "stop", + ], + "port": "5000", + "protocol": "http", + "query": Array [], + "variable": Array [], + }, + }, + "response": Array [], + }, + ], + "variable": Array [ + Object { + "key": "accountName", + "type": "any", + "value": "foobardb187u", + }, + Object { + "key": "subscriptionId", + "type": "any", + }, + Object { + "key": "resourceGroupName", + "type": "any", + }, + Object { + "key": "location", + "type": "any", + }, + Object { + "key": "client_id", + "type": "any", + }, + Object { + "key": "client_secret", + "type": "any", + }, + Object { + "key": "tenantId", + "type": "any", + }, + Object { + "key": "x_enable_auth", + "type": "any", + "value": "true", + }, + Object { + "key": "x_bearer_token", + "type": "any", + }, + Object { + "key": "x_bearer_token_expires_on", + "type": "any", + }, + Object { + "key": "x_polling_url", + "type": "any", + }, + Object { + "key": "x_retry_after", + "type": "any", + "value": "10", + }, + ], + }, + Object { + "auth": Object { + "bearer": Array [ + Object { + "key": "token", + "type": "string", + "value": "{{x_bearer_token}}", + }, + ], + "type": "bearer", + }, + "event": Array [ + Object { + "id": "ew9nh8", + "listen": "prerequest", + "script": Object { + "exec": Array [ + "", + "if (pm.variables.get(\\"x_enable_auth\\") !== \\"true\\") {", + " return;", + "}", + "let vars = [\\"client_id\\", \\"client_secret\\", \\"tenantId\\", \\"subscriptionId\\"];", + "vars.forEach(function (item, index, array) {", + " pm.expect(", + " pm.variables.get(item),", + " item + \\" variable not set\\"", + " ).to.not.be.undefined;", + " pm.expect(pm.variables.get(item), item + \\" variable not set\\").to.not.be.empty;", + "});", + "if (", + " !pm.collectionVariables.get(\\"x_bearer_token\\") ||", + " Date.now() >", + " new Date(pm.collectionVariables.get(\\"x_bearer_token_expires_on\\") * 1000)", + ") {", + " pm.sendRequest(", + " {", + " url:", + " \\"https://login.microsoftonline.com/\\" +", + " pm.variables.get(\\"tenantId\\") +", + " \\"/oauth2/token\\",", + " method: \\"POST\\",", + " header: \\"Content-Type: application/x-www-form-urlencoded\\",", + " body: {", + " mode: \\"urlencoded\\",", + " urlencoded: [", + " { key: \\"grant_type\\", value: \\"client_credentials\\", disabled: false },", + " {", + " key: \\"client_id\\",", + " value: pm.variables.get(\\"client_id\\"),", + " disabled: false,", + " },", + " {", + " key: \\"client_secret\\",", + " value: pm.variables.get(\\"client_secret\\"),", + " disabled: false,", + " },", + " { key: \\"resource\\", value: \\"https://management.azure.com\\", disabled: false },", + " ],", + " },", + " },", + " function (err, res) {", + " if (err) {", + " console.log(err);", + " } else {", + " let resJson = res.json();", + " pm.collectionVariables.set(", + " \\"x_bearer_token_expires_on\\",", + " resJson.expires_on", + " );", + " pm.collectionVariables.set(\\"x_bearer_token\\", resJson.access_token);", + " }", + " }", + " );", + "}", + ], + "id": "sp8ib7", + "type": "text/javascript", + }, + }, + ], + "info": Object { + "_postman_id": "jestRunIdTestProxy", + "description": Object { + "content": "{\\"apiScenarioFilePath\\":\\"Microsoft.Storage/stable/2021-08-01/scenarios/storageQuickStart.yaml\\",\\"apiScenarioName\\":\\"patchVariables\\",\\"swaggerFilePaths\\":[\\"Microsoft.Storage/stable/2021-08-01/storage.json\\"]}", + "type": "text/plain", + }, + "name": "patchVariables", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "version": undefined, + }, + "item": Array [ + Object { + "event": Array [ Object { - "id": "sp8ib7", + "id": "yzy1ec", + "listen": "test", + "script": Object { + "exec": Array [ + "", + "pm.test(\\"Started TestProxy recording\\", function() {", + " pm.response.to.be.success;", + " pm.response.to.have.header(\\"x-recording-id\\");", + " pm.collectionVariables.set(\\"x_recording_id\\", pm.response.headers.get(\\"x-recording-id\\"));", + "});", + ], + "id": "bw1q38", + "type": "text/javascript", + }, + }, + ], + "id": "2vc31r", + "name": "startTestProxyRecording", + "request": Object { + "body": Object { + "mode": "raw", + "raw": "{\\"x-recording-file\\": \\"./recordings/patchVariables_jestRunIdTestProxy.json\\"}", + }, + "method": "POST", + "url": Object { + "host": Array [ + "localhost", + ], + "path": Array [ + "record", + "start", + ], + "port": "5000", + "protocol": "http", + "query": Array [], + "variable": Array [], + }, + }, + "response": Array [], + }, + Object { + "description": "{\\"type\\":\\"LRO\\",\\"poller_item_name\\":\\"createStorageAccount_poller\\",\\"operationId\\":\\"StorageAccounts_Create\\",\\"itemName\\":\\"createStorageAccount\\",\\"step\\":\\"createStorageAccount\\"}", + "event": Array [ + Object { + "id": "zo75y7", + "listen": "prerequest", + "script": Object { + "exec": Array [ + "pm.variables.set(\\"parameters\\", \\"[object Object]\\");", + ], + "id": "ehebqq", + "type": "text/javascript", + }, + }, + Object { + "id": "odehko", + "listen": "test", + "script": Object { + "exec": Array [ + "pm.test(\\"response status code assertion.\\", function() {", + "pm.response.to.be.success;", + "});", + ], + "id": "9quvnq", + "type": "text/javascript", + }, + }, + Object { + "id": "f9zxy5", "listen": "test", "script": Object { "exec": Array [ @@ -1882,12 +2127,304 @@ Array [ " pm.collectionVariables.set(\\"x_polling_url\\", pollingUrl.replace(\\"https://management.azure.com\\",\\"http://localhost:5000\\"));", "}", ], - "id": "d9yng9", + "id": "col7eq", "type": "text/javascript", }, }, ], - "id": "c9wzyn", + "id": "l0fzps", + "name": "createStorageAccount", + "request": Object { + "body": Object { + "mode": "raw", + "raw": "{ + \\"properties\\": { + \\"sku\\": \\"Standard\\", + \\"kind\\": \\"StorageV2\\", + \\"location\\": \\"{{location}}\\", + \\"properties\\": { + \\"encryption\\": { + \\"services\\": { + \\"blob\\": {} + }, + \\"keySource\\": \\"Microsoft.Storage\\" + } + }, + \\"patches\\": [ + { + \\"add\\": \\"/properties/kind\\", + \\"value\\": \\"StorageV2\\" + } + ] + } +}", + }, + "header": Array [ + Object { + "key": "x-recording-upstream-base-uri", + "value": "https://management.azure.com", + }, + Object { + "key": "x-recording-id", + "value": "{{x_recording_id}}", + }, + Object { + "key": "x-recording-mode", + "value": "record", + }, + Object { + "key": "Content-Type", + "value": "application/json", + }, + ], + "method": "PUT", + "url": Object { + "host": Array [ + "http://localhost:5000", + ], + "path": Array [ + "subscriptions", + ":subscriptionId", + "resourceGroups", + ":resourceGroupName", + "providers", + "Microsoft.Storage", + "storageAccounts", + ":accountName", + ], + "query": Array [ + Object { + "key": "api-version", + "value": "2021-08-01", + }, + ], + "variable": Array [ + Object { + "key": "resourceGroupName", + "type": "any", + "value": "{{resourceGroupName}}", + }, + Object { + "key": "accountName", + "type": "any", + "value": "{{accountName}}", + }, + Object { + "key": "subscriptionId", + "type": "any", + "value": "{{subscriptionId}}", + }, + ], + }, + }, + "response": Array [], + }, + Object { + "description": "{\\"type\\":\\"poller\\",\\"lro_item_name\\":\\"createStorageAccount\\"}", + "event": Array [ + Object { + "id": "wa7yg9", + "listen": "test", + "script": Object { + "exec": Array [ + "", + "try {", + " if (pm.response.code === 202) {", + " postman.setNextRequest('_createStorageAccount_poller_mock_delay');", + " } else if (pm.response.code === 204) {", + " postman.setNextRequest('_createStorageAccount_generated_get');", + " } else {", + " const terminalStatus = [\\"Succeeded\\", \\"Failed\\", \\"Canceled\\"];", + " if (pm.response.json().status !== undefined && terminalStatus.indexOf(pm.response.json().status) === -1) {", + " postman.setNextRequest('_createStorageAccount_poller_mock_delay')", + " } else {", + " postman.setNextRequest('_createStorageAccount_generated_get')", + " }", + " }", + "} catch(err) {", + " postman.setNextRequest('_createStorageAccount_generated_get')", + "}", + ], + "id": "i2mz21", + "type": "text/javascript", + }, + }, + ], + "id": "76ivhq", + "name": "_createStorageAccount_poller", + "request": Object { + "header": Array [ + Object { + "key": "x-recording-upstream-base-uri", + "value": "https://management.azure.com", + }, + Object { + "key": "x-recording-id", + "value": "{{x_recording_id}}", + }, + Object { + "key": "x-recording-mode", + "value": "record", + }, + ], + "method": "GET", + "url": Object { + "host": Array [ + "{{x_polling_url}}", + ], + "query": Array [], + "variable": Array [], + }, + }, + "response": Array [], + }, + Object { + "description": "{\\"type\\":\\"mock\\",\\"lro_item_name\\":\\"createStorageAccount\\"}", + "event": Array [ + Object { + "id": "86w5gc", + "listen": "prerequest", + "script": Object { + "exec": Array [ + "postman.setNextRequest('_createStorageAccount_poller')", + ], + "id": "8ef99f", + "type": "text/javascript", + }, + }, + ], + "id": "b3xozx", + "name": "_createStorageAccount_poller_mock_delay", + "request": Object { + "method": "GET", + "url": Object { + "host": Array [ + "postman-echo", + "com", + ], + "path": Array [ + "delay", + "{{x_retry_after}}", + ], + "protocol": "https", + "query": Array [], + "variable": Array [], + }, + }, + "response": Array [], + }, + Object { + "description": "{\\"type\\":\\"generated-get\\",\\"lro_item_name\\":\\"createStorageAccount\\",\\"step\\":\\"createStorageAccount\\"}", + "event": Array [ + Object { + "id": "hty0qz", + "listen": "test", + "script": Object { + "exec": Array [ + "pm.test(\\"response status code assertion.\\", function() {", + "pm.response.to.be.success;", + "});", + ], + "id": "20gl49", + "type": "text/javascript", + }, + }, + ], + "id": "ugk6h2", + "name": "_createStorageAccount_generated_get", + "request": Object { + "header": Array [ + Object { + "key": "x-recording-upstream-base-uri", + "value": "https://management.azure.com", + }, + Object { + "key": "x-recording-id", + "value": "{{x_recording_id}}", + }, + Object { + "key": "x-recording-mode", + "value": "record", + }, + Object { + "key": "Content-Type", + "value": "application/json", + }, + ], + "method": "GET", + "url": Object { + "host": Array [ + "http://localhost:5000", + ], + "path": Array [ + "subscriptions", + ":subscriptionId", + "resourceGroups", + ":resourceGroupName", + "providers", + "Microsoft.Storage", + "storageAccounts", + ":accountName", + ], + "query": Array [ + Object { + "key": "api-version", + "value": "2021-08-01", + }, + ], + "variable": Array [ + Object { + "key": "resourceGroupName", + "type": "any", + "value": "{{resourceGroupName}}", + }, + Object { + "key": "accountName", + "type": "any", + "value": "{{accountName}}", + }, + Object { + "key": "subscriptionId", + "type": "any", + "value": "{{subscriptionId}}", + }, + ], + }, + }, + "response": Array [], + }, + Object { + "event": Array [ + Object { + "id": "2r0mc4", + "listen": "test", + "script": Object { + "exec": Array [ + "pm.test(\\"response code should be 2xx\\", function() {", + "pm.response.to.be.success;", + "});", + ], + "id": "56m9l3", + "type": "text/javascript", + }, + }, + Object { + "id": "182s89", + "listen": "test", + "script": Object { + "exec": Array [ + "", + "const pollingUrl = pm.response.headers.get(\\"Location\\") || pm.response.headers.get(\\"Azure-AsyncOperation\\");", + "if (pollingUrl) {", + " pm.collectionVariables.set(\\"x_polling_url\\", pollingUrl.replace(\\"https://management.azure.com\\",\\"http://localhost:5000\\"));", + "}", + ], + "id": "hakk8a", + "type": "text/javascript", + }, + }, + ], + "id": "qbyj9c", "name": "deleteResourceGroup", "request": Object { "header": Array [ @@ -1945,7 +2482,7 @@ Array [ "description": "{\\"type\\":\\"poller\\",\\"lro_item_name\\":\\"deleteResourceGroup\\"}", "event": Array [ Object { - "id": "ehebqq", + "id": "vwghxn", "listen": "test", "script": Object { "exec": Array [ @@ -1967,12 +2504,12 @@ Array [ " postman.setNextRequest('stopTestProxyRecording')", "}", ], - "id": "f9zxy5", + "id": "fmkiq3", "type": "text/javascript", }, }, ], - "id": "ew9nh8", + "id": "jy1tzu", "name": "_deleteResourceGroup_poller", "request": Object { "header": Array [ @@ -2004,18 +2541,18 @@ Array [ "description": "{\\"type\\":\\"mock\\",\\"lro_item_name\\":\\"deleteResourceGroup\\"}", "event": Array [ Object { - "id": "yzy1ec", + "id": "tdrxs5", "listen": "prerequest", "script": Object { "exec": Array [ "postman.setNextRequest('_deleteResourceGroup_poller')", ], - "id": "bw1q38", + "id": "y8jsuq", "type": "text/javascript", }, }, ], - "id": "2vc31r", + "id": "x0t20h", "name": "_deleteResourceGroup_poller_mock_delay", "request": Object { "method": "GET", @@ -2038,7 +2575,7 @@ Array [ Object { "event": Array [ Object { - "id": "odehko", + "id": "jt84jj", "listen": "test", "script": Object { "exec": Array [ @@ -2048,12 +2585,12 @@ Array [ "});", "", ], - "id": "9quvnq", + "id": "r3ps8d", "type": "text/javascript", }, }, ], - "id": "zo75y7", + "id": "c6vfm3", "name": "stopTestProxyRecording", "request": Object { "header": Array [ @@ -2081,10 +2618,37 @@ Array [ }, ], "variable": Array [ + Object { + "key": "parameters", + "type": "any", + "value": Object { + "properties": Object { + "kind": "StorageV2", + "location": "westus", + "patches": Array [ + Object { + "add": "/properties/kind", + "value": "StorageV2", + }, + ], + "properties": Object { + "encryption": Object { + "keySource": "Microsoft.Storage", + "services": Object { + "blob": Object {}, + }, + }, + }, + "sku": Object { + "name": "Standard_LRS", + }, + }, + }, + }, Object { "key": "accountName", "type": "any", - "value": "foobardb187u", + "value": "star4of8l", }, Object { "key": "subscriptionId", @@ -4451,7 +5015,7 @@ Array [ " postman.setNextRequest('_createStorageAccount_generated_get')", "}", ], - "id": "bsqg1o", + "id": "dm09uw", "type": "text/javascript", }, }, @@ -4661,161 +5225,6 @@ Array [ }, "response": Array [], }, - Object { - "event": Array [ - Object { - "id": "9ezdsu", - "listen": "test", - "script": Object { - "exec": Array [ - "pm.test(\\"response code should be 2xx\\", function() {", - "pm.response.to.be.success;", - "});", - ], - "id": "q1cfqt", - "type": "text/javascript", - }, - }, - Object { - "id": "lk4mhm", - "listen": "test", - "script": Object { - "exec": Array [ - "", - "const pollingUrl = pm.response.headers.get(\\"Location\\") || pm.response.headers.get(\\"Azure-AsyncOperation\\");", - "if (pollingUrl) {", - " pm.collectionVariables.set(\\"x_polling_url\\", pollingUrl);", - "}", - ], - "id": "vm8psu", - "type": "text/javascript", - }, - }, - ], - "id": "dm09uw", - "name": "deleteResourceGroup", - "request": Object { - "header": Array [ - Object { - "key": "Content-Type", - "value": "application/json", - }, - ], - "method": "DELETE", - "url": Object { - "host": Array [ - "https://management", - "azure", - "com", - ], - "path": Array [ - "subscriptions", - ":subscriptionId", - "resourcegroups", - ":resourceGroupName", - ], - "query": Array [ - Object { - "key": "api-version", - "value": "2020-06-01", - }, - ], - "variable": Array [ - Object { - "key": "subscriptionId", - "type": "any", - "value": "{{subscriptionId}}", - }, - Object { - "key": "resourceGroupName", - "type": "any", - "value": "{{resourceGroupName}}", - }, - ], - }, - }, - "response": Array [], - }, - Object { - "description": "{\\"type\\":\\"poller\\",\\"lro_item_name\\":\\"deleteResourceGroup\\"}", - "event": Array [ - Object { - "id": "kqos97", - "listen": "test", - "script": Object { - "exec": Array [ - "", - "try {", - " if (pm.response.code === 202) {", - " postman.setNextRequest('_deleteResourceGroup_poller_mock_delay');", - " } else if (pm.response.code === 204) {", - " postman.setNextRequest(null);", - " } else {", - " const terminalStatus = [\\"Succeeded\\", \\"Failed\\", \\"Canceled\\"];", - " if (pm.response.json().status !== undefined && terminalStatus.indexOf(pm.response.json().status) === -1) {", - " postman.setNextRequest('_deleteResourceGroup_poller_mock_delay')", - " } else {", - " postman.setNextRequest(null)", - " }", - " }", - "} catch(err) {", - " postman.setNextRequest(null)", - "}", - ], - "id": "a7lkxi", - "type": "text/javascript", - }, - }, - ], - "id": "ivu9xy", - "name": "_deleteResourceGroup_poller", - "request": Object { - "method": "GET", - "url": Object { - "host": Array [ - "{{x_polling_url}}", - ], - "query": Array [], - "variable": Array [], - }, - }, - "response": Array [], - }, - Object { - "description": "{\\"type\\":\\"mock\\",\\"lro_item_name\\":\\"deleteResourceGroup\\"}", - "event": Array [ - Object { - "id": "qh9z16", - "listen": "prerequest", - "script": Object { - "exec": Array [ - "postman.setNextRequest('_deleteResourceGroup_poller')", - ], - "id": "spylrr", - "type": "text/javascript", - }, - }, - ], - "id": "mge3qz", - "name": "_deleteResourceGroup_poller_mock_delay", - "request": Object { - "method": "GET", - "url": Object { - "host": Array [ - "postman-echo", - "com", - ], - "path": Array [ - "delay", - "{{x_retry_after}}", - ], - "protocol": "https", - "query": Array [], - "variable": Array [], - }, - }, - "response": Array [], - }, ], "variable": Array [ Object { @@ -4871,5 +5280,603 @@ Array [ }, ], }, + Object { + "auth": Object { + "bearer": Array [ + Object { + "key": "token", + "type": "string", + "value": "{{x_bearer_token}}", + }, + ], + "type": "bearer", + }, + "event": Array [ + Object { + "id": "9ezdsu", + "listen": "prerequest", + "script": Object { + "exec": Array [ + "", + "if (pm.variables.get(\\"x_enable_auth\\") !== \\"true\\") {", + " return;", + "}", + "let vars = [\\"client_id\\", \\"client_secret\\", \\"tenantId\\", \\"subscriptionId\\"];", + "vars.forEach(function (item, index, array) {", + " pm.expect(", + " pm.variables.get(item),", + " item + \\" variable not set\\"", + " ).to.not.be.undefined;", + " pm.expect(pm.variables.get(item), item + \\" variable not set\\").to.not.be.empty;", + "});", + "if (", + " !pm.collectionVariables.get(\\"x_bearer_token\\") ||", + " Date.now() >", + " new Date(pm.collectionVariables.get(\\"x_bearer_token_expires_on\\") * 1000)", + ") {", + " pm.sendRequest(", + " {", + " url:", + " \\"https://login.microsoftonline.com/\\" +", + " pm.variables.get(\\"tenantId\\") +", + " \\"/oauth2/token\\",", + " method: \\"POST\\",", + " header: \\"Content-Type: application/x-www-form-urlencoded\\",", + " body: {", + " mode: \\"urlencoded\\",", + " urlencoded: [", + " { key: \\"grant_type\\", value: \\"client_credentials\\", disabled: false },", + " {", + " key: \\"client_id\\",", + " value: pm.variables.get(\\"client_id\\"),", + " disabled: false,", + " },", + " {", + " key: \\"client_secret\\",", + " value: pm.variables.get(\\"client_secret\\"),", + " disabled: false,", + " },", + " { key: \\"resource\\", value: \\"https://management.azure.com\\", disabled: false },", + " ],", + " },", + " },", + " function (err, res) {", + " if (err) {", + " console.log(err);", + " } else {", + " let resJson = res.json();", + " pm.collectionVariables.set(", + " \\"x_bearer_token_expires_on\\",", + " resJson.expires_on", + " );", + " pm.collectionVariables.set(\\"x_bearer_token\\", resJson.access_token);", + " }", + " }", + " );", + "}", + ], + "id": "q1cfqt", + "type": "text/javascript", + }, + }, + ], + "info": Object { + "_postman_id": "jestRunId", + "description": Object { + "content": "{\\"apiScenarioFilePath\\":\\"Microsoft.Storage/stable/2021-08-01/scenarios/storageQuickStart.yaml\\",\\"apiScenarioName\\":\\"patchVariables\\",\\"swaggerFilePaths\\":[\\"Microsoft.Storage/stable/2021-08-01/storage.json\\"]}", + "type": "text/plain", + }, + "name": "patchVariables", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "version": undefined, + }, + "item": Array [ + Object { + "description": "{\\"type\\":\\"LRO\\",\\"poller_item_name\\":\\"createStorageAccount_poller\\",\\"operationId\\":\\"StorageAccounts_Create\\",\\"itemName\\":\\"createStorageAccount\\",\\"step\\":\\"createStorageAccount\\"}", + "event": Array [ + Object { + "id": "ivu9xy", + "listen": "prerequest", + "script": Object { + "exec": Array [ + "pm.variables.set(\\"parameters\\", \\"[object Object]\\");", + ], + "id": "lk4mhm", + "type": "text/javascript", + }, + }, + Object { + "id": "spylrr", + "listen": "test", + "script": Object { + "exec": Array [ + "pm.test(\\"response status code assertion.\\", function() {", + "pm.response.to.be.success;", + "});", + ], + "id": "mge3qz", + "type": "text/javascript", + }, + }, + Object { + "id": "eq5yyi", + "listen": "test", + "script": Object { + "exec": Array [ + "", + "const pollingUrl = pm.response.headers.get(\\"Location\\") || pm.response.headers.get(\\"Azure-AsyncOperation\\");", + "if (pollingUrl) {", + " pm.collectionVariables.set(\\"x_polling_url\\", pollingUrl);", + "}", + ], + "id": "qh9z16", + "type": "text/javascript", + }, + }, + ], + "id": "vm8psu", + "name": "createStorageAccount", + "request": Object { + "body": Object { + "mode": "raw", + "raw": "{ + \\"properties\\": { + \\"sku\\": \\"Standard\\", + \\"kind\\": \\"StorageV2\\", + \\"location\\": \\"{{location}}\\", + \\"properties\\": { + \\"encryption\\": { + \\"services\\": { + \\"blob\\": {} + }, + \\"keySource\\": \\"Microsoft.Storage\\" + } + }, + \\"patches\\": [ + { + \\"add\\": \\"/properties/kind\\", + \\"value\\": \\"StorageV2\\" + } + ] + } +}", + }, + "header": Array [ + Object { + "key": "Content-Type", + "value": "application/json", + }, + ], + "method": "PUT", + "url": Object { + "host": Array [ + "https://management", + "azure", + "com", + ], + "path": Array [ + "subscriptions", + ":subscriptionId", + "resourceGroups", + ":resourceGroupName", + "providers", + "Microsoft.Storage", + "storageAccounts", + ":accountName", + ], + "query": Array [ + Object { + "key": "api-version", + "value": "2021-08-01", + }, + ], + "variable": Array [ + Object { + "key": "resourceGroupName", + "type": "any", + "value": "{{resourceGroupName}}", + }, + Object { + "key": "accountName", + "type": "any", + "value": "{{accountName}}", + }, + Object { + "key": "subscriptionId", + "type": "any", + "value": "{{subscriptionId}}", + }, + ], + }, + }, + "response": Array [], + }, + Object { + "description": "{\\"type\\":\\"poller\\",\\"lro_item_name\\":\\"createStorageAccount\\"}", + "event": Array [ + Object { + "id": "c9wzyn", + "listen": "test", + "script": Object { + "exec": Array [ + "", + "try {", + " if (pm.response.code === 202) {", + " postman.setNextRequest('_createStorageAccount_poller_mock_delay');", + " } else if (pm.response.code === 204) {", + " postman.setNextRequest('_createStorageAccount_generated_get');", + " } else {", + " const terminalStatus = [\\"Succeeded\\", \\"Failed\\", \\"Canceled\\"];", + " if (pm.response.json().status !== undefined && terminalStatus.indexOf(pm.response.json().status) === -1) {", + " postman.setNextRequest('_createStorageAccount_poller_mock_delay')", + " } else {", + " postman.setNextRequest('_createStorageAccount_generated_get')", + " }", + " }", + "} catch(err) {", + " postman.setNextRequest('_createStorageAccount_generated_get')", + "}", + ], + "id": "f9zxy5", + "type": "text/javascript", + }, + }, + ], + "id": "kqos97", + "name": "_createStorageAccount_poller", + "request": Object { + "method": "GET", + "url": Object { + "host": Array [ + "{{x_polling_url}}", + ], + "query": Array [], + "variable": Array [], + }, + }, + "response": Array [], + }, + Object { + "description": "{\\"type\\":\\"mock\\",\\"lro_item_name\\":\\"createStorageAccount\\"}", + "event": Array [ + Object { + "id": "65xm09", + "listen": "prerequest", + "script": Object { + "exec": Array [ + "postman.setNextRequest('_createStorageAccount_poller')", + ], + "id": "a7lkxi", + "type": "text/javascript", + }, + }, + ], + "id": "bsqg1o", + "name": "_createStorageAccount_poller_mock_delay", + "request": Object { + "method": "GET", + "url": Object { + "host": Array [ + "postman-echo", + "com", + ], + "path": Array [ + "delay", + "{{x_retry_after}}", + ], + "protocol": "https", + "query": Array [], + "variable": Array [], + }, + }, + "response": Array [], + }, + Object { + "description": "{\\"type\\":\\"generated-get\\",\\"lro_item_name\\":\\"createStorageAccount\\",\\"step\\":\\"createStorageAccount\\"}", + "event": Array [ + Object { + "id": "d9yng9", + "listen": "test", + "script": Object { + "exec": Array [ + "pm.test(\\"response status code assertion.\\", function() {", + "pm.response.to.be.success;", + "});", + ], + "id": "wlgh2r", + "type": "text/javascript", + }, + }, + ], + "id": "gsyqal", + "name": "_createStorageAccount_generated_get", + "request": Object { + "header": Array [ + Object { + "key": "Content-Type", + "value": "application/json", + }, + ], + "method": "GET", + "url": Object { + "host": Array [ + "https://management", + "azure", + "com", + ], + "path": Array [ + "subscriptions", + ":subscriptionId", + "resourceGroups", + ":resourceGroupName", + "providers", + "Microsoft.Storage", + "storageAccounts", + ":accountName", + ], + "query": Array [ + Object { + "key": "api-version", + "value": "2021-08-01", + }, + ], + "variable": Array [ + Object { + "key": "resourceGroupName", + "type": "any", + "value": "{{resourceGroupName}}", + }, + Object { + "key": "accountName", + "type": "any", + "value": "{{accountName}}", + }, + Object { + "key": "subscriptionId", + "type": "any", + "value": "{{subscriptionId}}", + }, + ], + }, + }, + "response": Array [], + }, + Object { + "event": Array [ + Object { + "id": "2vc31r", + "listen": "test", + "script": Object { + "exec": Array [ + "pm.test(\\"response code should be 2xx\\", function() {", + "pm.response.to.be.success;", + "});", + ], + "id": "ew9nh8", + "type": "text/javascript", + }, + }, + Object { + "id": "yzy1ec", + "listen": "test", + "script": Object { + "exec": Array [ + "", + "const pollingUrl = pm.response.headers.get(\\"Location\\") || pm.response.headers.get(\\"Azure-AsyncOperation\\");", + "if (pollingUrl) {", + " pm.collectionVariables.set(\\"x_polling_url\\", pollingUrl);", + "}", + ], + "id": "bw1q38", + "type": "text/javascript", + }, + }, + ], + "id": "sp8ib7", + "name": "deleteResourceGroup", + "request": Object { + "header": Array [ + Object { + "key": "Content-Type", + "value": "application/json", + }, + ], + "method": "DELETE", + "url": Object { + "host": Array [ + "https://management", + "azure", + "com", + ], + "path": Array [ + "subscriptions", + ":subscriptionId", + "resourcegroups", + ":resourceGroupName", + ], + "query": Array [ + Object { + "key": "api-version", + "value": "2020-06-01", + }, + ], + "variable": Array [ + Object { + "key": "subscriptionId", + "type": "any", + "value": "{{subscriptionId}}", + }, + Object { + "key": "resourceGroupName", + "type": "any", + "value": "{{resourceGroupName}}", + }, + ], + }, + }, + "response": Array [], + }, + Object { + "description": "{\\"type\\":\\"poller\\",\\"lro_item_name\\":\\"deleteResourceGroup\\"}", + "event": Array [ + Object { + "id": "col7eq", + "listen": "test", + "script": Object { + "exec": Array [ + "", + "try {", + " if (pm.response.code === 202) {", + " postman.setNextRequest('_deleteResourceGroup_poller_mock_delay');", + " } else if (pm.response.code === 204) {", + " postman.setNextRequest(null);", + " } else {", + " const terminalStatus = [\\"Succeeded\\", \\"Failed\\", \\"Canceled\\"];", + " if (pm.response.json().status !== undefined && terminalStatus.indexOf(pm.response.json().status) === -1) {", + " postman.setNextRequest('_deleteResourceGroup_poller_mock_delay')", + " } else {", + " postman.setNextRequest(null)", + " }", + " }", + "} catch(err) {", + " postman.setNextRequest(null)", + "}", + ], + "id": "76ivhq", + "type": "text/javascript", + }, + }, + ], + "id": "l0fzps", + "name": "_deleteResourceGroup_poller", + "request": Object { + "method": "GET", + "url": Object { + "host": Array [ + "{{x_polling_url}}", + ], + "query": Array [], + "variable": Array [], + }, + }, + "response": Array [], + }, + Object { + "description": "{\\"type\\":\\"mock\\",\\"lro_item_name\\":\\"deleteResourceGroup\\"}", + "event": Array [ + Object { + "id": "9quvnq", + "listen": "prerequest", + "script": Object { + "exec": Array [ + "postman.setNextRequest('_deleteResourceGroup_poller')", + ], + "id": "zo75y7", + "type": "text/javascript", + }, + }, + ], + "id": "ehebqq", + "name": "_deleteResourceGroup_poller_mock_delay", + "request": Object { + "method": "GET", + "url": Object { + "host": Array [ + "postman-echo", + "com", + ], + "path": Array [ + "delay", + "{{x_retry_after}}", + ], + "protocol": "https", + "query": Array [], + "variable": Array [], + }, + }, + "response": Array [], + }, + ], + "variable": Array [ + Object { + "key": "parameters", + "type": "any", + "value": Object { + "properties": Object { + "kind": "StorageV2", + "location": "westus", + "patches": Array [ + Object { + "add": "/properties/kind", + "value": "StorageV2", + }, + ], + "properties": Object { + "encryption": Object { + "keySource": "Microsoft.Storage", + "services": Object { + "blob": Object {}, + }, + }, + }, + "sku": Object { + "name": "Standard_LRS", + }, + }, + }, + }, + Object { + "key": "accountName", + "type": "any", + "value": "star4of8l", + }, + Object { + "key": "subscriptionId", + "type": "any", + }, + Object { + "key": "resourceGroupName", + "type": "any", + }, + Object { + "key": "location", + "type": "any", + }, + Object { + "key": "client_id", + "type": "any", + }, + Object { + "key": "client_secret", + "type": "any", + }, + Object { + "key": "tenantId", + "type": "any", + }, + Object { + "key": "x_enable_auth", + "type": "any", + "value": "true", + }, + Object { + "key": "x_bearer_token", + "type": "any", + }, + Object { + "key": "x_bearer_token_expires_on", + "type": "any", + }, + Object { + "key": "x_polling_url", + "type": "any", + }, + Object { + "key": "x_retry_after", + "type": "any", + "value": "10", + }, + ], + }, ] `; diff --git a/test/apiScenario/fixtures/specification/storage/resource-manager/Microsoft.Storage/stable/2021-08-01/scenarios/storageQuickStart.yaml b/test/apiScenario/fixtures/specification/storage/resource-manager/Microsoft.Storage/stable/2021-08-01/scenarios/storageQuickStart.yaml index b56efbc6..d60698b1 100644 --- a/test/apiScenario/fixtures/specification/storage/resource-manager/Microsoft.Storage/stable/2021-08-01/scenarios/storageQuickStart.yaml +++ b/test/apiScenario/fixtures/specification/storage/resource-manager/Microsoft.Storage/stable/2021-08-01/scenarios/storageQuickStart.yaml @@ -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