Adding separated tests for admins and users to enforce modularization. Rewrite of several tests.

This commit is contained in:
Carlos A. da Silva 2009-10-11 10:49:25 -03:00
parent 62bef5605a
commit 1226c3d8de
17 changed files with 448 additions and 150 deletions

View File

@ -23,7 +23,7 @@ class Notifier < ::ActionMailer::Base
recipients record.email recipients record.email
sent_on Time.now sent_on Time.now
content_type 'text/html' content_type 'text/html'
body record.class.name.downcase.to_sym => record body record.class.name.downcase.to_sym => record, :resource => record
end end
def translate(key, options={}) def translate(key, options={})

View File

@ -1,5 +1,5 @@
Welcome <%= @user.email %>! Welcome <%= @resource.email %>!
You can confirm your account through the link below: You can confirm your account through the link below:
<%#= link_to 'Confirm my account', confirmation_url(@user, :perishable_token => @user.perishable_token) %> <%= link_to 'Confirm my account', confirmation_url(@resource, :perishable_token => @resource.perishable_token) %>

View File

@ -1,8 +1,8 @@
Hello <%= @user.email %>! Hello <%= @resource.email %>!
Someone has requested a link to change your password, and you can do this through the link below. Someone has requested a link to change your password, and you can do this through the link below.
<%#= link_to 'Change my password', edit_password_url(@user, :perishable_token => @user.perishable_token) %> <%= link_to 'Change my password', edit_password_url(@resource, :perishable_token => @resource.perishable_token) %>
If you didn't request this, please ignore this email. If you didn't request this, please ignore this email.
Your password won't change until you access the link above and create a new one. Your password won't change until you access the link above and create a new one.

View File

@ -24,7 +24,7 @@ module Devise
# Proxy to the authenticated? method on warden # Proxy to the authenticated? method on warden
# #
def authenticated?(scope=resource_name) def authenticated?(scope=:default)
warden.authenticated?(scope.to_sym) warden.authenticated?(scope.to_sym)
end end
alias_method :logged_in?, :authenticated? alias_method :logged_in?, :authenticated?

View File

@ -25,9 +25,10 @@ module Devise
end end
# Verify authenticated user and redirect to sign in if no authentication # Verify authenticated user and redirect to sign in if no authentication
# is found # is found. By default resource_name is verified, but you can pass in any
# scope to verify whether there is a user authenticated within that scope.
# #
def authenticate!(scope) def authenticate!(scope=resource_name)
redirect_to new_session_path(scope) unless authenticated?(scope) redirect_to new_session_path(scope) unless authenticated?(scope)
end end

View File

@ -2,12 +2,6 @@ module Devise
module Controllers module Controllers
module Resources module Resources
# def self.included(base)
# base.class_eval do
# helper_method :resource, :resource_name, :resource_class
# end
# end
def resource def resource
@resource ||= instance_variable_get(:"@#{resource_name}") @resource ||= instance_variable_get(:"@#{resource_name}")
end end
@ -27,7 +21,7 @@ module Devise
private private
def resource_name_or_request_path(object=nil) def resource_name_or_request_path(object=nil)
object ? (object.is_a?(::ActiveRecord::Base) ? object.class.name : object) : request.path object ? (object.is_a?(::ActiveRecord::Base) ? object.class.name.downcase : object) : request.path
end end
end end
end end

View File

@ -34,13 +34,13 @@ class ControllerAuthenticableTest < ActionController::TestCase
end end
test 'run authenticate? with scope on warden' do test 'run authenticate? with scope on warden' do
@mock_warden.expects(:authenticated?).with(:my_scope).returns(true) @mock_warden.expects(:authenticated?).with(:my_scope)
@controller.authenticated?(:my_scope) @controller.authenticated?(:my_scope)
end end
test 'proxy logged_in? to authenticated' do test 'proxy logged_in? to authenticated' do
@mock_warden.expects(:authenticated?).returns(true) @mock_warden.expects(:authenticated?).with(:my_scope)
@controller.logged_in? @controller.logged_in?(:my_scope)
end end
test 'run user on warden' do test 'run user on warden' do

View File

