diff --git a/sdkgen/nodejs-request/npm/test-lint.js b/sdkgen/nodejs-request/npm/test-lint.js new file mode 100644 index 0000000..1a604ca --- /dev/null +++ b/sdkgen/nodejs-request/npm/test-lint.js @@ -0,0 +1,57 @@ +#!/usr/bin/env node +require('shelljs/global'); + +var chalk = require('chalk'), + async = require('async'), + ESLintCLIEngine = require('eslint').CLIEngine, + + /** + * The list of source code files / directories to be linted. + * + * @type {Array} + */ + LINT_SOURCE_DIRS = [ + './lib', + // './test', + './npm/*.js', + './index.js' + ]; + +module.exports = function (exit) { + // banner line + console.info(chalk.yellow.bold('\nLinting files using eslint...')); + + async.waterfall([ + + /** + * Instantiates an ESLint CLI engine and runs it in the scope defined within LINT_SOURCE_DIRS. + * + * @param {Function} next - The callback function whose invocation marks the end of the lint test run. + * @returns {*} + */ + function (next) { + next(null, (new ESLintCLIEngine()).executeOnFiles(LINT_SOURCE_DIRS)); + }, + + /** + * Processes a test report from the Lint test runner, and displays meaningful results. + * + * @param {Object} report - The overall test report for the current lint test. + * @param {Object} report.results - The set of test results for the current lint run. + * @param {Function} next - The callback whose invocation marks the completion of the post run tasks. + * @returns {*} + */ + function (report, next) { + var errorReport = ESLintCLIEngine.getErrorResults(report.results); + // log the result to CLI + console.info(ESLintCLIEngine.getFormatter()(report.results)); + // log the success of the parser if it has no errors + (errorReport && !errorReport.length) && console.info(chalk.green('eslint ok!')); + // ensure that the exit code is non zero in case there was an error + next(Number(errorReport && errorReport.length) || 0); + } + ], exit); +}; + +// ensure we run this script exports if this is a direct stdin.tty run +!module.parent && module.exports(exit); diff --git a/sdkgen/nodejs-request/npm/test-unit.js b/sdkgen/nodejs-request/npm/test-unit.js new file mode 100644 index 0000000..648d066 --- /dev/null +++ b/sdkgen/nodejs-request/npm/test-unit.js @@ -0,0 +1,60 @@ +#!/usr/bin/env node +/* eslint-env node, es6 */ +// --------------------------------------------------------------------------------------------------------------------- +// This script is intended to execute all unit tests. +// --------------------------------------------------------------------------------------------------------------------- + +require('shelljs/global'); + +// set directories and files for test and coverage report +var path = require('path'), + + NYC = require('nyc'), + chalk = require('chalk'), + recursive = require('recursive-readdir'), + + COV_REPORT_PATH = '.coverage', + SPEC_SOURCE_DIR = path.join(__dirname, '..', 'test', 'unit'); + +module.exports = function (exit) { + // banner line + console.info(chalk.yellow.bold('Running unit tests using mocha on node...')); + + test('-d', COV_REPORT_PATH) && rm('-rf', COV_REPORT_PATH); + mkdir('-p', COV_REPORT_PATH); + mkdir('-p', COV_REPORT_PATH + '/processinfo'); + + var Mocha = require('mocha'), + nyc = new NYC({ + reportDir: COV_REPORT_PATH, + tempDirectory: COV_REPORT_PATH, + reporter: ['text', 'lcov', 'text-summary'], + exclude: ['config', 'test'], + hookRunInContext: true, + hookRunInThisContext: true + }); + + nyc.wrap(); + // add all spec files to mocha + recursive(SPEC_SOURCE_DIR, function (err, files) { + if (err) { console.error(err); return exit(1); } + + var mocha = new Mocha({ timeout: 1000 * 60 }); + + files.filter(function (file) { // extract all test files + return (file.substr(-8) === '.test.js'); + }).forEach(mocha.addFile.bind(mocha)); + + mocha.run(function (runError) { + runError && console.error(runError.stack || runError); + + nyc.reset(); + nyc.writeCoverageFile(); + nyc.report(); + exit(runError ? 1 : 0); + }); + }); +}; + +// ensure we run this script exports if this is a direct stdin.tty run +!module.parent && module.exports(exit); diff --git a/sdkgen/nodejs-request/npm/test.js b/sdkgen/nodejs-request/npm/test.js new file mode 100644 index 0000000..fc6a007 --- /dev/null +++ b/sdkgen/nodejs-request/npm/test.js @@ -0,0 +1,15 @@ +#!/usr/bin/env node +var chalk = require('chalk'), + exit = require('shelljs').exit, + prettyms = require('pretty-ms'), + startedAt = Date.now(), + name = require('../package.json').name; + +require('async').series([ + require('./test-lint'), + require('./test-unit') +], function (code) { + // eslint-disable-next-line max-len + console.info(chalk[code ? 'red' : 'green'](`\n${name}: duration ${prettyms(Date.now() - startedAt)}\n${name}: ${code ? 'not ok' : 'ok'}!`)); + exit(code && (typeof code === 'number' ? code : 1) || 0); +}); diff --git a/sdkgen/nodejs-request/package.json b/sdkgen/nodejs-request/package.json index 3216cf7..832cfd1 100644 --- a/sdkgen/nodejs-request/package.json +++ b/sdkgen/nodejs-request/package.json @@ -4,6 +4,9 @@ "description": "Converts Postman Collection to nodejs-request client SDK", "main": "index.js", "license": "Apache-2.0", + "scripts": { + "test": "node npm/test.js" + }, "dependencies": { "request": "^2.88.2" } diff --git a/sdkgen/nodejs-request/test/fixtures/utilMethodOutputs.json b/sdkgen/nodejs-request/test/fixtures/utilMethodOutputs.json new file mode 100644 index 0000000..36842c2 --- /dev/null +++ b/sdkgen/nodejs-request/test/fixtures/utilMethodOutputs.json @@ -0,0 +1,9 @@ +{ + "SANITIZE" : "test\\'string\\\\n\\\\", + "GENERATE_FUNCTION_SNIPPEPT": "/**\nThe HTTP `GET` request method is meant to retrieve data from a server. The data\nis identified by a unique URI (Uniform Resource Identifier). \n\nA `GET` request can pass parameters to the server using "Query String \nParameters". For example, in the following request,\n\n> http://example.com/hi/there?hand=wave\n\nThe parameter "hand" has the value "wave".\n\nThis endpoint echoes the HTTP headers, request parameters and the complete\nURI requested.\n@param {String} variables.url\n@param {String} variables.var1\n@param {String} variables.var4\n@param {String} variables.var2\n@param {String} variables.var5\n@param {Function} callback - Callback function to return response (err, res)\n*/\nthis.GET_REQUEST = function(variables, callback){\nif (typeof variables === 'function') {\ncallback = variables;\nvariables = {};\n}\nvar url = variables.url ? variables.url : self.variables.url;\nvar var1 = variables.var1 ? variables.var1 : self.variables.var1;\nvar var4 = variables.var4 ? variables.var4 : self.variables.var4;\nvar var2 = variables.var2 ? variables.var2 : self.variables.var2;\nvar var5 = variables.var5 ? variables.var5 : self.variables.var5;\nvar options = {\n 'method': 'GET',\n 'url': '' + url + '/get?foo1=' + var1 + '' + var4 + '&foo2=' + var2 + '' + var5 + '',\n 'headers': {\n }\n};\nrequest(options, function (error, response) {\n callback(error, response);\n});\n}", + "ITEM_HANDLER": { + "COLLECTION_AS_PARENT": "/**\nThe HTTP `GET` request method is meant to retrieve data from a server. The data\nis identified by a unique URI (Uniform Resource Identifier). \n\nA `GET` request can pass parameters to the server using "Query String \nParameters". For example, in the following request,\n\n> http://example.com/hi/there?hand=wave\n\nThe parameter "hand" has the value "wave".\n\nThis endpoint echoes the HTTP headers, request parameters and the complete\nURI requested.\n@param {String} variables.url\n@param {String} variables.var1\n@param {String} variables.var4\n@param {String} variables.var2\n@param {String} variables.var5\n@param {Function} callback - Callback function to return response (err, res)\n*/\nthis.GET_REQUEST = function(variables, callback){\nif (typeof variables === 'function') {\ncallback = variables;\nvariables = {};\n}\nvar url = variables.url ? variables.url : self.variables.url;\nvar var1 = variables.var1 ? variables.var1 : self.variables.var1;\nvar var4 = variables.var4 ? variables.var4 : self.variables.var4;\nvar var2 = variables.var2 ? variables.var2 : self.variables.var2;\nvar var5 = variables.var5 ? variables.var5 : self.variables.var5;\nvar options = {\n 'method': 'GET',\n 'url': '' + url + '/get?foo1=' + var1 + '' + var4 + '&foo2=' + var2 + '' + var5 + '',\n 'headers': {\n }\n};\nrequest(options, function (error, response) {\n callback(error, response);\n});\n};\n\n", + "ITEMGROUP_AS_PARENT": "/**\nThe HTTP `POST` request method is meant to transfer data to a server \n(and elicit a response). What data is returned depends on the implementation\nof the server.\n\nA `POST` request can pass parameters to the server using "Query String \nParameters", as well as the Request Body. For example, in the following request,\n\n> POST /hi/there?hand=wave\n>\n> <request-body>\n\nThe parameter "hand" has the value "wave". The request body can be in multiple\nformats. These formats are defined by the MIME type of the request. The MIME \nType can be set using the ``Content-Type`` HTTP header. The most commonly used \nMIME types are:\n\n* `multipart/form-data`\n* `application/x-www-form-urlencoded`\n* `application/json`\n\nThis endpoint echoes the HTTP headers, request parameters, the contents of\nthe request body and the complete URI requested when data is sent as a form parameter.\n@param {String} variables.url\n@param {String} variables.var4\n@param {String} variables.var5\n@param {Function} callback - Callback function to return response (err, res)\n*/\n\"POST_FORM_DATA\": function(variables, callback){\nif (typeof variables === 'function') {\ncallback = variables;\nvariables = {};\n}\nvar url = variables.url ? variables.url : self.variables.url;\nvar var4 = variables.var4 ? variables.var4 : self.variables.var4;\nvar var5 = variables.var5 ? variables.var5 : self.variables.var5;\nvar options = {\n 'method': 'POST',\n 'url': '' + url + '/post',\n 'headers': {\n },\n form: {\n 'foo1': '' + var4 + '',\n 'foo2': '' + var5 + ''\n }\n};\nrequest(options, function (error, response) {\n callback(error, response);\n});\n}\n" + }, + "GET_VARIABLE_FUNCTIONS": "/**\nFunction to set variables for entire SDK. These variables will override existing/default values.\n\n@param {Object} Object containing env variables\n*/\nSDK.prototype.setVariables = function (vars) {\nlet variables = JSON.parse(JSON.stringify(this.variables || configVariables));\nObject.keys(vars).forEach(function (key) {\nvariables[key] = vars[key];\n});\nthis.variables = variables;\nreturn this.variables;\n};\n\n/**\nMethod to retrieve current variable.\n\n@param {string} [var] - Variable name\n@returns {Object} object containing variables\n*/\nSDK.prototype.getVariables = function (variable) {\nreturn variable ? this.variables[variable] : this.variables;\n};\n\nmodule.exports = SDK;\n" +} diff --git a/sdkgen/nodejs-request/test/unit/snippet.test.js b/sdkgen/nodejs-request/test/unit/snippet.test.js new file mode 100644 index 0000000..8e4ab24 --- /dev/null +++ b/sdkgen/nodejs-request/test/unit/snippet.test.js @@ -0,0 +1,96 @@ +const expect = require('chai').expect, + sdk = require('postman-collection'), + collection = { + SDKGEN: require('../../../../test/fixtures/SDKGEN.postman_collection.json') + }, + variables = { + SDKGEN: require('../../../../test/fixtures/SDKGEN_ENVIRONMENT.json') + }, + generate = require('../../index').generate, + COLLECTION_INSTANCE = new sdk.Collection(collection.SDKGEN); + +describe('Tests for generated sdk', () => { + + it('should generate sdk snippet', async () => { + await generate(COLLECTION_INSTANCE, {}, (err, snippet) => { + if (err) { + expect(err).to.be.null; + } + expect(snippet).to.be.a('string'); + }); + }); + + it('should include nodejs-request library import', async () => { + await generate(COLLECTION_INSTANCE, {}, (err, snippet) => { + if (err) { + expect(err).to.be.null; + } + expect(snippet).to.be.a('string'); + expect(snippet).to.include('var request = require(\'request\')'); + }); + }); + + + it('should add variable if provided', async () => { + await generate(COLLECTION_INSTANCE, { + variableList: new sdk.VariableList(null, variables.SDKGEN.values) + }, (err, snippet) => { + if (err) { + expect(err).to.be.null; + } + expect(snippet).to.be.a('string'); + expect(snippet).to.include('\'url\': \'www.google.com\''); + expect(snippet).to.include('\'var1\': \'valenv1\''); + expect(snippet).to.include('\'var2\': \'valenv2\''); + }); + }); + + it('should have default constructor for generated module', async () => { + await generate(COLLECTION_INSTANCE, {}, (err, snippet) => { + if (err) { + expect(err).to.be.null; + } + expect(snippet).to.be.a('string'); + expect(snippet).to.include('function SDK(config = {})'); + }); + }); + + it('should have get/set Variable methods', async () => { + await generate(COLLECTION_INSTANCE, {}, (err, snippet) => { + if (err) { + expect(err).to.be.null; + } + expect(snippet).to.be.a('string'); + expect(snippet).to.include('SDK.prototype.setVariables = function (vars) {'); + expect(snippet).to.include('SDK.prototype.getVariables = function (variable) {'); + }); + }); + + it('should set initial variables values', async () => { + await generate(COLLECTION_INSTANCE, {}, (err, snippet) => { + if (err) { + expect(err).to.be.null; + } + expect(snippet).to.be.a('string'); + expect(snippet).to.include('this.variables = this.setVariables(config)') + }); + }); + + it('should have self variable declaration', async () => { + await generate(COLLECTION_INSTANCE, {}, (err, snippet) => { + if (err) { + expect(err).to.be.null; + } + expect(snippet).to.include('self = this'); + }); + }); + + it('should have export module snipept', async () => { + await generate(COLLECTION_INSTANCE, {}, (err, snippet) => { + if (err) { + expect(err).to.be.null; + } + expect(snippet).to.include('module.exports = SDK'); + }); + }); +}); diff --git a/sdkgen/nodejs-request/test/unit/util.test.js b/sdkgen/nodejs-request/test/unit/util.test.js new file mode 100644 index 0000000..56d9ccd --- /dev/null +++ b/sdkgen/nodejs-request/test/unit/util.test.js @@ -0,0 +1,60 @@ +const expect = require('chai').expect, + sdk = require('postman-collection'), + utils = require('../../lib/util'), + outputs = require('../fixtures/utilMethodOutputs.json'), + collection = { + SDKGEN: require('../../../../test/fixtures/SDKGEN.postman_collection.json') + }, + COLLECTION_INSTANCE = new sdk.Collection(collection.SDKGEN); + +describe('Util methods tests:', () => { + it('should sanitize strings properly', () => { + // eslint-disable-next-line quotes + let s = "test'string\\n\\"; + s = utils.sanitize(s); + expect(s).to.be.a('string'); + expect(s).to.equals(outputs.SANITIZE); + }); + + it('should generate function snippet for a request', async () => { + let snippet; + try { + snippet = await utils.generateFunctionSnippet(COLLECTION_INSTANCE.items.members[2], {}); + } + catch (err) { + expect(err).to.be.null; + } + expect(snippet).to.be.a('string'); + expect(snippet).to.be.equals(outputs.GENERATE_FUNCTION_SNIPPEPT); + }); + + it('should generate item snippet for input item (parent --> collection instance)', async () => { + let snippet; + try { + snippet = await utils.itemHandler(COLLECTION_INSTANCE.items.members[2], {}); + } + catch (err) { + expect(err).to.be.null; + } + expect(snippet).to.be.a('string'); + expect(snippet).to.be.equals(outputs.ITEM_HANDLER.COLLECTION_AS_PARENT); + }); + + it('should generate item snippet for input item (parent --> itemgroup instance)', async () => { + let snippet; + try { + snippet = await utils.itemHandler(COLLECTION_INSTANCE.items.members[0].items.members[0], {}); + } + catch (err) { + expect(err).to.be.null; + } + expect(snippet).to.be.a('string'); + expect(snippet).to.include(outputs.ITEM_HANDLER.ITEMGROUP_AS_PARENT); + }); + + it('should generate snippet for get/set methods', () => { + let snippet = utils.getVariableFunctions(); + expect(snippet).to.be.a('string'); + expect(snippet).to.include(outputs.GET_VARIABLE_FUNCTIONS); + }); +}); diff --git a/test/fixtures/SDKGEN.postman_collection.json b/test/fixtures/SDKGEN.postman_collection.json new file mode 100644 index 0000000..d541a5d --- /dev/null +++ b/test/fixtures/SDKGEN.postman_collection.json @@ -0,0 +1,442 @@ +{ + "info": { + "_postman_id": "50f156aa-f628-437c-8a52-4e426d091a0d", + "name": "SDKGEN", + "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "Request Methods", + "item": [ + { + "name": "POST Form Data", + "event": [ + { + "listen": "test", + "script": { + "id": "437c9683-1e81-422e-839c-6964d9014bca", + "exec": [ + "pm.test(\"response is ok\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"response body has json with form data\", function () {", + " pm.response.to.have.jsonBody('form.foo1', 'bar1')", + " .and.have.jsonBody('form.foo2', 'bar2');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "foo1", + "value": "{{var4}}", + "type": "text" + }, + { + "key": "foo2", + "value": "{{var5}}", + "type": "text" + } + ], + "options": { + "urlencoded": {} + } + }, + "url": { + "raw": "{{url}}/post", + "host": [ + "{{url}}" + ], + "path": [ + "post" + ] + }, + "description": "The HTTP `POST` request method is meant to transfer data to a server \n(and elicit a response). What data is returned depends on the implementation\nof the server.\n\nA `POST` request can pass parameters to the server using \"Query String \nParameters\", as well as the Request Body. For example, in the following request,\n\n> POST /hi/there?hand=wave\n>\n> \n\nThe parameter \"hand\" has the value \"wave\". The request body can be in multiple\nformats. These formats are defined by the MIME type of the request. The MIME \nType can be set using the ``Content-Type`` HTTP header. The most commonly used \nMIME types are:\n\n* `multipart/form-data`\n* `application/x-www-form-urlencoded`\n* `application/json`\n\nThis endpoint echoes the HTTP headers, request parameters, the contents of\nthe request body and the complete URI requested when data is sent as a form parameter." + }, + "response": [] + }, + { + "name": "DELETE Request", + "event": [ + { + "listen": "test", + "script": { + "id": "c577bd6a-5ecc-487e-8a7a-269c7be74187", + "exec": [ + "pm.test(\"response is ok\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"response body has json with form data\", function () {", + " pm.response.to.have.jsonBody('data', ", + " 'This is expected to be sent back as part of response body.');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "This is expected to be sent back as part of response body.{{var1}}", + "options": { + "raw": {} + } + }, + "url": { + "raw": "{{url}}/delete", + "host": [ + "{{url}}" + ], + "path": [ + "delete" + ] + }, + "description": "The HTTP `DELETE` method is used to delete resources on a server. The exact\nuse of `DELETE` requests depends on the server implementation. In general, \n`DELETE` requests support both, Query String parameters as well as a Request \nBody.\n\nThis endpoint accepts an HTTP `DELETE` request and provides debug information\nsuch as the HTTP headers, Query String arguments, and the Request Body." + }, + "response": [] + }, + { + "name": "Request Methods", + "item": [ + { + "name": "POST Form Data", + "event": [ + { + "listen": "test", + "script": { + "id": "437c9683-1e81-422e-839c-6964d9014bca", + "exec": [ + "pm.test(\"response is ok\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"response body has json with form data\", function () {", + " pm.response.to.have.jsonBody('form.foo1', 'bar1')", + " .and.have.jsonBody('form.foo2', 'bar2');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "foo1", + "value": "{{var4}}", + "type": "text" + }, + { + "key": "foo2", + "value": "{{var5}}", + "type": "text" + } + ], + "options": { + "urlencoded": {} + } + }, + "url": { + "raw": "{{url}}/post", + "host": [ + "{{url}}" + ], + "path": [ + "post" + ] + }, + "description": "The HTTP `POST` request method is meant to transfer data to a server \n(and elicit a response). What data is returned depends on the implementation\nof the server.\n\nA `POST` request can pass parameters to the server using \"Query String \nParameters\", as well as the Request Body. For example, in the following request,\n\n> POST /hi/there?hand=wave\n>\n> \n\nThe parameter \"hand\" has the value \"wave\". The request body can be in multiple\nformats. These formats are defined by the MIME type of the request. The MIME \nType can be set using the ``Content-Type`` HTTP header. The most commonly used \nMIME types are:\n\n* `multipart/form-data`\n* `application/x-www-form-urlencoded`\n* `application/json`\n\nThis endpoint echoes the HTTP headers, request parameters, the contents of\nthe request body and the complete URI requested when data is sent as a form parameter." + }, + "response": [] + }, + { + "name": "DELETE Request", + "event": [ + { + "listen": "test", + "script": { + "id": "c577bd6a-5ecc-487e-8a7a-269c7be74187", + "exec": [ + "pm.test(\"response is ok\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"response body has json with form data\", function () {", + " pm.response.to.have.jsonBody('data', ", + " 'This is expected to be sent back as part of response body.');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "This is expected to be sent back as part of response body.{{var1}}", + "options": { + "raw": {} + } + }, + "url": { + "raw": "{{url}}/delete", + "host": [ + "{{url}}" + ], + "path": [ + "delete" + ] + }, + "description": "The HTTP `DELETE` method is used to delete resources on a server. The exact\nuse of `DELETE` requests depends on the server implementation. In general, \n`DELETE` requests support both, Query String parameters as well as a Request \nBody.\n\nThis endpoint accepts an HTTP `DELETE` request and provides debug information\nsuch as the HTTP headers, Query String arguments, and the Request Body." + }, + "response": [] + } + ], + "description": "HTTP has multiple request \"verbs\", such as `GET`, `PUT`, `POST`, `DELETE`,\n`PATCH`, `HEAD`, etc. \n\nAn HTTP Method (verb) defines how a request should be interpreted by a server. \nThe endpoints in this section demonstrate various HTTP Verbs. Postman supports \nall the HTTP Verbs, including some rarely used ones, such as `PROPFIND`, `UNLINK`, \netc.\n\nFor details about HTTP Verbs, refer to [RFC 2616](http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9)\n", + "protocolProfileBehavior": {} + } + ], + "description": "HTTP has multiple request \"verbs\", such as `GET`, `PUT`, `POST`, `DELETE`,\n`PATCH`, `HEAD`, etc. \n\nAn HTTP Method (verb) defines how a request should be interpreted by a server. \nThe endpoints in this section demonstrate various HTTP Verbs. Postman supports \nall the HTTP Verbs, including some rarely used ones, such as `PROPFIND`, `UNLINK`, \netc.\n\nFor details about HTTP Verbs, refer to [RFC 2616](http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9)\n", + "protocolProfileBehavior": {} + }, + { + "name": "POST Raw Text", + "event": [ + { + "listen": "test", + "script": { + "id": "7537c088-dfa6-467d-90ee-f22e40ef0d0f", + "exec": [ + "pm.test(\"response is ok\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"response body has json with request body\", function () {", + " pm.response.to.have.jsonBody('data', ", + " 'This is expected to be sent back as part of response body.');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "This is expected to be sent back as part of response body {{var3}} {{var2}}", + "options": { + "raw": {} + } + }, + "url": { + "raw": "{{url}}/post", + "host": [ + "{{url}}" + ], + "path": [ + "post" + ] + }, + "description": "The HTTP `POST` request method is meant to transfer data to a server \n(and elicit a response). What data is returned depends on the implementation\nof the server.\n\nA `POST` request can pass parameters to the server using \"Query String \nParameters\", as well as the Request Body. For example, in the following request,\n\n> POST /hi/there?hand=wave\n>\n> \n\nThe parameter \"hand\" has the value \"wave\". The request body can be in multiple\nformats. These formats are defined by the MIME type of the request. The MIME \nType can be set using the ``Content-Type`` HTTP header. The most commonly used \nMIME types are:\n\n* `multipart/form-data`\n* `application/x-www-form-urlencoded`\n* `application/json`\n\nThis endpoint echoes the HTTP headers, request parameters, the contents of\nthe request body and the complete URI requested." + }, + "response": [] + }, + { + "name": "GET Request", + "event": [ + { + "listen": "test", + "script": { + "id": "0dbbd1ff-b941-495d-99fe-22737e4dad66", + "exec": [ + "pm.test(\"response is ok\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"response body has json with request queries\", function () {", + " pm.response.to.have.jsonBody('args.foo1', 'bar1')", + " .and.have.jsonBody('args.foo2', 'bar2');", + "});", + "", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{url}}/get?foo1={{var1}}{{var4}}&foo2={{var2}}{{var5}}", + "host": [ + "{{url}}" + ], + "path": [ + "get" + ], + "query": [ + { + "key": "foo1", + "value": "{{var1}}{{var4}}" + }, + { + "key": "foo2", + "value": "{{var2}}{{var5}}" + } + ] + }, + "description": "The HTTP `GET` request method is meant to retrieve data from a server. The data\nis identified by a unique URI (Uniform Resource Identifier). \n\nA `GET` request can pass parameters to the server using \"Query String \nParameters\". For example, in the following request,\n\n> http://example.com/hi/there?hand=wave\n\nThe parameter \"hand\" has the value \"wave\".\n\nThis endpoint echoes the HTTP headers, request parameters and the complete\nURI requested." + }, + "response": [ + { + "name": "GET Request Woops", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "https://postman-echo.com/get?foo1=bar1&foo2=bar2", + "protocol": "https", + "host": [ + "postman-echo", + "com" + ], + "path": [ + "get" + ], + "query": [ + { + "key": "foo1", + "value": "bar1" + }, + { + "key": "foo2", + "value": "bar2" + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Date", + "value": "Tue, 11 Jun 2019 10:43:13 GMT" + }, + { + "key": "ETag", + "value": "W/\"161-aLhNcsGArlgLSKbxPqfBW3viHPI\"" + }, + { + "key": "Server", + "value": "nginx" + }, + { + "key": "set-cookie", + "value": "sails.sid=s%3AGz-wblZgXE8FCDq7aJpx_tUgZUcG3Nsw.LdNEN8L0C7nGWkvGLwvdw6R2s6Syjr%2FzkvyevA8qR0c; Path=/; HttpOnly" + }, + { + "key": "Vary", + "value": "Accept-Encoding" + }, + { + "key": "Content-Length", + "value": "249" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"args\": {\n \"foo1\": \"bar1\",\n \"foo2\": \"bar2\"\n },\n \"headers\": {\n \"x-forwarded-proto\": \"https\",\n \"host\": \"postman-echo.com\",\n \"accept\": \"*/*\",\n \"accept-encoding\": \"gzip, deflate\",\n \"cache-control\": \"no-cache\",\n \"postman-token\": \"5c27cd7d-6b16-4e5a-a0ef-191c9a3a275f\",\n \"user-agent\": \"PostmanRuntime/7.6.1\",\n \"x-forwarded-port\": \"443\"\n },\n \"url\": \"https://postman-echo.com/get?foo1=bar1&foo2=bar2\"\n}" + } + ] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "460a48a8-81c2-4403-9aec-d0b22dfee7ba", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "d8a1d27a-41b5-4fb2-aec7-6a3e7c0ba83a", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "variable": [ + { + "id": "8fe8e6d0-b967-4da6-9dde-6474e4e04da9", + "key": "var1", + "value": "valur" + }, + { + "id": "862de742-ba99-4743-a2f7-baf6571e1273", + "key": "var2", + "value": "value2" + }, + { + "id": "d3ad6058-3684-4260-ba9c-b622d64fa456", + "key": "var3", + "value": "value3" + }, + { + "id": "da9901ac-442a-4715-a281-f5a9ab210117", + "key": "var4", + "value": "value4" + }, + { + "id": "9799d2a0-4761-417a-8702-7a057acafb33", + "key": "var5", + "value": "value5" + }, + { + "id": "6a1391a6-eaa0-428a-a2a6-7020eac3eb85", + "key": "url", + "value": "https://postman-echo.com" + } + ], + "protocolProfileBehavior": {} +} \ No newline at end of file diff --git a/test/fixtures/SDKGEN_ENVIRONMENT.json b/test/fixtures/SDKGEN_ENVIRONMENT.json new file mode 100644 index 0000000..620e8ae --- /dev/null +++ b/test/fixtures/SDKGEN_ENVIRONMENT.json @@ -0,0 +1,24 @@ +{ + "id": "a338c919-4bfb-48e0-a23d-992cf0b04431", + "name": "sdkgen_test", + "values": [ + { + "key": "url", + "value": "www.google.com", + "enabled": true + }, + { + "key": "var1", + "value": "valenv1", + "enabled": true + }, + { + "key": "var2", + "value": "valenv2", + "enabled": true + } + ], + "_postman_variable_scope": "environment", + "_postman_exported_at": "2020-07-20T22:50:39.600Z", + "_postman_exported_using": "Postman/7.28.0" +} \ No newline at end of file diff --git a/test/unit/sdkgen.test.js b/test/unit/sdkgen.test.js new file mode 100644 index 0000000..638e7da --- /dev/null +++ b/test/unit/sdkgen.test.js @@ -0,0 +1,118 @@ +/* eslint-disable max-len */ +const expect = require('chai').expect, + sdkgen = require('../../'), + sdk = require('postman-collection'), + collections = { + SDKGEN: require('../fixtures/SDKGEN.postman_collection.json') + }; +describe('Generate function', () => { + + it('should generate sdk snippet without outputType option', async () => { + await sdkgen.generate({ + type: 'json', + source: collections.SDKGEN + }, { + language: 'Nodejs', + variant: 'request' + }, (err, snippet) => { + expect(err).to.be.null; + expect(snippet).to.include('request = require(\'request\')'); + }); + }); + + it('should generate sdk snippet with outputType as String', async () => { + await sdkgen.generate({ + type: 'json', + source: collections.SDKGEN + }, { + language: 'Nodejs', + variant: 'request', + outputType: 'String' + }, (err, snippet) => { + expect(err).to.be.null; + expect(snippet).to.include('request = require(\'request\')'); + }); + }); + + it('should generate sdk snippet with outputType as File', async () => { + await sdkgen.generate({ + type: 'json', + source: collections.SDKGEN + }, { + language: 'Nodejs', + variant: 'request', + outputType: 'file', + // ../sdk.js resolves to root folder because this file is being called from npm folder + outputFilePath: '../sdk.js' + }, (err, output) => { + expect(err).to.be.null; + expect(output).to.include('File exported at location:'); + }); + }); + + it('should throw an error if outputfilepath is invalid', async () => { + await sdkgen.generate({ + type: 'json', + source: collections.SDKGEN + }, { + language: 'Nodejs', + variant: 'request', + outputType: 'file', + outputFilePath: '../' + }, (err) => { + expect.fail(null, null, err); + }); + }); + + it('should generate sdk snippet with source as collection json', async () => { + await sdkgen.generate({ + type: 'json', + source: collections.SDKGEN + }, { + language: 'Nodejs', + variant: 'request' + }, (err, snippet) => { + expect(err).to.be.null; + expect(snippet).to.include('request = require(\'request\')'); + }); + }); + + it('should generate sdk snippet with source as PostmanCollection instance', async () => { + let collection = new sdk.Collection(collections.SDKGEN); + await sdkgen.generate({ + type: 'json', + source: collection + }, { + language: 'Nodejs', + variant: 'request' + }, (err, snippet) => { + expect(err).to.be.null; + expect(snippet).to.include('request = require(\'request\')'); + }); + }); + + // TODO fix issue with response resolution + it('should generate sdk snippet with source as url', async () => { + await sdkgen.generate( + { + type: 'string', + source: 'https://www.getpostman.com/collections/c8aa0d9bd381c73c5ac3' + }, { + language: 'Nodejs', + variant: 'request' + }, (err, snippet) => { + expect(err).to.be.null; + expect(snippet).to.include('request = require(\'request\')'); + }); + }); + + + it('should throw an error if invalid colleciton source is provided', async () => { + await sdkgen.generate('random letters', { + language: 'Nodejs', + variant: 'request' + }, (err) => { + expect(err); + }); + }); +});