Browse Source

Merge pull request #942 from pelias/unexpected_parameters

Check for unexpected parameters in query input
pull/944/head
Lily He 7 years ago committed by GitHub
parent
commit
5fffcee4ba
  1. 15
      sanitizer/_boundary_country.js
  2. 11
      sanitizer/_categories.js
  3. 6
      sanitizer/_city_name_standardizer.js
  4. 6
      sanitizer/_deprecate_quattroshapes.js
  5. 68
      sanitizer/_flag_bool.js
  6. 19
      sanitizer/_geo_autocomplete.js
  7. 18
      sanitizer/_geo_reverse.js
  8. 22
      sanitizer/_geo_search.js
  9. 8
      sanitizer/_geonames_deprecation.js
  10. 6
      sanitizer/_geonames_warnings.js
  11. 10
      sanitizer/_ids.js
  12. 6
      sanitizer/_iso2_to_iso3.js
  13. 37
      sanitizer/_location_bias.js
  14. 6
      sanitizer/_single_scalar_parameters.js
  15. 59
      sanitizer/_size.js
  16. 11
      sanitizer/_sources_and_layers.js
  17. 19
      sanitizer/_synthesize_analysis.js
  18. 118
      sanitizer/_targets.js
  19. 11
      sanitizer/_text.js
  20. 13
      sanitizer/_text_addressit.js
  21. 6
      sanitizer/_tokenizer.js
  22. 25
      sanitizer/autocomplete.js
  23. 8
      sanitizer/defer_to_addressit.js
  24. 31
      sanitizer/nearby.js
  25. 17
      sanitizer/place.js
  26. 23
      sanitizer/reverse.js
  27. 56
      sanitizer/sanitizeAll.js
  28. 25
      sanitizer/search.js
  29. 29
      sanitizer/search_fallback.js
  30. 28
      sanitizer/structured_geocoding.js
  31. 25
      test/unit/sanitizer/_boundary_country.js
  32. 27
      test/unit/sanitizer/_categories.js
  33. 20
      test/unit/sanitizer/_city_name_standardizer.js
  34. 10
      test/unit/sanitizer/_deprecate_quattroshapes.js
  35. 20
      test/unit/sanitizer/_flag_bool.js
  36. 10
      test/unit/sanitizer/_geo_reverse.js
  37. 12
      test/unit/sanitizer/_geonames_deprecation.js
  38. 12
      test/unit/sanitizer/_geonames_warnings.js
  39. 39
      test/unit/sanitizer/_ids.js
  40. 12
      test/unit/sanitizer/_iso2_to_iso3.js
  41. 24
      test/unit/sanitizer/_layers.js
  42. 26
      test/unit/sanitizer/_location_bias.js
  43. 14
      test/unit/sanitizer/_single_scalar_parameters.js
  44. 18
      test/unit/sanitizer/_size.js
  45. 14
      test/unit/sanitizer/_sources.js
  46. 31
      test/unit/sanitizer/_sources_and_layers.js
  47. 31
      test/unit/sanitizer/_synthesize_analysis.js
  48. 14
      test/unit/sanitizer/_text.js
  49. 36
      test/unit/sanitizer/_text_addressit.js
  50. 38
      test/unit/sanitizer/_tokenizer.js
  51. 139
      test/unit/sanitizer/autocomplete.js
  52. 38
      test/unit/sanitizer/defer_to_addressit.js
  53. 163
      test/unit/sanitizer/nearby.js
  54. 138
      test/unit/sanitizer/place.js
  55. 295
      test/unit/sanitizer/reverse.js
  56. 227
      test/unit/sanitizer/sanitizeAll.js
  57. 152
      test/unit/sanitizer/search.js
  58. 197
      test/unit/sanitizer/search_fallback.js
  59. 159
      test/unit/sanitizer/structured_geocoding.js

15
sanitizer/_boundary_country.js