@ -13,6 +13,16 @@ class ResourcesTest < ActionController::TestCase
assert_equal 'admin', @controller.resource_name assert_equal 'admin', @controller.resource_name
end end
test 'get resource name from an active_record object' do
user = Admin.new
assert_equal 'admin', @controller.resource_name(user)
end
test 'get resource name from a symbol or string' do
assert_equal 'admin', @controller.resource_name(:admin)
assert_equal 'admin', @controller.resource_name('admin')
end
test 'get resource class from request path' do test 'get resource class from request path' do
@request.path = '/users/session' @request.path = '/users/session'
assert_equal User, @controller.resource_class assert_equal User, @controller.resource_class

View File

@ -0,0 +1,99 @@
require 'test/test_helper'
class AdminsAuthenticationTest < ActionController::IntegrationTest
test 'home should be accessible without signed in admins' do
visit '/'
assert_response :success
assert_template 'home/index'
end
test 'not signed in as admin should not be able to access admins actions' do
get admins_path
assert_response :redirect
assert_redirected_to new_admin_session_path
assert_not warden.authenticated?(:admin)
end
test 'signed in as user should not be able to access admins actions' do
sign_in_as_user
assert warden.authenticated?(:user)
assert_not warden.authenticated?(:admin)
get admins_path
assert_response :redirect
assert_redirected_to new_admin_session_path
end
test 'signed in as admin should be able to access admin actions successfully' do
sign_in_as_admin
assert warden.authenticated?(:admin)
assert_not warden.authenticated?(:user)
get admins_path
assert_response :success
assert_template 'admins/index'
assert_contain 'Welcome Admin'
end
test 'admin signing in with invalid email should return to sign in form with error message' do
sign_in_as_admin do
fill_in 'email', :with => 'wrongemail@test.com'
end
assert_response :success
assert_template 'sessions/new'
assert_contain 'Invalid email or password'
assert_not warden.authenticated?(:admin)
end
test 'admin signing in with invalid pasword should return to sign in form with error message' do
sign_in_as_admin do
fill_in 'password', :with => 'abcdef'
end
assert_response :success
assert_template 'sessions/new'
assert_contain 'Invalid email or password'
assert_not warden.authenticated?(:admin)
end
test 'not confirmed admin should not be able to login' do
sign_in_as_admin(:confirm => false)
assert_contain 'Invalid email or password'
assert_not warden.authenticated?(:admin)
end
test 'already confirmed admin should be able to sign in successfully' do
sign_in_as_admin
assert_response :success
assert_template 'home/index'
assert_contain 'Signed in successfully'
assert_not_contain 'Sign In'
assert warden.authenticated?(:admin)
assert_not warden.authenticated?(:user)
end
test 'not authenticated admin should not be able to sign out' do
delete admin_session_path
assert_response :redirect
assert_redirected_to new_admin_session_path
assert_not warden.authenticated?(:admin)
end
test 'authenticated admin should be able to sign out' do
sign_in_as_admin
assert warden.authenticated?(:admin)
delete admin_session_path
assert_response :redirect
assert_redirected_to new_admin_session_path
assert_not warden.authenticated?(:admin)
end
end

View File

@ -0,0 +1,49 @@
require 'test/test_helper'
class AdminsConfirmationTest < ActionController::IntegrationTest
test 'admin should be able to request a new confirmation' do
admin = create_admin
ActionMailer::Base.deliveries.clear
visit new_admin_session_path
click_link 'Didn\'t receive confirmation instructions?'
fill_in 'email', :with => admin.email
click_button 'Resend confirmation instructions'
assert_template 'sessions/new'
assert_contain 'You will receive an email with instructions about how to confirm your account in a few minutes'
assert_equal 1, ActionMailer::Base.deliveries.size
end
test 'admin with invalid perishable token should not be able to confirm an account' do
visit user_confirmation_path(:perishable_token => 'invalid_perishable')
assert_response :success
assert_template 'confirmations/new'
assert_have_selector '#errorExplanation'
assert_contain 'invalid confirmation'
end
test 'admin with valid perishable token should be able to confirm an account' do
admin = create_admin(:confirm => false)
assert_not admin.confirmed?
visit admin_confirmation_path(:perishable_token => admin.perishable_token)
assert_template 'sessions/new'
assert_contain 'Your account was successfully confirmed!'
assert admin.reload.confirmed?
end
test 'admin already confirmed user should not be able to confirm the account again' do
admin = create_admin
visit admin_confirmation_path(:perishable_token => admin.perishable_token)
assert_template 'confirmations/new'
assert_have_selector '#errorExplanation'
assert_contain 'already confirmed'
end
end

