public
Last active

Test Omniauth Facebook Callback Controllers in Devise with rspec

  • Download Gist
gistfile1.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
require 'spec_helper'
 
describe Users::OauthCallbacksController, "handle facebook authentication callback" do
describe "#annonymous user" do
context "when facebook email doesn't exist in the system" do
before(:each) do
stub_env_for_omniauth
 
get :facebook
@user = User.where(:email => "ghost@nobody.com").first
end
 
it { @user.should_not be_nil }
 
it "should create authentication with facebook id" do
authentication = @user.authentications.where(:provider => "facebook", :uid => "1234").first
authentication.should_not be_nil
end
 
it { should be_user_signed_in }
 
it { response.should redirect_to tasks_path }
end
context "when facebook email already exist in the system" do
before(:each) do
stub_env_for_omniauth
User.create!(:email => "ghost@nobody.com", :password => "my_secret")
get :facebook
end
it { flash[:notice].should == "Your email ghost@nobody.com is already exist in the system. You need to sign in first."}
it { response.should redirect_to new_user_session_path }
end
end
describe "#logged in user" do
context "when user don't have facebook authentication" do
before(:each) do
stub_env_for_omniauth
 
user = User.create!(:email => "user@example.com", :password => "my_secret")
sign_in user
 
get :facebook
end
 
it "should add facebook authentication to current user" do
user = User.where(:email => "user@example.com").first
user.should_not be_nil
fb_authentication = user.authentications.where(:provider => "facebook").first
fb_authentication.should_not be_nil
fb_authentication.uid.should == "1234"
end
 
it { should be_user_signed_in }
 
it { response.should redirect_to authentications_path }
it { flash[:notice].should == "Facebook is connected with your account."}
end
context "when user already connect with facebook" do
before(:each) do
stub_env_for_omniauth
user = User.create!(:email => "ghost@nobody.com", :password => "my_secret")
user.authentications.create!(:provider => "facebook", :uid => "1234")
sign_in user
 
get :facebook
end
it "should not add new facebook authentication" do
user = User.where(:email => "ghost@nobody.com").first
user.should_not be_nil
fb_authentications = user.authentications.where(:provider => "facebook")
fb_authentications.count.should == 1
end
it { should be_user_signed_in }
it { flash[:notice].should == "Signed in successfully." }
it { response.should redirect_to tasks_path }
end
end
end
 
def stub_env_for_omniauth
# This a Devise specific thing for functional tests. See https://github.com/plataformatec/devise/issues/closed#issue/608
request.env["devise.mapping"] = Devise.mappings[:user]
env = { "omniauth.auth" => { "provider" => "facebook", "uid" => "1234", "extra" => { "user_hash" => { "email" => "ghost@nobody.com" } } } }
@controller.stub!(:env).and_return(env)
end

Why do you stub in the ominauth.auth field when you don't stub in Devise's hash as well?
You might as well just set in and shorten the call stack. Adding to that, the information you set from https://github.com/intridea/omniauth/wiki/Integration-Testing could be taken into play here.

I agree with @jalcine.
A safer approach would be request.env["omniauth.auth"] = env["omniauth.auth"] and so the stub_env_for_omniauth will be:

def stub_env_for_omniauth
  # This a Devise specific thing for functional tests. See https://github.com/plataformatec/devise/issues/closed#issue/608
  request.env["devise.mapping"] = Devise.mappings[:user]
  env = { "omniauth.auth" => { "provider" => "facebook", "uid" => "1234", "extra" => { "user_hash" => { "email" => "ghost@nobody.com" } } } }
  request.env["omniauth.auth"] = env["omniauth.auth"]
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.