From d807048ceb5e84254dd666b4a63bc725947d48fd Mon Sep 17 00:00:00 2001
From: Alex Reisner <alex@alexreisner.com>
Date: Thu, 13 Mar 2014 14:25:06 -0400
Subject: [PATCH] Raise RequestDenied on HTTP 401 response.

This is relevant for SmartyStreets, and seems like a good idea in
general (possibly supported by other APIs).
---
 lib/geocoder/lookups/base.rb | 8 ++++++++
 test/test_helper.rb          | 8 ++++++++
 test/unit/lookup_test.rb     | 9 +++++++++
 3 files changed, 25 insertions(+)

diff --git a/lib/geocoder/lookups/base.rb b/lib/geocoder/lookups/base.rb
index 9d0ae832..115f914d 100644
--- a/lib/geocoder/lookups/base.rb
+++ b/lib/geocoder/lookups/base.rb
@@ -214,6 +214,7 @@ module Geocoder
         else
           check_api_key_configuration!(query)
           response = make_api_request(query)
+          check_response_for_errors!(response)
           body = response.body
           if cache and valid_response?(response)
             cache[key] = body
@@ -223,6 +224,13 @@ module Geocoder
         body
       end
 
+      def check_response_for_errors!(response)
+        if response.code.to_i == 401
+          raise_error(Geocoder::RequestDenied) ||
+            warn("Geocoding API error: 401 Unauthorized")
+        end
+      end
+
       ##
       # Make an HTTP(S) request to a geocoding API and
       # return the response object.
diff --git a/test/test_helper.rb b/test/test_helper.rb
index a59a6f1c..2309827b 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -347,3 +347,11 @@ class GeocoderTestCase < Test::Unit::TestCase
     Geocoder.configure(:api_key => key)
   end
 end
+
+class MockHttpResponse
+  attr_reader :code, :body
+  def initialize(options = {})
+    @code = options[:code].to_s
+    @body = options[:body]
+  end
+end
diff --git a/test/unit/lookup_test.rb b/test/unit/lookup_test.rb
index 83561537..5ece0de4 100644
--- a/test/unit/lookup_test.rb
+++ b/test/unit/lookup_test.rb
@@ -56,6 +56,15 @@ class LookupTest < GeocoderTestCase
     end
   end
 
+  def test_raises_exception_on_401_response
+    Geocoder.configure(always_raise: [Geocoder::RequestDenied])
+    assert_raises Geocoder::RequestDenied do
+      lookup = Geocoder::Lookup.get(:smarty_streets)
+      response = MockHttpResponse.new(code: 401)
+      lookup.send(:check_response_for_errors!, response)
+    end
+  end
+
   def test_raises_exception_on_invalid_key
     Geocoder.configure(:always_raise => [Geocoder::InvalidApiKey])
     #Geocoder::Lookup.all_services_except_test.each do |l|
-- 
GitLab