require 'rails_helper'

RSpec.describe Promotions::BackfillChannelsController do

  include_context 'mocked permissions'

  let(:permission) { 'promotions' }

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

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

        before do
          expect(Promotions::BackfillChannel).to receive(:all).and_return([])
          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
  end

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

      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
  end

  describe 'create' do
    describe 'permissions' do
      let(:action) { :create }
      let(:audit) { History::Audit.new(action: "create", user_type: "ldap_user", user_id: "cool_ldap_login", resource_type: 'backfill_channel', resource_id: 'aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1', changes: [ {:attribute => "user_id", :old_value => nil, :new_value => 2}, {:attribute => "login", :old_value => nil, :new_value => "test_login"}, {:attribute => "priority", :old_value => nil, :new_value => 1}, {:attribute => "title", :old_value => nil, :new_value => "title"}, {:attribute => "image_url", :old_value => nil, :new_value => "url"}, {:attribute => "sponsored", :old_value => nil, :new_value => false}, {:attribute => "description_raw", :old_value => nil, :new_value => "description"}, {:attribute => "language", :old_value => nil, :new_value => "en"}, {:attribute => "active", :old_value => nil, :new_value => false}]) }
      let(:expected_url) { '/admin/backfill_channels' }
      let(:expected_body) { '{"backfill_channel":{"id":null,"user_id":null,"login":"test_login","priority":1,"title":"title","image_url":"url","created_on":null,"updated_on":null,"inserted_at":null,"updated_at":null,"sponsored":false,"description_raw":"description","language":"en","active":false}}'}
      let(:expected_headers) { { 'Content-Type' => 'application/json' } }
      let(:hypeman_response) { double 'hypeman response' }

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

        before do
          expect(Promotions::BackfillChannel).to receive(:post).with(expected_url, { body: expected_body, headers: expected_headers }).and_return(hypeman_response)
          expect(hypeman_response).to receive(:body).and_return({"backfill_channel" => {"id" => 'aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1', "user_id" => 2, title: "title", description_raw: "description", priority: 1, image_url: "url", sponsored: false, active: false, language: "en", login: "test_login"}}).at_least(1)
          expect(hypeman_response).to receive(:success?).and_return(true).at_least(1)

          expect(History::AddAudit).to receive(:add).with(audit)
          post action, params: { promotions_backfill_channel: {title: "title", description_raw: "description", priority: 1, image_url: "url", sponsored: false, active: false, language: "en", login: "test_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
          promotions_backfill_channel_options = {
            login: 'test_login',
            priority: 10,
            title: 'test_title',
            description_raw: 'test_description',
            image_url: 'test_image',
            language: 'test_language',
            active: true
          }
          post action, :params => {:id => 'aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1',  :promotions_backfill_channel => promotions_backfill_channel_options}
        end

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

  describe 'edit' do
    describe 'permissions' do
      let(:action) { :edit }
      let(:dummy_item) { Promotions::BackfillChannel.new }
      params = {:id => 'aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1'}

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

        before do
          expect(Promotions::BackfillChannel).to receive(:find).with('aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1').and_return(dummy_item)
          get action, :params => params
        end

        it_behaves_like 'it returns a success response'
      end

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

        before do
          expect(Promotions::BackfillChannel).to receive(:find).with('aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1').and_return(dummy_item)
          get action,  :params => params
        end

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

  describe 'update' do
    describe 'permissions' do
      let(:action) { :update }
      let(:dummy_item) { Promotions::BackfillChannel.from_attributes(id: 'aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1', login: 'test', title: "title", description_raw: "description", priority: 1, image_url: "url", sponsored: false, active: false, user_id: "2", language: "en") }
      let(:expected_url) { '/admin/backfill_channels/aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1' }
      let(:expected_body) { '{"backfill_channel":{"priority":10,"title":"new_title","image_url":"url","sponsored":false,"description_raw":"new_description","active":false}}'}
      let(:expected_headers) { { 'Content-Type' => 'application/json' } }
      let(:hypeman_response) { double 'hypeman response' }
      let(:audit) { History::Audit.new(action: "update", user_type: "ldap_user", user_id: "cool_ldap_login", resource_type: 'backfill_channel', resource_id: 'aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1', changes: [{:attribute => "priority", :old_value => 1, :new_value => 10}, {:attribute => "title", :old_value => "title", :new_value => "new_title"}, {:attribute => "description_raw", :old_value => 'description', :new_value => 'new_description'}]) }

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

        before do
          expect(Promotions::BackfillChannel).to receive(:find).with('aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1').and_return(dummy_item)
          expect(Promotions::BackfillChannel).to receive(:put).with(expected_url, { body: expected_body, headers: expected_headers }).and_return(hypeman_response)
          expect(hypeman_response).to receive(:success?).and_return(true).at_least(1)

          expect(History::AddAudit).to receive(:add).with(audit)
          post action, :params => {:id => 'aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1',
                                   :promotions_backfill_channel => {priority: 10, title: 'new_title', description_raw: 'new_description'}}
        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
          expect(Promotions::BackfillChannel).to receive(:find).with('aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1').and_return(dummy_item)
          params = {
            id: 'aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1',
            promotions_backfill_channel: {
              user_id: 2,
              priority: 10,
              title: 'test_title',
              description_raw: 'test_description',
              image_url: 'test_image',
              language: 'en',
              active: true
            }
          }
          post action, :params => params
        end
        it_behaves_like 'it redirects the user and displays an error'
      end
    end
  end

  describe 'destroy' do
    describe 'permissions' do
      let(:action) { :destroy }
      let(:dummy_item) { Promotions::BackfillChannel.from_attributes(id: 'aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1', title: "title", description_raw: "description", priority: 1, image_url: "url", sponsored: false, active: false, user_id: 2, language: "en") }
      let(:expected_url) { '/admin/backfill_channels/aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1' }
      let(:hypeman_response) { double 'hypeman response' }
      let(:audit) { History::Audit.new(action: "delete", user_type: "ldap_user", user_id: "cool_ldap_login", resource_type: 'backfill_channel', resource_id: 'aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1', changes: [{:attribute => "user_id", :old_value => 2, :new_value => nil}, {:attribute => "login", :old_value => nil, :new_value => nil}, {:attribute => "priority", :old_value => 1, :new_value => nil}, {:attribute => "title", :old_value => "title", :new_value => nil}, {:attribute => "image_url", :old_value => "url", :new_value => nil}, {:attribute => "sponsored", :old_value => false, :new_value => nil}, {:attribute => "description_raw", :old_value => "description", :new_value => nil}, {:attribute => "language", :old_value => "en", :new_value => nil}, {:attribute => "active", :old_value => false, :new_value => nil}]) }

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

        before do
          expect(Promotions::BackfillChannel).to receive(:find).with('aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1').and_return(dummy_item)
          expect(Promotions::BackfillChannel).to receive(:delete).with(expected_url).and_return(hypeman_response)
          expect(hypeman_response).to receive(:success?).and_return(true).at_least(1)

          expect(History::AddAudit).to receive(:add).with(audit)
          post action, :params => {:id => 'aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1'}
        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
          expect(Promotions::BackfillChannel).to receive(:find).with('aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1').and_return(dummy_item)
          post action, :params => {:id => 'aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1'}
        end

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