stripe-ruby-mock 2.5.8 → 4.0.0
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.
- checksums.yaml +5 -5
- data/.github/workflows/rspec_tests.yml +38 -0
- data/.gitignore +1 -1
- data/.rspec +2 -1
- data/CHANGELOG.md +77 -0
- data/Gemfile +1 -5
- data/README.md +19 -11
- data/lib/stripe_mock/api/client.rb +2 -2
- data/lib/stripe_mock/api/errors.rb +34 -28
- data/lib/stripe_mock/api/instance.rb +1 -1
- data/lib/stripe_mock/api/webhooks.rb +68 -24
- data/lib/stripe_mock/client.rb +2 -1
- data/lib/stripe_mock/data/list.rb +42 -9
- data/lib/stripe_mock/data.rb +359 -21
- data/lib/stripe_mock/instance.rb +23 -5
- data/lib/stripe_mock/request_handlers/account_links.rb +15 -0
- data/lib/stripe_mock/request_handlers/accounts.rb +17 -6
- data/lib/stripe_mock/request_handlers/balance_transactions.rb +2 -2
- data/lib/stripe_mock/request_handlers/charges.rb +31 -5
- data/lib/stripe_mock/request_handlers/checkout_session.rb +179 -0
- data/lib/stripe_mock/request_handlers/customers.rb +47 -19
- data/lib/stripe_mock/request_handlers/ephemeral_key.rb +1 -1
- data/lib/stripe_mock/request_handlers/events.rb +30 -3
- data/lib/stripe_mock/request_handlers/express_login_links.rb +15 -0
- data/lib/stripe_mock/request_handlers/helpers/coupon_helpers.rb +6 -0
- data/lib/stripe_mock/request_handlers/helpers/search_helpers.rb +67 -0
- data/lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb +36 -12
- data/lib/stripe_mock/request_handlers/helpers/token_helpers.rb +1 -1
- data/lib/stripe_mock/request_handlers/invoices.rb +26 -6
- data/lib/stripe_mock/request_handlers/payment_intents.rb +202 -0
- data/lib/stripe_mock/request_handlers/payment_methods.rb +124 -0
- data/lib/stripe_mock/request_handlers/plans.rb +1 -1
- data/lib/stripe_mock/request_handlers/prices.rb +71 -0
- data/lib/stripe_mock/request_handlers/products.rb +15 -5
- data/lib/stripe_mock/request_handlers/promotion_codes.rb +43 -0
- data/lib/stripe_mock/request_handlers/refunds.rb +13 -2
- data/lib/stripe_mock/request_handlers/setup_intents.rb +100 -0
- data/lib/stripe_mock/request_handlers/sources.rb +12 -6
- data/lib/stripe_mock/request_handlers/subscriptions.rb +146 -25
- data/lib/stripe_mock/request_handlers/tokens.rb +6 -4
- data/lib/stripe_mock/request_handlers/transfers.rb +12 -1
- data/lib/stripe_mock/request_handlers/validators/param_validators.rb +124 -9
- data/lib/stripe_mock/server.rb +2 -2
- data/lib/stripe_mock/test_strategies/base.rb +98 -12
- data/lib/stripe_mock/test_strategies/live.rb +23 -12
- data/lib/stripe_mock/test_strategies/mock.rb +6 -2
- data/lib/stripe_mock/version.rb +1 -1
- data/lib/stripe_mock/webhook_fixtures/account.updated.json +1 -1
- data/lib/stripe_mock/webhook_fixtures/balance.available.json +27 -15
- data/lib/stripe_mock/webhook_fixtures/charge.captured.json +143 -0
- data/lib/stripe_mock/webhook_fixtures/charge.dispute.created.json +63 -16
- data/lib/stripe_mock/webhook_fixtures/charge.failed.json +101 -44
- data/lib/stripe_mock/webhook_fixtures/charge.refund.updated.json +35 -0
- data/lib/stripe_mock/webhook_fixtures/charge.refunded.json +145 -50
- data/lib/stripe_mock/webhook_fixtures/charge.succeeded.json +114 -43
- data/lib/stripe_mock/webhook_fixtures/checkout.session.completed.json +79 -0
- data/lib/stripe_mock/webhook_fixtures/checkout.session.completed.payment_mode.json +53 -0
- data/lib/stripe_mock/webhook_fixtures/checkout.session.completed.setup_mode.json +45 -0
- data/lib/stripe_mock/webhook_fixtures/customer.created.json +37 -45
- data/lib/stripe_mock/webhook_fixtures/customer.deleted.json +36 -32
- data/lib/stripe_mock/webhook_fixtures/customer.source.created.json +31 -22
- data/lib/stripe_mock/webhook_fixtures/customer.source.updated.json +36 -25
- data/lib/stripe_mock/webhook_fixtures/customer.subscription.created.json +135 -47
- data/lib/stripe_mock/webhook_fixtures/customer.subscription.deleted.json +134 -45
- data/lib/stripe_mock/webhook_fixtures/customer.subscription.updated.json +135 -56
- data/lib/stripe_mock/webhook_fixtures/customer.updated.json +38 -46
- data/lib/stripe_mock/webhook_fixtures/invoice.created.json +176 -49
- data/lib/stripe_mock/webhook_fixtures/invoice.finalized.json +171 -0
- data/lib/stripe_mock/webhook_fixtures/invoice.paid.json +171 -0
- data/lib/stripe_mock/webhook_fixtures/invoice.payment_action_required.json +171 -0
- data/lib/stripe_mock/webhook_fixtures/invoice.payment_failed.json +149 -83
- data/lib/stripe_mock/webhook_fixtures/invoice.payment_succeeded.json +149 -90
- data/lib/stripe_mock/webhook_fixtures/invoice.upcoming.json +70 -0
- data/lib/stripe_mock/webhook_fixtures/invoice.updated.json +178 -50
- data/lib/stripe_mock/webhook_fixtures/invoiceitem.created.json +87 -13
- data/lib/stripe_mock/webhook_fixtures/invoiceitem.updated.json +88 -14
- data/lib/stripe_mock/webhook_fixtures/mandate.updated.json +34 -0
- data/lib/stripe_mock/webhook_fixtures/payment_intent.amount_capturable_updated.json +170 -0
- data/lib/stripe_mock/webhook_fixtures/payment_intent.canceled.json +73 -0
- data/lib/stripe_mock/webhook_fixtures/payment_intent.created.json +86 -0
- data/lib/stripe_mock/webhook_fixtures/payment_intent.payment_failed.json +225 -0
- data/lib/stripe_mock/webhook_fixtures/payment_intent.processing.json +162 -0
- data/lib/stripe_mock/webhook_fixtures/payment_intent.requires_action.json +191 -0
- data/lib/stripe_mock/webhook_fixtures/payment_intent.succeeded.json +196 -0
- data/lib/stripe_mock/webhook_fixtures/payment_link.created.json +47 -0
- data/lib/stripe_mock/webhook_fixtures/payment_link.updated.json +50 -0
- data/lib/stripe_mock/webhook_fixtures/payment_method.attached.json +63 -0
- data/lib/stripe_mock/webhook_fixtures/payment_method.detached.json +62 -0
- data/lib/stripe_mock/webhook_fixtures/payout.created.json +40 -0
- data/lib/stripe_mock/webhook_fixtures/payout.paid.json +40 -0
- data/lib/stripe_mock/webhook_fixtures/payout.updated.json +46 -0
- data/lib/stripe_mock/webhook_fixtures/plan.created.json +30 -13
- data/lib/stripe_mock/webhook_fixtures/plan.deleted.json +30 -13
- data/lib/stripe_mock/webhook_fixtures/plan.updated.json +34 -14
- data/lib/stripe_mock/webhook_fixtures/price.created.json +42 -0
- data/lib/stripe_mock/webhook_fixtures/price.deleted.json +42 -0
- data/lib/stripe_mock/webhook_fixtures/price.updated.json +48 -0
- data/lib/stripe_mock/webhook_fixtures/product.created.json +40 -0
- data/lib/stripe_mock/webhook_fixtures/product.deleted.json +40 -0
- data/lib/stripe_mock/webhook_fixtures/product.updated.json +47 -0
- data/lib/stripe_mock/webhook_fixtures/quote.accepted.json +92 -0
- data/lib/stripe_mock/webhook_fixtures/quote.canceled.json +92 -0
- data/lib/stripe_mock/webhook_fixtures/quote.created.json +92 -0
- data/lib/stripe_mock/webhook_fixtures/quote.finalized.json +92 -0
- data/lib/stripe_mock/webhook_fixtures/setup_intent.canceled.json +46 -0
- data/lib/stripe_mock/webhook_fixtures/setup_intent.created.json +51 -0
- data/lib/stripe_mock/webhook_fixtures/setup_intent.setup_failed.json +100 -0
- data/lib/stripe_mock/webhook_fixtures/setup_intent.succeeded.json +46 -0
- data/lib/stripe_mock/webhook_fixtures/subscription_schedule.canceled.json +119 -0
- data/lib/stripe_mock/webhook_fixtures/subscription_schedule.created.json +114 -0
- data/lib/stripe_mock/webhook_fixtures/subscription_schedule.released.json +111 -0
- data/lib/stripe_mock/webhook_fixtures/subscription_schedule.updated.json +125 -0
- data/lib/stripe_mock/webhook_fixtures/tax_rate.created.json +32 -0
- data/lib/stripe_mock/webhook_fixtures/tax_rate.updated.json +37 -0
- data/lib/stripe_mock.rb +11 -0
- data/spec/instance_spec.rb +13 -13
- data/spec/integration_examples/completing_checkout_sessions_example.rb +37 -0
- data/spec/list_spec.rb +38 -0
- data/spec/readme_spec.rb +1 -1
- data/spec/server_spec.rb +6 -3
- data/spec/shared_stripe_examples/account_examples.rb +10 -2
- data/spec/shared_stripe_examples/account_link_examples.rb +16 -0
- data/spec/shared_stripe_examples/balance_examples.rb +6 -0
- data/spec/shared_stripe_examples/balance_transaction_examples.rb +3 -3
- data/spec/shared_stripe_examples/bank_examples.rb +3 -3
- data/spec/shared_stripe_examples/bank_token_examples.rb +5 -7
- data/spec/shared_stripe_examples/card_examples.rb +4 -4
- data/spec/shared_stripe_examples/card_token_examples.rb +17 -21
- data/spec/shared_stripe_examples/charge_examples.rb +106 -22
- data/spec/shared_stripe_examples/checkout_session_examples.rb +99 -0
- data/spec/shared_stripe_examples/coupon_examples.rb +1 -1
- data/spec/shared_stripe_examples/customer_examples.rb +149 -53
- data/spec/shared_stripe_examples/dispute_examples.rb +2 -2
- data/spec/shared_stripe_examples/error_mock_examples.rb +8 -7
- data/spec/shared_stripe_examples/express_login_link_examples.rb +12 -0
- data/spec/shared_stripe_examples/external_account_examples.rb +3 -3
- data/spec/shared_stripe_examples/invoice_examples.rb +148 -40
- data/spec/shared_stripe_examples/invoice_item_examples.rb +1 -1
- data/spec/shared_stripe_examples/payment_intent_examples.rb +283 -0
- data/spec/shared_stripe_examples/payment_method_examples.rb +454 -0
- data/spec/shared_stripe_examples/payout_examples.rb +2 -2
- data/spec/shared_stripe_examples/plan_examples.rb +135 -92
- data/spec/shared_stripe_examples/price_examples.rb +292 -0
- data/spec/shared_stripe_examples/product_examples.rb +215 -0
- data/spec/shared_stripe_examples/promotion_code_examples.rb +68 -0
- data/spec/shared_stripe_examples/refund_examples.rb +38 -21
- data/spec/shared_stripe_examples/setup_intent_examples.rb +85 -0
- data/spec/shared_stripe_examples/subscription_examples.rb +706 -324
- data/spec/shared_stripe_examples/subscription_items_examples.rb +3 -2
- data/spec/shared_stripe_examples/transfer_examples.rb +16 -7
- data/spec/shared_stripe_examples/webhook_event_examples.rb +62 -16
- data/spec/spec_helper.rb +8 -5
- data/spec/stripe_mock_spec.rb +4 -4
- data/spec/support/shared_contexts/stripe_validator_spec.rb +8 -0
- data/spec/support/stripe_examples.rb +11 -1
- data/stripe-ruby-mock.gemspec +9 -5
- metadata +115 -47
- data/.travis.yml +0 -28
- data/spec/shared_stripe_examples/product_example.rb +0 -65
@@ -6,13 +6,14 @@ def expect_card_error(code, param)
|
|
6
6
|
expect(e.http_status).to eq(402)
|
7
7
|
expect(e.code).to eq(code)
|
8
8
|
expect(e.param).to eq(param)
|
9
|
+
expect(e.http_body).to eq(e.json_body.to_json)
|
9
10
|
}
|
10
11
|
end
|
11
12
|
|
12
13
|
shared_examples 'Stripe Error Mocking' do
|
13
14
|
|
14
15
|
it "mocks a manually given stripe card error" do
|
15
|
-
error = Stripe::CardError.new('Test Msg', 'param_name', 'bad_code', http_status: 444, http_body: 'body', json_body:
|
16
|
+
error = Stripe::CardError.new('Test Msg', 'param_name', code: 'bad_code', http_status: 444, http_body: 'body', json_body: {})
|
16
17
|
StripeMock.prepare_error(error)
|
17
18
|
|
18
19
|
expect { Stripe::Customer.create() }.to raise_error {|e|
|
@@ -23,14 +24,14 @@ shared_examples 'Stripe Error Mocking' do
|
|
23
24
|
|
24
25
|
expect(e.http_status).to eq(444)
|
25
26
|
expect(e.http_body).to eq('body')
|
26
|
-
expect(e.json_body).to eq(
|
27
|
+
expect(e.json_body).to eq({})
|
27
28
|
}
|
28
29
|
end
|
29
30
|
|
30
31
|
|
31
32
|
it "mocks a manually gives stripe invalid request error" do
|
32
33
|
|
33
|
-
error = Stripe::InvalidRequestError.new('Test Invalid', 'param', http_status: 987, http_body: 'ibody', json_body:
|
34
|
+
error = Stripe::InvalidRequestError.new('Test Invalid', 'param', http_status: 987, http_body: 'ibody', json_body: {})
|
34
35
|
StripeMock.prepare_error(error)
|
35
36
|
|
36
37
|
expect { Stripe::Charge.create(amount: 1, currency: 'usd') }.to raise_error {|e|
|
@@ -40,22 +41,22 @@ shared_examples 'Stripe Error Mocking' do
|
|
40
41
|
|
41
42
|
expect(e.http_status).to eq(987)
|
42
43
|
expect(e.http_body).to eq('ibody')
|
43
|
-
expect(e.json_body).to eq(
|
44
|
+
expect(e.json_body).to eq({})
|
44
45
|
}
|
45
46
|
end
|
46
47
|
|
47
48
|
|
48
49
|
it "mocks a manually gives stripe invalid auth error" do
|
49
|
-
error = Stripe::AuthenticationError.new('Bad Auth', http_status: 499, http_body: 'abody', json_body:
|
50
|
+
error = Stripe::AuthenticationError.new('Bad Auth', http_status: 499, http_body: 'abody', json_body: {})
|
50
51
|
StripeMock.prepare_error(error)
|
51
52
|
|
52
|
-
expect { stripe_helper.create_plan() }.to raise_error {|e|
|
53
|
+
expect { stripe_helper.create_plan(id: "test_plan") }.to raise_error {|e|
|
53
54
|
expect(e).to be_a(Stripe::AuthenticationError)
|
54
55
|
expect(e.message).to eq('Bad Auth')
|
55
56
|
|
56
57
|
expect(e.http_status).to eq(499)
|
57
58
|
expect(e.http_body).to eq('abody')
|
58
|
-
expect(e.json_body).to eq(
|
59
|
+
expect(e.json_body).to eq({})
|
59
60
|
}
|
60
61
|
end
|
61
62
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples 'Express Login Link API' do
|
4
|
+
describe 'create an Express Login Link' do
|
5
|
+
it 'creates a login link' do
|
6
|
+
account_link = Stripe::Account.create_login_link('acct_103ED82ePvKYlo2C')
|
7
|
+
|
8
|
+
expect(account_link).to be_a Stripe::LoginLink
|
9
|
+
expect(account_link.url).to start_with('https://connect.stripe.com/express/')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -63,7 +63,7 @@ shared_examples 'External Account API' do
|
|
63
63
|
let!(:bank) { account.external_accounts.create(external_account: bank_token) }
|
64
64
|
|
65
65
|
it "can retrieve all account's banks" do
|
66
|
-
retrieved = account.external_accounts.
|
66
|
+
retrieved = account.external_accounts.list
|
67
67
|
expect(retrieved.count).to eq(1)
|
68
68
|
end
|
69
69
|
|
@@ -142,7 +142,7 @@ shared_examples 'External Account API' do
|
|
142
142
|
|
143
143
|
account = Stripe::Account.retrieve('test_account')
|
144
144
|
|
145
|
-
list = account.external_accounts.
|
145
|
+
list = account.external_accounts.list
|
146
146
|
|
147
147
|
expect(list.object).to eq("list")
|
148
148
|
expect(list.count).to eq(2)
|
@@ -159,7 +159,7 @@ shared_examples 'External Account API' do
|
|
159
159
|
Stripe::Account.create(id: 'no_banks', type: 'custom', country: "US")
|
160
160
|
account = Stripe::Account.retrieve('no_banks')
|
161
161
|
|
162
|
-
list = account.external_accounts.
|
162
|
+
list = account.external_accounts.list
|
163
163
|
|
164
164
|
expect(list.object).to eq("list")
|
165
165
|
expect(list.count).to eq(0)
|
@@ -14,6 +14,11 @@ shared_examples 'Invoice API' do
|
|
14
14
|
expect(data[invoice.id]).to_not be_nil
|
15
15
|
expect(data[invoice.id][:id]).to eq(invoice.id)
|
16
16
|
end
|
17
|
+
|
18
|
+
it "supports invoice number" do
|
19
|
+
original = Stripe::Invoice.create
|
20
|
+
expect(original.number).to be
|
21
|
+
end
|
17
22
|
end
|
18
23
|
|
19
24
|
context "retrieving an invoice" do
|
@@ -48,31 +53,114 @@ shared_examples 'Invoice API' do
|
|
48
53
|
end
|
49
54
|
|
50
55
|
it "stores invoices for a customer in memory" do
|
51
|
-
|
56
|
+
invoices = Stripe::Invoice.list(customer: @customer.id)
|
57
|
+
expect(invoices.map(&:id)).to eq([@invoice.id])
|
52
58
|
end
|
53
59
|
|
54
60
|
it "stores all invoices in memory" do
|
55
|
-
expect(Stripe::Invoice.
|
61
|
+
expect(Stripe::Invoice.list.map(&:id)).to match_array([@invoice.id, @invoice2.id])
|
56
62
|
end
|
57
63
|
|
58
64
|
it "defaults count to 10 invoices" do
|
59
65
|
11.times { Stripe::Invoice.create }
|
60
|
-
expect(Stripe::Invoice.
|
66
|
+
expect(Stripe::Invoice.list.count).to eq(10)
|
61
67
|
end
|
62
68
|
|
63
69
|
it "is marked as having more when more objects exist" do
|
64
70
|
11.times { Stripe::Invoice.create }
|
65
71
|
|
66
|
-
expect(Stripe::Invoice.
|
72
|
+
expect(Stripe::Invoice.list.has_more).to eq(true)
|
67
73
|
end
|
68
74
|
|
69
75
|
context "when passing limit" do
|
70
76
|
it "gets that many invoices" do
|
71
|
-
expect(Stripe::Invoice.
|
77
|
+
expect(Stripe::Invoice.list(limit: 1).count).to eq(1)
|
72
78
|
end
|
73
79
|
end
|
74
80
|
end
|
75
81
|
|
82
|
+
context "searching invoices" do
|
83
|
+
# the Search API requires about a minute between writes and reads, so add sleeps accordingly when running live
|
84
|
+
it "searches invoices for exact matches", :aggregate_failures do
|
85
|
+
response = Stripe::Invoice.search({query: 'currency:"usd"'}, stripe_version: '2020-08-27')
|
86
|
+
expect(response.data.size).to eq(0)
|
87
|
+
|
88
|
+
product = stripe_helper.create_product
|
89
|
+
stripe_helper.create_plan(
|
90
|
+
amount: 500,
|
91
|
+
interval: 'month',
|
92
|
+
product: product.id,
|
93
|
+
currency: 'usd',
|
94
|
+
id: 'Sample5',
|
95
|
+
)
|
96
|
+
customer = Stripe::Customer.create(email: 'johnny@appleseed.com', source: stripe_helper.generate_card_token)
|
97
|
+
subscription = Stripe::Subscription.create(customer: customer.id, items: [{plan: 'Sample5'}])
|
98
|
+
one = Stripe::Invoice.create(
|
99
|
+
customer: customer.id,
|
100
|
+
currency: 'usd',
|
101
|
+
subscription: subscription.id,
|
102
|
+
metadata: {key: 'uno'},
|
103
|
+
number: 'one-1',
|
104
|
+
receipt_number: '111',
|
105
|
+
)
|
106
|
+
two = Stripe::Invoice.create(
|
107
|
+
customer: customer.id,
|
108
|
+
currency: 'gbp',
|
109
|
+
subscription: subscription.id,
|
110
|
+
metadata: {key: 'dos'},
|
111
|
+
number: 'two-2',
|
112
|
+
receipt_number: '222',
|
113
|
+
)
|
114
|
+
|
115
|
+
response = Stripe::Invoice.search({query: 'currency:"gbp"'}, stripe_version: '2020-08-27')
|
116
|
+
expect(response.data.map(&:id)).to match_array([two.id])
|
117
|
+
|
118
|
+
response = Stripe::Invoice.search({query: %(customer:"#{customer.id}")}, stripe_version: '2020-08-27')
|
119
|
+
expect(response.data.map(&:id)).to match_array([one.id, two.id])
|
120
|
+
|
121
|
+
response = Stripe::Invoice.search({query: 'number:"one-1"'}, stripe_version: '2020-08-27')
|
122
|
+
expect(response.data.map(&:id)).to match_array([one.id])
|
123
|
+
|
124
|
+
response = Stripe::Invoice.search({query: 'receipt_number:"222"'}, stripe_version: '2020-08-27')
|
125
|
+
expect(response.data.map(&:id)).to match_array([two.id])
|
126
|
+
|
127
|
+
response = Stripe::Invoice.search({query: %(subscription:"#{subscription.id}")}, stripe_version: '2020-08-27')
|
128
|
+
expect(response.data.map(&:id)).to match_array([one.id, two.id])
|
129
|
+
|
130
|
+
response = Stripe::Invoice.search({query: 'total:1000'}, stripe_version: '2020-08-27')
|
131
|
+
expect(response.data.map(&:id)).to match_array([one.id, two.id])
|
132
|
+
|
133
|
+
response = Stripe::Invoice.search({query: 'metadata["key"]:"uno"'}, stripe_version: '2020-08-27')
|
134
|
+
expect(response.data.map(&:id)).to match_array([one.id])
|
135
|
+
end
|
136
|
+
|
137
|
+
it "respects limit", :aggregate_failures do
|
138
|
+
customer = Stripe::Customer.create(email: 'one@one.com', name: 'one', phone: '1111111111', metadata: {key: 'uno'})
|
139
|
+
11.times do
|
140
|
+
Stripe::Invoice.create(customer: customer.id, currency: 'usd')
|
141
|
+
end
|
142
|
+
|
143
|
+
response = Stripe::Invoice.search({query: %(customer:"#{customer.id}")}, stripe_version: '2020-08-27')
|
144
|
+
expect(response.data.size).to eq(10)
|
145
|
+
response = Stripe::Invoice.search({query: %(customer:"#{customer.id}"), limit: 1}, stripe_version: '2020-08-27')
|
146
|
+
expect(response.data.size).to eq(1)
|
147
|
+
end
|
148
|
+
|
149
|
+
it "reports search errors", :aggregate_failures do
|
150
|
+
expect {
|
151
|
+
Stripe::Invoice.search({limit: 1}, stripe_version: '2020-08-27')
|
152
|
+
}.to raise_error(Stripe::InvalidRequestError, /Missing required param: query./)
|
153
|
+
|
154
|
+
expect {
|
155
|
+
Stripe::Invoice.search({query: 'asdf'}, stripe_version: '2020-08-27')
|
156
|
+
}.to raise_error(Stripe::InvalidRequestError, /We were unable to parse your search query./)
|
157
|
+
|
158
|
+
expect {
|
159
|
+
Stripe::Invoice.search({query: 'foo:"bar"'}, stripe_version: '2020-08-27')
|
160
|
+
}.to raise_error(Stripe::InvalidRequestError, /Field `foo` is an unsupported search field for resource `invoices`./)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
76
164
|
context "paying an invoice" do
|
77
165
|
before do
|
78
166
|
@invoice = Stripe::Invoice.create
|
@@ -82,12 +170,28 @@ shared_examples 'Invoice API' do
|
|
82
170
|
@invoice = @invoice.pay
|
83
171
|
expect(@invoice.attempted).to eq(true)
|
84
172
|
expect(@invoice.paid).to eq(true)
|
173
|
+
expect(@invoice.status).to eq("paid")
|
85
174
|
end
|
86
175
|
|
87
176
|
it 'creates a new charge object' do
|
88
177
|
expect{ @invoice.pay }.to change { Stripe::Charge.list.data.count }.by 1
|
89
178
|
end
|
90
179
|
|
180
|
+
it 'should work with Stripe::Invoice.pay(invoice_id)' do
|
181
|
+
expect(@invoice.paid).to_not eq(true)
|
182
|
+
|
183
|
+
expect {
|
184
|
+
Stripe::Invoice.pay(@invoice.id)
|
185
|
+
}.to change { Stripe::Charge.list.data.count }.by 1
|
186
|
+
|
187
|
+
@invoice = Stripe::Invoice.retrieve(id: @invoice.id)
|
188
|
+
expect(@invoice).to_not be_nil
|
189
|
+
|
190
|
+
expect(@invoice.attempted).to eq(true)
|
191
|
+
expect(@invoice.paid).to eq(true)
|
192
|
+
expect(@invoice.status).to eq("paid")
|
193
|
+
end
|
194
|
+
|
91
195
|
it 'sets the charge attribute' do
|
92
196
|
@invoice = @invoice.pay
|
93
197
|
expect(@invoice.charge).to be_a String
|
@@ -109,8 +213,9 @@ shared_examples 'Invoice API' do
|
|
109
213
|
context "retrieving upcoming invoice" do
|
110
214
|
let(:customer) { Stripe::Customer.create(source: stripe_helper.generate_card_token) }
|
111
215
|
let(:coupon_amtoff) { stripe_helper.create_coupon(id: '100OFF', currency: 'usd', amount_off: 100_00, duration: 'repeating', duration_in_months: 6) }
|
112
|
-
let(:coupon_pctoff) { stripe_helper.create_coupon(id: '
|
113
|
-
let(:
|
216
|
+
let(:coupon_pctoff) { stripe_helper.create_coupon(id: '50OFF', currency: 'usd', percent_off: 50, amount_off: nil, duration: 'repeating', duration_in_months: 6) }
|
217
|
+
let(:product) { stripe_helper.create_product(id: "prod_123") }
|
218
|
+
let(:plan) { stripe_helper.create_plan(id: '50m', product: product.id, amount: 50_00, interval: 'month', nickname: '50m', currency: 'usd') }
|
114
219
|
let(:quantity) { 3 }
|
115
220
|
let(:subscription) { Stripe::Subscription.create(plan: plan.id, customer: customer.id, quantity: quantity) }
|
116
221
|
|
@@ -131,7 +236,10 @@ shared_examples 'Invoice API' do
|
|
131
236
|
describe 'parameter validation' do
|
132
237
|
it 'fails without parameters' do
|
133
238
|
expect { Stripe::Invoice.upcoming() }.to raise_error {|e|
|
134
|
-
|
239
|
+
expect(e).to be_a(Stripe::InvalidRequestError)
|
240
|
+
expect(e.http_status).to eq(400)
|
241
|
+
expect(e.message).to eq('Missing required param: customer if subscription is not provided')
|
242
|
+
}
|
135
243
|
end
|
136
244
|
|
137
245
|
it 'fails without a valid customer' do
|
@@ -144,7 +252,7 @@ shared_examples 'Invoice API' do
|
|
144
252
|
expect { Stripe::Invoice.upcoming(gazebo: 'raindance') }.to raise_error {|e|
|
145
253
|
expect(e).to be_a(Stripe::InvalidRequestError)
|
146
254
|
expect(e.http_status).to eq(400)
|
147
|
-
expect(e.message).to eq('Missing required param: customer') }
|
255
|
+
expect(e.message).to eq('Missing required param: customer if subscription is not provided') }
|
148
256
|
end
|
149
257
|
|
150
258
|
it 'fails without a subscription' do
|
@@ -198,8 +306,8 @@ shared_examples 'Invoice API' do
|
|
198
306
|
expect(upcoming.discount).not_to be_nil
|
199
307
|
expect(upcoming.discount.coupon.id).to eq '100OFF'
|
200
308
|
expect(upcoming.discount.customer).to eq customer.id
|
201
|
-
expect(upcoming.discount.start).to be_within(
|
202
|
-
expect(upcoming.discount.end).to be_within(
|
309
|
+
expect(upcoming.discount.start).to be_within(60).of Time.now.to_i
|
310
|
+
expect(upcoming.discount.end).to be_within(60).of (Time.now.to_datetime >> 6).to_time.to_i
|
203
311
|
expect(upcoming.amount_due).to eq plan.amount * quantity - 100_00
|
204
312
|
expect(upcoming.subtotal).to eq(upcoming.lines.data[0].amount)
|
205
313
|
expect(upcoming.total).to eq upcoming.subtotal - 100_00
|
@@ -211,10 +319,10 @@ shared_examples 'Invoice API' do
|
|
211
319
|
|
212
320
|
# Then
|
213
321
|
expect(upcoming.discount).not_to be_nil
|
214
|
-
expect(upcoming.discount.coupon.id).to eq '
|
322
|
+
expect(upcoming.discount.coupon.id).to eq '50OFF'
|
215
323
|
expect(upcoming.discount.customer).to eq customer.id
|
216
|
-
expect(upcoming.discount.start).to be_within(
|
217
|
-
expect(upcoming.discount.end).to be_within(
|
324
|
+
expect(upcoming.discount.start).to be_within(60).of Time.now.to_i
|
325
|
+
expect(upcoming.discount.end).to be_within(60).of (Time.now.to_datetime >> 6).to_time.to_i
|
218
326
|
expect(upcoming.amount_due).to eq (plan.amount * quantity) * 0.5
|
219
327
|
expect(upcoming.subtotal).to eq(upcoming.lines.data[0].amount)
|
220
328
|
expect(upcoming.total).to eq upcoming.subtotal * 0.5
|
@@ -223,7 +331,7 @@ shared_examples 'Invoice API' do
|
|
223
331
|
|
224
332
|
describe 'proration' do
|
225
333
|
shared_examples 'failing when proration date is outside of the subscription current period' do
|
226
|
-
it 'fails', live: true do
|
334
|
+
it 'fails', live: true, skip: 'Stripe does not raise error anymore' do
|
227
335
|
expect { Stripe::Invoice.upcoming(
|
228
336
|
customer: customer.id,
|
229
337
|
subscription: subscription.id,
|
@@ -248,9 +356,9 @@ shared_examples 'Invoice API' do
|
|
248
356
|
|
249
357
|
[false, true].each do |with_trial|
|
250
358
|
describe "prorating a subscription with a new plan, with_trial: #{with_trial}" do
|
251
|
-
let(:new_monthly_plan) { stripe_helper.create_plan(id: '100m', amount: 100_00, interval: 'month'
|
252
|
-
let(:new_yearly_plan) { stripe_helper.create_plan(id: '100y', amount: 100_00, interval: 'year'
|
253
|
-
let(:plan) { stripe_helper.create_plan(id: '50m', amount: 50_00, interval: 'month'
|
359
|
+
let(:new_monthly_plan) { stripe_helper.create_plan(id: '100m', product: product.id, amount: 100_00, interval: 'month') }
|
360
|
+
let(:new_yearly_plan) { stripe_helper.create_plan(id: '100y', product: product.id, amount: 100_00, interval: 'year') }
|
361
|
+
let(:plan) { stripe_helper.create_plan(id: '50m', product: product.id, amount: 50_00, interval: 'month') }
|
254
362
|
|
255
363
|
it 'prorates while maintaining billing interval', live: true do
|
256
364
|
# Given
|
@@ -271,19 +379,17 @@ shared_examples 'Invoice API' do
|
|
271
379
|
# Then
|
272
380
|
expect(upcoming).to be_a Stripe::Invoice
|
273
381
|
expect(upcoming.customer).to eq(customer.id)
|
274
|
-
if with_trial
|
275
|
-
expect(upcoming.amount_due).to be_within(1).of 0
|
276
|
-
else
|
277
|
-
expect(upcoming.amount_due).to be_within(1).of prorated_amount_due - credit_balance
|
278
|
-
end
|
279
382
|
expect(upcoming.starting_balance).to eq -credit_balance
|
280
|
-
expect(upcoming.ending_balance).to be_nil
|
281
383
|
expect(upcoming.subscription).to eq(subscription.id)
|
282
384
|
|
283
385
|
if with_trial
|
386
|
+
expect(upcoming.amount_due).to be_within(1).of 0
|
284
387
|
expect(upcoming.lines.data.length).to eq(2)
|
388
|
+
# expect(upcoming.ending_balance).to be_within(50).of -13540 # -13322
|
285
389
|
else
|
390
|
+
expect(upcoming.amount_due).to be_within(1).of prorated_amount_due - credit_balance
|
286
391
|
expect(upcoming.lines.data.length).to eq(3)
|
392
|
+
expect(upcoming.ending_balance).to eq 0
|
287
393
|
end
|
288
394
|
|
289
395
|
expect(upcoming.lines.data[0].proration).to be_truthy
|
@@ -308,9 +414,10 @@ shared_examples 'Invoice API' do
|
|
308
414
|
# Given
|
309
415
|
proration_date = Time.now + 5 * 24 * 3600 # 5 days later
|
310
416
|
new_quantity = 2
|
311
|
-
unused_amount = plan.amount * quantity * (subscription.current_period_end - proration_date.to_i) / (subscription.current_period_end - subscription.current_period_start)
|
417
|
+
unused_amount = (plan.amount.to_f * quantity * (subscription.current_period_end - proration_date.to_i) / (subscription.current_period_end - subscription.current_period_start)).round
|
312
418
|
prorated_amount_due = new_yearly_plan.amount * new_quantity - unused_amount
|
313
419
|
credit_balance = 1000
|
420
|
+
amount_due = prorated_amount_due - credit_balance
|
314
421
|
customer.account_balance = -credit_balance
|
315
422
|
customer.save
|
316
423
|
query = { customer: customer.id, subscription: subscription.id, subscription_plan: new_yearly_plan.id, subscription_proration_date: proration_date.to_i, subscription_quantity: new_quantity }
|
@@ -323,12 +430,13 @@ shared_examples 'Invoice API' do
|
|
323
430
|
expect(upcoming).to be_a Stripe::Invoice
|
324
431
|
expect(upcoming.customer).to eq(customer.id)
|
325
432
|
if with_trial
|
433
|
+
# expect(upcoming.ending_balance).to be_within(50).of -13540 # -13322
|
326
434
|
expect(upcoming.amount_due).to eq 0
|
327
435
|
else
|
328
|
-
expect(upcoming.
|
436
|
+
expect(upcoming.ending_balance).to eq 0
|
437
|
+
expect(upcoming.amount_due).to be_within(1).of amount_due
|
329
438
|
end
|
330
439
|
expect(upcoming.starting_balance).to eq -credit_balance
|
331
|
-
expect(upcoming.ending_balance).to be_nil
|
332
440
|
expect(upcoming.subscription).to eq(subscription.id)
|
333
441
|
|
334
442
|
expect(upcoming.lines.data[0].proration).to be_truthy
|
@@ -351,7 +459,7 @@ shared_examples 'Invoice API' do
|
|
351
459
|
it 'generates a preview without performing an actual proration', live: true do
|
352
460
|
expect(preview.subtotal).to eq 150_00
|
353
461
|
# this is a future invoice (generted at the end of the current subscription cycle), rather than a proration invoice
|
354
|
-
expect(preview.
|
462
|
+
expect(preview.due_date).to be_nil
|
355
463
|
expect(preview.period_start).to eq subscription.current_period_start
|
356
464
|
expect(preview.period_end).to eq subscription.current_period_end
|
357
465
|
expect(preview.lines.count).to eq 1
|
@@ -393,7 +501,7 @@ shared_examples 'Invoice API' do
|
|
393
501
|
end
|
394
502
|
|
395
503
|
it 'sets the start and end of billing periods correctly when plan has an interval_count' do
|
396
|
-
@oddplan = stripe_helper.create_plan(interval: "week", interval_count: 11)
|
504
|
+
@oddplan = stripe_helper.create_plan(product: product.id, interval: "week", interval_count: 11, id: "weekly_pl")
|
397
505
|
@subscription = Stripe::Subscription.create(plan: @oddplan.id, customer: customer.id)
|
398
506
|
@upcoming = Stripe::Invoice.upcoming(customer: customer.id)
|
399
507
|
|
@@ -404,9 +512,9 @@ shared_examples 'Invoice API' do
|
|
404
512
|
end
|
405
513
|
|
406
514
|
it 'chooses the most recent of multiple subscriptions' do
|
407
|
-
@shortplan = stripe_helper.create_plan(id: 'a', interval: "week") # 1 week sub
|
408
|
-
@plainplan = stripe_helper.create_plan(id: 'b')
|
409
|
-
@longplan = stripe_helper.create_plan(id: 'c', interval: "year") # 1 year sub
|
515
|
+
@shortplan = stripe_helper.create_plan(id: 'a', product: product.id, interval: "week") # 1 week sub
|
516
|
+
@plainplan = stripe_helper.create_plan(id: 'b', product: product.id, interval: "month") # 1 month sub
|
517
|
+
@longplan = stripe_helper.create_plan(id: 'c', product: product.id, interval: "year") # 1 year sub
|
410
518
|
|
411
519
|
@plainsub = Stripe::Subscription.create(plan: @plainplan.id, customer: customer.id)
|
412
520
|
@shortsub = Stripe::Subscription.create(plan: @shortplan.id, customer: customer.id)
|
@@ -428,7 +536,7 @@ shared_examples 'Invoice API' do
|
|
428
536
|
context 'retrieving invoice line items' do
|
429
537
|
it 'returns all line items for created invoice' do
|
430
538
|
invoice = Stripe::Invoice.create(customer: customer.id)
|
431
|
-
line_items = invoice.lines.
|
539
|
+
line_items = invoice.lines.list
|
432
540
|
|
433
541
|
expect(invoice).to be_a Stripe::Invoice
|
434
542
|
expect(line_items.count).to eq(1)
|
@@ -438,7 +546,7 @@ shared_examples 'Invoice API' do
|
|
438
546
|
end
|
439
547
|
|
440
548
|
it 'returns all line items for upcoming invoice' do
|
441
|
-
plan = stripe_helper.create_plan()
|
549
|
+
plan = stripe_helper.create_plan(product: product.id, id: "silver_pl")
|
442
550
|
subscription = Stripe::Subscription.create(plan: plan.id, customer: customer.id)
|
443
551
|
upcoming = Stripe::Invoice.upcoming(customer: customer.id)
|
444
552
|
line_items = upcoming.lines
|
@@ -454,7 +562,7 @@ shared_examples 'Invoice API' do
|
|
454
562
|
context 'calculates month and year offsets correctly' do
|
455
563
|
|
456
564
|
it 'for one month plan on the 1st' do
|
457
|
-
@plan = stripe_helper.create_plan()
|
565
|
+
@plan = stripe_helper.create_plan(product: product.id, id: "one_mo_plan")
|
458
566
|
@sub = Stripe::Subscription.create(plan: @plan.id, customer: customer.id, current_period_start: Time.utc(2014,1,1,12).to_i)
|
459
567
|
@upcoming = Stripe::Invoice.upcoming(customer: customer.id)
|
460
568
|
|
@@ -465,7 +573,7 @@ shared_examples 'Invoice API' do
|
|
465
573
|
end
|
466
574
|
|
467
575
|
it 'for one year plan on the 1st' do
|
468
|
-
@plan = stripe_helper.create_plan(interval: "year")
|
576
|
+
@plan = stripe_helper.create_plan(interval: "year", product: product.id, id: "year_plan")
|
469
577
|
@sub = Stripe::Subscription.create(plan: @plan.id, customer: customer.id, current_period_start: Time.utc(2012,1,1,12).to_i)
|
470
578
|
@upcoming = Stripe::Invoice.upcoming(customer: customer.id)
|
471
579
|
|
@@ -476,7 +584,7 @@ shared_examples 'Invoice API' do
|
|
476
584
|
end
|
477
585
|
|
478
586
|
it 'for one month plan on the 31st' do
|
479
|
-
@plan = stripe_helper.create_plan()
|
587
|
+
@plan = stripe_helper.create_plan(product: product.id, id: "one_mo_plan")
|
480
588
|
@sub = Stripe::Subscription.create(plan: @plan.id, customer: customer.id, current_period_start: Time.utc(2014,1,31,12).to_i)
|
481
589
|
@upcoming = Stripe::Invoice.upcoming(customer: customer.id)
|
482
590
|
|
@@ -487,7 +595,7 @@ shared_examples 'Invoice API' do
|
|
487
595
|
end
|
488
596
|
|
489
597
|
it 'for one year plan on feb. 29th' do
|
490
|
-
@plan = stripe_helper.create_plan(interval: "year")
|
598
|
+
@plan = stripe_helper.create_plan(product: product.id, interval: "year", id: "year_plan")
|
491
599
|
@sub = Stripe::Subscription.create(plan: @plan.id, customer: customer.id, current_period_start: Time.utc(2012,2,29,12).to_i)
|
492
600
|
@upcoming = Stripe::Invoice.upcoming(customer: customer.id)
|
493
601
|
|
@@ -498,7 +606,7 @@ shared_examples 'Invoice API' do
|
|
498
606
|
end
|
499
607
|
|
500
608
|
it 'for two month plan on dec. 31st' do
|
501
|
-
@plan = stripe_helper.create_plan(interval_count: 2)
|
609
|
+
@plan = stripe_helper.create_plan(product: product.id, interval_count: 2, id: 'two_mo_plan')
|
502
610
|
@sub = Stripe::Subscription.create(plan: @plan.id, customer: customer.id, current_period_start: Time.utc(2013,12,31,12).to_i)
|
503
611
|
@upcoming = Stripe::Invoice.upcoming(customer: customer.id)
|
504
612
|
|
@@ -509,7 +617,7 @@ shared_examples 'Invoice API' do
|
|
509
617
|
end
|
510
618
|
|
511
619
|
it 'for three month plan on nov. 30th' do
|
512
|
-
@plan = stripe_helper.create_plan(interval_count: 3)
|
620
|
+
@plan = stripe_helper.create_plan(product: product.id, interval_count: 3)
|
513
621
|
@sub = Stripe::Subscription.create(plan: @plan.id, customer: customer.id, current_period_start: Time.utc(2013,11,30,12).to_i)
|
514
622
|
@upcoming = Stripe::Invoice.upcoming(customer: customer.id)
|
515
623
|
|