trev9065
trev9065

Reputation: 3501

Devise and OmniAuth twitter integration testing with rspec

I am trying to write a integration test for signing in with twitter using OmniAuth and Devise. I am having trouble getting the request variable to be set. It works in the controller test but not the integration test which leads me to think that I am not configuring the spec helper properly. I have looked around, but I can't seem to find a working solution. Here is what I have so far:

# spec/integrations/session_spec.rb
require 'spec_helper'
describe "signing in" do
  before do
    request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:twitter]
    visit new_user_session_path
    click_link "Sign in with twitter"
  end

  it "should sign in the user with the authentication" do
    (1+1).should == 3
  end
end

This spec raies a error before it can get to the test and I am not quite sure where the request variable needs to be initialized. The error is:

Failure/Error: request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:twitter]
  NoMethodError:
    undefined method `env' for nil:NilClass

Now I use the request variable in my controller spec and the test pass but it is not being initialized for the integration tests.

 # spec/spec_helper.rb
 Dir[Rails.root.join("spec/support/*.rb")].each {|f| require f}
 ...

 # spec/support/devise.rb
 RSpec.configure do |config|
   config.include Devise::TestHelpers, :type => :controller
 end

Thanks for the help!

Upvotes: 4

Views: 1879

Answers (4)

Dmitrii
Dmitrii

Reputation: 181

When using request specs with newer versions of RSpec, which do not allow access to the request object:

before do
  Rails.application.env_config["devise.mapping"] = Devise.mappings[:user] # If using Devise
  Rails.application.env_config["omniauth.auth"] = OmniAuth.config.mock_auth[:twitter]
end

Upvotes: 0

Matt Connolly
Matt Connolly

Reputation: 9857

This one works for me during test using rspec + devise + omniauth + omniauth-google-apps. No doubt the twitter solution will be very similar:

# use this method in request specs to sign in as the given user.
def login(user)
  OmniAuth.config.test_mode = true
  hash = OmniAuth::AuthHash.new
  hash[:info] = {email: user.email, name: user.name}
  OmniAuth.config.mock_auth[:google_apps] = hash

  visit new_user_session_path
  click_link "Sign in with Google Apps"
end

Upvotes: 2

Junichi Ito
Junichi Ito

Reputation: 2598

Capybara README says "Access to session and request is not possible from the test", so I gave up to configure in test and decided to write a helper method in application_controller.rb.

before_filter :set_request_env
def set_request_env
  if ENV["RAILS_ENV"] == 'test'
    request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:twitter] 
  end
end

Upvotes: 3

Samantha John
Samantha John

Reputation: 978

The Devise test helpers are only meant to be used in controller specs not integration specs. In capybara there is no request object so setting it won't work.

What you should do instead is scope loading of Devise test helpers to your controller specs, something like this:

class ActionController::TestCase
  include Devise::TestHelpers
end

and use the warden helper for capybara specs as suggested in this guide: https://github.com/plataformatec/devise/wiki/How-To:-Test-with-Capybara

For a more detailed discussion look at this github issue page: https://github.com/nbudin/devise_cas_authenticatable/issues/36

Upvotes: 2

Related Questions