Browse Source

Merge pull request #103 from pelias/address-details

Detail Param
pull/93/merge 1.2.0
Diana Shkolnikov 10 years ago
parent
commit
d8ac05ea65
  1. 10
      DOCS.md
  2. 2
      controller/doc.js
  3. 2
      controller/search.js
  4. 2
      controller/suggest.js
  5. 33
      helper/geojsonify.js
  6. 39
      sanitiser/_details.js
  7. 4
      sanitiser/_geo.js
  8. 4
      sanitiser/_id.js
  9. 4
      sanitiser/_input.js
  10. 4
      sanitiser/_size.js
  11. 3
      sanitiser/coarse.js
  12. 3
      sanitiser/doc.js
  13. 1
      sanitiser/reverse.js
  14. 1
      sanitiser/search.js
  15. 1
      sanitiser/suggest.js
  16. 54
      test/unit/controller/doc.js
  17. 54
      test/unit/controller/search.js
  18. 64
      test/unit/controller/suggest.js
  19. 84
      test/unit/helper/geojsonify.js
  20. 3
      test/unit/sanitiser/coarse.js
  21. 46
      test/unit/sanitiser/doc.js
  22. 40
      test/unit/sanitiser/reverse.js
  23. 42
      test/unit/sanitiser/search.js
  24. 42
      test/unit/sanitiser/suggest.js

10
DOCS.md

@ -20,7 +20,10 @@ Full text search endpoint which queries the elasticsearch doc store, slightly sl
* can be one of the following comma separated string values
* bottom left lat, bottom left lon, top right lat, top right lon
* left, bottom, right, top
* min longitude, min latitude, max longitude, max latitude
* min longitude, min latitude, max longitude, max latitude
* **details**: indicates if results should contain detailed, should be `true` or `false`
* when false results will only contain `id`, `layer`, and `text` properties
* when true, all available properties will be included in results
## /search/coarse
@ -37,6 +40,7 @@ This is a coarse forward geocoder endpoint which only searches admin dataset lay
* **bbox**: the bounding box frome which you want all your results to come
* **size**: (defaults to 10)
* **layers**: (defaults to ```admin```)
* **details**: (defaults to `true`)
## /suggest
@ -53,6 +57,7 @@ The autocomplete endpoint, it offers fast response time. Mixes results from arou
* **zoom**: zoom level from which you wish to view the world
* **size**: number of results requested (defaults to 10)
* **layers**: datasets you wish to query (defaults to ```poi,admin,address```)
* **details**: (defaults to `true`)
## /suggest/coarse
@ -69,6 +74,7 @@ Only queries the admin layers.
* **zoom**: zoom level from which you wish to view the world
* **size**: number of results requested (defaults to 10)
* **layers**: datasets you wish to query (defaults to ```admin```)
* **details**: (defaults to `true`)
## /suggest/nearby
@ -85,6 +91,7 @@ Works as autocomplete for places located near a latitude/longitude, this endpoin
* **zoom**: zoom level from which you wish to view the world
* **size**: number of results you need (defaults to 10)
* **layers**: datasets you wish to query (defaults to ```poi,admin,address```)
* **details**: (defaults to `true`)
## /reverse
@ -99,6 +106,7 @@ Reverse geocoding endpoint.
* **zoom**: zoom level from which you wish to view the world
* **bbox**: bounding box
* **layers**: (defaults to ```poi,admin,address```)
* **details**: (defaults to `true`)
## /doc

2
controller/doc.js

