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