Skip to content

Commit

Permalink
MSMA-3589 Apply get_address_uk customisation to upstream v1.8.4
Browse files Browse the repository at this point in the history
* Previously original commits were preserved and carried forward but this led
  to increasingly complex updates. All previous commits have now been captured
  in this single commit to make future updates simpler

  Previously https://atgglobal.atlassian.net/browse/SMA-1970 which after
  migration became https://keyloop.atlassian.net/browse/MSMA-2040

Previous commit comments:

Author: Phil Johnson <[email protected]>
Date:   Tue Jun 14 16:22:25 2016 +0100
    Add Support For GetAddress UK Postcode Geocoding And Lookups
    This commit adds support for GetAddress (getaddress.io) postcode geocoding and lookups.

Author: Phil Johnson <[email protected]>
Date:   Tue Jun 14 17:52:36 2016 +0100
    GetAddressUk: Remove Spaces From Query In query_url
    This commit removes the sanitize method from query (as it's never a hash) and instead ensures the query string doesn't contain whitespace.

https://keyloop.atlassian.net/browse/MSMA-3589
  • Loading branch information
mark-young-atg committed Dec 13, 2024
1 parent 134eacb commit 4537519
Show file tree
Hide file tree
Showing 14 changed files with 192 additions and 2 deletions.
12 changes: 12 additions & 0 deletions README_API_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,18 @@ Regional Street Address Lookups
* **Terms of Service**: http://wiki.geoportail.lu/doku.php?id=en:mcg_1
* **Limitations**: ?
#### GetAddressUk (`:get_address__uk`)
* **API key**: required
* **Quota**: 20/day for free through 5,000/day for £20/mo
* **Region**: UK
* **SSL support**: yes
* **Languages**: English
* **Documentation**: https://getaddress.io/Documentation
* **Terms of Service**: https://getaddress.io/#faq
* **Limitations**: No restrictions on use
* **Notes**: To use GetAddress you must include an API key: `Geocoder.configure(:lookup => :get_address_uk, :api_key => 'your_api_key')`.
### LatLon.io (`:latlon`)
* **API key**: required
Expand Down
3 changes: 2 additions & 1 deletion lib/geocoder/lookup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ def street_services
:geoapify,
:photon,
:twogis,
:pc_miler
:pc_miler,
:get_address_uk
]
end

Expand Down
53 changes: 53 additions & 0 deletions lib/geocoder/lookups/get_address_uk.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
require 'geocoder/lookups/base'
require 'geocoder/results/get_address_uk'

module Geocoder::Lookup
class GetAddressUk < Base
# Documentation: https://getaddress.io/Documentation

def name
'GetAddressUk'
end

private

def base_query_url(query)
"#{protocol}://api.getaddress.io/v2/uk/#{query.to_s.split.join}?api-key=#{configuration.api_key}"
end

def supported_protocols
[:https]
end

def results(query)
response = fetch_data query
return [] if response.nil? || !response.is_a?(Hash) || response.empty?
if response['Message']
raise_exception_for_response response
return []
end
[response]
end

def raise_exception_for_response(response)
return if response['Message'] == 'Not Found'
case response['Message']
when 'Bad Request'
raise_error(Geocoder::InvalidRequest, response['Message']) ||
Geocoder.log(:warn, 'getaddress.io error: Your postcode is not valid')
when 'Unauthorized'
raise_error(Geocoder::InvalidApiKey) ||
Geocoder.log(:warn, 'Invalid getaddress.io API key.')
when 'Too Many Requests'
raise_error(Geocoder::OverQueryLimitError) ||
Geocoder.log(:warn, 'getaddress.io error: You have made more requests than your allowed limit.')
when 'Internal Server Error'
raise_error(Geocoder::ServiceUnavailable) ||
Geocoder.log(:warn, 'getaddress.io error: Internal Server Error.')
else # anything else just raise general error with the api message
raise_error(Geocoder::Error, response['Message']) ||
Geocoder.log(:warn, response['Message'])
end
end
end
end
51 changes: 51 additions & 0 deletions lib/geocoder/results/get_address_uk.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
require 'geocoder/results/base'

module Geocoder::Result
class GetAddressUk < Base

def coordinates
[@data['Latitude'].to_f, @data['Longitude'].to_f]
end
alias_method :to_coordinates, :coordinates

def blank_result
''
end
alias_method :postal_code, :blank_result
alias_method :os_grid, :blank_result

def address
@data['Addresses'].first
end

def city
city = @data['Addresses'].first.split(',')[-2] || blank_result
city.strip
end

def state
state = @data['Addresses'].first.split(',')[-1] || blank_result
state.strip
end
alias_method :state_code, :state

# This is a UK only API; all results are UK specific, hence omitted from API response.
def country
'United Kingdom'
end

def country_code
'UK'
end

def self.response_attributes
%w[Latitude Longitude Addresses]
end

