zerosum dirt(nap)

evolution through a series of accidents

zerosum dirt(nap)

TwitterAuth Integration Testing

July 13, 2009 by nap · Comments

Michael Bleigh’s TwitterAuth gem is truly full of awesome. It’s a complete OAuth authentication and API access solution for building Twitter apps with Rails. It uses familiar conventions borrowed from the Restful Authentication plugin, too. If you’re building a Rails-based app and you want to allow your users to Sign in with Twitter there’s just no better way to go.

TwitterAuth

For this particular app, I’m using the dynamic duo of Cucumber and Webrat to whip up integration tests. Since I initially stumbled a little bit when thinking about how to test integrated authentication against an external source like Twitter, I thought I’d doc the solution here in case other people were having the same issue.

Ready? Let’s do it.

Setup

First, install the TwitterAuth gem and use the provided generator to whip up the appropriate facilities. You’ll need to register your Twitter application accounts too. Or you know what? Screw it. If you want to make this super easy on yourself, Mike wrote a really great Twitter app Rails template that does all the setup for you, including walking you through getting the dev accounts. It’s nice, try it out. You’ll be up and writing Twitter apps in no time.

For the rest of this I’m going to assume that you have all of that working, and have installed Cucumber too. Don’t have Cucumber? Install it using RubyGems and then just run script/generate cucumber inside your Rails app.

Authentication Feature

So let’s write a Cucumber feature to test authentication in our boilerplate Twitter template application. Put the following in features/authentication.feature:

Feature: Authentication
In order to create and edit games
As a user
I want to sign in with Twitter

  Scenario: Login via Twitter
    When I go to "the homepage"
    And I follow "Login via Twitter"
    And Twitter authorizes me
    Then I should see "Logged in as"

  Scenario: Checking login status
    Given I am signed in
    When I go to "the homepage"
    Then I should see "Logged in as"

  Scenario: Log out
    Given I am signed in
    When I go to "the homepage"
    And I follow "Log out"
    Then I should see "Login via Twitter"

Step Definitions

Next, you’ll need to write step definitions to satisfy the missing steps. Do that by creating a file called features/step_definitions/auth_steps.rb. The content of the file should define the following two steps:

Given /^I am signed in$/ do  
  visit login_path
  visit oauth_callback_path
end  

When /^Twitter authorizes me$/ do
  visit oauth_callback_path
end

Fake Style

The secret sauce here is FakeWeb. We’ll use it to fake out responses from the Twitter auth service so that your integration tests stay local (and reliable). Make sure to gem install fakeweb, and add the following to tests/environments/cucumber.rb:

config.gem "fakeweb", :version => ">= 1.2.5"

Now edit Cucumber’s features/support/env.rb file:

FakeWeb.allow_net_connect = false
FakeWeb.register_uri(:post, 'http://twitter.com/oauth/request_token', :body => 'oauth_token=fake&oauth_token_secret=fake')
FakeWeb.register_uri(:post, 'http://twitter.com/oauth/access_token', :body => 'oauth_token=fake&oauth_token_secret=fake')
FakeWeb.register_uri(:get, 'http://twitter.com/account/verify_credentials.json', :response => File.join(RAILS_ROOT, 'features', 'fixtures', 'verify_credentials.json'))

Here we’re stubbing out the interaction with Twitter auth, and responding to all outbound authorization attempts with canned data. Note that this references a fixture file, containing a sample verify_credentials API response from Twitter. You can obtain a copy using curl from the comfort of your terminal prompt (substitute your own username and password):

curl -i -u user:pass "http://twitter.com/account/verify_credentials.json" > verify_credentials.json

The last thing you’ll want to do is to check your twitter_auth.yml file and make sure there’s a cucumber environment defined in it. If not, you may need to add it.

And We’re Done

Alright that should do it. Go ahead and run rake features. Everything should be green. And green is good. If you need to write other features that are dependent on a login requirement, you can reuse the same “Given I am signed in” step that we created earlier.

Thanks to b.kocik, whose original post on using FakeWeb to stub Twitter auth was 80% of the solution I needed here.

blog comments powered by Disqus