nruth
2010-Jul-08 16:36 UTC
[rspec-users] 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
Wincent Colaiuta
2010-Jul-08 17:15 UTC
[rspec-users] rspec-rails how to selectively turn on csrf protection for controller specs?
El 08/07/2010, a las 18:36, nruth escribi?:> 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".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
Phillip Koebbe
2010-Jul-09 01:49 UTC
[rspec-users] rspec-rails how to selectively turn on csrf protection for controller specs?
On 2010-07-08 12:15 PM, Wincent Colaiuta wrote:> El 08/07/2010, a las 18:36, nruth escribi?: > >> 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". > 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. >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