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