diff --git a/app/models/page.rb b/app/models/page.rb index b03b8e1..8de60e8 100644 --- a/app/models/page.rb +++ b/app/models/page.rb @@ -12,6 +12,7 @@ def full_title end end + # TODO: Convert to named_scope def self_and_siblings Page.find(:all, :conditions => ["parent_id = ?", self.parent_id], :order => 'page_order') end @@ -67,6 +68,9 @@ def page_body(page = self.page_number) # page/0 should return nil (out of bound) # page/n where n > pages should return nil (out of bound) # + # TODO: Possible bug: + # - @split_pages is cached, so if you change the body again and then call + # split_page!, the code looks like it will ignore the cache def split_page!(page_number = 1) if self.page_type == 'page' self[:page_body] = self.body @@ -112,7 +116,8 @@ def last_page protected def check_page_type - self.page_type = ((@split_pages = self.body.split(/\{pagebreak\}/i)).length > 1) ? "multipage": "page" + self.page_type = "page" and return if self.body.blank? || (@split_pages = self.body.split(/\{pagebreak\}/i)).length == 1 + self.page_type = "multipage" end def check_page_order diff --git a/spec/fixtures/pages.yml b/spec/fixtures/pages.yml new file mode 100644 index 0000000..76bae0b --- /dev/null +++ b/spec/fixtures/pages.yml @@ -0,0 +1,70 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html +home: + id: 1 + name: home + title: Home + full_title: Home Page + published: 1 + linked: 1 + +second_level: + id: 2 + name: second + title: Second Level + parent_id: 1 + published: 1 + linked: 1 + +third_level: + id: 3 + name: third + title: Third Level + parent_id: 2 + published: 1 + linked: 1 + +fourth_level: + id: 9 + name: fourth + title: Fourth Level + parent_id: 3 + published: 1 + linked: 1 + +unpublished: + id: 4 + name: unpublished + title: Unpublished + parent_id: 2 + published: 0 + linked: 0 + +swap_test: + id: 5 + name: swap_test + title: Swap Test + parent_id: 1 + +swap_test1: + id: 6 + name: swap1 + title: Swap Test 1 + parent_id: 5 + page_order: 1 + +swap_test2: + id: 7 + name: swap2 + title: Swap Test 2 + parent_id: 5 + page_order: 3 + +swap_test3: + id: 8 + name: swap3 + title: Swap Test 3 + parent_id: 5 + page_order: 4 + + + diff --git a/spec/models/page_spec.rb b/spec/models/page_spec.rb new file mode 100644 index 0000000..4bf6d7a --- /dev/null +++ b/spec/models/page_spec.rb @@ -0,0 +1,491 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe Page do + fixtures :pages + + describe '#ancestor_path' do + it "should return / for the home page" do + Page.find_by_name('home').ancestor_path.should eql('/') + end + + it "should return / for the second level page" do + Page.find_by_name('second').ancestor_path.should eql('/') + end + + it "should return /second/ for the third level page" do + Page.find_by_name('third').ancestor_path.should eql('/second/') + end + + it "should return /second/third/ for the fourth level page" do + Page.find_by_name('fourth').ancestor_path.should eql('/second/third/') + end + + end + + describe '#full_title' do + it "should override title if it is a different value" do + @page = Page.find_by_name('home') + @page.full_title.should eql(pages(:home).full_title) + @page.title.should eql(pages(:home).title) + @page.full_title.should_not eql(@page.title) + end + + it "should default to title if full_title is not set" do + @page = Page.find_by_name('second') + @page.title.should eql(pages(:second_level).title) + @page.title.should eql(@page.full_title) + end + end + + describe '#publishable_children' do + it "should return children that are flagged as publishable. (DEPRECATION: This should be converted to named_scope)" do + Page.find_by_name('second').should have(2).children + Page.find_by_name('second').should have(1).publishable_children + end + end + + describe '#find_page_by_path' do + it "should return the home page when the path is empty" do + Page.find_page_by_path([]).should eql(pages(:home)) + end + + it "should return the home page when passed 'home'" do + Page.find_page_by_path(%w(home)).should eql(pages(:home)) + end + + it "should return the children pages of the home page" do + Page.find_page_by_path(%w(second)).should eql(pages(:second_level)) + end + + it "should descend the path and find the correct page" do + Page.find_page_by_path(%w(second third)).should eql(pages(:third_level)) + Page.find_page_by_path(%w(second third fourth)).should eql(pages(:fourth_level)) + end + + it "should verify the path is in the proper sequence" do + Page.find_page_by_path(%w(fourth third second)).should be_nil + end + + it "should handle corrupt paths gracefully" do + Page.find_page_by_path([""]*4).should be_nil + Page.find_page_by_path(['second', '', 'third']).should be_nil + Page.find_page_by_path(['second', 'third', '']).should be_nil + end + end + + describe 'multipage' do + before(:each) do + @multipage = pages(:fourth_level) + @multipage.body = "Multipage 1\n{pagebreak}Multipage 2\n{pagebreak}Multipage 3\n" + @multipage.save + @multipage.reload + end + + describe "#find_page_by_path" do + it "should return the home page when the path is empty" do + Page.find_page_by_path([]).should eql(pages(:home)) + end + + it "should return the home page when passed 'home'" do + Page.find_page_by_path(%w(home)).should eql(pages(:home)) + end + + it "should return the children pages of the home page" do + Page.find_page_by_path(%w(second)).should eql(pages(:second_level)) + end + + it "should descend the path and find the correct page" do + Page.find_page_by_path(%w(second third)).should eql(pages(:third_level)) + Page.find_page_by_path(%w(second third fourth)).should eql(pages(:fourth_level)) + end + + it "should verify the path is in the proper sequence" do + Page.find_page_by_path(%w(fourth third second)).should be_nil + end + + it "should handle corrupt paths gracefully" do + Page.find_page_by_path([""]*4).should be_nil + Page.find_page_by_path(['second', '', 'third']).should be_nil + Page.find_page_by_path(['second', 'third', '']).should be_nil + end + end + + describe "handling leaves" do + it "should return a page_body based on the page number at the end of the path" do + @page = Page.find_page_by_path(%w(second third fourth 1)) + @page.should eql(pages(:fourth_level)) + @page.page_body.should eql("Multipage 1\n") + @page.page_number.should eql(1) + @page.pages.should eql(3) + + @page = Page.find_page_by_path(%w(second third fourth 2)) + @page.should eql(pages(:fourth_level)) + @page.page_body.should eql("Multipage 2\n") + @page.page_number.should eql(2) + @page.pages.should eql(3) + + @page = Page.find_page_by_path(%w(second third fourth 3)) + @page.should eql(pages(:fourth_level)) + @page.page_body.should eql("Multipage 3\n") + @page.page_number.should eql(3) + @page.pages.should eql(3) + end + + it "should default to the first page" do + @page = Page.find_page_by_path(%w(second third fourth)) + @page.should eql(pages(:fourth_level)) + @page.page_body.should eql("Multipage 1\n") + @page.page_number.should eql(1) + @page.pages.should eql(3) + end + + it "should return nil when page number is out of bounds" do + @page = Page.find_page_by_path(%w(second third fourth 0)) + @page.should be_nil + end + + it "should return page with a nil page_body when it exceeds the maximum page number (DEPRECATION: This behavior needs to be changed)" do + @page = Page.find_page_by_path(%w(second third fourth 5)) + @page.should eql(pages(:fourth_level)) + @page.page_body.should be_nil + @page.page_number.should eql(5) + @page.pages.should eql(3) + end + + it "should descend and verify each path of the page" do + Page.find_page_by_path(%w(second third 5 fourth)).should be_nil + Page.find_page_by_path(%w(second third 5)).should be_nil + end + end + end + + describe "handling multipages in non-leaf pages" do + before(:each) do + @multipage = pages(:third_level) + @multipage.body = "Multipage 1\n{pagebreak}Multipage 2\n{pagebreak}Multipage 3\n" + @multipage.save + @multipage.reload + end + + # Multipage in the middle of the path should be ignored + describe "#find_page_by_path" do + it "should return the home page when the path is empty" do + Page.find_page_by_path([]).should eql(pages(:home)) + end + + it "should return the home page when passed 'home'" do + Page.find_page_by_path(%w(home)).should eql(pages(:home)) + end + + it "should return the children pages of the home page" do + Page.find_page_by_path(%w(second)).should eql(pages(:second_level)) + end + + it "should descend the path and find the correct page" do + Page.find_page_by_path(%w(second third)).should eql(pages(:third_level)) + Page.find_page_by_path(%w(second third fourth)).should eql(pages(:fourth_level)) + end + + it "should verify the path is in the proper sequence" do + Page.find_page_by_path(%w(fourth third second)).should be_nil + end + + it "should handle corrupt paths gracefully" do + Page.find_page_by_path([""]*4).should be_nil + Page.find_page_by_path(['second', '', 'third']).should be_nil + Page.find_page_by_path(['second', 'third', '']).should be_nil + end + end + + describe "handling in-line multipages" do + it "should return a page_body based on the page number at the end of the path" do + @page = Page.find_page_by_path(%w(second third 1)) + @page.should eql(pages(:third_level)) + @page.page_body.should eql("Multipage 1\n") + @page.page_number.should eql(1) + @page.pages.should eql(3) + + @page = Page.find_page_by_path(%w(second third 2)) + @page.should eql(pages(:third_level)) + @page.page_body.should eql("Multipage 2\n") + @page.page_number.should eql(2) + @page.pages.should eql(3) + + @page = Page.find_page_by_path(%w(second third 3)) + @page.should eql(pages(:third_level)) + @page.page_body.should eql("Multipage 3\n") + @page.page_number.should eql(3) + @page.pages.should eql(3) + end + + it "should default to the first page" do + @page = Page.find_page_by_path(%w(second third)) + @page.should eql(pages(:third_level)) + @page.page_body.should eql("Multipage 1\n") + @page.page_number.should eql(1) + @page.pages.should eql(3) + end + + it "should return nil when page number is out of bounds" do + @page = Page.find_page_by_path(%w(second third 0)) + @page.should be_nil + end + + it "should return page with a nil page_body when it exceeds the maximum page number (DEPRECATION: This behavior needs to be changed)" do + @page = Page.find_page_by_path(%w(second third 5)) + @page.should eql(pages(:third_level)) + @page.page_body.should be_nil + @page.page_number.should eql(5) + @page.pages.should eql(3) + end + + it "should descend and verify each path of the page" do + Page.find_page_by_path(%w(second third 5 fourth)).should be_nil + Page.find_page_by_path(%w(second 5)).should be_nil + Page.find_page_by_path(%w(2 second third)).should be_nil + Page.find_page_by_path(%w(second third fourth)).should eql(pages(:fourth_level)) + end + end + + end + + describe "handling multipages in non-leaf pages" do + before(:each) do + @multipage = pages(:home) + @multipage.body = "Multipage 1\n{pagebreak}Multipage 2\n{pagebreak}Multipage 3\n" + @multipage.save + @multipage.reload + end + + # Multipage in the middle of the path should be ignored + describe "#find_page_by_path" do + it "should return the home page when the path is empty" do + Page.find_page_by_path([]).should eql(pages(:home)) + end + + it "should return the home page when passed 'home'" do + Page.find_page_by_path(%w(home)).should eql(pages(:home)) + end + + it "should return the children pages of the home page" do + Page.find_page_by_path(%w(second)).should eql(pages(:second_level)) + end + + it "should descend the path and find the correct page" do + Page.find_page_by_path(%w(second third)).should eql(pages(:third_level)) + Page.find_page_by_path(%w(second third fourth)).should eql(pages(:fourth_level)) + end + + it "should verify the path is in the proper sequence" do + Page.find_page_by_path(%w(fourth third second)).should be_nil + end + + it "should handle corrupt paths gracefully" do + Page.find_page_by_path([""]*4).should be_nil + Page.find_page_by_path(['second', '', 'third']).should be_nil + Page.find_page_by_path(['second', 'third', '']).should be_nil + end + end + + describe "handling home multipages" do + it "should return a page_body based on the page number at the end of the path" do + @page = Page.find_page_by_path(%w(1)) + @page.should eql(pages(:home)) + @page.page_body.should eql("Multipage 1\n") + @page.page_number.should eql(1) + @page.pages.should eql(3) + + @page = Page.find_page_by_path(%w(2)) + @page.should eql(pages(:home)) + @page.page_body.should eql("Multipage 2\n") + @page.page_number.should eql(2) + @page.pages.should eql(3) + + @page = Page.find_page_by_path(%w(3)) + @page.should eql(pages(:home)) + @page.page_body.should eql("Multipage 3\n") + @page.page_number.should eql(3) + @page.pages.should eql(3) + end + + it "should default to the first page" do + @page = Page.find_page_by_path([]) + @page.should eql(pages(:home)) + @page.page_body.should eql("Multipage 1\n") + @page.page_number.should eql(1) + @page.pages.should eql(3) + end + + it "should return nil when page number is out of bounds" do + @page = Page.find_page_by_path(%w(0)) + @page.should be_nil + end + + it "should return page with a nil page_body when it exceeds the maximum page number (DEPRECATION: This behavior needs to be changed)" do + @page = Page.find_page_by_path(%w(5)) + @page.should eql(pages(:home)) + @page.page_body.should be_nil + @page.page_number.should eql(5) + @page.pages.should eql(3) + end + + it "should descend and verify each path of the page" do + Page.find_page_by_path(%w(second third 5 fourth)).should be_nil + Page.find_page_by_path(%w(second 5)).should be_nil + Page.find_page_by_path(%w(2 second third)).should be_nil + Page.find_page_by_path(%w(second third fourth)).should eql(pages(:fourth_level)) + end + end + + it "should handle home/1, home/2, etc. pages" + + end + + describe "#find_child" do + + it "should find a child page by name" do + # Since home and '' have funkiness, better test something from mid-level + Page.find_by_name("second").find_child(pages(:third_level).name).should eql(pages(:third_level)) + end + + it "should find a child page of home despite the weird home alias" do + Page.find_by_name("home").should eql(pages(:home)) + Page.find_by_name("home").find_child(pages(:second_level).name).should eql(pages(:second_level)) + end + + it "should return nil if it cannot find the child page by name" do + Page.find_by_name("second").find_child(pages(:fourth_level).name).should be_nil + # swap_test1 is in a different branch from second_level + Page.find_by_name("second").find_child(pages(:swap_test1).name).should be_nil + end + + it "should return nil if the child is unpublished" do + pages(:unpublished).parent.should eql(pages(:second_level)) + Page.find_by_name("second").find_child(pages(:unpublished).name).should be_nil + end + + end + + describe "#split_page!" do + before(:each) do + @page = Page.create( + :name => 'test', + :title => 'Test Page Type', + :parent => pages(:second_level), + :body => 'No multipage' + ) + @page.reload + @page.page_type.should eql("page") + + @page.update_attributes(:body => "Multipage 1\n{pagebreak}Multipage 2\n{pagebreak}Multipage 3\n") + @page.reload + # Must split pages, or page_number an pages will NOT be set + @page.split_page! + end + + it "should automatically detect {pagebreak} and convert the page to a multipage" do + @page.page_type.should eql("multipage") + @page.page_number.should eql(1) + end + + it "should set page_number to 1 after converting a page to a multipage" do + @page.page_number.should eql(1) + end + + it "should set page body to the first page after converting a page to a multipage" do + @page.page_body.should eql("Multipage 1\n") + end + + it "should set pages after converting a page to a multipage" do + @page.pages.should eql(3) + end + + it "should accept a page number and set the appropriate multipage values" do + 1.upto(3) do |p| + @page.split_page!(p) + @page.page_number.should eql(p) + @page.pages.should eql(3) + @page.page_body.should eql("Multipage #{p}\n") + end + end + + it "should handle out-of-bound page splits gracefully" do + [0, 5, 23].each do |p| + @page.split_page!(p) + @page.page_number.should eql(p) + @page.pages.should eql(3) + @page.page_body.should be_nil + end + end + + it "should handle non-multipage gracefully" do + @page.update_attributes(:body => "Back to normal page") + @page.reload + + @page.split_page! + @page.page_number.should eql(1) + @page.pages.should eql(1) + @page.page_body.should eql(@page.body) + end + + end + + describe "#swap!" do + + def check_page_order(*args) + # Reset @siblings when this called + @siblings = pages(:swap_test1).self_and_siblings + @siblings.each_with_index do |page, i| + page.should eql(pages("swap_test#{args[i]}")) + # Page order is not recalculated, they are just swapped + page.page_order.should eql(pages("swap_test#{i + 1}").page_order) + end + end + + before(:each) do + # Check fixture integrity + pages(:swap_test).should have(3).children + @siblings = pages(:swap_test1).self_and_siblings + @siblings.length.should eql(3) + + # Check siblings return correct page ordering + check_page_order(1, 2, 3) + end + + it "should ignore out-of-bound swaps" do + # Swap 0 with -1 + @siblings[0].swap!(-1).should be_nil + check_page_order(1, 2, 3) + + # Swap 2 with 3 + @siblings[2].swap!(1).should be_nil + check_page_order(1, 2, 3) + + # Swap 1 with -1 + @siblings[1].swap!(-2).should be_nil + check_page_order(1, 2, 3) + + # Swap 1 with 3 + @siblings[1].swap!(2).should be_nil + check_page_order(1, 2, 3) + end + + it "should swap a page with a number page relative to it in page order" do + @siblings[0].swap!(1).should_not be_nil + check_page_order(2, 1, 3) + + @siblings[1].swap!(1).should_not be_nil + check_page_order(2, 3, 1) + + @siblings[1].swap!(-1).should_not be_nil + check_page_order(3, 2, 1) + + @siblings[2].swap!(-2).should_not be_nil + check_page_order(1, 2, 3) + end + + + end + + +end diff --git a/spec/models/page_test.rb b/spec/models/page_test.rb new file mode 100644 index 0000000..076e8d6 --- /dev/null +++ b/spec/models/page_test.rb @@ -0,0 +1,370 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class PageTest < Test::Unit::TestCase + fixtures :pages + + # Replace this with your real tests. + def test_ancestor_path + page = Page.find_by_name "home" + assert_equal page.ancestor_path, "/" + page = Page.find_by_name "second" + assert_equal page.ancestor_path, "/" + page = Page.find_by_name "third" + assert_equal page.ancestor_path, "/second/" + page = Page.find_by_name "fourth" + assert_equal page.ancestor_path, "/second/third/" + end + + def test_full_title + page = Page.find_by_name "home" + assert_equal page.full_title, pages(:home).full_title + assert_equal page.title, pages(:home).title + + page = Page.find_by_name "second" + assert_equal page.title, pages(:second_level).title + assert_equal page.full_title, page.title + end + + def test_publishable_children + pages = pages(:second_level).children + assert_equal pages.length, 2 + pages = pages(:second_level).publishable_children + assert_equal pages.length, 1 + end + + def test_find_page_by_path + page = Page.find_page_by_path [] + assert_equal page, pages(:home) + page = Page.find_page_by_path %w(home) + assert_equal page, pages(:home) + page = Page.find_page_by_path %w(second) + assert_equal page, pages(:second_level) + page = Page.find_page_by_path %w(second third) + assert_equal page, pages(:third_level) + page = Page.find_page_by_path %w(second third fourth) + assert_equal page, pages(:fourth_level) + page = Page.find_page_by_path %w(fourth third second) + assert_nil page + end + + def test_find_page_by_path_invalid + assert_nil(Page.find_page_by_path([""] * 4)) + assert_nil(Page.find_page_by_path(["second", "", "third"])) + assert_nil(Page.find_page_by_path(["second", "third", ""])) + end + + def test_find_page_by_path_multipage + multipage = pages(:fourth_level) + multipage.body = "Multipage 1\n{pagebreak}Multipage 2\n{pagebreak}Multipage 3\n" + multipage.save + multipage.reload + test_find_page_by_path + test_find_page_by_path_invalid + + page = Page.find_page_by_path %w(second third fourth 1) + assert_equal page, pages(:fourth_level) + assert_equal page.page_body, "Multipage 1\n" + assert_equal page.page_number, 1 + assert_equal page.pages, 3 + + page = Page.find_page_by_path %w(second third fourth 2) + assert_equal page, pages(:fourth_level) + assert_equal page.page_body, "Multipage 2\n" + assert_equal page.page_number, 2 + assert_equal page.pages, 3 + + page = Page.find_page_by_path %w(second third fourth 3) + assert_equal page, pages(:fourth_level) + assert_equal page.page_body, "Multipage 3\n" + assert_equal page.page_number, 3 + assert_equal page.pages, 3 + + page = Page.find_page_by_path %w(second third fourth ) + assert_equal page, pages(:fourth_level) + assert_equal page.page_body, "Multipage 1\n" + assert_equal page.page_number, 1 + assert_equal page.pages, 3 + + # Out of bounds check + page = Page.find_page_by_path %w(second third fourth 0) + assert_nil page + + page = Page.find_page_by_path %w(second third fourth 5) + assert_equal page, pages(:fourth_level) + assert_nil page.page_body + assert_equal page.page_number, 5 + assert_equal page.pages, 3 + + page = Page.find_page_by_path %w(second third 5 fourth) + assert_nil page + page = Page.find_page_by_path %w(second third 5) + assert_nil page + end + + def test_find_page_by_path_multipage_third_level + multipage = pages(:third_level) + multipage.body = "Multipage 1\n{pagebreak}Multipage 2\n{pagebreak}Multipage 3\n" + multipage.save + multipage.reload + + # Multipage in the middle of the path should be ignored + test_find_page_by_path + test_find_page_by_path_invalid + + page = Page.find_page_by_path %w(second third 1) + assert_equal page, pages(:third_level) + assert_equal page.page_body, "Multipage 1\n" + assert_equal page.page_number, 1 + assert_equal page.pages, 3 + + page = Page.find_page_by_path %w(second third 2) + assert_equal page, pages(:third_level) + assert_equal page.page_body, "Multipage 2\n" + assert_equal page.page_number, 2 + assert_equal page.pages, 3 + + page = Page.find_page_by_path %w(second third 3) + assert_equal page, pages(:third_level) + assert_equal page.page_body, "Multipage 3\n" + assert_equal page.page_number, 3 + assert_equal page.pages, 3 + + page = Page.find_page_by_path %w(second third ) + assert_equal page, pages(:third_level) + assert_equal page.page_body, "Multipage 1\n" + assert_equal page.page_number, 1 + assert_equal page.pages, 3 + + # Out of bounds check + page = Page.find_page_by_path %w(second third 0) + assert_nil page + + page = Page.find_page_by_path %w(second third 5) + assert_equal page, pages(:third_level) + assert_nil page.page_body + assert_equal page.page_number, 5 + assert_equal page.pages, 3 + + page = Page.find_page_by_path %w(second third 5 fourth) + assert_nil page + page = Page.find_page_by_path %w(second 5) + assert_nil page + page = Page.find_page_by_path %w(2 second third) + assert_nil page + page = Page.find_page_by_path %w(second third fourth) + assert_equal page, pages(:fourth_level) + end + + def test_find_page_by_path_multipage_home + multipage = pages(:home) + multipage.body = "Multipage 1\n{pagebreak}Multipage 2\n{pagebreak}Multipage 3\n" + multipage.save + multipage.reload + assert multipage, pages(:home) + + # Multipage in the middle of the path should be ignored + test_find_page_by_path + test_find_page_by_path_invalid + + page = Page.find_page_by_path %w(1) + assert_equal page, pages(:home) + assert_equal page.page_body, "Multipage 1\n" + assert_equal page.page_number, 1 + assert_equal page.pages, 3 + + page = Page.find_page_by_path %w(2) + assert_equal page, pages(:home) + assert_equal page.page_body, "Multipage 2\n" + assert_equal page.page_number, 2 + assert_equal page.pages, 3 + + page = Page.find_page_by_path %w(3) + assert_equal page, pages(:home) + assert_equal page.page_body, "Multipage 3\n" + assert_equal page.page_number, 3 + assert_equal page.pages, 3 + + page = Page.find_page_by_path %w() + assert_equal page, pages(:home) + assert_equal page.page_body, "Multipage 1\n" + assert_equal page.page_number, 1 + assert_equal page.pages, 3 + + # Out of bounds check + page = Page.find_page_by_path %w(0) + assert_nil page + + page = Page.find_page_by_path %w(5) + assert_equal page, pages(:home) + assert_nil page.page_body + assert_equal page.page_number, 5 + assert_equal page.pages, 3 + + page = Page.find_page_by_path %w(second third 5 fourth) + assert_nil page + page = Page.find_page_by_path %w(second 5) + assert_nil page + page = Page.find_page_by_path %w(2 second third) + assert_nil page + page = Page.find_page_by_path %w(second third fourth) + assert_equal page, pages(:fourth_level) + end + + def test_find_child + page = Page.find_by_name "home" + assert_equal page, pages(:home) + page = page.find_child(pages(:second_level).name) + assert_equal page, pages(:second_level) + page = page.find_child(pages(:third_level).name) + assert_equal page, pages(:third_level) + page = page.find_child(pages(:fourth_level).name) + assert_equal page, pages(:fourth_level) + page = pages(:second_level).find_child(pages(:fourth_level).name) + assert_nil page + page = pages(:second_level).find_child(pages(:swap_test1).name) + assert_nil page + page = pages(:second_level).find_child(pages(:unpublished).name) + assert_nil page + end + + def test_page_type + page = Page.new + page.name = "test" + page.title = "Test Page Type" + page.parent = pages(:second_level) + page.body = "No multipage" + page.save + page.reload + assert_equal page.page_type, "page" + page.split_page! + assert_equal page.page_number, 1 + assert_equal page.pages, 1 + assert page.body, page.page_body + #find_page = Page.find_page_by_path(%w() + + page.body = "Multipage 1\n{pagebreak}Multipage 2\n{pagebreak}Multipage 3\n" + assert_equal page.page_type, "page" # Test before_save filter + page.save + page.reload + assert_equal page.page_type, "multipage" + + # Check defaults + page.split_page! + assert_equal page.page_number, 1 + assert_equal page.pages, 3 + assert_equal page.page_body, "Multipage 1\n" + + + # Check in-bound splits + 1.upto(3) do |i| + page.split_page!(i) + assert_equal page.page_number, i + assert_equal page.pages, 3 + assert_equal page.page_body, "Multipage #{i}\n" + end + + # Check out-of-boundsplits + page.split_page!(0) + assert_equal page.page_number, 0 + assert_equal page.pages, 3 + assert_nil page.page_body + + page.split_page!(5) + assert_equal page.page_number, 5 + assert_equal page.pages, 3 + assert_nil page.page_body + + # Saving back to a normal page + page.body = "Back to normal page" + assert_equal page.page_type, "multipage" + page.save + page.reload + assert_equal page.page_type, "page" + + page.split_page! + assert_equal page.page_number, 1 + assert_equal page.pages, 1 + assert page.body, page.page_body + end + + def test_page_swap + # Check fixture integrity + assert_equal pages(:swap_test).children.size, 3 + siblings = pages(:swap_test1).self_and_siblings + assert_equal siblings.length, 3 + + # Check siblings return correct page ordering + assert_equal siblings[0], pages(:swap_test1) + assert_equal siblings[1], pages(:swap_test2) + assert_equal siblings[2], pages(:swap_test3) + assert_equal siblings[0].page_order, pages(:swap_test1).page_order + assert_equal siblings[1].page_order, pages(:swap_test2).page_order + assert_equal siblings[2].page_order, pages(:swap_test3).page_order + + # Check out of bounds + assert_nil siblings[0].swap!(-1) + assert_nil siblings[2].swap!(1) + assert_nil siblings[1].swap!(-2) + assert_nil siblings[1].swap!(2) + + # Check first swap + assert siblings[0].swap!(1) + siblings = pages(:swap_test1).self_and_siblings + assert_equal siblings.length, 3 + assert_equal siblings[0], pages(:swap_test2) + assert_equal siblings[1], pages(:swap_test1) + assert_equal siblings[2], pages(:swap_test3) + # Page order in the fixture should still remain the same + assert_equal siblings[0].page_order, pages(:swap_test1).page_order + assert_equal siblings[1].page_order, pages(:swap_test2).page_order + assert_equal siblings[2].page_order, pages(:swap_test3).page_order + + # Check second swap + assert siblings[1].swap!(1) + siblings = pages(:swap_test1).self_and_siblings + assert_equal siblings.length, 3 + assert_equal siblings[0], pages(:swap_test2) + assert_equal siblings[1], pages(:swap_test3) + assert_equal siblings[2], pages(:swap_test1) + # Page order in the fixture should still remain the same + assert_equal siblings[0].page_order, pages(:swap_test1).page_order + assert_equal siblings[1].page_order, pages(:swap_test2).page_order + assert_equal siblings[2].page_order, pages(:swap_test3).page_order + + # Check third swap + assert siblings[1].swap!(-1) + siblings = pages(:swap_test1).self_and_siblings + assert_equal siblings.length, 3 + assert_equal siblings[0], pages(:swap_test3) + assert_equal siblings[1], pages(:swap_test2) + assert_equal siblings[2], pages(:swap_test1) + # Page order in the fixture should still remain the same + assert_equal siblings[0].page_order, pages(:swap_test1).page_order + assert_equal siblings[1].page_order, pages(:swap_test2).page_order + assert_equal siblings[2].page_order, pages(:swap_test3).page_order + + # Check fourth swap + assert siblings[2].swap!(-2) + siblings = pages(:swap_test1).self_and_siblings + assert_equal siblings.length, 3 + assert_equal siblings[0], pages(:swap_test1) + assert_equal siblings[1], pages(:swap_test2) + assert_equal siblings[2], pages(:swap_test3) + # Page order in the fixture should still remain the same + assert_equal siblings[0].page_order, pages(:swap_test1).page_order + assert_equal siblings[1].page_order, pages(:swap_test2).page_order + assert_equal siblings[2].page_order, pages(:swap_test3).page_order + end + + def test_page_order_integrity + page = Page.new + page.name = "page_order_integrity" + page.title = "Test Page Order Integrity" + page.parent = pages(:swap_test) + page.body = "page_order_integrity" + page.page_order = pages(:swap_test1).page_order + page.save + page = Page.find_by_name 'page_order_integrity' + assert_equal page.page_order, page.last_page + end +end