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