[rspec-users] before_save model callback rspec testing

Csongor Bartus lists at ruby-forum.com
Fri Jun 20 12:01:42 EDT 2008


Thanks Pat,

I've tried this way but the test did not passed ...
I'm trying to Rspec Authorization's plugin User class 
(http://www.writertopia.com/developers/authorization)

Which looks like this:

# == Schema Information
# Schema version: 92
#
# Table name: users
#
#  id                        :integer(11)     not null, primary key
#  login                     :string(255)
#  email                     :string(255)
#  crypted_password          :string(40)
#  salt                      :string(40)
#  created_at                :datetime
#  updated_at                :datetime
#  remember_token            :string(255)
#  remember_token_expires_at :datetime
#


require 'digest/sha1'

class User < ActiveRecord::Base

  # Relationships
  # -------------
  has_many :roles, :dependent => :destroy


  # Authentication plugins
  # ----------------------
  acts_as_authorized_user
  acts_as_authorizable


  # Callbacks
  # ---------

  # for Authentication
  before_save :encrypt_password


  # methods from the Authentication plugin
  # --------------------------------------

  # Hardwired roles
  def has_role?( role, authorized_object = nil )
    # - site admin
    return true if self.login.downcase == 'admin' and (role == 'admin' 
or role == 'site_admin')
    super
  end

  # Authenticates a user by their login name and unencrypted password. 
Returns the user or nil.
  def self.authenticate(login, password)
    u = find_by_login(login) # need to get the salt
    u && u.authenticated?(password) ? u : nil
  end

  # Encrypts some data with the salt.
  def self.encrypt(password, salt)
    Digest::SHA1.hexdigest("--#{salt}--#{password}--")
  end

  # Encrypts the password with the user salt
  def encrypt(password)
    self.class.encrypt(password, salt)
  end

  def authenticated?(password)
    crypted_password == encrypt(password)
  end

  def remember_token?
    remember_token_expires_at && Time.now.utc < 
remember_token_expires_at
  end

  # These create and unset the fields required for remembering users 
between browser closes
  def remember_me
    self.remember_token_expires_at = 2.weeks.from_now.utc
    self.remember_token            = 
encrypt("#{email}--#{remember_token_expires_at}")
    save(false)
  end

  def forget_me
    self.remember_token_expires_at = nil
    self.remember_token            = nil
    save(false)
  end


  protected

    def encrypt_password
      return if password.blank?
      self.salt = 
Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
      self.crypted_password = encrypt(password)
    end


    def password_required?
      crypted_password.blank? || !password.blank?
    end

end


I've managed to Rspec the following tests (copying from Rspec output):

User validations
- :login must be present
- :email must be present
- :password must be present
- :password_confirmation must be present
- :login length must be 2..40
- :email length must be 2..40
- :password length must be 2..40
- :login must be unique
- :email must be unique
- :login must not contain <  >  +  :  ;  !  #  $  %  ^  &  *  /
- :email must not contain <  >  +  :  ;  !  #  $  %  ^  &  *  /
- :password must not contain <  >  +  :  ;  !  #  $  %  ^  &  *  /

and

User Acts As Authenticated Authentication
- cannot login with empty username and empty password
- cannot login with valid username and empty password
- cannot login with empty username and valid password
- cannot login with invalid username
- cannot login with invalid password
- can login with valid username and valid password
- there can be two passwords with the same value


But when I'm trying to test if the password is encrypted I'm getting 
errors.

I'm trying "your" way:

u = User.create(:login => "test", :email => "test at test.com", :password 
=> "test123", :password_confirmation => "test123")
u.crypted_password.should_not be_nil

the error message is:
NoMethodError in 'User ActiveRecord Callbacks before save encrypts 
password'
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each
./spec/models/user_spec.rb:82:

[line 82 ia User.create(...)


and "my" way:

@user = User.new
        @user.login = "test"
        @user.email = "test at test.com"
        @user.password = "test123"
        @user.password_confirmation = "test123"
        @user.save
@user.crypted_password.should_not be_nil

the error message is:
'User Acts As Authenticated encrypts password' FAILED
expected not nil, got nil




-- 
Posted via http://www.ruby-forum.com/.


More information about the rspec-users mailing list