RoR: Testing with simple_captcha & HTTP-Auth
09 Feb 2008While developing a small Ruby on Rails application for The Pilot’s Camping Directory website I ran into a few problems that weren’t solved by a simple google search - so I’m documenting them here for future posterity and googling. I had problems with testing when using some security features to keep out riff-raff. It was not obvious how to handle simple_captcha or simple_http_auth while doing testing so I scratched around the net and pieced together a solution for each of the problems. These work with Rails 1.2. With Rails 2.0 YMMV - but then 2.0 breaks every rails tutorial ever written so I don’t feel bad if this blows up in 2.0.
Using Mocks for testing with simple_captcha
Tests will fail when trying to save something protected by a captcha - obviously - as stoping automated lever-pulling is exactly what a captcha is designed to do. In my application I use capcha at the model level, so I simply override the save_with_captcha method with a simple save.
Here’s what my mocks/test/recipient.rb looks like:
`# Can’t fake captcha for testing - so we mock it out.
require_dependency ‘models/recipient’
class Recipient < ActiveRecord::Base
def self.save_with_captcha
self.save
end
end
`
**Functional Testing HTTP-Auth
**To test HTTP Authorization / Authentication you must set up your request environment to pass the http authorization into the application. This is known to work with the simple_http_auth plugin, the plugin that I used for my application. Specify this in the setup section of your functional test.
``
def setup
@controller = SupersecretController.new
@request = ActionController::TestRequest.new
@request.env[‘HTTP_AUTHORIZATION’] = “Basic “ + Base64.encode64(ADMIN_USER
+’:’ + ADMIN_PASSWORD )
end
`
**Integration Testing HTTP-Auth
**Integration testing simulates making requests directly to the webserver. To work with http authorization here you must pass in the appropriate authentication headers when making each get/post request. An example is below:
`
@htauth = “Basic “ + Base64.encode64(ADMIN_USER+’:’ + ADMIN_PASSWORD )
get(“/supersecret/index”, nil , {:authorization => @htauth})
`