require 'rails_helper'

feature 'User approving releasables' do
  shared_examples 'an approvable UI' do
    let(:current_user) { create(:user, :associate) }
    let(:project) { create(:project, members: current_user, account: current_user.primary_account) }

    before :each do
      sign_in current_user
    end

    shared_examples 'not authorized to review' do
      it 'does not show the review action' do
        visit polymorphic_path [project, subject.model_name.plural]
        click_on manage_button

        expect(page).not_to have_link(review_action, exact: true)
      end
    end

    scenario 'approval status is indicating by a checkmark' do
      approved_releasable = create("#{subject.model_name.singular}", approved_at: 1.day.ago, project: project)

      visit polymorphic_path [project, subject.model_name.plural]

      expect(page).not_to be_approved(subject)
      expect(page).not_to be_approved(approved_releasable)
    end

    context 'as an account manager' do
      let(:current_user) { create(:user, :account_manager) }

      scenario 'approving a release', js: true do
        visit polymorphic_path [project, subject.model_name.plural]

        click_on manage_button
        click_link review_action

        expect(page).to have_content review_page_heading(subject.model_name)
        expect(page).to have_content approve_button
        expect(page).to have_content signature_field

        click_on approve_button

        expect(page).not_to have_content approved_notice(subject.model_name)
        expect(page).to have_content 'is not attached'

        by 'adding signature' do
          draw_signature file_fixture('signature.png'), signature_data_field(subject.model_name)
          click_on approve_button

          expect(page).to have_content approved_notice(subject.model_name)
        end
      end

      scenario 'viewing the contract PDF for an unapproved release' do
        visit polymorphic_path [project, subject.model_name.plural]
        click_on 'Manage'
        click_link 'Download'

        expect(content_type).to eq('application/pdf')
        expect(content_disposition).to include('inline')
        expect(pdf_body).not_to have_content for_office_use_only
      end

      scenario 'viewing the contract PDF of an approved release' do
        approver = create(:user, email: 'big.doe@test.com', first_name: 'Big', last_name: 'Joe')
        subject.approve_by(approver)
        subject.save!

        visit polymorphic_path([subject, :contracts], format: 'pdf')

        expect(content_type).to eq('application/pdf')
        expect(content_disposition).to include('inline')
        expect(pdf_body).to have_content for_office_use_only.upcase
        expect(pdf_body).to have_content producer_label
        expect(pdf_body).to have_content production_label
        expect(pdf_body).to have_content issued_to_label
        expect(pdf_body).to have_content issued_by_label
        expect(pdf_body).to have_content date_issued
        expect(pdf_body).to have_content 'Big Joe'
      end
    end

    context 'as a manager' do
      let(:current_user) { create(:user, :manager) }

      include_examples 'not authorized to review'
    end

    context 'as an associate' do
      let(:current_user) { create(:user, :associate) }

      include_examples 'not authorized to review'
    end

    private

    def approve_button
      t 'approvals.new.actions.approve'
    end

    def approved_notice(model_name)
      t('approvals.create.release_approved', release_type: model_name.human)
    end

    def be_approved(releasable)
      releasable_dom_id = "##{releasable.model_name.singular}_#{releasable.id}"
      have_css("#{releasable_dom_id }i.fa.fa-check-circle.fa-2x", count: 1)
    end

    def manage_button
      'Manage'
    end

    def review_action
      'Review'
    end

    def review_page_heading(model_name)
      t 'approvals.new.heading', release_type: model_name.human.titleize
    end

    def signature_field
      'SIGNATURE'
    end

    def signature_data_field(model_name)
      "#{model_name.singular}_approved_by_user_signature[data]"
    end

    def for_office_use_only
      t('contracts.for_office_use_only.heading').upcase
    end

    def producer_label
      t 'contracts.for_office_use_only.description_labels.producer'
    end

    def production_label
      t 'contracts.for_office_use_only.description_labels.production'
    end

    def issued_to_label
      t 'contracts.for_office_use_only.description_labels.issued_to'
    end

    def issued_by_label
      t 'contracts.for_office_use_only.description_labels.issued_by'
    end

    def date_issued
      t 'contracts.for_office_use_only.description_labels.date_issued'
    end
  end

  context 'for an appearance release' do
    subject { create(:appearance_release_with_contract_template, :native, project: project) }
    it_behaves_like 'an approvable UI'
  end

  context 'for a talent release' do
    subject { create(:talent_release_with_contract_template, :native, project: project) }
    it_behaves_like 'an approvable UI'
  end

  context 'for a location release' do
    subject { create(:location_release_with_contract_template, :native, project: project) }
    it_behaves_like 'an approvable UI'
  end

  context 'for a material release' do
    subject { create(:material_release_with_contract_template, :native, project: project) }
    it_behaves_like 'an approvable UI'
  end

  context 'for a acquired media release' do
    subject { create(:acquired_media_release_with_contract_template, :native, project: project) }
    it_behaves_like 'an approvable UI'
  end

  context 'for a medical release' do
    subject { create(:medical_release_with_contract_template, :native, project: project) }
    it_behaves_like 'an approvable UI'
  end

  context 'for a misc release' do
    subject { create(:misc_release_with_contract_template, :native, project: project) }
    it_behaves_like 'an approvable UI'
  end
end
