@@ 18,9 18,11 @@ class Transaction
def self.resolve_payment_method(customer, payment_method)
EMPromise.all([
+ ExpiringLock.new("jmp_customer_credit_card_lock-#{customer.customer_id}")
+ .with(els: -> { raise "Too many transactions today" }) { nil },
customer.declines,
payment_method || customer.payment_methods.then(&:default_payment_method)
- ]).then do |(declines, selected_method)|
+ ]).then do |(_, declines, selected_method)|
raise "Declined" if declines >= 2
raise "No valid payment method on file" unless selected_method
@@ 7,6 7,7 @@ require "transaction"
Transaction::DB = Minitest::Mock.new
Transaction::BRAINTREE = Minitest::Mock.new
Transaction::REDIS = Minitest::Mock.new
+ExpiringLock::REDIS = Minitest::Mock.new
class TransactionTest < Minitest::Test
FAKE_BRAINTREE_TRANSACTION =
@@ 18,6 19,11 @@ class TransactionTest < Minitest::Test
)
def test_sale_fails
+ ExpiringLock::REDIS.expect(
+ :set,
+ EMPromise.resolve("OK"),
+ ["jmp_customer_credit_card_lock-test", Time, "EX", 86400, "NX"]
+ )
CustomerFinancials::REDIS.expect(
:get,
EMPromise.resolve("1"),
@@ 50,10 56,16 @@ class TransactionTest < Minitest::Test
).sync
end
assert_mock CustomerFinancials::REDIS
+ assert_mock ExpiringLock::REDIS
end
em :test_sale_fails
def test_sale
+ ExpiringLock::REDIS.expect(
+ :set,
+ EMPromise.resolve("OK"),
+ ["jmp_customer_credit_card_lock-test", Time, "EX", 86400, "NX"]
+ )
CustomerFinancials::REDIS.expect(
:get,
EMPromise.resolve("1"),
@@ 83,6 95,7 @@ class TransactionTest < Minitest::Test
).sync
assert_kind_of Transaction, result
assert_mock CustomerFinancials::REDIS
+ assert_mock ExpiringLock::REDIS
end
em :test_sale