1 require File.dirname(__FILE__) + '/../spec_helper'
3 class PageSpecTestPage < Page
4 description 'this is just a test page'
9 'request' => @request.inspect[20..30],
10 'response' => @response.inspect[20..31]
23 describe Page, 'validations' do
25 test_helper :validations
28 @page = @model = Page.new(page_params)
31 it 'should validate length of' do
36 }.each do |field, max|
37 assert_invalid field, ('%d-character limit' % max), 'x' * (max + 1)
38 assert_valid field, 'x' * max
42 it 'should validate presence of' do
43 [:title, :slug, :breadcrumb].each do |field|
44 assert_invalid field, 'required', '', ' ', nil
48 it 'should validate format of' do
49 @page.parent = pages(:home)
50 assert_valid :slug, 'abc', 'abcd-efg', 'abcd_efg', 'abc.html', '/', '123'
51 assert_invalid :slug, 'invalid format', 'abcd efg', ' abcd', 'abcd/efg'
54 it 'should validate numericality of' do
55 assert_invalid :status_id, 'required', '', nil
56 [:id, :status_id, :parent_id].each do |field|
57 assert_valid field, '1', '2'
58 assert_invalid field, 'must be a number', 'abcd', '1,2', '1.3'
62 it 'should validate uniqueness of' do
63 @page.parent = pages(:parent)
64 assert_invalid :slug, 'slug already in use for child of parent', 'child', 'child-2', 'child-3'
65 assert_valid :slug, 'child-4'
68 it 'should allow mass assignment for class name' do
69 @page.attributes = { :class_name => 'ArchivePage' }
71 @page.class_name.should == 'ArchivePage'
74 it 'should not be valid when class name is not a descendant of page' do
75 @page.class_name = 'Object'
76 @page.valid?.should == false
77 assert_not_nil @page.errors.on(:class_name)
78 @page.errors.on(:class_name).should == 'must be set to a valid descendant of Page'
81 it 'should not be valid when class name is not a descendant of page and it is set through mass assignment' do
82 @page.attributes = {:class_name => 'Object' }
83 @page.valid?.should == false
84 assert_not_nil @page.errors.on(:class_name)
85 @page.errors.on(:class_name).should == 'must be set to a valid descendant of Page'
88 it 'should be valid when class name is page or empty or nil' do
89 [nil, '', 'Page'].each do |value|
90 @page = ArchivePage.new(page_params)
91 @page.class_name = value
93 @page.class_name.should == value
98 describe Page, "behaviors" do
99 it 'should include' do
100 Page.included_modules.should include(StandardTags)
101 Page.included_modules.should include(Annotatable)
105 describe Page, "layout" do
106 scenario :pages_with_layouts
108 it 'should be accessible' do
109 @page = pages(:first)
110 @page.layout_id.should == layout_id(:main)
111 @page.layout.name.should == "Main"
114 it 'should be inherited' do
115 @page = pages(:inherited_layout)
116 @page.layout_id.should == nil
117 @page.layout.should == @page.parent.layout
125 @page = pages(:first)
128 it 'should have parts' do
129 @page.parts.count.should == 1
130 pages(:home).parts.count.should == 4
133 it 'should destroy dependant parts' do
134 @page.parts.create(page_part_params(:name => 'test', :page_id => nil))
135 assert_kind_of PagePart, @page.parts.find_by_name('test')
139 assert_nil PagePart.find_by_page_id_and_name(id, 'test')
142 it 'should allow access to parts by name with a string' do
143 part = @page.part('body')
144 part.name.should == 'body'
147 it 'should allow access to parts by name with a symbol' do
148 part = @page.part(:body)
149 part.name.should == 'body'
152 it 'should allow access to parts by name when page is unsaved' do
153 part = PagePart.new(:content => "test", :name => "test")
155 @page.part('test').should == part
156 @page.part(:test).should == part
159 it 'should allow access to parts by name created with the build method when page is unsaved' do
160 @page.parts.build(:content => "test", :name => "test")
161 @page.part('test').content.should == "test"
162 @page.part(:test).content.should == "test"
165 it 'should set published_at when published' do
166 @page = Page.new(page_params(:status_id => '1', :published_at => nil))
167 assert_nil @page.published_at
169 @page.status_id = Status[:published].id
171 assert_not_nil @page.published_at
172 @page.published_at.day.should == Time.now.day
175 it 'should not update published_at when already published' do
176 @page = Page.new(page_params(:status_id => Status[:published].id))
177 @page.published_at.should be_kind_of(Time)
179 expected = @page.published_at
181 @page.published_at.should == expected
184 it 'should answer true when published' do
185 @page.status = Status[:published]
186 @page.published?.should == true
189 it 'should answer false when not published' do
190 @page.status = Status[:draft]
191 @page.published?.should be_false
194 it "should answer the page's url" do
195 @page = pages(:parent)
196 @page.url.should == '/parent/'
197 @page.children.first.url.should == '/parent/child/'
199 grandchild = pages(:grandchild)
200 grandchild.url.should == '/parent/child/grandchild/'
203 it 'should allow you to calculate a child url from the parent' do
204 @page = pages(:parent)
205 child = pages(:child)
206 @page.child_url(child).should == '/parent/child/'
209 it 'should return the appropriate status code in headers' do
210 @page.headers.should == { 'Status' => ActionController::Base::DEFAULT_RENDER_STATUS_CODE }
213 it 'should have status' do
215 @page.status.should == Status[:published]
218 it 'should allow you to set the status' do
220 draft = Status[:draft]
222 @page.status.should == draft
223 @page.status_id.should == draft.id
226 it 'should respond to cache? with true (by default)' do
227 @page.cache?.should == true
230 it 'should respond to virtual? with false (by default)' do
231 @page.virtual?.should == false
234 it 'should allow you to tell if a part exists based on a string or symbol' do
236 @page.has_part?(:body).should == true
237 @page.has_part?('sidebar').should == true
238 @page.has_part?(:obviously_false_part_name).should == false
241 it 'should allow you to tell if a part is inherited' do
242 @page = pages(:child)
243 @page.has_part?(:sidebar).should == false
244 @page.inherits_part?(:sidebar).should == true
247 @page.has_part?(:sidebar).should == true
248 @page.inherits_part?(:sidebar).should == false
251 it 'should allow you to tell if a part exists or is inherited' do
252 @page = pages(:child)
253 @page.has_part?(:sidebar).should == false
254 @page.has_or_inherits_part?(:sidebar).should == true
255 @page.has_or_inherits_part?(:obviously_false_part_name).should == false
258 @page.has_part?(:sidebar).should == true
259 @page.has_or_inherits_part?(:sidebar).should == true
260 @page.has_or_inherits_part?(:obviously_false_part_name).should == false
263 it 'should support optimistic locking' do
264 p1, p2 = pages(:first), pages(:first)
266 lambda { p2.save! }.should raise_error(ActiveRecord::StaleObjectError)
270 describe Page, "before save filter" do
274 Page.create(page_params(:title =>"Month Index", :class_name => "ArchiveMonthIndexPage"))
275 @page = Page.find_by_title("Month Index")
278 it 'should set the class name correctly' do
279 @page.should be_kind_of(ArchiveMonthIndexPage)
282 it 'should set the virtual bit correctly' do
283 @page.virtual?.should == true
284 @page.virtual.should == true
287 it 'should update virtual based on new class name' do
288 # turn a regular page into a virtual page
289 @page.class_name = "ArchiveMonthIndexPage"
290 @page.save.should == true
291 @page.virtual?.should == true
292 @page.send(:read_attribute, :virtual).should == true
294 # turn a virtual page into a non-virtual one
295 ["", nil, "Page", "EnvDumpPage"].each do |value|
296 @page = ArchiveYearIndexPage.create(page_params)
297 @page.class_name = value
298 @page.save.should == true
299 @page = Page.find @page.id
300 @page.should be_instance_of(Page.descendant_class(value))
301 @page.virtual?.should == false
302 @page.send(:read_attribute, :virtual).should == false
307 describe Page, "rendering" do
308 scenario :pages, :markup_pages, :snippets, :layouts
315 it 'should render' do
316 @page.render.should == 'Hello world!'
319 it 'should render with a filter' do
320 pages(:textile).render.should == '<p>Some <strong>Textile</strong> content.</p>'
323 it 'should render with tags' do
324 pages(:radius).render.should == "Radius body."
327 it 'should render with a layout' do
328 @page.update_attribute(:layout_id, layout_id(:main))
329 @page.render.should == "<html>\n <head>\n <title>Home</title>\n </head>\n <body>\n Hello world!\n </body>\n</html>\n"
332 it 'should render a part' do
333 @page.render_part(:body).should == "Hello world!"
336 it 'should render a snippet' do
337 assert_snippet_renders :first, 'test'
340 it 'should render a snippet with a filter' do
341 assert_snippet_renders :markdown, '<p><strong>markdown</strong></p>'
344 it 'should render a snippet with a tag' do
345 assert_snippet_renders :radius, 'Home'
348 it 'should render custom pages with tags' do
349 create_page "Test Page", :body => "<r:test1 /> <r:test2 />", :class_name => "PageSpecTestPage"
350 pages(:test_page).should render_as('Hello world! Another test. body.')
354 describe Page, "#find_by_url" do
355 scenario :pages, :file_not_found
361 it 'should allow you to find the home page' do
362 @page.find_by_url('/') .should == @page
365 it 'should allow you to find deeply nested pages' do
366 @page.find_by_url('/parent/child/grandchild/great-grandchild/').should == pages(:great_grandchild)
369 it 'should not allow you to find virtual pages' do
370 @page.find_by_url('/virtual/').should == pages(:file_not_found)
373 it 'should find the FileNotFoundPage when a page does not exist' do
374 @page.find_by_url('/nothing-doing/').should == pages(:file_not_found)
377 it 'should find a custom file not found page' do
378 @page.find_by_url('/gallery/nothing-doing/').should == pages(:no_picture)
381 it 'should not find draft pages in live mode' do
382 @page.find_by_url('/draft/').should == pages(:file_not_found)
385 it 'should find draft pages in dev mode' do
386 @page.find_by_url('/draft/', false).should == pages(:draft)
390 describe Page, "class" do
391 it 'should have a description' do
392 PageSpecTestPage.description.should == 'this is just a test page'
395 it 'should have a display name' do
396 Page.display_name.should == "Page"
398 PageSpecTestPage.display_name.should == "Page Spec Test"
400 PageSpecTestPage.display_name = "New Name"
401 PageSpecTestPage.display_name.should == "New Name"
403 FileNotFoundPage.display_name.should == "File Not Found"
406 it 'should list decendants' do
407 descendants = Page.descendants
408 assert_kind_of Array, descendants
409 assert_match /PageSpecTestPage/, descendants.inspect
412 it 'should allow initialization with empty defaults' do
413 @page = Page.new_with_defaults({})
414 @page.parts.size.should == 0
417 it 'should allow initialization with default page parts' do
418 @page = Page.new_with_defaults({ 'defaults.page.parts' => 'a, b, c'})
419 @page.parts.size.should == 3
420 @page.parts.first.name.should == 'a'
421 @page.parts.last.name.should == 'c'
424 it 'should allow initialization with default page status' do
425 @page = Page.new_with_defaults({ 'defaults.page.status' => 'published' })
426 @page.status.should == Status[:published]
429 it 'should allow you to get the class name of a descendant class with a string' do
430 ["", nil, "Page"].each do |value|
431 Page.descendant_class(value).should == Page
433 Page.descendant_class("PageSpecTestPage").should == PageSpecTestPage
436 it 'should allow you to determine if a string is a valid descendant class name' do
437 ["", nil, "Page", "PageSpecTestPage"].each do |value|
438 Page.is_descendant_class_name?(value).should == true
440 Page.is_descendant_class_name?("InvalidPage").should == false
444 describe Page, "class find_by_url" do
445 scenario :pages, :file_not_found
447 it 'should find the home page' do
448 Page.find_by_url('/').should == pages(:home)
451 it 'should find children' do
452 Page.find_by_url('/parent/child/').should == pages(:child)
455 it 'should not find draft pages in live mode' do
456 Page.find_by_url('/draft/').should == pages(:file_not_found)
457 Page.find_by_url('/draft/', false).should == pages(:draft)
460 it 'should raise an exception when root page is missing' do
462 Page.find_by_parent_id().should be_nil
463 lambda { Page.find_by_url "/" }.should raise_error(Page::MissingRootPageError, 'Database missing root page')
467 describe Page, "processing" do
468 scenario :pages_with_layouts
471 @request = ActionController::TestRequest.new :url => '/page/'
472 @response = ActionController::TestResponse.new
475 it 'should set response body' do
477 @page.process(@request, @response)
478 @response.body.should match(/Hello world!/)
481 it 'should set headers and pass request and response' do
482 create_page "Test Page", :class_name => "PageSpecTestPage"
483 @page = pages(:test_page)
484 @page.process(@request, @response)
485 @response.headers['cool'].should == 'beans'
486 @response.headers['request'].should == 'TestRequest'
487 @response.headers['response'].should == 'TestResponse'
490 it 'should set content type based on layout' do
492 @page.process(@request, @response)
493 assert_response :success
494 @response.headers['Content-Type'].should == 'text/html;charset=utf8'