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