Browse Source

Rename `source` to `sources`

... with a dash of refactoring thrown in for good measure
pull/250/head
Diana Shkolnikov 9 years ago
parent
commit
67e034f5f2
  1. 20
      helper/types.js
  2. 30
      middleware/_types.js
  3. 8
      query/sources.js
  4. 44
      sanitiser/_source.js
  5. 44
      sanitiser/_sources.js
  6. 2
      sanitiser/reverse.js
  7. 2
      sanitiser/search.js
  8. 32
      test/unit/helper/types.js
  9. 2
      test/unit/run.js
  10. 31
      test/unit/sanitiser/_sources.js

20
helper/types.js

@ -9,23 +9,29 @@ var intersection = function intersection(set1, set2) {
});
};
/**
* Combine all types and determine the unique subset
*
* @param {Array} clean_types
* @returns {Array}
*/
module.exports = function calculate_types(clean_types) {
if (!clean_types) {
return undefined;
if (!clean_types || !(clean_types.from_layers || clean_types.from_sources || clean_types.from_address_parser)) {
throw new Error('clean_types should not be null or undefined');
}
/* the layers and source parameters are cumulative:
* perform a set insersection of their specified types
* perform a set intersection of their specified types
*/
if (clean_types.from_layers || clean_types.from_source) {
if (clean_types.from_layers || clean_types.from_sources) {
var types = valid_types;
if (clean_types.from_layers) {
types = intersection(types, clean_types.from_layers);
}
if (clean_types.from_source) {
types = intersection(types, clean_types.from_source);
if (clean_types.from_sources) {
types = intersection(types, clean_types.from_sources);
}
return types;
@ -38,4 +44,6 @@ module.exports = function calculate_types(clean_types) {
if (clean_types.from_address_parser) {
return clean_types.from_address_parser;
}
throw new Error('no types specified');
};

30
middleware/_types.js

@ -8,17 +8,27 @@ var types_helper = require( '../helper/types' );
* message instead of searching at all.
*/
function middleware(req, res, next) {
var types = types_helper(req.clean.types);
req.clean = req.clean || {};
if (types !== undefined && types.length !== undefined) {
if (types.length === 0) {
var err = 'You have specified both the `source` and `layers` ' +
'parameters in a combination that will return no results.';
res.status(400); // 400 Bad Request
return next(err);
} else {
req.clean.type = types;
}
if (req.clean.hasOwnProperty('types') === false) {
return next();
}
try {
var types = types_helper(req.clean.types);
if ((types instanceof Array) && types.length === 0) {
var err = 'You have specified both the `sources` and `layers` ' +
'parameters in a combination that will return no results.';
res.status(400); // 400 Bad Request
return next(err);
}
req.clean.type = types;
}
catch (err) {
// this means there were no types specified
delete req.clean.types;
}
next();

8
query/sources.js

@ -3,8 +3,12 @@
*/
module.exports = {
'geonames': ['geoname'],
'gn' : ['geoname'],
'geonames' : ['geoname'],
'oa' : ['openaddresses'],
'openaddresses' : ['openaddresses'],
'quattroshapes': ['admin0', 'admin1', 'admin2', 'neighborhood', 'locality', 'local_admin'],
'qs' : ['admin0', 'admin1', 'admin2', 'neighborhood', 'locality', 'local_admin'],
'quattroshapes' : ['admin0', 'admin1', 'admin2', 'neighborhood', 'locality', 'local_admin'],
'osm' : ['osmaddress', 'osmnode', 'osmway'],
'openstreetmap' : ['osmaddress', 'osmnode', 'osmway']
};

44
sanitiser/_source.js

@ -1,44 +0,0 @@
var isObject = require('is-object');
var sources_map = require( '../query/sources' );
var all_sources = Object.keys(sources_map);
function sanitize( req ) {
req.clean = req.clean || {};
var params = req.query;
req.clean.types = req.clean.types || {};
// ensure the input params are a valid object
if( !isObject( params ) ){
params = {};
}
// default case (no layers specified in GET params)
// don't even set the from_layers key in this case
if('string' !== typeof params.source || !params.source.length){
return { error: false };
}
var sources = params.source.split(',');
var invalid_sources = sources.filter(function(source) {
return all_sources.indexOf(source) === -1;
});
if (invalid_sources.length > 0) {
return {
error: true,
msg: '`' + invalid_sources[0] + '` is an invalid source parameter. Valid options: ' + all_sources.join(', ')
};
}
var types = sources.reduce(function(acc, source) {
return acc.concat(sources_map[source]);
}, []);
req.clean.types.from_source = types;
return { error: false };
}
module.exports = sanitize;

44
sanitiser/_sources.js

@ -0,0 +1,44 @@
var isObject = require('is-object');
var sources_map = require( '../query/sources' );
function sanitize( req ) {
var params = req.query || {};
req.clean = req.clean || {};
req.clean.types = req.clean.types || {};
// default case (no sources specified in GET params)
if (params.hasOwnProperty('sources') === false) {
return { error: false };
}
params.sources = params.sources.trim();
if (params.sources.trim().length === 0) {
return {
error: true,
message: '`sources` parameter cannot be an empty string. Valid options: ' + Object.keys(sources_map).join(', ')
};
}
var sources = params.sources.split(',');
var invalid_sources = sources.filter(function(source) {
return sources_map.hasOwnProperty(source) === false;
});
if (invalid_sources.length > 0) {
return {
error: true,
message: '`' + invalid_sources[0] + '` is an invalid source parameter. Valid options: ' + Object.keys(sources_map).join(', ')
};
}
req.clean.types.from_sources = sources.reduce(function(acc, source) {
return acc.concat(sources_map[source]);
}, []);
return { error: false };
}
module.exports = sanitize;

2
sanitiser/reverse.js

@ -2,7 +2,7 @@ var _sanitize = require('../sanitiser/_sanitize'),
sanitiser = {
latlonzoom: require('../sanitiser/_geo_reverse'),
layers: require('../sanitiser/_layers'),
suorce: require('../sanitiser/_source'),
suorce: require('../sanitiser/_sources'),
details: require('../sanitiser/_details'),
size: require('../sanitiser/_size'),
categories: function ( req ) {

2
sanitiser/search.js

@ -4,7 +4,7 @@ var _sanitize = require('../sanitiser/_sanitize'),
text: require('../sanitiser/_text'),
size: require('../sanitiser/_size'),
layers: require('../sanitiser/_layers'),
source: require('../sanitiser/_source'),
source: require('../sanitiser/_sources'),
details: require('../sanitiser/_details'),
latlonzoom: require('../sanitiser/_geo_search')
};

32
test/unit/helper/types.js

@ -1,20 +1,32 @@
var types = require('../../../helper/types');
var valid_types = require( '../../../query/types' );
module.exports.tests = {};
module.exports.tests.no_cleaned_types = function(test, common) {
test('no cleaned types', function(t) {
var actual = types(undefined);
t.equal(actual, undefined, 'all valid types returned for empty input');
t.end();
try {
types();
t.fail('exception should be thrown');
}
catch (err) {
t.equal(err.message, 'clean_types should not be null or undefined', 'no input should result in exception');
}
finally {
t.end();
}
});
test('no cleaned types', function(t) {
var cleaned_types = {};
var actual = types(cleaned_types);
t.equal(actual, undefined, 'all valid types returned for empty input');
t.end();
try {
types({});
t.fail('exception should be thrown');
}
catch (err) {
t.equal(err.message, 'clean_types should not be null or undefined', 'no input should result in exception');
}
finally {
t.end();
}
});
};
@ -58,7 +70,7 @@ module.exports.tests.layers_parameter_and_address_parser = function(test, common
module.exports.tests.source_parameter = function(test, common) {
test('source parameter specified', function(t) {
var cleaned_types = {
from_source: ['openaddresses']
from_sources: ['openaddresses']
};
var actual = types(cleaned_types);
@ -72,7 +84,7 @@ module.exports.tests.source_parameter = function(test, common) {
module.exports.tests.source_and_layers_parameters = function(test, common) {
test('source and layers parameter both specified', function(t) {
var cleaned_types = {
from_source: ['openaddresses'],
from_sources: ['openaddresses'],
from_layers: ['osmaddress', 'openaddresses']
};

2
test/unit/run.js

@ -8,7 +8,7 @@ var tests = [
require('./controller/search'),
require('./service/mget'),
require('./service/search'),
require('./sanitiser/_source'),
require('./sanitiser/_sources'),
require('./sanitiser/search'),
require('./sanitiser/reverse'),
require('./sanitiser/place'),

31
test/unit/sanitiser/_source.js → test/unit/sanitiser/_sources.js

@ -1,11 +1,11 @@
var sanitize = require( '../../../sanitiser/_source' );
var sanitize = require( '../../../sanitiser/_sources' );
var success_response = { error: false };
module.exports.tests = {};
module.exports.tests.no_sources = function(test, common) {
test('source is not set', function(t) {
test('sources is not set', function(t) {
var req = {
query: { }
};
@ -20,14 +20,20 @@ module.exports.tests.no_sources = function(test, common) {
test('source is empty string', function(t) {
var req = {
query: {
source: ''
sources: ''
}
};
var expected_response = {
error: true,
message: '`sources` parameter cannot be an empty string. ' +
'Valid options: gn, geonames, oa, openaddresses, qs, quattroshapes, osm, openstreetmap'
};
var response = sanitize(req);
t.deepEqual(req.clean.types, {}, 'clean.types should be empty object');
t.deepEqual(response, success_response, 'no error returned');
t.deepEqual(response, expected_response, 'no error returned');
t.end();
});
};
@ -36,13 +42,13 @@ module.exports.tests.valid_sources = function(test, common) {
test('geonames source', function(t) {
var req = {
query: {
source: 'geonames'
sources: 'geonames'
}
};
var response = sanitize(req);
t.deepEqual(req.clean.types, { from_source: ['geoname'] }, 'clean.types should contain from_source entry with geonames');
t.deepEqual(req.clean.types, { from_sources: ['geoname'] }, 'clean.types should contain from_source entry with geonames');
t.deepEqual(response, success_response, 'no error returned');
t.end();
});
@ -50,11 +56,11 @@ module.exports.tests.valid_sources = function(test, common) {
test('openstreetmap source', function(t) {
var req = {
query: {
source: 'openstreetmap'
sources: 'openstreetmap'
}
};
var expected_types = {
from_source: ['osmaddress', 'osmnode', 'osmway']
from_sources: ['osmaddress', 'osmnode', 'osmway']
};
var response = sanitize(req);
@ -67,11 +73,11 @@ module.exports.tests.valid_sources = function(test, common) {
test('multiple sources', function(t) {
var req = {
query: {
source: 'openstreetmap,openaddresses'
sources: 'openstreetmap,openaddresses'
}
};
var expected_types = {
from_source: ['osmaddress', 'osmnode', 'osmway', 'openaddresses']
from_sources: ['osmaddress', 'osmnode', 'osmway', 'openaddresses']
};
var response = sanitize(req);
@ -87,12 +93,13 @@ module.exports.tests.invalid_sources = function(test, common) {
test('geonames source', function(t) {
var req = {
query: {
source: 'notasource'
sources: 'notasource'
}
};
var expected_response = {
error: true,
msg: '`notasource` is an invalid source parameter. Valid options: geonames, openaddresses, quattroshapes, openstreetmap'
message: '`notasource` is an invalid source parameter. ' +
'Valid options: gn, geonames, oa, openaddresses, qs, quattroshapes, osm, openstreetmap'
};
var response = sanitize(req);
Loading…
Cancel
Save