diff --git a/package.json b/package.json index b151fbd5..d9a588d1 100644 --- a/package.json +++ b/package.json @@ -53,11 +53,11 @@ "morgan": "1.7.0", "pelias-categories": "1.1.0", "pelias-config": "2.3.1", - "pelias-labels": "1.5.0", + "pelias-labels": "1.5.1", "pelias-logger": "0.1.0", "pelias-model": "4.3.0", "pelias-query": "8.9.0", - "pelias-text-analyzer": "1.5.0", + "pelias-text-analyzer": "1.6.0", "stats-lite": "2.0.3", "through2": "2.0.1" }, diff --git a/query/search.js b/query/search.js index 945276e9..41e5775f 100644 --- a/query/search.js +++ b/query/search.js @@ -120,7 +120,7 @@ function generateQuery( clean ){ } function getQuery(vs) { - if (hasStreet(vs) || isCityStateOnlyWithOptionalCountry(vs)) { + if (hasStreet(vs) || isCityStateOnlyWithOptionalCountry(vs) || isCityCountryOnly(vs)) { return { type: 'fallback', body: fallbackQuery.render(vs) @@ -138,8 +138,8 @@ function hasStreet(vs) { } function isCityStateOnlyWithOptionalCountry(vs) { - var isSet = function(layer) { - return vs.isset('input:' + layer); + var isSet = (layer) => { + return vs.isset(`input:${layer}`); }; var allowedFields = ['locality', 'region']; @@ -150,4 +150,18 @@ function isCityStateOnlyWithOptionalCountry(vs) { } +function isCityCountryOnly(vs) { + var isSet = (layer) => { + return vs.isset(`input:${layer}`); + }; + + var allowedFields = ['locality', 'country']; + var disallowedFields = ['query', 'category', 'housenumber', 'street', + 'neighbourhood', 'borough', 'postcode', 'county', 'region']; + + return allowedFields.every(isSet) && + !disallowedFields.some(isSet); + +} + module.exports = generateQuery; diff --git a/sanitizer/_synthesize_analysis.js b/sanitizer/_synthesize_analysis.js index 788132ec..04ffeb34 100644 --- a/sanitizer/_synthesize_analysis.js +++ b/sanitizer/_synthesize_analysis.js @@ -1,7 +1,15 @@ const _ = require('lodash'); -const fields = ['address', 'neighbourhood', 'borough', 'city', 'county', - 'state', 'postalcode', 'country']; +const fields = { + 'address': 'address', + 'neighbourhood': 'neighbourhood', + 'borough': 'borough', + 'locality': 'city', + 'county': 'county', + 'region': 'state', + 'postalcode': 'postalcode', + 'country': 'country' +}; function normalizeWhitespaceToSingleSpace(val) { return _.replace(_.trim(val), /\s+/g, ' '); @@ -18,9 +26,9 @@ function sanitize( raw, clean ){ const messages = { errors: [], warnings: [] }; // collect all the valid values into a single object - clean.parsed_text = fields.reduce( (o, f) => { + clean.parsed_text = Object.keys(fields).reduce( (o, f) => { if (_.isString(raw[f]) && !_.isEmpty(_.trim(raw[f]))) { - o[f] = normalizeWhitespaceToSingleSpace(raw[f]); + o[fields[f]] = normalizeWhitespaceToSingleSpace(raw[f]); } return o; @@ -32,7 +40,7 @@ function sanitize( raw, clean ){ } else if (_.isEmpty(Object.keys(clean.parsed_text))) { messages.errors.push( - `at least one of the following fields is required: ${fields.join(', ')}`); + `at least one of the following fields is required: ${Object.keys(fields).join(', ')}`); } return messages; diff --git a/sanitizer/search.js b/sanitizer/search.js index 53a6b57c..450f6b62 100644 --- a/sanitizer/search.js +++ b/sanitizer/search.js @@ -5,6 +5,7 @@ var sanitizeAll = require('../sanitizer/sanitizeAll'), quattroshapes_deprecation: require('../sanitizer/_deprecate_quattroshapes'), singleScalarParameters: require('../sanitizer/_single_scalar_parameters'), text: require('../sanitizer/_text'), + iso2_to_iso3: require('../sanitizer/_iso2_to_iso3'), size: require('../sanitizer/_size')(/* use defaults*/), layers: require('../sanitizer/_targets')('layers', type_mapping.layer_mapping), sources: require('../sanitizer/_targets')('sources', type_mapping.source_mapping), diff --git a/test/unit/query/search.js b/test/unit/query/search.js index f16a79ae..1f312d0d 100644 --- a/test/unit/query/search.js +++ b/test/unit/query/search.js @@ -447,6 +447,164 @@ module.exports.tests.city_state = function(test, common) { }; +module.exports.tests.city_country = function(test, common) { + test('only city and country set should return query', function(t) { + var clean = { + parsed_text: { + 'city': 'city value', + 'country': 'country value' + } + }; + + var query = generate(clean); + + t.notEqual(query, undefined, 'should not have returned undefined'); + t.end(); + + }); + + test('city-only should return undefined', function(t) { + var clean = { + parsed_text: { + city: 'city value' + } + }; + + var query = generate(clean); + + t.equals(query, undefined, 'should have returned undefined'); + t.end(); + + }); + + test('country-only should return undefined', function(t) { + var clean = { + parsed_text: { + country: 'country value' + } + }; + + var query = generate(clean); + + t.equals(query, undefined, 'should have returned undefined'); + t.end(); + + }); + + test('city/country with query should return undefined', function(t) { + var clean = { + parsed_text: { + city: 'city value', + country: 'country value', + query: 'query value' + } + }; + + var query = generate(clean); + + t.equals(query, undefined, 'should have returned undefined'); + t.end(); + + }); + + test('city/country with category should return undefined', function(t) { + var clean = { + parsed_text: { + city: 'city value', + country: 'country value', + category: 'category value' + } + }; + + var query = generate(clean); + + t.equals(query, undefined, 'should have returned undefined'); + t.end(); + + }); + + test('city/country with number should return undefined', function(t) { + var clean = { + parsed_text: { + city: 'city value', + country: 'country value', + number: 'number value' + } + }; + + var query = generate(clean); + + t.equals(query, undefined, 'should have returned undefined'); + t.end(); + + }); + + test('city/country with neighbourhood should return undefined', function(t) { + var clean = { + parsed_text: { + city: 'city value', + country: 'country value', + neighbourhood: 'neighbourhood value' + } + }; + + var query = generate(clean); + + t.equals(query, undefined, 'should have returned undefined'); + t.end(); + + }); + + test('city/country with borough should return undefined', function(t) { + var clean = { + parsed_text: { + city: 'city value', + country: 'country value', + borough: 'borough value' + } + }; + + var query = generate(clean); + + t.equals(query, undefined, 'should have returned undefined'); + t.end(); + + }); + + test('city/country with postalcode should return undefined', function(t) { + var clean = { + parsed_text: { + city: 'city value', + country: 'country value', + postalcode: 'postalcode value' + } + }; + + var query = generate(clean); + + t.equals(query, undefined, 'should have returned undefined'); + t.end(); + + }); + + test('city/country with county should return undefined', function(t) { + var clean = { + parsed_text: { + city: 'city value', + country: 'country value', + county: 'county value' + } + }; + + var query = generate(clean); + + t.equals(query, undefined, 'should have returned undefined'); + t.end(); + + }); + +}; + module.exports.all = function (tape, common) { function test(name, testFunction) { return tape('search query ' + name, testFunction); diff --git a/test/unit/sanitizer/_synthesize_analysis.js b/test/unit/sanitizer/_synthesize_analysis.js index d137ad49..20f05fc0 100644 --- a/test/unit/sanitizer/_synthesize_analysis.js +++ b/test/unit/sanitizer/_synthesize_analysis.js @@ -10,9 +10,9 @@ module.exports.tests.text_parser = function(test, common) { address: ' \t address \t value \t ', neighbourhood: ' \t neighbourhood \t value \t ', borough: ' \t borough \t value \t ', - city: ' \t city \t value \t ', + locality: ' \t locality \t value \t ', county: ' \t county \t value \t ', - state: ' \t state \t value \t ', + region: ' \t region \t value \t ', postalcode: ' \t postalcode \t value \t ', country: ' \t country \t value \t ' }; @@ -24,9 +24,9 @@ module.exports.tests.text_parser = function(test, common) { address: 'address value', neighbourhood: 'neighbourhood value', borough: 'borough value', - city: 'city value', + city: 'locality value', county: 'county value', - state: 'state value', + state: 'region value', postalcode: 'postalcode value', country: 'country value' } @@ -51,9 +51,9 @@ module.exports.tests.text_parser = function(test, common) { address: getInvalidValue(), neighbourhood: getInvalidValue(), borough: getInvalidValue(), - city: getInvalidValue(), + locality: getInvalidValue(), county: getInvalidValue(), - state: getInvalidValue(), + region: getInvalidValue(), postalcode: getInvalidValue(), country: getInvalidValue() }; @@ -68,7 +68,7 @@ module.exports.tests.text_parser = function(test, common) { t.deepEquals(clean, expected_clean); t.deepEquals(messages.errors, ['at least one of the following fields is required: ' + - 'address, neighbourhood, borough, city, county, state, postalcode, country'], 'no errors'); + 'address, neighbourhood, borough, locality, county, region, postalcode, country'], 'no errors'); t.deepEquals(messages.warnings, [], 'no warnings'); t.end(); @@ -85,7 +85,7 @@ module.exports.tests.text_parser = function(test, common) { t.deepEquals(clean, expected_clean); t.deepEquals(messages.errors, ['at least one of the following fields is required: ' + - 'address, neighbourhood, borough, city, county, state, postalcode, country'], 'no errors'); + 'address, neighbourhood, borough, locality, county, region, postalcode, country'], 'no errors'); t.deepEquals(messages.warnings, [], 'no warnings'); t.end(); diff --git a/test/unit/sanitizer/search.js b/test/unit/sanitizer/search.js index b656d943..fa60e58a 100644 --- a/test/unit/sanitizer/search.js +++ b/test/unit/sanitizer/search.js @@ -21,6 +21,10 @@ module.exports.tests.sanitize = function(test, common) { called_sanitizers.push('_text'); return { errors: [], warnings: [] }; }, + '../sanitizer/_iso2_to_iso3': function() { + called_sanitizers.push('_iso2_to_iso3'); + return { errors: [], warnings: [] }; + }, '../sanitizer/_size': function() { if (arguments.length === 0) { return function() { @@ -81,6 +85,7 @@ module.exports.tests.sanitize = function(test, common) { '_deprecate_quattroshapes', '_single_scalar_parameters', '_text', + '_iso2_to_iso3', '_size', '_targets/layers', '_targets/sources',