mirror of https://github.com/pelias/api.git
Peter Johnson a.k.a. insertcoffee
9 years ago
19 changed files with 450 additions and 241 deletions
@ -1,25 +0,0 @@
|
||||
module.exports = function(alias_layers) { |
||||
// make a copy of the array so, you are not modifying original ref
|
||||
var layers = alias_layers.slice(0); |
||||
|
||||
// expand aliases
|
||||
var expand_aliases = function(alias, layers, layer_indeces) { |
||||
var alias_index = layers.indexOf(alias); |
||||
if (alias_index !== -1 ) { |
||||
layers.splice(alias_index, 1); |
||||
layers = layers.concat(layer_indeces); |
||||
} |
||||
return layers; |
||||
}; |
||||
|
||||
layers = expand_aliases('poi', layers, ['geoname','osmnode','osmway']); |
||||
layers = expand_aliases('admin', layers, ['admin0','admin1','admin2','neighborhood','locality','local_admin']); |
||||
layers = expand_aliases('address', layers, ['osmaddress','openaddresses']); |
||||
|
||||
// de-dupe
|
||||
layers = layers.filter(function(item, pos) { |
||||
return layers.indexOf(item) === pos; |
||||
}); |
||||
|
||||
return layers; |
||||
}; |
@ -0,0 +1,15 @@
|
||||
/* |
||||
* Mapping from data layers to type values |
||||
*/ |
||||
|
||||
module.exports = { |
||||
'venue': ['geoname','osmnode','osmway'], |
||||
'address': ['osmaddress','openaddresses'], |
||||
'country': ['admin0'], |
||||
'region': ['admin1'], |
||||
'county': ['admin2'], |
||||
'locality': ['locality'], |
||||
'localadmin': ['local_admin'], |
||||
'neighbourhood': ['neighborhood'], |
||||
'coarse': ['admin0','admin1','admin2','neighborhood','locality','local_admin'], |
||||
}; |
@ -0,0 +1,81 @@
|
||||
|
||||
var _ = require('lodash'), |
||||
check = require('check-types'); |
||||
|
||||
function setup( paramName, targetMap ) { |
||||
return function( raw, clean ){ |
||||
return sanitize( raw, clean, { |
||||
paramName: paramName, |
||||
targetMap: targetMap, |
||||
targetMapKeysString: Object.keys(targetMap).join(',') |
||||
}); |
||||
}; |
||||
} |
||||
|
||||
function sanitize( raw, clean, opts ) { |
||||
|
||||
// error & warning messages
|
||||
var messages = { errors: [], warnings: [] }; |
||||
|
||||
// init clean.types
|
||||
clean.types = clean.types || {}; |
||||
|
||||
// the string of targets (comma delimeted)
|
||||
var targetsString = raw[opts.paramName]; |
||||
|
||||
// trim whitespace
|
||||
if( check.unemptyString( targetsString ) ){ |
||||
targetsString = targetsString.trim(); |
||||
|
||||
// param must be a valid non-empty string
|
||||
if( !check.unemptyString( targetsString ) ){ |
||||
messages.errors.push( |
||||
opts.paramName + ' parameter cannot be an empty string. Valid options: ' + opts.targetMapKeysString |
||||
); |
||||
} |
||||
else { |
||||
|
||||
// split string in to array and lowercase each target string
|
||||
var targets = targetsString.split(',').map( function( target ){ |
||||
return target.toLowerCase(); // lowercase inputs
|
||||
}); |
||||
|
||||
// emit an error for each target *not* present in the targetMap
|
||||
targets.filter( function( target ){ |
||||
return !opts.targetMap.hasOwnProperty(target); |
||||
}).forEach( function( target ){ |
||||
messages.errors.push( |
||||
'\'' + target + '\' is an invalid ' + opts.paramName + ' parameter. Valid options: ' + opts.targetMapKeysString |
||||
); |
||||
}); |
||||
|
||||
// only set types value when no error occured
|
||||
if( !messages.errors.length ){ |
||||
|
||||
// store the values under a new key as 'clean.types.from_*'
|
||||
var typesKey = 'from_' + opts.paramName; |
||||
|
||||
// ?
|
||||
clean.types[typesKey] = targets.reduce(function(acc, target) { |
||||
return acc.concat(opts.targetMap[target]); |
||||
}, []); |
||||
|
||||
// dedupe in case aliases expanded to common things or user typed in duplicates
|
||||
clean.types[typesKey] = _.unique(clean.types[typesKey]); |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
// string is empty
|
||||
else if( check.string( targetsString ) ){ |
||||
messages.errors.push( |
||||
opts.paramName + ' parameter cannot be an empty string. Valid options: ' + opts.targetMapKeysString |
||||
); |
||||
} |
||||
|
||||
|
||||
return messages; |
||||
} |
||||
|
||||
module.exports = setup; |
@ -0,0 +1,120 @@
|
||||
|
||||
var sanitize = require('../../../sanitiser/_targets')('layers', require('../../../query/layers')); |
||||
|
||||
module.exports.tests = {}; |
||||
|
||||
module.exports.tests.sanitize_layers = function(test, common) { |
||||
test('unspecified', function(t) { |
||||
var messages = sanitize({ layers: undefined }, {}); |
||||
t.equal(messages.errors.length, 0, 'no errors'); |
||||
t.end(); |
||||
}); |
||||
test('invalid layer', function(t) { |
||||
var raw = { layers: 'test_layer' }; |
||||
var clean = {}; |
||||
|
||||
var messages = sanitize(raw, clean); |
||||
|
||||
var msg = ' is an invalid layers parameter. Valid options: '; |
||||
t.equal(messages.errors.length, 1, 'errors set'); |
||||
t.true(messages.errors[0].match(msg), 'invalid layer requested'); |
||||
t.true(messages.errors[0].length > msg.length, 'invalid error message'); |
||||
t.end(); |
||||
}); |
||||
test('venue (alias) layer', function(t) { |
||||
var venue_layers = ['geoname','osmnode','osmway']; |
||||
var raw = { layers: 'venue' }; |
||||
var clean = {}; |
||||
|
||||
sanitize(raw, clean); |
||||
|
||||
t.deepEqual(clean.types.from_layers, venue_layers, 'venue layers set'); |
||||
t.end(); |
||||
}); |
||||
test('coarse (alias) layer', function(t) { |
||||
var admin_layers = ['admin0','admin1','admin2','neighborhood','locality','local_admin']; |
||||
var raw = { layers: 'coarse' }; |
||||
var clean = {}; |
||||
|
||||
sanitize(raw, clean); |
||||
|
||||
t.deepEqual(clean.types.from_layers, admin_layers, 'coarse layers set'); |
||||
t.end(); |
||||
}); |
||||
test('address (alias) layer', function(t) { |
||||
var address_layers = ['osmaddress','openaddresses']; |
||||
var raw = { layers: 'address' }; |
||||
var clean = {}; |
||||
|
||||
sanitize(raw, clean); |
||||
|
||||
t.deepEqual(clean.types.from_layers, address_layers, 'address layers set'); |
||||
t.end(); |
||||
}); |
||||
test('venue alias layer plus regular layers', function(t) { |
||||
var venue_layers = ['geoname','osmnode','osmway']; |
||||
var reg_layers = ['admin0', 'admin1']; |
||||
var raw = { layers: 'venue,country,region' }; |
||||
var clean = {}; |
||||
|
||||
sanitize(raw, clean); |
||||
|
||||
t.deepEqual(clean.types.from_layers, venue_layers.concat(reg_layers), 'venue + regular layers'); |
||||
t.end(); |
||||
}); |
||||
test('coarse alias layer plus regular layers', function(t) { |
||||
var admin_layers = ['admin0','admin1','admin2','neighborhood','locality','local_admin']; |
||||
var reg_layers = ['geoname', 'osmnode', 'osmway']; |
||||
|
||||
var raw = { layers: 'coarse,venue,country' }; |
||||
var clean = {}; |
||||
|
||||
sanitize(raw, clean); |
||||
|
||||
t.deepEqual(clean.types.from_layers, admin_layers.concat(reg_layers), 'coarse + regular layers set'); |
||||
t.end(); |
||||
}); |
||||
test('address alias layer plus regular layers', function(t) { |
||||
var address_layers = ['osmaddress','openaddresses']; |
||||
var reg_layers = ['admin0', 'locality']; |
||||
|
||||
var raw = { layers: 'address,country,locality' }; |
||||
var clean = {}; |
||||
|
||||
sanitize(raw, clean); |
||||
|
||||
t.deepEqual(clean.types.from_layers, address_layers.concat(reg_layers), 'address + regular layers set'); |
||||
t.end(); |
||||
}); |
||||
test('alias layer plus regular layers (no duplicates)', function(t) { |
||||
var venue_layers = ['geoname','osmnode','osmway','admin0']; |
||||
var raw = { layers: 'venue,country' }; |
||||
var clean = {}; |
||||
|
||||
sanitize(raw, clean); |
||||
|
||||
t.deepEqual(clean.types.from_layers, venue_layers, 'venue layers found (no duplicates)'); |
||||
t.end(); |
||||
}); |
||||
test('multiple alias layers (no duplicates)', function(t) { |
||||
var alias_layers = ['geoname','osmnode','osmway','admin0','admin1','admin2','neighborhood','locality','local_admin']; |
||||
var raw = { layers: 'venue,coarse' }; |
||||
var clean = {}; |
||||
|
||||
sanitize(raw, clean); |
||||
|
||||
t.deepEqual(clean.types.from_layers, alias_layers, 'all layers found (no duplicates)'); |
||||
t.end(); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.all = function (tape, common) { |
||||
|
||||
function test(name, testFunction) { |
||||
return tape('SANTIZE _layers ' + name, testFunction); |
||||
} |
||||
|
||||
for( var testCase in module.exports.tests ){ |
||||
module.exports.tests[testCase](test, common); |
||||
} |
||||
}; |
@ -0,0 +1,132 @@
|
||||
var sanitize = require( '../../../sanitiser/_targets' )('sources', require('../../../query/sources')); |
||||
|
||||
var success_messages = { error: false }; |
||||
|
||||
module.exports.tests = {}; |
||||
|
||||
module.exports.tests.no_sources = function(test, common) { |
||||
test('sources is not set', function(t) { |
||||
var req = { |
||||
query: { }, |
||||
clean: { } |
||||
}; |
||||
|
||||
var messages = sanitize(req.query, req.clean); |
||||
|
||||
t.deepEqual(req.clean.types, {}, 'clean.types should be empty object'); |
||||
t.deepEqual(messages.errors, [], 'no error returned'); |
||||
t.deepEqual(messages.warnings, [], 'no warnings returned'); |
||||
t.end(); |
||||
}); |
||||
|
||||
test('source is empty string', function(t) { |
||||
var req = { |
||||
query: { |
||||
sources: '' |
||||
}, |
||||
clean: { } |
||||
}; |
||||
|
||||
var expected_error = 'sources parameter cannot be an empty string. ' + |
||||
'Valid options: gn,geonames,oa,openaddresses,qs,quattroshapes,osm,openstreetmap'; |
||||
|
||||
var messages = sanitize(req.query, req.clean); |
||||
|
||||
t.deepEqual(req.clean.types, {}, 'clean.types should be empty object'); |
||||
t.deepEqual(messages.errors.length, 1, 'error returned'); |
||||
t.deepEqual(messages.errors[0], expected_error, 'error returned'); |
||||
t.deepEqual(messages.warnings, [], 'no warnings returned'); |
||||
t.end(); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.tests.valid_sources = function(test, common) { |
||||
test('geonames source', function(t) { |
||||
var req = { |
||||
query: { |
||||
sources: 'geonames' |
||||
}, |
||||
clean: { } |
||||
}; |
||||
|
||||
var messages = sanitize(req.query, req.clean); |
||||
|
||||
t.deepEqual(req.clean.types, { from_sources: ['geoname'] }, 'clean.types should contain from_source entry with geonames'); |
||||
t.deepEqual(messages.errors, [], 'no error returned'); |
||||
t.deepEqual(messages.warnings, [], 'no warnings returned'); |
||||
|
||||
t.end(); |
||||
}); |
||||
|
||||
test('openstreetmap source', function(t) { |
||||
var req = { |
||||
query: { |
||||
sources: 'openstreetmap' |
||||
}, |
||||
clean: { } |
||||
}; |
||||
var expected_types = { |
||||
from_sources: ['osmaddress', 'osmnode', 'osmway'] |
||||
}; |
||||
|
||||
var messages = sanitize(req.query, req.clean); |
||||
|
||||
t.deepEqual(req.clean.types, expected_types, 'clean.types should contain from_source entry with multiple entries for openstreetmap'); |
||||
t.deepEqual(messages.errors, [], 'no error returned'); |
||||
t.deepEqual(messages.warnings, [], 'no warnings returned'); |
||||
t.end(); |
||||
}); |
||||
|
||||
test('multiple sources', function(t) { |
||||
var req = { |
||||
query: { |
||||
sources: 'openstreetmap,openaddresses' |
||||
}, |
||||
clean: { } |
||||
}; |
||||
var expected_types = { |
||||
from_sources: ['osmaddress', 'osmnode', 'osmway', 'openaddresses'] |
||||
}; |
||||
|
||||
var messages = sanitize(req.query, req.clean); |
||||
|
||||
t.deepEqual(req.clean.types, expected_types, |
||||
'clean.types should contain from_source entry with multiple entries for openstreetmap and openadresses'); |
||||
t.deepEqual(messages.errors, [], 'no error returned'); |
||||
t.deepEqual(messages.warnings, [], 'no warnings returned'); |
||||
t.end(); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.tests.invalid_sources = function(test, common) { |
||||
test('geonames source', function(t) { |
||||
var req = { |
||||
query: { |
||||
sources: 'notasource' |
||||
}, |
||||
clean: { } |
||||
}; |
||||
var expected_messages = { |
||||
errors: [ |
||||
'\'notasource\' is an invalid sources parameter. Valid options: gn,geonames,oa,openaddresses,qs,quattroshapes,osm,openstreetmap' |
||||
], |
||||
warnings: [] |
||||
}; |
||||
|
||||
var messages = sanitize(req.query, req.clean); |
||||
|
||||
t.deepEqual(messages, expected_messages, 'error with message returned'); |
||||
t.deepEqual(req.clean.types, { }, 'clean.types should remain empty'); |
||||
t.end(); |
||||
}); |
||||
}; |
||||
|
||||
module.exports.all = function (tape, common) { |
||||
function test(name, testFunction) { |
||||
return tape('SANTIZE _sources ' + name, testFunction); |
||||
} |
||||
|
||||
for( var testCase in module.exports.tests ){ |
||||
module.exports.tests[testCase](test, common); |
||||
} |
||||
}; |
Loading…
Reference in new issue