require 'rails_helper'

RSpec.describe Promotions::ScheduledVodsController do

  include_context 'mocked permissions'

  let(:permission) { 'scheduled_vods' }

  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::ScheduledVod).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 }
      let(:dummy_item) { Promotions::ScheduledVod.from_attributes(id: "aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1", vod_id: 'somemd5', title: "title", description_raw: "description", priority: 1, image_url: "url", sponsored: false, user_id: "2", languages: ["en"], start_date:'2017-09-18T18:00:00Z', end_date: '2017-09-19T18:00:00Z') }

      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 with appropriate permissions an authorized user for cloning' do
        include_context 'an authorized user'

        let(:params) { {duplicate: "aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1"} }
        let(:hypeman_response) { double 'hypeman response' }

        before do
          expect(Promotions::ScheduledVod).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
          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) do
        audit_options = {
          action: "create",
          user_type: "ldap_user",
          user_id: "cool_ldap_login",
          resource_type: 'scheduled_vod',
          resource_id: "aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1",
          changes: [
            {
              attribute: "user_id",
              old_value: nil,
              new_value: 1
            },
            {
              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: "vod_id",
              old_value: nil,
              new_value: "somemd5"
            },
            {
              attribute: "description_raw",
              old_value: nil,
              new_value: "description"
            },
            {
              attribute: "languages",
              old_value: nil,
              new_value: ["en"]
            },
            {
              attribute: "start_date",
              old_value: nil,
              new_value: "2017-09-18 18:00:00Z"
            },
            {
              attribute: "end_date",
              old_value: nil,
              new_value: "2017-09-19 18:00:00Z"
            }
          ]
        }
        History::Audit.new(audit_options)
      end
      let(:expected_url) { '/admin/vods' }
      let(:expected_body) { '{"scheduled_vod":{"user_id":null,"login":"test_login","priority":1,"title":"title","image_url":"url","inserted_at":null,"updated_at":null,"sponsored":false,"vod_id":"somemd5","description_raw":"description","languages":["en"],"start_date":"2017-09-18 18:00:00Z","end_date":"2017-09-19 18:00:00Z"}}'}
      let(:expected_headers) { { 'Content-Type' => 'application/json' } }
      let(:hypeman_response) { double 'hypeman response' }
      let(:returned_obj) do
        {
          "scheduled_vod" => {
            "vod_id" => "somemd5",
            "user_id" => 1,
            "title" => "title 1",
            "start_date" => "2017-09-18T18:00:00Z",
            "sponsored" => false,
            "priority" => 1,
            "login" => "test",
            "languages" => "en",
            "image_url" => "url",
            "id" => "aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1",
            "end_date" => "2017-09-19T18:00:00Z",
            "description_rendered" => "<p>description</p>\n", "description_raw" => "description"
          }
        }
      end

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

        before do
          expect(Promotions::ScheduledVod).to receive(:post).with(expected_url, { body: expected_body, headers: expected_headers }).and_return(hypeman_response)
          expect(hypeman_response).to receive(:body).and_return(returned_obj).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_scheduled_vod: {vod_id:"somemd5", title: "title", description_raw: "description", priority: 1, image_url: "url", sponsored: false, start_date: "2017-09-18T18:00:00Z", end_date: "2017-09-19T18:00:00Z", languages: "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
          params = {
            promotions_scheduled_vod: {
              login: 'test',
              priority: 10,
              title: 'test_title',
              description_raw: 'test_description',
              image_url: 'test_image',
              languages: 'testlanguage',
              start_date: '2017-09-18T18:00:00Z',
              end_date: '2017-09-19T18:00:00Z',
              vod_id: 'somemd5'
            }
          }
          post action, :params => params
        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::ScheduledVod.new }
      params = {:id => 'aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1'}

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

        before do
          expect(Promotions::ScheduledVod).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::ScheduledVod).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::ScheduledVod.from_attributes(id: "aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1", vod_id: 'somemd5', title: "title", description_raw: "description", priority: 1, image_url: "url", sponsored: false, user_id: "2", languages: ["en"], start_date:'2017-09-18T18:00:00Z', end_date: '2017-09-19T18:00:00Z') }
      let(:expected_url) { '/admin/vods/aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1' }
      let(:expected_body) { '{"scheduled_vod":{"priority":4,"title":"new_title","image_url":"new_url","sponsored":false,"vod_id":"somemd5","description_raw":"description","languages":["en"],"start_date":"2017-09-18 18:00:00Z","end_date":"2017-09-19 18:00:00Z"}}'}
      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: 'scheduled_vod', resource_id: "aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1", changes: [{:attribute => "priority", :old_value => 1, :new_value => 4}, {:attribute => "title", :old_value => "title", :new_value => "new_title"}, {:attribute => "image_url", :old_value => "url", :new_value => "new_url"}]) }

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

        before do
          expect(Promotions::ScheduledVod).to receive(:find).with('aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1').and_return(dummy_item)
          expect(Promotions::ScheduledVod).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_scheduled_vod: {priority: 4, title: 'new_title', languages: 'en', image_url: 'new_url'}}
        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::ScheduledVod).to receive(:find).with('aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1').and_return(dummy_item)
          params = {
            id: 'aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1',
            promotions_scheduled_vod: {
              user_id: 2,
              priority: 4,
              title: 'test_title',
              description_raw: 'test_description',
              image_url: 'test_image',
              languages: 'en'
            }
          }
          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::ScheduledVod.from_attributes(vod_id: "somemd5", id:'aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1', title: "title", description_raw: "description", description_rendered: "<p>description</p>\n", priority: 1, image_url: "url", sponsored: false, start_date: "2017-09-19T18:00:00Z", end_date: "2017-09-20T18:00:00Z", user_id: 2, languages: ["en"]) }
      let(:expected_url) { '/admin/vods/aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1' }
      let(:hypeman_response) { double 'hypeman response' }
      let(:audit) do
        options = {
          action: "delete",
          user_type: "ldap_user",
          user_id: "cool_ldap_login",
          resource_type: 'scheduled_vod',
          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: "vod_id",
              old_value: "somemd5",
              new_value: nil
            },
            {
              attribute: "description_raw",
              old_value: "description",
              new_value: nil
            },
            {
              attribute: "languages",
              old_value: ["en"],
              new_value: nil
            },
            {
              attribute: "start_date",
              old_value: "2017-09-19 18:00:00Z",
              new_value: nil
            },
            {
              attribute: "end_date",
              old_value: "2017-09-20 18:00:00Z",
              new_value: nil
            }
          ]
        }
        History::Audit.new(options)
      end

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

        before do
          expect(Promotions::ScheduledVod).to receive(:find).with('aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee1').and_return(dummy_item)
          expect(Promotions::ScheduledVod).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::ScheduledVod).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
