From 13fa2cf46a5b3d90f1831604ab35fd70f2fd1872 Mon Sep 17 00:00:00 2001 From: kobenguyent Date: Thu, 13 Jun 2024 09:53:28 +0200 Subject: [PATCH 1/4] feat(rest): print curl --- docs/helpers/REST.md | 31 +++++------------------ lib/helper/REST.js | 60 ++++++++++++++++++++------------------------ 2 files changed, 33 insertions(+), 58 deletions(-) diff --git a/docs/helpers/REST.md b/docs/helpers/REST.md index cd96d5e0f..50ce31202 100644 --- a/docs/helpers/REST.md +++ b/docs/helpers/REST.md @@ -23,12 +23,12 @@ Type: [object][4] ### Properties - `endpoint` **[string][3]?** API base URL -- `prettyPrintJson` **[boolean][6]?** pretty print json for response/request on console logs -- `timeout` **[number][5]?** timeout for requests in milliseconds. 10000ms by default -- `defaultHeaders` **[object][4]?** a list of default headers -- `httpAgent` **[object][4]?** create an agent with SSL certificate -- `onRequest` **[function][7]?** a async function which can update request object. -- `onResponse` **[function][7]?** a async function which can update response object. +- `prettyPrintJson` **[boolean][6]?** pretty print json for response/request on console logs. +- `printCurl` **[boolean][6]?** print cURL request on console logs. False by default. +- `timeout` **[number][5]?** timeout for requests in milliseconds. 10000ms by default. +- `defaultHeaders` **[object][4]?** a list of default headers. +- `onRequest` **[function][7]?** an async function which can update request object. +- `onResponse` **[function][7]?** an async function which can update response object. - `maxUploadFileSize` **[number][5]?** set the max content file size in MB when performing api calls. @@ -47,25 +47,6 @@ Type: [object][4] } } } -``` - - With httpAgent - -```js -{ - helpers: { - REST: { - endpoint: 'http://site.com/api', - prettyPrintJson: true, - httpAgent: { - key: fs.readFileSync(__dirname + '/path/to/keyfile.key'), - cert: fs.readFileSync(__dirname + '/path/to/certfile.cert'), - rejectUnauthorized: false, - keepAlive: true - } - } - } -} ``` ## Access From Helpers diff --git a/lib/helper/REST.js b/lib/helper/REST.js index 0af333464..c61be117d 100644 --- a/lib/helper/REST.js +++ b/lib/helper/REST.js @@ -1,6 +1,5 @@ const axios = require('axios').default; const Helper = require('@codeceptjs/helper'); -const { Agent } = require('https'); const Secret = require('../secret'); const { beautify } = require('../utils'); @@ -11,12 +10,12 @@ const { beautify } = require('../utils'); * @typedef RESTConfig * @type {object} * @prop {string} [endpoint] - API base URL - * @prop {boolean} [prettyPrintJson=false] - pretty print json for response/request on console logs - * @prop {number} [timeout=1000] - timeout for requests in milliseconds. 10000ms by default - * @prop {object} [defaultHeaders] - a list of default headers - * @prop {object} [httpAgent] - create an agent with SSL certificate - * @prop {function} [onRequest] - a async function which can update request object. - * @prop {function} [onResponse] - a async function which can update response object. + * @prop {boolean} [prettyPrintJson=false] - pretty print json for response/request on console logs. + * @prop {boolean} [printCurl=false] - print cURL request on console logs. False by default. + * @prop {number} [timeout=1000] - timeout for requests in milliseconds. 10000ms by default. + * @prop {object} [defaultHeaders] - a list of default headers. + * @prop {function} [onRequest] - an async function which can update request object. + * @prop {function} [onResponse] - an async function which can update response object. * @prop {number} [maxUploadFileSize] - set the max content file size in MB when performing api calls. */ const config = {}; @@ -42,24 +41,6 @@ const config = {}; * } *} * ``` - * With httpAgent - * - * ```js - * { - * helpers: { - * REST: { - * endpoint: 'http://site.com/api', - * prettyPrintJson: true, - * httpAgent: { - * key: fs.readFileSync(__dirname + '/path/to/keyfile.key'), - * cert: fs.readFileSync(__dirname + '/path/to/certfile.cert'), - * rejectUnauthorized: false, - * keepAlive: true - * } - * } - * } - * } - * ``` * * ## Access From Helpers * @@ -96,14 +77,7 @@ class REST extends Helper { this._setConfig(config); this.headers = { ...this.options.defaultHeaders }; - - // Create an agent with SSL certificate - if (this.options.httpAgent) { - if (!this.options.httpAgent.key || !this.options.httpAgent.cert) throw Error('Please recheck your httpAgent config!'); - this.httpsAgent = new Agent(this.options.httpAgent); - } - - this.axios = this.httpsAgent ? axios.create({ httpsAgent: this.httpsAgent }) : axios.create(); + this.axios = axios.create(); // @ts-ignore this.axios.defaults.headers = this.options.defaultHeaders; } @@ -192,6 +166,7 @@ class REST extends Helper { } this.options.prettyPrintJson ? this.debugSection('Request', beautify(JSON.stringify(_debugRequest))) : this.debugSection('Request', JSON.stringify(_debugRequest)); + if (this.options.printCurl) this.debugSection('CURL Request', curlize(request)); let response; try { @@ -372,3 +347,22 @@ class REST extends Helper { } } module.exports = REST; + +function curlize(request) { + let curl = `curl --location --request ${request.method ? request.method.toUpperCase() : 'GET'} ${request.baseURL} `.replace("'", ''); + + if (request.headers) { + Object.entries(request.headers).forEach(([key, value]) => { + curl += `-H "${key}: ${value}" `; + }); + } + + if (!curl.toLowerCase().includes('content-type: application/json')) { + curl += '-H "Content-Type: application/json" '; + } + + if (request.data) { + curl += `-d '${JSON.stringify(request.data)}'`; + } + return curl; +} From 3de904ee9d2202e909186ee59b2023f119ea68ef Mon Sep 17 00:00:00 2001 From: kobenguyent Date: Sat, 15 Jun 2024 19:23:30 +0200 Subject: [PATCH 2/4] fix: missing some code --- docs/helpers/REST.md | 20 ++++++++++++++++++++ lib/helper/REST.js | 30 +++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/docs/helpers/REST.md b/docs/helpers/REST.md index 50ce31202..953208444 100644 --- a/docs/helpers/REST.md +++ b/docs/helpers/REST.md @@ -27,6 +27,7 @@ Type: [object][4] - `printCurl` **[boolean][6]?** print cURL request on console logs. False by default. - `timeout` **[number][5]?** timeout for requests in milliseconds. 10000ms by default. - `defaultHeaders` **[object][4]?** a list of default headers. +- `httpAgent` **[object][4]?** create an agent with SSL certificate - `onRequest` **[function][7]?** an async function which can update request object. - `onResponse` **[function][7]?** an async function which can update response object. - `maxUploadFileSize` **[number][5]?** set the max content file size in MB when performing api calls. @@ -47,6 +48,25 @@ Type: [object][4] } } } +``` + + With httpAgent + +```js +{ + helpers: { + REST: { + endpoint: 'http://site.com/api', + prettyPrintJson: true, + httpAgent: { + key: fs.readFileSync(__dirname + '/path/to/keyfile.key'), + cert: fs.readFileSync(__dirname + '/path/to/certfile.cert'), + rejectUnauthorized: false, + keepAlive: true + } + } + } +} ``` ## Access From Helpers diff --git a/lib/helper/REST.js b/lib/helper/REST.js index c61be117d..60a92be65 100644 --- a/lib/helper/REST.js +++ b/lib/helper/REST.js @@ -1,5 +1,6 @@ const axios = require('axios').default; const Helper = require('@codeceptjs/helper'); +const { Agent } = require('https'); const Secret = require('../secret'); const { beautify } = require('../utils'); @@ -14,6 +15,7 @@ const { beautify } = require('../utils'); * @prop {boolean} [printCurl=false] - print cURL request on console logs. False by default. * @prop {number} [timeout=1000] - timeout for requests in milliseconds. 10000ms by default. * @prop {object} [defaultHeaders] - a list of default headers. + * @prop {object} [httpAgent] - create an agent with SSL certificate * @prop {function} [onRequest] - an async function which can update request object. * @prop {function} [onResponse] - an async function which can update response object. * @prop {number} [maxUploadFileSize] - set the max content file size in MB when performing api calls. @@ -42,6 +44,25 @@ const config = {}; *} * ``` * + * With httpAgent + * + * ```js + * { + * helpers: { + * REST: { + * endpoint: 'http://site.com/api', + * prettyPrintJson: true, + * httpAgent: { + * key: fs.readFileSync(__dirname + '/path/to/keyfile.key'), + * cert: fs.readFileSync(__dirname + '/path/to/certfile.cert'), + * rejectUnauthorized: false, + * keepAlive: true + * } + * } + * } + * } + * ``` + * * ## Access From Helpers * * Send REST requests by accessing `_executeRequest` method: @@ -77,7 +98,14 @@ class REST extends Helper { this._setConfig(config); this.headers = { ...this.options.defaultHeaders }; - this.axios = axios.create(); + + // Create an agent with SSL certificate + if (this.options.httpAgent) { + if (!this.options.httpAgent.key || !this.options.httpAgent.cert) throw Error('Please recheck your httpAgent config!'); + this.httpsAgent = new Agent(this.options.httpAgent); + } + + this.axios = this.httpsAgent ? axios.create({ httpsAgent: this.httpsAgent }) : axios.create(); // @ts-ignore this.axios.defaults.headers = this.options.defaultHeaders; } From 698328d20e0b8a7915e92ad249e21ac135a31c34 Mon Sep 17 00:00:00 2001 From: kobenguyent Date: Mon, 17 Jun 2024 09:16:42 +0200 Subject: [PATCH 3/4] address CR --- lib/helper/REST.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/helper/REST.js b/lib/helper/REST.js index 60a92be65..57119b267 100644 --- a/lib/helper/REST.js +++ b/lib/helper/REST.js @@ -194,7 +194,13 @@ class REST extends Helper { } this.options.prettyPrintJson ? this.debugSection('Request', beautify(JSON.stringify(_debugRequest))) : this.debugSection('Request', JSON.stringify(_debugRequest)); - if (this.options.printCurl) this.debugSection('CURL Request', curlize(request)); + if (this.options.printCurl) { + if (request.data && !isValidJSON(request.data)) { + this.debugSection('CURL Request', 'cURL is not printed as the request body is not a JSON'); + } else { + this.debugSection('CURL Request', curlize(request)); + } + } let response; try { @@ -394,3 +400,17 @@ function curlize(request) { } return curl; } + +/** + * Checks if the given text is valid JSON. + * @param {string} text - The text to check. + * @returns {boolean} - Returns true if the text is valid JSON, otherwise false. + */ +function isValidJSON(text) { + try { + JSON.parse(text); + return true; + } catch (error) { + return false; + } +} From 5d7b4af62a4eab50af8bc99223233d25d6b381f0 Mon Sep 17 00:00:00 2001 From: kobenguyent Date: Mon, 17 Jun 2024 09:57:57 +0200 Subject: [PATCH 4/4] address CR --- lib/helper/REST.js | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/lib/helper/REST.js b/lib/helper/REST.js index 57119b267..7e4e3b3c2 100644 --- a/lib/helper/REST.js +++ b/lib/helper/REST.js @@ -195,11 +195,7 @@ class REST extends Helper { this.options.prettyPrintJson ? this.debugSection('Request', beautify(JSON.stringify(_debugRequest))) : this.debugSection('Request', JSON.stringify(_debugRequest)); if (this.options.printCurl) { - if (request.data && !isValidJSON(request.data)) { - this.debugSection('CURL Request', 'cURL is not printed as the request body is not a JSON'); - } else { - this.debugSection('CURL Request', curlize(request)); - } + this.debugSection('CURL Request', curlize(request)); } let response; @@ -383,6 +379,7 @@ class REST extends Helper { module.exports = REST; function curlize(request) { + if (request.data?.constructor.name.toLowerCase() === 'formdata') return 'cURL is not printed as the request body is not a JSON'; let curl = `curl --location --request ${request.method ? request.method.toUpperCase() : 'GET'} ${request.baseURL} `.replace("'", ''); if (request.headers) { @@ -400,17 +397,3 @@ function curlize(request) { } return curl; } - -/** - * Checks if the given text is valid JSON. - * @param {string} text - The text to check. - * @returns {boolean} - Returns true if the text is valid JSON, otherwise false. - */ -function isValidJSON(text) { - try { - JSON.parse(text); - return true; - } catch (error) { - return false; - } -}