How to use Omniauth + capybara for testing FB Connect? - ruby-on-rails

I have a rails 3 app + devise using capybara for integration tests. Right now I have sign and sign up tests working but don't have tests for FB Connect.
How can I add Omniauth tests to ensure sign up and sign in work? Any one have an example or a up to date tutorial that shows how this is done? All I could find is fragments of info.
Thanks

I don't have the complete example. I added the following to my test.rb(You can add it to a initializer and add it if the enviroment is test).
OmniAuth.config.test_mode = true
FACEBOOK_INFO = {
"id"=> "220439",
"email" => "bret#facebook.com",
}
OmniAuth.config.mock_auth[:facebook] = {
"uid" => '12345',
"provider" => 'facebook',
"user_info" => {"name" => "Bret Taylor", "nickname" => 'btaylor'},
"credentials" => {"token" => 'plataformatec'},
"extra" => {"user_hash" => FACEBOOK_INFO}
}
This simulates the call to omniauth. So in your test, when you simulate a click to the facebook button, the response you will get is the one from OmniAuth.config.mock_auth[:facebook].

Related

omniauth-saml nil values in info hash

I'm working with devise and omniauth-saml, following the instructions from https://github.com/PracticallyGreen/omniauth-saml and the omniauth Facebook example https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview
I have a simplesamlphp server running, using the metadata provided by omniauth, and everything seems to be connecting properly, but the response from the simplesaml server has nil values for email, first_name, last_name and name. The weird thing is that it is returning the email and name values, just not in a useful part of the response (see below - super#man.com is the email, Clark Kent is the name)
The weird thing is that I get these nil values with both omniauth-saml and devise-saml-authenticatable gems, but I think my simplesamlphp server is configured properly.
The response from omniauth looks like this:
#<OmniAuth::AuthHash credentials=#<OmniAuth::AuthHash> extra=#<OmniAuth::AuthHash raw_info=#<OneLogin::RubySaml::Attributes:0x007fc695850148 #attributes={"urn:oid:0.9.2342.19200300.100.1.1"=>["super#man.com"], "urn:oid:2.16.840.1.113730.3.1.241"=>["Clark Kent"], "fingerprint"=>"FINGERPRINT REMOVED"}>> info=#<OmniAuth::AuthHash::InfoHash email=nil first_name=nil last_name=nil name=nil> provider="saml" uid="_ca76f49ccb6ccce7827111ae1ff0563f534f0a4d1a">
The simplesamlphp config looks like this:
$metadata['http://localhost:3000/saml/users/auth/saml/metadata'] = array(
'AssertionConsumerService' => 'http://localhost:3000/saml/users/auth/saml/callback',
'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:email',
'simplesaml.nameidattribute' => 'email',
);
I am sure that there are good values for the user in the database, and when I test authentication on the IDP itself, everything works as expected.
I solved this. The problem was that I was trying to use values that didn't use the ldap attribute names.
I changed my sp metadata as follows (after modifying my model to use first_name and last_name instead of just name)
$metadata['http://localhost:3000/saml/users/auth/saml/metadata'] = array(
'AssertionConsumerService' => 'http://localhost:3000/saml/users/auth/saml/callback',
'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:email',
'authproc' => array(
95 => array(
'class' => 'core:AttributeMap',
'givenName' => 'first_name',
'sn' => 'last_name',
'mail' => 'email',
),
96 => array(
'class' => 'core:AttributeLimit',
'email', 'first_name', 'last_name'
),
),
'simplesaml.nameidattribute' => 'email',
);

Rspec Suite Failing on OmniAuth Mock Auth Hash

My Rspec tests are all passing individually but are failing as the whole suite.
I have narrowed the issue down to using the mock omniauth hash describe in spec/support/devise.rb:
OmniAuth.config.test_mode = true
OmniAuth.config.mock_auth[:facebook] = {
"uid" => "1111",
"provider" => "facebook",
"credentials" => {
"token" => "token",
"secret" => "secret"
},
"extra" => {
"raw_info" => {
"name" => "Adam Waite",
"username" => "adamjwaite",
"email" => "adam#adam.com"
}
}
}
OmniAuth.config.add_mock(:facebook, OmniAuth.config.mock_auth[:facebook])
When I inspect OmniAuth.config.mock_auth[:facebook] just before the tests fails (using pry) it returns :invalid_credentials if run in the suite. If I run the same test in an individual test file it appears as it's displayed.
Here's the failing test in the registration method in my UsersController:
describe "GET :new" do
describe "as an unauthenticated user with a facebook omniauth session" do
before do
session[:omniauth_facebook] = OmniAuth.config.mock_auth[:facebook]
get :new
end
specify { assigns[:registering_with_facebook].should == true }
specify { assigns[:registering_with_twitter].should == false }
specify { response.should be_success }
end
end
It's also worth mentioning that the application function correctly too. I would just like the suite to pass.
Anyone shine any light on what's happening?
Whenever a test works in isolation, but fails with other tests, you have a test ordering issue. Some earlier test is changing global state and leaving it that way, which negatively affects this test.
I've created a small tool to help me find ordering issues in my own suites: rspec-search-and-destroy. It will take your test suite and bisect it until it finds the one test that is setting the bad global state. Of course, you can do this yourself by hand, but hopefully the tool can automate the drudgery.
Once you have found the earlier test, then you need to inspect it to figure out what global state is being set and how you can properly sandbox that change to just the test that needs it.

How to disable Premailer for individual emails

We have a couple of instances where we don't want Premailer to process the emails in our rails project.
Is it possible to turn off Premailer for individual triggers? I have tried the following without success:
mail :to => user.email, :subject => subject, :premailer => false
replace :premailer => false with skip_premailer: true

Twitter User Hash for Sorcery Authentication

I'm using the Sorcery gem and their external module to authenticate with Twitter. I've got the authentication working, but I want to store the user's Twitter profile image URL in my database after a successful log in. Sorcery seems to have a configuration option that's meant to do exactly what I want:
config.twitter.user_info_mapping = {:nickname => "screen_name"}
Maybe I've missed something in the Sorcery documentation, but I can't find any information about what "keys" are available. I tried this to no avail:
config.twitter.user_info_mapping = {:nickname => "screen_name", :avatar_url => "profile_image_url"}
Has anyone found documentation about this?
That is just what you get from twitter in json format.
Here is a twitter documentation about it https://dev.twitter.com/docs/api/1/get/account/verify_credentials
config.twitter.user_info_mapping = {:username => "screen_name",
:realname => "name",
:location => "place",
:web => "url",
:bio => "description"}

HowTo Write tests for Devise & Omniauth in my Rails 3 app?

I have a Rails 3 app with Omniauth and Devise. I haven't been able to find a solid tutorial showing how I should write specs for testing the functionality.
What I want to achieve is to ensure that the Sign Up and Sign In forms are working... meaning users can create accounts. I also want to be sure that the Omniauth FB Connect works as well at all times.
What/how can I write test for these scenarios above?
Thanks
The tests were very useful to test the pretty complex method I have to process authentication from Yahoo, Facebook, Google and AOL. Especially the edge cases.
This should get you started, it is the first of my 10+ scenarios.
.feature file
Feature: Signinin with third party service: Google, Aol, Facebook and Yahoo
In order to use the site
As a User
I want to sign in using my Facebook or Gmail accounts
Before do
OmniAuth.config.test_mode = true
end
After do
OmniAuth.config.test_mode = false
end
Scenario Outline: Sign with valid names and emails
Given that I have a valid "<provider>" account with email "<email>" and name "<name>"
And that I am not signed in
And I go to the sign in page
When I follow image link "<provider>"
Then I should see "You signed in using your <provider> account ("
And I should see "Welcome to Death Star"
Examples: valid name and email variations
| provider | email | name |
| Google | lukeskywaler#gmail.com | luke skywlaker |
| Facebook | darth.vader#aol.com | darth vader |
my_step.rb helper:
Given /^that I have a valid "([^"]*)" account with email "([^"]*)" and name "([^"]*)"$/ do |provider, email, name|
OmniAuth.config.test_mode = true
if provider.downcase == "yahoo" or provider.downcase == "google" or provider.downcase == "aol"
# the symbol passed to mock_auth is the same as the name of the provider set up in the initializer
OmniAuth.config.mock_auth[:open_id] =
{
'provider' => "#{provider}",
'uid' => "#{provider}.com",
'user_info' => { 'email' => "#{email}", 'name' => "#{name}"}
}
else
# the symbol passed to mock_auth is the same as the name of the provider set up in the initializer
OmniAuth.config.mock_auth[:facebook] = {
'provider' => 'facebook',
'uid' => "531564247",
'credentials' => {
'token'=> "18915faketoken22|2.NKt21XnznTNEDTTERDGYXI2UUw__.3600.1302234329200-531564247|Mi0DhWREl6g-T9bMZnL82u7s4MI"
},
'user_info' => {
'nickname' => "profile.php?id=53232564247",
'email' => "#{email}",
'first_name' => "Luke",
'last_name' => "Skywalker",
'name' => "Luke Skywalker",
'image' => "http://graph.facebook.com/5asd54247/picture?type=square",
'urls' => {
'facebook' => "http://www.facebook.com/profile.php?id=5asd54247",
'website' => ""
}
},
'extra' => {
'user_hash' => {
'id' => "5asd54247",
'name' => "#{name}",
'first_name' => "#{name.split(' ')[0]}",
'last_name' => "#{name.split(' ')[1]}",
'link' => "http://www.facebook.com/profile.php?id=5asd54247",
'birthday' => "12/7/1932",
'hometown' => {
'id' => "104048449631599",
'name' => "Menlo Park, California"
},
'location' => {
'id' => "104048449631599",
'name' => "Menlo Park, California"
},
'gender' => "male",
'email' => "#{email}",
'timezone' => "-7",
'locale' => "en_US",
'verified' => true
}
}
}
end
end
Hope this help.

Resources