#--
# Copyright (c) 2007 Robert S. Thau, Smartleaf, Inc.
# 
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# 
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
require File.dirname(__FILE__) + '/../test_helper'
require File.dirname(__FILE__) + '/rest_test_boilerplate'
require 'users_controller'

# Re-raise errors caught by the controller.
class UsersController; def rescue_action(e) raise e end; end

class UsersControllerTest < Test::Unit::TestCase

  use_all_fixtures
  self.use_transactional_fixtures = false

  def controller_class; UsersController;   end
  def model_class;      User;              end
  def ids_for_update;   [users(:lucy).id]; end

  def resource_create_inputs
    return { :name       => 'littlericky',
             :full_name  => 'Ricky Ricardo, Jr.',
             :locked_out => 'false',
             :password   => '',
             :password_confirmation => '',
             :owner_firm_id => firms(:ricardo).id.to_s }
  end

  def resource_edit_inputs
    return { :locked_out => 'false',
             :password   => '',
             :password_confirmation => '' }
  end

  include RestTestBoilerplate

  def setup
    super
    log_in_as users(:ricky)
  end

  def test_index_assigns
    logged_in_as users(:lucy) do

      get :index
      assert_response :success
      assert_template 'index'
      assert_equal [], assigns(:users)

      User.as( users( :universal_grant_guy )) do
        users(:lucy).role_assignments.create! :role => roles(:ricardo_admin)
      end

      ricardos = User.find_all_by_owner_firm_id( firms(:ricardo) )

      get :index
      assert_response :success
      assert_template 'index'
      assert_equal ricardos.sort_by(&:id), assigns(:users).sort_by(&:id)
      
    end
  end

  def test_post_create_frills

      post :create, 
        :user => { :name       => 'littlericky',
                   :full_name  => 'Ricky Ricardo, Jr.',
                   :locked_out => 'true',
                   :password   => 'havana23',
                   :password_confirmation => 'havana23' },
        :firm_id => firms(:ricardo).id.to_s,
        :new_role_id => roles(:ricardo_twiddler).id.to_s

      new_user = User.find_by_name('littlericky')
      assert_not_nil new_user

      assert_redirected_to :action => 'show', :id => new_user.id

      assert_equal firms(:ricardo),            new_user.firm
      assert_equal 'Ricky Ricardo, Jr.',       new_user.full_name
      assert new_user.has_password?( 'havana23' )
      assert new_user.locked_out?

  end

  def test_post_create_bad
    logged_in_as( users( :ricky )) do

      old_user_count = User.count

      post :create, 
        :user => { :name       => 'littlericky',
                   :full_name  => 'Ricky Ricardo, Jr.',
                   :locked_out => 'true',
                   :password   => 'havana23',
                   :password_confirmation => '' },
        :firm_id => firms(:ricardo).id.to_s,
        :new_role_id => roles(:ricardo_twiddler).id.to_s

      assert_response :success
      assert_template 'new'
      assert_equal    old_user_count, User.count
      assert_nil      User.find_by_name('littlericky')

      assert_equal 'littlericky', assigns(:user).name

    end
  end

  def test_post_create_permerrs

      old_user_count = User.count

      assert_raises( PermissionFailure ) do
        post :create, 
          :user => { :name       => 'littlericky',
                     :full_name  => 'Ricky Ricardo, Jr.',
                     :locked_out => 'true',
                     :owner_firm_id => firms(:mertz).id.to_s }
      end

      # With transactional fixtures, the following spuriously fail:

      assert_nil      User.find_by_name('littlericky')
      assert_equal    old_user_count, User.count

  end

  def test_show_permerr
    logged_in_as( users( :ricky )) do
      assert_raises( PermissionFailure ) do
        get :show, :id => users(:fred)
      end
    end
  end

  def test_get_acting_as_user

    log_in_as users( :ricky )
    get :acting_as_user
    assert_equal [users(:ricky)], assigns(:users)

    log_in_as users( :fred )
    get :acting_as_user
    assert_equal [users(:ethel), users(:fred)], assigns(:users)
    assert_tag :tag => 'input', 
               :attributes => { :value => users(:fred).id.to_s,
                                :checked => 'checked' }

    log_in_as users( :fred ), :acting_as => users( :ethel )
    get :acting_as_user
    assert_equal [users(:ethel), users(:fred)], assigns(:users)
    assert_tag :tag => 'input', 
               :attributes => { :value => users(:ethel).id.to_s,
                                :checked => 'checked' }
    assert_no_tag :tag => 'input', 
                  :attributes => { :value => users(:fred).id.to_s,
                                   :checked => 'checked' }

  end

  def test_post_acting_as_user_good

    log_in_as users( :fred )
    post :acting_as_user, :user_id => users(:ethel).id
    assert_redirected_to :action => 'acting_as_user'
    assert_equal users(:fred).id, session[:user_of_record_id]
    assert_equal users(:ethel).id, session[:current_user_id]

  end

  def test_post_acting_as_user_bad
    log_in_as users( :fred )
    assert_raises( PermissionFailure ) do
      post :acting_as_user,
           :user_id => users(:lucy).id.to_s
    end
  end

  def test_should_destroy
    # no it shouldn't
  end

end