View File

@ -0,0 +1,104 @@
require 'test/test_helper'
class AdminsPasswordRecoveryTest < ActionController::IntegrationTest
def visit_new_password_path
visit new_admin_session_path
click_link 'Forgot password?'
end
def request_forgot_password(&block)
visit_new_password_path
assert_response :success
assert_template 'passwords/new'
assert_not warden.authenticated?(:admin)
fill_in 'email', :with => 'admin@test.com'
yield if block_given?
click_button 'Send me reset password instructions'
end
def reset_password(options={}, &block)
visit edit_admin_password_path(:perishable_token => options[:perishable_token])
assert_response :success
assert_template 'passwords/edit'
fill_in 'Password', :with => '987654321'
fill_in 'Password confirmation', :with => '987654321'
yield if block_given?
click_button 'Change my password'
end
test 'authenticated admin should not be able to visit forgot password page' do
sign_in_as_admin
assert warden.authenticated?(:admin)
get new_admin_password_path
assert_response :redirect
assert_redirected_to root_path
end
test 'not authenticated admin should be able to request a forgot password' do
create_admin
request_forgot_password
assert_template 'sessions/new'
assert_contain 'You will receive an email with instructions about how to reset your password in a few minutes.'
end
test 'not authenticated admin with invalid email should receive an error message' do
request_forgot_password do
fill_in 'email', :with => 'invalid.test@test.com'
end
assert_response :success
assert_template 'passwords/new'
assert_have_selector 'input[type=text][value=\'invalid.test@test.com\']'
assert_contain 'Email not found'
end
test 'authenticated admin should not be able to visit edit password page' do
sign_in_as_admin
get edit_admin_password_path
assert_response :redirect
assert_redirected_to root_path
assert warden.authenticated?(:admin)
end
test 'not authenticated admin with invalid perishable token should not be able to change his password' do
admin = create_admin
reset_password :perishable_token => 'invalid_perishable'
assert_response :success
assert_template 'passwords/edit'
assert_have_selector '#errorExplanation'
assert_contain 'invalid confirmation'
assert_not admin.reload.valid_password?('987654321')
end
test 'not authenticated admin with valid perisable token but invalid password should not be able to change his password' do
admin = create_admin
reset_password :perishable_token => admin.perishable_token do
fill_in 'Password confirmation', :with => 'other_password'
end
assert_response :success
assert_template 'passwords/edit'
assert_have_selector '#errorExplanation'
assert_contain 'Password doesn\'t match confirmation'
assert_not admin.reload.valid_password?('987654321')
end
test 'not authenticated admin with valid data should be able to change his password' do
admin = create_admin
reset_password :perishable_token => admin.perishable_token
assert_template 'sessions/new'
assert_contain 'Your password was changed successfully.'
assert admin.reload.valid_password?('987654321')
end
end

View File

@ -1,67 +0,0 @@
require 'test/test_helper'
class AuthenticationTest < ActionController::IntegrationTest
test 'not authenticated user should load up sign in form' do
visit '/'
assert_response :success
assert_template 'sessions/new'
end
test 'signing in with invalid email should return to sign in form with error message' do
sign_in do
fill_in 'email', :with => 'wrongemail@test.com'
end
assert_response :success
assert_template 'sessions/new'
assert_contain 'Invalid email or password'
assert !warden.authenticated?(:user)
end
test 'signing in with invalid pasword should return to sign in form with error message' do
sign_in do
fill_in 'password', :with => 'abcdef'
end
assert_response :success
assert_template 'sessions/new'
assert_contain 'Invalid email or password'
assert !warden.authenticated?
end
test 'not confirmed user should not be able to login' do
sign_in(:confirm => false)
assert_contain 'Invalid email or password'
assert !warden.authenticated?
end
test 'already confirmed user should be able to sign in successfully' do
sign_in
assert_response :success
assert_template 'home/index'
assert_contain 'Signed in successfully'
assert_not_contain 'Sign In'
assert warden.authenticated?(:user)
end
test 'not authenticated user should not be able to sign out' do
delete 'users/session'
assert_response :redirect
assert_redirected_to new_user_session_path
assert !warden.authenticated?(:user)
end
test 'authenticated user should be able to sign out' do
sign_in
assert warden.authenticated?(:user)
delete 'users/session'
assert_response :redirect
assert_redirected_to new_user_session_path
assert !warden.authenticated?(:user)
end
end

View File

@ -0,0 +1,99 @@
require 'test/test_helper'
class UsersAuthenticationTest < ActionController::IntegrationTest
test 'home should be accessible without signed in users' do
visit '/'
assert_response :success
assert_template 'home/index'
end
test 'not signed in as user should not be able to access users actions' do
get users_path
assert_response :redirect
assert_redirected_to new_user_session_path
assert_not warden.authenticated?(:user)
end
test 'signed in as admin should not be able to access users actions' do
sign_in_as_admin
assert warden.authenticated?(:admin)
assert_not warden.authenticated?(:user)
get users_path
assert_response :redirect
assert_redirected_to new_user_session_path
end
test 'signed in as user should be able to access users actions successfully' do
sign_in_as_user
assert warden.authenticated?(:user)
assert_not warden.authenticated?(:admin)
get users_path
assert_response :success
assert_template 'users/index'
assert_contain 'Welcome User'
end
test 'user signing in with invalid email should return to sign in form with error message' do
sign_in_as_user do
fill_in 'email', :with => 'wrongemail@test.com'
end
assert_response :success
assert_template 'sessions/new'
assert_contain 'Invalid email or password'
assert_not warden.authenticated?(:user)
end
test 'user signing in with invalid pasword should return to sign in form with error message' do
sign_in_as_user do
fill_in 'password', :with => 'abcdef'
end
assert_response :success
assert_template 'sessions/new'
assert_contain 'Invalid email or password'
assert_not warden.authenticated?(:user)
end
test 'not confirmed user should not be able to login' do
sign_in_as_user(:confirm => false)
assert_contain 'Invalid email or password'
assert_not warden.authenticated?(:user)
end
test 'already confirmed user should be able to sign in successfully' do
sign_in_as_user
assert_response :success
assert_template 'home/index'
assert_contain 'Signed in successfully'
assert_not_contain 'Sign In'
assert warden.authenticated?(:user)
assert_not warden.authenticated?(:admin)
end
test 'not authenticated user should not be able to sign out' do
delete user_session_path
assert_response :redirect
assert_redirected_to new_user_session_path
assert_not warden.authenticated?(:user)
end
test 'authenticated user should be able to sign out' do
sign_in_as_user
assert warden.authenticated?(:user)
delete user_session_path
assert_response :redirect
assert_redirected_to new_user_session_path
assert_not warden.authenticated?(:user)
end
end

View File

@ -1,11 +1,12 @@
require 'test/test_helper' require 'test/test_helper'
class ConfirmationsTest < ActionController::IntegrationTest class UsersConfirmationTest < ActionController::IntegrationTest
test 'should be able to request a new confirmation' do test 'user should be able to request a new confirmation' do
user = create_user user = create_user
ActionMailer::Base.deliveries.clear
visit 'users/session/new' visit new_user_session_path
click_link 'Didn\'t receive confirmation instructions?' click_link 'Didn\'t receive confirmation instructions?'
fill_in 'email', :with => user.email fill_in 'email', :with => user.email
@ -15,9 +16,10 @@ class ConfirmationsTest < ActionController::IntegrationTest
# assert_redirected_to root_path # assert_redirected_to root_path
assert_template 'sessions/new' assert_template 'sessions/new'
assert_contain 'You will receive an email with instructions about how to confirm your account in a few minutes' assert_contain 'You will receive an email with instructions about how to confirm your account in a few minutes'
assert_equal 1, ActionMailer::Base.deliveries.size
end end
test 'with invalid perishable token should not be able to confirm an account' do test 'user with invalid perishable token should not be able to confirm an account' do
visit user_confirmation_path(:perishable_token => 'invalid_perishable') visit user_confirmation_path(:perishable_token => 'invalid_perishable')
assert_response :success assert_response :success
@ -26,7 +28,7 @@ class ConfirmationsTest < ActionController::IntegrationTest
assert_contain 'invalid confirmation' assert_contain 'invalid confirmation'
end end
test 'with valid perishable token should be able to confirm an account' do test 'user with valid perishable token should be able to confirm an account' do
user = create_user(:confirm => false) user = create_user(:confirm => false)
assert_not user.confirmed? assert_not user.confirmed?
@ -39,7 +41,7 @@ class ConfirmationsTest < ActionController::IntegrationTest
assert user.reload.confirmed? assert user.reload.confirmed?
end end
test 'already confirmed user should not be able to confirm the account again' do test 'user already confirmed user should not be able to confirm the account again' do
user = create_user user = create_user
visit user_confirmation_path(:perishable_token => user.perishable_token) visit user_confirmation_path(:perishable_token => user.perishable_token)

View File

@ -1,36 +1,43 @@
require 'test/test_helper' require 'test/test_helper'
class PasswordRecoveryTest < ActionController::IntegrationTest class UsersPasswordRecoveryTest < ActionController::IntegrationTest
def visit_new_password_path def visit_new_password_path
visit 'users/session/new' visit new_user_session_path
click_link 'Forgot password?' click_link 'Forgot password?'
end end
def request_forgot_password(&block) def request_forgot_password(&block)
visit_new_password_path visit_new_password_path
fill_in 'email', :with => 'test@test.com' assert_response :success
assert_template 'passwords/new'
assert_not warden.authenticated?(:user)
fill_in 'email', :with => 'user@test.com'
yield if block_given? yield if block_given?
click_button 'Send me reset password instructions' click_button 'Send me reset password instructions'
end end
def reset_password(options={}, &block)
visit edit_user_password_path(:perishable_token => options[:perishable_token])
assert_response :success
assert_template 'passwords/edit'
fill_in 'Password', :with => '987654321'
fill_in 'Password confirmation', :with => '987654321'
yield if block_given?
click_button 'Change my password'
end
test 'authenticated user should not be able to visit forgot password page' do test 'authenticated user should not be able to visit forgot password page' do
sign_in sign_in_as_user
assert warden.authenticated?(:user)
get new_user_password_path get new_user_password_path
assert_response :redirect assert_response :redirect
assert_redirected_to root_path assert_redirected_to root_path
assert warden.authenticated?(:user)
end
test 'not authenticated user should be able to visit forgot password page' do
visit_new_password_path
assert_response :success
assert_template 'passwords/new'
assert !warden.authenticated?(:user)
end end
test 'not authenticated user should be able to request a forgot password' do test 'not authenticated user should be able to request a forgot password' do
@ -56,7 +63,7 @@ class PasswordRecoveryTest < ActionController::IntegrationTest
end end
test 'authenticated user should not be able to visit edit password page' do test 'authenticated user should not be able to visit edit password page' do
sign_in sign_in_as_user
get edit_user_password_path get edit_user_password_path
@ -65,51 +72,36 @@ class PasswordRecoveryTest < ActionController::IntegrationTest
assert warden.authenticated?(:user) assert warden.authenticated?(:user)
end end
test 'not authenticated with invalid perishable token should not be able to change his password' do test 'not authenticated user with invalid perishable token should not be able to change his password' do
create_user user = create_user
visit edit_user_password_path(:perishable_token => 'invalid_perishable') reset_password :perishable_token => 'invalid_perishable'
assert_response :success
assert_template 'passwords/edit'
fill_in 'Password', :with => '987654321'
fill_in 'Password confirmation', :with => '987654321'
click_button 'Change my password'
assert_response :success assert_response :success
assert_template 'passwords/edit' assert_template 'passwords/edit'
assert_have_selector '#errorExplanation' assert_have_selector '#errorExplanation'
assert_contain 'invalid confirmation' assert_contain 'invalid confirmation'
assert !@user.reload.valid_password?('987654321') assert_not user.reload.valid_password?('987654321')
end end
test 'not authenticated with valid perisable token but invalid password should not be able to change his password' do test 'not authenticated user with valid perisable token but invalid password should not be able to change his password' do
create_user user = create_user
visit edit_user_password_path(:perishable_token => @user.perishable_token) reset_password :perishable_token => user.perishable_token do
fill_in 'Password confirmation', :with => 'other_password'
fill_in 'Password', :with => '987654321' end
fill_in 'Password confirmation', :with => 'other_password'
click_button 'Change my password'
assert_response :success assert_response :success
assert_template 'passwords/edit' assert_template 'passwords/edit'
assert_have_selector '#errorExplanation' assert_have_selector '#errorExplanation'
assert_contain 'Password doesn\'t match confirmation' assert_contain 'Password doesn\'t match confirmation'
assert !@user.reload.valid_password?('987654321') assert_not user.reload.valid_password?('987654321')
end end
test 'not authenticated with valid data should be able to change his password' do test 'not authenticated user with valid data should be able to change his password' do
create_user user = create_user
visit edit_user_password_path(:perishable_token => @user.perishable_token) reset_password :perishable_token => user.perishable_token
fill_in 'Password', :with => '987654321'
fill_in 'Password confirmation', :with => '987654321'
click_button 'Change my password'
# TODO: revisit this
assert_template 'sessions/new' assert_template 'sessions/new'
# assert_response :redirect
# assert_redirected_to new_session_path
assert_contain 'Your password was changed successfully.' assert_contain 'Your password was changed successfully.'
assert @user.reload.valid_password?('987654321') assert user.reload.valid_password?('987654321')
end end
end end

