Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require 'digest/sha1'
- class User < ActiveRecord::Base
- # Virtual attribute for the unencrypted password
- attr_accessor :password
- # password and password confirmation matching is case insensitive; time to normalize
- before_validation :normalize_password_fields
- # before_validation :normalize_email -- geoff?
- validates_presence_of :login, :email, :postal_code, :dob
- validates_presence_of :password, :if => :password_required?
- validates_presence_of :password_confirmation, :if => :password_required?
- validates_length_of :password, :within => 4..32, :if => :password_required?
- validates_length_of :login, :within => 4..16
- validates_length_of :email, :within => 5..100
- validates_length_of :postal_code, :within => 5..16
- validates_confirmation_of :password, :if => :password_required?
- validates_format_of :postal_code,
- :with => /(\d{5,})|([ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ])\ {0,1}(\d[ABCEGHJKLMNPRSTVWXYZ]\d)/,
- :on => :save,
- :message => "has an invalid format"
- validates_format_of :login,
- :with => /^[A-Za-z0-9]+$/,
- :on => :save,
- :message => "can only contain alphanumeric characters"
- validates_length_of :mobile_phone_area, :is => 3
- validates_length_of :mobile_phone_prefix, :is => 3
- validates_length_of :mobile_phone_number, :is => 4
- validates_numericality_of :mobile_phone_area, :mobile_phone_prefix, :mobile_phone_number
- validates_format_of :email,
- :with => /^[A-Z0-9._-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i,
- :on => :save,
- :message=>"has an invalid format"
- validates_uniqueness_of :login, :email, :case_sensitive => false
- validates_date :dob, :before => Proc.new {13.years.ago}
- before_save :encrypt_password
- before_save :reformat_postal_code
- before_create :make_activation_code
- def validate
- if ReservedWord.find_by_word(login)
- logger.info "found reserved word match"
- errors.add("login", "is a bad word")
- end
- end
- def normalize_password_fields
- return if password.blank?
- return if password.nil?
- return if password_confirmation.blank?
- return if password_confirmation.nil?
- self.password = password.downcase
- self.password_confirmation = password_confirmation.downcase
- end
- # def normalize_email
- # self.email.downcase
- # end
- # Activates the user in the database.
- def activate
- @activated = true
- self.attributes = {:activated_at => Time.now.utc, :activation_code => nil}
- save(false)
- end
- def activated?
- !! activation_code.nil?
- end
- # Returns true if the user has just been activated.
- def recently_activated?
- @activated
- end
- # Authenticates a user by their login name and unencrypted password. Returns the user or nil.
- def self.authenticate(login, password)
- u = find :first, :conditions => ['login = ? and activated_at IS NOT NULL', 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
- remember_me_for 2.weeks
- end
- def remember_me_for(time)
- remember_me_until time.from_now.utc
- end
- def remember_me_until(time)
- self.remember_token_expires_at = time
- 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
- # before filter
- 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
- def reformat_postal_code
- return if postal_code.blank?
- ## both canadian and american codes are at least 5 characters
- return if postal_code.length < 5
- # american
- if /\d{5,}/.match(postal_code)
- self.postal_code = /(\d{5,})/.match(postal_code.to_s)[0]
- end
- # canadian
- if /^([ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ])\ {0,1}(\d[ABCEGHJKLMNPRSTVWXYZ]\d)$/.match(postal_code)
- self.postal_code = postal_code.sub(/^([ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ])\ {0,1}(\d[ABCEGHJKLMNPRSTVWXYZ]\d)$/, '\1 \2')
- end
- end
- def make_activation_code
- self.activation_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
- end
- end
- ##
- require File.dirname(__FILE__) + '/../test_helper'
- class UserTest < Test::Unit::TestCase
- # Be sure to include AuthenticatedTestHelper in test/test_helper.rb instead.
- # Then, you can remove it from this and the functional test.
- include AuthenticatedTestHelper
- fixtures :users
- 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_require_email
- assert_no_difference User, :count do
- u = create_user(:email => nil)
- assert u.errors.on(:email)
- end
- end
- def test_should_require_dob
- assert_no_difference User, :count do
- u = create_user(:dob => nil)
- assert u.errors.on(:dob)
- end
- end
- ## in case we end up requiring a mobile #
- # def test_should_require_mobile_phone_area
- # assert_no_difference User, :count do
- # u = create_user(:mobile_phone_area => nil)
- # assert u.errors.on(:mobile_phone_area)
- # end
- # end
- #
- # def test_should_require_mobile_phone_prefix
- # assert_no_difference User, :count do
- # u = create_user(:mobile_phone_prefix => nil)
- # assert u.errors.on(:mobile_phone_prefix)
- # end
- # end
- #
- # def test_should_require_mobile_phone_number
- # assert_no_difference User, :count do
- # u = create_user(:mobile_phone_number => nil)
- # assert u.errors.on(:mobile_phone_number)
- # end
- # end
- #
- # def test_should_require_mobile_phone_carrier
- # assert_no_difference User, :count do
- # u = create_user(:mobile_phone_carrier => nil)
- # assert u.errors.on(:mobile_phone_carrier)
- # end
- # end
- def test_should_require_valid_email
- assert_no_difference User, :count do
- u = create_user(:email => "invalid_email@address")
- assert u.errors.on(:email)
- end
- assert_no_difference User, :count do
- u = create_user(:email => "@.")
- assert u.errors.on(:email)
- end
- ## validate dot after @ sign
- assert_no_difference User, :count do
- u = create_user(:email => "@.")
- assert u.errors.on(:email)
- end
- end
- def test_should_require_login_max_length # max is defined in model validations at 16
- assert_no_difference User, :count do
- u = create_user(:login => "abcdefghijklmnopqrstuvwxyz") # the alphabet is 26
- assert u.errors.on(:login)
- end
- end
- def test_should_require_login_min_length # min is defined in model validations at 4
- assert_no_difference User, :count do
- u = create_user(:email => "abc") # three character string
- assert u.errors.on(:email)
- end
- end
- def test_should_require_login_alphanumeric_only
- assert_no_difference User, :count do
- u = create_user(:login => "bad!!usr^$%$")
- assert u.errors.on(:login)
- end
- end
- def test_should_require_email_alphanumeric_only
- # assert_no_difference User, :count do
- # u = create_user(:email => "bad!!user^$%$%@invalid.net") # three character string
- # assert u.errors.on(:email)
- # end
- flunk "this test needs to be fixed"
- end
- ## for uniqueness test
- def test_should_require_email_should_be_case_insensitive
- u1 = create_user(:email => "user@taken.com")
- assert_no_difference User, :count do
- u2 = create_user(:email => "UsEr@TAKEN.com")
- assert u2.errors.on(:email)
- end
- end
- def test_should_require_email_max_length
- assert_no_difference User, :count do
- u = create_user(:email => "supercallafragilisticespeyalladocioussuperbaroomma@supercallafragilisticespeyalladocioussuperbaroomma.com")
- assert u.errors.on(:email)
- end
- end
- def test_email_min_length
- assert_no_difference User, :count do
- u = create_user(:email => "j@.")
- assert u.errors.on(:email)
- end
- end
- def test_should_not_allow_reserved_screenname
- # assert_no_difference User, :count do
- # u = create_user(:login => "allah")
- # assert u.errors.on(:login)
- # end
- end
- def test_password_case_insensitive
- end
- def test_should_require_password_min_length
- assert_no_difference User, :count do
- u = create_user(:password => "123")
- assert u.errors.on(:password)
- end
- end
- def test_should_require_password_max_length
- assert_no_difference User, :count do
- u = create_user(:password => "0123456789012345678901234567890123456789")
- assert u.errors.on(:password)
- end
- end
- def test_should_require_postal_code
- assert_no_difference User, :count do
- u = create_user(:postal_code => nil)
- assert u.errors.on(:postal_code)
- end
- end
- def test_should_require_postal_code_min_length
- assert_no_difference User, :count do
- u = create_user(:postal_code => "12")
- assert u.errors.on(:postal_code)
- end
- end
- def test_should_require_postal_code_max_length
- assert_no_difference User, :count do
- u = create_user(:postal_code => "123456789123456789")
- assert u.errors.on(:postal_code)
- end
- end
- def test_should_only_save_first_five_digits_postal_code
- user = create_user(:postal_code => "90027-1600")
- assert_equal("90027", user.postal_code)
- end
- def test_should_validate_us_postal_code
- assert_difference User, :count do
- user = create_user(:postal_code => "11356")
- assert !user.new_record?, "#{user.errors.full_messages.to_sentence}"
- assert_equal("11356", user.postal_code)
- end
- end
- def test_should_validate_us_postal_code_plus_four
- assert_difference User, :count do
- user = create_user(:postal_code => "11356-6543")
- assert !user.new_record?, "#{user.errors.full_messages.to_sentence}"
- assert_equal("11356", user.postal_code)
- end
- end
- def test_should_validate_us_postal_code_plus_six
- assert_difference User, :count do
- user = create_user(:postal_code => "11356-654321")
- assert !user.new_record?, "#{user.errors.full_messages.to_sentence}"
- assert_equal("11356", user.postal_code)
- end
- end
- def test_should_require_valid_ca_postal_code
- assert_difference User, :count do
- user = create_user(:postal_code => "V6T 2G3")
- assert !user.new_record?, "#{user.errors.full_messages.to_sentence}"
- assert_equal("V6T 2G3", user.postal_code)
- end
- end
- def test_should_validate_ca_postal_code_no_spaces
- assert_difference User, :count do
- user = create_user(:postal_code => "V6T2G3")
- assert !user.new_record?, "#{user.errors.full_messages.to_sentence}"
- end
- end
- def test_should_reformat_ca_postal_code_no_spaces
- assert_difference User, :count do
- user = create_user(:postal_code => "V6T2G3")
- assert_equal("V6T 2G3", user.postal_code)
- end
- end
- def test_should_validate_numericality_of_mobile_phone_number
- assert_no_difference User, :count do
- user = create_user(:mobile_phone_number => "abcd")
- assert user.errors.on(:mobile_phone_number)
- end
- end
- def test_should_validate_numericality_of_mobile_phone_area
- assert_no_difference User, :count do
- user = create_user(:mobile_phone_area => "abc")
- assert user.errors.on(:mobile_phone_area)
- end
- end
- def test_should_validate_numericality_of_mobile_phone_prefix
- assert_no_difference User, :count do
- user = create_user(:mobile_phone_prefix => "def")
- assert user.errors.on(:mobile_phone_prefix)
- end
- end
- def test_should_validate_length_of_mobile_phone_number # limit 4
- assert_no_difference User, :count do
- user = create_user(:mobile_phone_number => "123456")
- assert user.errors.on(:mobile_phone_number)
- end
- end
- def test_should_validate_length_of_mobile_phone_area # limit 3
- assert_no_difference User, :count do
- user = create_user(:mobile_phone_area => "6543")
- assert user.errors.on(:mobile_phone_area)
- end
- end
- def test_should_validate_length_of_mobile_phone_prefix # limit 3
- assert_no_difference User, :count do
- user = create_user(:mobile_phone_prefix => "210225")
- assert user.errors.on(:mobile_phone_prefix)
- end
- end
- def test_should_require_thirteen_years_of_age
- assert_no_difference User, :count do
- u = create_user(:dob => "2007-01-26")
- assert user.errors.on(:dob)
- end
- end
- # def test_should_require_country_code
- # end
- #
- # def test_should_validate_country_code
- # end
- ## this needs to happen on all fields
- def test_should_strip_leading_and_trailing_spaces
- end
- ## does this belong in the unit test? we already have a similar test in the users_controller_test.rb
- def test_should_match_password_confirmation_case_insensitive
- assert_difference User, :count do
- create_user(:password => "whatever", :password_confirmation => "WHATEVER")
- end
- end
- def test_should_allow_7bit_ascii_password
- end
- def test_should_reset_password
- users(:jacqui).update_attributes(:password => 'new password', :password_confirmation => 'new password')
- assert_equal users(:jacqui), User.authenticate('jacqui', 'new password')
- end
- def test_should_not_rehash_password
- users(:jacqui).update_attributes(:login => 'jacqui2')
- assert_equal users(:jacqui), User.authenticate('jacqui2', 'test')
- end
- def test_should_authenticate_user
- assert_equal users(:jacqui), User.authenticate('jacqui', 'test')
- end
- def test_should_set_remember_token
- users(:jacqui).remember_me
- assert_not_nil users(:jacqui).remember_token
- assert_not_nil users(:jacqui).remember_token_expires_at
- end
- def test_should_unset_remember_token
- users(:jacqui).remember_me
- assert_not_nil users(:jacqui).remember_token
- users(:jacqui).forget_me
- assert_nil users(:jacqui).remember_token
- end
- def test_should_remember_me_for_one_week
- before = 1.week.from_now.utc
- users(:jacqui).remember_me_for 1.week
- after = 1.week.from_now.utc
- assert_not_nil users(:jacqui).remember_token
- assert_not_nil users(:jacqui).remember_token_expires_at
- assert users(:jacqui).remember_token_expires_at.between?(before, after)
- end
- def test_should_remember_me_until_one_week
- time = 1.week.from_now.utc
- users(:jacqui).remember_me_until time
- assert_not_nil users(:jacqui).remember_token
- assert_not_nil users(:jacqui).remember_token_expires_at
- assert_equal users(:jacqui).remember_token_expires_at, time
- end
- def test_should_remember_me_default_two_weeks
- before = 2.weeks.from_now.utc
- users(:jacqui).remember_me
- after = 2.weeks.from_now.utc
- assert_not_nil users(:jacqui).remember_token
- assert_not_nil users(:jacqui).remember_token_expires_at
- assert users(:jacqui).remember_token_expires_at.between?(before, after)
- end
- protected
- def create_user(options = {})
- User.create({ :login => 'whatever', :email => 'whoever@example.com', :password => 'whatever', :password_confirmation => 'whatever', :postal_code => '90027', :dob => '1977-08-12', :mobile_phone_area => '415', :mobile_phone_prefix => '341', :mobile_phone_number => '7140' }.merge(options))
- end
- end
Add Comment
Please, Sign In to add comment