From 76e2c227a4dfb21db9bc7095cc9d49fd4367e254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yuan=20Xulei=28=E8=A2=81=E5=BE=90=E7=A3=8A=29?= Date: Thu, 4 May 2023 12:38:50 +0800 Subject: [PATCH] support providing parameter values and post body values for getting snippets --- index.js | 14 ++++++---- openapi-to-har.js | 65 ++++++++++++++++++++++++++++++++++------------- test/test.js | 26 +++++++++++++++++-- 3 files changed, 81 insertions(+), 24 deletions(-) diff --git a/index.js b/index.js index ea07bdf..7692e11 100644 --- a/index.js +++ b/index.js @@ -20,15 +20,19 @@ const HTTPSnippet = require('httpsnippet'); * @param {string} method HTTP method identifying endpoint, e.g., 'get' * @param {array} targets List of languages to create snippets in, e.g, * ['cURL', 'Node'] - * @param {object} values Optional: Values for the query parameters if present + * @param {object} parameterValues Optional: Values for the parameters if present + * @param {object} requestBodyValues Optional: Values for the request body if present */ -const getEndpointSnippets = function (openApi, path, method, targets, values) { +const getEndpointSnippets = function (openApi, path, method, targets, parameterValues, requestBodyValues) { // if optional parameter is not provided, set it to empty object - if (typeof values === 'undefined') { - values = {}; + if (typeof parameterValues === 'undefined') { + parameterValues = {}; + } + if (typeof requestBodyValues === 'undefined') { + requestBodyValues = {}; } - const hars = OpenAPIToHar.getEndpoint(openApi, path, method, values); + const hars = OpenAPIToHar.getEndpoint(openApi, path, method, parameterValues, requestBodyValues); const snippets = []; for (const har of hars) { diff --git a/openapi-to-har.js b/openapi-to-har.js index 2d9daf2..d5b82a2 100644 --- a/openapi-to-har.js +++ b/openapi-to-har.js @@ -27,24 +27,28 @@ const OpenAPISampler = require('openapi-sampler'); * @param {Object} openApi OpenAPI document * @param {string} path Key of the path * @param {string} method Key of the method - * @param {Object} queryParamValues Optional: Values for the query parameters if present + * @param {Object} paramValues Optional: Values for the parameters if present + * @param {object} requestBodyValues Optional: Values for the request body if present * @return {array} List of HAR Request objects for the endpoint */ -const createHar = function (openApi, path, method, queryParamValues) { +const createHar = function (openApi, path, method, paramValues, requestBodyValues) { // if the operational parameter is not provided, set it to empty object - if (typeof queryParamValues === 'undefined') { - queryParamValues = {}; + if (typeof paramValues === 'undefined') { + paramValues = {}; + } + if (typeof requestBodyValues === 'undefined') { + requestBodyValues = {}; } const baseUrl = getBaseUrl(openApi, path, method); const baseHar = { method: method.toUpperCase(), - url: baseUrl + getFullPath(openApi, path, method), - headers: getHeadersArray(openApi, path, method), - queryString: getQueryStrings(openApi, path, method, queryParamValues), + url: baseUrl + getFullPath(openApi, path, method, paramValues), + headers: getHeadersArray(openApi, path, method, paramValues), + queryString: getQueryStrings(openApi, path, method, paramValues), httpVersion: 'HTTP/1.1', - cookies: getCookies(openApi, path, method), + cookies: getCookies(openApi, path, method, paramValues), headersSize: 0, bodySize: 0, }; @@ -52,7 +56,7 @@ const createHar = function (openApi, path, method, queryParamValues) { let hars = []; // get payload data, if available: - const postDatas = getPayloads(openApi, path, method); + const postDatas = getPayloads(openApi, path, method, requestBodyValues); // For each postData create a snippet if (postDatas.length > 0) { @@ -297,9 +301,14 @@ const createHarParameterObjects = function ( * @param {object} openApi * @param {string} path * @param {string} method + * @param {object} requestBodyValues Optional: Values for the request body if present * @return {array} A list of payload objects */ -const getPayloads = function (openApi, path, method) { +const getPayloads = function (openApi, path, method, requestBodyValues) { + // If requestBodyValues is not defined, set it to an empty object + if (typeof requestBodyValues === 'undefined') { + requestBodyValues = {}; + } if (typeof openApi.paths[path][method].parameters !== 'undefined') { for (let i in openApi.paths[path][method].parameters) { const param = openApi.paths[path][method].parameters[i]; @@ -355,6 +364,13 @@ const getPayloads = function (openApi, path, method) { { skipReadOnly: true }, openApi ); + // fill the sample with the provided values from the request body values + for (const name in requestBodyValues) { + const value = requestBodyValues[name]; + if (value) { + sample[name] = value; + } + } if (type === 'application/json') { payloads.push({ mimeType: type, @@ -609,16 +625,21 @@ const getQueryStrings = function (openApi, path, method, values) { * @param {Object} openApi OpenApi document * @param {string} path Key of the path * @param {string} method Key of the method + * @param {Object} paramValues Optional: Values for the parameters if present * @return {string} Full path including example values */ -const getFullPath = function (openApi, path, method) { +const getFullPath = function (openApi, path, method, paramValues) { let fullPath = path; - + // if the operational parameter is not provided, set it to empty object + if (typeof paramValues === undefined) { + paramValues = {}; + } const pathParameters = getParameterCollectionIn( openApi, path, method, - 'path' + 'path', + paramValues ); pathParameters.forEach(({ name, value }) => { fullPath = fullPath.replace('{' + name + '}', value); @@ -633,9 +654,14 @@ const getFullPath = function (openApi, path, method) { * @param {Object} openApi OpenAPI document * @param {string} path Key of the path * @param {string} method Key of the method + * @param {Object} paramValues Optional: Values for the parameters if present */ -const getCookies = function (openApi, path, method) { - return getParameterCollectionIn(openApi, path, method, 'cookie'); +const getCookies = function (openApi, path, method, paramValues) { + // if the operational parameter is not provided, set it to empty object + if (typeof paramValues === 'undefined') { + paramValues = {}; + } + return getParameterCollectionIn(openApi, path, method, 'cookie', paramValues); }; /** @@ -645,11 +671,16 @@ const getCookies = function (openApi, path, method) { * @param {Object} openApi OpenAPI document * @param {string} path Key of the path * @param {string} method Key of the method + * @param {Object} paramValues Optional: Values for the parameters if present * @return {HarParameterObject[]} List of objects describing the header */ -const getHeadersArray = function (openApi, path, method) { +const getHeadersArray = function (openApi, path, method, paramValues) { const headers = []; const pathObj = openApi.paths[path][method]; + // if the operational parameter is not provided, set it to empty object + if (typeof paramValues === 'undefined') { + paramValues = {}; + } // 'accept' header: if (typeof pathObj.consumes !== 'undefined') { @@ -663,7 +694,7 @@ const getHeadersArray = function (openApi, path, method) { } // headers defined in path object: - headers.push(...getParameterCollectionIn(openApi, path, method, 'header')); + headers.push(...getParameterCollectionIn(openApi, path, method, 'header', paramValues)); // security: let basicAuthDef; diff --git a/test/test.js b/test/test.js index cd59409..cd9ab2a 100644 --- a/test/test.js +++ b/test/test.js @@ -121,6 +121,23 @@ test('Testing optionally provided parameter values', function (t) { t.false(/not-a-query-param/.test(result.snippets[0].content)); }); +test('Testing optionally provided parameter values in path and query', function (t) { + t.plan(2); + // checks the 'Pages' schema... + const result = OpenAPISnippets.getEndpointSnippets( + InstagramOpenAPI, + '/geographies/{geo-id}/media/recent', + 'get', + ['node_request'], + { + 'geo-id': 'geo-id-xxx', + 'count': 1024, + } + ); + t.true(/geo-id-xxx/.test(result.snippets[0].content)); + t.true(/1024/.test(result.snippets[0].content)); +}); + test('Testing the case when default is present but a value is provided, use the provided value', function (t) { t.plan(2); // checks the 'Pages' schema... @@ -209,12 +226,17 @@ test('Generate snippet with multipart/form-data', function (t) { FormDataExampleReferenceAPI, '/pets', 'patch', - ['node_request'] + ['node_request'], + {}, + { + 'pet[name]': 'happy', + 'pet[tag]': 'puppy' + } ); const snippet = result.snippets[0].content; t.true(/boundary=---011000010111000001101001/.test(snippet)); t.true( - /formData: {'pet\[name\]': 'string', 'pet\[tag\]': 'string'}/.test(snippet) + /formData: {'pet\[name\]': 'happy', 'pet\[tag\]': 'puppy'}/.test(snippet) ); t.end(); });