epopia-stripe-ruby-mock 2.5.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) hide show
  1. checksums.yaml +7 -0
  2. data/.env +2 -0
  3. data/.gitignore +8 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +28 -0
  6. data/Gemfile +12 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +413 -0
  9. data/Rakefile +14 -0
  10. data/bin/stripe-mock-server +19 -0
  11. data/lib/stripe_mock.rb +95 -0
  12. data/lib/stripe_mock/api/account_balance.rb +14 -0
  13. data/lib/stripe_mock/api/bank_tokens.rb +13 -0
  14. data/lib/stripe_mock/api/card_tokens.rb +13 -0
  15. data/lib/stripe_mock/api/client.rb +41 -0
  16. data/lib/stripe_mock/api/conversion_rate.rb +14 -0
  17. data/lib/stripe_mock/api/debug.rb +11 -0
  18. data/lib/stripe_mock/api/errors.rb +65 -0
  19. data/lib/stripe_mock/api/global_id_prefix.rb +22 -0
  20. data/lib/stripe_mock/api/instance.rb +38 -0
  21. data/lib/stripe_mock/api/live.rb +15 -0
  22. data/lib/stripe_mock/api/server.rb +39 -0
  23. data/lib/stripe_mock/api/test_helpers.rb +24 -0
  24. data/lib/stripe_mock/api/webhooks.rb +88 -0
  25. data/lib/stripe_mock/client.rb +127 -0
  26. data/lib/stripe_mock/data.rb +1193 -0
  27. data/lib/stripe_mock/data/list.rb +73 -0
  28. data/lib/stripe_mock/error_queue.rb +27 -0
  29. data/lib/stripe_mock/errors/closed_client_connection_error.rb +9 -0
  30. data/lib/stripe_mock/errors/server_timeout_error.rb +12 -0
  31. data/lib/stripe_mock/errors/stripe_mock_error.rb +15 -0
  32. data/lib/stripe_mock/errors/uninitialized_instance_error.rb +9 -0
  33. data/lib/stripe_mock/errors/unstarted_state_error.rb +9 -0
  34. data/lib/stripe_mock/errors/unsupported_request_error.rb +4 -0
  35. data/lib/stripe_mock/instance.rb +237 -0
  36. data/lib/stripe_mock/request_handlers/accounts.rb +86 -0
  37. data/lib/stripe_mock/request_handlers/balance.rb +17 -0
  38. data/lib/stripe_mock/request_handlers/balance_transactions.rb +37 -0
  39. data/lib/stripe_mock/request_handlers/cards.rb +35 -0
  40. data/lib/stripe_mock/request_handlers/charges.rb +177 -0
  41. data/lib/stripe_mock/request_handlers/country_spec.rb +22 -0
  42. data/lib/stripe_mock/request_handlers/coupons.rb +35 -0
  43. data/lib/stripe_mock/request_handlers/customers.rb +137 -0
  44. data/lib/stripe_mock/request_handlers/disputes.rb +35 -0
  45. data/lib/stripe_mock/request_handlers/ephemeral_key.rb +13 -0
  46. data/lib/stripe_mock/request_handlers/events.rb +21 -0
  47. data/lib/stripe_mock/request_handlers/external_accounts.rb +55 -0
  48. data/lib/stripe_mock/request_handlers/helpers/bank_account_helpers.rb +14 -0
  49. data/lib/stripe_mock/request_handlers/helpers/card_helpers.rb +127 -0
  50. data/lib/stripe_mock/request_handlers/helpers/charge_helpers.rb +16 -0
  51. data/lib/stripe_mock/request_handlers/helpers/coupon_helpers.rb +17 -0
  52. data/lib/stripe_mock/request_handlers/helpers/external_account_helpers.rb +49 -0
  53. data/lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb +119 -0
  54. data/lib/stripe_mock/request_handlers/helpers/token_helpers.rb +44 -0
  55. data/lib/stripe_mock/request_handlers/invoice_items.rb +45 -0
  56. data/lib/stripe_mock/request_handlers/invoices.rb +177 -0
  57. data/lib/stripe_mock/request_handlers/orders.rb +80 -0
  58. data/lib/stripe_mock/request_handlers/payment_intents.rb +203 -0
  59. data/lib/stripe_mock/request_handlers/payment_methods.rb +112 -0
  60. data/lib/stripe_mock/request_handlers/payouts.rb +32 -0
  61. data/lib/stripe_mock/request_handlers/plans.rb +42 -0
  62. data/lib/stripe_mock/request_handlers/products.rb +43 -0
  63. data/lib/stripe_mock/request_handlers/recipients.rb +60 -0
  64. data/lib/stripe_mock/request_handlers/refunds.rb +91 -0
  65. data/lib/stripe_mock/request_handlers/sources.rb +55 -0
  66. data/lib/stripe_mock/request_handlers/subscription_items.rb +36 -0
  67. data/lib/stripe_mock/request_handlers/subscriptions.rb +296 -0
  68. data/lib/stripe_mock/request_handlers/tax_rates.rb +36 -0
  69. data/lib/stripe_mock/request_handlers/tokens.rb +75 -0
  70. data/lib/stripe_mock/request_handlers/transfers.rb +65 -0
  71. data/lib/stripe_mock/request_handlers/validators/param_validators.rb +32 -0
  72. data/lib/stripe_mock/server.rb +93 -0
  73. data/lib/stripe_mock/test_strategies/base.rb +81 -0
  74. data/lib/stripe_mock/test_strategies/live.rb +40 -0
  75. data/lib/stripe_mock/test_strategies/mock.rb +27 -0
  76. data/lib/stripe_mock/util.rb +44 -0
  77. data/lib/stripe_mock/version.rb +4 -0
  78. data/lib/stripe_mock/webhook_fixtures/account.application.deauthorized.json +12 -0
  79. data/lib/stripe_mock/webhook_fixtures/account.external_account.created.json +27 -0
  80. data/lib/stripe_mock/webhook_fixtures/account.external_account.deleted.json +27 -0
  81. data/lib/stripe_mock/webhook_fixtures/account.external_account.updated.json +27 -0
  82. data/lib/stripe_mock/webhook_fixtures/account.updated.json +26 -0
  83. data/lib/stripe_mock/webhook_fixtures/balance.available.json +25 -0
  84. data/lib/stripe_mock/webhook_fixtures/charge.dispute.closed.json +22 -0
  85. data/lib/stripe_mock/webhook_fixtures/charge.dispute.created.json +22 -0
  86. data/lib/stripe_mock/webhook_fixtures/charge.dispute.funds_reinstated.json +88 -0
  87. data/lib/stripe_mock/webhook_fixtures/charge.dispute.funds_withdrawn.json +88 -0
  88. data/lib/stripe_mock/webhook_fixtures/charge.dispute.updated.json +25 -0
  89. data/lib/stripe_mock/webhook_fixtures/charge.failed.json +56 -0
  90. data/lib/stripe_mock/webhook_fixtures/charge.refunded.json +69 -0
  91. data/lib/stripe_mock/webhook_fixtures/charge.succeeded.json +55 -0
  92. data/lib/stripe_mock/webhook_fixtures/charge.updated.json +58 -0
  93. data/lib/stripe_mock/webhook_fixtures/coupon.created.json +23 -0
  94. data/lib/stripe_mock/webhook_fixtures/coupon.deleted.json +23 -0
  95. data/lib/stripe_mock/webhook_fixtures/customer.created.json +54 -0
  96. data/lib/stripe_mock/webhook_fixtures/customer.deleted.json +42 -0
  97. data/lib/stripe_mock/webhook_fixtures/customer.discount.created.json +28 -0
  98. data/lib/stripe_mock/webhook_fixtures/customer.discount.deleted.json +28 -0
  99. data/lib/stripe_mock/webhook_fixtures/customer.discount.updated.json +43 -0
  100. data/lib/stripe_mock/webhook_fixtures/customer.source.created.json +32 -0
  101. data/lib/stripe_mock/webhook_fixtures/customer.source.deleted.json +32 -0
  102. data/lib/stripe_mock/webhook_fixtures/customer.source.updated.json +36 -0
  103. data/lib/stripe_mock/webhook_fixtures/customer.subscription.created.json +66 -0
  104. data/lib/stripe_mock/webhook_fixtures/customer.subscription.deleted.json +65 -0
  105. data/lib/stripe_mock/webhook_fixtures/customer.subscription.trial_will_end.json +65 -0
  106. data/lib/stripe_mock/webhook_fixtures/customer.subscription.updated.json +78 -0
  107. data/lib/stripe_mock/webhook_fixtures/customer.updated.json +57 -0
  108. data/lib/stripe_mock/webhook_fixtures/invoice.created.json +71 -0
  109. data/lib/stripe_mock/webhook_fixtures/invoice.payment_failed.json +105 -0
  110. data/lib/stripe_mock/webhook_fixtures/invoice.payment_succeeded.json +112 -0
  111. data/lib/stripe_mock/webhook_fixtures/invoice.updated.json +74 -0
  112. data/lib/stripe_mock/webhook_fixtures/invoiceitem.created.json +21 -0
  113. data/lib/stripe_mock/webhook_fixtures/invoiceitem.deleted.json +21 -0
  114. data/lib/stripe_mock/webhook_fixtures/invoiceitem.updated.json +24 -0
  115. data/lib/stripe_mock/webhook_fixtures/plan.created.json +20 -0
  116. data/lib/stripe_mock/webhook_fixtures/plan.deleted.json +20 -0
  117. data/lib/stripe_mock/webhook_fixtures/plan.updated.json +23 -0
  118. data/lib/stripe_mock/webhook_fixtures/transfer.created.json +89 -0
  119. data/lib/stripe_mock/webhook_fixtures/transfer.failed.json +89 -0
  120. data/lib/stripe_mock/webhook_fixtures/transfer.paid.json +89 -0
  121. data/lib/stripe_mock/webhook_fixtures/transfer.updated.json +92 -0
  122. data/lib/trollop.rb +782 -0
  123. data/spec/_dummy/webhooks/dummy.event.json +6 -0
  124. data/spec/api/instance_spec.rb +30 -0
  125. data/spec/fixtures/create_refund.yml +126 -0
  126. data/spec/fixtures/stripe_webhooks/account.updated.json +7 -0
  127. data/spec/fixtures/stripe_webhooks/custom.account.updated.json +5 -0
  128. data/spec/instance_spec.rb +100 -0
  129. data/spec/integration_examples/charge_token_examples.rb +51 -0
  130. data/spec/integration_examples/customer_card_examples.rb +42 -0
  131. data/spec/integration_examples/prepare_error_examples.rb +38 -0
  132. data/spec/list_spec.rb +140 -0
  133. data/spec/readme_spec.rb +75 -0
  134. data/spec/server_spec.rb +139 -0
  135. data/spec/shared_stripe_examples/account_examples.rb +96 -0
  136. data/spec/shared_stripe_examples/balance_examples.rb +11 -0
  137. data/spec/shared_stripe_examples/balance_transaction_examples.rb +63 -0
  138. data/spec/shared_stripe_examples/bank_examples.rb +229 -0
  139. data/spec/shared_stripe_examples/bank_token_examples.rb +59 -0
  140. data/spec/shared_stripe_examples/card_examples.rb +307 -0
  141. data/spec/shared_stripe_examples/card_token_examples.rb +185 -0
  142. data/spec/shared_stripe_examples/charge_examples.rb +510 -0
  143. data/spec/shared_stripe_examples/country_specs_examples.rb +18 -0
  144. data/spec/shared_stripe_examples/coupon_examples.rb +85 -0
  145. data/spec/shared_stripe_examples/customer_examples.rb +453 -0
  146. data/spec/shared_stripe_examples/dispute_examples.rb +98 -0
  147. data/spec/shared_stripe_examples/ephemeral_key_examples.rb +17 -0
  148. data/spec/shared_stripe_examples/error_mock_examples.rb +162 -0
  149. data/spec/shared_stripe_examples/external_account_examples.rb +170 -0
  150. data/spec/shared_stripe_examples/extra_features_examples.rb +36 -0
  151. data/spec/shared_stripe_examples/invoice_examples.rb +524 -0
  152. data/spec/shared_stripe_examples/invoice_item_examples.rb +69 -0
  153. data/spec/shared_stripe_examples/payment_intent_examples.rb +131 -0
  154. data/spec/shared_stripe_examples/payment_method_examples.rb +175 -0
  155. data/spec/shared_stripe_examples/payout_examples.rb +68 -0
  156. data/spec/shared_stripe_examples/plan_examples.rb +194 -0
  157. data/spec/shared_stripe_examples/product_example.rb +65 -0
  158. data/spec/shared_stripe_examples/recipient_examples.rb +118 -0
  159. data/spec/shared_stripe_examples/refund_examples.rb +472 -0
  160. data/spec/shared_stripe_examples/subscription_examples.rb +1148 -0
  161. data/spec/shared_stripe_examples/subscription_items_examples.rb +75 -0
  162. data/spec/shared_stripe_examples/tax_rate_examples.rb +42 -0
  163. data/spec/shared_stripe_examples/transfer_examples.rb +130 -0
  164. data/spec/shared_stripe_examples/validation_examples.rb +19 -0
  165. data/spec/shared_stripe_examples/webhook_event_examples.rb +261 -0
  166. data/spec/spec_helper.rb +58 -0
  167. data/spec/stripe_mock_spec.rb +123 -0
  168. data/spec/support/stripe_examples.rb +42 -0
  169. data/spec/util_spec.rb +121 -0
  170. data/stripe-ruby-mock.gemspec +27 -0
  171. metadata +344 -0
