From ac96a001a8cb92725e3a8c04980cecf57fe742dd Mon Sep 17 00:00:00 2001
From: Andrew Brown
Date: Thu, 10 Jul 2025 23:40:36 -0700
Subject: [PATCH] Fix Stripe subscription errors by migrating deprecated
sources API to payment_methods API
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 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
---
Gemfile | 4 +
Gemfile.lock | 37 ++
app/controllers/subscriptions_controller.rb | 26 +-
app/controllers/users_controller.rb | 9 +-
app/services/subscription_service.rb | 16 +-
app/views/subscriptions/history.html.erb | 6 +-
lib/tasks/data_integrity.rake | 3 +-
.../subscriptions_controller_spec.rb | 461 +++++++++---------
spec/factories.rb | 18 +-
spec/rails_helper.rb | 1 +
10 files changed, 331 insertions(+), 250 deletions(-)
diff --git a/Gemfile b/Gemfile
index 27fc5286..0a4f74df 100644
--- a/Gemfile
+++ b/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
diff --git a/Gemfile.lock b/Gemfile.lock
index 9305c72a..a09825a0 100644
--- a/Gemfile.lock
+++ b/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
diff --git a/app/controllers/subscriptions_controller.rb b/app/controllers/subscriptions_controller.rb
index 685f1fca..4aad9ede 100644
--- a/app/controllers/subscriptions_controller.rb
+++ b/app/controllers/subscriptions_controller.rb
@@ -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
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 817c28e6..4ff030dd 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -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)
diff --git a/app/services/subscription_service.rb b/app/services/subscription_service.rb
index 12b036bb..d76611ac 100644
--- a/app/services/subscription_service.rb
+++ b/app/services/subscription_service.rb
@@ -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(
diff --git a/app/views/subscriptions/history.html.erb b/app/views/subscriptions/history.html.erb
index b7729db3..4430f448 100644
--- a/app/views/subscriptions/history.html.erb
+++ b/app/views/subscriptions/history.html.erb
@@ -14,7 +14,7 @@
- <% if @stripe_customer.sources.total_count == 0 %>
+ <% if @stripe_payment_methods.data.length == 0 %>
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 %>
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.
@@ -34,7 +34,7 @@
- <% if @stripe_customer.sources.total_count > 0 %>
+ <% if @stripe_payment_methods.data.length > 0 %>
<%= link_to "Add new payment method", payment_info_path %>
<%= link_to "Delete existing payment method", delete_payment_method_path %>
diff --git a/lib/tasks/data_integrity.rake b/lib/tasks/data_integrity.rake
index 35fc3a53..7db2c4af 100644
--- a/lib/tasks/data_integrity.rake
+++ b/lib/tasks/data_integrity.rake
@@ -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
diff --git a/spec/controllers/subscriptions_controller_spec.rb b/spec/controllers/subscriptions_controller_spec.rb
index 091cf60a..d22d86da 100644
--- a/spec/controllers/subscriptions_controller_spec.rb
+++ b/spec/controllers/subscriptions_controller_spec.rb
@@ -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
\ No newline at end of file
diff --git a/spec/factories.rb b/spec/factories.rb
index a8c32c6d..94df4c31 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -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
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
index bca709ad..6ca79b28 100644
--- a/spec/rails_helper.rb
+++ b/spec/rails_helper.rb
@@ -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|