Clone
require File.expand_path('../../test_helper', File.dirname(__FILE__))

class CmsPageTest < ActiveSupport::TestCase
  
  def test_fixtures_validity
    Cms::Page.all.each do |page|
      assert page.valid?, page.errors.full_messages.to_s
      assert_equal page.read_attribute(:content), page.content(true)
    end
  end
  
  def test_validations
    page = Cms::Page.new
    page.save
    assert page.invalid?
    assert_has_errors_on page, [:layout, :slug, :label]
  end
  
  def test_validation_of_parent_presence
    page = cms_sites(:default).pages.new(new_params)
    assert !page.parent
    assert page.valid?, page.errors.full_messages.to_s
    assert_equal cms_pages(:default), page.parent
  end
  
  def test_validation_of_parent_relationship
    page = cms_pages(:default)
    assert !page.parent
    page.parent = page
    assert page.invalid?
    assert_has_errors_on page, :parent_id
    page.parent = cms_pages(:child)
    assert page.invalid?
    assert_has_errors_on page, :parent_id
  end
  
  def test_validation_of_target_page
    page = cms_pages(:child)
    page.target_page = cms_pages(:default)
    page.save!
    assert_equal cms_pages(:default), page.target_page
    page.target_page = page
    assert page.invalid?
    assert_has_errors_on page, :target_page_id
  end
  
  def test_label_assignment
    page = cms_sites(:default).pages.new(
      :slug   => 'test',
      :parent => cms_pages(:default),
      :layout => cms_layouts(:default)
    )
    assert page.valid?
    assert_equal 'Test', page.label
  end
  
  def test_creation
    assert_difference ['Cms::Page.count', 'Cms::Block.count'] do
      page = cms_sites(:default).pages.create!(
        :label  => 'test',
        :slug   => 'test',
        :parent => cms_pages(:default),
        :layout => cms_layouts(:default),
        :blocks_attributes => [
          { :label    => 'default_page_text',
            :content  => 'test' }
        ]
      )
      assert page.is_published?
      assert_equal 1, page.position
    end
  end
  
  def test_initialization_of_full_path
    page = Cms::Page.new
    assert_equal '/', page.full_path
    
    page = Cms::Page.new(new_params)
    assert page.invalid?
    assert_has_errors_on page, :site_id
    
    page = cms_sites(:default).pages.new(new_params(:parent => cms_pages(:default)))
    assert page.valid?
    assert_equal '/test-page', page.full_path
    
    page = cms_sites(:default).pages.new(new_params(:parent => cms_pages(:child)))
    assert page.valid?
    assert_equal '/child-page/test-page', page.full_path
    
    Cms::Page.destroy_all
    page = cms_sites(:default).pages.new(new_params)
    assert page.valid?
    assert_equal '/', page.full_path
  end
  
  def test_sync_child_pages
    page = cms_pages(:child)
    page_1 = cms_sites(:default).pages.create!(new_params(:parent => page, :slug => 'test-page-1'))
    page_2 = cms_sites(:default).pages.create!(new_params(:parent => page, :slug => 'test-page-2'))
    page_3 = cms_sites(:default).pages.create!(new_params(:parent => page_2, :slug => 'test-page-3'))
    page_4 = cms_sites(:default).pages.create!(new_params(:parent => page_1, :slug => 'test-page-4'))
    assert_equal '/child-page/test-page-1', page_1.full_path
    assert_equal '/child-page/test-page-2', page_2.full_path
    assert_equal '/child-page/test-page-2/test-page-3', page_3.full_path
    assert_equal '/child-page/test-page-1/test-page-4', page_4.full_path
    
    page.update_attributes!(:slug => 'updated-page')
    assert_equal '/updated-page', page.full_path
    page_1.reload; page_2.reload; page_3.reload; page_4.reload
    assert_equal '/updated-page/test-page-1', page_1.full_path
    assert_equal '/updated-page/test-page-2', page_2.full_path
    assert_equal '/updated-page/test-page-2/test-page-3', page_3.full_path
    assert_equal '/updated-page/test-page-1/test-page-4', page_4.full_path
    
    page_2.update_attributes!(:parent => page_1)
    page_1.reload; page_2.reload; page_3.reload; page_4.reload
    assert_equal '/updated-page/test-page-1', page_1.full_path
    assert_equal '/updated-page/test-page-1/test-page-2', page_2.full_path
    assert_equal '/updated-page/test-page-1/test-page-2/test-page-3', page_3.full_path
    assert_equal '/updated-page/test-page-1/test-page-4', page_4.full_path
  end
  
  def test_children_count_updating
    page_1 = cms_pages(:default)
    page_2 = cms_pages(:child)
    assert_equal 1, page_1.children_count
    assert_equal 0, page_2.children_count
    
    page_3 = cms_sites(:default).pages.create!(new_params(:parent => page_2))
    page_1.reload; page_2.reload
    assert_equal 1, page_1.children_count
    assert_equal 1, page_2.children_count
    assert_equal 0, page_3.children_count
    
    page_3.update_attributes!(:parent => page_1)
    page_1.reload; page_2.reload
    assert_equal 2, page_1.children_count
    assert_equal 0, page_2.children_count
    
    page_3.destroy
    page_1.reload; page_2.reload
    assert_equal 1, page_1.children_count
    assert_equal 0, page_2.children_count
  end
  
  def test_cascading_destroy
    assert_difference 'Cms::Page.count', -2 do
      cms_pages(:default).destroy
    end
  end
  
  def test_options_for_select
    assert_equal ['Default Page', '. . Child Page'], 
      Cms::Page.options_for_select(cms_sites(:default)).collect{|t| t.first }
    assert_equal ['Default Page'], 
      Cms::Page.options_for_select(cms_sites(:default), cms_pages(:child)).collect{|t| t.first }
    assert_equal [], 
      Cms::Page.options_for_select(cms_sites(:default), cms_pages(:default))
    
    page = Cms::Page.new(new_params(:parent => cms_pages(:default)))
    assert_equal ['Default Page', '. . Child Page'],
      Cms::Page.options_for_select(cms_sites(:default), page).collect{|t| t.first }
  end
  
  def test_cms_blocks_attributes_accessor
    page = cms_pages(:default)
    assert_equal page.blocks.count, page.blocks_attributes.size
    assert_equal 'default_field_text', page.blocks_attributes.first[:label]
    assert_equal 'default_field_text_content', page.blocks_attributes.first[:content]
  end
  
  def test_content_caching
    page = cms_pages(:default)
    assert_equal page.read_attribute(:content), page.content
    assert_equal page.read_attribute(:content), page.content(true)
    
    page.update_attribute(:content, 'changed')
    assert_equal page.read_attribute(:content), page.content
    assert_equal page.read_attribute(:content), page.content(true)
    assert_not_equal 'changed', page.read_attribute(:content)
  end
  
  def test_scope_published
    assert_equal 2, Cms::Page.published.count
    cms_pages(:child).update_attribute(:is_published, false)
    assert_equal 1, Cms::Page.published.count
  end
  
  def test_root?
    assert cms_pages(:default).root?
    assert !cms_pages(:child).root?
  end
  
  def test_url
    assert_equal 'http://test.host/', cms_pages(:default).url
    assert_equal 'http://test.host/child-page', cms_pages(:child).url
  end
  
protected
  
  def new_params(options = {})
    {
      :label  => 'Test Page',
      :slug   => 'test-page',
      :layout => cms_layouts(:default)
    }.merge(options)
  end
end