require 'rails_helper'

RSpec.describe Boxart::GamesController do
  include_context 'mocked permissions'

  let(:permission) { 'boxart_upload' }

  describe 'index' do
    let(:action) { :index }

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

        before do
          get action
        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 action
        end

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

    describe 'requesting a game that exists' do
      let(:dummy_game) { Boxart::Game.new(:name => 'foo') }

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

        before do
          expect(Boxart::Game).to receive(:find).with('foo').and_return(dummy_game)
          expect(dummy_game).to receive(:persisted?).and_return(true)
          get action, params: { :name => 'foo' }
        end

        it_behaves_like 'it redirects the user and does not display an error'
      end
    end

    describe 'requesting a game that does not exist' do
      let(:dummy_game) { Boxart::Game.new :errors => ['rip'] }

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

        before do
          expect(Boxart::Game).to receive(:find).with('foo').and_return(dummy_game)
          dummy_game.errors = ['mock error']
          expect(dummy_game).to receive(:persisted?).and_return(false)
          get action, params: { :name => 'foo' }
        end

        it 'shows an error' do
          expect(flash[:error]).to be_present
        end
      end
    end
  end

  describe 'show' do
    let(:action) { :show }

    describe 'a game that exists' do
      let(:dummy_game) { Boxart::Game.new :name => 'foo' }

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

        before do
          expect(Boxart::Game).to receive(:find).with('foo').and_return(dummy_game)
          expect(dummy_game).to receive(:persisted?).and_return(true)
          get action, :params => {:id => 'foo'}
        end

        it_behaves_like 'it returns a success response'
      end
    end

    describe 'a game that does not exist' do
      let(:dummy_game) { Boxart::Game.new :errors => ['rip'] }

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

        before do
          expect(Boxart::Game).to receive(:find).with('foo').and_return(dummy_game)
          get action, :params => {:id => 'foo'}
        end

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

  describe 'update' do
    let(:action) { :update }

    describe 'clicks upload without supplying an image' do
      let(:dummy_game) { Boxart::Game.new :name => 'update' }

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

        before do
          expect(Boxart::Game).to receive(:find).with('foo').and_return(dummy_game)
          expect(dummy_game).to receive(:persisted?).and_return(true)
          put action, :params => {:id => 'foo'}
        end

        it 'shows an error' do
          expect(flash[:error]).to be_present
        end
      end
    end

    describe 'upload succeeds' do
      let(:dummy_game) { Boxart::Game.new :name => 'update', :image => 'foo' }

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

        before do
          expect(Boxart::Game).to receive(:find).with('foo').and_return(dummy_game)
          expect(dummy_game).to receive(:persisted?).and_return(true, true)
          expect(dummy_game).to receive(:save).and_return(true)
          put action, :params => { :id => 'foo' }
        end

        it_behaves_like 'it redirects the user and does not display an error'
      end
    end

    describe 'upload fails' do
      let(:dummy_game) { Boxart::Game.new :name => 'update', :image => 'foo' }

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

        before do
          expect(Boxart::Game).to receive(:find).with('foo').and_return(dummy_game)
          expect(dummy_game).to receive(:persisted?).and_return(true)
          expect(dummy_game).to receive(:save).and_return(false)
          dummy_game.errors = ['fail']
          put action, :params => { :id => 'foo' }
        end

        it 'shows an error' do
          expect(flash[:error]).to be_present
        end
      end
    end
  end
end
