From 13a7b42de74e91c5d13eacdcae0121e53b9c9306 Mon Sep 17 00:00:00 2001 From: Lily He Date: Fri, 21 Jul 2017 17:09:25 -0400 Subject: [PATCH 01/17] Standardize sanitizers to export setup function that returns sanitize and expected function --- sanitizer/_boundary_country.js | 15 ++- sanitizer/_categories.js | 11 +- sanitizer/_city_name_standardizer.js | 6 +- sanitizer/_deprecate_quattroshapes.js | 6 +- sanitizer/_flag_bool.js | 68 +++++----- sanitizer/_geo_autocomplete.js | 19 ++- sanitizer/_geo_reverse.js | 16 ++- sanitizer/_geo_search.js | 22 +++- sanitizer/_geonames_deprecation.js | 8 +- sanitizer/_geonames_warnings.js | 6 +- sanitizer/_ids.js | 10 +- sanitizer/_iso2_to_iso3.js | 6 +- sanitizer/_location_bias.js | 37 +++--- sanitizer/_single_scalar_parameters.js | 6 +- sanitizer/_size.js | 59 +++++---- sanitizer/_sources_and_layers.js | 11 +- sanitizer/_synthesize_analysis.js | 19 ++- sanitizer/_targets.js | 118 +++++++++--------- sanitizer/_text.js | 11 +- sanitizer/_text_addressit.js | 8 +- sanitizer/_tokenizer.js | 6 +- test/unit/sanitizer/_boundary_country.js | 25 ++-- test/unit/sanitizer/_categories.js | 27 ++-- .../unit/sanitizer/_city_name_standardizer.js | 20 +-- .../sanitizer/_deprecate_quattroshapes.js | 10 +- test/unit/sanitizer/_flag_bool.js | 20 ++- test/unit/sanitizer/_geo_reverse.js | 10 +- test/unit/sanitizer/_geonames_deprecation.js | 12 +- test/unit/sanitizer/_geonames_warnings.js | 12 +- test/unit/sanitizer/_ids.js | 39 +++--- test/unit/sanitizer/_iso2_to_iso3.js | 12 +- test/unit/sanitizer/_layers.js | 24 ++-- test/unit/sanitizer/_location_bias.js | 26 ++-- .../sanitizer/_single_scalar_parameters.js | 14 +-- test/unit/sanitizer/_size.js | 18 ++- test/unit/sanitizer/_sources.js | 14 +-- test/unit/sanitizer/_sources_and_layers.js | 31 +++-- test/unit/sanitizer/_synthesize_analysis.js | 31 +++-- test/unit/sanitizer/_text.js | 13 +- test/unit/sanitizer/_text_addressit.js | 30 ++--- test/unit/sanitizer/_tokenizer.js | 38 +++--- 41 files changed, 544 insertions(+), 350 deletions(-) diff --git a/sanitizer/_boundary_country.js b/sanitizer/_boundary_country.js index b859013e..2b7f9bb3 100644 --- a/sanitizer/_boundary_country.js +++ b/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 +}); diff --git a/sanitizer/_categories.js b/sanitizer/_categories.js index 06e65800..b964d1e7 100644 --- a/sanitizer/_categories.js +++ b/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 +}); diff --git a/sanitizer/_city_name_standardizer.js b/sanitizer/_city_name_standardizer.js index 3bcf817d..6724eda1 100644 --- a/sanitizer/_city_name_standardizer.js +++ b/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 +}); diff --git a/sanitizer/_deprecate_quattroshapes.js b/sanitizer/_deprecate_quattroshapes.js index bd45c025..50f3af8e 100644 --- a/sanitizer/_deprecate_quattroshapes.js +++ b/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 +}); diff --git a/sanitizer/_flag_bool.js b/sanitizer/_flag_bool.js index 4ed5c339..aab2daac 100644 --- a/sanitizer/_flag_bool.js +++ b/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: 'private'}]; + } // 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; diff --git a/sanitizer/_geo_autocomplete.js b/sanitizer/_geo_autocomplete.js index 45c2f921..e6ba948b 100644 --- a/sanitizer/_geo_autocomplete.js +++ b/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 +}); diff --git a/sanitizer/_geo_reverse.js b/sanitizer/_geo_reverse.js index 1bb85043..da811219 100644 --- a/sanitizer/_geo_reverse.js +++ b/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,16 @@ module.exports = function sanitize( raw, clean ){ } return messages; -}; +} + +function _expected(){ + return [ + { name: 'point.lat' }, + { name: 'point.lon' }, + { name: 'boundary.circle.radius'}]; +} + +module.exports = () => ({ + sanitize: _sanitize, + expected: _expected +}); diff --git a/sanitizer/_geo_search.js b/sanitizer/_geo_search.js index ae820fbf..b41184e7 100644 --- a/sanitizer/_geo_search.js +++ b/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 +}); diff --git a/sanitizer/_geonames_deprecation.js b/sanitizer/_geonames_deprecation.js index ceb4e591..b3cc8185 100644 --- a/sanitizer/_geonames_deprecation.js +++ b/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 +}); diff --git a/sanitizer/_geonames_warnings.js b/sanitizer/_geonames_warnings.js index eda12131..3422c4f6 100644 --- a/sanitizer/_geonames_warnings.js +++ b/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 +}); diff --git a/sanitizer/_ids.js b/sanitizer/_ids.js index ba456766..89590ac3 100644 --- a/sanitizer/_ids.js +++ b/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 +}); diff --git a/sanitizer/_iso2_to_iso3.js b/sanitizer/_iso2_to_iso3.js index d8fc1837..6b37cec2 100644 --- a/sanitizer/_iso2_to_iso3.js +++ b/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 +}); diff --git a/sanitizer/_location_bias.js b/sanitizer/_location_bias.js index 4c9c7f8b..ee99e5e9 100644 --- a/sanitizer/_location_bias.js +++ b/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; diff --git a/sanitizer/_single_scalar_parameters.js b/sanitizer/_single_scalar_parameters.js index 2b06cc65..4c49fc21 100644 --- a/sanitizer/_single_scalar_parameters.js +++ b/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 +}); diff --git a/sanitizer/_size.js b/sanitizer/_size.js index b2b5e62e..aaced3f9 100644 --- a/sanitizer/_size.js +++ b/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 for joi + 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; diff --git a/sanitizer/_sources_and_layers.js b/sanitizer/_sources_and_layers.js index fa0325b2..97b56049 100644 --- a/sanitizer/_sources_and_layers.js +++ b/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 +}); diff --git a/sanitizer/_synthesize_analysis.js b/sanitizer/_synthesize_analysis.js index 6c702f9e..a4764549 100644 --- a/sanitizer/_synthesize_analysis.js +++ b/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 +}); diff --git a/sanitizer/_targets.js b/sanitizer/_targets.js index a8a50400..180f9442 100644 --- a/sanitizer/_targets.js +++ b/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; diff --git a/sanitizer/_text.js b/sanitizer/_text.js index 82662473..19e5f5b5 100644 --- a/sanitizer/_text.js +++ b/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' }, { name: 'parsed_text' }]; +} // export function -module.exports = sanitize; +module.exports = () => ({ + sanitize: _sanitize, + expected: _expected +}); diff --git a/sanitizer/_text_addressit.js b/sanitizer/_text_addressit.js index 68a293bf..6c34699a 100644 --- a/sanitizer/_text_addressit.js +++ b/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: [] }; @@ -36,9 +36,9 @@ function sanitize( raw, clean ){ } // export function -module.exports = sanitize; - - +module.exports = () => ({ + sanitize: _sanitize +}); // this is the addressit functionality from https://github.com/pelias/text-analyzer/blob/master/src/addressItParser.js var DELIM = ','; diff --git a/sanitizer/_tokenizer.js b/sanitizer/_tokenizer.js index 328cd1aa..18b5d3e0 100644 --- a/sanitizer/_tokenizer.js +++ b/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 +}); diff --git a/test/unit/sanitizer/_boundary_country.js b/test/unit/sanitizer/_boundary_country.js index 9411acdf..7649da66 100644 --- a/test/unit/sanitizer/_boundary_country.js +++ b/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 valid parameters in object form for Joi schema 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 ){ diff --git a/test/unit/sanitizer/_categories.js b/test/unit/sanitizer/_categories.js index 64e9555f..84589098 100644 --- a/test/unit/sanitizer/_categories.js +++ b/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 valid parameters in object form for Joi schema 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 ){ diff --git a/test/unit/sanitizer/_city_name_standardizer.js b/test/unit/sanitizer/_city_name_standardizer.js index da362868..5a01e58b 100644 --- a/test/unit/sanitizer/_city_name_standardizer.js +++ b/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'); diff --git a/test/unit/sanitizer/_deprecate_quattroshapes.js b/test/unit/sanitizer/_deprecate_quattroshapes.js index 61b581aa..d468b97f 100644 --- a/test/unit/sanitizer/_deprecate_quattroshapes.js +++ b/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 ){ diff --git a/test/unit/sanitizer/_flag_bool.js b/test/unit/sanitizer/_flag_bool.js index 55ecdc94..04e31f49 100644 --- a/test/unit/sanitizer/_flag_bool.js +++ b/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 valid parameters in object form for Joi schema validation', (t) => { + const expected = [{ name: 'private' }]; + const validParameters = sanitizer('dirty_param', 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 ){ diff --git a/test/unit/sanitizer/_geo_reverse.js b/test/unit/sanitizer/_geo_reverse.js index 223cf9fa..c2fa6bd9 100644 --- a/test/unit/sanitizer/_geo_reverse.js +++ b/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); diff --git a/test/unit/sanitizer/_geonames_deprecation.js b/test/unit/sanitizer/_geonames_deprecation.js index f7676db3..41bd86c6 100644 --- a/test/unit/sanitizer/_geonames_deprecation.js +++ b/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 ){ diff --git a/test/unit/sanitizer/_geonames_warnings.js b/test/unit/sanitizer/_geonames_warnings.js index 47881781..d4e20e6c 100644 --- a/test/unit/sanitizer/_geonames_warnings.js +++ b/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, ' + diff --git a/test/unit/sanitizer/_ids.js b/test/unit/sanitizer/_ids.js index e1dfb680..f376c2ca 100644 --- a/test/unit/sanitizer/_ids.js +++ b/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 valid parameters in object form for Joi schema 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 ){ diff --git a/test/unit/sanitizer/_iso2_to_iso3.js b/test/unit/sanitizer/_iso2_to_iso3.js index 7d27499b..27fe7eb6 100644 --- a/test/unit/sanitizer/_iso2_to_iso3.js +++ b/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 ){ diff --git a/test/unit/sanitizer/_layers.js b/test/unit/sanitizer/_layers.js index 5a0c0693..11c618c8 100644 --- a/test/unit/sanitizer/_layers.js +++ b/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 ){ diff --git a/test/unit/sanitizer/_location_bias.js b/test/unit/sanitizer/_location_bias.js index 6778f045..35afca38 100644 --- a/test/unit/sanitizer/_location_bias.js +++ b/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(); }); diff --git a/test/unit/sanitizer/_single_scalar_parameters.js b/test/unit/sanitizer/_single_scalar_parameters.js index c3322703..1710caa8 100644 --- a/test/unit/sanitizer/_single_scalar_parameters.js +++ b/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(); }); diff --git a/test/unit/sanitizer/_size.js b/test/unit/sanitizer/_size.js index 6553685d..0bd1e415 100644 --- a/test/unit/sanitizer/_size.js +++ b/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 valid parameters in object form for Joi schema 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 ){ diff --git a/test/unit/sanitizer/_sources.js b/test/unit/sanitizer/_sources.js index e8eb8ef5..e14f88dc 100644 --- a/test/unit/sanitizer/_sources.js +++ b/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'); diff --git a/test/unit/sanitizer/_sources_and_layers.js b/test/unit/sanitizer/_sources_and_layers.js index f506c1f9..b0266095 100644 --- a/test/unit/sanitizer/_sources_and_layers.js +++ b/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 valid parameters in object form for Joi schema 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` ' + diff --git a/test/unit/sanitizer/_synthesize_analysis.js b/test/unit/sanitizer/_synthesize_analysis.js index 82352c8d..fd13b947 100644 --- a/test/unit/sanitizer/_synthesize_analysis.js +++ b/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 valid parameters in object form for Joi schema 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) { diff --git a/test/unit/sanitizer/_text.js b/test/unit/sanitizer/_text.js index 78b9a676..2692967d 100644 --- a/test/unit/sanitizer/_text.js +++ b/test/unit/sanitizer/_text.js @@ -1,4 +1,4 @@ -const sanitizer = require('../../../sanitizer/_text'); +const sanitizer = require('../../../sanitizer/_text')(); module.exports.tests = {}; @@ -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,13 @@ 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) => { diff --git a/test/unit/sanitizer/_text_addressit.js b/test/unit/sanitizer/_text_addressit.js index 26989c18..5d8f0d47 100644 --- a/test/unit/sanitizer/_text_addressit.js +++ b/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); diff --git a/test/unit/sanitizer/_tokenizer.js b/test/unit/sanitizer/_tokenizer.js index c5208ffe..e5becebb 100644 --- a/test/unit/sanitizer/_tokenizer.js +++ b/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, [ From 368c0aa4cb0884e0b331335d9be9b68084083e17 Mon Sep 17 00:00:00 2001 From: Lily He Date: Fri, 28 Jul 2017 15:34:31 -0400 Subject: [PATCH 02/17] added expected parameters list to _text_addressit --- sanitizer/_text_addressit.js | 7 ++++++- test/unit/sanitizer/_text_addressit.js | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/sanitizer/_text_addressit.js b/sanitizer/_text_addressit.js index 6c34699a..381eebb7 100644 --- a/sanitizer/_text_addressit.js +++ b/sanitizer/_text_addressit.js @@ -35,9 +35,14 @@ function _sanitize( raw, clean ){ return messages; } +function _expected(){ + return [{ name: 'text' }]; +} + // export function module.exports = () => ({ - sanitize: _sanitize + sanitize: _sanitize, + expected: _expected }); // this is the addressit functionality from https://github.com/pelias/text-analyzer/blob/master/src/addressItParser.js diff --git a/test/unit/sanitizer/_text_addressit.js b/test/unit/sanitizer/_text_addressit.js index 5d8f0d47..c5291635 100644 --- a/test/unit/sanitizer/_text_addressit.js +++ b/test/unit/sanitizer/_text_addressit.js @@ -339,6 +339,12 @@ module.exports.tests.text_parser = function(test, common) { }); + test('return an array of valid parameters in object form for Joi schema validation', (t) => { + const expected = [{ name: 'text' }]; + const validParameters = sanitizer.expected(); + t.deepEquals(validParameters, expected); + t.end(); + }); }; module.exports.all = function (tape, common) { From a683e27a871c2439ace558d283680800bc01c391 Mon Sep 17 00:00:00 2001 From: Lily He Date: Fri, 28 Jul 2017 15:35:45 -0400 Subject: [PATCH 03/17] removed 'parsed_text' from list of expected params for _text --- sanitizer/_text.js | 2 +- test/unit/sanitizer/_text.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/sanitizer/_text.js b/sanitizer/_text.js index 19e5f5b5..1df63411 100644 --- a/sanitizer/_text.js +++ b/sanitizer/_text.js @@ -22,7 +22,7 @@ function _sanitize( raw, clean ){ } function _expected(){ - return [{ name: 'text' }, { name: 'parsed_text' }]; + return [{ name: 'text' }]; } // export function module.exports = () => ({ diff --git a/test/unit/sanitizer/_text.js b/test/unit/sanitizer/_text.js index 2692967d..0a6729b1 100644 --- a/test/unit/sanitizer/_text.js +++ b/test/unit/sanitizer/_text.js @@ -52,7 +52,6 @@ module.exports.tests.text_parser = function(test, common) { t.deepEquals(validParameters, expected); t.end(); }); - }; module.exports.all = (tape, common) => { From af906c05a8fc021d02025e6c3bb30a638f80d713 Mon Sep 17 00:00:00 2001 From: Lily He Date: Fri, 28 Jul 2017 15:41:05 -0400 Subject: [PATCH 04/17] sanitizeAll validates req.query parameters, export async runAllChecks function --- sanitizer/sanitizeAll.js | 51 ++++++++- test/unit/sanitizer/sanitizeAll.js | 172 ++++++++++++++++++++--------- 2 files changed, 166 insertions(+), 57 deletions(-) diff --git a/sanitizer/sanitizeAll.js b/sanitizer/sanitizeAll.js index f6af363e..dafa1cb8 100644 --- a/sanitizer/sanitizeAll.js +++ b/sanitizer/sanitizeAll.js @@ -1,3 +1,5 @@ +const async = require('async'); + function sanitize( req, sanitizers, cb ){ // init an object to store clean (sanitized) input parameters if not initialized req.clean = req.clean || {}; @@ -8,10 +10,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 ); + var sanity = sanitizers[s].sanitize( params, req.clean ); // if errors occurred then set them // on the req object. @@ -25,10 +27,51 @@ function sanitize( req, sanitizers, cb ){ req.warnings = req.warnings.concat( sanity.warnings ); } } + return cb( undefined, req.clean ); +} + +// Adds to schemaKeys every acceptable parameter passed through API call +function checkParameters(req, sanitizers, cb) { + // source of input parameters + // (in this case from the GET querystring params) + const params = req.query || {}; + const goodParameters = {}; + + for (var s in sanitizers) { - // @todo remove these args, they do not need to be passed out + // checks if there is a function that returns valid params + if (typeof sanitizers[s].expected === 'function'){ + /** func returns {array} ex: [{ name: 'text' }, { name: 'parsed_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, add a warning to messages + for (let p in params) { + if (!goodParameters.hasOwnProperty(p)){ + req.warnings = req.warnings.concat('Invalid Parameter: ' + p); + } + } return cb( undefined, req.clean ); } +// runs both sanitize and checkParameters functions in async parallel +function runAllChecks (req, sanitizers, cb) { + async.parallel([ + sanitize.bind(null, req, sanitizers), + checkParameters.bind(null, req, sanitizers) + ], cb); +} + // export function -module.exports = sanitize; +module.exports = { + sanitize: sanitize, + checkParameters: checkParameters, + runAllChecks: runAllChecks +}; diff --git a/test/unit/sanitizer/sanitizeAll.js b/test/unit/sanitizer/sanitizeAll.js index bcddba05..5e81aada 100644 --- a/test/unit/sanitizer/sanitizeAll.js +++ b/test/unit/sanitizer/sanitizeAll.js @@ -1,26 +1,31 @@ var sanitizeAll = require('../../../sanitizer/sanitizeAll'); +const Joi = require('joi'); 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,7 +36,7 @@ module.exports.tests.all = function(test, common) { warnings: ['warning 1', 'warning 2', 'warning 3'] }; - sanitizeAll(req, sanitizers, function(){ + sanitizeAll.sanitize(req, sanitizers, function (){ t.deepEquals(req, expected_req); t.end(); }); @@ -47,22 +52,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,7 +83,7 @@ module.exports.tests.all = function(test, common) { warnings: ['pre-existing warning', 'warning 1', 'warning 2', 'warning 3'] }; - sanitizeAll(req, sanitizers, function(){ + sanitizeAll.sanitize(req, sanitizers, function () { t.deepEquals(req, expected_req); t.end(); }); @@ -84,33 +93,35 @@ module.exports.tests.all = function(test, common) { 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(){ + sanitizeAll.sanitize(req, sanitizers, function () { t.deepEquals(req, expected_req); t.end(); }); @@ -119,18 +130,20 @@ module.exports.tests.all = function(test, common) { 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,13 +153,66 @@ module.exports.tests.all = function(test, common) { warnings: [] }; - sanitizeAll(req, sanitizers, function(){ + sanitizeAll.sanitize(req, sanitizers, function () { t.deepEquals(req, expected_req); t.end(); }); }); + test('unexpected parameters should throw warning', function(t) { + var req = { + query: { + unknown_value: 'query value' + }, + errors: [], + warnings: [] + }; + var sanitizers = { + 'first': { + expected: function _expected () { + // add value as a valid parameter for joi + return [{ + name: 'value' + }]; + } + } + }; + + sanitizeAll.checkParameters(req, sanitizers, function () { + t.equals(req.errors.length, 0); + t.deepEquals(req.warnings[0], 'Invalid Parameter: unknown_value'); + t.end(); + }); + + }); + + test('expected parameters should not throw warning', function(t) { + var req = { + query: { + value: 'query value' + }, + errors: [], + warnings: [] + }; + var sanitizers = { + 'first': { + expected: function _expected () { + // add value as a valid parameter for joi + return [{ + name: 'value' + }]; + } + } + }; + + sanitizeAll.checkParameters(req, sanitizers, function () { + t.equals(req.errors.length, 0); + t.equals(req.warnings.length, 0); + t.end(); + }); + }); + }; module.exports.all = function (tape, common) { From 048696752645f472dabfdcc90d84b4763ef0781a Mon Sep 17 00:00:00 2001 From: Lily He Date: Fri, 28 Jul 2017 15:42:58 -0400 Subject: [PATCH 05/17] add two more acceptable params for _geo_reverse --- sanitizer/_geo_reverse.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sanitizer/_geo_reverse.js b/sanitizer/_geo_reverse.js index da811219..885ae15e 100644 --- a/sanitizer/_geo_reverse.js +++ b/sanitizer/_geo_reverse.js @@ -44,6 +44,8 @@ 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'}]; } From 1f527be3e3ac434efeaac5fa1b239a601c146c9d Mon Sep 17 00:00:00 2001 From: Lily He Date: Fri, 28 Jul 2017 15:56:30 -0400 Subject: [PATCH 06/17] call runAllChecks for search, search_fallback, autocomplete & structured sanitizing --- sanitizer/autocomplete.js | 22 +-- sanitizer/search.js | 26 +-- sanitizer/search_fallback.js | 34 ++++ sanitizer/structured_geocoding.js | 28 +-- test/unit/sanitizer/autocomplete.js | 139 ++++++++------ test/unit/sanitizer/search.js | 152 +++++++++------ test/unit/sanitizer/search_fallback.js | 197 ++++++++++++++++++++ test/unit/sanitizer/structured_geocoding.js | 159 ++++++++++------ 8 files changed, 548 insertions(+), 209 deletions(-) create mode 100644 sanitizer/search_fallback.js create mode 100644 test/unit/sanitizer/search_fallback.js diff --git a/sanitizer/autocomplete.js b/sanitizer/autocomplete.js index ed875bf5..55315e41 100644 --- a/sanitizer/autocomplete.js +++ b/sanitizer/autocomplete.js @@ -4,30 +4,28 @@ 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 ){ + return ( req, res, next ) => { + sanitizeAll.runAllChecks(req, sanitizers, ( err, clean ) => { if( err ){ res.status(400); // 400 Bad Request return next(err); } - next(); + next(); }); }; }; diff --git a/sanitizer/search.js b/sanitizer/search.js index 4319e55c..c36a4d14 100644 --- a/sanitizer/search.js +++ b/sanitizer/search.js @@ -3,27 +3,29 @@ 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 ){ + return ( req, res, next ) => { + sanitizeAll.runAllChecks(req, sanitizers, ( err, clean ) => { + if( err ){ + res.status(400); // 400 Bad Request + return next(err); + } next(); }); }; diff --git a/sanitizer/search_fallback.js b/sanitizer/search_fallback.js new file mode 100644 index 00000000..628ee4b8 --- /dev/null +++ b/sanitizer/search_fallback.js @@ -0,0 +1,34 @@ +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, ( err, clean ) => { + if( err ){ + res.status(400); // 400 Bad Request + return next(err); + } + next(); + }); + +}; diff --git a/sanitizer/structured_geocoding.js b/sanitizer/structured_geocoding.js index e19a2837..f5c95afc 100644 --- a/sanitizer/structured_geocoding.js +++ b/sanitizer/structured_geocoding.js @@ -4,27 +4,31 @@ 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 ){ + return ( req, res, next ) => { + sanitizeAll.runAllChecks(req, sanitizers, ( err, clean ) => { + if( err ){ + res.status(400); // 400 Bad Request + return next(err); + } next(); }); }; + }; diff --git a/test/unit/sanitizer/autocomplete.js b/test/unit/sanitizer/autocomplete.js index 9f0b4a3a..db46765e 100644 --- a/test/unit/sanitizer/autocomplete.js +++ b/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 = [ diff --git a/test/unit/sanitizer/search.js b/test/unit/sanitizer/search.js index e887280a..420c3a87 100644 --- a/test/unit/sanitizer/search.js +++ b/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) => { diff --git a/test/unit/sanitizer/search_fallback.js b/test/unit/sanitizer/search_fallback.js new file mode 100644 index 00000000..49c7294b --- /dev/null +++ b/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); + } +}; diff --git a/test/unit/sanitizer/structured_geocoding.js b/test/unit/sanitizer/structured_geocoding.js index 3cc10432..93cc8c21 100644 --- a/test/unit/sanitizer/structured_geocoding.js +++ b/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'); + } + } + }; } }); From 670c673419028a626adb525efb241849d253266f Mon Sep 17 00:00:00 2001 From: Lily He Date: Fri, 28 Jul 2017 15:59:47 -0400 Subject: [PATCH 07/17] call runAllChecks for nearby, reverse, and place sanitizing --- sanitizer/nearby.js | 10 +++++++--- sanitizer/place.js | 14 +++++++++----- sanitizer/reverse.js | 20 ++++++++++++-------- test/unit/sanitizer/nearby.js | 5 +++-- test/unit/sanitizer/place.js | 15 ++++++++------- test/unit/sanitizer/reverse.js | 29 +++++++++++++++-------------- 6 files changed, 54 insertions(+), 39 deletions(-) diff --git a/sanitizer/nearby.js b/sanitizer/nearby.js index d518b997..46f1ae2c 100644 --- a/sanitizer/nearby.js +++ b/sanitizer/nearby.js @@ -4,10 +4,10 @@ var reverseSanitizers = require('./reverse').sanitizer_list; // add categories to the sanitizer list var sanitizers = _.merge({}, reverseSanitizers, { - categories: require('../sanitizer/_categories') + categories: require('../sanitizer/_categories')() }); -var sanitize = function(req, cb) { sanitizeAll(req, sanitizers, cb); }; +var sanitize = sanitizeAll.runAllChecks; // export sanitize for testing module.exports.sanitize = sanitize; @@ -15,7 +15,11 @@ module.exports.sanitizer_list = sanitizers; // middleware module.exports.middleware = function( req, res, next ){ - sanitize( req, function( err, clean ){ + sanitize(req, sanitizers, ( err, clean ) => { + if( err ){ + res.status(400); // 400 Bad Request + return next(err); + } next(); }); }; diff --git a/sanitizer/place.js b/sanitizer/place.js index 3a6d4408..363fa7ef 100644 --- a/sanitizer/place.js +++ b/sanitizer/place.js @@ -1,20 +1,24 @@ 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); }; +var sanitize = sanitizeAll.runAllChecks; // 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 ){ +module.exports.middleware = function(req, res, next){ + sanitize(req, sanitizers, ( err, clean ) => { + if( err ){ + res.status(400); // 400 Bad Request + return next(err); + } next(); }); }; diff --git a/sanitizer/reverse.js b/sanitizer/reverse.js index e5ef3272..0a02f9a8 100644 --- a/sanitizer/reverse.js +++ b/sanitizer/reverse.js @@ -2,20 +2,20 @@ 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); }; +var sanitize = sanitizeAll.runAllChecks; // export sanitize for testing module.exports.sanitize = sanitize; @@ -23,7 +23,11 @@ module.exports.sanitizer_list = sanitizers; // middleware module.exports.middleware = function( req, res, next ){ - sanitize( req, function( err, clean ){ + sanitize(req, sanitizers, ( err, clean ) => { + if( err ){ + res.status(400); // 400 Bad Request + return next(err); + } next(); }); }; diff --git a/test/unit/sanitizer/nearby.js b/test/unit/sanitizer/nearby.js index 72be019a..f816ea62 100644 --- a/test/unit/sanitizer/nearby.js +++ b/test/unit/sanitizer/nearby.js @@ -3,6 +3,7 @@ var nearby = require('../../../sanitizer/nearby'); var defaults = require('../../../query/reverse_defaults'); var sanitize = nearby.sanitize; var middleware = nearby.middleware; +var sanitizer_list = nearby.sanitizer_list; var defaultClean = { 'point.lat': 0, 'point.lon': 0, @@ -17,7 +18,7 @@ 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.equal(sanitize.length, 3, 'sanitize interface takes one argument: req'); t.end(); }); test('middleware interface', function(t) { @@ -52,7 +53,7 @@ module.exports.tests.middleware_success = function(test, common) { 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 ){ diff --git a/test/unit/sanitizer/place.js b/test/unit/sanitizer/place.js index b7a4b6b8..ecbe295e 100644 --- a/test/unit/sanitizer/place.js +++ b/test/unit/sanitizer/place.js @@ -1,6 +1,7 @@ var place = require('../../../sanitizer/place'), sanitize = place.sanitize, middleware = place.middleware, + sanitizer_list = place.sanitizer_list, defaultClean = { ids: [ { source: 'geonames', layer: 'venue', id: '123' } ], private: false }; // these are the default values you would expect when no input params are specified. @@ -9,7 +10,7 @@ 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.equal(sanitize.length, 3, 'sanitize interface takes one arg: req'); t.end(); }); test('middleware interface', function(t) { @@ -32,7 +33,7 @@ module.exports.tests.sanitize_private = function(test, common) { invalid_values.forEach(function(value) { test('invalid private param ' + value, function(t) { var req = { query: { ids:'geonames:venue:123', 'private': value } }; - sanitize(req, function(){ + sanitize(req, sanitizer_list, () => { t.deepEqual( req.errors, [], 'no errors' ); t.deepEqual( req.warnings, [], 'no warnings' ); t.equal(req.clean.private, false, 'default private set (to false)'); @@ -45,7 +46,7 @@ module.exports.tests.sanitize_private = function(test, common) { valid_values.forEach(function(value) { test('valid private param ' + value, function(t) { var req = { query: { ids:'geonames:venue:123', 'private': value } }; - sanitize(req, function(){ + sanitize(req, sanitizer_list, () => { t.deepEqual( req.errors, [], 'no errors' ); t.deepEqual( req.warnings, [], 'no warnings' ); t.equal(req.clean.private, true, 'private set to true'); @@ -58,7 +59,7 @@ module.exports.tests.sanitize_private = function(test, common) { 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(){ + sanitize(req, sanitizer_list, () => { t.deepEqual( req.errors, [], 'no errors' ); t.deepEqual( req.warnings, [], 'no warnings' ); t.equal(req.clean.private, false, 'private set to false'); @@ -69,7 +70,7 @@ module.exports.tests.sanitize_private = function(test, common) { test('test default behavior', function(t) { var req = { query: { ids:'geonames:venue:123' } }; - sanitize(req, function(){ + sanitize(req, sanitizer_list, () => { t.deepEqual( req.errors, [], 'no errors' ); t.deepEqual( req.warnings, [], 'no warnings' ); t.equal(req.clean.private, false, 'private set to false'); @@ -81,7 +82,7 @@ module.exports.tests.sanitize_private = function(test, common) { module.exports.tests.invalid_params = function(test, common) { test('no params', function(t) { var req = { query: {} }; - sanitize( req, function(){ + sanitize(req, sanitizer_list, () => { t.equal( req.errors[0], 'invalid param \'ids\': length must be >0', 'error for missing `ids` param'); t.deepEqual( req.warnings, [], 'no warnings' ); t.end(); @@ -105,7 +106,7 @@ module.exports.tests.middleware_success = function(test, common) { 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 ){ diff --git a/test/unit/sanitizer/reverse.js b/test/unit/sanitizer/reverse.js index c7125743..16f05d39 100644 --- a/test/unit/sanitizer/reverse.js +++ b/test/unit/sanitizer/reverse.js @@ -4,6 +4,7 @@ var reverse = require('../../../sanitizer/reverse'), sanitize = reverse.sanitize, middleware = reverse.middleware, + sanitizer_list = reverse.sanitizer_list, defaults = require('../../../query/reverse_defaults'), defaultError = 'missing param \'lat\'', defaultClean = { 'point.lat': 0, @@ -23,7 +24,7 @@ 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.equal(sanitize.length, 3, 'sanitize interface takes one param: req'); t.end(); }); test('middleware interface', function(t) { @@ -52,7 +53,7 @@ module.exports.tests.sanitize_lat = function(test, common) { test('invalid lat', function(t) { lats.invalid.forEach( function( lat ){ var req = { query: { 'point.lat': lat, 'point.lon': 0 } }; - sanitize(req, function(){ + sanitize(req, sanitizer_list, () => { 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'); }); @@ -62,7 +63,7 @@ module.exports.tests.sanitize_lat = function(test, common) { test('valid lat', function(t) { lats.valid.forEach( function( lat ){ var req = { query: { 'point.lat': lat, 'point.lon': 0 } }; - sanitize(req, function(){ + sanitize(req, sanitizer_list, () => { var expected_lat = parseFloat( lat ); t.deepEqual(req.errors, [], 'no errors'); }); @@ -72,7 +73,7 @@ module.exports.tests.sanitize_lat = function(test, common) { test('missing lat', function(t) { lats.missing.forEach( function( lat ){ var req = { query: { 'point.lat': lat, 'point.lon': 0 } }; - sanitize(req, function(){ + sanitize(req, sanitizer_list, () => { 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'); }); @@ -89,7 +90,7 @@ module.exports.tests.sanitize_lon = function(test, common) { test('valid lon', function(t) { lons.valid.forEach( function( lon ){ var req = { query: { 'point.lat': 0, 'point.lon': lon } }; - sanitize(req, function(){ + sanitize(req, sanitizer_list, () => { var expected_lon = parseFloat( lon ); t.deepEqual(req.errors, [], 'no errors'); }); @@ -102,7 +103,7 @@ module.exports.tests.sanitize_lon = function(test, common) { // @todo: why is lat set? var expected = { 'point.lat': 0, private: false, size: 10 }; - sanitize(req, function(){ + sanitize(req, sanitizer_list, () => { 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'); }); @@ -114,21 +115,21 @@ module.exports.tests.sanitize_lon = function(test, common) { 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(){ + sanitize(req, sanitizer_list, () => { t.equal(req.clean.size, 10, 'default size set'); t.end(); }); }); test('below min size value', function(t) { var req = { query: { size: -100, 'point.lat': 0, 'point.lon': 0 } }; - sanitize(req, function(){ + sanitize(req, sanitizer_list, () => { 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(){ + sanitize(req, sanitizer_list, () => { t.equal(req.clean.size, 40, 'max size set'); t.end(); }); @@ -140,7 +141,7 @@ module.exports.tests.sanitize_private = function(test, common) { 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(){ + sanitize(req, sanitizer_list, () => { t.equal(req.clean.private, false, 'default private set (to false)'); t.end(); }); @@ -151,7 +152,7 @@ module.exports.tests.sanitize_private = function(test, common) { 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(){ + sanitize(req, sanitizer_list, () => { t.equal(req.clean.private, true, 'private set to true'); t.end(); }); @@ -162,7 +163,7 @@ module.exports.tests.sanitize_private = function(test, common) { 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(){ + sanitize(req, sanitizer_list, () => { t.equal(req.clean.private, false, 'private set to false'); t.end(); }); @@ -171,7 +172,7 @@ module.exports.tests.sanitize_private = function(test, common) { test('test default behavior', function(t) { var req = { query: { 'point.lat': 0, 'point.lon': 0 } }; - sanitize(req, function(){ + sanitize(req, sanitizer_list, () => { t.equal(req.clean.private, false, 'private set to false'); t.end(); }); @@ -193,7 +194,7 @@ module.exports.tests.middleware_success = function(test, common) { 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 ){ From 279b70b7d7f7b6781e99d8f7dfa32b4169daabc0 Mon Sep 17 00:00:00 2001 From: Lily He Date: Fri, 28 Jul 2017 16:06:34 -0400 Subject: [PATCH 08/17] typo: delete mentions of joi in sanitizers --- sanitizer/_size.js | 2 +- sanitizer/sanitizeAll.js | 2 +- test/unit/sanitizer/_boundary_country.js | 2 +- test/unit/sanitizer/_categories.js | 2 +- test/unit/sanitizer/_flag_bool.js | 2 +- test/unit/sanitizer/_ids.js | 2 +- test/unit/sanitizer/_size.js | 2 +- test/unit/sanitizer/_sources_and_layers.js | 2 +- test/unit/sanitizer/_synthesize_analysis.js | 2 +- test/unit/sanitizer/_text_addressit.js | 2 +- test/unit/sanitizer/sanitizeAll.js | 5 ++--- 11 files changed, 12 insertions(+), 13 deletions(-) diff --git a/sanitizer/_size.js b/sanitizer/_size.js index aaced3f9..614412d0 100644 --- a/sanitizer/_size.js +++ b/sanitizer/_size.js @@ -41,7 +41,7 @@ function _setup( size_min, size_max, size_def ){ }, expected: function _expected() { - // add size as a valid parameter for joi + // add size as a valid parameter return [{ name: 'size' }]; } }; diff --git a/sanitizer/sanitizeAll.js b/sanitizer/sanitizeAll.js index dafa1cb8..47861737 100644 --- a/sanitizer/sanitizeAll.js +++ b/sanitizer/sanitizeAll.js @@ -30,7 +30,7 @@ function sanitize( req, sanitizers, cb ){ return cb( undefined, req.clean ); } -// Adds to schemaKeys every acceptable parameter passed through API call +// Adds to goodParameters every acceptable parameter passed through API call function checkParameters(req, sanitizers, cb) { // source of input parameters // (in this case from the GET querystring params) diff --git a/test/unit/sanitizer/_boundary_country.js b/test/unit/sanitizer/_boundary_country.js index 7649da66..3db2a4d3 100644 --- a/test/unit/sanitizer/_boundary_country.js +++ b/test/unit/sanitizer/_boundary_country.js @@ -66,7 +66,7 @@ module.exports.tests.sanitize_boundary_country = function(test, common) { t.end(); }); - test('return an array of valid parameters in object form for Joi schema validation', (t) => { + 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); diff --git a/test/unit/sanitizer/_categories.js b/test/unit/sanitizer/_categories.js index 84589098..0c7dbe59 100644 --- a/test/unit/sanitizer/_categories.js +++ b/test/unit/sanitizer/_categories.js @@ -158,7 +158,7 @@ module.exports.tests.invalid_categories = function(test, common) { t.end(); }); - test('return an array of valid parameters in object form for Joi schema validation', (t) => { + test('return an array of expected parameters in object form for validation', (t) => { const expected = [{ name: 'categories' }]; const validParameters = sanitizer.expected(); diff --git a/test/unit/sanitizer/_flag_bool.js b/test/unit/sanitizer/_flag_bool.js index 04e31f49..193e8234 100644 --- a/test/unit/sanitizer/_flag_bool.js +++ b/test/unit/sanitizer/_flag_bool.js @@ -52,7 +52,7 @@ module.exports.tests.validate_default_behavior = function(test, common) { }; module.exports.tests.check_valid_parameters = function(test, common) { - test('return an array of valid parameters in object form for Joi schema validation', (t) => { + test('return an array of expected parameters in object form for validation', (t) => { const expected = [{ name: 'private' }]; const validParameters = sanitizer('dirty_param', true).expected(); t.deepEquals(validParameters, expected); diff --git a/test/unit/sanitizer/_ids.js b/test/unit/sanitizer/_ids.js index f376c2ca..bf82ec8e 100644 --- a/test/unit/sanitizer/_ids.js +++ b/test/unit/sanitizer/_ids.js @@ -205,7 +205,7 @@ module.exports.tests.de_dupe = function(test, common) { }; module.exports.tests.valid_Parameters = function(test, common) { - test('return an array of valid parameters in object form for Joi schema validation', (t) => { + 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); diff --git a/test/unit/sanitizer/_size.js b/test/unit/sanitizer/_size.js index 0bd1e415..7b3a9e35 100644 --- a/test/unit/sanitizer/_size.js +++ b/test/unit/sanitizer/_size.js @@ -35,7 +35,7 @@ module.exports.tests.sanitize_size = function(test, common) { t.end(); }); - test('return an array of valid parameters in object form for Joi schema validation', function(t) { + 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); diff --git a/test/unit/sanitizer/_sources_and_layers.js b/test/unit/sanitizer/_sources_and_layers.js index b0266095..0a936b21 100644 --- a/test/unit/sanitizer/_sources_and_layers.js +++ b/test/unit/sanitizer/_sources_and_layers.js @@ -106,7 +106,7 @@ test('valid combination', function(t) { t.end(); }); - test('return an array of valid parameters in object form for Joi schema validation', function (t) { + 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); diff --git a/test/unit/sanitizer/_synthesize_analysis.js b/test/unit/sanitizer/_synthesize_analysis.js index fd13b947..287b0e0d 100644 --- a/test/unit/sanitizer/_synthesize_analysis.js +++ b/test/unit/sanitizer/_synthesize_analysis.js @@ -233,7 +233,7 @@ module.exports.tests.text_parser = function(test, common) { }); - test('return an array of valid parameters in object form for Joi schema validation', function (t) { + test('return an array of expected parameters in object form for validation', function (t) { const sanitizer = require('../../../sanitizer/_synthesize_analysis'); const expected = [ { 'name': 'venue' }, diff --git a/test/unit/sanitizer/_text_addressit.js b/test/unit/sanitizer/_text_addressit.js index c5291635..5fad89a8 100644 --- a/test/unit/sanitizer/_text_addressit.js +++ b/test/unit/sanitizer/_text_addressit.js @@ -339,7 +339,7 @@ module.exports.tests.text_parser = function(test, common) { }); - test('return an array of valid parameters in object form for Joi schema validation', (t) => { + 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); diff --git a/test/unit/sanitizer/sanitizeAll.js b/test/unit/sanitizer/sanitizeAll.js index 5e81aada..53bd0c30 100644 --- a/test/unit/sanitizer/sanitizeAll.js +++ b/test/unit/sanitizer/sanitizeAll.js @@ -1,5 +1,4 @@ var sanitizeAll = require('../../../sanitizer/sanitizeAll'); -const Joi = require('joi'); module.exports.tests = {}; @@ -171,7 +170,7 @@ module.exports.tests.all = function(test, common) { var sanitizers = { 'first': { expected: function _expected () { - // add value as a valid parameter for joi + // add value as a valid parameter return [{ name: 'value' }]; @@ -198,7 +197,7 @@ module.exports.tests.all = function(test, common) { var sanitizers = { 'first': { expected: function _expected () { - // add value as a valid parameter for joi + // add value as a valid parameter return [{ name: 'value' }]; From b9de4b67884ad724dadad35bc4e5fc1942615ede Mon Sep 17 00:00:00 2001 From: Lily He Date: Fri, 28 Jul 2017 16:25:02 -0400 Subject: [PATCH 09/17] additional test to verify runAllCheck works for sanitizeAll --- test/unit/sanitizer/sanitizeAll.js | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/test/unit/sanitizer/sanitizeAll.js b/test/unit/sanitizer/sanitizeAll.js index 53bd0c30..1355fed3 100644 --- a/test/unit/sanitizer/sanitizeAll.js +++ b/test/unit/sanitizer/sanitizeAll.js @@ -212,6 +212,50 @@ module.exports.tests.all = function(test, common) { }); }); + test('runAllChecks calls both sanitize and expectedParameters function', function(t) { + var req = { + query: { + value: 'query' + } + }; + + var sanitizers = { + 'first': { + sanitize: function(params) { + req.clean.query = params; + return { + errors: [], + warnings: ['warning 1'] + }; + }, + expected: function _expected () { + // add value as a valid parameter + return [{ + name: 'value' + }]; + } + } + }; + + var expected_req = { + query: { + value: 'query' + }, + clean: { + query: { + value: 'query' + } + }, + errors: [], + warnings: ['warning 1'] + }; + + sanitizeAll.runAllChecks(req, sanitizers, function () { + t.deepEquals(req, expected_req); + t.end(); + }); + }); + }; module.exports.all = function (tape, common) { From a27ac0fc888c4ee6a96e665c20e92bedf700e257 Mon Sep 17 00:00:00 2001 From: Lily He Date: Fri, 28 Jul 2017 17:34:56 -0400 Subject: [PATCH 10/17] use strict for ecmascript 6 syntax, fix typos --- sanitizer/sanitizeAll.js | 8 +++++--- test/unit/sanitizer/nearby.js | 2 +- test/unit/sanitizer/place.js | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/sanitizer/sanitizeAll.js b/sanitizer/sanitizeAll.js index 47861737..c21c78ff 100644 --- a/sanitizer/sanitizeAll.js +++ b/sanitizer/sanitizeAll.js @@ -1,3 +1,5 @@ +'use strict'; + const async = require('async'); function sanitize( req, sanitizers, cb ){ @@ -12,7 +14,7 @@ function sanitize( req, sanitizers, cb ){ // (in this case from the GET querystring params) const params = req.query || {}; - for (var s in sanitizers) { + for (let s in sanitizers) { var sanity = sanitizers[s].sanitize( params, req.clean ); // if errors occurred then set them @@ -37,11 +39,11 @@ function checkParameters(req, sanitizers, cb) { const params = req.query || {}; const goodParameters = {}; - for (var s in sanitizers) { + for (let s in sanitizers) { // checks if there is a function that returns valid params if (typeof sanitizers[s].expected === 'function'){ - /** func returns {array} ex: [{ name: 'text' }, { name: 'parsed_text' }] */ + /** func returns {array} ex: [{ name: 'text' }] */ for (let t in sanitizers[s].expected()) { /** {object} prop */ const prop = sanitizers[s].expected()[t]; diff --git a/test/unit/sanitizer/nearby.js b/test/unit/sanitizer/nearby.js index f816ea62..11ef459e 100644 --- a/test/unit/sanitizer/nearby.js +++ b/test/unit/sanitizer/nearby.js @@ -18,7 +18,7 @@ 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, 3, 'sanitize interface takes one argument: req'); + t.equal(sanitize.length, 3, 'sanitize interface takes three args'); t.end(); }); test('middleware interface', function(t) { diff --git a/test/unit/sanitizer/place.js b/test/unit/sanitizer/place.js index ecbe295e..af3a9859 100644 --- a/test/unit/sanitizer/place.js +++ b/test/unit/sanitizer/place.js @@ -10,7 +10,7 @@ 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, 3, 'sanitize interface takes one arg: req'); + t.equal(sanitize.length, 3, 'sanitize interface takes three args'); t.end(); }); test('middleware interface', function(t) { From 80a3a259ef40bdefa7b51fe25b4410d579a586b0 Mon Sep 17 00:00:00 2001 From: Lily He Date: Mon, 31 Jul 2017 18:00:33 -0400 Subject: [PATCH 11/17] remove callback in sanitizeAll.runAllChecks for sync processing --- sanitizer/autocomplete.js | 9 +--- sanitizer/nearby.js | 9 +--- sanitizer/place.js | 9 +--- sanitizer/reverse.js | 9 +--- sanitizer/sanitizeAll.js | 33 +++++++-------- sanitizer/search.js | 9 +--- sanitizer/search_fallback.js | 9 +--- sanitizer/structured_geocoding.js | 10 ++--- test/unit/sanitizer/sanitizeAll.js | 68 ++++++++++++------------------ 9 files changed, 56 insertions(+), 109 deletions(-) diff --git a/sanitizer/autocomplete.js b/sanitizer/autocomplete.js index 55315e41..85fcec86 100644 --- a/sanitizer/autocomplete.js +++ b/sanitizer/autocomplete.js @@ -20,12 +20,7 @@ module.exports.middleware = (_api_pelias_config) => { }; return ( req, res, next ) => { - sanitizeAll.runAllChecks(req, sanitizers, ( err, clean ) => { - if( err ){ - res.status(400); // 400 Bad Request - return next(err); - } - next(); - }); + sanitizeAll.runAllChecks(req, sanitizers); + next(); }; }; diff --git a/sanitizer/nearby.js b/sanitizer/nearby.js index 46f1ae2c..00efefc4 100644 --- a/sanitizer/nearby.js +++ b/sanitizer/nearby.js @@ -15,11 +15,6 @@ module.exports.sanitizer_list = sanitizers; // middleware module.exports.middleware = function( req, res, next ){ - sanitize(req, sanitizers, ( err, clean ) => { - if( err ){ - res.status(400); // 400 Bad Request - return next(err); - } - next(); - }); + sanitizeAll.runAllChecks(req, sanitizers); + next(); }; diff --git a/sanitizer/place.js b/sanitizer/place.js index 363fa7ef..6800b06b 100644 --- a/sanitizer/place.js +++ b/sanitizer/place.js @@ -14,11 +14,6 @@ module.exports.sanitizer_list = sanitizers; // middleware module.exports.middleware = function(req, res, next){ - sanitize(req, sanitizers, ( err, clean ) => { - if( err ){ - res.status(400); // 400 Bad Request - return next(err); - } - next(); - }); + sanitizeAll.runAllChecks(req, sanitizers); + next(); }; diff --git a/sanitizer/reverse.js b/sanitizer/reverse.js index 0a02f9a8..91094812 100644 --- a/sanitizer/reverse.js +++ b/sanitizer/reverse.js @@ -23,11 +23,6 @@ module.exports.sanitizer_list = sanitizers; // middleware module.exports.middleware = function( req, res, next ){ - sanitize(req, sanitizers, ( err, clean ) => { - if( err ){ - res.status(400); // 400 Bad Request - return next(err); - } - next(); - }); + sanitizeAll.runAllChecks(req, sanitizers); + next(); }; diff --git a/sanitizer/sanitizeAll.js b/sanitizer/sanitizeAll.js index c21c78ff..af6e1510 100644 --- a/sanitizer/sanitizeAll.js +++ b/sanitizer/sanitizeAll.js @@ -1,8 +1,5 @@ 'use strict'; - -const async = require('async'); - -function sanitize( req, sanitizers, cb ){ +function sanitize( req, sanitizers ){ // init an object to store clean (sanitized) input parameters if not initialized req.clean = req.clean || {}; @@ -29,11 +26,11 @@ function sanitize( req, sanitizers, cb ){ req.warnings = req.warnings.concat( sanity.warnings ); } } - return cb( undefined, req.clean ); } // Adds to goodParameters every acceptable parameter passed through API call -function checkParameters(req, sanitizers, cb) { +function checkParameters( req, sanitizers ) { + req.warnings = req.warnings || []; // source of input parameters // (in this case from the GET querystring params) const params = req.query || {}; @@ -41,9 +38,9 @@ function checkParameters(req, sanitizers, cb) { for (let s in sanitizers) { - // checks if there is a function that returns valid params + // checks if function exists if (typeof sanitizers[s].expected === 'function'){ - /** func returns {array} ex: [{ name: 'text' }] */ + /** expected() returns {array} ex: [{ name: 'text' }] */ for (let t in sanitizers[s].expected()) { /** {object} prop */ const prop = sanitizers[s].expected()[t]; @@ -54,21 +51,21 @@ function checkParameters(req, sanitizers, cb) { } } } - // If there are any unexpected parameters, add a warning to messages - for (let p in params) { - if (!goodParameters.hasOwnProperty(p)){ - req.warnings = req.warnings.concat('Invalid Parameter: ' + p); + // 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); + } } } - return cb( undefined, req.clean ); } // runs both sanitize and checkParameters functions in async parallel -function runAllChecks (req, sanitizers, cb) { - async.parallel([ - sanitize.bind(null, req, sanitizers), - checkParameters.bind(null, req, sanitizers) - ], cb); +function runAllChecks (req, sanitizers) { + sanitize(req, sanitizers); + checkParameters(req, sanitizers); } // export function diff --git a/sanitizer/search.js b/sanitizer/search.js index c36a4d14..9db5f900 100644 --- a/sanitizer/search.js +++ b/sanitizer/search.js @@ -21,13 +21,8 @@ module.exports.middleware = (_api_pelias_config) => { }; return ( req, res, next ) => { - sanitizeAll.runAllChecks(req, sanitizers, ( err, clean ) => { - if( err ){ - res.status(400); // 400 Bad Request - return next(err); - } - next(); - }); + sanitizeAll.runAllChecks(req, sanitizers); + next(); }; }; diff --git a/sanitizer/search_fallback.js b/sanitizer/search_fallback.js index 628ee4b8..6c8297be 100644 --- a/sanitizer/search_fallback.js +++ b/sanitizer/search_fallback.js @@ -23,12 +23,7 @@ module.exports.middleware = function( req, res, next ){ } // calls to sanitize the input // omits check if parameters are valid since it only calls _text_addressit - sanitizeAll.sanitize(req, sanitizers, ( err, clean ) => { - if( err ){ - res.status(400); // 400 Bad Request - return next(err); - } - next(); - }); + sanitizeAll.sanitize(req, sanitizers); + next(); }; diff --git a/sanitizer/structured_geocoding.js b/sanitizer/structured_geocoding.js index f5c95afc..b84d843c 100644 --- a/sanitizer/structured_geocoding.js +++ b/sanitizer/structured_geocoding.js @@ -22,13 +22,9 @@ module.exports.middleware = (_api_pelias_config) => { }; return ( req, res, next ) => { - sanitizeAll.runAllChecks(req, sanitizers, ( err, clean ) => { - if( err ){ - res.status(400); // 400 Bad Request - return next(err); - } - next(); - }); + sanitizeAll.runAllChecks(req, sanitizers); + next(); + }; }; diff --git a/test/unit/sanitizer/sanitizeAll.js b/test/unit/sanitizer/sanitizeAll.js index 1355fed3..f74e7efb 100644 --- a/test/unit/sanitizer/sanitizeAll.js +++ b/test/unit/sanitizer/sanitizeAll.js @@ -35,10 +35,9 @@ module.exports.tests.all = function(test, common) { warnings: ['warning 1', 'warning 2', 'warning 3'] }; - sanitizeAll.sanitize(req, sanitizers, function (){ - t.deepEquals(req, expected_req); - t.end(); - }); + sanitizeAll.runAllChecks(req, sanitizers); + t.deepEquals(req, expected_req); + t.end(); }); @@ -82,11 +81,9 @@ module.exports.tests.all = function(test, common) { warnings: ['pre-existing warning', 'warning 1', 'warning 2', 'warning 3'] }; - sanitizeAll.sanitize(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) { @@ -97,7 +94,7 @@ module.exports.tests.all = function(test, common) { }; var sanitizers = { 'first': { - sanitize: function(params) { + sanitize: function (params) { req.clean.query = params; return { errors: [], @@ -120,11 +117,9 @@ module.exports.tests.all = function(test, common) { warnings: [] }; - sanitizeAll.sanitize(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) { @@ -152,11 +147,9 @@ module.exports.tests.all = function(test, common) { warnings: [] }; - sanitizeAll.sanitize(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 throw warning', function(t) { @@ -178,12 +171,10 @@ module.exports.tests.all = function(test, common) { } }; - sanitizeAll.checkParameters(req, sanitizers, function () { - t.equals(req.errors.length, 0); - t.deepEquals(req.warnings[0], 'Invalid Parameter: unknown_value'); - t.end(); - }); - + 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 throw warning', function(t) { @@ -205,14 +196,14 @@ module.exports.tests.all = function(test, common) { } }; - sanitizeAll.checkParameters(req, sanitizers, function () { - t.equals(req.errors.length, 0); - t.equals(req.warnings.length, 0); - t.end(); - }); + sanitizeAll.checkParameters(req, sanitizers); + t.equals(req.errors.length, 0); + t.equals(req.warnings.length, 0); + t.end(); + }); - test('runAllChecks calls both sanitize and expectedParameters function', function(t) { + test('sanitizer without expected() should not validate parameters', function(t) { var req = { query: { value: 'query' @@ -227,12 +218,6 @@ module.exports.tests.all = function(test, common) { errors: [], warnings: ['warning 1'] }; - }, - expected: function _expected () { - // add value as a valid parameter - return [{ - name: 'value' - }]; } } }; @@ -250,10 +235,9 @@ module.exports.tests.all = function(test, common) { warnings: ['warning 1'] }; - sanitizeAll.runAllChecks(req, sanitizers, function () { - t.deepEquals(req, expected_req); - t.end(); - }); + sanitizeAll.runAllChecks(req, sanitizers); + t.deepEquals(req, expected_req); + t.end(); }); }; From 07c7e7d483d760d59759c71d052129e9c6ce4696 Mon Sep 17 00:00:00 2001 From: Lily He Date: Tue, 1 Aug 2017 16:50:25 -0400 Subject: [PATCH 12/17] test reverse, nearby, place sanitizer wrappers w/ proxyquire --- test/unit/sanitizer/nearby.js | 74 ++++----- test/unit/sanitizer/place.js | 137 +++++---------- test/unit/sanitizer/reverse.js | 294 +++++++++++++-------------------- 3 files changed, 185 insertions(+), 320 deletions(-) diff --git a/test/unit/sanitizer/nearby.js b/test/unit/sanitizer/nearby.js index 11ef459e..f691d4b8 100644 --- a/test/unit/sanitizer/nearby.js +++ b/test/unit/sanitizer/nearby.js @@ -1,52 +1,36 @@ - -var nearby = require('../../../sanitizer/nearby'); -var defaults = require('../../../query/reverse_defaults'); -var sanitize = nearby.sanitize; -var middleware = nearby.middleware; -var sanitizer_list = nearby.sanitizer_list; - -var defaultClean = { 'point.lat': 0, - 'point.lon': 0, - 'boundary.circle.lat': 0, - 'boundary.circle.lon': 0, - size: 10, - private: false - }; +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, 3, 'sanitize interface takes three args'); - 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', 'categories']; - t.deepEqual(Object.keys(nearby.sanitizer_list), expected); - 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); +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 nearby = proxyquire('../../../sanitizer/nearby.js', { + '../sanitizer/_categories': function () { + return { + sanitize: () => { + called_sanitizers.push('_categories'); + return { errors: [], warnings: [] }; + } + }; + } + }); + + const expected_sanitizers = [ + '_categories' + ]; + + const req = {}; + const res = {}; + + nearby.middleware(req, res, () => { + t.deepEquals(called_sanitizers, expected_sanitizers); t.end(); - }; - middleware( req, undefined, next ); + }); }); }; diff --git a/test/unit/sanitizer/place.js b/test/unit/sanitizer/place.js index af3a9859..b55946f8 100644 --- a/test/unit/sanitizer/place.js +++ b/test/unit/sanitizer/place.js @@ -1,108 +1,61 @@ -var place = require('../../../sanitizer/place'), - sanitize = place.sanitize, - middleware = place.middleware, - sanitizer_list = place.sanitizer_list, - 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, 3, 'sanitize interface takes three args'); - 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, sanitizer_list, () => { - 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, sanitizer_list, () => { - 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, sanitizer_list, () => { - 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, sanitizer_list, () => { - 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, sanitizer_list, () => { - 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) { diff --git a/test/unit/sanitizer/reverse.js b/test/unit/sanitizer/reverse.js index 16f05d39..cb1edf9c 100644 --- a/test/unit/sanitizer/reverse.js +++ b/test/unit/sanitizer/reverse.js @@ -1,194 +1,122 @@ - -// @todo: refactor this test, it's pretty messy, brittle and hard to follow - -var reverse = require('../../../sanitizer/reverse'), - sanitize = reverse.sanitize, - middleware = reverse.middleware, - sanitizer_list = reverse.sanitizer_list, - 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, 3, 'sanitize interface takes one param: req'); - 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, sanitizer_list, () => { - 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, sanitizer_list, () => { - 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, sanitizer_list, () => { - 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, sanitizer_list, () => { - 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, sanitizer_list, () => { - 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, sanitizer_list, () => { - 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, sanitizer_list, () => { - 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, sanitizer_list, () => { - 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, sanitizer_list, () => { - 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, sanitizer_list, () => { - 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, sanitizer_list, () => { - 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, sanitizer_list, () => { - 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) { From 9a88d5a28b481618bb4add7393d85edb58a9a6b0 Mon Sep 17 00:00:00 2001 From: Lily He Date: Tue, 1 Aug 2017 17:01:48 -0400 Subject: [PATCH 13/17] unmerge nearby sanitizers from reverse sanitizer_list --- sanitizer/nearby.js | 18 +++++-- test/unit/sanitizer/nearby.js | 94 +++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 4 deletions(-) diff --git a/sanitizer/nearby.js b/sanitizer/nearby.js index 00efefc4..021efa77 100644 --- a/sanitizer/nearby.js +++ b/sanitizer/nearby.js @@ -1,11 +1,21 @@ -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, { +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')() -}); +}; var sanitize = sanitizeAll.runAllChecks; diff --git a/test/unit/sanitizer/nearby.js b/test/unit/sanitizer/nearby.js index f691d4b8..d2d11f1f 100644 --- a/test/unit/sanitizer/nearby.js +++ b/test/unit/sanitizer/nearby.js @@ -10,6 +10,90 @@ 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 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: () => { @@ -21,6 +105,16 @@ module.exports.tests.sanitize = function(test, common) { }); 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' ]; From db56ce45c34ca6f712d8336371f1421e7d892570 Mon Sep 17 00:00:00 2001 From: Lily He Date: Tue, 1 Aug 2017 17:03:51 -0400 Subject: [PATCH 14/17] remove exporting sanitize for testing --- sanitizer/nearby.js | 6 ------ sanitizer/place.js | 6 ------ sanitizer/reverse.js | 6 ------ test/unit/sanitizer/sanitizeAll.js | 4 ++-- 4 files changed, 2 insertions(+), 20 deletions(-) diff --git a/sanitizer/nearby.js b/sanitizer/nearby.js index 021efa77..a26b93a3 100644 --- a/sanitizer/nearby.js +++ b/sanitizer/nearby.js @@ -17,12 +17,6 @@ var sanitizers = { categories: require('../sanitizer/_categories')() }; -var sanitize = sanitizeAll.runAllChecks; - -// export sanitize for testing -module.exports.sanitize = sanitize; -module.exports.sanitizer_list = sanitizers; - // middleware module.exports.middleware = function( req, res, next ){ sanitizeAll.runAllChecks(req, sanitizers); diff --git a/sanitizer/place.js b/sanitizer/place.js index 6800b06b..4ab7af16 100644 --- a/sanitizer/place.js +++ b/sanitizer/place.js @@ -6,12 +6,6 @@ var sanitizeAll = require('../sanitizer/sanitizeAll'), private: require('../sanitizer/_flag_bool')('private', false) }; -var sanitize = sanitizeAll.runAllChecks; - -// export sanitize for testing -module.exports.sanitize = sanitize; -module.exports.sanitizer_list = sanitizers; - // middleware module.exports.middleware = function(req, res, next){ sanitizeAll.runAllChecks(req, sanitizers); diff --git a/sanitizer/reverse.js b/sanitizer/reverse.js index 91094812..1ecb92e1 100644 --- a/sanitizer/reverse.js +++ b/sanitizer/reverse.js @@ -15,12 +15,6 @@ var sanitizeAll = require('../sanitizer/sanitizeAll'), boundary_country: require('../sanitizer/_boundary_country')() }; -var sanitize = sanitizeAll.runAllChecks; - -// export sanitize for testing -module.exports.sanitize = sanitize; -module.exports.sanitizer_list = sanitizers; - // middleware module.exports.middleware = function( req, res, next ){ sanitizeAll.runAllChecks(req, sanitizers); diff --git a/test/unit/sanitizer/sanitizeAll.js b/test/unit/sanitizer/sanitizeAll.js index f74e7efb..e8502813 100644 --- a/test/unit/sanitizer/sanitizeAll.js +++ b/test/unit/sanitizer/sanitizeAll.js @@ -152,7 +152,7 @@ module.exports.tests.all = function(test, common) { t.end(); }); - test('unexpected parameters should throw warning', function(t) { + test('unexpected parameters should add warning', function(t) { var req = { query: { unknown_value: 'query value' @@ -177,7 +177,7 @@ module.exports.tests.all = function(test, common) { t.end(); }); - test('expected parameters should not throw warning', function(t) { + test('expected parameters should not add warning', function(t) { var req = { query: { value: 'query value' From 8e45af1e499f6a285b0968137494114d683cb452 Mon Sep 17 00:00:00 2001 From: Lily He Date: Wed, 2 Aug 2017 14:08:11 -0400 Subject: [PATCH 15/17] adapt defer_to_addressit to new sanitizer format --- sanitizer/defer_to_addressit.js | 8 ++--- test/unit/sanitizer/defer_to_addressit.js | 38 ++++++++++++++++------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/sanitizer/defer_to_addressit.js b/sanitizer/defer_to_addressit.js index 8822f72c..7fa47e6c 100644 --- a/sanitizer/defer_to_addressit.js +++ b/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(); }; diff --git a/test/unit/sanitizer/defer_to_addressit.js b/test/unit/sanitizer/defer_to_addressit.js index 9fe4675e..156d575a 100644 --- a/test/unit/sanitizer/defer_to_addressit.js +++ b/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': { From a5cf44bef4ffa187d29f3a2f452f8f35a930a418 Mon Sep 17 00:00:00 2001 From: Lily He Date: Wed, 2 Aug 2017 14:10:22 -0400 Subject: [PATCH 16/17] clarify _text sanitizer test message --- test/unit/sanitizer/_text.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/sanitizer/_text.js b/test/unit/sanitizer/_text.js index 0a6729b1..1fde352b 100644 --- a/test/unit/sanitizer/_text.js +++ b/test/unit/sanitizer/_text.js @@ -3,7 +3,7 @@ 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' }; From bf234f55396c0e9dcda89e9b3ec64780e0aa98d4 Mon Sep 17 00:00:00 2001 From: Lily He Date: Thu, 3 Aug 2017 18:25:42 -0400 Subject: [PATCH 17/17] flag_bool expects parameter opts.paramName --- sanitizer/_flag_bool.js | 2 +- test/unit/sanitizer/_flag_bool.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sanitizer/_flag_bool.js b/sanitizer/_flag_bool.js index aab2daac..5665c844 100644 --- a/sanitizer/_flag_bool.js +++ b/sanitizer/_flag_bool.js @@ -41,7 +41,7 @@ function _setup( paramName, defaultValue ) { }, // end of _sanitize function expected: function _expected(){ - return [{ name: 'private'}]; + return [{ name: opts.paramName}]; } // end of _expected function }; // end of return object } // end of _setup function diff --git a/test/unit/sanitizer/_flag_bool.js b/test/unit/sanitizer/_flag_bool.js index 193e8234..bdbb1385 100644 --- a/test/unit/sanitizer/_flag_bool.js +++ b/test/unit/sanitizer/_flag_bool.js @@ -53,8 +53,8 @@ module.exports.tests.validate_default_behavior = function(test, common) { 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: 'private' }]; - const validParameters = sanitizer('dirty_param', true).expected(); + const expected = [{ name: 'value' }]; // depends on first argument of sanitizer() + const validParameters = sanitizer('value', true).expected(); t.deepEquals(validParameters, expected); t.end(); });