From a3743c5018f559e10c0d3b958d27b8f15e34901e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Antonio=20Rodr=C3=ADguez?= Date: Mon, 6 Oct 2014 10:41:03 +0200 Subject: [PATCH 01/12] Prepare npm publication --- .gitignore | 3 +++ package.json | 9 ++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 8dc75e3..f24ceec 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ node_modules # npm npm-debug.log + +tests +presentation diff --git a/package.json b/package.json index ba48c78..44d8e5e 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,15 @@ { "name": "tartare", "version": "0.5.0", - "description": "Gherkin-like Mocha extension and reporter, and testing tools library for Node.js", + "description": "Gherkin-like Mocha extension and reporter, and testing tools library for Javascript", + "main": "./index", "bin": { "tartare": "./bin/tartare", "apimockserver": "./bin/apimockserver" }, "repository": { "type": "git", - "url": "git@github.com:telefonicaid/tartare.git" - }, - "engines": { - "node": "0.10.31" + "url": "https://github.com/telefonicaid/tartare.git" }, "license": "Apache-2.0", "author": { @@ -38,6 +36,7 @@ "testing", "QA" ], + "bugs": "https://github.com/telefonicaid/tartare/issues", "dependencies": { "buffertools": "2.1.2", "chai": "1.9.1", From 5fddc8b90dcf378a30e74b422e00b870a76e8180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Antonio=20Rodr=C3=ADguez?= Date: Mon, 6 Oct 2014 13:28:33 +0200 Subject: [PATCH 02/12] Add support for 2waySSL to ApiMockServer --- ReleaseNotes.md | 12 ++++++- bin/apimockserver | 55 ++++++++++++++++++++++++------- lib/apimock/middlewares.js | 8 ++++- lib/apimock/server.js | 67 ++++++++++++++++++++++++++------------ package.json | 2 +- 5 files changed, 109 insertions(+), 35 deletions(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index a5d6ad5..cba2809 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,5 +1,14 @@ # RELEASE NOTES +## v0.6.0 / XXX + +### API Mock + +* API Mock now supports 2waySSL. Write `apimockserver` without parameters to see how to use it. Last requests objects will + include a new property named `certificate` that will convey the details of the certificate used by the client to establish + the connection. + + ## v0.5.0 / 3 Oct 2014 ### Gherkin framework and reporter @@ -67,7 +76,8 @@ { minorBug: 'my-bug-id', desc: 'This is a variant with a minor bug' } ]; ``` - + + ## v0.4.0 / 7 Aug 2014 ### Gherkin framework and reporter diff --git a/bin/apimockserver b/bin/apimockserver index 88db24d..1b90b2c 100755 --- a/bin/apimockserver +++ b/bin/apimockserver @@ -23,35 +23,66 @@ 'use strict'; -var optimist = require('optimist'); +var optimist = require('optimist') + , util = require('util') + ; + var argv = optimist - .usage('\nUsage: apimockserver -a -p [-s -k -c ]') + .usage('\nUsage: apimockserver -a \n' + + ' [-p ]\n' + + ' [-s -k -c ]\n' + + ' [-2 <2wayssl_port> -k -c -w ]') .options('a', { alias: 'admin-port', describe: 'Administration port', demand: true }) - .options('p', { alias: 'port', describe: 'API Mock Server port (HTTP)', demand: true }) + .options('p', { alias: 'port', describe: 'API Mock Server port (HTTP)' }) .options('s', { alias: 'ssl-port', describe: 'API Mock Server port (HTTPS)' }) - .options('k', { alias: 'key', describe: 'Private key file for HTTPS server' }) - .options('c', { alias: 'cert', describe: 'Certificate file for HTTPS server' }) + .options('2', { alias: '2wayssl-port', describe: 'API Mock Server port (2waySSL)' }) + .options('k', { alias: 'key', describe: 'Private key file for HTTPS/2waySSL server' }) + .options('c', { alias: 'cert', describe: 'Certificate file for HTTPS/2waySSL server' }) + .options('w', { alias: 'ca', describe: 'Authority certificate file for 2waySSL server' }) .options('t', { alias: 'timeout', describe: 'Server timeout (default: 2 min)' }) .argv; if ((argv.a && typeof(argv.a) !== 'number') || (argv.p && typeof(argv.p) !== 'number') || (argv.s && typeof(argv.s) !== 'number') || - (argv.k && typeof(argv.k) !== 'string') || - (argv.c && typeof(argv.c) !== 'string') || - (argv.s && !(argv.k && argv.c)) || - (argv.t && typeof(argv.t) !== 'number')) { + (argv['2'] && typeof(argv['2']) !== 'number') || + (argv.w && util.isArray(argv.w)) || + (argv.t && typeof(argv.t) !== 'number') || + (argv.s && !(argv.k && argv.c)) || // k and c are mandatory when s exists + (argv['2'] && !(argv.k && argv.c && argv.w))) { // k, c and w are mandatory when 2 exists optimist.showHelp(); process.exit(1); } +if (argv.s && argv['2']) { + if (!(util.isArray(argv.k) && argv.k.length === 2 && util.isArray(argv.c) && argv.c.length === 2)) { + optimist.showHelp(); + process.exit(1); + } +} else if (argv.s || argv['2']) { + if (util.isArray(argv.k) || util.isArray(argv.c)) { + optimist.showHelp(); + process.exit(1); + } + argv.k = [argv.k]; + argv.c = [argv.c]; +} + var settings = {}; settings.adminPort = argv.a; -settings.httpPort = argv.p; +if (argv.p) { + settings.httpPort = argv.p; +} if (argv.s) { settings.httpsPort = argv.s; - settings.httpsKeyPath = argv.k; - settings.httpsCertPath = argv.c; + settings.httpsKeyPath = argv.k[0]; + settings.httpsCertPath = argv.c[0]; +} +if (argv['2']) { + settings.twowaysslPort = argv['2']; + settings.twowaysslKeyPath = argv.k[1] || argv.k[0]; + settings.twowaysslCertPath = argv.c[1] || argv.c[0]; + settings.twowaysslCAPath = argv.w; } if (argv.t) { settings.timeout = argv.t; diff --git a/lib/apimock/middlewares.js b/lib/apimock/middlewares.js index 97d6e72..dff248a 100644 --- a/lib/apimock/middlewares.js +++ b/lib/apimock/middlewares.js @@ -93,6 +93,12 @@ function _buildRequestObject(req, config, cb) { remotePort: req.connection.remotePort }; + // Get remote certificate + var certificate = req.connection.getPeerCertificate(); + if (certificate && Object.keys(certificate).length) { + requestObj.certificate = certificate; + } + var chunks = []; req.on('data', function(chunk) { @@ -197,7 +203,7 @@ function _unmarshallConfig(config) { * Convert query and headers to its JSON representation, since nedb does not allow keys (header names) to have dots. * * @param lastRequest - * @param copy True if marhalled object must be a copy of the original object + * @param copy True if marshalled object must be a copy of the original object * @private */ function _marshallLastRequest(lastRequest, copy) { diff --git a/lib/apimock/server.js b/lib/apimock/server.js index d659fd4..45a2f13 100644 --- a/lib/apimock/server.js +++ b/lib/apimock/server.js @@ -23,6 +23,8 @@ module.exports = function apiMockServer(settings) { var http = require('http') + , https = require('https') + , fs = require('fs') , express = require('express') , Datastore = require('nedb') , middlewares = require('./middlewares') @@ -98,30 +100,30 @@ module.exports = function apiMockServer(settings) { }) .listen(settings.adminPort); - http.createServer(middlewares.mock.requestHandler) - .on('error', function onError(err) { - console.log('API Mock Server (HTTP) ERROR:'); - console.error(err.stack); - process.exit(-102); - }) - .on('listening', function onListening() { - console.log('API Mock Server (HTTP) listening on port', settings.httpPort); - }) - .on('connection', function onConnection(socket) { - socket.setTimeout(context.timeout); - }) - .listen(settings.httpPort); + if (settings.httpPort) { + http.createServer(middlewares.mock.requestHandler) + .on('error', function onError(err) { + console.log('API Mock Server (HTTP) ERROR:'); + console.error(err.stack); + process.exit(-102); + }) + .on('listening', function onListening() { + console.log('API Mock Server (HTTP) listening on port', settings.httpPort); + }) + .on('connection', function onConnection(socket) { + socket.setTimeout(context.timeout); + }) + .listen(settings.httpPort); + } if (settings.httpsPort) { - var https = require('https') - , fs = require('fs') - ; - // Read private key and certificate to set up an SSL server - var privateKey = fs.readFileSync(settings.httpsKeyPath, 'utf8') - , certificate = fs.readFileSync(settings.httpsCertPath, 'utf8'); + var optsHttps = { + key: fs.readFileSync(settings.httpsKeyPath, 'utf8'), + cert: fs.readFileSync(settings.httpsCertPath, 'utf8') + }; - https.createServer({ key: privateKey, cert: certificate }, middlewares.mock.requestHandler) + https.createServer(optsHttps, middlewares.mock.requestHandler) .on('error', function onError(err) { console.log('API Mock Server (HTTPS) ERROR:'); console.error(err.stack); @@ -136,4 +138,29 @@ module.exports = function apiMockServer(settings) { .listen(settings.httpsPort); } + if (settings.twowaysslPort) { + // Read private key, certificate and authority certificate to set up a 2waySSL server + var optsTwowayssl = { + key: fs.readFileSync(settings.twowaysslKeyPath, 'utf8'), + cert: fs.readFileSync(settings.twowaysslCertPath, 'utf8'), + ca: fs.readFileSync(settings.twowaysslCAPath, 'utf8'), + requestCert: true, + rejectUnauthorized: true + }; + + https.createServer(optsTwowayssl, middlewares.mock.requestHandler) + .on('error', function onError(err) { + console.log('API Mock Server (2waySSL) ERROR:'); + console.error(err.stack); + process.exit(-103); + }) + .on('listening', function onListening() { + console.log('API Mock Server (2waySSL) listening on port', settings.twowaysslPort); + }) + .on('connection', function onConnection(socket) { + socket.setTimeout(context.timeout); + }) + .listen(settings.twowaysslPort); + } + }; diff --git a/package.json b/package.json index 44d8e5e..a270b0a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tartare", - "version": "0.5.0", + "version": "0.6.0", "description": "Gherkin-like Mocha extension and reporter, and testing tools library for Javascript", "main": "./index", "bin": { From c760856ce2a266b00d2a20236d8761b099dc6ec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Antonio=20Rodr=C3=ADguez?= Date: Wed, 8 Oct 2014 17:04:00 +0200 Subject: [PATCH 03/12] Allow mock referencing request body properties from the response when the body is json or xml --- ReleaseNotes.md | 20 ++++++++++++++++++++ lib/apimock/middlewares.js | 10 ++++++++++ lib/collections.js | 1 + package.json | 5 +++-- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index a5d6ad5..28b957c 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,5 +1,25 @@ # RELEASE NOTES +## v0.6.0 / XXX + +### API Mock + +* Mock responses may include references to request body fields when the body can be parsed as JSON or XML. + XML bodies are converted to JSON using [xml2json](https://www.npmjs.org/package/xml2json). + If the body can be parsed, it will be accessible through a `bodyJson` property. + +```json +{ + "method": "POST", + "path": "/", + "response": { + "statusCode": 200, + "body": "Result: {{{bodyJson.fieldName}}}" + } +} +``` + + ## v0.5.0 / 3 Oct 2014 ### Gherkin framework and reporter diff --git a/lib/apimock/middlewares.js b/lib/apimock/middlewares.js index 97d6e72..fe6ba4a 100644 --- a/lib/apimock/middlewares.js +++ b/lib/apimock/middlewares.js @@ -28,6 +28,7 @@ var jsonschema = require('jsonschema') , _ = require('underscore') , extend = require('node.extend') , schemas = require('./json-schemas') + , xml2json = require('xml2json') , utils = require('../utils') ; @@ -104,6 +105,15 @@ function _buildRequestObject(req, config, cb) { if (!config.binaryBody) { requestObj.body = iconv.decode(bodyBuffer, requestObj.charset || 'utf-8'); requestObj.binaryBody = false; + try { + // Try to parse the body as a JSON document + requestObj.bodyJson = JSON.parse(requestObj.body); + } catch(err) { + try { + // Try to parse the body as an XML document + requestObj.bodyJson = xml2json.toJson(requestObj.body, { object: true, coerce: false, sanitize: false }); + } catch(err) {} + } } else { requestObj.body = bodyBuffer.toString('base64'); requestObj.binaryBody = true; diff --git a/lib/collections.js b/lib/collections.js index a71c013..73f3999 100644 --- a/lib/collections.js +++ b/lib/collections.js @@ -51,6 +51,7 @@ var request = require('request') var ApiCollectionsGroup = function ApiCollectionsGroup(config) { config = config || {}; config.headers = config.headers || {}; + config.followRedirect = config.followRedirect || false; /** * This class models an specific collection, once customized to behave diff --git a/package.json b/package.json index 44d8e5e..780a992 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tartare", - "version": "0.5.0", + "version": "0.6.0", "description": "Gherkin-like Mocha extension and reporter, and testing tools library for Javascript", "main": "./index", "bin": { @@ -54,6 +54,7 @@ "optimist": "0.6.1", "request": "2.40.0", "synchronize": "0.9.8", - "underscore": "1.7.0" + "underscore": "1.7.0", + "xml2json": "0.5.1" } } From 47d3c4fd2b413fbaea27a6f75385407a9678ef03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Antonio=20Rodr=C3=ADguez?= Date: Wed, 8 Oct 2014 17:19:08 +0200 Subject: [PATCH 04/12] FIX bodyJson property must be marshalled before storing it in nedb --- lib/apimock/middlewares.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/apimock/middlewares.js b/lib/apimock/middlewares.js index fe6ba4a..d30fcbc 100644 --- a/lib/apimock/middlewares.js +++ b/lib/apimock/middlewares.js @@ -205,9 +205,11 @@ function _unmarshallConfig(config) { /** * Convert query and headers to its JSON representation, since nedb does not allow keys (header names) to have dots. + * The bodyJson property needs also to be marshalled because when converting from XML to JSON, come fields could + * start with '$', which is not allowed by nedb * * @param lastRequest - * @param copy True if marhalled object must be a copy of the original object + * @param copy True if marshalled object must be a copy of the original object * @private */ function _marshallLastRequest(lastRequest, copy) { @@ -218,11 +220,14 @@ function _marshallLastRequest(lastRequest, copy) { if (_lastRequest.headers) { _lastRequest.headers = JSON.stringify(_lastRequest.headers); } + if (_lastRequest.bodyJson) { + _lastRequest.bodyJson = JSON.stringify(_lastRequest.bodyJson); + } return _lastRequest; } /** - * Convert query and headers from JSON to its javascript object representation + * Convert query, headers and bodyJson from JSON to its javascript object representation * * @param lastRequests * @private @@ -239,6 +244,10 @@ function _unmarshallLastRequests(lastRequests) { if (lastRequest.headers) { lastRequest.headers = JSON.parse(lastRequest.headers); } + // Convert jsonBody from JSON to javascript object + if (lastRequest.jsonBody) { + lastRequest.jsonBody = JSON.parse(lastRequest.jsonBody); + } }); return lastRequests; } From 10218d2ef3f8cf50c25c19fc99e41da6d26836fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Antonio=20Rodr=C3=ADguez?= Date: Wed, 15 Oct 2014 10:51:12 +0200 Subject: [PATCH 05/12] Fix wellFormedXXXApiResponse assertions does not check the presence of a content-type header --- lib/chai-plugins/unica-api.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/chai-plugins/unica-api.js b/lib/chai-plugins/unica-api.js index d39a1c7..17e7ace 100644 --- a/lib/chai-plugins/unica-api.js +++ b/lib/chai-plugins/unica-api.js @@ -42,9 +42,11 @@ chai.use(function(_chai, utils) { Assertion.addProperty('wellFormedJsonApiResponse', function assertWellFormedJsonApiResponse() { var negated = utils.flag(this, 'negate'); var res = this._obj; + + new Assertion(res).to.have.httpHeaders('content-type'); + var actualContentType = res.headers['content-type'].split(';')[0]; var expectedContentType = 'application/json'; - this.assert( actualContentType === expectedContentType, 'expected Content-Type header to be #{exp} but is #{act}', @@ -73,9 +75,11 @@ chai.use(function(_chai, utils) { Assertion.addProperty('wellFormedXmlApiResponse', function assertWellFormedXmlApiResponse() { var negated = utils.flag(this, 'negate'); var res = this._obj; + + new Assertion(res).to.have.httpHeaders('content-type'); + var actualContentType = res.headers['content-type'].split(';')[0]; var expectedContentTypes = [ 'application/xml', 'text/xml' ]; - this.assert( expectedContentTypes.indexOf(actualContentType) !== -1, 'expected Content-Type header to be one of #{exp} but is #{act}', @@ -104,9 +108,11 @@ chai.use(function(_chai, utils) { Assertion.addProperty('wellFormedSoap11ApiResponse', function assertWellFormedSoap11ApiResponse() { var negated = utils.flag(this, 'negate'); var res = this._obj; + + new Assertion(res).to.have.httpHeaders('content-type'); + var actualContentType = res.headers['content-type'].split(';')[0]; var expectedContentType = 'text/xml'; - this.assert( actualContentType === expectedContentType, 'expected Content-Type header to be #{exp} but is #{act}', From 8ad4b2509d211bfc813a0b259f1a735a05e933d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Antonio=20Rodr=C3=ADguez?= Date: Wed, 15 Oct 2014 10:56:39 +0200 Subject: [PATCH 06/12] Bump version to 0.6.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 44d8e5e..a270b0a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tartare", - "version": "0.5.0", + "version": "0.6.0", "description": "Gherkin-like Mocha extension and reporter, and testing tools library for Javascript", "main": "./index", "bin": { From 30cc61032f8eae6f16c9510ba9b4a8e2cbb29927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Antonio=20Rodr=C3=ADguez?= Date: Wed, 15 Oct 2014 11:06:14 +0200 Subject: [PATCH 07/12] Make collections to not follow redirections by default --- lib/collections.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/collections.js b/lib/collections.js index a71c013..73f3999 100644 --- a/lib/collections.js +++ b/lib/collections.js @@ -51,6 +51,7 @@ var request = require('request') var ApiCollectionsGroup = function ApiCollectionsGroup(config) { config = config || {}; config.headers = config.headers || {}; + config.followRedirect = config.followRedirect || false; /** * This class models an specific collection, once customized to behave From b8964f1f2f45647b14ad4a78daf8ba97b9ce0bd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Antonio=20Rodr=C3=ADguez?= Date: Wed, 15 Oct 2014 16:59:15 +0200 Subject: [PATCH 08/12] FIX typo jsonBody-->bodyJson --- lib/apimock/middlewares.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/apimock/middlewares.js b/lib/apimock/middlewares.js index d30fcbc..dd88dbb 100644 --- a/lib/apimock/middlewares.js +++ b/lib/apimock/middlewares.js @@ -245,8 +245,8 @@ function _unmarshallLastRequests(lastRequests) { lastRequest.headers = JSON.parse(lastRequest.headers); } // Convert jsonBody from JSON to javascript object - if (lastRequest.jsonBody) { - lastRequest.jsonBody = JSON.parse(lastRequest.jsonBody); + if (lastRequest.bodyJson) { + lastRequest.bodyJson = JSON.parse(lastRequest.bodyJson); } }); return lastRequests; From 1658810f3307c6ce8a7fca6da780ce955f0230ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Antonio=20Rodr=C3=ADguez?= Date: Fri, 17 Oct 2014 12:47:35 +0200 Subject: [PATCH 09/12] Adapt utils to start API Mock Server to the new API Mock Server command line options --- lib/server.js | 68 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 19 deletions(-) diff --git a/lib/server.js b/lib/server.js index f8e7344..ba5527f 100644 --- a/lib/server.js +++ b/lib/server.js @@ -56,11 +56,19 @@ var renderConfigFile = function renderConfigFile(templateConfigFile, outputConfi /** * Run an instance of API Mock Server. * @param settings Startup settings for the mock: - * - adminPort: Administration port. - * - httpPort: HTTP port. - * - httpsPort: HTTPS port. - * - key: Key file used to run the HTTPS server. - * - cert: Cert file used to run the HTTPS server. + * - admin: Administration server options: + * - port: Administration port. + * - http: HTTP server options: + * - port: HTTP port. + * - https: HTTPS server options: + * - port: HTTPS port. + * - key: Key file used to run the HTTPS server. + * - cert: Cert file used to run the HTTPS server. + * - twoWaySsl: 2waySSL server options: + * - port: 2waySSL port. + * - key: Key file used to run the 2waySSL server. + * - cert: Cert file used to run the 2waySSL server. + * - ca: CA file used to run the 2waySSL server. * - timeout: Default response timeout. * @param timeout Max time to wait for the API Mock Server to start before returning an error. * @param cb @@ -73,24 +81,40 @@ var startApiMockServer = function startApiMockServer(settings, timeout, cb) { timeout = timeout || 5000; var args = []; - if (settings.adminPort) { + if (settings.admin && settings.admin.port) { args.push('-a'); - args.push(settings.adminPort); + args.push(settings.admin.port); } - if (settings.httpPort) { + if (settings.http && settings.http.port) { args.push('-p'); - args.push(settings.httpPort); + args.push(settings.http.port); } - if (settings.httpsPort) { + if (settings.https && settings.https.port) { args.push('-s'); - args.push(settings.httpsPort); - if (settings.key) { + args.push(settings.https.port); + if (settings.https.key) { args.push('-k'); - args.push(settings.key); + args.push(settings.https.key); } - if (settings.cert) { + if (settings.https.cert) { args.push('-c'); - args.push(settings.cert); + args.push(settings.https.cert); + } + } + if (settings.twoWaySsl && settings.twoWaySsl.port) { + args.push('-2'); + args.push(settings.twoWaySsl.port); + if (settings.twoWaySsl.key) { + args.push('-k'); + args.push(settings.twoWaySsl.key); + } + if (settings.twoWaySsl.cert) { + args.push('-c'); + args.push(settings.twoWaySsl.cert); + } + if (settings.twoWaySsl.ca) { + args.push('-w'); + args.push(settings.twoWaySsl.ca); } } if (settings.timeout) { @@ -104,12 +128,17 @@ var startApiMockServer = function startApiMockServer(settings, timeout, cb) { , stdout = ''; var listening = { - adminPort: false, - httpPort: false + adminPort: false }; - if (settings.httpsPort) { + if (settings.http && settings.http.port) { + listening.httpPort = false; + } + if (settings.https && settings.https.port) { listening.httpsPort = false; } + if (settings.twoWaySsl && settings.twoWaySsl.port) { + listening.twoWaySslPort = false; + } var timeoutId = setTimeout(function() { // Just in case the API mock server does not start properly after some time @@ -169,6 +198,7 @@ var stopApiMockServer = function stopApiMockServer(pid) { * - command: The server executable command. * - args: Array of arguments to be passed to the server. * - env: Object with environment key-value pairs. + * - cwd: String with the current working directory of the child process * - startupMessages: Messages (String or Array) to be searched in stdout or stderr * to consider that the served has started. * If it doesn't exist or is null this function will wait for the server to exit @@ -196,7 +226,7 @@ var startServer = function startServer(serverOpts, timeout, cb) { } var startupMessagesFound = serverOpts.startupMessages ? serverOpts.startupMessages.map(function() { return false; }) : null; - var server = cp.spawn(serverOpts.command, serverOpts.args, { env: serverOpts.env }); + var server = cp.spawn(serverOpts.command, serverOpts.args, { cwd: serverOpts.cwd, env: serverOpts.env }); var stderr = '' , stdout = ''; From 17bc52ea4bc77e81ada866ba650f6a14bf81f20d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Antonio=20Rodr=C3=ADguez?= Date: Mon, 20 Oct 2014 17:36:27 +0200 Subject: [PATCH 10/12] ADD PR feedback --- lib/apimock/middlewares.js | 8 +++++--- lib/server.js | 10 +++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/apimock/middlewares.js b/lib/apimock/middlewares.js index 6e3103a..f2ccd72 100644 --- a/lib/apimock/middlewares.js +++ b/lib/apimock/middlewares.js @@ -95,9 +95,11 @@ function _buildRequestObject(req, config, cb) { }; // Get remote certificate - var certificate = req.connection.getPeerCertificate(); - if (certificate && Object.keys(certificate).length) { - requestObj.certificate = certificate; + if (req.connection.getPeerCertificate) { + var certificate = req.connection.getPeerCertificate(); + if (certificate && Object.keys(certificate).length) { + requestObj.certificate = certificate; + } } var chunks = []; diff --git a/lib/server.js b/lib/server.js index ba5527f..246bc8c 100644 --- a/lib/server.js +++ b/lib/server.js @@ -128,16 +128,16 @@ var startApiMockServer = function startApiMockServer(settings, timeout, cb) { , stdout = ''; var listening = { - adminPort: false + admin: false }; if (settings.http && settings.http.port) { - listening.httpPort = false; + listening.http = false; } if (settings.https && settings.https.port) { - listening.httpsPort = false; + listening.https = false; } if (settings.twoWaySsl && settings.twoWaySsl.port) { - listening.twoWaySslPort = false; + listening.twoWaySsl = false; } var timeoutId = setTimeout(function() { @@ -168,7 +168,7 @@ var startApiMockServer = function startApiMockServer(settings, timeout, cb) { // Look for each server to have been started for (var server in listening) { if (listening.hasOwnProperty(server)) { - listening[server] = (stdout.indexOf('listening on port ' + settings[server]) !== -1); + listening[server] = (stdout.indexOf('listening on port ' + settings[server].port) !== -1); } } if (_.reduce(listening, function(memo, value) { return memo && value; }, true)) { From 14dd31e18ae004a7eb41f6fd818594e98f737c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Antonio=20Rodr=C3=ADguez?= Date: Thu, 6 Nov 2014 14:58:26 +0100 Subject: [PATCH 11/12] Set release date --- ReleaseNotes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 12f1bfc..0ed7ee2 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,6 +1,6 @@ # RELEASE NOTES -## v0.6.0 / XXX +## v0.6.0 / 6 Nov 2014 ### API Mock From 41a5ca15aa8c71cb6cd729d346befe1e051aa33a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Antonio=20Rodr=C3=ADguez?= Date: Thu, 6 Nov 2014 15:08:01 +0100 Subject: [PATCH 12/12] FIX usage of striked text when THEME=CLEAR --- lib/mocha-gherkin/reporters/gherkin.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/mocha-gherkin/reporters/gherkin.js b/lib/mocha-gherkin/reporters/gherkin.js index 72c6a66..e2778f3 100644 --- a/lib/mocha-gherkin/reporters/gherkin.js +++ b/lib/mocha-gherkin/reporters/gherkin.js @@ -70,8 +70,8 @@ var styles = { variantPending: clc.green.italic, stepLabel: clc.yellow, stepText: clc.black, - stepLabelPending: clc.yellow.strike, - stepTextPending: clc.whiteBright.strike, + stepLabelPending: clc.yellow.italic, + stepTextPending: clc.black.italic, stepLabelFailed: clc.red, stepTextFailed: clc.red, hookFailed: clc.red,