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

class TopicsControllerTest < Test::Rails::ControllerTestCase

  fixtures :topics, :users, :settings, :support_materials, :readings, :comments
  
  def setup
    super
    login_as :laura
  end
  
  def test_show
    get :show, :id => 1
    assert_response :success # Assert we got a 200
        
    assert_assigned :topic
    assert_assigned :topic_comments     
    assert_assigned :most_read_comments 
    assert_assigned :highest_rated_comments 
  end  
  
  def test_experts_do_see_future_topics
    login_as :frank
    get :index
    
    assert_response :success # Assert we got a 200
        
    assert_assigned :topics
    assert assigns(:topics).include?(topics(:senate_reform)) # senate_reform is for the future
  end
  
  def test_admin_do_see_future_topics
    login_as :laura
    get :index

    assert assigns(:topics).include?(topics(:senate_reform))   
  end
  
  def test_guests_do_not_see_future_topics
    login_as :visitor1
    get :index

    assert !assigns(:topics).include?(topics(:senate_reform))    
  end
  
  def test_participants_do_not_see_future_topics
    login_as :quentin
    get :index

    assert !assigns(:topics).include?(topics(:senate_reform))   
  end
  
  def test_participant_cannot_see_future_topics
    login_as :ernest
    assert_raises(ActiveRecord::RecordNotFound) {
      get :show, :id => 3
    }
  end
  
  def test_participant_cannot_see_held_topics
    login_as :ernest
    assert_raises(ActiveRecord::RecordNotFound) {
      get :show, :id => 2
    }
  end
  
  def test_guest_cannot_see_future_topics
    login_as :visitor1
    assert_raises(ActiveRecord::RecordNotFound) {
      get :show, :id => 3
    }
  end
  
  def test_guest_cannot_see_held_topics
    login_as :visitor1 
    assert_raises(ActiveRecord::RecordNotFound) {
      get :show, :id => 2
    }
  end

  def test_guest_cannot_preview
    assert_requires_login(:visitor1) { get :preview, :id => 1}
  end

  def test_participant_cannot_preview
    assert_requires_login(:ernest) { get :preview}
  end
    
  # participants
  def test_participant_show_topic
    login_as :ernest # he's a participant
    get :show, :id => 1
    assert_response :success
  end
  
  # guests
  def test_guest_show_topic
    login_as :visitor1
    get :show, :id => 1
    assert_response :success
  end
  
  def test_valid_fixture_is_valid
    assert_valid Topic.new(valid_topic_data)
  end
  
  def test_current_user
    get :new
    assert assigns(:current_user)
  end
  
  def test_index_not_explosive
    assert_nothing_raised { get :index}
    assert_response :success
  end
  
  def test_index_lists_all_topics
    get :index
    assert assigns(:topics)
  end
  
  def test_index_lists_edit_links
    get :show, :id => 1
    assert_match( /edit/, @response.body)
  end
  
  def test_index_admins_get_approve_links
    @request.session[:user] = users(:thomas).id
    get :show, :id => topics(:senate_reform).id
    assert_response :success
    assert_match( /approve/, @response.body)
  end
  
  def test_index_experts_dont_get_approve_links
    login_as :frank
    get :show, :id => topics(:senate_reform).id
    assert_response :success
    assert_no_match( /approve/, @response.body)
  end
    
  # date conflict tests
  def test_create_on_taken_date_saves_but_adds_notice
    post :new, {:topic => topics(:senate_reform).attributes } 
  
    assert_response :redirect
    assert_equal "Another topic is already scheduled for that day", flash[:alert]
  end
  
  def test_edit_on_taken_date_saves_but_adds_notice
    topics(:direct_democracy).update_attribute(:start_date, topics(:senate_reform).start_date)
    post :edit, {:id => topics(:senate_reform).id, :topic => topics(:senate_reform).attributes.merge({'start_date' => topics(:direct_democracy).start_date})} # conflicts with direct_democracy
    assert_response :redirect
    assert_equal "Another topic is already scheduled for that day", flash[:alert]
  end
  
  def test_new_not_explosive
    assert_nothing_raised { get :new}
    assert_response :success
  end
  
  def test_new_assings_topic
    get :new
    assert assigns(:topic)
  end
  
  def test_create_new_topic_not_explosive
    assert_nothing_raised { 
      post :new
    }
  end
  
  def test_create_new_topic_renders_on_fail
    post :new
    assert_response :success # successful create redirects
  end
  
  def test_create_new_topic_success
    old_count = Topic.count
    post :new, { 'topic' => valid_topic_data }
    
    assert_equal old_count + 1, Topic.count, "new topic not saved"
  end
  
  def test_create_new_topic_has_current_user
    login_as :frank
    Topic.delete_all
    post :new, { 'topic' => valid_topic_data }
    
    assert_equal users(:frank), Topic.find(:first).expert
  end
  
  def test_create_new_topic_sets_flash
    post :new, { 'topic' => valid_topic_data }
    
    assert flash[:notice], "flash not found after creating new Topic"
  end
  
  def test_edit_not_explosive
    assert_nothing_raised { get :edit, :id => 1}
    assert_response :success
  end
  
  def test_edit_assings_topic
    get :edit, :id => 1
    assert assigns(:topic)
  end
  
  def test_post_edit_topic_not_explosive
    assert_nothing_raised { post :edit, :id => 1 }
  end
  
  def test_without_id_redirects
    get :edit
    assert_response :redirect
  end
  
  def test_post_edit_topic_renders_on_fail
    post :edit, {:id => 1, :topic => { :title => '' }} # should be illegal title length
    assert_response :success # successful create redirects
  end
  
  def test_post_edit_topic_success
    old_count = Topic.count
    post :edit, { :id => 1, 'topic' => valid_topic_data}
    
    assert_equal old_count, Topic.count, "new topic created"
  end
  
  def test_edit_topic_has_original_user
    @request.session['user'] = users(:laura).id # she's an admin
    post :edit, { :id => 1, 'topic' => valid_topic_data }
    
    assert_equal users(:frank).id, Topic.find(:first).expert.id, "topic expert changed durring edit"
  end
  
  def test_edit_topic_sets_flash
    post :edit, { :id => 1, 'topic' => valid_topic_data}
    
    assert flash[:notice], "flash not found after editing Topic"
  end
  
  
  # TopicsControllerApproveTest
  
  def test_approve_without_id_redirects
    login_as :laura
    get :approve
    assert_response :redirect
  end
  
  def test_approve_limited_to_admins
    login_as :laura
    @request.session[:user] = users(:frank).id # he's an expert
    get :approve, :id => 2    
    assert !Topic.find(2).approved?, "Expert should not have been able to approve a topic"
  end
  
  def test_approved_topic_is_approved
    login_as :laura
    get :approve, :id => 2    
    assert_response :redirect
    assert Topic.find(2).approved?, "topic not set to approved"
  end
  
  def test_approved_shows_notice
    login_as :laura
    get :approve, :id => 2    
    assert flash[:notice], "flash message missing"
  end
  
  
  # TopicsControllerHoldTest
   
  def test_hold_without_id_redirects
    login_as :laura
    get :hold
    assert_response :redirect
  end
  
  def test_editor_cannot_hold
    login_as :laura
    @request.session[:user] = users(:frank).id # he's an expert
    assert_no_difference(Topic.find(1), :approved?, "Expert should not be able to hold a topic") do
      get :hold, :id => 1
    end
  end
  
  def test_participant_cannot_hold
    login_as :laura
    @request.session[:user] = users(:ernest).id # # he's a participant
    assert_no_difference(Topic.find(1), :approved?, "Participant should not be able to hold a topic") do
       get :hold, :id => 1  
    end
  end
  
  def test_hold_topic_is_held
    login_as :laura
    get :hold, :id => 1    
    assert_response :redirect
    assert !Topic.find(1).approved?, "topic now being held"
  end
  
  def test_hold_shows_notice
    login_as :laura
    get :hold, :id => 2    
    assert flash[:notice], "flash message missing"
  end
  
  def test_rss
    login_as :visitor1
    get :rss
    assert assigns(:topics)
    assert_equal 1, assigns(:topics).length
  end
  
  def test_rss_should_not_create_session
    session[:user] = nil
    get :rss
    assert !session[:user], "User found in session #{session[:user]}"
  end
  
  def test_should_not_crash_on_update_with_invalid_date
    assert_nothing_raised { post :edit, :id=> 3, :topic => topic_with_invalid_start_date }     
  end
  
  def test_should_not_crash_on_create_with_invalid_date
    assert_nothing_raised { post :new, :topic => topic_with_invalid_start_date }         
  end
  
  def test_should_not_save_topic_with_invalid_date
    assert_no_difference Topic, :count do
      post :new, :topic => topic_with_invalid_start_date
    end
  end
  
  def test_topic_should_be_invalid_with_invalid_date
    post :new, :topic => topic_with_invalid_start_date
    assert_response :success
    assert assigns(:topic)
    assert !assigns(:topic).valid?
    assert assigns(:topic).errors.on("start_date")
  end
  
  def test_show_topic_with_no_comments_not_explosive
    newest_topic = Topic.new(valid_topic_data)
    newest_topic.save!
    assert_nothing_raised() { get :show, :id => newest_topic.id }
  end
  
  def valid_topic_data
      { 
        :title => 'Guilty Looks Enter Tree Beers',
        :introduction => 'Wants pawn term dare worsted ladle gull hoe hat search putty yowler coils debt pimple colder Guilty Looks. Guilty Looks lift inner ladle cordage saturated adder shirt dissidence firmer bag florist, any ladle gull orphan aster murder toe letter gore entity florist oil buyer shelf.', 
        :body_copy => %s{"Guilty Looks!" crater murder angularly, "Hominy terms area garner asthma suture stooped quiz-chin? Goiter door florist? Sordidly NUT!"

  "Wire nut, murder?" wined Guilty Looks, hoe dint peony tension tore murder's scaldings.

  "Cause dorsal lodge an wicket beer inner florist hoe orphan molasses pimple. Ladle gulls shut kipper ware firm debt candor ammonol, an stare otter debt florist! Debt florist's mush toe dentures furry ladle gull!"

  Wail, pimple oil-wares wander doe wart udder pimple dum wampum toe doe. Debt's jest hormone nurture. Wan moaning, Guilty Looks dissipater murder, an win entity florist.

  Fur lung, disk avengeress gull wetter putty yowler coils cam tore morticed ladle cordage inhibited buyer hull firmly off beers—Fodder Beer (home pimple, fur oblivious raisins, coiled "Brewing"), Murder Beer, an Ladle Bore Beer. Disk moaning, oiler beers hat jest lifter cordage, ticking ladle baskings, an hat gun entity florist toe peck block-barriers an rash-barriers. Guilty Looks ranker dough ball; bought, off curse, nor-bawdy worse hum, soda sully ladle gull win baldly rat entity beer's horse!

  Honor tipple inner darning rum, stud tree boils fuller sop—wan grade bag boiler sop, wan muddle-sash boil, an wan tawny ladle boil. Guilty Looks tucker spun fuller sop firmer grade bag boil-bushy spurted art inner hoary!

  "Arch!" crater gull, "Debt sop's toe hart—barns mar mouse!"}, 
        'start_date' => "2006-12-10",
        'expert_id'  => '3' # frank the expert
         }
  end
  
  def topic_with_invalid_start_date
    invalid_start_date = {
      "start_date(1i)"=>"2006", 
      "start_date(2i)"=>"11",
      "start_date(3i)"=>"31", # there is no Nov 31st
    }
    d = valid_topic_data
    d.delete('start_date')
    d.merge(invalid_start_date)    
  end
  
end