const geojsonify = require('../../../helper/geojsonify'); const proxyquire = require('proxyquire').noCallThru(); module.exports.tests = {}; module.exports.tests.interface = function(test, common) { test('valid interface', function(t) { t.equal(typeof geojsonify, 'function', 'geojsonify is a function'); t.equal(geojsonify.length, 2, 'accepts x arguments'); t.end(); }); }; // ref: https://github.com/pelias/pelias/issues/84 module.exports.tests.earth = function(test, common) { test('earth', function(t) { var earth = [{ '_type': 'geoname', '_id': '6295630', 'source': 'whosonfirst', 'layer': 'continent', 'name': { 'default': 'Earth' }, 'center_point': { 'lon': 0, 'lat': 0 } }]; t.doesNotThrow(function(){ geojsonify( {}, earth ); }); t.end(); }); }; module.exports.tests.all = (test, common) => { test('bounding_box should be calculated using points when avaiable', t => { const input = [ { _id: 'id 1', source: 'source 1', source_id: 'source_id 1', layer: 'layer 1', name: { default: 'name 1', }, center_point: { lat: 12.121212, lon: 21.212121 } }, { _id: 'id 2', source: 'source 2', source_id: 'source_id 2', layer: 'layer 2', name: { default: 'name 2', }, center_point: { lat: 13.131313, lon: 31.313131 } } ]; const geojsonify = proxyquire('../../../helper/geojsonify', { './geojsonify_place_details': (params, source, dst) => { if (source._id === 'id 1') { return { property1: 'property 1', property2: 'property 2' }; } else if (source._id === 'id 2') { return { property3: 'property 3', property4: 'property 4' }; } } }); const actual = geojsonify({}, input); const expected = { type: 'FeatureCollection', features: [ { type: 'Feature', geometry: { type: 'Point', coordinates: [ 21.212121, 12.121212 ] }, properties: { id: 'id 1', gid: 'source 1:layer 1:id 1', layer: 'layer 1', source: 'source 1', source_id: 'source_id 1', name: 'name 1', property1: 'property 1', property2: 'property 2' } }, { type: 'Feature', geometry: { type: 'Point', coordinates: [ 31.313131, 13.131313 ] }, properties: { id: 'id 2', gid: 'source 2:layer 2:id 2', layer: 'layer 2', source: 'source 2', source_id: 'source_id 2', name: 'name 2', property3: 'property 3', property4: 'property 4' } } ], bbox: [21.212121, 12.121212, 31.313131, 13.131313] }; t.deepEquals(actual, expected); t.end(); }); test('bounding_box should be calculated using polygons when avaiable', t => { const input = [ { _id: 'id 1', source: 'source 1', source_id: 'source_id 1', layer: 'layer 1', name: { default: 'name 1', }, bounding_box: { min_lon: 1, min_lat: 1, max_lon: 2, max_lat: 2 }, center_point: { lat: 12.121212, lon: 21.212121 } }, { _id: 'id 2', source: 'source 2', source_id: 'source_id 2', layer: 'layer 2', name: { default: 'name 2', }, bounding_box: { min_lon: -3, min_lat: -3, max_lon: -1, max_lat: -1 }, center_point: { lat: 13.131313, lon: 31.313131 } } ]; const geojsonify = proxyquire('../../../helper/geojsonify', { './geojsonify_place_details': (params, source, dst) => { if (source._id === 'id 1') { return { property1: 'property 1', property2: 'property 2' }; } else if (source._id === 'id 2') { return { property3: 'property 3', property4: 'property 4' }; } } }); const actual = geojsonify({}, input); const expected = { type: 'FeatureCollection', features: [ { type: 'Feature', geometry: { type: 'Point', coordinates: [ 21.212121, 12.121212 ] }, properties: { id: 'id 1', gid: 'source 1:layer 1:id 1', layer: 'layer 1', source: 'source 1', source_id: 'source_id 1', name: 'name 1', property1: 'property 1', property2: 'property 2' }, bbox: [ 1, 1, 2, 2 ] }, { type: 'Feature', geometry: { type: 'Point', coordinates: [ 31.313131, 13.131313 ] }, properties: { id: 'id 2', gid: 'source 2:layer 2:id 2', layer: 'layer 2', source: 'source 2', source_id: 'source_id 2', name: 'name 2', property3: 'property 3', property4: 'property 4' }, bbox: [ -3, -3, -1, -1 ] } ], bbox: [ -3, -3, 2, 2 ] }; t.deepEquals(actual, expected); t.end(); }); test('bounding_box should be calculated using polygons AND points when avaiable', t => { const input = [ { _id: 'id 1', source: 'source 1', source_id: 'source_id 1', layer: 'layer 1', name: { default: 'name 1', }, center_point: { lat: 12.121212, lon: 21.212121 } }, { _id: 'id 2', source: 'source 2', source_id: 'source_id 2', layer: 'layer 2', name: { default: 'name 2', }, bounding_box: { min_lon: -3, min_lat: -3, max_lon: -1, max_lat: -1 }, center_point: { lat: 13.131313, lon: 31.313131 } } ]; const geojsonify = proxyquire('../../../helper/geojsonify', { './geojsonify_place_details': (params, source, dst) => { if (source._id === 'id 1') { return { property1: 'property 1', property2: 'property 2' }; } else if (source._id === 'id 2') { return { property3: 'property 3', property4: 'property 4' }; } } }); const actual = geojsonify({}, input); const expected = { type: 'FeatureCollection', features: [ { type: 'Feature', geometry: { type: 'Point', coordinates: [ 21.212121, 12.121212 ] }, properties: { id: 'id 1', gid: 'source 1:layer 1:id 1', layer: 'layer 1', source: 'source 1', source_id: 'source_id 1', name: 'name 1', property1: 'property 1', property2: 'property 2' } }, { type: 'Feature', geometry: { type: 'Point', coordinates: [ 31.313131, 13.131313 ] }, properties: { id: 'id 2', gid: 'source 2:layer 2:id 2', layer: 'layer 2', source: 'source 2', source_id: 'source_id 2', name: 'name 2', property3: 'property 3', property4: 'property 4' }, bbox: [ -3, -3, -1, -1 ] } ], bbox: [ -3, -3, 21.212121, 12.121212 ] }; t.deepEquals(actual, expected); t.end(); }); }; module.exports.tests.non_optimal_conditions = (test, common) => { test('null/undefined places should log warnings and be ignored', t => { const logger = require('pelias-mock-logger')(); const input = [ null, undefined, { _id: 'id 1', source: 'source 1', source_id: 'source_id 1', layer: 'layer 1', name: { default: 'name 1', }, center_point: { lat: 12.121212, lon: 21.212121 } } ]; const geojsonify = proxyquire('../../../helper/geojsonify', { './geojsonify_place_details': (params, source, dst) => { if (source._id === 'id 1') { return { property1: 'property 1', property2: 'property 2' }; } }, 'pelias-logger': logger }); const actual = geojsonify({}, input); const expected = { type: 'FeatureCollection', features: [ { type: 'Feature', geometry: { type: 'Point', coordinates: [ 21.212121, 12.121212 ] }, properties: { id: 'id 1', gid: 'source 1:layer 1:id 1', layer: 'layer 1', source: 'source 1', source_id: 'source_id 1', name: 'name 1', property1: 'property 1', property2: 'property 2' } } ], bbox: [21.212121, 12.121212, 21.212121, 12.121212] }; t.deepEquals(actual, expected); t.ok(logger.isWarnMessage('No doc or center_point property')); t.end(); }); test('places w/o center_point should log warnings and be ignored', t => { const logger = require('pelias-mock-logger')(); const input = [ { _id: 'id 1', source: 'source 1', source_id: 'source_id 1', layer: 'layer 1', name: { default: 'name 1', } }, { _id: 'id 2', source: 'source 2', source_id: 'source_id 2', layer: 'layer 2', name: { default: 'name 2', }, center_point: { lat: 13.131313, lon: 31.313131 } } ]; const geojsonify = proxyquire('../../../helper/geojsonify', { './geojsonify_place_details': (params, source, dst) => { if (source._id === 'id 2') { return { property3: 'property 3', property4: 'property 4' }; } }, 'pelias-logger': logger }); const actual = geojsonify({}, input); const expected = { type: 'FeatureCollection', features: [ { type: 'Feature', geometry: { type: 'Point', coordinates: [ 31.313131, 13.131313 ] }, properties: { id: 'id 2', gid: 'source 2:layer 2:id 2', layer: 'layer 2', source: 'source 2', source_id: 'source_id 2', name: 'name 2', property3: 'property 3', property4: 'property 4' } } ], bbox: [31.313131, 13.131313, 31.313131, 13.131313] }; t.deepEquals(actual, expected); t.ok(logger.isWarnMessage('No doc or center_point property')); t.end(); }); test('places w/o names should log warnings and be ignored', t => { const logger = require('pelias-mock-logger')(); const input = [ { _id: 'id 1', source: 'source 1', source_id: 'source_id 1', layer: 'layer 1', center_point: { lat: 12.121212, lon: 21.212121 } }, { _id: 'id 2', source: 'source 2', source_id: 'source_id 2', layer: 'layer 2', name: {}, center_point: { lat: 13.131313, lon: 31.313131 } }, { _id: 'id 3', source: 'source 3', source_id: 'source_id 3', layer: 'layer 3', name: { default: 'name 3', }, center_point: { lat: 14.141414, lon: 41.414141 } } ]; const geojsonify = proxyquire('../../../helper/geojsonify', { './geojsonify_place_details': (params, source, dst) => { if (source._id === 'id 1') { return { property1: 'property 1', property2: 'property 2' }; } else if (source._id === 'id 2') { return { property3: 'property 3', property4: 'property 4' }; } else if (source._id === 'id 3') { return { property5: 'property 5', property6: 'property 6' }; } }, 'pelias-logger': logger }); const actual = geojsonify({}, input); const expected = { type: 'FeatureCollection', features: [ { type: 'Feature', geometry: { type: 'Point', coordinates: [ 21.212121, 12.121212 ] }, properties: { id: 'id 1', gid: 'source 1:layer 1:id 1', layer: 'layer 1', source: 'source 1', source_id: 'source_id 1', property1: 'property 1', property2: 'property 2' } }, { type: 'Feature', geometry: { type: 'Point', coordinates: [ 31.313131, 13.131313 ] }, properties: { id: 'id 2', gid: 'source 2:layer 2:id 2', layer: 'layer 2', source: 'source 2', source_id: 'source_id 2', property3: 'property 3', property4: 'property 4' } }, { type: 'Feature', geometry: { type: 'Point', coordinates: [ 41.414141, 14.141414 ] }, properties: { id: 'id 3', gid: 'source 3:layer 3:id 3', layer: 'layer 3', source: 'source 3', source_id: 'source_id 3', name: 'name 3', property5: 'property 5', property6: 'property 6' } } ], bbox: [21.212121, 12.121212, 41.414141, 14.141414] }; t.deepEquals(actual, expected); t.ok(logger.isWarnMessage('doc source 1:layer 1:id 1 does not contain name.default')); t.ok(logger.isWarnMessage('doc source 2:layer 2:id 2 does not contain name.default')); t.end(); }); test('no points', t => { const logger = require('pelias-mock-logger')(); const input = []; const geojsonify = proxyquire('../../../helper/geojsonify', { './geojsonify_place_details': (params, source, dst) => { t.fail('should not have bee called'); }, 'pelias-logger': logger }); const actual = geojsonify({}, input); const expected = { type: 'FeatureCollection', features: [] }; t.deepEquals(actual, expected); t.end(); }); }; // ensure that if elasticsearch returns an array of values for name.default // .. that we handle this case and select the first element for the label. module.exports.tests.nameAliases = function(test, common) { test('name aliases', function(t) { var aliases = [{ '_type': 'example', '_id': '1', 'source': 'example', 'layer': 'example', 'name': { 'default': ['Example1', 'Example2'] // note the array }, 'center_point': { 'lon': 0, 'lat': 0 } }]; const expected = { type: 'FeatureCollection', features: [{ type: 'Feature', geometry: { type: 'Point', coordinates: [ 0, 0 ] }, properties: { id: '1', gid: 'example:example:1', layer: 'example', source: 'example', source_id: undefined, name: 'Example1' } }], bbox: [ 0, 0, 0, 0 ] }; var actual = geojsonify( {}, aliases ); t.deepEquals(actual, expected); t.end(); }); }; module.exports.all = (tape, common) => { function test(name, testFunction) { return tape(`geojsonify: ${name}`, testFunction); } for( var testCase in module.exports.tests ){ module.exports.tests[testCase](test, common); } };