require File.dirname(__FILE__) + '/../test_helper'

class TopicTest < Test::Rails::TestCase
  fixtures :topics, :users, :comments, :ratings

  def test_fixture
    assert_kind_of Topic, topics(:direct_democracy)
  end
  
  def test_author
    assert_kind_of User, topics(:direct_democracy).expert
    assert_equal 'Frank', topics(:direct_democracy).expert.name
  end
  
  def test__start_date_required
    assert_invalid(topics(:direct_democracy), :start_date, [nil, ''])
  end
  
  def test_expert_required
    topic_with_no_expert =  Topic.new
    assert !topic_with_no_expert.save
    assert topic_with_no_expert.errors.on('expert')
  end
  
  def test_expert_must_be_valid
    topic_with_no_expert =  Topic.new(:expert_id => 999999)
    assert !topic_with_no_expert.save
    assert topic_with_no_expert.errors.on('expert')
  end
  
  def test_new_topics_not_approved
    t = Topic.new(topics(:direct_democracy).attributes)
    assert t.save
    assert !t.approved?
  end
  
  def test_topics_have_comments
    create_fixtures :comments
    assert topics(:direct_democracy).comments
    assert_equal 4, topics(:direct_democracy).comments.count
  end
  
  def test_commentable_eh
    assert topics(:direct_democracy).commentable?
    assert !topics(:senate_reform).commentable? # in the past, but being held
    assert !topics(:guilty_looks).commentable?  # approved, but still in the future
  end
  
  def test_yesterday_is_not_the_future
    assert !Topic.new(:start_date => 1.day.ago.to_date).for_future?
  end
  
  def test_today_is_not_the_future
    assert !Topic.new(:start_date => Date.today).for_future?
  end
  
  def test_tommorow_is_the_future
    assert Topic.new(:start_date => 1.day.from_now.to_date).for_future?    
  end
  
  def test_topic_comments_word_total
    assert_equal 9, topics(:direct_democracy).comments.total_words
  end

  def test_reduce_to_best_rated
    best = Topic::reduce_to_best_rated(Topic.find([1,2,3])) # 2 has no ratings
    assert_equal topics(:direct_democracy).id, best.id
  end
  
  # poor approximation of test matrix
  [
    ['normal',      lambda {}],
    ['no_comments', lambda {Comment.delete_all}],
    ['no_ratings',  lambda {AbstractRating.delete_all}],
  ].each do | situation, setup_action|

    # comment methods not explosive
    %w{most_recent thread_starters find_three_best_avg_rating find_most_replied find_most_read}.each do |comment_method|
      define_method("test_topic_comments_#{comment_method}_not_exlosive_when_#{situation}") do
        setup_action.call
        assert_nothing_raised { topics(:direct_democracy).comments.send(comment_method)}
      end
    end

    # comment_ratings not explosive
    %w{find_most_rated_subject find_most_rated_subject}.each do |comment_method|
      define_method("test_topic_comment_ratings_#{comment_method}_not_exlosive_when_#{situation}") do
        setup_action.call
        assert_nothing_raised { topics(:direct_democracy).comment_ratings.send(comment_method)}
      end      
    end

  end
  
  def test_topic_comments_find_three_most_read_comments
    assert_equal comments(:day_old_reply), topics(:direct_democracy).comments.find_three_most_read.first
  end
  
  def test_topic_comments_find_three_best_avg_rating_comments
    assert_equal comments(:second_reply), topics(:direct_democracy).comments.find_three_best_avg_rating.first
  end
  
  def test_topic_comment_ratings__most_rated_subject
    assert_equal comments(:day_old_reply), topics(:direct_democracy).comment_ratings.find_most_rated_subject
  end 
  
  def test_topic_comment_ratings__best_average_rated_subject
    assert_equal comments(:day_old_reply), topics(:direct_democracy).comment_ratings.find_best_average_rated_subject
  end
  
  # def test_topic_comment_find_most_replied
  #   assert_nothing_raised { topics(:direct_democracy).comments.find_most_replied}
  # end
  # 
  # def test_topic_comment_find_most_read
  #   assert_nothing_raised { topics(:direct_democracy).comments.find_most_read}
  # end
  
  def test_report
    assert_nothing_raised() { Topic::report }
  end
  
  def test_make_private_bang
    t = topics(:direct_democracy)
    t.make_private!
    assert t.private?
  end
  
  def test_make_private_bang_privatizes_comments
    t = topics(:direct_democracy)
    t.make_private!
    assert t.comments.all?(&:private?)
  end
  
  def test_make_public_bang
    t = topics(:fourth)
    t.make_public!
    assert !t.private?
  end
  
  def test_make_public_bang_publicizes_comments
    t = topics(:fourth)
    t.make_public!
    assert !t.comments.any?(&:private?)
  end
end


# class TopicSearchTest < Test::Rails::TestCase
#   fixtures :topics, :search_terms, :search_terms_topics
#   
#   def test_find_using_term_not_explosive
#     assert_nothing_raised() { Topic.find_using_term('radish') }
#   end
#   
#   def test_find_using_term_finds_topics
#     assert_equal(2, Topic.find_using_term('inTopic1and3').length)
#   end
#   
#   def test_find_using_term_matches_multiple_terms
#     assert_equal(1, Topic.find_using_term('inTopic1').length)
#   end
# end