#--
# 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 'password_controller'
require 'roles_controller'
require 'users_controller'

# Re-raise errors caught by the controllers.

class PasswordController; def rescue_action(e) raise e end; end
class RolesController;    def rescue_action(e) raise e end; end
class UsersController;    def rescue_action(e) raise e end; end

class RequestLoggingTest < Test::Unit::TestCase

  use_all_fixtures

  def setup
    @request    = ActionController::TestRequest.new
    @response   = ActionController::TestResponse.new
    assert_equal 0, RequestLogEntry.count
  end

  def with_log_entry
    assert_equal 1, RequestLogEntry.count
    yield( (RequestLogEntry.find :all).first )
  end

  def test_logs_login_get

    # Simple case --- no one logged in, just make sure we produce
    # a log entry and don't blow up.

    @controller = PasswordController.new
    get :login

    with_log_entry do |entry|
      assert_equal 'PasswordController', entry.controller
      assert_equal 'login',              entry.action
      assert_equal 'get',                entry.http_method
    end
  end

  def test_logs_logged_in_users_and_targets

    # Interesting case --- logged in, acting as another user;
    # check that we get user name and target logged.

    @controller = RolesController.new

    log_in_as users(:lucy), :acting_as => users(:ricky)

    put :update, :id => roles(:ricardo_admin).id,
      :role => { :name => 'generalissimo' }

    with_log_entry do |entry|

      assert_equal 'RolesController',        entry.controller
      assert_equal 'update',                 entry.action
      assert_equal 'put',                    entry.http_method
      assert_equal users(:lucy).id,          entry.user_of_record_id
      assert_equal users(:lucy).name,        entry.user_of_record_name
      assert_equal users(:ricky).id,         entry.acting_user_id
      assert_equal users(:ricky).name,       entry.acting_user_name
      assert_equal 'Role',                   entry.model_class
      assert_equal roles(:ricardo_admin).id, entry.model_id

      assert_equal 'generalissimo', roles(:ricardo_admin).reload.name

    end
  end

  def test_logs_pchecks

    # Interesting case --- logged in, acting as another user;
    # check that we get user name and target logged.

    @controller = UsersController.new

    log_in_as users(:lucy), :acting_as => users(:ricky)

    put :update, :id => users(:ricky).id, :user => { :locked_out => 'true' }

    with_log_entry do |entry|

      assert_equal 'UsersController', entry.controller
      assert_equal 'update',          entry.action
      assert_equal 'put',             entry.http_method
      assert_equal 'User',            entry.model_class
      assert_equal users(:ricky).id,  entry.model_id

      assert entry.pcheck_log_entries.to_a.detect { |pcheck|
        pcheck.model_class == 'User'           &&
        pcheck.privilege   == 'pw_administer'  &&
        pcheck.model_id    == users(:ricky).id &&
        pcheck.success?
      }

    end
  end

end

