1# frozen_string_literal: true
2
3require "test_helper"
4require "bandwidth_tn_repo"
5require "local_calling_guide_repo"
6require "geo_code_repo"
7
8BandwidthTnRepo::DB = Minitest::Mock.new
9
10class BandwidthTnRepoTest < Minitest::Test
11 def test_local_inventory_recycled_with_price
12 bw_body = Nokogiri::XML::Builder.new { |xml|
13 xml.Response {
14 xml.TelephoneNumberDetails {
15 xml.City "Austin"
16 xml.State "TX"
17 }
18 }
19 }.to_xml
20
21 stub_request(
22 :get,
23 "https://dashboard.bandwidth.com/v1.0/tns/5565555555/tndetails"
24 )
25 .with(
26 headers: {
27 "Accept" => "application/xml",
28 "Accept-Encoding" => "gzip, compressed",
29 "Authorization" => "Bearer test_bw_oauth_token",
30 "User-Agent" => "Ruby-Bandwidth-Iris"
31 }
32 ).to_return(status: 200, body: bw_body, headers: {})
33
34 tel = "+15565555555"
35
36 BandwidthTnRepo::DB.expect(
37 :exec,
38 nil,
39 [
40 BandwidthTnRepo::STASH_QUERY,
41 [tel, "TX", "Austin", "test_bw_account", 10]
42 ]
43 )
44
45 BandwidthTnRepo.new.disconnect(tel, "test").sync
46
47 assert_mock BandwidthTnRepo::DB
48 end
49 em :test_local_inventory_recycled_with_price
50
51 def test_local_inventory_recycled_no_price
52 bw_body = Nokogiri::XML::Builder.new { |xml|
53 xml.Response {
54 xml.TelephoneNumberDetails {
55 xml.City "Austin"
56 xml.State "TX"
57 }
58 }
59 }.to_xml
60
61 stub_request(
62 :get,
63 "https://dashboard.bandwidth.com/v1.0/tns/5575555555/tndetails"
64 )
65 .with(
66 headers: {
67 "Accept" => "application/xml",
68 "Accept-Encoding" => "gzip, compressed",
69 "Authorization" => "Bearer test_bw_oauth_token",
70 "User-Agent" => "Ruby-Bandwidth-Iris"
71 }
72 ).to_return(status: 200, body: bw_body, headers: {})
73
74 tel = "+15575555555"
75
76 BandwidthTnRepo::DB.expect(
77 :exec,
78 nil,
79 [
80 BandwidthTnRepo::STASH_QUERY,
81 [tel, "TX", "Austin", "test_bw_account", 0]
82 ]
83 )
84
85 BandwidthTnRepo.new.disconnect(tel, "test").sync
86
87 assert_mock BandwidthTnRepo::DB
88 end
89 em :test_local_inventory_recycled_no_price
90
91 def test_stash_falls_back_to_lcg_on_unreadable
92 tel = "+15565555555"
93
94 # bw_r bw_l geo_r geo_l lcg_r lcg_l exp_r exp_l
95 [
96 ["TX", "Austin", "CA", "LA", "NY", "NYC", "TX", "Austin"],
97 ["TX", "1City", "CA", "LA", "NY", "NYC", "TX", "LA"],
98 ["TX", "1City", "CA", "2City", "NY", "NYC", "TX", "NYC"],
99 ["1ST", "Austin", "CA", "LA", "NY", "NYC", "CA", "Austin"],
100 ["1ST", "1City", "CA", "LA", "NY", "NYC", "CA", "LA"],
101 ["1ST", "1City", "CA", "2City", "NY", "NYC", "CA", "NYC"],
102 ["1ST", "Austin", "2ST", "LA", "NY", "NYC", "NY", "Austin"],
103 ["1ST", "1City", "2ST", "LA", "NY", "NYC", "NY", "LA"],
104 ["1ST", "1City", "2ST", "2City", "NY", "NYC", "NY", "NYC"],
105 ["TX", nil, "CA", "LA", "NY", "NYC", "TX", "LA"],
106 ["TX", nil, "CA", nil, "NY", "NYC", "TX", "NYC"],
107 [nil, "Austin", "CA", "LA", "NY", "NYC", "CA", "Austin"],
108 [nil, nil, "CA", "LA", "NY", "NYC", "CA", "LA"],
109 [nil, nil, "CA", nil, "NY", "NYC", "CA", "NYC"],
110 [nil, "Austin", nil, "LA", "NY", "NYC", "NY", "Austin"],
111 [nil, nil, nil, "LA", "NY", "NYC", "NY", "LA"],
112 [nil, nil, nil, nil, "NY", "NYC", "NY", "NYC"],
113 [:error, :error, "CA", "LA", "NY", "NYC", "CA", "LA"],
114 [:error, :error, "CA", "2City", "NY", "NYC", "CA", "NYC"],
115 [:error, :error, "2ST", "2City", "NY", "NYC", "NY", "NYC"],
116 ["TX", "1City", :error, :error, "NY", "NYC", "TX", "NYC"],
117 ["1ST", "Austin", :error, :error, "NY", "NYC", "NY", "Austin"],
118 ["1ST", "1City", :error, :error, "NY", "NYC", "NY", "NYC"],
119 [nil, nil, :error, :error, "NY", "NYC", "NY", "NYC"],
120 [:error, :error, :error, :error, "NY", "NYC", "NY", "NYC"]
121 ].each do |bw_r, bw_l, geo_r, geo_l, lcg_r, lcg_l, exp_r, exp_l|
122 WebMock.reset!
123 stub_bw_oauth_token
124 stub_bw_tndetails(bw_r, bw_l)
125
126 lcg_body = Nokogiri::XML::Builder.new { |xml|
127 xml.root {
128 xml.prefixdata {
129 xml.send(:"rc-lat", "30.267153")
130 xml.send(:"rc-lon", "-97.743061")
131 xml.rc(lcg_l)
132 xml.region(lcg_r)
133 }
134 }
135 }.to_xml
136
137 stub_request(
138 :get,
139 "https://localcallingguide.com/xmlprefix.php?npa=556&nxx=555"
140 ).to_return(status: 200, body: lcg_body)
141
142 stub_geocoder(geo_r, geo_l)
143
144 BandwidthTnRepo::DB.expect(
145 :exec,
146 nil,
147 [
148 BandwidthTnRepo::STASH_QUERY,
149 [tel, exp_r, exp_l, "test_bw_account", 10]
150 ]
151 )
152
153 BandwidthTnRepo.new(
154 local_calling_guide_repo: LocalCallingGuideRepo.new,
155 geo_code_repo: GeoCodeRepo.new(memcache: FakeMemcache.new)
156 ).disconnect(tel, "test").sync
157
158 assert_mock BandwidthTnRepo::DB
159 end
160 end
161 em :test_stash_falls_back_to_lcg_on_unreadable
162
163 def test_rate_center_resolves_region_and_locality_independently
164 fake_btn = Struct.new(:telephone_number, :bw_state, :bw_city) {
165 def get_details
166 { city: bw_city, state: bw_state }
167 end
168 }
169
170 fake_prefix = Struct.new(:lat, :lon, :region, :locality) {
171 def to_h
172 { "region" => region, "locality" => locality }
173 end
174 }
175
176 fake_geo_code = Struct.new(:locality, :region) {
177 def to_h
178 { locality: locality, region: region }
179 end
180 }
181
182 fake_lcg_repo = Struct.new(:prefix) {
183 def find(_npa, _nxx)
184 EMPromise.resolve(prefix)
185 end
186 }
187
188 fake_geo_repo = Struct.new(:result) {
189 def reverse(_lat, _lon)
190 EMPromise.resolve(result)
191 end
192 }
193
194 # bw_r bw_l geo_r geo_l lcg_r lcg_l exp_r exp_l
195 [
196 ["TX", "Austin", "CA", "LA", "NY", "NYC", "TX", "Austin"],
197 ["TX", "1City", "CA", "LA", "NY", "NYC", "TX", "LA"],
198 ["TX", "1City", "CA", "2City", "NY", "NYC", "TX", "NYC"],
199 ["1ST", "Austin", "CA", "LA", "NY", "NYC", "CA", "Austin"],
200 ["1ST", "1City", "CA", "LA", "NY", "NYC", "CA", "LA"],
201 ["1ST", "1City", "CA", "2City", "NY", "NYC", "CA", "NYC"],
202 ["1ST", "Austin", "2ST", "LA", "NY", "NYC", "NY", "Austin"],
203 ["1ST", "1City", "2ST", "LA", "NY", "NYC", "NY", "LA"],
204 ["1ST", "1City", "2ST", "2City", "NY", "NYC", "NY", "NYC"],
205 ["TX", nil, "CA", "LA", "NY", "NYC", "TX", "LA"],
206 ["TX", nil, "CA", nil, "NY", "NYC", "TX", "NYC"],
207 [nil, "Austin", "CA", "LA", "NY", "NYC", "CA", "Austin"],
208 [nil, nil, "CA", "LA", "NY", "NYC", "CA", "LA"],
209 [nil, nil, "CA", nil, "NY", "NYC", "CA", "NYC"],
210 [nil, "Austin", nil, "LA", "NY", "NYC", "NY", "Austin"],
211 [nil, nil, nil, "LA", "NY", "NYC", "NY", "LA"],
212 [nil, nil, nil, nil, "NY", "NYC", "NY", "NYC"]
213 ].each do |bw_r, bw_l, geo_r, geo_l, lcg_r, lcg_l, exp_r, exp_l|
214 btn = fake_btn.new("5565555555", bw_r, bw_l)
215 prefix = fake_prefix.new(30.0, -97.0, lcg_r, lcg_l)
216 geo = fake_geo_code.new(geo_l, geo_r)
217
218 result = BandwidthTnRepo::RateCenter.for(
219 btn,
220 lcg_repo: fake_lcg_repo.new(prefix),
221 geo_code_repo: fake_geo_repo.new(geo)
222 ).sync
223
224 assert_equal(
225 [exp_r, exp_l],
226 result.to_a,
227 "bw=#{[bw_r, bw_l]} geo=#{[geo_r, geo_l]} " \
228 "lcg=#{[lcg_r, lcg_l]}"
229 )
230 end
231 end
232 em :test_rate_center_resolves_region_and_locality_independently
233
234 def stub_bw_tndetails(bw_r, bw_l)
235 if bw_r == :error
236 stub_request(
237 :get,
238 "https://dashboard.bandwidth.com/v1.0/tns/5565555555/tndetails"
239 ).to_return(status: 404)
240 return
241 end
242
243 bw_body = Nokogiri::XML::Builder.new { |xml|
244 xml.Response {
245 xml.TelephoneNumberDetails {
246 xml.City(bw_l) if bw_l
247 xml.State(bw_r) if bw_r
248 }
249 }
250 }.to_xml
251
252 stub_request(
253 :get,
254 "https://dashboard.bandwidth.com/v1.0/tns/5565555555/tndetails"
255 )
256 .with(
257 headers: {
258 "Accept" => "application/xml",
259 "Accept-Encoding" => "gzip, compressed",
260 "Authorization" => "Bearer test_bw_oauth_token",
261 "User-Agent" => "Ruby-Bandwidth-Iris"
262 }
263 ).to_return(status: 200, body: bw_body, headers: {})
264 end
265
266 def stub_geocoder(geo_r, geo_l)
267 if geo_r == :error
268 stub_request(
269 :get,
270 "https://geocoder.ca/?json=1&latt=30.267153&longt=-97.743061"
271 ).to_return(status: 500)
272 return
273 end
274
275 geo_json = {
276 "latt" => "30.267153",
277 "longt" => "-97.743061"
278 }
279 geo_json["prov"] = geo_r if geo_r
280 geo_json["city"] = geo_l if geo_l
281
282 stub_request(
283 :get,
284 "https://geocoder.ca/?json=1&latt=30.267153&longt=-97.743061"
285 ).to_return(status: 200, body: geo_json.to_json)
286 end
287end