# frozen_string_literal: true
require "test_helper"
require "customer"
require "registration"
class RegistrationTest < Minitest::Test
def test_for_registered
sgx = OpenStruct.new(
registered?: OpenStruct.new(phone: "+15555550000")
)
iq = Blather::Stanza::Iq::Command.new
iq.from = "test@example.com"
result = execute_command(iq) do
Registration.for(
customer(sgx: sgx),
Minitest::Mock.new
)
end
assert_kind_of Registration::Registered, result
end
em :test_for_registered
def test_for_activated
web_manager = TelSelections.new(redis: FakeRedis.new)
web_manager.set("test@example.net", "+15555550000")
result = execute_command do
sgx = OpenStruct.new(registered?: false)
Registration.for(
customer(
plan_name: "test_usd",
expires_at: Time.now + 999,
sgx: sgx
),
web_manager
)
end
assert_kind_of Registration::Finish, result
end
em :test_for_activated
def test_for_not_activated_approved
sgx = OpenStruct.new(registered?: false)
web_manager = TelSelections.new(redis: FakeRedis.new)
web_manager.set("test\\40approved.example.com@component", "+15555550000")
iq = Blather::Stanza::Iq::Command.new
iq.from = "test@approved.example.com"
result = execute_command(iq) do
Registration.for(
customer(
sgx: sgx,
jid: Blather::JID.new("test\\40approved.example.com@component")
),
web_manager
)
end
assert_kind_of Registration::Activation::Allow, result
end
em :test_for_not_activated_approved
def test_for_not_activated_with_customer_id
sgx = OpenStruct.new(registered?: false)
web_manager = TelSelections.new(redis: FakeRedis.new)
web_manager.set("test@example.net", "+15555550000")
iq = Blather::Stanza::Iq::Command.new
iq.from = "test@example.com"
result = execute_command(iq) do
Registration.for(
customer(sgx: sgx),
web_manager
)
end
assert_kind_of Registration::Activation, result
end
em :test_for_not_activated_with_customer_id
class ActivationTest < Minitest::Test
Command::COMMAND_MANAGER = Minitest::Mock.new
def setup
@activation = Registration::Activation.new("test", "+15555550000")
end
def test_write
stub_request(
:get,
"https://dashboard.bandwidth.com/v1.0/tns/+15555550000"
).to_return(status: 201, body: <<~RESPONSE)
<TelephoneNumberResponse>
<TelephoneNumber>5555550000</TelephoneNumber>
</TelephoneNumberResponse>
RESPONSE
stub_request(
:get,
"https://dashboard.bandwidth.com/v1.0/tns/5555550000/ratecenter"
).to_return(status: 201, body: <<~RESPONSE)
<TelephoneNumberResponse>
<TelephoneNumberDetails>
<State>KE</State>
<RateCenter>FA</RateCenter>
</TelephoneNumberDetails>
</TelephoneNumberResponse>
RESPONSE
Command::COMMAND_MANAGER.expect(
:write,
EMPromise.reject(:test_result),
[Matching.new do |iq|
assert_equal :form, iq.form.type
assert_equal(
"You've selected +15555550000 (FA, KE) as your JMP number.",
iq.form.instructions.lines.first.chomp
)
end]
)
assert_equal(
:test_result,
execute_command { @activation.write.catch { |e| e } }
)
assert_mock Command::COMMAND_MANAGER
end
em :test_write
end
class AllowTest < Minitest::Test
Command::COMMAND_MANAGER = Minitest::Mock.new
Registration::Activation::Allow::DB = Minitest::Mock.new
def test_write_credit_to_nil
cust = Minitest::Mock.new(customer("test"))
allow = Registration::Activation::Allow.new(cust, "+15555550000", nil)
stub_request(
:get,
"https://dashboard.bandwidth.com/v1.0/tns/+15555550000"
).to_return(status: 201, body: <<~RESPONSE)
<TelephoneNumberResponse>
<TelephoneNumber>5555550000</TelephoneNumber>
</TelephoneNumberResponse>
RESPONSE
stub_request(
:get,
"https://dashboard.bandwidth.com/v1.0/tns/5555550000/ratecenter"
).to_return(status: 201, body: <<~RESPONSE)
<TelephoneNumberResponse>
<TelephoneNumberDetails>
<State>KE</State>
<RateCenter>FA</RateCenter>
</TelephoneNumberDetails>
</TelephoneNumberResponse>
RESPONSE
Command::COMMAND_MANAGER.expect(
:write,
EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
}),
[Matching.new do |iq|
assert_equal :form, iq.form.type
assert_equal(
"You've selected +15555550000 (FA, KE) as your JMP number.",
iq.form.instructions.lines.first.chomp
)
assert_equal 1, iq.form.fields.length
end]
)
Registration::Activation::Allow::DB.expect(
:transaction,
EMPromise.reject(:test_result)
) do |&blk|
blk.call
true
end
cust.expect(:with_plan, cust, ["test_usd"])
cust.expect(:activate_plan_starting_now, nil)
assert_equal(
:test_result,
execute_command { allow.write.catch { |e| e } }
)
assert_mock Command::COMMAND_MANAGER
end
em :test_write_credit_to_nil
def test_write_credit_to_refercust
cust = Minitest::Mock.new(customer("test"))
allow = Registration::Activation::Allow.new(
cust, "+15555550000", "refercust"
)
stub_request(
:get,
"https://dashboard.bandwidth.com/v1.0/tns/+15555550000"
).to_return(status: 201, body: <<~RESPONSE)
<TelephoneNumberResponse>
<TelephoneNumber>5555550000</TelephoneNumber>
</TelephoneNumberResponse>
RESPONSE
stub_request(
:get,
"https://dashboard.bandwidth.com/v1.0/tns/5555550000/ratecenter"
).to_return(status: 201, body: <<~RESPONSE)
<TelephoneNumberResponse>
<TelephoneNumberDetails>
<State>KE</State>
<RateCenter>FA</RateCenter>
</TelephoneNumberDetails>
</TelephoneNumberResponse>
RESPONSE
Command::COMMAND_MANAGER.expect(
:write,
EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
}),
[Matching.new do |iq|
assert_equal :form, iq.form.type
assert_equal(
"You've selected +15555550000 (FA, KE) as your JMP number.",
iq.form.instructions.lines.first.chomp
)
assert_equal 1, iq.form.fields.length
end]
)
Registration::Activation::Allow::DB.expect(
:transaction,
EMPromise.reject(:test_result)
) do |&blk|
blk.call
true
end
Registration::Activation::Allow::DB.expect(
:exec,
nil,
[String, ["refercust", "test"]]
)
cust.expect(:with_plan, cust, ["test_usd"])
cust.expect(:activate_plan_starting_now, nil)
assert_equal(
:test_result,
execute_command { allow.write.catch { |e| e } }
)
assert_mock Command::COMMAND_MANAGER
end
em :test_write_credit_to_refercust
end
class PaymentTest < Minitest::Test
CustomerFinancials::BRAINTREE = Minitest::Mock.new
def test_for_bitcoin
cust = Minitest::Mock.new(customer)
cust.expect(:with_plan, cust, ["test_usd"])
cust.expect(:save_plan!, nil)
iq = Blather::Stanza::Iq::Command.new
iq.form.fields = [
{ var: "activation_method", value: "bitcoin" },
{ var: "plan_name", value: "test_usd" }
]
result = Registration::Payment.for(iq, cust, "+15555550000")
assert_kind_of Registration::Payment::Bitcoin, result
assert_mock cust
end
def test_for_credit_card
cust = Minitest::Mock.new(customer)
cust.expect(:with_plan, cust, ["test_usd"])
cust.expect(:save_plan!, nil)
braintree_customer = Minitest::Mock.new
CustomerFinancials::BRAINTREE.expect(
:customer,
braintree_customer
)
braintree_customer.expect(
:find,
EMPromise.resolve(OpenStruct.new(payment_methods: [])),
["test"]
)
iq = Blather::Stanza::Iq::Command.new
iq.from = "test@example.com"
iq.form.fields = [
{ var: "activation_method", value: "credit_card" },
{ var: "plan_name", value: "test_usd" }
]
result = Registration::Payment.for(
iq,
cust,
"+15555550000"
).sync
assert_kind_of Registration::Payment::CreditCard, result
assert_mock cust
end
em :test_for_credit_card
def test_for_code
cust = Minitest::Mock.new(customer)
cust.expect(:with_plan, cust, ["test_usd"])
cust.expect(:save_plan!, nil)
iq = Blather::Stanza::Iq::Command.new
iq.form.fields = [
{ var: "activation_method", value: "code" },
{ var: "plan_name", value: "test_usd" }
]
result = Registration::Payment.for(
iq,
cust,
"+15555550000"
)
assert_kind_of Registration::Payment::InviteCode, result
assert_mock cust
end
class BitcoinTest < Minitest::Test
Registration::Payment::Bitcoin::BTC_SELL_PRICES = Minitest::Mock.new
CustomerFinancials::REDIS = Minitest::Mock.new
def setup
@customer = Minitest::Mock.new(
customer(plan_name: "test_usd")
)
@customer.expect(
:add_btc_address,
EMPromise.resolve("testaddr")
)
@bitcoin = Registration::Payment::Bitcoin.new(
@customer,
"+15555550000"
)
end
def test_write
CustomerFinancials::REDIS.expect(
:smembers,
EMPromise.resolve([]),
["jmp_customer_btc_addresses-test"]
)
reply_text = <<~NOTE
Activate your account by sending at least 1.000000 BTC to
testaddr
You will receive a notification when your payment is complete.
NOTE
blather = Minitest::Mock.new
blather.expect(
:<<,
nil,
[Matching.new do |reply|
assert_equal :canceled, reply.status
assert_equal :info, reply.note_type
assert_equal reply_text, reply.note.content
true
end]
)
Registration::Payment::Bitcoin::BTC_SELL_PRICES.expect(
:usd,
EMPromise.resolve(BigDecimal(1))
)
@bitcoin.stub(:save, EMPromise.resolve(nil)) do
execute_command(blather: blather) do
@bitcoin.write
end
end
assert_mock blather
end
em :test_write
end
class CreditCardTest < Minitest::Test
def setup
@credit_card = Registration::Payment::CreditCard.new(
customer,
"+15555550000"
)
end
def test_for
customer = Minitest::Mock.new(customer)
customer.expect(
:payment_methods,
EMPromise.resolve(OpenStruct.new(default_payment_method: :test))
)
assert_kind_of(
Registration::Payment::CreditCard::Activate,
Registration::Payment::CreditCard.for(
customer,
"+15555550000"
).sync
)
end
em :test_for
def test_write
result = execute_command do
Command::COMMAND_MANAGER.expect(
:write,
EMPromise.reject(:test_result),
[Matching.new do |reply|
assert_equal [:execute, :next], reply.allowed_actions
assert_equal(
"Add credit card, then return here to continue: " \
"http://creditcard.example.com",
reply.note.content
)
end]
)
@credit_card.write.catch { |e| e }
end
assert_equal :test_result, result
end
em :test_write
end
class ActivateTest < Minitest::Test
Registration::Payment::CreditCard::Activate::Finish =
Minitest::Mock.new
Registration::Payment::CreditCard::Activate::Transaction =
Minitest::Mock.new
Command::COMMAND_MANAGER = Minitest::Mock.new
def test_write
transaction = PromiseMock.new
transaction.expect(
:insert,
EMPromise.resolve(nil)
)
customer = Minitest::Mock.new(
customer(plan_name: "test_usd")
)
Registration::Payment::CreditCard::Activate::Transaction.expect(
:sale,
transaction
) do |acustomer, amount:, payment_method:|
assert_operator customer, :===, acustomer
assert_equal CONFIG[:activation_amount], amount
assert_equal :test_default_method, payment_method
end
customer.expect(:bill_plan, nil, [{ note: "Bill for first month" }])
Registration::Payment::CreditCard::Activate::Finish.expect(
:new,
OpenStruct.new(write: nil),
[customer, "+15555550000"]
)
execute_command do
Registration::Payment::CreditCard::Activate.new(
customer,
:test_default_method,
"+15555550000"
).write
end
Registration::Payment::CreditCard::Activate::Transaction.verify
transaction.verify
customer.verify
Registration::Payment::CreditCard::Activate::Finish.verify
end
em :test_write
def test_write_declines
customer = Minitest::Mock.new(
customer(plan_name: "test_usd")
)
iq = Blather::Stanza::Iq::Command.new
iq.from = "test@example.com"
msg = Registration::Payment::CreditCard::Activate::DECLINE_MESSAGE
Command::COMMAND_MANAGER.expect(
:write,
EMPromise.reject(:test_result),
[Matching.new do |reply|
assert_equal :error, reply.note_type
assert_equal(
"#{msg}: http://creditcard.example.com",
reply.note.content
)
end]
)
result = execute_command do
Registration::Payment::CreditCard::Activate::Transaction.expect(
:sale,
EMPromise.reject("declined")
) do |acustomer, amount:, payment_method:|
assert_operator customer, :===, acustomer
assert_equal CONFIG[:activation_amount], amount
assert_equal :test_default_method, payment_method
end
Registration::Payment::CreditCard::Activate.new(
customer,
:test_default_method,
"+15555550000"
).write.catch { |e| e }
end
assert_equal :test_result, result
Registration::Payment::CreditCard::Activate::Transaction.verify
end
em :test_write_declines
end
class InviteCodeTest < Minitest::Test
Registration::Payment::InviteCode::DB =
Minitest::Mock.new
Registration::Payment::InviteCode::REDIS =
Minitest::Mock.new
Command::COMMAND_MANAGER = Minitest::Mock.new
Registration::Payment::InviteCode::Finish =
Minitest::Mock.new
def test_write
customer = customer(plan_name: "test_usd")
Registration::Payment::InviteCode::DB.expect(:transaction, true, [])
Registration::Payment::InviteCode::Finish.expect(
:new,
OpenStruct.new(write: nil),
[
customer,
"+15555550000"
]
)
execute_command do
Registration::Payment::InviteCode::REDIS.expect(
:get,
EMPromise.resolve(nil),
["jmp_invite_tries-test"]
)
Command::COMMAND_MANAGER.expect(
:write,
EMPromise.resolve(
Blather::Stanza::Iq::Command.new.tap { |iq|
iq.form.fields = [{ var: "code", value: "abc" }]
}
),
[Matching.new do |reply|
assert_equal :form, reply.form.type
assert_nil reply.form.instructions
end]
)
Registration::Payment::InviteCode.new(
customer,
"+15555550000"
).write
end
assert_mock Command::COMMAND_MANAGER
assert_mock Registration::Payment::InviteCode::DB
assert_mock Registration::Payment::InviteCode::REDIS
assert_mock Registration::Payment::InviteCode::Finish
end
em :test_write
def test_write_bad_code
result = execute_command do
customer = customer(plan_name: "test_usd")
Registration::Payment::InviteCode::REDIS.expect(
:get,
EMPromise.resolve(0),
["jmp_invite_tries-test"]
)
Registration::Payment::InviteCode::DB.expect(:transaction, []) do
raise Registration::Payment::InviteCode::Invalid, "wut"
end
Registration::Payment::InviteCode::REDIS.expect(
:incr,
EMPromise.resolve(nil),
["jmp_invite_tries-test"]
)
Registration::Payment::InviteCode::REDIS.expect(
:expire,
EMPromise.resolve(nil),
["jmp_invite_tries-test", 60 * 60]
)
Command::COMMAND_MANAGER.expect(
:write,
EMPromise.resolve(
Blather::Stanza::Iq::Command.new.tap { |iq|
iq.form.fields = [{ var: "code", value: "abc" }]
}
),
[Matching.new do |reply|
assert_equal :form, reply.form.type
assert_nil reply.form.instructions
end]
)
Command::COMMAND_MANAGER.expect(
:write,
EMPromise.reject(:test_result),
[Matching.new do |reply|
assert_equal :form, reply.form.type
assert_equal "wut", reply.form.instructions
end]
)
Registration::Payment::InviteCode.new(
customer,
"+15555550000"
).write.catch { |e| e }
end
assert_equal :test_result, result
assert_mock Command::COMMAND_MANAGER
assert_mock Registration::Payment::InviteCode::DB
assert_mock Registration::Payment::InviteCode::REDIS
end
em :test_write_bad_code
def test_write_bad_code_over_limit
result = execute_command do
customer = customer(plan_name: "test_usd")
Registration::Payment::InviteCode::REDIS.expect(
:get,
EMPromise.resolve(11),
["jmp_invite_tries-test"]
)
Command::COMMAND_MANAGER.expect(
:write,
EMPromise.resolve(
Blather::Stanza::Iq::Command.new.tap { |iq|
iq.form.fields = [{ var: "code", value: "abc" }]
}
),
[Matching.new do |reply|
assert_equal :form, reply.form.type
assert_nil reply.form.instructions
end]
)
Registration::Payment::InviteCode::REDIS.expect(
:incr,
EMPromise.resolve(nil),
["jmp_invite_tries-test"]
)
Registration::Payment::InviteCode::REDIS.expect(
:expire,
EMPromise.resolve(nil),
["jmp_invite_tries-test", 60 * 60]
)
Command::COMMAND_MANAGER.expect(
:write,
EMPromise.reject(:test_result),
[Matching.new do |reply|
assert_equal :form, reply.form.type
assert_equal "Too many wrong attempts", reply.form.instructions
end]
)
Registration::Payment::InviteCode.new(
customer,
"+15555550000"
).write.catch { |e| e }
end
assert_equal :test_result, result
assert_mock Command::COMMAND_MANAGER
assert_mock Registration::Payment::InviteCode::REDIS
end
em :test_write_bad_code_over_limit
end
end
class FinishTest < Minitest::Test
Command::COMMAND_MANAGER = Minitest::Mock.new
Registration::Finish::TEL_SELECTIONS = FakeTelSelections.new
Registration::Finish::REDIS = Minitest::Mock.new
Bwmsgsv2Repo::REDIS = Minitest::Mock.new
def setup
@sgx = Minitest::Mock.new(TrivialBackendSgxRepo.new.get("test"))
iq = Blather::Stanza::Iq::Command.new
iq.from = "test\\40example.com@cheogram.com"
@finish = Registration::Finish.new(
customer(sgx: @sgx),
"+15555550000"
)
end
def test_write
create_order = stub_request(
:post,
"https://dashboard.bandwidth.com/v1.0/accounts//orders"
).to_return(status: 201, body: <<~RESPONSE)
<OrderResponse>
<Order>
<id>test_order</id>
</Order>
</OrderResponse>
RESPONSE
stub_request(
:get,
"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
).to_return(status: 201, body: <<~RESPONSE)
<OrderResponse>
<OrderStatus>COMPLETE</OrderStatus>
<CompletedNumbers>
<TelephoneNumber>
<FullNumber>5555550000</FullNumber>
</TelephoneNumber>
</CompletedNumbers>
</OrderResponse>
RESPONSE
stub_request(
:post,
"https://dashboard.bandwidth.com/v1.0/accounts//sites//sippeers//movetns"
)
Registration::Finish::REDIS.expect(
:del,
nil,
["pending_tel_for-test@example.net"]
)
Bwmsgsv2Repo::REDIS.expect(
:set,
nil,
[
"catapult_fwd-+15555550000",
"xmpp:test@example.net"
]
)
Bwmsgsv2Repo::REDIS.expect(
:set,
nil,
["catapult_fwd_timeout-customer_test@component", 25]
)
blather = Minitest::Mock.new
blather.expect(
:<<,
nil,
[Matching.new do |reply|
assert_equal :completed, reply.status
assert_equal :info, reply.note_type
assert_equal(
"Your JMP account has been activated as +15555550000",
reply.note.content
)
end]
)
execute_command(blather: blather) do
@sgx.expect(
:register!,
EMPromise.resolve(@sgx.with(registered?: IBR.new.tap do |ibr|
ibr.phone = "+15555550000"
end)),
["+15555550000"]
)
@finish.write
end
assert_requested create_order
assert_mock @sgx
assert_mock Registration::Finish::REDIS
assert_mock Bwmsgsv2Repo::REDIS
assert_mock blather
end
em :test_write
def test_write_tn_fail
create_order = stub_request(
:post,
"https://dashboard.bandwidth.com/v1.0/accounts//orders"
).to_return(status: 201, body: <<~RESPONSE)
<OrderResponse>
<Order>
<id>test_order</id>
</Order>
</OrderResponse>
RESPONSE
stub_request(
:get,
"https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
).to_return(status: 201, body: <<~RESPONSE)
<OrderResponse>
<OrderStatus>FAILED</OrderStatus>
</OrderResponse>
RESPONSE
result = execute_command do
Command::COMMAND_MANAGER.expect(
:write,
EMPromise.reject(:test_result),
[Matching.new do |iq|
assert_equal :form, iq.form.type
assert_equal(
"The JMP number +15555550000 is no longer available.",
iq.form.instructions
)
end]
)
@finish.write.catch { |e| e }
end
assert_equal :test_result, result
assert_mock Command::COMMAND_MANAGER
assert_instance_of(
TelSelections::ChooseTel,
Registration::Finish::TEL_SELECTIONS["test@example.com"]
)
assert_requested create_order
end
em :test_write_tn_fail
end
end