From 1a73c5ea46d8fe7e72960a689822889472cb4ec1 Mon Sep 17 00:00:00 2001
From: Philip Hallstrom <philip@pjkh.com>
Date: Tue, 1 Oct 2013 13:03:34 -0700
Subject: [PATCH] Add error checking for Mapquest lookup

---
 lib/geocoder/lookups/mapquest.rb       | 18 ++++++++++++++-
 test/fixtures/mapquest_error           | 16 +++++++++++++
 test/fixtures/mapquest_invalid_api_key | 16 +++++++++++++
 test/fixtures/mapquest_invalid_request | 16 +++++++++++++
 test/fixtures/mapquest_no_results      | 11 ++++++++-
 test/services_test.rb                  | 32 ++++++++++++++++++++++++++
 6 files changed, 107 insertions(+), 2 deletions(-)
 create mode 100644 test/fixtures/mapquest_error
 create mode 100644 test/fixtures/mapquest_invalid_api_key
 create mode 100644 test/fixtures/mapquest_invalid_request

diff --git a/lib/geocoder/lookups/mapquest.rb b/lib/geocoder/lookups/mapquest.rb
index db954d33..632e86b6 100644
--- a/lib/geocoder/lookups/mapquest.rb
+++ b/lib/geocoder/lookups/mapquest.rb
@@ -34,9 +34,25 @@ module Geocoder::Lookup
       params.merge(super)
     end
 
+    # http://www.mapquestapi.com/geocoding/status_codes.html
+    # http://open.mapquestapi.com/geocoding/status_codes.html
     def results(query)
       return [] unless doc = fetch_data(query)
-      doc["results"][0]['locations']
+      return doc["results"][0]['locations'] if doc['info']['statuscode'] == 0 # A successful geocode call
+
+      messages = doc['info']['messages'].join
+
+      case doc['info']['statuscode']
+      when 400 # Error with input
+        raise_error(Geocoder::InvalidRequest, messages) ||
+          warn("Mapquest Geocoding API error: #{messages}")
+      when 403 # Key related error
+        raise_error(Geocoder::InvalidApiKey, messages) ||
+          warn("Mapquest Geocoding API error: #{messages}")
+      when 500 # Unknown error
+        raise_error(Geocoder::Error, messages) ||
+          warn("Mapquest Geocoding API error: #{messages}")
+      end
     end
 
   end
diff --git a/test/fixtures/mapquest_error b/test/fixtures/mapquest_error
new file mode 100644
index 00000000..0f8adf2d
--- /dev/null
+++ b/test/fixtures/mapquest_error
@@ -0,0 +1,16 @@
+{
+  "results": [
+    {
+    "locations": []
+    }
+  ],
+  "info": {
+    "copyright": {
+      "text": "© 2012 MapQuest, Inc.",
+      "imageUrl": "http://api.mqcdn.com/res/mqlogo.gif",
+      "imageAltText": "© 2012 MapQuest, Inc."
+    },
+    "statuscode": 500,
+    "messages": ["Error processing request: ..."]
+  }
+}
diff --git a/test/fixtures/mapquest_invalid_api_key b/test/fixtures/mapquest_invalid_api_key
new file mode 100644
index 00000000..f8df9eb2
--- /dev/null
+++ b/test/fixtures/mapquest_invalid_api_key
@@ -0,0 +1,16 @@
+{
+  "results": [
+    {
+    "locations": []
+    }
+  ],
+  "info": {
+    "copyright": {
+      "text": "© 2012 MapQuest, Inc.",
+      "imageUrl": "http://api.mqcdn.com/res/mqlogo.gif",
+      "imageAltText": "© 2012 MapQuest, Inc."
+    },
+    "statuscode": 403,
+    "messages": ["..."]
+  }
+}
diff --git a/test/fixtures/mapquest_invalid_request b/test/fixtures/mapquest_invalid_request
new file mode 100644
index 00000000..00845a64
--- /dev/null
+++ b/test/fixtures/mapquest_invalid_request
@@ -0,0 +1,16 @@
+{
+  "results": [
+    {
+    "locations": []
+    }
+  ],
+  "info": {
+    "copyright": {
+      "text": "© 2012 MapQuest, Inc.",
+      "imageUrl": "http://api.mqcdn.com/res/mqlogo.gif",
+      "imageAltText": "© 2012 MapQuest, Inc."
+    },
+    "statuscode": 400,
+    "messages": ["Illegal argument from request: ..."]
+  }
+}
diff --git a/test/fixtures/mapquest_no_results b/test/fixtures/mapquest_no_results
index 0cfc3e76..b3924763 100644
--- a/test/fixtures/mapquest_no_results
+++ b/test/fixtures/mapquest_no_results
@@ -3,5 +3,14 @@
     {
     "locations": []
     }
-  ]
+  ],
+  "info": {
+    "copyright": {
+      "text": "© 2012 MapQuest, Inc.",
+      "imageUrl": "http://api.mqcdn.com/res/mqlogo.gif",
+      "imageAltText": "© 2012 MapQuest, Inc."
+    },
+    "statuscode": 0,
+    "messages": []
+  }
 }
diff --git a/test/services_test.rb b/test/services_test.rb
index 3a4e8e1a..68da4e9f 100644
--- a/test/services_test.rb
+++ b/test/services_test.rb
@@ -316,6 +316,38 @@ class ServicesTest < Test::Unit::TestCase
       result.address
   end
 
+  def test_mapquest_no_results
+    Geocoder.configure(:lookup => :mapquest)
+    set_api_key!(:mapquest)
+    assert_equal [], Geocoder.search("no results")
+  end
+
+  def test_mapquest_raises_exception_when_invalid_request
+    Geocoder.configure(:always_raise => [Geocoder::InvalidRequest])
+    l = Geocoder::Lookup.get(:mapquest)
+    assert_raises Geocoder::InvalidRequest do
+      l.send(:results, Geocoder::Query.new("invalid request"))
+    end
+  end
+
+  def test_mapquest_raises_exception_when_invalid_api_key
+    Geocoder.configure(:always_raise => [Geocoder::InvalidApiKey])
+    l = Geocoder::Lookup.get(:mapquest)
+    assert_raises Geocoder::InvalidApiKey do
+      l.send(:results, Geocoder::Query.new("invalid api key"))
+    end
+  end
+
+  def test_mapquest_raises_exception_when_error
+    Geocoder.configure(:always_raise => [Geocoder::Error])
+    l = Geocoder::Lookup.get(:mapquest)
+    assert_raises Geocoder::Error do
+      l.send(:results, Geocoder::Query.new("error"))
+    end
+  end
+
+
+
   # --- Esri ---
 
   def test_esri_query_for_geocode
-- 
GitLab