@@ -46,9 +46,11 @@ class TelSelections
@redis.del("pending_tel_for-#{jid}")
end
- def [](jid)
- @redis.get("pending_tel_for-#{jid}").then do |tel|
- tel ? HaveTel.new(tel) : ChooseTel.new(db: @db, memcache: @memcache)
+ def [](customer)
+ @redis.get("pending_tel_for-#{customer.jid}").then do |tel|
+ next HaveTel.new(tel) if tel
+
+ ChooseTel.new(customer, redis: @redis, db: @db, memcache: @memcache)
end
end
@@ -65,8 +67,10 @@ class TelSelections
class ChooseTel
class Fail < RuntimeError; end
- def initialize(db: DB, memcache: MEMCACHE)
+ def initialize(customer, redis: REDIS, db: DB, memcache: MEMCACHE)
+ @customer = customer
@db = db
+ @redis = redis
@memcache = memcache
end
@@ -92,12 +96,15 @@ class TelSelections
end
def choose_tel(iq)
- available = AvailableNumber.for(iq.form, db: @db, memcache: @memcache)
- return available if available.is_a?(Tn::Bandwidth)
-
- choose_from_list(available.tns)
- rescue Fail
- choose_tel_or_data(error: $!.to_s)
+ AvailableNumber.for(
+ iq.form, customer: customer, redis: @redis, db: @db, memcache: @memcache
+ ).then { |avail|
+ next avail if avail.is_a?(Tn::Bandwidth)
+
+ choose_from_list(avail.tns)
+ }.catch_only(Fail) do
+ choose_tel_or_data(error: $!.to_s)
+ end
end
def choose_from_list(tns)
@@ -119,19 +126,18 @@ class TelSelections
end
class AvailableNumber
- def self.for(form, db: DB, memcache: MEMCACHE)
+ def self.for(form, **kwargs)
qs = form.field("q")&.value.to_s.strip
return Tn.for_pending_value(qs) if qs =~ /\A\+1\d{10}\Z/
- quantity = Quantity.for(form)
- q = Q.for(feelinglucky(qs, form), db: db, memcache: memcache)
-
- new(
- q.iris_query
- .merge(enableTNDetail: true, LCA: false),
- q.sql_query, quantity,
- fallback: q.fallback, memcache: memcache, db: db
- )
+ Q.for(feelinglucky(qs, form), **kwargs).then do |q|
+ new(
+ q.iris_query
+ .merge(enableTNDetail: true, LCA: false),
+ q.sql_query, Quantity.for(form),
+ fallback: q.fallback, **kwargs
+ )
+ end
end
ACTION_FIELD = "http://jabber.org/protocol/commands#actions"
@@ -145,9 +151,9 @@ class TelSelections
def initialize(
iris_query, sql_query, quantity,
- fallback: [], memcache: MEMCACHE, db: DB
+ fallback: [], memcache: MEMCACHE, db: DB, **
)
- @iris_query = iris_query.merge(quantity.iris_query)
+ @iris_query = iris_query&.merge(quantity.iris_query)
@sql_query = sql_query
@quantity = quantity
@fallback = fallback
@@ -166,6 +172,8 @@ class TelSelections
end
def fetch_bandwidth_inventory
+ return [] unless @iris_query
+
BandwidthIris::AvailableNumber
.list(@iris_query)
.map { |tn| Tn::Bandwidth.new(Tn::Option.new(**tn)) }
@@ -402,12 +410,15 @@ class TelSelections
def self.for(q, **kwa)
q = replace_region_names(q) unless q.start_with?("~")
- @queries.each do |(regex, block)|
+ EMPromise.all(@queries.map { |(regex, block)|
match_data = (q =~ regex)
- return block.call($1 || $&, *$~.to_a[2..-1], **kwa) if match_data
- end
+ block.call($1 || $&, *$~.to_a[2..-1], **kwa) if match_data
+ }).then do |qs|
+ qs = qs.compact
+ raise Fail, "Format not recognized: #{q}" if qs.empty?
- raise Fail, "Format not recognized: #{q}"
+ qs.first
+ end
end
def self.replace_region_names(query)
@@ -547,7 +558,7 @@ class TelSelections
"west durham" => "Durham"
}.freeze
- def initialize(city, state, db: DB, memcache: MEMCACHE)
+ def initialize(city, state, db: DB, memcache: MEMCACHE, **)
@city = CITY_MAP.fetch(city.downcase, city)
@state = State.new(state)
@db = db
@@ -13,12 +13,13 @@ class TelSelectionsTest < Minitest::Test
end
def test_set_get
- assert_kind_of TelSelections::ChooseTel, @manager["jid@example.com"].sync
+ cust = OpenStruct.new(jid: "jid@example.com")
+ assert_kind_of TelSelections::ChooseTel, @manager[cust].sync
@manager.set(
"jid@example.com",
TelSelections::ChooseTel::Tn.for_pending_value("+15555550000")
).sync
- assert_kind_of TelSelections::HaveTel, @manager["jid@example.com"].sync
+ assert_kind_of TelSelections::HaveTel, @manager[cust].sync
end
em :test_set_get
@@ -30,7 +31,7 @@ class TelSelectionsTest < Minitest::Test
).sync
assert_equal(
"+15555550000",
- @manager[jid].then(&:choose_tel_or_data).sync.tel
+ @manager[OpenStruct.new(jid: jid)].then(&:choose_tel_or_data).sync.tel
)
end
em :test_choose_tel_have_tel
@@ -40,13 +41,16 @@ class TelSelectionsTest < Minitest::Test
form = Blather::Stanza::X.new
form.fields = [{ var: "q", value: "226" }]
iris_query = TelSelections::ChooseTel::AvailableNumber
- .for(form, db: FakeDB.new, memcache: FakeMemcache.new)
- .instance_variable_get(:@iris_query)
+ .for(
+ form,
+ redis: FakeRedis.new, db: FakeDB.new, memcache: FakeMemcache.new
+ ).sync.instance_variable_get(:@iris_query)
assert_equal(
{ areaCode: "226", enableTNDetail: true, LCA: false, quantity: 10 },
iris_query
)
end
+ em :test_for_no_rsm
def test_for_rsm
form = Blather::Stanza::X.new
@@ -57,14 +61,17 @@ class TelSelectionsTest < Minitest::Test
end
end
iris_query = TelSelections::ChooseTel::AvailableNumber
- .for(form, db: FakeDB.new, memcache: FakeMemcache.new)
- .instance_variable_get(:@iris_query)
+ .for(
+ form,
+ redis: FakeRedis.new, db: FakeDB.new, memcache: FakeMemcache.new
+ ).sync.instance_variable_get(:@iris_query)
# quantity should be 500 due to max inside tel selections
assert_equal(
{ areaCode: "226", enableTNDetail: true, LCA: false, quantity: 500 },
iris_query
)
end
+ em :test_for_rsm
def test_for_feelinglucky
form = Blather::Stanza::X.new
@@ -76,13 +83,16 @@ class TelSelectionsTest < Minitest::Test
}
]
iris_query = TelSelections::ChooseTel::AvailableNumber
- .for(form, db: FakeDB.new, memcache: FakeMemcache.new)
- .instance_variable_get(:@iris_query)
+ .for(
+ form,
+ redis: FakeRedis.new, db: FakeDB.new, memcache: FakeMemcache.new
+ ).sync.instance_variable_get(:@iris_query)
assert_equal(
{ areaCode: "810", enableTNDetail: true, LCA: false, quantity: 10 },
iris_query
)
end
+ em :test_for_feelinglucky
def test_fallback
stub_request(
@@ -123,8 +133,10 @@ class TelSelectionsTest < Minitest::Test
form.fields = [{ var: "q", value: "Kitchener, ON" }]
tns = execute_command do
TelSelections::ChooseTel::AvailableNumber
- .for(form, db: db, memcache: FakeMemcache.new)
- .tns
+ .for(
+ form,
+ redis: FakeRedis.new, db: db, memcache: FakeMemcache.new
+ ).sync.tns
end
assert_equal(
["(226) 555-12345 (Somewhere, ON)"],
@@ -152,8 +164,10 @@ class TelSelectionsTest < Minitest::Test
form.fields = [{ var: "q", value: "Kitchener, ON" }]
tns = execute_command do
TelSelections::ChooseTel::AvailableNumber
- .for(form, db: db, memcache: FakeMemcache.new)
- .tns
+ .for(
+ form,
+ redis: FakeRedis.new, db: db, memcache: FakeMemcache.new
+ ).sync.tns
end
assert_equal(
["(226) 555-12345 (Kitchener-Waterloo, ON)"],
@@ -218,12 +232,13 @@ class TelSelectionsTest < Minitest::Test
class QTest < Minitest::Test
def test_for_area_code
- q = TelSelections::ChooseTel::Q.for("226")
+ q = TelSelections::ChooseTel::Q.for("226").sync
assert_equal({ areaCode: "226" }, q.iris_query)
end
+ em :test_for_area_code
def test_for_area_code_sql
- q = TelSelections::ChooseTel::Q.for("226")
+ q = TelSelections::ChooseTel::Q.for("226").sync
assert_equal(
[
"SELECT * FROM tel_inventory " \
@@ -234,14 +249,16 @@ class TelSelectionsTest < Minitest::Test
q.sql_query
)
end
+ em :test_for_area_code_sql
def test_for_npanxx
- q = TelSelections::ChooseTel::Q.for("226666")
+ q = TelSelections::ChooseTel::Q.for("226666").sync
assert_equal({ npaNxx: "226666" }, q.iris_query)
end
+ em :test_for_npanxx
def test_for_npanxx_sql
- q = TelSelections::ChooseTel::Q.for("226666")
+ q = TelSelections::ChooseTel::Q.for("226666").sync
assert_equal(
[
"SELECT * FROM tel_inventory " \
@@ -252,14 +269,16 @@ class TelSelectionsTest < Minitest::Test
q.sql_query
)
end
+ em :test_for_npanxx_sql
def test_for_npanxxx
- q = TelSelections::ChooseTel::Q.for("2266667")
+ q = TelSelections::ChooseTel::Q.for("2266667").sync
assert_equal({ npaNxxx: "2266667" }, q.iris_query)
end
+ em :test_for_npanxxx
def test_for_npanxxx_sql
- q = TelSelections::ChooseTel::Q.for("2266667")
+ q = TelSelections::ChooseTel::Q.for("2266667").sync
assert_equal(
[
"SELECT * FROM tel_inventory " \
@@ -270,24 +289,28 @@ class TelSelectionsTest < Minitest::Test
q.sql_query
)
end
+ em :test_for_npanxxx_sql
def test_for_zip
- q = TelSelections::ChooseTel::Q.for("90210")
+ q = TelSelections::ChooseTel::Q.for("90210").sync
assert_equal({ zip: "90210" }, q.iris_query)
end
+ em :test_for_zip
def test_for_zip_sql
- q = TelSelections::ChooseTel::Q.for("90210")
+ q = TelSelections::ChooseTel::Q.for("90210").sync
refute q.sql_query
end
+ em :test_for_zip_sql
def test_for_localvanity
- q = TelSelections::ChooseTel::Q.for("~mboa")
+ q = TelSelections::ChooseTel::Q.for("~mboa").sync
assert_equal({ localVanity: "mboa" }, q.iris_query)
end
+ em :test_for_localvanity
def test_for_localvanity_sql
- q = TelSelections::ChooseTel::Q.for("~mboa")
+ q = TelSelections::ChooseTel::Q.for("~mboa").sync
assert_equal(
[
"SELECT * FROM tel_inventory " \
@@ -298,14 +321,16 @@ class TelSelectionsTest < Minitest::Test
q.sql_query
)
end
+ em :test_for_localvanity_sql
def test_for_state
- q = TelSelections::ChooseTel::Q.for("ON")
+ q = TelSelections::ChooseTel::Q.for("ON").sync
assert_equal({ state: "ON" }, q.iris_query)
end
+ em :test_for_state
def test_for_state_sql
- q = TelSelections::ChooseTel::Q.for("ON")
+ q = TelSelections::ChooseTel::Q.for("ON").sync
assert_equal(
[
"SELECT * FROM tel_inventory " \
@@ -316,14 +341,16 @@ class TelSelectionsTest < Minitest::Test
q.sql_query
)
end
+ em :test_for_state_sql
def test_for_state_name
- q = TelSelections::ChooseTel::Q.for("ontario")
+ q = TelSelections::ChooseTel::Q.for("ontario").sync
assert_equal({ state: "ON" }, q.iris_query)
end
+ em :test_for_state_name
def test_for_state_name_sql
- q = TelSelections::ChooseTel::Q.for("ontario")
+ q = TelSelections::ChooseTel::Q.for("ontario").sync
assert_equal(
[
"SELECT * FROM tel_inventory " \
@@ -334,14 +361,16 @@ class TelSelectionsTest < Minitest::Test
q.sql_query
)
end
+ em :test_for_state_name_sql
def test_for_new_york
- q = TelSelections::ChooseTel::Q.for("New York")
+ q = TelSelections::ChooseTel::Q.for("New York").sync
assert_equal({ state: "NY" }, q.iris_query)
end
+ em :test_for_new_york
def test_for_new_york_sql
- q = TelSelections::ChooseTel::Q.for("New York")
+ q = TelSelections::ChooseTel::Q.for("New York").sync
assert_equal(
[
"SELECT * FROM tel_inventory " \
@@ -352,22 +381,24 @@ class TelSelectionsTest < Minitest::Test
q.sql_query
)
end
+ em :test_for_new_york_sql
def test_for_new_york_ny
q = TelSelections::ChooseTel::Q.for(
"New York, NY",
- db: FakeDB.new,
+ redis: FakeRedis.new, db: FakeDB.new,
memcache: FakeMemcache.new
- )
+ ).sync
assert_equal({ city: "New York City", state: "NY" }, q.iris_query)
end
+ em :test_for_new_york_ny
def test_for_new_york_ny_sql
q = TelSelections::ChooseTel::Q.for(
"New York, NY",
- db: FakeDB.new,
+ redis: FakeRedis.new, db: FakeDB.new,
memcache: FakeMemcache.new
- )
+ ).sync
assert_equal(
[
"SELECT * FROM tel_inventory " \
@@ -379,22 +410,24 @@ class TelSelectionsTest < Minitest::Test
q.sql_query
)
end
+ em :test_for_new_york_ny_sql
def test_for_new_york_new_york
q = TelSelections::ChooseTel::Q.for(
"New York, New York",
- db: FakeDB.new,
+ redis: FakeRedis.new, db: FakeDB.new,
memcache: FakeMemcache.new
- )
+ ).sync
assert_equal({ city: "New York City", state: "NY" }, q.iris_query)
end
+ em :test_for_new_york_new_york
def test_for_new_york_new_york_sql
q = TelSelections::ChooseTel::Q.for(
"New York, New York",
- db: FakeDB.new,
+ redis: FakeRedis.new, db: FakeDB.new,
memcache: FakeMemcache.new
- )
+ ).sync
assert_equal(
[
"SELECT * FROM tel_inventory " \
@@ -406,22 +439,24 @@ class TelSelectionsTest < Minitest::Test
q.sql_query
)
end
+ em :test_for_new_york_new_york_sql
def test_for_citystate
q = TelSelections::ChooseTel::Q.for(
"Toronto, ON",
- db: FakeDB.new,
+ redis: FakeRedis.new, db: FakeDB.new,
memcache: FakeMemcache.new
- )
+ ).sync
assert_equal({ city: "Toronto", state: "ON" }, q.iris_query)
end
+ em :test_for_citystate
def test_for_citystate_sql
q = TelSelections::ChooseTel::Q.for(
"Toronto, ON",
- db: FakeDB.new,
+ redis: FakeRedis.new, db: FakeDB.new,
memcache: FakeMemcache.new
- )
+ ).sync
assert_equal(
[
"SELECT * FROM tel_inventory " \
@@ -433,22 +468,24 @@ class TelSelectionsTest < Minitest::Test
q.sql_query
)
end
+ em :test_for_citystate_sql
def test_for_citystate_name
q = TelSelections::ChooseTel::Q.for(
"Toronto, Ontario",
- db: FakeDB.new,
+ redis: FakeRedis.new, db: FakeDB.new,
memcache: FakeMemcache.new
- )
+ ).sync
assert_equal({ city: "Toronto", state: "ON" }, q.iris_query)
end
+ em :test_for_citystate_name
def test_for_citystate_name_sql
q = TelSelections::ChooseTel::Q.for(
"Toronto, Ontario",
- db: FakeDB.new,
+ redis: FakeRedis.new, db: FakeDB.new,
memcache: FakeMemcache.new
- )
+ ).sync
assert_equal(
[
"SELECT * FROM tel_inventory " \
@@ -460,9 +497,11 @@ class TelSelectionsTest < Minitest::Test
q.sql_query
)
end
+ em :test_for_citystate_name_sql
def test_for_garbage
- assert_raises { TelSelections::ChooseTel::Q.for("garbage") }
+ assert_raises { TelSelections::ChooseTel::Q.for("garbage").sync }
end
+ em :test_for_garbage
end
end