require "rails_helper"

RSpec.describe Subscriptions::TokensController do
  include_context "mocked permissions"

  let(:test_user_id) { '123' }
  let(:test_twitch_user) { Twitch::User.new(id: test_user_id) }

  describe '#index' do
    context 'a user with appropriate permissions' do
      include_context 'an authorized user'

      let(:permission) { 'ticket_products' }

      before do
        allow(Twitch::User).to receive(:find).with(test_user_id).and_return(test_twitch_user)

        allow(Subscriptions::Token).to receive(:get_token_balance).with(
          test_user_id
        ).and_return(0)

        allow(Payments::Transaction).to receive(:transactions_for_user).with(
          test_user_id
        ).and_return({})

        allow(Payments::PurchaseOrder).to receive(:filter).with(
          {
            :purchaser_id => test_user_id
          }
        ).and_return({})

        allow(History::Audit).to receive(:new).with(
          {
            :action => "update",
            :user_type => "ldap_user",
            :user_id => "cool_ldap_login",
            :resource_type => "token_product",
            :resource_id => nil,
            :changes => [
              {
                :attribute => :quantity,
                :old_value => 0,
                :new_value => "1"
              }
            ]
          }
        ).and_return(nil)

        allow(History::AddAudit).to receive(:add).with(nil).and_return(true)

        get :index, params: { subscriptions_tokens: {:userLogin => 'someLogin', :userID => '123' } }
      end

      it 'is able to grant tokens' do
        expect(response.code).to eq("200")
      end
    end

    context 'cannot find a user' do
      include_context 'an authorized user'

      let(:permission) { 'ticket_products' }

      before do
        allow(Twitch::User).to receive(:find).with('1').and_return(nil)

        allow(Subscriptions::Token).to receive(:get_token_balance).with(
          '1'
        ).and_return(0)

        allow(Payments::Transaction).to receive(:transactions_for_user).with(
          '1'
        ).and_return({})

        allow(Payments::PurchaseOrder).to receive(:filter).with(
          {
            :purchaser_id => test_user_id
          }
        ).and_return([])

        allow(Subscriptions::Token).to receive(:get_token_balance).with({ :user_id => "" }).and_return(0)

        allow(History::Audit).to receive(:new).with(
          {
            :action => "update",
            :user_type => "ldap_user",
            :user_id => "cool_ldap_login",
            :resource_type => "token_product",
            :resource_id => nil,
            :changes => [
              {
                :attribute => :quantity,
                :old_value => 0,
                :new_value => "1"
              }
            ]
          }
        ).and_return(nil)

        allow(History::AddAudit).to receive(:add).with(nil).and_return(true)

        get :index, params: { subscriptions_tokens: {:userLogin => 'someLogin', :userID => '1' } }
      end

      it 'is able to grant tokens' do
        expect(response.code).to eq("200")
      end
    end

    context "a user without appropriate permissions" do
      include_context "an unauthorized user"

      let(:permission) { "ticket_products" }

      before do
        allow(Subscriptions::Token).to receive(:get_token_balance).with(
          test_user_id
        ).and_return(0)

        allow(Subscriptions::Token).to receive(:get_token_balance).with({ :user_id => "" }).and_return(0)

        allow(Payments::PurchaseOrder).to receive(:filter).with(
          {
            :purchaser_id => test_user_id
          }
        ).and_return([])

        allow(Subscriptions::Token).to receive(:get_token_balance).with({ :user_id => "" }).and_return(0)

        allow(History::Audit).to receive(:new).with(
          {
            :action => "update",
            :user_type => "ldap_user",
            :user_id => "cool_ldap_login",
            :resource_type => "token_product",
            :resource_id => nil,
            :changes => [
              {
                :attribute => :quantity,
                :old_value => 0,
                :new_value => "1"
              }
            ]
          }
        ).and_return(nil)

        get :index, params: { subscriptions_tokens: {:quantity => 1 }, user_id: '123' }
      end

      it_behaves_like "it redirects the user and displays an error"
    end
  end

  describe '#grant_tokens' do
    context 'an authorized user can grant tokens' do
      include_context 'an authorized user'

      let(:permission) { 'ticket_products' }

      before do
        allow(Subscriptions::Token).to receive(:get_token_balance).with(
          test_user_id
        ).and_return(0)

        allow(Subscriptions::Token).to receive(:grant_tokens_for_user).with(
          test_user_id,
          '1'
        ).and_return(true)

        allow(Payments::PurchaseOrder).to receive(:filter).with(
          {
            :purchaser_id => test_user_id
           }
        ).and_return([])

        allow(Subscriptions::Token).to receive(:get_token_balance).with({ :user_id => "" }).and_return(0)

        allow(History::Audit).to receive(:new).with(
          {
            :action => "update",
            :user_type => "ldap_user",
            :user_id => "cool_ldap_login",
            :resource_type => "token_product",
            :resource_id => nil,
            :changes => [
              {
                :attribute => :quantity,
                :old_value => 0,
                :new_value => "1"
              }
            ]
          }
        ).and_return(nil)

        allow(History::AddAudit).to receive(:add).with(nil).and_return(true)

        post :grant_tokens, params: { subscriptions_tokens: {:quantity => 1 }, user_id: '123' }
      end

      it 'is able to grant tokens' do
        expect(response.code).to eq("302")
      end
    end

    context 'an authorized user cant grant more than 10 tokens' do
      include_context 'an authorized user'

      let(:permission) { 'ticket_products' }

      before do
        allow(Subscriptions::Token).to receive(:get_token_balance).with(
          test_user_id
        ).and_return(0)

        allow(Subscriptions::Token).to receive(:grant_tokens_for_user).with(
          test_user_id,
          '12'
        ).and_return(false)

        allow(Payments::PurchaseOrder).to receive(:filter).with(
          {
            :purchaser_id => test_user_id
          }
        ).and_return([])

        allow(Subscriptions::Token).to receive(:get_token_balance).with({ :user_id => "" }).and_return(0)

        allow(History::Audit).to receive(:new).with(
          {
            :action => "update",
            :user_type => "ldap_user",
            :user_id => "cool_ldap_login",
            :resource_type => "token_product",
            :resource_id => nil,
            :changes => [
              {
                :attribute => :quantity,
                :old_value => 0,
                :new_value => "1"
              }
            ]
          }
        ).and_return(nil)

        allow(History::AddAudit).to receive(:add).with(nil).and_return(true)

        post :grant_tokens, params: { subscriptions_tokens: {:quantity => 12 }, user_id: '123' }
      end

      it 'is able to grant tokens' do
        expect(response.code).to eq("302")
      end
    end
  end
end
