stripe 1.9.9 → 1.10.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.
data/.travis.yml CHANGED
@@ -4,6 +4,7 @@ rvm:
4
4
  - 1.9.2
5
5
  - 1.9.3
6
6
  - 2.0.0
7
+ - 2.1.0
7
8
  gemfile:
8
9
  - gemfiles/default-with-activesupport.gemfile
9
10
  - gemfiles/json.gemfile
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ === 1.10.0 2014-01-29
2
+
3
+ * Support for multiple subscriptions per customer
4
+
1
5
  === 1.9.9 2013-12-02
2
6
 
3
7
  * Add ApplicationFee API resource
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.9.9
1
+ 1.10.0
data/lib/stripe.rb CHANGED
@@ -36,6 +36,7 @@ require 'stripe/event'
36
36
  require 'stripe/transfer'
37
37
  require 'stripe/recipient'
38
38
  require 'stripe/card'
39
+ require 'stripe/subscription'
39
40
  require 'stripe/application_fee'
40
41
 
41
42
  # Errors
@@ -1,8 +1,8 @@
1
1
  module Stripe
2
2
  module APIOperations
3
3
  module Delete
4
- def delete
5
- response, api_key = Stripe.request(:delete, url, @api_key)
4
+ def delete(params = {})
5
+ response, api_key = Stripe.request(:delete, url, @api_key, params)
6
6
  refresh_from(response, api_key)
7
7
  self
8
8
  end
data/lib/stripe/card.rb CHANGED
@@ -2,6 +2,7 @@ module Stripe
2
2
  class Card < APIResource
3
3
  include Stripe::APIOperations::Update
4
4
  include Stripe::APIOperations::Delete
5
+ include Stripe::APIOperations::List
5
6
 
6
7
  def url
7
8
  "#{Customer.url}/#{CGI.escape(customer)}/cards/#{CGI.escape(id)}"
@@ -25,6 +25,10 @@ module Stripe
25
25
  Charge.all({ :customer => id }, @api_key)
26
26
  end
27
27
 
28
+ def create_upcoming_invoice(params={})
29
+ Invoice.create(params.merge(:customer => id), @api_key)
30
+ end
31
+
28
32
  def cancel_subscription(params={})
29
33
  response, api_key = Stripe.request(:delete, subscription_url, @api_key, params)
30
34
  refresh_from({ :subscription => response }, api_key, true)
@@ -102,6 +102,12 @@ module Stripe
102
102
  @values.each(&blk)
103
103
  end
104
104
 
105
+ if RUBY_VERSION < '1.9.2'
106
+ def respond_to?(symbol)
107
+ @values.has_key?(symbol) || super
108
+ end
109
+ end
110
+
105
111
  protected
106
112
 
107
113
  def metaclass
@@ -164,5 +170,9 @@ module Stripe
164
170
  end
165
171
  end
166
172
  end
173
+
174
+ def respond_to_missing?(symbol, include_private = false)
175
+ @values.has_key?(symbol) || super
176
+ end
167
177
  end
168
178
  end
@@ -0,0 +1,25 @@
1
+ module Stripe
2
+ class Subscription < APIResource
3
+ include Stripe::APIOperations::Update
4
+ include Stripe::APIOperations::Delete
5
+
6
+ def url
7
+ "#{Customer.url}/#{CGI.escape(customer)}/subscriptions/#{CGI.escape(id)}"
8
+ end
9
+
10
+ def self.retrieve(id, api_key=nil)
11
+ raise NotImplementedError.new("Subscriptions cannot be retrieved without a customer ID. Retrieve a subscription using customer.subscriptions.retrieve('subscription_id')")
12
+ end
13
+
14
+ def delete_discount
15
+ Stripe.request(:delete, discount_url, @api_key)
16
+ refresh_from({ :discount => nil }, api_key, true)
17
+ end
18
+
19
+ private
20
+
21
+ def discount_url
22
+ url + '/discount'
23
+ end
24
+ end
25
+ end
data/lib/stripe/util.rb CHANGED
@@ -29,6 +29,7 @@ module Stripe
29
29
  'transfer' => Transfer,
