diff --git a/lib/geo_code_repo.rb b/lib/geo_code_repo.rb index 3d591147c32ec2495571917017263d054642f777..7d2a02274f4db492abaf0789e70c38b0e854a341 100644 --- a/lib/geo_code_repo.rb +++ b/lib/geo_code_repo.rb @@ -10,12 +10,30 @@ class GeoCodeRepo @memcache = memcache end + # @param q [String] + # @return [EMPromise] def find(q) - cache(q) { + req(q, locate: q) + end + + # @param lat [Float] + # @param lon [Float] + # @return [EMPromise] + def reverse(lat, lon) + req("reverse_#{lat}_#{lon}", latt: lat, longt: lon) + end + +protected + + # @param cache_key [String] + # @param query [Hash] + # @return [EMPromise] + def req(cache_key, **query) + cache(cache_key) { EM::HttpRequest.new( "https://geocoder.ca/", tls: { verify_peer: true } - ).aget(query: { json: 1, locate: q }).then { |res| + ).aget(query: { json: 1, **query }).then { |res| json = JSON.parse(res.response) raise "Geocode Failure" unless json["latt"] && json["longt"] @@ -24,8 +42,6 @@ class GeoCodeRepo }.then(&GeoCode.method(:for)) end -protected - def cache(k, &blk) k = "geocode_#{k.gsub(/ /, '%20')}" promise = EMPromise.new diff --git a/test/test_geo_code_repo.rb b/test/test_geo_code_repo.rb new file mode 100644 index 0000000000000000000000000000000000000000..70364ff0884905e949eec33b0d23497b4e0a6ba6 --- /dev/null +++ b/test/test_geo_code_repo.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require "test_helper" +require "geo_code_repo" + +class GeoCodeRepoTest < Minitest::Test + def test_reverse + stub_request( + :get, + "https://geocoder.ca/?json=1&latt=40.739362&longt=-73.991043" + ).to_return(status: 200, body: { + "city" => "New York", + "prov" => "NY", + "latt" => "40.739362", + "longt" => "-73.991043", + "usa" => { "uscity" => "New York", "state" => "NY", "zip" => "10011" } + }.to_json) + + geo = GeoCodeRepo.new(memcache: FakeMemcache.new) + .reverse(40.739362, -73.991043).sync + + assert_equal "New York", geo.city + assert_equal "NY", geo.state + end + em :test_reverse + + def test_reverse_raises_on_missing_coords + stub_request( + :get, + "https://geocoder.ca/?json=1&latt=0.0&longt=0.0" + ).to_return(status: 200, body: { "error" => "no result" }.to_json) + + assert_raises(RuntimeError) do + GeoCodeRepo.new(memcache: FakeMemcache.new) + .reverse(0.0, 0.0).sync + end + end + em :test_reverse_raises_on_missing_coords +end