diff --git a/lib/customer.rb b/lib/customer.rb index af54dd0ce16ad9a1f084727dbadb99a4dec70e8b..f837ed7f4239b8a73aad26f35f8e07467addcc92 100644 --- a/lib/customer.rb +++ b/lib/customer.rb @@ -25,7 +25,7 @@ class Customer def_delegators :@plan, :active?, :activate_plan_starting_now, :bill_plan, :currency, :merchant_account, :plan_name, :minute_limit, :message_limit, :auto_top_up_amount, :monthly_overage_limit, - :monthly_price + :monthly_price, :save_plan! def_delegators :@sgx, :register!, :registered?, :set_ogm_url, :fwd, :transcription_enabled def_delegators :@usage, :usage_report, :message_usage, :incr_message_usage diff --git a/lib/customer_plan.rb b/lib/customer_plan.rb index 86fd8e2a1cdd04abbb793c94b423c666a53d1bfd..2dbaf0cbda3418e5286791c3addbd48d3cbf373e 100644 --- a/lib/customer_plan.rb +++ b/lib/customer_plan.rb @@ -44,6 +44,21 @@ class CustomerPlan ) end + def save_plan! + DB.exec_defer(<<~SQL, [@customer_id, plan_name]) + INSERT INTO plan_log + (customer_id, plan_name, date_range) + VALUES ( + $1, + $2, + tsrange( + LOCALTIMESTAMP - '2 seconds'::interval, + LOCALTIMESTAMP - '1 second'::interval + ) + ) + SQL + end + def bill_plan EM.promise_fiber do DB.transaction do @@ -54,12 +69,17 @@ class CustomerPlan end def activate_plan_starting_now - DB.exec(<<~SQL, [@customer_id, plan_name]).cmd_tuples.positive? - INSERT INTO plan_log - (customer_id, plan_name, date_range) + activated = DB.exec(<<~SQL, [@customer_id, plan_name]).cmd_tuples.positive? + INSERT INTO plan_log (customer_id, plan_name, date_range) VALUES ($1, $2, tsrange(LOCALTIMESTAMP, LOCALTIMESTAMP + '1 month')) ON CONFLICT DO NOTHING SQL + return false unless activated + + DB.exec(<<~SQL, [@customer_id]) + DELETE FROM plan_log WHERE customer_id=$1 AND date_range << '[now,now]' + AND upper(date_range) - lower(date_range) < '2 seconds' + SQL end def activation_date diff --git a/lib/registration.rb b/lib/registration.rb index 56044a869fc0e033281fc53ce3f54fd4302389ed..e3416d44d029deb61137c3a3836a9dc09ed6ba3c 100644 --- a/lib/registration.rb +++ b/lib/registration.rb @@ -136,9 +136,11 @@ class Registration def self.for(iq, customer, tel, final_message: nil, finish: Finish) plan_name = iq.form.field("plan_name").value.to_s customer = customer.with_plan(plan_name) - kinds.fetch(iq.form.field("activation_method")&.value&.to_s&.to_sym) { - raise "Invalid activation method" - }.call(customer, tel, final_message: final_message, finish: finish) + customer.save_plan!.then do + kinds.fetch(iq.form.field("activation_method")&.value&.to_s&.to_sym) { + raise "Invalid activation method" + }.call(customer, tel, final_message: final_message, finish: finish) + end end class Bitcoin @@ -156,14 +158,7 @@ class Registration attr_reader :customer_id, :tel def save - EMPromise.all([ - REDIS.setex("pending_tel_for-#{@customer.jid}", THIRTY_DAYS, tel), - REDIS.setex( - "pending_plan_for-#{customer_id}", - THIRTY_DAYS, - @customer.plan_name - ) - ]) + REDIS.setex("pending_tel_for-#{@customer.jid}", THIRTY_DAYS, tel) end def note_text(amount, addr) diff --git a/test/test_customer.rb b/test/test_customer.rb index 360cf4876336e45130d676f7244c4fa993de70a5..43442dda07fdc64696bd2fd386e6cf9c58650a03 100644 --- a/test/test_customer.rb +++ b/test/test_customer.rb @@ -38,6 +38,11 @@ class CustomerTest < Minitest::Test OpenStruct.new(cmd_tuples: 1), [String, ["test", "test_usd"]] ) + CustomerPlan::DB.expect( + :exec, + OpenStruct.new(cmd_tuples: 0), + [String, ["test"]] + ) customer(plan_name: "test_usd").bill_plan.sync CustomerPlan::DB.verify end diff --git a/test/test_registration.rb b/test/test_registration.rb index 08b18fc0f5f30f3517d6149c381ea9698b30bcd6..a6b8cc6572bc4c0fd98bd4f79c9b21140e2a2f25 100644 --- a/test/test_registration.rb +++ b/test/test_registration.rb @@ -245,10 +245,8 @@ class RegistrationTest < Minitest::Test def test_for_bitcoin cust = Minitest::Mock.new(customer) - cust.expect( - :add_btc_address, - EMPromise.resolve("testaddr") - ) + 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" }, @@ -256,9 +254,13 @@ class RegistrationTest < Minitest::Test ] 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, @@ -277,14 +279,18 @@ class RegistrationTest < Minitest::Test ] result = Registration::Payment.for( iq, - customer, + 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" }, @@ -292,10 +298,11 @@ class RegistrationTest < Minitest::Test ] result = Registration::Payment.for( iq, - customer, + cust, "+15555550000" ) assert_kind_of Registration::Payment::InviteCode, result + assert_mock cust end class BitcoinTest < Minitest::Test