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