30
30
  'recipient' => Recipient,
31
31
  'card' => Card,
32
+ 'subscription' => Subscription,
32
33
  'list' => ListObject,
33
34
  'application_fee' => ApplicationFee
34
35
  }
@@ -1,3 +1,3 @@
1
1
  module Stripe
2
- VERSION = '1.9.9'
2
+ VERSION = '1.10.0'
3
3
  end
data/stripe.gemspec CHANGED
@@ -10,6 +10,7 @@ spec = Gem::Specification.new do |s|
10
10
  s.authors = ['Ross Boucher', 'Greg Brockman']
11
11
  s.email = ['boucher@stripe.com', 'gdb@stripe.com']
12
12
  s.homepage = 'https://stripe.com/api'
13
+ s.license = 'MIT'
13
14
 
14
15
  s.add_dependency('rest-client', '~> 1.4')
15
16
  s.add_dependency('mime-types', '~> 1.25')
@@ -32,13 +32,19 @@ module Stripe
32
32
  assert_equal "c_test_customer", c.id
33
33
  end
34
34
 
35
+ should "create_upcoming_invoice should create a new invoice" do
36
+ @mock.expects(:post).once.returns(test_response(test_invoice))
37
+ i = Stripe::Customer.new("test_customer").create_upcoming_invoice
38
+ assert_equal "c_test_customer", i.customer
39
+ end
40
+
35
41
  should "be able to update a customer's subscription" do
36
42
  @mock.expects(:get).once.returns(test_response(test_customer))
37
43
  c = Stripe::Customer.retrieve("test_customer")
38
44
 
39
45
  @mock.expects(:post).once.with do |url, api_key, params|
40
46
  url == "#{Stripe.api_base}/v1/customers/c_test_customer/subscription" && api_key.nil? && CGI.parse(params) == {'plan' => ['silver']}
41
- end.returns(test_response(test_subscription('silver')))
47
+ end.returns(test_response(test_subscription(:plan => 'silver')))
42
48
  s = c.update_subscription({:plan => 'silver'})
43
49
 
44
50
  assert_equal 'subscription', s.object
@@ -51,10 +57,10 @@ module Stripe
51
57
 
52
58
  # Not an accurate response, but whatever
53
59
 
54
- @mock.expects(:delete).once.with("#{Stripe.api_base}/v1/customers/c_test_customer/subscription?at_period_end=true", nil, nil).returns(test_response(test_subscription('silver')))
60
+ @mock.expects(:delete).once.with("#{Stripe.api_base}/v1/customers/c_test_customer/subscription?at_period_end=true", nil, nil).returns(test_response(test_subscription(:plan => 'silver')))
55
61
  c.cancel_subscription({:at_period_end => 'true'})
56
62
 
57
- @mock.expects(:delete).once.with("#{Stripe.api_base}/v1/customers/c_test_customer/subscription", nil, nil).returns(test_response(test_subscription('silver')))
63
+ @mock.expects(:delete).once.with("#{Stripe.api_base}/v1/customers/c_test_customer/subscription", nil, nil).returns(test_response(test_subscription(:plan => 'silver')))
58
64
  c.cancel_subscription
59
65
  end
60
66
 
@@ -8,6 +8,12 @@ module Stripe
8
8
  assert_equal 'in_test_invoice', i.id
9
9
  end
10
10
 
11
+ should "create should create a new invoice" do
12
+ @mock.expects(:post).once.returns(test_response(test_invoice))
13
+ i = Stripe::Invoice.create
14
+ assert_equal "in_test_invoice", i.id
15
+ end
16
+
11
17
  should "pay should pay an invoice" do
12
18
  @mock.expects(:get).once.returns(test_response(test_invoice))
13
19
  i = Stripe::Invoice.retrieve('in_test_invoice')
