require "rails_helper"

RSpec.describe Payments::PurchaseRefundsController do
  include_context "mocked permissions"

  let(:permission) { "purchase_refunds" }

  describe "#index" do
    subject { get :index, params: params }

    let(:params) { {} }
    let(:user) { double(id: 12345, partner_program?: false, affiliate?: false, developer?: false) }
    let(:body) { { } }
    let(:resp) { double(success?: true, body: body) }

    before do
      body['payments_count'] = 2
      body['gross_amount_usd'] = 10
      allow(Twitch::User).to receive(:find_by_login).and_return(user)
      allow(Payments::RefundPreview).to receive(:refund_preview).and_return(resp)
    end

    describe "with no product types and purchaser login" do
      let(:action) { :index }
      let(:login) { 'foo' }
      let(:reason) { 'ato_fraud' }
      let(:params) { { created_at_start: '2019-01-01', purchaser_login: login, reason: reason } }

      context 'a user with appropriate permissions' do
        include_context 'an authorized user'

        before do
          subject
        end

        it 'redirects the user to the same page and displays an error' do
          expect(response.code).to eq('302')
          expect(response.location).to eql('http://test.host/payments/purchase_refunds')
          expect(flash[:error]).to eql('You must choose at least one of Subs, Gift Subs, or Bits to refund')
        end
      end
    end

    describe "with product types and start date, but no purchaser login" do
      let(:action) { :index }
      let(:params) { { bits: true, created_at_start: '2019-01-01' } }

      context 'a user with appropriate permissions' do
        include_context 'an authorized user'

        before do
          subject
        end

        it_behaves_like 'it returns a success response'
      end
    end

    describe "with product types, start date, and purchaser login" do
      let(:action) { :index }
      let(:login) { 'foo' }
      let(:params) { { bits: true, created_at_start: '2019-01-01', purchaser_login: login } }

      context 'a user with appropriate permissions' do
        include_context 'an authorized user'

        context 'succeeds:' do
          include_context 'it creates any tracking call'

          before do
            subject
          end

          context 'when everything works' do
            let(:user) { double(id: 12345, partner_program?: false, affiliate?: false, developer?: false, blank?: false) }

            it_behaves_like 'it returns a success response'
          end

          context 'when the user is an affiliate' do
            let(:user) { double(id: 12345, partner_program?: false, affiliate?: true, developer?: false, blank?: false) }
            it_behaves_like 'it returns a success response'
          end

        end

        context 'fails:' do

          before do
            subject
          end

          context 'when user lookup fails' do
            let(:user) { double(id: 12345, partner_program?: false, affiliate?: false, developer?: false, blank?: true) }

            it 'redirects the user to the same page and displays an error' do
              expect(response.code).to eq('302')
              expect(response.location).to eql('http://test.host/payments/purchase_refunds')
              expect(flash[:error]).to eql("No user found with username: #{login}")
            end
          end

          context 'when the user is a developer' do
            let(:user) { double(id: 12345, partner_program?: false, affiliate?: false, developer?: true, blank?: false) }

            it 'redirects the user to the same page and displays an error' do
              expect(response.code).to eq('302')
              expect(response.location).to start_with('http://test.host/payments/purchase_refunds')
              expect(flash[:error]).to eql('Mass refunds cannot be performed for partners or extension developers')
            end
          end

          context 'when the user is a partner' do
            let(:user) { double(id: 12345, partner_program?: true, affiliate?: false, developer?: false, blank?: false) }

            it 'redirects the user to the same page and displays an error' do
              expect(response.code).to eq('302')
              expect(response.location).to start_with('http://test.host/payments/purchase_refunds')
              expect(flash[:error]).to eql('Mass refunds cannot be performed for partners or extension developers')
            end
          end

          context 'when the response contains a non-200 status code' do
            let(:resp) { double(success?: false, body: body) }

            it 'redirects the user to the same page and displays an error' do
              expect(response.code).to eq('302')
              expect(response.location).to start_with('http://test.host/payments/purchase_refunds')
              expect(flash[:error]).to eql('Failed to generate a refund preview. If this issue persists, contact #admin-services on Slack for help')
            end
          end
        end
      end
    end
  end

  describe '#create' do
    subject { get :create, params: params }

    describe 'permissions' do
      let(:action) { :create }

      context 'with a created_at date param' do
        include_context 'an authorized user'
        include_context 'it creates any tracking call'

        let(:params) { { created_at_start: '2019-01-01', reason: 'ato_fraud' } }
        before do
          allow(Payments::RefundAllPayments).to receive(:refund_all_payments).and_return(true)
          subject
        end

        it_behaves_like 'it redirects the user and displays a success message'
      end
    end
  end
end
