Rspec-rails how to selectively turn on csrf protection for controller specs?

I’m setting up a Paypal IPN listener and need the create action to not
use rails’ default CSRF protection.

I’ve got that working fine & test it actually works with cucumber
(where I’ve turned CSRF back on, since it’s full-stack testing) but
would like my controller spec to mention the need for
protect_from_forgery :except => [:create] (and fail when it’s not
set).

I’ve not had any luck with telling the controller or
ActionController::Base to use forgery protection in the spec and am a
bit stuck.

Has anyone done this before, or do any of these look possible:

  • reload the rails app for part of the spec, using a different rails
    initializer (i.e. without
    config.action_controller.allow_forgery_protection = false as in
    environments/test.rb)
  • tell the controller to use forgery protection despite it being
    turned off in the rails test environment config (haven’t had any luck
    with this so far).
  • have some specs split off from the main specs which run in a
    different rails environment, e.g. test-with-csrf rather than test.

versions: rails 2.3.8, rspec 1.3.0, rspec-rails 1.3.2

Any help or pointers to old topics would be greatly appreciated,
google made this look a bit unexplored beyond “rails fixes csrf by
default, turn off in tests”.

Cheers
Nick

El 08/07/2010, a las 18:36, nruth
escribió:

ActionController::Base to use forgery protection in the spec and am a
with this so far).

  • have some specs split off from the main specs which run in a
    different rails environment, e.g. test-with-csrf rather than test.

versions: rails 2.3.8, rspec 1.3.0, rspec-rails 1.3.2

Any help or pointers to old topics would be greatly appreciated,
google made this look a bit unexplored beyond “rails fixes csrf by
default, turn off in tests”.

I think Cucumber is the right level to test this at. But if you really,
really want to test it at the RSpec level, take a look at what the
protect_from_forgery method actually does:

actionpack/lib/action_controller/metal/request_forgery_protection.rb

It boils down to this:

before_filter :verify_authenticity_token, options

So you could introspect the controller and ask it what its
before_filters are, and see if “verify_authenticity_token” is present or
absent. But I fear it would require some ugly hacking via
instance_variable_get, which is why I say that Cucumber is the right
level to test this sort of thing on.

Cheers,
Wincent

On 2010-07-08 12:15 PM, Wincent C. wrote:

I’ve not had any luck with telling the controller or
turned off in the rails test environment config (haven’t had any luck

actionpack/lib/action_controller/metal/request_forgery_protection.rb

It boils down to this:

before_filter :verify_authenticity_token, options

So you could introspect the controller and ask it what its before_filters are, and see if “verify_authenticity_token” is present or absent. But I fear it would require some ugly hacking via instance_variable_get, which is why I say that Cucumber is the right level to test this sort of thing on.

Actually, it’s not that difficult. I have a macro (or whatever the
proper term is) to spec the existence of before_filters. It looks like:

 def should_have_before_filters(*filters)
     filters.each do |filter|
         it "should have before_filter #{filter}"  do
             controller.class.before_filters.should include(filter)
         end
     end
 end

 alias_method :should_have_before_filter, 

:should_have_before_filters

This is RSpec 1.3.x for Rails 2.3.x. I have no idea if this will work in
RSpec 2.x and Rails 3.

Peace,
Phillip