# rubocop:disable RSpec/ExampleLength, RSpec/MultipleExpectations require "rails_helper" RSpec.describe "StripeSubscriptions", type: :request do let(:user) { create(:user, :super_admin) } let(:mock_instance) { instance_double(MembershipService) } let(:stripe_helper) { StripeMock.create_test_helper } before do StripeMock.start sign_in user end after { StripeMock.stop } describe "POST StripeSubscriptions#create" do context "when a valid request is made" do # Amount is a string here because Stripe returns a string when form is submitted before do post "/stripe_subscriptions", params: { amount: "12", stripe_token: stripe_helper.generate_card_token } end it "creates a customer in Stripe and assigns it to the correct user" do customer = Stripe::Customer.retrieve(user.stripe_id_code) expect(customer.is_a?(Stripe::Customer)).to eq(true) end it "assigns the proper role based on the amount" do expect(user.roles.last.name).to eq("level_2_member") end it "updates the user's monthly_dues with the proper amount" do expect(user.monthly_dues).to eq(1200) end it "redirects to /settings/membership" do expect(response.body).to include("Thank you so much") end end it "can't accept anything less than $1" do post "/stripe_subscriptions", params: { amount: rand(100) / 100, stripe_token: stripe_helper.generate_card_token } expect(response).to redirect_to("/membership") user.reload expect(user.stripe_id_code).to eq(nil) expect(user.roles.count).to eq(1) end # only one type of invalid request right now context "when an invalid request is made" do it "redirects to /enter if there's no current_user" do sign_out user post "/stripe_subscriptions", params: { amount: "1" } expect(response).to redirect_to("/enter") end it "errors if amount is less than 0" do post "/stripe_subscriptions", params: { amount: "-1" } expect(response).to redirect_to("/membership") end it "errors if amount is 0" do post "/stripe_subscriptions", params: { amount: "0" } expect(response).to redirect_to("/membership") end it "denies requests without credit card" do post "/stripe_subscriptions", params: { amount: "25" } expect(response).to redirect_to("/membership") # user.reload # expect(user.stripe_id_code).to be(nil) end end it "handles errors if MembershipService#subscribe_customer fails" do allow(MembershipService).to receive(:new).and_return(mock_instance) allow(mock_instance).to receive(:subscribe_customer).and_return(nil) post "/stripe_subscriptions", params: { amount: "1" } expect(response).to redirect_to("/membership") end end describe "PUT StripeSubscriptions#update" do before do user.add_role(:level_2_member) end context "when there's a subscription for update" do before do post "/stripe_subscriptions", params: { amount: "12", stripe_token: stripe_helper.generate_card_token } end it "assigns the proper role with a new subscription" do put "/stripe_subscriptions/current_user", params: { amount: "30", stripe_token: stripe_helper.generate_card_token } expect(user.has_role?("level_4_member")).to eq(true) end it "updates the user's monthly_dues with the proper amount" do put "/stripe_subscriptions/current_user", params: { amount: "30", stripe_token: stripe_helper.generate_card_token } user.reload expect(user.monthly_dues).to eq(3000) end it "handles errors if MembershipService#update_subscription fails" do allow(MembershipService).to receive(:new).and_return(mock_instance) allow(mock_instance).to receive(:update_subscription).and_return(nil) put "/stripe_subscriptions/current_user", params: { amount: "30", stripe_token: stripe_helper.generate_card_token } expect(response).to redirect_to("/settings/membership") end it "can't accept anything less than $1" do put "/stripe_subscriptions/current_user", params: { amount: rand(100) / 100 } expect(response).to redirect_to("/settings/billing") user.reload expect(user.stripe_id_code).not_to eq(nil) expect(user.has_role?(:level_1_member)).to eq(false) end end end describe "DESTROY StripeSubscriptions#destroy" do before do user.add_role(:level_2_member) post "/stripe_subscriptions", params: { amount: "12", stripe_token: stripe_helper.generate_card_token } end context "when a valid request is made" do it "deletes membership" do delete "/stripe_subscriptions/current_user", params: { stripe_token: stripe_helper.generate_card_token } expect(user.has_role?("level_2_member")).to eq(false) end it "returns user monthly dues to zero" do delete "/stripe_subscriptions/current_user", params: { stripe_token: stripe_helper.generate_card_token } user.reload expect(user.monthly_dues).to eq(0) end it "handles errors if MembershipService#unsubscribe_customer fails" do allow(MembershipService).to receive(:new).and_return(mock_instance) allow(mock_instance).to receive(:unsubscribe_customer).and_return(nil) delete "/stripe_subscriptions/current_user" expect(response).to redirect_to("/settings") end end end end # rubocop:enable RSpec/ExampleLength, RSpec/MultipleExpectations