fix the specs for the page model
This commit is contained in:
parent
73b559260e
commit
02e48f5c36
@ -9,6 +9,13 @@ module Locomotive
|
||||
include ::Mongoid::Tree
|
||||
include ::Mongoid::Tree::Ordering
|
||||
|
||||
## fields ##
|
||||
field :depth, :type => Integer, :default => 0
|
||||
|
||||
## callbacks ##
|
||||
before_save :persist_depth
|
||||
before_destroy :delete_descendants
|
||||
|
||||
## indexes ##
|
||||
index :position
|
||||
index [:depth.asc, :position.asc]
|
||||
@ -88,6 +95,16 @@ module Locomotive
|
||||
end
|
||||
end
|
||||
|
||||
def depth
|
||||
self.parent_ids.count
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def persist_depth
|
||||
self.attributes[:depth] = self.depth
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -42,7 +42,7 @@ module Locomotive
|
||||
validates_presence_of :site, :title, :slug
|
||||
validates_uniqueness_of :slug, :scope => [:site_id, :parent_id]
|
||||
validates_uniqueness_of :handle, :allow_blank => true
|
||||
validates_exclusion_of :slug, :in => Locomotive.config.reserved_slugs, :if => Proc.new { |p| p.depth == 0 }
|
||||
validates_exclusion_of :slug, :in => Locomotive.config.reserved_slugs, :if => Proc.new { |p| p.depth <= 1 }
|
||||
|
||||
## named scopes ##
|
||||
scope :latest_updated, :order_by => [[:updated_at, :desc]], :limit => Locomotive.config.ui.latest_entries_nb
|
||||
|
@ -67,8 +67,7 @@ module Locomotive
|
||||
:slug => slug,
|
||||
:title => ::I18n.t("attributes.defaults.pages.#{slug}.title"),
|
||||
:raw_template => ::I18n.t("attributes.defaults.pages.#{slug}.body"),
|
||||
:published => true,
|
||||
:depth => 0
|
||||
:published => true
|
||||
})
|
||||
end
|
||||
end
|
||||
|
@ -6,7 +6,7 @@ module Locomotive
|
||||
:domain => 'example.com',
|
||||
:reserved_subdomains => %w{www admin email blog webmail mail support help site sites},
|
||||
# :forbidden_paths => %w{layouts snippets stylesheets javascripts assets admin system api},
|
||||
:reserved_slugs => %w{stylesheets javascripts assets admin images api pages edit},
|
||||
:reserved_slugs => %w{stylesheets javascripts assets admin locomotive images api pages edit},
|
||||
:locales => %w{en de fr pt-BR it nl no es ru},
|
||||
:site_locales => %w{en de fr pt-BR it nl no es ru},
|
||||
:cookie_key => '_locomotive_session',
|
||||
|
@ -31,4 +31,45 @@ module Mongoid#:nodoc:
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# make the validators work with localized field
|
||||
module Validations #:nodoc:
|
||||
|
||||
def read_attribute_for_validation_with_localization(attr)
|
||||
if fields[attr.to_s] && fields[attr.to_s].localized?
|
||||
send(attr.to_sym)
|
||||
else
|
||||
read_attribute_for_validation_without_localization(attr)
|
||||
end
|
||||
end
|
||||
|
||||
alias_method_chain :read_attribute_for_validation, :localization
|
||||
|
||||
class PresenceValidator < ActiveModel::EachValidator
|
||||
|
||||
def validate_each(document, attribute, value)
|
||||
document.errors.add(attribute, :blank, options) if value.blank?
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
#
|
||||
# class UniquenessValidator < ActiveModel::EachValidator
|
||||
#
|
||||
# protected
|
||||
#
|
||||
# def criterion_with_localization(document, attribute, value)
|
||||
# field = document.fields[attribute.to_s]
|
||||
# if field && field.localized? && !value.blank?
|
||||
# value = document.send(attribute.to_sym)
|
||||
# end
|
||||
#
|
||||
# criterion_without_localization(document, attribute, value)
|
||||
# end
|
||||
#
|
||||
# alias_method_chain :criterion, :localization
|
||||
#
|
||||
# end
|
||||
#
|
||||
# end
|
||||
end
|
||||
|
@ -15,7 +15,6 @@ describe Locomotive::GlobalActionsCell do
|
||||
end
|
||||
|
||||
it 'has a link to edit my account' do
|
||||
puts "last test"
|
||||
menu.should have_link('Admin')
|
||||
end
|
||||
|
||||
|
@ -13,45 +13,69 @@ describe Locomotive::Page do
|
||||
FactoryGirl.build(:page).should be_valid
|
||||
end
|
||||
|
||||
# Validations ##
|
||||
describe 'validation' do
|
||||
|
||||
%w{site title}.each do |field|
|
||||
it "should validate presence of #{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"]
|
||||
%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
|
||||
end
|
||||
|
||||
it 'should validate presence of slug' do
|
||||
page = FactoryGirl.build(:page, :title => nil, :slug => nil)
|
||||
page.should_not be_valid
|
||||
page.errors[:slug].should == ["can't be blank"]
|
||||
end
|
||||
|
||||
it 'should validate uniqueness of slug' do
|
||||
page = FactoryGirl.create(:page)
|
||||
(page = FactoryGirl.build(:page, :site => page.site)).should_not be_valid
|
||||
page.errors[:slug].should == ["is already taken"]
|
||||
end
|
||||
|
||||
it 'should validate uniqueness of 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"]
|
||||
|
||||
page.slug = 'index'
|
||||
page.valid?.should be_true
|
||||
end
|
||||
|
||||
%w{admin stylesheets images javascripts}.each do |slug|
|
||||
it "should consider '#{slug}' as invalid" do
|
||||
page = FactoryGirl.build(:page, :slug => slug)
|
||||
it 'requires the presence of the slug' do
|
||||
page = FactoryGirl.build(:page, :title => nil, :slug => nil)
|
||||
page.should_not be_valid
|
||||
page.errors[:slug].should == ["is reserved"]
|
||||
page.errors[:slug].should == ["can't be blank"]
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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"]
|
||||
|
||||
page.slug = 'index'
|
||||
page.valid?.should be_true
|
||||
end
|
||||
|
||||
%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
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Named scopes ##
|
||||
@ -64,7 +88,9 @@ describe Locomotive::Page do
|
||||
|
||||
it 'should tell if the page is the index one' do
|
||||
FactoryGirl.build(:page, :slug => 'index', :site => nil).index?.should be_true
|
||||
FactoryGirl.build(:page, :slug => 'index', :depth => 1, :site => nil).index?.should be_false
|
||||
page = FactoryGirl.build(:page, :slug => 'index', :site => nil)
|
||||
page.stubs(:depth).returns(1)
|
||||
page.index?.should be_false
|
||||
end
|
||||
|
||||
it 'should have normalized slug' do
|
||||
@ -108,44 +134,42 @@ describe Locomotive::Page do
|
||||
|
||||
end
|
||||
|
||||
describe 'acts as tree' do
|
||||
describe 'tree organization' do
|
||||
|
||||
before(:each) do
|
||||
@home = FactoryGirl.create(:page)
|
||||
@child_1 = FactoryGirl.create(:page, :title => 'Subpage 1', :slug => 'foo', :parent_id => @home._id, :site => @home.site)
|
||||
end
|
||||
|
||||
it 'should add root elements' do
|
||||
it 'adds root elements' do
|
||||
page_404 = FactoryGirl.create(:page, :title => 'Page not found', :slug => '404', :site => @home.site)
|
||||
Locomotive::Page.roots.count.should == 2
|
||||
Locomotive::Page.roots.should == [@home, page_404]
|
||||
end
|
||||
|
||||
it 'should add sub pages' do
|
||||
it 'adds sub pages' do
|
||||
child_2 = FactoryGirl.create(:page, :title => 'Subpage 2', :slug => 'bar', :parent => @home, :site => @home.site)
|
||||
@home = Locomotive::Page.find(@home.id)
|
||||
@home.children.count.should == 2
|
||||
@home.children.should == [@child_1, child_2]
|
||||
end
|
||||
|
||||
it 'should move its children accordingly' do
|
||||
it 'moves its children accordingly' do
|
||||
sub_child_1 = FactoryGirl.create(:page, :title => 'Sub Subpage 1', :slug => 'bar', :parent => @child_1, :site => @home.site)
|
||||
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)
|
||||
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)
|
||||
|
||||
@child_1.parent_id = archives._id
|
||||
@child_1.parent = archives
|
||||
@child_1.save
|
||||
|
||||
@child_1.position.should == 2
|
||||
@home.reload.children.count.should == 1
|
||||
|
||||
archives.reload.children.count.should == 2
|
||||
archives.children.last.depth.should == 2
|
||||
archives.children.last.position.should == 2
|
||||
archives.children.last.children.first.depth.should == 3
|
||||
end
|
||||
|
||||
it 'should destroy descendants as well' do
|
||||
it 'destroys descendants as well' do
|
||||
FactoryGirl.create(:page, :title => 'Sub Subpage 1', :slug => 'bar', :parent_id => @child_1._id, :site => @home.site)
|
||||
@child_1.destroy
|
||||
Locomotive::Page.where(:slug => 'bar').first.should be_nil
|
||||
@ -163,12 +187,12 @@ describe Locomotive::Page do
|
||||
end
|
||||
|
||||
it 'should be at the bottom of the folder once created' do
|
||||
[@child_1, @child_2, @child_3].each_with_index { |c, i| c.position.should == i + 1 }
|
||||
[@child_1, @child_2, @child_3].each_with_index { |c, i| c.position.should == i }
|
||||
end
|
||||
|
||||
it 'should have its position updated if a sibling is removed' do
|
||||
@child_2.destroy
|
||||
[@child_1, @child_3.reload].each_with_index { |c, i| c.position.should == i + 1 }
|
||||
[@child_1, @child_3.reload].each_with_index { |c, i| c.position.should == i }
|
||||
end
|
||||
|
||||
end
|
||||
@ -176,8 +200,9 @@ describe Locomotive::Page do
|
||||
describe 'templatized extension' do
|
||||
|
||||
before(:each) do
|
||||
@page = FactoryGirl.build(:page, :site => nil, :templatized => true, :content_type_id => 42)
|
||||
Locomotive::ContentType.stubs(:find).returns(FactoryGirl.build(:content_type, :site => nil))
|
||||
@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))
|
||||
end
|
||||
|
||||
it 'is considered as a templatized page' do
|
||||
@ -189,8 +214,52 @@ describe Locomotive::Page do
|
||||
@page.slug.should == 'content_type_template'
|
||||
end
|
||||
|
||||
it 'does forget to set the content type id' do
|
||||
@page.content_type_id.should == 42
|
||||
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
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@ -198,12 +267,12 @@ describe Locomotive::Page do
|
||||
describe 'listed extension' do
|
||||
|
||||
it 'is considered as a visible page' do
|
||||
@page = FactoryGirl.build(:page, :site => nil, :content_type_id => 42)
|
||||
@page = FactoryGirl.build(:page, :site => nil)
|
||||
@page.listed?.should be_true
|
||||
end
|
||||
|
||||
it 'is not considered as a visible page' do
|
||||
@page = FactoryGirl.build(:page, :site => nil, :listed => false, :content_type_id => 42)
|
||||
@page = FactoryGirl.build(:page, :site => nil, :listed => false)
|
||||
@page.listed?.should be_false
|
||||
end
|
||||
|
||||
@ -231,4 +300,14 @@ describe Locomotive::Page do
|
||||
@page.errors[:redirect_url].should == ["is invalid"]
|
||||
end
|
||||
end
|
||||
|
||||
class Foo
|
||||
end
|
||||
|
||||
class Locomotive::Entry42
|
||||
end
|
||||
|
||||
def fake_bson_id(id)
|
||||
BSON::ObjectId(id.to_s.rjust(24, '0'))
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user