Additions to User unit tests, inspired by a review of the acts_as_authenticated generator

git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@559 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
lukemelia 2007-07-07 04:31:32 +00:00
parent a7e8a849e3
commit ae9ecb398f
4 changed files with 202 additions and 53 deletions

View file

@ -83,6 +83,7 @@ class User < ActiveRecord::Base
validates_presence_of :login
validates_presence_of :password, :if => :password_required?
validates_length_of :password, :within => 5..40, :if => :password_required?
validates_presence_of :password_confirmation, :if => :password_required?
validates_confirmation_of :password
validates_length_of :login, :within => 3..80
validates_uniqueness_of :login, :on => :create

View file

@ -0,0 +1,113 @@
module AuthenticatedTestHelper
# Sets the current user in the session from the user fixtures.
def login_as(user)
@request.session[:user] = user ? users(user).id : nil
end
def content_type(type)
@request.env['Content-Type'] = type
end
def accept(accept)
@request.env["HTTP_ACCEPT"] = accept
end
def authorize_as(user)
if user
@request.env["HTTP_AUTHORIZATION"] = "Basic #{Base64.encode64("#{users(user).login}:test")}"
accept 'application/xml'
content_type 'application/xml'
else
@request.env["HTTP_AUTHORIZATION"] = nil
accept nil
content_type nil
end
end
# http://project.ioni.st/post/217#post-217
#
# def test_new_publication
# assert_difference(Publication, :count) do
# post :create, :publication => {...}
# # ...
# end
# end
#
def assert_difference(object, method = nil, difference = 1)
initial_value = object.send(method)
yield
assert_equal initial_value + difference, object.send(method), "#{object}##{method}"
end
def assert_no_difference(object, method, &block)
assert_difference object, method, 0, &block
end
# Assert the block redirects to the login
#
# assert_requires_login(:bob) { |c| c.get :edit, :id => 1 }
#
def assert_requires_login(login = nil)
yield HttpLoginProxy.new(self, login)
end
def assert_http_authentication_required(login = nil)
yield XmlLoginProxy.new(self, login)
end
def reset!(*instance_vars)
instance_vars = [:controller, :request, :response] unless instance_vars.any?
instance_vars.collect! { |v| "@#{v}".to_sym }
instance_vars.each do |var|
instance_variable_set(var, instance_variable_get(var).class.new)
end
end
end
class BaseLoginProxy
attr_reader :controller
attr_reader :options
def initialize(controller, login)
@controller = controller
@login = login
end
private
def authenticated
raise NotImplementedError
end
def check
raise NotImplementedError
end
def method_missing(method, *args)
@controller.reset!
authenticate
@controller.send(method, *args)
check
end
end
class HttpLoginProxy < BaseLoginProxy
protected
def authenticate
@controller.login_as @login if @login
end
def check
@controller.assert_redirected_to :controller => 'account', :action => 'login'
end
end
class XmlLoginProxy < BaseLoginProxy
protected
def authenticate
@controller.accept 'application/xml'
@controller.authorize_as @login if @login
end
def check
@controller.assert_response 401
end
end

View file

@ -1,7 +1,7 @@
ENV["RAILS_ENV"] = "test"
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
require File.expand_path(File.dirname(__FILE__) + "/../app/controllers/application")
require 'test/rails' #you need the zentest gem isntalled
require 'test/rails' #you need the zentest gem installed
require 'test_help'
require 'flexmock/test_unit' #and the flexmock gem, too!
@ -14,7 +14,8 @@ module Tracks
end
class Test::Unit::TestCase
include AuthenticatedTestHelper
def xml_document
@xml_document ||= HTML::Document.new(@response.body, false, true)
end
@ -24,6 +25,13 @@ class Test::Unit::TestCase
assert_select(*args, &block)
end
def assert_error_on(model_instance, attribute, expected_error)
actual_error = model_instance.errors.on attribute.to_sym
assert_equal expected_error, actual_error
end
alias_method :assert_errors_on, :assert_error_on
end
class Test::Rails::HelperTestCase

View file