View File

@ -7,17 +7,36 @@ class ActionController::IntegrationTest
def create_user(options={}) def create_user(options={})
@user ||= begin @user ||= begin
user = User.create!( user = User.create!(
:email => 'test@test.com', :password => '123456', :password_confirmation => '123456' :email => 'user@test.com', :password => '123456', :password_confirmation => '123456'
) )
user.confirm! unless options[:confirm] == false user.confirm! unless options[:confirm] == false
user user
end end
end end
def sign_in(options={}, &block) def create_admin(options={})
@admin ||= begin
admin = Admin.create!(
:email => 'admin@test.com', :password => '123456', :password_confirmation => '123456'
)
admin.confirm! unless options[:confirm] == false
admin
end
end
def sign_in_as_user(options={}, &block)
create_user(options) create_user(options)
visit 'users/session/new' visit new_user_session_path
fill_in 'email', :with => 'test@test.com' fill_in 'email', :with => 'user@test.com'
fill_in 'password', :with => '123456'
yield if block_given?
click_button 'Sign In'
end
def sign_in_as_admin(options={}, &block)
create_admin(options)
visit new_admin_session_path
fill_in 'email', :with => 'admin@test.com'
fill_in 'password', :with => '123456' fill_in 'password', :with => '123456'
yield if block_given? yield if block_given?
click_button 'Sign In' click_button 'Sign In'

View File

@ -14,18 +14,14 @@ ActiveRecord::Migration.verbose = false
ActiveRecord::Base.logger = Logger.new(nil) ActiveRecord::Base.logger = Logger.new(nil)
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:") ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
ActiveRecord::Schema.define(:version => 1) do ActiveRecord::Schema.define(:version => 1) do
create_table :users do |t| [:users, :admins].each do |table|
t.string :email, :null => false create_table table do |t|
t.string :encrypted_password, :null => false t.string :email, :null => false
t.string :password_salt, :null => false t.string :encrypted_password, :null => false
t.string :perishable_token t.string :password_salt, :null => false
t.datetime :confirmed_at t.string :perishable_token
end t.datetime :confirmed_at
end
create_table :admins do |t|
t.string :email, :null => false
t.string :encrypted_password, :null => false
t.string :password_salt, :null => false
end end
end end