Created
January 24, 2011 02:19
-
-
Save jittuu/792715 to your computer and use it in GitHub Desktop.
Test Omniauth Facebook Callback Controllers in Devise with rspec
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 => "[email protected]").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 => "[email protected]", :password => "my_secret") | |
get :facebook | |
end | |
it { flash[:notice].should == "Your email [email protected] 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 => "[email protected]", :password => "my_secret") | |
sign_in user | |
get :facebook | |
end | |
it "should add facebook authentication to current user" do | |
user = User.where(:email => "[email protected]").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 => "[email protected]", :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 => "[email protected]").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" => "[email protected]" } } } } | |
@controller.stub!(:env).and_return(env) | |
end |
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" => "[email protected]" } } } }
request.env["omniauth.auth"] = env["omniauth.auth"]
end
It would be better to use OmniAuth::AuthHash.new
in order to simulate the params; otherwise you could get errors if you accessed params in your code like request.env["omniauth.auth"].provider
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]
request.env["omniauth.auth"] = OmniAuth::AuthHash.new({
"provider"=>"facebook",
"uid"=>uid,
...
})
end
Great tests! I used them in my project. Thanks!
Couple of tests I'd add would be to test when user rejects facebook authentication.
Also, here's another test I added, which is not necessarily needed, but I like to have it around:
it "should alias #facebook to #auth_all" do
expect(Users::OauthCallbacksController.instance_method(:facebook)).to eq(Users::OauthCallbacksController.instance_method(:auth_all))
end
For those who are doing request tests in Rails 7:
RSpec.describe OmniauthCallbacksController, type: :request do
context "when admin does not exist" do
it "should redirect admin to new session path" do
OmniAuth.config.test_mode = true
OmniAuth.config.mock_auth[:google_oauth2] = OmniAuth::AuthHash.new(
provider: "google_oauth2",
uid: "123",
info: OmniAuth::AuthHash::InfoHash.new(email: "[email protected]", name: "jose"),
extra: {
raw_info: OmniAuth::AuthHash.new(email_verified: true)
}
)
Rails.application.env_config["omniauth.auth"] = OmniAuth.config.mock_auth[:google_oauth2]
get admin_google_oauth2_omniauth_callback_path
expect(response.code).to eq("302")
expect(response).to redirect_to(new_admin_session_path)
expect(flash[:alert]).to eq("User not found")
end
end
end
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.