@@ -0,0 +1,1148 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples 'Customer Subscriptions' do
4
+
5
+ def gen_card_tk
6
+ stripe_helper.generate_card_token
7
+ end
8
+
9
+ context "creating a new subscription" do
10
+ it "adds a new subscription to customer with none using items", :live => true do
11
+ plan = stripe_helper.create_plan(id: 'silver', product: { name: 'Silver Plan' },
12
+ amount: 4999, currency: 'usd')
13
+ customer = Stripe::Customer.create(source: gen_card_tk)
14
+
15
+ expect(customer.subscriptions.data).to be_empty
16
+ expect(customer.subscriptions.count).to eq(0)
17
+
18
+ sub = Stripe::Subscription.create({ items: [{ plan: 'silver' }],
19
+ customer: customer.id, metadata: { foo: "bar", example: "yes" } })
20
+
21
+ expect(sub.object).to eq('subscription')
22
+ expect(sub.plan.to_hash).to eq(plan.to_hash)
23
+ expect(sub.metadata.foo).to eq( "bar" )
24
+ expect(sub.metadata.example).to eq( "yes" )
25
+
26
+ customer = Stripe::Customer.retrieve(customer.id)
27
+ expect(customer.subscriptions.data).to_not be_empty
28
+ expect(customer.subscriptions.count).to eq(1)
29
+ expect(customer.subscriptions.data.length).to eq(1)
30
+ expect(customer.charges.data.length).to eq(1)
31
+ expect(customer.currency).to eq( "usd" )
32
+
33
+ expect(customer.subscriptions.data.first.id).to eq(sub.id)
34
+ expect(customer.subscriptions.data.first.plan.to_hash).to eq(plan.to_hash)
35
+ expect(customer.subscriptions.data.first.customer).to eq(customer.id)
36
+ expect(customer.subscriptions.data.first.metadata.foo).to eq( "bar" )
37
+ expect(customer.subscriptions.data.first.metadata.example).to eq( "yes" )
38
+ end
39
+
40
+ it "adds a new subscription to customer with none", :live => true do
41
+ plan = stripe_helper.create_plan(id: 'silver', product: { name: 'Silver Plan' },
42
+ amount: 4999, currency: 'usd')
43
+ customer = Stripe::Customer.create(source: gen_card_tk)
44
+
45
+ expect(customer.subscriptions.data).to be_empty
46
+ expect(customer.subscriptions.count).to eq(0)
47
+
48
+ sub = Stripe::Subscription.create({ plan: 'silver', customer: customer.id, metadata: { foo: "bar", example: "yes" } })
49
+
50
+ expect(sub.object).to eq('subscription')
51
+ expect(sub.plan.to_hash).to eq(plan.to_hash)
52
+ expect(sub.metadata.foo).to eq( "bar" )
53
+ expect(sub.metadata.example).to eq( "yes" )
54
+
55
+ customer = Stripe::Customer.retrieve(customer.id)
56
+ expect(customer.subscriptions.data).to_not be_empty
57
+ expect(customer.subscriptions.count).to eq(1)
58
+ expect(customer.subscriptions.data.length).to eq(1)
59
+ expect(customer.charges.data.length).to eq(1)
60
+ expect(customer.currency).to eq( "usd" )
61
+
62
+ expect(customer.subscriptions.data.first.id).to eq(sub.id)
63
+ expect(customer.subscriptions.data.first.plan.to_hash).to eq(plan.to_hash)
64
+ expect(customer.subscriptions.data.first.customer).to eq(customer.id)
65
+ expect(customer.subscriptions.data.first.billing).to eq('charge_automatically')
66
+ expect(customer.subscriptions.data.first.metadata.foo).to eq( "bar" )
67
+ expect(customer.subscriptions.data.first.metadata.example).to eq( "yes" )
68
+ end
69
+
70
+ it 'when customer object provided' do
71
+ plan = stripe_helper.create_plan(id: 'silver', product: { name: 'Silver Plan' }, amount: 4999, currency: 'usd')
72
+ customer = Stripe::Customer.create(source: gen_card_tk)
73
+
74
+ expect(customer.subscriptions.data).to be_empty
75
+ expect(customer.subscriptions.count).to eq(0)
76
+
77
+ sub = Stripe::Subscription.create({ plan: 'silver', customer: customer, metadata: { foo: "bar", example: "yes" } })
78
+
79
+ expect(sub.object).to eq('subscription')
80
+ expect(sub.plan.to_hash).to eq(plan.to_hash)
81
+ expect(sub.billing).to eq('charge_automatically')
82
+ expect(sub.metadata.foo).to eq( "bar" )
83
+ expect(sub.metadata.example).to eq( "yes" )
84
+
85
+ customer = Stripe::Customer.retrieve(customer.id)
86
+ expect(customer.subscriptions.data).to_not be_empty
87
+ expect(customer.subscriptions.count).to eq(1)
88
+ expect(customer.subscriptions.data.length).to eq(1)
89
+ expect(customer.charges.data.length).to eq(1)
90
+ expect(customer.currency).to eq( "usd" )
91
+
92
+ expect(customer.subscriptions.data.first.id).to eq(sub.id)
93
+ expect(customer.subscriptions.data.first.plan.to_hash).to eq(plan.to_hash)
94
+
95
+ expect(customer.subscriptions.data.first.customer).to eq(customer.id)
96
+ expect(customer.subscriptions.data.first.billing).to eq('charge_automatically')
97
+ expect(customer.subscriptions.data.first.metadata.foo).to eq( "bar" )
98
+ expect(customer.subscriptions.data.first.metadata.example).to eq( "yes" )
99
+ end
100
+
101
+ it "adds a new subscription to customer (string/symbol agnostic)" do
102
+ customer = Stripe::Customer.create(source: gen_card_tk)
103
+ expect(customer.subscriptions.count).to eq(0)
104
+
105
+ plan = stripe_helper.create_plan(id: :silver, product: { name: 'Silver Plan' },
106
+ amount: 4999, currency: 'usd')
107
+ sub = Stripe::Subscription.create({ plan: 'silver', customer: customer.id })
108
+ customer = Stripe::Customer.retrieve(customer.id)
109
+ expect(sub.plan.to_hash).to eq(plan.to_hash)
110
+ expect(customer.subscriptions.count).to eq(1)
111
+
112
+ plan = stripe_helper.create_plan(id: 'gold', product: { name: 'Gold Plan' },
113
+ amount: 14999, currency: 'usd')
114
+ sub = Stripe::Subscription.create({ plan: 'gold', customer: customer.id })
115
+ customer = Stripe::Customer.retrieve(customer.id)
116
+ expect(sub.plan.to_hash).to eq(plan.to_hash)
117
+ expect(customer.subscriptions.count).to eq(2)
118
+ end
119
+
120
+ it 'creates a charge for the customer', live: true do
121
+ stripe_helper.create_plan(id: 'silver', product: { name: 'Silver Plan' },
122
+ amount: 4999)
123
+
124
+ customer = Stripe::Customer.create(source: gen_card_tk)
125
+ Stripe::Subscription.create({ plan: 'silver', customer: customer.id, metadata: { foo: "bar", example: "yes" } })
126
+ customer = Stripe::Customer.retrieve(customer.id)
127
+
128
+ expect(customer.charges.data.length).to eq(1)
129
+ expect(customer.charges.data.first.amount).to eq(4999)
130
+ end
131
+
132
+ it 'contains coupon object', live: true do
133
+ plan = stripe_helper.create_plan(id: 'plan_with_coupon', product: { name: 'One More Test Plan' },
134
+ amount: 777)
135
+ coupon = stripe_helper.create_coupon(id: 'free_coupon', duration: 'repeating', duration_in_months: 3)
136
+ customer = Stripe::Customer.create(source: gen_card_tk)
137
+ Stripe::Subscription.create(plan: plan.id, customer: customer.id, coupon: coupon.id)
138
+ customer = Stripe::Customer.retrieve(customer.id)
139
+
140
+ expect(customer.subscriptions.data).to be_a(Array)
141
+ expect(customer.subscriptions.data.count).to eq(1)
142
+ expect(customer.subscriptions.data.first.discount).not_to be_nil
143
+ expect(customer.subscriptions.data.first.discount).to be_a(Stripe::Discount)
144
+ expect(customer.subscriptions.data.first.discount.coupon.id).to eq(coupon.id)
145
+ end
146
+
147
+ it 'when coupon is not exist', live: true do
148
+ plan = stripe_helper.create_plan(id: 'plan_with_coupon', product: { name: 'One More Test Plan' },
149
+ amount: 777)
150
+ customer = Stripe::Customer.create(source: gen_card_tk)
151
+
152
+ expect { Stripe::Subscription.create(plan: plan.id, customer: customer.id, coupon: 'none') }.to raise_error {|e|
153
+ expect(e).to be_a Stripe::InvalidRequestError
154
+ expect(e.http_status).to eq(400)
155
+ expect(e.message).to eq('No such coupon: none')
156
+ }
157
+ end
158
+
159
+ it "correctly sets quantity, application_fee_percent and tax_percent" do
160
+ Stripe::Plan.create(
161
+ :amount => 2500,
162
+ :interval => 'month',
163
+ :product => {
164
+ :name => 'Test plan'
165
+ },
166
+ :currency => 'usd',
167
+ :id => 'silver',
168
+ :statement_description => "testPlan"
169
+ )
170
+ customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk)
171
+
172
+ subscription = Stripe::Subscription.create({
173
+ plan: "silver", customer: customer.id, quantity: 2, application_fee_percent: 10, tax_percent: 20})
174
+ expect(subscription.quantity).to eq(2)
175
+ expect(subscription.application_fee_percent).to eq(10)
176
+ expect(subscription.tax_percent).to eq(20)
177
+ end
178
+
179
+ it "correctly sets created when it's not provided as a parameter", live: true do
180
+ customer = Stripe::Customer.create(source: gen_card_tk)
181
+ plan = stripe_helper.create_plan(id: 'silver', product: { name: 'Silver Plan' },
182
+ amount: 4999, currency: 'usd')
183
+ subscription = Stripe::Subscription.create({ plan: 'silver', customer: customer.id })
184
+
185
+ expect(subscription.created).to eq(subscription.current_period_start)
186
+ end
187
+
188
+ it "correctly sets created when it's provided as a parameter" do
189
+ customer = Stripe::Customer.create(source: gen_card_tk)
190
+ plan = stripe_helper.create_plan(id: 'silver', product: { name: 'Silver Plan' },
191
+ amount: 4999, currency: 'usd')
192
+ subscription = Stripe::Subscription.create({ plan: 'silver', customer: customer.id, created: 1473576318 })
193
+
194
+ expect(subscription.created).to eq(1473576318)
195
+ end
196
+
197
+ it "adds additional subscription to customer with existing subscription" do
198
+ silver = stripe_helper.create_plan(id: 'silver')
199
+ gold = stripe_helper.create_plan(id: 'gold')
200
+ customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk, plan: 'gold')
201
+
202
+ sub = Stripe::Subscription.create({ plan: 'silver', customer: customer.id })
203
+
204
+ expect(sub.object).to eq('subscription')
205
+ expect(sub.plan.to_hash).to eq(silver.to_hash)
206
+
207
+ customer = Stripe::Customer.retrieve('test_customer_sub')
208
+ expect(customer.subscriptions.data).to_not be_empty
209
+ expect(customer.subscriptions.count).to eq(2)
210
+ expect(customer.subscriptions.data.length).to eq(2)
211
+
212
+ expect(customer.subscriptions.data.last.plan.to_hash).to eq(gold.to_hash)
213
+ expect(customer.subscriptions.data.last.customer).to eq(customer.id)
214
+
215
+ expect(customer.subscriptions.data.first.id).to eq(sub.id)
216
+ expect(customer.subscriptions.data.first.plan.to_hash).to eq(silver.to_hash)
217
+ expect(customer.subscriptions.data.first.customer).to eq(customer.id)
218
+ end
219
+
220
+ it "subscribes a cardless customer when specifing a card token" do
221
+ plan = stripe_helper.create_plan(id: 'enterprise', amount: 499)
222
+ customer = Stripe::Customer.create(id: 'cardless')
223
+
224
+ sub = Stripe::Subscription.create(plan: 'enterprise', customer: customer.id, source: gen_card_tk)
225
+ customer = Stripe::Customer.retrieve('cardless')
226
+
227
+ expect(customer.subscriptions.data.first.id).to eq(sub.id)
228
+ expect(customer.subscriptions.data.first.customer).to eq(customer.id)
229
+
230
+ expect(customer.sources.count).to eq(1)
231
+ expect(customer.sources.data.length).to eq(1)
232
+ expect(customer.default_source).to_not be_nil
233
+ expect(customer.default_source).to eq customer.sources.data.first.id
234
+ end
235
+
236
+ it "throws an error when plan does not exist" do
237
+ customer = Stripe::Customer.create(id: 'cardless')
238
+
239
+ expect { Stripe::Subscription.create({ plan: 'gazebo', customer: customer.id }) }.to raise_error {|e|
240
+ expect(e).to be_a Stripe::InvalidRequestError
241
+ expect(e.http_status).to eq(404)
242
+ expect(e.message).to_not be_nil
243
+ }
244
+
245
+ expect(customer.subscriptions.data).to be_empty
246
+ expect(customer.subscriptions.count).to eq(0)
247
+ end
248
+
249
+ it "throws an error when subscribing a customer with no card" do
250
+ plan = stripe_helper.create_plan(id: 'enterprise', amount: 499)
251
+ customer = Stripe::Customer.create(id: 'cardless')
252
+
253
+ expect { Stripe::Subscription.create({ plan: 'enterprise', customer: customer.id }) }.to raise_error {|e|
254
+ expect(e).to be_a Stripe::InvalidRequestError
255
+ expect(e.http_status).to eq(400)
256
+ expect(e.message).to_not be_nil
257
+ }
258
+
259
+ expect(customer.subscriptions.data).to be_empty
260
+ expect(customer.subscriptions.count).to eq(0)
261
+ end
262
+
263
+ it "throws an error when subscribing the customer to a second plan in a different currency" do
264
+ usd_plan = stripe_helper.create_plan(id: 'enterprise_usd', amount: 499, currency: 'usd')
265
+ customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk)
266
+ usd_subscription = Stripe::Subscription.create({ plan: 'enterprise_usd', customer: customer.id })
267
+
268
+ eur_plan = stripe_helper.create_plan(id: 'enterprise_eur', amount: 499, currency: 'eur')
269
+ expect { Stripe::Subscription.create({ plan: 'enterprise_eur', customer: customer.id }) }.to raise_error {|e|
270
+ expect(e).to be_a Stripe::InvalidRequestError
271
+ expect(e.http_status).to eq(400)
272
+ expect(e.message).to_not be_nil
273
+ }
274
+ end
275
+
276
+ it 'when attempting to create a new subscription with the params trial', live: true do
277
+ plan = stripe_helper.create_plan(id: 'trial', amount: 999)
278
+ customer = Stripe::Customer.create(source: gen_card_tk)
279
+
280
+ expect{ Stripe::Subscription.create(plan: plan.id, customer: customer.id, trial: 10) }.to raise_error {|e|
281
+ expect(e).to be_a Stripe::InvalidRequestError
282
+ expect(e.http_status).to eq(400)
283
+ expect(e.param).to eq('trial')
284
+ expect(e.message).to match /Received unknown parameter/
285
+ }
286
+ end
287
+
288
+ it "subscribes a customer with no card to a plan with a free trial" do
289
+ plan = stripe_helper.create_plan(id: 'trial', amount: 999, trial_period_days: 14)
290
+ customer = Stripe::Customer.create(id: 'cardless')
291
+
292
+ sub = Stripe::Subscription.create({ plan: 'trial', customer: customer.id })
293
+
294
+ expect(sub.object).to eq('subscription')
295
+ expect(sub.plan.to_hash).to eq(plan.to_hash)
296
+ expect(sub.trial_end - sub.trial_start).to eq(14 * 86400)
297
+ expect(sub.billing_cycle_anchor).to be_nil
298
+
299
+ customer = Stripe::Customer.retrieve('cardless')
300
+ expect(customer.subscriptions.data).to_not be_empty
301
+ expect(customer.subscriptions.count).to eq(1)
302
+ expect(customer.subscriptions.data.length).to eq(1)
303
+
304
+ expect(customer.subscriptions.data.first.id).to eq(sub.id)
305
+ expect(customer.subscriptions.data.first.plan.to_hash).to eq(plan.to_hash)
306
+ expect(customer.subscriptions.data.first.customer).to eq(customer.id)
307
+ expect(customer.charges.count).to eq(0)
308
+ end
309
+
310
+ it "subscribes a customer with no card to a plan with a free trial with plan as item" do
311
+ plan = stripe_helper.create_plan(id: 'trial', amount: 999, trial_period_days: 14)
312
+ customer = Stripe::Customer.create(id: 'cardless')
313
+
314
+ sub = Stripe::Subscription.create({ items: [ { plan: 'trial' } ], customer: customer.id })
315
+
316
+ expect(sub.object).to eq('subscription')
317
+ expect(sub.items.data[0].plan.to_hash).to eq(plan.to_hash)
318
+ # no idea how to fix this one
319
+ # expect(sub.trial_end - sub.trial_start).to eq(14 * 86400)
320
+
321
+ customer = Stripe::Customer.retrieve('cardless')
322
+ expect(customer.subscriptions.data).to_not be_empty
323
+ expect(customer.subscriptions.count).to eq(1)
324
+ expect(customer.subscriptions.data.length).to eq(1)
325
+
326
+ expect(customer.subscriptions.data.first.id).to eq(sub.id)
327
+ expect(customer.subscriptions.data.first.items.data.first.plan.to_hash).to eq(plan.to_hash)
328
+ expect(customer.subscriptions.data.first.customer).to eq(customer.id)
329
+ # No idea on this one
330
+ # expect(customer.charges.count).to eq(0)
331
+ end
332
+
333
+ it "subscribes a customer with no card to a free plan" do
334
+ plan = stripe_helper.create_plan(id: 'free_tier', amount: 0)
335
+ customer = Stripe::Customer.create(id: 'cardless')
336
+
337
+ sub = Stripe::Subscription.create({ plan: 'free_tier', customer: customer.id })
338
+
339
+ expect(sub.object).to eq('subscription')
340
+ expect(sub.plan.to_hash).to eq(plan.to_hash)
341
+
342
+ customer = Stripe::Customer.retrieve('cardless')
343
+ expect(customer.subscriptions.data).to_not be_empty
344
+ expect(customer.subscriptions.count).to eq(1)
345
+ expect(customer.subscriptions.data.length).to eq(1)
346
+
347
+ expect(customer.subscriptions.data.first.id).to eq(sub.id)
348
+ expect(customer.subscriptions.data.first.plan.to_hash).to eq(plan.to_hash)
349
+ expect(customer.subscriptions.data.first.customer).to eq(customer.id)
350
+ end
351
+
352
+ it "overrides trial length when trial end is set" do
353
+ plan = stripe_helper.create_plan(id: 'trial', amount: 999, trial_period_days: 14)
354
+ customer = Stripe::Customer.create(id: 'short_trial')
355
+ trial_end = Time.now.utc.to_i + 3600
356
+
357
+ sub = Stripe::Subscription.create({ plan: 'trial', customer: customer.id, trial_end: trial_end })
358
+
359
+ expect(sub.object).to eq('subscription')
360
+ expect(sub.plan.to_hash).to eq(plan.to_hash)
361
+ expect(sub.current_period_end).to eq(trial_end)
362
+ expect(sub.trial_end).to eq(trial_end)
363
+ end
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
+
389
+ it "returns without a trial when trial_end is set to 'now'" do
390
+ plan = stripe_helper.create_plan(id: 'trial', amount: 999, trial_period_days: 14)
391
+ customer = Stripe::Customer.create(id: 'no_trial', source: gen_card_tk)
392
+
393
+ sub = Stripe::Subscription.create({ plan: 'trial', customer: customer.id, trial_end: "now" })
394
+
395
+ expect(sub.object).to eq('subscription')
396
+ expect(sub.plan.to_hash).to eq(plan.to_hash)
397
+ expect(sub.status).to eq('active')
398
+ expect(sub.trial_start).to be_nil
399
+ expect(sub.trial_end).to be_nil
400
+ end
401
+
402
+ it "raises error when trial_end is not an integer or 'now'" do
403
+ plan = stripe_helper.create_plan(id: 'trial', amount: 999, trial_period_days: 14)
404
+ customer = Stripe::Customer.create(id: 'cus_trial')
405
+
406
+ expect { Stripe::Subscription.create({ plan: 'trial', customer: customer.id, trial_end: "gazebo" }) }.to raise_error {|e|
407
+ expect(e).to be_a Stripe::InvalidRequestError
408
+ expect(e.http_status).to eq(400)
409
+ expect(e.message).to eq("Invalid timestamp: must be an integer")
410
+ }
411
+ end
412
+
413
+ it "raises error when trial_end is set to a time in the past" do
414
+ plan = stripe_helper.create_plan(id: 'trial', amount: 999, trial_period_days: 14)
415
+ customer = Stripe::Customer.create(id: 'past_trial')
416
+ trial_end = Time.now.utc.to_i - 3600
417
+
418
+ expect { Stripe::Subscription.create({ plan: 'trial', customer: customer.id, trial_end: trial_end }) }.to raise_error {|e|
419
+ expect(e).to be_a Stripe::InvalidRequestError
420
+ expect(e.http_status).to eq(400)
421
+ expect(e.message).to eq("Invalid timestamp: must be an integer Unix timestamp in the future")
422
+ }
423
+ end
424
+
425
+ it "raises error when trial_end is set to a time more than five years in the future" do
426
+ plan = stripe_helper.create_plan(id: 'trial', amount: 999, trial_period_days: 14)
427
+ customer = Stripe::Customer.create(id: 'long_trial')
428
+ trial_end = Time.now.utc.to_i + 31557600*5 + 3600 # 5 years + 1 hour
429
+
430
+ expect { Stripe::Subscription.create({ plan: 'trial', customer: customer.id, trial_end: trial_end }) }.to raise_error {|e|
431
+ expect(e).to be_a Stripe::InvalidRequestError
432
+ expect(e.http_status).to eq(400)
433
+ expect(e.message).to eq("Invalid timestamp: can be no more than five years in the future")
434
+ }
435
+ end
436
+
437
+ it 'overrides current period end when billing cycle anchor is set' do
438
+ plan = stripe_helper.create_plan(id: 'plan', amount: 999)
439
+ customer = Stripe::Customer.create(source: gen_card_tk)
440
+ billing_cycle_anchor = Time.now.utc.to_i + 3600
441
+
442
+ sub = Stripe::Subscription.create({ plan: 'plan', customer: customer.id, billing_cycle_anchor: billing_cycle_anchor })
443
+
444
+ expect(sub.status).to eq('active')
445
+ expect(sub.current_period_end).to eq(billing_cycle_anchor)
446
+ expect(sub.billing_cycle_anchor).to eq(billing_cycle_anchor)
447
+ end
448
+
449
+ it 'when plan defined inside items', live: true do
450
+ plan = stripe_helper.create_plan(id: 'BASE_PRICE_PLAN1')
451
+
452
+ plan2 = stripe_helper.create_plan(id: 'PER_USER_PLAN1')
453
+ customer = Stripe::Customer.create(
454
+ source: {
455
+ object: 'card',
456
+ exp_month: 11,
457
+ exp_year: 2019,
458
+ number: '4242424242424242',
459
+ cvc: '123'
460
+ }
461
+ )
462
+ subscription = Stripe::Subscription.create(
463
+ customer: customer.id,
464
+ items: [
465
+ { plan: plan.id, quantity: 1 },
466
+ { plan: plan2.id, quantity: 2 }
467
+ ]
468
+ )
469
+
470
+ expect(subscription.id).to match /(test_su_|sub_).+/
471
+ expect(subscription.plan).to eq nil
472
+ expect(subscription.items.data[0].plan.id).to eq plan.id
473
+ expect(subscription.items.data[1].plan.id).to eq plan2.id
474
+ expect(subscription.items.data[0].quantity).to eq 1
475
+ expect(subscription.items.data[1].quantity).to eq 2
476
+ end
477
+
478
+ it 'when plan defined inside items for trials with no card', live: true do
479
+ plan = stripe_helper.create_plan(id: 'BASE_PRICE_PLAN1')
480
+
481
+ plan2 = stripe_helper.create_plan(id: 'PER_USER_PLAN1')
482
+ customer = Stripe::Customer.create
483
+ trial_end = Time.now.utc.to_i + 3600
484
+
485
+ subscription = Stripe::Subscription.create(
486
+ customer: customer.id,
487
+ items: [
488
+ { plan: plan.id, quantity: 1 },
489
+ { plan: plan2.id, quantity: 2 }
490
+ ],
491
+ trial_end: trial_end
492
+ )
493
+
494
+ expect(subscription.id).to match /(test_su_|sub_).+/
495
+ expect(subscription.plan).to eq nil
496
+ expect(subscription.items.data[0].plan.id).to eq plan.id
497
+ expect(subscription.items.data[1].plan.id).to eq plan2.id
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
555
+
556
+ it "accepts a hash of items" do
557
+ silver = stripe_helper.create_plan(id: 'silver')
558
+ customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk)
559
+
560
+ sub = Stripe::Subscription.create({ items: { '0' => { plan: 'silver' } }, customer: customer.id })
561
+ sub.delete(at_period_end: true)
562
+
563
+ expect(sub.cancel_at_period_end).to be_truthy
564
+ expect(sub.save).to be_truthy
565
+ expect(sub.cancel_at_period_end).to be_falsey
566
+ end
567
+
568
+ end
569
+
570
+ context "updating a subscription" do
571
+ it 'raises invalid request exception when subscription is cancelled' do
572
+ stripe_helper.create_plan(id: 'the truth')
573
+ customer = Stripe::Customer.create(source: gen_card_tk, plan: 'the truth')
574
+
575
+ subscription = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
576
+ subscription.delete
577
+
578
+ expect { subscription.save }.to raise_error { |e|
579
+ expect(e).to be_a(Stripe::InvalidRequestError)
580
+ expect(e.http_status).to eq(404)
581
+ expect(e.message).to eq("No such subscription: #{subscription.id}")
582
+ }
583
+ end
584
+
585
+ it "updates a stripe customer's existing subscription with one plan inside items" do
586
+ silver = stripe_helper.create_plan(id: 'silver')
587
+ customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk)
588
+
589
+ sub = Stripe::Subscription.create({ items: [ { plan: 'silver' } ], customer: customer.id })
590
+ sub.delete(at_period_end: true)
591
+
592
+ expect(sub.cancel_at_period_end).to be_truthy
593
+ expect(sub.save).to be_truthy
594
+ expect(sub.cancel_at_period_end).to be_falsey
595
+ end
596
+
597
+ it "updates a stripe customer's existing subscription when plan inside of items" do
598
+ silver = stripe_helper.create_plan(id: 'silver')
599
+ gold = stripe_helper.create_plan(id: 'gold')
600
+ customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk, plan: 'silver')
601
+
602
+ sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
603
+ sub.plan = 'gold'
604
+ sub.quantity = 5
605
+ sub.metadata.foo = "bar"
606
+ sub.metadata.example = "yes"
607
+
608
+ expect(sub.save).to be_truthy
609
+
610
+ expect(sub.object).to eq('subscription')
611
+ expect(sub.plan.to_hash).to eq(gold.to_hash)
612
+ expect(sub.quantity).to eq(5)
613
+ expect(sub.metadata.foo).to eq( "bar" )
614
+ expect(sub.metadata.example).to eq( "yes" )
615
+
616
+ customer = Stripe::Customer.retrieve('test_customer_sub')
617
+ expect(customer.subscriptions.data).to_not be_empty
618
+ expect(customer.subscriptions.count).to eq(1)
619
+ expect(customer.subscriptions.data.length).to eq(1)
620
+
621
+ expect(customer.subscriptions.data.first.id).to eq(sub.id)
622
+ expect(customer.subscriptions.data.first.plan.to_hash).to eq(gold.to_hash)
623
+ expect(customer.subscriptions.data.first.customer).to eq(customer.id)
624
+ end
625
+
626
+ it "updates a stripe customer's existing subscription with single plan when multiple plans inside of items" do
627
+ silver_plan = stripe_helper.create_plan(id: 'silver')
628
+ gold_plan = stripe_helper.create_plan(id: 'gold')
629
+ addon_plan = stripe_helper.create_plan(id: 'addon_plan')
630
+ customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk, plan: silver_plan.id)
631
+
632
+ sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
633
+ sub.items = [{ plan: gold_plan.id, quantity: 2 }, { plan: addon_plan.id, quantity: 2 }]
634
+ expect(sub.save).to be_truthy
635
+
636
+ expect(sub.object).to eq('subscription')
637
+ expect(sub.plan).to be_nil
638
+
639
+ customer = Stripe::Customer.retrieve('test_customer_sub')
640
+ expect(customer.subscriptions.data).to_not be_empty
641
+ expect(customer.subscriptions.count).to eq(1)
642
+ expect(customer.subscriptions.data.length).to eq(1)
643
+
644
+ expect(customer.subscriptions.data.first.id).to eq(sub.id)
645
+ expect(customer.subscriptions.data.first.plan).to be_nil
646
+ expect(customer.subscriptions.data.first.customer).to eq(customer.id)
647
+ expect(customer.subscriptions.data.first.items.data[0].plan.to_hash).to eq(gold_plan.to_hash)
648
+ expect(customer.subscriptions.data.first.items.data[1].plan.to_hash).to eq(addon_plan.to_hash)
649
+ end
650
+
651
+ it "updates a stripe customer's existing subscription with multple plans when multiple plans inside of items" do
652
+ silver_plan = stripe_helper.create_plan(id: 'silver')
653
+ gold_plan = stripe_helper.create_plan(id: 'gold')
654
+ addon1_plan = stripe_helper.create_plan(id: 'addon1')
655
+ addon2_plan = stripe_helper.create_plan(id: 'addon2')
656
+ customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk)
657
+ sub = Stripe::Subscription.create(customer: customer.id, items: [{ plan: silver_plan.id }, { plan: addon1_plan.id }])
658
+
659
+ sub.items = [{ plan: gold_plan.id, quantity: 2 }, { plan: addon2_plan.id, quantity: 2 }]
660
+ expect(sub.save).to be_truthy
661
+
662
+ expect(sub.object).to eq('subscription')
663
+ expect(sub.plan).to be_nil
664
+
665
+ customer = Stripe::Customer.retrieve('test_customer_sub')
666
+ expect(customer.subscriptions.data).to_not be_empty
667
+ expect(customer.subscriptions.count).to eq(1)
668
+ expect(customer.subscriptions.data.length).to eq(1)
669
+
670
+ expect(customer.subscriptions.data.first.id).to eq(sub.id)
671
+ expect(customer.subscriptions.data.first.plan).to be_nil
672
+ expect(customer.subscriptions.data.first.customer).to eq(customer.id)
673
+ expect(customer.subscriptions.data.first.items.data[0].plan.to_hash).to eq(gold_plan.to_hash)
674
+ expect(customer.subscriptions.data.first.items.data[1].plan.to_hash).to eq(addon2_plan.to_hash)
675
+ end
676
+
677
+ it 'when adds coupon', live: true do
678
+ plan = stripe_helper.create_plan(id: 'plan_with_coupon2', product: { name: 'One More Test Plan' },
679
+ amount: 777)
680
+ coupon = stripe_helper.create_coupon
681
+ customer = Stripe::Customer.create(source: gen_card_tk, plan: plan.id)
682
+ subscription = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
683
+
684
+ subscription.coupon = coupon.id
685
+ subscription.save
686
+
687
+ expect(subscription.discount).not_to be_nil
688
+ expect(subscription.discount).to be_a(Stripe::Discount)
689
+ expect(subscription.discount.coupon.id).to eq(coupon.id)
690
+ end
691
+
692
+ it 'when add not exist coupon' do
693
+ plan = stripe_helper.create_plan(id: 'plan_with_coupon3', product: { name: 'One More Test Plan' },
694
+ amount: 777)
695
+ customer = Stripe::Customer.create(source: gen_card_tk, plan: plan.id)
696
+ subscription = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
697
+
698
+ subscription.coupon = 'none'
699
+
700
+ expect { subscription.save }.to raise_error {|e|
701
+ expect(e).to be_a Stripe::InvalidRequestError
702
+ expect(e.http_status).to eq(400)
703
+ expect(e.message).to eq('No such coupon: none')
704
+ }
705
+
706
+ end
707
+
708
+ it 'when coupon is removed' do
709
+ plan = stripe_helper.create_plan(id: 'plan_with_coupon3', product: { name: 'One More Test Plan' },
710
+ amount: 777)
711
+ customer = Stripe::Customer.create(source: gen_card_tk, plan: plan.id)
712
+ coupon = stripe_helper.create_coupon
713
+ subscription = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
714
+
715
+ subscription.coupon = coupon.id
716
+ subscription.save
717
+ subscription.coupon = nil
718
+ subscription.save
719
+
720
+ expect(subscription.discount).to be_nil
721
+ end
722
+
723
+ it "throws an error when plan does not exist" do
724
+ free = stripe_helper.create_plan(id: 'free', amount: 0)
725
+ customer = Stripe::Customer.create(id: 'cardless', plan: 'free')
726
+
727
+ sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
728
+ sub.plan = 'gazebo'
729
+
730
+ expect { sub.save }.to raise_error {|e|
731
+ expect(e).to be_a Stripe::InvalidRequestError
732
+ expect(e.http_status).to eq(404)
733
+ expect(e.message).to_not be_nil
734
+ }
735
+
736
+ customer = Stripe::Customer.retrieve('cardless')
737
+ expect(customer.subscriptions.count).to eq(1)
738
+ expect(customer.subscriptions.data.length).to eq(1)
739
+ expect(customer.subscriptions.data.first.plan.to_hash).to eq(free.to_hash)
740
+ end
741
+
742
+ it "throws an error when subscription does not exist" do
743
+ free = stripe_helper.create_plan(id: 'free', amount: 0)
744
+ customer = Stripe::Customer.create(id: 'cardless', plan: 'free')
745
+
746
+ expect { Stripe::Subscription.retrieve("gazebo") }.to raise_error {|e|
747
+ expect(e).to be_a Stripe::InvalidRequestError
748
+ expect(e.http_status).to eq(404)
749
+ expect(e.message).to_not be_nil
750
+ }
751
+
752
+ customer = Stripe::Customer.retrieve('cardless')
753
+ expect(customer.subscriptions.count).to eq(1)
754
+ expect(customer.subscriptions.data.length).to eq(1)
755
+ expect(customer.subscriptions.data.first.plan.to_hash).to eq(free.to_hash)
756
+ end
757
+
758
+ [nil, 0].each do |trial_period_days|
759
+ it "throws an error when updating a customer with no card, and plan trail_period_days = #{trial_period_days}", live: true do
760
+ begin
761
+ free = stripe_helper.create_plan(id: 'free', amount: 0)
762
+ paid = stripe_helper.create_plan(id: 'enterprise', amount: 499, trial_period_days: trial_period_days)
763
+ customer = Stripe::Customer.create(description: 'cardless', plan: 'free')
764
+
765
+ sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
766
+ sub.plan = 'enterprise'
767
+
768
+ expect { sub.save }.to raise_error {|e|
769
+ expect(e).to be_a Stripe::InvalidRequestError
770
+ expect(e.http_status).to eq(400)
771
+ expect(e.message).to_not be_nil
772
+ }
773
+
774
+ customer = Stripe::Customer.retrieve(customer.id)
775
+ expect(customer.subscriptions.count).to eq(1)
776
+ expect(customer.subscriptions.data.length).to eq(1)
777
+ expect(customer.subscriptions.data.first.plan.to_hash).to eq(free.to_hash)
778
+ ensure
779
+ customer.delete if customer
780
+ paid.delete if paid
781
+ free.delete if free
782
+ end
783
+ end
784
+ end
785
+
786
+ it 'updates a subscription if the customer has a free trial', live: true do
787
+ stripe_helper.create_plan(id: 'enterprise', amount: 499)
788
+ trial_end = Time.now.utc.to_i + 3600
789
+ customer = Stripe::Customer.create(plan: 'enterprise',
790
+ trial_end: trial_end)
791
+ subscription = customer.subscriptions.first
792
+ subscription.quantity = 2
793
+ subscription.save
794
+ expect(subscription.quantity).to eq(2)
795
+ end
796
+
797
+ it "updates a customer with no card to a plan with a free trial" do
798
+ free = stripe_helper.create_plan(id: 'free', amount: 0)
799
+ trial = stripe_helper.create_plan(id: 'trial', amount: 999, trial_period_days: 14)
800
+ customer = Stripe::Customer.create(id: 'cardless', plan: 'free')
801
+
802
+ sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
803
+ sub.plan = 'trial'
804
+ sub.save
805
+
806
+ expect(sub.object).to eq('subscription')
807
+ expect(sub.plan.to_hash).to eq(trial.to_hash)
808
+
809
+ customer = Stripe::Customer.retrieve('cardless')
810
+ expect(customer.subscriptions.data).to_not be_empty
811
+ expect(customer.subscriptions.count).to eq(1)
812
+ expect(customer.subscriptions.data.length).to eq(1)
813
+
814
+ expect(customer.subscriptions.data.first.id).to eq(sub.id)
815
+ expect(customer.subscriptions.data.first.plan.to_hash).to eq(trial.to_hash)
816
+ expect(customer.subscriptions.data.first.customer).to eq(customer.id)
817
+ end
818
+
819
+ it "updates a customer with no card to a free plan" do
820
+ free = stripe_helper.create_plan(id: 'free', amount: 0)
821
+ gratis = stripe_helper.create_plan(id: 'gratis', amount: 0)
822
+ customer = Stripe::Customer.create(id: 'cardless', plan: 'free')
823
+
824
+ sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
825
+ sub.plan = 'gratis'
826
+ sub.save
827
+
828
+ expect(sub.object).to eq('subscription')
829
+ expect(sub.plan.to_hash).to eq(gratis.to_hash)
830
+
831
+ customer = Stripe::Customer.retrieve('cardless')
832
+ expect(customer.subscriptions.data).to_not be_empty
833
+ expect(customer.subscriptions.count).to eq(1)
834
+ expect(customer.subscriptions.data.length).to eq(1)
835
+
836
+ expect(customer.subscriptions.data.first.id).to eq(sub.id)
837
+ expect(customer.subscriptions.data.first.plan.to_hash).to eq(gratis.to_hash)
838
+ expect(customer.subscriptions.data.first.customer).to eq(customer.id)
839
+ end
840
+
841
+ it "sets a card when updating a customer's subscription" do
842
+ free = stripe_helper.create_plan(id: 'free', amount: 0)
843
+ paid = stripe_helper.create_plan(id: 'paid', amount: 499)
844
+ customer = Stripe::Customer.create(id: 'test_customer_sub', plan: 'free')
845
+
846
+ sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
847
+ sub.plan = 'paid'
848
+ sub.source = gen_card_tk
849
+ sub.save
850
+
851
+ customer = Stripe::Customer.retrieve('test_customer_sub')
852
+
853
+ expect(customer.sources.count).to eq(1)
854
+ expect(customer.sources.data.length).to eq(1)
855
+ expect(customer.default_source).to_not be_nil
856
+ expect(customer.default_source).to eq customer.sources.data.first.id
857
+ end
858
+
859
+ it "overrides trial length when trial end is set" do
860
+ plan = stripe_helper.create_plan(id: 'trial', amount: 999, trial_period_days: 14)
861
+ customer = Stripe::Customer.create(id: 'test_trial_end', plan: 'trial')
862
+
863
+ sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
864
+
865
+ trial_end = Time.now.utc.to_i + 3600
866
+ sub.trial_end = trial_end
867
+ sub.save
868
+
869
+ expect(sub.object).to eq('subscription')
870
+ expect(sub.trial_end).to eq(trial_end)
871
+ expect(sub.current_period_end).to eq(trial_end)
872
+ end
873
+
874
+ it "returns without a trial when trial_end is set to 'now'" do
875
+ plan = stripe_helper.create_plan(id: 'trial', amount: 999, trial_period_days: 14)
876
+ customer = Stripe::Customer.create(id: 'test_trial_end', plan: 'trial')
877
+
878
+ sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
879
+
880
+ sub.trial_end = "now"
881
+ sub.save
882
+
883
+ expect(sub.object).to eq('subscription')
884
+ expect(sub.plan.to_hash).to eq(plan.to_hash)
885
+ expect(sub.status).to eq('active')
886
+ expect(sub.trial_start).to be_nil
887
+ expect(sub.trial_end).to be_nil
888
+ end
889
+
890
+ it "changes an active subscription to a trial when trial_end is set" do
891
+ plan = stripe_helper.create_plan(id: 'no_trial', amount: 999)
892
+ customer = Stripe::Customer.create(id: 'test_trial_end', plan: 'no_trial', source: gen_card_tk)
893
+
894
+ sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
895
+
896
+ trial_end = Time.now.utc.to_i + 3600
897
+ sub.trial_end = trial_end
898
+ sub.save
899
+
900
+ expect(sub.object).to eq('subscription')
901
+ expect(sub.plan.to_hash).to eq(plan.to_hash)
902
+ expect(sub.status).to eq('trialing')
903
+ expect(sub.trial_end).to eq(trial_end)
904
+ expect(sub.current_period_end).to eq(trial_end)
905
+ end
906
+
907
+
908
+ it "raises error when trial_end is not an integer or 'now'" do
909
+ plan = stripe_helper.create_plan(id: 'no_trial', amount: 999)
910
+ customer = Stripe::Customer.create(id: 'test_trial_end', plan: 'no_trial', source: gen_card_tk)
911
+
912
+ sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
913
+ sub.trial_end = "gazebo"
914
+
915
+ expect { sub.save }.to raise_error {|e|
916
+ expect(e).to be_a Stripe::InvalidRequestError
917
+ expect(e.http_status).to eq(400)
918
+ expect(e.message).to eq("Invalid timestamp: must be an integer")
919
+ }
920
+ end
921
+ end
922
+
923
+ context "cancelling a subscription" do
924
+
925
+ it "cancels a stripe customer's subscription", :live => true do
926
+ truth = stripe_helper.create_plan(id: 'the truth')
927
+ customer = Stripe::Customer.create(source: gen_card_tk, plan: "the truth")
928
+
929
+ sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
930
+ result = sub.delete
931
+
932
+ expect(result.status).to eq('canceled')
933
+ expect(result.cancel_at_period_end).to eq false
934
+ expect(result.canceled_at).to_not be_nil
935
+ expect(result.id).to eq(sub.id)
936
+
937
+ customer = Stripe::Customer.retrieve(customer.id)
938
+ expect(customer.subscriptions.data).to be_empty
939
+ expect(customer.subscriptions.count).to eq(0)
940
+ expect(customer.subscriptions.data.length).to eq(0)
941
+ end
942
+
943
+ it "cancels a stripe customer's subscription at period end" do
944
+ truth = stripe_helper.create_plan(id: 'the_truth')
945
+ customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk, plan: "the_truth")
946
+
947
+ sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
948
+ result = sub.delete(at_period_end: true)
949
+
950
+ expect(result.status).to eq('active')
951
+ expect(result.cancel_at_period_end).to eq(true)
952
+ expect(result.id).to eq(sub.id)
953
+
954
+ customer = Stripe::Customer.retrieve('test_customer_sub')
955
+ expect(customer.subscriptions.data).to_not be_empty
956
+ expect(customer.subscriptions.count).to eq(1)
957
+ expect(customer.subscriptions.data.length).to eq(1)
958
+
959
+ expect(customer.subscriptions.data.first.status).to eq('active')
960
+ expect(customer.subscriptions.data.first.cancel_at_period_end).to eq(true)
961
+ expect(customer.subscriptions.data.first.ended_at).to be_nil
962
+ expect(customer.subscriptions.data.first.canceled_at).to_not be_nil
963
+ end
964
+
965
+ it "resumes an at period end cancelled subscription" do
966
+ truth = stripe_helper.create_plan(id: 'the_truth')
967
+ customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk, plan: "the_truth")
968
+
969
+ sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
970
+ result = sub.delete(at_period_end: true)
971
+
972
+ sub.plan = 'the_truth'
973
+ sub.save
974
+
975
+ customer = Stripe::Customer.retrieve('test_customer_sub')
976
+ expect(customer.subscriptions.data).to_not be_empty
977
+ expect(customer.subscriptions.count).to eq(1)
978
+ expect(customer.subscriptions.data.length).to eq(1)
979
+
980
+ expect(customer.subscriptions.data.first.status).to eq('active')
981
+ expect(customer.subscriptions.data.first.cancel_at_period_end).to eq(false)
982
+ expect(customer.subscriptions.data.first.ended_at).to be_nil
983
+ expect(customer.subscriptions.data.first.canceled_at).to be_nil
984
+ end
985
+ end
986
+
987
+ it "supports 'cancelling' by updating cancel_at_period_end" do
988
+ truth = stripe_helper.create_plan(id: 'the_truth')
989
+ customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk, plan: "the_truth")
990
+
991
+ sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
992
+ result = Stripe::Subscription.update(sub.id, cancel_at_period_end: true)
993
+
994
+ expect(result.status).to eq('active')
995
+ expect(result.cancel_at_period_end).to eq(true)
996
+ expect(result.id).to eq(sub.id)
997
+
998
+ customer = Stripe::Customer.retrieve('test_customer_sub')
999
+ expect(customer.subscriptions.data).to_not be_empty
1000
+ expect(customer.subscriptions.count).to eq(1)
1001
+ expect(customer.subscriptions.data.length).to eq(1)
1002
+
1003
+ expect(customer.subscriptions.data.first.status).to eq('active')
1004
+ expect(customer.subscriptions.data.first.cancel_at_period_end).to eq(true)
1005
+ expect(customer.subscriptions.data.first.ended_at).to be_nil
1006
+ expect(customer.subscriptions.data.first.canceled_at).to_not be_nil
1007
+ end
1008
+
1009
+ it "resumes a subscription cancelled by updating cancel_at_period_end" do
1010
+ truth = stripe_helper.create_plan(id: 'the_truth')
1011
+ customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk, plan: "the_truth")
1012
+
1013
+ sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
1014
+ Stripe::Subscription.update(sub.id, cancel_at_period_end: true)
1015
+
1016
+ result = Stripe::Subscription.update(sub.id, cancel_at_period_end: false)
1017
+
1018
+ expect(result.status).to eq('active')
1019
+ expect(result.cancel_at_period_end).to eq(false)
1020
+ expect(result.id).to eq(sub.id)
1021
+
1022
+ customer = Stripe::Customer.retrieve('test_customer_sub')
1023
+ expect(customer.subscriptions.data).to_not be_empty
1024
+ expect(customer.subscriptions.count).to eq(1)
1025
+ expect(customer.subscriptions.data.length).to eq(1)
1026
+
1027
+ expect(customer.subscriptions.data.first.status).to eq('active')
1028
+ expect(customer.subscriptions.data.first.cancel_at_period_end).to eq(false)
1029
+ expect(customer.subscriptions.data.first.ended_at).to be_nil
1030
+ expect(customer.subscriptions.data.first.canceled_at).to be_nil
1031
+ end
1032
+
1033
+ it "doesn't change status of subscription when cancelling at period end" do
1034
+ trial = stripe_helper.create_plan(id: 'trial', trial_period_days: 14)
1035
+ customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk, plan: "trial")
1036
+
1037
+ sub = Stripe::Subscription.retrieve(customer.subscriptions.data.first.id)
1038
+ result = sub.delete(at_period_end: true)
1039
+
1040
+ expect(result.status).to eq('trialing')
1041
+
1042
+ customer = Stripe::Customer.retrieve('test_customer_sub')
1043
+
1044
+ expect(customer.subscriptions.data.first.status).to eq('trialing')
1045
+ end
1046
+
1047
+ it "doesn't require a card when trial_end is present", :live => true do
1048
+ plan = stripe_helper.create_plan(
1049
+ :amount => 2000,
1050
+ :interval => 'month',
1051
+ :name => 'Amazing Gold Plan',
1052
+ :currency => 'usd',
1053
+ :id => 'gold'
1054
+ )
1055
+
1056
+ stripe_customer = Stripe::Customer.create
1057
+ options = {plan: plan.id, customer: stripe_customer.id, trial_end: (Date.today + 30).to_time.to_i}
1058
+ Stripe::Subscription.create options
1059
+ end
1060
+
1061
+ context 'retrieving a single subscription' do
1062
+ let(:customer) { Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk, plan: 'free') }
1063
+ let(:subscription) { Stripe::Subscription.retrieve(customer.subscriptions.data.first.id) }
1064
+
1065
+ before do
1066
+ stripe_helper.create_plan(id: 'free', amount: 0)
1067
+ Stripe::Subscription.create({ plan: 'free', customer: customer.id })
1068
+ end
1069
+
1070
+ it 'retrieves a single subscription' do
1071
+ expect(subscription).to be_truthy
1072
+ end
1073
+
1074
+ it "includes 'items' object on retrieved subscription" do
1075
+ expect(subscription.items).to be_truthy
1076
+ expect(subscription.items.object).to eq('list')
1077
+ expect(subscription.items.data.class).to eq(Array)
1078
+ expect(subscription.items.data.count).to eq(1)
1079
+ expect(subscription.items.data.first.id).to eq('test_txn_default')
1080
+ expect(subscription.items.data.first.created).to eq(1504716183)
1081
+ expect(subscription.items.data.first.object).to eq('subscription_item')
1082
+ expect(subscription.items.data.first.plan.amount).to eq(0)
1083
+ expect(subscription.items.data.first.plan.created).to eq(1466698898)
1084
+ expect(subscription.items.data.first.plan.currency).to eq('usd')
1085
+ expect(subscription.items.data.first.quantity).to eq(2)
1086
+ end
1087
+ end
1088
+
1089
+ context "retrieve multiple subscriptions" do
1090
+
1091
+ it "retrieves a list of multiple subscriptions" do
1092
+ free = stripe_helper.create_plan(id: 'free', amount: 0)
1093
+ paid = stripe_helper.create_plan(id: 'paid', amount: 499)
1094
+ customer = Stripe::Customer.create(id: 'test_customer_sub', source: gen_card_tk, plan: "free")
1095
+ Stripe::Subscription.create({ plan: 'paid', customer: customer.id })
1096
+
1097
+ subs = Stripe::Subscription.all({ customer: customer.id })
1098
+
1099
+ expect(subs.object).to eq("list")
1100
+ expect(subs.count).to eq(2)
1101
+ expect(subs.data.length).to eq(2)
1102
+ end
1103
+
1104
+ it "retrieves an empty list if there's no subscriptions" do
1105
+ Stripe::Customer.create(id: 'no_subs')
1106
+ customer = Stripe::Customer.retrieve('no_subs')
1107
+
1108
+ list = Stripe::Subscription.all({ customer: customer.id })
1109
+
1110
+ expect(list.object).to eq("list")
1111
+ expect(list.count).to eq(0)
1112
+ expect(list.data.length).to eq(0)
1113
+ end
1114
+ end
1115
+
1116
+ describe "metadata" do
1117
+
1118
+ it "creates a stripe customer and subscribes them to a plan with meta data", :live => true do
1119
+
1120
+ stripe_helper.
1121
+ create_plan(
1122
+ :amount => 500,
1123
+ :interval => 'month',
1124
+ :product => {
1125
+ :name => 'Sample Plan'
1126
+ },
1127
+ :currency => 'usd',
1128
+ :id => 'Sample5'
1129
+ )
1130
+
1131
+ customer = Stripe::Customer.create({
1132
+ email: 'johnny@appleseed.com',
1133
+ source: gen_card_tk
1134
+ })
1135
+
1136
+ subscription = Stripe::Subscription.create({ plan: "Sample5", customer: customer.id })
1137
+ subscription.metadata['foo'] = 'bar'
1138
+
1139
+ expect(subscription.save).to be_a Stripe::Subscription
1140
+
1141
+ customer = Stripe::Customer.retrieve(customer.id)
1142
+ expect(customer.email).to eq('johnny@appleseed.com')
1143
+ expect(customer.subscriptions.first.plan.id).to eq('Sample5')
1144
+ expect(customer.subscriptions.first.metadata['foo']).to eq('bar')
1145
+ end
1146
+ end
1147
+
1148
+ end