require "rails_helper"

RSpec.describe Twitch::ReservationsController do
  include_context "mocked permissions"

  let(:permission) {"reservations"}

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

        before do
          get :index
        end

        it_behaves_like "it returns a success response"
      end

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

        before do
          get :index
        end

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

    describe "finding a Reservation" do
      let(:find_by_login) {'reserved_name'}

      include_context "an authorized user"

      before do
        allow(Twitch::Reservation).to receive(:find).once.with(find_by_login)
          .and_return(Twitch::Reservation.new(login: 'reserved_name', type: 'Reserved Record', reason: 'testing'))

        get :index, params: {find_by_login: find_by_login}
      end

      it_behaves_like "it returns a success response"
    end
  end

  describe "#new" do
    describe "permissions" do
      context "a user with appropriate permissions" do
        include_context "an authorized user"
        let(:reservation) {Twitch::Reservation.new}

        before do
          allow(Twitch::Reservation).to receive(:new).once.and_return(reservation)

          get :new
        end

        it_behaves_like "it returns a success response"
      end

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

        before do
          get :new
        end

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

  describe "#create" do
    describe "permissions" do
      context "a user with appropriate permissions" do
        include_context "an authorized user"
        let(:reservation) {Twitch::Reservation.new(login: 'reserved_name', type: 'Reserved Record', reason: 'testing')}

        before do
          expect(Twitch::Reservation).to receive(:create).once.with(ActionController::Parameters.new(login: 'reserved_name', type: 'Reserved Record', reason: 'testing')).and_return(Struct.new(:status).new(200))
          expect(History::AddAudit).to receive(:add).once

          get :create, params: {:twitch_reservation => {login: 'reserved_name', type: 'Reserved Record', reason: 'testing'}}
        end

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

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

        before do
          get :create
        end

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

  describe "#show" do
    let(:reservation) {Twitch::Reservation.new(login: 'reserved_name', type: 'Reserved Record', reason: 'testing')}

    describe "permissions" do
      context "a user with appropriate permissions" do
        include_context "an authorized user"

        before do
          allow(Twitch::Reservation).to receive(:find).once.with(reservation.login).and_return(reservation)

          get :show, params: {id: reservation.login}
        end

        it_behaves_like "it returns a success response"
      end

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

        before do
          get :show, params: {id: reservation.id}
        end

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

  describe "#update" do
    describe "permissions" do
      context "a user with appropriate permissions" do
        include_context "an authorized user"
        let(:reservation) {Twitch::Reservation.new(login: 'reserved_name', type: 'Reserved Record', reason: 'testing')}

        before do
          allow(Twitch::Reservation).to receive(:find).once.with(reservation.login).and_return(reservation)
          expect(reservation).to receive(:update).once.with(ActionController::Parameters.new(login: 'reserved_name', type: 'Reserved Record', reason: 'updated testing')).and_return(Struct.new(:status).new(200))
          expect(History::AddAudit).to receive(:add).once

          get :update, params: {:id => 'reserved_name', :twitch_reservation => {login: 'reserved_name', type: 'Reserved Record', reason: 'updated testing'}}
        end

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

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

        before do
          get :update, params: {:id => 'reserved_name', :twitch_reservation => {login: 'reserved_name', type: 'Reserved Record', reason: 'updated testing'}}
        end

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

  describe "#destroy" do
    let(:reservation) {Twitch::Reservation.new(login: 'reserved_name', type: 'Reserved Record', reason: 'testing')}

    describe "permissions" do
      context "a user with appropriate permissions" do
        include_context "an authorized user"

        before do
          allow(Twitch::Reservation).to receive(:find).once.with(reservation.login).and_return(reservation)

          expect(reservation).to receive(:destroy).once.and_return(true)
          expect(History::AddAudit).to receive(:add).once

          delete :destroy, params: {id: reservation.login}
        end

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

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

        before do
          delete :destroy, params: {id: reservation.login}
        end

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