diff --git a/.travis.yml b/.travis.yml index 8e0ee44f4..226554783 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,8 +16,6 @@ addons: - ubuntu-toolchain-r-test packages: - g++-4.8 -before_install: -- npm install mitm script: npm run dist after_success: - npm run coverage diff --git a/package.json b/package.json index 7652e0ed6..9664fda9c 100644 --- a/package.json +++ b/package.json @@ -83,8 +83,7 @@ "lodash.isfunction": "3.0.8", "lodash.isnil": "4.0.0", "lodash.isundefined": "3.0.1", - "lodash.omitby": "4.4.0", - "mitm": "1.2.1" + "lodash.omitby": "4.4.0" }, "devDependencies": { "@pact-foundation/pact-node": "4.5.1", diff --git a/src/interceptor/index.js b/src/interceptor/index.js deleted file mode 100644 index db0f16863..000000000 --- a/src/interceptor/index.js +++ /dev/null @@ -1,95 +0,0 @@ -'use strict' - -import Mitm from 'mitm' -import { request } from 'http' -import find from 'lodash.find' -import isNil from 'lodash.isnil' -import { parse as parseUrl } from 'url' - -import logger from '../common/logger' - -export default class Interceptor { - - constructor (proxyHost) { - if (isNil(proxyHost)) { - throw new Error('Please provide a proxy to route the request to.') - } - - this.whitelist = [ parseUrl(proxyHost) ] - this.mitm = Mitm() - this.mitm.disable() - this.disabled = true - this.proxyHost = proxyHost - } - - interceptRequestsOn (url) { - const blacklist = [] - - if (isNil(url)) { - logger.info('!!!! INTERCEPTING ALL REQUESTS !!!!') - } else { - logger.info(`Intercepting URL "${url}"`) - const parsedUrl = parseUrl(url) - if (parsedUrl.port === null) { - parsedUrl.port = parsedUrl.protocol === 'http:' ? 80 : 443 - } - blacklist.push(parsedUrl) - } - - logger.info('Enabling interceptor.') - this.mitm.enable() - this.disabled = false - - const whitelist = this.whitelist - this.mitm.on('connect', function (socket, opts) { - const port = opts.port || null - - logger.info(`Intercepting connection with hostname "${opts.host}", port "${port}"`) - - const foundBypass = !!find(whitelist, { hostname: opts.host, port }) - const shouldIntercept = !!find(blacklist, { hostname: opts.host, port }) - if (foundBypass || !shouldIntercept) { - logger.info(`Bypassing request to "${opts.host}"`) - socket.bypass() - } - }) - - const proxyHost = this.proxyHost - this.mitm.on('request', (interceptedRequest, res) => { - logger.info(`Request intercepted. Triggering call to Mock Server on "${proxyHost}${interceptedRequest.url}"`) - - const opts = parseUrl(`${proxyHost}${interceptedRequest.url}`) - opts.method = interceptedRequest.method.toLowerCase() - opts.headers = interceptedRequest.headers || {} - - const proxyRequest = request(opts, (interceptedResponse) => { - let interceptedResponseBody = '' - interceptedResponse.setEncoding('utf8') - interceptedResponse.on('data', (data) => { interceptedResponseBody += data }) - interceptedResponse.on('end', () => { - logger.info(`HTTP ${interceptedResponse.statusCode} on ${interceptedRequest.url}`) - - if (interceptedResponse.statusCode > 400) { - res.statusCode = interceptedResponse.statusCode - } - - res.end(interceptedResponseBody) - }) - }) - - proxyRequest.on('error', (err) => { - console.log(`HTTP ${err.statusCode} on ${interceptedRequest.url}`) - res.end(err) - }) - - proxyRequest.end() - }) - } - - stopIntercepting () { - logger.info('Disabling interceptor.') - this.mitm.disable() - this.disabled = true - } - -} diff --git a/src/pact.js b/src/pact.js index b9ae4e2bc..b4d9df12a 100644 --- a/src/pact.js +++ b/src/pact.js @@ -8,7 +8,6 @@ var MockService = require('./dsl/mockService').default var Interaction = require('./dsl/interaction').default var responseParser = require('./common/responseParser').default -var Interceptor = require('./interceptor').default var Matchers = require('./dsl/matchers') /** @@ -21,7 +20,7 @@ var Matchers = require('./dsl/matchers') * @param {String} consumer - the name of the consumer * @param {String} provider - the name of the provider * @param {number} port - port of the mock service, defaults to 1234 - * @returns {Object} Pact - returns an {@link Interceptor}, a {@link Matcher#term}, a {@link Matcher#eachLike}, a {@link Matcher#somethingLike} and an {@link Interaction}. + * @returns {Object} Pact - returns a {@link Matcher#term}, a {@link Matcher#eachLike}, a {@link Matcher#somethingLike} and an {@link Interaction}. */ module.exports = ({consumer, provider, port = 1234, host = '127.0.0.1', ssl = false}) => { if (isNil(consumer)) { @@ -93,4 +92,3 @@ module.exports = ({consumer, provider, port = 1234, host = '127.0.0.1', ssl = fa } module.exports.Matchers = Matchers -module.exports.Interceptor = Interceptor diff --git a/test/dsl/integration_with_interceptor.spec.js b/test/dsl/integration_with_interceptor.spec.js deleted file mode 100644 index 6ea18be3e..000000000 --- a/test/dsl/integration_with_interceptor.spec.js +++ /dev/null @@ -1,146 +0,0 @@ -import path from 'path' -import { expect } from 'chai' -import request from 'superagent' -import wrapper from '@pact-foundation/pact-node' - -import Pact from '../../src/pact' -import Interceptor from '../../src/interceptor' - -describe('Pact with Interceptor', () => { - - const MOCK_PORT = Math.floor(Math.random() * 999) + 9000 - const PROVIDER_PORT = Math.floor(Math.random() * 999) + 9000 - const PROVIDER_URL = `http://localhost:${PROVIDER_PORT}` - const mockServer = wrapper.createServer({ - port: MOCK_PORT, - log: path.resolve(process.cwd(), 'logs', 'mockserver-integration.log'), - dir: path.resolve(process.cwd(), 'pacts'), - spec: 2 - }) - - const interceptor = new Interceptor(`http://localhost:${MOCK_PORT}`) - - const EXPECTED_BODY = [{ - id: 1, - name: 'Project 1', - due: '2016-02-11T09:46:56.023Z', - tasks: [ - {id: 1, name: 'Do the laundry', 'done': true}, - {id: 2, name: 'Do the dishes', 'done': false}, - {id: 3, name: 'Do the backyard', 'done': false}, - {id: 4, name: 'Do nothing', 'done': false} - ] - }] - - var provider - - after(() => { - wrapper.removeAllServers() - }) - - before((done) => { - mockServer.start().then(() => { - provider = Pact({ - consumer: 'Consumer Interceptor', - provider: 'Provider Interceptor', - port: MOCK_PORT - }) - interceptor.interceptRequestsOn(PROVIDER_URL) - done() - }) - }) - - after((done) => { - provider.finalize() - .then(() => mockServer.delete()) - .then(() => { - interceptor.stopIntercepting() - done() - }) - }) - - context('with a single request', () => { - - // add interactions, as many as needed - beforeEach((done) => { - provider.addInteraction({ - state: 'i have a list of projects', - uponReceiving: 'a request for projects', - withRequest: { - method: 'get', - path: '/projects', - headers: { 'Accept': 'application/json' } - }, - willRespondWith: { - status: 200, - headers: { 'Content-Type': 'application/json' }, - body: EXPECTED_BODY - } - }).then(() => done()) - }) - - // execute your assertions - it('successfully verifies', (done) => { - const verificationPromise = request - .get(`${PROVIDER_URL}/projects`) - .set({ 'Accept': 'application/json' }) - .then(provider.verify) - - expect(verificationPromise).to.eventually.eql(JSON.stringify(EXPECTED_BODY)).notify(done) - }) - }) - - context('with two requests', () => { - - beforeEach((done) => { - let interaction2 = provider.addInteraction({ - state: 'i have a list of projects', - uponReceiving: 'a request for a project that does not exist', - withRequest: { - method: 'get', - path: '/projects/2', - headers: { 'Accept': 'application/json' } - }, - willRespondWith: { - status: 404, - headers: { 'Content-Type': 'application/json' } - } - }).then(() => done()) - }) - - it('successfully verifies', (done) => { - let promiseResults = [] - - const verificationPromise = - request.get(`${PROVIDER_URL}/projects`) - .set({ 'Accept': 'application/json' }) - .then((response) => { - promiseResults.push(response) - return request.get(`${PROVIDER_URL}/projects/2`).set({ 'Accept': 'application/json' }) - }) - .then(() => {}, (err) => { promiseResults.push(err.response) }) - .then(() => provider.verify(promiseResults)) - - expect(verificationPromise).to.eventually.eql([JSON.stringify(EXPECTED_BODY), '']).notify(done) - }) - }) - - context('with an unexpected interaction', () => { - it('fails verification', (done) => { - let promiseResults = [] - - const verificationPromise = - request.get(`${PROVIDER_URL}/projects`) - .set({ 'Accept': 'application/json' }) - .then((response) => { - promiseResults.push(response) - return request.delete(`${PROVIDER_URL}/projects/2`) - }) - .then(() => {}, (err) => { promiseResults.push(err.response) }) - .then(() => provider.verify(promiseResults)) - - expect(verificationPromise).to.be.rejectedWith('No interaction found for DELETE /projects/2').notify(done) - }) - }) - -}) diff --git a/test/interceptor/index.spec.js b/test/interceptor/index.spec.js deleted file mode 100644 index fe6884907..000000000 --- a/test/interceptor/index.spec.js +++ /dev/null @@ -1,68 +0,0 @@ -import sinon from 'sinon' -import { expect } from 'chai' -import request from 'superagent' - -import Interceptor from '../../src/interceptor' - -describe('Interceptor', () => { - - describe('#constructor', () => { - it('creates Interceptor for targetHost', () => { - const interceptor = new Interceptor('http://proxy:1234') - expect(interceptor).to.not.be.undefined - expect(interceptor.disabled).to.eql(true) - }) - - it('does not create Interceptor when proxy is missing', () => { - expect(() => new Interceptor()).to.throw(Error, 'Please provide a proxy to route the request to.') - }) - - describe('mitm interceptor', () => { - const interceptor = new Interceptor('http://proxy:1234') - - before(() => { - sinon.spy(interceptor.mitm, 'on') - interceptor.interceptRequestsOn('www.google.com.au') - }) - - after(() => { - interceptor.mitm.on.restore() - interceptor.stopIntercepting() - }) - - it('is listening on "connect"', () => { - expect(interceptor.mitm.on).to.have.been.calledWith('connect') - }) - - it('is listening on "request"', () => { - expect(interceptor.mitm.on).to.have.been.calledWith('request') - }) - }) - }) - - xdescribe('when host is supposed to be intercepted', () => { - const interceptor = new Interceptor('http://localhost:1234') - - beforeEach(() => { - interceptor.interceptRequestsOn('http://docs.pact.io') - }); - - afterEach(() => { - interceptor.stopIntercepting() - }) - - it('intercepts the request going to "www.google.com.au"', (done) => { - const nock = require('nock') - nock('http://localhost:1234') - .get('/documentation/javascript.html') - .reply(200, { data: 'successfully intercepted' }) - - request.get('http://docs.pact.io/documentation/javascript.html') - .then((response) => { - expect(JSON.parse(response.text)).to.eql({ data: 'successfully intercepted' }) - nock.restore() - done() - }) - }) - }) -})