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