diff --git a/lib/geocoder/lookups/base.rb b/lib/geocoder/lookups/base.rb index 33fc8b644cd25a8f547f3cee2f23217969b1d4a3..c19a61da5947bc9ee73d7a74d5a003f32c4e7b64 100644 --- a/lib/geocoder/lookups/base.rb +++ b/lib/geocoder/lookups/base.rb @@ -16,6 +16,13 @@ module Geocoder class Base + ## + # Human-readable name of the geocoding API. + # + def name + fail + end + ## # Query the geocoding API and return a Geocoder::Result object. # Returns +nil+ on timeout or error. @@ -43,6 +50,14 @@ module Geocoder nil end + ## + # Array containing string descriptions of keys required by the API. + # Empty array if keys are optional or not required. + # + def required_api_key_parts + [] + end + private # ------------------------------------------------------------- @@ -162,6 +177,7 @@ module Geocoder if cache and body = cache[key] @cache_hit = true else + check_api_key_configuration!(query) response = make_api_request(query) body = response.body if cache and (200..399).include?(response.code.to_i) @@ -185,6 +201,16 @@ module Geocoder end end + def check_api_key_configuration!(query) + key_parts = query.lookup.required_api_key_parts + if key_parts.size > Array(Geocoder::Configuration.api_key).size + parts_string = key_parts.size == 1 ? key_parts.first : key_parts + raise Geocoder::ConfigurationError, + "The #{query.lookup.name} API requires a key to be configured: " + + parts_string.inspect + end + end + ## # The working Cache object. # diff --git a/lib/geocoder/lookups/bing.rb b/lib/geocoder/lookups/bing.rb index 1f8f4c2079b6f393513b18d2a5ce2c2c709d1ced..54dfa13d7453e3d36ddf942bf49364f4b0580ad3 100644 --- a/lib/geocoder/lookups/bing.rb +++ b/lib/geocoder/lookups/bing.rb @@ -4,10 +4,18 @@ require "geocoder/results/bing" module Geocoder::Lookup class Bing < Base + def name + "Bing" + end + def map_link_url(coordinates) "http://www.bing.com/maps/default.aspx?cp=#{coordinates.join('~')}" end + def required_api_key_parts + ["key"] + end + private # --------------------------------------------------------------- def results(query) diff --git a/lib/geocoder/lookups/freegeoip.rb b/lib/geocoder/lookups/freegeoip.rb index e6f8f23178f8c4db52ac4122815a380a05f6d805..b94946a60a9f046ccfff54788cbaeabd4311247b 100644 --- a/lib/geocoder/lookups/freegeoip.rb +++ b/lib/geocoder/lookups/freegeoip.rb @@ -4,6 +4,10 @@ require 'geocoder/results/freegeoip' module Geocoder::Lookup class Freegeoip < Base + def name + "FreeGeoIP" + end + private # --------------------------------------------------------------- def parse_raw_data(raw_data) diff --git a/lib/geocoder/lookups/geocoder_ca.rb b/lib/geocoder/lookups/geocoder_ca.rb index 9c62d954dfa9ec49ebbb51b3cefc819c1f351440..44b256c0c2803d72f850d520e480ff42aa16af8b 100644 --- a/lib/geocoder/lookups/geocoder_ca.rb +++ b/lib/geocoder/lookups/geocoder_ca.rb @@ -4,6 +4,14 @@ require "geocoder/results/geocoder_ca" module Geocoder::Lookup class GeocoderCa < Base + def name + "Geocoder.ca" + end + + def required_api_key_parts + ["key"] + end + private # --------------------------------------------------------------- def results(query) diff --git a/lib/geocoder/lookups/google.rb b/lib/geocoder/lookups/google.rb index 13bb676351260674d6a7dbc47f469586fac895f3..b6b9302a71e4b55c153a9757303c770850c09887 100644 --- a/lib/geocoder/lookups/google.rb +++ b/lib/geocoder/lookups/google.rb @@ -4,6 +4,10 @@ require "geocoder/results/google" module Geocoder::Lookup class Google < Base + def name + "Google" + end + def map_link_url(coordinates) "http://maps.google.com/maps?q=#{coordinates.join(',')}" end diff --git a/lib/geocoder/lookups/google_premier.rb b/lib/geocoder/lookups/google_premier.rb index b725b9fb4543aacd07206a7746a92d54f1bcdbf3..a61cc56d87285436bb951b4a6c9dc59482778685 100644 --- a/lib/geocoder/lookups/google_premier.rb +++ b/lib/geocoder/lookups/google_premier.rb @@ -6,6 +6,14 @@ require 'geocoder/results/google_premier' module Geocoder::Lookup class GooglePremier < Google + def name + "Google Premier" + end + + def required_api_key_parts + ["private key", "client", "channel"] + end + private # --------------------------------------------------------------- def query_url_params(query) diff --git a/lib/geocoder/lookups/mapquest.rb b/lib/geocoder/lookups/mapquest.rb index 6a852933e9e83aaf3b8b7e048bfa5d7edeb40913..fd5ae8c643c0228158ed8e01bf8727f869ae5904 100644 --- a/lib/geocoder/lookups/mapquest.rb +++ b/lib/geocoder/lookups/mapquest.rb @@ -5,6 +5,14 @@ require "geocoder/results/mapquest" module Geocoder::Lookup class Mapquest < Base + def name + "Mapquest" + end + + def required_api_key_parts + ["key"] + end + private # --------------------------------------------------------------- def query_url(query) diff --git a/lib/geocoder/lookups/nominatim.rb b/lib/geocoder/lookups/nominatim.rb index 0391d1bbbc854f8de8eb0126fa7fe239fc0b3a09..f7ed5638e6237583b000481c700a1c731a8808ea 100644 --- a/lib/geocoder/lookups/nominatim.rb +++ b/lib/geocoder/lookups/nominatim.rb @@ -4,6 +4,10 @@ require "geocoder/results/nominatim" module Geocoder::Lookup class Nominatim < Base + def name + "Nominatim" + end + def map_link_url(coordinates) "http://www.openstreetmap.org/?lat=#{coordinates[0]}&lon=#{coordinates[1]}&zoom=15&layers=M" end diff --git a/lib/geocoder/lookups/test.rb b/lib/geocoder/lookups/test.rb index 89aa97f4445d7d65c75caea6b0fe6d67c3d75dbe..ebf7b5d76a2d201aeb39599826d0b1100ce22fd0 100644 --- a/lib/geocoder/lookups/test.rb +++ b/lib/geocoder/lookups/test.rb @@ -5,6 +5,10 @@ module Geocoder module Lookup class Test < Base + def name + "Test" + end + def self.add_stub(query_text, results) stubs[query_text] = results end diff --git a/lib/geocoder/lookups/yahoo.rb b/lib/geocoder/lookups/yahoo.rb index b4381782ad7e9cfaa656a3dcdb44f3fc16669cc2..be1925df82eecb85f0c761d12399f447510812ba 100644 --- a/lib/geocoder/lookups/yahoo.rb +++ b/lib/geocoder/lookups/yahoo.rb @@ -5,10 +5,18 @@ require 'oauth_util' module Geocoder::Lookup class Yahoo < Base + def name + "Yahoo BOSS" + end + def map_link_url(coordinates) "http://maps.yahoo.com/#lat=#{coordinates[0]}&lon=#{coordinates[1]}" end + def required_api_key_parts + ["consumer key", "consumer secret"] + end + private # --------------------------------------------------------------- def results(query) diff --git a/lib/geocoder/lookups/yandex.rb b/lib/geocoder/lookups/yandex.rb index 70dbaa7d4106e58291f0a79b45d1ce392e6206e1..7470eb0fc6ac43194162d107d107146432694948 100644 --- a/lib/geocoder/lookups/yandex.rb +++ b/lib/geocoder/lookups/yandex.rb @@ -4,10 +4,18 @@ require "geocoder/results/yandex" module Geocoder::Lookup class Yandex < Base + def name + "Yandex" + end + def map_link_url(coordinates) "http://maps.yandex.ru/?ll=#{coordinates.reverse.join(',')}" end + def required_api_key_parts + ["key"] + end + private # --------------------------------------------------------------- def results(query) diff --git a/test/lookup_test.rb b/test/lookup_test.rb index b721e4a1b51bfc826b77a9f86886e51bdd1a87fc..4c9a00478a879694992d7abf1b6f84a9086f75f6 100644 --- a/test/lookup_test.rb +++ b/test/lookup_test.rb @@ -36,4 +36,11 @@ class LookupTest < Test::Unit::TestCase assert_match "showpostal=1", g.send(:query_url, Geocoder::Query.new("Madison Square Garden, New York, NY 10001, United States")) end + def test_raises_configuration_error_on_missing_key + assert_raises Geocoder::ConfigurationError do + Geocoder::Configuration.lookup = :bing + Geocoder::Configuration.api_key = nil + Geocoder.search("Madison Square Garden, New York, NY 10001, United States") + end + end end diff --git a/test/services_test.rb b/test/services_test.rb index 0000b57be0f2e7e5f75e9a63d59c86caf92230a7..d33a648f16f6e8cab7a1eea80f3e19e825f5b2fb 100644 --- a/test/services_test.rb +++ b/test/services_test.rb @@ -77,11 +77,13 @@ class ServicesTest < Test::Unit::TestCase def test_yahoo_no_results Geocoder::Configuration.lookup = :yahoo + set_api_key!(:yahoo) assert_equal [], Geocoder.search("no results") end def test_yahoo_error Geocoder::Configuration.lookup = :yahoo + set_api_key!(:yahoo) # keep test output clean: suppress timeout warning orig = $VERBOSE; $VERBOSE = nil assert_equal [], Geocoder.search("error") @@ -91,12 +93,14 @@ class ServicesTest < Test::Unit::TestCase def test_yahoo_result_components Geocoder::Configuration.lookup = :yahoo + set_api_key!(:yahoo) result = Geocoder.search("madison square garden").first assert_equal "10001", result.postal_code end def test_yahoo_address_formatting Geocoder::Configuration.lookup = :yahoo + set_api_key!(:yahoo) result = Geocoder.search("madison square garden").first assert_equal "Madison Square Garden, New York, NY 10001, United States", result.address end @@ -108,6 +112,7 @@ class ServicesTest < Test::Unit::TestCase # keep test output clean: suppress timeout warning orig = $VERBOSE; $VERBOSE = nil Geocoder::Configuration.lookup = :yandex + set_api_key!(:yandex) assert_equal [], Geocoder.search("invalid key") ensure $VERBOSE = orig @@ -118,6 +123,7 @@ class ServicesTest < Test::Unit::TestCase def test_geocoder_ca_result_components Geocoder::Configuration.lookup = :geocoder_ca + set_api_key!(:geocoder_ca) result = Geocoder.search([45.423733, -75.676333]).first assert_equal "CA", result.country_code assert_equal "289 Somerset ST E, Ottawa, ON K1N6W1, Canada", result.address @@ -141,6 +147,7 @@ class ServicesTest < Test::Unit::TestCase def test_bing_result_components Geocoder::Configuration.lookup = :bing + set_api_key!(:bing) result = Geocoder.search("Madison Square Garden, New York, NY").first assert_equal "Madison Square Garden, NY", result.address assert_equal "NY", result.state @@ -149,6 +156,7 @@ class ServicesTest < Test::Unit::TestCase def test_bing_no_results Geocoder::Configuration.lookup = :bing + set_api_key!(:bing) results = Geocoder.search("no results") assert_equal 0, results.length end @@ -157,22 +165,24 @@ class ServicesTest < Test::Unit::TestCase def test_nominatim_result_components Geocoder::Configuration.lookup = :nominatim + set_api_key!(:nominatim) result = Geocoder.search("Madison Square Garden, New York, NY").first assert_equal "10001", result.postal_code end def test_nominatim_address_formatting Geocoder::Configuration.lookup = :nominatim + set_api_key!(:nominatim) result = Geocoder.search("Madison Square Garden, New York, NY").first assert_equal "Madison Square Garden, West 31st Street, Long Island City, New York City, New York, 10001, United States of America", result.address end + # --- MapQuest --- def test_api_route Geocoder::Configuration.lookup = :mapquest Geocoder::Configuration.api_key = "abc123" - lookup = Geocoder::Lookup::Mapquest.new query = Geocoder::Query.new("Bluffton, SC") res = lookup.send(:query_url, query) @@ -182,12 +192,14 @@ class ServicesTest < Test::Unit::TestCase def test_mapquest_result_components Geocoder::Configuration.lookup = :mapquest + set_api_key!(:mapquest) result = Geocoder.search("Madison Square Garden, New York, NY").first assert_equal "10001", result.postal_code end def test_mapquest_address_formatting Geocoder::Configuration.lookup = :mapquest + set_api_key!(:mapquest) result = Geocoder.search("Madison Square Garden, New York, NY").first assert_equal "46 West 31st Street, New York, NY, 10001, US", result.address diff --git a/test/test_helper.rb b/test/test_helper.rb index 81deb6f3f269fb9bec6809fe2948d909694378ab..bff1219907fc5343f6426f114a9290135e195a05 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -326,19 +326,14 @@ class Test::Unit::TestCase end def set_api_key!(lookup_name) - if lookup_name == :google_premier - Geocoder::Configuration.api_key = [ - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', - 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb', - 'cccccccccccccccccccccccccccccc' - ] - elsif lookup_name == :yahoo - Geocoder::Configuration.api_key = [ - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', - 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' - ] + lookup = Geocoder::Lookup.get(lookup_name) + if lookup.required_api_key_parts.size == 1 + key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + elsif lookup.required_api_key_parts.size > 1 + key = lookup.required_api_key_parts else - Geocoder::Configuration.api_key = nil + key = nil end + Geocoder::Configuration.api_key = key end end