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::Transaction = 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 = PromiseMock.new
167 tx.expect(:insert, EMPromise.resolve(nil))
168 LowBalance::AutoTopUp::Transaction.expect(
169 :sale,
170 tx,
171 [@customer], amount: 100
172 )
173 @auto_top_up.notify!
174 assert_mock tx
175 end
176 em :test_notify!
177
178 def test_top_up_amount_when_target_greater_than_expected_balance
179 customer = Minitest::Mock.new(customer(
180 balance: 10,
181 auto_top_up_amount: 15
182 ))
183 auto_top_up = LowBalance::AutoTopUp.new(customer, nil, 30, margin: 5)
184
185 assert_equal 25, auto_top_up.top_up_amount
186 end
187 em :test_top_up_amount_when_target_greater_than_expected_balance
188
189 def test_top_up_amount_when_target_less_than_expected_balance
190 customer = Minitest::Mock.new(customer(
191 balance: 10,
192 auto_top_up_amount: 15
193 ))
194 auto_top_up = LowBalance::AutoTopUp.new(customer, nil, 12, margin: 5)
195
196 assert_equal 15, auto_top_up.top_up_amount
197 end
198 em :test_top_up_amount_when_target_less_than_expected_balance
199
200 def test_negative_balance_target_less_than_expected_balance
201 customer = Minitest::Mock.new(customer(
202 balance: -11,
203 auto_top_up_amount: 15
204 ))
205 auto_top_up = LowBalance::AutoTopUp.new(customer, nil, 35, margin: 5)
206
207 assert_equal 51, auto_top_up.top_up_amount
208 end
209 em :test_negative_balance_target_less_than_expected_balance
210
211 def test_very_low_balance_notify!
212 customer = Minitest::Mock.new(customer(
213 balance: -100,
214 auto_top_up_amount: 15
215 ))
216 auto_top_up = LowBalance::AutoTopUp.new(customer)
217
218 tx = PromiseMock.new
219 tx.expect(:insert, EMPromise.resolve(nil))
220 LowBalance::AutoTopUp::Transaction.expect(
221 :sale,
222 tx,
223 [customer], amount: 110
224 )
225 auto_top_up.notify!
226 assert_mock tx
227 end
228 em :test_very_low_balance_notify!
229
230 def test_border_low_balance_notify!
231 customer = Minitest::Mock.new(customer(
232 balance: -11,
233 auto_top_up_amount: 15
234 ))
235 auto_top_up = LowBalance::AutoTopUp.new(customer)
236
237 tx = PromiseMock.new
238 tx.expect(:insert, EMPromise.resolve(nil))
239 LowBalance::AutoTopUp::Transaction.expect(
240 :sale,
241 tx,
242 [customer], amount: 21
243 )
244 auto_top_up.notify!
245 assert_mock tx
246 end
247 em :test_border_low_balance_notify!
248
249 def test_decline_notify!
250 @customer.expect(
251 :stanza_to,
252 nil,
253 [Matching.new { |m|
254 assert_equal(
255 "Automatic top-up transaction for $100 failed: test",
256 m.body
257 )
258 }]
259 )
260 LowBalance::AutoTopUp::Transaction.expect(
261 :sale,
262 EMPromise.reject(RuntimeError.new("test")),
263 [@customer], amount: 100
264 )
265 @auto_top_up.notify!.sync
266 assert_mock @customer
267 end
268 em :test_decline_notify!
269 end
270end