Cucumber, Webrat, HTTP auth, and your API

When you want to authenticate against an API in your application, and you use the standard Rails integration test methods to call your endpoint, #basic_auth won’t work:

When /^I post to "([^\"]*)" as "(.*)\/(.*)" with the following params:$/ do |path, username, password, table|
  basic_auth(username, password)
  post_params = table.hashes.first
  post path, post_params
end

You’ll have to specify the HTTP authorization credentials yourself:

When /^I post to "([^\"]*)" as "(.*)\/(.*)" with the following params:$/ do |path, username, password, table|
  encoded_login = ["#{username}:#{password}"].pack("m*").gsub(/\n/, '')
  post_params = table.hashes.first
  post path, post_params, { "HTTP_AUTHORIZATION" => "Basic #{encoded_login}" }
end

The encoded_login bit is nicked from Webrat’s implementation of #basic_auth in core/session.rb.

Addendum

Update: Actually, a cleaner way to do this is to use Webrat’s visit or request_page methods, which allow you to use basic_auth:

When /^I post to "([^\"]*)" as "(.*)\/(.*)" with the following params:$/ do |path, username, password, table|
  basic_auth(username, password)
  post_params = table.hashes.first
  visit path, :post, post_params
end

Step up

What’s your favorite Cucumber step you’ve seen lately?

Sharpen your programming skills by completing coding exercises that are reviewed by other developers at Upcase today.