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					"+1226%"
232				],
233				q.sql_query
234			)
235		end
236
237		def test_for_npanxx
238			q = TelSelections::ChooseTel::Q.for("226666")
239			assert_equal({ npaNxx: "226666" }, q.iris_query)
240		end
241
242		def test_for_npanxx_sql
243			q = TelSelections::ChooseTel::Q.for("226666")
244			assert_equal(
245				[
246					"SELECT * FROM tel_inventory " \
247					"WHERE available_after < LOCALTIMESTAMP AND tel LIKE $1",
248					"+1226666%"
249				],
250				q.sql_query
251			)
252		end
253
254		def test_for_npanxxx
255			q = TelSelections::ChooseTel::Q.for("2266667")
256			assert_equal({ npaNxxx: "2266667" }, q.iris_query)
257		end
258
259		def test_for_npanxxx_sql
260			q = TelSelections::ChooseTel::Q.for("2266667")
261			assert_equal(
262				[
263					"SELECT * FROM tel_inventory " \
264					"WHERE available_after < LOCALTIMESTAMP AND tel LIKE $1",
265					"+12266667%"
266				],
267				q.sql_query
268			)
269		end
270
271		def test_for_zip
272			q = TelSelections::ChooseTel::Q.for("90210")
273			assert_equal({ zip: "90210" }, q.iris_query)
274		end
275
276		def test_for_zip_sql
277			q = TelSelections::ChooseTel::Q.for("90210")
278			refute q.sql_query
279		end
280
281		def test_for_localvanity
282			q = TelSelections::ChooseTel::Q.for("~mboa")
283			assert_equal({ localVanity: "mboa" }, q.iris_query)
284		end
285
286		def test_for_localvanity_sql
287			q = TelSelections::ChooseTel::Q.for("~mboa")
288			assert_equal(
289				[
290					"SELECT * FROM tel_inventory " \
291					"WHERE available_after < LOCALTIMESTAMP AND tel LIKE $1",
292					"%6262%"
293				],
294				q.sql_query
295			)
296		end
297
298		def test_for_state
299			q = TelSelections::ChooseTel::Q.for("ON")
300			assert_equal({ state: "ON" }, q.iris_query)
301		end
302
303		def test_for_state_sql
304			q = TelSelections::ChooseTel::Q.for("ON")
305			assert_equal(
306				[
307					"SELECT * FROM tel_inventory " \
308					"WHERE available_after < LOCALTIMESTAMP AND region = $1",
309					"ON"
310				],
311				q.sql_query
312			)
313		end
314
315		def test_for_state_name
316			q = TelSelections::ChooseTel::Q.for("ontario")
317			assert_equal({ state: "ON" }, q.iris_query)
318		end
319
320		def test_for_state_name_sql
321			q = TelSelections::ChooseTel::Q.for("ontario")
322			assert_equal(
323				[
324					"SELECT * FROM tel_inventory " \
325					"WHERE available_after < LOCALTIMESTAMP AND region = $1",
326					"ON"
327				],
328				q.sql_query
329			)
330		end
331
332		def test_for_new_york
333			q = TelSelections::ChooseTel::Q.for("New York")
334			assert_equal({ state: "NY" }, q.iris_query)
335		end
336
337		def test_for_new_york_sql
338			q = TelSelections::ChooseTel::Q.for("New York")
339			assert_equal(
340				[
341					"SELECT * FROM tel_inventory " \
342					"WHERE available_after < LOCALTIMESTAMP AND region = $1",
343					"NY"
344				],
345				q.sql_query
346			)
347		end
348
349		def test_for_new_york_ny
350			q = TelSelections::ChooseTel::Q.for(
351				"New York, NY",
352				db: FakeDB.new,
353				memcache: FakeMemcache.new
354			)
355			assert_equal({ city: "New York City", state: "NY" }, q.iris_query)
356		end
357
358		def test_for_new_york_ny_sql
359			q = TelSelections::ChooseTel::Q.for(
360				"New York, NY",
361				db: FakeDB.new,
362				memcache: FakeMemcache.new
363			)
364			assert_equal(
365				[
366					"SELECT * FROM tel_inventory " \
367					"WHERE available_after < LOCALTIMESTAMP " \
368					"AND region = $1 AND locality = $2",
369					"NY", "New York City"
370				],
371				q.sql_query
372			)
373		end
374
375		def test_for_new_york_new_york
376			q = TelSelections::ChooseTel::Q.for(
377				"New York, New York",
378				db: FakeDB.new,
379				memcache: FakeMemcache.new
380			)
381			assert_equal({ city: "New York City", state: "NY" }, q.iris_query)
382		end
383
384		def test_for_new_york_new_york_sql
385			q = TelSelections::ChooseTel::Q.for(
386				"New York, New York",
387				db: FakeDB.new,
388				memcache: FakeMemcache.new
389			)
390			assert_equal(
391				[
392					"SELECT * FROM tel_inventory " \
393					"WHERE available_after < LOCALTIMESTAMP " \
394					"AND region = $1 AND locality = $2",
395					"NY", "New York City"
396				],
397				q.sql_query
398			)
399		end
400
401		def test_for_citystate
402			q = TelSelections::ChooseTel::Q.for(
403				"Toronto, ON",
404				db: FakeDB.new,
405				memcache: FakeMemcache.new
406			)
407			assert_equal({ city: "Toronto", state: "ON" }, q.iris_query)
408		end
409
410		def test_for_citystate_sql
411			q = TelSelections::ChooseTel::Q.for(
412				"Toronto, ON",
413				db: FakeDB.new,
414				memcache: FakeMemcache.new
415			)
416			assert_equal(
417				[
418					"SELECT * FROM tel_inventory " \
419					"WHERE available_after < LOCALTIMESTAMP " \
420					"AND region = $1 AND locality = $2",
421					"ON", "Toronto"
422				],
423				q.sql_query
424			)
425		end
426
427		def test_for_citystate_name
428			q = TelSelections::ChooseTel::Q.for(
429				"Toronto, Ontario",
430				db: FakeDB.new,
431				memcache: FakeMemcache.new
432			)
433			assert_equal({ city: "Toronto", state: "ON" }, q.iris_query)
434		end
435
436		def test_for_citystate_name_sql
437			q = TelSelections::ChooseTel::Q.for(
438				"Toronto, Ontario",
439				db: FakeDB.new,
440				memcache: FakeMemcache.new
441			)
442			assert_equal(
443				[
444					"SELECT * FROM tel_inventory " \
445					"WHERE available_after < LOCALTIMESTAMP " \
446					"AND region = $1 AND locality = $2",
447					"ON", "Toronto"
448				],
449				q.sql_query
450			)
451		end
452
453		def test_for_garbage
454			assert_raises { TelSelections::ChooseTel::Q.for("garbage") }
455		end
456	end
457end