Browse Source

converted placeholder to microservice-wrapper

pull/850/head
Stephen Hess 8 years ago
parent
commit
471f565997
  1. 4
      package.json
  2. 6
      routes/v1.js
  3. 6
      service/configurations/PlaceHolder.js
  4. 48
      service/configurations/ServiceConfiguration.js
  5. 100
      service/http_json.js
  6. 2
      test/unit/run.js
  7. 24
      test/unit/service/configurations/PlaceHolder.js
  8. 58
      test/unit/service/configurations/ServiceConfiguration.js
  9. 569
      test/unit/service/http_json.js

4
package.json

@ -60,8 +60,7 @@
"pelias-config": "2.10.0", "pelias-config": "2.10.0",
"pelias-labels": "1.6.0", "pelias-labels": "1.6.0",
"pelias-logger": "0.2.0", "pelias-logger": "0.2.0",
"pelias-mock-logger": "^1.0.1", "pelias-microservice-wrapper": "^1.1.0",
"pelias-model": "4.8.1",
"pelias-query": "8.15.0", "pelias-query": "8.15.0",
"pelias-text-analyzer": "1.8.2", "pelias-text-analyzer": "1.8.2",
"predicates": "^1.0.1", "predicates": "^1.0.1",
@ -78,6 +77,7 @@
"jshint": "^2.5.6", "jshint": "^2.5.6",
"npm-check": "git://github.com/orangejulius/npm-check.git#disable-update-check", "npm-check": "git://github.com/orangejulius/npm-check.git#disable-update-check",
"nsp": "^2.2.0", "nsp": "^2.2.0",
"pelias-mock-logger": "^1.0.1",
"precommit-hook": "^3.0.0", "precommit-hook": "^3.0.0",
"proxyquire": "^1.7.10", "proxyquire": "^1.7.10",
"semantic-release": "^6.3.2", "semantic-release": "^6.3.2",

6
routes/v1.js