@ -1,7 +1,7 @@
var check = require('check-types');
var iso3166 = require('iso3166-1');
const check = require('check-types');
const iso3166 = require('iso3166-1');
function sanitize(raw, clean) {
function _sanitize(raw, clean) {
// error & warning messages
var messages = { errors: [], warnings: [] };
@ -37,4 +37,11 @@ function containsIsoCode(isoCode) {
return iso3166.is2(isoCode) || iso3166.is3(isoCode);
}
module.exports = sanitize;
function _expected(){
return [{ name: 'boundary.country' }];
}
module.exports = () => ({
sanitize: _sanitize,
expected: _expected
});

11
sanitizer/_categories.js

@ -1,4 +1,3 @@
var check = require('check-types');
var categoryTaxonomy = require('pelias-categories');
@ -8,7 +7,7 @@ var ERRORS = {
};
// validate inputs, convert types and apply defaults
function sanitize( raw, clean, categories ) {
function _sanitize( raw, clean, categories ) {
categories = categories || categoryTaxonomy;
@ -50,5 +49,11 @@ function sanitize( raw, clean, categories ) {
return messages;
}
function _expected() {
return [{ name: 'categories' }];
}
// export function
module.exports = sanitize;
module.exports = () => ({
sanitize: _sanitize,
expected: _expected
});

6
sanitizer/_city_name_standardizer.js

@ -15,7 +15,7 @@ function transliterate(match) {
}
// transliterate ft/mt/saint/sainte to fort/mount/st/ste, respectively
function sanitize(raw, clean) {
function _sanitize(raw, clean) {
// error & warning messages
// this function doesn't add any error or warning messages
const messages = { errors: [], warnings: [] };
@ -44,4 +44,6 @@ function sanitize(raw, clean) {
}
module.exports = sanitize;
module.exports = () => ({
sanitize: _sanitize
});

6
sanitizer/_deprecate_quattroshapes.js

@ -10,7 +10,7 @@ var _ = require('lodash');
@see: https://github.com/pelias/api/issues/442
**/
function sanitize( raw, clean, opts ) {
function _sanitize( raw, clean, opts ) {
// error & warning messages
var messages = { errors: [], warnings: [] };
@ -38,4 +38,6 @@ function sanitize( raw, clean, opts ) {
return messages;
}
module.exports = sanitize;
module.exports = () => ({
sanitize: _sanitize
});

68
sanitizer/_flag_bool.js

@ -5,38 +5,46 @@ var _ = require('lodash');
*
* @param {string} paramName name of parameter being sanitized
* @param {boolean} defaultValue value to set variable to if none specified
* @returns {Function}
* @returns {Object} object containing functions
*/
function setup( paramName, defaultValue ) {
return function( raw, clean ){
return sanitize( raw, clean, {
paramName: paramName,
defaultValue: defaultValue
});
function _setup( paramName, defaultValue ) {
/**
* {object} opts
*/
const opts = {
paramName: paramName,
defaultValue: defaultValue
};
}
/**
* Validate inputs, convert types and apply defaults
*
* @param {object} raw
* @param {object} clean
* @param {object} opts
* @returns {{errors: Array, warnings: Array}}
*/
function sanitize( raw, clean, opts ){
// error & warning messages`1
var messages = { errors: [], warnings: [] };
if( !_.isUndefined( raw[opts.paramName] ) ){
clean[opts.paramName] = isTruthy( raw[opts.paramName] );
}
else {
clean[opts.paramName] = opts.defaultValue;
}
return messages;
}
return {
/**
* Validate inputs, convert types and apply defaults
*
* @param {object} raw
* @param {object} clean
* @returns {{errors: Array, warnings: Array}}
*/
sanitize: function _sanitize( raw, clean){
// error & warning messages`1
var messages = { errors: [], warnings: [] };
if( !_.isUndefined( raw[opts.paramName] ) ){
clean[opts.paramName] = isTruthy( raw[opts.paramName] );
}
else {
clean[opts.paramName] = opts.defaultValue;
}
return messages;
}, // end of _sanitize function
expected: function _expected(){
return [{ name: opts.paramName}];
} // end of _expected function
}; // end of return object
} // end of _setup function
/**
* Determine if param value is "truthy"
@ -47,4 +55,4 @@ function isTruthy(val) {
return _.includes( ['true', '1', 1, true], val );
}
module.exports = setup;
module.exports = _setup;

19
sanitizer/_geo_autocomplete.js

@ -3,7 +3,7 @@ var LAT_LON_IS_REQUIRED = false;
var RECT_IS_REQUIRED = false;
// validate inputs, convert types and apply defaults
module.exports = function sanitize( raw, clean ){
function _sanitize( raw, clean ){
// error & warning messages
var messages = { errors: [], warnings: [] };
@ -17,4 +17,19 @@ module.exports = function sanitize( raw, clean ){
}
return messages;
};
}
function _expected(){
return [
{ name: 'focus.point.lat' },
{ name: 'focus.point.lon' },
{ name: 'boundary.rect.min_lat' },
{ name: 'boundary.rect.max_lat' },
{ name: 'boundary.rect.min_lon' },
{ name: 'boundary.rect.max_lon' }];
}
module.exports = () => ({
sanitize: _sanitize,
expected: _expected
});

18
sanitizer/_geo_reverse.js

@ -7,7 +7,7 @@ var LAT_LON_IS_REQUIRED = true,
const non_coarse_layers = ['venue', 'address', 'street'];
// validate inputs, convert types and apply defaults
module.exports = function sanitize( raw, clean ){
function _sanitize( raw, clean ){
// error & warning messages
var messages = { errors: [], warnings: [] };
@ -38,4 +38,18 @@ module.exports = function sanitize( raw, clean ){
}
return messages;
};
}
function _expected(){
return [
{ name: 'point.lat' },
{ name: 'point.lon' },
{ name: 'boundary.circle.lon' }, // copied from point.lon by the API, not user input
{ name: 'boundary.circle.lat' }, // copied from point.lat by the API, not user input
{ name: 'boundary.circle.radius'}];
}
module.exports = () => ({
sanitize: _sanitize,
expected: _expected
});

22
sanitizer/_geo_search.js

@ -6,7 +6,7 @@ var RECT_IS_REQUIRED = false;
var CIRCLE_IS_REQUIRED = false;
// validate inputs, convert types and apply defaults
module.exports = function sanitize( raw, clean ){
function _sanitize( raw, clean ){
// error & warning messages
var messages = { errors: [], warnings: [] };
@ -21,4 +21,22 @@ module.exports = function sanitize( raw, clean ){
}
return messages;
};
}
function _expected(){
return [
{ name: 'focus.point.lat' },
{ name: 'focus.point.lon' },
{ name: 'boundary.circle.lon'},
{ name: 'boundary.circle.lat'},
{ name: 'boundary.circle.radius'},
{ name: 'boundary.rect.min_lat' },
{ name: 'boundary.rect.max_lat' },
{ name: 'boundary.rect.min_lon' },
{ name: 'boundary.rect.max_lon' }];
}
module.exports = () => ({
sanitize: _sanitize,
expected: _expected
});

8
sanitizer/_geonames_deprecation.js

@ -5,7 +5,7 @@ with the release of coarse reverse as a separate thing and ES reverse only
handling venues, addresses, and streets, geonames make no sense in the reverse context
**/
function sanitize( raw, clean, opts ) {
function _sanitize( raw, clean, opts ) {
// error & warning messages
const messages = { errors: [], warnings: [] };
@ -19,7 +19,9 @@ function sanitize( raw, clean, opts ) {
}
return messages;
}
module.exports = sanitize;
module.exports = () => ({
sanitize: _sanitize
});

6
sanitizer/_geonames_warnings.js

@ -9,7 +9,7 @@ function hasAnyNonAdminFields(parsed_text) {
non_admin_fields));
}
function sanitize( raw, clean ){
function _sanitize( raw, clean ){
// error & warning messages
const messages = { errors: [], warnings: [] };
@ -34,4 +34,6 @@ function sanitize( raw, clean ){
return messages;
}
module.exports = sanitize;
module.exports = () => ({
sanitize: _sanitize
});

10
sanitizer/_ids.js

@ -52,7 +52,7 @@ function sanitizeId(rawId, messages) {
};
}
function sanitize( raw, clean ){
function _sanitize( raw, clean ){
// error & warning messages
var messages = { errors: [], warnings: [] };
@ -84,5 +84,11 @@ function sanitize( raw, clean ){
return messages;
}
function _expected(){
return [{ name: 'ids' }];
}
// export function
module.exports = sanitize;
module.exports = () => ({
sanitize: _sanitize,
expected: _expected
});

6
sanitizer/_iso2_to_iso3.js

@ -4,7 +4,7 @@ const iso3166 = require('iso3166-1');
// this sanitizer exists solely to convert an ISO2 country value to ISO3
// eg - 'TH' -> 'THA'
// this can go away once altnames imports ISO2 country values from WOF
function sanitize( raw, clean ){
function _sanitize( raw, clean ){
// error & warning messages
const messages = { errors: [], warnings: [] };
@ -16,4 +16,6 @@ function sanitize( raw, clean ){
}
// export function
module.exports = sanitize;
module.exports = () => ({
sanitize: _sanitize
});

37
sanitizer/_location_bias.js

@ -4,28 +4,29 @@ Set a focus.lat and focus.lon if specified in pelias config
* @param {object} defaultParameters property of pelias config
*/
function setup(defaultParameters){
function _setup(defaultParameters){
return {
sanitize: function sanitize(raw, clean){
/*
check that:
1. {object} raw exists
2. pelias-config included the properties focus.point.lat and focus.point.lon
3. raw.focus.point.lon and raw.focus.point.lat have not been set
*/
if (!_.isUndefined(raw) &&
!_.isUndefined(defaultParameters['focus.point.lat']) &&
!_.isUndefined(defaultParameters['focus.point.lon']) &&
!_.has(raw, 'focus.point.lon') &&
!_.has(raw, 'focus.point.lat') ) {
return function setLocationBias(raw, clean){
/*
check that:
1. {object} raw exists
2. pelias-config included the properties focus.point.lat and focus.point.lon
3. raw.focus.point.lon and raw.focus.point.lat have not been set
*/
if (!_.isUndefined(raw) &&
!_.isUndefined(defaultParameters['focus.point.lat']) &&
!_.isUndefined(defaultParameters['focus.point.lon']) &&
!_.has(raw, 'focus.point.lon') &&
!_.has(raw, 'focus.point.lat') ) {
raw['focus.point.lat'] = defaultParameters['focus.point.lat'];
raw['focus.point.lon'] = defaultParameters['focus.point.lon'];
}
raw['focus.point.lat'] = defaultParameters['focus.point.lat'];
raw['focus.point.lon'] = defaultParameters['focus.point.lon'];
return { errors: [], warnings: [] };
}
return { errors: [], warnings: [] };
};
}
// if focus.point.lat and focus.point.lon already exists, don't change
module.exports = setup;
module.exports = _setup;

6
sanitizer/_single_scalar_parameters.js

@ -3,7 +3,7 @@ var _ = require('lodash'),
check = require('check-types');
// validate inputs
function sanitize( raw, clean ){
function _sanitize( raw, clean ){
// error & warning messages
var messages = { errors: [], warnings: [] };
@ -22,4 +22,6 @@ function sanitize( raw, clean ){
}
// export function
module.exports = sanitize;
module.exports = () => ({
sanitize: _sanitize
});

59
sanitizer/_size.js

@ -5,40 +5,47 @@ var MIN_SIZE = 1,
DEFAULT_SIZE = 10;
// validate inputs, convert types and apply defaults
function setup( size_min, size_max, size_def ){
function _setup( size_min, size_max, size_def ){
// allow caller to inject custom min/max/default values
if( !check.number( size_min ) ){ size_min = MIN_SIZE; }
if( !check.number( size_max ) ){ size_max = MAX_SIZE; }
if( !check.number( size_def ) ){ size_def = DEFAULT_SIZE; }
return function sanitize( raw, clean ){
// error & warning messages
var messages = { errors: [], warnings: [] };
// coercions
clean.size = parseInt( raw.size, 10 );
// invalid numeric input
if( isNaN( clean.size ) ){
clean.size = size_def;
return {
sanitize: function _sanitize( raw, clean ){
// error & warning messages
var messages = { errors: [], warnings: [] };
// coercions
clean.size = parseInt( raw.size, 10 );
// invalid numeric input
if( isNaN( clean.size ) ){
clean.size = size_def;
}
// ensure size falls within defined range
else if( clean.size > size_max ){
// set the max size
messages.warnings.push('out-of-range integer \'size\', using MAX_SIZE');
clean.size = size_max;
}
else if( clean.size < size_min ){
// set the min size
messages.warnings.push('out-of-range integer \'size\', using MIN_SIZE');
clean.size = size_min;
}
return messages;
},
expected: function _expected() {
// add size as a valid parameter
return [{ name: 'size' }];
}
// ensure size falls within defined range
else if( clean.size > size_max ){
// set the max size
messages.warnings.push('out-of-range integer \'size\', using MAX_SIZE');
clean.size = size_max;
}
else if( clean.size < size_min ){
// set the min size
messages.warnings.push('out-of-range integer \'size\', using MIN_SIZE');
clean.size = size_min;
}
return messages;
};
}
// export function
module.exports = setup;
module.exports = _setup;

11
sanitizer/_sources_and_layers.js

@ -5,7 +5,7 @@ var type_mapping = require( '../helper/type_mapping' );
* This sanitizer depends on clean.layers and clean.sources
* so it has to be run after those sanitizers have been run
*/
function sanitize( raw, clean ){
function _sanitize( raw, clean ){
var messages = { errors: [], warnings: [] };
var possible_errors = [];
@ -34,4 +34,11 @@ function sanitize( raw, clean ){
return messages;
}
module.exports = sanitize;
function _expected(){
return [{ 'name': 'sources' }, { 'name': 'layers' }];
}
module.exports = () => ({
sanitize: _sanitize,
expected: _expected
});

19
sanitizer/_synthesize_analysis.js

@ -35,7 +35,7 @@ function getHouseNumberField(analyzed_address) {
}
function sanitize( raw, clean ){
function _sanitize( raw, clean ){
// error & warning messages
const messages = { errors: [], warnings: [] };
@ -86,5 +86,20 @@ function sanitize( raw, clean ){
return messages;
}
function _expected() {
return [
{ 'name': 'venue' },
{ 'name': 'address' },
{ 'name': 'neighbourhood' },
{ 'name': 'borough' },
{ 'name': 'locality' },
{ 'name': 'county' },
{ 'name': 'region' },
{ 'name': 'postalcode' },
{ 'name': 'country' }];
}
// export function
module.exports = sanitize;
module.exports = () => ({
sanitize: _sanitize,
expected: _expected
});

118
sanitizer/_targets.js

@ -5,70 +5,72 @@ function getValidKeys(mapping) {
return _.uniq(Object.keys(mapping)).join(',');
}
function setup( paramName, targetMap ) {
return function( raw, clean ){
return sanitize( raw, clean, {
paramName: paramName,
targetMap: targetMap,
targetMapKeysString: getValidKeys(targetMap)
});
function _setup( paramName, targetMap ) {
const opts = {
paramName: paramName,
targetMap: targetMap,
targetMapKeysString: getValidKeys(targetMap)
};
}
function sanitize( raw, clean, opts ) {
// error & warning messages
var messages = { errors: [], warnings: [] };
// the string of targets (comma delimeted)
var targetsString = raw[opts.paramName];
// trim whitespace
if( check.nonEmptyString( targetsString ) ){
targetsString = targetsString.trim();
// param must be a valid non-empty string
if( !check.nonEmptyString( 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
);
});
return {
sanitize: function _sanitize( raw, clean ) {
// error & warning messages
var messages = { errors: [], warnings: [] };
// the string of targets (comma delimeted)
var targetsString = raw[opts.paramName];
// trim whitespace
if( check.nonEmptyString( targetsString ) ){
targetsString = targetsString.trim();
// param must be a valid non-empty string
if( !check.nonEmptyString( 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
});
// only set types value when no error occured
if( !messages.errors.length ){
clean[opts.paramName] = targets.reduce(function(acc, target) {
return acc.concat(opts.targetMap[target]);
}, []);
// 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
);
});
// dedupe in case aliases expanded to common things or user typed in duplicates
clean[opts.paramName] = _.uniq(clean[opts.paramName]);
// only set types value when no error occured
if( !messages.errors.length ){
clean[opts.paramName] = 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[opts.paramName] = _.uniq(clean[opts.paramName]);
}
}
}
}
}
// string is empty
else if( check.string( targetsString ) ){
messages.errors.push(
opts.paramName + ' parameter cannot be an empty string. Valid options: ' + opts.targetMapKeysString
);
}
// 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;
}
return messages;
} // end of _sanitize function
}; // end of object to be returned
} // end of _setup function
module.exports = setup;
module.exports = _setup;

11
sanitizer/_text.js

@ -2,7 +2,8 @@ const check = require('check-types');
const _ = require('lodash');
// validate texts, convert types and apply defaults
function sanitize( raw, clean ){
function _sanitize( raw, clean ){
// error & warning messages
const messages = { errors: [], warnings: [] };
@ -20,5 +21,11 @@ function sanitize( raw, clean ){
return messages;
}
function _expected(){
return [{ name: 'text' }];
}
// export function
module.exports = sanitize;
module.exports = () => ({
sanitize: _sanitize,
expected: _expected
});

13
sanitizer/_text_addressit.js

@ -5,7 +5,7 @@ var _ = require('lodash');
var logger = require('pelias-logger').get('api');
// validate texts, convert types and apply defaults
function sanitize( raw, clean ){
function _sanitize( raw, clean ){
// error & warning messages
var messages = { errors: [], warnings: [] };
@ -35,10 +35,15 @@ function sanitize( raw, clean ){
return messages;
}
// export function
module.exports = sanitize;
function _expected(){
return [{ name: 'text' }];
}
// export function
module.exports = () => ({
sanitize: _sanitize,
expected: _expected
});
// this is the addressit functionality from https://github.com/pelias/text-analyzer/blob/master/src/addressItParser.js
var DELIM = ',';

6
sanitizer/_tokenizer.js

@ -14,7 +14,7 @@ var check = require('check-types');
note: this sanitizer should run *after* the '_text' sanitizer so it can
use the output of clean.parsed_text where available.
**/
function sanitize( raw, clean ){
function _sanitize( raw, clean ){
// error & warning messages
var messages = { errors: [], warnings: [] };
@ -103,4 +103,6 @@ function sanitize( raw, clean ){
}
// export function
module.exports = sanitize;
module.exports = () => ({
sanitize: _sanitize
});

25
sanitizer/autocomplete.js

@ -4,30 +4,23 @@ var sanitizeAll = require('../sanitizer/sanitizeAll');
// middleware
module.exports.middleware = (_api_pelias_config) => {
var sanitizers = {
singleScalarParameters: require('../sanitizer/_single_scalar_parameters'),
text: require('../sanitizer/_text_addressit'),
tokenizer: require('../sanitizer/_tokenizer'),
singleScalarParameters: require('../sanitizer/_single_scalar_parameters')(),
text: require('../sanitizer/_text_addressit')(),
tokenizer: require('../sanitizer/_tokenizer')(),
size: require('../sanitizer/_size')(10, 10, 10),
layers: require('../sanitizer/_targets')('layers', type_mapping.layer_mapping),
sources: require('../sanitizer/_targets')('sources', type_mapping.source_mapping),
// depends on the layers and sources sanitizers, must be run after them
sources_and_layers: require('../sanitizer/_sources_and_layers'),
sources_and_layers: require('../sanitizer/_sources_and_layers')(),
private: require('../sanitizer/_flag_bool')('private', false),
location_bias: require('../sanitizer/_location_bias')(_api_pelias_config.defaultParameters),
geo_autocomplete: require('../sanitizer/_geo_autocomplete'),
boundary_country: require('../sanitizer/_boundary_country'),
categories: require('../sanitizer/_categories')
geo_autocomplete: require('../sanitizer/_geo_autocomplete')(),
boundary_country: require('../sanitizer/_boundary_country')(),
categories: require('../sanitizer/_categories')()
};
var sanitize = function(req, cb) { sanitizeAll(req, sanitizers, cb); };
return function( req, res, next ){
sanitize( req, function( err, clean ){
if( err ){
res.status(400); // 400 Bad Request
return next(err);
}
return ( req, res, next ) => {
sanitizeAll.runAllChecks(req, sanitizers);
next();
});
};
};

8
sanitizer/defer_to_addressit.js

@ -1,9 +1,8 @@
const sanitizeAll = require('../sanitizer/sanitizeAll'),
sanitizers = {
text: require('../sanitizer/_text_addressit')
text: require('../sanitizer/_text_addressit')()
};
const sanitize = function(req, cb) { sanitizeAll(req, sanitizers, cb); };
const logger = require('pelias-logger').get('api');
const logging = require( '../helper/logging' );
@ -23,9 +22,8 @@ module.exports = (should_execute) => {
logger.info(`fallback queryText: ${queryText}`);
}
sanitize( req, function( err, clean ){
next();
});
sanitizeAll.sanitize(req, sanitizers);
next();
};

31
sanitizer/nearby.js

@ -1,21 +1,24 @@
var _ = require('lodash');
var sanitizeAll = require('../sanitizer/sanitizeAll');
var reverseSanitizers = require('./reverse').sanitizer_list;
var type_mapping = require('../helper/type_mapping');
// add categories to the sanitizer list
var sanitizers = _.merge({}, reverseSanitizers, {
categories: require('../sanitizer/_categories')
});
var sanitize = function(req, cb) { sanitizeAll(req, sanitizers, cb); };
// export sanitize for testing
module.exports.sanitize = sanitize;
module.exports.sanitizer_list = sanitizers;
var sanitizers = {
singleScalarParameters: require('../sanitizer/_single_scalar_parameters')(),
quattroshapes_deprecation: require('../sanitizer/_deprecate_quattroshapes')(),
layers: require('../sanitizer/_targets')('layers', type_mapping.layer_mapping),
sources: require('../sanitizer/_targets')('sources', type_mapping.source_mapping),
// depends on the layers and sources sanitizers, must be run after them
sources_and_layers: require('../sanitizer/_sources_and_layers')(),
geonames_deprecation: require('../sanitizer/_geonames_deprecation')(),
size: require('../sanitizer/_size')(/* use defaults*/),
private: require('../sanitizer/_flag_bool')('private', false),
geo_reverse: require('../sanitizer/_geo_reverse')(),
boundary_country: require('../sanitizer/_boundary_country')(),
categories: require('../sanitizer/_categories')()
};
// middleware
module.exports.middleware = function( req, res, next ){
sanitize( req, function( err, clean ){
next();
});
sanitizeAll.runAllChecks(req, sanitizers);
next();
};

17
sanitizer/place.js

@ -1,20 +1,13 @@
var sanitizeAll = require('../sanitizer/sanitizeAll'),
sanitizers = {
singleScalarParameters: require('../sanitizer/_single_scalar_parameters'),
ids: require('../sanitizer/_ids'),
singleScalarParameters: require('../sanitizer/_single_scalar_parameters')(),
ids: require('../sanitizer/_ids')(),
private: require('../sanitizer/_flag_bool')('private', false)
};
var sanitize = function(req, cb) { sanitizeAll(req, sanitizers, cb); };
// export sanitize for testing
module.exports.sanitize = sanitize;
module.exports.sanitizer_list = sanitizers;
// middleware
module.exports.middleware = function( req, res, next ){
sanitize( req, function( err, clean ){
next();
});
module.exports.middleware = function(req, res, next){
sanitizeAll.runAllChecks(req, sanitizers);
next();
};

23
sanitizer/reverse.js

@ -2,28 +2,21 @@
var type_mapping = require('../helper/type_mapping');
var sanitizeAll = require('../sanitizer/sanitizeAll'),
sanitizers = {
singleScalarParameters: require('../sanitizer/_single_scalar_parameters'),
quattroshapes_deprecation: require('../sanitizer/_deprecate_quattroshapes'),
singleScalarParameters: require('../sanitizer/_single_scalar_parameters')(),
quattroshapes_deprecation: require('../sanitizer/_deprecate_quattroshapes')(),
layers: require('../sanitizer/_targets')('layers', type_mapping.layer_mapping),
sources: require('../sanitizer/_targets')('sources', type_mapping.source_mapping),
// depends on the layers and sources sanitizers, must be run after them
sources_and_layers: require('../sanitizer/_sources_and_layers'),
geonames_deprecation: require('../sanitizer/_geonames_deprecation'),
sources_and_layers: require('../sanitizer/_sources_and_layers')(),
geonames_deprecation: require('../sanitizer/_geonames_deprecation')(),
size: require('../sanitizer/_size')(/* use defaults*/),
private: require('../sanitizer/_flag_bool')('private', false),
geo_reverse: require('../sanitizer/_geo_reverse'),
boundary_country: require('../sanitizer/_boundary_country')
geo_reverse: require('../sanitizer/_geo_reverse')(),
boundary_country: require('../sanitizer/_boundary_country')()
};
var sanitize = function(req, cb) { sanitizeAll(req, sanitizers, cb); };
// export sanitize for testing
module.exports.sanitize = sanitize;
module.exports.sanitizer_list = sanitizers;
// middleware
module.exports.middleware = function( req, res, next ){
sanitize( req, function( err, clean ){
next();
});
sanitizeAll.runAllChecks(req, sanitizers);
next();
};

56
sanitizer/sanitizeAll.js

@ -1,4 +1,5 @@
function sanitize( req, sanitizers, cb ){
'use strict';
function sanitize( req, sanitizers ){
// init an object to store clean (sanitized) input parameters if not initialized
req.clean = req.clean || {};
@ -8,10 +9,10 @@ function sanitize( req, sanitizers, cb ){
// source of input parameters
// (in this case from the GET querystring params)
var params = req.query || {};
const params = req.query || {};
for (var s in sanitizers) {
var sanity = sanitizers[s]( params, req.clean );
for (let s in sanitizers) {
var sanity = sanitizers[s].sanitize( params, req.clean );
// if errors occurred then set them
// on the req object.
@ -25,10 +26,51 @@ function sanitize( req, sanitizers, cb ){
req.warnings = req.warnings.concat( sanity.warnings );
}
}
}
// Adds to goodParameters every acceptable parameter passed through API call
function checkParameters( req, sanitizers ) {
req.warnings = req.warnings || [];
// source of input parameters
// (in this case from the GET querystring params)
const params = req.query || {};
const goodParameters = {};
for (let s in sanitizers) {
// checks if function exists
if (typeof sanitizers[s].expected === 'function'){
/** expected() returns {array} ex: [{ name: 'text' }] */
for (let t in sanitizers[s].expected()) {
/** {object} prop */
const prop = sanitizers[s].expected()[t];
if (prop.hasOwnProperty('name')){
// adds name of valid parameter
goodParameters[prop.name] = prop.name;
}
}
}
}
// If there are any unexpected parameters & goodParameters isn't empty,
// add a warning message
if (Object.keys(goodParameters).length !== 0) {
for (let p in params) {
if (!goodParameters.hasOwnProperty(p)){
req.warnings = req.warnings.concat('Invalid Parameter: ' + p);
}
}
}
}
// @todo remove these args, they do not need to be passed out
return cb( undefined, req.clean );
// runs both sanitize and checkParameters functions in async parallel
function runAllChecks (req, sanitizers) {
sanitize(req, sanitizers);
checkParameters(req, sanitizers);
}
// export function
module.exports = sanitize;
module.exports = {
sanitize: sanitize,
checkParameters: checkParameters,
runAllChecks: runAllChecks
};

25
sanitizer/search.js

@ -3,29 +3,26 @@ var sanitizeAll = require('../sanitizer/sanitizeAll');
// middleware
module.exports.middleware = (_api_pelias_config) => {
var sanitizers = {
singleScalarParameters: require('../sanitizer/_single_scalar_parameters'),
quattroshapes_deprecation: require('../sanitizer/_deprecate_quattroshapes'),
text: require('../sanitizer/_text'),
singleScalarParameters: require('../sanitizer/_single_scalar_parameters')(),
quattroshapes_deprecation: require('../sanitizer/_deprecate_quattroshapes')(),
text: require('../sanitizer/_text')(),
size: require('../sanitizer/_size')(/* use defaults*/),
layers: require('../sanitizer/_targets')('layers', type_mapping.layer_mapping),
sources: require('../sanitizer/_targets')('sources', type_mapping.source_mapping),
// depends on the layers and sources sanitizers, must be run after them
sources_and_layers: require('../sanitizer/_sources_and_layers'),
sources_and_layers: require('../sanitizer/_sources_and_layers')(),
private: require('../sanitizer/_flag_bool')('private', false),
location_bias: require('../sanitizer/_location_bias')(_api_pelias_config.defaultParameters),
geo_search: require('../sanitizer/_geo_search'),
boundary_country: require('../sanitizer/_boundary_country'),
categories: require('../sanitizer/_categories'),
geo_search: require('../sanitizer/_geo_search')(),
boundary_country: require('../sanitizer/_boundary_country')(),
categories: require('../sanitizer/_categories')(),
// this can go away once geonames has been abrogated
geonames_warnings: require('../sanitizer/_geonames_warnings')
geonames_warnings: require('../sanitizer/_geonames_warnings')()
};
var sanitize = function(req, cb) { sanitizeAll(req, sanitizers, cb); };
return function( req, res, next ){
sanitize( req, function( err, clean ){
next();
});
return ( req, res, next ) => {
sanitizeAll.runAllChecks(req, sanitizers);
next();
};
};

29
sanitizer/search_fallback.js

@ -0,0 +1,29 @@
var sanitizeAll = require('../sanitizer/sanitizeAll'),
sanitizers = {
text: require('../sanitizer/_text_addressit')()
};
var logger = require('pelias-logger').get('api');
var logging = require( '../helper/logging' );
var _ = require('lodash');
// middleware
module.exports.middleware = function( req, res, next ){
// if res.data already has results then don't call the _text_autocomplete sanitizer
// this has been put into place for when the libpostal integration way of querying
// ES doesn't return anything and we want to fallback to the old logic
if (_.get(res, 'data', []).length > 0) {
return next();
}
// log the query that caused a fallback since libpostal+new-queries didn't return anything
if (req.path === '/v1/search') {
const queryText = logging.isDNT(req) ? '[text removed]' : req.clean.text;
logger.info(`fallback queryText: ${queryText}`);
}
// calls to sanitize the input
// omits check if parameters are valid since it only calls _text_addressit
sanitizeAll.sanitize(req, sanitizers);
next();
};

28
sanitizer/structured_geocoding.js

@ -4,27 +4,27 @@ var sanitizeAll = require('../sanitizer/sanitizeAll');
// middleware
module.exports.middleware = (_api_pelias_config) => {
var sanitizers = {
singleScalarParameters: require('../sanitizer/_single_scalar_parameters'),
quattroshapes_deprecation: require('../sanitizer/_deprecate_quattroshapes'),
synthesize_analysis: require('../sanitizer/_synthesize_analysis'),
iso2_to_iso3: require('../sanitizer/_iso2_to_iso3'),
city_name_standardizer: require('../sanitizer/_city_name_standardizer'),
singleScalarParameters: require('../sanitizer/_single_scalar_parameters')(),
quattroshapes_deprecation: require('../sanitizer/_deprecate_quattroshapes')(),
synthesize_analysis: require('../sanitizer/_synthesize_analysis')(),
iso2_to_iso3: require('../sanitizer/_iso2_to_iso3')(),
city_name_standardizer: require('../sanitizer/_city_name_standardizer')(),
size: require('../sanitizer/_size')(/* use defaults*/),
layers: require('../sanitizer/_targets')('layers', type_mapping.layer_mapping),
sources: require('../sanitizer/_targets')('sources', type_mapping.source_mapping),
// depends on the layers and sources sanitizers, must be run after them
sources_and_layers: require('../sanitizer/_sources_and_layers'),
sources_and_layers: require('../sanitizer/_sources_and_layers')(),
private: require('../sanitizer/_flag_bool')('private', false),
location_bias: require('../sanitizer/_location_bias')(_api_pelias_config.defaultParameters),
geo_search: require('../sanitizer/_geo_search'),
boundary_country: require('../sanitizer/_boundary_country'),
categories: require('../sanitizer/_categories')
geo_search: require('../sanitizer/_geo_search')(),
boundary_country: require('../sanitizer/_boundary_country')(),
categories: require('../sanitizer/_categories')()
};
var sanitize = function(req, cb) { sanitizeAll(req, sanitizers, cb); };
return function( req, res, next ){
sanitize( req, function( err, clean ){
next();
});
return ( req, res, next ) => {
sanitizeAll.runAllChecks(req, sanitizers);
next();
};
};

25
test/unit/sanitizer/_boundary_country.js

@ -1,4 +1,4 @@
var sanitize = require('../../../sanitizer/_boundary_country');
var sanitizer = require('../../../sanitizer/_boundary_country')();
module.exports.tests = {};
@ -6,7 +6,7 @@ module.exports.tests.sanitize_boundary_country = function(test, common) {
test('raw w/o boundary should set boundary.country undefined', function(t) {
var raw = { };
var clean = {};
var errorsAndWarnings = sanitize(raw, clean);
var errorsAndWarnings = sanitizer.sanitize(raw, clean);
t.equals(clean['boundary.country'], undefined, 'should be undefined');
t.deepEquals(errorsAndWarnings, { errors: [], warnings: [] }, 'no warnings or errors');
t.end();
@ -15,7 +15,7 @@ module.exports.tests.sanitize_boundary_country = function(test, common) {
test('boundary.country explicitly undefined in raw should leave boundary.country undefined', function(t) {
var raw = { 'boundary.country': undefined };
var clean = {};
var errorsAndWarnings = sanitize(raw, clean);
var errorsAndWarnings = sanitizer.sanitize(raw, clean);
t.equals(clean['boundary.country'], undefined, 'should be undefined');
t.deepEquals(errorsAndWarnings, { errors: [], warnings: [] }, 'no warnings or errors');
t.end();
@ -24,7 +24,7 @@ module.exports.tests.sanitize_boundary_country = function(test, common) {
test('non-string boundary.country should set boundary.country to undefined and return warning', function(t) {
var raw = { 'boundary.country': ['this isn\'t a string primitive'] };
var clean = {};
var errorsAndWarnings = sanitize(raw, clean);
var errorsAndWarnings = sanitizer.sanitize(raw, clean);
t.equals(clean['boundary.country'], undefined, 'should be undefined');
t.deepEquals(errorsAndWarnings, { errors: ['boundary.country is not a string'], warnings: [] }, 'non-string country warning');
t.end();
@ -33,7 +33,7 @@ module.exports.tests.sanitize_boundary_country = function(test, common) {
test('iso2 boundary.country in raw should set boundary.country to ISO3 uppercased', function(t) {
var raw = { 'boundary.country': 'aq' };
var clean = {};
var errorsAndWarnings = sanitize(raw, clean);
var errorsAndWarnings = sanitizer.sanitize(raw, clean);
t.equals(clean['boundary.country'], 'ATA', 'should be uppercased ISO3');
t.deepEquals(errorsAndWarnings, { errors: [], warnings: [] }, 'no warnings or errors');
t.end();
@ -42,7 +42,7 @@ module.exports.tests.sanitize_boundary_country = function(test, common) {
test('iso3 boundary.country in raw should set boundary.country to matching ISO3 uppercased', function(t) {
var raw = { 'boundary.country': 'aTa' };
var clean = {};
var errorsAndWarnings = sanitize(raw, clean);
var errorsAndWarnings = sanitizer.sanitize(raw, clean);
t.equals(clean['boundary.country'], 'ATA', 'should be uppercased ISO3');
t.deepEquals(errorsAndWarnings, { errors: [], warnings: [] }, 'no warnings or errors');
t.end();
@ -51,7 +51,7 @@ module.exports.tests.sanitize_boundary_country = function(test, common) {
test('unknown 2-character boundary.country should set boundary.country to undefined', function(t) {
var raw = { 'boundary.country': 'zq' };
var clean = {};
var errorsAndWarnings = sanitize(raw, clean);
var errorsAndWarnings = sanitizer.sanitize(raw, clean);
t.equals(clean['boundary.country'], undefined, 'should be undefined');
t.deepEquals(errorsAndWarnings, { errors: ['zq is not a valid ISO2/ISO3 country code'], warnings: [] }, 'country not found warning`');
t.end();
@ -60,17 +60,24 @@ module.exports.tests.sanitize_boundary_country = function(test, common) {
test('unknown 3-character boundary.country should set boundary.country to undefined', function(t) {
var raw = { 'boundary.country': 'zqx' };
var clean = {};
var errorsAndWarnings = sanitize(raw, clean);
var errorsAndWarnings = sanitizer.sanitize(raw, clean);
t.equals(clean['boundary.country'], undefined, 'should be undefined');
t.deepEquals(errorsAndWarnings, { errors: ['zqx is not a valid ISO2/ISO3 country code'], warnings: [] }, 'country not found warning`');
t.end();
});
test('return an array of expected parameters in object form for validation', (t) => {
const expected = [{ name: 'boundary.country' }];
const validParameters = sanitizer.expected();
t.deepEquals(validParameters, expected);
t.end();
});
};
module.exports.all = function (tape, common) {
function test(name, testFunction) {
return tape('SANTIZE _boundary_country ' + name, testFunction);
return tape('SANITIZE _boundary_country ' + name, testFunction);
}
for( var testCase in module.exports.tests ){

27
test/unit/sanitizer/_categories.js

@ -1,4 +1,4 @@
var sanitize = require( '../../../sanitizer/_categories');
var sanitizer = require( '../../../sanitizer/_categories')();
module.exports.tests = {};
@ -9,7 +9,7 @@ module.exports.tests.no_categories = function(test, common) {
clean: { }
};
var messages = sanitize(req.query, req.clean);
var messages = sanitizer.sanitize(req.query, req.clean);
t.equal(req.clean.categories, undefined, 'no categories should be defined');
t.deepEqual(messages.errors, [], 'no error returned');
@ -27,7 +27,7 @@ module.exports.tests.no_categories = function(test, common) {
var expected_error = 'Categories parameter cannot be left blank. See documentation of service for valid options.';
var messages = sanitize(req.query, req.clean);
var messages = sanitizer.sanitize(req.query, req.clean);
t.equal(req.clean.categories, undefined, 'no categories should be defined');
t.deepEqual(messages.errors.length, 1, 'error returned');
@ -46,7 +46,7 @@ module.exports.tests.no_categories = function(test, common) {
var expected_error = 'Invalid categories parameter value(s). See documentation of service for valid options.';
var messages = sanitize(req.query, req.clean);
var messages = sanitizer.sanitize(req.query, req.clean);
t.equal(req.clean.categories, undefined, 'no categories should be defined');
t.deepEqual(messages.errors.length, 1, 'error returned');
@ -74,7 +74,7 @@ module.exports.tests.valid_categories = function(test, common) {
clean: { }
};
var messages = sanitize(req.query, req.clean, validCategories);
var messages = sanitizer.sanitize(req.query, req.clean, validCategories);
t.deepEqual(req.clean.categories, ['food'], 'categories should contain food');
t.deepEqual(messages.errors, [], 'no error returned');
@ -95,7 +95,7 @@ module.exports.tests.valid_categories = function(test, common) {
};
var expectedCategories = ['food', 'health'];
var messages = sanitize(req.query, req.clean, validCategories);
var messages = sanitizer.sanitize(req.query, req.clean, validCategories);
t.deepEqual(req.clean.categories, expectedCategories,
'clean.categories should be an array with proper values');
@ -130,7 +130,7 @@ module.exports.tests.invalid_categories = function(test, common) {
warnings: []
};
var messages = sanitize(req.query, req.clean, validCategories);
var messages = sanitizer.sanitize(req.query, req.clean, validCategories);
t.deepEqual(messages, expected_messages, 'error with message returned');
t.equal(req.clean.categories, undefined, 'clean.categories should remain empty');
@ -151,17 +151,26 @@ module.exports.tests.invalid_categories = function(test, common) {
warnings: []
};
var messages = sanitize(req.query, req.clean, validCategories);
var messages = sanitizer.sanitize(req.query, req.clean, validCategories);
t.deepEqual(messages, expected_messages, 'error with message returned');
t.equal(req.clean.categories, undefined, 'clean.categories should remain empty');
t.end();
});
test('return an array of expected parameters in object form for validation', (t) => {
const expected = [{ name: 'categories' }];
const validParameters = sanitizer.expected();
t.deepEquals(validParameters, expected);
t.end();
});
};
module.exports.all = function (tape, common) {
function test(name, testFunction) {
return tape('SANTIZE _categories ' + name, testFunction);
return tape('SANITIZE _categories ' + name, testFunction);
}
for( var testCase in module.exports.tests ){

20
test/unit/sanitizer/_city_name_standardizer.js

@ -1,5 +1,5 @@
const _ = require('lodash');
const sanitizer = require('../../../sanitizer/_city_name_standardizer');
const sanitizer = require('../../../sanitizer/_city_name_standardizer')();
module.exports.tests = {};
@ -13,7 +13,7 @@ module.exports.tests.text_parser = function(test, common) {
const expected_clean = {
};
const messages = sanitizer(raw, clean);
const messages = sanitizer.sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');
@ -39,7 +39,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
const messages = sanitizer(raw, clean);
const messages = sanitizer.sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');
@ -77,7 +77,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
const messages = sanitizer(raw, clean);
const messages = sanitizer.sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');
@ -115,7 +115,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
const messages = sanitizer(raw, clean);
const messages = sanitizer.sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');
@ -153,7 +153,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
const messages = sanitizer(raw, clean);
const messages = sanitizer.sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');
@ -191,7 +191,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
const messages = sanitizer(raw, clean);
const messages = sanitizer.sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');
@ -215,7 +215,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
const messages = sanitizer(raw, clean);
const messages = sanitizer.sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');
@ -239,7 +239,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
const messages = sanitizer(raw, clean);
const messages = sanitizer.sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');
@ -263,7 +263,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
const messages = sanitizer(raw, clean);
const messages = sanitizer.sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');

10
test/unit/sanitizer/_deprecate_quattroshapes.js

@ -1,4 +1,4 @@
var sanitize = require('../../../sanitizer/_deprecate_quattroshapes');
var sanitizer = require('../../../sanitizer/_deprecate_quattroshapes')();
module.exports.tests = {};
@ -7,7 +7,7 @@ module.exports.tests.warning_message_1 = function(test, common) {
var raw = { sources: 'qs' };
var clean = {};
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.deepEquals(messages, {
errors: [],
warnings: ['You are using Quattroshapes as a data source in this query. ' +
@ -27,7 +27,7 @@ module.exports.tests.warning_message_2 = function(test, common) {
var raw = { sources: 'quattroshapes' };
var clean = {};
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.deepEquals(messages, {
errors: [],
warnings: ['You are using Quattroshapes as a data source in this query. ' +
@ -47,7 +47,7 @@ module.exports.tests.rewrite = function(test, common) {
var raw = { sources: 'qs,quattroshapes,qs,quattroshapes,osm' };
var clean = {};
sanitize(raw, clean);
sanitizer.sanitize(raw, clean);
t.equals(raw.sources,'osm,whosonfirst','use wof instead of qs');
t.end();
@ -56,7 +56,7 @@ module.exports.tests.rewrite = function(test, common) {
module.exports.all = function (tape, common) {
function test(name, testFunction) {
return tape('SANTIZE _deprecate_quattroshapes ' + name, testFunction);
return tape('SANITIZE _deprecate_quattroshapes ' + name, testFunction);
}
for( var testCase in module.exports.tests ){

20
test/unit/sanitizer/_flag_bool.js

@ -1,5 +1,4 @@
var sanitizer = require('../../../sanitizer/_flag_bool');
var sanitize = sanitizer('dirty_param', true);
module.exports.tests = {};
@ -9,7 +8,7 @@ module.exports.tests.sanitize_private = function(test, common) {
test('invalid dirty_param ' + value, function (t) {
var raw = {dirty_param: value};
var clean = {};
sanitize(raw, clean);
sanitizer('dirty_param', true).sanitize(raw, clean);
t.equal(clean.dirty_param, false, 'default clean value set (to false)');
t.end();
});
@ -20,7 +19,7 @@ module.exports.tests.sanitize_private = function(test, common) {
test('valid dirty_param ' + value, function (t) {
var raw = {dirty_param: value};
var clean = {};
sanitize(raw, clean);
sanitizer('dirty_param', true).sanitize(raw, clean);
t.equal(clean.dirty_param, true, 'clean value set to true');
t.end();
});
@ -31,7 +30,7 @@ module.exports.tests.sanitize_private = function(test, common) {
test('test setting false explicitly ' + value, function (t) {
var raw = {dirty_param: value};
var clean = {};
sanitize(raw, clean);
sanitizer('dirty_param', true).sanitize(raw, clean);
t.equal(clean.dirty_param, false, 'clean value set to false');
t.end();
});
@ -45,17 +44,26 @@ module.exports.tests.validate_default_behavior = function(test, common) {
var sanitize_true = sanitizer('foo_bar', defaultValue);
var raw = {};
var clean = {};
sanitize_true(raw, clean);
sanitize_true.sanitize(raw, clean);
t.equal(clean.foo_bar, defaultValue, 'foo_bar set to ' + defaultValue);
t.end();
});
});
};
module.exports.tests.check_valid_parameters = function(test, common) {
test('return an array of expected parameters in object form for validation', (t) => {
const expected = [{ name: 'value' }]; // depends on first argument of sanitizer()
const validParameters = sanitizer('value', true).expected();
t.deepEquals(validParameters, expected);
t.end();
});
};
module.exports.all = function (tape, common) {
function test(name, testFunction) {
return tape('SANTIZE _flag_bool: ' + name, testFunction);
return tape('SANITIZE _flag_bool: ' + name, testFunction);
}
for( var testCase in module.exports.tests ){

10
test/unit/sanitizer/_geo_reverse.js

@ -1,6 +1,6 @@
'use strict';
const sanitize = require('../../../sanitizer/_geo_reverse');
const sanitizer = require('../../../sanitizer/_geo_reverse')();
const defaults = require('../../../query/reverse_defaults');
module.exports.tests = {};
@ -13,7 +13,7 @@ module.exports.tests.warning_situations = (test, common) => {
'boundary.circle.lat': '13.131313'
};
const clean = {};
const errorsAndWarnings = sanitize(raw, clean);
const errorsAndWarnings = sanitizer.sanitize(raw, clean);
t.equals(clean['boundary.circle.lat'], 12.121212, 'should be set to point.lat');
t.deepEquals(errorsAndWarnings, {
@ -31,7 +31,7 @@ module.exports.tests.warning_situations = (test, common) => {
'boundary.circle.lon': '31.313131'
};
const clean = {};
const errorsAndWarnings = sanitize(raw, clean);
const errorsAndWarnings = sanitizer.sanitize(raw, clean);
t.equals(clean['boundary.circle.lon'], 21.212121, 'should be set to point.lon');
t.deepEquals(errorsAndWarnings, {
@ -49,7 +49,7 @@ module.exports.tests.warning_situations = (test, common) => {
'boundary.circle.radius': '17'
};
const clean = {};
const errorsAndWarnings = sanitize(raw, clean);
const errorsAndWarnings = sanitizer.sanitize(raw, clean);
// t.equals(clean['boundary.circle.radius'], 12.121212, 'should be set to point.lat')
t.deepEquals(errorsAndWarnings, {
@ -70,7 +70,7 @@ module.exports.tests.success_conditions = (test, common) => {
'boundary.circle.radius': '3248732857km' // this will never be the default
};
const clean = {};
const errorsAndWarnings = sanitize(raw, clean);
const errorsAndWarnings = sanitizer.sanitize(raw, clean);
t.equals(raw['boundary.circle.lat'], 12.121212);
t.equals(raw['boundary.circle.lon'], 21.212121);

12
test/unit/sanitizer/_geonames_deprecation.js

@ -1,4 +1,4 @@
const geonames_deprecation = require('../../../sanitizer/_geonames_deprecation');
const sanitizer = require('../../../sanitizer/_geonames_deprecation')();
module.exports.tests = {};
@ -6,7 +6,7 @@ module.exports.tests.no_warnings_or_errors_conditions = (test, common) => {
test('undefined sources should add neither warnings nor errors', (t) => {
const clean = {};
const messages = geonames_deprecation(undefined, clean);
const messages = sanitizer.sanitize(undefined, clean);
t.deepEquals(clean, {});
t.deepEquals(messages, { errors: [], warnings: [] });
@ -19,7 +19,7 @@ module.exports.tests.no_warnings_or_errors_conditions = (test, common) => {
sources: ['source 1', 'source 2'],
};
const messages = geonames_deprecation(undefined, clean);
const messages = sanitizer.sanitize(undefined, clean);
t.deepEquals(clean.sources, ['source 1', 'source 2']);
t.deepEquals(messages, { errors: [], warnings: [] });
@ -36,7 +36,7 @@ module.exports.tests.error_conditions = (test, common) => {
sources: [sources]
};
const messages = geonames_deprecation(undefined, clean);
const messages = sanitizer.sanitize(undefined, clean);
t.deepEquals(clean.sources, [sources]);
t.deepEquals(messages.errors, ['/reverse does not support geonames']);
@ -57,7 +57,7 @@ module.exports.tests.warning_conditions = (test, common) => {
sources: ['another source', sources, 'yet another source']
};
const messages = geonames_deprecation(undefined, clean);
const messages = sanitizer.sanitize(undefined, clean);
t.deepEquals(clean.sources, ['another source', 'yet another source']);
t.deepEquals(messages.errors, []);
@ -73,7 +73,7 @@ module.exports.tests.warning_conditions = (test, common) => {
module.exports.all = (tape, common) => {
function test(name, testFunction) {
return tape(`SANTIZE _geonames_deprecation ${name}`, testFunction);
return tape(`SANITIZE _geonames_deprecation ${name}`, testFunction);
}
for( var testCase in module.exports.tests ){

12
test/unit/sanitizer/_geonames_warnings.js

@ -1,6 +1,6 @@
const _ = require('lodash');
const geonames_warnings = require('../../../sanitizer/_geonames_warnings');
const sanitizer = require('../../../sanitizer/_geonames_warnings')();
const nonAdminProperties = ['number', 'street', 'query', 'category'];
const adminProperties = ['neighbourhood', 'borough', 'city', 'county', 'state', 'postalcode', 'country'];
@ -13,7 +13,7 @@ module.exports.tests.no_errors = (test, common) => {
sources: ['geonames'],
};
const messages = geonames_warnings(undefined, clean);
const messages = sanitizer.sanitize(undefined, clean);
t.deepEquals(messages, { errors: [], warnings: [] });
t.end();
@ -30,7 +30,7 @@ module.exports.tests.no_errors = (test, common) => {
clean.parsed_text[nonAdminProperty] = `${nonAdminProperty} value`;
clean.parsed_text[adminProperty] = `${adminProperty} value`;
const messages = geonames_warnings(undefined, clean);
const messages = sanitizer.sanitize(undefined, clean);
t.deepEquals(messages, { errors: [], warnings: [] });
@ -50,7 +50,7 @@ module.exports.tests.no_errors = (test, common) => {
clean.parsed_text[nonAdminProperty] = `${nonAdminProperty} value`;
clean.parsed_text[adminProperty] = `${adminProperty} value`;
const messages = geonames_warnings(undefined, clean);
const messages = sanitizer.sanitize(undefined, clean);
t.deepEquals(messages, { errors: [], warnings: [] });
@ -68,7 +68,7 @@ module.exports.tests.error_conditions = (test, common) => {
const clean = _.set({ sources: ['geonames'] },
['parsed_text', property], `${property} value`);
const messages = geonames_warnings(undefined, clean);
const messages = sanitizer.sanitize(undefined, clean);
t.deepEquals(messages.errors, ['input contains only administrative area data, ' +
'no results will be returned when sources=geonames']);
@ -87,7 +87,7 @@ module.exports.tests.warning_conditions = (test, common) => {
const clean = _.set({ sources: ['source 1', 'geonames', 'source 2'] },
['parsed_text', property], `${property} value`);
const messages = geonames_warnings(undefined, clean);
const messages = sanitizer.sanitize(undefined, clean);
t.deepEquals(messages.errors, []);
t.deepEquals(messages.warnings, ['input contains only administrative area data, ' +

39
test/unit/sanitizer/_ids.js

@ -1,4 +1,4 @@
var sanitize = require('../../../sanitizer/_ids');
var sanitizer = require('../../../sanitizer/_ids')();
var delimiter = ':';
var type_mapping = require('../../../helper/type_mapping');
@ -15,7 +15,7 @@ module.exports.tests.invalid_ids = function(test, common) {
var raw = { ids: '' };
var clean = {};
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.equal(messages.errors[0], lengthError, 'ids length error returned');
t.equal(clean.ids, undefined, 'ids unset in clean object');
@ -26,7 +26,7 @@ module.exports.tests.invalid_ids = function(test, common) {
var raw = { ids: ':' };
var clean = {};
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.equal(messages.errors[0], formatError(':'), 'format error returned');
t.equal(clean.ids, undefined, 'ids unset in clean object');
@ -37,7 +37,7 @@ module.exports.tests.invalid_ids = function(test, common) {
var raw = { ids: '::' };
var clean = {};
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.equal(messages.errors[0], formatError('::'), 'format error returned');
t.equal(clean.ids, undefined, 'ids unset in clean object');
@ -48,7 +48,7 @@ module.exports.tests.invalid_ids = function(test, common) {
var raw = { ids: 'geoname:' };
var clean = {};
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.equal(messages.errors[0], formatError('geoname:'), 'format error returned');
t.equal(clean.ids, undefined, 'ids unset in clean object');
@ -59,7 +59,7 @@ module.exports.tests.invalid_ids = function(test, common) {
var raw = { ids: ':234' };
var clean = {};
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.equal(messages.errors[0], formatError(':234'), 'format error returned');
t.equal(clean.ids, undefined, 'ids unset in clean object');
@ -72,7 +72,7 @@ module.exports.tests.invalid_ids = function(test, common) {
var expected_error = 'invalidsource is invalid. It must be one of these values - [' +
Object.keys(type_mapping.source_mapping).join(', ') + ']';
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.equal(messages.errors[0], expected_error, 'format error returned');
t.equal(clean.ids, undefined, 'ids unset in clean object');
@ -83,7 +83,7 @@ module.exports.tests.invalid_ids = function(test, common) {
var raw = { ids: 'geonames:23' };
var clean = {};
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.equal(messages.errors[0], formatError('geonames:23'), 'format error returned');
t.equal(clean.ids, undefined, 'ids unset in clean object');
@ -96,7 +96,7 @@ module.exports.tests.valid_ids = function(test, common) {
var raw = { ids: 'openaddresses:address:20' };
var clean = {};
var messages = sanitize( raw, clean );
var messages = sanitizer.sanitize( raw, clean );
var expected_ids = [{
source: 'openaddresses',
@ -112,7 +112,7 @@ test('ids: valid short input (openaddresses)', function(t) {
var raw = { ids: 'oa:address:20' };
var clean = {};
var messages = sanitize( raw, clean );
var messages = sanitizer.sanitize( raw, clean );
var expected_ids = [{
source: 'openaddresses',
@ -133,7 +133,7 @@ test('ids: valid short input (openaddresses)', function(t) {
id: 'node:500',
}];
var messages = sanitize( raw, clean );
var messages = sanitizer.sanitize( raw, clean );
t.deepEqual( messages.errors, [], ' no errors');
t.deepEqual( clean.ids, expected_ids, 'osm has node: or way: in id field');
@ -149,7 +149,7 @@ test('ids: valid short input (openaddresses)', function(t) {
id: 'node:500',
}];
var messages = sanitize( raw, clean );
var messages = sanitizer.sanitize( raw, clean );
t.deepEqual( messages.errors, [], ' no errors');
t.deepEqual( clean.ids, expected_ids, 'osm has node: or way: in id field');
@ -162,7 +162,7 @@ module.exports.tests.multiple_ids = function(test, common) {
var raw = { ids: 'geonames:venue:1,openstreetmap:address:way:2' };
var clean = {};
var messages = sanitize( raw, clean);
var messages = sanitizer.sanitize( raw, clean);
var expected_ids = [ {
source: 'geonames',
@ -186,7 +186,7 @@ module.exports.tests.de_dupe = function(test, common) {
var raw = { ids: 'geonames:venue:1,openstreetmap:venue:node:2,geonames:venue:1' };
var clean = {};
var messages = sanitize( raw, clean );
var messages = sanitizer.sanitize( raw, clean );
var expected_ids = [ {
source: 'geonames',
@ -204,9 +204,18 @@ module.exports.tests.de_dupe = function(test, common) {
});
};
module.exports.tests.valid_Parameters = function(test, common) {
test('return an array of expected parameters in object form for validation', (t) => {
const expected = [{ name: 'ids' }];
const validParameters = sanitizer.expected();
t.deepEquals(validParameters, expected);
t.end();
});
};
module.exports.all = function (tape, common) {
function test(name, testFunction) {
return tape('SANTIZE _ids ' + name, testFunction);
return tape('SANITIZE _ids ' + name, testFunction);
}
for( var testCase in module.exports.tests ){

12
test/unit/sanitizer/_iso2_to_iso3.js

@ -1,4 +1,4 @@
const sanitizer = require('../../../sanitizer/_iso2_to_iso3');
const sanitizer = require('../../../sanitizer/_iso2_to_iso3')();
module.exports.tests = {};
@ -12,7 +12,7 @@ module.exports.tests.text_parser = function(test, common) {
const expected_clean = {
};
const messages = sanitizer(raw, clean);
const messages = sanitizer.sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');
@ -38,7 +38,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
const messages = sanitizer(raw, clean);
const messages = sanitizer.sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');
@ -64,7 +64,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
const messages = sanitizer(raw, clean);
const messages = sanitizer.sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');
@ -90,7 +90,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
const messages = sanitizer(raw, clean);
const messages = sanitizer.sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');
@ -103,7 +103,7 @@ module.exports.tests.text_parser = function(test, common) {
module.exports.all = function (tape, common) {
function test(name, testFunction) {
return tape('sanitizer _iso2_to_iso3: ' + name, testFunction);
return tape('SANITIZE _iso2_to_iso3: ' + name, testFunction);
}
for( const testCase in module.exports.tests ){

24
test/unit/sanitizer/_layers.js

@ -1,12 +1,12 @@
var type_mapping = require('../../../helper/type_mapping');
var sanitize = require('../../../sanitizer/_targets')('layers', type_mapping.layer_mapping);
var sanitizer = require('../../../sanitizer/_targets')('layers', type_mapping.layer_mapping);
module.exports.tests = {};
module.exports.tests.sanitize_layers = function(test, common) {
test('unspecified', function(t) {
var messages = sanitize({ layers: undefined }, {});
var messages = sanitizer.sanitize({ layers: undefined }, {});
t.equal(messages.errors.length, 0, 'no errors');
t.end();
});
@ -15,7 +15,7 @@ module.exports.tests.sanitize_layers = function(test, common) {
var raw = { layers: 'test_layer' };
var clean = {};
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
var msg = ' is an invalid layers parameter. Valid options: ';
t.equal(messages.errors.length, 1, 'errors set');
@ -28,7 +28,7 @@ module.exports.tests.sanitize_layers = function(test, common) {
var raw = { layers: 'venue' };
var clean = {};
sanitize(raw, clean);
sanitizer.sanitize(raw, clean);
var venue_layers = ['venue'];
t.deepEqual(clean.layers, venue_layers, 'venue layers set');
@ -39,7 +39,7 @@ module.exports.tests.sanitize_layers = function(test, common) {
var raw = { layers: 'coarse' };
var clean = {};
sanitize(raw, clean);
sanitizer.sanitize(raw, clean);
var admin_layers = [ 'continent', 'country', 'dependency',
'macroregion', 'region', 'locality', 'localadmin', 'macrocounty', 'county',
@ -53,7 +53,7 @@ module.exports.tests.sanitize_layers = function(test, common) {
var raw = { layers: 'address' };
var clean = {};
sanitize(raw, clean);
sanitizer.sanitize(raw, clean);
t.deepEqual(clean.layers, ['address'], 'address layer set');
t.end();
@ -63,7 +63,7 @@ module.exports.tests.sanitize_layers = function(test, common) {
var raw = { layers: 'venue,country,region' };
var clean = {};
sanitize(raw, clean);
sanitizer.sanitize(raw, clean);
var expected_layers = ['venue', 'country', 'region'];
t.deepEqual(clean.layers, expected_layers, 'venue + regular layers');
@ -74,7 +74,7 @@ module.exports.tests.sanitize_layers = function(test, common) {
var raw = { layers: 'coarse,country' };
var clean = {};
sanitize(raw, clean);
sanitizer.sanitize(raw, clean);
var expected_layers = [ 'continent', 'country', 'dependency',
'macroregion', 'region', 'locality', 'localadmin', 'macrocounty', 'county',
@ -88,7 +88,7 @@ module.exports.tests.sanitize_layers = function(test, common) {
var raw = { layers: 'address,country,locality' };
var clean = {};
sanitize(raw, clean);
sanitizer.sanitize(raw, clean);
var expected_layers = ['address', 'country', 'locality' ];
t.deepEqual(clean.layers, expected_layers, 'address + regular layers set');
@ -99,7 +99,7 @@ module.exports.tests.sanitize_layers = function(test, common) {
var raw = { layers: 'venue,country' };
var clean = {};
sanitize(raw, clean);
sanitizer.sanitize(raw, clean);
var expected_layers = ['venue', 'country'];
t.deepEqual(clean.layers, expected_layers, 'venue layers found (no duplicates)');
@ -110,7 +110,7 @@ module.exports.tests.sanitize_layers = function(test, common) {
var raw = { layers: 'venue,coarse' };
var clean = {};
sanitize(raw, clean);
sanitizer.sanitize(raw, clean);
var coarse_layers = [ 'continent',
'country', 'dependency', 'macroregion', 'region', 'locality', 'localadmin',
@ -126,7 +126,7 @@ module.exports.tests.sanitize_layers = function(test, common) {
module.exports.all = function (tape, common) {
function test(name, testFunction) {
return tape('SANTIZE _layers ' + name, testFunction);
return tape('SANITIZE _layers ' + name, testFunction);
}
for( var testCase in module.exports.tests ){

26
test/unit/sanitizer/_location_bias.js

@ -1,4 +1,4 @@
const setup = require('../../../sanitizer/_location_bias');
const sanitizer = require('../../../sanitizer/_location_bias');
module.exports.tests = {};
@ -8,14 +8,14 @@ module.exports.tests.setLocationBias = function(test, common) {
'focus.point.lat': 12.12121212,
'focus.point.lon': 21.21212121
};
const locationBias = setup(defaultParameters);
const locationBias = sanitizer(defaultParameters);
const raw = {};
const expected = {
'focus.point.lat': 12.12121212,
'focus.point.lon': 21.21212121
};
locationBias(raw, undefined);
locationBias.sanitize(raw, undefined);
t.deepEqual(raw, expected, 'focus point should be set');
t.end();
@ -26,9 +26,9 @@ module.exports.tests.setLocationBias = function(test, common) {
'focus.point.lat': 12.12121212,
'focus.point.lon': 21.21212121
};
const locationBias = setup(defaultParameters);
const locationBias = sanitizer(defaultParameters);
locationBias(undefined, undefined);
locationBias.sanitize(undefined, undefined);
t.deepEqual(undefined, undefined, 'should be unmodified' );
t.end();
});
@ -37,11 +37,11 @@ module.exports.tests.setLocationBias = function(test, common) {
const defaultParameters = {
'focus.point.lon': 12.2121212
};
const locationBias = setup(defaultParameters);
const locationBias = sanitizer(defaultParameters);
const raw = {};
const expected = {};
locationBias(raw, undefined);
locationBias.sanitize(raw, undefined);
t.deepEqual(raw, expected, 'should be unmodified' );
t.end();
});
@ -50,11 +50,11 @@ module.exports.tests.setLocationBias = function(test, common) {
const defaultParameters = {
'focus.point.lat': 12.2121212
};
const locationBias = setup(defaultParameters);
const locationBias = sanitizer(defaultParameters);
const raw = {};
const expected = {};
locationBias(raw, undefined);
locationBias.sanitize(raw, undefined);
t.deepEqual(raw, expected, 'should be unmodified' );
t.end();
});
@ -64,7 +64,7 @@ module.exports.tests.setLocationBias = function(test, common) {
'focus.point.lon': 12.2121212,
'focus.point.lat': 12.2121212
};
const locationBias = setup(defaultParameters);
const locationBias = sanitizer(defaultParameters);
const raw = {
'focus.point.lon': 43.4343434
};
@ -72,7 +72,7 @@ module.exports.tests.setLocationBias = function(test, common) {
'focus.point.lon': 43.4343434
};
locationBias(raw, undefined);
locationBias.sanitize(raw, undefined);
t.deepEqual(raw, expected, 'should be unmodified' );
t.end();
});
@ -82,7 +82,7 @@ module.exports.tests.setLocationBias = function(test, common) {
'focus.point.lon': 12.2121212,
'focus.point.lat': 12.2121212
};
const locationBias = setup(defaultParameters);
const locationBias = sanitizer(defaultParameters);
const raw = {
'focus.point.lat': 34.3434343
};
@ -90,7 +90,7 @@ module.exports.tests.setLocationBias = function(test, common) {
'focus.point.lat': 34.3434343
};
locationBias(raw, undefined);
locationBias.sanitize(raw, undefined);
t.deepEqual(raw, expected, 'should be unmodified' );
t.end();
});

14
test/unit/sanitizer/_single_scalar_parameters.js

@ -1,4 +1,4 @@
var sanitize = require('../../../sanitizer/_single_scalar_parameters');
var sanitizer = require('../../../sanitizer/_single_scalar_parameters')();
module.exports.tests = {};
@ -10,8 +10,8 @@ module.exports.tests.single_scalar_parameters = function(test, common) {
arrayParameter2: ['value3']
};
var clean = {};
var errorsAndWarnings = sanitize(raw, clean);
t.deepEquals(errorsAndWarnings, {
var messages = sanitizer.sanitize(raw, clean);
t.deepEquals(messages, {
errors: [
'\'arrayParameter1\' parameter can only have one value',
'\'arrayParameter2\' parameter can only have one value',
@ -33,8 +33,8 @@ module.exports.tests.single_scalar_parameters = function(test, common) {
objectParameter2: { }
};
var clean = {};
var errorsAndWarnings = sanitize(raw, clean);
t.deepEquals(errorsAndWarnings, {
var messages = sanitizer.sanitize(raw, clean);
t.deepEquals(messages, {
errors: [
'\'objectParameter1\' parameter must be a scalar',
'\'objectParameter2\' parameter must be a scalar'
@ -51,8 +51,8 @@ module.exports.tests.single_scalar_parameters = function(test, common) {
test('request with all scalar parameters should return empty errors', function(t) {
var raw = { scalarParameter1: 'value1', scalarParameter2: 2, scalarParameter3: true };
var clean = {};
var errorsAndWarnings = sanitize(raw, clean);
t.deepEquals(errorsAndWarnings, { errors: [], warnings: [] });
var messages = sanitizer.sanitize(raw, clean);
t.deepEquals(messages, { errors: [], warnings: [] });
t.end();
});

18
test/unit/sanitizer/_size.js

@ -1,4 +1,4 @@
var sanitize = require('../../../sanitizer/_size');
var sanitizer = require('../../../sanitizer/_size');
module.exports.tests = {};
@ -6,7 +6,7 @@ module.exports.tests.sanitize_size = function(test, common) {
test('size=0', function(t) {
var raw = { size: 0 };
var clean = {};
var res = sanitize(/*defaults*/)(raw, clean);
var res = sanitizer(/*defaults*/).sanitize(raw, clean);
t.equal(res.errors.length, 0, 'should return no errors');
t.equal(res.warnings.length, 1, 'should return warning');
t.equal(res.warnings[0], 'out-of-range integer \'size\', using MIN_SIZE', 'check warning text');
@ -17,7 +17,7 @@ module.exports.tests.sanitize_size = function(test, common) {
test('size=10000', function(t) {
var raw = { size: 10000 };
var clean = {};
var res = sanitize(/*defaults*/)(raw, clean);
var res = sanitizer(/*defaults*/).sanitize(raw, clean);
t.equal(res.errors.length, 0, 'should return no errors');
t.equal(res.warnings.length, 1, 'should return warning');
t.equal(res.warnings[0], 'out-of-range integer \'size\', using MAX_SIZE', 'check warning text');
@ -28,20 +28,26 @@ module.exports.tests.sanitize_size = function(test, common) {
test('size not set', function(t) {
var raw = {};
var clean = {};
var res = sanitize(/*defaults*/)(raw, clean);
var res = sanitizer(/*defaults*/).sanitize(raw, clean);
t.equal(res.errors.length, 0, 'should return no errors');
t.equal(res.warnings.length, 0, 'should return no warning');
t.equal(clean.size, 10, 'default to 10');
t.end();
});
test('return an array of expected parameters in object form for validation', function(t) {
const expected = [{ name: 'size' }];
const validParameters = sanitizer(/*defaults*/).expected();
t.deepEquals(validParameters, expected);
t.end();
});
var valid_sizes = [5, '5', 5.5, '5.5'];
valid_sizes.forEach(function (size) {
test('size=' + size, function (t) {
var raw = {size: size};
var clean = {};
var res = sanitize(/*defaults*/)(raw, clean);
var res = sanitizer(/*defaults*/).sanitize(raw, clean);
t.equal(res.errors.length, 0, 'should return no errors');
t.equal(res.warnings.length, 0, 'should return warning');
t.equal(clean.size, 5, 'set to correct integer');
@ -52,7 +58,7 @@ module.exports.tests.sanitize_size = function(test, common) {
module.exports.all = function (tape, common) {
function test(name, testFunction) {
return tape('SANTIZE _size ' + name, testFunction);
return tape('SANITIZE _size ' + name, testFunction);
}
for( var testCase in module.exports.tests ){

14
test/unit/sanitizer/_sources.js

@ -1,5 +1,5 @@
var type_mapping = require('../../../helper/type_mapping');
var sanitize = require( '../../../sanitizer/_targets' )('sources', type_mapping.source_mapping);
var sanitizer = require( '../../../sanitizer/_targets' )('sources', type_mapping.source_mapping);
var success_messages = { error: false };
@ -12,7 +12,7 @@ module.exports.tests.no_sources = function(test, common) {
clean: { }
};
var messages = sanitize(req.query, req.clean);
var messages = sanitizer.sanitize(req.query, req.clean);
t.equal(req.clean.sources, undefined, 'no sources should be defined');
t.deepEqual(messages.errors, [], 'no error returned');
@ -31,7 +31,7 @@ module.exports.tests.no_sources = function(test, common) {
var expected_error = 'sources parameter cannot be an empty string. ' +
'Valid options: osm,oa,gn,wof,openstreetmap,openaddresses,geonames,whosonfirst';
var messages = sanitize(req.query, req.clean);
var messages = sanitizer.sanitize(req.query, req.clean);
t.equal(req.clean.sources, undefined, 'no sources should be defined');
t.deepEqual(messages.errors.length, 1, 'error returned');
@ -50,7 +50,7 @@ module.exports.tests.valid_sources = function(test, common) {
clean: { }
};
var messages = sanitize(req.query, req.clean);
var messages = sanitizer.sanitize(req.query, req.clean);
t.deepEqual(req.clean.sources, ['geonames'], 'sources should contain geonames');
t.deepEqual(messages.errors, [], 'no error returned');
@ -67,7 +67,7 @@ module.exports.tests.valid_sources = function(test, common) {
clean: { }
};
var messages = sanitize(req.query, req.clean);
var messages = sanitizer.sanitize(req.query, req.clean);
t.deepEqual(req.clean.sources, ['openstreetmap'], 'abbreviation is expanded to full version');
t.deepEqual(messages.errors, [], 'no error returned');
@ -83,7 +83,7 @@ module.exports.tests.valid_sources = function(test, common) {
clean: { }
};
var messages = sanitize(req.query, req.clean);
var messages = sanitizer.sanitize(req.query, req.clean);
t.deepEqual(req.clean.sources, ['openstreetmap', 'openaddresses'],
'clean.sources should contain openstreetmap and openadresses');
@ -109,7 +109,7 @@ module.exports.tests.invalid_sources = function(test, common) {
warnings: []
};
var messages = sanitize(req.query, req.clean);
var messages = sanitizer.sanitize(req.query, req.clean);
t.deepEqual(messages, expected_messages, 'error with message returned');
t.equal(req.clean.sources, undefined, 'clean.sources should remain empty');

31
test/unit/sanitizer/_sources_and_layers.js

@ -1,4 +1,4 @@
var sanitize = require('../../../sanitizer/_sources_and_layers');
var sanitizer = require('../../../sanitizer/_sources_and_layers')();
var type_mapping = require('../../../helper/type_mapping');
@ -9,7 +9,7 @@ module.exports.tests.inactive = function(test, common) {
var raw = {};
var clean = {};
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.equal(messages.errors.length, 0, 'should return no errors');
t.equal(messages.warnings.length, 0, 'should return no warnings');
@ -20,7 +20,7 @@ module.exports.tests.inactive = function(test, common) {
var raw = {};
var clean = { layers: ['venue'] };
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.equal(messages.errors.length, 0, 'should return no errors');
t.equal(messages.warnings.length, 0, 'should return no warnings');
@ -31,7 +31,7 @@ module.exports.tests.inactive = function(test, common) {
var raw = {};
var clean = { sources: ['openstreetmap'] };
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.equal(messages.errors.length, 0, 'should return no errors');
t.equal(messages.warnings.length, 0, 'should return no warnings');
@ -44,7 +44,7 @@ module.exports.tests.no_errors = function(test, common) {
var raw = {};
var clean = { sources: ['openstreetmap'], layers: ['venue'] };
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.equal(messages.errors.length, 0, 'should return no errors');
t.equal(messages.warnings.length, 0, 'should return no warnings');
@ -55,7 +55,7 @@ test('valid combination', function(t) {
var raw = {};
var clean = { sources: ['geonames'], layers: ['borough'] };
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.equal(messages.errors.length, 0, 'should return no errors');
t.equal(messages.warnings.length, 0, 'should return no warnings');
@ -66,7 +66,7 @@ test('valid combination', function(t) {
var raw = {};
var clean = { sources: ['geonames'], layers: ['macroregion'] };
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.equal(messages.errors.length, 0, 'should return no errors');
t.equal(messages.warnings.length, 0, 'should return no warnings');
@ -77,7 +77,7 @@ test('valid combination', function(t) {
var raw = {};
var clean = { sources: ['whosonfirst'], layers: ['venue'] };
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.equal(messages.errors.length, 0, 'should return no errors');
t.equal(messages.warnings.length, 0, 'should return no warnings');
@ -88,7 +88,7 @@ test('valid combination', function(t) {
var raw = {};
var clean = { sources: ['openstreetmap', 'openaddresses'], layers: ['venue'] };
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.equal(messages.errors.length, 0, 'should return no errors');
t.equal(messages.warnings.length, 0, 'should return no warnings');
@ -99,12 +99,19 @@ test('valid combination', function(t) {
var raw = {};
var clean = { sources: ['openaddresses'], layers: ['address', 'country'] };
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.equal(messages.errors.length, 0, 'should return no errors');
t.equal(messages.warnings.length, 0, 'should return no warnings');
t.end();
});
test('return an array of expected parameters in object form for validation', function (t) {
const expected = [{ 'name': 'sources' }, { 'name': 'layers' }];
const validParameters = sanitizer.expected();
t.deepEquals(validParameters, expected);
t.end();
});
};
module.exports.tests.invalid_combination = function(test, common) {
@ -112,7 +119,7 @@ module.exports.tests.invalid_combination = function(test, common) {
var raw = {};
var clean = { sources: ['whosonfirst'], layers: ['address'] };
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.equal(messages.errors.length, 1, 'should return an error');
t.equal(messages.errors[0], 'You have specified both the `sources` and `layers` ' +
@ -125,7 +132,7 @@ module.exports.tests.invalid_combination = function(test, common) {
var raw = {};
var clean = { sources: ['openstreetmap'], layers: ['country', 'locality'] };
var messages = sanitize(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.equal(messages.errors.length, 2, 'should return an error');
t.equal(messages.errors[0], 'You have specified both the `sources` and `layers` ' +

31
test/unit/sanitizer/_synthesize_analysis.js

@ -37,7 +37,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
const messages = sanitizer(raw, clean);
const messages = sanitizer().sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');
@ -76,7 +76,7 @@ module.exports.tests.text_parser = function(test, common) {
parsed_text: {}
};
const messages = sanitizer(raw, clean);
const messages = sanitizer().sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, ['at least one of the following fields is required: ' +
@ -99,7 +99,7 @@ module.exports.tests.text_parser = function(test, common) {
const expected_clean = { parsed_text: {} };
const messages = sanitizer(raw, clean);
const messages = sanitizer().sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, ['at least one of the following fields is required: ' +
@ -128,7 +128,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
const messages = sanitizer(raw, clean);
const messages = sanitizer().sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');
@ -161,7 +161,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
const messages = sanitizer(raw, clean);
const messages = sanitizer().sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');
@ -194,7 +194,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
const messages = sanitizer(raw, clean);
const messages = sanitizer().sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');
@ -224,7 +224,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
const messages = sanitizer(raw, clean);
const messages = sanitizer().sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, [], 'no errors');
@ -233,6 +233,23 @@ module.exports.tests.text_parser = function(test, common) {
});
test('return an array of expected parameters in object form for validation', function (t) {
const sanitizer = require('../../../sanitizer/_synthesize_analysis');
const expected = [
{ 'name': 'venue' },
{ 'name': 'address' },
{ 'name': 'neighbourhood' },
{ 'name': 'borough' },
{ 'name': 'locality' },
{ 'name': 'county' },
{ 'name': 'region' },
{ 'name': 'postalcode' },
{ 'name': 'country' }];
const validParameters = sanitizer().expected();
t.deepEquals(validParameters, expected);
t.end();
});
};
module.exports.all = function (tape, common) {

14
test/unit/sanitizer/_text.js

@ -1,9 +1,9 @@
const sanitizer = require('../../../sanitizer/_text');
const sanitizer = require('../../../sanitizer/_text')();
module.exports.tests = {};
module.exports.tests.text_parser = function(test, common) {
test('non-empty raw.text should call analyzer and set clean.text and not clean.parsed_text', t => {
test('non-empty raw.text should overwrite clean.text', t => {
const raw = {
text: 'raw input'
};
@ -15,7 +15,7 @@ module.exports.tests.text_parser = function(test, common) {
text: raw.text
};
const messages = sanitizer(raw, clean);
const messages = sanitizer.sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages, { warnings: [], errors: [] }, 'no errors/warnings');
@ -34,7 +34,7 @@ module.exports.tests.text_parser = function(test, common) {
const expected_clean = {
};
const messages = sanitizer(raw, clean);
const messages = sanitizer.sanitize(raw, clean);
t.deepEquals(clean, expected_clean);
t.deepEquals(messages.errors, ['invalid param \'text\': text length, must be >0'], 'no errors');
@ -46,6 +46,12 @@ module.exports.tests.text_parser = function(test, common) {
});
test('return an array of expected parameters in object form for validation', (t) => {
const expected = [{ name: 'text' }];
const validParameters = sanitizer.expected();
t.deepEquals(validParameters, expected);
t.end();
});
};
module.exports.all = (tape, common) => {

36
test/unit/sanitizer/_text_addressit.js

@ -1,4 +1,4 @@
var sanitizer = require('../../../sanitizer/_text_addressit');
var sanitizer = require('../../../sanitizer/_text_addressit')();
var type_mapping = require('../../../helper/type_mapping');
module.exports.tests = {};
@ -11,7 +11,7 @@ module.exports.tests.text_parser = function(test, common) {
var clean = {
};
var messages = sanitizer(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.deepEquals(messages.errors, [], 'no errors');
t.deepEquals(messages.warnings, [], 'no warnings');
@ -42,7 +42,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
var messages = sanitizer(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.deepEqual(messages, { errors: [], warnings: [] } );
t.deepEqual(clean, expected_clean);
@ -67,7 +67,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
var messages = sanitizer(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.deepEqual(messages, { errors: [], warnings: [] } );
t.deepEqual(clean, expected_clean);
@ -98,7 +98,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
var messages = sanitizer(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.deepEqual(messages, { errors: [], warnings: [] } );
t.deepEqual(clean, expected_clean);
@ -122,7 +122,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
var messages = sanitizer(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.deepEqual(messages, { errors: [], warnings: [] } );
t.deepEqual(clean, expected_clean);
@ -144,7 +144,7 @@ module.exports.tests.text_parser = function(test, common) {
text: 'yugolsavia'
};
var messages = sanitizer(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.deepEqual(messages, { errors: [], warnings: [] } );
t.deepEqual(clean, expected_clean);
@ -164,7 +164,7 @@ module.exports.tests.text_parser = function(test, common) {
text: 'small town'
};
var messages = sanitizer(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.deepEqual(messages, { errors: [], warnings: [] } );
t.deepEqual(clean, expected_clean);
@ -184,7 +184,7 @@ module.exports.tests.text_parser = function(test, common) {
text: '123 main'
};
var messages = sanitizer(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.deepEqual(messages, { errors: [], warnings: [] } );
t.deepEqual(clean, expected_clean);
@ -204,7 +204,7 @@ module.exports.tests.text_parser = function(test, common) {
text: 'main 123'
};
var messages = sanitizer(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.deepEqual(messages, { errors: [], warnings: [] } );
t.deepEqual(clean, expected_clean);
@ -228,7 +228,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
var messages = sanitizer(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.deepEqual(messages, { errors: [], warnings: [] } );
t.deepEqual(clean, expected_clean);
@ -253,7 +253,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
var messages = sanitizer(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.deepEqual(messages, { errors: [], warnings: [] } );
t.deepEqual(clean, expected_clean);
@ -279,7 +279,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
var messages = sanitizer(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.deepEqual(messages, { errors: [], warnings: [] } );
t.deepEqual(clean, expected_clean);
@ -305,7 +305,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
var messages = sanitizer(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.deepEqual(messages, { errors: [], warnings: [] } );
t.deepEqual(clean, expected_clean);
@ -331,7 +331,7 @@ module.exports.tests.text_parser = function(test, common) {
}
};
var messages = sanitizer(raw, clean);
var messages = sanitizer.sanitize(raw, clean);
t.deepEqual(messages, { errors: [], warnings: [] } );
t.deepEqual(clean, expected_clean);
@ -339,6 +339,12 @@ module.exports.tests.text_parser = function(test, common) {
});
test('return an array of expected parameters in object form for validation', (t) => {
const expected = [{ name: 'text' }];
const validParameters = sanitizer.expected();
t.deepEquals(validParameters, expected);
t.end();
});
};
module.exports.all = function (tape, common) {

38
test/unit/sanitizer/_tokenizer.js

@ -1,4 +1,4 @@
var sanitizer = require('../../../sanitizer/_tokenizer');
var sanitizer = require('../../../sanitizer/_tokenizer')();
module.exports.tests = {};
@ -6,7 +6,7 @@ module.exports.tests.sanity_checks = function(test, common) {
test('clean.text not set', function(t) {
var clean = {}; // clean.text not set
var messages = sanitizer({}, clean);
var messages = sanitizer.sanitize({}, clean);
// no tokens produced
t.deepEquals(clean.tokens, [], 'no tokens');
@ -22,7 +22,7 @@ module.exports.tests.sanity_checks = function(test, common) {
test('clean.text not a string', function(t) {
var clean = { text: {} }; // clean.text not a string
var messages = sanitizer({}, clean);
var messages = sanitizer.sanitize({}, clean);
// no tokens produced
t.deepEquals(clean.tokens, [], 'no tokens');
@ -38,7 +38,7 @@ module.exports.tests.sanity_checks = function(test, common) {
test('empty string', function(t) {
var clean = { text: '' };
var messages = sanitizer({}, clean);
var messages = sanitizer.sanitize({}, clean);
// no tokens produced
t.deepEquals(clean.tokens, [], 'no tokens');
@ -54,7 +54,7 @@ module.exports.tests.sanity_checks = function(test, common) {
test('clean.parsed_text set but clean.parsed_text.name invalid', function(t) {
var clean = { parsed_text: { text: {} } };
var messages = sanitizer({}, clean);
var messages = sanitizer.sanitize({}, clean);
// no tokens produced
t.deepEquals(clean.tokens, [], 'no tokens');
@ -70,7 +70,7 @@ module.exports.tests.sanity_checks = function(test, common) {
test('favor clean.parsed_text.name over clean.text', function(t) {
var clean = { parsed_text: { name: 'foo' }, text: 'bar' };
var messages = sanitizer({}, clean);
var messages = sanitizer.sanitize({}, clean);
// favor clean.parsed_text.name over clean.text
t.deepEquals(clean.tokens, [ 'foo' ], 'use clean.parsed_text.name');
@ -86,7 +86,7 @@ module.exports.tests.sanity_checks = function(test, common) {
test('favor clean.parsed_text street data over clean.text', function(t) {
var clean = { parsed_text: { number: '190', street: 'foo st' }, text: 'bar' };
var messages = sanitizer({}, clean);
var messages = sanitizer.sanitize({}, clean);
// favor clean.parsed_text.name over clean.text
t.deepEquals(clean.tokens, [ '190', 'foo', 'st' ], 'use street name + number');
@ -102,7 +102,7 @@ module.exports.tests.sanity_checks = function(test, common) {
test('favor clean.parsed_text.name over clean.parsed_text street data', function(t) {
var clean = { parsed_text: { number: '190', street: 'foo st', name: 'foo' }, text: 'bar' };
var messages = sanitizer({}, clean);
var messages = sanitizer.sanitize({}, clean);
// favor clean.parsed_text.name over all other variables
t.deepEquals(clean.tokens, [ 'foo' ], 'use clean.parsed_text.name');
@ -121,7 +121,7 @@ module.exports.tests.space_delimiter = function(test, common) {
test('space delimiter - simple', function(t) {
var clean = { text: '30 west 26th street new york' };
var messages = sanitizer({}, clean);
var messages = sanitizer.sanitize({}, clean);
// tokens produced
t.deepEquals(clean.tokens, [
@ -156,7 +156,7 @@ module.exports.tests.space_delimiter = function(test, common) {
test('space delimiter - multiple spaces / other whitespace', function(t) {
var clean = { text: ' 30 west \t26th \nstreet new york ' };
var messages = sanitizer({}, clean);
var messages = sanitizer.sanitize({}, clean);
// tokens produced
t.deepEquals(clean.tokens, [
@ -194,7 +194,7 @@ module.exports.tests.comma_delimiter = function(test, common) {
test('comma delimiter - simple', function(t) {
var clean = { text: '30 west 26th street, new york' };
var messages = sanitizer({}, clean);
var messages = sanitizer.sanitize({}, clean);
// tokens produced
t.deepEquals(clean.tokens, [
@ -229,7 +229,7 @@ module.exports.tests.comma_delimiter = function(test, common) {
test('comma delimiter - multiple commas', function(t) {
var clean = { text: ',30 west 26th street,,, new york,' };
var messages = sanitizer({}, clean);
var messages = sanitizer.sanitize({}, clean);
// tokens produced
t.deepEquals(clean.tokens, [
@ -267,7 +267,7 @@ module.exports.tests.forward_slash_delimiter = function(test, common) {
test('forward slash delimiter - simple', function(t) {
var clean = { text: 'Bedell Street/133rd Avenue' };
var messages = sanitizer({}, clean);
var messages = sanitizer.sanitize({}, clean);
// tokens produced
t.deepEquals(clean.tokens, [
@ -298,7 +298,7 @@ module.exports.tests.forward_slash_delimiter = function(test, common) {
test('forward slash - multiple slashes', function(t) {
var clean = { text: '/Bedell Street//133rd Avenue/' };
var messages = sanitizer({}, clean);
var messages = sanitizer.sanitize({}, clean);
// tokens produced
t.deepEquals(clean.tokens, [
@ -332,7 +332,7 @@ module.exports.tests.final_token_single_gram = function(test, common) {
test('final token single gram - numeric', function(t) {
var clean = { text: 'grolmanstrasse 1' };
var messages = sanitizer({}, clean);
var messages = sanitizer.sanitize({}, clean);
// tokens produced
t.deepEquals(clean.tokens, [
@ -359,7 +359,7 @@ module.exports.tests.final_token_single_gram = function(test, common) {
test('final token single gram - non-numeric', function(t) {
var clean = { text: 'grolmanstrasse a' };
var messages = sanitizer({}, clean);
var messages = sanitizer.sanitize({}, clean);
// tokens produced
t.deepEquals(clean.tokens, [
@ -389,7 +389,7 @@ module.exports.tests.back_slash_delimiter = function(test, common) {
test('back slash delimiter - simple', function(t) {
var clean = { text: 'Bedell Street\\133rd Avenue' };
var messages = sanitizer({}, clean);
var messages = sanitizer.sanitize({}, clean);
// tokens produced
t.deepEquals(clean.tokens, [
@ -408,7 +408,7 @@ module.exports.tests.back_slash_delimiter = function(test, common) {
test('back slash - multiple slashes', function(t) {
var clean = { text: '\\Bedell Street\\\\133rd Avenue\\' };
var messages = sanitizer({}, clean);
var messages = sanitizer.sanitize({}, clean);
// tokens produced
t.deepEquals(clean.tokens, [
@ -430,7 +430,7 @@ module.exports.tests.mixed_delimiter = function(test, common) {
test('mixed delimiters', function(t) {
var clean = { text: ',/Bedell Street\\, \n\t ,\\//133rd Avenue, /\n/' };
var messages = sanitizer({}, clean);
var messages = sanitizer.sanitize({}, clean);
// tokens produced
t.deepEquals(clean.tokens, [

139
test/unit/sanitizer/autocomplete.js

@ -8,82 +8,111 @@ module.exports.tests.sanitizers = function(test, common) {
var called_sanitizers = [];
var autocomplete = proxyquire('../../../sanitizer/autocomplete', {
'../sanitizer/_single_scalar_parameters': () => {
called_sanitizers.push('_single_scalar_parameters');
return { errors: [], warnings: [] };
'../sanitizer/_single_scalar_parameters': function () {
return {
sanitize: () => {
called_sanitizers.push('_single_scalar_parameters');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_text_addressit': () => {
called_sanitizers.push('_text_addressit');
return { errors: [], warnings: [] };
'../sanitizer/_text_addressit': function () {
return {
sanitize: () => {
called_sanitizers.push('_text_addressit');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_tokenizer': () => {
called_sanitizers.push('_tokenizer');
return { errors: [], warnings: [] };
'../sanitizer/_tokenizer': function () {
return {
sanitize: () => {
called_sanitizers.push('_tokenizer');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_size': function() {
'../sanitizer/_size': function () {
if (_.isEqual(_.values(arguments), [10, 10, 10])) {
return () => {
called_sanitizers.push('_size');
return { errors: [], warnings: [] };
return {
sanitize: () => {
called_sanitizers.push('_size');
return { errors: [], warnings: [] };
}
};
} else {
throw new Error('incorrect parameters passed to _size');
}
},
'../sanitizer/_targets': (type) => {
'../sanitizer/_targets': function (type) {
if (['layers', 'sources'].indexOf(type) !== -1) {
return () => {
called_sanitizers.push(`_targets/${type}`);
return { errors: [], warnings: [] };
};
}
else {
return {
sanitize: () => {
called_sanitizers.push(`_targets/${type}`);
return { errors: [], warnings: [] };
}
};
} else {
throw new Error('incorrect parameters passed to _targets');
}
},
'../sanitizer/_sources_and_layers': () => {
called_sanitizers.push('_sources_and_layers');
return { errors: [], warnings: [] };
},
'../sanitizer/_flag_bool': function() {
if (arguments[0] === 'private' && arguments[1] === false) {
return () => {
called_sanitizers.push('_flag_bool');
return { errors: [], warnings: [] };
};
}
else {
throw new Error('incorrect parameters passed to _flag_bool');
}
},
'../sanitizer/_location_bias': (defaultParameters) => {
if (defaultParameters.key === 'value'){
return () => {
called_sanitizers.push('_location_bias');
'../sanitizer/_sources_and_layers': function () {
return {
sanitize: () => {
called_sanitizers.push('_sources_and_layers');
return { errors: [], warnings: [] };
};
}
};
},
'../sanitizer/_flag_bool': function () {
if (arguments[0] === 'private' && arguments[1] === false) {
return {
sanitize: () => {
called_sanitizers.push('_flag_bool');
return { errors: [], warnings: [] };
}
};
} else {
throw new Error('incorrect parameter passed to _location_bias');
throw new Error('incorrect parameters passed to _flag_bool');
}
},
'../sanitizer/_geo_autocomplete': () => {
called_sanitizers.push('_geo_autocomplete');
return { errors: [], warnings: [] };
'../sanitizer/_location_bias': function (defaultParameters) {
return {
sanitize: () => {
if (defaultParameters.key === 'value'){
called_sanitizers.push('_location_bias');
return { errors: [], warnings: [] };
} else {
throw new Error('incorrect parameter passed to _location_bias');
}
}
};
},
'../sanitizer/_boundary_country': () => {
called_sanitizers.push('_boundary_country');
return { errors: [], warnings: [] };
'../sanitizer/_geo_autocomplete': function () {
return {
sanitize: () => {
called_sanitizers.push('_geo_autocomplete');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_categories': () => {
called_sanitizers.push('_categories');
return { errors: [], warnings: [] };
'../sanitizer/_boundary_country': function () {
return {
sanitize: () => {
called_sanitizers.push('_boundary_country');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_categories': function () {
return {
sanitize: () => {
called_sanitizers.push('_categories');
return { errors: [], warnings: [] };
}
};
}
});
const expected_sanitizers = [

38
test/unit/sanitizer/defer_to_addressit.js

@ -12,8 +12,12 @@ module.exports.tests.sanitize = (test, common) => {
// rather than re-verify the functionality of all the sanitizers, this test just verifies that they
// were all called correctly
const defer_to_addressit = proxyquire('../../../sanitizer/defer_to_addressit', {
'../sanitizer/_text_addressit': () => {
t.fail('_text_addressit should not have been called');
'../sanitizer/_text_addressit': function () {
return {
sanitize: () => {
t.fail('_text_addressit should not have been called');
}
};
},
'pelias-logger': logger
})(() => false);
@ -33,9 +37,13 @@ module.exports.tests.sanitize = (test, common) => {
// rather than re-verify the functionality of all the sanitizers, this test just verifies that they
// were all called correctly
const defer_to_addressit = proxyquire('../../../sanitizer/defer_to_addressit', {
'../sanitizer/_text_addressit': () => {
t.pass('_text_addressit should have been called');
return { errors: [], warnings: [] };
'../sanitizer/_text_addressit': function () {
return {
sanitize: () => {
t.pass('_text_addressit should have been called');
return { errors: [], warnings: [] };
}
};
},
'pelias-logger': logger,
'../helper/logging': {
@ -65,9 +73,13 @@ module.exports.tests.sanitize = (test, common) => {
// rather than re-verify the functionality of all the sanitizers, this test just verifies that they
// were all called correctly
const defer_to_addressit = proxyquire('../../../sanitizer/defer_to_addressit', {
'../sanitizer/_text_addressit': () => {
t.pass('_text_addressit should have been called');
return { errors: [], warnings: [] };
'../sanitizer/_text_addressit': function () {
return {
sanitize: () => {
t.pass('_text_addressit should have been called');
return { errors: [], warnings: [] };
}
};
},
'pelias-logger': logger
})(() => true);
@ -94,9 +106,13 @@ module.exports.tests.sanitize = (test, common) => {
// rather than re-verify the functionality of all the sanitizers, this test just verifies that they
// were all called correctly
const defer_to_addressit = proxyquire('../../../sanitizer/defer_to_addressit', {
'../sanitizer/_text_addressit': () => {
t.pass('_text_addressit should have been called');
return { errors: [], warnings: [] };
'../sanitizer/_text_addressit': function () {
return {
sanitize: () => {
t.pass('_text_addressit should have been called');
return { errors: [], warnings: [] };
}
};
},
'pelias-logger': logger,
'../helper/logging': {

163
test/unit/sanitizer/nearby.js

@ -1,58 +1,137 @@
const _ = require('lodash'),
proxyquire = require('proxyquire').noCallThru();
var nearby = require('../../../sanitizer/nearby');
var defaults = require('../../../query/reverse_defaults');
var sanitize = nearby.sanitize;
var middleware = nearby.middleware;
module.exports.tests = {};
var defaultClean = { 'point.lat': 0,
'point.lon': 0,
'boundary.circle.lat': 0,
'boundary.circle.lon': 0,
size: 10,
private: false
};
module.exports.tests.sanitize = function(test, common) {
test('verify that all sanitizers were called as expected', function(t) {
var called_sanitizers = [];
module.exports.tests = {};
// rather than re-verify the functionality of all the sanitizers, this test just verifies that they
// were all called correctly
var nearby = proxyquire('../../../sanitizer/nearby.js', {
'../sanitizer/_single_scalar_parameters': function () {
return {
sanitize: () => {
called_sanitizers.push('_single_scalar_parameters');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_deprecate_quattroshapes': function () {
return {
sanitize: () => {
called_sanitizers.push('_deprecate_quattroshapes');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_targets': function (type) {
if (['layers', 'sources'].indexOf(type) !== -1) {
return {
sanitize: () => {
called_sanitizers.push(`_targets/${type}`);
return { errors: [], warnings: [] };
}
};
} else {
throw new Error('incorrect parameters passed to _targets');
}
},
'../sanitizer/_sources_and_layers': function () {
return {
sanitize: () => {
called_sanitizers.push('_sources_and_layers');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_geonames_deprecation': function () {
return {
sanitize: () => {
called_sanitizers.push('_geonames_deprecations');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_size': function () {
if (_.isEmpty(arguments)) {
return {
sanitize: () => {
called_sanitizers.push('_size');
return { errors: [], warnings: [] };
}
};
} else {
throw new Error('should not have passed any parameters to _size');
}
},
'../sanitizer/_flag_bool': function () {
if (arguments[0] === 'private' && arguments[1] === false) {
return {
sanitize: () => {
called_sanitizers.push('_flag_bool');
return { errors: [], warnings: [] };
}
};
} else {
throw new Error('incorrect parameters passed to _flag_bool');
}
},
'../sanitizer/_geo_reverse': function () {
return {
sanitize: () => {
called_sanitizers.push('_geo_reverse');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_boundary_country': function () {
return {
sanitize: () => {
called_sanitizers.push('_boundary_country');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_categories': function () {
return {
sanitize: () => {
called_sanitizers.push('_categories');
return { errors: [], warnings: [] };
}
};
}
});
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 middleware, 'function', 'middleware is a function');
t.equal(middleware.length, 3, 'sanitizee has a valid middleware');
t.end();
});
};
const expected_sanitizers = [
'_single_scalar_parameters',
'_deprecate_quattroshapes',
'_targets/layers',
'_targets/sources',
'_sources_and_layers',
'_geonames_deprecations',
'_size',
'_flag_bool',
'_geo_reverse',
'_boundary_country',
'_categories'
];
module.exports.tests.sanitizers = function(test, common) {
test('check sanitizer list', function (t) {
var expected = ['singleScalarParameters', 'quattroshapes_deprecation', 'layers',
'sources', 'sources_and_layers', 'geonames_deprecation', 'size', 'private',
'geo_reverse', 'boundary_country', 'categories'];
t.deepEqual(Object.keys(nearby.sanitizer_list), expected);
t.end();
});
};
const req = {};
const res = {};
module.exports.tests.middleware_success = function(test, common) {
test('middleware success', function(t) {
var req = { query: { 'point.lat': 0, 'point.lon': 0 }};
var next = function(){
t.deepEqual(req.errors, [], 'no error message set');
t.deepEqual(req.clean, defaultClean);
nearby.middleware(req, res, () => {
t.deepEquals(called_sanitizers, expected_sanitizers);
t.end();
};
middleware( req, undefined, next );
});
});
};
module.exports.all = function (tape, common) {
function test(name, testFunction) {
return tape('SANTIZE /nearby ' + name, testFunction);
return tape('SANITIZE /nearby ' + name, testFunction);
}
for( var testCase in module.exports.tests ){

138
test/unit/sanitizer/place.js

@ -1,111 +1,65 @@
var place = require('../../../sanitizer/place'),
sanitize = place.sanitize,
middleware = place.middleware,
defaultClean = { ids: [ { source: 'geonames', layer: 'venue', id: '123' } ], private: false };
const _ = require('lodash'),
proxyquire = require('proxyquire').noCallThru();
// these are the default values you would expect when no input params are specified.
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 middleware, 'function', 'middleware is a function');
t.equal(middleware.length, 3, 'sanitize has a valid middleware');
t.end();
});
};
module.exports.tests.sanitizers = function(test, common) {
test('check sanitizer list', function (t) {
var expected = ['singleScalarParameters', 'ids', 'private' ];
t.deepEqual(Object.keys(place.sanitizer_list), expected);
t.end();
});
};
module.exports.tests.sanitize = function(test, common) {
test('verify that all sanitizers were called as expected', function(t) {
var called_sanitizers = [];
module.exports.tests.sanitize_private = function(test, common) {
var invalid_values = [null, -1, 123, NaN, 'abc'];
invalid_values.forEach(function(value) {
test('invalid private param ' + value, function(t) {
var req = { query: { ids:'geonames:venue:123', 'private': value } };
sanitize(req, function(){
t.deepEqual( req.errors, [], 'no errors' );
t.deepEqual( req.warnings, [], 'no warnings' );
t.equal(req.clean.private, false, 'default private set (to false)');
t.end();
});
// rather than re-verify the functionality of all the sanitizers, this test just verifies that they
// were all called correctly
var place = proxyquire('../../../sanitizer/place.js', {
'../sanitizer/_single_scalar_parameters': function () {
return {
sanitize: () => {
called_sanitizers.push('_single_scalar_parameters');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_ids': function () {
return {
sanitize: () => {
called_sanitizers.push('_ids');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_flag_bool': function () {
if (arguments[0] === 'private' && arguments[1] === false) {
return {
sanitize: () => {
called_sanitizers.push('_flag_bool');
return { errors: [], warnings: [] };
}
};
} else {
throw new Error('incorrect parameters passed to _flag_bool');
}
}
});
});
var valid_values = ['true', true, 1];
valid_values.forEach(function(value) {
test('valid private param ' + value, function(t) {
var req = { query: { ids:'geonames:venue:123', 'private': value } };
sanitize(req, function(){
t.deepEqual( req.errors, [], 'no errors' );
t.deepEqual( req.warnings, [], 'no warnings' );
t.equal(req.clean.private, true, 'private set to true');
t.end();
});
});
});
var valid_false_values = ['false', false, 0];
valid_false_values.forEach(function(value) {
test('test setting false explicitly ' + value, function(t) {
var req = { query: { ids:'geonames:venue:123', 'private': value } };
sanitize(req, function(){
t.deepEqual( req.errors, [], 'no errors' );
t.deepEqual( req.warnings, [], 'no warnings' );
t.equal(req.clean.private, false, 'private set to false');
t.end();
});
});
});
const expected_sanitizers = [
'_single_scalar_parameters',
'_ids',
'_flag_bool'
];
test('test default behavior', function(t) {
var req = { query: { ids:'geonames:venue:123' } };
sanitize(req, function(){
t.deepEqual( req.errors, [], 'no errors' );
t.deepEqual( req.warnings, [], 'no warnings' );
t.equal(req.clean.private, false, 'private set to false');
t.end();
});
});
};
const req = {};
const res = {};
module.exports.tests.invalid_params = function(test, common) {
test('no params', function(t) {
var req = { query: {} };
sanitize( req, function(){
t.equal( req.errors[0], 'invalid param \'ids\': length must be >0', 'error for missing `ids` param');
t.deepEqual( req.warnings, [], 'no warnings' );
place.middleware(req, res, () => {
t.deepEquals(called_sanitizers, expected_sanitizers);
t.end();
});
});
};
module.exports.tests.middleware_success = function(test, common) {
test('middleware success', function(t) {
var req = { query: { ids: 'geonames:venue:123' }};
var next = function(){
t.deepEqual( req.errors, [], 'no errors' );
t.deepEqual( req.warnings, [], 'no warnings' );
t.deepEqual(req.clean, defaultClean);
t.end();
};
middleware( req, undefined, next );
});
};
module.exports.all = function (tape, common) {
function test(name, testFunction) {
return tape('SANTIZE /place ' + name, testFunction);
return tape('SANITIZE /place ' + name, testFunction);
}
for( var testCase in module.exports.tests ){

295
test/unit/sanitizer/reverse.js

@ -1,199 +1,128 @@
// @todo: refactor this test, it's pretty messy, brittle and hard to follow
var reverse = require('../../../sanitizer/reverse'),
sanitize = reverse.sanitize,
middleware = reverse.middleware,
defaults = require('../../../query/reverse_defaults'),
defaultError = 'missing param \'lat\'',
defaultClean = { 'point.lat': 0,
'point.lon': 0,
'boundary.circle.lat': 0,
'boundary.circle.lon': 0,
size: 10,
private: false
};
// these are the default values you would expect when no input params are specified.
// @todo: why is this different from $defaultClean?
var emptyClean = { private: false, size: 10 };
const _ = require('lodash'),
proxyquire = require('proxyquire').noCallThru();
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 middleware, 'function', 'middleware is a function');
t.equal(middleware.length, 3, 'sanitizee has a valid middleware');
t.end();
});
};
module.exports.tests.sanitizers = function(test, common) {
test('check sanitizer list', function (t) {
var expected = ['singleScalarParameters', 'quattroshapes_deprecation', 'layers',
'sources', 'sources_and_layers', 'geonames_deprecation', 'size', 'private',
'geo_reverse', 'boundary_country'];
t.deepEqual(Object.keys(reverse.sanitizer_list), expected);
t.end();
});
};
module.exports.tests.sanitize_lat = function(test, common) {
var lats = {
invalid: [],
valid: [ 0, 45, 90, -0, '0', '45', '90', -181, -120, -91, 91, 120, 181 ],
missing: ['', undefined, null]
};
test('invalid lat', function(t) {
lats.invalid.forEach( function( lat ){
var req = { query: { 'point.lat': lat, 'point.lon': 0 } };
sanitize(req, function(){
t.equal(req.errors[0], 'invalid param \'point.lat\': must be >-90 and <90', lat + ' is an invalid latitude');
t.deepEqual(req.clean, emptyClean, 'clean only has default values set');
});
});
t.end();
});
test('valid lat', function(t) {
lats.valid.forEach( function( lat ){
var req = { query: { 'point.lat': lat, 'point.lon': 0 } };
sanitize(req, function(){
var expected_lat = parseFloat( lat );
t.deepEqual(req.errors, [], 'no errors');
});
});
t.end();
});
test('missing lat', function(t) {
lats.missing.forEach( function( lat ){
var req = { query: { 'point.lat': lat, 'point.lon': 0 } };
sanitize(req, function(){
t.equal(req.errors[0], 'missing param \'point.lat\'', 'latitude is a required field');
t.deepEqual(req.clean, emptyClean, 'clean only has default values set');
});
});
t.end();
});
};
module.exports.tests.sanitize_lon = function(test, common) {
var lons = {
valid: [ -360, -181, 181, -180, -1, -0, 0, 45, 90, '-180', '0', '180' ],
missing: ['', undefined, null]
};
test('valid lon', function(t) {
lons.valid.forEach( function( lon ){
var req = { query: { 'point.lat': 0, 'point.lon': lon } };
sanitize(req, function(){
var expected_lon = parseFloat( lon );
t.deepEqual(req.errors, [], 'no errors');
});
module.exports.tests.sanitize = function(test, common) {
test('verify that all sanitizers were called as expected', function(t) {
var called_sanitizers = [];
// rather than re-verify the functionality of all the sanitizers, this test just verifies that they
// were all called correctly
var reverse = proxyquire('../../../sanitizer/reverse.js', {
'../sanitizer/_single_scalar_parameters': function () {
return {
sanitize: () => {
called_sanitizers.push('_single_scalar_parameters');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_deprecate_quattroshapes': function () {
return {
sanitize: () => {
called_sanitizers.push('_deprecate_quattroshapes');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_targets': function (type) {
if (['layers', 'sources'].indexOf(type) !== -1) {
return {
sanitize: () => {
called_sanitizers.push(`_targets/${type}`);
return { errors: [], warnings: [] };
}
};
} else {
throw new Error('incorrect parameters passed to _targets');
}
},
'../sanitizer/_sources_and_layers': function () {
return {
sanitize: () => {
called_sanitizers.push('_sources_and_layers');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_geonames_deprecation': function () {
return {
sanitize: () => {
called_sanitizers.push('_geonames_deprecations');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_size': function () {
if (_.isEmpty(arguments)) {
return {
sanitize: () => {
called_sanitizers.push('_size');
return { errors: [], warnings: [] };
}
};
} else {
throw new Error('should not have passed any parameters to _size');
}
},
'../sanitizer/_flag_bool': function () {
if (arguments[0] === 'private' && arguments[1] === false) {
return {
sanitize: () => {
called_sanitizers.push('_flag_bool');
return { errors: [], warnings: [] };
}
};
} else {
throw new Error('incorrect parameters passed to _flag_bool');
}
},
'../sanitizer/_geo_reverse': function () {
return {
sanitize: () => {
called_sanitizers.push('_geo_reverse');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_boundary_country': function () {
return {
sanitize: () => {
called_sanitizers.push('_boundary_country');
return { errors: [], warnings: [] };
}
};
}
});
t.end();
});
test('missing lon', function(t) {
lons.missing.forEach( function( lon ){
var req = { query: { 'point.lat': 0, 'point.lon': lon } };
// @todo: why is lat set?
var expected = { 'point.lat': 0, private: false, size: 10 };
sanitize(req, function(){
t.equal(req.errors[0], 'missing param \'point.lon\'', 'longitude is a required field');
t.deepEqual(req.clean, expected, 'clean only has default values set');
});
});
t.end();
});
};
module.exports.tests.sanitize_size = function(test, common) {
test('invalid size value', function(t) {
var req = { query: { size: 'a', 'point.lat': 0, 'point.lon': 0 } };
sanitize(req, function(){
t.equal(req.clean.size, 10, 'default size set');
const expected_sanitizers = [
'_single_scalar_parameters',
'_deprecate_quattroshapes',
'_targets/layers',
'_targets/sources',
'_sources_and_layers',
'_geonames_deprecations',
'_size',
'_flag_bool',
'_geo_reverse',
'_boundary_country'
];
const req = {};
const res = {};
reverse.middleware(req, res, () => {
t.deepEquals(called_sanitizers, expected_sanitizers);
t.end();
});
});
test('below min size value', function(t) {
var req = { query: { size: -100, 'point.lat': 0, 'point.lon': 0 } };
sanitize(req, function(){
t.equal(req.clean.size, 1, 'min size set');
t.end();
});
});
test('above max size value', function(t) {
var req = { query: { size: 9999, 'point.lat': 0, 'point.lon': 0 } };
sanitize(req, function(){
t.equal(req.clean.size, 40, 'max size set');
t.end();
});
});
};
module.exports.tests.sanitize_private = function(test, common) {
var invalid_values = [null, -1, 123, NaN, 'abc'];
invalid_values.forEach(function(value) {
test('invalid private param ' + value, function(t) {
var req = { query: { 'point.lat': 0, 'point.lon': 0, 'private': value } };
sanitize(req, function(){
t.equal(req.clean.private, false, 'default private set (to false)');
t.end();
});
});
});
var valid_values = ['true', true, 1, '1'];
valid_values.forEach(function(value) {
test('valid private param ' + value, function(t) {
var req = { query: { 'point.lat': 0, 'point.lon': 0, 'private': value } };
sanitize(req, function(){
t.equal(req.clean.private, true, 'private set to true');
t.end();
});
});
});
var valid_false_values = ['false', false, 0];
valid_false_values.forEach(function(value) {
test('test setting false explicitly ' + value, function(t) {
var req = { query: { 'point.lat': 0, 'point.lon': 0, 'private': value } };
sanitize(req, function(){
t.equal(req.clean.private, false, 'private set to false');
t.end();
});
});
});
test('test default behavior', function(t) {
var req = { query: { 'point.lat': 0, 'point.lon': 0 } };
sanitize(req, function(){
t.equal(req.clean.private, false, 'private set to false');
t.end();
});
});
};
module.exports.tests.middleware_success = function(test, common) {
test('middleware success', function(t) {
var req = { query: { 'point.lat': 0, 'point.lon': 0 }};
var next = function(){
t.deepEqual(req.errors, [], 'no error message set');
t.deepEqual(req.clean, defaultClean);
t.end();
};
middleware( req, undefined, next );
});
};
module.exports.all = function (tape, common) {
function test(name, testFunction) {
return tape('SANTIZE /reverse ' + name, testFunction);
return tape('SANITIZE /reverse ' + name, testFunction);
}
for( var testCase in module.exports.tests ){

227
test/unit/sanitizer/sanitizeAll.js

@ -5,22 +5,26 @@ module.exports.tests = {};
module.exports.tests.all = function(test, common) {
test('req.clean/errors/warnings should be initialized when they are not', function(t) {
var req = {};
var sanitizers = [
function() {
req.clean.a = 'first sanitizer';
return {
errors: ['error 1', 'error 2'],
warnings: ['warning 1', 'warning 2']
};
var sanitizers = {
'first': {
sanitize: function(){
req.clean.a = 'first sanitizer';
return {
errors: ['error 1', 'error 2'],
warnings: ['warning 1', 'warning 2']
};
}
},
function() {
req.clean.b = 'second sanitizer';
return {
errors: ['error 3'],
warnings: ['warning 3']
};
'second': {
sanitize: function() {
req.clean.b = 'second sanitizer';
return {
errors: ['error 3'],
warnings: ['warning 3']
};
}
}
];
};
var expected_req = {
clean: {
@ -31,10 +35,9 @@ module.exports.tests.all = function(test, common) {
warnings: ['warning 1', 'warning 2', 'warning 3']
};
sanitizeAll(req, sanitizers, function(){
t.deepEquals(req, expected_req);
t.end();
});
sanitizeAll.runAllChecks(req, sanitizers);
t.deepEquals(req, expected_req);
t.end();
});
@ -47,22 +50,26 @@ module.exports.tests.all = function(test, common) {
warnings: ['pre-existing warning']
};
var sanitizers = [
function() {
req.clean.a = 'first sanitizer';
return {
errors: ['error 1', 'error 2'],
warnings: ['warning 1', 'warning 2']
};
var sanitizers = {
'first': {
sanitize: function(){
req.clean.a = 'first sanitizer';
return {
errors: ['error 1', 'error 2'],
warnings: ['warning 1', 'warning 2']
};
}
},
function() {
req.clean.b = 'second sanitizer';
return {
errors: ['error 3'],
warnings: ['warning 3']
};
'second': {
sanitize: function() {
req.clean.b = 'second sanitizer';
return {
errors: ['error 3'],
warnings: ['warning 3']
};
}
}
];
};
var expected_req = {
clean: {
@ -74,63 +81,63 @@ module.exports.tests.all = function(test, common) {
warnings: ['pre-existing warning', 'warning 1', 'warning 2', 'warning 3']
};
sanitizeAll(req, sanitizers, function(){
t.deepEquals(req, expected_req);
t.end();
});
sanitizeAll.runAllChecks(req, sanitizers);
t.deepEquals(req, expected_req);
t.end();
});
test('req.query should be passed to individual sanitizers when available', function(t) {
var req = {
query: {
value: 'query value'
value: 'query'
}
};
var sanitizers = [
function(params) {
req.clean.query = params;
return {
errors: [],
warnings: []
};
var sanitizers = {
'first': {
sanitize: function (params) {
req.clean.query = params;
return {
errors: [],
warnings: []
};
}
}
];
};
var expected_req = {
query: {
value: 'query value'
value: 'query'
},
clean: {
query: {
value: 'query value'
value: 'query'
}
},
errors: [],
warnings: []
};
sanitizeAll(req, sanitizers, function(){
t.deepEquals(req, expected_req);
t.end();
});
sanitizeAll.runAllChecks(req, sanitizers);
t.deepEquals(req, expected_req);
t.end();
});
test('an empty object should be passed to individual sanitizers when req.query is unavailable', function(t) {
var req = {};
var sanitizers = [
function(params) {
if (Object.keys(params).length === 0) {
req.clean.empty_object_was_passed = true;
var sanitizers = {
'first': {
sanitize: function(params) {
if (Object.keys(params).length === 0) {
req.clean.empty_object_was_passed = true;
}
return {
errors: [],
warnings: []
};
}
return {
errors: [],
warnings: []
};
}
];
};
var expected_req = {
clean: {
@ -140,11 +147,97 @@ module.exports.tests.all = function(test, common) {
warnings: []
};
sanitizeAll(req, sanitizers, function(){
t.deepEquals(req, expected_req);
t.end();
});
sanitizeAll.runAllChecks(req, sanitizers);
t.deepEquals(req, expected_req);
t.end();
});
test('unexpected parameters should add warning', function(t) {
var req = {
query: {
unknown_value: 'query value'
},
errors: [],
warnings: []
};
var sanitizers = {
'first': {
expected: function _expected () {
// add value as a valid parameter
return [{
name: 'value'
}];
}
}
};
sanitizeAll.checkParameters(req, sanitizers);
t.equals(req.errors.length, 0);
t.deepEquals(req.warnings[0], 'Invalid Parameter: unknown_value');
t.end();
});
test('expected parameters should not add warning', function(t) {
var req = {
query: {
value: 'query value'
},
errors: [],
warnings: []
};
var sanitizers = {
'first': {
expected: function _expected () {
// add value as a valid parameter
return [{
name: 'value'
}];
}
}
};
sanitizeAll.checkParameters(req, sanitizers);
t.equals(req.errors.length, 0);
t.equals(req.warnings.length, 0);
t.end();
});
test('sanitizer without expected() should not validate parameters', function(t) {
var req = {
query: {
value: 'query'
}
};
var sanitizers = {
'first': {
sanitize: function(params) {
req.clean.query = params;
return {
errors: [],
warnings: ['warning 1']
};
}
}
};
var expected_req = {
query: {
value: 'query'
},
clean: {
query: {
value: 'query'
}
},
errors: [],
warnings: ['warning 1']
};
sanitizeAll.runAllChecks(req, sanitizers);
t.deepEquals(req, expected_req);
t.end();
});
};

152
test/unit/sanitizer/search.js

@ -9,86 +9,122 @@ module.exports.tests.sanitize = (test, common) => {
// rather than re-verify the functionality of all the sanitizers, this test just verifies that they
// were all called correctly
// each mock dependency is a function that returns an object.
// the object contains a key called {function} sanitize,
// which pushes the name of the sanitizer to {array} called_sanitizers
const search = proxyquire('../../../sanitizer/search', {
'../sanitizer/_deprecate_quattroshapes': () => {
called_sanitizers.push('_deprecate_quattroshapes');
return { errors: [], warnings: [] };
'../sanitizer/_deprecate_quattroshapes': function () {
return {
sanitize: () => {
called_sanitizers.push('_deprecate_quattroshapes');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_single_scalar_parameters': () => {
called_sanitizers.push('_single_scalar_parameters');
return { errors: [], warnings: [] };
'../sanitizer/_single_scalar_parameters': function () {
return {
sanitize: () => {
called_sanitizers.push('_single_scalar_parameters');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_text': () => {
called_sanitizers.push('_text');
return { errors: [], warnings: [] };
'../sanitizer/_text': function () {
return {
sanitize: () => {
called_sanitizers.push('_text');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_size': function() {
if (_.isEmpty(arguments)) {
return () => {
called_sanitizers.push('_size');
return { errors: [], warnings: [] };
return {
sanitize: () => {
called_sanitizers.push('_size');
return { errors: [], warnings: [] };
}
};
} else {
throw new Error('should not have passed any parameters to _size');
}
},
'../sanitizer/_targets': (type) => {
'../sanitizer/_targets': function (type) {
if (['layers', 'sources'].indexOf(type) !== -1) {
return () => {
called_sanitizers.push(`_targets/${type}`);
return { errors: [], warnings: [] };
};
}
else {
return {
sanitize: () => {
called_sanitizers.push(`_targets/${type}`);
return { errors: [], warnings: [] };
}
};
} else {
throw new Error('incorrect parameters passed to _targets');
}
},
'../sanitizer/_sources_and_layers': () => {
called_sanitizers.push('_sources_and_layers');
return { errors: [], warnings: [] };
'../sanitizer/_sources_and_layers': function () {
return {
sanitize: () => {
called_sanitizers.push('_sources_and_layers');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_flag_bool': function() {
'../sanitizer/_flag_bool': function () {
if (arguments[0] === 'private' && arguments[1] === false) {
return () => {
called_sanitizers.push('_flag_bool');
return { errors: [], warnings: [] };
};
}
else {
throw new Error('incorrect parameters passed to _flag_bool');
return {
sanitize: () => {
called_sanitizers.push('_flag_bool');
return { errors: [], warnings: [] };
}
};
} else {
throw new Error('incorrect parameters passed to _flag_bool');
}
},
'../sanitizer/_geo_search': () => {
called_sanitizers.push('_geo_search');
return { errors: [], warnings: [] };
},
'../sanitizer/_boundary_country': () => {
called_sanitizers.push('_boundary_country');
return { errors: [], warnings: [] };
'../sanitizer/_geo_search': function () {
return {
sanitize: () => {
called_sanitizers.push('_geo_search');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_categories': () => {
called_sanitizers.push('_categories');
return { errors: [], warnings: [] };
'../sanitizer/_boundary_country': function () {
return {
sanitize: () => {
called_sanitizers.push('_boundary_country');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_geonames_warnings': () => {
called_sanitizers.push('_geonames_warnings');
return { errors: [], warnings: [] };
'../sanitizer/_categories': function () {
return {
sanitize: () => {
called_sanitizers.push('_categories');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_location_bias': (defaultParameters) => {
if (defaultParameters.key === 'value'){
return () => {
called_sanitizers.push('_location_bias');
'../sanitizer/_geonames_warnings': function () {
return {
sanitize: () => {
called_sanitizers.push('_geonames_warnings');
return { errors: [], warnings: [] };
};
} else {
throw new Error('incorrect parameter passed to _location_bias');
}
}
};
},
'../sanitizer/_location_bias': function (defaultParameters) {
return {
sanitize: () => {
if (defaultParameters.key === 'value'){
called_sanitizers.push('_location_bias');
return { errors: [], warnings: [] };
} else {
throw new Error('incorrect parameter passed to _location_bias');
}
}
};
}
});
@ -113,6 +149,7 @@ module.exports.tests.sanitize = (test, common) => {
const res = {};
const middleware = search.middleware({
// mock pelias config ap.defaultParameters section for location bias
defaultParameters: {
key: 'value'
}
@ -124,6 +161,7 @@ module.exports.tests.sanitize = (test, common) => {
});
});
};
module.exports.all = (tape, common) => {

197
test/unit/sanitizer/search_fallback.js

@ -0,0 +1,197 @@
var proxyquire = require('proxyquire').noCallThru();
module.exports.tests = {};
module.exports.tests.sanitize = function(test, common) {
test('verify that all sanitizers were called as expected when `res` is undefined', function(t) {
var called_sanitizers = [];
// rather than re-verify the functionality of all the sanitizers, this test just verifies that they
// were all called correctly
var search = proxyquire('../../../sanitizer/search_fallback', {
'../sanitizer/_text_addressit': function () {
return {
sanitize: () => {
called_sanitizers.push('_text_addressit');
return { errors: [], warnings: [] };
}
};
}
});
var expected_sanitizers = [
'_text_addressit'
];
var req = {};
search.middleware(req, undefined, function(){
t.deepEquals(called_sanitizers, expected_sanitizers);
t.end();
});
});
test('verify that all sanitizers were called as expected when `res` has no `data` property', function(t) {
var called_sanitizers = [];
// rather than re-verify the functionality of all the sanitizers, this test just verifies that they
// were all called correctly
var search = proxyquire('../../../sanitizer/search_fallback', {
'../sanitizer/_text_addressit': function () {
return {
sanitize: () => {
called_sanitizers.push('_text_addressit');
return { errors: [], warnings: [] };
}
};
},
});
var expected_sanitizers = [
'_text_addressit'
];
var req = {};
var res = {};
search.middleware(req, res, function(){
t.deepEquals(called_sanitizers, expected_sanitizers);
t.end();
});
});
test('verify that all sanitizers were called as expected when res.data is empty', function(t) {
var called_sanitizers = [];
// rather than re-verify the functionality of all the sanitizers, this test just verifies that they
// were all called correctly
var search = proxyquire('../../../sanitizer/search_fallback', {
'../sanitizer/_text_addressit': function () {
return {
sanitize: () => {
called_sanitizers.push('_text_addressit');
return { errors: [], warnings: [] };
}
};
},
});
var expected_sanitizers = [
'_text_addressit'
];
var req = {};
var res = {
data: []
};
search.middleware(req, res, function(){
t.deepEquals(called_sanitizers, expected_sanitizers);
t.end();
});
});
test('non-empty res.data should not call the _text_autocomplete sanitizer', function(t) {
var called_sanitizers = [];
// rather than re-verify the functionality of all the sanitizers, this test just verifies that they
// were all called correctly
var search = proxyquire('../../../sanitizer/search_fallback', {
'../sanitizer/_text_autocomplete': function() {
throw new Error('_text_autocomplete sanitizer should not have been called');
}
});
var expected_sanitizers = [];
var req = {};
var res = {
data: [{}]
};
search.middleware(req, res, function(){
t.deepEquals(called_sanitizers, expected_sanitizers);
t.end();
});
});
test('req.clean.text should be logged when isDNT=false', (t) => {
const infoLog = [];
const search = proxyquire('../../../sanitizer/search_fallback', {
'pelias-logger': {
get: () => {
return {
info: (msg) => {
infoLog.push(msg);
}
};
}
},
'../helper/logging': {
isDNT: () => { return false; }
}
});
const req = {
path: '/v1/search',
clean: {
text: 'this is the query text'
}
};
search.middleware(req, undefined, () => {
t.deepEquals(infoLog, [`fallback queryText: ${req.clean.text}`]);
t.end();
});
});
test('req.clean.text should not be logged when isDNT=true', (t) => {
const infoLog = [];
const search = proxyquire('../../../sanitizer/search_fallback', {
'pelias-logger': {
get: () => {
return {
info: (msg) => {
infoLog.push(msg);
}
};
}
},
'../helper/logging': {
isDNT: () => { return true; }
}
});
const req = {
path: '/v1/search',
clean: {
text: 'this is the query text'
}
};
search.middleware(req, undefined, () => {
t.deepEquals(infoLog, ['fallback queryText: [text removed]']);
t.end();
});
});
};
module.exports.all = function (tape, common) {
function test(name, testFunction) {
return tape('SANITIZE /search_fallback ' + name, testFunction);
}
for( var testCase in module.exports.tests ){
module.exports.tests[testCase](test, common);
}
};

159
test/unit/sanitizer/structured_geocoding.js

@ -1,4 +1,5 @@
var proxyquire = require('proxyquire').noCallThru();
const _ = require('lodash');
module.exports.tests = {};
@ -9,89 +10,125 @@ module.exports.tests.sanitize = function(test, common) {
// rather than re-verify the functionality of all the sanitizers, this test just verifies that they
// were all called correctly
var search = proxyquire('../../../sanitizer/structured_geocoding', {
'../sanitizer/_deprecate_quattroshapes': function() {
called_sanitizers.push('_deprecate_quattroshapes');
return { errors: [], warnings: [] };
},
'../sanitizer/_single_scalar_parameters': function() {
called_sanitizers.push('_single_scalar_parameters');
return { errors: [], warnings: [] };
'../sanitizer/_deprecate_quattroshapes': function () {
return {
sanitize: () => {
called_sanitizers.push('_deprecate_quattroshapes');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_synthesize_analysis': function() {
called_sanitizers.push('_synthesize_analysis');
return { errors: [], warnings: [] };
'../sanitizer/_single_scalar_parameters': function () {
return {
sanitize: () => {
called_sanitizers.push('_single_scalar_parameters');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_iso2_to_iso3': function() {
called_sanitizers.push('_iso2_to_iso3');
return { errors: [], warnings: [] };
'../sanitizer/_synthesize_analysis': function () {
return {
sanitize: () => {
called_sanitizers.push('_synthesize_analysis');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_city_name_standardizer': function() {
called_sanitizers.push('_city_name_standardizer');
return { errors: [], warnings: [] };
'../sanitizer/_iso2_to_iso3': function () {
return {
sanitize: () => {
called_sanitizers.push('_iso2_to_iso3');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_size': function() {
if (arguments.length === 0) {
return function() {
called_sanitizers.push('_size');
'../sanitizer/_city_name_standardizer': function () {
return {
sanitize: () => {
called_sanitizers.push('_city_name_standardizer');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_size': function () {
if (_.isEmpty(arguments)) {
return {
sanitize: () => {
called_sanitizers.push('_size');
return { errors: [], warnings: [] };
}
};
} else {
throw new Error('should not have passed any parameters to _size');
}
},
'../sanitizer/_targets': function(type) {
'../sanitizer/_targets': function (type) {
if (['layers', 'sources'].indexOf(type) !== -1) {
return function() {
called_sanitizers.push('_targets/' + type);
return { errors: [], warnings: [] };
};
}
else {
return {
sanitize: () => {
called_sanitizers.push(`_targets/${type}`);
return { errors: [], warnings: [] };
}
};
} else {
throw new Error('incorrect parameters passed to _targets');
}
},
'../sanitizer/_sources_and_layers': function() {
called_sanitizers.push('_sources_and_layers');
return { errors: [], warnings: [] };
'../sanitizer/_sources_and_layers': function () {
return {
sanitize: () => {
called_sanitizers.push('_sources_and_layers');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_flag_bool': function() {
'../sanitizer/_flag_bool': function () {
if (arguments[0] === 'private' && arguments[1] === false) {
return function() {
called_sanitizers.push('_flag_bool');
return { errors: [], warnings: [] };
};
}
else {
throw new Error('incorrect parameters passed to _flag_bool');
return {
sanitize: () => {
called_sanitizers.push('_flag_bool');
return { errors: [], warnings: [] };
}
};
} else {
throw new Error('incorrect parameters passed to _flag_bool');
}
},
'../sanitizer/_geo_search': function() {
called_sanitizers.push('_geo_search');
return { errors: [], warnings: [] };
'../sanitizer/_geo_search': function () {
return {
sanitize: () => {
called_sanitizers.push('_geo_search');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_boundary_country': function() {
called_sanitizers.push('_boundary_country');
return { errors: [], warnings: [] };
'../sanitizer/_boundary_country': function () {
return {
sanitize: () => {
called_sanitizers.push('_boundary_country');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_categories': function() {
called_sanitizers.push('_categories');
return { errors: [], warnings: [] };
'../sanitizer/_categories': function () {
return {
sanitize: () => {
called_sanitizers.push('_categories');
return { errors: [], warnings: [] };
}
};
},
'../sanitizer/_location_bias': function (defaultParameters) {
if (defaultParameters.key === 'value'){
return () => {
called_sanitizers.push('_location_bias');
return { errors: [], warnings: [] };
};
} else {
throw new Error('incorrect parameter passed to _location_bias');
}
return {
sanitize: () => {
if (defaultParameters.key === 'value'){
called_sanitizers.push('_location_bias');
return { errors: [], warnings: [] };
} else {
throw new Error('incorrect parameter passed to _location_bias');
}
}
};
}
});

Loading…
Cancel
Save