stripe-ruby-mock 2.5.6 → 2.5.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/stripe_mock.rb +1 -0
- data/lib/stripe_mock/data.rb +17 -2
- data/lib/stripe_mock/instance.rb +32 -2
- data/lib/stripe_mock/request_handlers/charges.rb +7 -4
- data/lib/stripe_mock/request_handlers/customers.rb +2 -2
- data/lib/stripe_mock/request_handlers/helpers/coupon_helpers.rb +10 -11
- data/lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb +9 -1
- data/lib/stripe_mock/request_handlers/invoices.rb +1 -1
- data/lib/stripe_mock/request_handlers/products.rb +43 -0
- data/lib/stripe_mock/request_handlers/refunds.rb +6 -3
- data/lib/stripe_mock/request_handlers/subscriptions.rb +40 -22
- data/lib/stripe_mock/request_handlers/tokens.rb +2 -2
- data/lib/stripe_mock/version.rb +1 -1
- data/lib/stripe_mock/webhook_fixtures/invoice.created.json +1 -1
- data/lib/stripe_mock/webhook_fixtures/invoice.payment_succeeded.json +1 -1
- data/lib/stripe_mock/webhook_fixtures/invoice.updated.json +1 -1
- data/spec/shared_stripe_examples/charge_examples.rb +23 -14
- data/spec/shared_stripe_examples/customer_examples.rb +1 -1
- data/spec/shared_stripe_examples/invoice_examples.rb +1 -1
- data/spec/shared_stripe_examples/plan_examples.rb +1 -1
- data/spec/shared_stripe_examples/product_example.rb +65 -0
- data/spec/shared_stripe_examples/refund_examples.rb +16 -10
- data/spec/shared_stripe_examples/subscription_examples.rb +128 -2
- data/spec/shared_stripe_examples/transfer_examples.rb +5 -5
- data/spec/support/stripe_examples.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c1a6cfda90439e30a5198b5e83135070138179b
|
4
|
+
data.tar.gz: d1a78b4802fe6b7d37c11b104eec9a0c08f06b40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9bd40fd514426cb1a58c52bd2b1c3841bff41a5c8a2a73e8a3dbfb43fc98422b3c51f8b7761e7e7f2a010afd0bb260db5778e2796dd501ce0c28d63e53dca783
|
7
|
+
data.tar.gz: bedeb87ade1eeba6a46e9573628187bb66f1bd886233cf21f60383668350f95a9562b53f16f4d7068169393782e54d62e5f9ea680ea8b7a6849c2fe225ace4ea
|
data/README.md
CHANGED
data/lib/stripe_mock.rb
CHANGED
@@ -70,6 +70,7 @@ require 'stripe_mock/request_handlers/subscriptions.rb'
|
|
70
70
|
require 'stripe_mock/request_handlers/tokens.rb'
|
71
71
|
require 'stripe_mock/request_handlers/country_spec.rb'
|
72
72
|
require 'stripe_mock/request_handlers/ephemeral_key.rb'
|
73
|
+
require 'stripe_mock/request_handlers/products.rb'
|
73
74
|
require 'stripe_mock/instance'
|
74
75
|
|
75
76
|
require 'stripe_mock/test_strategies/base.rb'
|
data/lib/stripe_mock/data.rb
CHANGED
@@ -335,7 +335,7 @@ module StripeMock
|
|
335
335
|
lines << Data.mock_line_item() if lines.empty?
|
336
336
|
invoice = {
|
337
337
|
id: 'in_test_invoice',
|
338
|
-
|
338
|
+
created: 1349738950,
|
339
339
|
period_end: 1349738950,
|
340
340
|
period_start: 1349738950,
|
341
341
|
lines: {
|
@@ -409,7 +409,7 @@ module StripeMock
|
|
409
409
|
{
|
410
410
|
id: "test_ii",
|
411
411
|
object: "invoiceitem",
|
412
|
-
|
412
|
+
created: 1349738920,
|
413
413
|
amount: 1099,
|
414
414
|
livemode: false,
|
415
415
|
proration: false,
|
@@ -510,6 +510,21 @@ module StripeMock
|
|
510
510
|
}.merge(params)
|
511
511
|
end
|
512
512
|
|
513
|
+
def self.mock_product(params = {})
|
514
|
+
{
|
515
|
+
id: "default_test_prod",
|
516
|
+
object: "product",
|
517
|
+
active: true,
|
518
|
+
created: 1556896214,
|
519
|
+
livemode: false,
|
520
|
+
metadata: {},
|
521
|
+
name: "Default Test Product",
|
522
|
+
statement_descriptor: "PRODUCT",
|
523
|
+
type: "service",
|
524
|
+
updated: 1556918200,
|
525
|
+
}.merge(params)
|
526
|
+
end
|
527
|
+
|
513
528
|
def self.mock_recipient(cards, params={})
|
514
529
|
rp_id = params[:id] || "test_rp_default"
|
515
530
|
cards.each {|card| card[:recipient] = rp_id}
|
data/lib/stripe_mock/instance.rb
CHANGED
@@ -36,6 +36,7 @@ module StripeMock
|
|
36
36
|
include StripeMock::RequestHandlers::InvoiceItems
|
37
37
|
include StripeMock::RequestHandlers::Orders
|
38
38
|
include StripeMock::RequestHandlers::Plans
|
39
|
+
include StripeMock::RequestHandlers::Products
|
39
40
|
include StripeMock::RequestHandlers::Refunds
|
40
41
|
include StripeMock::RequestHandlers::Recipients
|
41
42
|
include StripeMock::RequestHandlers::Transfers
|
@@ -46,7 +47,8 @@ module StripeMock
|
|
46
47
|
|
47
48
|
attr_reader :accounts, :balance, :balance_transactions, :bank_tokens, :charges, :coupons, :customers,
|
48
49
|
:disputes, :events, :invoices, :invoice_items, :orders, :plans, :recipients,
|
49
|
-
:refunds, :transfers, :payouts, :subscriptions, :country_spec, :subscriptions_items
|
50
|
+
:refunds, :transfers, :payouts, :subscriptions, :country_spec, :subscriptions_items,
|
51
|
+
:products
|
50
52
|
|
51
53
|
attr_accessor :error_queue, :debug, :conversion_rate, :account_balance
|
52
54
|
|
@@ -65,6 +67,7 @@ module StripeMock
|
|
65
67
|
@invoice_items = {}
|
66
68
|
@orders = {}
|
67
69
|
@plans = {}
|
70
|
+
@products = {}
|
68
71
|
@recipients = {}
|
69
72
|
@refunds = {}
|
70
73
|
@transfers = {}
|
@@ -175,7 +178,8 @@ module StripeMock
|
|
175
178
|
amount = params[:amount]
|
176
179
|
unless amount.nil?
|
177
180
|
# Fee calculation
|
178
|
-
params[:fee]
|
181
|
+
calculate_fees(params) unless params[:fee]
|
182
|
+
params[:net] = amount - params[:fee]
|
179
183
|
params[:amount] = amount * @conversion_rate
|
180
184
|
end
|
181
185
|
@balance_transactions[id] = Data.mock_balance_transaction(params.merge(id: id))
|
@@ -196,5 +200,31 @@ module StripeMock
|
|
196
200
|
response = Struct.new(:data)
|
197
201
|
response.new(hash)
|
198
202
|
end
|
203
|
+
|
204
|
+
def calculate_fees(params)
|
205
|
+
application_fee = params[:application_fee] || 0
|
206
|
+
params[:fee] = processing_fee(params[:amount]) + application_fee
|
207
|
+
params[:fee_details] = [
|
208
|
+
{
|
209
|
+
amount: processing_fee(params[:amount]),
|
210
|
+
application: nil,
|
211
|
+
currency: params[:currency] || StripeMock.default_currency,
|
212
|
+
description: "Stripe processing fees",
|
213
|
+
type: "stripe_fee"
|
214
|
+
}
|
215
|
+
]
|
216
|
+
if application_fee
|
217
|
+
params[:fee_details] << {
|
218
|
+
amount: application_fee,
|
219
|
+
currency: params[:currency] || StripeMock.default_currency,
|
220
|
+
description: "Application fee",
|
221
|
+
type: "application_fee"
|
222
|
+
}
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def processing_fee(amount)
|
227
|
+
(30 + (amount.abs * 0.029).ceil) * (amount > 0 ? 1 : -1)
|
228
|
+
end
|
199
229
|
end
|
200
230
|
end
|
@@ -13,9 +13,12 @@ module StripeMock
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def new_charge(route, method_url, params, headers)
|
16
|
-
if
|
17
|
-
|
18
|
-
|
16
|
+
if headers && headers[:idempotency_key]
|
17
|
+
params[:idempotency_key] = headers[:idempotency_key]
|
18
|
+
if charges.any?
|
19
|
+
original_charge = charges.values.find { |c| c[:idempotency_key] == headers[:idempotency_key]}
|
20
|
+
return charges[original_charge[:id]] if original_charge
|
21
|
+
end
|
19
22
|
end
|
20
23
|
|
21
24
|
id = new_id('ch')
|
@@ -41,7 +44,7 @@ module StripeMock
|
|
41
44
|
end
|
42
45
|
|
43
46
|
ensure_required_params(params)
|
44
|
-
bal_trans_params = { amount: params[:amount], source: id }
|
47
|
+
bal_trans_params = { amount: params[:amount], source: id, application_fee: params[:application_fee] }
|
45
48
|
|
46
49
|
balance_transaction_id = new_balance_transaction('txn', bal_trans_params)
|
47
50
|
|
@@ -51,7 +51,7 @@ module StripeMock
|
|
51
51
|
coupon = coupons[ params[:coupon] ]
|
52
52
|
assert_existence :coupon, params[:coupon], coupon
|
53
53
|
|
54
|
-
|
54
|
+
add_coupon_to_object(customers[params[:id]], coupon)
|
55
55
|
end
|
56
56
|
|
57
57
|
customers[ params[:id] ]
|
@@ -90,7 +90,7 @@ module StripeMock
|
|
90
90
|
coupon = coupons[ params[:coupon] ]
|
91
91
|
assert_existence :coupon, params[:coupon], coupon
|
92
92
|
|
93
|
-
|
93
|
+
add_coupon_to_object(cus, coupon)
|
94
94
|
end
|
95
95
|
|
96
96
|
cus
|
@@ -1,18 +1,17 @@
|
|
1
1
|
module StripeMock
|
2
2
|
module RequestHandlers
|
3
3
|
module Helpers
|
4
|
+
def add_coupon_to_object(object, coupon)
|
5
|
+
discount_attrs = {}.tap do |attrs|
|
6
|
+
attrs[object[:object]] = object[:id]
|
7
|
+
attrs[:coupon] = coupon
|
8
|
+
attrs[:start] = Time.now.to_i
|
9
|
+
attrs[:end] = (DateTime.now >> coupon[:duration_in_months].to_i).to_time.to_i if coupon[:duration] == 'repeating'
|
10
|
+
end
|
4
11
|
|
5
|
-
|
6
|
-
|
7
|
-
coupon: coupon,
|
8
|
-
customer: customer[:id],
|
9
|
-
start: Time.now.to_i,
|
10
|
-
}
|
11
|
-
customer[:discount][:end] = (DateTime.now >> coupon[:duration_in_months]).to_time.to_i if coupon[:duration].to_sym == :repeating && coupon[:duration_in_months]
|
12
|
-
|
13
|
-
customer
|
12
|
+
object[:discount] = Stripe::Discount.construct_from(discount_attrs)
|
13
|
+
object
|
14
14
|
end
|
15
|
-
|
16
15
|
end
|
17
16
|
end
|
18
|
-
end
|
17
|
+
end
|
@@ -30,7 +30,15 @@ module StripeMock
|
|
30
30
|
start_time = options[:current_period_start] || now
|
31
31
|
params = { customer: cus[:id], current_period_start: start_time, created: created_time }
|
32
32
|
params.merge!({ :plan => (plans.size == 1 ? plans.first : nil) })
|
33
|
-
|
33
|
+
keys_to_merge = /application_fee_percent|quantity|metadata|tax_percent|billing|days_until_due/
|
34
|
+
params.merge! options.select {|k,v| k =~ keys_to_merge}
|
35
|
+
|
36
|
+
if options[:cancel_at_period_end] == true
|
37
|
+
params.merge!(cancel_at_period_end: true, canceled_at: now)
|
38
|
+
elsif options[:cancel_at_period_end] == false
|
39
|
+
params.merge!(cancel_at_period_end: false, canceled_at: nil)
|
40
|
+
end
|
41
|
+
|
34
42
|
# TODO: Implement coupon logic
|
35
43
|
|
36
44
|
if (((plan && plan[:trial_period_days]) || 0) == 0 && options[:trial_end].nil?) || options[:trial_end] == "now"
|
@@ -138,7 +138,7 @@ module StripeMock
|
|
138
138
|
id: new_id('in'),
|
139
139
|
customer: customer[:id],
|
140
140
|
discount: customer[:discount],
|
141
|
-
|
141
|
+
created: invoice_date,
|
142
142
|
starting_balance: customer[:account_balance],
|
143
143
|
subscription: preview_subscription[:id],
|
144
144
|
period_start: prorating ? invoice_date : preview_subscription[:current_period_start],
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module StripeMock
|
2
|
+
module RequestHandlers
|
3
|
+
module Products
|
4
|
+
def self.included(base)
|
5
|
+
base.add_handler 'post /v1/products', :create_product
|
6
|
+
base.add_handler 'get /v1/products/(.*)', :retrieve_product
|
7
|
+
base.add_handler 'post /v1/products/(.*)', :update_product
|
8
|
+
base.add_handler 'get /v1/products', :list_products
|
9
|
+
base.add_handler 'delete /v1/products/(.*)', :destroy_product
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_product(_route, _method_url, params, _headers)
|
13
|
+
params[:id] ||= new_id('prod')
|
14
|
+
products[params[:id]] = Data.mock_product(params)
|
15
|
+
end
|
16
|
+
|
17
|
+
def retrieve_product(route, method_url, _params, _headers)
|
18
|
+
id = method_url.match(route).captures.first
|
19
|
+
assert_existence :product, id, products[id]
|
20
|
+
end
|
21
|
+
|
22
|
+
def update_product(route, method_url, params, _headers)
|
23
|
+
id = method_url.match(route).captures.first
|
24
|
+
product = assert_existence :product, id, products[id]
|
25
|
+
|
26
|
+
product.merge!(params)
|
27
|
+
end
|
28
|
+
|
29
|
+
def list_products(_route, _method_url, params, _headers)
|
30
|
+
limit = params[:limit] || 10
|
31
|
+
Data.mock_list_object(products.values.take(limit), params)
|
32
|
+
end
|
33
|
+
|
34
|
+
def destroy_product(route, method_url, _params, _headers)
|
35
|
+
id = method_url.match(route).captures.first
|
36
|
+
assert_existence :product, id, products[id]
|
37
|
+
|
38
|
+
products.delete(id)
|
39
|
+
{ id: id, object: 'product', deleted: true }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -10,9 +10,12 @@ module StripeMock
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def new_refund(route, method_url, params, headers)
|
13
|
-
if
|
14
|
-
|
15
|
-
|
13
|
+
if headers && headers[:idempotency_key]
|
14
|
+
params[:idempotency_key] = headers[:idempotency_key]
|
15
|
+
if refunds.any?
|
16
|
+
original_refund = refunds.values.find { |c| c[:idempotency_key] == headers[:idempotency_key]}
|
17
|
+
return refunds[original_refund[:id]] if original_refund
|
18
|
+
end
|
16
19
|
end
|
17
20
|
|
18
21
|
charge = assert_existence :charge, params[:charge], charges[params[:charge]]
|
@@ -60,7 +60,7 @@ module StripeMock
|
|
60
60
|
coupon = coupons[coupon_id]
|
61
61
|
|
62
62
|
if coupon
|
63
|
-
subscription
|
63
|
+
add_coupon_to_object(subscription, coupon)
|
64
64
|
else
|
65
65
|
raise Stripe::InvalidRequestError.new("No such coupon: #{coupon_id}", 'coupon', http_status: 400)
|
66
66
|
end
|
@@ -73,6 +73,13 @@ module StripeMock
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def create_subscription(route, method_url, params, headers)
|
76
|
+
if headers && headers[:idempotency_key]
|
77
|
+
if subscriptions.any?
|
78
|
+
original_subscription = subscriptions.values.find { |c| c[:idempotency_key] == headers[:idempotency_key]}
|
79
|
+
puts original_subscription
|
80
|
+
return subscriptions[original_subscription[:id]] if original_subscription
|
81
|
+
end
|
82
|
+
end
|
76
83
|
route =~ method_url
|
77
84
|
|
78
85
|
subscription_plans = get_subscription_plans_from_params(params)
|
@@ -95,7 +102,7 @@ module StripeMock
|
|
95
102
|
customer[:default_source] = new_card[:id]
|
96
103
|
end
|
97
104
|
|
98
|
-
allowed_params = %w(customer application_fee_percent coupon items metadata plan quantity source tax_percent trial_end trial_period_days current_period_start created prorate billing_cycle_anchor)
|
105
|
+
allowed_params = %w(customer application_fee_percent coupon items metadata plan quantity source tax_percent trial_end trial_period_days current_period_start created prorate billing_cycle_anchor billing days_until_due idempotency_key)
|
99
106
|
unknown_params = params.keys - allowed_params.map(&:to_sym)
|
100
107
|
if unknown_params.length > 0
|
101
108
|
raise Stripe::InvalidRequestError.new("Received unknown parameter: #{unknown_params.join}", unknown_params.first.to_s, http_status: 400)
|
@@ -103,6 +110,9 @@ module StripeMock
|
|
103
110
|
|
104
111
|
subscription = Data.mock_subscription({ id: (params[:id] || new_id('su')) })
|
105
112
|
subscription = resolve_subscription_changes(subscription, subscription_plans, customer, params)
|
113
|
+
if headers[:idempotency_key]
|
114
|
+
subscription[:idempotency_key] = headers[:idempotency_key]
|
115
|
+
end
|
106
116
|
|
107
117
|
# Ensure customer has card to charge if plan has no trial and is not free
|
108
118
|
# Note: needs updating for subscriptions with multiple plans
|
@@ -117,7 +127,7 @@ module StripeMock
|
|
117
127
|
coupon = coupons[coupon_id]
|
118
128
|
|
119
129
|
if coupon
|
120
|
-
subscription
|
130
|
+
add_coupon_to_object(subscription, coupon)
|
121
131
|
else
|
122
132
|
raise Stripe::InvalidRequestError.new("No such coupon: #{coupon_id}", 'coupon', http_status: 400)
|
123
133
|
end
|
@@ -174,9 +184,9 @@ module StripeMock
|
|
174
184
|
|
175
185
|
coupon = coupons[coupon_id]
|
176
186
|
if coupon
|
177
|
-
subscription
|
187
|
+
add_coupon_to_object(subscription, coupon)
|
178
188
|
elsif coupon_id == ""
|
179
|
-
subscription[:discount] =
|
189
|
+
subscription[:discount] = nil
|
180
190
|
else
|
181
191
|
raise Stripe::InvalidRequestError.new("No such coupon: #{coupon_id}", 'coupon', http_status: 400)
|
182
192
|
end
|
@@ -189,6 +199,7 @@ module StripeMock
|
|
189
199
|
end
|
190
200
|
|
191
201
|
params[:current_period_start] = subscription[:current_period_start]
|
202
|
+
params[:trial_end] = params[:trial_end] || subscription[:trial_end]
|
192
203
|
subscription = resolve_subscription_changes(subscription, subscription_plans, customer, params)
|
193
204
|
|
194
205
|
# delete the old subscription, replace with the new subscription
|
@@ -244,26 +255,33 @@ module StripeMock
|
|
244
255
|
plan_ids.map { |plan_id| plans[plan_id] }
|
245
256
|
end
|
246
257
|
|
258
|
+
# Ensure customer has card to charge unless one of the following criterias is met:
|
259
|
+
# 1) is in trial
|
260
|
+
# 2) is free
|
261
|
+
# 3) has billing set to send invoice
|
247
262
|
def verify_card_present(customer, plan, subscription, params={})
|
248
|
-
if customer[:default_source]
|
249
|
-
|
250
|
-
|
251
|
-
plan[:amount] != 0 &&
|
252
|
-
plan[:trial_end].nil?)) &&
|
253
|
-
params[:trial_end].nil? &&
|
254
|
-
(subscription.nil? || subscription[:trial_end].nil? || subscription[:trial_end] == 'now')
|
255
|
-
|
256
|
-
if subscription[:items]
|
257
|
-
trial = subscription[:items][:data].none? do |item|
|
258
|
-
plan = item[:plan]
|
259
|
-
(plan[:trial_period_days].nil? || plan[:trial_period_days] == 0) &&
|
260
|
-
(plan[:trial_end].nil? || plan[:trial_end] == 'now')
|
261
|
-
end
|
262
|
-
return if trial
|
263
|
-
end
|
263
|
+
return if customer[:default_source]
|
264
|
+
return if customer[:trial_end]
|
265
|
+
return if params[:trial_end]
|
264
266
|
|
265
|
-
|
267
|
+
plan_trial_period_days = plan[:trial_period_days] || 0
|
268
|
+
plan_has_trial = plan_trial_period_days != 0 || plan[:amount] == 0 || plan[:trial_end]
|
269
|
+
return if plan && plan_has_trial
|
270
|
+
|
271
|
+
return if subscription && subscription[:trial_end] && subscription[:trial_end] != 'now'
|
272
|
+
|
273
|
+
if subscription[:items]
|
274
|
+
trial = subscription[:items][:data].none? do |item|
|
275
|
+
plan = item[:plan]
|
276
|
+
(plan[:trial_period_days].nil? || plan[:trial_period_days] == 0) &&
|
277
|
+
(plan[:trial_end].nil? || plan[:trial_end] == 'now')
|
278
|
+
end
|
279
|
+
return if trial
|
266
280
|
end
|
281
|
+
|
282
|
+
return if params[:billing] == 'send_invoice'
|
283
|
+
|
284
|
+
raise Stripe::InvalidRequestError.new('You must supply a valid card xoxo', nil, http_status: 400)
|
267
285
|
end
|
268
286
|
|
269
287
|
def verify_active_status(subscription)
|
@@ -46,12 +46,12 @@ module StripeMock
|
|
46
46
|
end
|
47
47
|
|
48
48
|
if bank_account
|
49
|
-
token_id = generate_bank_token(bank_account)
|
49
|
+
token_id = generate_bank_token(bank_account.dup)
|
50
50
|
bank_account = @bank_tokens[token_id]
|
51
51
|
|
52
52
|
Data.mock_bank_account_token(params.merge :id => token_id, :bank_account => bank_account)
|
53
53
|
else
|
54
|
-
token_id = generate_card_token(customer_card)
|
54
|
+
token_id = generate_card_token(customer_card.dup)
|
55
55
|
card = @card_tokens[token_id]
|
56
56
|
|
57
57
|
Data.mock_card_token(params.merge :id => token_id, :card => card)
|
data/lib/stripe_mock/version.rb
CHANGED
@@ -163,15 +163,19 @@ shared_examples 'Charge API' do
|
|
163
163
|
end
|
164
164
|
|
165
165
|
it "creates a balance transaction" do
|
166
|
+
amount = 300
|
167
|
+
fee = 10
|
166
168
|
charge = Stripe::Charge.create({
|
167
|
-
amount:
|
169
|
+
amount: amount,
|
168
170
|
currency: 'USD',
|
169
|
-
source: stripe_helper.generate_card_token
|
171
|
+
source: stripe_helper.generate_card_token,
|
172
|
+
application_fee: fee,
|
170
173
|
})
|
171
174
|
bal_trans = Stripe::BalanceTransaction.retrieve(charge.balance_transaction)
|
172
|
-
expect(bal_trans.amount).to eq(
|
173
|
-
expect(bal_trans.fee).to eq(39)
|
175
|
+
expect(bal_trans.amount).to eq(amount)
|
176
|
+
expect(bal_trans.fee).to eq(39 + fee)
|
174
177
|
expect(bal_trans.source).to eq(charge.id)
|
178
|
+
expect(bal_trans.net).to eq(amount - bal_trans.fee)
|
175
179
|
end
|
176
180
|
|
177
181
|
context 'when conversion rate is set' do
|
@@ -472,29 +476,34 @@ shared_examples 'Charge API' do
|
|
472
476
|
|
473
477
|
describe "idempotency" do
|
474
478
|
let(:customer) { Stripe::Customer.create(email: 'johnny@appleseed.com') }
|
475
|
-
let(:
|
479
|
+
let(:charge_params) {{
|
476
480
|
amount: 777,
|
477
481
|
currency: 'USD',
|
478
482
|
customer: customer.id,
|
479
|
-
capture: true
|
483
|
+
capture: true
|
484
|
+
}}
|
485
|
+
let(:charge_headers) {{
|
480
486
|
idempotency_key: 'onceisenough'
|
481
487
|
}}
|
482
488
|
|
483
489
|
it "returns the original charge if the same idempotency_key is passed in" do
|
484
|
-
charge1 = Stripe::Charge.create(
|
485
|
-
charge2 = Stripe::Charge.create(
|
490
|
+
charge1 = Stripe::Charge.create(charge_params, charge_headers)
|
491
|
+
charge2 = Stripe::Charge.create(charge_params, charge_headers)
|
486
492
|
|
487
493
|
expect(charge1).to eq(charge2)
|
488
494
|
end
|
489
495
|
|
490
|
-
|
491
|
-
|
492
|
-
|
496
|
+
context 'different key' do
|
497
|
+
let(:different_charge_headers) {{
|
498
|
+
idempotency_key: 'thisoneisdifferent'
|
499
|
+
}}
|
493
500
|
|
494
|
-
|
495
|
-
|
501
|
+
it "returns different charges if different idempotency_keys are used for each charge" do
|
502
|
+
charge1 = Stripe::Charge.create(charge_params, charge_headers)
|
503
|
+
charge2 = Stripe::Charge.create(charge_params, different_charge_headers)
|
496
504
|
|
497
|
-
|
505
|
+
expect(charge1).not_to eq(charge2)
|
506
|
+
end
|
498
507
|
end
|
499
508
|
end
|
500
509
|
|
@@ -226,7 +226,7 @@ shared_examples 'Customer API' do
|
|
226
226
|
discount = Stripe::Customer.retrieve(customer.id).discount
|
227
227
|
expect(discount).to_not be_nil
|
228
228
|
expect(discount.coupon).to_not be_nil
|
229
|
-
expect(discount.end).to be_within(1).of (Time.now
|
229
|
+
expect(discount.end).to be_within(1).of (Time.now.to_datetime >> 12).to_time.to_i
|
230
230
|
end
|
231
231
|
after { Stripe::Coupon.retrieve(coupon.id).delete }
|
232
232
|
after { Stripe::Customer.retrieve(customer.id).delete }
|
@@ -351,7 +351,7 @@ shared_examples 'Invoice API' do
|
|
351
351
|
it 'generates a preview without performing an actual proration', live: true do
|
352
352
|
expect(preview.subtotal).to eq 150_00
|
353
353
|
# this is a future invoice (generted at the end of the current subscription cycle), rather than a proration invoice
|
354
|
-
expect(preview.
|
354
|
+
expect(preview.created).to be_within(1).of subscription.current_period_end
|
355
355
|
expect(preview.period_start).to eq subscription.current_period_start
|
356
356
|
expect(preview.period_end).to eq subscription.current_period_end
|
357
357
|
expect(preview.lines.count).to eq 1
|
@@ -157,7 +157,7 @@ shared_examples 'Plan API' do
|
|
157
157
|
expect { subject }.to raise_error(Stripe::InvalidRequestError, message)
|
158
158
|
end
|
159
159
|
|
160
|
-
it("requires a
|
160
|
+
it("requires a product") { @name = :product }
|
161
161
|
it("requires an amount") { @name = :amount }
|
162
162
|
it("requires a currency") { @name = :currency }
|
163
163
|
it("requires an interval") { @name = :interval }
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples 'Product API' do
|
4
|
+
it 'creates a product' do
|
5
|
+
product = Stripe::Product.create(
|
6
|
+
name: 'my awesome product',
|
7
|
+
type: 'service'
|
8
|
+
)
|
9
|
+
|
10
|
+
expect(product.name).to eq 'my awesome product'
|
11
|
+
expect(product.type).to eq 'service'
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'retrieves a product' do
|
15
|
+
Stripe::Product.create(
|
16
|
+
id: 'test_prod_1',
|
17
|
+
name: 'my awesome product',
|
18
|
+
type: 'service'
|
19
|
+
)
|
20
|
+
|
21
|
+
product = Stripe::Product.retrieve('test_prod_1')
|
22
|
+
|
23
|
+
expect(product.name).to eq 'my awesome product'
|
24
|
+
expect(product.type).to eq 'service'
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'updates a product' do
|
28
|
+
Stripe::Product.create(
|
29
|
+
id: 'test_prod_1',
|
30
|
+
name: 'my awesome product',
|
31
|
+
type: 'service'
|
32
|
+
)
|
33
|
+
|
34
|
+
Stripe::Product.update('test_prod_1', name: 'my lame product')
|
35
|
+
|
36
|
+
product = Stripe::Product.retrieve('test_prod_1')
|
37
|
+
|
38
|
+
expect(product.name).to eq 'my lame product'
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'lists all products' do
|
42
|
+
2.times do |n|
|
43
|
+
Stripe::Product.create(
|
44
|
+
name: "product #{n}",
|
45
|
+
type: 'service'
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
products = Stripe::Product.list
|
50
|
+
|
51
|
+
expect(products.map(&:name)).to match_array ['product 0', 'product 1']
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'destroys a product', live: true do
|
55
|
+
Stripe::Product.create(
|
56
|
+
id: 'test_prod_1',
|
57
|
+
name: 'my awesome product',
|
58
|
+
type: 'service'
|
59
|
+
)
|
60
|
+
|
61
|
+
Stripe::Product.delete('test_prod_1')
|
62
|
+
|
63
|
+
expect { Stripe::Product.retrieve('test_prod_1') }. to raise_error(Stripe::InvalidRequestError)
|
64
|
+
end
|
65
|
+
end
|
@@ -337,26 +337,32 @@ shared_examples 'Refund API' do
|
|
337
337
|
capture: true
|
338
338
|
)
|
339
339
|
end
|
340
|
-
let(:
|
341
|
-
charge: charge.id
|
340
|
+
let(:refund_params) {{
|
341
|
+
charge: charge.id
|
342
|
+
}}
|
343
|
+
|
344
|
+
let(:refund_headers) {{
|
342
345
|
idempotency_key: 'onceisenough'
|
343
346
|
}}
|
344
347
|
|
345
348
|
it "returns the original refund if the same idempotency_key is passed in" do
|
346
|
-
refund1 = Stripe::Refund.create(
|
347
|
-
refund2 = Stripe::Refund.create(
|
349
|
+
refund1 = Stripe::Refund.create(refund_params, refund_headers)
|
350
|
+
refund2 = Stripe::Refund.create(refund_params, refund_headers)
|
348
351
|
|
349
352
|
expect(refund1).to eq(refund2)
|
350
353
|
end
|
351
354
|
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
+
context 'different key' do
|
356
|
+
let(:different_refund_headers) {{
|
357
|
+
idempotency_key: 'thisoneisdifferent'
|
358
|
+
}}
|
355
359
|
|
356
|
-
|
357
|
-
|
360
|
+
it "returns different charges if different idempotency_keys are used for each charge" do
|
361
|
+
refund1 = Stripe::Refund.create(refund_params, refund_headers)
|
362
|
+
refund2 = Stripe::Refund.create(refund_params, different_refund_headers)
|
358
363
|
|
359
|
-
|
364
|
+
expect(refund1).not_to eq(refund2)
|
365
|
+
end
|
360
366
|
end
|
361
367
|
end
|
362
368
|
end
|
@@ -140,7 +140,7 @@ shared_examples 'Customer Subscriptions' do
|
|
140
140
|
expect(customer.subscriptions.data).to be_a(Array)
|
141
141
|
expect(customer.subscriptions.data.count).to eq(1)
|
142
142
|
expect(customer.subscriptions.data.first.discount).not_to be_nil
|
143
|
-
expect(customer.subscriptions.data.first.discount).to be_a(Stripe::
|
143
|
+
expect(customer.subscriptions.data.first.discount).to be_a(Stripe::Discount)
|
144
144
|
expect(customer.subscriptions.data.first.discount.coupon.id).to eq(coupon.id)
|
145
145
|
end
|
146
146
|
|
@@ -362,6 +362,30 @@ shared_examples 'Customer Subscriptions' do
|
|
362
362
|
expect(sub.trial_end).to eq(trial_end)
|
363
363
|
end
|
364
364
|
|
365
|
+
it "does not override trial end when trial end is not set" do
|
366
|
+
plan = stripe_helper.create_plan(id: 'trial', amount: 999, trial_period_days: 14)
|
367
|
+
customer = Stripe::Customer.create(id: 'short_trial')
|
368
|
+
trial_end = Time.now.utc.to_i + 3600
|
369
|
+
metadata = {description: 'original description'}
|
370
|
+
|
371
|
+
sub = Stripe::Subscription.create({ plan: 'trial', customer: customer.id, trial_end: trial_end, metadata: metadata })
|
372
|
+
|
373
|
+
expect(sub.object).to eq('subscription')
|
374
|
+
expect(sub.plan.to_hash).to eq(plan.to_hash)
|
375
|
+
expect(sub.current_period_end).to eq(trial_end)
|
376
|
+
expect(sub.trial_end).to eq(trial_end)
|
377
|
+
expect(sub.metadata.description).to eq(metadata[:description])
|
378
|
+
|
379
|
+
metadata = {description: 'updated description'}
|
380
|
+
sub = Stripe::Subscription.update(sub.id, { metadata: metadata })
|
381
|
+
|
382
|
+
expect(sub.object).to eq('subscription')
|
383
|
+
expect(sub.plan.to_hash).to eq(plan.to_hash)
|
384
|
+
expect(sub.current_period_end).to eq(trial_end)
|
385
|
+
expect(sub.trial_end).to eq(trial_end) # check that the trial_end has NOT changed
|
386
|
+
expect(sub.metadata.description).to eq(metadata[:description]) # check that the description has changed
|
387
|
+
end
|
388
|
+
|
365
389
|
it "returns without a trial when trial_end is set to 'now'" do
|
366
390
|
plan = stripe_helper.create_plan(id: 'trial', amount: 999, trial_period_days: 14)
|
367
391
|
customer = Stripe::Customer.create(id: 'no_trial', source: gen_card_tk)
|
@@ -472,6 +496,62 @@ shared_examples 'Customer Subscriptions' do
|
|
472
496
|
expect(subscription.items.data[0].plan.id).to eq plan.id
|
473
497
|
expect(subscription.items.data[1].plan.id).to eq plan2.id
|
474
498
|
end
|
499
|
+
|
500
|
+
it 'add a new subscription to bill via an invoice' do
|
501
|
+
plan = stripe_helper.create_plan(id: 'silver', product: { name: 'Silver Plan' },
|
502
|
+
amount: 4999, currency: 'usd')
|
503
|
+
customer = Stripe::Customer.create(id: 'cardless')
|
504
|
+
|
505
|
+
expect(customer.subscriptions.data).to be_empty
|
506
|
+
expect(customer.subscriptions.count).to eq(0)
|
507
|
+
|
508
|
+
sub = Stripe::Subscription.create({
|
509
|
+
plan: 'silver',
|
510
|
+
customer: customer.id,
|
511
|
+
metadata: { foo: 'bar', example: 'yes' },
|
512
|
+
billing: 'send_invoice',
|
513
|
+
days_until_due: 30,
|
514
|
+
})
|
515
|
+
|
516
|
+
expect(sub.object).to eq('subscription')
|
517
|
+
expect(sub.plan.to_hash).to eq(plan.to_hash)
|
518
|
+
expect(sub.billing).to eq 'send_invoice'
|
519
|
+
expect(sub.days_until_due).to eq 30
|
520
|
+
end
|
521
|
+
|
522
|
+
let(:subscription_header) {{
|
523
|
+
:idempotency_key => 'a_idempotency_key'
|
524
|
+
}}
|
525
|
+
|
526
|
+
it "adds a new subscription to customer with identical idempotency key" do
|
527
|
+
plan = stripe_helper.create_plan(id: 'silver', product: { name: 'Silver Plan' },
|
528
|
+
amount: 4999, currency: 'usd')
|
529
|
+
customer = Stripe::Customer.create(source: gen_card_tk)
|
530
|
+
|
531
|
+
expect(customer.subscriptions.data).to be_empty
|
532
|
+
expect(customer.subscriptions.count).to eq(0)
|
533
|
+
|
534
|
+
sub1 = Stripe::Subscription.create({ items: [{ plan: 'silver' }], customer: customer.id }, subscription_header)
|
535
|
+
sub2 = Stripe::Subscription.create({ items: [{ plan: 'silver' }], customer: customer.id }, subscription_header)
|
536
|
+
expect(sub1).to eq(sub2)
|
537
|
+
end
|
538
|
+
|
539
|
+
it "adds a new subscription to customer with different idempotency key", :live => true do
|
540
|
+
plan = stripe_helper.create_plan(id: 'silver', product: { name: 'Silver Plan' },
|
541
|
+
amount: 4999, currency: 'usd')
|
542
|
+
customer = Stripe::Customer.create(source: gen_card_tk)
|
543
|
+
|
544
|
+
expect(customer.subscriptions.data).to be_empty
|
545
|
+
expect(customer.subscriptions.count).to eq(0)
|
546
|
+
|
547
|
+
another_subscription_header = {
|
548
|
+
:idempotency_key => 'another_idempotency_key'
|
549
|
+
}
|
550
|
+
|
551
|
+
sub1 = Stripe::Subscription.create({ items: [{ plan: 'silver' }], customer: customer.id }, subscription_header)
|
552
|
+
sub2 = Stripe::Subscription.create({ items: [{ plan: 'silver' }], customer: customer.id }, another_subscription_header)
|
553
|
+
expect(sub1).not_to eq(sub2)
|
554
|
+
end
|
475
555
|
end
|
476
556
|
|
477
557
|
context "updating a subscription" do
|
@@ -592,7 +672,7 @@ shared_examples 'Customer Subscriptions' do
|
|
592
672
|
subscription.save
|
593
673
|
|
594
674
|
expect(subscription.discount).not_to be_nil
|
595
|
-
expect(subscription.discount).to
|
675
|
+
expect(subscription.discount).to be_a(Stripe::Discount)
|
596
676
|
expect(subscription.discount.coupon.id).to eq(coupon.id)
|
597
677
|
end
|
598
678
|
|
@@ -891,6 +971,52 @@ shared_examples 'Customer Subscriptions' do
|
|
891
971
|
end
|
892
972
|
end
|
893
973
|
|
974
|
+
it "supports 'cancelling' by updating cancel_at_period_end" do
|
975
|
+
truth = stripe_helper.create_plan(id: 'the_truth')
|
976
|
+
customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk, plan: "the_truth")
|
977
|
+
|
978
|
+
sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
|
979
|
+
result = Stripe::Subscription.update(sub.id, cancel_at_period_end: true)
|
980
|
+
|
981
|
+
expect(result.status).to eq('active')
|
982
|
+
expect(result.cancel_at_period_end).to eq(true)
|
983
|
+
expect(result.id).to eq(sub.id)
|
984
|
+
|
985
|
+
customer = Stripe::Customer.retrieve('test_customer_sub')
|
986
|
+
expect(customer.subscriptions.data).to_not be_empty
|
987
|
+
expect(customer.subscriptions.count).to eq(1)
|
988
|
+
expect(customer.subscriptions.data.length).to eq(1)
|
989
|
+
|
990
|
+
expect(customer.subscriptions.data.first.status).to eq('active')
|
991
|
+
expect(customer.subscriptions.data.first.cancel_at_period_end).to eq(true)
|
992
|
+
expect(customer.subscriptions.data.first.ended_at).to be_nil
|
993
|
+
expect(customer.subscriptions.data.first.canceled_at).to_not be_nil
|
994
|
+
end
|
995
|
+
|
996
|
+
it "resumes a subscription cancelled by updating cancel_at_period_end" do
|
997
|
+
truth = stripe_helper.create_plan(id: 'the_truth')
|
998
|
+
customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk, plan: "the_truth")
|
999
|
+
|
1000
|
+
sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
|
1001
|
+
Stripe::Subscription.update(sub.id, cancel_at_period_end: true)
|
1002
|
+
|
1003
|
+
result = Stripe::Subscription.update(sub.id, cancel_at_period_end: false)
|
1004
|
+
|
1005
|
+
expect(result.status).to eq('active')
|
1006
|
+
expect(result.cancel_at_period_end).to eq(false)
|
1007
|
+
expect(result.id).to eq(sub.id)
|
1008
|
+
|
1009
|
+
customer = Stripe::Customer.retrieve('test_customer_sub')
|
1010
|
+
expect(customer.subscriptions.data).to_not be_empty
|
1011
|
+
expect(customer.subscriptions.count).to eq(1)
|
1012
|
+
expect(customer.subscriptions.data.length).to eq(1)
|
1013
|
+
|
1014
|
+
expect(customer.subscriptions.data.first.status).to eq('active')
|
1015
|
+
expect(customer.subscriptions.data.first.cancel_at_period_end).to eq(false)
|
1016
|
+
expect(customer.subscriptions.data.first.ended_at).to be_nil
|
1017
|
+
expect(customer.subscriptions.data.first.canceled_at).to be_nil
|
1018
|
+
end
|
1019
|
+
|
894
1020
|
it "doesn't change status of subscription when cancelling at period end" do
|
895
1021
|
trial = stripe_helper.create_plan(id: 'trial', trial_period_days: 14)
|
896
1022
|
customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk, plan: "trial")
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
shared_examples 'Transfer API' do
|
4
4
|
|
5
5
|
it "creates a stripe transfer" do
|
6
|
-
destination = Stripe::Account.create(email: "#{SecureRandom.uuid}@example.com", id: "acct_12345")
|
6
|
+
destination = Stripe::Account.create(type: "custom", email: "#{SecureRandom.uuid}@example.com", id: "acct_12345")
|
7
7
|
transfer = Stripe::Transfer.create(amount: 100, currency: "usd", destination: destination.id)
|
8
8
|
|
9
9
|
expect(transfer.id).to match /^test_tr/
|
@@ -31,7 +31,7 @@ shared_examples 'Transfer API' do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
describe "listing transfers" do
|
34
|
-
let(:destination) { Stripe::Account.create(email: "#{SecureRandom.uuid}@example.com", business_name: "MyCo") }
|
34
|
+
let(:destination) { Stripe::Account.create(type: "custom", email: "#{SecureRandom.uuid}@example.com", business_name: "MyCo") }
|
35
35
|
|
36
36
|
before do
|
37
37
|
3.times do
|
@@ -48,7 +48,7 @@ shared_examples 'Transfer API' do
|
|
48
48
|
end
|
49
49
|
|
50
50
|
it "filters the search to a specific destination" do
|
51
|
-
d2 = Stripe::Account.create(email: "#{SecureRandom.uuid}@example.com", business_name: "MyCo")
|
51
|
+
d2 = Stripe::Account.create(type: "custom", email: "#{SecureRandom.uuid}@example.com", business_name: "MyCo")
|
52
52
|
Stripe::Transfer.create(amount: "100", currency: "usd", destination: d2.id)
|
53
53
|
|
54
54
|
expect(Stripe::Transfer.all(destination: d2.id).count).to eq(1)
|
@@ -104,7 +104,7 @@ shared_examples 'Transfer API' do
|
|
104
104
|
end
|
105
105
|
|
106
106
|
it "when amount is not integer", live: true do
|
107
|
-
dest = Stripe::Account.create(type: "
|
107
|
+
dest = Stripe::Account.create(type: "custom", email: "#{SecureRandom.uuid}@example.com", business_name: "Alex Smith")
|
108
108
|
expect { Stripe::Transfer.create(amount: '400.2',
|
109
109
|
currency: 'usd',
|
110
110
|
destination: dest.id,
|
@@ -116,7 +116,7 @@ shared_examples 'Transfer API' do
|
|
116
116
|
end
|
117
117
|
|
118
118
|
it "when amount is negative", live: true do
|
119
|
-
dest = Stripe::Account.create(type: "
|
119
|
+
dest = Stripe::Account.create(type: "custom", email: "#{SecureRandom.uuid}@example.com", business_name: "Alex Smith")
|
120
120
|
expect { Stripe::Transfer.create(amount: '-400',
|
121
121
|
currency: 'usd',
|
122
122
|
destination: dest.id,
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
def require_stripe_examples
|
3
2
|
Dir["./spec/shared_stripe_examples/**/*.rb"].each {|f| require f}
|
4
3
|
Dir["./spec/integration_examples/**/*.rb"].each {|f| require f}
|
@@ -21,6 +20,7 @@ def it_behaves_like_stripe(&block)
|
|
21
20
|
it_behaves_like 'Invoice API', &block
|
22
21
|
it_behaves_like 'Invoice Item API', &block
|
23
22
|
it_behaves_like 'Plan API', &block
|
23
|
+
it_behaves_like 'Product API', &block
|
24
24
|
it_behaves_like 'Recipient API', &block
|
25
25
|
it_behaves_like 'Refund API', &block
|
26
26
|
it_behaves_like 'Transfer API', &block
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stripe-ruby-mock
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.5.
|
4
|
+
version: 2.5.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gilbert
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-05-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: stripe
|
@@ -159,6 +159,7 @@ files:
|
|
159
159
|
- lib/stripe_mock/request_handlers/orders.rb
|
160
160
|
- lib/stripe_mock/request_handlers/payouts.rb
|
161
161
|
- lib/stripe_mock/request_handlers/plans.rb
|
162
|
+
- lib/stripe_mock/request_handlers/products.rb
|
162
163
|
- lib/stripe_mock/request_handlers/recipients.rb
|
163
164
|
- lib/stripe_mock/request_handlers/refunds.rb
|
164
165
|
- lib/stripe_mock/request_handlers/sources.rb
|
@@ -247,6 +248,7 @@ files:
|
|
247
248
|
- spec/shared_stripe_examples/invoice_item_examples.rb
|
248
249
|
- spec/shared_stripe_examples/payout_examples.rb
|
249
250
|
- spec/shared_stripe_examples/plan_examples.rb
|
251
|
+
- spec/shared_stripe_examples/product_example.rb
|
250
252
|
- spec/shared_stripe_examples/recipient_examples.rb
|
251
253
|
- spec/shared_stripe_examples/refund_examples.rb
|
252
254
|
- spec/shared_stripe_examples/subscription_examples.rb
|
@@ -315,6 +317,7 @@ test_files:
|
|
315
317
|
- spec/shared_stripe_examples/invoice_item_examples.rb
|
316
318
|
- spec/shared_stripe_examples/payout_examples.rb
|
317
319
|
- spec/shared_stripe_examples/plan_examples.rb
|
320
|
+
- spec/shared_stripe_examples/product_example.rb
|
318
321
|
- spec/shared_stripe_examples/recipient_examples.rb
|
319
322
|
- spec/shared_stripe_examples/refund_examples.rb
|
320
323
|
- spec/shared_stripe_examples/subscription_examples.rb
|