Cucumber, Webrat, HTTP auth, and your API

Jason Morrison

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?

''