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