@ -55,77 +55,57 @@ class UserTest < Test::Rails::TestCase
# Test a password shorter than 5 characters
#
def test_validate_short_password
assert_equal "#{Digest::SHA1.hexdigest("#{Tracks::Config.salt}--sesame--")}", @other_user.password
@other_user.password = "four"
assert !@other_user.save
assert_equal 1, @other_user.errors.count
assert_equal "is too short (minimum is 5 characters)", @other_user.errors.on(:password)
assert_no_difference User, :count do
u = create_user :password => generate_random_string(4)
assert_error_on u, :password, "is too short (minimum is 5 characters)"
end
end
# Test a password longer than 40 characters
#
def test_validate_long_password
assert_equal "#{Digest::SHA1.hexdigest("#{Tracks::Config.salt}--sesame--")}", @other_user.password
@other_user.password = generate_random_string(41)
assert !@other_user.save
assert_equal 1, @other_user.errors.count
assert_equal "is too long (maximum is 40 characters)", @other_user.errors.on(:password)
assert_no_difference User, :count do
u = create_user :password => generate_random_string(41)
assert_error_on u, :password, "is too long (maximum is 40 characters)"
end
end
# Test that correct length password is valid
#
def test_validate_correct_length_password
assert_equal "#{Digest::SHA1.hexdigest("#{Tracks::Config.salt}--sesame--")}", @other_user.password
@other_user.password = generate_random_string(6)
assert @other_user.save
assert_difference User, :count do
create_user :password => generate_random_string(6)
end
end
# Test a missing password
#
def test_validate_missing_password
assert_equal 2, @other_user.id
@other_user.password = ""
assert !@other_user.save
assert_equal 2, @other_user.errors.count
assert_equal ["is too short (minimum is 5 characters)", "can't be blank"], @other_user.errors.on(:password)
assert_no_difference User, :count do
u = create_user :password => ''
assert_errors_on u, :password, ["is too short (minimum is 5 characters)", "can't be blank"]
end
end
# Test a login shorter than 3 characters
#
def test_validate_short_login
assert_equal "jane", @other_user.login
@other_user.login = "ba"
assert !@other_user.save
assert_equal 1, @other_user.errors.count
assert_equal "is too short (minimum is 3 characters)", @other_user.errors.on(:login)
assert_no_difference User, :count do
u = create_user :login => 'ba'
assert_error_on u, :login, "is too short (minimum is 3 characters)"
end
end
# Test a login longer than 80 characters
#
def test_validate_long_login
assert_equal "jane", @other_user.login
@other_user.login = generate_random_string(81)
assert !@other_user.save
assert_equal 1, @other_user.errors.count
assert_equal "is too long (maximum is 80 characters)", @other_user.errors.on(:login)
assert_no_difference User, :count do
u = create_user :login => generate_random_string(81)
assert_error_on u, :login, "is too long (maximum is 80 characters)"
end
end
# Test that correct length login is valid
#
def test_validate_correct_length_login
assert_equal "jane", @other_user.login
@other_user.login = generate_random_string(6)
assert @other_user.save
assert_difference User, :count do
create_user :login => generate_random_string(6)
end
end
# Test a missing login
#
def test_validate_missing_login
assert_equal 2, @other_user.id
@other_user.login = ""
assert !@other_user.save
assert_equal 2, @other_user.errors.count
assert_equal ["is too short (minimum is 3 characters)", "can't be blank"], @other_user.errors.on(:login)
assert_no_difference User, :count do
u = create_user :login => ''
assert_errors_on u, :login, ["is too short (minimum is 3 characters)", "can't be blank"]
end
end
def test_display_name_with_first_and_last_name_set
@ -290,6 +270,53 @@ class UserTest < Test::Rails::TestCase
assert_equal 2, projects(:gardenclean).position
assert_equal 3, projects(:moremoney).position
end
def test_should_create_user
assert_difference User, :count do
user = create_user
assert !user.new_record?, "#{user.errors.full_messages.to_sentence}"
end
end
def test_should_require_login
assert_no_difference User, :count do
u = create_user(:login => nil)
assert u.errors.on(:login)
end
end
def test_should_require_password
assert_no_difference User, :count do
u = create_user(:password => nil)
assert u.errors.on(:password)
end
end
def test_should_require_password_confirmation
assert_no_difference User, :count do
u = create_user(:password_confirmation => nil)
assert u.errors.on(:password_confirmation)
end
end
def test_should_reset_password
users(:other_user).update_attributes(:password => 'new password', :password_confirmation => 'new password')
assert_equal users(:other_user), User.authenticate('jane', 'new password')
end
def test_should_not_rehash_password
users(:other_user).update_attributes(:login => 'jane2')
assert_equal users(:other_user), User.authenticate('jane2', 'sesame')
end
def test_should_authenticate_user
assert_equal users(:other_user), User.authenticate('jane', 'sesame')
end
protected
def create_user(options = {})
options[:password_confirmation] = options[:password] unless options.has_key?(:password_confirmation) || !options.has_key?(:password)
User.create({ :login => 'quire', :password => 'quire', :password_confirmation => 'quire' }.merge(options))
end
end