require 'rails_helper'

describe SmocaBuildController, :type => :controller do

  describe 'GET index' do

    it 'renders template' do
      get :index
      expect(response).to have_http_status(200)
      expect(response).to render_template(:index)
    end

    it 'returns Smoca builds' do
      FactoryGirl.create(:smoca_build, id: 1)
      FactoryGirl.create(:smoca_build, id: 2)

      get :index
      expect(assigns(:builds)).not_to be_empty
      expect(assigns(:paginated_builds)).not_to be_empty
    end

    describe 'sorting' do

      let(:developer) { 'foobar' }

      it 'by developer' do
        build1 = FactoryGirl.create(:smoca_build, id: 1, developer: developer)
        build2 = FactoryGirl.create(:smoca_build, id: 2, developer: 'notthatdeveloper')
        build3 = FactoryGirl.create(:smoca_build, id: 3, developer: developer)

        get :index, :developer => developer

        smoca_build = assigns(:paginated_builds)
        expect(smoca_build).to      include(build1)
        expect(smoca_build).not_to  include(build2)
        expect(smoca_build).to      include(build3)
      end

      it 'by result' do
        build1 = FactoryGirl.create(:smoca_build, id: 1, result: 'SUCCESS')
        build2 = FactoryGirl.create(:smoca_build, id: 2, result: 'FAILURE')
        build3 = FactoryGirl.create(:smoca_build, id: 3, result: 'SUCCESS')

        get :index, :result => 'SUCCESS'

        smoca_build = assigns(:paginated_builds)
        expect(smoca_build).to      include(build1)
        expect(smoca_build).not_to  include(build2)
        expect(smoca_build).to      include(build3)
      end

      describe 'time filter "start_date" && "end_date" parameters' do

        let(:inputted_start_date) { '2016-05-20' }
        let(:inputted_end_date) { '2016-05-25' }
        let(:tz) { 'UTC' }
        let(:start_time_suffix) { "00:00:00 #{tz}"} # Beginning of the day, including timezone
        let(:end_time_suffix) { "23:59:59 #{tz}" } # End of the day

        it 'defaults to a 1 month range when no parameters provided' do
          get :index
          todays_utc_date = Time.now.utc.to_date # Converts to a date based on UTC time.
          # Can't just use Date.today because that doesn't account for UTC timezone

          expect(assigns(:start_date)).to eq(Time.parse("#{todays_utc_date - 1.month} #{start_time_suffix}"))
          expect(assigns(:end_date)).to eq(Time.parse("#{todays_utc_date} #{end_time_suffix}"))
        end

        it 'uses date input when provided by user' do
          get :index, :date => {:start_date => inputted_start_date, :end_date => inputted_end_date}

          expect(assigns(:start_date)).to eq(Time.parse("#{inputted_start_date} #{start_time_suffix}"))
          expect(assigns(:end_date)).to eq(Time.parse("#{inputted_end_date} #{end_time_suffix}"))
        end

        it 'returns only users within the supplied time range' do
          build1 = FactoryGirl.create(:smoca_build, id: 1,
                                      initiated_at: Time.parse("#{inputted_start_date} #{start_time_suffix}"))
          build2 = FactoryGirl.create(:smoca_build, id: 2,
                                      initiated_at: Time.parse("#{inputted_end_date} #{end_time_suffix}"))

          # Bounds testing. Try +/- day, or +/- a second.
          build3 = FactoryGirl.create(:smoca_build, id: 3,
                                      initiated_at: Time.parse(
                                                                "#{inputted_start_date} #{start_time_suffix}") - 1.day)
          build4 = FactoryGirl.create(:smoca_build, id: 4,
                                      initiated_at: Time.parse(
                                                                "#{inputted_end_date} #{end_time_suffix}") + 1.day)

          build5 = FactoryGirl.create(:smoca_build, id: 5,
                                      initiated_at: Time.parse(
                                                                "#{inputted_start_date} #{start_time_suffix}") - 1.second)
          build6 = FactoryGirl.create(:smoca_build, id: 6,
                                      initiated_at: Time.parse(
                                                                "#{inputted_end_date} #{end_time_suffix}") + 1.second)

          get :index, :date => {:start_date => inputted_start_date, :end_date => inputted_end_date}

          builds = assigns(:paginated_builds)
          expect(builds).to include build1
          expect(builds).to include build2

          expect(builds).not_to include build3
          expect(builds).not_to include build4
          expect(builds).not_to include build5
          expect(builds).not_to include build6
        end

        it 'returns correct users by two search parameters (date and developer name)' do
          build1 = FactoryGirl.create(:smoca_build, id: 1, developer: developer,
                                      initiated_at: Time.parse("#{inputted_start_date} #{start_time_suffix}"))
          build2 = FactoryGirl.create(:smoca_build, id: 2, developer: 'nottherightdeveloper',
                                      initiated_at: Time.parse("#{inputted_start_date} #{start_time_suffix}"))

          get :index, :date => {:start_date => inputted_start_date, :end_date => inputted_end_date},
                      :developer => developer

          builds = assigns(:paginated_builds)
          expect(builds).to     include build1
          expect(builds).not_to include build2
        end

      end

    end
  end

  describe 'POST trigger_job' do

    it 'redirects to the record when successful' do
      allow_any_instance_of(SmocaBuildController).to receive(:initiate_jenkins_build).and_return({'location' => 'https://jenkins.internal.justin.tv/queue/item/4366/'})

      # Logging. This must be done before the message prints, because that makes total sense? </sarcasm>
      expect(Rails.logger).to receive(:debug).with(/Saved new SmocaBuild record: \d/)
      expect(Rails.logger).not_to receive(:error).with(/Encountered issue creating new SmocaBuild record. .*/)

      post :trigger_job, browser: 'Firefox', os: 'Linux', environment: 'clean-production', uid: 'foobar'

      record = assigns(:record)
      expect(response).to redirect_to smoca_build_path(record)
    end

    it 'redirects to home page when unsuccessful' do
      allow_any_instance_of(SmocaBuildController).to receive(:initiate_jenkins_build).and_return({'location' => 'https://jenkins.internal.justin.tv/queue/item/4366/'})
      allow_any_instance_of(SmocaBuild).to receive(:valid?).and_return(false)

      # Logging. This must be done before the message prints, because that makes total sense? </sarcasm>
      expect(Rails.logger).to receive(:error).with(/Encountered issue creating new SmocaBuild record. .*/)
      expect(Rails.logger).not_to receive(:debug).with(/Saved new SmocaBuild record: \d/)

      post :trigger_job, browser: 'Firefox', os: 'Linux', environment: 'clean-production', uid: 'foobar'

      expect(response).to redirect_to root_path
    end
  end
end
