1# frozen_string_literal: true
2
3require "test_helper"
4require "tel_selections"
5
6class TelSelectionsTest < Minitest::Test
7 def setup
8 @manager = TelSelections.new(
9 redis: FakeRedis.new,
10 db: FakeDB.new,
11 memcache: FakeMemcache.new
12 )
13 end
14
15 def test_set_get
16 assert_kind_of TelSelections::ChooseTel, @manager["jid@example.com"].sync
17 @manager.set(
18 "jid@example.com",
19 TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
20 ).sync
21 assert_kind_of TelSelections::HaveTel, @manager["jid@example.com"].sync
22 end
23 em :test_set_get
24
25 def test_choose_tel_have_tel
26 jid = "jid@example.com"
27 @manager.set(
28 jid,
29 TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
30 ).sync
31 assert_equal "+15555550000", @manager[jid].then(&:choose_tel).sync.tel
32 end
33 em :test_choose_tel_have_tel
34
35 class AvailableNumberTest < Minitest::Test
36 def test_for_no_rsm
37 form = Blather::Stanza::X.new
38 form.fields = [{ var: "q", value: "226" }]
39 iris_query = TelSelections::ChooseTel::AvailableNumber
40 .for(form, db: FakeDB.new, memcache: FakeMemcache.new)
41 .instance_variable_get(:@iris_query)
42 assert_equal(
43 { areaCode: "226", enableTNDetail: true, LCA: false, quantity: 10 },
44 iris_query
45 )
46 end
47
48 def test_for_rsm
49 form = Blather::Stanza::X.new
50 form.fields = [{ var: "q", value: "226" }]
51 Nokogiri::XML::Builder.with(form) do
52 set(xmlns: "http://jabber.org/protocol/rsm") do
53 max 500
54 end
55 end
56 iris_query = TelSelections::ChooseTel::AvailableNumber
57 .for(form, db: FakeDB.new, memcache: FakeMemcache.new)
58 .instance_variable_get(:@iris_query)
59 # quantity should be 500 due to max inside tel selections
60 assert_equal(
61 { areaCode: "226", enableTNDetail: true, LCA: false, quantity: 500 },
62 iris_query
63 )
64 end
65
66 def test_for_feelinglucky
67 form = Blather::Stanza::X.new
68 form.fields = [
69 { var: "q", value: "" },
70 {
71 var: "http://jabber.org/protocol/commands#actions",
72 value: "feelinglucky"
73 }
74 ]
75 iris_query = TelSelections::ChooseTel::AvailableNumber
76 .for(form, db: FakeDB.new, memcache: FakeMemcache.new)
77 .instance_variable_get(:@iris_query)
78 assert_equal(
79 { areaCode: "810", enableTNDetail: true, LCA: false, quantity: 10 },
80 iris_query
81 )
82 end
83
84 def test_fallback
85 stub_request(
86 :get,
87 "https://dashboard.bandwidth.com/v1.0/accounts//availableNumbers" \
88 "?city=Kitchener-Waterloo&enableTNDetail=true&lCA=false&" \
89 "quantity=10&state=ON"
90 ).to_return(status: 200, body: "")
91
92 stub_request(
93 :get,
94 "https://geocoder.ca/?json=1&locate=Kitchener-Waterloo,%20ON"
95 ).to_return(status: 200, body: {
96 postal: "N2H", longt: 0, latt: 0
97 }.to_json)
98
99 stub_request(
100 :get,
101 "https://dashboard.bandwidth.com/v1.0/accounts//availableNumbers" \
102 "?areaCode=226&enableTNDetail=true&quantity=10"
103 ).to_return(status: 200, body: <<~XML)
104 <SearchResult>
105 <TelephoneNumberList>
106 <TelephoneNumber>
107 <FullNumber>22655512345</FullNumber>
108 <City>Somewhere</City>
109 <State>ON</State>
110 </TelephoneNumber>
111 </TelephoneNumberList>
112 </SearchResult>
113 XML
114
115 db = FakeDB.new(
116 ["CA", "POINT(0.0000000000 0.0000000000)", 3] =>
117 [{ "area_code" => "226" }]
118 )
119 form = Blather::Stanza::X.new
120 form.fields = [{ var: "q", value: "Kitchener, ON" }]
121 tns = execute_command do
122 TelSelections::ChooseTel::AvailableNumber
123 .for(form, db: db, memcache: FakeMemcache.new)
124 .tns
125 end
126 assert_equal(
127 ["(226) 555-12345 (Somewhere, ON)"],
128 tns.map(&:to_s)
129 )
130 end
131 em :test_fallback
132
133 def test_local_inventory
134 stub_request(
135 :get,
136 "https://dashboard.bandwidth.com/v1.0/accounts//availableNumbers" \
137 "?city=Kitchener-Waterloo&enableTNDetail=true&lCA=false&" \
138 "quantity=10&state=ON"
139 ).to_return(status: 200, body: "")
140
141 db = FakeDB.new(
142 ["ON", "Kitchener-Waterloo"] => [{
143 "tel" => "+122655512345",
144 "region" => "ON",
145 "locality" => "Kitchener-Waterloo"
146 }]
147 )
148 form = Blather::Stanza::X.new
149 form.fields = [{ var: "q", value: "Kitchener, ON" }]
150 tns = execute_command do
151 TelSelections::ChooseTel::AvailableNumber
152 .for(form, db: db, memcache: FakeMemcache.new)
153 .tns
154 end
155 assert_equal(
156 ["(226) 555-12345 (Kitchener-Waterloo, ON)"],
157 tns.map(&:to_s)
158 )
159 end
160 em :test_local_inventory
161 end
162
163 class TnOptionTest < Minitest::Test
164 def setup
165 @tn = TelSelections::ChooseTel::Tn::Option.new(
166 full_number: "5551234567",
167 city: "Toronto",
168 state: "ON",
169 garbage: "stuff"
170 )
171 end
172
173 def test_to_s
174 assert_equal "(555) 123-4567 (Toronto, ON)", @tn.to_s
175 end
176
177 def test_tel
178 assert_equal "+15551234567", @tn.tel
179 end
180
181 def test_option
182 assert_equal(
183 Blather::Stanza::X::Field::Option.new(
184 label: "(555) 123-4567 (Toronto, ON)",
185 value: "+15551234567"
186 ),
187 @tn.option
188 )
189 end
190
191 def test_option_reference
192 ref = @tn.option.find("ns:reference", ns: "urn:xmpp:reference:0").first
193 assert_equal(
194 @tn.formatted_tel,
195 @tn.option.label[ref["begin"].to_i..ref["end"].to_i]
196 )
197 assert_equal "tel:+15551234567", ref["uri"]
198 end
199 end
200
201 class QTest < Minitest::Test
202 def test_for_area_code
203 q = TelSelections::ChooseTel::Q.for("226")
204 assert_equal({ areaCode: "226" }, q.iris_query)
205 end
206
207 def test_for_area_code_sql
208 q = TelSelections::ChooseTel::Q.for("226")
209 assert_equal(
210 [
211 "SELECT * FROM tel_inventory " \
212 "WHERE available_after < LOCALTIMESTAMP AND tel LIKE $1",
213 "+1226%"
214 ],
215 q.sql_query
216 )
217 end
218
219 def test_for_npanxx
220 q = TelSelections::ChooseTel::Q.for("226666")
221 assert_equal({ npaNxx: "226666" }, q.iris_query)
222 end
223
224 def test_for_npanxx_sql
225 q = TelSelections::ChooseTel::Q.for("226666")
226 assert_equal(
227 [
228 "SELECT * FROM tel_inventory " \
229 "WHERE available_after < LOCALTIMESTAMP AND tel LIKE $1",
230 "+1226666%"
231 ],
232 q.sql_query
233 )
234 end
235
236 def test_for_npanxxx
237 q = TelSelections::ChooseTel::Q.for("2266667")
238 assert_equal({ npaNxxx: "2266667" }, q.iris_query)
239 end
240
241 def test_for_npanxxx_sql
242 q = TelSelections::ChooseTel::Q.for("2266667")
243 assert_equal(
244 [
245 "SELECT * FROM tel_inventory " \
246 "WHERE available_after < LOCALTIMESTAMP AND tel LIKE $1",
247 "+12266667%"
248 ],
249 q.sql_query
250 )
251 end
252
253 def test_for_zip
254 q = TelSelections::ChooseTel::Q.for("90210")
255 assert_equal({ zip: "90210" }, q.iris_query)
256 end
257
258 def test_for_zip_sql
259 q = TelSelections::ChooseTel::Q.for("90210")
260 refute q.sql_query
261 end
262
263 def test_for_localvanity
264 q = TelSelections::ChooseTel::Q.for("~mboa")
265 assert_equal({ localVanity: "mboa" }, q.iris_query)
266 end
267
268 def test_for_localvanity_sql
269 q = TelSelections::ChooseTel::Q.for("~mboa")
270 assert_equal(
271 [
272 "SELECT * FROM tel_inventory " \
273 "WHERE available_after < LOCALTIMESTAMP AND tel LIKE $1",
274 "%6262%"
275 ],
276 q.sql_query
277 )
278 end
279
280 def test_for_state
281 q = TelSelections::ChooseTel::Q.for("ON")
282 assert_equal({ state: "ON" }, q.iris_query)
283 end
284
285 def test_for_state_sql
286 q = TelSelections::ChooseTel::Q.for("ON")
287 assert_equal(
288 [
289 "SELECT * FROM tel_inventory " \
290 "WHERE available_after < LOCALTIMESTAMP AND region = $1",
291 "ON"
292 ],
293 q.sql_query
294 )
295 end
296
297 def test_for_state_name
298 q = TelSelections::ChooseTel::Q.for("ontario")
299 assert_equal({ state: "ON" }, q.iris_query)
300 end
301
302 def test_for_state_name_sql
303 q = TelSelections::ChooseTel::Q.for("ontario")
304 assert_equal(
305 [
306 "SELECT * FROM tel_inventory " \
307 "WHERE available_after < LOCALTIMESTAMP AND region = $1",
308 "ON"
309 ],
310 q.sql_query
311 )
312 end
313
314 def test_for_new_york
315 q = TelSelections::ChooseTel::Q.for("New York")
316 assert_equal({ state: "NY" }, q.iris_query)
317 end
318
319 def test_for_new_york_sql
320 q = TelSelections::ChooseTel::Q.for("New York")
321 assert_equal(
322 [
323 "SELECT * FROM tel_inventory " \
324 "WHERE available_after < LOCALTIMESTAMP AND region = $1",
325 "NY"
326 ],
327 q.sql_query
328 )
329 end
330
331 def test_for_new_york_ny
332 q = TelSelections::ChooseTel::Q.for(
333 "New York, NY",
334 db: FakeDB.new,
335 memcache: FakeMemcache.new
336 )
337 assert_equal({ city: "New York City", state: "NY" }, q.iris_query)
338 end
339
340 def test_for_new_york_ny_sql
341 q = TelSelections::ChooseTel::Q.for(
342 "New York, NY",
343 db: FakeDB.new,
344 memcache: FakeMemcache.new
345 )
346 assert_equal(
347 [
348 "SELECT * FROM tel_inventory " \
349 "WHERE available_after < LOCALTIMESTAMP " \
350 "AND region = $1 AND locality = $2",
351 "NY", "New York City"
352 ],
353 q.sql_query
354 )
355 end
356
357 def test_for_new_york_new_york
358 q = TelSelections::ChooseTel::Q.for(
359 "New York, New York",
360 db: FakeDB.new,
361 memcache: FakeMemcache.new
362 )
363 assert_equal({ city: "New York City", state: "NY" }, q.iris_query)
364 end
365
366 def test_for_new_york_new_york_sql
367 q = TelSelections::ChooseTel::Q.for(
368 "New York, New York",
369 db: FakeDB.new,
370 memcache: FakeMemcache.new
371 )
372 assert_equal(
373 [
374 "SELECT * FROM tel_inventory " \
375 "WHERE available_after < LOCALTIMESTAMP " \
376 "AND region = $1 AND locality = $2",
377 "NY", "New York City"
378 ],
379 q.sql_query
380 )
381 end
382
383 def test_for_citystate
384 q = TelSelections::ChooseTel::Q.for(
385 "Toronto, ON",
386 db: FakeDB.new,
387 memcache: FakeMemcache.new
388 )
389 assert_equal({ city: "Toronto", state: "ON" }, q.iris_query)
390 end
391
392 def test_for_citystate_sql
393 q = TelSelections::ChooseTel::Q.for(
394 "Toronto, ON",
395 db: FakeDB.new,
396 memcache: FakeMemcache.new
397 )
398 assert_equal(
399 [
400 "SELECT * FROM tel_inventory " \
401 "WHERE available_after < LOCALTIMESTAMP " \
402 "AND region = $1 AND locality = $2",
403 "ON", "Toronto"
404 ],
405 q.sql_query
406 )
407 end
408
409 def test_for_citystate_name
410 q = TelSelections::ChooseTel::Q.for(
411 "Toronto, Ontario",
412 db: FakeDB.new,
413 memcache: FakeMemcache.new
414 )
415 assert_equal({ city: "Toronto", state: "ON" }, q.iris_query)
416 end
417
418 def test_for_citystate_name_sql
419 q = TelSelections::ChooseTel::Q.for(
420 "Toronto, Ontario",
421 db: FakeDB.new,
422 memcache: FakeMemcache.new
423 )
424 assert_equal(
425 [
426 "SELECT * FROM tel_inventory " \
427 "WHERE available_after < LOCALTIMESTAMP " \
428 "AND region = $1 AND locality = $2",
429 "ON", "Toronto"
430 ],
431 q.sql_query
432 )
433 end
434
435 def test_for_garbage
436 assert_raises { TelSelections::ChooseTel::Q.for("garbage") }
437 end
438 end
439end