Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

Testing OAuth Apis in rails 3.x apps

  1. Install phantomjs
  2. Add rspec, poltergeist, capybara, vcr to Gemfile
  3. bundle install
  4. Create spec/acceptance folder
  5. Create spec/acceptance/acceptance_helper.rb (see below)
  6. Create spec for oauth flow (see below) read the comments carefully

NB: My signup flow is something like:

  • visit http://localhost/users/sign_up
  • user fills in details
  • user gets redirected to oauth provider
  • on oauth provider site, user logs in, and approves app
  • user is redirected back to http://localhost/oauth/callback?code=<a_code>
  • Oauth code (<auth_code>) is upgraded to access_token and refresh_token, and persisted
  • user is redirected to app, now authenticated

Suggestions more than welcome!

require 'spec_helper'
require 'email_spec'
require 'capybara/poltergeist'
require 'vcr'
VCR.configure do |c|
c.cassette_library_dir = 'spec/acceptance/cassettes'
c.hook_into :fakeweb
c.ignore_localhost = true
end
RSpec.configure do |c|
c.extend VCR::RSpec::Macros
end
Capybara.javascript_driver = :poltergeist
Capybara.ignore_hidden_elements = true
Capybara.server_port = 7787
# Put your acceptance spec helpers inside spec/acceptance/support
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
require 'acceptance/acceptance_helper'
feature 'Signup:', %q{
In order to start using the app
Users should be able to signup
And link with an OAuth provider
} do
#VCR will record interactions if cassette file doesn't exist, otherwise it will use what's in the cassette
use_vcr_cassette 'registration', :record => :once
#This is a nice little tweak, that saves the current state of the browser on a spec fail and opens it
after do
if example.exception
page.driver.render('testoutput.png')
`open testoutput.png`
end
end
background do
visit '/users/sign_up
end
#If your app relies on JS, don't forget :js => true, or you will hate yourself
scenario 'create an account', :js => true do
#skips any jQuery animations, for speed
page.driver.evaluate_script('$.fx.off = true')
#First we just want to fill in the form and submit
fill_fields({
"First name" => "Philip",
"Last name" => "Roberts",
"Company" => "Float",
"Email" => 'phil@floatapp.com',
"Choose your password" => "password"
})
click_button "Start your free trial!"
# This is where it gets interesting. If we are recording the VCR cassette, we want to
# actually go through the interaction with the third party. These steps will depend on the
# third-party
if VCR.current_cassette.recording?
page.should have_content 'Please log in'
fill_fields({
:email => "my_username",
:password => "my_password"
})
find(:css, 'input[type=submit]').click
find(:css, 'a[href="grant_approval"]').click
# This will take us back to our callback /oauth/callback with a real code.
# This code will be upgraded, and all the interactions for doing so will be recorded for next time
else
#If we are not recording, skip the third party stuff, and use the recorded token upgrade
visit '/oauth/callback?code=fake'
end
page.should have_content "Welcome!"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment