Request formats, filters, and functional tests…

I recently had to write some tests against a controller that was filtering based on the requesting format. In this case, I wanted to allow xml requests only, and redirect to login on everything else. This was fine when browsing or using curl by doing a simple:

skip_before_filter :login_required,
  :only => [:create],
  :if => {|c| c.request.format.xml?}

My problem came when I was trying to create tests to verify that both html and xml requests did in fact produce the correct response. After many hours of messing around, I came up with a simple solution. First I skip the filters for every request, then I have another filter to re-enable them on anything but the xml request:

skip_before_filter :login_required, :only => [:create]
before_filter :only => [:create] do |c|
  c.send(:login_required) unless c.request.format.xml?

Voila!!! This allowed me to continue with my rails testing and browser and curl work appropriately. (I use curl to test the xml request).

def test_not_logged_in_normal_post
  post :create, :login => "", :password => "test"
  assert_response :redirect

def test_not_logged_in_xml_post
  post :create, :format => "xml", :login => "", :password => "test"
  assert_response :success

Simple & Clean Rails Date/Time Format

Here is a quick, clean and easy way to get use from strftime on your date/time fields. Create a file called date_format.rb in the config/initializers directory and add the following code:

  :datetime_military => '%Y-%m-%d %H:%M',
  :datetime          => '%Y-%m-%d %I:%M%P',
  :time              => '%I:%M%P',
  :time_military     => '%H:%M%P',
  :datetime_short    => '%m/%d %I:%M'

Then in your views, you can do the following:

@object.time_field.to_s(:datetime)     # Or any other format you created