Here is my feature:
Scenario: Professor is not signed up and tries to sign in with Facebook
Given I do not exist as a professor
When I sign in as a professor with Facebook
Then I should see a successful sign in message
When I return to the site
Then I should be signed in as a professor
Here is the step definition for When I sign in as a professor with Facebook
When /^I sign in as a professor with Facebook$/ do
set_omniauth
visit "/professors/auth/facebook"
end
And here is the definition of set_omniauth helper:
def set_omniauth(opts = {})
default = {:provider => :facebook,
:uuid => "1234",
:facebook => {
:email => "[email protected]",
}
}
credentials = default.merge(opts)
provider = credentials[:provider]
user_hash = credentials[provider]
OmniAuth.config.test_mode = true
OmniAuth.config.mock_auth[provider] = {
'uid' => credentials[:uuid],
"extra" => {
"user_hash" => {
"email" => user_hash[:email],
}
}
}
end
So... When I visit /professors/auth/facebook
, this action is called
def facebook
@professor = Professor.find_for_facebook_oauth(request.env["omniauth.auth"], current_professor)
if @professor.persisted?
flash[:notice] = "Welcome! You have signed up successfully."
sign_in_and_redirect @professor, :event => :authentication
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
redirect_to new_professor_registration_url
end
end
And finally, the method find_for_facebook_oauth definition is:
def self.find_for_facebook_oauth(access_token, signed_in_resource=nil)
data = access_token["extra"]["raw_info"]
if professor = self.find_by_email(data.email)
professor
else # Create a professor with a stub password.
self.create(:email => data.email, :password => Devise.friendly_token[0,20])
end
end
When running this feature, I get the following error message:
undefined method `email' for {"email"=>"[email protected]"}:Hash (NoMethodError)
So, I checked what Facebook actually returns:
#<Hashie::Mash email="[email protected]" ...
But this is a different object than a normal hash set in:
OmniAuth.config.mock_auth[provider] = {
'uid' => credentials[:uuid],
"extra" => {
"user_hash" => {
"email" => user_hash[:email],
}
}
So, my question is: How would I test this properly? I followed OmniAuth Integration Tetsing and they set a Hash, and not a Hashie.
You need to create your Hash using a built in OmniAuth method for creating a Hashie object:
OmniAuth.config.mock_auth[provider] = OmniAuth::AuthHash.new({
'uid' => credentials[:uuid],
"extra" => {
"user_hash" => {
"email" => user_hash[:email],
}
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With