require 'test_helper'

class PuppetclassesControllerTest < ActionController::TestCase
  include LookupKeysHelper
  def test_index
    get :index, {}, set_session_user
    assert_template 'index'
  end

  def test_new
    get :new, {}, set_session_user
    assert_template 'new'
  end

  def test_create_invalid
    Puppetclass.any_instance.stubs(:valid?).returns(false)
    post :create, {}, set_session_user
    assert_template 'new'
  end

  def test_create_valid
    Puppetclass.any_instance.stubs(:valid?).returns(true)
    post :create, {}, set_session_user
    assert_redirected_to puppetclasses_url
  end

  def test_edit
    get :edit, {:id => Puppetclass.first.to_param}, set_session_user
    assert_template 'edit'
  end

  def test_update_invalid
    Puppetclass.any_instance.stubs(:valid?).returns(false)
    put :update, {:id => Puppetclass.first.to_param}, set_session_user
    assert_template 'edit'
  end

  def test_update_valid
    Puppetclass.any_instance.stubs(:valid?).returns(true)
    put :update, {:id => Puppetclass.first.to_param}, set_session_user
    assert_redirected_to puppetclasses_url
  end

  def test_destroy
    puppetclass = Puppetclass.first
    delete :destroy, {:id => puppetclass.to_param}, set_session_user
    assert_redirected_to puppetclasses_url
    assert !Puppetclass.exists?(puppetclass.id)
  end

  def setup_user
    @request.session[:user] = users(:one).id
    users(:one).roles       = [Role.find_by_name('Anonymous'), Role.find_by_name('Viewer')]
  end

  test 'user with viewer rights should fail to edit a puppetclass' do
    setup_user
    get :edit, {:id => Puppetclass.first.to_param}, set_session_user.merge(:user => users(:one).id)
    assert_equal @response.status, 403
  end

  test 'user with viewer rights should succeed in viewing puppetclasses' do
    setup_user
    get :index, {}, set_session_user
    assert_response :success
  end

  test 'new db rows are not added to HostClass when POST to parameters' do
    host = hosts(:one)
    puppetclass = puppetclasses(:four)  #puppetclass to be added to host
    host_puppetclass_ids = host.puppetclass_ids
    assert_difference('HostClass.count', 0) do
      post :parameters, {:id => puppetclass.id, :host_id => host.id, :host => {:puppetclass_ids => (host_puppetclass_ids + [puppetclass.id])}}, set_session_user
    end
  end

  test 'new db rows are not added to HostgroupClass when POST to parameters' do
    hostgroup = hostgroups(:common)
    puppetclass = puppetclasses(:four)  #puppetclass to be added to hostgroup
    hostgroup_puppetclass_ids = hostgroup.puppetclass_ids
    assert_difference('HostgroupClass.count', 0) do
      post :parameters, {:id => puppetclass.id, :host_id => hostgroup.id, :hostgroup => {:puppetclass_ids => (hostgroup_puppetclass_ids + [puppetclass.id])}}, set_session_user
    end
  end

  # NOTES: for tests below testing ajax POST to method parameters
  # puppetclass(:two) has TWO overridable lookup keys:  1) special_info and 2) custom_class_param
  # special_info is a smart_variable that is added independant of environment
  # custom_class_param is a smart_class_param for production environment only AND is marked as :override => TRUE
  test 'puppetclass lookup keys are added to partial _class_paramters on EXISTING host form through ajax POST to parameters' do
    host = hosts(:one)
    puppetclass = puppetclasses(:two)
    post :parameters, {:id => puppetclass.id, :host_id => host.id, :host => host.attributes }, set_session_user
    assert_response :success
    lookup_keys_added = overridable_lookup_keys(puppetclass, host)
    assert_equal 2, lookup_keys_added.count
    assert lookup_keys_added.map(&:key).include?("special_info")
    assert lookup_keys_added.map(&:key).include?("custom_class_param")
  end

  test 'puppetclass smart class parameters are NOT added if environment does not match' do
    # below is the same test as above, except environment is changed from production to global_puppetmaster, so custom_class_param is NOT added
    host = hosts(:one)
    puppetclass = puppetclasses(:two)
    post :parameters, {:id => puppetclass.id, :host_id => host.id, :host => host.attributes.merge!('environment_id' => environments(:global_puppetmaster).id) }, set_session_user
    assert_response :success
    lookup_keys_added = overridable_lookup_keys(puppetclass, assigns(:obj))
    assert_equal 1, lookup_keys_added.count
    assert lookup_keys_added.map(&:key).include?("special_info")
    refute lookup_keys_added.map(&:key).include?("custom_class_param")
  end


  test 'puppetclass lookup keys are added to partial _class_paramters on EXISTING hostgroup form through ajax POST to parameters' do
    hostgroup = hostgroups(:common)
    puppetclass = puppetclasses(:two)
    # host_id is posted instead of hostgroup_id per host_edit.js#load_puppet_class_parameters
    post :parameters, {:id => puppetclass.id, :host_id => hostgroup.id, :hostgroup => hostgroup.attributes }, set_session_user
    assert_response :success
    lookup_keys_added = overridable_lookup_keys(puppetclass, hostgroup)
    assert_equal 2, lookup_keys_added.count
    assert lookup_keys_added.map(&:key).include?("special_info")
    assert lookup_keys_added.map(&:key).include?("custom_class_param")
  end

  test 'puppetclass lookup keys are added to partial _class_paramters on NEW host form through ajax POST to parameters' do
    host = Host::Managed.new(:name => "new_host", :environment_id => environments(:production).id)
    puppetclass = puppetclasses(:two)
    post :parameters, {:id => puppetclass.id, :host_id => 'null', :host => host.attributes }, set_session_user
    assert_response :success
    lookup_keys_added = overridable_lookup_keys(puppetclass, host)
    assert_equal 2, lookup_keys_added.count
    assert lookup_keys_added.map(&:key).include?("special_info")
    assert lookup_keys_added.map(&:key).include?("custom_class_param")
  end

  test 'puppetclass lookup keys are added to partial _class_paramters on NEW hostgroup form through ajax POST to parameters' do
    hostgroup = Hostgroup.new(:name => "new_hostgroup", :environment_id => environments(:production).id)
    puppetclass = puppetclasses(:two)
    # host_id is posted instead of hostgroup_id per host_edit.js#load_puppet_class_parameters
    post :parameters, {:id => puppetclass.id, :host_id => 'null', :hostgroup => hostgroup.attributes }, set_session_user
    assert_response :success
    lookup_keys_added = overridable_lookup_keys(puppetclass, hostgroup)
    assert_equal 2, lookup_keys_added.count
    assert lookup_keys_added.map(&:key).include?("special_info")
    assert lookup_keys_added.map(&:key).include?("custom_class_param")
  end

  test "sorting by environment name on the index screen should work" do
    setup_user
    get :index, {:order => "environment ASC"}, set_session_user
    assert_equal puppetclasses(:three), assigns(:puppetclasses).last
  end

  test "text filtering on the index screen should work" do
    setup_user
    get :index, {:search => "git"}, set_session_user
    assert_equal puppetclasses(:three), assigns(:puppetclasses).first
  end

  test "predicate filtering on the index screen should work" do
    setup_user
    get :index, {:search => "environment = testing"}, set_session_user
    assert_equal puppetclasses(:three), assigns(:puppetclasses).first
  end
end