@ -4,6 +4,7 @@ var elasticsearch = require('elasticsearch');
const all = require('predicates').all; const all = require('predicates').all;
const any = require('predicates').any; const any = require('predicates').any;
const not = require('predicates').not; const not = require('predicates').not;
const _ = require('lodash');
/** ----------------------- sanitizers ----------------------- **/ /** ----------------------- sanitizers ----------------------- **/
var sanitizers = { var sanitizers = {
@ -72,6 +73,7 @@ const isAdminOnlyAnalysis = require('../controller/predicates/is_admin_only_anal
// shorthand for standard early-exit conditions // shorthand for standard early-exit conditions
const hasResponseDataOrRequestErrors = any(hasResponseData, hasRequestErrors); const hasResponseDataOrRequestErrors = any(hasResponseData, hasRequestErrors);
const serviceWrapper = require('pelias-microservice-wrapper').service;
const PlaceHolder = require('../service/configurations/PlaceHolder'); const PlaceHolder = require('../service/configurations/PlaceHolder');
/** /**
@ -88,8 +90,8 @@ function addRoutes(app, peliasConfig) {
const pipService = require('../service/pointinpolygon')(peliasConfig.api.pipService); const pipService = require('../service/pointinpolygon')(peliasConfig.api.pipService);
const placeholderConfiguration = new PlaceHolder(peliasConfig.api.services.placeholder); const placeholderConfiguration = new PlaceHolder(peliasConfig.api.services.placeholder);
const placeholderService = require('../service/http_json')(placeholderConfiguration); const placeholderService = serviceWrapper(placeholderConfiguration);
const isPlaceholderServiceEnabled = require('../controller/predicates/is_service_enabled')(placeholderConfiguration.getBaseUrl()); const isPlaceholderServiceEnabled = _.constant(placeholderConfiguration.isEnabled());
const coarse_reverse_should_execute = all( const coarse_reverse_should_execute = all(
not(hasRequestErrors), isPipServiceEnabled, isCoarseReverse not(hasRequestErrors), isPipServiceEnabled, isCoarseReverse

6
service/configurations/PlaceHolder.js

@ -1,8 +1,10 @@
'use strict'; 'use strict';
const url = require('url');
const _ = require('lodash'); const _ = require('lodash');
const ServiceConfiguration = require('./ServiceConfiguration'); const ServiceConfiguration = require('pelias-microservice-wrapper').ServiceConfiguration;
class PlaceHolder extends ServiceConfiguration { class PlaceHolder extends ServiceConfiguration {
constructor(o) { constructor(o) {
@ -22,7 +24,7 @@ class PlaceHolder extends ServiceConfiguration {
} }
getUrl(req) { getUrl(req) {
return `${this.baseUrl}/search`; return url.resolve(this.baseUrl, 'search');
} }
} }

48
service/configurations/ServiceConfiguration.js

@ -1,48 +0,0 @@
'use strict';
const _ = require('lodash');
class ServiceConfiguration {
constructor(name, config) {
if (_.isEmpty(name)) {
throw 'name is required';
}
this.name = name;
this.baseUrl = config.url;
this.timeout = config.timeout || 250;
this.retries = config.retries || 3;
}
getName() {
return this.name;
}
getBaseUrl() {
return this.baseUrl;
}
getUrl() {
return this.baseUrl;
}
getRetries() {
return this.retries;
}
getTimeout() {
return this.timeout;
}
getParameters() {
return {};
}
getHeaders() {
return {};
}
}
module.exports = ServiceConfiguration;

100
service/http_json.js

@ -1,100 +0,0 @@
const request = require('superagent');
const _ = require('lodash');
const isDNT = require( '../helper/logging' ).isDNT;
const logger = require( 'pelias-logger' ).get( 'placeholder' );
const ServiceConfiguration = require('./configurations/ServiceConfiguration');
// superagent doesn't exposed the assembled GET request, so synthesize it
function synthesizeUrl(serviceConfig, req) {
const parameters = _.map(serviceConfig.getParameters(), (value, key) => {
return `${key}=${value}`;
}).join('&');
if (parameters) {
return encodeURI(`${serviceConfig.getUrl(req)}?${parameters}`);
} else {
return serviceConfig.getUrl(req);
}
}
module.exports = function setup(serviceConfig) {
if (!(serviceConfig instanceof ServiceConfiguration)) {
throw Error('serviceConfig should be an instance of ServiceConfiguration');
}
if (_.isEmpty(serviceConfig.getBaseUrl())) {
logger.warn(`${serviceConfig.getName()} service disabled`);
return (req, callback) => {
// respond with an error to any call
callback(`${serviceConfig.getName()} service disabled`);
};
}
logger.info(`using ${serviceConfig.getName()} service at ${serviceConfig.getBaseUrl()}`);
return (req, callback) => {
const headers = serviceConfig.getHeaders(req) || {};
const do_not_track = isDNT(req);
if (do_not_track) {
headers.dnt = '1';
}
request
.get(serviceConfig.getUrl(req))
.set(headers)
.timeout(serviceConfig.getTimeout())
.retry(serviceConfig.getRetries())
.accept('json')
.query(serviceConfig.getParameters(req))
.on('error', (err) => {
if (err.status) {
// first handle case where a non-200 was returned
if (do_not_track) {
logger.error(`${serviceConfig.getBaseUrl()} [do_not_track] returned status ${err.status}: ${err.response.text}`);
return callback(`${serviceConfig.getBaseUrl()} [do_not_track] returned status ${err.status}: ${err.response.text}`);
} else {
logger.error(`${synthesizeUrl(serviceConfig, req)} returned status ${err.status}: ${err.response.text}`);
return callback(`${synthesizeUrl(serviceConfig, req)} returned status ${err.status}: ${err.response.text}`);
}
}
// handle case that something catastrophic happened while contacting the server
if (do_not_track) {
logger.error(`${serviceConfig.getBaseUrl()} [do_not_track]: ${JSON.stringify(err)}`);
return callback(err);
} else {
logger.error(`${serviceConfig.getUrl(req)}: ${JSON.stringify(err)}`);
return callback(err);
}
})
.end((err, response) => {
// bail early if there's an error (shouldn't happen since it was already handled above)
if (err) {
return;
}
// if json was returned then just return it
if (response.type === 'application/json') {
return callback(null, response.body);
}
if (do_not_track) {
logger.error(`${serviceConfig.getBaseUrl()} [do_not_track] could not parse response: ${response.text}`);
return callback(`${serviceConfig.getBaseUrl()} [do_not_track] could not parse response: ${response.text}`);
} else {
logger.error(`${synthesizeUrl(serviceConfig, req)} could not parse response: ${response.text}`);
return callback(`${synthesizeUrl(serviceConfig, req)} could not parse response: ${response.text}`);
}
});
};
};

2
test/unit/run.js

@ -80,9 +80,7 @@ var tests = [
require('./sanitizer/search'), require('./sanitizer/search'),
require('./sanitizer/search_fallback'), require('./sanitizer/search_fallback'),
require('./sanitizer/wrap'), require('./sanitizer/wrap'),
require('./service/http_json'),
require('./service/configurations/PlaceHolder'), require('./service/configurations/PlaceHolder'),
require('./service/configurations/ServiceConfiguration'),
require('./service/mget'), require('./service/mget'),
require('./service/search'), require('./service/search'),
require('./service/interpolation'), require('./service/interpolation'),

24
test/unit/service/configurations/PlaceHolder.js

@ -5,7 +5,7 @@ const PlaceHolder = require('../../../../service/configurations/PlaceHolder');
module.exports.tests.all = (test, common) => { module.exports.tests.all = (test, common) => {
test('getName should return \'placeholder\'', (t) => { test('getName should return \'placeholder\'', (t) => {
const configBlob = { const configBlob = {
url: 'base url', url: 'http://localhost:1234',
timeout: 17, timeout: 17,
retries: 19 retries: 19
}; };
@ -13,7 +13,7 @@ module.exports.tests.all = (test, common) => {
const placeholder = new PlaceHolder(configBlob); const placeholder = new PlaceHolder(configBlob);
t.equals(placeholder.getName(), 'placeholder'); t.equals(placeholder.getName(), 'placeholder');
t.equals(placeholder.getBaseUrl(), 'base url'); t.equals(placeholder.getBaseUrl(), 'http://localhost:1234/');
t.equals(placeholder.getTimeout(), 17); t.equals(placeholder.getTimeout(), 17);
t.equals(placeholder.getRetries(), 19); t.equals(placeholder.getRetries(), 19);
t.end(); t.end();
@ -22,21 +22,21 @@ module.exports.tests.all = (test, common) => {
test('getUrl should return value passed to constructor', (t) => { test('getUrl should return value passed to constructor', (t) => {
const configBlob = { const configBlob = {
url: 'base url', url: 'http://localhost:1234',
timeout: 17, timeout: 17,
retries: 19 retries: 19
}; };
const placeholder = new PlaceHolder(configBlob); const placeholder = new PlaceHolder(configBlob);
t.equals(placeholder.getUrl(), 'base url/search'); t.equals(placeholder.getUrl(), 'http://localhost:1234/search');
t.end(); t.end();
}); });
test('getParameters should return object with text and lang from req', (t) => { test('getParameters should return object with text and lang from req', (t) => {
const configBlob = { const configBlob = {
url: 'base url', url: 'http://localhost:1234',
timeout: 17, timeout: 17,
retries: 19 retries: 19
}; };
@ -112,6 +112,20 @@ module.exports.tests.all = (test, common) => {
}); });
test('baseUrl ending in / should not have double /\'s return by getUrl', (t) => {
const configBlob = {
url: 'http://localhost:1234/blah',
timeout: 17,
retries: 19
};
const placeholder = new PlaceHolder(configBlob);
t.deepEquals(placeholder.getUrl(), 'http://localhost:1234/blah/search');
t.end();
});
}; };
module.exports.all = (tape, common) => { module.exports.all = (tape, common) => {

58
test/unit/service/configurations/ServiceConfiguration.js

@ -1,58 +0,0 @@
module.exports.tests = {};
const ServiceConfiguration = require('../../../../service/configurations/ServiceConfiguration');
module.exports.tests.all = (test, common) => {
test('timeout and retries overrides should be returned by getters', (t) => {
const configBlob = {
url: 'base url',
timeout: 17,
retries: 19
};
const serviceConfiguration = new ServiceConfiguration('service name', configBlob);
t.equals(serviceConfiguration.getName(), 'service name');
t.equals(serviceConfiguration.getBaseUrl(), 'base url');
t.deepEquals(serviceConfiguration.getParameters(), {});
t.deepEquals(serviceConfiguration.getHeaders(), {});
t.equals(serviceConfiguration.getUrl(), 'base url');
t.equals(serviceConfiguration.getRetries(), 19);
t.equals(serviceConfiguration.getTimeout(), 17);
t.end();
});
test('configBlob w/o timeout or retries should default to 250 and 3, respectively', (t) => {
const configBlob = {
url: 'base url'
};
const serviceConfiguration = new ServiceConfiguration('service name', configBlob);
t.equals(serviceConfiguration.getTimeout(), 250, 'should be a default of 250');
t.equals(serviceConfiguration.getRetries(), 3, 'should be a default of 3');
t.end();
});
test('missing name should throw error', (t) => {
t.throws(() => {
// lint complains if using `new` and not assigning to something
const config = new ServiceConfiguration(undefined, { url: 'base url' });
}, /^name is required$/);
t.end();
});
};
module.exports.all = (tape, common) => {
function test(name, testFunction) {
return tape(`SERVICE CONFIGURATION /ServiceConfiguration ${name}`, testFunction);
}
for( var testCase in module.exports.tests ){
module.exports.tests[testCase](test, common);
}
};

569
test/unit/service/http_json.js

@ -1,569 +0,0 @@
'use strict';
const proxyquire = require('proxyquire').noCallThru();
const express = require('express');
const setup = require('../../../service/http_json');
const ServiceConfiguration = require('../../../service/configurations/ServiceConfiguration');
module.exports.tests = {};
module.exports.tests.interface = (test, common) => {
test('valid interface', (t) => {
const logger = require('pelias-mock-logger')();
var service = proxyquire('../../../service/http_json', {
'pelias-logger': logger
});
t.equal(typeof service, 'function', 'service is a function');
t.end();
});
};
module.exports.tests.conforms_to = (test, common) => {
test('non-ServiceConfiguration instance should throw error', (t) => {
const serviceConfig = 'not an instance of serviceConfiguration';
t.throws(setup.bind(null, serviceConfig), /serviceConfig should be an instance of ServiceConfiguration/);
t.end();
});
};
module.exports.tests.do_nothing_service = (test, common) => {
test('undefined config.url should return service that logs that config.name service is not available', (t) => {
const logger = require('pelias-mock-logger')();
const MockServiceConfig = class extends ServiceConfiguration {
constructor(o) {
super('foo', { } );
}
};
const service = proxyquire('../../../service/http_json', {
'pelias-logger': logger
})(new MockServiceConfig());
t.ok(logger.isWarnMessage(/^foo service disabled$/));
service({}, (err) => {
t.equals(err, 'foo service disabled');
t.end();
});
});
};
module.exports.tests.failure_conditions = (test, common) => {
test('server returning error should log it and return no results', (t) => {
const server = express().listen();
const port = server.address().port;
// immediately close the server so to ensure an error response
server.close();
const logger = require('pelias-mock-logger')();
const MockServiceConfig = class extends ServiceConfiguration {
constructor(o) {
super('foo', { url: `http://localhost:${port}` } );
}
getUrl(req) {
return `http://localhost:${port}/built_url`;
}
};
const service = proxyquire('../../../service/http_json', {
'pelias-logger': logger
})(new MockServiceConfig());
t.ok(logger.isInfoMessage(new RegExp(`using foo service at http://localhost:${port}`)));
service({}, (err, results) => {
t.equals(err.code, 'ECONNREFUSED');
t.notOk(results);
t.ok(logger.isErrorMessage(new RegExp(`^http://localhost:${port}/built_url: .*ECONNREFUSED`)),
'there should be a connection refused error message');
t.end();
server.close();
});
});
test('[DNT] server returning error should log it w/sanitized URL and return no results', (t) => {
const server = express().listen();
const port = server.address().port;
// immediately close the server so to ensure an error response
server.close();
const logger = require('pelias-mock-logger')();
const MockServiceConfig = class extends ServiceConfiguration {
constructor(o) {
super('foo', { url: `http://localhost:${port}` } );
}
getUrl(req) {
return `http://localhost:${port}/built_url`;
}
};
const service = proxyquire('../../../service/http_json', {
'pelias-logger': logger,
'../helper/logging': {
isDNT: () => { return true; }
}
})(new MockServiceConfig());
t.ok(logger.isInfoMessage(new RegExp(`using foo service at http://localhost:${port}`)));
service({}, (err, results) => {
t.equals(err.code, 'ECONNREFUSED');
t.notOk(results);
t.ok(logger.isErrorMessage(new RegExp(`^http://localhost:${port} \\[do_not_track\\]: .*ECONNREFUSED`)),
'there should be a connection refused error message');
t.end();
server.close();
});
});
test('server returning non-200 response should log error and return no results', (t) => {
const webServer = express();
webServer.get('/some_endpoint', (req, res, next) => {
t.notOk(req.headers.hasOwnProperty('dnt'), 'dnt header should not have been passed');
t.equals(req.headers.header1, 'header1 value', 'all headers should have been passed');
t.deepEquals(req.query, { param1: 'param1 value', param2: 'param2 value' });
res.status(400).send('a bad request was made');
});
const server = webServer.listen();
const port = server.address().port;
const logger = require('pelias-mock-logger')();
const MockServiceConfig = class extends ServiceConfiguration {
constructor(o) {
super('foo', { url: `http://localhost:${port}` } );
}
getUrl(req) {
return `http://localhost:${port}/some_endpoint`;
}
getParameters(req) {
return { param1: 'param1 value', param2: 'param2 value' };
}
getHeaders(req) {
return { header1: 'header1 value' };
}
};
const service = proxyquire('../../../service/http_json', {
'pelias-logger': logger
})(new MockServiceConfig());
t.ok(logger.isInfoMessage(new RegExp(`using foo service at http://localhost:${port}`)));
service({}, (err, results) => {
t.equals(err, `http://localhost:${port}/some_endpoint?param1=param1%20value&param2=param2%20value ` +
'returned status 400: a bad request was made');
t.notOk(results);
t.ok(logger.isErrorMessage(`http://localhost:${port}/some_endpoint?param1=param1%20value&param2=param2%20value ` +
`returned status 400: a bad request was made`));
t.end();
server.close();
});
});
test('[DNT] server returning non-200 response should log sanitized error and return no results', (t) => {
const webServer = express();
webServer.get('/some_endpoint', (req, res, next) => {
t.equals(req.headers.dnt, '1');
t.equals(req.headers.header1, 'header1 value', 'all headers should have been passed');
t.deepEquals(req.query, { param1: 'param1 value', param2: 'param2 value' });
res.status(400).send('a bad request was made');
});
const server = webServer.listen();
const port = server.address().port;
const logger = require('pelias-mock-logger')();
const MockServiceConfig = class extends ServiceConfiguration {
constructor(o) {
super('foo', { url: `http://localhost:${port}` } );
}
getUrl(req) {
return `http://localhost:${port}/some_endpoint`;
}
getParameters(req) {
return { param1: 'param1 value', param2: 'param2 value' };
}
getHeaders(req) {
return { header1: 'header1 value' };
}
};
const service = proxyquire('../../../service/http_json', {
'pelias-logger': logger,
'../helper/logging': {
isDNT: () => { return true; }
}
})(new MockServiceConfig());
t.ok(logger.isInfoMessage(new RegExp(`using foo service at http://localhost:${port}`)));
service({}, (err, results) => {
t.equals(err, `http://localhost:${port} [do_not_track] returned status 400: a bad request was made`);
t.notOk(results);
t.ok(logger.isErrorMessage(`http://localhost:${port} [do_not_track] ` +
`returned status 400: a bad request was made`));
t.end();
server.close();
});
});
test('server returning 200 statusCode but with non-JSON response should log error and return undefined', (t) => {
const webServer = express();
webServer.get('/some_endpoint', (req, res, next) => {
t.notOk(req.headers.hasOwnProperty('dnt'), 'dnt header should not have been passed');
t.equals(req.headers.header1, 'header1 value', 'all headers should have been passed');
t.deepEquals(req.query, { param1: 'param1 value', param2: 'param2 value' });
res.set('Content-Type', 'text/plain').status(200).send('this is not parseable as JSON');
});
const server = webServer.listen();
const port = server.address().port;
const logger = require('pelias-mock-logger')();
const MockServiceConfig = class extends ServiceConfiguration {
constructor(o) {
super('foo', { url: `http://localhost:${port}` } );
}
getUrl(req) {
return `http://localhost:${port}/some_endpoint`;
}
getParameters(req) {
return { param1: 'param1 value', param2: 'param2 value' };
}
getHeaders(req) {
return { header1: 'header1 value' };
}
};
const service = proxyquire('../../../service/http_json', {
'pelias-logger': logger
})(new MockServiceConfig());
t.ok(logger.isInfoMessage(new RegExp(`using foo service at http://localhost:${port}`)));
service({}, (err, results) => {
t.equals(err, `http://localhost:${port}/some_endpoint?param1=param1%20value&param2=param2%20value ` +
`could not parse response: this is not parseable as JSON`);
t.notOk(results, 'should return undefined');
t.ok(logger.isErrorMessage(`http://localhost:${port}/some_endpoint?param1=param1%20value&param2=param2%20value ` +
`could not parse response: this is not parseable as JSON`));
t.end();
server.close();
});
});
test('[DNT] server returning 200 statusCode but with non-JSON response should log sanitized error and return undefined', (t) => {
const webServer = express();
webServer.get('/some_endpoint', (req, res, next) => {
t.equals(req.headers.dnt, '1');
t.equals(req.headers.header1, 'header1 value', 'all headers should have been passed');
t.deepEquals(req.query, { param1: 'param1 value', param2: 'param2 value' });
res.status(200).send('this is not parseable as JSON');
});
const server = webServer.listen();
const port = server.address().port;
const logger = require('pelias-mock-logger')();
const MockServiceConfig = class extends ServiceConfiguration {
constructor(o) {
super('foo', { url: `http://localhost:${port}` } );
}
getUrl(req) {
return `http://localhost:${port}/some_endpoint`;
}
getParameters(req) {
return { param1: 'param1 value', param2: 'param2 value' };
}
getHeaders(req) {
return { header1: 'header1 value' };
}
};
const service = proxyquire('../../../service/http_json', {
'pelias-logger': logger,
'../helper/logging': {
isDNT: () => { return true; }
}
})(new MockServiceConfig());
t.ok(logger.isInfoMessage(new RegExp(`using foo service at http://localhost:${port}`)));
service({}, (err, results) => {
t.equals(err, `http://localhost:${port} [do_not_track] ` +
`could not parse response: this is not parseable as JSON`);
t.notOk(results, 'should return undefined');
t.ok(logger.isErrorMessage(`http://localhost:${port} [do_not_track] ` +
`could not parse response: this is not parseable as JSON`));
t.end();
server.close();
});
});
test('server timing out on all requests should log and return error', (t) => {
const webServer = express();
let requestCount = 0;
webServer.get('/some_endpoint', (req, res, next) => {
requestCount++;
res.set('Content-Type', 'text/plain').status(503).send('request timeout');
});
const server = webServer.listen();
const port = server.address().port;
const logger = require('pelias-mock-logger')();
const MockServiceConfig = class extends ServiceConfiguration {
constructor(o) {
super('foo', { url: `http://localhost:${port}` } );
}
getUrl(req) {
return `http://localhost:${port}/some_endpoint`;
}
getParameters(req) {
return { param1: 'param1 value', param2: 'param2 value' };
}
getHeaders(req) {
return { header1: 'header1 value' };
}
getRetries() {
return 1;
}
};
const service = proxyquire('../../../service/http_json', {
'pelias-logger': logger
})(new MockServiceConfig());
t.ok(logger.isInfoMessage(new RegExp(`using foo service at http://localhost:${port}`)));
service({}, (err, results) => {
t.equals(err, `http://localhost:${port}/some_endpoint?param1=param1%20value&param2=param2%20value ` +
'returned status 503: request timeout');
t.notOk(results);
t.ok(logger.isErrorMessage(`http://localhost:${port}/some_endpoint?param1=param1%20value&param2=param2%20value ` +
`returned status 503: request timeout`));
t.equals(requestCount, 2);
t.end();
server.close();
});
});
};
module.exports.tests.success_conditions = (test, common) => {
test('server returning statusCode 200 should return no error and parsed output', (t) => {
const webServer = express();
webServer.get('/some_endpoint', (req, res, next) => {
t.notOk(req.headers.hasOwnProperty('dnt'), 'dnt header should not have been passed');
t.equals(req.headers.header1, 'header1 value', 'all headers should have been passed');
t.deepEquals(req.query, { param1: 'param1 value', param2: 'param2 value' });
res.status(200).json([1, 2, 3]);
});
const server = webServer.listen();
const port = server.address().port;
const logger = require('pelias-mock-logger')();
const MockServiceConfig = class extends ServiceConfiguration {
constructor(o) {
super('foo', { url: `http://localhost:${port}` } );
}
getUrl(req) {
return `http://localhost:${port}/some_endpoint`;
}
getParameters(req) {
return { param1: 'param1 value', param2: 'param2 value' };
}
getHeaders(req) {
return { header1: 'header1 value' };
}
};
const service = proxyquire('../../../service/http_json', {
'pelias-logger': logger
})(new MockServiceConfig());
t.ok(logger.isInfoMessage(new RegExp(`using foo service at http://localhost:${port}`)));
service({}, (err, results) => {
t.notOk(err, 'should be no error');
t.deepEquals(results, [1, 2, 3]);
t.notOk(logger.hasErrorMessages());
t.end();
server.close();
});
});
test('getHeaders returning undefined should use empty headers object', (t) => {
const webServer = express();
webServer.get('/some_endpoint', (req, res, next) => {
t.equals(req.headers.dnt, '1');
t.deepEquals(req.query, { param1: 'param1 value', param2: 'param2 value' });
res.status(200).json([1, 2, 3]);
});
const server = webServer.listen();
const port = server.address().port;
const logger = require('pelias-mock-logger')();
const MockServiceConfig = class extends ServiceConfiguration {
constructor(o) {
super('foo', { url: `http://localhost:${port}` } );
}
getUrl(req) {
return `http://localhost:${port}/some_endpoint`;
}
getParameters(req) {
return { param1: 'param1 value', param2: 'param2 value' };
}
getHeaders(req) {
return undefined;
}
};
const service = proxyquire('../../../service/http_json', {
'pelias-logger': logger,
'../helper/logging': {
isDNT: () => { return true; }
}
})(new MockServiceConfig());
t.ok(logger.isInfoMessage(new RegExp(`using foo service at http://localhost:${port}`)));
service({}, (err, results) => {
t.notOk(err, 'should be no error');
t.deepEquals(results, [1, 2, 3]);
t.notOk(logger.hasErrorMessages());
t.end();
server.close();
});
});
test('server succeeding on last timeout chance should return no error and parsed output', (t) => {
const webServer = express();
let requestCount = 0;
webServer.get('/some_endpoint', (req, res, next) => {
if (++requestCount < 3) {
res.status(503);
} else {
t.notOk(req.headers.hasOwnProperty('dnt'), 'dnt header should not have been passed');
t.equals(req.headers.header1, 'header1 value', 'all headers should have been passed');
t.deepEquals(req.query, { param1: 'param1 value', param2: 'param2 value' });
res.status(200).json([1, 2, 3]);
}
});
const server = webServer.listen();
const port = server.address().port;
const logger = require('pelias-mock-logger')();
const MockServiceConfig = class extends ServiceConfiguration {
constructor(o) {
super('foo', { url: `http://localhost:${port}` } );
}
getUrl(req) {
return `http://localhost:${port}/some_endpoint`;
}
getParameters(req) {
return { param1: 'param1 value', param2: 'param2 value' };
}
getHeaders(req) {
return { header1: 'header1 value' };
}
};
const service = proxyquire('../../../service/http_json', {
'pelias-logger': logger
})(new MockServiceConfig());
t.ok(logger.isInfoMessage(new RegExp(`using foo service at http://localhost:${port}`)));
service({}, (err, results) => {
t.notOk(err, 'should be no error');
t.deepEquals(results, [1, 2, 3]);
t.notOk(logger.hasErrorMessages());
t.equals(requestCount, 3);
t.end();
server.close();
});
});
};
module.exports.all = (tape, common) => {
function test(name, testFunction) {
return tape(`SERVICE /http_json ${name}`, testFunction);
}
for( var testCase in module.exports.tests ){
module.exports.tests[testCase](test, common);
}
};
Loading…
Cancel
Save