stripe-ruby-mock 2.5.8 → 3.1.0.rc3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -1
  3. data/.travis.yml +6 -9
  4. data/CHANGELOG.md +41 -0
  5. data/Gemfile +1 -0
  6. data/README.md +17 -11
  7. data/lib/stripe_mock.rb +8 -0
  8. data/lib/stripe_mock/api/client.rb +1 -1
  9. data/lib/stripe_mock/api/errors.rb +34 -28
  10. data/lib/stripe_mock/api/instance.rb +1 -1
  11. data/lib/stripe_mock/api/webhooks.rb +5 -0
  12. data/lib/stripe_mock/client.rb +2 -1
  13. data/lib/stripe_mock/data.rb +285 -16
  14. data/lib/stripe_mock/data/list.rb +42 -9
  15. data/lib/stripe_mock/instance.rb +18 -4
  16. data/lib/stripe_mock/request_handlers/account_links.rb +15 -0
  17. data/lib/stripe_mock/request_handlers/balance_transactions.rb +2 -2
  18. data/lib/stripe_mock/request_handlers/charges.rb +6 -4
  19. data/lib/stripe_mock/request_handlers/checkout.rb +15 -0
  20. data/lib/stripe_mock/request_handlers/checkout_session.rb +22 -0
  21. data/lib/stripe_mock/request_handlers/customers.rb +35 -18
  22. data/lib/stripe_mock/request_handlers/ephemeral_key.rb +1 -1
  23. data/lib/stripe_mock/request_handlers/express_login_links.rb +15 -0
  24. data/lib/stripe_mock/request_handlers/helpers/coupon_helpers.rb +5 -0
  25. data/lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb +12 -7
  26. data/lib/stripe_mock/request_handlers/helpers/token_helpers.rb +1 -1
  27. data/lib/stripe_mock/request_handlers/invoices.rb +10 -4
  28. data/lib/stripe_mock/request_handlers/payment_intents.rb +182 -0
  29. data/lib/stripe_mock/request_handlers/payment_methods.rb +120 -0
  30. data/lib/stripe_mock/request_handlers/plans.rb +1 -1
  31. data/lib/stripe_mock/request_handlers/prices.rb +44 -0
  32. data/lib/stripe_mock/request_handlers/products.rb +1 -0
  33. data/lib/stripe_mock/request_handlers/setup_intents.rb +93 -0
  34. data/lib/stripe_mock/request_handlers/sources.rb +12 -6
  35. data/lib/stripe_mock/request_handlers/subscriptions.rb +45 -22
  36. data/lib/stripe_mock/request_handlers/tokens.rb +6 -4
  37. data/lib/stripe_mock/request_handlers/validators/param_validators.rb +123 -9
  38. data/lib/stripe_mock/server.rb +2 -2
  39. data/lib/stripe_mock/test_strategies/base.rb +67 -8
  40. data/lib/stripe_mock/test_strategies/live.rb +23 -12
  41. data/lib/stripe_mock/test_strategies/mock.rb +6 -2
  42. data/lib/stripe_mock/version.rb +1 -1
  43. data/lib/stripe_mock/webhook_fixtures/balance.available.json +6 -0
  44. data/lib/stripe_mock/webhook_fixtures/charge.failed.json +166 -38
  45. data/lib/stripe_mock/webhook_fixtures/customer.created.json +1 -0
  46. data/lib/stripe_mock/webhook_fixtures/customer.updated.json +1 -0
  47. data/lib/stripe_mock/webhook_fixtures/payment_intent.payment_failed.json +186 -0
  48. data/lib/stripe_mock/webhook_fixtures/payment_intent.succeeded.json +164 -0
  49. data/lib/stripe_mock/webhook_fixtures/product.created.json +34 -0
  50. data/lib/stripe_mock/webhook_fixtures/product.deleted.json +34 -0
  51. data/lib/stripe_mock/webhook_fixtures/product.updated.json +38 -0
  52. data/spec/instance_spec.rb +10 -12
  53. data/spec/list_spec.rb +38 -0
  54. data/spec/server_spec.rb +6 -3
  55. data/spec/shared_stripe_examples/account_examples.rb +1 -1
  56. data/spec/shared_stripe_examples/account_link_examples.rb +16 -0
  57. data/spec/shared_stripe_examples/balance_examples.rb +6 -0
  58. data/spec/shared_stripe_examples/balance_transaction_examples.rb +3 -3
  59. data/spec/shared_stripe_examples/bank_examples.rb +3 -3
  60. data/spec/shared_stripe_examples/card_examples.rb +4 -4
  61. data/spec/shared_stripe_examples/card_token_examples.rb +17 -21
  62. data/spec/shared_stripe_examples/charge_examples.rb +9 -22
  63. data/spec/shared_stripe_examples/checkout_examples.rb +47 -0
  64. data/spec/shared_stripe_examples/coupon_examples.rb +1 -1
  65. data/spec/shared_stripe_examples/customer_examples.rb +93 -53
  66. data/spec/shared_stripe_examples/dispute_examples.rb +2 -2
  67. data/spec/shared_stripe_examples/error_mock_examples.rb +8 -7
  68. data/spec/shared_stripe_examples/express_login_link_examples.rb +12 -0
  69. data/spec/shared_stripe_examples/external_account_examples.rb +3 -3
  70. data/spec/shared_stripe_examples/invoice_examples.rb +41 -39
  71. data/spec/shared_stripe_examples/invoice_item_examples.rb +1 -1
  72. data/spec/shared_stripe_examples/payment_intent_examples.rb +147 -0
  73. data/spec/shared_stripe_examples/payment_method_examples.rb +449 -0
  74. data/spec/shared_stripe_examples/payout_examples.rb +2 -2
  75. data/spec/shared_stripe_examples/plan_examples.rb +135 -92
  76. data/spec/shared_stripe_examples/price_examples.rb +183 -0
  77. data/spec/shared_stripe_examples/product_examples.rb +147 -0
  78. data/spec/shared_stripe_examples/refund_examples.rb +25 -21
  79. data/spec/shared_stripe_examples/setup_intent_examples.rb +68 -0
  80. data/spec/shared_stripe_examples/subscription_examples.rb +430 -318
  81. data/spec/shared_stripe_examples/subscription_items_examples.rb +3 -2
  82. data/spec/shared_stripe_examples/transfer_examples.rb +6 -6
  83. data/spec/shared_stripe_examples/webhook_event_examples.rb +11 -11
  84. data/spec/spec_helper.rb +7 -4
  85. data/spec/stripe_mock_spec.rb +4 -4
  86. data/spec/support/shared_contexts/stripe_validator_spec.rb +8 -0
  87. data/spec/support/stripe_examples.rb +9 -1
  88. data/stripe-ruby-mock.gemspec +8 -3
  89. metadata +72 -34
  90. data/spec/shared_stripe_examples/product_example.rb +0 -65
