From 2ba20514440f8f67f3422f82b5866cb795fb7af2 Mon Sep 17 00:00:00 2001
From: Michal Musialik <michal@michalmusialik.com>
Date: Mon, 13 Mar 2017 18:12:08 +0100
Subject: [PATCH] Allow geoip2 result language to be changed for each result
 (#1157)

Maxmind geoip2 returns a collection of names in all available languages
for each field.
This commit allows us to change the language of a single result without
having to reconfigure Geocoder.
---
 lib/geocoder/results/geoip2.rb           | 28 +++++++++++++++++++-----
 test/unit/lookups/geoip2_test.rb         | 18 +++++++++++++++
 test/unit/lookups/maxmind_geoip2_test.rb | 20 +++++++++++++++++
 3 files changed, 61 insertions(+), 5 deletions(-)

diff --git a/lib/geocoder/results/geoip2.rb b/lib/geocoder/results/geoip2.rb
index 96721ad5..5e8b0088 100644
--- a/lib/geocoder/results/geoip2.rb
+++ b/lib/geocoder/results/geoip2.rb
@@ -15,11 +15,15 @@ module Geocoder
       end
 
       def city
-        data.fetch('city', {}).fetch('names', {}).fetch(locale, '')
+        fetch_name(
+          data.fetch('city', {}).fetch('names', {})
+        )
       end
 
       def state
-        data.fetch('subdivisions', []).fetch(0, {}).fetch('names', {}).fetch(locale, '')
+        fetch_name(
+          data.fetch('subdivisions', []).fetch(0, {}).fetch('names', {})
+        )
       end
 
       def state_code
@@ -27,7 +31,9 @@ module Geocoder
       end
 
       def country
-        data.fetch('country', {}).fetch('names', {}).fetch(locale, '')
+        fetch_name(
+          data.fetch('country', {}).fetch('names', {})
+        )
       end
 
       def country_code
@@ -48,14 +54,26 @@ module Geocoder
         end
       end
 
+      def language=(l)
+        @language = l.to_s
+      end
+
+      def language
+        @language ||= default_language
+      end
+
       private
 
       def data
         @data.to_hash
       end
 
-      def locale
-        @locale ||= Geocoder.config[:language].to_s
+      def default_language
+        @default_language = Geocoder.config[:language].to_s
+      end
+
+      def fetch_name(names)
+        names[language] || names[default_language] || ''
       end
     end
   end
diff --git a/test/unit/lookups/geoip2_test.rb b/test/unit/lookups/geoip2_test.rb
index d50e3bce..62e752eb 100644
--- a/test/unit/lookups/geoip2_test.rb
+++ b/test/unit/lookups/geoip2_test.rb
@@ -35,4 +35,22 @@ class Geoip2Test < GeocoderTestCase
     Geocoder::Configuration.language = :ru
     assert_equal 'Маунтин-Вью', result.city
   end
+
+  def test_dynamic_localization
+    result = Geocoder.search('8.8.8.8').first
+
+    result.language = :ru
+
+    assert_equal 'Маунтин-Вью', result.city
+  end
+
+  def test_dynamic_localization_fallback
+    result = Geocoder.search('8.8.8.8').first
+
+    result.language = :unsupported_language
+
+    assert_equal 'Mountain View', result.city
+    assert_equal 'California', result.state
+    assert_equal 'United States', result.country
+  end
 end
diff --git a/test/unit/lookups/maxmind_geoip2_test.rb b/test/unit/lookups/maxmind_geoip2_test.rb
index a930a201..125b05cb 100644
--- a/test/unit/lookups/maxmind_geoip2_test.rb
+++ b/test/unit/lookups/maxmind_geoip2_test.rb
@@ -29,4 +29,24 @@ class MaxmindGeoip2Test < GeocoderTestCase
     results = Geocoder.search("no results")
     assert_equal 0, results.length
   end
+
+  def test_dynamic_localization
+    result = Geocoder.search('1.2.3.4').first
+
+    result.language = :ru
+
+    assert_equal 'Лос-Анджелес', result.city
+    assert_equal 'Калифорния', result.state
+    assert_equal 'США', result.country
+  end
+
+  def test_dynamic_localization_fallback
+    result = Geocoder.search('1.2.3.4').first
+
+    result.language = :unsupported_language
+
+    assert_equal 'Los Angeles', result.city
+    assert_equal 'California', result.state
+    assert_equal 'United States', result.country
+  end
 end
-- 
GitLab