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 @local_tel = TelSelections::ChooseTel::Tn::LocalInventory.new(
172 @tn,
173 "test_account",
174 price: 10.0
175 )
176 end
177
178 def test_to_s
179 assert_equal "(555) 123-4567 (Toronto, ON)", @tn.to_s
180 end
181
182 def test_tel
183 assert_equal "+15551234567", @tn.tel
184 end
185
186 def test_option
187 assert_equal(
188 Blather::Stanza::X::Field::Option.new(
189 label: "(555) 123-4567 (Toronto, ON)",
190 value: "+15551234567"
191 ),
192 @tn.option
193 )
194 end
195
196 def test_option_positive_price
197 assert_equal(
198 Blather::Stanza::X::Field::Option.new(
199 label: "(555) 123-4567 (Toronto, ON) +$10.00",
200 value: "+15551234567"
201 ),
202 @local_tel.option
203 )
204 end
205
206 def test_option_reference
207 ref = @tn.option.find("ns:reference", ns: "urn:xmpp:reference:0").first
208 assert_equal(
209 @tn.formatted_tel,
210 @tn.option.label[ref["begin"].to_i..ref["end"].to_i]
211 )
212 assert_equal "tel:+15551234567", ref["uri"]
213 end
214 end
215
216 class QTest < Minitest::Test
217 def test_for_area_code
218 q = TelSelections::ChooseTel::Q.for("226")
219 assert_equal({ areaCode: "226" }, q.iris_query)
220 end
221
222 def test_for_area_code_sql
223 q = TelSelections::ChooseTel::Q.for("226")
224 assert_equal(
225 [
226 "SELECT * FROM tel_inventory " \
227 "WHERE available_after < LOCALTIMESTAMP AND tel LIKE $1",
228 "+1226%"
229 ],
230 q.sql_query
231 )
232 end
233
234 def test_for_npanxx
235 q = TelSelections::ChooseTel::Q.for("226666")
236 assert_equal({ npaNxx: "226666" }, q.iris_query)
237 end
238
239 def test_for_npanxx_sql
240 q = TelSelections::ChooseTel::Q.for("226666")
241 assert_equal(
242 [
243 "SELECT * FROM tel_inventory " \
244 "WHERE available_after < LOCALTIMESTAMP AND tel LIKE $1",
245 "+1226666%"
246 ],
247 q.sql_query
248 )
249 end
250
251 def test_for_npanxxx
252 q = TelSelections::ChooseTel::Q.for("2266667")
253 assert_equal({ npaNxxx: "2266667" }, q.iris_query)
254 end
255
256 def test_for_npanxxx_sql
257 q = TelSelections::ChooseTel::Q.for("2266667")
258 assert_equal(
259 [
260 "SELECT * FROM tel_inventory " \
261 "WHERE available_after < LOCALTIMESTAMP AND tel LIKE $1",
262 "+12266667%"
263 ],
264 q.sql_query
265 )
266 end
267
268 def test_for_zip
269 q = TelSelections::ChooseTel::Q.for("90210")
270 assert_equal({ zip: "90210" }, q.iris_query)
271 end
272
273 def test_for_zip_sql
274 q = TelSelections::ChooseTel::Q.for("90210")
275 refute q.sql_query
276 end
277
278 def test_for_localvanity
279 q = TelSelections::ChooseTel::Q.for("~mboa")
280 assert_equal({ localVanity: "mboa" }, q.iris_query)
281 end
282
283 def test_for_localvanity_sql
284 q = TelSelections::ChooseTel::Q.for("~mboa")
285 assert_equal(
286 [
287 "SELECT * FROM tel_inventory " \
288 "WHERE available_after < LOCALTIMESTAMP AND tel LIKE $1",
289 "%6262%"
290 ],
291 q.sql_query
292 )
293 end
294
295 def test_for_state
296 q = TelSelections::ChooseTel::Q.for("ON")
297 assert_equal({ state: "ON" }, q.iris_query)
298 end
299
300 def test_for_state_sql
301 q = TelSelections::ChooseTel::Q.for("ON")
302 assert_equal(
303 [
304 "SELECT * FROM tel_inventory " \
305 "WHERE available_after < LOCALTIMESTAMP AND region = $1",
306 "ON"
307 ],
308 q.sql_query
309 )
310 end
311
312 def test_for_state_name
313 q = TelSelections::ChooseTel::Q.for("ontario")
314 assert_equal({ state: "ON" }, q.iris_query)
315 end
316
317 def test_for_state_name_sql
318 q = TelSelections::ChooseTel::Q.for("ontario")
319 assert_equal(
320 [
321 "SELECT * FROM tel_inventory " \
322 "WHERE available_after < LOCALTIMESTAMP AND region = $1",
323 "ON"
324 ],
325 q.sql_query
326 )
327 end
328
329 def test_for_new_york
330 q = TelSelections::ChooseTel::Q.for("New York")
331 assert_equal({ state: "NY" }, q.iris_query)
332 end
333
334 def test_for_new_york_sql
335 q = TelSelections::ChooseTel::Q.for("New York")
336 assert_equal(
337 [
338 "SELECT * FROM tel_inventory " \
339 "WHERE available_after < LOCALTIMESTAMP AND region = $1",
340 "NY"
341 ],
342 q.sql_query
343 )
344 end
345
346 def test_for_new_york_ny
347 q = TelSelections::ChooseTel::Q.for(
348 "New York, NY",
349 db: FakeDB.new,
350 memcache: FakeMemcache.new
351 )
352 assert_equal({ city: "New York City", state: "NY" }, q.iris_query)
353 end
354
355 def test_for_new_york_ny_sql
356 q = TelSelections::ChooseTel::Q.for(
357 "New York, NY",
358 db: FakeDB.new,
359 memcache: FakeMemcache.new
360 )
361 assert_equal(
362 [
363 "SELECT * FROM tel_inventory " \
364 "WHERE available_after < LOCALTIMESTAMP " \
365 "AND region = $1 AND locality = $2",
366 "NY", "New York City"
367 ],
368 q.sql_query
369 )
370 end
371
372 def test_for_new_york_new_york
373 q = TelSelections::ChooseTel::Q.for(
374 "New York, New York",
375 db: FakeDB.new,
376 memcache: FakeMemcache.new
377 )
378 assert_equal({ city: "New York City", state: "NY" }, q.iris_query)
379 end
380
381 def test_for_new_york_new_york_sql
382 q = TelSelections::ChooseTel::Q.for(
383 "New York, New York",
384 db: FakeDB.new,
385 memcache: FakeMemcache.new
386 )
387 assert_equal(
388 [
389 "SELECT * FROM tel_inventory " \
390 "WHERE available_after < LOCALTIMESTAMP " \
391 "AND region = $1 AND locality = $2",
392 "NY", "New York City"
393 ],
394 q.sql_query
395 )
396 end
397
398 def test_for_citystate
399 q = TelSelections::ChooseTel::Q.for(
400 "Toronto, ON",
401 db: FakeDB.new,
402 memcache: FakeMemcache.new
403 )
404 assert_equal({ city: "Toronto", state: "ON" }, q.iris_query)
405 end
406
407 def test_for_citystate_sql
408 q = TelSelections::ChooseTel::Q.for(
409 "Toronto, ON",
410 db: FakeDB.new,
411 memcache: FakeMemcache.new
412 )
413 assert_equal(
414 [
415 "SELECT * FROM tel_inventory " \
416 "WHERE available_after < LOCALTIMESTAMP " \
417 "AND region = $1 AND locality = $2",
418 "ON", "Toronto"
419 ],
420 q.sql_query
421 )
422 end
423
424 def test_for_citystate_name
425 q = TelSelections::ChooseTel::Q.for(
426 "Toronto, Ontario",
427 db: FakeDB.new,
428 memcache: FakeMemcache.new
429 )
430 assert_equal({ city: "Toronto", state: "ON" }, q.iris_query)
431 end
432
433 def test_for_citystate_name_sql
434 q = TelSelections::ChooseTel::Q.for(
435 "Toronto, Ontario",
436 db: FakeDB.new,
437 memcache: FakeMemcache.new
438 )
439 assert_equal(
440 [
441 "SELECT * FROM tel_inventory " \
442 "WHERE available_after < LOCALTIMESTAMP " \
443 "AND region = $1 AND locality = $2",
444 "ON", "Toronto"
445 ],
446 q.sql_query
447 )
448 end
449
450 def test_for_garbage
451 assert_raises { TelSelections::ChooseTel::Q.for("garbage") }
452 end
453 end
454end