From cb7d22df91efff84c7d056dde93b7eded8095453 Mon Sep 17 00:00:00 2001 From: Stephen Hess Date: Thu, 24 Sep 2015 17:05:10 -0400 Subject: [PATCH 1/9] switched ES lookup field from "type" -> "_type", fixes issue with /place lookup on Eiffel Tower gid --- controller/place.js | 9 ++------- test/unit/controller/place.js | 4 ++-- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/controller/place.js b/controller/place.js index 101430c5..e24be2fc 100644 --- a/controller/place.js +++ b/controller/place.js @@ -19,13 +19,8 @@ function setup( backend ){ /* * some gids aren't resolvable to a single type (ex: osmnode and osmway * both have source osm and layer venue), so expect an array of - * possible values. It's important to use `type` here instead of - * `_type`, as the former actually queries against the type, and thus - * can accept multiple match values. `_type`, on the other hand, - * simply changes the actual URL of the query sent to Elasticsearch to - * contain a type, which obviously can only take a single type. - */ - type: id.types, + * possible values. */ + _type: id.types, _id: id.id }; }); diff --git a/test/unit/controller/place.js b/test/unit/controller/place.js index 20455e3a..1d38f5d5 100644 --- a/test/unit/controller/place.js +++ b/test/unit/controller/place.js @@ -41,7 +41,7 @@ module.exports.tests.functional_success = function(test, common) { test('functional success', function(t) { var backend = mockBackend( 'client/mget/ok/1', function( cmd ){ - t.deepEqual(cmd, { body: { docs: [ { _id: 123, _index: 'pelias', type: [ 'a' ] } ] } }, 'correct backend command'); + t.deepEqual(cmd, { body: { docs: [ { _id: 123, _index: 'pelias', _type: [ 'a' ] } ] } }, 'correct backend command'); }); var controller = setup( backend ); var res = { @@ -70,7 +70,7 @@ module.exports.tests.functional_success = function(test, common) { module.exports.tests.functional_failure = function(test, common) { test('functional failure', function(t) { var backend = mockBackend( 'client/mget/fail/1', function( cmd ){ - t.deepEqual(cmd, { body: { docs: [ { _id: 123, _index: 'pelias', type: [ 'b' ] } ] } }, 'correct backend command'); + t.deepEqual(cmd, { body: { docs: [ { _id: 123, _index: 'pelias', _type: [ 'b' ] } ] } }, 'correct backend command'); }); var controller = setup( backend ); var req = { clean: { ids: [ {'id' : 123, types: [ 'b' ] } ] }, errors: [], warnings: [] }; From 3a5e6f781196e38ba8cb31311ce8958d0fb18b85 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Fri, 25 Sep 2015 18:42:17 +0200 Subject: [PATCH 2/9] tweak boost values --- query/defaults.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/query/defaults.js b/query/defaults.js index cf9422d0..38bafbbe 100644 --- a/query/defaults.js +++ b/query/defaults.js @@ -39,35 +39,35 @@ module.exports = extend( false, peliasQuery.defaults, { 'address:housenumber:analyzer': 'standard', 'address:housenumber:field': 'address.number', - 'address:housenumber:boost': 1, + 'address:housenumber:boost': 3, 'address:street:analyzer': 'standard', 'address:street:field': 'address.street', - 'address:street:boost': 1, + 'address:street:boost': 3, 'address:postcode:analyzer': 'standard', 'address:postcode:field': 'address.zip', - 'address:postcode:boost': 1, + 'address:postcode:boost': 3, 'admin:alpha3:analyzer': 'standard', 'admin:alpha3:field': 'alpha3', - 'admin:alpha3:boost': 1, + 'admin:alpha3:boost': 5, 'admin:admin0:analyzer': 'peliasAdmin', 'admin:admin0:field': 'admin0', - 'admin:admin0:boost': 1, + 'admin:admin0:boost': 4, 'admin:admin1:analyzer': 'peliasAdmin', 'admin:admin1:field': 'admin1', - 'admin:admin1:boost': 1, + 'admin:admin1:boost': 3, 'admin:admin1_abbr:analyzer': 'peliasAdmin', 'admin:admin1_abbr:field': 'admin1_abbr', - 'admin:admin1_abbr:boost': 1, + 'admin:admin1_abbr:boost': 3, 'admin:admin2:analyzer': 'peliasAdmin', 'admin:admin2:field': 'admin2', - 'admin:admin2:boost': 1, + 'admin:admin2:boost': 2, 'admin:local_admin:analyzer': 'peliasAdmin', 'admin:local_admin:field': 'local_admin', From c7a79c57b5bfd279e3ae73a5280dd771dfaf2e67 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Fri, 25 Sep 2015 19:01:27 +0200 Subject: [PATCH 3/9] reduce streetnumber boost --- query/defaults.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/query/defaults.js b/query/defaults.js index 38bafbbe..daea1ffd 100644 --- a/query/defaults.js +++ b/query/defaults.js @@ -43,7 +43,7 @@ module.exports = extend( false, peliasQuery.defaults, { 'address:street:analyzer': 'standard', 'address:street:field': 'address.street', - 'address:street:boost': 3, + 'address:street:boost': 2, 'address:postcode:analyzer': 'standard', 'address:postcode:field': 'address.zip', From 31ae318861297e340710f679dacf51c602bdd96e Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Fri, 25 Sep 2015 19:06:20 +0200 Subject: [PATCH 4/9] tweaks --- query/defaults.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/query/defaults.js b/query/defaults.js index daea1ffd..83ddb4d9 100644 --- a/query/defaults.js +++ b/query/defaults.js @@ -39,11 +39,11 @@ module.exports = extend( false, peliasQuery.defaults, { 'address:housenumber:analyzer': 'standard', 'address:housenumber:field': 'address.number', - 'address:housenumber:boost': 3, + 'address:housenumber:boost': 2, 'address:street:analyzer': 'standard', 'address:street:field': 'address.street', - 'address:street:boost': 2, + 'address:street:boost': 5, 'address:postcode:analyzer': 'standard', 'address:postcode:field': 'address.zip', From f3ba5411cd0c5bab908cbd55c9e20db85e3dda9b Mon Sep 17 00:00:00 2001 From: Julian Simioni Date: Wed, 23 Sep 2015 16:35:27 -0400 Subject: [PATCH 5/9] Sort test file names --- test/unit/run.js | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/test/unit/run.js b/test/unit/run.js index 7da0c978..2356ce21 100644 --- a/test/unit/run.js +++ b/test/unit/run.js @@ -6,34 +6,34 @@ var tests = [ require('./controller/index'), require('./controller/place'), require('./controller/search'), - require('./service/mget'), - require('./service/search'), - require('./sanitiser/_ids'), - require('./sanitiser/_flag_bool'), - require('./sanitiser/autocomplete'), - require('./sanitiser/_sources'), - require('./sanitiser/_boundary_country'), - require('./sanitiser/search'), - require('./sanitiser/_layers'), - require('./sanitiser/reverse'), - require('./sanitiser/place'), - require('./query/search'), - require('./query/autocomplete'), - require('./query/reverse'), - require('./query/defaults'), - require('./helper/query_parser'), require('./helper/geojsonify'), - require('./helper/labelSchema'), require('./helper/labelGenerator'), - require('./helper/types'), + require('./helper/labelSchema'), + require('./helper/query_parser'), require('./helper/type_mapping'), - require('./sanitiser/_geo_common'), - require('./middleware/distance'), - require('./middleware/confidenceScoreReverse'), + require('./helper/types'), require('./middleware/confidenceScore'), - require('./sanitiser/_size'), - require('./sanitiser/_single_scalar_parameters'), + require('./middleware/confidenceScoreReverse'), + require('./middleware/distance'), + require('./query/autocomplete'), + require('./query/defaults'), + require('./query/reverse'), + require('./query/search'), + require('./sanitiser/_boundary_country'), + require('./sanitiser/_flag_bool'), + require('./sanitiser/_geo_common'), require('./sanitiser/_geo_reverse'), + require('./sanitiser/_ids'), + require('./sanitiser/_layers'), + require('./sanitiser/_single_scalar_parameters'), + require('./sanitiser/_size'), + require('./sanitiser/_sources'), + require('./sanitiser/autocomplete'), + require('./sanitiser/place'), + require('./sanitiser/reverse'), + require('./sanitiser/search'), + require('./service/mget'), + require('./service/search'), ]; tests.map(function(t) { From aa08fb9772fa85974705993dfe6d68e2439505ab Mon Sep 17 00:00:00 2001 From: Julian Simioni Date: Wed, 23 Sep 2015 16:59:13 -0400 Subject: [PATCH 6/9] Add optional and required group parameter sanitizers --- sanitiser/_groups.js | 57 ++++++++++++++++++++++++++ test/unit/run.js | 1 + test/unit/sanitiser/_groups.js | 75 ++++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 sanitiser/_groups.js create mode 100644 test/unit/sanitiser/_groups.js diff --git a/sanitiser/_groups.js b/sanitiser/_groups.js new file mode 100644 index 00000000..a06b839c --- /dev/null +++ b/sanitiser/_groups.js @@ -0,0 +1,57 @@ +var _ = require('lodash'); + +/* + * Specify an object and array of keys to check. + * An error will be thrown if at least one, but not all of them are specified + * + * @param {object} - the object + * @param {array} - keys to check + * + * returns true if all are present, false if none are present, throws an exception otherwise + */ +function optional_group(object, keys) { + var contained_in_object = _.contains.bind(null, Object.keys(object)); + + if (keys.every(contained_in_object)) { + return true; + } else if (!keys.some(contained_in_object)) { + return false; + } else { + throw new Error(error_message(keys)); + } +} + +/* + * Specify an object and array of keys to check. + * An error will be thrown if any of the keys are missing from the object + */ +function required_group(object, keys) { + var contained_in_object = _.contains.bind(null, Object.keys(object)); + + if (keys.every(contained_in_object)) { + return true; + } else { + throw new Error(error_message(keys)); + } +} + +/* + * Create a friendly error message from a list of keys + */ +function error_message(keys) { + var start = 'parameters '; + + var listStart = keys.slice(0, -1).join(', '); + var listEnd = ' and ' + keys[keys.length - 1]; + + var adjective = (keys.length > 2) ? 'all' : 'both'; + + var end = ' must ' + adjective + ' be specified'; + + return start + listStart + listEnd + end; +} + +module.exports = { + optional: optional_group, + required: required_group +}; diff --git a/test/unit/run.js b/test/unit/run.js index 2356ce21..7e0fe272 100644 --- a/test/unit/run.js +++ b/test/unit/run.js @@ -23,6 +23,7 @@ var tests = [ require('./sanitiser/_flag_bool'), require('./sanitiser/_geo_common'), require('./sanitiser/_geo_reverse'), + require('./sanitiser/_groups'), require('./sanitiser/_ids'), require('./sanitiser/_layers'), require('./sanitiser/_single_scalar_parameters'), diff --git a/test/unit/sanitiser/_groups.js b/test/unit/sanitiser/_groups.js new file mode 100644 index 00000000..63b86ea7 --- /dev/null +++ b/test/unit/sanitiser/_groups.js @@ -0,0 +1,75 @@ +var groups = require('../../../sanitiser/_groups'); + +module.exports.tests = {}; + +module.exports.tests.optional_group = function(test, common) { + test('optional group none present ', function(t) { + var object = {}; + t.doesNotThrow(function() { + var present = groups.optional(object, [ 'a', 'b' ]); + t.equal(present, false, 'group reported not present'); + }); + t.end(); + }); + + test('optional group all present ', function(t) { + var object = { 'a': 5, 'b': 9 }; + t.doesNotThrow(function() { + var present = groups.optional(object, [ 'a', 'b' ]); + t.equal(present, true, 'group reported present'); + }); + t.end(); + }); + + test('optional group some present ', function(t) { + var object = { 'b': 9 }; + t.throws(function() { + groups.optional(object, [ 'a', 'b' ]); + }, new RegExp('parameters a and b must both be specified')); + t.end(); + }); + + test('optional group some present (larger group) ', function(t) { + var object = { 'b': 9, 'd': 5 }; + t.throws(function() { + groups.optional(object, [ 'a', 'b', 'c', 'd', 'e' ]); + }, new RegExp('parameters a, b, c, d and e must all be specified')); + t.end(); + }); +}; + +module.exports.tests.required_group = function(test, common) { + test('required group none present ', function(t) { + var object = {}; + t.throws(function() { + groups.required(object, [ 'a', 'b' ]); + }, new RegExp('parameters a and b must both be specified')); + t.end(); + }); + + test('required group all present ', function(t) { + var object = { 'a': 5, 'b': 9 }; + t.doesNotThrow(function() { + groups.required(object, [ 'a', 'b' ]); + }); + t.end(); + }); + + test('required group some present ', function(t) { + var object = { 'b': 9 }; + t.throws(function() { + groups.required(object, [ 'a', 'b' ]); + }, new RegExp('parameters a and b must both be specified')); + t.end(); + }); +}; + +module.exports.all = function (tape, common) { + function test(name, testFunction) { + return tape('SANTIZE _groups ' + name, testFunction); + } + + for( var testCase in module.exports.tests ){ + module.exports.tests[testCase](test, common); + } +}; From 415029e02b18720efc3d38edc36f28ffafb8e526 Mon Sep 17 00:00:00 2001 From: Julian Simioni Date: Wed, 23 Sep 2015 17:28:35 -0400 Subject: [PATCH 7/9] Use groups sanitiser in sanitize_rect and sanitize_point --- sanitiser/_geo_common.js | 86 +++++++++++++++-------------------- test/unit/sanitiser/search.js | 4 +- 2 files changed, 38 insertions(+), 52 deletions(-) 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); }); From b315adc6aa3e1b6ab2f5b0d3407ae8f54a492bba Mon Sep 17 00:00:00 2001 From: Julian Simioni Date: Wed, 23 Sep 2015 17:30:55 -0400 Subject: [PATCH 8/9] Use groups sanitiser in sanitize_circle --- sanitiser/_geo_common.js | 41 ++++++---------------------------------- 1 file changed, 6 insertions(+), 35 deletions(-) diff --git a/sanitiser/_geo_common.js b/sanitiser/_geo_common.js index d63d0455..31209e94 100644 --- a/sanitiser/_geo_common.js +++ b/sanitiser/_geo_common.js @@ -49,42 +49,13 @@ function sanitize_rect( key_prefix, clean, raw, bbox_is_required ) { */ function sanitize_circle( key_prefix, clean, raw, circle_is_required ) { - // the names we use to define the centroid - 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++; - } - }); - - // all fields specified - if( 2 === totalFieldsSpecified ) { - // 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 ); + sanitize_point( key_prefix, clean, raw, circle_is_required); - if( check.assigned( raw[ key_prefix + '.radius' ] ) ){ - sanitize_coord( key_prefix + '.radius', clean, raw[ key_prefix + '.radius' ], true ); - } - } - // fields only partially specified - else if( totalFieldsSpecified > 0 ){ - var format1 = 'missing circle param \'%s\' requires all of: \'%s\' to be present'; - throw new Error( util.format( format1, key_prefix, mandatoryProps.join('\',\'') ) ); - } - // radius was specified without lat or lon - else if( raw.hasOwnProperty( key_prefix + '.radius' ) ){ - var format2 = 'missing circle param \'%s\' requires all of: \'%s\' to be present'; - throw new Error( util.format( format2, key_prefix, mandatoryProps.join('\',\'') ) ); - } - // fields required, eg. ( totalFieldsSpecified === 0 && bbox_is_required === true ) - else if( circle_is_required ){ - var format3 = 'missing circle param \'%s\' requires all of: \'%s\' to be present'; - throw new Error( util.format( format3, key_prefix, mandatoryProps.join('\',\'') ) ); + if( check.assigned( raw[ key_prefix + '.radius' ] ) ){ + sanitize_coord( key_prefix + '.radius', clean, raw[ key_prefix + '.radius' ], true ); + sanitize_point( key_prefix, clean, raw, true); + } else { + sanitize_point( key_prefix, clean, raw, circle_is_required); } } From c3417a0ace2d760dc9adec2e435debd31ecd6420 Mon Sep 17 00:00:00 2001 From: Julian Simioni Date: Thu, 24 Sep 2015 17:40:21 -0400 Subject: [PATCH 9/9] Cleanup comments for usage of groups sanitizer --- sanitiser/_geo_common.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/sanitiser/_geo_common.js b/sanitiser/_geo_common.js index 31209e94..0ca1184e 100644 --- a/sanitiser/_geo_common.js +++ b/sanitiser/_geo_common.js @@ -15,12 +15,13 @@ var groups = require('./_groups'), * @param {bool} bbox_is_required */ function sanitize_rect( key_prefix, clean, raw, bbox_is_required ) { - - // the names we use to define the corners of the rect + // calculate full property names from the key_prefix var properties = [ 'min_lat', 'max_lat', 'min_lon', 'max_lon' ].map(function(prop) { return key_prefix + '.' + prop; }); + // sanitize the rect property group, this throws an exception if + // the group is not complete var bbox_present; if (bbox_is_required) { bbox_present = groups.required(raw, properties); @@ -32,9 +33,9 @@ function sanitize_rect( key_prefix, clean, raw, bbox_is_required ) { // and not present if (!bbox_present) { return; } + // check each property individually. now that it is known a bbox is present, + // all properties must exist, so pass the true flag for coord_is_required 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); }); } @@ -48,9 +49,8 @@ function sanitize_rect( key_prefix, clean, raw, bbox_is_required ) { * @param {bool} circle_is_required */ function sanitize_circle( key_prefix, clean, raw, circle_is_required ) { - - sanitize_point( key_prefix, clean, raw, circle_is_required); - + // sanitize both a point and a radius if radius is present + // otherwise just sanittize the point if( check.assigned( raw[ key_prefix + '.radius' ] ) ){ sanitize_coord( key_prefix + '.radius', clean, raw[ key_prefix + '.radius' ], true ); sanitize_point( key_prefix, clean, raw, true); @@ -68,13 +68,13 @@ function sanitize_circle( key_prefix, clean, raw, circle_is_required ) { * @param {bool} point_is_required */ function sanitize_point( key_prefix, clean, raw, point_is_required ) { - - // the names we use to define the point + // calculate full property names from the key_prefix var properties = [ 'lat', 'lon'].map(function(prop) { return key_prefix + '.' + prop; }); - + // sanitize the rect property group, this throws an exception if + // the group is not complete var point_present; if (point_is_required) { point_present = groups.required(raw, properties); @@ -86,9 +86,9 @@ function sanitize_point( key_prefix, clean, raw, point_is_required ) { // and not present if (!point_present) { return; } + // check each property individually. now that it is known a bbox is present, + // all properties must exist, so pass the true flag for coord_is_required 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); }); }