UNPKG

mountebank-test

Version:

Over the wire test doubles

195 lines (164 loc) 7.02 kB
'use strict'; var Q = require('q'), helpers = require('../util/helpers'), exceptions = require('../util/errors'), url = require('url'); function create (protocols, imposters, Imposter, logger) { function queryIsFalse (query, key) { if (!query.hasOwnProperty(key)) { return true; } return query[key].toLowerCase() !== 'false'; } function queryBoolean (query, key) { if (!query.hasOwnProperty(key)) { return false; } return query[key].toLowerCase() === 'true'; } function deleteAllImposters () { var ids = Object.keys(imposters), promises = ids.map(function (id) { return imposters[id].stop(); }); ids.forEach(function (id) { delete imposters[id]; }); return Q.all(promises); } function validatePort (port, errors) { var portIsValid = (port === undefined) || (port.toString().indexOf('.') === -1 && port > 0 && port < 65536); if (!portIsValid) { errors.push(exceptions.ValidationError("invalid value for 'port'")); } } function validateProtocol (protocol, errors) { var Protocol = protocols[protocol]; if (typeof protocol === 'undefined') { errors.push(exceptions.ValidationError("'protocol' is a required field")); } else if (!Protocol) { errors.push(exceptions.ValidationError('the ' + protocol + ' protocol is not yet supported')); } } function validate (request, logger) { var errors = [], valid = Q({ isValid: false, errors: errors }); validatePort(request.port, errors); validateProtocol(request.protocol, errors); if (errors.length > 0) { return valid; } else { return protocols[request.protocol].Validator.create().validate(request, logger); } } function respondWithValidationErrors (response, validationErrors) { logger.warn('error creating imposter: ' + JSON.stringify(exceptions.details(validationErrors))); response.statusCode = 400; response.send({ errors: validationErrors }); } function respondWithCreationError (response, error) { logger.warn('error creating imposter: ' + JSON.stringify(exceptions.details(error))); response.statusCode = (error.code === 'insufficient access') ? 403 : 400; response.send({ errors: [error] }); } function get (request, response) { response.format({ json: function () { var query = url.parse(request.url, true).query, options = { replayable: queryBoolean(query, 'replayable'), removeProxies: queryBoolean(query, 'removeProxies'), list: !(queryBoolean(query, 'replayable') || queryBoolean(query, 'removeProxies')) }, result = Object.keys(imposters).reduce(function (accumulator, id) { return accumulator.concat(imposters[id].toJSON(options)); }, []); response.send({ imposters: result }); }, html: function () { var result = Object.keys(imposters).reduce(function (accumulator, id) { return accumulator.concat(imposters[id].toJSON()); }, []); response.render('imposters', { imposters: result }); } }); } function post (request, response) { var protocol = request.body.protocol, validationPromise = validate(request.body, logger); logger.debug(helpers.socketName(request.socket) + ' => ' + JSON.stringify(request.body)); return validationPromise.then(function (validation) { if (validation.isValid) { return Imposter.create(protocols[protocol], request.body).then(function (imposter) { imposters[imposter.port] = imposter; response.setHeader('Location', imposter.url); response.statusCode = 201; response.send(imposter.toJSON()); }, function (error) { respondWithCreationError(response, error); }); } else { respondWithValidationErrors(response, validation.errors); } }); } function del (request, response) { var query = url.parse(request.url, true).query, options = { // default to replayable for backwards compatibility replayable: queryIsFalse(query, 'replayable'), removeProxies: queryBoolean(query, 'removeProxies') }, json = Object.keys(imposters).reduce(function (accumulator, id) { return accumulator.concat(imposters[id].toJSON(options)); }, []); return deleteAllImposters().then(function () { response.send({ imposters: json }); }); } function put (request, response) { var requestImposters = request.body.imposters || [], validationPromises = requestImposters.map(function (imposter) { return validate(imposter, logger); }); logger.debug(helpers.socketName(request.socket) + ' => ' + JSON.stringify(request.body)); return Q.all(validationPromises).then(function (validations) { var isValid = validations.every(function (validation) { return validation.isValid; }); if (isValid) { return deleteAllImposters().then(function () { var creationPromises = request.body.imposters.map(function (imposter) { return Imposter.create(protocols[imposter.protocol], imposter); }); return Q.all(creationPromises); }).then(function (allImposters) { var json = allImposters.map(function (imposter) { return imposter.toJSON({ list: true }); }); allImposters.forEach(function (imposter) { imposters[imposter.port] = imposter; }); response.send({ imposters: json }); }, function (error) { respondWithCreationError(response, error); }); } else { var validationErrors = validations.reduce(function (accumulator, validation) { return accumulator.concat(validation.errors); }, []); respondWithValidationErrors(response, validationErrors); } }); } return { get: get, post: post, del: del, put: put }; } module.exports = { create: create };