stripe-ruby-mock 2.5.3 → 2.5.4
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 +4 -4
- data/README.md +3 -2
- data/lib/stripe_mock.rb +5 -0
- data/lib/stripe_mock/data.rb +15 -15
- data/lib/stripe_mock/instance.rb +1 -0
- data/lib/stripe_mock/request_handlers/charges.rb +1 -1
- data/lib/stripe_mock/request_handlers/customers.rb +1 -1
- data/lib/stripe_mock/request_handlers/external_accounts.rb +55 -0
- data/lib/stripe_mock/request_handlers/helpers/bank_account_helpers.rb +1 -1
- data/lib/stripe_mock/request_handlers/helpers/card_helpers.rb +5 -5
- data/lib/stripe_mock/request_handlers/helpers/external_account_helpers.rb +49 -0
- data/lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb +14 -13
- data/lib/stripe_mock/request_handlers/invoices.rb +3 -3
- data/lib/stripe_mock/request_handlers/plans.rb +1 -0
- data/lib/stripe_mock/request_handlers/subscriptions.rb +35 -54
- data/lib/stripe_mock/test_strategies/base.rb +3 -3
- data/lib/stripe_mock/version.rb +1 -1
- data/spec/instance_spec.rb +14 -0
- data/spec/shared_stripe_examples/bank_examples.rb +1 -1
- data/spec/shared_stripe_examples/charge_examples.rb +1 -1
- data/spec/shared_stripe_examples/customer_examples.rb +2 -2
- data/spec/shared_stripe_examples/external_account_examples.rb +170 -0
- data/spec/shared_stripe_examples/invoice_examples.rb +15 -14
- data/spec/shared_stripe_examples/plan_examples.rb +11 -0
- data/spec/shared_stripe_examples/subscription_examples.rb +69 -5
- data/spec/support/stripe_examples.rb +1 -0
- metadata +6 -3
- data/ChangeLog.rdoc +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 771c4e4adbc92b37176d94b8f91fb1f2bef740ba
|
4
|
+
data.tar.gz: 86c21735586588ea3aabc958d3eb93dda6dbc7ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c747fed9cf7824d59fdb1be3ec1b399beabd69d54d08101c1c46d96792fe400e4d7b8c1aa6a816c981d58d902a3fdf46c6edff21bd280a07615799384a4a82f
|
7
|
+
data.tar.gz: 68b2ab17e0f504f783bd8c5a20893ec89bee491a29cac16a824d8cdb45e48f7a2a34e307b153feb7fe58662ee661d2732c4d838391cf23497ea20fe0a90393a5
|
data/README.md
CHANGED
@@ -12,7 +12,7 @@ This gem has unexpectedly grown in popularity and I've gotten pretty busy, so I'
|
|
12
12
|
|
13
13
|
In your gemfile:
|
14
14
|
|
15
|
-
gem 'stripe-ruby-mock', '~> 2.5.
|
15
|
+
gem 'stripe-ruby-mock', '~> 2.5.4', :require => 'stripe_mock'
|
16
16
|
|
17
17
|
## Features
|
18
18
|
|
@@ -68,7 +68,7 @@ describe MyApp do
|
|
68
68
|
# Specify :source in place of :card (with same value) to return customer with source data
|
69
69
|
customer = Stripe::Customer.create({
|
70
70
|
email: 'johnny@appleseed.com',
|
71
|
-
|
71
|
+
source: stripe_helper.generate_card_token
|
72
72
|
})
|
73
73
|
expect(customer.email).to eq('johnny@appleseed.com')
|
74
74
|
end
|
@@ -170,6 +170,7 @@ StripeMock.prepare_card_error(:incorrect_cvc)
|
|
170
170
|
StripeMock.prepare_card_error(:card_declined)
|
171
171
|
StripeMock.prepare_card_error(:missing)
|
172
172
|
StripeMock.prepare_card_error(:processing_error)
|
173
|
+
StripeMock.prepare_card_error(:incorrect_zip)
|
173
174
|
```
|
174
175
|
|
175
176
|
You can see the details of each error in [lib/stripe_mock/api/errors.rb](lib/stripe_mock/api/errors.rb)
|
data/lib/stripe_mock.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'ostruct'
|
2
2
|
require 'multi_json'
|
3
3
|
require 'dante'
|
4
|
+
require 'time'
|
4
5
|
|
5
6
|
require 'stripe'
|
6
7
|
|
@@ -37,6 +38,7 @@ require 'stripe_mock/api/test_helpers'
|
|
37
38
|
require 'stripe_mock/api/webhooks'
|
38
39
|
|
39
40
|
require 'stripe_mock/request_handlers/helpers/bank_account_helpers.rb'
|
41
|
+
require 'stripe_mock/request_handlers/helpers/external_account_helpers.rb'
|
40
42
|
require 'stripe_mock/request_handlers/helpers/card_helpers.rb'
|
41
43
|
require 'stripe_mock/request_handlers/helpers/charge_helpers.rb'
|
42
44
|
require 'stripe_mock/request_handlers/helpers/coupon_helpers.rb'
|
@@ -46,6 +48,7 @@ require 'stripe_mock/request_handlers/helpers/token_helpers.rb'
|
|
46
48
|
require 'stripe_mock/request_handlers/validators/param_validators.rb'
|
47
49
|
|
48
50
|
require 'stripe_mock/request_handlers/accounts.rb'
|
51
|
+
require 'stripe_mock/request_handlers/external_accounts.rb'
|
49
52
|
require 'stripe_mock/request_handlers/balance.rb'
|
50
53
|
require 'stripe_mock/request_handlers/balance_transactions.rb'
|
51
54
|
require 'stripe_mock/request_handlers/charges.rb'
|
@@ -74,11 +77,13 @@ require 'stripe_mock/test_strategies/live.rb'
|
|
74
77
|
|
75
78
|
module StripeMock
|
76
79
|
|
80
|
+
@default_currency = 'usd'
|
77
81
|
lib_dir = File.expand_path(File.dirname(__FILE__), '../..')
|
78
82
|
@webhook_fixture_path = './spec/fixtures/stripe_webhooks/'
|
79
83
|
@webhook_fixture_fallback_path = File.join(lib_dir, 'stripe_mock/webhook_fixtures')
|
80
84
|
|
81
85
|
class << self
|
86
|
+
attr_accessor :default_currency
|
82
87
|
attr_accessor :webhook_fixture_path
|
83
88
|
end
|
84
89
|
end
|
data/lib/stripe_mock/data.rb
CHANGED
@@ -3,7 +3,7 @@ module StripeMock
|
|
3
3
|
|
4
4
|
def self.mock_account(params = {})
|
5
5
|
id = params[:id] || 'acct_103ED82ePvKYlo2C'
|
6
|
-
currency = params[:currency] ||
|
6
|
+
currency = params[:currency] || StripeMock.default_currency
|
7
7
|
{
|
8
8
|
id: id,
|
9
9
|
email: "bob@example.com",
|
@@ -103,7 +103,7 @@ module StripeMock
|
|
103
103
|
|
104
104
|
def self.mock_customer(sources, params)
|
105
105
|
cus_id = params[:id] || "test_cus_default"
|
106
|
-
currency = params[:currency] ||
|
106
|
+
currency = params[:currency] || StripeMock.default_currency
|
107
107
|
sources.each {|source| source[:customer] = cus_id}
|
108
108
|
{
|
109
109
|
email: 'stripe_mock@example.com',
|
@@ -134,7 +134,7 @@ module StripeMock
|
|
134
134
|
|
135
135
|
def self.mock_charge(params={})
|
136
136
|
charge_id = params[:id] || "ch_1fD6uiR9FAA2zc"
|
137
|
-
currency = params[:currency] ||
|
137
|
+
currency = params[:currency] || StripeMock.default_currency
|
138
138
|
{
|
139
139
|
id: charge_id,
|
140
140
|
object: "charge",
|
@@ -196,7 +196,7 @@ module StripeMock
|
|
196
196
|
end
|
197
197
|
|
198
198
|
def self.mock_refund(params={})
|
199
|
-
currency = params[:currency] ||
|
199
|
+
currency = params[:currency] || StripeMock.default_currency
|
200
200
|
{
|
201
201
|
id: "re_4fWhgUh5si7InF",
|
202
202
|
amount: 1,
|
@@ -248,7 +248,7 @@ module StripeMock
|
|
248
248
|
end
|
249
249
|
|
250
250
|
def self.mock_bank_account(params={})
|
251
|
-
currency = params[:currency] ||
|
251
|
+
currency = params[:currency] || StripeMock.default_currency
|
252
252
|
{
|
253
253
|
id: "test_ba_default",
|
254
254
|
object: "bank_account",
|
@@ -306,7 +306,7 @@ module StripeMock
|
|
306
306
|
plan: {
|
307
307
|
amount: 999,
|
308
308
|
created: 1504035972,
|
309
|
-
currency:
|
309
|
+
currency: StripeMock.default_currency
|
310
310
|
},
|
311
311
|
quantity: 1
|
312
312
|
}]
|
@@ -328,7 +328,7 @@ module StripeMock
|
|
328
328
|
|
329
329
|
def self.mock_invoice(lines, params={})
|
330
330
|
in_id = params[:id] || "test_in_default"
|
331
|
-
currency = params[:currency] ||
|
331
|
+
currency = params[:currency] || StripeMock.default_currency
|
332
332
|
lines << Data.mock_line_item() if lines.empty?
|
333
333
|
invoice = {
|
334
334
|
id: 'in_test_invoice',
|
@@ -379,7 +379,7 @@ module StripeMock
|
|
379
379
|
end
|
380
380
|
|
381
381
|
def self.mock_line_item(params = {})
|
382
|
-
currency = params[:currency] ||
|
382
|
+
currency = params[:currency] || StripeMock.default_currency
|
383
383
|
{
|
384
384
|
id: "ii_test",
|
385
385
|
object: "line_item",
|
@@ -402,7 +402,7 @@ module StripeMock
|
|
402
402
|
end
|
403
403
|
|
404
404
|
def self.mock_invoice_item(params = {})
|
405
|
-
currency = params[:currency] ||
|
405
|
+
currency = params[:currency] || StripeMock.default_currency
|
406
406
|
{
|
407
407
|
id: "test_ii",
|
408
408
|
object: "invoiceitem",
|
@@ -490,7 +490,7 @@ module StripeMock
|
|
490
490
|
end
|
491
491
|
|
492
492
|
def self.mock_plan(params={})
|
493
|
-
currency = params[:currency] ||
|
493
|
+
currency = params[:currency] || StripeMock.default_currency
|
494
494
|
{
|
495
495
|
id: "2",
|
496
496
|
object: "plan",
|
@@ -591,7 +591,7 @@ module StripeMock
|
|
591
591
|
end
|
592
592
|
|
593
593
|
def self.mock_transfer(params={})
|
594
|
-
currency = params[:currency] ||
|
594
|
+
currency = params[:currency] || StripeMock.default_currency
|
595
595
|
id = params[:id] || 'tr_test_transfer'
|
596
596
|
{
|
597
597
|
:status => 'pending',
|
@@ -623,7 +623,7 @@ module StripeMock
|
|
623
623
|
end
|
624
624
|
|
625
625
|
def self.mock_payout(params={})
|
626
|
-
currency = params[:currency] ||
|
626
|
+
currency = params[:currency] || StripeMock.default_currency
|
627
627
|
id = params[:id] || 'po_test_payout'
|
628
628
|
{
|
629
629
|
:amount => 100,
|
@@ -647,7 +647,7 @@ module StripeMock
|
|
647
647
|
|
648
648
|
def self.mock_dispute(params={})
|
649
649
|
@timestamp ||= Time.now.to_i
|
650
|
-
currency = params[:currency] ||
|
650
|
+
currency = params[:currency] || StripeMock.default_currency
|
651
651
|
id = params[:id] || "dp_test_dispute"
|
652
652
|
{
|
653
653
|
:id => id,
|
@@ -967,7 +967,7 @@ module StripeMock
|
|
967
967
|
end
|
968
968
|
|
969
969
|
def self.mock_balance_transaction(params = {})
|
970
|
-
currency = params[:currency] ||
|
970
|
+
currency = params[:currency] || StripeMock.default_currency
|
971
971
|
bt_id = params[:id] || 'test_txn_default'
|
972
972
|
source = params[:source] || 'ch_test_charge'
|
973
973
|
{
|
@@ -1015,7 +1015,7 @@ module StripeMock
|
|
1015
1015
|
object: 'plan',
|
1016
1016
|
amount: 1337,
|
1017
1017
|
created: 1504716177,
|
1018
|
-
currency:
|
1018
|
+
currency: StripeMock.default_currency,
|
1019
1019
|
interval: 'month',
|
1020
1020
|
interval_count: 1,
|
1021
1021
|
livemode: false,
|
data/lib/stripe_mock/instance.rb
CHANGED
@@ -20,6 +20,7 @@ module StripeMock
|
|
20
20
|
@@handlers.find {|h| method_url =~ h[:route] }
|
21
21
|
end
|
22
22
|
|
23
|
+
include StripeMock::RequestHandlers::ExternalAccounts
|
23
24
|
include StripeMock::RequestHandlers::Accounts
|
24
25
|
include StripeMock::RequestHandlers::Balance
|
25
26
|
include StripeMock::RequestHandlers::BalanceTransactions
|
@@ -41,7 +41,7 @@ module StripeMock
|
|
41
41
|
end
|
42
42
|
|
43
43
|
ensure_required_params(params)
|
44
|
-
bal_trans_params = { amount: params[:amount], source:
|
44
|
+
bal_trans_params = { amount: params[:amount], source: id }
|
45
45
|
|
46
46
|
balance_transaction_id = new_balance_transaction('txn', bal_trans_params)
|
47
47
|
|
@@ -40,7 +40,7 @@ module StripeMock
|
|
40
40
|
end
|
41
41
|
|
42
42
|
subscription = Data.mock_subscription({ id: new_id('su') })
|
43
|
-
subscription
|
43
|
+
subscription = resolve_subscription_changes(subscription, [plan], customers[ params[:id] ], params)
|
44
44
|
add_subscription_to_customer(customers[ params[:id] ], subscription)
|
45
45
|
subscriptions[subscription[:id]] = subscription
|
46
46
|
elsif params[:trial_end]
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module StripeMock
|
2
|
+
module RequestHandlers
|
3
|
+
module ExternalAccounts
|
4
|
+
|
5
|
+
def ExternalAccounts.included(klass)
|
6
|
+
klass.add_handler 'get /v1/accounts/(.*)/external_accounts', :retrieve_external_accounts
|
7
|
+
klass.add_handler 'post /v1/accounts/(.*)/external_accounts', :create_external_account
|
8
|
+
klass.add_handler 'post /v1/accounts/(.*)/external_accounts/(.*)/verify', :verify_external_account
|
9
|
+
klass.add_handler 'get /v1/accounts/(.*)/external_accounts/(.*)', :retrieve_external_account
|
10
|
+
klass.add_handler 'delete /v1/accounts/(.*)/external_accounts/(.*)', :delete_external_account
|
11
|
+
klass.add_handler 'post /v1/accounts/(.*)/external_accounts/(.*)', :update_external_account
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_external_account(route, method_url, params, headers)
|
15
|
+
route =~ method_url
|
16
|
+
add_external_account_to(:account, $1, params, accounts)
|
17
|
+
end
|
18
|
+
|
19
|
+
def retrieve_external_accounts(route, method_url, params, headers)
|
20
|
+
route =~ method_url
|
21
|
+
retrieve_object_cards(:account, $1, accounts)
|
22
|
+
end
|
23
|
+
|
24
|
+
def retrieve_external_account(route, method_url, params, headers)
|
25
|
+
route =~ method_url
|
26
|
+
account = assert_existence :account, $1, accounts[$1]
|
27
|
+
|
28
|
+
assert_existence :card, $2, get_card(account, $2)
|
29
|
+
end
|
30
|
+
|
31
|
+
def delete_external_account(route, method_url, params, headers)
|
32
|
+
route =~ method_url
|
33
|
+
delete_card_from(:account, $1, $2, accounts)
|
34
|
+
end
|
35
|
+
|
36
|
+
def update_external_account(route, method_url, params, headers)
|
37
|
+
route =~ method_url
|
38
|
+
account = assert_existence :account, $1, accounts[$1]
|
39
|
+
|
40
|
+
card = assert_existence :card, $2, get_card(account, $2)
|
41
|
+
card.merge!(params)
|
42
|
+
card
|
43
|
+
end
|
44
|
+
|
45
|
+
def verify_external_account(route, method_url, params, headers)
|
46
|
+
route =~ method_url
|
47
|
+
account = assert_existence :account, $1, accounts[$1]
|
48
|
+
|
49
|
+
external_account = assert_existence :bank_account, $2, verify_bank_account(account, $2)
|
50
|
+
external_account
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -3,7 +3,7 @@ module StripeMock
|
|
3
3
|
module Helpers
|
4
4
|
|
5
5
|
def verify_bank_account(object, bank_account_id, class_name='Customer')
|
6
|
-
bank_accounts = object[:bank_accounts] || object[:sources]
|
6
|
+
bank_accounts = object[:external_accounts] || object[:bank_accounts] || object[:sources]
|
7
7
|
bank_account = bank_accounts[:data].find{|acc| acc[:id] == bank_account_id }
|
8
8
|
return if bank_account.nil?
|
9
9
|
bank_account['status'] = 'verified'
|
@@ -3,7 +3,7 @@ module StripeMock
|
|
3
3
|
module Helpers
|
4
4
|
|
5
5
|
def get_card(object, card_id, class_name='Customer')
|
6
|
-
cards = object[:cards] || object[:sources]
|
6
|
+
cards = object[:cards] || object[:sources] || object[:external_accounts]
|
7
7
|
card = cards[:data].find{|cc| cc[:id] == card_id }
|
8
8
|
if card.nil?
|
9
9
|
if class_name == 'Recipient'
|
@@ -36,7 +36,7 @@ module StripeMock
|
|
36
36
|
|
37
37
|
def add_card_to_object(type, card, object, replace_current=false)
|
38
38
|
card[type] = object[:id]
|
39
|
-
cards_or_sources = object[:cards] || object[:sources]
|
39
|
+
cards_or_sources = object[:cards] || object[:sources] || object[:external_accounts]
|
40
40
|
|
41
41
|
is_customer = object.has_key?(:sources)
|
42
42
|
|
@@ -58,7 +58,7 @@ module StripeMock
|
|
58
58
|
|
59
59
|
def retrieve_object_cards(type, type_id, objects)
|
60
60
|
resource = assert_existence type, type_id, objects[type_id]
|
61
|
-
cards = resource[:cards] || resource[:sources]
|
61
|
+
cards = resource[:cards] || resource[:sources] || resource[:external_accounts]
|
62
62
|
|
63
63
|
Data.mock_list_object(cards[:data])
|
64
64
|
end
|
@@ -69,7 +69,7 @@ module StripeMock
|
|
69
69
|
assert_existence :card, card_id, get_card(resource, card_id)
|
70
70
|
|
71
71
|
card = { id: card_id, deleted: true }
|
72
|
-
cards_or_sources = resource[:cards] || resource[:sources]
|
72
|
+
cards_or_sources = resource[:cards] || resource[:sources] || resource[:external_accounts]
|
73
73
|
cards_or_sources[:data].reject!{|cc|
|
74
74
|
cc[:id] == card[:id]
|
75
75
|
}
|
@@ -103,7 +103,7 @@ module StripeMock
|
|
103
103
|
def add_card_to(type, type_id, params, objects)
|
104
104
|
resource = assert_existence type, type_id, objects[type_id]
|
105
105
|
|
106
|
-
card = card_from_params(params[:card] || params[:source])
|
106
|
+
card = card_from_params(params[:card] || params[:source] || params[:external_accounts])
|
107
107
|
add_card_to_object(type, card, resource)
|
108
108
|
end
|
109
109
|
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module StripeMock
|
2
|
+
module RequestHandlers
|
3
|
+
module Helpers
|
4
|
+
|
5
|
+
def add_external_account_to(type, type_id, params, objects)
|
6
|
+
resource = assert_existence type, type_id, objects[type_id]
|
7
|
+
|
8
|
+
source =
|
9
|
+
if params[:card]
|
10
|
+
card_from_params(params[:card])
|
11
|
+
elsif params[:bank_account]
|
12
|
+
bank_from_params(params[:bank_account])
|
13
|
+
else
|
14
|
+
begin
|
15
|
+
get_card_by_token(params[:external_account])
|
16
|
+
rescue Stripe::InvalidRequestError
|
17
|
+
bank_from_params(params[:external_account])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
add_external_account_to_object(type, source, resource)
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_external_account_to_object(type, source, object, replace_current=false)
|
24
|
+
source[type] = object[:id]
|
25
|
+
accounts = object[:external_accounts]
|
26
|
+
|
27
|
+
if replace_current && accounts[:data]
|
28
|
+
accounts[:data].delete_if {|source| source[:id] == object[:default_source]}
|
29
|
+
object[:default_source] = source[:id]
|
30
|
+
accounts[:data] = [source]
|
31
|
+
else
|
32
|
+
accounts[:total_count] = (accounts[:total_count] || 0) + 1
|
33
|
+
(accounts[:data] ||= []) << source
|
34
|
+
end
|
35
|
+
object[:default_source] = source[:id] if object[:default_source].nil?
|
36
|
+
|
37
|
+
source
|
38
|
+
end
|
39
|
+
|
40
|
+
def bank_from_params(attrs_or_token)
|
41
|
+
if attrs_or_token.is_a? Hash
|
42
|
+
attrs_or_token = generate_bank_token(attrs_or_token)
|
43
|
+
end
|
44
|
+
get_bank_by_token(attrs_or_token)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -6,22 +6,31 @@ module StripeMock
|
|
6
6
|
customer[:subscriptions][:data].find{|sub| sub[:id] == sub_id }
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
9
|
+
def resolve_subscription_changes(subscription, plans, customer, options = {})
|
10
|
+
subscription.merge!(custom_subscription_params(plans, customer, options))
|
11
|
+
subscription[:items][:data] = plans.map { |plan| Data.mock_subscription_item({ plan: plan }) }
|
12
|
+
subscription
|
13
|
+
end
|
14
|
+
|
15
|
+
def custom_subscription_params(plans, cus, options = {})
|
10
16
|
verify_trial_end(options[:trial_end]) if options[:trial_end]
|
11
17
|
|
18
|
+
plan = plans.first if plans.size == 1
|
19
|
+
|
12
20
|
now = Time.now.utc.to_i
|
13
21
|
created_time = options[:created] || now
|
14
22
|
start_time = options[:current_period_start] || now
|
15
|
-
params = {
|
23
|
+
params = { customer: cus[:id], current_period_start: start_time, created: created_time }
|
24
|
+
params.merge!({ :plan => (plans.size == 1 ? plans.first : nil) })
|
16
25
|
params.merge! options.select {|k,v| k =~ /application_fee_percent|quantity|metadata|tax_percent/}
|
17
26
|
# TODO: Implement coupon logic
|
18
27
|
|
19
28
|
if (((plan && plan[:trial_period_days]) || 0) == 0 && options[:trial_end].nil?) || options[:trial_end] == "now"
|
20
|
-
end_time = get_ending_time(start_time, plan)
|
21
|
-
params.merge!({status: 'active', current_period_end: end_time, trial_start: nil, trial_end: nil})
|
29
|
+
end_time = options[:billing_cycle_anchor] || get_ending_time(start_time, plan)
|
30
|
+
params.merge!({status: 'active', current_period_end: end_time, trial_start: nil, trial_end: nil, billing_cycle_anchor: options[:billing_cycle_anchor]})
|
22
31
|
else
|
23
32
|
end_time = options[:trial_end] || (Time.now.utc.to_i + plan[:trial_period_days]*86400)
|
24
|
-
params.merge!({status: 'trialing', current_period_end: end_time, trial_start: start_time, trial_end: end_time})
|
33
|
+
params.merge!({status: 'trialing', current_period_end: end_time, trial_start: start_time, trial_end: end_time, billing_cycle_anchor: nil})
|
25
34
|
end
|
26
35
|
|
27
36
|
params
|
@@ -87,14 +96,6 @@ module StripeMock
|
|
87
96
|
items.each { |i| total += (i[:quantity] || 1) * i[:plan][:amount] }
|
88
97
|
total
|
89
98
|
end
|
90
|
-
|
91
|
-
def mock_subscription_items(items = [])
|
92
|
-
data = []
|
93
|
-
items.each do |i|
|
94
|
-
data << Data.mock_subscription_item(i.merge(plan: plans[i[:plan].to_s]))
|
95
|
-
end
|
96
|
-
data
|
97
|
-
end
|
98
99
|
end
|
99
100
|
end
|
100
101
|
end
|
@@ -87,7 +87,7 @@ module StripeMock
|
|
87
87
|
invoice_date = Time.now.to_i
|
88
88
|
subscription_plan = assert_existence :plan, subscription_plan_id, plans[subscription_plan_id.to_s]
|
89
89
|
preview_subscription = Data.mock_subscription
|
90
|
-
preview_subscription
|
90
|
+
preview_subscription = resolve_subscription_changes(preview_subscription, [subscription_plan], customer, { trial_end: params[:subscription_trial_end] })
|
91
91
|
preview_subscription[:id] = subscription[:id]
|
92
92
|
preview_subscription[:quantity] = subscription_quantity
|
93
93
|
subscription_proration_date = params[:subscription_proration_date] || Time.now
|
@@ -166,9 +166,9 @@ module StripeMock
|
|
166
166
|
#anonymous charge
|
167
167
|
def invoice_charge(invoice)
|
168
168
|
begin
|
169
|
-
new_charge(nil, nil, {customer: invoice[:customer]["id"], amount: invoice[:amount_due], currency:
|
169
|
+
new_charge(nil, nil, {customer: invoice[:customer]["id"], amount: invoice[:amount_due], currency: StripeMock.default_currency}, nil)
|
170
170
|
rescue Stripe::InvalidRequestError
|
171
|
-
new_charge(nil, nil, {source: generate_card_token, amount: invoice[:amount_due], currency:
|
171
|
+
new_charge(nil, nil, {source: generate_card_token, amount: invoice[:amount_due], currency: StripeMock.default_currency}, nil)
|
172
172
|
end
|
173
173
|
end
|
174
174
|
|
@@ -32,24 +32,10 @@ module StripeMock
|
|
32
32
|
customer[:subscriptions]
|
33
33
|
end
|
34
34
|
|
35
|
-
def plan_id_from_params(params)
|
36
|
-
if params[:plan]
|
37
|
-
params[:plan].to_s
|
38
|
-
elsif params[:items]
|
39
|
-
item = params[:items].values.find { |item| item[:plan] }
|
40
|
-
if item
|
41
|
-
item[:plan].to_s
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
35
|
def create_customer_subscription(route, method_url, params, headers)
|
47
36
|
route =~ method_url
|
48
37
|
|
49
|
-
|
50
|
-
|
51
|
-
plan = assert_existence :plan, plan_id, plans[plan_id]
|
52
|
-
|
38
|
+
subscription_plans = get_subscription_plans_from_params(params)
|
53
39
|
customer = assert_existence :customer, $1, customers[$1]
|
54
40
|
|
55
41
|
if params[:source]
|
@@ -59,10 +45,11 @@ module StripeMock
|
|
59
45
|
end
|
60
46
|
|
61
47
|
subscription = Data.mock_subscription({ id: (params[:id] || new_id('su')) })
|
62
|
-
subscription
|
48
|
+
subscription = resolve_subscription_changes(subscription, subscription_plans, customer, params)
|
63
49
|
|
64
50
|
# Ensure customer has card to charge if plan has no trial and is not free
|
65
|
-
|
51
|
+
# Note: needs updating for subscriptions with multiple plans
|
52
|
+
verify_card_present(customer, subscription_plans.first, subscription, params)
|
66
53
|
|
67
54
|
if params[:coupon]
|
68
55
|
coupon_id = params[:coupon]
|
@@ -82,25 +69,23 @@ module StripeMock
|
|
82
69
|
subscriptions[subscription[:id]] = subscription
|
83
70
|
add_subscription_to_customer(customer, subscription)
|
84
71
|
|
85
|
-
clear_top_level_plan_if_multiple_items(subscription)
|
86
|
-
|
87
72
|
subscriptions[subscription[:id]]
|
88
73
|
end
|
89
74
|
|
90
75
|
def create_subscription(route, method_url, params, headers)
|
91
76
|
route =~ method_url
|
92
77
|
|
93
|
-
|
94
|
-
|
95
|
-
plan = plan_id ? assert_existence(:plan, plan_id, plans[plan_id]) : nil
|
78
|
+
subscription_plans = get_subscription_plans_from_params(params)
|
96
79
|
|
97
80
|
customer = params[:customer]
|
98
81
|
customer_id = customer.is_a?(Stripe::Customer) ? customer[:id] : customer.to_s
|
99
82
|
customer = assert_existence :customer, customer_id, customers[customer_id]
|
100
83
|
|
101
|
-
if
|
102
|
-
|
103
|
-
|
84
|
+
if subscription_plans && customer
|
85
|
+
subscription_plans.each do |plan|
|
86
|
+
unless customer[:currency].to_s == plan[:currency].to_s
|
87
|
+
raise Stripe::InvalidRequestError.new("Customer's currency of #{customer[:currency]} does not match plan's currency of #{plan[:currency]}", 'currency', http_status: 400)
|
88
|
+
end
|
104
89
|
end
|
105
90
|
end
|
106
91
|
|
@@ -110,18 +95,18 @@ module StripeMock
|
|
110
95
|
customer[:default_source] = new_card[:id]
|
111
96
|
end
|
112
97
|
|
113
|
-
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)
|
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)
|
114
99
|
unknown_params = params.keys - allowed_params.map(&:to_sym)
|
115
100
|
if unknown_params.length > 0
|
116
101
|
raise Stripe::InvalidRequestError.new("Received unknown parameter: #{unknown_params.join}", unknown_params.first.to_s, http_status: 400)
|
117
102
|
end
|
118
103
|
|
119
104
|
subscription = Data.mock_subscription({ id: (params[:id] || new_id('su')) })
|
120
|
-
subscription
|
121
|
-
subscription[:items][:data] = mock_subscription_items(params[:items].values) if params[:items]
|
105
|
+
subscription = resolve_subscription_changes(subscription, subscription_plans, customer, params)
|
122
106
|
|
123
107
|
# Ensure customer has card to charge if plan has no trial and is not free
|
124
|
-
|
108
|
+
# Note: needs updating for subscriptions with multiple plans
|
109
|
+
verify_card_present(customer, subscription_plans.first, subscription, params)
|
125
110
|
|
126
111
|
if params[:coupon]
|
127
112
|
coupon_id = params[:coupon]
|
@@ -141,8 +126,6 @@ module StripeMock
|
|
141
126
|
subscriptions[subscription[:id]] = subscription
|
142
127
|
add_subscription_to_customer(customer, subscription)
|
143
128
|
|
144
|
-
clear_top_level_plan_if_multiple_items(subscription)
|
145
|
-
|
146
129
|
subscriptions[subscription[:id]]
|
147
130
|
end
|
148
131
|
|
@@ -176,21 +159,12 @@ module StripeMock
|
|
176
159
|
customer[:default_source] = new_card[:id]
|
177
160
|
end
|
178
161
|
|
179
|
-
|
180
|
-
plan_id = plan_id_from_params(params)
|
181
|
-
|
182
|
-
unless plan_id
|
183
|
-
plan_id = if subscription[:plan]
|
184
|
-
subscription[:plan][:id]
|
185
|
-
elsif subscription[:items]
|
186
|
-
row = subscription[:items][:data].find { |item| item[:plan] }
|
187
|
-
if row
|
188
|
-
row[:plan][:id]
|
189
|
-
end
|
190
|
-
end
|
191
|
-
end
|
162
|
+
subscription_plans = get_subscription_plans_from_params(params)
|
192
163
|
|
193
|
-
|
164
|
+
# subscription plans are not being updated but load them for the response
|
165
|
+
if subscription_plans.empty?
|
166
|
+
subscription_plans = subscription[:items][:data].map { |item| item[:plan] }
|
167
|
+
end
|
194
168
|
|
195
169
|
if params[:coupon]
|
196
170
|
coupon_id = params[:coupon]
|
@@ -207,10 +181,7 @@ module StripeMock
|
|
207
181
|
raise Stripe::InvalidRequestError.new("No such coupon: #{coupon_id}", 'coupon', http_status: 400)
|
208
182
|
end
|
209
183
|
end
|
210
|
-
|
211
|
-
assert_existence :plan, plan_id, plan
|
212
|
-
params[:plan] = plan if params[:plan]
|
213
|
-
verify_card_present(customer, plan, subscription)
|
184
|
+
verify_card_present(customer, subscription_plans.first, subscription)
|
214
185
|
|
215
186
|
if subscription[:cancel_at_period_end]
|
216
187
|
subscription[:cancel_at_period_end] = false
|
@@ -218,14 +189,12 @@ module StripeMock
|
|
218
189
|
end
|
219
190
|
|
220
191
|
params[:current_period_start] = subscription[:current_period_start]
|
221
|
-
subscription
|
192
|
+
subscription = resolve_subscription_changes(subscription, subscription_plans, customer, params)
|
222
193
|
|
223
194
|
# delete the old subscription, replace with the new subscription
|
224
195
|
customer[:subscriptions][:data].reject! { |sub| sub[:id] == subscription[:id] }
|
225
196
|
customer[:subscriptions][:data] << subscription
|
226
197
|
|
227
|
-
clear_top_level_plan_if_multiple_items(subscription)
|
228
|
-
|
229
198
|
subscription
|
230
199
|
end
|
231
200
|
|
@@ -259,8 +228,20 @@ module StripeMock
|
|
259
228
|
|
260
229
|
private
|
261
230
|
|
262
|
-
def
|
263
|
-
|
231
|
+
def get_subscription_plans_from_params(params)
|
232
|
+
plan_ids = if params[:plan]
|
233
|
+
[params[:plan].to_s]
|
234
|
+
elsif params[:items]
|
235
|
+
items = params[:items]
|
236
|
+
items = items.values if items.respond_to?(:values)
|
237
|
+
items.map { |item| item[:plan].to_s if item[:plan] }
|
238
|
+
else
|
239
|
+
[]
|
240
|
+
end
|
241
|
+
plan_ids.each do |plan_id|
|
242
|
+
assert_existence :plan, plan_id, plans[plan_id]
|
243
|
+
end
|
244
|
+
plan_ids.map { |plan_id| plans[plan_id] }
|
264
245
|
end
|
265
246
|
|
266
247
|
def verify_card_present(customer, plan, subscription, params={})
|
@@ -3,7 +3,7 @@ module StripeMock
|
|
3
3
|
class Base
|
4
4
|
|
5
5
|
def create_plan_params(params={})
|
6
|
-
currency = params[:currency] ||
|
6
|
+
currency = params[:currency] || StripeMock.default_currency
|
7
7
|
{
|
8
8
|
:id => 'stripe_mock_default_plan_id',
|
9
9
|
:name => 'StripeMock Default Plan ID',
|
@@ -23,7 +23,7 @@ module StripeMock
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def generate_bank_token(bank_account_params={})
|
26
|
-
currency = bank_account_params[:currency] ||
|
26
|
+
currency = bank_account_params[:currency] || StripeMock.default_currency
|
27
27
|
bank_account = {
|
28
28
|
:country => "US",
|
29
29
|
:currency => currency,
|
@@ -39,7 +39,7 @@ module StripeMock
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def create_coupon_params(params = {})
|
42
|
-
currency = params[:currency] ||
|
42
|
+
currency = params[:currency] || StripeMock.default_currency
|
43
43
|
{
|
44
44
|
id: '10BUCKS',
|
45
45
|
amount_off: 1000,
|
data/lib/stripe_mock/version.rb
CHANGED
data/spec/instance_spec.rb
CHANGED
@@ -52,4 +52,18 @@ describe StripeMock::Instance do
|
|
52
52
|
StripeMock.set_conversion_rate(1.25)
|
53
53
|
expect(StripeMock.instance.conversion_rate).to eq(1.25)
|
54
54
|
end
|
55
|
+
|
56
|
+
it "allows non-usd default currency" do
|
57
|
+
old_default_currency = StripeMock.default_currency
|
58
|
+
customer = begin
|
59
|
+
StripeMock.default_currency = "jpy"
|
60
|
+
Stripe::Customer.create({
|
61
|
+
email: 'johnny@appleseed.com',
|
62
|
+
source: stripe_helper.generate_card_token
|
63
|
+
})
|
64
|
+
ensure
|
65
|
+
StripeMock.default_currency = old_default_currency
|
66
|
+
end
|
67
|
+
expect(customer.currency).to eq("jpy")
|
68
|
+
end
|
55
69
|
end
|
@@ -40,7 +40,7 @@ shared_examples 'Bank API' do
|
|
40
40
|
expect(bank.last4).to eq("6789")
|
41
41
|
end
|
42
42
|
|
43
|
-
it "creates a single bank with a generated bank token"
|
43
|
+
it "creates a single bank with a generated bank token" do
|
44
44
|
customer = Stripe::Customer.create
|
45
45
|
expect(customer.sources.count).to eq 0
|
46
46
|
|
@@ -171,7 +171,7 @@ shared_examples 'Charge API' do
|
|
171
171
|
bal_trans = Stripe::BalanceTransaction.retrieve(charge.balance_transaction)
|
172
172
|
expect(bal_trans.amount).to eq(charge.amount)
|
173
173
|
expect(bal_trans.fee).to eq(39)
|
174
|
-
expect(bal_trans.source).to eq(charge.
|
174
|
+
expect(bal_trans.source).to eq(charge.id)
|
175
175
|
end
|
176
176
|
|
177
177
|
context 'when conversion rate is set' do
|
@@ -220,8 +220,8 @@ shared_examples 'Customer API' do
|
|
220
220
|
end
|
221
221
|
|
222
222
|
describe 'repeating coupon with duration limit', live: true do
|
223
|
-
let!(:coupon) {
|
224
|
-
let!(:customer) { Stripe::Customer.create(coupon:
|
223
|
+
let!(:coupon) { stripe_helper.create_coupon(id: '10OFF', amount_off: 1000, currency: 'usd', duration: 'repeating', duration_in_months: 12) }
|
224
|
+
let!(:customer) { Stripe::Customer.create(coupon: coupon.id) }
|
225
225
|
it 'creates the discount with the end date', live: true do
|
226
226
|
discount = Stripe::Customer.retrieve(customer.id).discount
|
227
227
|
expect(discount).to_not be_nil
|
@@ -0,0 +1,170 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples 'External Account API' do
|
4
|
+
|
5
|
+
it 'creates/returns a bank when using account.external_accounts.create given a bank token' do
|
6
|
+
account = Stripe::Account.create(id: 'test_account', type: 'custom', country: "US")
|
7
|
+
bank_token = stripe_helper.generate_bank_token(last4: "1123", exp_month: 11, exp_year: 2099)
|
8
|
+
bank = account.external_accounts.create(external_account: bank_token)
|
9
|
+
|
10
|
+
expect(bank.account).to eq('test_account')
|
11
|
+
expect(bank.last4).to eq("1123")
|
12
|
+
expect(bank.exp_month).to eq(11)
|
13
|
+
expect(bank.exp_year).to eq(2099)
|
14
|
+
|
15
|
+
account = Stripe::Account.retrieve('test_account')
|
16
|
+
expect(account.external_accounts.count).to eq(1)
|
17
|
+
bank = account.external_accounts.first
|
18
|
+
expect(bank.account).to eq('test_account')
|
19
|
+
expect(bank.last4).to eq("1123")
|
20
|
+
expect(bank.exp_month).to eq(11)
|
21
|
+
expect(bank.exp_year).to eq(2099)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'creates/returns a bank when using account.external_accounts.create given bank params' do
|
25
|
+
account = Stripe::Account.create(id: 'test_account', type: 'custom', country: "US")
|
26
|
+
bank = account.external_accounts.create(external_account: {
|
27
|
+
object: 'bank_account',
|
28
|
+
account_number: '000123456789',
|
29
|
+
routing_number: '110000000',
|
30
|
+
country: 'US',
|
31
|
+
currency: 'usd'
|
32
|
+
})
|
33
|
+
|
34
|
+
expect(bank.account).to eq('test_account')
|
35
|
+
expect(bank.routing_number).to eq('110000000')
|
36
|
+
expect(bank.country).to eq('US')
|
37
|
+
expect(bank.currency).to eq('usd')
|
38
|
+
|
39
|
+
account = Stripe::Account.retrieve('test_account')
|
40
|
+
expect(account.external_accounts.count).to eq(1)
|
41
|
+
bank = account.external_accounts.first
|
42
|
+
expect(bank.account).to eq('test_account')
|
43
|
+
expect(bank.routing_number).to eq('110000000')
|
44
|
+
expect(bank.country).to eq('US')
|
45
|
+
expect(bank.currency).to eq('usd')
|
46
|
+
end
|
47
|
+
|
48
|
+
it "creates a single bank with a generated bank token" do
|
49
|
+
account = Stripe::Account.create(type: 'custom', country: "US")
|
50
|
+
expect(account.external_accounts.count).to eq 0
|
51
|
+
|
52
|
+
account.external_accounts.create external_account: stripe_helper.generate_bank_token
|
53
|
+
# Yes, stripe-ruby does not actually add the new bank to the account instance
|
54
|
+
expect(account.external_accounts.count).to eq 0
|
55
|
+
|
56
|
+
account2 = Stripe::Account.retrieve(account.id)
|
57
|
+
expect(account2.external_accounts.count).to eq 1
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "retrieval and deletion with accounts" do
|
61
|
+
let!(:account) { Stripe::Account.create(id: 'test_account', type: 'custom', country: "US") }
|
62
|
+
let!(:bank_token) { stripe_helper.generate_bank_token(last4: "1123", exp_month: 11, exp_year: 2099) }
|
63
|
+
let!(:bank) { account.external_accounts.create(external_account: bank_token) }
|
64
|
+
|
65
|
+
it "can retrieve all account's banks" do
|
66
|
+
retrieved = account.external_accounts.all
|
67
|
+
expect(retrieved.count).to eq(1)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "retrieves an account bank" do
|
71
|
+
retrieved = account.external_accounts.retrieve(bank.id)
|
72
|
+
expect(retrieved.to_s).to eq(bank.to_s)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "retrieves an account's bank after re-fetching the account" do
|
76
|
+
retrieved = Stripe::Account.retrieve(account.id).external_accounts.retrieve(bank.id)
|
77
|
+
expect(retrieved.id).to eq bank.id
|
78
|
+
end
|
79
|
+
|
80
|
+
it "deletes an accounts bank" do
|
81
|
+
bank.delete
|
82
|
+
retrieved_acct = Stripe::Account.retrieve(account.id)
|
83
|
+
expect(retrieved_acct.external_accounts.data).to be_empty
|
84
|
+
end
|
85
|
+
|
86
|
+
context "deletion when the user has two external accounts" do
|
87
|
+
let!(:bank_token_2) { stripe_helper.generate_bank_token(last4: "1123", exp_month: 11, exp_year: 2099) }
|
88
|
+
let!(:bank_2) { account.external_accounts.create(external_account: bank_token_2) }
|
89
|
+
|
90
|
+
it "has just one bank anymore" do
|
91
|
+
bank.delete
|
92
|
+
retrieved_acct = Stripe::Account.retrieve(account.id)
|
93
|
+
expect(retrieved_acct.external_accounts.data.count).to eq 1
|
94
|
+
expect(retrieved_acct.external_accounts.data.first.id).to eq bank_2.id
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "Errors" do
|
100
|
+
it "throws an error when the account does not have the retrieving bank id" do
|
101
|
+
account = Stripe::Account.create(type: 'custom', country: "US")
|
102
|
+
bank_id = "bank_123"
|
103
|
+
expect { account.external_accounts.retrieve(bank_id) }.to raise_error {|e|
|
104
|
+
expect(e).to be_a Stripe::InvalidRequestError
|
105
|
+
expect(e.message).to match /no.*source/i
|
106
|
+
expect(e.message).to include bank_id
|
107
|
+
expect(e.param).to eq 'id'
|
108
|
+
expect(e.http_status).to eq 404
|
109
|
+
}
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "update bank" do
|
114
|
+
let!(:account) { Stripe::Account.create(id: 'test_account', type: 'custom', country: "US") }
|
115
|
+
let!(:bank_token) { stripe_helper.generate_bank_token(last4: "1123", exp_month: 11, exp_year: 2099) }
|
116
|
+
let!(:bank) { account.external_accounts.create(external_account: bank_token) }
|
117
|
+
|
118
|
+
it "updates the bank" do
|
119
|
+
exp_month = 10
|
120
|
+
exp_year = 2098
|
121
|
+
|
122
|
+
bank.exp_month = exp_month
|
123
|
+
bank.exp_year = exp_year
|
124
|
+
bank.save
|
125
|
+
|
126
|
+
retrieved = account.external_accounts.retrieve(bank.id)
|
127
|
+
|
128
|
+
expect(retrieved.exp_month).to eq(exp_month)
|
129
|
+
expect(retrieved.exp_year).to eq(exp_year)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context "retrieve multiple banks" do
|
134
|
+
|
135
|
+
it "retrieves a list of multiple banks" do
|
136
|
+
account = Stripe::Account.create(id: 'test_account', type: 'custom', country: "US")
|
137
|
+
|
138
|
+
bank_token = stripe_helper.generate_bank_token(last4: "1123", exp_month: 11, exp_year: 2099)
|
139
|
+
bank1 = account.external_accounts.create(external_accout: bank_token)
|
140
|
+
bank_token = stripe_helper.generate_bank_token(last4: "1124", exp_month: 12, exp_year: 2098)
|
141
|
+
bank2 = account.external_accounts.create(external_account: bank_token)
|
142
|
+
|
143
|
+
account = Stripe::Account.retrieve('test_account')
|
144
|
+
|
145
|
+
list = account.external_accounts.all
|
146
|
+
|
147
|
+
expect(list.object).to eq("list")
|
148
|
+
expect(list.count).to eq(2)
|
149
|
+
expect(list.data.length).to eq(2)
|
150
|
+
|
151
|
+
expect(list.data.first.object).to eq("bank_account")
|
152
|
+
expect(list.data.first.to_hash).to eq(bank1.to_hash)
|
153
|
+
|
154
|
+
expect(list.data.last.object).to eq("bank_account")
|
155
|
+
expect(list.data.last.to_hash).to eq(bank2.to_hash)
|
156
|
+
end
|
157
|
+
|
158
|
+
it "retrieves an empty list if there's no subscriptions" do
|
159
|
+
Stripe::Account.create(id: 'no_banks', type: 'custom', country: "US")
|
160
|
+
account = Stripe::Account.retrieve('no_banks')
|
161
|
+
|
162
|
+
list = account.external_accounts.all
|
163
|
+
|
164
|
+
expect(list.object).to eq("list")
|
165
|
+
expect(list.count).to eq(0)
|
166
|
+
expect(list.data.length).to eq(0)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
@@ -107,12 +107,12 @@ shared_examples 'Invoice API' do
|
|
107
107
|
end
|
108
108
|
|
109
109
|
context "retrieving upcoming invoice" do
|
110
|
-
let(:customer) {
|
111
|
-
let(:coupon_amtoff) {
|
112
|
-
let(:coupon_pctoff) {
|
113
|
-
let(:plan) {
|
110
|
+
let(:customer) { Stripe::Customer.create(source: stripe_helper.generate_card_token) }
|
111
|
+
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: '50%OFF', currency: 'usd', percent_off: 50, amount_off: nil, duration: 'repeating', duration_in_months: 6) }
|
113
|
+
let(:plan) { stripe_helper.create_plan(id: '50m', amount: 50_00, interval: 'month', name: '50m', currency: 'usd') }
|
114
114
|
let(:quantity) { 3 }
|
115
|
-
let(:subscription) {
|
115
|
+
let(:subscription) { Stripe::Subscription.create(plan: plan.id, customer: customer.id, quantity: quantity) }
|
116
116
|
|
117
117
|
before(with_customer: true) { customer }
|
118
118
|
before(with_coupon_amtoff: true) { coupon_amtoff }
|
@@ -122,11 +122,11 @@ shared_examples 'Invoice API' do
|
|
122
122
|
before(with_plan: true) { plan }
|
123
123
|
before(with_subscription: true) { subscription }
|
124
124
|
|
125
|
-
after { subscription.delete rescue nil if @teardown_subscription }
|
126
|
-
after { plan.delete rescue nil if @teardown_plan }
|
127
|
-
after { coupon_pctoff.delete rescue nil if @teardown_coupon_pctoff }
|
128
|
-
after { coupon_amtoff.delete rescue nil if @teardown_coupon_amtoff }
|
129
|
-
after { customer.delete rescue nil if @teardown_customer }
|
125
|
+
# after { subscription.delete rescue nil if @teardown_subscription }
|
126
|
+
# after { plan.delete rescue nil if @teardown_plan }
|
127
|
+
# after { coupon_pctoff.delete rescue nil if @teardown_coupon_pctoff }
|
128
|
+
# after { coupon_amtoff.delete rescue nil if @teardown_coupon_amtoff }
|
129
|
+
# after { customer.delete rescue nil if @teardown_customer }
|
130
130
|
|
131
131
|
describe 'parameter validation' do
|
132
132
|
it 'fails without parameters' do
|
@@ -248,8 +248,9 @@ shared_examples 'Invoice API' do
|
|
248
248
|
|
249
249
|
[false, true].each do |with_trial|
|
250
250
|
describe "prorating a subscription with a new plan, with_trial: #{with_trial}" do
|
251
|
-
let(:new_monthly_plan) {
|
252
|
-
let(:new_yearly_plan) {
|
251
|
+
let(:new_monthly_plan) { stripe_helper.create_plan(id: '100m', amount: 100_00, interval: 'month', name: '100m', currency: 'usd') }
|
252
|
+
let(:new_yearly_plan) { stripe_helper.create_plan(id: '100y', amount: 100_00, interval: 'year', name: '100y', currency: 'usd') }
|
253
|
+
let(:plan) { stripe_helper.create_plan(id: '50m', amount: 50_00, interval: 'month', name: '50m', currency: 'usd') }
|
253
254
|
|
254
255
|
it 'prorates while maintaining billing interval', live: true do
|
255
256
|
# Given
|
@@ -341,8 +342,8 @@ shared_examples 'Invoice API' do
|
|
341
342
|
expect(upcoming.lines.data[1].quantity).to eq new_quantity
|
342
343
|
end
|
343
344
|
|
344
|
-
after { new_monthly_plan.delete rescue nil if @teardown_monthly_plan }
|
345
|
-
after { new_yearly_plan.delete rescue nil if @teardown_yearly_plan }
|
345
|
+
# after { new_monthly_plan.delete rescue nil if @teardown_monthly_plan }
|
346
|
+
# after { new_yearly_plan.delete rescue nil if @teardown_yearly_plan }
|
346
347
|
end
|
347
348
|
end
|
348
349
|
|
@@ -30,6 +30,17 @@ shared_examples 'Plan API' do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
|
33
|
+
it "creates a stripe plan without specifying ID" do
|
34
|
+
plan = Stripe::Plan.create(
|
35
|
+
:name => 'The Mock Plan',
|
36
|
+
:amount => 9900,
|
37
|
+
:currency => 'USD',
|
38
|
+
:interval => 1,
|
39
|
+
)
|
40
|
+
|
41
|
+
expect(plan.id).to match(/^test_plan/)
|
42
|
+
end
|
43
|
+
|
33
44
|
it "stores a created stripe plan in memory" do
|
34
45
|
plan = Stripe::Plan.create(
|
35
46
|
:id => 'pid_2',
|
@@ -283,6 +283,7 @@ shared_examples 'Customer Subscriptions' do
|
|
283
283
|
expect(sub.object).to eq('subscription')
|
284
284
|
expect(sub.plan.to_hash).to eq(plan.to_hash)
|
285
285
|
expect(sub.trial_end - sub.trial_start).to eq(14 * 86400)
|
286
|
+
expect(sub.billing_cycle_anchor).to be_nil
|
286
287
|
|
287
288
|
customer = Stripe::Customer.retrieve('cardless')
|
288
289
|
expect(customer.subscriptions.data).to_not be_empty
|
@@ -398,6 +399,18 @@ shared_examples 'Customer Subscriptions' do
|
|
398
399
|
}
|
399
400
|
end
|
400
401
|
|
402
|
+
it 'overrides current period end when billing cycle anchor is set' do
|
403
|
+
plan = stripe_helper.create_plan(id: 'plan', amount: 999)
|
404
|
+
customer = Stripe::Customer.create(source: gen_card_tk)
|
405
|
+
billing_cycle_anchor = Time.now.utc.to_i + 3600
|
406
|
+
|
407
|
+
sub = Stripe::Subscription.create({ plan: 'plan', customer: customer.id, billing_cycle_anchor: billing_cycle_anchor })
|
408
|
+
|
409
|
+
expect(sub.status).to eq('active')
|
410
|
+
expect(sub.current_period_end).to eq(billing_cycle_anchor)
|
411
|
+
expect(sub.billing_cycle_anchor).to eq(billing_cycle_anchor)
|
412
|
+
end
|
413
|
+
|
401
414
|
it 'when plan defined inside items', live: true do
|
402
415
|
plan = stripe_helper.create_plan(id: 'BASE_PRICE_PLAN1')
|
403
416
|
|
@@ -504,6 +517,57 @@ shared_examples 'Customer Subscriptions' do
|
|
504
517
|
expect(customer.subscriptions.data.first.customer).to eq(customer.id)
|
505
518
|
end
|
506
519
|
|
520
|
+
it "updates a stripe customer's existing subscription with single plan when multiple plans inside of items" do
|
521
|
+
silver_plan = stripe_helper.create_plan(id: 'silver')
|
522
|
+
gold_plan = stripe_helper.create_plan(id: 'gold')
|
523
|
+
addon_plan = stripe_helper.create_plan(id: 'addon_plan')
|
524
|
+
customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk, plan: silver_plan.id)
|
525
|
+
|
526
|
+
sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
|
527
|
+
sub.items = [{ plan: gold_plan.id, quantity: 2 }, { plan: addon_plan.id, quantity: 2 }]
|
528
|
+
expect(sub.save).to be_truthy
|
529
|
+
|
530
|
+
expect(sub.object).to eq('subscription')
|
531
|
+
expect(sub.plan).to be_nil
|
532
|
+
|
533
|
+
customer = Stripe::Customer.retrieve('test_customer_sub')
|
534
|
+
expect(customer.subscriptions.data).to_not be_empty
|
535
|
+
expect(customer.subscriptions.count).to eq(1)
|
536
|
+
expect(customer.subscriptions.data.length).to eq(1)
|
537
|
+
|
538
|
+
expect(customer.subscriptions.data.first.id).to eq(sub.id)
|
539
|
+
expect(customer.subscriptions.data.first.plan).to be_nil
|
540
|
+
expect(customer.subscriptions.data.first.customer).to eq(customer.id)
|
541
|
+
expect(customer.subscriptions.data.first.items.data[0].plan.to_hash).to eq(gold_plan.to_hash)
|
542
|
+
expect(customer.subscriptions.data.first.items.data[1].plan.to_hash).to eq(addon_plan.to_hash)
|
543
|
+
end
|
544
|
+
|
545
|
+
it "updates a stripe customer's existing subscription with multple plans when multiple plans inside of items" do
|
546
|
+
silver_plan = stripe_helper.create_plan(id: 'silver')
|
547
|
+
gold_plan = stripe_helper.create_plan(id: 'gold')
|
548
|
+
addon1_plan = stripe_helper.create_plan(id: 'addon1')
|
549
|
+
addon2_plan = stripe_helper.create_plan(id: 'addon2')
|
550
|
+
customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk)
|
551
|
+
sub = Stripe::Subscription.create(customer: customer.id, items: [{ plan: silver_plan.id }, { plan: addon1_plan.id }])
|
552
|
+
|
553
|
+
sub.items = [{ plan: gold_plan.id, quantity: 2 }, { plan: addon2_plan.id, quantity: 2 }]
|
554
|
+
expect(sub.save).to be_truthy
|
555
|
+
|
556
|
+
expect(sub.object).to eq('subscription')
|
557
|
+
expect(sub.plan).to be_nil
|
558
|
+
|
559
|
+
customer = Stripe::Customer.retrieve('test_customer_sub')
|
560
|
+
expect(customer.subscriptions.data).to_not be_empty
|
561
|
+
expect(customer.subscriptions.count).to eq(1)
|
562
|
+
expect(customer.subscriptions.data.length).to eq(1)
|
563
|
+
|
564
|
+
expect(customer.subscriptions.data.first.id).to eq(sub.id)
|
565
|
+
expect(customer.subscriptions.data.first.plan).to be_nil
|
566
|
+
expect(customer.subscriptions.data.first.customer).to eq(customer.id)
|
567
|
+
expect(customer.subscriptions.data.first.items.data[0].plan.to_hash).to eq(gold_plan.to_hash)
|
568
|
+
expect(customer.subscriptions.data.first.items.data[1].plan.to_hash).to eq(addon2_plan.to_hash)
|
569
|
+
end
|
570
|
+
|
507
571
|
it 'when adds coupon', live: true do
|
508
572
|
plan = stripe_helper.create_plan(id: 'plan_with_coupon2', name: 'One More Test Plan', amount: 777)
|
509
573
|
coupon = stripe_helper.create_coupon
|
@@ -857,13 +921,13 @@ shared_examples 'Customer Subscriptions' do
|
|
857
921
|
expect(subscription.items.object).to eq('list')
|
858
922
|
expect(subscription.items.data.class).to eq(Array)
|
859
923
|
expect(subscription.items.data.count).to eq(1)
|
860
|
-
expect(subscription.items.data.first.id).to eq('
|
861
|
-
expect(subscription.items.data.first.created).to eq(
|
924
|
+
expect(subscription.items.data.first.id).to eq('test_txn_default')
|
925
|
+
expect(subscription.items.data.first.created).to eq(1504716183)
|
862
926
|
expect(subscription.items.data.first.object).to eq('subscription_item')
|
863
|
-
expect(subscription.items.data.first.plan.amount).to eq(
|
864
|
-
expect(subscription.items.data.first.plan.created).to eq(
|
927
|
+
expect(subscription.items.data.first.plan.amount).to eq(0)
|
928
|
+
expect(subscription.items.data.first.plan.created).to eq(1466698898)
|
865
929
|
expect(subscription.items.data.first.plan.currency).to eq('usd')
|
866
|
-
expect(subscription.items.data.first.quantity).to eq(
|
930
|
+
expect(subscription.items.data.first.quantity).to eq(2)
|
867
931
|
end
|
868
932
|
end
|
869
933
|
|
@@ -13,6 +13,7 @@ def it_behaves_like_stripe(&block)
|
|
13
13
|
it_behaves_like 'Card API', &block
|
14
14
|
it_behaves_like 'Charge API', &block
|
15
15
|
it_behaves_like 'Bank API', &block
|
16
|
+
it_behaves_like 'External Account API', &block
|
16
17
|
it_behaves_like 'Coupon API', &block
|
17
18
|
it_behaves_like 'Customer API', &block
|
18
19
|
it_behaves_like 'Dispute 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.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gilbert
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-05-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: stripe
|
@@ -105,7 +105,6 @@ files:
|
|
105
105
|
- .gitignore
|
106
106
|
- .rspec
|
107
107
|
- .travis.yml
|
108
|
-
- ChangeLog.rdoc
|
109
108
|
- Gemfile
|
110
109
|
- LICENSE.txt
|
111
110
|
- README.md
|
@@ -146,10 +145,12 @@ files:
|
|
146
145
|
- lib/stripe_mock/request_handlers/customers.rb
|
147
146
|
- lib/stripe_mock/request_handlers/disputes.rb
|
148
147
|
- lib/stripe_mock/request_handlers/events.rb
|
148
|
+
- lib/stripe_mock/request_handlers/external_accounts.rb
|
149
149
|
- lib/stripe_mock/request_handlers/helpers/bank_account_helpers.rb
|
150
150
|
- lib/stripe_mock/request_handlers/helpers/card_helpers.rb
|
151
151
|
- lib/stripe_mock/request_handlers/helpers/charge_helpers.rb
|
152
152
|
- lib/stripe_mock/request_handlers/helpers/coupon_helpers.rb
|
153
|
+
- lib/stripe_mock/request_handlers/helpers/external_account_helpers.rb
|
153
154
|
- lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb
|
154
155
|
- lib/stripe_mock/request_handlers/helpers/token_helpers.rb
|
155
156
|
- lib/stripe_mock/request_handlers/invoice_items.rb
|
@@ -238,6 +239,7 @@ files:
|
|
238
239
|
- spec/shared_stripe_examples/customer_examples.rb
|
239
240
|
- spec/shared_stripe_examples/dispute_examples.rb
|
240
241
|
- spec/shared_stripe_examples/error_mock_examples.rb
|
242
|
+
- spec/shared_stripe_examples/external_account_examples.rb
|
241
243
|
- spec/shared_stripe_examples/extra_features_examples.rb
|
242
244
|
- spec/shared_stripe_examples/invoice_examples.rb
|
243
245
|
- spec/shared_stripe_examples/invoice_item_examples.rb
|
@@ -304,6 +306,7 @@ test_files:
|
|
304
306
|
- spec/shared_stripe_examples/customer_examples.rb
|
305
307
|
- spec/shared_stripe_examples/dispute_examples.rb
|
306
308
|
- spec/shared_stripe_examples/error_mock_examples.rb
|
309
|
+
- spec/shared_stripe_examples/external_account_examples.rb
|
307
310
|
- spec/shared_stripe_examples/extra_features_examples.rb
|
308
311
|
- spec/shared_stripe_examples/invoice_examples.rb
|
309
312
|
- spec/shared_stripe_examples/invoice_item_examples.rb
|
data/ChangeLog.rdoc
DELETED