2010-11-08 17:42:14 +00:00
|
|
|
# coding: utf-8
|
|
|
|
|
2010-04-25 00:33:38 +00:00
|
|
|
require 'spec_helper'
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2011-11-20 11:47:41 +00:00
|
|
|
describe Locomotive::Page do
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-05-10 22:39:52 +00:00
|
|
|
before(:each) do
|
2011-11-24 13:37:17 +00:00
|
|
|
Locomotive::Site.any_instance.stubs(:create_default_pages!).returns(true)
|
|
|
|
Locomotive::Page.any_instance.stubs(:set_default_raw_template).returns(true)
|
2010-05-10 22:39:52 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-04-25 00:33:38 +00:00
|
|
|
it 'should have a valid factory' do
|
2011-08-25 21:28:56 +00:00
|
|
|
FactoryGirl.build(:page).should be_valid
|
2010-04-25 00:33:38 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2012-02-16 21:07:00 +00:00
|
|
|
describe 'validation' do
|
|
|
|
|
|
|
|
%w{site title}.each do |field|
|
|
|
|
it "requires the presence of the #{field}" do
|
|
|
|
page = FactoryGirl.build(:page, field.to_sym => nil)
|
|
|
|
page.should_not be_valid
|
|
|
|
page.errors[field.to_sym].should == ["can't be blank"]
|
|
|
|
end
|
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2012-02-16 21:07:00 +00:00
|
|
|
it 'requires the presence of the slug' do
|
|
|
|
page = FactoryGirl.build(:page, :title => nil, :slug => nil)
|
2010-04-25 00:33:38 +00:00
|
|
|
page.should_not be_valid
|
2012-02-16 21:07:00 +00:00
|
|
|
page.errors[:slug].should == ["can't be blank"]
|
2010-04-25 00:33:38 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2012-02-16 21:07:00 +00:00
|
|
|
it 'requires the uniqueness of the slug' do
|
|
|
|
page = FactoryGirl.create(:page)
|
|
|
|
another_page = FactoryGirl.build(:page, :site => page.site)
|
|
|
|
another_page.should_not be_valid
|
|
|
|
another_page.errors[:slug].should == ["is already taken"]
|
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2012-02-16 21:07:00 +00:00
|
|
|
it 'requires the uniqueness of the slug within a "folder"' do
|
|
|
|
site = FactoryGirl.create(:site)
|
|
|
|
root = FactoryGirl.create(:page, :slug => 'index', :site => site)
|
|
|
|
child_1 = FactoryGirl.create(:page, :slug => 'first_child', :parent => root, :site => site)
|
|
|
|
(page = FactoryGirl.build(:page, :slug => 'first_child', :parent => root, :site => site)).should_not be_valid
|
|
|
|
page.errors[:slug].should == ["is already taken"]
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2012-02-16 21:07:00 +00:00
|
|
|
page.slug = 'index'
|
|
|
|
page.valid?.should be_true
|
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2012-02-16 21:07:00 +00:00
|
|
|
%w{admin locomotive stylesheets images javascripts}.each do |slug|
|
|
|
|
it "considers '#{slug}' as invalid" do
|
|
|
|
page = FactoryGirl.build(:page, :slug => slug)
|
|
|
|
page.stubs(:depth).returns(1)
|
|
|
|
page.should_not be_valid
|
|
|
|
page.errors[:slug].should == ["is reserved"]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context '#i18n' do
|
|
|
|
|
|
|
|
before(:each) do
|
|
|
|
::Mongoid::Fields::I18n.locale = 'en'
|
|
|
|
@page = FactoryGirl.build(:page, :title => 'Hello world')
|
|
|
|
::Mongoid::Fields::I18n.locale = 'fr'
|
|
|
|
end
|
|
|
|
|
|
|
|
after(:all) do
|
|
|
|
::Mongoid::Fields::I18n.locale = 'en'
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'requires the presence of the title' do
|
|
|
|
@page.title = ''
|
|
|
|
@page.valid?.should be_false
|
|
|
|
@page.errors[:title].should == ["can't be blank"]
|
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2012-03-14 00:16:01 +00:00
|
|
|
it 'tells if a page has been translated or not' do
|
|
|
|
@page.translated?.should be_false
|
|
|
|
@page.title = 'Hello world'
|
|
|
|
@page.translated?.should be_true
|
|
|
|
end
|
|
|
|
|
2010-04-30 14:05:53 +00:00
|
|
|
end
|
2012-02-16 21:07:00 +00:00
|
|
|
|
2010-04-25 00:33:38 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-05-02 23:33:17 +00:00
|
|
|
# Named scopes ##
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-05-02 23:33:17 +00:00
|
|
|
# Associations ##
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-05-02 23:33:17 +00:00
|
|
|
# Methods ##
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-04-25 00:33:38 +00:00
|
|
|
describe 'once created' do
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-05-02 23:33:17 +00:00
|
|
|
it 'should tell if the page is the index one' do
|
2011-08-25 21:28:56 +00:00
|
|
|
FactoryGirl.build(:page, :slug => 'index', :site => nil).index?.should be_true
|
2012-02-16 21:07:00 +00:00
|
|
|
page = FactoryGirl.build(:page, :slug => 'index', :site => nil)
|
|
|
|
page.stubs(:depth).returns(1)
|
|
|
|
page.index?.should be_false
|
2010-05-02 23:33:17 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-04-30 14:05:53 +00:00
|
|
|
it 'should have normalized slug' do
|
2011-08-25 21:28:56 +00:00
|
|
|
page = FactoryGirl.build(:page, :slug => ' Valid ité.html ')
|
2010-04-30 14:05:53 +00:00
|
|
|
page.valid?
|
2011-06-21 20:03:24 +00:00
|
|
|
page.slug.should == 'valid-ite-html'
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2011-08-25 21:28:56 +00:00
|
|
|
page = FactoryGirl.build(:page, :title => ' Valid ité.html ', :slug => nil, :site => page.site)
|
2010-05-02 23:33:17 +00:00
|
|
|
page.should be_valid
|
2011-06-21 20:03:24 +00:00
|
|
|
page.slug.should == 'valid-ite-html'
|
2010-04-30 14:05:53 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-07-09 10:38:50 +00:00
|
|
|
it 'has no cache strategy' do
|
2011-08-25 21:28:56 +00:00
|
|
|
page = FactoryGirl.build(:page, :site => nil)
|
2010-07-09 10:38:50 +00:00
|
|
|
page.with_cache?.should == false
|
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-04-25 00:33:38 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-07-13 00:46:17 +00:00
|
|
|
describe '#deleting' do
|
2010-07-23 20:09:54 +00:00
|
|
|
|
|
|
|
before(:each) do
|
2011-08-25 21:28:56 +00:00
|
|
|
@page = FactoryGirl.build(:page)
|
2010-05-10 22:39:52 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-07-13 00:46:17 +00:00
|
|
|
it 'does not delete the index page' do
|
2010-05-10 22:39:52 +00:00
|
|
|
@page.stubs(:index?).returns(true)
|
|
|
|
lambda {
|
2010-07-13 00:46:17 +00:00
|
|
|
@page.destroy.should be_false
|
|
|
|
@page.errors.first == 'You can not remove index or 404 pages'
|
2011-11-24 13:37:17 +00:00
|
|
|
}.should_not change(Locomotive::Page, :count)
|
2010-05-10 22:39:52 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-07-13 00:46:17 +00:00
|
|
|
it 'does not delete the 404 page' do
|
2010-05-10 22:39:52 +00:00
|
|
|
@page.stubs(:not_found?).returns(true)
|
|
|
|
lambda {
|
2010-07-13 00:46:17 +00:00
|
|
|
@page.destroy.should be_false
|
|
|
|
@page.errors.first == 'You can not remove index or 404 pages'
|
2011-11-24 13:37:17 +00:00
|
|
|
}.should_not change(Locomotive::Page, :count)
|
2010-05-10 22:39:52 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-05-10 22:39:52 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2012-02-16 21:07:00 +00:00
|
|
|
describe 'tree organization' do
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-04-30 14:05:53 +00:00
|
|
|
before(:each) do
|
2011-08-25 21:28:56 +00:00
|
|
|
@home = FactoryGirl.create(:page)
|
|
|
|
@child_1 = FactoryGirl.create(:page, :title => 'Subpage 1', :slug => 'foo', :parent_id => @home._id, :site => @home.site)
|
2010-04-30 14:05:53 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2012-02-16 21:07:00 +00:00
|
|
|
it 'adds root elements' do
|
2011-08-25 21:28:56 +00:00
|
|
|
page_404 = FactoryGirl.create(:page, :title => 'Page not found', :slug => '404', :site => @home.site)
|
2011-11-24 13:37:17 +00:00
|
|
|
Locomotive::Page.roots.count.should == 2
|
|
|
|
Locomotive::Page.roots.should == [@home, page_404]
|
2010-04-30 14:05:53 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2012-02-16 21:07:00 +00:00
|
|
|
it 'adds sub pages' do
|
2011-08-25 21:28:56 +00:00
|
|
|
child_2 = FactoryGirl.create(:page, :title => 'Subpage 2', :slug => 'bar', :parent => @home, :site => @home.site)
|
2011-11-24 13:37:17 +00:00
|
|
|
@home = Locomotive::Page.find(@home.id)
|
2010-10-14 14:01:18 +00:00
|
|
|
@home.children.count.should == 2
|
|
|
|
@home.children.should == [@child_1, child_2]
|
2010-04-30 14:05:53 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2012-02-16 21:07:00 +00:00
|
|
|
it 'moves its children accordingly' do
|
2011-08-25 21:28:56 +00:00
|
|
|
sub_child_1 = FactoryGirl.create(:page, :title => 'Sub Subpage 1', :slug => 'bar', :parent => @child_1, :site => @home.site)
|
2012-02-16 21:07:00 +00:00
|
|
|
archives = FactoryGirl.create(:page, :title => 'archives', :slug => 'archives', :parent => @home, :site => @home.site)
|
|
|
|
posts = FactoryGirl.create(:page, :title => 'posts', :slug => 'posts', :parent => archives, :site => @home.site)
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2012-02-16 21:07:00 +00:00
|
|
|
@child_1.parent = archives
|
2010-05-02 23:33:17 +00:00
|
|
|
@child_1.save
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-05-02 23:33:17 +00:00
|
|
|
@home.reload.children.count.should == 1
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-05-02 23:33:17 +00:00
|
|
|
archives.reload.children.count.should == 2
|
|
|
|
archives.children.last.depth.should == 2
|
|
|
|
archives.children.last.children.first.depth.should == 3
|
2010-04-30 14:05:53 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2012-02-16 21:07:00 +00:00
|
|
|
it 'destroys descendants as well' do
|
2011-08-25 21:28:56 +00:00
|
|
|
FactoryGirl.create(:page, :title => 'Sub Subpage 1', :slug => 'bar', :parent_id => @child_1._id, :site => @home.site)
|
2010-05-02 23:33:17 +00:00
|
|
|
@child_1.destroy
|
2011-11-24 13:37:17 +00:00
|
|
|
Locomotive::Page.where(:slug => 'bar').first.should be_nil
|
2010-04-30 14:05:53 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-04-30 14:05:53 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-05-02 23:33:17 +00:00
|
|
|
describe 'acts as list' do
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-05-09 12:44:53 +00:00
|
|
|
before(:each) do
|
2011-08-25 21:28:56 +00:00
|
|
|
@home = FactoryGirl.create(:page)
|
|
|
|
@child_1 = FactoryGirl.create(:page, :title => 'Subpage 1', :slug => 'foo', :parent => @home, :site => @home.site)
|
|
|
|
@child_2 = FactoryGirl.create(:page, :title => 'Subpage 2', :slug => 'bar', :parent => @home, :site => @home.site)
|
|
|
|
@child_3 = FactoryGirl.create(:page, :title => 'Subpage 3', :slug => 'acme', :parent => @home, :site => @home.site)
|
2010-05-09 12:44:53 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-05-09 12:44:53 +00:00
|
|
|
it 'should be at the bottom of the folder once created' do
|
2012-02-16 21:07:00 +00:00
|
|
|
[@child_1, @child_2, @child_3].each_with_index { |c, i| c.position.should == i }
|
2010-05-09 12:44:53 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-05-09 12:44:53 +00:00
|
|
|
it 'should have its position updated if a sibling is removed' do
|
|
|
|
@child_2.destroy
|
2012-02-16 21:07:00 +00:00
|
|
|
[@child_1, @child_3.reload].each_with_index { |c, i| c.position.should == i }
|
2010-05-09 12:44:53 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-05-30 23:57:33 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-07-16 20:36:07 +00:00
|
|
|
describe 'templatized extension' do
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-07-16 20:36:07 +00:00
|
|
|
before(:each) do
|
2012-02-16 21:07:00 +00:00
|
|
|
@page = FactoryGirl.build(:page, :templatized => true, :target_klass_name => 'Foo')
|
|
|
|
# @page.stubs(:target_klass)
|
|
|
|
# Locomotive::ContentType.stubs(:find).returns(FactoryGirl.build(:content_type, :site => nil))
|
2010-07-16 20:36:07 +00:00
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-07-16 20:36:07 +00:00
|
|
|
it 'is considered as a templatized page' do
|
|
|
|
@page.templatized?.should be_true
|
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2010-07-16 20:36:07 +00:00
|
|
|
it 'fills in the slug field' do
|
|
|
|
@page.valid?
|
|
|
|
@page.slug.should == 'content_type_template'
|
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
|
2012-02-16 21:07:00 +00:00
|
|
|
it 'returns the target klass' do
|
|
|
|
@page.target_klass.should == Foo
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'has a name for the target entry' do
|
|
|
|
@page.target_entry_name.should == 'foo'
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'uses the find_by_permalink method when fetching the entry' do
|
|
|
|
Foo.expects(:find_by_permalink)
|
|
|
|
@page.fetch_target_entry('foo')
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'using a content type' do
|
|
|
|
|
|
|
|
before(:each) do
|
|
|
|
@site = FactoryGirl.build(:site)
|
|
|
|
@content_type = FactoryGirl.build(:content_type, :slug => 'posts', :site => @site)
|
|
|
|
@page.site = @site
|
|
|
|
@page.target_klass_name = 'Locomotive::Entry42'
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'has a name for the target entry' do
|
|
|
|
@site.stubs(:content_types).returns(mock(:find => @content_type))
|
|
|
|
@page.target_entry_name.should == 'post'
|
|
|
|
end
|
|
|
|
|
|
|
|
context '#security' do
|
|
|
|
|
|
|
|
before(:each) do
|
|
|
|
Locomotive::ContentType.stubs(:find).returns(@content_type)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'is valid if the content type belongs to the site' do
|
|
|
|
@page.send(:ensure_target_klass_name_security)
|
|
|
|
@page.errors.should be_empty
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not valid the page if the content type does not belong to the site' do
|
|
|
|
@content_type.site = FactoryGirl.build(:site)
|
|
|
|
@page.send(:ensure_target_klass_name_security)
|
|
|
|
@page.errors[:target_klass_name].should == ['presents a security problem']
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2010-07-23 20:09:54 +00:00
|
|
|
end
|
|
|
|
|
2010-07-16 20:36:07 +00:00
|
|
|
end
|
2011-03-05 00:51:44 +00:00
|
|
|
|
2011-02-01 08:07:18 +00:00
|
|
|
describe 'listed extension' do
|
2011-03-05 00:51:44 +00:00
|
|
|
|
2011-02-01 08:07:18 +00:00
|
|
|
it 'is considered as a visible page' do
|
2012-02-16 21:07:00 +00:00
|
|
|
@page = FactoryGirl.build(:page, :site => nil)
|
2011-02-01 08:07:18 +00:00
|
|
|
@page.listed?.should be_true
|
|
|
|
end
|
2011-03-05 00:51:44 +00:00
|
|
|
|
2011-02-01 08:07:18 +00:00
|
|
|
it 'is not considered as a visible page' do
|
2012-02-16 21:07:00 +00:00
|
|
|
@page = FactoryGirl.build(:page, :site => nil, :listed => false)
|
2011-02-01 08:07:18 +00:00
|
|
|
@page.listed?.should be_false
|
2011-02-01 06:39:20 +00:00
|
|
|
end
|
2011-03-05 00:51:44 +00:00
|
|
|
|
2011-02-01 06:39:20 +00:00
|
|
|
end
|
2011-01-06 14:48:41 +00:00
|
|
|
|
|
|
|
describe 'redirect extension' do
|
|
|
|
|
|
|
|
before(:each) do
|
2011-08-25 21:28:56 +00:00
|
|
|
@page = FactoryGirl.build(:page, :site => nil, :redirect=> true, :redirect_url => 'http://www.google.com/')
|
2011-01-06 14:48:41 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'is considered as a redirect page' do
|
|
|
|
@page.redirect?.should be_true
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'validates the redirect_url if redirect is set' do
|
|
|
|
@page.redirect_url = nil
|
|
|
|
@page.should_not be_valid
|
|
|
|
@page.errors[:redirect_url].should == ["can't be blank"]
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should validate format of redirect_url' do
|
|
|
|
@page.redirect_url = "invalid url with spaces"
|
|
|
|
@page.should_not be_valid
|
|
|
|
@page.errors[:redirect_url].should == ["is invalid"]
|
|
|
|
end
|
|
|
|
end
|
2012-02-16 21:07:00 +00:00
|
|
|
|
|
|
|
class Foo
|
|
|
|
end
|
|
|
|
|
|
|
|
class Locomotive::Entry42
|
|
|
|
end
|
|
|
|
|
|
|
|
def fake_bson_id(id)
|
|
|
|
BSON::ObjectId(id.to_s.rjust(24, '0'))
|
|
|
|
end
|
2010-07-23 20:09:54 +00:00
|
|
|
end
|