From a8322922d92263b448f52f65f2c6165347e856e8 Mon Sep 17 00:00:00 2001 From: sweco-semhul Date: Thu, 2 Nov 2017 12:00:04 +0100 Subject: [PATCH] Adding unit attribute for addresses in api output --- helper/diffPlaces.js | 5 +++ helper/geojsonify_place_details.js | 1 + middleware/localNamingConventions.js | 8 +++- middleware/renamePlacenames.js | 1 + sanitizer/_text_addressit.js | 1 + service/configurations/Interpolation.js | 6 ++- test/unit/helper/diffPlaces.js | 44 +++++++++++++++++++ test/unit/helper/geojsonify_place_details.js | 7 +++ .../unit/middleware/localNamingConventions.js | 27 +++++++++++- test/unit/sanitizer/_text_addressit.js | 27 ++++++++++++ .../service/configurations/Interpolation.js | 37 ++++++++++++++++ 11 files changed, 160 insertions(+), 4 deletions(-) diff --git a/helper/diffPlaces.js b/helper/diffPlaces.js index 712c7959..9c28a935 100644 --- a/helper/diffPlaces.js +++ b/helper/diffPlaces.js @@ -102,6 +102,11 @@ function assertAddressMatch(item1, item2) { propMatch(item1.address_parts, item2.address_parts, 'zip'); } + // only compare unit if both records have it, otherwise just ignore and assume it's the same + if (item1.address_parts.hasOwnProperty('unit') && item2.address_parts.hasOwnProperty('unit')) { + propMatch(item1.address_parts, item2.address_parts, 'unit'); + } + return false; } diff --git a/helper/geojsonify_place_details.js b/helper/geojsonify_place_details.js index c80da8b1..15c7650f 100644 --- a/helper/geojsonify_place_details.js +++ b/helper/geojsonify_place_details.js @@ -6,6 +6,7 @@ const _ = require('lodash'); // If a property is identified as a single string, assume it should be presented as a string in response // If something other than string is desired, use the following structure: { name: 'category', type: 'array' } const DETAILS_PROPS = [ + { name: 'unit', type: 'string' }, { name: 'housenumber', type: 'string' }, { name: 'street', type: 'string' }, { name: 'postalcode', type: 'string' }, diff --git a/middleware/localNamingConventions.js b/middleware/localNamingConventions.js index 20c77f6b..7628857d 100644 --- a/middleware/localNamingConventions.js +++ b/middleware/localNamingConventions.js @@ -45,8 +45,12 @@ function applyLocalNamingConventions(req, res, next) { // flip the housenumber and street name // eg. '101 Grolmanstraße' -> 'Grolmanstraße 101' function flipNumberAndStreet(place) { - var standard = ( place.address_parts.number + ' ' + place.address_parts.street ), - flipped = ( place.address_parts.street + ' ' + place.address_parts.number ); + var unit = ''; + if(place.address_parts.hasOwnProperty('unit')) { + unit = ' ' + place.address_parts.unit; + } + var standard = ( place.address_parts.number + unit + ' ' + place.address_parts.street ), + flipped = ( place.address_parts.street + ' ' + place.address_parts.number + unit ); // flip street name and housenumber if( place.name.default === standard ){ diff --git a/middleware/renamePlacenames.js b/middleware/renamePlacenames.js index 9f63cb6e..b56a6139 100644 --- a/middleware/renamePlacenames.js +++ b/middleware/renamePlacenames.js @@ -5,6 +5,7 @@ const _ = require('lodash'); const PARENT_PROPS = require('../helper/placeTypes'); const ADDRESS_PROPS = [ + { name: 'unit', newName: 'unit' }, { name: 'number', newName: 'housenumber' }, { name: 'zip', newName: 'postalcode', transform: (value) => { return [value]; } }, { name: 'street', newName: 'street' } diff --git a/sanitizer/_text_addressit.js b/sanitizer/_text_addressit.js index 6cf31f4d..2da75c06 100644 --- a/sanitizer/_text_addressit.js +++ b/sanitizer/_text_addressit.js @@ -85,6 +85,7 @@ function parse(query) { _.extend(addressWithAdminParts, addressWithAddressParts); var address_parts = [ 'name', + 'unit', 'number', 'street', 'city', diff --git a/service/configurations/Interpolation.js b/service/configurations/Interpolation.js index 1bb08d77..fb3ff028 100644 --- a/service/configurations/Interpolation.js +++ b/service/configurations/Interpolation.js @@ -12,12 +12,16 @@ class Language extends ServiceConfiguration { } getParameters(req, hit) { - return { + let res = { number: req.clean.parsed_text.number, street: hit.address_parts.street || req.clean.parsed_text.street, lat: hit.center_point.lat, lon: hit.center_point.lon }; + if(req.clean.parsed_text.hasOwnProperty('unit')) { + res.unit = req.clean.parsed_text.unit; + } + return res; } diff --git a/test/unit/helper/diffPlaces.js b/test/unit/helper/diffPlaces.js index a7dd692d..da93965f 100644 --- a/test/unit/helper/diffPlaces.js +++ b/test/unit/helper/diffPlaces.js @@ -166,6 +166,50 @@ module.exports.tests.dedupe = function(test, common) { t.false(isDifferent(item1, item2), 'should be the same'); t.end(); }); + + test('catch diff address by unit', function(t) { + var item1 = { + 'address_parts': { + 'unit': 'A', + 'number': '1', + 'street': 'Main Street', + 'zip': '90210' + } + }; + var item2 = { + 'address_parts': { + 'unit': 'B', + 'number': '1', + 'street': 'Main Street', + 'zip': '90210' + } + }; + + t.true(isDifferent(item1, item2), 'should be different'); + t.end(); + }); + + test('catch diff address by unit', function(t) { + var item1 = { + 'address_parts': { + 'unit': 'A', + 'number': '1', + 'street': 'Main Street', + 'zip': '90210' + } + }; + var item2 = { + 'address_parts': { + 'unit': 'A', + 'number': '1', + 'street': 'Main Street', + 'zip': '90210' + } + }; + + t.false(isDifferent(item1, item2), 'should be the same'); + t.end(); + }); }; module.exports.all = function (tape, common) { diff --git a/test/unit/helper/geojsonify_place_details.js b/test/unit/helper/geojsonify_place_details.js index c7f2c8ac..e0788574 100644 --- a/test/unit/helper/geojsonify_place_details.js +++ b/test/unit/helper/geojsonify_place_details.js @@ -5,6 +5,7 @@ module.exports.tests = {}; module.exports.tests.geojsonify_place_details = (test, common) => { test('plain old string values should be copied verbatim, replacing old values', t => { const source = { + unit: 'unit value', housenumber: 'housenumber value', street: 'street value', postalcode: 'postalcode value', @@ -53,6 +54,7 @@ module.exports.tests.geojsonify_place_details = (test, common) => { }; const expected = { + unit: 'unit value', housenumber: 'housenumber value', street: 'street value', postalcode: 'postalcode value', @@ -110,6 +112,7 @@ module.exports.tests.geojsonify_place_details = (test, common) => { test('\'empty\' string-type values should be output as \'\'', t => { [ [], {}, '', 17, true, null, undefined ].forEach(empty_value => { const source = { + unit: empty_value, housenumber: empty_value, street: empty_value, postalcode: empty_value, @@ -170,6 +173,7 @@ module.exports.tests.geojsonify_place_details = (test, common) => { test('source arrays should be copy first value', t => { const source = { + unit: ['unit value 1', 'unit value 2'], housenumber: ['housenumber value 1', 'housenumber value 2'], street: ['street value 1', 'street value 2'], postalcode: ['postalcode value 1', 'postalcode value 2'], @@ -218,6 +222,7 @@ module.exports.tests.geojsonify_place_details = (test, common) => { }; const expected = { + unit: 'unit value 1', housenumber: 'housenumber value 1', street: 'street value 1', postalcode: 'postalcode value 1', @@ -275,6 +280,7 @@ module.exports.tests.geojsonify_place_details = (test, common) => { test('non-empty objects should be converted to strings', t => { // THIS TEST SHOWS THAT THE CODE DOES NOT DO WHAT IT EXPECTED const source = { + unit: { unit: 'unit value' }, housenumber: { housenumber: 'housenumber value'}, street: { street: 'street value'}, postalcode: { postalcode: 'postalcode value'}, @@ -323,6 +329,7 @@ module.exports.tests.geojsonify_place_details = (test, common) => { }; const expected = { + unit: '[object Object]', housenumber: '[object Object]', street: '[object Object]', postalcode: '[object Object]', diff --git a/test/unit/middleware/localNamingConventions.js b/test/unit/middleware/localNamingConventions.js index 1d4102f0..91d39f0d 100644 --- a/test/unit/middleware/localNamingConventions.js +++ b/test/unit/middleware/localNamingConventions.js @@ -90,8 +90,28 @@ module.exports.tests.flipNumberAndStreet = function(test, common) { } }; + var dkAddressWithUnit = { + '_id': 'test5', + '_type': 'test', + 'name': { 'default': '26 2 th Nikolaj Plads' }, + 'center_point': { 'lon': 12.580921, 'lat': 55.678665 }, + 'address_parts': { + 'zip': '1067', + 'unit': '2 th', + 'number': '26', + 'street': 'Nikolaj Plads' + }, + 'parent': { + 'region': ['København'], + 'locality': ['København K'], + 'country_a': ['DNK'], + 'county': ['Region Hovedstaden'], + 'country': ['Denmark'] + } + }; + var req = {}, - res = { data: [ ukAddress, deAddress, nlAddress, unknownCountryAddress ] }, + res = { data: [ ukAddress, deAddress, nlAddress, unknownCountryAddress, dkAddressWithUnit ] }, middleware = localNamingConventions(); test('flipNumberAndStreet', function(t) { @@ -113,6 +133,11 @@ module.exports.tests.flipNumberAndStreet = function(test, common) { // being disabled), don't have the name flipped t.equal( res.data[3].name.default, '123 Main Street', 'standard name'); + // DNK address should have the housenumber and street name flipped, too + // this definition comes from pelias configuration + // In this case address have unit and it should also be added to flipped address name + t.equal( res.data[4].name.default, 'Nikolaj Plads 26 2 th', 'flipped name' ); + t.end(); }); }); diff --git a/test/unit/sanitizer/_text_addressit.js b/test/unit/sanitizer/_text_addressit.js index 5fad89a8..b8d4a4b3 100644 --- a/test/unit/sanitizer/_text_addressit.js +++ b/test/unit/sanitizer/_text_addressit.js @@ -236,6 +236,33 @@ module.exports.tests.text_parser = function(test, common) { }); + test('valid address, unit', function(t) { + var raw = { + text: 'Shop 8, 431 St Kilda Rd Melbourne' + }; + var clean = {}; + + var expected_clean = { + text: 'Shop 8, 431 St Kilda Rd Melbourne', + parser: 'addressit', + parsed_text: { + name: 'Shop 8', + unit: '8', + number: '431', + street: 'St Kilda Rd', + regions: [ 'Melbourne' ], + admin_parts: '431 St Kilda Rd Melbourne' + } + }; + + var messages = sanitizer.sanitize(raw, clean); + + t.deepEqual(messages, { errors: [], warnings: [] } ); + t.deepEqual(clean, expected_clean); + t.end(); + + }); + test('valid address, house number', function(t) { var raw = { text: '123 main st new york ny' diff --git a/test/unit/service/configurations/Interpolation.js b/test/unit/service/configurations/Interpolation.js index c71df69e..40ec2136 100644 --- a/test/unit/service/configurations/Interpolation.js +++ b/test/unit/service/configurations/Interpolation.js @@ -115,6 +115,43 @@ module.exports.tests.all = (test, common) => { }); + test('getParameters should return unit when req.clean.parsed_text.unit is set', t => { + const configBlob = { + url: 'base url' + }; + + const interpolation = new Interpolation(configBlob); + + const req = { + clean: { + parsed_text: { + unit: 'parsed unit value', + number: 'parsed number value', + street: 'parsed street value' + } + } + }; + + const hit = { + address_parts: { + }, + center_point: { + lat: 12.121212, + lon: 21.212121 + } + }; + + t.deepEquals(interpolation.getParameters(req, hit), { + unit: 'parsed unit value', + number: 'parsed number value', + street: 'parsed street value', + lat: 12.121212, + lon: 21.212121 + }); + t.end(); + + }); + test('baseUrl ending in / should not have double /\'s return by getUrl', t => { const configBlob = { url: 'http://localhost:1234/'