Skip to content
This repository has been archived by the owner on Aug 15, 2018. It is now read-only.

Commit

Permalink
added page controller test, initial xml output for pages
Browse files Browse the repository at this point in the history
  • Loading branch information
Josh Adams committed Apr 20, 2009
1 parent 5bd3c74 commit 8592dcf
Show file tree
Hide file tree
Showing 12 changed files with 255 additions and 52 deletions.
31 changes: 26 additions & 5 deletions app/controllers/page_controller.rb
Expand Up @@ -3,15 +3,36 @@ class PageController < ApplicationController
# http://domain.com/* -> maps to the tree structure stored in db
# Currently in need of some serious refactoring
def indexer
handle_xml
logger.info params['path'].inspect
@page = Page.visible.find_page_by_path params['path']
@breadcrumb = @page.ancestors.reverse.collect { |x| [x.full_path, x.title] } if @page
@top_page = params[:path][0] || 'root'
render :template => "404", :status => 404, :layout => false and return unless @page
if @page.is_published? || (logged_in? && current_user.can_view_drafts?)
render :template => 'content/page' and return if @page.page_type == "page"
else
render :template => 'content/unpublished' and return if @page.page_type == "page"
respond_to do |format|
format.html do
if @page.is_published? || (logged_in? && current_user.can_view_drafts?)
render :template => 'content/page' and return if @page.page_type == "page"
else
render :template => 'content/unpublished' and return if @page.page_type == "page"
end
render :template => 'content/multipage' # FIXME: we seem to never, ever hit this anyway
end
format.xml do
@page.page_plugins
render :xml => @page.to_xml
end
end
end

protected
# FIXME: This is awful, awful, but due to our route for pages, necessary at present
def handle_xml
if params['path'].is_a?(Array)
if params['path'].last =~ /\.xml/
request.format = :xml
params['path'].last.gsub!(/\.xml/, '')
end
end
render :template => 'content/multipage'
end
end
18 changes: 17 additions & 1 deletion app/models/page.rb
Expand Up @@ -30,7 +30,7 @@ class Page < ActiveRecord::Base

validates_presence_of :name, :title

named_scope :visible, lambda{ { :conditions => ["(expires_on > ? OR expires_on IS NULL) AND published = ? AND (publish_at <= ? OR publish_at IS NULL )", Time.now.getgm, true, Time.now.getgm] } }
named_scope :visible, lambda{ { :conditions => ["(expires_on > ? OR expires_on IS NULL) AND status = 'published' AND (publish_at <= ? OR publish_at IS NULL )", Time.now.getgm, Time.now.getgm] } }
named_scope :self_and_siblings, lambda {|page| {:conditions => ["parent_id = ?", page.parent_id], :order => 'page_order'}}
named_scope :expired, lambda {|p| { :conditions => ["expires_on < ?", Time.now.getgm] } }
named_scope :expires_soon, lambda {|p| { :conditions => ["expires_on < ?", Time.now.getgm + 5.days ] } }
Expand Down Expand Up @@ -187,8 +187,10 @@ def find_child(child_name)

# Accepts params[:path] and returns the page object or nil
def self.find_page_by_path(path)
logger.info path.inspect
#logger.error("==> find_page_by_path: path = [ #{path.join("/")} ]")
page = Page.root
return page if path == ['home'] # hack to make calling the home page path easier
return nil if page.nil?

# Not DRY. This piece of code handles multipage root
Expand Down Expand Up @@ -251,6 +253,20 @@ def permalinkable_title
title.downcase.gsub(/ /, '-')
end

def to_xml(options = {})
options[:indent] ||= 2
xml = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
xml.instruct! unless options[:skip_instruct]
xml.page do
attributes.to_xml(:builder => xml, :skip_instruct => true, :root => "attributes")
xml.tag!("page-plugins") do
self.page_plugins.each do |page_plugin|
page_plugin.module.attributes.to_xml(:builder => xml, :skip_instruct => true, :root => 'page-plugin')
end
end
end
end

protected
def check_page_type
self.page_type = "page" and return if self.body.blank? || (@split_pages = self.body.split(/\{pagebreak\}/i)).length == 1
Expand Down
4 changes: 4 additions & 0 deletions app/models/page_plugin.rb
Expand Up @@ -24,6 +24,10 @@ def module
end
end

def module_xml
self.module.to_xml(:skip_instruct => true)
end

def module_class
Object.path2class(module_type)
end
Expand Down
1 change: 1 addition & 0 deletions config/environment.rb
Expand Up @@ -58,6 +58,7 @@
config.gem 'thoughtbot-shoulda', :lib => 'shoulda', :source => 'http://gems.github.com'
config.gem 'thoughtbot-factory_girl', :lib => 'factory_girl', :source => 'http://gems.github.com'
config.gem 'flexmock'
config.gem 'hpricot', :source => 'http://code.whytheluckystiff.net'

config.gem 'spicycode-rcov', :lib => 'rcov', :source => 'http://gems.github.com'
config.gem 'jgre-monkeyspecdoc', :lib => 'monkeyspecdoc', :source => 'http://gems.github.com'
Expand Down
60 changes: 60 additions & 0 deletions lib/hpricot_test_helper.rb
@@ -0,0 +1,60 @@
require 'hpricot'

