1# frozen_string_literal: true
2
3require "test_helper"
4require "credit_card_sale"
5require "customer"
6require "transaction"
7require "ostruct"
8
9CreditCardSale::BRAINTREE = Minitest::Mock.new
10CreditCardSale::REDIS = Minitest::Mock.new
11TrustLevelRepo::REDIS = Minitest::Mock.new
12TrustLevelRepo::DB = Minitest::Mock.new
13CustomerFinancials::REDIS = Minitest::Mock.new
14
15class CreditCardSaleTest < Minitest::Test
16 FAKE_BRAINTREE_TRANSACTION =
17 OpenStruct.new(
18 customer_details: OpenStruct.new(id: "customer"),
19 id: "transaction",
20 created_at: Time.at(0),
21 amount: 12
22 )
23
24 def test_sale_fails
25 CreditCardSale::REDIS.expect(
26 :exists,
27 EMPromise.resolve(0),
28 ["jmp_customer_credit_card_lock-test"]
29 )
30 TrustLevelRepo::REDIS.expect(
31 :get,
32 EMPromise.resolve("Customer"),
33 ["jmp_customer_trust_level-test"]
34 )
35 TrustLevelRepo::DB.expect(
36 :query_one,
37 EMPromise.resolve({}),
38 [String, "test"], default: {}
39 )
40 CustomerFinancials::REDIS.expect(
41 :get,
42 EMPromise.resolve("1"),
43 ["jmp_pay_decline-test"]
44 )
45 CustomerFinancials::REDIS.expect(
46 :incr,
47 EMPromise.resolve(nil),
48 ["jmp_pay_decline-test"]
49 )
50 CustomerFinancials::REDIS.expect(
51 :expire,
52 EMPromise.resolve(nil),
53 ["jmp_pay_decline-test", 60 * 60 * 24]
54 )
55 braintree_transaction = Minitest::Mock.new
56 CreditCardSale::BRAINTREE.expect(:transaction, braintree_transaction)
57 braintree_transaction.expect(
58 :sale,
59 EMPromise.resolve(
60 OpenStruct.new(success?: false, message: "declined")
61 ),
62 amount: 99,
63 merchant_account_id: "merchant_usd",
64 options: { submit_for_settlement: true },
65 payment_method_token: "token"
66 )
67 assert_raises(BraintreeFailure) do
68 CreditCardSale.new(
69 customer(plan_name: "test_usd"),
70 amount: 99,
71 payment_method: OpenStruct.new(token: "token")
72 ).sale.sync
73 end
74 assert_mock CustomerFinancials::REDIS
75 assert_mock CreditCardSale::REDIS
76 assert_mock TrustLevelRepo::REDIS
77 assert_mock TrustLevelRepo::DB
78 end
79 em :test_sale_fails
80
81 def test_sale_locked
82 CreditCardSale::REDIS.expect(
83 :exists,
84 EMPromise.resolve(1),
85 ["jmp_customer_credit_card_lock-test"]
86 )
87 TrustLevelRepo::REDIS.expect(
88 :get,
89 EMPromise.resolve("Customer"),
90 ["jmp_customer_trust_level-test"]
91 )
92 TrustLevelRepo::DB.expect(
93 :query_one,
94 EMPromise.resolve({}),
95 [String, "test"], default: {}
96 )
97 CustomerFinancials::REDIS.expect(
98 :get,
99 EMPromise.resolve("0"),
100 ["jmp_pay_decline-test"]
101 )
102 assert_raises("locked") do
103 CreditCardSale.new(
104 customer(plan_name: "test_usd"),
105 amount: 123,
106 payment_method: OpenStruct.new(token: "token")
107 ).sale.sync
108 end
109 assert_mock CustomerFinancials::REDIS
110 assert_mock CreditCardSale::REDIS
111 assert_mock TrustLevelRepo::REDIS
112 assert_mock TrustLevelRepo::DB
113 end
114 em :test_sale_locked
115
116 def test_sale_amount_too_high
117 CreditCardSale::REDIS.expect(
118 :exists,
119 EMPromise.resolve(0),
120 ["jmp_customer_credit_card_lock-test"]
121 )
122 TrustLevelRepo::REDIS.expect(
123 :get,
124 EMPromise.resolve("Customer"),
125 ["jmp_customer_trust_level-test"]
126 )
127 TrustLevelRepo::DB.expect(
128 :query_one,
129 EMPromise.resolve({}),
130 [String, "test"], default: {}
131 )
132 CustomerFinancials::REDIS.expect(
133 :get,
134 EMPromise.resolve("0"),
135 ["jmp_pay_decline-test"]
136 )
137
138 assert_raises(AmountTooHighError) do
139 CreditCardSale.new(
140 customer(plan_name: "test_usd"),
141 amount: 131,
142 payment_method: OpenStruct.new(token: "token")
143 ).sale.sync
144 end
145
146 assert_mock CustomerFinancials::REDIS
147 assert_mock CreditCardSale::REDIS
148 assert_mock TrustLevelRepo::REDIS
149 assert_mock TrustLevelRepo::DB
150 end
151 em :test_sale_amount_too_high
152
153 def test_sale_too_many_declines
154 CreditCardSale::REDIS.expect(
155 :exists,
156 EMPromise.resolve(0),
157 ["jmp_customer_credit_card_lock-test"]
158 )
159 TrustLevelRepo::REDIS.expect(
160 :get,
161 EMPromise.resolve("Customer"),
162 ["jmp_customer_trust_level-test"]
163 )
164 TrustLevelRepo::DB.expect(
165 :query_one,
166 EMPromise.resolve({}),
167 [String, "test"], default: {}
168 )
169 CustomerFinancials::REDIS.expect(
170 :get,
171 EMPromise.resolve("3"),
172 ["jmp_pay_decline-test"]
173 )
174
175 assert_raises(DeclinedError) do
176 CreditCardSale.new(
177 customer(plan_name: "test_usd"),
178 amount: 50,
179 payment_method: OpenStruct.new(token: "token")
180 ).sale.sync
181 end
182
183 assert_mock CustomerFinancials::REDIS
184 assert_mock CreditCardSale::REDIS
185 assert_mock TrustLevelRepo::REDIS
186 assert_mock TrustLevelRepo::DB
187 end
188 em :test_sale_too_many_declines
189
190 def test_sale
191 req = stub_request(
192 :post,
193 "https://api.churnbuster.io/v1/successful_payments"
194 ).with(
195 body: {
196 customer: {
197 source: "braintree",
198 source_id: "test",
199 email: "test@smtp.cheogram.com",
200 properties: {}
201 },
202 payment: {
203 source: "braintree",
204 source_id: "transaction",
205 amount_in_cents: 9900,
206 currency: "USD"
207 }
208 }.to_json
209 ).to_return(status: 200, body: "", headers: {})
210
211 CreditCardSale::REDIS.expect(
212 :exists,
213 EMPromise.resolve(0),
214 ["jmp_customer_credit_card_lock-test"]
215 )
216 TrustLevelRepo::REDIS.expect(
217 :get,
218 EMPromise.resolve("Customer"),
219 ["jmp_customer_trust_level-test"]
220 )
221 TrustLevelRepo::DB.expect(
222 :query_one,
223 EMPromise.resolve({}),
224 [String, "test"], default: {}
225 )
226 CustomerFinancials::REDIS.expect(
227 :get,
228 EMPromise.resolve("1"),
229 ["jmp_pay_decline-test"]
230 )
231 braintree_transaction = Minitest::Mock.new
232 CreditCardSale::BRAINTREE.expect(:transaction, braintree_transaction)
233 braintree_transaction.expect(
234 :sale,
235 EMPromise.resolve(
236 OpenStruct.new(
237 success?: true,
238 transaction: FAKE_BRAINTREE_TRANSACTION
239 )
240 ),
241 amount: 99,
242 payment_method_token: "token",
243 merchant_account_id: "merchant_usd",
244 options: { submit_for_settlement: true }
245 )
246 CreditCardSale::REDIS.expect(
247 :setex,
248 EMPromise.resolve(1),
249 ["jmp_customer_credit_card_lock-test", 86400, "1"]
250 )
251 result = CreditCardSale.new(
252 customer(plan_name: "test_usd"),
253 amount: 99,
254 payment_method: OpenStruct.new(token: "token")
255 ).sale.sync
256 assert_equal FAKE_BRAINTREE_TRANSACTION, result
257 assert_mock CustomerFinancials::REDIS
258 assert_mock CreditCardSale::REDIS
259 assert_mock TrustLevelRepo::REDIS
260 assert_mock TrustLevelRepo::DB
261 assert_requested req
262 end
263 em :test_sale
264
265 def test_builder
266 expected = Transaction.new(
267 customer_id: "customer",
268 transaction_id: "transaction",
269 created_at: Time.at(0),
270 settled_after: Time.at(7776000),
271 amount: 12,
272 note: "Credit card payment"
273 )
274
275 assert_equal(
276 expected,
277 CreditCardSale::BraintreeTransaction.build(FAKE_BRAINTREE_TRANSACTION)
278 )
279 end
280
281 def test_create
282 req = stub_request(
283 :post,
284 "https://api.churnbuster.io/v1/successful_payments"
285 ).with(
286 body: {
287 customer: {
288 source: "braintree",
289 source_id: "test",
290 email: "test@smtp.cheogram.com",
291 properties: {}
292 },
293 payment: {
294 source: "braintree",
295 source_id: "transaction",
296 amount_in_cents: 9900,
297 currency: "USD"
298 }
299 }.to_json
300 ).to_return(status: 200, body: "", headers: {})
301
302 CreditCardSale::REDIS.expect(
303 :exists,
304 EMPromise.resolve(0),
305 ["jmp_customer_credit_card_lock-test"]
306 )
307 TrustLevelRepo::REDIS.expect(
308 :get,
309 EMPromise.resolve("Customer"),
310 ["jmp_customer_trust_level-test"]
311 )
312 TrustLevelRepo::DB.expect(
313 :query_one,
314 EMPromise.resolve({}),
315 [String, "test"], default: {}
316 )
317 CustomerFinancials::REDIS.expect(
318 :get,
319 EMPromise.resolve("1"),
320 ["jmp_pay_decline-test"]
321 )
322 braintree_transaction = Minitest::Mock.new
323 CreditCardSale::BRAINTREE.expect(:transaction, braintree_transaction)
324 response = EMPromise.resolve(
325 OpenStruct.new(
326 success?: true,
327 transaction: FAKE_BRAINTREE_TRANSACTION
328 )
329 )
330 braintree_transaction.expect(
331 :sale,
332 response,
333 amount: 99,
334 payment_method_token: "token",
335 merchant_account_id: "merchant_usd",
336 options: { submit_for_settlement: true }
337 )
338 CreditCardSale::REDIS.expect(
339 :setex,
340 EMPromise.resolve(1),
341 ["jmp_customer_credit_card_lock-test", 86400, "1"]
342 )
343
344 transaction = PromiseMock.new
345 transaction.expect(:insert, EMPromise.resolve(nil))
346
347 transaction_class = Minitest::Mock.new
348 transaction_class.expect(
349 :new,
350 transaction,
351 customer_id: "customer",
352 transaction_id: "transaction",
353 created_at: Time.at(0),
354 settled_after: Time.at(7776000),
355 amount: 12,
356 note: "Credit card payment"
357 )
358
359 result = CreditCardSale.create(
360 customer(plan_name: "test_usd"),
361 amount: 99,
362 payment_method: OpenStruct.new(token: "token"),
363 transaction_class: transaction_class
364 ).sync
365
366 assert_equal transaction.object_id, result.object_id
367 assert_mock transaction_class
368 assert_mock transaction
369 assert_mock CustomerFinancials::REDIS
370 assert_mock CreditCardSale::REDIS
371 assert_mock TrustLevelRepo::REDIS
372 assert_mock TrustLevelRepo::DB
373 assert_requested req
374 end
375 em :test_create
376end