Browse Source

Merge pull request #12 from pelias/geojson

geojsonify suggest API
pull/14/head
Peter Johnson @insertcoffee 10 years ago
parent
commit
245974ea7f
  1. 53
      controller/suggest.js
  2. 1
      package.json
  3. 9
      test/ciao/suggest/success.coffee
  4. 36
      test/unit/controller/suggest.js
  5. 7
      test/unit/mock/backend.js

53
controller/suggest.js

@ -1,4 +1,6 @@
var GeoJSON = require('geojson');
function setup( backend, query ){
// allow overriding of dependencies
@ -26,11 +28,14 @@ function setup( backend, query ){
docs = data['pelias'][0].options || [];
}
// convert docs to geojson
var geojson = geoJsonifyDocs( docs );
// response envelope
geojson.date = new Date().getTime();
// respond
return res.status(200).json({
date: new Date().getTime(),
body: docs
});
return res.status(200).json( geojson );
});
}
@ -38,4 +43,44 @@ function setup( backend, query ){
return controller;
}
function geoJsonifyDocs( docs ){
// emit a warning if the doc format is invalid
// @note: if you see this error, fix it ASAP!
function warning(){
console.error( 'error: invalid doc', __filename );
return false; // remove offending doc from results
}
// flatten & expand data for geojson conversion
var geodata = docs.map( function( doc ){
// something went very wrong
if( !doc || !doc.payload ) return warning();
// split payload id string in to geojson properties
if( 'string' !== typeof doc.payload.id ) return warning();
var idParts = doc.payload.id.split('/');
doc.type = idParts[0];
doc.id = idParts[1];
// split payload geo string in to geojson properties
if( 'string' !== typeof doc.payload.geo ) return warning();
var geoParts = doc.payload.geo.split(',');
doc.lat = parseFloat( geoParts[1] );
doc.lng = parseFloat( geoParts[0] );
// remove payload from doc
delete doc.payload;
return doc;
// filter-out invalid entries
}).filter( function( doc ){
return doc;
});
// convert to geojson
return GeoJSON.parse( geodata, { Point: ['lat', 'lng'] } );
}
module.exports = setup;

1
package.json

@ -33,6 +33,7 @@
},
"dependencies": {
"express": "^4.8.8",
"geojson": "https://github.com/missinglink/GeoJSON.js/tarball/master",
"geopipes-elasticsearch-backend": "0.0.7",
"pelias-esclient": "0.0.25",
"toobusy": "^0.2.4"

9
test/ciao/suggest/success.coffee

@ -9,7 +9,8 @@ response.statusCode.should.equal 200
now = new Date().getTime()
should.exist json
should.not.exist json.error
should.exist json.date
json.date.should.be.within now-2000, now+2000
should.exist json.body
json.body.should.be.instanceof Array
json.date.should.be.within now-5000, now+5000
#? valid geojson
json.type.should.equal 'FeatureCollection'
json.features.should.be.instanceof Array

36
test/unit/controller/suggest.js

@ -15,7 +15,33 @@ module.exports.tests.interface = function(test, common) {
// functionally test controller (backend success)
module.exports.tests.functional_success = function(test, common) {
test('functional test', function(t) {
// expected geojson features for 'client/suggest/ok/1' fixture
var expected = [{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [ 101, -10.1 ]
},
properties: {
id: 'mockid',
type: 'mocktype',
value: 1
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [ 101, -10.1 ]
},
properties: {
id: 'mockid',
type: 'mocktype',
value: 2
}
}];
test('functional success', function(t) {
var backend = mockBackend( 'client/suggest/ok/1', function( cmd ){
t.deepEqual(cmd, { body: { a: 'b' }, index: 'pelias' }, 'correct backend command');
});
@ -26,10 +52,12 @@ module.exports.tests.functional_success = function(test, common) {
return res;
},
json: function( json ){
console.log(json);
t.equal(typeof json, 'object', 'returns json');
t.equal(typeof json.date, 'number', 'date set');
t.true(Array.isArray(json.body), 'body is array');
t.deepEqual(json.body, [ { value: 1 }, { value: 2 } ], 'values correctly mapped');
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();
}
};
@ -39,7 +67,7 @@ module.exports.tests.functional_success = function(test, common) {
// functionally test controller (backend failure)
module.exports.tests.functional_failure = function(test, common) {
test('functional test', function(t) {
test('functional failure', function(t) {
var backend = mockBackend( 'client/suggest/fail/1', function( cmd ){
t.deepEqual(cmd, { body: { a: 'b' }, index: 'pelias' }, 'correct backend command');
});

7
test/unit/mock/backend.js

@ -1,7 +1,12 @@
var mockPayload = {
id: 'mocktype/mockid',
geo: '101,-10.1'
};
var responses = {};
responses['client/suggest/ok/1'] = function( cmd, cb ){
return cb( undefined, suggestEnvelope([ { value: 1 }, { value: 2 } ]) );
return cb( undefined, suggestEnvelope([ { value: 1, payload: mockPayload }, { value: 2, payload: mockPayload } ]) );
};
responses['client/suggest/fail/1'] = function( cmd, cb ){
return cb( 'a backend error occurred' );

Loading…
Cancel
Save