diff --git a/sanitiser/_geo_common.js b/sanitiser/_geo_common.js index bc5a4bcc..d63d0455 100644 --- a/sanitiser/_geo_common.js +++ b/sanitiser/_geo_common.js @@ -1,7 +1,8 @@ /** * helper sanitiser methods for geo parameters */ -var util = require('util'), +var groups = require('./_groups'), + util = require('util'), check = require('check-types'), _ = require('lodash'); @@ -16,35 +17,26 @@ var util = require('util'), function sanitize_rect( key_prefix, clean, raw, bbox_is_required ) { // the names we use to define the corners of the rect - var mandatoryProps = [ 'min_lat', 'max_lat', 'min_lon', 'max_lon' ]; - - // count up how many fields the user actually specified - var totalFieldsSpecified = 0; - mandatoryProps.forEach( function( prop ){ - if( raw.hasOwnProperty( key_prefix + '.' + prop ) ){ - totalFieldsSpecified++; - } + var properties = [ 'min_lat', 'max_lat', 'min_lon', 'max_lon' ].map(function(prop) { + return key_prefix + '.' + prop; }); - // all fields specified - if( 4 === totalFieldsSpecified ) { - // reuse the coord sanitizer and set required:true so we get a fatal error if - // any one of the corners is not specified. - sanitize_coord( key_prefix + '.min_lat', clean, raw[ key_prefix + '.min_lat' ], true ); - sanitize_coord( key_prefix + '.max_lat', clean, raw[ key_prefix + '.max_lat' ], true ); - sanitize_coord( key_prefix + '.min_lon', clean, raw[ key_prefix + '.min_lon' ], true ); - sanitize_coord( key_prefix + '.max_lon', clean, raw[ key_prefix + '.max_lon' ], true ); - } - // fields only partially specified - else if( totalFieldsSpecified > 0 ){ - var format1 = 'missing rect param \'%s\' requires all of: \'%s\' to be present'; - throw new Error( util.format( format1, key_prefix, mandatoryProps.join('\',\'') ) ); - } - // fields required, eg. ( totalFieldsSpecified === 0 && bbox_is_required === true ) - else if( bbox_is_required ){ - var format2 = 'missing rect param \'%s\' requires all of: \'%s\' to be present'; - throw new Error( util.format( format2, key_prefix, mandatoryProps.join('\',\'') ) ); + var bbox_present; + if (bbox_is_required) { + bbox_present = groups.required(raw, properties); + } else { + bbox_present = groups.optional(raw, properties); } + + // don't bother checking individual elements if bbox is not required + // and not present + if (!bbox_present) { return; } + + properties.forEach(function(prop) { + // reuse the coord sanitizer and set required:true so we get a fatal error if + // any one of the coords is not specified. + sanitize_coord(prop, clean, raw[prop], true); + }); } /** @@ -107,33 +99,27 @@ function sanitize_circle( key_prefix, clean, raw, circle_is_required ) { function sanitize_point( key_prefix, clean, raw, point_is_required ) { // the names we use to define the point - var mandatoryProps = [ 'lat', 'lon' ]; - - // count up how many fields the user actually specified - var totalFieldsSpecified = 0; - mandatoryProps.forEach( function( prop ){ - if( raw.hasOwnProperty( key_prefix + '.' + prop ) ){ - totalFieldsSpecified++; - } + var properties = [ 'lat', 'lon'].map(function(prop) { + return key_prefix + '.' + prop; }); - // all fields specified - if( 2 === totalFieldsSpecified ) { + + var point_present; + if (point_is_required) { + point_present = groups.required(raw, properties); + } else { + point_present = groups.optional(raw, properties); + } + + // don't bother checking individual elements if point is not required + // and not present + if (!point_present) { return; } + + properties.forEach(function(prop) { // reuse the coord sanitizer and set required:true so we get a fatal error if // any one of the coords is not specified. - sanitize_coord( key_prefix + '.lat', clean, raw[ key_prefix + '.lat' ], true ); - sanitize_coord( key_prefix + '.lon', clean, raw[ key_prefix + '.lon' ], true ); - } - // fields only partially specified - else if( totalFieldsSpecified > 0 ){ - var format1 = 'missing point param \'%s\' requires all of: \'%s\' to be present'; - throw new Error( util.format( format1, key_prefix, mandatoryProps.join('\',\'') ) ); - } - // fields required, eg. ( totalFieldsSpecified === 0 && bbox_is_required === true ) - else if( point_is_required ){ - var format2 = 'missing point param \'%s\' requires all of: \'%s\' to be present'; - throw new Error( util.format( format2, key_prefix, mandatoryProps.join('\',\'') ) ); - } + sanitize_coord(prop, clean, raw[prop], true); + }); } /** diff --git a/test/unit/sanitiser/search.js b/test/unit/sanitiser/search.js index f50a46a2..59bc87f3 100644 --- a/test/unit/sanitiser/search.js +++ b/test/unit/sanitiser/search.js @@ -167,7 +167,7 @@ module.exports.tests.sanitize_optional_geo = function(test, common) { var req = { query: { text: 'test', 'focus.point.lon': 0 } }; sanitize(req, function(){ var expected_lon = 0; - t.equal(req.errors[0], 'missing point param \'focus.point\' requires all of: \'lat\',\'lon\' to be present'); + t.equal(req.errors[0], 'parameters focus.point.lat and focus.point.lon must both be specified'); t.equal(req.clean['focus.point.lat'], undefined); t.equal(req.clean['focus.point.lon'], undefined); }); @@ -177,7 +177,7 @@ module.exports.tests.sanitize_optional_geo = function(test, common) { var req = { query: { text: 'test', 'focus.point.lat': 0 } }; sanitize(req, function(){ var expected_lat = 0; - t.equal(req.errors[0], 'missing point param \'focus.point\' requires all of: \'lat\',\'lon\' to be present'); + t.equal(req.errors[0], 'parameters focus.point.lat and focus.point.lon must both be specified'); t.equal(req.clean['focus.point.lat'], undefined); t.equal(req.clean['focus.point.lon'], undefined); });