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::REDIS.expect(
36 :get,
37 EMPromise.resolve(nil),
38 ["jmp_customer_activater-test"]
39 )
40 CustomerPlan::DB.expect(
41 :query_one, {}, [String, "test"]
42 )
43 TrustLevelRepo::DB.expect(
44 :query_one,
45 EMPromise.resolve({}),
46 [String, "test"], default: {}
47 )
48 TrustLevelRepo::DB.expect(
49 :query_one,
50 EMPromise.resolve({}),
51 [String, "test"], default: {}
52 )
53 CustomerFinancials::REDIS.expect(
54 :get,
55 EMPromise.resolve("1"),
56 ["jmp_pay_decline-test"]
57 )
58 CustomerFinancials::REDIS.expect(
59 :incr,
60 EMPromise.resolve(nil),
61 ["jmp_pay_decline-test"]
62 )
63 CustomerFinancials::REDIS.expect(
64 :expire,
65 EMPromise.resolve(nil),
66 ["jmp_pay_decline-test", 60 * 60 * 24]
67 )
68 braintree_transaction = Minitest::Mock.new
69 CreditCardSale::BRAINTREE.expect(:transaction, braintree_transaction)
70 braintree_transaction.expect(
71 :sale,
72 EMPromise.resolve(
73 OpenStruct.new(success?: false, message: "declined")
74 ),
75 amount: 99,
76 merchant_account_id: "merchant_usd",
77 descriptor: { name: "JMPchat" },
78 options: { submit_for_settlement: true },
79 payment_method_token: "token"
80 )
81 assert_raises(BraintreeFailure) do
82 CreditCardSale.new(
83 customer(plan_name: "test_usd"),
84 amount: 99,
85 payment_method: OpenStruct.new(token: "token")
86 ).sale.sync
87 end
88 assert_mock CustomerFinancials::REDIS
89 assert_mock CustomerPlan::DB
90 assert_mock CreditCardSale::REDIS
91 assert_mock TrustLevelRepo::REDIS
92 assert_mock TrustLevelRepo::DB
93 end
94 em :test_sale_fails
95
96 def test_sale_locked
97 CreditCardSale::REDIS.expect(
98 :exists,
99 EMPromise.resolve(1),
100 ["jmp_customer_credit_card_lock-test"]
101 )
102 TrustLevelRepo::REDIS.expect(
103 :get,
104 EMPromise.resolve("Customer"),
105 ["jmp_customer_trust_level-test"]
106 )
107 TrustLevelRepo::REDIS.expect(
108 :get,
109 EMPromise.resolve(nil),
110 ["jmp_customer_activater-test"]
111 )
112 CustomerPlan::DB.expect(
113 :query_one, {}, [String, "test"]
114 )
115 TrustLevelRepo::DB.expect(
116 :query_one,
117 EMPromise.resolve({}),
118 [String, "test"], default: {}
119 )
120 TrustLevelRepo::DB.expect(
121 :query_one,
122 EMPromise.resolve({}),
123 [String, "test"], default: {}
124 )
125 CustomerFinancials::REDIS.expect(
126 :get,
127 EMPromise.resolve("0"),
128 ["jmp_pay_decline-test"]
129 )
130 assert_raises("locked") do
131 CreditCardSale.new(
132 customer(plan_name: "test_usd"),
133 amount: 123,
134 payment_method: OpenStruct.new(token: "token")
135 ).sale.sync
136 end
137 assert_mock CustomerFinancials::REDIS
138 assert_mock CustomerPlan::DB
139 assert_mock CreditCardSale::REDIS
140 assert_mock TrustLevelRepo::REDIS
141 assert_mock TrustLevelRepo::DB
142 end
143 em :test_sale_locked
144
145 def test_sale_amount_too_high
146 CreditCardSale::REDIS.expect(
147 :exists,
148 EMPromise.resolve(0),
149 ["jmp_customer_credit_card_lock-test"]
150 )
151 TrustLevelRepo::REDIS.expect(
152 :get,
153 EMPromise.resolve("Customer"),
154 ["jmp_customer_trust_level-test"]
155 )
156 TrustLevelRepo::REDIS.expect(
157 :get,
158 EMPromise.resolve(nil),
159 ["jmp_customer_activater-test"]
160 )
161 CustomerPlan::DB.expect(
162 :query_one, {}, [String, "test"]
163 )
164 TrustLevelRepo::DB.expect(
165 :query_one,
166 EMPromise.resolve({}),
167 [String, "test"], default: {}
168 )
169 TrustLevelRepo::DB.expect(
170 :query_one,
171 EMPromise.resolve({}),
172 [String, "test"], default: {}
173 )
174 CustomerFinancials::REDIS.expect(
175 :get,
176 EMPromise.resolve("0"),
177 ["jmp_pay_decline-test"]
178 )
179
180 assert_raises(AmountTooHighError) do
181 CreditCardSale.new(
182 customer(plan_name: "test_usd"),
183 amount: 131,
184 payment_method: OpenStruct.new(token: "token")
185 ).sale.sync
186 end
187
188 assert_mock CustomerFinancials::REDIS
189 assert_mock CustomerPlan::DB
190 assert_mock CreditCardSale::REDIS
191 assert_mock TrustLevelRepo::REDIS
192 assert_mock TrustLevelRepo::DB
193 end
194 em :test_sale_amount_too_high
195
196 def test_sale_too_many_declines
197 CreditCardSale::REDIS.expect(
198 :exists,
199 EMPromise.resolve(0),
200 ["jmp_customer_credit_card_lock-test"]
201 )
202 TrustLevelRepo::REDIS.expect(
203 :get,
204 EMPromise.resolve("Customer"),
205 ["jmp_customer_trust_level-test"]
206 )
207 TrustLevelRepo::REDIS.expect(
208 :get,
209 EMPromise.resolve("Customer"),
210 ["jmp_customer_activater-test"]
211 )
212 CustomerPlan::DB.expect(
213 :query_one, {}, [String, "test"]
214 )
215 TrustLevelRepo::DB.expect(
216 :query_one,
217 EMPromise.resolve({}),
218 [String, "test"], default: {}
219 )
220 TrustLevelRepo::DB.expect(
221 :query_one,
222 EMPromise.resolve({}),
223 [String, "test"], default: {}
224 )
225 CustomerFinancials::REDIS.expect(
226 :get,
227 EMPromise.resolve("3"),
228 ["jmp_pay_decline-test"]
229 )
230
231 assert_raises(DeclinedError) do
232 CreditCardSale.new(
233 customer(plan_name: "test_usd"),
234 amount: 50,
235 payment_method: OpenStruct.new(token: "token")
236 ).sale.sync
237 end
238
239 assert_mock CustomerFinancials::REDIS
240 assert_mock CustomerPlan::DB
241 assert_mock CreditCardSale::REDIS
242 assert_mock TrustLevelRepo::REDIS
243 assert_mock TrustLevelRepo::DB
244 end
245 em :test_sale_too_many_declines
246
247 def test_sale
248 req = stub_request(
249 :post,
250 "https://api.churnbuster.io/v1/successful_payments"
251 ).with(
252 body: {
253 customer: {
254 source: "braintree",
255 source_id: "test",
256 email: "test@smtp.cheogram.com",
257 properties: {}
258 },
259 payment: {
260 source: "braintree",
261 source_id: "transaction",
262 amount_in_cents: 9900,
263 currency: "USD"
264 }
265 }.to_json
266 ).to_return(status: 200, body: "", headers: {})
267
268 CreditCardSale::REDIS.expect(
269 :exists,
270 EMPromise.resolve(0),
271 ["jmp_customer_credit_card_lock-test"]
272 )
273 TrustLevelRepo::REDIS.expect(
274 :get,
275 EMPromise.resolve("Customer"),
276 ["jmp_customer_trust_level-test"]
277 )
278 TrustLevelRepo::REDIS.expect(
279 :get,
280 EMPromise.resolve(nil),
281 ["jmp_customer_activater-test"]
282 )
283 CustomerPlan::DB.expect(
284 :query_one, {}, [String, "test"]
285 )
286 TrustLevelRepo::DB.expect(
287 :query_one,
288 EMPromise.resolve({}),
289 [String, "test"], default: {}
290 )
291 TrustLevelRepo::DB.expect(
292 :query_one,
293 EMPromise.resolve({}),
294 [String, "test"], default: {}
295 )
296 CustomerFinancials::REDIS.expect(
297 :get,
298 EMPromise.resolve("1"),
299 ["jmp_pay_decline-test"]
300 )
301 braintree_transaction = Minitest::Mock.new
302 CreditCardSale::BRAINTREE.expect(:transaction, braintree_transaction)
303 braintree_transaction.expect(
304 :sale,
305 EMPromise.resolve(
306 OpenStruct.new(
307 success?: true,
308 transaction: FAKE_BRAINTREE_TRANSACTION
309 )
310 ),
311 amount: 99,
312 payment_method_token: "token",
313 merchant_account_id: "merchant_usd",
314 descriptor: { name: "JMPchat" },
315 options: { submit_for_settlement: true }
316 )
317 CreditCardSale::REDIS.expect(
318 :setex,
319 EMPromise.resolve(1),
320 ["jmp_customer_credit_card_lock-test", 86400, "1"]
321 )
322 result = CreditCardSale.new(
323 customer(plan_name: "test_usd"),
324 amount: 99,
325 payment_method: OpenStruct.new(token: "token")
326 ).sale.sync
327 assert_equal FAKE_BRAINTREE_TRANSACTION, result
328 assert_mock CustomerFinancials::REDIS
329 assert_mock CustomerPlan::DB
330 assert_mock CreditCardSale::REDIS
331 assert_mock TrustLevelRepo::REDIS
332 assert_mock TrustLevelRepo::DB
333 assert_requested req
334 end
335 em :test_sale
336
337 def test_builder
338 expected = Transaction.new(
339 customer_id: "customer",
340 transaction_id: "transaction",
341 created_at: Time.at(0),
342 settled_after: Time.at(7776000),
343 amount: 12,
344 note: "Credit card payment"
345 )
346
347 assert_equal(
348 expected,
349 CreditCardSale::BraintreeTransaction.build(FAKE_BRAINTREE_TRANSACTION)
350 )
351 end
352
353 def test_create
354 req = stub_request(
355 :post,
356 "https://api.churnbuster.io/v1/successful_payments"
357 ).with(
358 body: {
359 customer: {
360 source: "braintree",
361 source_id: "test",
362 email: "test@smtp.cheogram.com",
363 properties: {}
364 },
365 payment: {
366 source: "braintree",
367 source_id: "transaction",
368 amount_in_cents: 9900,
369 currency: "USD"
370 }
371 }.to_json
372 ).to_return(status: 200, body: "", headers: {})
373
374 CreditCardSale::REDIS.expect(
375 :exists,
376 EMPromise.resolve(0),
377 ["jmp_customer_credit_card_lock-test"]
378 )
379 TrustLevelRepo::REDIS.expect(
380 :get,
381 EMPromise.resolve("Customer"),
382 ["jmp_customer_trust_level-test"]
383 )
384 TrustLevelRepo::REDIS.expect(
385 :get,
386 EMPromise.resolve(nil),
387 ["jmp_customer_activater-test"]
388 )
389 CustomerPlan::DB.expect(
390 :query_one, {}, [String, "test"]
391 )
392 TrustLevelRepo::DB.expect(
393 :query_one,
394 EMPromise.resolve({}),
395 [String, "test"], default: {}
396 )
397 TrustLevelRepo::DB.expect(
398 :query_one,
399 EMPromise.resolve({}),
400 [String, "test"], default: {}
401 )
402 CustomerFinancials::REDIS.expect(
403 :get,
404 EMPromise.resolve("1"),
405 ["jmp_pay_decline-test"]
406 )
407 braintree_transaction = Minitest::Mock.new
408 CreditCardSale::BRAINTREE.expect(:transaction, braintree_transaction)
409 response = EMPromise.resolve(
410 OpenStruct.new(
411 success?: true,
412 transaction: FAKE_BRAINTREE_TRANSACTION
413 )
414 )
415 braintree_transaction.expect(
416 :sale,
417 response,
418 amount: 99,
419 payment_method_token: "token",
420 merchant_account_id: "merchant_usd",
421 descriptor: { name: "JMPchat" },
422 options: { submit_for_settlement: true }
423 )
424 CreditCardSale::REDIS.expect(
425 :setex,
426 EMPromise.resolve(1),
427 ["jmp_customer_credit_card_lock-test", 86400, "1"]
428 )
429
430 transaction = PromiseMock.new
431 transaction.expect(:insert, EMPromise.resolve(nil))
432
433 transaction_class = Minitest::Mock.new
434 transaction_class.expect(
435 :new,
436 transaction,
437 customer_id: "customer",
438 transaction_id: "transaction",
439 created_at: Time.at(0),
440 settled_after: Time.at(7776000),
441 amount: 12,
442 note: "Credit card payment"
443 )
444
445 result = CreditCardSale.create(
446 customer(plan_name: "test_usd"),
447 amount: 99,
448 payment_method: OpenStruct.new(token: "token"),
449 transaction_class: transaction_class
450 ).sync
451
452 assert_equal transaction.object_id, result.object_id
453 assert_mock transaction_class
454 assert_mock transaction
455 assert_mock CustomerFinancials::REDIS
456 assert_mock CustomerPlan::DB
457 assert_mock CreditCardSale::REDIS
458 assert_mock TrustLevelRepo::REDIS
459 assert_mock TrustLevelRepo::DB
460 assert_requested req
461 end
462 em :test_create
463end