# frozen_string_literal: true require 'spec_helper' RSpec.describe Admin::StripeAccountsController do let(:enterprise) { create(:distributor_enterprise) } describe "#connect" do let(:client_id) { ENV.fetch('STRIPE_CLIENT_ID', nil) } before do Stripe.client_id = client_id allow(controller).to receive(:spree_current_user) { enterprise.owner } end it "redirects to Stripe Authorization url constructed OAuth" do # A deterministic id results in a deterministic state JWT token get :connect, params: { enterprise_id: 1 } expect(response).to redirect_to("https://connect.stripe.com/oauth/authorize?" \ "state=eyJhbGciOiJIUzI1NiJ9.eyJlbnRlcnByaXNlX2lkIjoiMSJ9" \ ".jSSFGn0bLhwuiQYK5ORmHWW7aay1l030bcfGwn1JbFg&" \ "scope=read_write&client_id=#{client_id}&response_type=code") end end describe "#destroy" do let(:params) { { format: :json, id: "client_id" } } context "when the specified stripe account doesn't exist" do it "raises an error?" do spree_delete :destroy, params end end context "when the specified stripe account exists", :vcr, :stripe_version do let(:connected_account) do Stripe::Account.create({ type: 'standard', country: 'AU', email: 'jumping.jack@example.com', business_type: "non_profit" }) end let(:stripe_account) { create(:stripe_account, enterprise:, stripe_user_id: connected_account.id) } before do # So that we can stub #deauthorize_and_destroy allow(StripeAccount).to receive(:find) { stripe_account } params[:id] = stripe_account.id end after do Stripe::Account.delete(connected_account.id) end context "when I don't manage the enterprise linked to the stripe account" do let(:some_user) { create(:user) } before { allow(controller).to receive(:spree_current_user) { some_user } } it "redirects to unauthorized" do spree_delete :destroy, params expect(response).to redirect_to unauthorized_path end end context "when I manage the enterprise linked to the stripe account" do before { allow(controller).to receive(:spree_current_user) { enterprise.owner } } context "and the attempt to deauthorize_and_destroy succeeds" do before { allow(stripe_account).to receive(:deauthorize_and_destroy) { stripe_account } } it "redirects to unauthorized" do spree_delete :destroy, params expect(response).to redirect_to edit_admin_enterprise_path(enterprise) expect(flash[:success]).to eq "Stripe account disconnected." end end context "and the attempt to deauthorize_and_destroy fails" do before { allow(stripe_account).to receive(:deauthorize_and_destroy) { false } } it "redirects to unauthorized" do spree_delete :destroy, params expect(response).to redirect_to edit_admin_enterprise_path(enterprise) expect(flash[:error]).to eq "Failed to disconnect Stripe." end end end end end describe "#status" do let(:params) { { format: :json, enterprise_id: enterprise.id } } context "when I don't manage the specified enterprise" do let(:user) { create(:user) } before do allow(controller).to receive(:spree_current_user) { user } end it "redirects to unauthorized" do get(:status, params:) expect(response).to redirect_to unauthorized_path end end context "when I manage the specified enterprise" do before do allow(controller).to receive(:spree_current_user) { enterprise.owner } end context "when Stripe is not enabled" do it "returns with a status of 'stripe_disabled'" do get(:status, params:) json_response = response.parsed_body expect(json_response["status"]).to eq "stripe_disabled" end end context "when Stripe is enabled" do before { allow(Spree::Config).to receive(:stripe_connect_enabled).and_return(true) } context "when no stripe account is associated with the specified enterprise" do it "returns with a status of 'account_missing'" do get(:status, params:) json_response = response.parsed_body expect(json_response["status"]).to eq "account_missing" end end context "when a stripe account is associated with the specified enterprise", :vcr, :stripe_version do let(:connected_account) do Stripe::Account.create({ type: 'standard', country: 'AU', email: 'jumping.jack@example.com', business_type: "non_profit" }) end let!(:account) { create(:stripe_account, stripe_user_id: connected_account.id, enterprise:) } after do Stripe::Account.delete(connected_account.id) end context "but access has been revoked or does not exist on stripe's servers" do let(:message) { "The provided key 'sk_test_******************************uCJm' " \ "does not have access to account 'acct_fake_account' (or that account " \ "does not exist). Application access may have been revoked." } before do account.update(stripe_user_id: "acct_fake_account") end it "returns with a status of 'access_revoked'" do expect { response = get(:status, params:) }.to raise_error Stripe::PermissionError, message end end context "which is connected" do it "returns with a status of 'connected'" do response = get(:status, params:) json_response = response.parsed_body expect(json_response["status"]).to eq "connected" # serializes required attrs expect(json_response["charges_enabled"]).to eq false # ignores other attrs expect(json_response["some_other_attr"]).to be nil end end end end end end end