response_attributes.each do |a|
define_method a do
@data[a]
end
end
end
end
1 change: 1 addition & 0 deletions test/fixtures/get_address_uk_invalid_key
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Message":"Unauthorized"}
1 change: 1 addition & 0 deletions test/fixtures/get_address_uk_invalid_postcode
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Message":"Bad Request"}
1 change: 1 addition & 0 deletions test/fixtures/get_address_uk_mk11df
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Latitude":52.00535583496094, "Longitude":-0.7367798686027527, "Addresses":["3 Denbigh Road, , , , Bletchley, Milton Keynes, Buckinghamshire", "A L D Automotives Ltd, Denbigh Road, , , Bletchley, Milton Keynes, Buckinghamshire", "Aero Tec Laboratories, A T L Technology Centre, Denbigh Road, , Bletchley, Milton Keynes, Buckinghamshire", "International Car Rental Ltd, Denbigh House, Denbigh Road, , Bletchley, Milton Keynes, Buckinghamshire"]}
1 change: 1 addition & 0 deletions test/fixtures/get_address_uk_no_results
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Message":"Not Found"}
1 change: 1 addition & 0 deletions test/fixtures/get_address_uk_over_query_limit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Message":"Too Many Requests"}
1 change: 1 addition & 0 deletions test/fixtures/get_address_uk_server_error
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Message":"Internal Server Error"}
12 changes: 12 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,18 @@ def default_fixture_filename
end
end

require 'geocoder/lookups/get_address_uk'
class GetAddressUk
private
def fixture_prefix
'get_address_uk'
end

def default_fixture_filename
"#{fixture_prefix}_mk11df"
end
end

require 'geocoder/lookups/latlon'
class Latlon
private
Expand Down
2 changes: 1 addition & 1 deletion test/unit/lookup_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def test_search_returns_empty_array_when_no_results

def test_query_url_contains_values_in_params_hash
Geocoder::Lookup.all_services_except_test.each do |l|
next if [:freegeoip, :maxmind_local, :telize, :pointpin, :geoip2, :maxmind_geoip2, :mapbox, :ipdata_co, :ipinfo_io, :ipapi_com, :ipregistry, :ipstack, :postcodes_io, :uk_ordnance_survey_names, :amazon_location_service, :ipbase, :ip2location_lite].include? l # does not use query string
next if [:freegeoip, :maxmind_local, :telize, :pointpin, :geoip2, :maxmind_geoip2, :mapbox, :ipdata_co, :ipinfo_io, :ipapi_com, :ipregistry, :ipstack, :postcodes_io, :uk_ordnance_survey_names, :amazon_location_service, :ipbase, :ip2location_lite, :get_address_uk].include? l # does not use query string
set_api_key!(l)
url = Geocoder::Lookup.get(l).query_url(Geocoder::Query.new(
"test", :params => {:one_in_the_hand => "two in the bush"}
Expand Down
54 changes: 54 additions & 0 deletions test/unit/lookups/get_address_uk_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# encoding: utf-8
require 'test_helper'

class GetAddressUkTest < GeocoderTestCase

def setup
Geocoder.configure(lookup: :get_address_uk)
set_api_key!(:get_address_uk)
end

def test_result_components_with_postcode
results = Geocoder.search('mk11df')
assert_equal 1, results.size
assert_equal '3 Denbigh Road, , , , Bletchley, Milton Keynes, Buckinghamshire', results.first.address
assert_equal [52.00535583496094, -0.7367798686027527], results.first.coordinates
assert_equal 'Milton Keynes', results.first.city
end

def test_no_results
assert_equal [], Geocoder.search('no results')
end

def test_invalid_key
Geocoder.configure(always_raise: [Geocoder::InvalidApiKey])

assert_raises Geocoder::InvalidApiKey do
Geocoder.search('invalid key')
end
end

def test_invalid_postcode
Geocoder.configure(always_raise: [Geocoder::InvalidRequest])

assert_raises Geocoder::InvalidRequest do
Geocoder.search('invalid postcode')
end
end

def test_over_query_limit
Geocoder.configure(always_raise: [Geocoder::OverQueryLimitError])

assert_raises Geocoder::OverQueryLimitError do
Geocoder.search('over query limit')
end
end

def test_server_error
Geocoder.configure(always_raise: [Geocoder::ServiceUnavailable])

assert_raises(Geocoder::ServiceUnavailable) do
Geocoder.search('server error')
end
end
end
1 change: 1 addition & 0 deletions test/unit/result_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class ResultTest < GeocoderTestCase
def test_forward_geocoding_result_has_required_attributes
Geocoder::Lookup.all_services_except_test.each do |l|
next if [
:get_address_uk, # Doesn't search by coordinates
:ip2location, # has pay-per-attribute pricing model
:ip2location_io, # has pay-per-attribute pricing model
:ip2location_lite, # no forward geocoding
Expand Down

0 comments on commit 4537519

Please sign in to comment.