@ -23,7 +23,7 @@ function setup( backend ){
if( err ){ return next( err ); }
// convert docs to geojson
var geojson = geojsonify( docs );
var geojson = geojsonify( docs, req.clean );
// response envelope
geojson.date = new Date().getTime();

2
controller/search.js

@ -28,7 +28,7 @@ function setup( backend, query ){
if( err ){ return next( err ); }
// convert docs to geojson
var geojson = geojsonify( docs );
var geojson = geojsonify( docs, req.clean );
// response envelope
geojson.date = new Date().getTime();

2
controller/suggest.js

@ -27,7 +27,7 @@ function setup( backend, query, query_mixer ){
function reply( docs ){
// convert docs to geojson
var geojson = geojsonify( docs );
var geojson = geojsonify( docs, req.clean );
// response envelope
geojson.date = new Date().getTime();

33
helper/geojsonify.js

@ -3,7 +3,7 @@ var GeoJSON = require('geojson'),
extent = require('geojson-extent'),
outputGenerator = require('./outputGenerator');
function search( docs ){
function search( docs, params ){
// emit a warning if the doc format is invalid
// @note: if you see this error, fix it ASAP!
@ -12,6 +12,9 @@ function search( docs ){
return false; // remove offending doc from results
}
var details = params ? params.details : {};
details = details === true || details === 1;
// flatten & expand data for geojson conversion
var geodata = docs.map( function( doc ){
@ -29,19 +32,21 @@ function search( docs ){
output.lat = parseFloat( doc.center_point.lat );
output.lng = parseFloat( doc.center_point.lon );
// map name
if( !doc.name || !doc.name.default ) { return warning(); }
output.name = doc.name.default;
// map admin values
if( doc.alpha3 ){ output.alpha3 = doc.alpha3; }
if( doc.admin0 ){ output.admin0 = doc.admin0; }
if( doc.admin1 ){ output.admin1 = doc.admin1; }
if( doc.admin1_abbr ){ output.admin1_abbr = doc.admin1_abbr; }
if( doc.admin2 ){ output.admin2 = doc.admin2; }
if( doc.local_admin ){ output.local_admin = doc.local_admin; }
if( doc.locality ){ output.locality = doc.locality; }
if( doc.neighborhood ){ output.neighborhood = doc.neighborhood; }
if (details) {
// map name
if( !doc.name || !doc.name.default ) { return warning(); }
output.name = doc.name.default;
// map admin values
if( doc.alpha3 ){ output.alpha3 = doc.alpha3; }
if( doc.admin0 ){ output.admin0 = doc.admin0; }
if( doc.admin1 ){ output.admin1 = doc.admin1; }
if( doc.admin1_abbr ){ output.admin1_abbr = doc.admin1_abbr; }
if( doc.admin2 ){ output.admin2 = doc.admin2; }
if( doc.local_admin ){ output.local_admin = doc.local_admin; }
if( doc.locality ){ output.locality = doc.locality; }
if( doc.neighborhood ){ output.neighborhood = doc.neighborhood; }
}
// generate region-specific text string
output.text = outputGenerator( doc );

39
sanitiser/_details.js

@ -0,0 +1,39 @@
var isObject = require('is-object');
// validate inputs, convert types and apply defaults
function sanitize( req, default_value ){
var clean = req.clean || {};
var params= req.query;
if (default_value === undefined) {
default_value = true;
}
default_value = !!default_value;
// ensure the input params are a valid object
if( !isObject( params ) ){
params = {};
}
if (params.details !== undefined) {
var details = params.details;
if (typeof params.details === 'string') {
details = params.details === 'true';
}
clean.details = details === true || details === 1;
} else {
clean.details = default_value;
}
req.clean = clean;
return {'error':false};
}
// export function
module.exports = sanitize;

4
sanitiser/_geo.js

@ -1,3 +1,5 @@
var isObject = require('is-object');
// validate inputs, convert types and apply defaults
function sanitize( req, latlon_is_required ){
@ -6,7 +8,7 @@ function sanitize( req, latlon_is_required ){
latlon_is_required = latlon_is_required || false;
// ensure the input params are a valid object
if( Object.prototype.toString.call( params ) !== '[object Object]' ){
if( !isObject( params ) ){
params = {};
}

4
sanitiser/_id.js

@ -1,3 +1,5 @@
var isObject = require('is-object');
// validate inputs, convert types and apply defaults
// id generally looks like 'geoname:4163334' (type:id)
// so, both type and id are required fields.
@ -10,7 +12,7 @@ function sanitize( req ){
var delim = ':';
// ensure params is a valid object
if( Object.prototype.toString.call( params ) !== '[object Object]' ){
if( !isObject( params ) ){
params = {};
}

4
sanitiser/_input.js

@ -1,3 +1,5 @@
var isObject = require('is-object');
// validate inputs, convert types and apply defaults
function sanitize( req ){
@ -6,7 +8,7 @@ function sanitize( req ){
var delim = ',';
// ensure the input params are a valid object
if( Object.prototype.toString.call( params ) !== '[object Object]' ){
if( !isObject( params ) ){
params = {};
}

4
sanitiser/_size.js

@ -1,3 +1,5 @@
var isObject = require('is-object');
// validate inputs, convert types and apply defaults
function sanitize( req, default_size){
@ -7,7 +9,7 @@ function sanitize( req, default_size){
default_size = default_size || 10;
// ensure the input params are a valid object
if( Object.prototype.toString.call( params ) !== '[object Object]' ){
if( !isObject( params ) ){
params = {};
}

3
sanitiser/coarse.js

@ -9,7 +9,8 @@ var logger = require('../src/logger'),
var layers = require('../sanitiser/_layers');
return layers(req);
},
latlonzoom: require('../sanitiser/_geo')
latlonzoom: require('../sanitiser/_geo'),
details: require('../sanitiser/_details')
};
var sanitize = function(req, cb) { _sanitize(req, sanitizers, cb); };

3
sanitiser/doc.js

@ -2,7 +2,8 @@
var logger = require('../src/logger'),
_sanitize = require('../sanitiser/_sanitize'),
sanitizers = {
id: require('../sanitiser/_id')
id: require('../sanitiser/_id'),
details: require('../sanitiser/_details')
};
var sanitize = function(req, cb) { _sanitize(req, sanitizers, cb); };

1
sanitiser/reverse.js

@ -6,6 +6,7 @@ var _sanitize = require('../sanitiser/_sanitize'),
return geo(req, true);
},
layers: require('../sanitiser/_layers'),
details: require('../sanitiser/_details'),
size: function( req ) {
var size = require('../sanitiser/_size');
return size(req, 1);

1
sanitiser/search.js

@ -5,6 +5,7 @@ var logger = require('../src/logger'),
input: require('../sanitiser/_input'),
size: require('../sanitiser/_size'),
layers: require('../sanitiser/_layers'),
details: require('../sanitiser/_details'),
latlonzoom: require('../sanitiser/_geo')
};

1
sanitiser/suggest.js

@ -5,6 +5,7 @@ var logger = require('../src/logger'),
input: require('../sanitiser/_input'),
size: require('../sanitiser/_size'),
layers: require('../sanitiser/_layers'),
details: require('../sanitiser/_details'),
latlonzoom: function( req ) {
var geo = require('../sanitiser/_geo');
return geo(req, true);

54
test/unit/controller/doc.js

@ -17,6 +17,52 @@ module.exports.tests.functional_success = function(test, common) {
// expected geojson features for 'client/doc/ok/1' fixture
var expected = [{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [ -50.5, 100.1 ]
},
properties: {
id: 'myid1',
layer: 'mytype1',
text: 'test name1, city1, state1'
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [ -51.5, 100.2 ]
},
properties: {
id: 'myid2',
layer: 'mytype2',
text: 'test name2, city2, state2'
}
}];
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');
});
var controller = setup( backend );
var res = {
status: function( code ){
t.equal(code, 200, 'status set');
return res;
},
json: function( json ){
t.equal(typeof json, 'object', 'returns json');
t.equal(typeof json.date, 'number', 'date set');
t.equal(json.type, 'FeatureCollection', 'valid geojson');
t.true(Array.isArray(json.features), 'features is array');
t.deepEqual(json.features, expected, 'values correctly mapped');
t.end();
}
};
controller( { clean: { ids: [ {'id' : 123, 'type': 'a' } ] } }, res );
});
var detailed_expectation = [{
type: 'Feature',
geometry: {
type: 'Point',
@ -47,8 +93,8 @@ module.exports.tests.functional_success = function(test, common) {
text: 'test name2, city2, state2'
}
}];
test('functional success', function(t) {
test('functional success (with details)', 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');
});
@ -63,11 +109,11 @@ module.exports.tests.functional_success = function(test, common) {
t.equal(typeof json.date, 'number', 'date set');
t.equal(json.type, 'FeatureCollection', 'valid geojson');
t.true(Array.isArray(json.features), 'features is array');
t.deepEqual(json.features, expected, 'values correctly mapped');
t.deepEqual(json.features, detailed_expectation, 'values correctly mapped along with details');
t.end();
}
};
controller( { clean: { ids: [ {'id' : 123, 'type': 'a' } ] } }, res );
controller( { clean: { ids: [ {'id' : 123, 'type': 'a' } ], details: true } }, res );
});
};

54
test/unit/controller/search.js

@ -18,6 +18,52 @@ module.exports.tests.functional_success = function(test, common) {
// expected geojson features for 'client/suggest/ok/1' fixture
var expected = [{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [ -50.5, 100.1 ]
},
properties: {
id: 'myid1',
layer: 'mytype1',
text: 'test name1, city1, state1'
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [ -51.5, 100.2 ]
},
properties: {
id: 'myid2',
layer: 'mytype2',
text: 'test name2, city2, state2'
}
}];
test('functional success', function(t) {
var backend = mockBackend( 'client/search/ok/1', function( cmd ){
t.deepEqual(cmd, { body: { a: 'b' }, index: 'pelias', searchType: 'dfs_query_then_fetch' }, 'correct backend command');
});
var controller = setup( backend, mockQuery() );
var res = {
status: function( code ){
t.equal(code, 200, 'status set');
return res;
},
json: function( json ){
t.equal(typeof json, 'object', 'returns json');
t.equal(typeof json.date, 'number', 'date set');
t.equal(json.type, 'FeatureCollection', 'valid geojson');
t.true(Array.isArray(json.features), 'features is array');
t.deepEqual(json.features, expected, 'values correctly mapped');
t.end();
}
};
controller( { clean: { a: 'b' } }, res );
});
var detailed_expectation = [{
type: 'Feature',
geometry: {
type: 'Point',
@ -49,9 +95,9 @@ module.exports.tests.functional_success = function(test, common) {
}
}];
test('functional success', function(t) {
test('functional success (with details)', function(t) {
var backend = mockBackend( 'client/search/ok/1', function( cmd ){
t.deepEqual(cmd, { body: { a: 'b' }, index: 'pelias', searchType: 'dfs_query_then_fetch' }, 'correct backend command');
t.deepEqual(cmd, { body: { a: 'b', details: true }, index: 'pelias', searchType: 'dfs_query_then_fetch' }, 'correct backend command');
});
var controller = setup( backend, mockQuery() );
var res = {
@ -64,11 +110,11 @@ module.exports.tests.functional_success = function(test, common) {
t.equal(typeof json.date, 'number', 'date set');
t.equal(json.type, 'FeatureCollection', 'valid geojson');
t.true(Array.isArray(json.features), 'features is array');
t.deepEqual(json.features, expected, 'values correctly mapped');
t.deepEqual(json.features, detailed_expectation, 'values with details correctly mapped');
t.end();
}
};
controller( { clean: { a: 'b' } }, res );
controller( { clean: { a: 'b', details: true } }, res );
});
};

64
test/unit/controller/suggest.js

@ -18,6 +18,62 @@ module.exports.tests.functional_success = function(test, common) {
// expected geojson features for 'client/mget/ok/1' fixture
var expected = [{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [ -50.5, 100.1 ]
},
properties: {
id: 'myid1',
layer: 'mytype1',
text: 'test name1, city1, state1'
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [ -51.5, 100.2 ]
},
properties: {
id: 'myid2',
layer: 'mytype2',
text: 'test name2, city2, state2'
}
}];
test('functional success', function(t) {
var backend = mockBackend( 'client/suggest/ok/1', function( cmd ){
// the backend executes suggest (vanilla and admin-only) and mget, so we check them all based on cmd
if( cmd.body.docs ){
t.deepEqual(cmd, {
body: { docs: [
{ _id: 'mockid1', _index: 'pelias', _type: 'mocktype' },
{ _id: 'mockid2', _index: 'pelias', _type: 'mocktype' }
]}
}, 'correct mget command');
} else {
t.deepEqual(cmd, { body: { input: 'b' }, index: 'pelias' }, 'correct suggest command');
}
});
var controller = setup( backend, mockQuery() );
var res = {
status: function( code ){
t.equal(code, 200, 'status set');
return res;
},
json: function( json ){
t.equal(typeof json, 'object', 'returns json');
t.equal(typeof json.date, 'number', 'date set');
t.equal(json.type, 'FeatureCollection', 'valid geojson');
t.true(Array.isArray(json.features), 'features is array');
t.deepEqual(json.features, expected, 'values correctly mapped');
t.end();
}
};
controller( { clean: { input: 'b' } }, res );
});
var detailed_expectation = [{
type: 'Feature',
geometry: {
type: 'Point',
@ -49,7 +105,7 @@ module.exports.tests.functional_success = function(test, common) {
}
}];
test('functional success', function(t) {
test('functional success (with details)', function(t) {
var backend = mockBackend( 'client/suggest/ok/1', function( cmd ){
// the backend executes suggest (vanilla and admin-only) and mget, so we check them all based on cmd
if( cmd.body.docs ){
@ -60,7 +116,7 @@ module.exports.tests.functional_success = function(test, common) {
]}
}, 'correct mget command');
} else {
t.deepEqual(cmd, { body: { input: 'b' }, index: 'pelias' }, 'correct suggest command');
t.deepEqual(cmd, { body: { input: 'b', details: true }, index: 'pelias' }, 'correct suggest command');
}
});
var controller = setup( backend, mockQuery() );
@ -74,11 +130,11 @@ module.exports.tests.functional_success = function(test, common) {
t.equal(typeof json.date, 'number', 'date set');
t.equal(json.type, 'FeatureCollection', 'valid geojson');
t.true(Array.isArray(json.features), 'features is array');
t.deepEqual(json.features, expected, 'values correctly mapped');
t.deepEqual(json.features, detailed_expectation, 'values with details correctly mapped');
t.end();
}
};
controller( { clean: { input: 'b' } }, res );
controller( { clean: { input: 'b', details: true } }, res );
});
};

84
test/unit/helper/geojsonify.js

@ -6,7 +6,7 @@ module.exports.tests = {};
module.exports.tests.interface = function(test, common) {
test('valid interface .search()', function(t) {
t.equal(typeof geojsonify.search, 'function', 'search is a function');
t.equal(geojsonify.search.length, 1, 'accepts x arguments');
t.equal(geojsonify.search.length, 2, 'accepts x arguments');
t.end();
});
};
@ -178,11 +178,89 @@ module.exports.tests.search = function(test, common) {
]
};
test('geojsonify.search()', function(t) {
var truthy_params = [true, 1];
test('geojsonify.search(doc, true) with details', function(t) {
var json = geojsonify.search( input, { details: true } );
t.deepEqual(json, expected, 'all docs (with details) mapped');
t.end();
});
truthy_params.forEach(function(details) {
test('geojsonify.search(doc, '+ details +') with details', function(t) {
var json = geojsonify.search( input, { details: details } );
t.deepEqual(json, expected, 'all docs (with details) mapped');
t.end();
});
});
var no_details_expected = {
'type': 'FeatureCollection',
'bbox': [ -73.985656, 40.748432, -0.101795, 51.5337144 ],
'features': [
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [
-0.1069716,
51.5337144
]
},
'properties': {
'id': 'id1',
'layer': 'type1',
'text': '\'Round Midnight Jazz and Blues Bar, test3, Angel'
}
},
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [
-0.101795,
51.517806
]
},
'properties': {
'id': 'id2',
'layer': 'type2',
'text': 'Blues Cafe, test3, Smithfield'
}
},
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [
-73.985656,
40.748432
]
},
'properties': {
'id': '34633854',
'layer': 'osmway',
'text': 'Empire State Building, Manhattan, NY'
}
}
]
};
test('geojsonify.search(doc) with no details (default)', function(t) {
var json = geojsonify.search( input );
t.deepEqual(json, expected, 'all docs mapped');
t.deepEqual(json, no_details_expected, 'all docs (with no details) mapped');
t.end();
});
var falsy_params = [false, undefined, null, 0, -1, 123, 'abc'];
falsy_params.forEach(function(details) {
test('geojsonify.search(doc, '+ details +') with no details', function(t) {
var json = geojsonify.search( input, { details: details } );
t.deepEqual(json, no_details_expected, 'all docs (with no details) mapped');
t.end();
});
});
};
module.exports.all = function (tape, common) {

3
test/unit/sanitiser/coarse.js

@ -53,7 +53,8 @@ module.exports.tests.middleware_success = function(test, common) {
size: 10,
layers: [ 'admin0', 'admin1', 'admin2', 'neighborhood', 'locality', 'local_admin' ],
lat: 0,
lon: 0
lon: 0,
details: true
};
t.equal(message, undefined, 'no error message set');
t.deepEqual(req.clean, defaultClean);

46
test/unit/sanitiser/doc.js

@ -10,7 +10,7 @@ var doc = require('../../../sanitiser/doc'),
defaultMissingTypeError = function(input) {
var type = input.split(delimiter)[0];
return type + ' is invalid. It must be one of these values - [' + indeces.join(', ') + ']'; },
defaultClean = { ids: [ { id: '123', type: 'geoname' } ] },
defaultClean = { ids: [ { id: '123', type: 'geoname' } ], details: true },
sanitize = function(query, cb) { _sanitize({'query':query}, cb); },
inputs = {
valid: [ 'geoname:1', 'osmnode:2', 'admin0:53', 'osmway:44', 'geoname:5' ],
@ -56,7 +56,7 @@ module.exports.tests.sanitize_id = function(test, common) {
test('valid input', function(t) {
inputs.valid.forEach( function( input ){
var input_parts = input.split(delimiter);
var expected = { ids: [ { id: input_parts[1], type: input_parts[0] } ] };
var expected = { ids: [ { id: input_parts[1], type: input_parts[0] } ], details: true };
sanitize({ id: input }, function( err, clean ){
t.equal(err, undefined, 'no error (' + input + ')' );
t.deepEqual(clean, expected, 'clean set correctly (' + input + ')');
@ -94,6 +94,7 @@ module.exports.tests.sanitize_ids = function(test, common) {
var input_parts = input.split(delimiter);
expected.ids.push({ id: input_parts[1], type: input_parts[0] });
});
expected.details = true;
sanitize({ id: inputs.valid }, function( err, clean ){
t.equal(err, undefined, 'no error' );
t.deepEqual(clean, expected, 'clean set correctly');
@ -102,8 +103,47 @@ module.exports.tests.sanitize_ids = function(test, common) {
});
};
module.exports.tests.sanitize_details = function(test, common) {
var invalid_values = [null, -1, 123, NaN, 'abc'];
invalid_values.forEach(function(details) {
test('invalid details param ' + details, function(t) {
sanitize({ id:'geoname:123', details: details }, function( err, clean ){
t.equal(clean.details, false, 'default details set (to false)');
t.end();
});
});
});
var valid_values = ['true', true, 1];
valid_values.forEach(function(details) {
test('valid details param ' + details, function(t) {
sanitize({ id:'geoname:123', details: details }, function( err, clean ){
t.equal(clean.details, true, 'details set to true');
t.end();
});
});
});
var valid_false_values = ['false', false, 0];
valid_false_values.forEach(function(details) {
test('test setting false explicitly ' + details, function(t) {
sanitize({ id:'geoname:123', details: details }, function( err, clean ){
t.equal(clean.details, false, 'details set to false');
t.end();
});
});
});
test('test default behavior', function(t) {
sanitize({ id:'geoname:123' }, function( err, clean ){
t.equal(clean.details, true, 'details set to true');
t.end();
});
});
};
module.exports.tests.de_dupe = function(test, common) {
var expected = { ids: [ { id: '1', type: 'geoname' }, { id: '2', type: 'osmnode' } ] };
var expected = { ids: [ { id: '1', type: 'geoname' }, { id: '2', type: 'osmnode' } ], details: true };
test('duplicate ids', function(t) {
sanitize( { id: ['geoname:1', 'osmnode:2', 'geoname:1'] }, function( err, clean ){
t.equal(err, undefined, 'no error' );

40
test/unit/sanitiser/reverse.js

@ -9,6 +9,7 @@ var suggest = require('../../../sanitiser/reverse'),
'locality', 'local_admin', 'osmaddress', 'openaddresses' ],
lon: 0,
size: 1,
details: true,
categories: []
},
sanitize = function(query, cb) { _sanitize({'query':query}, cb); };
@ -125,6 +126,45 @@ module.exports.tests.sanitize_size = function(test, common) {
});
};
module.exports.tests.sanitize_details = function(test, common) {
var invalid_values = [null, -1, 123, NaN, 'abc'];
invalid_values.forEach(function(details) {
test('invalid details param ' + details, function(t) {
sanitize({ input: 'test', lat: 0, lon: 0, details: details }, function( err, clean ){
t.equal(clean.details, false, 'details set to false');
t.end();
});
});
});
var valid_values = [true, 'true', 1];
valid_values.forEach(function(details) {
test('valid details param ' + details, function(t) {
sanitize({ input: 'test', lat: 0, lon: 0, details: details }, function( err, clean ){
t.equal(clean.details, true, 'details set to true');
t.end();
});
});
});
test('test default behavior', function(t) {
sanitize({ input: 'test', lat: 0, lon: 0 }, function( err, clean ){
t.equal(clean.details, true, 'details set to true');
t.end();
});
});
var valid_false_values = ['false', false, 0];
valid_false_values.forEach(function(details) {
test('test setting false explicitly ' + details, function(t) {
sanitize({ input: 'test', lat: 0, lon: 0, details: details }, function( err, clean ){
t.equal(clean.details, false, 'details set to false');
t.end();
});
});
});
};
module.exports.tests.sanitize_layers = function(test, common) {
test('unspecified', function(t) {
sanitize({ layers: undefined, input: 'test', lat: 0, lon: 0 }, function( err, clean ){

42
test/unit/sanitiser/search.js

@ -7,7 +7,8 @@ var search = require('../../../sanitiser/search'),
defaultClean = { input: 'test',
layers: [ 'geoname', 'osmnode', 'osmway', 'admin0', 'admin1', 'admin2', 'neighborhood',
'locality', 'local_admin', 'osmaddress', 'openaddresses' ],
size: 10
size: 10,
details: true
},
sanitize = function(query, cb) { _sanitize({'query':query}, cb); };
@ -266,6 +267,45 @@ module.exports.tests.sanitize_size = function(test, common) {
});
};
module.exports.tests.sanitize_details = function(test, common) {
var invalid_values = [null, -1, 123, NaN, 'abc'];
invalid_values.forEach(function(details) {
test('invalid details param ' + details, function(t) {
sanitize({ input: 'test', lat: 0, lon: 0, details: details }, function( err, clean ){
t.equal(clean.details, false, 'default details set (to false)');
t.end();
});
});
});
var valid_values = ['true', true, 1];
valid_values.forEach(function(details) {
test('valid details param ' + details, function(t) {
sanitize({ input: 'test', lat: 0, lon: 0, details: details }, function( err, clean ){
t.equal(clean.details, true, 'details set to true');
t.end();
});
});
});
var valid_false_values = ['false', false, 0];
valid_false_values.forEach(function(details) {
test('test setting false explicitly ' + details, function(t) {
sanitize({ input: 'test', lat: 0, lon: 0, details: details }, function( err, clean ){
t.equal(clean.details, false, 'details set to false');
t.end();
});
});
});
test('test default behavior', function(t) {
sanitize({ input: 'test', lat: 0, lon: 0 }, function( err, clean ){
t.equal(clean.details, true, 'details set to true');
t.end();
});
});
};
module.exports.tests.sanitize_layers = function(test, common) {
test('unspecified', function(t) {
sanitize({ layers: undefined, input: 'test' }, function( err, clean ){

42
test/unit/sanitiser/suggest.js

@ -9,7 +9,8 @@ var suggest = require('../../../sanitiser/suggest'),
layers: [ 'geoname', 'osmnode', 'osmway', 'admin0', 'admin1', 'admin2', 'neighborhood',
'locality', 'local_admin', 'osmaddress', 'openaddresses' ],
lon: 0,
size: 10
size: 10,
details: true
},
sanitize = function(query, cb) { _sanitize({'query':query}, cb); };
@ -235,6 +236,45 @@ module.exports.tests.sanitize_size = function(test, common) {
});
};
module.exports.tests.sanitize_details = function(test, common) {
var invalid_values = [null, -1, 123, NaN, 'abc'];
invalid_values.forEach(function(details) {
test('invalid details param ' + details, function(t) {
sanitize({ input: 'test', lat: 0, lon: 0, details: details }, function( err, clean ){
t.equal(clean.details, false, 'default details set (to false)');
t.end();
});
});
});
var valid_values = ['true', true, 1];
valid_values.forEach(function(details) {
test('valid details param ' + details, function(t) {
sanitize({ input: 'test', lat: 0, lon: 0, details: details }, function( err, clean ){
t.equal(clean.details, true, 'details set to true');
t.end();
});
});
});
var valid_false_values = ['false', false, 0];
valid_false_values.forEach(function(details) {
test('test setting false explicitly ' + details, function(t) {
sanitize({ input: 'test', lat: 0, lon: 0, details: details }, function( err, clean ){
t.equal(clean.details, false, 'details set to false');
t.end();
});
});
});
test('test default behavior', function(t) {
sanitize({ input: 'test', lat: 0, lon: 0 }, function( err, clean ){
t.equal(clean.details, true, 'details set to true');
t.end();
});
});
};
module.exports.tests.sanitize_layers = function(test, common) {
test('unspecified', function(t) {
sanitize({ layers: undefined, input: 'test', lat: 0, lon: 0 }, function( err, clean ){

Loading…
Cancel
Save