Skip to content

Instantly share code, notes, and snippets.

@lifo
Created March 5, 2009 22:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save lifo/74618 to your computer and use it in GitHub Desktop.
Save lifo/74618 to your computer and use it in GitHub Desktop.
commit ed20f4dcc656ac55adbe9515466ef19d102e9ead
Author: Pratik Naik <pratiknaik@gmail.com>
Date: Thu Mar 5 22:45:04 2009 +0000
should_be_fucking_restful
diff --git a/lib/shoulda/action_controller.rb b/lib/shoulda/action_controller.rb
index 4719851..3723c72 100644
--- a/lib/shoulda/action_controller.rb
+++ b/lib/shoulda/action_controller.rb
@@ -3,12 +3,17 @@ require 'shoulda/action_controller/helpers'
require 'shoulda/action_controller/matchers'
require 'shoulda/action_controller/macros'
+require 'shoulda/controller/resource_options'
+
module Test # :nodoc: all
module Unit
class TestCase
include Shoulda::ActionController::Matchers
include Shoulda::ActionController::Helpers
extend Shoulda::ActionController::Macros
+ Shoulda::Controller::VALID_FORMATS.each do |format|
+ include "Shoulda::Controller::#{format.to_s.upcase}".constantize
+ end
end
end
end
diff --git a/lib/shoulda/action_controller/helpers.rb b/lib/shoulda/action_controller/helpers.rb
index 654bf7b..59cbf78 100644
--- a/lib/shoulda/action_controller/helpers.rb
+++ b/lib/shoulda/action_controller/helpers.rb
@@ -42,6 +42,21 @@ module Shoulda # :nodoc:
instance_variable_set("@#{name}", old[name])
end
end
+
+ def get_existing_record(res) # :nodoc:
+ returning(instance_variable_get("@#{res.object}")) do |record|
+ assert(record, "This test requires you to set @#{res.object} in your setup block")
+ end
+ end
+
+ def make_parent_params(resource, record = nil, parent_names = nil) # :nodoc:
+ parent_names ||= resource.parents.reverse
+ return {} if parent_names == [] # Base case
+ parent_name = parent_names.shift
+ parent = record ? record.send(parent_name) : parent_name.to_s.classify.constantize.find(:first)
+
+ { :"#{parent_name}_id" => parent.to_param }.merge(make_parent_params(resource, parent, parent_names))
+ end
end
end
end
diff --git a/lib/shoulda/action_controller/macros.rb b/lib/shoulda/action_controller/macros.rb
index c9d5f75..b19fad5 100644
--- a/lib/shoulda/action_controller/macros.rb
+++ b/lib/shoulda/action_controller/macros.rb
@@ -21,9 +21,59 @@ module Shoulda # :nodoc:
# end
#
# Would produce 5 tests for the +show+ action
+ #
+ # Furthermore, the should_be_restful helper will create an entire set of tests which will verify that your
+ # controller responds restfully to a variety of requested formats.
module Macros
include Matchers
+ # <b>DEPRECATED:</b> Please see
+ # http://thoughtbot.lighthouseapp.com/projects/5807/tickets/78 for more
+ # information.
+ #
+ # Generates a full suite of tests for a restful controller.
+ #
+ # The following definition will generate tests for the +index+, +show+, +new+,
+ # +edit+, +create+, +update+ and +destroy+ actions, in both +html+ and +xml+ formats:
+ #
+ # should_be_restful do |resource|
+ # resource.parent = :user
+ #
+ # resource.create.params = { :title => "first post", :body => 'blah blah blah'}
+ # resource.update.params = { :title => "changed" }
+ # end
+ #
+ # This generates about 40 tests, all of the format:
+ # "on GET to :show should assign @user."
+ # "on GET to :show should not set the flash."
+ # "on GET to :show should render 'show' template."
+ # "on GET to :show should respond with success."
+ # "on GET to :show as xml should assign @user."
+ # "on GET to :show as xml should have ContentType set to 'application/xml'."
+ # "on GET to :show as xml should respond with success."
+ # "on GET to :show as xml should return <user/> as the root element."
+ # The +resource+ parameter passed into the block is a ResourceOptions object, and
+ # is used to configure the tests for the details of your resources.
+ #
+ def should_be_restful(&blk) # :yields: resource
+ resource = ::Shoulda::Controller::ResourceOptions.new
+ blk.call(resource)
+ resource.normalize!(self)
+
+ resource.formats.each do |format|
+ resource.actions.each do |action|
+ if self.respond_to? :"make_#{action}_#{format}_tests"
+ self.send(:"make_#{action}_#{format}_tests", resource)
+ else
+ should "test #{action} #{format}" do
+ flunk "Test for #{action} as #{format} not implemented"
+ end
+ end
+ end
+ end
+ end
+
+ # :section: Test macros
# Macro that creates a test asserting that the flash contains the given value.
# val can be a String, a Regex, or nil (indicating that the flash should not be set)
#
diff --git a/lib/shoulda/controller/formats/html.rb b/lib/shoulda/controller/formats/html.rb
new file mode 100644
index 0000000..1f77398
--- /dev/null
+++ b/lib/shoulda/controller/formats/html.rb
@@ -0,0 +1,199 @@
+module Shoulda # :nodoc:
+ module Controller # :nodoc:
+ module HTML # :nodoc: all
+ def self.included(other)
+ other.class_eval do
+ extend Shoulda::Controller::HTML::ClassMethods
+ end
+ end
+
+ module ClassMethods
+ def controller_name_from_class
+ self.name.gsub(/Test/, '')
+ end
+
+ def make_show_html_tests(res)
+ context "on GET to #{controller_name_from_class}#show" do
+ setup do
+ record = get_existing_record(res)
+ parent_params = make_parent_params(res, record)
+ get :show, parent_params.merge({ res.identifier => record.to_param })
+ end
+
+ if res.denied.actions.include?(:show)
+ should_not_assign_to res.object
+ should_redirect_to res.denied.redirect
+ should_set_the_flash_to res.denied.flash
+ else
+ should_assign_to res.object
+ should_respond_with :success
+ should_render_template :show
+ should_not_set_the_flash
+ end
+ end
+ end
+
+ def make_edit_html_tests(res)
+ context "on GET to #{controller_name_from_class}#edit" do
+ setup do
+ @record = get_existing_record(res)
+ parent_params = make_parent_params(res, @record)
+ get :edit, parent_params.merge({ res.identifier => @record.to_param })
+ end
+
+ if res.denied.actions.include?(:edit)
+ should_not_assign_to res.object
+ should_redirect_to res.denied.redirect
+ should_set_the_flash_to res.denied.flash
+ else
+ should_assign_to res.object
+ should_respond_with :success
+ should_render_template :edit
+ should_not_set_the_flash
+ should_render_a_form
+ should "set @#{res.object} to requested instance" do
+ assert_equal @record, assigns(res.object)
+ end
+ end
+ end
+ end
+
+ def make_index_html_tests(res)
+ context "on GET to #{controller_name_from_class}#index" do
+ setup do
+ record = get_existing_record(res) rescue nil
+ parent_params = make_parent_params(res, record)
+ get(:index, parent_params)
+ end
+
+ if res.denied.actions.include?(:index)
+ should_not_assign_to res.object.to_s.pluralize
+ should_redirect_to res.denied.redirect
+ should_set_the_flash_to res.denied.flash
+ else
+ should_respond_with :success
+ should_assign_to res.object.to_s.pluralize
+ should_render_template :index
+ should_not_set_the_flash
+ end
+ end
+ end
+
+ def make_new_html_tests(res)
+ context "on GET to #{controller_name_from_class}#new" do
+ setup do
+ record = get_existing_record(res) rescue nil
+ parent_params = make_parent_params(res, record)
+ get(:new, parent_params)
+ end
+
+ if res.denied.actions.include?(:new)
+ should_not_assign_to res.object
+ should_redirect_to res.denied.redirect
+ should_set_the_flash_to res.denied.flash
+ else
+ should_respond_with :success
+ should_assign_to res.object
+ should_not_set_the_flash
+ should_render_template :new
+ should_render_a_form
+ end
+ end
+ end
+
+ def make_destroy_html_tests(res)
+ context "on DELETE to #{controller_name_from_class}#destroy" do
+ setup do
+ @record = get_existing_record(res)
+ parent_params = make_parent_params(res, @record)
+ delete :destroy, parent_params.merge({ res.identifier => @record.to_param })
+ end
+
+ if res.denied.actions.include?(:destroy)
+ should_redirect_to res.denied.redirect
+ should_set_the_flash_to res.denied.flash
+
+ should "not destroy record" do
+ assert_nothing_raised { assert @record.reload }
+ end
+ else
+ should_set_the_flash_to res.destroy.flash
+ if res.destroy.redirect.is_a? Symbol
+ should_respond_with res.destroy.redirect
+ else
+ should_redirect_to res.destroy.redirect
+ end
+
+ should "destroy record" do
+ assert_raises(::ActiveRecord::RecordNotFound, "@#{res.object} was not destroyed.") do
+ @record.reload
+ end
+ end
+ end
+ end
+ end
+
+ def make_create_html_tests(res)
+ context "on POST to #{controller_name_from_class}#create with #{res.create.params.inspect}" do
+ setup do
+ record = get_existing_record(res) rescue nil
+ parent_params = make_parent_params(res, record)
+ @count = res.klass.count
+ post :create, parent_params.merge(res.object => res.create.params)
+ end
+
+ if res.denied.actions.include?(:create)
+ should_redirect_to res.denied.redirect
+ should_set_the_flash_to res.denied.flash
+ should_not_assign_to res.object
+
+ should "not create new record" do
+ assert_equal @count, res.klass.count
+ end
+ else
+ should_assign_to res.object
+ should_set_the_flash_to res.create.flash
+ if res.create.redirect.is_a? Symbol
+ should_respond_with res.create.redirect
+ else
+ should_redirect_to res.create.redirect
+ end
+
+ should "not have errors on @#{res.object}" do
+ assert_equal [], pretty_error_messages(assigns(res.object)), "@#{res.object} has errors:"
+ end
+ end
+ end
+ end
+
+ def make_update_html_tests(res)
+ context "on PUT to #{controller_name_from_class}#update with #{res.create.params.inspect}" do
+ setup do
+ @record = get_existing_record(res)
+ parent_params = make_parent_params(res, @record)
+ put :update, parent_params.merge(res.identifier => @record.to_param, res.object => res.update.params)
+ end
+
+ if res.denied.actions.include?(:update)
+ should_not_assign_to res.object
+ should_redirect_to res.denied.redirect
+ should_set_the_flash_to res.denied.flash
+ else
+ should_assign_to res.object
+ should_set_the_flash_to(res.update.flash)
+ if res.update.redirect.is_a? Symbol
+ should_respond_with res.update.redirect
+ else
+ should_redirect_to res.update.redirect
+ end
+
+ should "not have errors on @#{res.object}" do
+ assert_equal [], pretty_error_messages(assigns(res.object)), "@#{res.object} has errors:"
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/shoulda/controller/formats/xml.rb b/lib/shoulda/controller/formats/xml.rb
new file mode 100644
index 0000000..c8c97fd
--- /dev/null
+++ b/lib/shoulda/controller/formats/xml.rb
@@ -0,0 +1,168 @@
+module Shoulda # :nodoc:
+ module Controller # :nodoc:
+ module XML
+ def self.included(other) #:nodoc:
+ other.class_eval do
+ extend Shoulda::Controller::XML::ClassMethods
+ end
+ end
+
+ module ClassMethods
+ # Macro that creates a test asserting that the controller responded with an XML content-type
+ # and that the XML contains +<name/>+ as the root element.
+ def should_respond_with_xml_for(name = nil)
+ should "have ContentType set to 'application/xml'" do
+ assert_xml_response
+ end
+
+ if name
+ should "return <#{name}/> as the root element" do
+ body = @response.body.first(100).map {|l| " #{l}"}
+ assert_select name.to_s.dasherize, 1, "Body:\n#{body}...\nDoes not have <#{name}/> as the root element."
+ end
+ end
+ end
+ alias should_respond_with_xml should_respond_with_xml_for
+
+ protected
+
+ def make_show_xml_tests(res) # :nodoc:
+ context "on GET to #{controller_name_from_class}#show as xml" do
+ setup do
+ request_xml
+ record = get_existing_record(res)
+ parent_params = make_parent_params(res, record)
+ get :show, parent_params.merge({ res.identifier => record.to_param })
+ end
+
+ if res.denied.actions.include?(:show)
+ should_not_assign_to res.object
+ should_respond_with 401
+ else
+ should_assign_to res.object
+ should_respond_with :success
+ should_respond_with_xml_for res.object
+ end
+ end
+ end
+
+ def make_edit_xml_tests(res) # :nodoc:
+ # XML doesn't need an :edit action
+ end
+
+ def make_new_xml_tests(res) # :nodoc:
+ # XML doesn't need a :new action
+ end
+
+ def make_index_xml_tests(res) # :nodoc:
+ context "on GET to #{controller_name_from_class}#index as xml" do
+ setup do
+ request_xml
+ parent_params = make_parent_params(res)
+ get(:index, parent_params)
+ end
+
+ if res.denied.actions.include?(:index)
+ should_not_assign_to res.object.to_s.pluralize
+ should_respond_with 401
+ else
+ should_respond_with :success
+ should_respond_with_xml_for res.object.to_s.pluralize
+ should_assign_to res.object.to_s.pluralize
+ end
+ end
+ end
+
+ def make_destroy_xml_tests(res) # :nodoc:
+ context "on DELETE to #{controller_name_from_class}#destroy as xml" do
+ setup do
+ request_xml
+ @record = get_existing_record(res)
+ parent_params = make_parent_params(res, @record)
+ delete :destroy, parent_params.merge({ res.identifier => @record.to_param })
+ end
+
+ if res.denied.actions.include?(:destroy)
+ should_respond_with 401
+
+ should "not destroy record" do
+ assert @record.reload
+ end
+ else
+ should "destroy record" do
+ assert_raises(::ActiveRecord::RecordNotFound, "@#{res.object} was not destroyed.") do
+ @record.reload
+ end
+ end
+ end
+ end
+ end
+
+ def make_create_xml_tests(res) # :nodoc:
+ context "on POST to #{controller_name_from_class}#create as xml" do
+ setup do
+ request_xml
+ parent_params = make_parent_params(res)
+ @count = res.klass.count
+ post :create, parent_params.merge(res.object => res.create.params)
+ end
+
+ if res.denied.actions.include?(:create)
+ should_respond_with 401
+ should_not_assign_to res.object
+
+ should "not create new record" do
+ assert_equal @count, res.klass.count
+ end
+ else
+ should_assign_to res.object
+
+ should "not have errors on @#{res.object}" do
+ assert_equal [], pretty_error_messages(assigns(res.object)), "@#{res.object} has errors:"
+ end
+ end
+ end
+ end
+
+ def make_update_xml_tests(res) # :nodoc:
+ context "on PUT to #{controller_name_from_class}#update as xml" do
+ setup do
+ request_xml
+ @record = get_existing_record(res)
+ parent_params = make_parent_params(res, @record)
+ put :update, parent_params.merge(res.identifier => @record.to_param, res.object => res.update.params)
+ end
+
+ if res.denied.actions.include?(:update)
+ should_not_assign_to res.object
+ should_respond_with 401
+ else
+ should_assign_to res.object
+
+ should "not have errors on @#{res.object}" do
+ assert_equal [], assigns(res.object).errors.full_messages, "@#{res.object} has errors:"
+ end
+ end
+ end
+ end
+ end
+
+ # Sets the next request's format to 'application/xml'
+ def request_xml
+ @request.accept = "application/xml"
+ end
+
+ # Asserts that the controller's response was 'application/xml'
+ def assert_xml_response
+ content_type = (@response.headers["Content-Type"] || @response.headers["type"]).to_s
+ regex = %r{\bapplication/xml\b}
+
+ msg = "Content Type '#{content_type.inspect}' doesn't match '#{regex.inspect}'\n"
+ msg += "Body: #{@response.body.first(100).chomp} ..."
+
+ assert_match regex, content_type, msg
+ end
+
+ end
+ end
+end
diff --git a/lib/shoulda/controller/resource_options.rb b/lib/shoulda/controller/resource_options.rb
new file mode 100644
index 0000000..d8fb319
--- /dev/null
+++ b/lib/shoulda/controller/resource_options.rb
@@ -0,0 +1,233 @@
+module Shoulda # :nodoc:
+ module Controller
+ # Formats tested by #should_be_restful. Defaults to [:html, :xml]
+ VALID_FORMATS = Dir.glob(File.join(File.dirname(__FILE__), 'formats', '*.rb')).map { |f| File.basename(f, '.rb') }.map(&:to_sym) # :doc:
+ VALID_FORMATS.each {|f| require "shoulda/controller/formats/#{f}"}
+
+ # Actions tested by #should_be_restful
+ VALID_ACTIONS = [:index, :show, :new, :edit, :create, :update, :destroy] # :doc:
+
+ # A ResourceOptions object is passed into should_be_restful in order to configure the tests for your controller.
+ #
+ # Example:
+ # class UsersControllerTest < Test::Unit::TestCase
+ # fixtures :all
+ #
+ # def setup
+ # ...normal setup code...
+ # @user = User.find(:first)
+ # end
+ #
+ # should_be_restful do |resource|
+ # resource.identifier = :id
+ # resource.klass = User
+ # resource.object = :user
+ # resource.parent = []
+ # resource.actions = [:index, :show, :new, :edit, :update, :create, :destroy]
+ # resource.formats = [:html, :xml]
+ #
+ # resource.create.params = { :name => "bob", :email => 'bob@bob.com', :age => 13}
+ # resource.update.params = { :name => "sue" }
+ #
+ # resource.create.redirect = "user_url(@user)"
+ # resource.update.redirect = "user_url(@user)"
+ # resource.destroy.redirect = "users_url"
+ #
+ # resource.create.flash = /created/i
+ # resource.update.flash = /updated/i
+ # resource.destroy.flash = /removed/i
+ # end
+ # end
+ #
+ # Whenever possible, the resource attributes will be set to sensible defaults.
+ #
+ class ResourceOptions
+ # Configuration options for the create, update, destroy actions under should_be_restful
+ class ActionOptions
+ # String evaled to get the target of the redirection.
+ # All of the instance variables set by the controller will be available to the
+ # evaled code.
+ #
+ # Example:
+ # resource.create.redirect = "user_url(@user.company, @user)"
+ #
+ # Defaults to a generated url based on the name of the controller, the action, and the resource.parents list.
+ attr_accessor :redirect
+
+ # String or Regexp describing a value expected in the flash. Will match against any flash key.
+ #
+ # Defaults:
+ # destroy:: /removed/
+ # create:: /created/
+ # update:: /updated/
+ attr_accessor :flash
+
+ # Hash describing the params that should be sent in with this action.
+ attr_accessor :params
+ end
+
+ # Configuration options for the denied actions under should_be_restful
+ #
+ # Example:
+ # context "The public" do
+ # setup do
+ # @request.session[:logged_in] = false
+ # end
+ #
+ # should_be_restful do |resource|
+ # resource.parent = :user
+ #
+ # resource.denied.actions = [:index, :show, :edit, :new, :create, :update, :destroy]
+ # resource.denied.flash = /get outta here/i
+ # resource.denied.redirect = 'new_session_url'
+ # end
+ # end
+ #
+ class DeniedOptions
+ # String evaled to get the target of the redirection.
+ # All of the instance variables set by the controller will be available to the
+ # evaled code.
+ #
+ # Example:
+ # resource.create.redirect = "user_url(@user.company, @user)"
+ attr_accessor :redirect
+
+ # String or Regexp describing a value expected in the flash. Will match against any flash key.
+ #
+ # Example:
+ # resource.create.flash = /created/
+ attr_accessor :flash
+
+ # Actions that should be denied (only used by resource.denied). <i>Note that these actions will
+ # only be tested if they are also listed in +resource.actions+</i>
+ # The special value of :all will deny all of the REST actions.
+ attr_accessor :actions
+ end
+
+ # Name of key in params that references the primary key.
+ # Will almost always be :id (default), unless you are using a plugin or have patched rails.
+ attr_accessor :identifier
+
+ # Name of the ActiveRecord class this resource is responsible for. Automatically determined from
+ # test class if not explicitly set. UserTest => "User"
+ attr_accessor :klass
+
+ # Name of the instantiated ActiveRecord object that should be used by some of the tests.
+ # Defaults to the underscored name of the AR class. CompanyManager => :company_manager
+ attr_accessor :object
+
+ # Name of the parent AR objects. Can be set as parent= or parents=, and can take either
+ # the name of the parent resource (if there's only one), or an array of names (if there's
+ # more than one).
+ #
+ # Example:
+ # # in the routes...
+ # map.resources :companies do
+ # map.resources :people do
+ # map.resources :limbs
+ # end
+ # end
+ #
+ # # in the tests...
+ # class PeopleControllerTest < Test::Unit::TestCase
+ # should_be_restful do |resource|
+ # resource.parent = :companies
+ # end
+ # end
+ #
+ # class LimbsControllerTest < Test::Unit::TestCase
+ # should_be_restful do |resource|
+ # resource.parents = [:companies, :people]
+ # end
+ # end
+ attr_accessor :parent
+ alias parents parent
+ alias parents= parent=
+
+ # Actions that should be tested. Must be a subset of VALID_ACTIONS (default).
+ # Tests for each actionw will only be generated if the action is listed here.
+ # The special value of :all will test all of the REST actions.
+ #
+ # Example (for a read-only controller):
+ # resource.actions = [:show, :index]
+ attr_accessor :actions
+
+ # Formats that should be tested. Must be a subset of VALID_FORMATS (default).
+ # Each action will be tested against the formats listed here. The special value
+ # of :all will test all of the supported formats.
+ #
+ # Example:
+ # resource.actions = [:html, :xml]
+ attr_accessor :formats
+
+ # ActionOptions object specifying options for the create action.
+ attr_accessor :create
+
+ # ActionOptions object specifying options for the update action.
+ attr_accessor :update
+
+ # ActionOptions object specifying options for the desrtoy action.
+ attr_accessor :destroy
+
+ # DeniedOptions object specifying which actions should return deny a request, and what should happen in that case.
+ attr_accessor :denied
+
+ def initialize # :nodoc:
+ @create = ActionOptions.new
+ @update = ActionOptions.new
+ @destroy = ActionOptions.new
+ @denied = DeniedOptions.new
+
+ @create.flash ||= /created/i
+ @update.flash ||= /updated/i
+ @destroy.flash ||= /removed/i
+ @denied.flash ||= /denied/i
+
+ @create.params ||= {}
+ @update.params ||= {}
+
+ @actions = VALID_ACTIONS
+ @formats = VALID_FORMATS
+ @denied.actions = []
+ end
+
+ def normalize!(target) # :nodoc:
+ @denied.actions = VALID_ACTIONS if @denied.actions == :all
+ @actions = VALID_ACTIONS if @actions == :all
+ @formats = VALID_FORMATS if @formats == :all
+
+ @denied.actions = @denied.actions.map(&:to_sym)
+ @actions = @actions.map(&:to_sym)
+ @formats = @formats.map(&:to_sym)
+
+ ensure_valid_members(@actions, VALID_ACTIONS, 'actions')
+ ensure_valid_members(@denied.actions, VALID_ACTIONS, 'denied.actions')
+ ensure_valid_members(@formats, VALID_FORMATS, 'formats')
+
+ @identifier ||= :id
+ @klass ||= target.name.gsub(/ControllerTest$/, '').singularize.constantize
+ @object ||= @klass.name.tableize.singularize
+ @parent ||= []
+ @parent = [@parent] unless @parent.is_a? Array
+
+ collection_helper = [@parent, @object.to_s.pluralize, 'url'].flatten.join('_')
+ collection_args = @parent.map {|n| "@#{object}.#{n}"}.join(', ')
+ @destroy.redirect ||= "#{collection_helper}(#{collection_args})"
+
+ member_helper = [@parent, @object, 'url'].flatten.join('_')
+ member_args = [@parent.map {|n| "@#{object}.#{n}"}, "@#{object}"].flatten.join(', ')
+ @create.redirect ||= "#{member_helper}(#{member_args})"
+ @update.redirect ||= "#{member_helper}(#{member_args})"
+ @denied.redirect ||= "new_session_url"
+ end
+
+ private
+
+ def ensure_valid_members(ary, valid_members, name) # :nodoc:
+ invalid = ary - valid_members
+ raise ArgumentError, "Unsupported #{name}: #{invalid.inspect}" unless invalid.empty?
+ end
+ end
+ end
+end
+
diff --git a/test/functional/posts_controller_test.rb b/test/functional/posts_controller_test.rb
index 796492b..570dd6a 100644
--- a/test/functional/posts_controller_test.rb
+++ b/test/functional/posts_controller_test.rb
@@ -33,11 +33,32 @@ class PostsControllerTest < Test::Unit::TestCase
should_route :get, '/users/5/posts/new', :action => :new, :user_id => 5
should_route :put, '/users/5/posts/1', :action => :update, :id => 1, :user_id => 5
+ context "The public" do
+ setup do
+ @request.session[:logged_in] = false
+ end
+
+ should_be_restful do |resource|
+ resource.parent = :user
+
+ resource.denied.actions = [:index, :show, :edit, :new, :create, :update, :destroy]
+ resource.denied.flash = /what/i
+ resource.denied.redirect = '"/"'
+ end
+ end
+
context "Logged in" do
setup do
@request.session[:logged_in] = true
end
+ should_be_restful do |resource|
+ resource.parent = :user
+
+ resource.create.params = { :title => "first post", :body => 'blah blah blah'}
+ resource.update.params = { :title => "changed" }
+ end
+
context "viewing posts for a user" do
setup do
get :index, :user_id => users(:first)
diff --git a/test/functional/users_controller_test.rb b/test/functional/users_controller_test.rb
index cd0205f..a136ed3 100644
--- a/test/functional/users_controller_test.rb
+++ b/test/functional/users_controller_test.rb
@@ -16,4 +16,23 @@ class UsersControllerTest < Test::Unit::TestCase
should_filter_params :ssn
+ should_be_restful do |resource|
+ resource.identifier = :id
+ resource.klass = User
+ resource.object = :user
+ resource.parent = []
+ resource.actions = [:index, :show, :new, :edit, :update, :create, :destroy]
+ resource.formats = [:html, :xml]
+
+ resource.create.params = { :name => "bob", :email => 'bob@bob.com', :age => 13, :ssn => "123456789"}
+ resource.update.params = { :name => "sue" }
+
+ resource.create.redirect = "user_url(@user)"
+ resource.update.redirect = "user_url(@user)"
+ resource.destroy.redirect = "users_url"
+
+ resource.create.flash = /created/i
+ resource.update.flash = /updated/i
+ resource.destroy.flash = /removed/i
+ end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment