stripe 1.9.9 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
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: