mirror of
https://github.com/heartcombo/devise.git
synced 2022-11-09 12:18:31 -05:00
More and more tests to DeviseOauth.
This commit is contained in:
parent
00c6f583e2
commit
4bfa98eb7c
5 changed files with 261 additions and 60 deletions
|
@ -17,10 +17,20 @@ class OAuthableTest < ActionController::IntegrationTest
|
|||
teardown do
|
||||
Devise::Oauth.unshort_circuit_authorizers!
|
||||
Devise::Oauth.reset_stubs!
|
||||
User.singleton_class.remove_possible_method(:find_for_github_oauth)
|
||||
end
|
||||
|
||||
def stub_github!(times=1)
|
||||
def User.find_for_github_oauth(*); end
|
||||
|
||||
Devise::Oauth.stub!(:github) do |b|
|
||||
b.post('/login/oauth/access_token') { [200, {}, ACCESS_TOKEN.to_json] }
|
||||
end
|
||||
end
|
||||
|
||||
def stub_facebook!(times=1)
|
||||
data = (times == 1) ? FACEBOOK_INFO : FACEBOOK_INFO.except(:email)
|
||||
# If times != 1, use invalid data
|
||||
data = (times != 1) ? FACEBOOK_INFO.except(:email) : FACEBOOK_INFO
|
||||
|
||||
Devise::Oauth.stub!(:facebook) do |b|
|
||||
b.post('/oauth/access_token') { [200, {}, ACCESS_TOKEN.to_json] }
|
||||
|
@ -30,7 +40,7 @@ class OAuthableTest < ActionController::IntegrationTest
|
|||
end
|
||||
end
|
||||
|
||||
test "basic setup with persisted user" do
|
||||
test "[BASIC] setup with persisted user" do
|
||||
stub_facebook!
|
||||
|
||||
assert_difference "User.count", 1 do
|
||||
|
@ -43,9 +53,10 @@ class OAuthableTest < ActionController::IntegrationTest
|
|||
|
||||
assert warden.authenticated?(:user)
|
||||
assert_not warden.authenticated?(:admin)
|
||||
assert "plataformatec", warden.user(:user).facebook_token
|
||||
end
|
||||
|
||||
test "basic setup with not persisted user and follow up" do
|
||||
test "[BASIC] setup with not persisted user and follow up" do
|
||||
stub_facebook!(2)
|
||||
|
||||
assert_no_difference "User.count" do
|
||||
|
@ -68,5 +79,217 @@ class OAuthableTest < ActionController::IntegrationTest
|
|||
|
||||
assert warden.authenticated?(:user)
|
||||
assert_not warden.authenticated?(:admin)
|
||||
assert "plataformatec", warden.user(:user).facebook_token
|
||||
end
|
||||
|
||||
test "[BASIC] setup updating an existing user in database" do
|
||||
stub_facebook!
|
||||
user = create_user
|
||||
|
||||
assert_no_difference "User.count" do
|
||||
visit "/users/sign_in"
|
||||
click_link "Sign in with Facebook"
|
||||
end
|
||||
|
||||
assert_current_url "/"
|
||||
assert_contain "Successfully authorized from Facebook account."
|
||||
|
||||
assert_equal user, warden.user(:user)
|
||||
assert_equal "plataformatec", user.reload.facebook_token
|
||||
end
|
||||
|
||||
test "[BASIC] setup updating an existing user in session" do
|
||||
stub_facebook!
|
||||
|
||||
# Create an user and change his e-mail
|
||||
user = sign_in_as_user
|
||||
user.update_attribute(:email, "another@test.com")
|
||||
|
||||
assert_no_difference "User.count" do
|
||||
visit "/"
|
||||
click_link "Sign in with Facebook"
|
||||
end
|
||||
|
||||
assert_current_url "/"
|
||||
assert_contain "Successfully authorized from Facebook account."
|
||||
|
||||
assert_equal user, warden.user(:user)
|
||||
assert_equal "another@test.com", warden.user(:user).email
|
||||
assert_equal "plataformatec", user.reload.facebook_token
|
||||
end
|
||||
|
||||
test "[BASIC] setup skipping oauth callback" do
|
||||
stub_github!
|
||||
|
||||
assert_no_difference "User.count" do
|
||||
visit "/users/sign_in"
|
||||
click_link "Sign in with Github"
|
||||
end
|
||||
|
||||
assert_current_url "/users/sign_in"
|
||||
assert_contain "Skipped Oauth authorization for Github."
|
||||
|
||||
assert_not warden.authenticated?(:user)
|
||||
assert_not warden.authenticated?(:admin)
|
||||
end
|
||||
|
||||
test "[SESSION CLEANUP] ensures session is cleaned up after sign up" do
|
||||
stub_facebook!(2)
|
||||
|
||||
assert_no_difference "User.count" do
|
||||
visit "/users/sign_in"
|
||||
click_link "Sign in with Facebook"
|
||||
end
|
||||
|
||||
assert_contain "1 error prohibited this user from being saved"
|
||||
fill_in "Email", :with => "user.form@test.com"
|
||||
click_button "Sign up"
|
||||
|
||||
assert_contain "You have signed up successfully."
|
||||
visit "/users/sign_out"
|
||||
|
||||
user = sign_in_as_user
|
||||
assert_nil warden.user(:user).facebook_token
|
||||
assert_equal user, warden.user(:user)
|
||||
end
|
||||
|
||||
test "[SESSION CLEANUP] ensures session is cleaned up on cancel" do
|
||||
stub_facebook!(2)
|
||||
|
||||
assert_no_difference "User.count" do
|
||||
visit "/users/sign_in"
|
||||
click_link "Sign in with Facebook"
|
||||
end
|
||||
|
||||
assert_contain "1 error prohibited this user from being saved"
|
||||
visit "/users/cancel"
|
||||
|
||||
user = sign_in_as_user
|
||||
assert_nil warden.user(:user).facebook_token
|
||||
assert_equal user, warden.user(:user)
|
||||
end
|
||||
|
||||
test "[SESSION CLEANUP] ensures session is cleaned up on sign in" do
|
||||
stub_facebook!(2)
|
||||
|
||||
assert_no_difference "User.count" do
|
||||
visit "/users/sign_in"
|
||||
click_link "Sign in with Facebook"
|
||||
end
|
||||
|
||||
assert_contain "1 error prohibited this user from being saved"
|
||||
|
||||
user = sign_in_as_user
|
||||
assert_nil warden.user(:user).facebook_token
|
||||
assert_equal user, warden.user(:user)
|
||||
end
|
||||
|
||||
test "[I18N] scopes messages based on oauth callback for success" do
|
||||
stub_facebook!
|
||||
|
||||
store_translations :en, :devise => { :oauth_callbacks => {
|
||||
:facebook => { :success => "Welcome facebooker" } } } do
|
||||
visit "/users/sign_in"
|
||||
click_link "Sign in with Facebook"
|
||||
assert_contain "Welcome facebooker"
|
||||
end
|
||||
end
|
||||
|
||||
test "[I18N] scopes messages based on oauth callback and resource name for success" do
|
||||
stub_facebook!
|
||||
|
||||
store_translations :en, :devise => { :oauth_callbacks => {
|
||||
:user => { :facebook => { :success => "Welcome facebooker user" } },
|
||||
:facebook => { :success => "Welcome facebooker" } } } do
|
||||
visit "/users/sign_in"
|
||||
click_link "Sign in with Facebook"
|
||||
assert_contain "Welcome facebooker user"
|
||||
end
|
||||
end
|
||||
|
||||
test "[I18N] scopes messages based on oauth callback for skipped" do
|
||||
stub_github!
|
||||
|
||||
store_translations :en, :devise => { :oauth_callbacks => {
|
||||
:github => { :skipped => "Skipped github" } } } do
|
||||
visit "/users/sign_in"
|
||||
click_link "Sign in with Github"
|
||||
assert_contain "Skipped github"
|
||||
end
|
||||
end
|
||||
|
||||
test "[I18N] scopes messages based on oauth callback and resource name for skipped" do
|
||||
stub_github!
|
||||
|
||||
store_translations :en, :devise => { :oauth_callbacks => {
|
||||
:user => { :github => { :skipped => "Skipped github user" } },
|
||||
:github => { :skipped => "Skipped github" } } } do
|
||||
visit "/users/sign_in"
|
||||
click_link "Sign in with Github"
|
||||
assert_contain "Skipped github user"
|
||||
end
|
||||
end
|
||||
|
||||
test "[FAILURE] shows 404 if no code or error are given as params" do
|
||||
assert_raise AbstractController::ActionNotFound do
|
||||
visit "/users/oauth/facebook/callback"
|
||||
end
|
||||
end
|
||||
|
||||
test "[FAILURE] raises an error if model does not implement a hook" do
|
||||
begin
|
||||
visit "/users/oauth/github/callback?code=123456"
|
||||
raise "Expected visit to raise an error"
|
||||
rescue Exception => e
|
||||
assert_match "User does not respond to find_for_github_oauth", e.message
|
||||
end
|
||||
end
|
||||
|
||||
test "[FAILURE] handles callback error parameter according to the specification" do
|
||||
visit "/users/oauth/facebook/callback?error=access_denied"
|
||||
assert_current_url "/users/sign_in"
|
||||
assert_contain 'Could not authorize you from Facebook because "Access denied".'
|
||||
end
|
||||
|
||||
test "[FAILURE] handles callback error_reason just for Facebook compatibility" do
|
||||
visit "/users/oauth/facebook/callback?error_reason=access_denied"
|
||||
assert_current_url "/users/sign_in"
|
||||
assert_contain 'Could not authorize you from Facebook because "Access denied".'
|
||||
end
|
||||
|
||||
test "[FAILURE][I18N] uses I18n for custom messages" do
|
||||
store_translations :en, :devise => { :oauth_callbacks => { :access_denied => "Access denied bro" } } do
|
||||
visit "/users/oauth/facebook/callback?error=access_denied"
|
||||
assert_current_url "/users/sign_in"
|
||||
assert_contain "Access denied bro"
|
||||
end
|
||||
end
|
||||
|
||||
test "[FAILURE][I18N] uses I18n with oauth callback scope for custom messages" do
|
||||
store_translations :en, :devise => { :oauth_callbacks => {
|
||||
:facebook => { :access_denied => "Access denied bro" } } } do
|
||||
visit "/users/oauth/facebook/callback?error=access_denied"
|
||||
assert_current_url "/users/sign_in"
|
||||
assert_contain "Access denied bro"
|
||||
end
|
||||
end
|
||||
|
||||
test "[FAILURE][I18N] uses I18n with oauth callback scope and resource name for custom messages" do
|
||||
store_translations :en, :devise => { :oauth_callbacks => {
|
||||
:user => { :facebook => { :access_denied => "Access denied user" } },
|
||||
:facebook => { :access_denied => "Access denied bro" } } } do
|
||||
visit "/users/oauth/facebook/callback?error=access_denied"
|
||||
assert_current_url "/users/sign_in"
|
||||
assert_contain "Access denied user"
|
||||
end
|
||||
end
|
||||
|
||||
test "[FAILURE][I18N] trim messages to avoid long symbols lookups" do
|
||||
store_translations :en, :devise => { :oauth_callbacks => {
|
||||
:facebook => { ("a"*25) => "Access denied bro" } } } do
|
||||
visit "/users/oauth/facebook/callback?error=#{"a"*100}"
|
||||
assert_current_url "/users/sign_in"
|
||||
assert_contain "Access denied bro"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1 +1,5 @@
|
|||
Home!
|
||||
|
||||
<%- User.oauth_providers.each do |provider| %>
|
||||
<%= link_to "Sign in with #{provider.to_s.titleize}", user_oauth_authorize_url(provider) %><br />
|
||||
<% end =%>
|
|
@ -2,6 +2,8 @@ class CreateTables < ActiveRecord::Migration
|
|||
def self.up
|
||||
create_table :users do |t|
|
||||
t.string :username
|
||||
t.string :facebook_token
|
||||
|
||||
t.database_authenticatable :null => false
|
||||
t.confirmable
|
||||
t.recoverable
|
||||
|
|
|
@ -1,81 +1,47 @@
|
|||
# This file is auto-generated from the current state of the database. Instead of editing this file,
|
||||
# please use the migrations feature of Active Record to incrementally modify your database, and
|
||||
# then regenerate this schema definition.
|
||||
# This file is auto-generated from the current state of the database. Instead
|
||||
# of editing this file, please use the migrations feature of Active Record to
|
||||
# incrementally modify your database, and then regenerate this schema definition.
|
||||
#
|
||||
# Note that this schema.rb definition is the authoritative source for your database schema. If you need
|
||||
# to create the application database on another system, you should be using db:schema:load, not running
|
||||
# all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
||||
# Note that this schema.rb definition is the authoritative source for your
|
||||
# database schema. If you need to create the application database on another
|
||||
# system, you should be using db:schema:load, not running all the migrations
|
||||
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
||||
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
||||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20100401102949) do
|
||||
|
||||
create_table "accounts", :force => true do |t|
|
||||
t.string "email", :default => "", :null => false
|
||||
t.string "encrypted_password", :default => "", :null => false
|
||||
t.string "password_salt", :default => "", :null => false
|
||||
t.string "username"
|
||||
t.string "confirmation_token"
|
||||
t.datetime "confirmed_at"
|
||||
t.datetime "confirmation_sent_at"
|
||||
t.string "reset_password_token"
|
||||
t.string "remember_token"
|
||||
t.datetime "remember_created_at"
|
||||
t.integer "sign_in_count", :default => 0
|
||||
t.datetime "current_sign_in_at"
|
||||
t.datetime "last_sign_in_at"
|
||||
t.string "current_sign_in_ip"
|
||||
t.string "last_sign_in_ip"
|
||||
t.integer "failed_attempts", :default => 0
|
||||
t.string "unlock_token"
|
||||
t.datetime "locked_at"
|
||||
t.string "authentication_token"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
create_table "admins", :force => true do |t|
|
||||
t.string "email", :default => ""
|
||||
t.string "encrypted_password", :default => ""
|
||||
t.string "password_salt", :default => ""
|
||||
t.string "username"
|
||||
t.string "confirmation_token"
|
||||
t.datetime "confirmed_at"
|
||||
t.datetime "confirmation_sent_at"
|
||||
t.string "email", :default => ""
|
||||
t.string "encrypted_password", :limit => 128, :default => ""
|
||||
t.string "password_salt", :default => ""
|
||||
t.string "reset_password_token"
|
||||
t.string "remember_token"
|
||||
t.datetime "remember_created_at"
|
||||
t.integer "sign_in_count", :default => 0
|
||||
t.datetime "current_sign_in_at"
|
||||
t.datetime "last_sign_in_at"
|
||||
t.string "current_sign_in_ip"
|
||||
t.string "last_sign_in_ip"
|
||||
t.integer "failed_attempts", :default => 0
|
||||
t.integer "failed_attempts", :default => 0
|
||||
t.string "unlock_token"
|
||||
t.datetime "locked_at"
|
||||
t.string "authentication_token"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
create_table "users", :force => true do |t|
|
||||
t.string "email", :default => "", :null => false
|
||||
t.string "encrypted_password", :default => "", :null => false
|
||||
t.string "password_salt", :default => "", :null => false
|
||||
t.string "username"
|
||||
t.string "facebook_token"
|
||||
t.string "email", :default => "", :null => false
|
||||
t.string "encrypted_password", :limit => 128, :default => "", :null => false
|
||||
t.string "password_salt", :default => "", :null => false
|
||||
t.string "confirmation_token"
|
||||
t.datetime "confirmed_at"
|
||||
t.datetime "confirmation_sent_at"
|
||||
t.string "reset_password_token"
|
||||
t.string "remember_token"
|
||||
t.datetime "remember_created_at"
|
||||
t.integer "sign_in_count", :default => 0
|
||||
t.integer "sign_in_count", :default => 0
|
||||
t.datetime "current_sign_in_at"
|
||||
t.datetime "last_sign_in_at"
|
||||
t.string "current_sign_in_ip"
|
||||
t.string "last_sign_in_ip"
|
||||
t.integer "failed_attempts", :default => 0
|
||||
t.integer "failed_attempts", :default => 0
|
||||
t.string "unlock_token"
|
||||
t.datetime "locked_at"
|
||||
t.string "authentication_token"
|
||||
|
|
|
@ -12,7 +12,11 @@ module SharedUser
|
|||
|
||||
module ExtendMethods
|
||||
def find_for_facebook_oauth(access_token, signed_in_resource=nil)
|
||||
User.create { |u| u.update_with_facebook_oauth(access_token) }
|
||||
data = ActiveSupport::JSON.decode(access_token.get('/me'))
|
||||
user = signed_in_resource || User.find_by_email(data["email"]) || User.new
|
||||
user.update_with_facebook_oauth(access_token, data)
|
||||
user.save
|
||||
user
|
||||
end
|
||||
|
||||
def new_with_session(params, session)
|
||||
|
@ -25,18 +29,20 @@ module SharedUser
|
|||
end
|
||||
end
|
||||
|
||||
def update_with_facebook_oauth(access_token)
|
||||
data = ActiveSupport::JSON.decode(access_token.get('/me'))
|
||||
def update_with_facebook_oauth(access_token, data=nil)
|
||||
data ||= ActiveSupport::JSON.decode(access_token.get('/me'))
|
||||
|
||||
self.username = data["username"] unless username.present?
|
||||
self.email = data["email"] unless email.present?
|
||||
self.confirmed_at ||= Time.now
|
||||
|
||||
unless password.present?
|
||||
self.confirmed_at ||= Time.now
|
||||
self.facebook_token = access_token.token
|
||||
|
||||
unless encrypted_password.present?
|
||||
self.password = Devise.friendly_token
|
||||
self.password_confirmation = nil
|
||||
end
|
||||
|
||||
yield self if block_given?
|
||||
yield self if block_given?
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue