mirror of https://github.com/pelias/api.git
Harish Krishna
10 years ago
31 changed files with 834 additions and 163 deletions
@ -1,5 +1,4 @@
|
||||
language: node_js |
||||
script: "npm run unit" |
||||
node_js: |
||||
- "0.11" |
||||
- "0.10" |
@ -0,0 +1,46 @@
|
||||
|
||||
var app = require('express')(); |
||||
|
||||
/** ----------------------- middleware ----------------------- **/ |
||||
|
||||
app.use( require('./middleware/toobusy') ); // should be first
|
||||
app.use( require('./middleware/headers') ); |
||||
app.use( require('./middleware/cors') ); |
||||
app.use( require('./middleware/jsonp') ); |
||||
|
||||
var middlewares = {}; |
||||
middlewares.search = require('./middleware/search'); |
||||
|
||||
/** ----------------------- sanitisers ----------------------- **/ |
||||
|
||||
var sanitisers = {}; |
||||
sanitisers.sanitiser= require('./sanitiser/sanitise'); |
||||
|
||||
/** ----------------------- controllers ----------------------- **/ |
||||
|
||||
var controllers = {}; |
||||
controllers.index = require('./controller/index'); |
||||
controllers.suggest = require('./controller/suggest'); |
||||
controllers.search = require('./controller/search'); |
||||
|
||||
/** ----------------------- routes ----------------------- **/ |
||||
|
||||
// api root
|
||||
app.get( '/', controllers.index() ); |
||||
|
||||
// suggest API
|
||||
app.get( '/suggest', sanitisers.sanitiser.middleware, controllers.suggest() ); |
||||
|
||||
// search API
|
||||
app.get( '/search', sanitisers.sanitiser.middleware, middlewares.search.middleware, controllers.search() ); |
||||
|
||||
// reverse API
|
||||
app.get( '/reverse', sanitisers.sanitiser.middleware, controllers.search(undefined, require('../query/reverse')) ); |
||||
|
||||
|
||||
/** ----------------------- error middleware ----------------------- **/ |
||||
|
||||
app.use( require('./middleware/404') ); |
||||
app.use( require('./middleware/500') ); |
||||
|
||||
module.exports = app; |
@ -1,16 +1,22 @@
|
||||
|
||||
var pkg = require('../package'); |
||||
|
||||
function controller( req, res, next ){ |
||||
function setup(){ |
||||
|
||||
// stats
|
||||
res.json({ |
||||
name: pkg.name, |
||||
version: { |
||||
number: pkg.version |
||||
} |
||||
}); |
||||
function controller( req, res, next ){ |
||||
|
||||
// stats
|
||||
res.json({ |
||||
name: pkg.name, |
||||
version: { |
||||
number: pkg.version |
||||
} |
||||
}); |
||||
|
||||
} |
||||
|
||||
return controller; |
||||
|
||||
} |
||||
|
||||
module.exports = controller; |
||||
module.exports = setup; |
@ -1,37 +1,42 @@
|
||||
|
||||
var backend = require('../src/backend'); |
||||
function setup( backend, query ){ |
||||
|
||||
function controller( req, res, next ){ |
||||
var required_query = req.required_query ? req.required_query : 'search'; |
||||
var query = require('../query/' + required_query); |
||||
|
||||
// backend command
|
||||
var cmd = { |
||||
index: 'pelias', |
||||
body: query( req.clean ) |
||||
}; |
||||
// allow overriding of dependencies
|
||||
backend = backend || require('../src/backend'); |
||||
query = query || require('../query/search'); |
||||
|
||||
// query backend
|
||||
backend().client.search( cmd, function( err, data ){ |
||||
function controller( req, res, next ){ |
||||
|
||||
var docs = []; |
||||
// backend command
|
||||
var cmd = { |
||||
index: 'pelias', |
||||
body: query( req.clean ) |
||||
}; |
||||
|
||||
// handle backend errors
|
||||
if( err ){ return next( err ); } |
||||
// query backend
|
||||
backend().client.search( cmd, function( err, data ){ |
||||
|
||||
if( data && data.hits && data.hits.total){ |
||||
docs = data.hits.hits.map( function( hit ){ |
||||
return hit._source; |
||||
}); |
||||
} |
||||
var docs = []; |
||||
|
||||
// handle backend errors
|
||||
if( err ){ return next( err ); } |
||||
|
||||
if( data && data.hits && data.hits.total){ |
||||
docs = data.hits.hits.map( function( hit ){ |
||||
return hit._source; |
||||
}); |
||||
} |
||||
|
||||
// respond
|
||||
return res.status(200).json({ |
||||
date: new Date().getTime(), |
||||
body: docs |
||||
// respond
|
||||
return res.status(200).json({ |
||||
date: new Date().getTime(), |
||||
body: docs |
||||
}); |
||||
}); |
||||
}); |
||||
|
||||
} |
||||
|
||||
return controller; |
||||
} |
||||
|
||||
module.exports = controller; |
||||
module.exports = setup; |
||||
|
@ -1,35 +1,41 @@
|
||||
|
||||
var query = require('../query/suggest'), |
||||
backend = require('../src/backend'); |
||||
function setup( backend, query ){ |
||||
|
||||
function controller( req, res, next ){ |
||||
// allow overriding of dependencies
|
||||
backend = backend || require('../src/backend'); |
||||
query = query || require('../query/suggest'); |
||||
|
||||
// backend command
|
||||
var cmd = { |
||||
index: 'pelias', |
||||
body: query( req.clean ) |
||||
}; |
||||
function controller( req, res, next ){ |
||||
|
||||
// query backend
|
||||
backend().client.suggest( cmd, function( err, data ){ |
||||
// backend command
|
||||
var cmd = { |
||||
index: 'pelias', |
||||
body: query( req.clean ) |
||||
}; |
||||
|
||||
var docs = []; |
||||
// query backend
|
||||
backend().client.suggest( cmd, function( err, data ){ |
||||
|
||||
// handle backend errors
|
||||
if( err ){ return next( err ); } |
||||
var docs = []; |
||||
|
||||
// map response to a valid FeatureCollection
|
||||
if( data && Array.isArray( data.pelias ) && data.pelias.length ){ |
||||
docs = data['pelias'][0].options || []; |
||||
} |
||||
// handle backend errors
|
||||
if( err ){ return next( err ); } |
||||
|
||||
// respond
|
||||
return res.status(200).json({ |
||||
date: new Date().getTime(), |
||||
body: docs |
||||
// map response to a valid FeatureCollection
|
||||
if( data && Array.isArray( data.pelias ) && data.pelias.length ){ |
||||
docs = data['pelias'][0].options || []; |
||||
} |
||||
|
||||
// respond
|
||||
return res.status(200).json({ |
||||
date: new Date().getTime(), |
||||
body: docs |
||||
}); |
||||
}); |
||||
}); |
||||
|
||||
} |
||||
|
||||
return controller; |
||||
} |
||||
|
||||
module.exports = controller; |
||||
module.exports = setup; |
@ -1,29 +1,17 @@
|
||||
|
||||
var app = require('express')(); |
||||
|
||||
/** ----------------------- middleware ----------------------- **/ |
||||
|
||||
app.use( require('./middleware/headers') ); |
||||
app.use( require('./middleware/cors') ); |
||||
app.use( require('./middleware/jsonp') ); |
||||
|
||||
/** ----------------------- routes ----------------------- **/ |
||||
|
||||
// api root
|
||||
app.get( '/', require('./controller/index') ); |
||||
|
||||
// suggest API
|
||||
app.get( '/suggest', require('./sanitiser/sanitise'), require('./controller/suggest') ); |
||||
|
||||
// search API
|
||||
app.get( '/search', require('./sanitiser/sanitise'), require('./middleware/search'), require('./controller/search') ); |
||||
|
||||
// reverse API
|
||||
app.get( '/reverse', require('./sanitiser/sanitise'), require('./middleware/reverse'), require('./controller/search') ); |
||||
|
||||
/** ----------------------- error middleware ----------------------- **/ |
||||
|
||||
app.use( require('./middleware/404') ); |
||||
app.use( require('./middleware/500') ); |
||||
|
||||
app.listen( process.env.PORT || 3100 ); |
||||
var cluster = require('cluster'), |
||||
app = require('./app'), |
||||
multicore = false, |
||||
port = ( process.env.PORT || 3100 ); |
||||
|
||||
/** cluster webserver across all cores **/ |
||||
if( multicore ){ |
||||
// @todo: not finished yet
|
||||
// cluster(app)
|
||||
// .use(cluster.stats())
|
||||
// .listen( process.env.PORT || 3100 );
|
||||
} |
||||
else { |
||||
console.log( 'listening on ' + port ); |
||||
app.listen( process.env.PORT || 3100 ); |
||||
} |
||||
|
@ -1,7 +0,0 @@
|
||||
// middleware
|
||||
function middleware(req, res, next){ |
||||
req.required_query = "reverse"; |
||||
next(); |
||||
} |
||||
|
||||
module.exports = middleware; |
@ -0,0 +1,19 @@
|
||||
|
||||
// middleware which blocks requests when the eventloop is too busy
|
||||
var toobusy = require('toobusy'); |
||||
|
||||
function middleware(req, res, next){ |
||||
if( toobusy() ){ |
||||
res.status(503); // Service Unavailable
|
||||
return next('Server Overwhelmed'); |
||||
} |
||||
return next(); |
||||
} |
||||
|
||||
// calling .shutdown allows your process to exit normally
|
||||
process.on('SIGINT', function() { |
||||
toobusy.shutdown(); |
||||
process.exit(); |
||||
}); |
||||
|
||||
module.exports = middleware; |
@ -0,0 +1,14 @@
|
||||
#> valid reverse query |
||||
path: '/reverse?lat=29.49136&lon=-82.50622' |
||||
|
||||
#? 200 ok |
||||
response.statusCode.should.equal 200 |
||||
|
||||
#? valid response |
||||
now = new Date().getTime() |
||||
should.exist json |
||||
should.not.exist json.error |
||||
should.exist json.date |
||||
json.date.should.be.within now-2000, now+2000 |
||||
should.exist json.body |
||||
json.body.should.be.instanceof Array |
@ -0,0 +1,64 @@
|
||||
|
||||
var setup = require('../../../controller/search'), |
||||
mockBackend = require('../mock/backend'), |
||||
mockQuery = require('../mock/query'); |
||||
|
||||
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.equal(typeof setup(), 'function', 'setup returns a controller'); |
||||
t.end(); |
||||
}); |
||||
}; |
||||
|
||||
// functionally test controller (backend success)
|
||||
module.exports.tests.functional_success = function(test, common) { |
||||
test('functional test', function(t) { |
||||
var backend = mockBackend( 'client/search/ok/1', function( cmd ){ |
||||
t.deepEqual(cmd, { body: { a: 'b' }, index: 'pelias' }, 'correct backend command'); |
||||
}); |
||||
var controller = setup( backend, mockQuery() ); |
||||
var res = { |
||||
status: function( code ){ |
||||
t.equal(code, 200, 'status set'); |
||||
return res; |
||||
}, |
||||
json: function( json ){ |
||||
t.equal(typeof json, 'object', 'returns json'); |
||||
t.equal(typeof json.date, 'number', 'date set'); |
||||
t.true(Array.isArray(json.body), 'body is array'); |
||||
// t.deepEqual(json.body, [ { value: 1 }, { value: 2 } ], 'values correctly mapped');
|
||||
t.end(); |
||||
} |
||||
}; |
||||
controller( { clean: { a: 'b' } }, res ); |
||||
}); |
||||
}; |
||||
|
||||
// functionally test controller (backend failure)
|
||||
module.exports.tests.functional_failure = function(test, common) { |
||||
test('functional test', function(t) { |
||||
var backend = mockBackend( 'client/search/fail/1', function( cmd ){ |
||||
t.deepEqual(cmd, { body: { a: 'b' }, index: 'pelias' }, 'correct backend command'); |
||||
}); |
||||
var controller = setup( backend, mockQuery() ); |
||||
var next = function( message ){ |
||||
t.equal(message,'a backend error occurred','error passed to errorHandler'); |
||||
t.end(); |
||||
}; |
||||
controller( { clean: { a: 'b' } }, undefined, next ); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.all = function (tape, common) { |
||||
|
||||
function test(name, testFunction) { |
||||
return tape('GET /search ' + name, testFunction); |
||||
} |
||||
|
||||
for( var testCase in module.exports.tests ){ |
||||
module.exports.tests[testCase](test, common); |
||||
} |
||||
}; |
@ -0,0 +1,64 @@
|
||||
|
||||
var setup = require('../../../controller/suggest'), |
||||
mockBackend = require('../mock/backend'), |
||||
mockQuery = require('../mock/query'); |
||||
|
||||
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.equal(typeof setup(), 'function', 'setup returns a controller'); |
||||
t.end(); |
||||
}); |
||||
}; |
||||
|
||||
// functionally test controller (backend success)
|
||||
module.exports.tests.functional_success = function(test, common) { |
||||
test('functional test', function(t) { |
||||
var backend = mockBackend( 'client/suggest/ok/1', function( cmd ){ |
||||
t.deepEqual(cmd, { body: { a: 'b' }, index: 'pelias' }, 'correct backend command'); |
||||
}); |
||||
var controller = setup( backend, mockQuery() ); |
||||
var res = { |
||||
status: function( code ){ |
||||
t.equal(code, 200, 'status set'); |
||||
return res; |
||||
}, |
||||
json: function( json ){ |
||||
t.equal(typeof json, 'object', 'returns json'); |
||||
t.equal(typeof json.date, 'number', 'date set'); |
||||
t.true(Array.isArray(json.body), 'body is array'); |
||||
t.deepEqual(json.body, [ { value: 1 }, { value: 2 } ], 'values correctly mapped'); |
||||
t.end(); |
||||
} |
||||
}; |
||||
controller( { clean: { a: 'b' } }, res ); |
||||
}); |
||||
}; |
||||
|
||||
// functionally test controller (backend failure)
|
||||
module.exports.tests.functional_failure = function(test, common) { |
||||
test('functional test', function(t) { |
||||
var backend = mockBackend( 'client/suggest/fail/1', function( cmd ){ |
||||
t.deepEqual(cmd, { body: { a: 'b' }, index: 'pelias' }, 'correct backend command'); |
||||
}); |
||||
var controller = setup( backend, mockQuery() ); |
||||
var next = function( message ){ |
||||
t.equal(message,'a backend error occurred','error passed to errorHandler'); |
||||
t.end(); |
||||
}; |
||||
controller( { clean: { a: 'b' } }, undefined, next ); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.all = function (tape, common) { |
||||
|
||||
function test(name, testFunction) { |
||||
return tape('GET /suggest ' + name, testFunction); |
||||
} |
||||
|
||||
for( var testCase in module.exports.tests ){ |
||||
module.exports.tests[testCase](test, common); |
||||
} |
||||
}; |
@ -0,0 +1,42 @@
|
||||
|
||||
var responses = {}; |
||||
responses['client/suggest/ok/1'] = function( cmd, cb ){ |
||||
return cb( undefined, suggestEnvelope([ { value: 1 }, { value: 2 } ]) ); |
||||
}; |
||||
responses['client/suggest/fail/1'] = function( cmd, cb ){ |
||||
return cb( 'a backend error occurred' ); |
||||
}; |
||||
responses['client/search/ok/1'] = function( cmd, cb ){ |
||||
return cb( undefined, searchEnvelope([ { value: 1 }, { value: 2 } ]) ); |
||||
}; |
||||
responses['client/search/fail/1'] = function( cmd, cb ){ |
||||
return cb( 'a backend error occurred' ); |
||||
}; |
||||
|
||||
function setup( key, cmdCb ){ |
||||
function backend( a, b ){ |
||||
return { |
||||
client: { |
||||
suggest: function( cmd, cb ){ |
||||
if( 'function' === typeof cmdCb ){ cmdCb( cmd ); } |
||||
return responses[key].apply( this, arguments ); |
||||
}, |
||||
search: function( cmd, cb ){ |
||||
if( 'function' === typeof cmdCb ){ cmdCb( cmd ); } |
||||
return responses[key].apply( this, arguments ); |
||||
} |
||||
} |
||||
}; |
||||
} |
||||
return backend; |
||||
} |
||||
|
||||
function suggestEnvelope( options ){ |
||||
return { pelias: [{ options: options }]}; |
||||
} |
||||
|
||||
function searchEnvelope( options ){ |
||||
return { pelias: [{ options: options }]}; |
||||
} |
||||
|
||||
module.exports = setup; |
@ -0,0 +1,10 @@
|
||||
|
||||
function setup(){ |
||||
return query; |
||||
} |
||||
|
||||
function query( clean ){ |
||||
return clean; |
||||
} |
||||
|
||||
module.exports = setup; |
@ -0,0 +1,23 @@
|
||||
|
||||
var indeces = require('../../../query/indeces'); |
||||
|
||||
module.exports.tests = {}; |
||||
|
||||
module.exports.tests.interface = function(test, common) { |
||||
test('valid interface', function(t) { |
||||
t.true(Array.isArray(indeces), 'valid array'); |
||||
t.equal(indeces.length, 7, 'valid array'); |
||||
t.end(); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.all = function (tape, common) { |
||||
|
||||
function test(name, testFunction) { |
||||
return tape('indeces ' + name, testFunction); |
||||
} |
||||
|
||||
for( var testCase in module.exports.tests ){ |
||||
module.exports.tests[testCase](test, common); |
||||
} |
||||
}; |
@ -0,0 +1,52 @@
|
||||
|
||||
var generate = require('../../../query/reverse'); |
||||
|
||||
module.exports.tests = {}; |
||||
|
||||
module.exports.tests.interface = function(test, common) { |
||||
test('valid interface', function(t) { |
||||
t.equal(typeof generate, 'function', 'valid function'); |
||||
t.end(); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.tests.query = function(test, common) { |
||||
test('valid query', function(t) { |
||||
var query = generate({ |
||||
lat: 29.49136, lon: -82.50622 |
||||
}); |
||||
var expected = { |
||||
query:{ |
||||
filtered : { |
||||
query : { |
||||
match_all : {} |
||||
}, |
||||
filter : { |
||||
geo_distance : { |
||||
distance : '1km', |
||||
center_point : { |
||||
lat: 29.49136,
|
||||
lon: -82.50622 |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
size: 1 |
||||
}; |
||||
|
||||
t.deepEqual(query, expected, 'valid reverse query'); |
||||
t.end(); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.all = function (tape, common) { |
||||
|
||||
function test(name, testFunction) { |
||||
return tape('reverse query ' + name, testFunction); |
||||
} |
||||
|
||||
for( var testCase in module.exports.tests ){ |
||||
module.exports.tests[testCase](test, common); |
||||
} |
||||
}; |
@ -0,0 +1,79 @@
|
||||
|
||||
var generate = require('../../../query/search'); |
||||
|
||||
module.exports.tests = {}; |
||||
|
||||
module.exports.tests.interface = function(test, common) { |
||||
test('valid interface', function(t) { |
||||
t.equal(typeof generate, 'function', 'valid function'); |
||||
t.end(); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.tests.query = function(test, common) { |
||||
test('valid query', function(t) { |
||||
var query = generate({ |
||||
input: 'test', size: 10, |
||||
lat: 29.49136, lon: -82.50622, |
||||
bbox: { |
||||
top_left: { |
||||
lat: 11.51053655297385, |
||||
lon: -103.16362455862279 |
||||
}, |
||||
bottom_right: { |
||||
lat: 47.472183447026154, |
||||
lon: -61.84881544137721 |
||||
} |
||||
}, |
||||
layers: ['test'] |
||||
}); |
||||
var expected = { |
||||
query:{ |
||||
query_string : { |
||||
query: 'test', |
||||
fields: ['name.default'], |
||||
default_operator: 'OR' |
||||
} |
||||
}, |
||||
filter: { |
||||
geo_bounding_box: { |
||||
center_point: { |
||||
top_left: { |
||||
lat: 11.51053655297385, |
||||
lon: -103.16362455862279 |
||||
}, |
||||
bottom_right: { |
||||
lat: 47.472183447026154, |
||||
lon: -61.84881544137721 |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
sort : [{ |
||||
_geo_distance : { |
||||
center_point : { |
||||
lat: 29.49136,
|
||||
lon: -82.50622
|
||||
}, |
||||
order: 'asc', |
||||
unit: 'km' |
||||
} |
||||
}], |
||||
size: 10 |
||||
}; |
||||
|
||||
t.deepEqual(query, expected, 'valid search query'); |
||||
t.end(); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.all = function (tape, common) { |
||||
|
||||
function test(name, testFunction) { |
||||
return tape('search query ' + name, testFunction); |
||||
} |
||||
|
||||
for( var testCase in module.exports.tests ){ |
||||
module.exports.tests[testCase](test, common); |
||||
} |
||||
}; |
@ -0,0 +1,50 @@
|
||||
|
||||
var generate = require('../../../query/suggest'); |
||||
|
||||
module.exports.tests = {}; |
||||
|
||||
module.exports.tests.interface = function(test, common) { |
||||
test('valid interface', function(t) { |
||||
t.equal(typeof generate, 'function', 'valid function'); |
||||
t.end(); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.tests.query = function(test, common) { |
||||
test('valid query', function(t) { |
||||
var query = generate({ |
||||
input: 'test', size: 10, |
||||
lat: 0, lon: 0, |
||||
layers: ['test'] |
||||
}); |
||||
var expected = { |
||||
pelias: { |
||||
text: 'test', |
||||
completion: { |
||||
field: 'suggest', |
||||
size: 10, |
||||
context: { |
||||
dataset: [ 'test' ], |
||||
location: { |
||||
precision: 2, |
||||
value: [ 0, 0 ] |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
t.deepEqual(query, expected, 'valid suggest query'); |
||||
t.end(); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.all = function (tape, common) { |
||||
|
||||
function test(name, testFunction) { |
||||
return tape('suggest query ' + name, testFunction); |
||||
} |
||||
|
||||
for( var testCase in module.exports.tests ){ |
||||
module.exports.tests[testCase](test, common); |
||||
} |
||||
}; |
@ -0,0 +1,203 @@
|
||||
|
||||
var sanitize = require('../../../sanitiser/sanitise'), |
||||
defaultError = 'invalid param \'input\': text length, must be >0', |
||||
defaultClean = { input: 'test', lat: 0, layers: [ 'geoname', 'osmnode', 'osmway', 'admin0', 'admin1', 'admin2', 'neighborhood' ], lon: 0, size: 10, zoom: 10 }; |
||||
|
||||
module.exports.tests = {}; |
||||
|
||||
module.exports.tests.interface = function(test, common) { |
||||
test('sanitize interface', function(t) { |
||||
t.equal(typeof sanitize, 'function', 'sanitize is a function'); |
||||
t.equal(sanitize.length, 2, 'sanitize interface'); |
||||
t.end(); |
||||
}); |
||||
test('middleware interface', function(t) { |
||||
t.equal(typeof sanitize.middleware, 'function', 'middleware is a function'); |
||||
t.equal(sanitize.middleware.length, 3, 'sanitize is valid middleware'); |
||||
t.end(); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.tests.sanitize_input = function(test, common) { |
||||
var inputs = { |
||||
invalid: [ '', 100, null, undefined, new Date() ], |
||||
valid: [ 'a', 'aa', 'aaaaaaaa' ] |
||||
}; |
||||
inputs.invalid.forEach( function( input ){ |
||||
test('invalid input', function(t) { |
||||
sanitize({ input: input, lat: 0, lon: 0 }, function( err, clean ){ |
||||
t.equal(err, 'invalid param \'input\': text length, must be >0', 'invalid input'); |
||||
t.equal(clean, undefined, 'clean not set'); |
||||
t.end(); |
||||
}); |
||||
}); |
||||
}); |
||||
inputs.valid.forEach( function( input ){ |
||||
test('valid input', function(t) { |
||||
sanitize({ input: input, lat: 0, lon: 0 }, function( err, clean ){ |
||||
var expected = JSON.parse(JSON.stringify( defaultClean )); |
||||
expected.input = input; |
||||
t.equal(err, undefined, 'no error'); |
||||
t.deepEqual(clean, expected, 'clean set correctly'); |
||||
t.end(); |
||||
}); |
||||
}); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.tests.sanitize_lat = function(test, common) { |
||||
var lats = { |
||||
invalid: [ -1, -45, -90, 91, 120, 181 ], |
||||
valid: [ 0, 45, 90, -0, '0', '45', '90' ] |
||||
}; |
||||
lats.invalid.forEach( function( lat ){ |
||||
test('invalid lat', function(t) { |
||||
sanitize({ input: 'test', lat: lat, lon: 0 }, function( err, clean ){ |
||||
t.equal(err, 'invalid param \'lat\': must be >0 and <90', 'invalid latitude'); |
||||
t.equal(clean, undefined, 'clean not set'); |
||||
t.end(); |
||||
}); |
||||
}); |
||||
}); |
||||
lats.valid.forEach( function( lat ){ |
||||
test('valid lat', function(t) { |
||||
sanitize({ input: 'test', lat: lat, lon: 0 }, function( err, clean ){ |
||||
var expected = JSON.parse(JSON.stringify( defaultClean )); |
||||
expected.lat = parseFloat( lat ); |
||||
t.equal(err, undefined, 'no error'); |
||||
t.deepEqual(clean, expected, 'clean set correctly'); |
||||
t.end(); |
||||
}); |
||||
}); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.tests.sanitize_lon = function(test, common) { |
||||
var lons = { |
||||
invalid: [ -360, -181, 181, 360 ], |
||||
valid: [ -180, -1, -0, 0, 45, 90, '-180', '0', '180' ] |
||||
}; |
||||
lons.invalid.forEach( function( lon ){ |
||||
test('invalid lon', function(t) { |
||||
sanitize({ input: 'test', lat: 0, lon: lon }, function( err, clean ){ |
||||
t.equal(err, 'invalid param \'lon\': must be >-180 and <180', 'invalid longitude'); |
||||
t.equal(clean, undefined, 'clean not set'); |
||||
t.end(); |
||||
}); |
||||
}); |
||||
}); |
||||
lons.valid.forEach( function( lon ){ |
||||
test('valid lon', function(t) { |
||||
sanitize({ input: 'test', lat: 0, lon: lon }, function( err, clean ){ |
||||
var expected = JSON.parse(JSON.stringify( defaultClean )); |
||||
expected.lon = parseFloat( lon ); |
||||
t.equal(err, undefined, 'no error'); |
||||
t.deepEqual(clean, expected, 'clean set correctly'); |
||||
t.end(); |
||||
}); |
||||
}); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.tests.sanitize_zoom = function(test, common) { |
||||
test('invalid zoom value', function(t) { |
||||
sanitize({ zoom: 'a', input: 'test', lat: 0, lon: 0 }, function( err, clean ){ |
||||
t.equal(clean.zoom, 10, 'default zoom set'); |
||||
t.end(); |
||||
}); |
||||
}); |
||||
test('below min zoom value', function(t) { |
||||
sanitize({ zoom: -100, input: 'test', lat: 0, lon: 0 }, function( err, clean ){ |
||||
t.equal(clean.zoom, 1, 'min zoom set'); |
||||
t.end(); |
||||
}); |
||||
}); |
||||
test('above max zoom value', function(t) { |
||||
sanitize({ zoom: 9999, input: 'test', lat: 0, lon: 0 }, function( err, clean ){ |
||||
t.equal(clean.zoom, 18, 'max zoom set'); |
||||
t.end(); |
||||
}); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.tests.sanitize_size = function(test, common) { |
||||
test('invalid size value', function(t) { |
||||
sanitize({ size: 'a', input: 'test', lat: 0, lon: 0 }, function( err, clean ){ |
||||
t.equal(clean.size, 10, 'default size set'); |
||||
t.end(); |
||||
}); |
||||
}); |
||||
test('below min size value', function(t) { |
||||
sanitize({ size: -100, input: 'test', lat: 0, lon: 0 }, function( err, clean ){ |
||||
t.equal(clean.size, 1, 'min size set'); |
||||
t.end(); |
||||
}); |
||||
}); |
||||
test('above max size value', function(t) { |
||||
sanitize({ size: 9999, input: 'test', lat: 0, lon: 0 }, function( err, clean ){ |
||||
t.equal(clean.size, 40, 'max size set'); |
||||
t.end(); |
||||
}); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.tests.sanitize_layers = function(test, common) { |
||||
test('unspecified', function(t) { |
||||
sanitize({ layers: undefined, input: 'test', lat: 0, lon: 0 }, function( err, clean ){ |
||||
t.deepEqual(clean.layers, defaultClean.layers, 'default layers set'); |
||||
t.end(); |
||||
}); |
||||
}); |
||||
test('invalid layer', function(t) { |
||||
sanitize({ layers: 'test_layer', input: 'test', lat: 0, lon: 0 }, function( err, clean ){ |
||||
var msg = 'invalid param \'layer\': must be one or more of geoname,osmnode,osmway,admin0,admin1,admin2,neighborhood'; |
||||
t.equal(err, msg, 'invalid layer requested'); |
||||
t.end(); |
||||
}); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.tests.invalid_params = function(test, common) { |
||||
test('invalid input params', function(t) { |
||||
sanitize( undefined, function( err, clean ){ |
||||
t.equal(err, defaultError, 'handle invalid params gracefully'); |
||||
t.end(); |
||||
}); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.tests.middleware_failure = function(test, common) { |
||||
test('middleware failure', function(t) { |
||||
var res = { status: function( code ){ |
||||
t.equal(code, 400, 'status set'); |
||||
}}; |
||||
var next = function( message ){ |
||||
t.equal(message, defaultError); |
||||
t.end(); |
||||
}; |
||||
sanitize.middleware( {}, res, next ); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.tests.middleware_success = function(test, common) { |
||||
test('middleware success', function(t) { |
||||
var req = { query: { input: 'test', lat: 0, lon: 0 }}; |
||||
var next = function( message ){ |
||||
t.equal(message, undefined, 'no error message set'); |
||||
t.deepEqual(req.clean, defaultClean); |
||||
t.end(); |
||||
}; |
||||
sanitize.middleware( req, undefined, next ); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.all = function (tape, common) { |
||||
|
||||
function test(name, testFunction) { |
||||
return tape('SANTIZE /sanitise ' + name, testFunction); |
||||
} |
||||
|
||||
for( var testCase in module.exports.tests ){ |
||||
module.exports.tests[testCase](test, common); |
||||
} |
||||
}; |
Loading…
Reference in new issue