@@ -0,0 +1,164 @@
1
+ {
2
+ "id": "evt_00000000000000",
3
+ "object": "event",
4
+ "api_version": "2018-02-28",
5
+ "created": 1578499109,
6
+ "data": {
7
+ "object": {
8
+ "id": "pi_00000000000000",
9
+ "object": "payment_intent",
10
+ "allowed_source_types": ["card", "sepa_debit"],
11
+ "amount": 900,
12
+ "amount_capturable": 0,
13
+ "amount_received": 900,
14
+ "application": null,
15
+ "application_fee_amount": null,
16
+ "canceled_at": null,
17
+ "cancellation_reason": null,
18
+ "capture_method": "automatic",
19
+ "charges": {
20
+ "object": "list",
21
+ "data": [
22
+ {
23
+ "id": "ch_00000000000000",
24
+ "object": "charge",
25
+ "amount": 900,
26
+ "amount_refunded": 0,
27
+ "application": null,
28
+ "application_fee": null,
29
+ "application_fee_amount": null,
30
+ "balance_transaction": "txn_00000000000000",
31
+ "billing_details": {
32
+ "address": {
33
+ "city": null,
34
+ "country": "DE",
35
+ "line1": null,
36
+ "line2": null,
37
+ "postal_code": null,
38
+ "state": null
39
+ },
40
+ "email": null,
41
+ "name": null,
42
+ "phone": null
43
+ },
44
+ "captured": true,
45
+ "created": 1578499109,
46
+ "currency": "eur",
47
+ "customer": "cus_00000000000000",
48
+ "description": null,
49
+ "destination": "acct_00000000000000",
50
+ "dispute": null,
51
+ "disputed": false,
52
+ "failure_code": null,
53
+ "failure_message": null,
54
+ "fraud_details": {},
55
+ "invoice": null,
56
+ "livemode": false,
57
+ "metadata": {},
58
+ "on_behalf_of": null,
59
+ "order": null,
60
+ "outcome": {
61
+ "network_status": "approved_by_network",
62
+ "reason": null,
63
+ "risk_level": "normal",
64
+ "risk_score": 40,
65
+ "seller_message": "Payment complete.",
66
+ "type": "authorized"
67
+ },
68
+ "paid": true,
69
+ "payment_intent": "pi_00000000000000",
70
+ "payment_method": "pm_00000000000000",
71
+ "payment_method_details": {
72
+ "card": {
73
+ "brand": "visa",
74
+ "checks": {
75
+ "address_line1_check": null,
76
+ "address_postal_code_check": null,
77
+ "cvc_check": null
78
+ },
79
+ "country": "US",
80
+ "exp_month": 4,
81
+ "exp_year": 2024,
82
+ "fingerprint": "00000000000000",
83
+ "funding": "credit",
84
+ "installments": null,
85
+ "last4": "4242",
86
+ "network": "visa",
87
+ "three_d_secure": null,
88
+ "wallet": null
89
+ },
90
+ "type": "card"
91
+ },
92
+ "receipt_email": null,
93
+ "receipt_number": null,
94
+ "receipt_url": "https://pay.stripe.com/receipts/acct_00000000000000/ch_00000000000000/rcpt_00000000000000",
95
+ "refunded": false,
96
+ "refunds": {
97
+ "object": "list",
98
+ "data": [],
99
+ "has_more": false,
100
+ "total_count": 0,
101
+ "url": "/v1/charges/ch_00000000000000/refunds"
102
+ },
103
+ "review": null,
104
+ "shipping": null,
105
+ "source": null,
106
+ "source_transfer": null,
107
+ "statement_descriptor": "ACME Corp",
108
+ "statement_descriptor_suffix": null,
109
+ "status": "succeeded",
110
+ "transfer": "tr_00000000000000",
111
+ "transfer_data": {
112
+ "amount": null,
113
+ "destination": "acct_00000000000000"
114
+ },
115
+ "transfer_group": "group_pi_00000000000000"
116
+ }
117
+ ],
118
+ "has_more": false,
119
+ "total_count": 1,
120
+ "url": "/v1/charges?payment_intent=pi_00000000000000"
121
+ },
122
+ "client_secret": "pi_00000000000000",
123
+ "confirmation_method": "automatic",
124
+ "created": 1578499108,
125
+ "currency": "eur",
126
+ "customer": "cus_00000000000000",
127
+ "description": null,
128
+ "invoice": null,
129
+ "last_payment_error": null,
130
+ "livemode": false,
131
+ "metadata": {},
132
+ "next_action": null,
133
+ "next_source_action": null,
134
+ "on_behalf_of": null,
135
+ "payment_method": "pm_00000000000000",
136
+ "payment_method_options": {
137
+ "card": {
138
+ "installments": null,
139
+ "request_three_d_secure": "automatic"
140
+ }
141
+ },
142
+ "payment_method_types": ["card", "sepa_debit"],
143
+ "receipt_email": null,
144
+ "review": null,
145
+ "setup_future_usage": null,
146
+ "shipping": null,
147
+ "source": null,
148
+ "statement_descriptor": "ACME Corp",
149
+ "statement_descriptor_suffix": null,
150
+ "status": "succeeded",
151
+ "transfer_data": {
152
+ "destination": "acct_00000000000000"
153
+ },
154
+ "transfer_group": "group_pi_00000000000000"
155
+ }
156
+ },
157
+ "livemode": false,
158
+ "pending_webhooks": 2,
159
+ "request": {
160
+ "id": "req_00000000000000",
161
+ "idempotency_key": null
162
+ },
163
+ "type": "payment_intent.succeeded"
164
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "created": 1326853478,
3
+ "livemode": false,
4
+ "id": "evt_00000000000000",
5
+ "type": "product.created",
6
+ "object": "event",
7
+ "data": {
8
+ "object": {
9
+ "id": "prod_00000000000000",
10
+ "object": "product",
11
+ "active": true,
12
+ "attributes": [
13
+ ],
14
+ "caption": null,
15
+ "created": 1558795883,
16
+ "deactivate_on": [
17
+ ],
18
+ "description": null,
19
+ "images": [
20
+ ],
21
+ "livemode": false,
22
+ "metadata": {
23
+ },
24
+ "name": "Test Product",
25
+ "package_dimensions": null,
26
+ "shippable": null,
27
+ "statement_descriptor": null,
28
+ "type": "service",
29
+ "unit_label": null,
30
+ "updated": 1558795883,
31
+ "url": null
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "created": 1326853478,
3
+ "livemode": false,
4
+ "id": "evt_00000000000000",
5
+ "type": "product.deleted",
6
+ "object": "event",
7
+ "data": {
8
+ "object": {
9
+ "id": "prod_00000000000000",
10
+ "object": "product",
11
+ "active": true,
12
+ "attributes": [
13
+ ],
14
+ "caption": null,
15
+ "created": 1558795883,
16
+ "deactivate_on": [
17
+ ],
18
+ "description": null,
19
+ "images": [
20
+ ],
21
+ "livemode": false,
22
+ "metadata": {
23
+ },
24
+ "name": "Test Product",
25
+ "package_dimensions": null,
26
+ "shippable": null,
27
+ "statement_descriptor": null,
28
+ "type": "service",
29
+ "unit_label": null,
30
+ "updated": 1558795883,
31
+ "url": null
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,38 @@
1
+ {
2
+ "created": 1326853478,
3
+ "livemode": false,
4
+ "id": "evt_00000000000000",
5
+ "type": "product.updated",
6
+ "object": "event",
7
+ "data": {
8
+ "object": {
9
+ "id": "prod_00000000000000",
10
+ "object": "product",
11
+ "active": true,
12
+ "attributes": [
13
+ ],
14
+ "caption": null,
15
+ "created": 1558795883,
16
+ "deactivate_on": [
17
+ ],
18
+ "description": null,
19
+ "images": [
20
+ ],
21
+ "livemode": false,
22
+ "metadata": {
23
+ },
24
+ "name": "Test Product",
25
+ "package_dimensions": null,
26
+ "shippable": null,
27
+ "statement_descriptor": null,
28
+ "type": "service",
29
+ "unit_label": null,
30
+ "updated": 1558795883,
31
+ "url": null
32
+ },
33
+ "previous_attributes": {
34
+ "name": "Product Test",
35
+ "updated": 1558873981
36
+ }
37
+ }
38
+ }
@@ -13,13 +13,13 @@ describe StripeMock::Instance do
13
13
  after { StripeMock.stop }
14
14
 
15
15
  it "handles both string and symbol hash keys" do
16
- string_params = stripe_helper.create_plan_params(
17
- "id" => "str_abcde",
18
- :name => "String Plan"
16
+ symbol_params = stripe_helper.create_product_params(
17
+ :name => "Symbol Product",
18
+ "type" => "service"
19
19
  )
20
- res, api_key = StripeMock.instance.mock_request('post', '/v1/plans', api_key: 'api_key', params: string_params)
21
- expect(res.data[:id]).to eq('str_abcde')
22
- expect(res.data[:name]).to eq('String Plan')
20
+ res, api_key = StripeMock.instance.mock_request('post', '/v1/products', api_key: 'api_key', params: symbol_params)
21
+ expect(res.data[:name]).to eq('Symbol Product')
22
+ expect(res.data[:type]).to eq('service')
23
23
  end
24
24
 
25
25
  it "exits gracefully on an unrecognized handler url" do
@@ -54,17 +54,15 @@ describe StripeMock::Instance do
54
54
  end
55
55
 
56
56
  it "allows non-usd default currency" do
57
+ pending("Stripe::Plan requires currency param - how can we test this?")
57
58
  old_default_currency = StripeMock.default_currency
58
- customer = begin
59
+ plan = begin
59
60
  StripeMock.default_currency = "jpy"
60
- Stripe::Customer.create({
61
- email: 'johnny@appleseed.com',
62
- source: stripe_helper.generate_card_token
63
- })
61
+ Stripe::Plan.create(interval: 'month')
64
62
  ensure
65
63
  StripeMock.default_currency = old_default_currency
66
64
  end
67
- expect(customer.currency).to eq("jpy")
65
+ expect(plan.currency).to eq("jpy")
68
66
  end
69
67
 
70
68
  context 'when creating sources with metadata' do
data/spec/list_spec.rb CHANGED
@@ -109,6 +109,21 @@ describe StripeMock::Data::List do
109
109
  end
110
110
  end
111
111
 
112
+ context "active filter" do
113
+ it "accepts an active param which filters out data accordingly" do
114
+ product = Stripe::Product.create(id: "prod_123", name: "My Beautiful Product", type: "service")
115
+
116
+ plan_attributes = { product: product.id, interval: "month", currency: "usd", amount: 500 }
117
+ plan_a = Stripe::Plan.create(plan_attributes)
118
+ plan_b = Stripe::Plan.create(**plan_attributes, active: false)
119
+
120
+ list = StripeMock::Data::List.new([plan_a, plan_b], active: true)
121
+
122
+ expect(list.active).to eq(true)
123
+ expect(list.to_h[:data].count).to eq(1)
124
+ end
125
+ end
126
+
112
127
  context "pagination" do
113
128
  it "has a has_more field when it has more" do
114
129
  list = StripeMock::Data::List.new(
@@ -137,4 +152,27 @@ describe StripeMock::Data::List do
137
152
  expect { list.to_h }.to raise_error
138
153
  end
139
154
  end
155
+
156
+ context "with data containing records marked 'deleted'" do
157
+ let(:customer_data) { StripeMock.instance.customers.values }
158
+ let(:customers) do
159
+ customer_data.map { |datum| Stripe::Util.convert_to_stripe_object(datum) }
160
+ end
161
+
162
+ before do
163
+ StripeMock.instance.customers.clear
164
+ Stripe::Customer.create
165
+ Stripe::Customer.delete(Stripe::Customer.create.id)
166
+ end
167
+
168
+ it "does not raise error on initialization" do
169
+ expect { StripeMock::Data::List.new(customer_data) }.to_not raise_error
170
+ expect { StripeMock::Data::List.new(customers) }.to_not raise_error
171
+ end
172
+
173
+ it "omits records marked 'deleted'" do
174
+ expect(StripeMock::Data::List.new(customer_data).data.size).to eq(1)
175
+ expect(StripeMock::Data::List.new(customers).data.size).to eq(1)
176
+ end
177
+ end
140
178
  end
data/spec/server_spec.rb CHANGED
@@ -19,6 +19,7 @@ describe 'StripeMock Server', :mock_server => true do
19
19
 
20
20
  after { StripeMock.stop_client(:clear_server_data => true) }
21
21
 
22
+ let(:product) { stripe_helper.create_product }
22
23
 
23
24
  it "uses an RPC client for mock requests" do
24
25
  charge = Stripe::Charge.create(
@@ -37,21 +38,23 @@ describe 'StripeMock Server', :mock_server => true do
37
38
  customer = Stripe::Customer.create(email: 'johnny@appleseed.com')
38
39
  expect(customer.email).to eq('johnny@appleseed.com')
39
40
 
40
- server_customer_data = StripeMock.client.get_server_data(:customers)[customer.id]
41
+ server_customer_data = StripeMock.client.get_server_data(:customers)
42
+ server_customer_data = server_customer_data[server_customer_data.keys.first][customer.id.to_sym]
41
43
  expect(server_customer_data).to_not be_nil
42
44
  expect(server_customer_data[:email]).to eq('johnny@appleseed.com')
43
45
 
44
46
  StripeMock.stop_client
45
47
  StripeMock.start_client
46
48
 
47
- server_customer_data = StripeMock.client.get_server_data(:customers)[customer.id]
49
+ server_customer_data = StripeMock.client.get_server_data(:customers)
50
+ server_customer_data = server_customer_data[server_customer_data.keys.first][customer.id.to_sym]
48
51
  expect(server_customer_data).to_not be_nil
49
52
  expect(server_customer_data[:email]).to eq('johnny@appleseed.com')
50
53
  end
51
54
 
52
55
 
53
56
  it "returns a response with symbolized hash keys" do
54
- stripe_helper.create_plan(id: 'x')
57
+ stripe_helper.create_plan(id: 'x', product: product.id)
55
58
  response, api_key = StripeMock.redirect_to_mock_server('get', '/v1/plans/x', api_key: 'xxx')
56
59
  response.data.keys.each {|k| expect(k).to be_a(Symbol) }
57
60
  end
@@ -15,7 +15,7 @@ shared_examples 'Account API' do
15
15
  expect(account.id).to match /acct\_/
16
16
  end
17
17
  it 'retrieves all' do
18
- accounts = Stripe::Account.all
18
+ accounts = Stripe::Account.list
19
19
 
20
20
  expect(accounts).to be_a Stripe::ListObject
21
21
  expect(accounts.data.count).to satisfy { |n| n >= 1 }
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples 'Account Link API' do
4
+ describe 'create account link' do
5
+ it 'creates an account link' do
6
+ account_link = Stripe::AccountLink.create(
7
+ type: 'onboarding',
8
+ account: 'acct_103ED82ePvKYlo2C',
9
+ failure_url: 'https://stripe.com',
10
+ success_url: 'https://stripe.com'
11
+ )
12
+
13
+ expect(account_link).to be_a Stripe::AccountLink
14
+ end
15
+ end
16
+ end
@@ -8,4 +8,10 @@ shared_examples 'Balance API' do
8
8
  expect(balance.available[0].amount).to eq(2000)
9
9
  end
10
10
 
11
+ it "retrieves a stripe instant balance" do
12
+ StripeMock.set_account_balance(2000)
13
+ balance = Stripe::Balance.retrieve()
14
+ expect(balance.instant_available[0].amount).to eq(2000)
15
+ end
16
+
11
17
  end
@@ -26,7 +26,7 @@ shared_examples 'Balance Transaction API' do
26
26
  describe "listing balance transactions" do
27
27
 
28
28
  it "retrieves all balance transactions" do
29
- disputes = Stripe::BalanceTransaction.all
29
+ disputes = Stripe::BalanceTransaction.list
30
30
 
31
31
  expect(disputes.count).to eq(10)
32
32
  expect(disputes.map &:id).to include('txn_05RsQX2eZvKYlo2C0FRTGSSA','txn_15RsQX2eZvKYlo2C0ERTYUIA', 'txn_25RsQX2eZvKYlo2C0ZXCVBNM', 'txn_35RsQX2eZvKYlo2C0QAZXSWE', 'txn_45RsQX2eZvKYlo2C0EDCVFRT', 'txn_55RsQX2eZvKYlo2C0OIKLJUY', 'txn_65RsQX2eZvKYlo2C0ASDFGHJ', 'txn_75RsQX2eZvKYlo2C0EDCXSWQ', 'txn_85RsQX2eZvKYlo2C0UJMCDET', 'txn_95RsQX2eZvKYlo2C0EDFRYUI')
@@ -38,7 +38,7 @@ shared_examples 'Balance Transaction API' do
38
38
  transfer_id = Stripe::Transfer.create({ amount: 2730, currency: "usd" })
39
39
 
40
40
  # verify transfer currently has no balance transactions
41
- transfer_transactions = Stripe::BalanceTransaction.all({transfer: transfer_id})
41
+ transfer_transactions = Stripe::BalanceTransaction.list({transfer: transfer_id})
42
42
  expect(transfer_transactions.count).to eq(0)
43
43
 
44
44
  # verify we can create a new balance transaction associated with the transfer
@@ -55,7 +55,7 @@ shared_examples 'Balance Transaction API' do
55
55
  stripe_helper.upsert_stripe_object(:balance_transaction, {id: existing_txn_id, transfer: transfer_id})
56
56
 
57
57
  # now verify that only these balance transactions are retrieved with the transfer
58
- transfer_transactions = Stripe::BalanceTransaction.all({transfer: transfer_id})
58
+ transfer_transactions = Stripe::BalanceTransaction.list({transfer: transfer_id})
59
59
  expect(transfer_transactions.count).to eq(2)
60
60
  expect(transfer_transactions.map &:id).to include(new_txn_id, existing_txn_id)
61
61
  end