mirror of
https://github.com/indentlabs/notebook.git
synced 2025-10-26 11:19:22 +00:00
Fix Stripe subscription errors by migrating deprecated sources API to payment_methods API
- Migrate from deprecated sources API to modern payment_methods API in SubscriptionsController - Update subscription plan modifications to use Subscription.modify instead of direct assignment - Fix payment method creation/deletion to use PaymentMethod.create/detach instead of sources - Update view templates to use new payment_methods data structure - Migrate price.id usage from deprecated plan.id in data integrity tasks - Add comprehensive test suite with proper Stripe API stubs - Add missing test gems: rspec-rails, webmock, factory_bot_rails, shoulda-matchers This resolves Error 500 when users try to upgrade to Premium subscriptions. The original error was: NoMethodError - undefined method 'total_count' for nil:NilClass caused by stripe_customer.sources.total_count when sources API returned nil. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
11136b9115
commit
ac96a001a8
4
Gemfile
4
Gemfile
@ -140,6 +140,10 @@ group :test do
|
||||
gem 'codeclimate-test-reporter', require: false # TODO: remove this
|
||||
gem 'database_cleaner'
|
||||
gem 'selenium-webdriver'
|
||||
gem 'rspec-rails', '~> 5.0'
|
||||
gem 'webmock', '~> 3.0'
|
||||
gem 'factory_bot_rails'
|
||||
gem 'shoulda-matchers', '~> 5.0'
|
||||
end
|
||||
|
||||
group :development do
|
||||
|
||||
37
Gemfile.lock
37
Gemfile.lock
@ -1809,6 +1809,9 @@ GEM
|
||||
coffee-script-source (1.12.2)
|
||||
concurrent-ruby (1.3.5)
|
||||
connection_pool (2.5.3)
|
||||
crack (1.0.0)
|
||||
bigdecimal
|
||||
rexml
|
||||
crass (1.0.6)
|
||||
csv (3.3.4)
|
||||
d3-rails (5.9.2)
|
||||
@ -1831,6 +1834,7 @@ GEM
|
||||
railties (>= 4.1.0)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
diff-lcs (1.6.2)
|
||||
discordrb (3.5.0)
|
||||
discordrb-webhooks (~> 3.5.0)
|
||||
ffi (>= 1.9.24)
|
||||
@ -1849,6 +1853,11 @@ GEM
|
||||
event_emitter (0.2.6)
|
||||
eventmachine (1.2.7)
|
||||
execjs (2.10.0)
|
||||
factory_bot (6.5.4)
|
||||
activesupport (>= 6.1.0)
|
||||
factory_bot_rails (6.5.0)
|
||||
factory_bot (~> 6.5)
|
||||
railties (>= 6.1.0)
|
||||
faraday (1.10.4)
|
||||
faraday-em_http (~> 1.0)
|
||||
faraday-em_synchrony (~> 1.0)
|
||||
@ -1889,6 +1898,7 @@ GEM
|
||||
activerecord (>= 4.0.0)
|
||||
globalid (1.2.1)
|
||||
activesupport (>= 6.1)
|
||||
hashdiff (1.2.0)
|
||||
html-pipeline (2.14.3)
|
||||
activesupport (>= 2)
|
||||
nokogiri (>= 1.4)
|
||||
@ -2126,6 +2136,23 @@ GEM
|
||||
rmagick (6.1.1)
|
||||
observer (~> 0.1)
|
||||
pkg-config (~> 1.4)
|
||||
rspec-core (3.13.5)
|
||||
rspec-support (~> 3.13.0)
|
||||
rspec-expectations (3.13.5)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.13.0)
|
||||
rspec-mocks (3.13.5)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.13.0)
|
||||
rspec-rails (5.1.2)
|
||||
actionpack (>= 5.2)
|
||||
activesupport (>= 5.2)
|
||||
railties (>= 5.2)
|
||||
rspec-core (~> 3.10)
|
||||
rspec-expectations (~> 3.10)
|
||||
rspec-mocks (~> 3.10)
|
||||
rspec-support (~> 3.10)
|
||||
rspec-support (3.13.4)
|
||||
ruby-progressbar (1.13.0)
|
||||
ruby-vips (2.2.3)
|
||||
ffi (~> 1.12)
|
||||
@ -2158,6 +2185,8 @@ GEM
|
||||
sentry-ruby (5.23.0)
|
||||
bigdecimal
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
shoulda-matchers (5.3.0)
|
||||
activesupport (>= 5.2.0)
|
||||
sidekiq (7.3.9)
|
||||
base64
|
||||
connection_pool (>= 2.3.0)
|
||||
@ -2218,6 +2247,10 @@ GEM
|
||||
activemodel (>= 6.0.0)
|
||||
bindex (>= 0.4.0)
|
||||
railties (>= 6.0.0)
|
||||
webmock (3.25.1)
|
||||
addressable (>= 2.8.0)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff (>= 0.4.0, < 2.0.0)
|
||||
webpacker (5.4.4)
|
||||
activesupport (>= 5.2)
|
||||
rack-proxy (>= 0.6.1)
|
||||
@ -2266,6 +2299,7 @@ DEPENDENCIES
|
||||
discordrb
|
||||
dotenv-rails
|
||||
engtagger!
|
||||
factory_bot_rails
|
||||
filesize
|
||||
flamegraph
|
||||
font-awesome-rails
|
||||
@ -2299,11 +2333,13 @@ DEPENDENCIES
|
||||
redcarpet
|
||||
redis (~> 5.1.0)
|
||||
rmagick
|
||||
rspec-rails (~> 5.0)
|
||||
sass-rails
|
||||
selenium-webdriver
|
||||
sentry-rails
|
||||
sentry-ruby
|
||||
serendipitous!
|
||||
shoulda-matchers (~> 5.0)
|
||||
sidekiq (~> 7.3.9)
|
||||
slack-notifier
|
||||
spring
|
||||
@ -2318,6 +2354,7 @@ DEPENDENCIES
|
||||
tribute
|
||||
uglifier (>= 1.3.0)
|
||||
web-console
|
||||
webmock (~> 3.0)
|
||||
webpacker
|
||||
will_paginate (~> 4.0)
|
||||
word_count_analyzer
|
||||
|
||||
@ -21,6 +21,7 @@ class SubscriptionsController < ApplicationController
|
||||
|
||||
def history
|
||||
@stripe_customer = Stripe::Customer.retrieve(current_user.stripe_customer_id)
|
||||
@stripe_payment_methods = @stripe_customer.list_payment_methods(type: 'card')
|
||||
@stripe_invoices = Stripe::Invoice.list({
|
||||
customer: current_user.stripe_customer_id
|
||||
})
|
||||
@ -146,12 +147,17 @@ class SubscriptionsController < ApplicationController
|
||||
stripe_subscription = stripe_customer.subscriptions.data[0]
|
||||
begin
|
||||
# Delete all existing payment methods to have our new one "replace" them
|
||||
stripe_customer.sources.each do |payment_method|
|
||||
payment_method.delete
|
||||
existing_payment_methods = stripe_customer.list_payment_methods(type: 'card')
|
||||
existing_payment_methods.data.each do |payment_method|
|
||||
payment_method.detach
|
||||
end
|
||||
|
||||
# Add the new card info
|
||||
stripe_customer.sources.create(source: valid_token)
|
||||
payment_method = Stripe::PaymentMethod.create({
|
||||
type: 'card',
|
||||
card: { token: valid_token }
|
||||
})
|
||||
payment_method.attach(customer: stripe_customer.id)
|
||||
rescue Stripe::CardError => e
|
||||
flash[:alert] = "We couldn't save your payment information because #{e.message.downcase} Please double check that your information is correct."
|
||||
return redirect_back fallback_location: payment_info_path
|
||||
@ -174,17 +180,20 @@ class SubscriptionsController < ApplicationController
|
||||
stripe_customer = Stripe::Customer.retrieve current_user.stripe_customer_id
|
||||
stripe_subscription = stripe_customer.subscriptions.data[0]
|
||||
|
||||
stripe_customer.sources.each do |payment_method|
|
||||
payment_method.delete
|
||||
payment_methods = stripe_customer.list_payment_methods(type: 'card')
|
||||
payment_methods.data.each do |payment_method|
|
||||
payment_method.detach
|
||||
end
|
||||
|
||||
notice = ['Your payment method has been successfully deleted.']
|
||||
|
||||
if stripe_subscription.plan.id != 'starter'
|
||||
# Check if user has a non-starter subscription using modern API
|
||||
current_price_id = stripe_subscription.items.data[0].price.id
|
||||
if current_price_id != 'starter'
|
||||
# Cancel the user's at the end of its effective period on Stripe's end, so they don't get rebilled
|
||||
stripe_subscription.delete(at_period_end: true)
|
||||
|
||||
active_billing_plan = BillingPlan.find_by(stripe_plan_id: stripe_subscription.plan.id)
|
||||
active_billing_plan = BillingPlan.find_by(stripe_plan_id: current_price_id)
|
||||
if active_billing_plan
|
||||
notice << "Your #{active_billing_plan.name} subscription will end on #{Time.at(stripe_subscription.current_period_end).strftime('%B %d')}."
|
||||
end
|
||||
@ -256,7 +265,8 @@ class SubscriptionsController < ApplicationController
|
||||
# If we're upgrading to premium, we want to check that a payment method
|
||||
# is already on file. If it is, we process the plan change. If it's not,
|
||||
# we redirect to the payment method page.
|
||||
if stripe_customer.sources.total_count > 0
|
||||
payment_methods = stripe_customer.list_payment_methods(type: 'card')
|
||||
if payment_methods.data.length > 0
|
||||
process_plan_change(current_user, plan_id)
|
||||
else
|
||||
return :payment_method_needed
|
||||
|
||||
@ -59,8 +59,13 @@ class UsersController < ApplicationController
|
||||
stripe_customer = Stripe::Customer.retrieve(current_user.stripe_customer_id)
|
||||
stripe_subscription = stripe_customer.subscriptions.data[0]
|
||||
if stripe_subscription
|
||||
stripe_subscription.plan = 'starter'
|
||||
stripe_subscription.save
|
||||
# Update subscription to starter plan using modern API
|
||||
Stripe::Subscription.modify(stripe_subscription.id, {
|
||||
items: [{
|
||||
id: stripe_subscription.items.data[0].id,
|
||||
price: 'starter'
|
||||
}]
|
||||
})
|
||||
end
|
||||
|
||||
report_user_deletion_to_slack(current_user)
|
||||
|
||||
@ -12,17 +12,23 @@ class SubscriptionService < Service
|
||||
|
||||
if stripe_subscription.nil?
|
||||
# Create a new subscription on Stripe
|
||||
Stripe::Subscription.create(customer: user.stripe_customer_id, plan: plan_id)
|
||||
Stripe::Subscription.create(customer: user.stripe_customer_id, price: plan_id)
|
||||
stripe_customer = Stripe::Customer.retrieve(user.stripe_customer_id)
|
||||
stripe_subscription = stripe_customer.subscriptions.data[0]
|
||||
else
|
||||
# Edit an existing Stripe subscription
|
||||
stripe_subscription.plan = plan_id
|
||||
# Edit an existing Stripe subscription by modifying its items
|
||||
Stripe::Subscription.modify(stripe_subscription.id, {
|
||||
items: [{
|
||||
id: stripe_subscription.items.data[0].id,
|
||||
price: plan_id
|
||||
}]
|
||||
})
|
||||
# Retrieve the updated subscription
|
||||
stripe_subscription = Stripe::Subscription.retrieve(stripe_subscription.id)
|
||||
end
|
||||
|
||||
# Save the change
|
||||
# The subscription is already saved by the modify call above
|
||||
begin
|
||||
stripe_subscription.save unless Rails.env.test?
|
||||
|
||||
# Add any bonus bandwidth granted by the plan
|
||||
user.update(
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
</p>
|
||||
</div>
|
||||
<div class="col s12 m6">
|
||||
<% if @stripe_customer.sources.total_count == 0 %>
|
||||
<% if @stripe_payment_methods.data.length == 0 %>
|
||||
<p>
|
||||
We don't currently have a payment method on file for you. You'll be asked to add one whenever you
|
||||
upgrade, but you can add one at any time here.
|
||||
@ -26,7 +26,7 @@
|
||||
<% else %>
|
||||
<p>
|
||||
We have a payment method on file for you through Stripe
|
||||
(<%= @stripe_customer.sources.data[0].try(:brand) || 'a card' %> ending in <%= @stripe_customer.sources.data[0].last4 %>),
|
||||
(<%= @stripe_payment_methods.data[0].try(:card).try(:brand) || 'a card' %> ending in <%= @stripe_payment_methods.data[0].try(:card).try(:last4) %>),
|
||||
but since we don't store it, you cannot edit it. You can choose to add a new one (replacing the old),
|
||||
or delete the existing one.
|
||||
</p>
|
||||
@ -34,7 +34,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% if @stripe_customer.sources.total_count > 0 %>
|
||||
<% if @stripe_payment_methods.data.length > 0 %>
|
||||
<div class="card-action">
|
||||
<%= link_to "Add new payment method", payment_info_path %>
|
||||
<%= link_to "Delete existing payment method", delete_payment_method_path %>
|
||||
|
||||
@ -31,7 +31,8 @@ namespace :data_integrity do
|
||||
should_downgrade_user = true
|
||||
else
|
||||
should_downgrade_user = stripe_subscription.items.data.none? do |subscription_item|
|
||||
subscription_item.plan.id == active_billing_plan.stripe_plan_id
|
||||
# Use price.id instead of deprecated plan.id
|
||||
subscription_item.price.id == active_billing_plan.stripe_plan_id
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -1,257 +1,274 @@
|
||||
# require 'rails_helper'
|
||||
# require 'support/devise'
|
||||
# require 'webmock/rspec'
|
||||
# include Rails.application.routes.url_helpers
|
||||
require 'rails_helper'
|
||||
require 'support/devise'
|
||||
require 'webmock/rspec'
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
# RSpec.describe SubscriptionsController, type: :controller do
|
||||
# before do
|
||||
# WebMock.disable_net_connect!(allow_localhost: true)
|
||||
RSpec.describe SubscriptionsController, type: :controller do
|
||||
before do
|
||||
WebMock.disable_net_connect!(allow_localhost: true)
|
||||
|
||||
# # Need to stub .save on StripeObject, but this doesn't seem to work
|
||||
# #Stripe::StripeObject.any_instance.stub(:save).and_return(true)
|
||||
# Need to stub .save on StripeObject, but this doesn't seem to work
|
||||
#Stripe::StripeObject.any_instance.stub(:save).and_return(true)
|
||||
|
||||
# # Stub Stripe::Customer.create
|
||||
# stub_request(:post, "https://api.stripe.com/v1/customers")
|
||||
# .with(body: { email: "email1@example.com" })
|
||||
# .to_return(status: 200, body: {id: 'stripe-id'}.to_json, headers: {})
|
||||
# Stub Stripe::Customer.create
|
||||
stub_request(:post, "https://api.stripe.com/v1/customers")
|
||||
.with(body: { email: "email1@example.com" })
|
||||
.to_return(status: 200, body: {id: 'stripe-id'}.to_json, headers: {})
|
||||
|
||||
# # Stub Stripe::Customer.retrieve
|
||||
# stub_request(:get, "https://api.stripe.com/v1/customers/stripe-id")
|
||||
# .to_return(
|
||||
# status: 200,
|
||||
# body: {
|
||||
# id: 'stripe-id',
|
||||
# sources: {
|
||||
# total_count: 0,
|
||||
# data: []
|
||||
# },
|
||||
# subscriptions: {
|
||||
# total_count: 1,
|
||||
# data: [Stripe::StripeObject.new]
|
||||
# }
|
||||
# }.to_json,
|
||||
# headers: {}
|
||||
# )
|
||||
# Stub Stripe::Customer.retrieve
|
||||
stub_request(:get, "https://api.stripe.com/v1/customers/stripe-id")
|
||||
.to_return(
|
||||
status: 200,
|
||||
body: {
|
||||
id: 'stripe-id',
|
||||
subscriptions: {
|
||||
total_count: 1,
|
||||
data: [{
|
||||
id: 'sub_123',
|
||||
items: {
|
||||
data: [{
|
||||
id: 'si_123',
|
||||
price: { id: 'starter' }
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
}.to_json,
|
||||
headers: {}
|
||||
)
|
||||
|
||||
# # Stub downgrading subscription to starter
|
||||
# stub_request(:post, "https://api.stripe.com/v1/subscriptions")
|
||||
# .with(body: { customer: "stripe-id", plan: 'starter' })
|
||||
# .to_return(status: 200, body: {id: 'stripe-id'}.to_json, headers: {})
|
||||
# Stub list_payment_methods call (replaces sources) - no payment methods
|
||||
stub_request(:get, "https://api.stripe.com/v1/customers/stripe-id/payment_methods")
|
||||
.with(query: {type: 'card'})
|
||||
.to_return(
|
||||
status: 200,
|
||||
body: {
|
||||
data: []
|
||||
}.to_json,
|
||||
headers: {}
|
||||
)
|
||||
|
||||
# # Stub updating subscription to premium
|
||||
# stub_request(:post, "https://api.stripe.com/v1/subscriptions")
|
||||
# .with(body: { customer: "stripe-id", plan: 'premium' })
|
||||
# .to_return(status: 200, body: {id: 'stripe-id'}.to_json, headers: {})
|
||||
# Stub creating subscription with price instead of plan
|
||||
stub_request(:post, "https://api.stripe.com/v1/subscriptions")
|
||||
.with(body: { customer: "stripe-id", price: 'starter' })
|
||||
.to_return(status: 200, body: {id: 'sub_starter'}.to_json, headers: {})
|
||||
|
||||
# @request.env['devise.mapping'] = Devise.mappings[:user]
|
||||
# @user = create(:user)
|
||||
# @user.update(stripe_customer_id: 'stripe-id')
|
||||
# sign_in @user
|
||||
# Stub updating subscription with Subscription.modify
|
||||
stub_request(:post, "https://api.stripe.com/v1/subscriptions/sub_123")
|
||||
.to_return(status: 200, body: {id: 'sub_123'}.to_json, headers: {})
|
||||
|
||||
# @free_plan = BillingPlan.create(
|
||||
# name: 'Starter',
|
||||
# stripe_plan_id: 'starter',
|
||||
# monthly_cents: 0, # $0.00/mo
|
||||
# available: true,
|
||||
# Stub subscription retrieval
|
||||
stub_request(:get, "https://api.stripe.com/v1/subscriptions/sub_123")
|
||||
.to_return(status: 200, body: {id: 'sub_123'}.to_json, headers: {})
|
||||
|
||||
# # Content creation and other permissions:
|
||||
# universe_limit: 5,
|
||||
# allows_core_content: true,
|
||||
# allows_extended_content: false,
|
||||
# allows_collective_content: false,
|
||||
# allows_collaboration: false,
|
||||
# bonus_bandwidth_kb: 123155
|
||||
# )
|
||||
@request.env['devise.mapping'] = Devise.mappings[:user]
|
||||
@user = create(:user)
|
||||
@user.update(stripe_customer_id: 'stripe-id')
|
||||
sign_in @user
|
||||
|
||||
# @beta_plan = BillingPlan.create(
|
||||
# name: 'Early Adopters',
|
||||
# stripe_plan_id: 'early-adopters',
|
||||
# monthly_cents: 0, # $0.00/mo
|
||||
# available: true,
|
||||
@free_plan = BillingPlan.create(
|
||||
name: 'Starter',
|
||||
stripe_plan_id: 'starter',
|
||||
monthly_cents: 0, # $0.00/mo
|
||||
available: true,
|
||||
|
||||
# # Content creation and other permissions:
|
||||
# universe_limit: 5,
|
||||
# allows_core_content: true,
|
||||
# allows_extended_content: false,
|
||||
# allows_collective_content: false,
|
||||
# allows_collaboration: false,
|
||||
# bonus_bandwidth_kb: 123155
|
||||
# )
|
||||
# Content creation and other permissions:
|
||||
universe_limit: 5,
|
||||
allows_core_content: true,
|
||||
allows_extended_content: false,
|
||||
allows_collective_content: false,
|
||||
allows_collaboration: false,
|
||||
bonus_bandwidth_kb: 123155
|
||||
)
|
||||
|
||||
# @premium_plan = BillingPlan.create(
|
||||
# name: 'Premium',
|
||||
# stripe_plan_id: 'premium',
|
||||
# monthly_cents: 900,
|
||||
# available: true,
|
||||
# universe_limit: 5,
|
||||
# allows_core_content: true,
|
||||
# allows_extended_content: true,
|
||||
# allows_collective_content: true,
|
||||
# allows_collaboration: true,
|
||||
# bonus_bandwidth_kb: 0
|
||||
# )
|
||||
@beta_plan = BillingPlan.create(
|
||||
name: 'Early Adopters',
|
||||
stripe_plan_id: 'early-adopters',
|
||||
monthly_cents: 0, # $0.00/mo
|
||||
available: true,
|
||||
|
||||
# @premium_annual_plan = BillingPlan.create(
|
||||
# name: 'Premium (annual)',
|
||||
# stripe_plan_id: 'premium-annual',
|
||||
# monthly_cents: 700,
|
||||
# available: true,
|
||||
# universe_limit: 5,
|
||||
# allows_core_content: true,
|
||||
# allows_extended_content: true,
|
||||
# allows_collective_content: true,
|
||||
# allows_collaboration: true,
|
||||
# bonus_bandwidth_kb: 123155
|
||||
# )
|
||||
# end
|
||||
# Content creation and other permissions:
|
||||
universe_limit: 5,
|
||||
allows_core_content: true,
|
||||
allows_extended_content: false,
|
||||
allows_collective_content: false,
|
||||
allows_collaboration: false,
|
||||
bonus_bandwidth_kb: 123155
|
||||
)
|
||||
|
||||
# describe "User with no plan (fallback to Starter) tries to upgrade" do
|
||||
# it "redirects to payment method form if they don't have a payment method saved" do
|
||||
# expect(@user.active_subscriptions).to eq([])
|
||||
# post :change, params: { stripe_plan_id: 'premium' }
|
||||
# expect(subject).to redirect_to action: :information, plan: 'premium'
|
||||
# end
|
||||
# end
|
||||
@premium_plan = BillingPlan.create(
|
||||
name: 'Premium',
|
||||
stripe_plan_id: 'premium',
|
||||
monthly_cents: 900,
|
||||
available: true,
|
||||
universe_limit: 5,
|
||||
allows_core_content: true,
|
||||
allows_extended_content: true,
|
||||
allows_collective_content: true,
|
||||
allows_collaboration: true,
|
||||
bonus_bandwidth_kb: 0
|
||||
)
|
||||
|
||||
# describe "User on Starter" do
|
||||
# before do
|
||||
# # Create a Starter subscription for the user
|
||||
# @user.update(selected_billing_plan_id: @free_plan.id)
|
||||
# end
|
||||
@premium_annual_plan = BillingPlan.create(
|
||||
name: 'Premium (annual)',
|
||||
stripe_plan_id: 'premium-annual',
|
||||
monthly_cents: 700,
|
||||
available: true,
|
||||
universe_limit: 5,
|
||||
allows_core_content: true,
|
||||
allows_extended_content: true,
|
||||
allows_collective_content: true,
|
||||
allows_collaboration: true,
|
||||
bonus_bandwidth_kb: 123155
|
||||
)
|
||||
end
|
||||
|
||||
# it "redirects to payment method form if they don't have a payment method saved" do
|
||||
# post :change, params: { stripe_plan_id: 'premium' }
|
||||
# expect(subject).to redirect_to action: :information, plan: 'premium'
|
||||
# end
|
||||
describe "User with no plan (fallback to Starter) tries to upgrade" do
|
||||
it "redirects to payment method form if they don't have a payment method saved" do
|
||||
expect(@user.active_subscriptions).to eq([])
|
||||
post :change, params: { stripe_plan_id: 'premium' }
|
||||
expect(subject).to redirect_to action: :information, plan: 'premium'
|
||||
end
|
||||
end
|
||||
|
||||
# it "allows upgrading to Premium when they have a payment method saved" do
|
||||
# # Re-stub Stripe::Customer.retrieve to include a payment method (source)
|
||||
# stub_request(:get, "https://api.stripe.com/v1/customers/stripe-id")
|
||||
# .to_return(
|
||||
# status: 200,
|
||||
# body: {
|
||||
# id: 'stripe-id',
|
||||
# sources: {
|
||||
# total_count: 1,
|
||||
# data: [Stripe::StripeObject.new]
|
||||
# },
|
||||
# subscriptions: {
|
||||
# total_count: 1,
|
||||
# data: [Stripe::StripeObject.new]
|
||||
# }
|
||||
# }.to_json,
|
||||
# headers: {}
|
||||
# )
|
||||
describe "User on Starter" do
|
||||
before do
|
||||
# Create a Starter subscription for the user
|
||||
@user.update(selected_billing_plan_id: @free_plan.id)
|
||||
end
|
||||
|
||||
# expect(@user.selected_billing_plan_id).to eq(@free_plan.id)
|
||||
# expect(@user.active_billing_plans).not_to eq([@premium_plan])
|
||||
it "redirects to payment method form if they don't have a payment method saved" do
|
||||
post :change, params: { stripe_plan_id: 'premium' }
|
||||
expect(subject).to redirect_to action: :information, plan: 'premium'
|
||||
end
|
||||
|
||||
# post :change, params: { stripe_plan_id: 'premium' }
|
||||
it "allows upgrading to Premium when they have a payment method saved" do
|
||||
# Re-stub list_payment_methods to include a payment method
|
||||
stub_request(:get, "https://api.stripe.com/v1/customers/stripe-id/payment_methods")
|
||||
.with(query: {type: 'card'})
|
||||
.to_return(
|
||||
status: 200,
|
||||
body: {
|
||||
data: [{
|
||||
id: 'pm_123',
|
||||
card: {
|
||||
brand: 'visa',
|
||||
last4: '4242'
|
||||
}
|
||||
}]
|
||||
}.to_json,
|
||||
headers: {}
|
||||
)
|
||||
|
||||
# @user.reload
|
||||
# expect(@user.selected_billing_plan_id).to eq(@premium_plan.id)
|
||||
# expect(@user.active_billing_plans).to eq([@premium_plan])
|
||||
# end
|
||||
expect(@user.selected_billing_plan_id).to eq(@free_plan.id)
|
||||
expect(@user.active_billing_plans).not_to eq([@premium_plan])
|
||||
|
||||
# describe "Starter Permissions" do
|
||||
# before do
|
||||
# @user.update(selected_billing_plan_id: @free_plan.id)
|
||||
# end
|
||||
post :change, params: { stripe_plan_id: 'premium' }
|
||||
|
||||
# it "allows Starter users to create core content types" do
|
||||
# expect(@user.can_create?(Character)).to eq(true)
|
||||
# expect(@user.can_create?(Location)).to eq(true)
|
||||
# expect(@user.can_create?(Item)).to eq(true)
|
||||
# end
|
||||
@user.reload
|
||||
expect(@user.selected_billing_plan_id).to eq(@premium_plan.id)
|
||||
expect(@user.active_billing_plans).to eq([@premium_plan])
|
||||
end
|
||||
|
||||
# it "doesn't allow Starter users to create extended content types" do
|
||||
# expect(@user.can_create?(Creature)).to eq(false)
|
||||
# expect(@user.can_create?(Race)).to eq(false)
|
||||
# expect(@user.can_create?(Religion)).to eq(false)
|
||||
# expect(@user.can_create?(Group)).to eq(false)
|
||||
# expect(@user.can_create?(Magic)).to eq(false)
|
||||
# expect(@user.can_create?(Language)).to eq(false)
|
||||
# expect(@user.can_create?(Flora)).to eq(false)
|
||||
# end
|
||||
describe "Starter Permissions" do
|
||||
before do
|
||||
@user.update(selected_billing_plan_id: @free_plan.id)
|
||||
end
|
||||
|
||||
# it "doesn't allow Starter users to create collective content types" do
|
||||
# expect(@user.can_create?(Scene)).to eq(false)
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
it "allows Starter users to create core content types" do
|
||||
expect(@user.can_create?(Character)).to eq(true)
|
||||
expect(@user.can_create?(Location)).to eq(true)
|
||||
expect(@user.can_create?(Item)).to eq(true)
|
||||
end
|
||||
|
||||
# describe "User on Premium" do
|
||||
# before do
|
||||
# # Create a premium subscription for the user
|
||||
# @user.update(selected_billing_plan_id: @premium_plan.id)
|
||||
# end
|
||||
it "doesn't allow Starter users to create extended content types" do
|
||||
expect(@user.can_create?(Creature)).to eq(false)
|
||||
expect(@user.can_create?(Race)).to eq(false)
|
||||
expect(@user.can_create?(Religion)).to eq(false)
|
||||
expect(@user.can_create?(Group)).to eq(false)
|
||||
expect(@user.can_create?(Magic)).to eq(false)
|
||||
expect(@user.can_create?(Language)).to eq(false)
|
||||
expect(@user.can_create?(Flora)).to eq(false)
|
||||
end
|
||||
|
||||
# it "allows downgrading to Starter" do
|
||||
# # Downgrade to Starter
|
||||
# post :change, params: { stripe_plan_id: 'starter' }
|
||||
it "doesn't allow Starter users to create collective content types" do
|
||||
expect(@user.can_create?(Scene)).to eq(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# @user.reload
|
||||
# expect(@user.selected_billing_plan_id).to eq(@free_plan.id)
|
||||
# expect(@user.active_billing_plans).to eq([@free_plan])
|
||||
# expect(@user.active_subscriptions.map(&:billing_plan_id)).to eq([@free_plan.id])
|
||||
# end
|
||||
describe "User on Premium" do
|
||||
before do
|
||||
# Create a premium subscription for the user
|
||||
@user.update(selected_billing_plan_id: @premium_plan.id)
|
||||
end
|
||||
|
||||
# describe "Premium Permissions" do
|
||||
# it "allows Premium users to create core content types" do
|
||||
# @user.update(selected_billing_plan_id: 4)
|
||||
# expect(@user.can_create?(Character)).to eq(true)
|
||||
# expect(@user.can_create?(Location)).to eq(true)
|
||||
# expect(@user.can_create?(Item)).to eq(true)
|
||||
# end
|
||||
it "allows downgrading to Starter" do
|
||||
# Downgrade to Starter
|
||||
post :change, params: { stripe_plan_id: 'starter' }
|
||||
|
||||
# it "allows Premium users to create extended content types" do
|
||||
# @user.update(selected_billing_plan_id: 4)
|
||||
# expect(@user.can_create?(Creature)).to eq(true)
|
||||
# expect(@user.can_create?(Race)).to eq(true)
|
||||
# expect(@user.can_create?(Religion)).to eq(true)
|
||||
# expect(@user.can_create?(Group)).to eq(true)
|
||||
# expect(@user.can_create?(Magic)).to eq(true)
|
||||
# expect(@user.can_create?(Language)).to eq(true)
|
||||
# expect(@user.can_create?(Flora)).to eq(true)
|
||||
# end
|
||||
@user.reload
|
||||
expect(@user.selected_billing_plan_id).to eq(@free_plan.id)
|
||||
expect(@user.active_billing_plans).to eq([@free_plan])
|
||||
expect(@user.active_subscriptions.map(&:billing_plan_id)).to eq([@free_plan.id])
|
||||
end
|
||||
|
||||
# it "allows Premium users to create collective content types" do
|
||||
# @user.update(selected_billing_plan_id: 4)
|
||||
# expect(@user.can_create?(Scene)).to eq(true)
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
describe "Premium Permissions" do
|
||||
it "allows Premium users to create core content types" do
|
||||
@user.update(selected_billing_plan_id: 4)
|
||||
expect(@user.can_create?(Character)).to eq(true)
|
||||
expect(@user.can_create?(Location)).to eq(true)
|
||||
expect(@user.can_create?(Item)).to eq(true)
|
||||
end
|
||||
|
||||
# describe "Upload storage adjustments" do
|
||||
# before do
|
||||
# @user.active_subscriptions.create(billing_plan: @free_plan, start_date: Time.now - 5.days, end_date: Time.now + 5.days)
|
||||
# @user.update(selected_billing_plan_id: @free_plan.id)
|
||||
# end
|
||||
it "allows Premium users to create extended content types" do
|
||||
@user.update(selected_billing_plan_id: 4)
|
||||
expect(@user.can_create?(Creature)).to eq(true)
|
||||
expect(@user.can_create?(Race)).to eq(true)
|
||||
expect(@user.can_create?(Religion)).to eq(true)
|
||||
expect(@user.can_create?(Group)).to eq(true)
|
||||
expect(@user.can_create?(Magic)).to eq(true)
|
||||
expect(@user.can_create?(Language)).to eq(true)
|
||||
expect(@user.can_create?(Flora)).to eq(true)
|
||||
end
|
||||
|
||||
# it 'grants storage space to a user after upgrading' do
|
||||
# @user.update(upload_bandwidth_kb: 100)
|
||||
# post :change, params: { stripe_plan_id: 'premium' }
|
||||
# expect(@user.upload_bandwidth_kb).to eq(100 + @premium_plan.bonus_bandwidth_kb)
|
||||
# end
|
||||
it "allows Premium users to create collective content types" do
|
||||
@user.update(selected_billing_plan_id: 4)
|
||||
expect(@user.can_create?(Scene)).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# it 'decreases storage space for a user after downgrading' do
|
||||
# @user.update(upload_bandwidth_kb: 100)
|
||||
# post :change, params: { stripe_plan_id: 'starter' }
|
||||
# expect(@user.upload_bandwidth_kb).to eq(100 - @premium_plan.bonus_bandwidth_kb)
|
||||
# end
|
||||
describe "Upload storage adjustments" do
|
||||
before do
|
||||
@user.active_subscriptions.create(billing_plan: @free_plan, start_date: Time.now - 5.days, end_date: Time.now + 5.days)
|
||||
@user.update(selected_billing_plan_id: @free_plan.id)
|
||||
end
|
||||
|
||||
# it 'does not adjust storage space when going premium --> premium' do
|
||||
# @user.update(upload_bandwidth_kb: 101)
|
||||
# @user.update(selected_billing_plan_id: @premium_plan.id)
|
||||
# post :change, params: { stripe_plan_id: @premium_annual_plan.stripe_plan_id }
|
||||
# expect(@user.upload_bandwidth_kb).to eq(101)
|
||||
# end
|
||||
it 'grants storage space to a user after upgrading' do
|
||||
@user.update(upload_bandwidth_kb: 100)
|
||||
post :change, params: { stripe_plan_id: 'premium' }
|
||||
expect(@user.upload_bandwidth_kb).to eq(100 + @premium_plan.bonus_bandwidth_kb)
|
||||
end
|
||||
|
||||
# it 'does not adjust storage space if no plan change is made' do
|
||||
# @user.update(upload_bandwidth_kb: 101)
|
||||
# @user.update(selected_billing_plan_id: @premium_annual_plan.stripe_plan_id)
|
||||
# post :change, params: { stripe_plan_id: @premium_plan.stripe_plan_id }
|
||||
# expect(@user.upload_bandwidth_kb).to eq(101)
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
it 'decreases storage space for a user after downgrading' do
|
||||
@user.update(upload_bandwidth_kb: 100)
|
||||
post :change, params: { stripe_plan_id: 'starter' }
|
||||
expect(@user.upload_bandwidth_kb).to eq(100 - @premium_plan.bonus_bandwidth_kb)
|
||||
end
|
||||
|
||||
it 'does not adjust storage space when going premium --> premium' do
|
||||
@user.update(upload_bandwidth_kb: 101)
|
||||
@user.update(selected_billing_plan_id: @premium_plan.id)
|
||||
post :change, params: { stripe_plan_id: @premium_annual_plan.stripe_plan_id }
|
||||
expect(@user.upload_bandwidth_kb).to eq(101)
|
||||
end
|
||||
|
||||
it 'does not adjust storage space if no plan change is made' do
|
||||
@user.update(upload_bandwidth_kb: 101)
|
||||
@user.update(selected_billing_plan_id: @premium_annual_plan.stripe_plan_id)
|
||||
post :change, params: { stripe_plan_id: @premium_plan.stripe_plan_id }
|
||||
expect(@user.upload_bandwidth_kb).to eq(101)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,12 +1,12 @@
|
||||
# FactoryBot.define do
|
||||
# sequence :email do |n|
|
||||
# "email#{n}@example.com"
|
||||
# end
|
||||
FactoryBot.define do
|
||||
sequence :email do |n|
|
||||
"email#{n}@example.com"
|
||||
end
|
||||
|
||||
# factory :user do
|
||||
# email
|
||||
# password { 'password' }
|
||||
# end
|
||||
factory :user do
|
||||
email
|
||||
password { 'password' }
|
||||
end
|
||||
|
||||
# factory :universe do
|
||||
# sequence :name do |n|
|
||||
@ -58,4 +58,4 @@
|
||||
# attribute_category
|
||||
# field_type 'textarea'
|
||||
# end
|
||||
# end
|
||||
end
|
||||
|
||||
@ -56,6 +56,7 @@ RSpec.configure do |config|
|
||||
# config.filter_gems_from_backtrace("gem name")
|
||||
|
||||
config.include FactoryBot::Syntax::Methods
|
||||
config.include Devise::Test::ControllerHelpers, type: :controller
|
||||
end
|
||||
|
||||
Shoulda::Matchers.configure do |config|
|
||||
|
||||
Loading…
Reference in New Issue
Block a user