From 33341b7c998508c2c5a48399918eabb148060db5 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Thu, 12 Jan 2017 15:36:49 +0100 Subject: [PATCH] service: interpolation: tests --- package.json | 5 +- service/interpolation.js | 74 +++++++++++++++-- test/unit/run.js | 3 +- test/unit/service/interpolation.js | 129 +++++++++++++++++++++++++++++ 4 files changed, 199 insertions(+), 12 deletions(-) create mode 100644 test/unit/service/interpolation.js diff --git a/package.json b/package.json index 95b9aa53..141ad06e 100644 --- a/package.json +++ b/package.json @@ -71,11 +71,12 @@ "nsp": "^2.2.0", "precommit-hook": "^3.0.0", "proxyquire": "^1.7.10", + "semantic-release": "^6.3.2", "source-map": "^0.5.6", "tap-dot": "1.0.5", "tape": "^4.5.1", - "uglify-js": "^2.6.2", - "semantic-release": "^6.3.2" + "tmp": "0.0.31", + "uglify-js": "^2.6.2" }, "pre-commit": [ "lint", diff --git a/service/interpolation.js b/service/interpolation.js index 4e6fe405..4006e150 100644 --- a/service/interpolation.js +++ b/service/interpolation.js @@ -1,14 +1,38 @@ -var logger = require( 'pelias-logger' ).get( 'api' ); +var logger = require( 'pelias-logger' ).get( 'api' ), + request = require( 'superagent' ), + peliasConfig = require( 'pelias-config' ); /** - street address interpolation service + street address interpolation service client - see: https://github.com/pelias/interpolation + this file provides several different 'transports' which can be used to access the interpolation + service, either directly from disk or via a network connnection. + + the exported method for this module checks pelias-config for a configuration block such as: + + "interpolation": { + "client": { + "adapter": "http", + "host": "http://interpolation.wiz.co.nz" + } + } + + for more info on running the service see: https://github.com/pelias/interpolation **/ +/** + NullTransport + + disables the service completely +**/ +function NullTransport(){} +NullTransport.prototype.query = function( coord, number, street, cb ){ + cb(); // no-op +}; + /** RequireTransport @@ -16,14 +40,14 @@ var logger = require( 'pelias-logger' ).get( 'api' ); **/ function RequireTransport( addressDbPath, streetDbPath ){ try { - var lib = require('pelias-interpolation'); + var lib = require('pelias-interpolation'); // lazy load dependency this.query = lib.api.search( addressDbPath, streetDbPath ); } catch( e ){ logger.error( 'RequireTransport: failed to connect to interpolation service' ); } } RequireTransport.prototype.query = function( coord, number, street, cb ){ - throw new Error( 'transport not connected' ); + throw new Error( 'interpolation: transport not connected' ); }; /** @@ -32,7 +56,6 @@ RequireTransport.prototype.query = function( coord, number, street, cb ){ allows the api to be used via a remote web service **/ function HttpTransport( host ){ - var request = require('superagent'); this.query = function( coord, number, street, cb ){ request .get( host + '/search/geojson' ) @@ -40,12 +63,13 @@ function HttpTransport( host ){ .query({ lat: coord.lat, lon: coord.lon, number: number, street: street }) .end( function( err, res ){ if( err || !res ){ return cb( err ); } + if( 200 !== res.status ){ return cb( 'non 200 status' ); } return cb( null, res.body ); }); }; } HttpTransport.prototype.query = function( coord, number, street, cb ){ - throw new Error( 'transport not connected' ); + throw new Error( 'interpolation: transport not connected' ); }; /** @@ -53,6 +77,38 @@ HttpTransport.prototype.query = function( coord, number, street, cb ){ allows instantiation of transport depending on configuration and preference **/ -module.exports = function setup(){ - return new HttpTransport( 'http://interpolation.wiz.co.nz' ); +module.exports.search = function setup(){ + + // user config + var config = peliasConfig.generate(); + + // ensure config variables set correctly + if( !config.hasOwnProperty('interpolation') || !config.interpolation.hasOwnProperty('client') ){ + logger.warn( 'interpolation: configuration not found' ); + } + + // valid configuration found + else { + + // get adapter settings from config + var settings = config.interpolation.client; + + // http adapter + if( 'http' === settings.adapter && settings.hasOwnProperty('host') ){ + logger.info( 'interpolation: using http transport:', settings.host ); + return new HttpTransport( settings.host ); + } + + // require adapter + else if( 'require' === settings.adapter ){ + if( settings.hasOwnProperty('streetdb') && settings.hasOwnProperty('addressdb') ){ + logger.info( 'interpolation: using require transport' ); + return new RequireTransport( settings.addressdb, settings.streetdb ); + } + } + } + + // default adapter + logger.info( 'interpolation: using null transport' ); + return new NullTransport(); }; diff --git a/test/unit/run.js b/test/unit/run.js index 017492b5..7d5a3446 100644 --- a/test/unit/run.js +++ b/test/unit/run.js @@ -72,7 +72,8 @@ var tests = [ require('./sanitizer/search_fallback'), require('./sanitizer/wrap'), require('./service/mget'), - require('./service/search') + require('./service/search'), + require('./service/interpolation') ]; tests.map(function(t) { diff --git a/test/unit/service/interpolation.js b/test/unit/service/interpolation.js new file mode 100644 index 00000000..a11ed80f --- /dev/null +++ b/test/unit/service/interpolation.js @@ -0,0 +1,129 @@ + +var fs = require('fs'), + tmp = require('tmp'), + setup = require('../../../service/interpolation').search; + +module.exports.tests = {}; + +module.exports.tests.interface = function(test, common) { + test('valid interface', function(t) { + t.equal(typeof setup, 'function', 'setup is a function'); + t.end(); + }); +}; + +// adapter factory +module.exports.tests.factory = function(test, common) { + + test('http adapter', function(t) { + var config = { interpolation: { client: { + adapter: 'http', + host: 'http://example.com' + }}}; + + // adapter is driven by config + var tmpfile = tmp.tmpNameSync({ postfix: '.json' }); + fs.writeFileSync( tmpfile, JSON.stringify( config ), { encoding: 'utf8' } ); + process.env.PELIAS_CONFIG = tmpfile; + var adapter = setup(); + delete process.env.PELIAS_CONFIG; + + t.equal(adapter.constructor.name, 'HttpTransport', 'HttpTransport'); + t.equal(typeof adapter, 'object', 'adapter is an object'); + t.equal(typeof adapter.query, 'function', 'query is a function'); + t.equal(adapter.query.length, 4, 'query function signature'); + t.end(); + }); + + test('require adapter', function(t) { + var config = { interpolation: { client: { + adapter: 'require', + addressdb: '/tmp/address.db', + streetdb: '/tmp/street.db' + }}}; + + // adapter is driven by config + var tmpfile = tmp.tmpNameSync({ postfix: '.json' }); + fs.writeFileSync( tmpfile, JSON.stringify( config ), { encoding: 'utf8' } ); + process.env.PELIAS_CONFIG = tmpfile; + var adapter = setup(); + delete process.env.PELIAS_CONFIG; + + t.equal(adapter.constructor.name, 'RequireTransport', 'RequireTransport'); + t.equal(typeof adapter, 'object', 'adapter is an object'); + t.equal(typeof adapter.query, 'function', 'query is a function'); + t.equal(adapter.query.length, 4, 'query function signature'); + t.end(); + }); + + test('null adapter', function(t) { + var config = { interpolation: { client: { + adapter: 'null' + }}}; + + // adapter is driven by config + var tmpfile = tmp.tmpNameSync({ postfix: '.json' }); + fs.writeFileSync( tmpfile, JSON.stringify( config ), { encoding: 'utf8' } ); + process.env.PELIAS_CONFIG = tmpfile; + var adapter = setup(); + delete process.env.PELIAS_CONFIG; + + t.equal(adapter.constructor.name, 'NullTransport', 'NullTransport'); + t.equal(typeof adapter, 'object', 'adapter is an object'); + t.equal(typeof adapter.query, 'function', 'query is a function'); + t.equal(adapter.query.length, 4, 'query function signature'); + t.end(); + }); + + test('default adapter', function(t) { + var config = {}; + + // adapter is driven by config + var tmpfile = tmp.tmpNameSync({ postfix: '.json' }); + fs.writeFileSync( tmpfile, JSON.stringify( config ), { encoding: 'utf8' } ); + process.env.PELIAS_CONFIG = tmpfile; + var adapter = setup(); + delete process.env.PELIAS_CONFIG; + + t.equal(adapter.constructor.name, 'NullTransport', 'NullTransport'); + t.equal(typeof adapter, 'object', 'adapter is an object'); + t.equal(typeof adapter.query, 'function', 'query is a function'); + t.equal(adapter.query.length, 4, 'query function signature'); + t.end(); + }); + +}; + +// null transport +module.exports.tests.NullTransport = function(test, common) { + + test('http adapter', function(t) { + var config = {}; + + // adapter is driven by config + var tmpfile = tmp.tmpNameSync({ postfix: '.json' }); + fs.writeFileSync( tmpfile, JSON.stringify( config ), { encoding: 'utf8' } ); + process.env.PELIAS_CONFIG = tmpfile; + var adapter = setup(); + delete process.env.PELIAS_CONFIG; + + // test null transport performs a no-op + adapter.query( null, null, null, function( err, res ){ + t.equal(err, undefined, 'no-op'); + t.equal(res, undefined, 'no-op'); + t.end(); + }); + }); + +}; + +module.exports.all = function (tape, common) { + + function test(name, testFunction) { + return tape('SERVICE interpolation', testFunction); + } + + for( var testCase in module.exports.tests ){ + module.exports.tests[testCase](test, common); + } +};