test_tel_selections.rb

  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