diff --git a/sanitiser/_deprecate_quattroshapes.js b/sanitiser/_deprecate_quattroshapes.js new file mode 100644 index 00000000..ad724bbc --- /dev/null +++ b/sanitiser/_deprecate_quattroshapes.js @@ -0,0 +1,41 @@ +var _ = require('lodash'); + +/** + In the process of phasing out the 'quattroshapes' source in favour of 'whosonfirst' + we will emit a warning to users so they can begin upgrading their clients. + + In the interim we will automatically rewrite all requests for quattroshapes to whosonfirst. + + @todo: this is only temporary + @see: https://github.com/pelias/api/issues/442 +**/ + +function sanitize( raw, clean, opts ) { + // error & warning messages + var messages = { errors: [], warnings: [] }; + + // only applicably when 'sources' param is privided + if( raw.hasOwnProperty('sources') ){ + + var sources = raw.sources.split(','); + if (_.includes(sources, 'quattroshapes') || _.includes(sources, 'qs')) { + + // emit a warning message so users can transition. + messages.warnings.push('You are using Quattroshapes as a data source in this query. ' + + 'Quattroshapes will be disabled as a data source for Mapzen Search in the next several ' + + 'weeks, and is being replaced by Who\'s on First, an actively maintained data project ' + + 'based on Quattroshapes. Your existing queries WILL CONTINUE TO WORK for the foreseeable ' + + 'future, but results will be coming from Who\'s on First and `sources=quattroshapes` will ' + + 'be deprecated. If you have any questions, please email search@mapzen.com.'); + + // user requested 'quattroshapes', we will give them 'whosonfirst' instead. + sources = _.without(sources, 'quattroshapes', 'qs'); + sources.push('whosonfirst'); + raw.sources = sources.join(','); + } + } + + return messages; +} + +module.exports = sanitize; diff --git a/sanitiser/_warn_quattroshapes.js b/sanitiser/_warn_quattroshapes.js deleted file mode 100644 index 2b887e5f..00000000 --- a/sanitiser/_warn_quattroshapes.js +++ /dev/null @@ -1,25 +0,0 @@ -var _ = require('lodash'); - -function setup( paramName, targetMap ) { - return function( raw, clean ){ - return sanitize( raw, clean ); - }; -} - -function sanitize( raw, clean, opts ) { - // error & warning messages - var messages = { errors: [], warnings: [] }; - - if (_.includes(raw.sources, 'quattroshapes') || _.includes(raw.sources, 'qs')) { - messages.warnings.push( 'You are using Quattroshapes as a data source in this query. ' + - 'Quattroshapes will be disabled as a data source for Mapzen Search in the next several ' + - 'weeks, and is being replaced by Who\'s on First, an actively maintained data project ' + - 'based on Quattroshapes. Your existing queries WILL CONTINUE TO WORK for the foreseeable ' + - 'future, but results will be coming from Who\'s on First and `sources=quattroshapes` will ' + - 'be deprecated. If you have any questions, please email search@mapzen.com.'); - } - - return messages; -} - -module.exports = setup; diff --git a/sanitiser/reverse.js b/sanitiser/reverse.js index 5f0ffb6b..c8e1e3f4 100644 --- a/sanitiser/reverse.js +++ b/sanitiser/reverse.js @@ -2,12 +2,12 @@ var type_mapping = require('../helper/type_mapping'); var sanitizeAll = require('../sanitiser/sanitizeAll'), sanitizers = { + quattroshapes_deprecation: require('../sanitiser/_deprecate_quattroshapes'), singleScalarParameters: require('../sanitiser/_single_scalar_parameters'), layers: require('../sanitiser/_targets')('layers', type_mapping.layer_mapping), sources: require('../sanitiser/_targets')('sources', type_mapping.source_mapping), // depends on the layers and sources sanitisers, must be run after them sources_and_layers: require('../sanitiser/_sources_and_layers'), - quattroshapes_warning: require('../sanitiser/_warn_quattroshapes')(), size: require('../sanitiser/_size'), private: require('../sanitiser/_flag_bool')('private', false), geo_reverse: require('../sanitiser/_geo_reverse'), diff --git a/sanitiser/search.js b/sanitiser/search.js index 1388505a..8b26e54e 100644 --- a/sanitiser/search.js +++ b/sanitiser/search.js @@ -2,6 +2,7 @@ var type_mapping = require('../helper/type_mapping'); var sanitizeAll = require('../sanitiser/sanitizeAll'), sanitizers = { + quattroshapes_deprecation: require('../sanitiser/_deprecate_quattroshapes'), singleScalarParameters: require('../sanitiser/_single_scalar_parameters'), text: require('../sanitiser/_text'), size: require('../sanitiser/_size'), @@ -9,7 +10,6 @@ var sanitizeAll = require('../sanitiser/sanitizeAll'), sources: require('../sanitiser/_targets')('sources', type_mapping.source_mapping), // depends on the layers and sources sanitisers, must be run after them sources_and_layers: require('../sanitiser/_sources_and_layers'), - quattroshapes_warning: require('../sanitiser/_warn_quattroshapes')(), private: require('../sanitiser/_flag_bool')('private', false), geo_search: require('../sanitiser/_geo_search'), boundary_country: require('../sanitiser/_boundary_country'), diff --git a/test/ciao/reverse/sources_deprecation_warning.coffee b/test/ciao/reverse/sources_deprecation_warning.coffee new file mode 100644 index 00000000..c6e8d488 --- /dev/null +++ b/test/ciao/reverse/sources_deprecation_warning.coffee @@ -0,0 +1,34 @@ + +#> quattroshapes is being phased out and so should emit a warning message +path: '/v1/reverse?point.lat=1&point.lon=2&sources=qs' + +#? 200 ok +response.statusCode.should.be.equal 200 +response.should.have.header 'charset', 'utf8' +response.should.have.header 'content-type', 'application/json; charset=utf-8' + +#? valid geocoding block +should.exist json.geocoding +should.exist json.geocoding.version +should.exist json.geocoding.attribution +should.exist json.geocoding.query +should.exist json.geocoding.engine +should.exist json.geocoding.engine.name +should.exist json.geocoding.engine.author +should.exist json.geocoding.engine.version +should.exist json.geocoding.timestamp + +#? valid geojson +json.type.should.be.equal 'FeatureCollection' +json.features.should.be.instanceof Array + +#? expected errors +should.not.exist json.geocoding.errors + +#? expected warnings +should.exist json.geocoding.warnings +json.geocoding.warnings.should.eql [ 'You are using Quattroshapes as a data source in this query. Quattroshapes will be disabled as a data source for Mapzen Search in the next several weeks, and is being replaced by Who\'s on First, an actively maintained data project based on Quattroshapes. Your existing queries WILL CONTINUE TO WORK for the foreseeable future, but results will be coming from Who\'s on First and `sources=quattroshapes` will be deprecated. If you have any questions, please email search@mapzen.com.' ] + +#? inputs +json.geocoding.query['size'].should.eql 10 +json.geocoding.query.sources.should.eql ['whosonfirst'] # should use 'whosonfirst' instead of 'quattroshapes' diff --git a/test/ciao/reverse/sources_layers_invalid_combo.coffee b/test/ciao/reverse/sources_layers_invalid_combo.coffee index 565a68b1..baf157cc 100644 --- a/test/ciao/reverse/sources_layers_invalid_combo.coffee +++ b/test/ciao/reverse/sources_layers_invalid_combo.coffee @@ -27,7 +27,7 @@ should.exist json.geocoding.errors json.geocoding.errors.should.eql [ 'You have specified both the `sources` and `layers` parameters in a combination that will return no results: the whosonfirst source has nothing in the address layer' ] #? expected warnings -json.geocoding.warnings.should.eql [ 'You are using Quattroshapes as a data source in this query. Quattroshapes will be disabled as a data source for Mapzen Search in the next several weeks, and is being replaced by Who\'s on First, an actively maintained data project based on Quattroshapes. Your existing queries WILL CONTINUE TO WORK for the foreseeable future, but results will be coming from Who\'s on First and `sources=quattroshapes` will be deprecated. If you have any questions, please email search@mapzen.com.' ] +should.not.exist json.geocoding.warnings #? inputs json.geocoding.query['size'].should.eql 10 diff --git a/test/ciao/search/sources_deprecation_warning.coffee b/test/ciao/search/sources_deprecation_warning.coffee new file mode 100644 index 00000000..bfaad028 --- /dev/null +++ b/test/ciao/search/sources_deprecation_warning.coffee @@ -0,0 +1,35 @@ + +#> quattroshapes is being phased out and so should emit a warning message +path: '/v1/search?sources=qs&text=a' + +#? 200 ok +response.statusCode.should.be.equal 200 +response.should.have.header 'charset', 'utf8' +response.should.have.header 'content-type', 'application/json; charset=utf-8' + +#? valid geocoding block +should.exist json.geocoding +should.exist json.geocoding.version +should.exist json.geocoding.attribution +should.exist json.geocoding.query +should.exist json.geocoding.engine +should.exist json.geocoding.engine.name +should.exist json.geocoding.engine.author +should.exist json.geocoding.engine.version +should.exist json.geocoding.timestamp + +#? valid geojson +json.type.should.be.equal 'FeatureCollection' +json.features.should.be.instanceof Array + +#? expected errors +should.not.exist json.geocoding.errors + +#? expected warnings +should.exist json.geocoding.warnings +json.geocoding.warnings.should.eql [ 'You are using Quattroshapes as a data source in this query. Quattroshapes will be disabled as a data source for Mapzen Search in the next several weeks, and is being replaced by Who\'s on First, an actively maintained data project based on Quattroshapes. Your existing queries WILL CONTINUE TO WORK for the foreseeable future, but results will be coming from Who\'s on First and `sources=quattroshapes` will be deprecated. If you have any questions, please email search@mapzen.com.' ] + +#? inputs +json.geocoding.query['size'].should.eql 10 +json.geocoding.query['text'].should.eql 'a' +json.geocoding.query.sources.should.eql ['whosonfirst'] # should use 'whosonfirst' instead of 'quattroshapes' diff --git a/test/ciao/search/sources_layers_invalid_combo.coffee b/test/ciao/search/sources_layers_invalid_combo.coffee index b2880822..821bf243 100644 --- a/test/ciao/search/sources_layers_invalid_combo.coffee +++ b/test/ciao/search/sources_layers_invalid_combo.coffee @@ -27,7 +27,7 @@ should.exist json.geocoding.errors json.geocoding.errors.should.eql [ 'You have specified both the `sources` and `layers` parameters in a combination that will return no results: the whosonfirst source has nothing in the address layer' ] #? expected warnings -json.geocoding.warnings.should.eql [ 'You are using Quattroshapes as a data source in this query. Quattroshapes will be disabled as a data source for Mapzen Search in the next several weeks, and is being replaced by Who\'s on First, an actively maintained data project based on Quattroshapes. Your existing queries WILL CONTINUE TO WORK for the foreseeable future, but results will be coming from Who\'s on First and `sources=quattroshapes` will be deprecated. If you have any questions, please email search@mapzen.com.' ] +should.not.exist json.geocoding.warnings #? inputs json.geocoding.query['text'].should.eql 'a' diff --git a/test/unit/run.js b/test/unit/run.js index d7dfd23a..2e8b382e 100644 --- a/test/unit/run.js +++ b/test/unit/run.js @@ -46,6 +46,7 @@ var tests = [ require('./sanitiser/_sources'), require('./sanitiser/_sources_and_layers'), require('./sanitiser/_text'), + require('./sanitiser/_deprecate_quattroshapes'), require('./src/backend'), require('./sanitiser/autocomplete'), require('./sanitiser/place'), diff --git a/test/unit/sanitiser/_deprecate_quattroshapes.js b/test/unit/sanitiser/_deprecate_quattroshapes.js new file mode 100644 index 00000000..8c8a6b95 --- /dev/null +++ b/test/unit/sanitiser/_deprecate_quattroshapes.js @@ -0,0 +1,65 @@ +var sanitize = require('../../../sanitiser/_deprecate_quattroshapes'); + +module.exports.tests = {}; + +module.exports.tests.warning_message_1 = function(test, common) { + test('[qs] should emit a deprecation warning', function(t) { + var raw = { sources: 'qs' }; + var clean = {}; + + var messages = sanitize(raw, clean); + t.deepEquals(messages, { + errors: [], + warnings: ['You are using Quattroshapes as a data source in this query. ' + + 'Quattroshapes will be disabled as a data source for Mapzen Search in the next several ' + + 'weeks, and is being replaced by Who\'s on First, an actively maintained data project ' + + 'based on Quattroshapes. Your existing queries WILL CONTINUE TO WORK for the foreseeable ' + + 'future, but results will be coming from Who\'s on First and `sources=quattroshapes` will ' + + 'be deprecated. If you have any questions, please email search@mapzen.com.'] + }, 'warning emitted'); + + t.end(); + }); +}; + +module.exports.tests.warning_message_2 = function(test, common) { + test('[quattroshapes] should emit a deprecation warning', function(t) { + var raw = { sources: 'quattroshapes' }; + var clean = {}; + + var messages = sanitize(raw, clean); + t.deepEquals(messages, { + errors: [], + warnings: ['You are using Quattroshapes as a data source in this query. ' + + 'Quattroshapes will be disabled as a data source for Mapzen Search in the next several ' + + 'weeks, and is being replaced by Who\'s on First, an actively maintained data project ' + + 'based on Quattroshapes. Your existing queries WILL CONTINUE TO WORK for the foreseeable ' + + 'future, but results will be coming from Who\'s on First and `sources=quattroshapes` will ' + + 'be deprecated. If you have any questions, please email search@mapzen.com.'] + }, 'warning emitted'); + + t.end(); + }); +}; + +module.exports.tests.rewrite = function(test, common) { + test('should rewrite qs and quattroshapes to whosonfirst', function(t) { + var raw = { sources: 'qs,quattroshapes,qs,quattroshapes,osm' }; + var clean = {}; + + sanitize(raw, clean); + t.equals(raw.sources,'osm,whosonfirst','use wof instead of qs'); + + t.end(); + }); +}; + +module.exports.all = function (tape, common) { + function test(name, testFunction) { + return tape('SANTIZE _deprecate_quattroshapes ' + name, testFunction); + } + + for( var testCase in module.exports.tests ){ + module.exports.tests[testCase](test, common); + } +}; diff --git a/test/unit/sanitiser/reverse.js b/test/unit/sanitiser/reverse.js index f082cb11..fcce8226 100644 --- a/test/unit/sanitiser/reverse.js +++ b/test/unit/sanitiser/reverse.js @@ -36,8 +36,8 @@ module.exports.tests.interface = function(test, common) { module.exports.tests.sanitisers = function(test, common) { test('check sanitiser list', function (t) { - var expected = ['singleScalarParameters', 'layers', 'sources', 'sources_and_layers', - 'quattroshapes_warning', 'size', 'private', 'geo_reverse', 'boundary_country']; + var expected = ['quattroshapes_deprecation', 'singleScalarParameters', 'layers', + 'sources', 'sources_and_layers', 'size', 'private', 'geo_reverse', 'boundary_country']; t.deepEqual(Object.keys(reverse.sanitiser_list), expected); t.end(); }); diff --git a/test/unit/sanitiser/search.js b/test/unit/sanitiser/search.js index 03a41434..e09672ce 100644 --- a/test/unit/sanitiser/search.js +++ b/test/unit/sanitiser/search.js @@ -24,8 +24,8 @@ module.exports.tests.interface = function(test, common) { module.exports.tests.sanitisers = function(test, common) { test('check sanitiser list', function (t) { - var expected = ['singleScalarParameters', 'text', 'size', 'layers', 'sources', - 'sources_and_layers', 'quattroshapes_warning', 'private', 'geo_search', 'boundary_country' ]; + var expected = ['quattroshapes_deprecation', 'singleScalarParameters', 'text', 'size', + 'layers', 'sources', 'sources_and_layers', 'private', 'geo_search', 'boundary_country' ]; t.deepEqual(Object.keys(search.sanitiser_list), expected); t.end(); });