Change summary
lib/local_calling_guide_repo.rb | 25 ++++++++++++
test/test_local_calling_guide_repo.rb | 57 +++++++++++++++++++++++++++++
2 files changed, 82 insertions(+)
Detailed changes
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require "nokogiri"
+
+class LocalCallingGuideRepo
+ # @param npa [String] area code (first 3 digits after country code)
+ # @param nxx [String] exchange (digits 4-6)
+ # @return [EMPromise<Hash{Symbol => Float}>] :lat and :lon of the rate center
+ # @raise [RuntimeError] if no prefix data found
+ def find(npa, nxx)
+ EM::HttpRequest.new(
+ "https://localcallingguide.com/xmlprefix.php",
+ tls: { verify_peer: true }
+ ).aget(query: { npa: npa, nxx: nxx }).then { |res|
+ doc = Nokogiri::XML.parse(res.response)
+ prefix = doc.at("prefixdata")
+ raise "No prefix data for #{npa}-#{nxx}" unless prefix
+
+ {
+ lat: prefix.at("rc-lat").text.to_f,
+ lon: prefix.at("rc-lon").text.to_f
+ }
+ }
+ end
+end
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+require "test_helper"
+require "local_calling_guide_repo"
+
+class LocalCallingGuideRepoTest < Minitest::Test
+ def test_find_returns_lat_lon
+ body = Nokogiri::XML::Builder.new { |xml|
+ xml.root {
+ xml.prefixdata {
+ xml.npa "917"
+ xml.nxx "727"
+ xml.x "0"
+ xml.rc "NEW YORK"
+ xml.region "NY"
+ xml.send(:"rc-lat", "40.739362")
+ xml.send(:"rc-lon", "-73.991043")
+ }
+ xml.prefixdata {
+ xml.npa "917"
+ xml.nxx "727"
+ xml.x "1"
+ xml.rc "NEW YORK"
+ xml.region "NY"
+ xml.send(:"rc-lat", "40.739362")
+ xml.send(:"rc-lon", "-73.991043")
+ }
+ }
+ }.to_xml
+
+ stub_request(
+ :get,
+ "https://localcallingguide.com/xmlprefix.php?npa=917&nxx=727"
+ ).to_return(status: 200, body: body)
+
+ result = LocalCallingGuideRepo.new.find("917", "727").sync
+ assert_equal 40.739362, result[:lat]
+ assert_equal(-73.991043, result[:lon])
+ end
+ em :test_find_returns_lat_lon
+
+ def test_find_raises_on_missing_data
+ body = Nokogiri::XML::Builder.new { |xml|
+ xml.root
+ }.to_xml
+
+ stub_request(
+ :get,
+ "https://localcallingguide.com/xmlprefix.php?npa=000&nxx=000"
+ ).to_return(status: 200, body: body)
+
+ assert_raises(RuntimeError) do
+ LocalCallingGuideRepo.new.find("000", "000").sync
+ end
+ end
+ em :test_find_raises_on_missing_data
+end