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

#--######################################################################
# Copyright (c) 2006 Logica
# 
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
# 
# Onno van der Straaten:: initial implementation
#++######################################################################
# {Copyright (c) 2006 Logica}[link:files/COPYRIGHT.html]

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

class UsersControllerTest < Test::Unit::TestCase
  fixtures :users
  
  def setup
    logger.debug "Test Case: #{name}"
    @andy = users(:andy) # admin
    @george = users(:george) #cadmin
    @tony = users(:tony) #user
    @cash = users(:cash) #user
    @controller = UsersController.new
    @request    = ActionController::TestRequest.new
    @response   = ActionController::TestResponse.new
    @emails = ActionMailer::Base::deliveries
    @emails.clear        
  end
  
  def test_list
    get :list
    assert_tologin
    get :index
    assert_tologin
  end
  
  def test_list_cadmin
    # get the central admin
    get :list
    session['user'] = @george
    get :list
    assert_not_nil assigns(:users)
    assert_not_nil assigns(:admins)
    assert_not_nil assigns(:cadmin)     
  end
  
  def test_list_admin
    get :index
    session['user'] = @andy
    get :list
    assert_not_nil assigns(:users)
    assert_not_nil assigns(:admins)
    assert_not_nil assigns(:cadmin)     
  end
  
  # Shows:
  # 1. Only admins can request users list
  # 2. User cannot access account details
  def test_list_normaluser
    # 1
    get :list
    session['user'] = @tony
    get :list
    assert_unot_admin_message
    # 2
    post :account, :id => 1
    assert_equal session['user'], assigns(:user)
    assert_equal LoginController::FLASH_UNOT_ADMIN, flash['notice']
  end
  
  # Shows:
  # 1. user can edit his details
  # 2. user cannot edit another users details
  # 3. admin cannot edit another users details
  # 4. cadmin can edit another users details
  def test_edit
    # 1
    get :index
    session['user'] = @tony
    saved_name = @tony.name
    post :edit, :id => @tony.id, :user => {:name => 'test06_edit'}
    assert_response :success
    @tony.reload
    assert_equal 'test06_edit', @tony.name
    @tony.name = saved_name
    @tony.save!
    # 2
    session['user'] = @cash
    post :edit, :id => @tony.id, :user => {:name => 'test06_edit'}
    assert_response :success
    @tony.reload
    assert_equal saved_name, @tony.name # unchanged
    # 3
    session['user'] = @andy
    post :edit, :id => @tony.id, :user => {:name => 'test06_edit'}
    assert_response :success
    @tony.reload
    assert_equal saved_name, @tony.name # unchanged
    # 4
    session['user'] = @george
    post :edit, :id => @tony.id, :user => {:name => 'test06_edit'}
    assert_response :success
    @tony.reload
    assert_equal 'test06_edit', @tony.name # changed
    @tony.name = saved_name
    @tony.save!
  end
  
  def test_send_report
    get :index
    session['user'] = @cash
    post    :send_report, :type => 'M'
    assert_equal UsersController::FLASH_REPORT_SENT, flash['success']
    assert_redirected_to :action => 'account', :id => @cash.id
    assert_equal(1, @emails.size)
    email = @emails.first
    assert email.subject.index('Monthly')
    assert_equal("cash.oshman@epf.eclipse.org", email.bcc[0])
    assert_equal([ENV['EPFWIKI_REPLY_ADDRESS']], email.from)
    post    :send_report, :type => 'D'
    assert_equal UsersController::FLASH_REPORT_SENT, flash['success']
    post    :send_report, :type => 'W'
    assert_equal UsersController::FLASH_REPORT_SENT, flash['success']
  end

  # Show:
  # 1. User can access details 
  # 2. Cadmin is shown links 'list'
  # 3. User with data (comments, pages, uploads)
  def test_show
    get :index
    # 1
    session['user'] = @tony
    get :show, :id => @tony.id
    assert_response :success
    assert_template 'show'
    assert_not_nil assigns(:user)
    assert_not_nil assigns(:versions)
    assert_not_nil assigns(:comments)
    assert_not_nil assigns(:uploads)
    assert_not_nil assigns(:pages)    
    assert_equal @tony.id, assigns(:user).id
    # 2
    session['user'] = @george
    get :show, :id => @tony.id
    assert_equal @tony.id, assigns(:user).id # cadmin sees details of user
    assert_tag :tag => 'a', :attributes => {:href => '/users/list'}    
    assert_tag :tag => 'a', :attributes => {:href => '/sites/list'}        
    # 3
    create_templates
    p = WikiPage.find(:first)
    create_some_data(p)    
    get :show, :id => @andy.id
  end

  def test_edit_user
    get :list
    session['user'] = @tony
    post :edit, :id => session['user'].id, :user => { :name => 'Tony Renamed'}
    assert_response :success
    assert_template 'edit'    
    assert_not_nil assigns(:user)
    assert_equal User.find(assigns(:user).id).name, 'Tony Renamed' 
  end
  
  # Shows:
  # 1. George is central admin, Tony an ordinary user
  # 2. list of users contains links to make other admins the cadmin, and links to make other users admins
  # 3. George can make another Tony the central admin
  # 4. George can make another user cadmin after making Tony the central admin (untill his session expires) 
  # 5. Tony can make another user the cadmin after becoming central admin
  # 6. This is all one transaction (we cannot end up with having no cadmin)
  def test_cadmin
    # 1
    assert @george.cadmin?
    assert @tony.user?
    # 2
    get :list    
    session['user'] = @george
    get :list
    assert_response :success
    assert_template 'list'
    User.find_all_by_admin('Y').each do |user|
      assert_tag :tag => 'a', :attributes => {:href => "/users/cadmin/#{user.id}"}     
      assert_tag :tag => 'a', :attributes => {:href => "/users/admin/#{user.id}?admin=N"}           
    end
    User.find_all_by_admin('N').each do |user|
      assert_tag :tag => 'a', :attributes => {:href => "/users/admin/#{user.id}?admin=Y"}     
    end
    # 3
    assert_not_nil @george
    assert_not_nil @tony
    get :list
    post :cadmin, :id => @tony.id
    assert_redirected_to :action => 'list'
    assert_equal '', assigns(:cadmin).errors.full_messages.join(", ")        
    assert_equal '', assigns(:user).errors.full_messages.join(", ")
    @george.reload
    @tony.reload
    assert !@george.cadmin?
    assert @george.admin?
    assert @tony.cadmin?
    # 4
    post :cadmin, :id => @tony.id
    assert_unot_cadmin_message
    # 5
    session['user'] = @tony
    post :cadmin, :id => @george.id
    assert_redirected_to :action => 'list'
    @george.reload
    @tony.reload
    assert @george.cadmin?
    assert @george.admin?
    assert !@tony.cadmin?
    assert @tony.admin?
    # 6
    @george.name = nil # will cause save of this user to fail
    User.cadmin(@george, @tony)
    @george.reload
    @tony.reload
    assert @george.cadmin?
    assert @george.admin?
    assert !@tony.cadmin?
    assert @tony.admin?
    assert !@george.name.nil?
  end

  def test_account
    # TODO implement test
    #assert_tag :tag => 'a', :attributes => {:href => "/users/edit/#{@tony.id.to_s}"}
    #assert_tag :tag => 'a', :attributes => {:href => '/login/change_password'}

  end

end