module HpricotTestHelper
# returns the inner content of
# the first tag found by the css query
def tag(css_query)
process_output
@output.content_for(css_query)
end

# returns an array of tag contents
# for all of the tags found by the
# css query
def tags(css_query)
process_output
@output.content_for_all(css_query)
end

# returns a raw Hpricot::Elem object
# for the first result found by the query
def element(css_query)
process_output
@output[css_query].first
end

# returns an array of Hpricot::Elem objects
# for the results found by the query
def elements(css_query)
process_output
@output[css_query]
end

# small utility class for working with
# the Hpricot parser class
class DocumentOutput
def initialize(response_body)
@parser = Hpricot.parse(response_body)
end

def content_for(css_query)
@parser.search(css_query).first.inner_text
end

def content_for_all(css_query)
@parser.search(css_query).collect(&:inner_text)
end

def [](css_query)
@parser.search(css_query)
end
end

protected
# creates a new DocumentOutput object from the response
# body if hasn't already been created. This is
# called automatically by the element and tag methods
def process_output(force=false)
@output = HpricotTestHelper::DocumentOutput.new(@response.body) if @output.nil? || force
end
end
2 changes: 1 addition & 1 deletion test/factories.rb
@@ -1,5 +1,5 @@
Factory.sequence :page_name do |pn|
"Page #{pn}"
"home#{pn}"
end

Factory.sequence :user_login do |n|
Expand Down
4 changes: 4 additions & 0 deletions test/fixtures/content_sections.yml
@@ -0,0 +1,4 @@
home_content:
id: 1
name: home content
contents: These are the contents
29 changes: 5 additions & 24 deletions test/fixtures/page_plugins.yml
@@ -1,25 +1,6 @@
# == Schema Information
# Schema version: 20090125222830
#
# Table name: page_plugins
#
# id :integer(4) not null, primary key
# page_id :integer(4)
# module_type :string(255)
# module_id :integer(4)
# created_at :datetime
# updated_at :datetime
# position :integer(4)
#

# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html

one:
home_content:
id: 1
page_id: 1
module_type: MyString
module_id:

two:
page_id: 1
module_type: MyString
module_id:
module_type: "Ansuz::JAdams::ContentSection"
module_id: 1
position: 1
101 changes: 101 additions & 0 deletions test/fixtures/pages.yml
@@ -0,0 +1,101 @@
# == Schema Information
# Schema version: 2
#
# Table name: pages
#
# id :integer(11) not null, primary key
# name :string(255)
# title :string(255)
# full_title :string(255)
# body :text
# created_at :datetime
# updated_at :datetime
# page_order :integer(11) default(0)
# parent_id :integer(11)
# page_type :string(255) default("page")
# display_title :boolean(1) default(TRUE)
# published :boolean(1) default(TRUE)
# linked :boolean(1) default(TRUE)
# show_sub_menu :boolean(1)
#

# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
home:
id: 1
name: home
title: Home
full_title: Home Page
published: true
status: published
linked: true

second_level:
id: 2
name: second
title: Second Level
parent_id: 1
published: true
status: published
linked: true

third_level:
id: 3
name: third
title: Third Level
parent_id: 2
published: true
status: published
linked: true

fourth_level:
id: 9
name: fourth
title: Fourth Level
parent_id: 3
published: true
status: published
linked: true

unpublished:
id: 4
name: unpublished
title: Unpublished
parent_id: 2
published: false
status: draft
linked: false

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

expired:
id: 245
name: Expired
title: Expired test
parent_id: 9
page_order: 5
expires_on: <%= 2.days.ago %>
21 changes: 0 additions & 21 deletions test/fixtures/proto_page_plugins.yml

This file was deleted.

33 changes: 33 additions & 0 deletions test/functional/page_controller_test.rb
@@ -0,0 +1,33 @@
require 'test_helper'

class PageControllerTest < ActionController::TestCase
context "When hitting /pages/" do
setup do
# set up a page to visit
@page = pages(:home)
end
context "as a public user" do
context "for html" do
setup do
get :indexer, :path => ["home"]
end

should_respond_with :ok
should "have the content section module's content included" do
assert_select "div.page-plugin-0"
end
end

context "for xml" do
setup do
get :indexer, :path => ["home.xml"]
end

should_respond_with :ok
should "have the content section module's content included" do
assert tag("page page-plugins page-plugin contents")
end
end
end
end
end
3 changes: 3 additions & 0 deletions test/test_helper.rb
Expand Up @@ -4,11 +4,14 @@
require 'test/role_requirement_test_helper'
require 'flexmock/test_unit'
require 'exception_macros'
require 'hpricot_test_helper'

class Test::Unit::TestCase
# RoleRequirementTestHelper must be included to test RoleRequirement
include RoleRequirementTestHelper

include HpricotTestHelper

# Transactional fixtures accelerate your tests by wrapping each test method
# in a transaction that's rolled back on completion. This ensures that the
# test database remains unchanged so your fixtures don't have to be reloaded
Expand Down

0 comments on commit 8592dcf

Please sign in to comment.