Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add delete imposters method #12

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ The content of the new headers that is to be returned by the imposter. Must be a
}
```

<h3>Imposter.getImposter()</h3>
Performs a GET request to the Mountebank server to get the current state of the Imposter including details of each request.
Returns a Promise that resolves to the response returned from the Mountebank server

<h2> Functionality / Features Not Yet Implemented </h2>
<ul>
<li> Support for fuzzy matching (via regex) on incoming-request body content (as opposed to exact path match) [DONE] </li>
Expand Down
21 changes: 21 additions & 0 deletions src/imposter.js
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,27 @@ class Imposter {
return fetchReturnValue;
}

/** CLIENT-FACING METHOD ||ASYNC-METHOD
* gets the existing imposter
* mountebank will return details on the deleted imposter upon a successful delete request
* @return {Promise} we return a resolved promise containing the contents of the deleted imposter
*/
getImposter() {
// make GET request to the mountebank server (through fetch)...
return fetch(`http://${this.ImposterInformation.mountebankHost}:${this.ImposterInformation.mountebankPort}/imposters/${this.ImposterInformation.imposterPort}`, {
method: 'GET'
})
.then(function (response) { // retrieve the text body from the response
return response.text();
})
.then(function (body) {
return body; // Return resolved promise containing text body from response
})
.catch(function (error) {
throw new Error(error);
});
}

getStateResponse() {
return this.ImposterInformation.routeInformation;
}
Expand Down
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const tcpPortUsed = require('tcp-port-used');

exports.Imposter = require('./imposter');

exports.Utils = require('./utils');

exports.startMbServer = function (port) {
return tcpPortUsed.check(port, '127.0.0.1')
.then( function(inUse) {
Expand Down
60 changes: 60 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
'use strict';

const fetch = require('node-fetch');
const _ = require('lodash');

class Utils {
/**
* Sets up the skeleton for the routeInformation POST request body that will be sent to the Mountebank server to set up the imposter
* @param {Object} options The set of options to configure the imposter
* @param {String} options.mountebankHost The name of the network host or ip address of the Mountebank server (defaults to 127.0.0.1)
* @param {Number} options.mountebankPort The port number on which the Mountebank server is to listen on (defaults to 2525)
* @param {Number} options.imposterPort The port number on which this particular Imposter is to listen on
* @param {String} options.protocol The protocol that the imposter is to listen on. Options are http, https, tcp, and smtp (defaults to http)
* @return {Object } Returns an instance of the Imposter class
*/
constructor(options) {
if (!_.isObject(options)) {
throw new TypeError('options must be a Object');
}
if (options.protocol == null) {
options.protocol = 'http';
}
if (options.mountebankHost == null) {
options.mountebankHost = process.env.MOUNTEBANK_HOST || '127.0.0.1'
}
if (options.mountebankPort == null) {
options.mountebankPort = process.env.MOUNTEBANK_PORT || 2525;
}
/* This is the JSON representation of our available routes. This will be formatted similarly to swagger. This is NOT the body of our Imposter POST request */
this.ImposterInformation = {
'mountebankPort': options.mountebankPort,
'mountebankHost': options.mountebankHost,
'protocol': options.protocol,
'routeInformation': {}
};
}

/** ASYNC-METHOD
* deletes all imposters
* mountebank will return details on the deleted imposters upon a successful delete request
* @return {Promise} we return a resolved promise containing the contents of the deleted imposters
*/
deleteImposters() {
// make DELETE request to the mountebank server (through fetch)...
return fetch(`http://${this.ImposterInformation.mountebankHost}:${this.ImposterInformation.mountebankPort}/imposters`, {
method: 'delete'
})
.then(function (response) { // retrieve the text body from the response
return response.text();
})
.then(function (body) {
return body; // Return resolved promise containing text body from response
})
.catch(function (error) {
throw new Error(error);
});
}
}

module.exports = Utils;
79 changes: 79 additions & 0 deletions test/mountebank_posting.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ chai.use(chaiSubset);
// import the mountebank helper library
const mbHelper = require('../src/index');
const Imposter = mbHelper.Imposter;
const Utils = mbHelper.Utils;
const startMbServer = mbHelper.startMbServer;
const fetch = require('node-fetch');

Expand Down Expand Up @@ -45,6 +46,25 @@ describe('Posting when Mountebank is not running', function () {
return testImposter._deleteOldImposter().should.be.eventually.rejected;
});

it('getImposter should reject when MB is not running', function () {
const sampleResponse = {
'uri' : '/pets/123',
'verb' : 'PUT',
'res' : {
'statusCode': 200,
'responseHeaders' : { 'Content-Type' : 'application/json' },
'responseBody' : JSON.stringify({ 'somePetAttribute' : 'somePetValue' })
}
};
const testImposter = new Imposter({ 'imposterPort' : 3000 });
testImposter.addRoute(sampleResponse);
return testImposter.getImposter().should.be.eventually.rejected;
});

it('deleteImposters should reject when MB is not running', function () {
return new Utils({}).deleteImposters().should.be.eventually.rejected;
});

it('_updateResponse should reject when MB is not running', function () {
const sampleResponse = {
'uri' : '/pets/123',
Expand Down Expand Up @@ -173,7 +193,66 @@ describe('Posting to MounteBank', function () {
.should.eventually.deep.equal({ 'Content-Type' : 'application/xml' });
});

describe('Delete Imposters Test', function () {
const testUtil = new Utils({});
before(function startUpMounteBank() {
testUtil.deleteImposters();
});
it('should delete the imposter', function () {
const sampleRespnse = {
'uri': '/pets/123',
'verb': 'GET',
'res': {
'statusCode': 200,
'responseHeaders': {'Content-Type': 'application/json'},
'responseBody': JSON.stringify({'somePetAttribute': 'somePetValue'})
}
};
const testImposterA = new Imposter({'imposterPort': 3008});
testImposterA.addRoute(sampleRespnse);
testImposterA.postToMountebank();
const testImposterB = new Imposter({'imposterPort': 3009});
testImposterB.addRoute(sampleRespnse);
testImposterB.postToMountebank();

return testUtil.deleteImposters().then((response) => {
response = JSON.parse(response);
response.imposters.length.should.equal(2);
response.imposters[0].port.should.equal(3008);
response.imposters[1].port.should.equal(3009);
})
.catch(error => {
throw new Error(error);
});
});
});

describe('Complete Imposter Test', function () {
it('should return the imposter', function () {
const sampleRespnse = {
'uri' : '/pets/123',
'verb' : 'GET',
'res' : {
'statusCode': 200,
'responseHeaders' : { 'Content-Type' : 'application/json' },
'responseBody' : JSON.stringify({ 'somePetAttribute' : 'somePetValue' })
}
};
const testImposter = new Imposter({ 'imposterPort' : 3009 });
testImposter.addRoute(sampleRespnse);
testImposter.postToMountebank();
return testImposter.getImposter().then((response) => {
response = JSON.parse(response);
response.port.should.equal(3009);
response.stubs[0].predicates[0].matches.method.should.equal("GET");
response.stubs[0].predicates[0].matches.path.should.equal("/pets/123");
response.stubs[0].responses[0].is.body.should.equal(JSON.stringify({ 'somePetAttribute' : 'somePetValue' }));
})
.catch( error => {
throw new Error(error);
});
});

it('The correct response is returned when hitting a route on which an imposter is listening on', function () {
const sampleRespnse = {
'uri' : '/pets/123',
Expand Down