@@ -17,4 +23,4 @@ module Stripe
17
23
  assert_equal i.next_payment_attempt, nil
18
24
  end
19
25
  end
20
- end
26
+ end
@@ -0,0 +1,13 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module Stripe
4
+ class StripeObjectTest < Test::Unit::TestCase
5
+ should "implement #respond_to correctly" do
6
+ obj = Stripe::StripeObject.construct_from({ :some_key => "something", :id => 123 })
7
+
8
+ assert obj.respond_to?(:id)
9
+ assert obj.respond_to?(:some_key)
10
+ assert !obj.respond_to?(:some_other_key)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,72 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module Stripe
4
+ class SubscriptionTest < Test::Unit::TestCase
5
+ should "subscriptions should be listable" do
6
+ @mock.expects(:get).once.returns(test_response(test_customer))
7
+
8
+ customer = Stripe::Customer.retrieve('test_customer')
9
+
10
+ assert customer.subscriptions.first.kind_of?(Stripe::Subscription)
11
+ end
12
+
13
+ should "subscriptions should be refreshable" do
14
+ @mock.expects(:get).twice.returns(test_response(test_customer), test_response(test_subscription(:id => 'refreshed_subscription')))
15
+
16
+ customer = Stripe::Customer.retrieve('test_customer')
17
+ subscription = customer.subscriptions.first
18
+ subscription.refresh
19
+
20
+ assert_equal subscription.id, 'refreshed_subscription'
21
+ end
22
+
23
+ should "subscriptions should be deletable" do
24
+ @mock.expects(:get).once.returns(test_response(test_customer))
25
+ customer = Stripe::Customer.retrieve('test_customer')
26
+ subscription = customer.subscriptions.first
27
+
28
+ @mock.expects(:delete).once.with("#{Stripe.api_base}/v1/customers/c_test_customer/subscriptions/#{subscription.id}?at_period_end=true", nil, nil).returns(test_response(test_subscription))
29
+ subscription.delete :at_period_end => true
30
+
31
+ @mock.expects(:delete).once.with("#{Stripe.api_base}/v1/customers/c_test_customer/subscriptions/#{subscription.id}", nil, nil).returns(test_response(test_subscription))
32
+ subscription.delete
33
+ end
34
+
35
+ should "subscriptions should be updateable" do
36
+ @mock.expects(:get).once.returns(test_response(test_customer))
37
+ @mock.expects(:post).once.returns(test_response(test_subscription({:status => 'active'})))
38
+
39
+ customer = Stripe::Customer.retrieve('test_customer')
40
+ subscription = customer.subscriptions.first
41
+ assert_equal subscription.status, 'trialing'
42
+
43
+ subscription.status = 'active'
44
+ subscription.save
45
+
46
+ assert_equal subscription.status, 'active'
47
+ end
48
+
49
+ should "create should return a new subscription" do
50
+ @mock.expects(:get).once.returns(test_response(test_customer))
51
+ @mock.expects(:post).once.returns(test_response(test_subscription(:id => 'test_new_subscription')))
52
+
53
+ customer = Stripe::Customer.retrieve('test_customer')
54
+ subscription = customer.subscriptions.create(:plan => 'silver')
55
+ assert_equal subscription.id, 'test_new_subscription'
56
+ end
57
+
58
+ should "be able to delete a subscriptions's discount" do
59
+ @mock.expects(:get).once.returns(test_response(test_customer))
60
+ @mock.expects(:post).once.returns(test_response(test_subscription(:id => 'test_new_subscription')))
61
+
62
+
63
+ customer = Stripe::Customer.retrieve("test_customer")
64
+ subscription = customer.subscriptions.create(:plan => 'silver')
65
+
66
+ url = "#{Stripe.api_base}/v1/customers/c_test_customer/subscriptions/test_new_subscription/discount"
67
+ @mock.expects(:delete).once.with(url, nil, nil).returns(test_response(test_delete_discount_response))
68
+ subscription.delete_discount
69
+ assert_equal nil, subscription.discount
70
+ end
71
+ end
72
+ end
data/test/test_helper.rb CHANGED
@@ -94,17 +94,19 @@ def test_application_fee_array
94
94
  end
