require 'test_helper'

class UserFeedAbilityTest < ActiveSupport::TestCase
  def setup
    @service = feeds(:service)
    @secret = feeds(:secret_announcements)
  end

  test "Anyone can read viewable feed" do
    ability = Ability.new(User.new)
    assert ability.can?(:read, @service)
  end

  test "Anyone cannot read nonviewable feed" do
    ability = Ability.new(User.new)
    assert ability.cannot?(:read, @secret)
  end

  test "Group member can read nonviewable feed" do
    ability = Ability.new(users(:katie))
    assert ability.can?(:read, @secret)
  end

  test "Non Group member cannot read nonviewable feed" do
    ability = Ability.new(users(:kristen))
    assert ability.cannot?(:read, @secret)
  end

  test "Only group leaders can delete / update feed" do
    ability = Ability.new(users(:katie))
    assert ability.can?(:update, @service)
    assert ability.can?(:delete, @service)
    assert ability.can?(:moderate, @service)

    ability = Ability.new(users(:kristen))
    assert ability.cannot?(:update, @service)
    assert ability.cannot?(:delete, @service)
    assert ability.cannot?(:moderate, @service)

    ability = Ability.new(User.new)
    assert ability.cannot?(:update, @service)
    assert ability.cannot?(:delete, @service)
    assert ability.cannot?(:moderate, @service)

    membership = memberships(:karen_wtg)
    membership.perms[:feed] = :all
    membership.save
    ability = Ability.new(users(:karen))
    assert ability.can?(:update, @service)
    assert ability.can?(:delete, @service)
    assert ability.can?(:moderate, @service)

    [:none, :submissions].each do |p|
      membership.perms[:feed] = p
      membership.save
      ability = Ability.new(users(:karen))
      assert ability.cannot?(:update, @service)
      assert ability.cannot?(:delete, @service)
      if p == :none
        assert ability.cannot?(:moderate, @service)
      elsif p == :submissions
        assert ability.can?(:moderate, @service)
      end
    end
  end

  test "Group leaders and some supporters can create feeds" do
    ability = Ability.new(users(:katie))
    assert ability.can?(:create, Feed)
    can_feed = Feed.new(:group_id => groups(:wtg).id)
    assert ability.can?(:create, can_feed)
    cannot_feed = Feed.new(:group_id => groups(:rpitv).id)
    assert ability.cannot?(:create, cannot_feed)

    membership = memberships(:karen_wtg)
    membership.perms[:feed] = :all
    membership.save
    ability = Ability.new(users(:karen))
    assert ability.can?(:create, Feed)
    assert ability.can?(:create, can_feed)
    assert ability.cannot?(:create, cannot_feed)

    [:none, :submissions].each do |p|
      membership.perms[:feed] = p
      membership.save
      ability = Ability.new(users(:karen))
      assert ability.cannot?(:create, Feed)
      assert ability.cannot?(:create, can_feed)
      assert ability.cannot?(:create, cannot_feed)
    end
  end

  test "Admin can read all feeds" do
    ability = Ability.new(users(:admin))
    assert ability.can?(:create, Feed)
    assert ability.can?(:read, Feed)
    assert ability.can?(:submit_content, Feed)
    assert ability.can?(:update, Feed)
    assert ability.can?(:destroy, Feed)
  end

  test "Users have feed submit permission if and only if the have submission creation permission" do
    User.find_each do |user|
      ability = Ability.new(user)
      Feed.find_each do |feed|
        assert_equal ability.can?(:create, Submission.new(:feed => feed)), ability.can?(:submit_content, feed)
      end
    end
  end

  test "Feed update permission implies feed show permission" do
    User.find_each do |user|
      ability = Ability.new(user)
      Feed.find_each do |feed|
        assert ability.cannot?(:update, feed) || ability.can?(:show, feed), "Feed update permission does not imply show permission for user '#{user.email}' and feed '#{feed.name}' (Can update? #{ability.can?(:update, feed)}, Can index? #{ability.can?(:show, feed)})"
      end
    end
  end

  test "Feed show permission implies feed index permission" do
    User.find_each do |user|
      ability = Ability.new(user)
      Feed.find_each do |feed|
        assert ability.cannot?(:show, feed) || ability.can?(:index, feed), "Feed show permission does not imply index permission for user '#{user.email}' and feed '#{feed.name}' (Can show? #{ability.can?(:show, feed)}, Can index? #{ability.can?(:index, feed)})"
      end
    end
  end

  test "Feed update permission implies feed index permission" do
    User.find_each do |user|
      ability = Ability.new(user)
      Feed.find_each do |feed|
        assert ability.cannot?(:update, feed) || ability.can?(:index, feed), "Feed update permission does not imply index permission for user '#{user.email}' and feed '#{feed.name}' (Can update? #{ability.can?(:update, feed)}, Can index? #{ability.can?(:index, feed)})"
      end
    end
  end


end

