diff --git a/Gemfile b/Gemfile index 1aef4acc1..92332c2e6 100644 --- a/Gemfile +++ b/Gemfile @@ -86,4 +86,5 @@ group :test do gem "capybara" gem "selenium-webdriver" gem "codecov", require: false + gem 'stripe-ruby-mock', require: "stripe_mock" end diff --git a/Gemfile.lock b/Gemfile.lock index e93fe7071..1bab4040e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -134,6 +134,7 @@ GEM concurrent-ruby (1.1.7) crass (1.0.6) daemons (1.3.1) + dante (0.2.0) delayed_job (4.1.8) activesupport (>= 3.0, < 6.1) delayed_job_active_record (4.1.4) @@ -354,6 +355,10 @@ GEM streamio-ffmpeg (3.0.2) multi_json (~> 1.8) stripe (5.28.0) + stripe-ruby-mock (3.0.1) + dante (>= 0.2.0) + multi_json (~> 1.0) + stripe (> 5, < 6) thor (1.0.1) thread_safe (0.3.6) tzinfo (1.2.8) @@ -452,6 +457,7 @@ DEPENDENCIES stackprof streamio-ffmpeg stripe + stripe-ruby-mock unicorn unicorn-worker-killer webpacker (>= 4.0.x) diff --git a/app/controllers/user_upgrades_controller.rb b/app/controllers/user_upgrades_controller.rb index 903f7b6ec..be7ee116a 100644 --- a/app/controllers/user_upgrades_controller.rb +++ b/app/controllers/user_upgrades_controller.rb @@ -42,15 +42,10 @@ class UserUpgradesController < ApplicationController end begin - charge = Stripe::Charge.create( - :amount => cost, - :currency => "usd", - :card => params[:stripeToken], - :description => params[:desc] - ) + charge = Stripe::Charge.create(amount: cost, currency: "usd", source: params[:stripeToken], description: params[:desc]) @user.promote_to!(level, User.system, is_upgrade: true) flash[:success] = true - rescue Stripe::CardError => e + rescue Stripe::StripeError => e DanbooruLogger.log(e) flash[:error] = e.message end diff --git a/test/functional/user_upgrades_controller_test.rb b/test/functional/user_upgrades_controller_test.rb index b4450f8a1..8fbd64d34 100644 --- a/test/functional/user_upgrades_controller_test.rb +++ b/test/functional/user_upgrades_controller_test.rb @@ -1,6 +1,14 @@ require 'test_helper' class UserUpgradesControllerTest < ActionDispatch::IntegrationTest + setup do + StripeMock.start + end + + teardown do + StripeMock.stop + end + context "The user upgrades controller" do context "new action" do should "render" do @@ -15,5 +23,97 @@ class UserUpgradesControllerTest < ActionDispatch::IntegrationTest assert_response :success end end + + context "create action" do + setup do + @user = create(:user) + @token = StripeMock.generate_card_token + end + + context "a self upgrade" do + should "upgrade a Member to Gold" do + post_auth user_upgrade_path, @user, params: { stripeToken: @token, desc: "Upgrade to Gold" } + + assert_redirected_to user_upgrade_path + assert_equal(true, @user.reload.is_gold?) + end + + should "upgrade a Member to Platinum" do + post_auth user_upgrade_path, @user, params: { stripeToken: @token, desc: "Upgrade to Platinum" } + + assert_redirected_to user_upgrade_path + assert_equal(true, @user.reload.is_platinum?) + end + + should "upgrade a Gold user to Platinum" do + @user.update!(level: User::Levels::GOLD) + post_auth user_upgrade_path, @user, params: { stripeToken: @token, desc: "Upgrade Gold to Platinum" } + + assert_redirected_to user_upgrade_path + assert_equal(true, @user.reload.is_platinum?) + end + + should "log an account upgrade modaction" do + assert_difference("ModAction.user_account_upgrade.count") do + post_auth user_upgrade_path, @user, params: { stripeToken: @token, desc: "Upgrade to Gold" } + end + end + + should "send the user a dmail" do + assert_difference("@user.dmails.received.count") do + post_auth user_upgrade_path, @user, params: { stripeToken: @token, desc: "Upgrade to Gold" } + end + end + end + + context "a gifted upgrade" do + should "upgrade the user to Gold" do + @other_user = create(:user) + post_auth user_upgrade_path, @user, params: { stripeToken: @token, desc: "Upgrade to Gold", user_id: @other_user.id } + + assert_redirected_to user_upgrade_path(user_id: @other_user.id) + assert_equal(true, @other_user.reload.is_gold?) + assert_equal(false, @user.reload.is_gold?) + end + end + + context "an upgrade with a missing Stripe token" do + should "not upgrade the user" do + post_auth user_upgrade_path, @user, params: { desc: "Upgrade to Gold" } + + assert_response :success + assert_equal(true, @user.reload.is_member?) + end + end + + context "an upgrade with an invalid Stripe token" do + should "not upgrade the user" do + post_auth user_upgrade_path, @user, params: { stripeToken: "garbage", desc: "Upgrade to Gold" } + + assert_redirected_to user_upgrade_path + assert_equal(true, @user.reload.is_member?) + end + end + + context "an upgrade with an credit card that is declined" do + should "not upgrade the user" do + StripeMock.prepare_card_error(:card_declined) + post_auth user_upgrade_path, @user, params: { stripeToken: @token, desc: "Upgrade to Gold" } + + assert_redirected_to user_upgrade_path + assert_equal(true, @user.reload.is_member?) + end + end + + context "an upgrade with an credit card that is expired" do + should "not upgrade the user" do + StripeMock.prepare_card_error(:expired_card) + post_auth user_upgrade_path, @user, params: { stripeToken: @token, desc: "Upgrade to Gold" } + + assert_redirected_to user_upgrade_path + assert_equal(true, @user.reload.is_member?) + end + end + end end end