# frozen_string_literal: true

require “rails_helper”

RSpec.describe UserPolicy, type: :policy do

subject { described_class.new(user, user_record) }

<%- if auth0? -%>

let(:resolved_scope) { described_class::Scope.new(user, []).resolve }

<%- else -%>

let(:resolved_scope) { described_class::Scope.new(user, User.all).resolve }

<%- end -%>

let(:user_record) do

<%- if auth0? -%>

build(:user, uid: 123)

<%- else -%>

build_stubbed(:user).tap do |record|
  allow(record).to receive(:id).and_return(123)
end

<%- end -%>

end

context "as a guest" do
  let(:user) { nil }

  it { is_expected.to forbid_action(:index) }
  it { is_expected.to forbid_action(:show) }
  it { is_expected.to forbid_actions(%i[new create]) }
  it { is_expected.to forbid_actions(%i[edit update]) }
  it { is_expected.to forbid_action(:destroy) }

<%- if auth0? -%>

it "raises a Pundit::NotDefinedError" do
  expect { resolved_scope }.to raise_error(Pundit::NotDefinedError)
end

<%- else -%>

it "returns no items in scope" do
  expect(resolved_scope.to_sql).to eq(User.none.to_sql)
end

<%- end -%>

end

context "as the same user" do
  let(:user) { user_record }

  it { is_expected.to permit_actions(%i[edit update]) }
  it { is_expected.to permit_action(:destroy) }

  it { is_expected.to forbid_action(:index) }
  it { is_expected.to forbid_action(:show) }
  it { is_expected.to forbid_actions(%i[new create]) }

  it { is_expected.to permit_mass_assignment_of(:name).for_action(:update) }

<%- if auth0? -%>

it "raises a Pundit::NotDefinedError" do
  expect { resolved_scope }.to raise_error(Pundit::NotDefinedError)
end

<%- else -%>

it "returns the a scope with only the user" do
  expect(resolved_scope.to_sql).to eq(User.where(id: user.id).to_sql)
end

<%- end -%>

context "as a user with admin persmission" do

<%- if auth0? -%>

let(:user) { build(:user, :admin, uid: 123) }

<%- else -%>

     before do
       user.admin = true
     end
<%- end -%>

     it { is_expected.to permit_actions(%i[edit update]) }

     it { is_expected.to forbid_action(:index) }
     it { is_expected.to forbid_action(:show) }
     it { is_expected.to forbid_actions(%i[new create]) }
     it { is_expected.to forbid_action(:destroy) }

     it { is_expected.to permit_mass_assignment_of(:name).for_action(:update) }

<%- if auth0? -%>

it "raises a Pundit::NotDefinedError" do
  expect { resolved_scope }.to raise_error(Pundit::NotDefinedError)
end

<%- else -%>

it "returns the a scope with only the user" do
  expect(resolved_scope.to_sql).to eq(User.where(id: user.id).to_sql)
end

<%- end -%>

  end
end

context "with a different user" do
  let(:user) do

<%- if auth0? -%>

    build(:user, uid: 987)
<%- else -%>
    build_stubbed(:user).tap do |record|
      allow(record).to receive(:id).and_return(987)
    end
<%- end -%>
  end

  it { is_expected.to forbid_action(:index) }
  it { is_expected.to forbid_action(:show) }
  it { is_expected.to forbid_actions(%i[new create]) }
  it { is_expected.to forbid_actions(%i[edit update]) }
  it { is_expected.to forbid_action(:destroy) }

  it { is_expected.to forbid_mass_assignment_of(:name).for_action(:update) }

  context "when the user is an admin" do

<%- if auth0? -%>

let(:user) { build(:user, :admin, uid: 987) }

<%- else -%>

     before do
       user.admin = true
     end
<%- end -%>

     it { is_expected.to forbid_action(:index) }
     it { is_expected.to forbid_action(:show) }
     it { is_expected.to forbid_actions(%i[new create]) }
     it { is_expected.to forbid_actions(%i[edit update]) }
     it { is_expected.to forbid_action(:destroy) }

     it { is_expected.to forbid_mass_assignment_of(:name).for_action(:update) }
   end
 end

end