node-consumer-pact-interceptor
Advanced tools
Comparing version 1.1.0 to 2.0.0
82
index.js
'use strict'; | ||
var interceptor = require('./lib/interceptor'); | ||
var intercept = require('./lib/interceptor'); | ||
var async = require('async'); | ||
module.exports = function(pact){ | ||
/** | ||
* @param {object} pact The pact specification | ||
* @param {string/regex} The url to intercept | ||
* @param cb The callback to fire on *each* interaction | ||
*/ | ||
module.exports = function(pact, url, setState, testSeriesCallback) { | ||
if(!pact || !pact.provider || !pact.consumer || !pact.provider.name || !pact.consumer.name) { | ||
throw "When creating an interceptor it's necessary to provide a consumer and provider"; | ||
} | ||
else if(!pact.interactions || pact.interactions.length < 1){ | ||
throw { | ||
error: "No interactions in pact found", | ||
}; | ||
} | ||
else { | ||
if(!pact || !pact.provider || !pact.consumer || !pact.provider.name || !pact.consumer.name) { | ||
throw "When creating an interceptor it's necessary to provide a consumer and provider"; | ||
} | ||
else if(!pact.interactions || pact.interactions.length < 1){ | ||
throw { | ||
error: "No interactions in pact found", | ||
}; | ||
} | ||
else if(pact.interactions.length > 1){ | ||
throw { | ||
error: "No more than a single interaction per provider is currently supported", | ||
found: pact.interactions.length | ||
}; | ||
} | ||
var asyncArray = []; | ||
return interceptor(pact); | ||
pact.interactions.forEach(function(interaction) { | ||
asyncArray.push(function(testCallback){ | ||
var interceptor = intercept(pact); | ||
interceptor.start(url, interaction, function(err) { | ||
if(err){ // There was a failure in pact assertion(s) | ||
interceptor.teardown(); | ||
testCallback(null, { | ||
interaction: interaction, | ||
failure: err | ||
}); | ||
} | ||
else { | ||
interceptor.teardown(); | ||
testCallback(null, { | ||
interaction: interaction, | ||
failure: false | ||
}); | ||
} | ||
}); | ||
setState(null, interaction, function(err){ | ||
//console.log("after interception", err) | ||
}); | ||
}) | ||
}); | ||
async.series(asyncArray, function(err, results){ | ||
if(err){ | ||
console.error("series failure", err); | ||
} | ||
else { | ||
results.forEach(function(test, index){ | ||
if(test.failure){ | ||
console.log(index, " Test failure: ", test.failure.message); | ||
console.log("\t", test.interaction.description); | ||
console.log(test.interaction.provider_state); | ||
console.log(test.failure); | ||
} | ||
else{ | ||
console.log(index, " Test success: ", test.interaction.description); | ||
console.log("\t", test.interaction.provider_state); | ||
} | ||
}); | ||
testSeriesCallback(null, results) | ||
} | ||
}); | ||
} | ||
}; |
@@ -15,4 +15,3 @@ 'use strict'; | ||
*/ | ||
function pactInterceptor(mitm, pact, interceptorUrl, cb){ | ||
function pactInterceptor(mitm, pact, interceptorUrl, interaction, cb){ | ||
if (typeof interceptorUrl === 'string'){ | ||
@@ -24,7 +23,7 @@ var urlToIntercept = url.parse(interceptorUrl); | ||
} | ||
var expectedRequest = pact.interactions[0].request; | ||
var expectedResponse = pact.interactions[0].response; | ||
var expectedRequest = interaction.request; | ||
var expectedResponse = interaction.response; | ||
mitm.on("request", function(req, res) { | ||
var matchesOnRegex = regexUrl && req.url.match(regexUrl); | ||
@@ -31,0 +30,0 @@ var matchesOnString = urlToIntercept && req.headers.host === urlToIntercept.host && req.url === urlToIntercept.path; |
@@ -22,2 +22,3 @@ 'use strict'; | ||
body = responseSpec.body; | ||
res.end(body); | ||
} | ||
@@ -24,0 +25,0 @@ else if(responseSpec.body){ //Assume it's JSON |
{ | ||
"name": "node-consumer-pact-interceptor", | ||
"version": "1.1.0", | ||
"version": "2.0.0", | ||
"description": "A means to intercept outgoing requests for the purpose of validating consumer pacts", | ||
@@ -27,4 +27,5 @@ "main": "index.js", | ||
"mitm": "^1.2.0", | ||
"request": "^2.67.0" | ||
"request": "^2.67.0", | ||
"async": "^1.5.2" | ||
} | ||
} |
@@ -14,3 +14,2 @@ { | ||
"method": "get", | ||
"path": "/things/1234", | ||
"headers": { | ||
@@ -37,2 +36,21 @@ "authorization": "some Auth header" | ||
} | ||
}, | ||
{ | ||
"description": "A request for an example resource", | ||
"provider_state": "The provider has an example resource available", | ||
"request": { | ||
"method": "get", | ||
"headers": { | ||
"authorization": "some Auth header" | ||
} | ||
}, | ||
"response": { | ||
"status": 200, | ||
"headers": { | ||
"content-type": "application/json" | ||
}, | ||
"body": { | ||
"abc": "abc" | ||
} | ||
} | ||
} | ||
@@ -39,0 +57,0 @@ ], |
369
test/test.js
'use strict'; | ||
// FIXME Make this code DRYer, | ||
@@ -10,353 +9,39 @@ // The GET and POST examples are essentially duplicated code. | ||
var expect = require('chai').expect; | ||
var request = require('request'); | ||
var intercept = require('../index.js'); | ||
describe('Pact Interceptor: - simple GET request', function(){ | ||
var pactSpec = require('./simple-GET-pact.json'); | ||
var httpReq; | ||
var httpBody; | ||
describe('When receiving a request for which to create a pact', function(){ | ||
describe('When the request matches the specification', function(){ | ||
before(function(){ | ||
var params = { | ||
method: "get", | ||
url: "http://somedomain.com", | ||
headers: { authorization: "some Auth header" }, | ||
json: true | ||
}; | ||
var pactSpec = require('./simple-GET-pact.json'); | ||
var pact; | ||
var interceptor; | ||
var intercept; | ||
var httpReq; | ||
var httpBody; | ||
beforeEach(function(){ | ||
interceptor = require('../'); | ||
intercept = interceptor(pactSpec); | ||
}); | ||
afterEach(function(){ | ||
intercept.teardown(); | ||
}); | ||
describe('When the request matches the specification and a regex', function(){ | ||
beforeEach(function(done){ | ||
intercept.start(/.*/, function(err, pactData){ | ||
if(err) { | ||
done(err); | ||
} | ||
else { | ||
pact = pactData; | ||
} | ||
}); | ||
var params = { | ||
method: pactSpec.interactions[0].request.method, | ||
url: "http://somedomain.com" + pactSpec.interactions[0].request.path, | ||
headers: pactSpec.interactions[0].request.headers, | ||
body: pactSpec.interactions[0].request.body, | ||
json: true | ||
}; | ||
request(params, function(err, req, body){ | ||
if(err) { | ||
done(err); | ||
} | ||
else { | ||
httpReq = req; | ||
httpBody = body; | ||
done(); | ||
} | ||
}); | ||
}); | ||
it('Should intercept the request and provide the specified statusCode', function(){ | ||
expect(httpReq.statusCode).to.eql(pactSpec.interactions[0].response.status); | ||
}); | ||
for(var header in pactSpec.interactions[0].response.headers) { | ||
it('Should provide appropriate response header: ' + header, function(){ | ||
expect(httpReq.headers[header]).to.eql(pactSpec.interactions[0].response.headers[header]); | ||
}); | ||
var setState = function(err, interaction, cb){ | ||
request(params, function(err, req, body){ | ||
if(err) { | ||
//done(err); | ||
} | ||
it('Should provide appropriate response body', function(){ | ||
expect(httpBody).to.eql(pactSpec.interactions[0].response.body); | ||
}); | ||
it('Should intercept the request and return the pact object after verification', function(){ | ||
expect(pact).to.eql(pactSpec); | ||
}); | ||
}); | ||
describe('When the request matches the specification', function(){ | ||
beforeEach(function(done){ | ||
intercept.start("http://somedomain.com" + pactSpec.interactions[0].request.path, function(err, pactData){ | ||
if(err) { | ||
done(err); | ||
} | ||
else { | ||
pact = pactData; | ||
} | ||
}); | ||
var params = { | ||
method: pactSpec.interactions[0].request.method, | ||
url: "http://somedomain.com" + pactSpec.interactions[0].request.path, | ||
headers: pactSpec.interactions[0].request.headers, | ||
body: pactSpec.interactions[0].request.body, | ||
json: true | ||
}; | ||
request(params, function(err, req, body){ | ||
if(err) { | ||
done(err); | ||
} | ||
else { | ||
httpReq = req; | ||
httpBody = body; | ||
done(); | ||
} | ||
}); | ||
}); | ||
it('Should intercept the request and provide the specified statusCode', function(){ | ||
expect(httpReq.statusCode).to.eql(pactSpec.interactions[0].response.status); | ||
}); | ||
for(var header in pactSpec.interactions[0].response.headers) { | ||
it('Should provide appropriate response header: ' + header, function(){ | ||
expect(httpReq.headers[header]).to.eql(pactSpec.interactions[0].response.headers[header]); | ||
}); | ||
else { | ||
httpReq = req; | ||
httpBody = body; | ||
} | ||
it('Should provide appropriate response body', function(){ | ||
expect(httpBody).to.eql(pactSpec.interactions[0].response.body); | ||
}); | ||
it('Should intercept the request and return the pact object after verification', function(){ | ||
expect(pact).to.eql(pactSpec); | ||
}); | ||
}); | ||
}; | ||
describe('When the request fails to match the expectation', function(){ | ||
var assertionErr; | ||
describe(': because of a failure to match method', function(){ | ||
beforeEach(function(done){ | ||
intercept.start("http://somedomain.com" + pactSpec.interactions[0].request.path, function(err, pactData){ | ||
if(err) { | ||
assertionErr = err; | ||
done(); | ||
} | ||
else { | ||
done("The test did not yield an error object"); | ||
} | ||
}); | ||
var params = { | ||
method: "put", | ||
url: "http://somedomain.com" + pactSpec.interactions[0].request.path, | ||
headers: pactSpec.interactions[0].request.headers, | ||
body: pactSpec.interactions[0].request.body, | ||
json: true | ||
}; | ||
request(params, function(err, req, body){ | ||
//should never get here | ||
if(err) { | ||
console.log(err); | ||
} | ||
}); | ||
}); | ||
it('should show what the expectation should have been', function(){ | ||
expect(assertionErr.expected).to.equal("get"); | ||
}); | ||
it('Should list the failure (method) in this case as the "actual" result', function(){ | ||
expect(assertionErr.actual).to.equal('PUT'); | ||
}); | ||
it('should provide a message about what\'s wrong', function(){ | ||
expect(assertionErr.message).to.equal('HTTP Methods are not equal'); | ||
}); | ||
}); | ||
}); | ||
describe('When receiving a request which is to be not intercepted', function(){ | ||
var responseCode; | ||
var responseError; | ||
beforeEach(function(done){ | ||
intercept.start('http://some-other-url', function(err, pactData){ | ||
responseError = err; | ||
}); | ||
request.get('http://google.com', function(err, req, body){ | ||
responseCode = req.statusCode; | ||
done(); | ||
}); | ||
}); | ||
it('Should not intercept the request', function(){ | ||
expect(responseCode).to.eql(400); | ||
expect(responseError).to.eql({ | ||
"error": "recevied a request which was not part of the assertion", | ||
"url": "google.com/" | ||
}); | ||
}); | ||
}); | ||
intercept(pactSpec, /.*/, setState, function(err, testResults){ | ||
if(err){ | ||
console.error(err); //Failure in setting up tests | ||
} | ||
}); | ||
}); | ||
}); | ||
describe('Pact Interceptor: - simple POST request', function(){ | ||
describe('When receiving a request for which to create a pact', function(){ | ||
var pactSpec = require(__dirname + '/post-pact.json'); | ||
var pact; | ||
var interceptor; | ||
var intercept; | ||
var httpReq; | ||
var httpBody; | ||
beforeEach(function(){ | ||
interceptor = require('../'); | ||
intercept = interceptor(pactSpec); | ||
}); | ||
afterEach(function(){ | ||
intercept.teardown(); | ||
}); | ||
describe('When the request matches the specification', function(){ | ||
beforeEach(function(done){ | ||
intercept.start("http://somedomain.com" + pactSpec.interactions[0].request.path, function(err, pactData){ | ||
if(err) { | ||
done(err); | ||
} | ||
else { | ||
pact = pactData; | ||
} | ||
}); | ||
var params = { | ||
method: pactSpec.interactions[0].request.method, | ||
url: "http://somedomain.com" + pactSpec.interactions[0].request.path, | ||
headers: pactSpec.interactions[0].request.headers, | ||
body: pactSpec.interactions[0].request.body, | ||
json: true | ||
}; | ||
request(params, function(err, req, body){ | ||
if(err) { | ||
done(err); | ||
} | ||
else { | ||
httpReq = req; | ||
httpBody = body; | ||
done(); | ||
} | ||
}); | ||
}); | ||
it('Should intercept the request and provide the specified statusCode', function(){ | ||
expect(httpReq.statusCode).to.eql(pactSpec.interactions[0].response.status); | ||
}); | ||
for(var header in pactSpec.interactions[0].response.headers) { | ||
it('Should provide appropriate response header: ' + header, function(){ | ||
expect(httpReq.headers[header]).to.eql(pactSpec.interactions[0].response.headers[header]); | ||
}); | ||
} | ||
it('Should provide appropriate response body', function(){ | ||
expect(httpBody).to.eql(pactSpec.interactions[0].response.body); | ||
}); | ||
it('Should intercept the request and return the pact object after verification', function(){ | ||
expect(pact).to.eql(pactSpec); | ||
}); | ||
}); | ||
describe('When the request fails to match the expectation', function(){ | ||
var assertionErr; | ||
describe('because of a failure to match method', function(){ | ||
beforeEach(function(done){ | ||
intercept.start("http://somedomain.com" + pactSpec.interactions[0].request.path, function(err, pactData){ | ||
if(err) { | ||
assertionErr = err; | ||
done(); | ||
} | ||
else { | ||
done("The test did not yield an error object"); | ||
} | ||
}); | ||
var params = { | ||
method: "put", | ||
url: "http://somedomain.com" + pactSpec.interactions[0].request.path, | ||
headers: pactSpec.interactions[0].request.headers, | ||
body: pactSpec.interactions[0].request.body, | ||
json: true | ||
}; | ||
request(params, function(err, req, body){ | ||
//should never get here | ||
if(err) { | ||
console.log(err); | ||
} | ||
}); | ||
}); | ||
it('should show what the expectation should have been', function(){ | ||
expect(assertionErr.expected).to.equal("post"); | ||
}); | ||
it('Should list the failure (method) in this case as the "actual" result', function(){ | ||
expect(assertionErr.actual).to.equal('PUT'); | ||
}); | ||
it('should provide a message about what\'s wrong', function(){ | ||
expect(assertionErr.message).to.equal('HTTP Methods are not equal'); | ||
}); | ||
}); | ||
}); | ||
describe('When receiving a request which is to be not intercepted', function(){ | ||
var responseCode; | ||
var responseError; | ||
beforeEach(function(done){ | ||
intercept.start('http://some-other-url', function(err, pactData){ | ||
responseError = err; | ||
}); | ||
request.get('http://google.com', function(err, req, body){ | ||
responseCode = req.statusCode; | ||
done(); | ||
}); | ||
}); | ||
it('Should not intercept the request', function(){ | ||
expect(responseCode).to.eql(400); | ||
expect(responseError).to.eql({ | ||
"error": "recevied a request which was not part of the assertion", | ||
"url": "google.com/" | ||
}); | ||
}); | ||
}); | ||
it('Should intercept the request and provide the specified statusCode', function(){ | ||
expect(httpReq.statusCode).to.eql(pactSpec.interactions[0].response.status); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
0
19119
5
511
+ Addedasync@^1.5.2
+ Addedasync@1.5.2(transitive)