Guest User

Untitled

a guest
Feb 28th, 2018
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.08 KB | None | 0 0
  1. require 'digest/sha1'
  2. class User < ActiveRecord::Base
  3. # Virtual attribute for the unencrypted password
  4. attr_accessor :password
  5.  
  6. # password and password confirmation matching is case insensitive; time to normalize
  7. before_validation :normalize_password_fields
  8. # before_validation :normalize_email -- geoff?
  9.  
  10. validates_presence_of :login, :email, :postal_code, :dob
  11. validates_presence_of :password, :if => :password_required?
  12. validates_presence_of :password_confirmation, :if => :password_required?
  13. validates_length_of :password, :within => 4..32, :if => :password_required?
  14. validates_length_of :login, :within => 4..16
  15. validates_length_of :email, :within => 5..100
  16. validates_length_of :postal_code, :within => 5..16
  17.  
  18. validates_confirmation_of :password, :if => :password_required?
  19.  
  20. validates_format_of :postal_code,
  21. :with => /(\d{5,})|([ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ])\ {0,1}(\d[ABCEGHJKLMNPRSTVWXYZ]\d)/,
  22. :on => :save,
  23. :message => "has an invalid format"
  24. validates_format_of :login,
  25. :with => /^[A-Za-z0-9]+$/,
  26. :on => :save,
  27. :message => "can only contain alphanumeric characters"
  28. validates_length_of :mobile_phone_area, :is => 3
  29. validates_length_of :mobile_phone_prefix, :is => 3
  30. validates_length_of :mobile_phone_number, :is => 4
  31. validates_numericality_of :mobile_phone_area, :mobile_phone_prefix, :mobile_phone_number
  32.  
  33. validates_format_of :email,
  34. :with => /^[A-Z0-9._-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i,
  35. :on => :save,
  36. :message=>"has an invalid format"
  37.  
  38. validates_uniqueness_of :login, :email, :case_sensitive => false
  39.  
  40. validates_date :dob, :before => Proc.new {13.years.ago}
  41. before_save :encrypt_password
  42. before_save :reformat_postal_code
  43. before_create :make_activation_code
  44.  
  45. def validate
  46. if ReservedWord.find_by_word(login)
  47. logger.info "found reserved word match"
  48. errors.add("login", "is a bad word")
  49. end
  50. end
  51.  
  52. def normalize_password_fields
  53. return if password.blank?
  54. return if password.nil?
  55. return if password_confirmation.blank?
  56. return if password_confirmation.nil?
  57. self.password = password.downcase
  58. self.password_confirmation = password_confirmation.downcase
  59. end
  60.  
  61. # def normalize_email
  62. # self.email.downcase
  63. # end
  64.  
  65. # Activates the user in the database.
  66. def activate
  67. @activated = true
  68. self.attributes = {:activated_at => Time.now.utc, :activation_code => nil}
  69. save(false)
  70. end
  71.  
  72. def activated?
  73. !! activation_code.nil?
  74. end
  75.  
  76. # Returns true if the user has just been activated.
  77. def recently_activated?
  78. @activated
  79. end
  80.  
  81. # Authenticates a user by their login name and unencrypted password. Returns the user or nil.
  82. def self.authenticate(login, password)
  83. u = find :first, :conditions => ['login = ? and activated_at IS NOT NULL', login] # need to get the salt
  84. u && u.authenticated?(password) ? u : nil
  85. end
  86.  
  87. # Encrypts some data with the salt.
  88. def self.encrypt(password, salt)
  89. Digest::SHA1.hexdigest("--#{salt}--#{password}--")
  90. end
  91.  
  92. # Encrypts the password with the user salt
  93. def encrypt(password)
  94. self.class.encrypt(password, salt)
  95. end
  96.  
  97. def authenticated?(password)
  98. crypted_password == encrypt(password)
  99. end
  100.  
  101. def remember_token?
  102. remember_token_expires_at && Time.now.utc < remember_token_expires_at
  103. end
  104.  
  105. # These create and unset the fields required for remembering users between browser closes
  106. def remember_me
  107. remember_me_for 2.weeks
  108. end
  109.  
  110. def remember_me_for(time)
  111. remember_me_until time.from_now.utc
  112. end
  113.  
  114. def remember_me_until(time)
  115. self.remember_token_expires_at = time
  116. self.remember_token = encrypt("#{email}--#{remember_token_expires_at}")
  117. save(false)
  118. end
  119.  
  120. def forget_me
  121. self.remember_token_expires_at = nil
  122. self.remember_token = nil
  123. save(false)
  124. end
  125.  
  126. protected
  127. # before filter
  128. def encrypt_password
  129. return if password.blank?
  130. self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
  131. self.crypted_password = encrypt(password)
  132. end
  133.  
  134. def password_required?
  135. crypted_password.blank? || !password.blank?
  136. end
  137.  
  138. def reformat_postal_code
  139. return if postal_code.blank?
  140. ## both canadian and american codes are at least 5 characters
  141. return if postal_code.length < 5
  142.  
  143. # american
  144. if /\d{5,}/.match(postal_code)
  145. self.postal_code = /(\d{5,})/.match(postal_code.to_s)[0]
  146. end
  147.  
  148. # canadian
  149. if /^([ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ])\ {0,1}(\d[ABCEGHJKLMNPRSTVWXYZ]\d)$/.match(postal_code)
  150. self.postal_code = postal_code.sub(/^([ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ])\ {0,1}(\d[ABCEGHJKLMNPRSTVWXYZ]\d)$/, '\1 \2')
  151. end
  152. end
  153.  
  154. def make_activation_code
  155. self.activation_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
  156. end
  157. end
  158.  
  159.  
  160. ##
  161.  
  162. require File.dirname(__FILE__) + '/../test_helper'
  163.  
  164. class UserTest < Test::Unit::TestCase
  165. # Be sure to include AuthenticatedTestHelper in test/test_helper.rb instead.
  166. # Then, you can remove it from this and the functional test.
  167. include AuthenticatedTestHelper
  168. fixtures :users
  169.  
  170. def test_should_create_user
  171. assert_difference User, :count do
  172. user = create_user
  173. assert !user.new_record?, "#{user.errors.full_messages.to_sentence}"
  174. end
  175. end
  176.  
  177. def test_should_require_login
  178. assert_no_difference User, :count do
  179. u = create_user(:login => nil)
  180. assert u.errors.on(:login)
  181. end
  182. end
  183.  
  184. def test_should_require_password
  185. assert_no_difference User, :count do
  186. u = create_user(:password => nil)
  187. assert u.errors.on(:password)
  188. end
  189. end
  190.  
  191. def test_should_require_password_confirmation
  192. assert_no_difference User, :count do
  193. u = create_user(:password_confirmation => nil)
  194. assert u.errors.on(:password_confirmation)
  195. end
  196. end
  197.  
  198. def test_should_require_email
  199. assert_no_difference User, :count do
  200. u = create_user(:email => nil)
  201. assert u.errors.on(:email)
  202. end
  203. end
  204.  
  205. def test_should_require_dob
  206. assert_no_difference User, :count do
  207. u = create_user(:dob => nil)
  208. assert u.errors.on(:dob)
  209. end
  210. end
  211.  
  212. ## in case we end up requiring a mobile #
  213. # def test_should_require_mobile_phone_area
  214. # assert_no_difference User, :count do
  215. # u = create_user(:mobile_phone_area => nil)
  216. # assert u.errors.on(:mobile_phone_area)
  217. # end
  218. # end
  219. #
  220. # def test_should_require_mobile_phone_prefix
  221. # assert_no_difference User, :count do
  222. # u = create_user(:mobile_phone_prefix => nil)
  223. # assert u.errors.on(:mobile_phone_prefix)
  224. # end
  225. # end
  226. #
  227. # def test_should_require_mobile_phone_number
  228. # assert_no_difference User, :count do
  229. # u = create_user(:mobile_phone_number => nil)
  230. # assert u.errors.on(:mobile_phone_number)
  231. # end
  232. # end
  233. #
  234. # def test_should_require_mobile_phone_carrier
  235. # assert_no_difference User, :count do
  236. # u = create_user(:mobile_phone_carrier => nil)
  237. # assert u.errors.on(:mobile_phone_carrier)
  238. # end
  239. # end
  240.  
  241. def test_should_require_valid_email
  242. assert_no_difference User, :count do
  243. u = create_user(:email => "invalid_email@address")
  244. assert u.errors.on(:email)
  245. end
  246. assert_no_difference User, :count do
  247. u = create_user(:email => "@.")
  248. assert u.errors.on(:email)
  249. end
  250.  
  251. ## validate dot after @ sign
  252. assert_no_difference User, :count do
  253. u = create_user(:email => "@.")
  254. assert u.errors.on(:email)
  255. end
  256. end
  257.  
  258. def test_should_require_login_max_length # max is defined in model validations at 16
  259. assert_no_difference User, :count do
  260. u = create_user(:login => "abcdefghijklmnopqrstuvwxyz") # the alphabet is 26
  261. assert u.errors.on(:login)
  262. end
  263. end
  264.  
  265. def test_should_require_login_min_length # min is defined in model validations at 4
  266. assert_no_difference User, :count do
  267. u = create_user(:email => "abc") # three character string
  268. assert u.errors.on(:email)
  269. end
  270. end
  271.  
  272. def test_should_require_login_alphanumeric_only
  273. assert_no_difference User, :count do
  274. u = create_user(:login => "bad!!usr^$%$")
  275. assert u.errors.on(:login)
  276. end
  277. end
  278.  
  279. def test_should_require_email_alphanumeric_only
  280. # assert_no_difference User, :count do
  281. # u = create_user(:email => "bad!!user^$%$%@invalid.net") # three character string
  282. # assert u.errors.on(:email)
  283. # end
  284. flunk "this test needs to be fixed"
  285. end
  286.  
  287. ## for uniqueness test
  288. def test_should_require_email_should_be_case_insensitive
  289. u1 = create_user(:email => "user@taken.com")
  290.  
  291. assert_no_difference User, :count do
  292. u2 = create_user(:email => "UsEr@TAKEN.com")
  293. assert u2.errors.on(:email)
  294. end
  295. end
  296.  
  297. def test_should_require_email_max_length
  298. assert_no_difference User, :count do
  299. u = create_user(:email => "supercallafragilisticespeyalladocioussuperbaroomma@supercallafragilisticespeyalladocioussuperbaroomma.com")
  300. assert u.errors.on(:email)
  301. end
  302. end
  303.  
  304. def test_email_min_length
  305. assert_no_difference User, :count do
  306. u = create_user(:email => "j@.")
  307. assert u.errors.on(:email)
  308. end
  309. end
  310.  
  311. def test_should_not_allow_reserved_screenname
  312. # assert_no_difference User, :count do
  313. # u = create_user(:login => "allah")
  314. # assert u.errors.on(:login)
  315. # end
  316. end
  317.  
  318. def test_password_case_insensitive
  319. end
  320.  
  321. def test_should_require_password_min_length
  322. assert_no_difference User, :count do
  323. u = create_user(:password => "123")
  324. assert u.errors.on(:password)
  325. end
  326. end
  327.  
  328. def test_should_require_password_max_length
  329. assert_no_difference User, :count do
  330. u = create_user(:password => "0123456789012345678901234567890123456789")
  331. assert u.errors.on(:password)
  332. end
  333. end
  334.  
  335. def test_should_require_postal_code
  336. assert_no_difference User, :count do
  337. u = create_user(:postal_code => nil)
  338. assert u.errors.on(:postal_code)
  339. end
  340. end
  341.  
  342. def test_should_require_postal_code_min_length
  343. assert_no_difference User, :count do
  344. u = create_user(:postal_code => "12")
  345. assert u.errors.on(:postal_code)
  346. end
  347. end
  348.  
  349. def test_should_require_postal_code_max_length
  350. assert_no_difference User, :count do
  351. u = create_user(:postal_code => "123456789123456789")
  352. assert u.errors.on(:postal_code)
  353. end
  354. end
  355.  
  356. def test_should_only_save_first_five_digits_postal_code
  357. user = create_user(:postal_code => "90027-1600")
  358. assert_equal("90027", user.postal_code)
  359. end
  360.  
  361. def test_should_validate_us_postal_code
  362. assert_difference User, :count do
  363. user = create_user(:postal_code => "11356")
  364. assert !user.new_record?, "#{user.errors.full_messages.to_sentence}"
  365. assert_equal("11356", user.postal_code)
  366. end
  367. end
  368.  
  369. def test_should_validate_us_postal_code_plus_four
  370. assert_difference User, :count do
  371. user = create_user(:postal_code => "11356-6543")
  372. assert !user.new_record?, "#{user.errors.full_messages.to_sentence}"
  373. assert_equal("11356", user.postal_code)
  374. end
  375. end
  376.  
  377. def test_should_validate_us_postal_code_plus_six
  378. assert_difference User, :count do
  379. user = create_user(:postal_code => "11356-654321")
  380. assert !user.new_record?, "#{user.errors.full_messages.to_sentence}"
  381. assert_equal("11356", user.postal_code)
  382. end
  383. end
  384.  
  385. def test_should_require_valid_ca_postal_code
  386. assert_difference User, :count do
  387. user = create_user(:postal_code => "V6T 2G3")
  388. assert !user.new_record?, "#{user.errors.full_messages.to_sentence}"
  389. assert_equal("V6T 2G3", user.postal_code)
  390. end
  391. end
  392.  
  393. def test_should_validate_ca_postal_code_no_spaces
  394. assert_difference User, :count do
  395. user = create_user(:postal_code => "V6T2G3")
  396. assert !user.new_record?, "#{user.errors.full_messages.to_sentence}"
  397. end
  398. end
  399.  
  400. def test_should_reformat_ca_postal_code_no_spaces
  401. assert_difference User, :count do
  402. user = create_user(:postal_code => "V6T2G3")
  403. assert_equal("V6T 2G3", user.postal_code)
  404. end
  405. end
  406.  
  407. def test_should_validate_numericality_of_mobile_phone_number
  408. assert_no_difference User, :count do
  409. user = create_user(:mobile_phone_number => "abcd")
  410. assert user.errors.on(:mobile_phone_number)
  411. end
  412. end
  413.  
  414. def test_should_validate_numericality_of_mobile_phone_area
  415. assert_no_difference User, :count do
  416. user = create_user(:mobile_phone_area => "abc")
  417. assert user.errors.on(:mobile_phone_area)
  418. end
  419. end
  420.  
  421. def test_should_validate_numericality_of_mobile_phone_prefix
  422. assert_no_difference User, :count do
  423. user = create_user(:mobile_phone_prefix => "def")
  424. assert user.errors.on(:mobile_phone_prefix)
  425. end
  426. end
  427.  
  428. def test_should_validate_length_of_mobile_phone_number # limit 4
  429. assert_no_difference User, :count do
  430. user = create_user(:mobile_phone_number => "123456")
  431. assert user.errors.on(:mobile_phone_number)
  432. end
  433. end
  434.  
  435. def test_should_validate_length_of_mobile_phone_area # limit 3
  436. assert_no_difference User, :count do
  437. user = create_user(:mobile_phone_area => "6543")
  438. assert user.errors.on(:mobile_phone_area)
  439. end
  440. end
  441.  
  442. def test_should_validate_length_of_mobile_phone_prefix # limit 3
  443. assert_no_difference User, :count do
  444. user = create_user(:mobile_phone_prefix => "210225")
  445. assert user.errors.on(:mobile_phone_prefix)
  446. end
  447. end
  448. def test_should_require_thirteen_years_of_age
  449. assert_no_difference User, :count do
  450. u = create_user(:dob => "2007-01-26")
  451. assert user.errors.on(:dob)
  452. end
  453. end
  454.  
  455.  
  456. # def test_should_require_country_code
  457. # end
  458. #
  459. # def test_should_validate_country_code
  460. # end
  461.  
  462. ## this needs to happen on all fields
  463. def test_should_strip_leading_and_trailing_spaces
  464. end
  465.  
  466. ## does this belong in the unit test? we already have a similar test in the users_controller_test.rb
  467. def test_should_match_password_confirmation_case_insensitive
  468. assert_difference User, :count do
  469. create_user(:password => "whatever", :password_confirmation => "WHATEVER")
  470. end
  471. end
  472.  
  473. def test_should_allow_7bit_ascii_password
  474. end
  475.  
  476. def test_should_reset_password
  477. users(:jacqui).update_attributes(:password => 'new password', :password_confirmation => 'new password')
  478. assert_equal users(:jacqui), User.authenticate('jacqui', 'new password')
  479. end
  480.  
  481. def test_should_not_rehash_password
  482. users(:jacqui).update_attributes(:login => 'jacqui2')
  483. assert_equal users(:jacqui), User.authenticate('jacqui2', 'test')
  484. end
  485.  
  486. def test_should_authenticate_user
  487. assert_equal users(:jacqui), User.authenticate('jacqui', 'test')
  488. end
  489.  
  490. def test_should_set_remember_token
  491. users(:jacqui).remember_me
  492. assert_not_nil users(:jacqui).remember_token
  493. assert_not_nil users(:jacqui).remember_token_expires_at
  494. end
  495.  
  496. def test_should_unset_remember_token
  497. users(:jacqui).remember_me
  498. assert_not_nil users(:jacqui).remember_token
  499. users(:jacqui).forget_me
  500. assert_nil users(:jacqui).remember_token
  501. end
  502.  
  503. def test_should_remember_me_for_one_week
  504. before = 1.week.from_now.utc
  505. users(:jacqui).remember_me_for 1.week
  506. after = 1.week.from_now.utc
  507. assert_not_nil users(:jacqui).remember_token
  508. assert_not_nil users(:jacqui).remember_token_expires_at
  509. assert users(:jacqui).remember_token_expires_at.between?(before, after)
  510. end
  511.  
  512. def test_should_remember_me_until_one_week
  513. time = 1.week.from_now.utc
  514. users(:jacqui).remember_me_until time
  515. assert_not_nil users(:jacqui).remember_token
  516. assert_not_nil users(:jacqui).remember_token_expires_at
  517. assert_equal users(:jacqui).remember_token_expires_at, time
  518. end
  519.  
  520. def test_should_remember_me_default_two_weeks
  521. before = 2.weeks.from_now.utc
  522. users(:jacqui).remember_me
  523. after = 2.weeks.from_now.utc
  524. assert_not_nil users(:jacqui).remember_token
  525. assert_not_nil users(:jacqui).remember_token_expires_at
  526. assert users(:jacqui).remember_token_expires_at.between?(before, after)
  527. end
  528.  
  529. protected
  530. def create_user(options = {})
  531. 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))
  532. end
  533. end
Add Comment
Please, Sign In to add comment