require "rails_helper"

describe ContractTemplatePolicy do
  let(:user) { create(:user) }
  let(:project) { create(:project, account: user.primary_account) }
  let(:contract_template) { build(:contract_template, project: project) }
  let(:user_context) { build(:user_context, user: user, account: user.primary_account) }

  subject { described_class }

  context "for an associate" do
    let(:user) { create(:user, :associate) }

    permissions :create? do
      it { is_expected.not_to permit(user_context, :create) }
    end

    permissions :show? do
      it { is_expected.to permit(user_context, :show) }
    end

    permissions :destroy? do
      it { is_expected.not_to permit(user_context, contract_template) }

      context "when there are associated releases" do
        let(:contract_template) { create(:contract_template, appearance_releases: build_list(:appearance_release, 1)) }

        it { is_expected.not_to permit(user_context, contract_template) }
      end
    end
  end

  context "for a manager" do
    let(:user) { create(:user, :manager) }

    permissions :create? do
      it { is_expected.to permit(user_context, :create) }
    end

    permissions :show? do
      it { is_expected.to permit(user_context, :show) }
    end

    permissions :destroy? do
      it { is_expected.to permit(user_context, contract_template) }

      context "when there are associated releases" do
        let(:contract_template) { create(:contract_template, appearance_releases: build_list(:appearance_release, 1)) }

        it { is_expected.to permit(user_context, contract_template) }
      end
    end
  end

  context "for an account manager" do
    let(:user) { create(:user, :account_manager) }

    permissions :create? do
      it { is_expected.to permit(user_context, :create) }
    end

    permissions :show? do
      it { is_expected.to permit(user_context, :show) }
    end

    permissions :destroy? do
      it { is_expected.to permit(user_context, contract_template) }

      context "when there are associated releases" do
        let(:contract_template) { create(:contract_template, appearance_releases: build_list(:appearance_release, 1)) }

        it { is_expected.to permit(user_context, contract_template) }
      end
    end
  end

  permissions ".scope" do
    let!(:member_project) do
      create(:project_with_contract_template, name: "Member Project", members: user, account: account)
    end
    let!(:non_member_project) do
      create(:project_with_contract_template, name: "Non-Member Project", account: account)
    end
    let!(:outside_project) do
      create(:project_with_contract_template, name: "Outside Project", account: build(:account))
    end

    let(:account) { build(:account) }
    let(:user_context) { build(:user_context, user: user, account: account) }

    subject { Pundit.policy_scope!(user_context, ContractTemplate) }

    context "for an account manager" do
      let(:user) { create(:user, :account_manager, primary_account: account)}

      it { is_expected.to include(member_project.contract_templates.first) }
      it { is_expected.to include(non_member_project.contract_templates.first) }
      it { is_expected.not_to include(outside_project.contract_templates.first) }
    end

    context "for manager" do
      let(:user) { create(:user, :manager, primary_account: account) }

      it { is_expected.to include(member_project.contract_templates.first) }
      it { is_expected.not_to include(non_member_project.contract_templates.first) }
      it { is_expected.not_to include(outside_project.contract_templates.first) }
    end

    context "for associate" do
      let(:user) { create(:user, :associate, primary_account: account) }

      it { is_expected.to include(member_project.contract_templates.first) }
      it { is_expected.not_to include(non_member_project.contract_templates.first) }
      it { is_expected.not_to include(outside_project.contract_templates.first) }
    end
  end
end
