##// END OF EJS Templates
Makes email adress uniqueness case-insensitive (#2473)....
Jean-Philippe Lang -
r2251:212bf1e2bbe6
parent child
Show More
@@ -1,294 +1,294
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require "digest/sha1"
18 require "digest/sha1"
19
19
20 class User < ActiveRecord::Base
20 class User < ActiveRecord::Base
21
21
22 # Account statuses
22 # Account statuses
23 STATUS_ANONYMOUS = 0
23 STATUS_ANONYMOUS = 0
24 STATUS_ACTIVE = 1
24 STATUS_ACTIVE = 1
25 STATUS_REGISTERED = 2
25 STATUS_REGISTERED = 2
26 STATUS_LOCKED = 3
26 STATUS_LOCKED = 3
27
27
28 USER_FORMATS = {
28 USER_FORMATS = {
29 :firstname_lastname => '#{firstname} #{lastname}',
29 :firstname_lastname => '#{firstname} #{lastname}',
30 :firstname => '#{firstname}',
30 :firstname => '#{firstname}',
31 :lastname_firstname => '#{lastname} #{firstname}',
31 :lastname_firstname => '#{lastname} #{firstname}',
32 :lastname_coma_firstname => '#{lastname}, #{firstname}',
32 :lastname_coma_firstname => '#{lastname}, #{firstname}',
33 :username => '#{login}'
33 :username => '#{login}'
34 }
34 }
35
35
36 has_many :memberships, :class_name => 'Member', :include => [ :project, :role ], :conditions => "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}", :order => "#{Project.table_name}.name"
36 has_many :memberships, :class_name => 'Member', :include => [ :project, :role ], :conditions => "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}", :order => "#{Project.table_name}.name"
37 has_many :members, :dependent => :delete_all
37 has_many :members, :dependent => :delete_all
38 has_many :projects, :through => :memberships
38 has_many :projects, :through => :memberships
39 has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify
39 has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify
40 has_many :changesets, :dependent => :nullify
40 has_many :changesets, :dependent => :nullify
41 has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
41 has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
42 has_one :rss_token, :dependent => :destroy, :class_name => 'Token', :conditions => "action='feeds'"
42 has_one :rss_token, :dependent => :destroy, :class_name => 'Token', :conditions => "action='feeds'"
43 belongs_to :auth_source
43 belongs_to :auth_source
44
44
45 # Active non-anonymous users scope
45 # Active non-anonymous users scope
46 named_scope :active, :conditions => "#{User.table_name}.status = #{STATUS_ACTIVE}"
46 named_scope :active, :conditions => "#{User.table_name}.status = #{STATUS_ACTIVE}"
47
47
48 acts_as_customizable
48 acts_as_customizable
49
49
50 attr_accessor :password, :password_confirmation
50 attr_accessor :password, :password_confirmation
51 attr_accessor :last_before_login_on
51 attr_accessor :last_before_login_on
52 # Prevents unauthorized assignments
52 # Prevents unauthorized assignments
53 attr_protected :login, :admin, :password, :password_confirmation, :hashed_password
53 attr_protected :login, :admin, :password, :password_confirmation, :hashed_password
54
54
55 validates_presence_of :login, :firstname, :lastname, :mail, :if => Proc.new { |user| !user.is_a?(AnonymousUser) }
55 validates_presence_of :login, :firstname, :lastname, :mail, :if => Proc.new { |user| !user.is_a?(AnonymousUser) }
56 validates_uniqueness_of :login, :if => Proc.new { |user| !user.login.blank? }
56 validates_uniqueness_of :login, :if => Proc.new { |user| !user.login.blank? }
57 validates_uniqueness_of :mail, :if => Proc.new { |user| !user.mail.blank? }
57 validates_uniqueness_of :mail, :if => Proc.new { |user| !user.mail.blank? }, :case_sensitive => false
58 # Login must contain lettres, numbers, underscores only
58 # Login must contain lettres, numbers, underscores only
59 validates_format_of :login, :with => /^[a-z0-9_\-@\.]*$/i
59 validates_format_of :login, :with => /^[a-z0-9_\-@\.]*$/i
60 validates_length_of :login, :maximum => 30
60 validates_length_of :login, :maximum => 30
61 validates_format_of :firstname, :lastname, :with => /^[\w\s\'\-\.]*$/i
61 validates_format_of :firstname, :lastname, :with => /^[\w\s\'\-\.]*$/i
62 validates_length_of :firstname, :lastname, :maximum => 30
62 validates_length_of :firstname, :lastname, :maximum => 30
63 validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :allow_nil => true
63 validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :allow_nil => true
64 validates_length_of :mail, :maximum => 60, :allow_nil => true
64 validates_length_of :mail, :maximum => 60, :allow_nil => true
65 validates_length_of :password, :minimum => 4, :allow_nil => true
65 validates_length_of :password, :minimum => 4, :allow_nil => true
66 validates_confirmation_of :password, :allow_nil => true
66 validates_confirmation_of :password, :allow_nil => true
67
67
68 def before_create
68 def before_create
69 self.mail_notification = false
69 self.mail_notification = false
70 true
70 true
71 end
71 end
72
72
73 def before_save
73 def before_save
74 # update hashed_password if password was set
74 # update hashed_password if password was set
75 self.hashed_password = User.hash_password(self.password) if self.password
75 self.hashed_password = User.hash_password(self.password) if self.password
76 end
76 end
77
77
78 def reload(*args)
78 def reload(*args)
79 @name = nil
79 @name = nil
80 super
80 super
81 end
81 end
82
82
83 # Returns the user that matches provided login and password, or nil
83 # Returns the user that matches provided login and password, or nil
84 def self.try_to_login(login, password)
84 def self.try_to_login(login, password)
85 # Make sure no one can sign in with an empty password
85 # Make sure no one can sign in with an empty password
86 return nil if password.to_s.empty?
86 return nil if password.to_s.empty?
87 user = find(:first, :conditions => ["login=?", login])
87 user = find(:first, :conditions => ["login=?", login])
88 if user
88 if user
89 # user is already in local database
89 # user is already in local database
90 return nil if !user.active?
90 return nil if !user.active?
91 if user.auth_source
91 if user.auth_source
92 # user has an external authentication method
92 # user has an external authentication method
93 return nil unless user.auth_source.authenticate(login, password)
93 return nil unless user.auth_source.authenticate(login, password)
94 else
94 else
95 # authentication with local password
95 # authentication with local password
96 return nil unless User.hash_password(password) == user.hashed_password
96 return nil unless User.hash_password(password) == user.hashed_password
97 end
97 end
98 else
98 else
99 # user is not yet registered, try to authenticate with available sources
99 # user is not yet registered, try to authenticate with available sources
100 attrs = AuthSource.authenticate(login, password)
100 attrs = AuthSource.authenticate(login, password)
101 if attrs
101 if attrs
102 user = new(*attrs)
102 user = new(*attrs)
103 user.login = login
103 user.login = login
104 user.language = Setting.default_language
104 user.language = Setting.default_language
105 if user.save
105 if user.save
106 user.reload
106 user.reload
107 logger.info("User '#{user.login}' created from the LDAP") if logger
107 logger.info("User '#{user.login}' created from the LDAP") if logger
108 end
108 end
109 end
109 end
110 end
110 end
111 user.update_attribute(:last_login_on, Time.now) if user && !user.new_record?
111 user.update_attribute(:last_login_on, Time.now) if user && !user.new_record?
112 user
112 user
113 rescue => text
113 rescue => text
114 raise text
114 raise text
115 end
115 end
116
116
117 # Return user's full name for display
117 # Return user's full name for display
118 def name(formatter = nil)
118 def name(formatter = nil)
119 if formatter
119 if formatter
120 eval('"' + (USER_FORMATS[formatter] || USER_FORMATS[:firstname_lastname]) + '"')
120 eval('"' + (USER_FORMATS[formatter] || USER_FORMATS[:firstname_lastname]) + '"')
121 else
121 else
122 @name ||= eval('"' + (USER_FORMATS[Setting.user_format] || USER_FORMATS[:firstname_lastname]) + '"')
122 @name ||= eval('"' + (USER_FORMATS[Setting.user_format] || USER_FORMATS[:firstname_lastname]) + '"')
123 end
123 end
124 end
124 end
125
125
126 def active?
126 def active?
127 self.status == STATUS_ACTIVE
127 self.status == STATUS_ACTIVE
128 end
128 end
129
129
130 def registered?
130 def registered?
131 self.status == STATUS_REGISTERED
131 self.status == STATUS_REGISTERED
132 end
132 end
133
133
134 def locked?
134 def locked?
135 self.status == STATUS_LOCKED
135 self.status == STATUS_LOCKED
136 end
136 end
137
137
138 def check_password?(clear_password)
138 def check_password?(clear_password)
139 User.hash_password(clear_password) == self.hashed_password
139 User.hash_password(clear_password) == self.hashed_password
140 end
140 end
141
141
142 def pref
142 def pref
143 self.preference ||= UserPreference.new(:user => self)
143 self.preference ||= UserPreference.new(:user => self)
144 end
144 end
145
145
146 def time_zone
146 def time_zone
147 @time_zone ||= (self.pref.time_zone.blank? ? nil : ActiveSupport::TimeZone[self.pref.time_zone])
147 @time_zone ||= (self.pref.time_zone.blank? ? nil : ActiveSupport::TimeZone[self.pref.time_zone])
148 end
148 end
149
149
150 def wants_comments_in_reverse_order?
150 def wants_comments_in_reverse_order?
151 self.pref[:comments_sorting] == 'desc'
151 self.pref[:comments_sorting] == 'desc'
152 end
152 end
153
153
154 # Return user's RSS key (a 40 chars long string), used to access feeds
154 # Return user's RSS key (a 40 chars long string), used to access feeds
155 def rss_key
155 def rss_key
156 token = self.rss_token || Token.create(:user => self, :action => 'feeds')
156 token = self.rss_token || Token.create(:user => self, :action => 'feeds')
157 token.value
157 token.value
158 end
158 end
159
159
160 # Return an array of project ids for which the user has explicitly turned mail notifications on
160 # Return an array of project ids for which the user has explicitly turned mail notifications on
161 def notified_projects_ids
161 def notified_projects_ids
162 @notified_projects_ids ||= memberships.select {|m| m.mail_notification?}.collect(&:project_id)
162 @notified_projects_ids ||= memberships.select {|m| m.mail_notification?}.collect(&:project_id)
163 end
163 end
164
164
165 def notified_project_ids=(ids)
165 def notified_project_ids=(ids)
166 Member.update_all("mail_notification = #{connection.quoted_false}", ['user_id = ?', id])
166 Member.update_all("mail_notification = #{connection.quoted_false}", ['user_id = ?', id])
167 Member.update_all("mail_notification = #{connection.quoted_true}", ['user_id = ? AND project_id IN (?)', id, ids]) if ids && !ids.empty?
167 Member.update_all("mail_notification = #{connection.quoted_true}", ['user_id = ? AND project_id IN (?)', id, ids]) if ids && !ids.empty?
168 @notified_projects_ids = nil
168 @notified_projects_ids = nil
169 notified_projects_ids
169 notified_projects_ids
170 end
170 end
171
171
172 def self.find_by_rss_key(key)
172 def self.find_by_rss_key(key)
173 token = Token.find_by_value(key)
173 token = Token.find_by_value(key)
174 token && token.user.active? ? token.user : nil
174 token && token.user.active? ? token.user : nil
175 end
175 end
176
176
177 def self.find_by_autologin_key(key)
177 def self.find_by_autologin_key(key)
178 token = Token.find_by_action_and_value('autologin', key)
178 token = Token.find_by_action_and_value('autologin', key)
179 token && (token.created_on > Setting.autologin.to_i.day.ago) && token.user.active? ? token.user : nil
179 token && (token.created_on > Setting.autologin.to_i.day.ago) && token.user.active? ? token.user : nil
180 end
180 end
181
181
182 # Makes find_by_mail case-insensitive
182 # Makes find_by_mail case-insensitive
183 def self.find_by_mail(mail)
183 def self.find_by_mail(mail)
184 find(:first, :conditions => ["LOWER(mail) = ?", mail.to_s.downcase])
184 find(:first, :conditions => ["LOWER(mail) = ?", mail.to_s.downcase])
185 end
185 end
186
186
187 # Sort users by their display names
187 # Sort users by their display names
188 def <=>(user)
188 def <=>(user)
189 self.to_s.downcase <=> user.to_s.downcase
189 self.to_s.downcase <=> user.to_s.downcase
190 end
190 end
191
191
192 def to_s
192 def to_s
193 name
193 name
194 end
194 end
195
195
196 def logged?
196 def logged?
197 true
197 true
198 end
198 end
199
199
200 def anonymous?
200 def anonymous?
201 !logged?
201 !logged?
202 end
202 end
203
203
204 # Return user's role for project
204 # Return user's role for project
205 def role_for_project(project)
205 def role_for_project(project)
206 # No role on archived projects
206 # No role on archived projects
207 return nil unless project && project.active?
207 return nil unless project && project.active?
208 if logged?
208 if logged?
209 # Find project membership
209 # Find project membership
210 membership = memberships.detect {|m| m.project_id == project.id}
210 membership = memberships.detect {|m| m.project_id == project.id}
211 if membership
211 if membership
212 membership.role
212 membership.role
213 else
213 else
214 @role_non_member ||= Role.non_member
214 @role_non_member ||= Role.non_member
215 end
215 end
216 else
216 else
217 @role_anonymous ||= Role.anonymous
217 @role_anonymous ||= Role.anonymous
218 end
218 end
219 end
219 end
220
220
221 # Return true if the user is a member of project
221 # Return true if the user is a member of project
222 def member_of?(project)
222 def member_of?(project)
223 role_for_project(project).member?
223 role_for_project(project).member?
224 end
224 end
225
225
226 # Return true if the user is allowed to do the specified action on project
226 # Return true if the user is allowed to do the specified action on project
227 # action can be:
227 # action can be:
228 # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
228 # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
229 # * a permission Symbol (eg. :edit_project)
229 # * a permission Symbol (eg. :edit_project)
230 def allowed_to?(action, project, options={})
230 def allowed_to?(action, project, options={})
231 if project
231 if project
232 # No action allowed on archived projects
232 # No action allowed on archived projects
233 return false unless project.active?
233 return false unless project.active?
234 # No action allowed on disabled modules
234 # No action allowed on disabled modules
235 return false unless project.allows_to?(action)
235 return false unless project.allows_to?(action)
236 # Admin users are authorized for anything else
236 # Admin users are authorized for anything else
237 return true if admin?
237 return true if admin?
238
238
239 role = role_for_project(project)
239 role = role_for_project(project)
240 return false unless role
240 return false unless role
241 role.allowed_to?(action) && (project.is_public? || role.member?)
241 role.allowed_to?(action) && (project.is_public? || role.member?)
242
242
243 elsif options[:global]
243 elsif options[:global]
244 # authorize if user has at least one role that has this permission
244 # authorize if user has at least one role that has this permission
245 roles = memberships.collect {|m| m.role}.uniq
245 roles = memberships.collect {|m| m.role}.uniq
246 roles.detect {|r| r.allowed_to?(action)} || (self.logged? ? Role.non_member.allowed_to?(action) : Role.anonymous.allowed_to?(action))
246 roles.detect {|r| r.allowed_to?(action)} || (self.logged? ? Role.non_member.allowed_to?(action) : Role.anonymous.allowed_to?(action))
247 else
247 else
248 false
248 false
249 end
249 end
250 end
250 end
251
251
252 def self.current=(user)
252 def self.current=(user)
253 @current_user = user
253 @current_user = user
254 end
254 end
255
255
256 def self.current
256 def self.current
257 @current_user ||= User.anonymous
257 @current_user ||= User.anonymous
258 end
258 end
259
259
260 def self.anonymous
260 def self.anonymous
261 anonymous_user = AnonymousUser.find(:first)
261 anonymous_user = AnonymousUser.find(:first)
262 if anonymous_user.nil?
262 if anonymous_user.nil?
263 anonymous_user = AnonymousUser.create(:lastname => 'Anonymous', :firstname => '', :mail => '', :login => '', :status => 0)
263 anonymous_user = AnonymousUser.create(:lastname => 'Anonymous', :firstname => '', :mail => '', :login => '', :status => 0)
264 raise 'Unable to create the anonymous user.' if anonymous_user.new_record?
264 raise 'Unable to create the anonymous user.' if anonymous_user.new_record?
265 end
265 end
266 anonymous_user
266 anonymous_user
267 end
267 end
268
268
269 private
269 private
270 # Return password digest
270 # Return password digest
271 def self.hash_password(clear_password)
271 def self.hash_password(clear_password)
272 Digest::SHA1.hexdigest(clear_password || "")
272 Digest::SHA1.hexdigest(clear_password || "")
273 end
273 end
274 end
274 end
275
275
276 class AnonymousUser < User
276 class AnonymousUser < User
277
277
278 def validate_on_create
278 def validate_on_create
279 # There should be only one AnonymousUser in the database
279 # There should be only one AnonymousUser in the database
280 errors.add_to_base 'An anonymous user already exists.' if AnonymousUser.find(:first)
280 errors.add_to_base 'An anonymous user already exists.' if AnonymousUser.find(:first)
281 end
281 end
282
282
283 def available_custom_fields
283 def available_custom_fields
284 []
284 []
285 end
285 end
286
286
287 # Overrides a few properties
287 # Overrides a few properties
288 def logged?; false end
288 def logged?; false end
289 def admin; false end
289 def admin; false end
290 def name; 'Anonymous' end
290 def name; 'Anonymous' end
291 def mail; nil end
291 def mail; nil end
292 def time_zone; nil end
292 def time_zone; nil end
293 def rss_key; nil end
293 def rss_key; nil end
294 end
294 end
@@ -1,167 +1,180
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.dirname(__FILE__) + '/../test_helper'
19
19
20 class UserTest < Test::Unit::TestCase
20 class UserTest < Test::Unit::TestCase
21 fixtures :users, :members, :projects
21 fixtures :users, :members, :projects
22
22
23 def setup
23 def setup
24 @admin = User.find(1)
24 @admin = User.find(1)
25 @jsmith = User.find(2)
25 @jsmith = User.find(2)
26 @dlopper = User.find(3)
26 @dlopper = User.find(3)
27 end
27 end
28
28
29 def test_truth
29 def test_truth
30 assert_kind_of User, @jsmith
30 assert_kind_of User, @jsmith
31 end
31 end
32
32
33 def test_create
33 def test_create
34 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
34 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
35
35
36 user.login = "jsmith"
36 user.login = "jsmith"
37 user.password, user.password_confirmation = "password", "password"
37 user.password, user.password_confirmation = "password", "password"
38 # login uniqueness
38 # login uniqueness
39 assert !user.save
39 assert !user.save
40 assert_equal 1, user.errors.count
40 assert_equal 1, user.errors.count
41
41
42 user.login = "newuser"
42 user.login = "newuser"
43 user.password, user.password_confirmation = "passwd", "password"
43 user.password, user.password_confirmation = "passwd", "password"
44 # password confirmation
44 # password confirmation
45 assert !user.save
45 assert !user.save
46 assert_equal 1, user.errors.count
46 assert_equal 1, user.errors.count
47
47
48 user.password, user.password_confirmation = "password", "password"
48 user.password, user.password_confirmation = "password", "password"
49 assert user.save
49 assert user.save
50 end
51
52 def test_mail_uniqueness_should_not_be_case_sensitive
53 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
54 u.login = 'newuser1'
55 u.password, u.password_confirmation = "password", "password"
56 assert u.save
57
58 u = User.new(:firstname => "new", :lastname => "user", :mail => "newUser@Somenet.foo")
59 u.login = 'newuser2'
60 u.password, u.password_confirmation = "password", "password"
61 assert !u.save
62 assert_equal 'activerecord_error_taken', u.errors.on(:mail)
50 end
63 end
51
64
52 def test_update
65 def test_update
53 assert_equal "admin", @admin.login
66 assert_equal "admin", @admin.login
54 @admin.login = "john"
67 @admin.login = "john"
55 assert @admin.save, @admin.errors.full_messages.join("; ")
68 assert @admin.save, @admin.errors.full_messages.join("; ")
56 @admin.reload
69 @admin.reload
57 assert_equal "john", @admin.login
70 assert_equal "john", @admin.login
58 end
71 end
59
72
60 def test_destroy
73 def test_destroy
61 User.find(2).destroy
74 User.find(2).destroy
62 assert_nil User.find_by_id(2)
75 assert_nil User.find_by_id(2)
63 assert Member.find_all_by_user_id(2).empty?
76 assert Member.find_all_by_user_id(2).empty?
64 end
77 end
65
78
66 def test_validate
79 def test_validate
67 @admin.login = ""
80 @admin.login = ""
68 assert !@admin.save
81 assert !@admin.save
69 assert_equal 1, @admin.errors.count
82 assert_equal 1, @admin.errors.count
70 end
83 end
71
84
72 def test_password
85 def test_password
73 user = User.try_to_login("admin", "admin")
86 user = User.try_to_login("admin", "admin")
74 assert_kind_of User, user
87 assert_kind_of User, user
75 assert_equal "admin", user.login
88 assert_equal "admin", user.login
76 user.password = "hello"
89 user.password = "hello"
77 assert user.save
90 assert user.save
78
91
79 user = User.try_to_login("admin", "hello")
92 user = User.try_to_login("admin", "hello")
80 assert_kind_of User, user
93 assert_kind_of User, user
81 assert_equal "admin", user.login
94 assert_equal "admin", user.login
82 assert_equal User.hash_password("hello"), user.hashed_password
95 assert_equal User.hash_password("hello"), user.hashed_password
83 end
96 end
84
97
85 def test_name_format
98 def test_name_format
86 assert_equal 'Smith, John', @jsmith.name(:lastname_coma_firstname)
99 assert_equal 'Smith, John', @jsmith.name(:lastname_coma_firstname)
87 Setting.user_format = :firstname_lastname
100 Setting.user_format = :firstname_lastname
88 assert_equal 'John Smith', @jsmith.reload.name
101 assert_equal 'John Smith', @jsmith.reload.name
89 Setting.user_format = :username
102 Setting.user_format = :username
90 assert_equal 'jsmith', @jsmith.reload.name
103 assert_equal 'jsmith', @jsmith.reload.name
91 end
104 end
92
105
93 def test_lock
106 def test_lock
94 user = User.try_to_login("jsmith", "jsmith")
107 user = User.try_to_login("jsmith", "jsmith")
95 assert_equal @jsmith, user
108 assert_equal @jsmith, user
96
109
97 @jsmith.status = User::STATUS_LOCKED
110 @jsmith.status = User::STATUS_LOCKED
98 assert @jsmith.save
111 assert @jsmith.save
99
112
100 user = User.try_to_login("jsmith", "jsmith")
113 user = User.try_to_login("jsmith", "jsmith")
101 assert_equal nil, user
114 assert_equal nil, user
102 end
115 end
103
116
104 def test_create_anonymous
117 def test_create_anonymous
105 AnonymousUser.delete_all
118 AnonymousUser.delete_all
106 anon = User.anonymous
119 anon = User.anonymous
107 assert !anon.new_record?
120 assert !anon.new_record?
108 assert_kind_of AnonymousUser, anon
121 assert_kind_of AnonymousUser, anon
109 end
122 end
110
123
111 def test_rss_key
124 def test_rss_key
112 assert_nil @jsmith.rss_token
125 assert_nil @jsmith.rss_token
113 key = @jsmith.rss_key
126 key = @jsmith.rss_key
114 assert_equal 40, key.length
127 assert_equal 40, key.length
115
128
116 @jsmith.reload
129 @jsmith.reload
117 assert_equal key, @jsmith.rss_key
130 assert_equal key, @jsmith.rss_key
118 end
131 end
119
132
120 def test_role_for_project
133 def test_role_for_project
121 # user with a role
134 # user with a role
122 role = @jsmith.role_for_project(Project.find(1))
135 role = @jsmith.role_for_project(Project.find(1))
123 assert_kind_of Role, role
136 assert_kind_of Role, role
124 assert_equal "Manager", role.name
137 assert_equal "Manager", role.name
125
138
126 # user with no role
139 # user with no role
127 assert !@dlopper.role_for_project(Project.find(2)).member?
140 assert !@dlopper.role_for_project(Project.find(2)).member?
128 end
141 end
129
142
130 def test_mail_notification_all
143 def test_mail_notification_all
131 @jsmith.mail_notification = true
144 @jsmith.mail_notification = true
132 @jsmith.notified_project_ids = []
145 @jsmith.notified_project_ids = []
133 @jsmith.save
146 @jsmith.save
134 @jsmith.reload
147 @jsmith.reload
135 assert @jsmith.projects.first.recipients.include?(@jsmith.mail)
148 assert @jsmith.projects.first.recipients.include?(@jsmith.mail)
136 end
149 end
137
150
138 def test_mail_notification_selected
151 def test_mail_notification_selected
139 @jsmith.mail_notification = false
152 @jsmith.mail_notification = false
140 @jsmith.notified_project_ids = [1]
153 @jsmith.notified_project_ids = [1]
141 @jsmith.save
154 @jsmith.save
142 @jsmith.reload
155 @jsmith.reload
143 assert Project.find(1).recipients.include?(@jsmith.mail)
156 assert Project.find(1).recipients.include?(@jsmith.mail)
144 end
157 end
145
158
146 def test_mail_notification_none
159 def test_mail_notification_none
147 @jsmith.mail_notification = false
160 @jsmith.mail_notification = false
148 @jsmith.notified_project_ids = []
161 @jsmith.notified_project_ids = []
149 @jsmith.save
162 @jsmith.save
150 @jsmith.reload
163 @jsmith.reload
151 assert !@jsmith.projects.first.recipients.include?(@jsmith.mail)
164 assert !@jsmith.projects.first.recipients.include?(@jsmith.mail)
152 end
165 end
153
166
154 def test_comments_sorting_preference
167 def test_comments_sorting_preference
155 assert !@jsmith.wants_comments_in_reverse_order?
168 assert !@jsmith.wants_comments_in_reverse_order?
156 @jsmith.pref.comments_sorting = 'asc'
169 @jsmith.pref.comments_sorting = 'asc'
157 assert !@jsmith.wants_comments_in_reverse_order?
170 assert !@jsmith.wants_comments_in_reverse_order?
158 @jsmith.pref.comments_sorting = 'desc'
171 @jsmith.pref.comments_sorting = 'desc'
159 assert @jsmith.wants_comments_in_reverse_order?
172 assert @jsmith.wants_comments_in_reverse_order?
160 end
173 end
161
174
162 def test_find_by_mail_should_be_case_insensitive
175 def test_find_by_mail_should_be_case_insensitive
163 u = User.find_by_mail('JSmith@somenet.foo')
176 u = User.find_by_mail('JSmith@somenet.foo')
164 assert_not_nil u
177 assert_not_nil u
165 assert_equal 'jsmith@somenet.foo', u.mail
178 assert_equal 'jsmith@somenet.foo', u.mail
166 end
179 end
167 end
180 end
General Comments 0
You need to be logged in to leave comments. Login now