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
sent_on Time.now
content_type 'text/html'
body record.class.name.downcase.to_sym => record
body record.class.name.downcase.to_sym => record, :resource => record
end
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:
<%#= 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.
<%#= 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.
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
#
def authenticated?(scope=resource_name)
def authenticated?(scope=:default)
warden.authenticated?(scope.to_sym)
end
alias_method :logged_in?, :authenticated?

View File

@ -25,9 +25,10 @@ module Devise
end
# 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)
end

View File

@ -2,12 +2,6 @@ module Devise
module Controllers
module Resources
# def self.included(base)
# base.class_eval do
# helper_method :resource, :resource_name, :resource_class
# end
# end
def resource
@resource ||= instance_variable_get(:"@#{resource_name}")
end
@ -27,7 +21,7 @@ module Devise
private
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

View File

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

View File

@ -13,6 +13,16 @@ class ResourcesTest < ActionController::TestCase
assert_equal 'admin', @controller.resource_name
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
@request.path = '/users/session'
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'
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
ActionMailer::Base.deliveries.clear
visit 'users/session/new'
visit new_user_session_path
click_link 'Didn\'t receive confirmation instructions?'
fill_in 'email', :with => user.email
@ -15,9 +16,10 @@ class ConfirmationsTest < ActionController::IntegrationTest
# assert_redirected_to root_path
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 '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')
assert_response :success
@ -26,7 +28,7 @@ class ConfirmationsTest < ActionController::IntegrationTest
assert_contain 'invalid confirmation'
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)
assert_not user.confirmed?
@ -39,7 +41,7 @@ class ConfirmationsTest < ActionController::IntegrationTest
assert user.reload.confirmed?
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
visit user_confirmation_path(:perishable_token => user.perishable_token)

View File

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

View File

@ -7,17 +7,36 @@ class ActionController::IntegrationTest
def create_user(options={})
@user ||= begin
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
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)
visit 'users/session/new'
fill_in 'email', :with => 'test@test.com'
visit new_user_session_path
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'
yield if block_given?
click_button 'Sign In'

View File

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