epopia-stripe-ruby-mock 2.5.8

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.
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