95
95
 
96
96
  def test_customer(params={})
97
+ id = params[:id] || 'c_test_customer'
97
98
  {
98
99
  :subscription_history => [],
99
100
  :bills => [],
100
101
  :charges => [],
101
102
  :livemode => false,
102
103
  :object => "customer",
103
- :id => "c_test_customer",
104
+ :id => id,
104
105
  :default_card => "cc_test_card",
105
106
  :created => 1304114758,
106
- :cards => test_card_array('c_test_customer'),
107
- :metadata => {}
107
+ :cards => test_card_array(id),
108
+ :metadata => {},
109
+ :subscriptions => test_subscription_array(id)
108
110
  }.merge(params)
109
111
  end
110
112
 
@@ -180,7 +182,8 @@ def test_coupon(params={})
180
182
  end
181
183
 
182
184
  #FIXME nested overrides would be better than hardcoding plan_id
183
- def test_subscription(plan_id="gold")
185
+ def test_subscription(params = {})
186
+ plan = params.delete(:plan) || 'gold'
184
187
  {
185
188
  :current_period_end => 1308681468,
186
189
  :status => "trialing",
@@ -189,14 +192,23 @@ def test_subscription(plan_id="gold")
189
192
  :amount => 7500,
190
193
  :trial_period_days => 30,
191
194
  :object => "plan",
192
- :identifier => plan_id
195
+ :identifier => plan
193
196
  },
194
197
  :current_period_start => 1308595038,
195
198
  :start => 1308595038,
196
199
  :object => "subscription",
197
200
  :trial_start => 1308595038,
198
201
  :trial_end => 1308681468,
199
- :customer => "c_test_customer"
202
+ :customer => "c_test_customer",
203
+ :id => 's_test_subscription'
204
+ }.merge(params)
205
+ end
206
+
207
+ def test_subscription_array(customer_id)
208
+ {
209
+ :data => [test_subscription, test_subscription, test_subscription],
210
+ :object => 'list',
211
+ :url => '/v1/customers/' + customer_id + '/subscriptions'
200
212
  }
201
213
  end
202
214
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stripe
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.9
4
+ version: 1.10.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-12-04 00:00:00.000000000 Z
13
+ date: 2014-01-30 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rest-client
@@ -183,6 +183,7 @@ files:
183
183
  - lib/stripe/recipient.rb
184
184
  - lib/stripe/singleton_api_resource.rb
185
185
  - lib/stripe/stripe_object.rb
186
+ - lib/stripe/subscription.rb
186
187
  - lib/stripe/token.rb
187
188
  - lib/stripe/transfer.rb
188
189
  - lib/stripe/util.rb
@@ -197,10 +198,13 @@ files:
197
198
  - test/stripe/invoice_test.rb
198
199
  - test/stripe/list_object_test.rb
199
200
  - test/stripe/metadata_test.rb
201
+ - test/stripe/stripe_object_test.rb
202
+ - test/stripe/subscription_test.rb
200
203
  - test/stripe/util_test.rb
201
204
  - test/test_helper.rb
202
205
  homepage: https://stripe.com/api
203
- licenses: []
206
+ licenses:
207
+ - MIT
204
208
  post_install_message:
205
209
  rdoc_options: []
206
210
  require_paths:
@@ -233,5 +237,8 @@ test_files:
233
237
  - test/stripe/invoice_test.rb
234
238
  - test/stripe/list_object_test.rb
235
239
  - test/stripe/metadata_test.rb
240
+ - test/stripe/stripe_object_test.rb
241
+ - test/stripe/subscription_test.rb
236
242
  - test/stripe/util_test.rb
237
243
  - test/test_helper.rb
244
+ has_rdoc: