test_low_balance.rb

  1# frozen_string_literal: true
  2
  3require "test_helper"
  4require "low_balance"
  5
  6ExpiringLock::REDIS = Minitest::Mock.new
  7CustomerPlan::REDIS = Minitest::Mock.new
  8CustomerFinancials::REDIS = Minitest::Mock.new
  9LowBalance::AutoTopUp::REDIS = Minitest::Mock.new
 10
 11class LowBalanceTest < Minitest::Test
 12	def test_for_locked
 13		ExpiringLock::REDIS.expect(
 14			:set,
 15			EMPromise.resolve(nil),
 16			["jmp_customer_low_balance-test", Time, "EX", 604800, "NX"]
 17		)
 18		assert_kind_of LowBalance::Locked, LowBalance.for(customer).sync
 19	end
 20	em :test_for_locked
 21
 22	def test_for_no_auto_top_up
 23		ExpiringLock::REDIS.expect(
 24			:set,
 25			EMPromise.resolve("OK"),
 26			["jmp_customer_low_balance-test", Time, "EX", 604800, "NX"]
 27		)
 28		CustomerFinancials::REDIS.expect(
 29			:smembers,
 30			EMPromise.resolve([]),
 31			["jmp_customer_btc_addresses-test"]
 32		)
 33		assert_kind_of(
 34			LowBalance,
 35			LowBalance.for(customer).sync
 36		)
 37		assert_mock ExpiringLock::REDIS
 38	end
 39	em :test_for_no_auto_top_up
 40
 41	def test_for_auto_top_up_on_transaction_amount
 42		ExpiringLock::REDIS.expect(
 43			:set,
 44			EMPromise.resolve("OK"),
 45			["jmp_customer_low_balance-test", Time, "EX", 604800, "NX"]
 46		)
 47		CustomerFinancials::REDIS.expect(
 48			:smembers,
 49			EMPromise.resolve([]),
 50			["block_credit_cards"]
 51		)
 52		LowBalance::AutoTopUp::REDIS.expect(
 53			:exists,
 54			0,
 55			["jmp_auto_top_up_block-abcd"]
 56		)
 57		braintree_customer = Minitest::Mock.new
 58		CustomerFinancials::BRAINTREE.expect(:customer, braintree_customer)
 59		payment_methods = OpenStruct.new(payment_methods: [
 60			OpenStruct.new(default?: true, unique_number_identifier: "abcd")
 61		])
 62		braintree_customer.expect(
 63			:find,
 64			EMPromise.resolve(payment_methods),
 65			["test"]
 66		)
 67		assert_kind_of(
 68			LowBalance::AutoTopUp,
 69			LowBalance.for(customer(auto_top_up_amount: 1), 15).sync
 70		)
 71		assert_mock ExpiringLock::REDIS
 72		assert_mock CustomerFinancials::REDIS
 73		assert_mock CustomerFinancials::BRAINTREE
 74		assert_mock braintree_customer
 75	end
 76	em :test_for_auto_top_up_on_transaction_amount
 77
 78	def test_for_auto_top_up
 79		ExpiringLock::REDIS.expect(
 80			:set,
 81			EMPromise.resolve("OK"),
 82			["jmp_customer_low_balance-test", Time, "EX", 604800, "NX"]
 83		)
 84		CustomerFinancials::REDIS.expect(
 85			:smembers,
 86			EMPromise.resolve([]),
 87			["block_credit_cards"]
 88		)
 89		LowBalance::AutoTopUp::REDIS.expect(
 90			:exists,
 91			0,
 92			["jmp_auto_top_up_block-abcd"]
 93		)
 94		braintree_customer = Minitest::Mock.new
 95		CustomerFinancials::BRAINTREE.expect(:customer, braintree_customer)
 96		payment_methods = OpenStruct.new(payment_methods: [
 97			OpenStruct.new(default?: true, unique_number_identifier: "abcd")
 98		])
 99		braintree_customer.expect(
100			:find,
101			EMPromise.resolve(payment_methods),
102			["test"]
103		)
104		assert_kind_of(
105			LowBalance::AutoTopUp,
106			LowBalance.for(customer(auto_top_up_amount: 15)).sync
107		)
108		assert_mock ExpiringLock::REDIS
109		assert_mock CustomerFinancials::REDIS
110		assert_mock CustomerFinancials::BRAINTREE
111		assert_mock braintree_customer
112	end
113	em :test_for_auto_top_up
114
115	def test_for_auto_top_up_blocked
116		ExpiringLock::REDIS.expect(
117			:set,
118			EMPromise.resolve("OK"),
119			["jmp_customer_low_balance-test", Time, "EX", 604800, "NX"]
120		)
121		CustomerFinancials::REDIS.expect(
122			:smembers,
123			EMPromise.resolve([]),
124			["block_credit_cards"]
125		)
126		CustomerFinancials::REDIS.expect(
127			:smembers,
128			EMPromise.resolve([]),
129			["jmp_customer_btc_addresses-test"]
130		)
131		LowBalance::AutoTopUp::REDIS.expect(
132			:exists,
133			1,
134			["jmp_auto_top_up_block-blocked"]
135		)
136		braintree_customer = Minitest::Mock.new
137		CustomerFinancials::BRAINTREE.expect(:customer, braintree_customer)
138		payment_methods = OpenStruct.new(payment_methods: [
139			OpenStruct.new(default?: true, unique_number_identifier: "blocked")
140		])
141		braintree_customer.expect(
142			:find,
143			EMPromise.resolve(payment_methods),
144			["test"]
145		)
146		assert_kind_of(
147			LowBalance,
148			LowBalance.for(customer(auto_top_up_amount: 15)).sync
149		)
150		assert_mock ExpiringLock::REDIS
151		assert_mock CustomerFinancials::REDIS
152		assert_mock CustomerFinancials::BRAINTREE
153		assert_mock braintree_customer
154	end
155	em :test_for_auto_top_up_blocked
156
157	class AutoTopUpTest < Minitest::Test
158		LowBalance::AutoTopUp::CreditCardSale = Minitest::Mock.new
159
160		def setup
161			@customer = Minitest::Mock.new(customer(auto_top_up_amount: 100))
162			@auto_top_up = LowBalance::AutoTopUp.new(@customer)
163		end
164
165		def test_notify!
166			tx = OpenStruct.new(total: 13)
167			LowBalance::AutoTopUp::CreditCardSale.expect(
168				:create,
169				EMPromise.resolve(tx),
170				[@customer], amount: 100
171			)
172			@auto_top_up.notify!
173		end
174		em :test_notify!
175
176		def test_top_up_amount_when_target_greater_than_expected_balance
177			customer = Minitest::Mock.new(customer(
178				balance: 10,
179				auto_top_up_amount: 15
180			))
181			auto_top_up = LowBalance::AutoTopUp.new(customer, nil, 30, margin: 5)
182
183			assert_equal 25, auto_top_up.top_up_amount
184		end
185		em :test_top_up_amount_when_target_greater_than_expected_balance
186
187		def test_top_up_amount_when_target_less_than_expected_balance
188			customer = Minitest::Mock.new(customer(
189				balance: 10,
190				auto_top_up_amount: 15
191			))
192			auto_top_up = LowBalance::AutoTopUp.new(customer, nil, 12, margin: 5)
193
194			assert_equal 15, auto_top_up.top_up_amount
195		end
196		em :test_top_up_amount_when_target_less_than_expected_balance
197
198		def test_negative_balance_target_less_than_expected_balance
199			customer = Minitest::Mock.new(customer(
200				balance: -11,
201				auto_top_up_amount: 15
202			))
203			auto_top_up = LowBalance::AutoTopUp.new(customer, nil, 35, margin: 5)
204
205			assert_equal 51, auto_top_up.top_up_amount
206		end
207		em :test_negative_balance_target_less_than_expected_balance
208
209		def test_very_low_balance_notify!
210			customer = Minitest::Mock.new(customer(
211				balance: -100,
212				auto_top_up_amount: 15
213			))
214			auto_top_up = LowBalance::AutoTopUp.new(customer)
215			tx = OpenStruct.new(total: 13)
216
217			LowBalance::AutoTopUp::CreditCardSale.expect(
218				:create,
219				EMPromise.resolve(tx),
220				[customer], amount: 110
221			)
222			auto_top_up.notify!
223		end
224		em :test_very_low_balance_notify!
225
226		def test_border_low_balance_notify!
227			customer = Minitest::Mock.new(customer(
228				balance: -11,
229				auto_top_up_amount: 15
230			))
231			auto_top_up = LowBalance::AutoTopUp.new(customer)
232			tx = OpenStruct.new(total: 13)
233
234			LowBalance::AutoTopUp::CreditCardSale.expect(
235				:create,
236				EMPromise.resolve(tx),
237				[customer], amount: 21
238			)
239			auto_top_up.notify!
240		end
241		em :test_border_low_balance_notify!
242
243		def test_decline_notify!
244			@customer.expect(
245				:stanza_to,
246				nil,
247				[Matching.new { |m|
248					assert_equal(
249						"Automatic top-up transaction for $100.00 failed: test",
250						m.body
251					)
252				}]
253			)
254			LowBalance::AutoTopUp::CreditCardSale.expect(
255				:create,
256				EMPromise.reject(RuntimeError.new("test")),
257				[@customer], amount: 100.to_d
258			)
259			@auto_top_up.notify!.sync
260			assert_mock @customer
261		end
262		em :test_decline_notify!
263	end
264end