##// END OF EJS Templates
Fixed: invalid SQL query on User#destroy (#1781)....
Jean-Philippe Lang -
r1754:6fc62d393cc4
parent child
Show More
@@ -1,293 +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", :dependent => :delete_all
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 :projects, :through => :memberships
38 has_many :projects, :through => :memberships
38 has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify
39 has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify
39 has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
40 has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
40 has_one :rss_token, :dependent => :destroy, :class_name => 'Token', :conditions => "action='feeds'"
41 has_one :rss_token, :dependent => :destroy, :class_name => 'Token', :conditions => "action='feeds'"
41 belongs_to :auth_source
42 belongs_to :auth_source
42
43
43 acts_as_customizable
44 acts_as_customizable
44
45
45 attr_accessor :password, :password_confirmation
46 attr_accessor :password, :password_confirmation
46 attr_accessor :last_before_login_on
47 attr_accessor :last_before_login_on
47 # Prevents unauthorized assignments
48 # Prevents unauthorized assignments
48 attr_protected :login, :admin, :password, :password_confirmation, :hashed_password
49 attr_protected :login, :admin, :password, :password_confirmation, :hashed_password
49
50
50 validates_presence_of :login, :firstname, :lastname, :mail, :if => Proc.new { |user| !user.is_a?(AnonymousUser) }
51 validates_presence_of :login, :firstname, :lastname, :mail, :if => Proc.new { |user| !user.is_a?(AnonymousUser) }
51 validates_uniqueness_of :login, :if => Proc.new { |user| !user.login.blank? }
52 validates_uniqueness_of :login, :if => Proc.new { |user| !user.login.blank? }
52 validates_uniqueness_of :mail, :if => Proc.new { |user| !user.mail.blank? }
53 validates_uniqueness_of :mail, :if => Proc.new { |user| !user.mail.blank? }
53 # Login must contain lettres, numbers, underscores only
54 # Login must contain lettres, numbers, underscores only
54 validates_format_of :login, :with => /^[a-z0-9_\-@\.]*$/i
55 validates_format_of :login, :with => /^[a-z0-9_\-@\.]*$/i
55 validates_length_of :login, :maximum => 30
56 validates_length_of :login, :maximum => 30
56 validates_format_of :firstname, :lastname, :with => /^[\w\s\'\-\.]*$/i
57 validates_format_of :firstname, :lastname, :with => /^[\w\s\'\-\.]*$/i
57 validates_length_of :firstname, :lastname, :maximum => 30
58 validates_length_of :firstname, :lastname, :maximum => 30
58 validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :allow_nil => true
59 validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :allow_nil => true
59 validates_length_of :mail, :maximum => 60, :allow_nil => true
60 validates_length_of :mail, :maximum => 60, :allow_nil => true
60 validates_length_of :password, :minimum => 4, :allow_nil => true
61 validates_length_of :password, :minimum => 4, :allow_nil => true
61 validates_confirmation_of :password, :allow_nil => true
62 validates_confirmation_of :password, :allow_nil => true
62
63
63 def before_create
64 def before_create
64 self.mail_notification = false
65 self.mail_notification = false
65 true
66 true
66 end
67 end
67
68
68 def before_save
69 def before_save
69 # update hashed_password if password was set
70 # update hashed_password if password was set
70 self.hashed_password = User.hash_password(self.password) if self.password
71 self.hashed_password = User.hash_password(self.password) if self.password
71 end
72 end
72
73
73 def self.active
74 def self.active
74 with_scope :find => { :conditions => [ "status = ?", STATUS_ACTIVE ] } do
75 with_scope :find => { :conditions => [ "status = ?", STATUS_ACTIVE ] } do
75 yield
76 yield
76 end
77 end
77 end
78 end
78
79
79 def self.find_active(*args)
80 def self.find_active(*args)
80 active do
81 active do
81 find(*args)
82 find(*args)
82 end
83 end
83 end
84 end
84
85
85 # Returns the user that matches provided login and password, or nil
86 # Returns the user that matches provided login and password, or nil
86 def self.try_to_login(login, password)
87 def self.try_to_login(login, password)
87 # Make sure no one can sign in with an empty password
88 # Make sure no one can sign in with an empty password
88 return nil if password.to_s.empty?
89 return nil if password.to_s.empty?
89 user = find(:first, :conditions => ["login=?", login])
90 user = find(:first, :conditions => ["login=?", login])
90 if user
91 if user
91 # user is already in local database
92 # user is already in local database
92 return nil if !user.active?
93 return nil if !user.active?
93 if user.auth_source
94 if user.auth_source
94 # user has an external authentication method
95 # user has an external authentication method
95 return nil unless user.auth_source.authenticate(login, password)
96 return nil unless user.auth_source.authenticate(login, password)
96 else
97 else
97 # authentication with local password
98 # authentication with local password
98 return nil unless User.hash_password(password) == user.hashed_password
99 return nil unless User.hash_password(password) == user.hashed_password
99 end
100 end
100 else
101 else
101 # user is not yet registered, try to authenticate with available sources
102 # user is not yet registered, try to authenticate with available sources
102 attrs = AuthSource.authenticate(login, password)
103 attrs = AuthSource.authenticate(login, password)
103 if attrs
104 if attrs
104 user = new(*attrs)
105 user = new(*attrs)
105 user.login = login
106 user.login = login
106 user.language = Setting.default_language
107 user.language = Setting.default_language
107 if user.save
108 if user.save
108 user.reload
109 user.reload
109 logger.info("User '#{user.login}' created from the LDAP") if logger
110 logger.info("User '#{user.login}' created from the LDAP") if logger
110 end
111 end
111 end
112 end
112 end
113 end
113 user.update_attribute(:last_login_on, Time.now) if user && !user.new_record?
114 user.update_attribute(:last_login_on, Time.now) if user && !user.new_record?
114 user
115 user
115 rescue => text
116 rescue => text
116 raise text
117 raise text
117 end
118 end
118
119
119 # Return user's full name for display
120 # Return user's full name for display
120 def name(formatter = nil)
121 def name(formatter = nil)
121 f = USER_FORMATS[formatter || Setting.user_format] || USER_FORMATS[:firstname_lastname]
122 f = USER_FORMATS[formatter || Setting.user_format] || USER_FORMATS[:firstname_lastname]
122 eval '"' + f + '"'
123 eval '"' + f + '"'
123 end
124 end
124
125
125 def active?
126 def active?
126 self.status == STATUS_ACTIVE
127 self.status == STATUS_ACTIVE
127 end
128 end
128
129
129 def registered?
130 def registered?
130 self.status == STATUS_REGISTERED
131 self.status == STATUS_REGISTERED
131 end
132 end
132
133
133 def locked?
134 def locked?
134 self.status == STATUS_LOCKED
135 self.status == STATUS_LOCKED
135 end
136 end
136
137
137 def check_password?(clear_password)
138 def check_password?(clear_password)
138 User.hash_password(clear_password) == self.hashed_password
139 User.hash_password(clear_password) == self.hashed_password
139 end
140 end
140
141
141 def pref
142 def pref
142 self.preference ||= UserPreference.new(:user => self)
143 self.preference ||= UserPreference.new(:user => self)
143 end
144 end
144
145
145 def time_zone
146 def time_zone
146 self.pref.time_zone.nil? ? nil : TimeZone[self.pref.time_zone]
147 self.pref.time_zone.nil? ? nil : TimeZone[self.pref.time_zone]
147 end
148 end
148
149
149 def wants_comments_in_reverse_order?
150 def wants_comments_in_reverse_order?
150 self.pref[:comments_sorting] == 'desc'
151 self.pref[:comments_sorting] == 'desc'
151 end
152 end
152
153
153 # 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
154 def rss_key
155 def rss_key
155 token = self.rss_token || Token.create(:user => self, :action => 'feeds')
156 token = self.rss_token || Token.create(:user => self, :action => 'feeds')
156 token.value
157 token.value
157 end
158 end
158
159
159 # 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
160 def notified_projects_ids
161 def notified_projects_ids
161 @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)
162 end
163 end
163
164
164 def notified_project_ids=(ids)
165 def notified_project_ids=(ids)
165 Member.update_all("mail_notification = #{connection.quoted_false}", ['user_id = ?', id])
166 Member.update_all("mail_notification = #{connection.quoted_false}", ['user_id = ?', id])
166 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?
167 @notified_projects_ids = nil
168 @notified_projects_ids = nil
168 notified_projects_ids
169 notified_projects_ids
169 end
170 end
170
171
171 def self.find_by_rss_key(key)
172 def self.find_by_rss_key(key)
172 token = Token.find_by_value(key)
173 token = Token.find_by_value(key)
173 token && token.user.active? ? token.user : nil
174 token && token.user.active? ? token.user : nil
174 end
175 end
175
176
176 def self.find_by_autologin_key(key)
177 def self.find_by_autologin_key(key)
177 token = Token.find_by_action_and_value('autologin', key)
178 token = Token.find_by_action_and_value('autologin', key)
178 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
179 end
180 end
180
181
181 def <=>(user)
182 def <=>(user)
182 if user.nil?
183 if user.nil?
183 -1
184 -1
184 elsif lastname.to_s.downcase == user.lastname.to_s.downcase
185 elsif lastname.to_s.downcase == user.lastname.to_s.downcase
185 firstname.to_s.downcase <=> user.firstname.to_s.downcase
186 firstname.to_s.downcase <=> user.firstname.to_s.downcase
186 else
187 else
187 lastname.to_s.downcase <=> user.lastname.to_s.downcase
188 lastname.to_s.downcase <=> user.lastname.to_s.downcase
188 end
189 end
189 end
190 end
190
191
191 def to_s
192 def to_s
192 name
193 name
193 end
194 end
194
195
195 def logged?
196 def logged?
196 true
197 true
197 end
198 end
198
199
199 def anonymous?
200 def anonymous?
200 !logged?
201 !logged?
201 end
202 end
202
203
203 # Return user's role for project
204 # Return user's role for project
204 def role_for_project(project)
205 def role_for_project(project)
205 # No role on archived projects
206 # No role on archived projects
206 return nil unless project && project.active?
207 return nil unless project && project.active?
207 if logged?
208 if logged?
208 # Find project membership
209 # Find project membership
209 membership = memberships.detect {|m| m.project_id == project.id}
210 membership = memberships.detect {|m| m.project_id == project.id}
210 if membership
211 if membership
211 membership.role
212 membership.role
212 else
213 else
213 @role_non_member ||= Role.non_member
214 @role_non_member ||= Role.non_member
214 end
215 end
215 else
216 else
216 @role_anonymous ||= Role.anonymous
217 @role_anonymous ||= Role.anonymous
217 end
218 end
218 end
219 end
219
220
220 # Return true if the user is a member of project
221 # Return true if the user is a member of project
221 def member_of?(project)
222 def member_of?(project)
222 role_for_project(project).member?
223 role_for_project(project).member?
223 end
224 end
224
225
225 # 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
226 # action can be:
227 # action can be:
227 # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
228 # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
228 # * a permission Symbol (eg. :edit_project)
229 # * a permission Symbol (eg. :edit_project)
229 def allowed_to?(action, project, options={})
230 def allowed_to?(action, project, options={})
230 if project
231 if project
231 # No action allowed on archived projects
232 # No action allowed on archived projects
232 return false unless project.active?
233 return false unless project.active?
233 # No action allowed on disabled modules
234 # No action allowed on disabled modules
234 return false unless project.allows_to?(action)
235 return false unless project.allows_to?(action)
235 # Admin users are authorized for anything else
236 # Admin users are authorized for anything else
236 return true if admin?
237 return true if admin?
237
238
238 role = role_for_project(project)
239 role = role_for_project(project)
239 return false unless role
240 return false unless role
240 role.allowed_to?(action) && (project.is_public? || role.member?)
241 role.allowed_to?(action) && (project.is_public? || role.member?)
241
242
242 elsif options[:global]
243 elsif options[:global]
243 # 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
244 roles = memberships.collect {|m| m.role}.uniq
245 roles = memberships.collect {|m| m.role}.uniq
245 roles.detect {|r| r.allowed_to?(action)}
246 roles.detect {|r| r.allowed_to?(action)}
246 else
247 else
247 false
248 false
248 end
249 end
249 end
250 end
250
251
251 def self.current=(user)
252 def self.current=(user)
252 @current_user = user
253 @current_user = user
253 end
254 end
254
255
255 def self.current
256 def self.current
256 @current_user ||= User.anonymous
257 @current_user ||= User.anonymous
257 end
258 end
258
259
259 def self.anonymous
260 def self.anonymous
260 anonymous_user = AnonymousUser.find(:first)
261 anonymous_user = AnonymousUser.find(:first)
261 if anonymous_user.nil?
262 if anonymous_user.nil?
262 anonymous_user = AnonymousUser.create(:lastname => 'Anonymous', :firstname => '', :mail => '', :login => '', :status => 0)
263 anonymous_user = AnonymousUser.create(:lastname => 'Anonymous', :firstname => '', :mail => '', :login => '', :status => 0)
263 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?
264 end
265 end
265 anonymous_user
266 anonymous_user
266 end
267 end
267
268
268 private
269 private
269 # Return password digest
270 # Return password digest
270 def self.hash_password(clear_password)
271 def self.hash_password(clear_password)
271 Digest::SHA1.hexdigest(clear_password || "")
272 Digest::SHA1.hexdigest(clear_password || "")
272 end
273 end
273 end
274 end
274
275
275 class AnonymousUser < User
276 class AnonymousUser < User
276
277
277 def validate_on_create
278 def validate_on_create
278 # There should be only one AnonymousUser in the database
279 # There should be only one AnonymousUser in the database
279 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)
280 end
281 end
281
282
282 def available_custom_fields
283 def available_custom_fields
283 []
284 []
284 end
285 end
285
286
286 # Overrides a few properties
287 # Overrides a few properties
287 def logged?; false end
288 def logged?; false end
288 def admin; false end
289 def admin; false end
289 def name; 'Anonymous' end
290 def name; 'Anonymous' end
290 def mail; nil end
291 def mail; nil end
291 def time_zone; nil end
292 def time_zone; nil end
292 def rss_key; nil end
293 def rss_key; nil end
293 end
294 end
@@ -1,155 +1,161
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
50 end
51
51
52 def test_update
52 def test_update
53 assert_equal "admin", @admin.login
53 assert_equal "admin", @admin.login
54 @admin.login = "john"
54 @admin.login = "john"
55 assert @admin.save, @admin.errors.full_messages.join("; ")
55 assert @admin.save, @admin.errors.full_messages.join("; ")
56 @admin.reload
56 @admin.reload
57 assert_equal "john", @admin.login
57 assert_equal "john", @admin.login
58 end
58 end
59
59
60 def test_destroy
61 User.find(2).destroy
62 assert_nil User.find_by_id(2)
63 assert Member.find_all_by_user_id(2).empty?
64 end
65
60 def test_validate
66 def test_validate
61 @admin.login = ""
67 @admin.login = ""
62 assert !@admin.save
68 assert !@admin.save
63 assert_equal 1, @admin.errors.count
69 assert_equal 1, @admin.errors.count
64 end
70 end
65
71
66 def test_password
72 def test_password
67 user = User.try_to_login("admin", "admin")
73 user = User.try_to_login("admin", "admin")
68 assert_kind_of User, user
74 assert_kind_of User, user
69 assert_equal "admin", user.login
75 assert_equal "admin", user.login
70 user.password = "hello"
76 user.password = "hello"
71 assert user.save
77 assert user.save
72
78
73 user = User.try_to_login("admin", "hello")
79 user = User.try_to_login("admin", "hello")
74 assert_kind_of User, user
80 assert_kind_of User, user
75 assert_equal "admin", user.login
81 assert_equal "admin", user.login
76 assert_equal User.hash_password("hello"), user.hashed_password
82 assert_equal User.hash_password("hello"), user.hashed_password
77 end
83 end
78
84
79 def test_name_format
85 def test_name_format
80 assert_equal 'Smith, John', @jsmith.name(:lastname_coma_firstname)
86 assert_equal 'Smith, John', @jsmith.name(:lastname_coma_firstname)
81 Setting.user_format = :firstname_lastname
87 Setting.user_format = :firstname_lastname
82 assert_equal 'John Smith', @jsmith.name
88 assert_equal 'John Smith', @jsmith.name
83 Setting.user_format = :username
89 Setting.user_format = :username
84 assert_equal 'jsmith', @jsmith.name
90 assert_equal 'jsmith', @jsmith.name
85 end
91 end
86
92
87 def test_lock
93 def test_lock
88 user = User.try_to_login("jsmith", "jsmith")
94 user = User.try_to_login("jsmith", "jsmith")
89 assert_equal @jsmith, user
95 assert_equal @jsmith, user
90
96
91 @jsmith.status = User::STATUS_LOCKED
97 @jsmith.status = User::STATUS_LOCKED
92 assert @jsmith.save
98 assert @jsmith.save
93
99
94 user = User.try_to_login("jsmith", "jsmith")
100 user = User.try_to_login("jsmith", "jsmith")
95 assert_equal nil, user
101 assert_equal nil, user
96 end
102 end
97
103
98 def test_create_anonymous
104 def test_create_anonymous
99 AnonymousUser.delete_all
105 AnonymousUser.delete_all
100 anon = User.anonymous
106 anon = User.anonymous
101 assert !anon.new_record?
107 assert !anon.new_record?
102 assert_kind_of AnonymousUser, anon
108 assert_kind_of AnonymousUser, anon
103 end
109 end
104
110
105 def test_rss_key
111 def test_rss_key
106 assert_nil @jsmith.rss_token
112 assert_nil @jsmith.rss_token
107 key = @jsmith.rss_key
113 key = @jsmith.rss_key
108 assert_equal 40, key.length
114 assert_equal 40, key.length
109
115
110 @jsmith.reload
116 @jsmith.reload
111 assert_equal key, @jsmith.rss_key
117 assert_equal key, @jsmith.rss_key
112 end
118 end
113
119
114 def test_role_for_project
120 def test_role_for_project
115 # user with a role
121 # user with a role
116 role = @jsmith.role_for_project(Project.find(1))
122 role = @jsmith.role_for_project(Project.find(1))
117 assert_kind_of Role, role
123 assert_kind_of Role, role
118 assert_equal "Manager", role.name
124 assert_equal "Manager", role.name
119
125
120 # user with no role
126 # user with no role
121 assert !@dlopper.role_for_project(Project.find(2)).member?
127 assert !@dlopper.role_for_project(Project.find(2)).member?
122 end
128 end
123
129
124 def test_mail_notification_all
130 def test_mail_notification_all
125 @jsmith.mail_notification = true
131 @jsmith.mail_notification = true
126 @jsmith.notified_project_ids = []
132 @jsmith.notified_project_ids = []
127 @jsmith.save
133 @jsmith.save
128 @jsmith.reload
134 @jsmith.reload
129 assert @jsmith.projects.first.recipients.include?(@jsmith.mail)
135 assert @jsmith.projects.first.recipients.include?(@jsmith.mail)
130 end
136 end
131
137
132 def test_mail_notification_selected
138 def test_mail_notification_selected
133 @jsmith.mail_notification = false
139 @jsmith.mail_notification = false
134 @jsmith.notified_project_ids = [1]
140 @jsmith.notified_project_ids = [1]
135 @jsmith.save
141 @jsmith.save
136 @jsmith.reload
142 @jsmith.reload
137 assert Project.find(1).recipients.include?(@jsmith.mail)
143 assert Project.find(1).recipients.include?(@jsmith.mail)
138 end
144 end
139
145
140 def test_mail_notification_none
146 def test_mail_notification_none
141 @jsmith.mail_notification = false
147 @jsmith.mail_notification = false
142 @jsmith.notified_project_ids = []
148 @jsmith.notified_project_ids = []
143 @jsmith.save
149 @jsmith.save
144 @jsmith.reload
150 @jsmith.reload
145 assert !@jsmith.projects.first.recipients.include?(@jsmith.mail)
151 assert !@jsmith.projects.first.recipients.include?(@jsmith.mail)
146 end
152 end
147
153
148 def test_comments_sorting_preference
154 def test_comments_sorting_preference
149 assert !@jsmith.wants_comments_in_reverse_order?
155 assert !@jsmith.wants_comments_in_reverse_order?
150 @jsmith.pref.comments_sorting = 'asc'
156 @jsmith.pref.comments_sorting = 'asc'
151 assert !@jsmith.wants_comments_in_reverse_order?
157 assert !@jsmith.wants_comments_in_reverse_order?
152 @jsmith.pref.comments_sorting = 'desc'
158 @jsmith.pref.comments_sorting = 'desc'
153 assert @jsmith.wants_comments_in_reverse_order?
159 assert @jsmith.wants_comments_in_reverse_order?
154 end
160 end
155 end
161 end
General Comments 0
You need to be logged in to leave comments. Login now