defmodule Towerops.Organizations.PolicyTest do
  use Towerops.DataCase

  alias Towerops.Organizations.Membership
  alias Towerops.Organizations.Policy

  describe "can?/3" do
    test "owner can do everything" do
      membership = %Membership{role: :owner}

      assert Policy.can?(membership, :delete, :organization) == true
      assert Policy.can?(membership, :edit, :organization) == true
      assert Policy.can?(membership, :manage, :members) == true
      assert Policy.can?(membership, :create, :site) == true
      assert Policy.can?(membership, :edit, :device) == true
      assert Policy.can?(membership, :view, :anything) == true
    end

    test "admin can do most things except delete organization" do
      membership = %Membership{role: :admin}

      assert Policy.can?(membership, :delete, :organization) == false
      assert Policy.can?(membership, :edit, :organization) == true
      assert Policy.can?(membership, :manage, :members) == true
      assert Policy.can?(membership, :create, :site) == true
      assert Policy.can?(membership, :edit, :device) == true
      assert Policy.can?(membership, :view, :anything) == true
    end

    test "member can create and edit sites/devices but not manage org" do
      membership = %Membership{role: :member}

      assert Policy.can?(membership, :view, :organization) == true
      assert Policy.can?(membership, :list, :organization) == true
      assert Policy.can?(membership, :delete, :organization) == false
      assert Policy.can?(membership, :create, :site) == true
      assert Policy.can?(membership, :edit, :site) == true
      assert Policy.can?(membership, :edit, :device) == true
      assert Policy.can?(membership, :view, :device) == true
      assert Policy.can?(membership, :delete, :site) == false
    end

    test "viewer can only view" do
      membership = %Membership{role: :viewer}

      assert Policy.can?(membership, :delete, :organization) == false
      assert Policy.can?(membership, :edit, :organization) == false
      assert Policy.can?(membership, :manage, :members) == false
      assert Policy.can?(membership, :create, :site) == false
      assert Policy.can?(membership, :edit, :device) == false
      assert Policy.can?(membership, :view, :site) == true
      assert Policy.can?(membership, :view, :device) == true
    end

    test "viewer can acknowledge alerts" do
      membership = %Membership{role: :viewer}

      assert Policy.can?(membership, :acknowledge, :alert) == true
    end

    test "viewer cannot perform other actions on alerts" do
      membership = %Membership{role: :viewer}

      assert Policy.can?(membership, :create, :alert) == false
      assert Policy.can?(membership, :edit, :alert) == false
      assert Policy.can?(membership, :delete, :alert) == false
    end

    test "nil membership cannot do anything" do
      assert Policy.can?(nil, :view, :organization) == false
      assert Policy.can?(nil, :edit, :site) == false
      assert Policy.can?(nil, :delete, :device) == false
    end

    test "member cannot manage memberships" do
      membership = %Membership{role: :member}

      assert Policy.can?(membership, :create, :membership) == false
      assert Policy.can?(membership, :edit, :membership) == false
    end

    test "member cannot manage invitations" do
      membership = %Membership{role: :member}

      assert Policy.can?(membership, :create, :invitation) == false
      assert Policy.can?(membership, :delete, :invitation) == false
    end

    test "member can list resources" do
      membership = %Membership{role: :member}

      assert Policy.can?(membership, :list, :site) == true
      assert Policy.can?(membership, :list, :device) == true
      assert Policy.can?(membership, :list, :alert) == true
    end

    test "member can create and view alerts" do
      membership = %Membership{role: :member}

      assert Policy.can?(membership, :create, :alert) == true
      assert Policy.can?(membership, :view, :alert) == true
      assert Policy.can?(membership, :edit, :alert) == true
    end

    test "viewer can list resources" do
      membership = %Membership{role: :viewer}

      assert Policy.can?(membership, :list, :site) == true
      assert Policy.can?(membership, :list, :device) == true
      assert Policy.can?(membership, :list, :alert) == true
      assert Policy.can?(membership, :list, :organization) == true
    end
  end
end
