= SUMMARY
An ActionController +verify+ directive redirects to an :action if certain actions are not done by POST. In one case, the redirect is to an empty hash instead; in another, nearly identical, it is to the correct hash. This is seen in a functional test.
Will someone please tell me what is going wrong, and how I can correct it?
= ENVIRONMENT
$ ruby --version ruby 1.8.6 (2008-03-03 patchlevel 114) [universal-darwin9.0] $ rails --version Rails 1.2.6
= DETAIL
(Much of this may be easier to see in the "CODE" section, below.)
AdminController is a subclass of ActionController, acting on instances of Permission, an ActiveRecord subclass. Permission#approve and Permission#deny set the :approval attribute to one string or another. admin/approve/:id and admin/deny/:id pass the respective methods to the id'ed Permission.
AdminController has a +verify+ directive to require that #approve and #deny be done by POST. If they are not, the session is to :redirect_to admin/list.
Class AdminControllerTest, a Test::Unit::TestCase, challenges the +verify+ by using GET requests instead. For many iterations of the test, AdminController passed. I then added some tests to AdminControllerTest; I did not change test_deny_not_post or test_accept_not_post.
test_deny_not_post then started failing at assert_redirected_to. The fail message is:
"response is not a redirection to all of the options supplied (redirection is <{}>), difference: <{"action"=>:list}>"
test_approve_not_post, which is nearly identical, DOES NOT fail.
Changing the +verify+'s :redirect_to to { :controller => :admin, :action => :list } gets the tests past the assert_redirected_to, but fails the follow_redirect (Can't follow redirects outside of current controller (from admin to admin)). This failure is in BOTH test_deny_not_post and test_approve_not_post.
My controller is failing a functional test, and I don't understand why. Will someone please tell me what is going wrong, and how I can correct it?
= CODE (abridged)
class AdminController < ApplicationController verify :method => :post, :only => [ :destroy, :create, :update, :deny, :approve ], :redirect_to => { :action => :list }, :add_flash => { :notice => 'You cannot do this directly.' }
def approve # before_filter sets @permission @permission.approve if @permission.save flash[:notice] = 'This request was approved.' else flash[:notice] = 'Could not approve the request (internal error).' end redirect_to :action => :list end
def deny # before_filter sets @permission @permission.deny if @permission.save flash[:notice] = 'This request was denied.' else flash[:notice] = 'Could not deny the request (internal error).' end redirect_to :action => :list end
class AdminControllerTest < Test::Unit::TestCase # #setup puts user credentials in @session
def test_approve_not_post get :approve, { :id => 3 }, @session assert_response :redirect assert_redirected_to :action => :list assert_equal 'You cannot do this directly.', flash[:notice] end
def test_deny_not_post get :deny, { :id => 3 }, @session assert_response :redirect assert_redirected_to :action => :list assert_equal 'You cannot do this directly.', flash[:notice] end end