comparison test/unit/user_test.rb @ 0:513646585e45

* Import Redmine trunk SVN rev 3859
author Chris Cannam
date Fri, 23 Jul 2010 15:52:44 +0100
parents
children cca12e1c1fd4
comparison
equal deleted inserted replaced
-1:000000000000 0:513646585e45
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
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
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 require File.dirname(__FILE__) + '/../test_helper'
19
20 class UserTest < ActiveSupport::TestCase
21 fixtures :users, :members, :projects, :roles, :member_roles, :auth_sources
22
23 def setup
24 @admin = User.find(1)
25 @jsmith = User.find(2)
26 @dlopper = User.find(3)
27 end
28
29 test 'object_daddy creation' do
30 User.generate_with_protected!(:firstname => 'Testing connection')
31 User.generate_with_protected!(:firstname => 'Testing connection')
32 assert_equal 2, User.count(:all, :conditions => {:firstname => 'Testing connection'})
33 end
34
35 def test_truth
36 assert_kind_of User, @jsmith
37 end
38
39 def test_create
40 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
41
42 user.login = "jsmith"
43 user.password, user.password_confirmation = "password", "password"
44 # login uniqueness
45 assert !user.save
46 assert_equal 1, user.errors.count
47
48 user.login = "newuser"
49 user.password, user.password_confirmation = "passwd", "password"
50 # password confirmation
51 assert !user.save
52 assert_equal 1, user.errors.count
53
54 user.password, user.password_confirmation = "password", "password"
55 assert user.save
56 end
57
58 context "User.login" do
59 should "be case-insensitive." do
60 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
61 u.login = 'newuser'
62 u.password, u.password_confirmation = "password", "password"
63 assert u.save
64
65 u = User.new(:firstname => "Similar", :lastname => "User", :mail => "similaruser@somenet.foo")
66 u.login = 'NewUser'
67 u.password, u.password_confirmation = "password", "password"
68 assert !u.save
69 assert_equal I18n.translate('activerecord.errors.messages.taken'), u.errors.on(:login)
70 end
71 end
72
73 def test_mail_uniqueness_should_not_be_case_sensitive
74 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
75 u.login = 'newuser1'
76 u.password, u.password_confirmation = "password", "password"
77 assert u.save
78
79 u = User.new(:firstname => "new", :lastname => "user", :mail => "newUser@Somenet.foo")
80 u.login = 'newuser2'
81 u.password, u.password_confirmation = "password", "password"
82 assert !u.save
83 assert_equal I18n.translate('activerecord.errors.messages.taken'), u.errors.on(:mail)
84 end
85
86 def test_update
87 assert_equal "admin", @admin.login
88 @admin.login = "john"
89 assert @admin.save, @admin.errors.full_messages.join("; ")
90 @admin.reload
91 assert_equal "john", @admin.login
92 end
93
94 def test_destroy
95 User.find(2).destroy
96 assert_nil User.find_by_id(2)
97 assert Member.find_all_by_user_id(2).empty?
98 end
99
100 def test_validate
101 @admin.login = ""
102 assert !@admin.save
103 assert_equal 1, @admin.errors.count
104 end
105
106 context "User#try_to_login" do
107 should "fall-back to case-insensitive if user login is not found as-typed." do
108 user = User.try_to_login("AdMin", "admin")
109 assert_kind_of User, user
110 assert_equal "admin", user.login
111 end
112
113 should "select the exact matching user first" do
114 case_sensitive_user = User.generate_with_protected!(:login => 'changed', :password => 'admin', :password_confirmation => 'admin')
115 # bypass validations to make it appear like existing data
116 case_sensitive_user.update_attribute(:login, 'ADMIN')
117
118 user = User.try_to_login("ADMIN", "admin")
119 assert_kind_of User, user
120 assert_equal "ADMIN", user.login
121
122 end
123 end
124
125 def test_password
126 user = User.try_to_login("admin", "admin")
127 assert_kind_of User, user
128 assert_equal "admin", user.login
129 user.password = "hello"
130 assert user.save
131
132 user = User.try_to_login("admin", "hello")
133 assert_kind_of User, user
134 assert_equal "admin", user.login
135 assert_equal User.hash_password("hello"), user.hashed_password
136 end
137
138 def test_name_format
139 assert_equal 'Smith, John', @jsmith.name(:lastname_coma_firstname)
140 Setting.user_format = :firstname_lastname
141 assert_equal 'John Smith', @jsmith.reload.name
142 Setting.user_format = :username
143 assert_equal 'jsmith', @jsmith.reload.name
144 end
145
146 def test_lock
147 user = User.try_to_login("jsmith", "jsmith")
148 assert_equal @jsmith, user
149
150 @jsmith.status = User::STATUS_LOCKED
151 assert @jsmith.save
152
153 user = User.try_to_login("jsmith", "jsmith")
154 assert_equal nil, user
155 end
156
157 if ldap_configured?
158 context "#try_to_login using LDAP" do
159 context "with failed connection to the LDAP server" do
160 should "return nil" do
161 @auth_source = AuthSourceLdap.find(1)
162 AuthSource.any_instance.stubs(:initialize_ldap_con).raises(Net::LDAP::LdapError, 'Cannot connect')
163
164 assert_equal nil, User.try_to_login('edavis', 'wrong')
165 end
166 end
167
168 context "with an unsuccessful authentication" do
169 should "return nil" do
170 assert_equal nil, User.try_to_login('edavis', 'wrong')
171 end
172 end
173
174 context "on the fly registration" do
175 setup do
176 @auth_source = AuthSourceLdap.find(1)
177 end
178
179 context "with a successful authentication" do
180 should "create a new user account if it doesn't exist" do
181 assert_difference('User.count') do
182 user = User.try_to_login('edavis', '123456')
183 assert !user.admin?
184 end
185 end
186
187 should "retrieve existing user" do
188 user = User.try_to_login('edavis', '123456')
189 user.admin = true
190 user.save!
191
192 assert_no_difference('User.count') do
193 user = User.try_to_login('edavis', '123456')
194 assert user.admin?
195 end
196 end
197 end
198 end
199 end
200
201 else
202 puts "Skipping LDAP tests."
203 end
204
205 def test_create_anonymous
206 AnonymousUser.delete_all
207 anon = User.anonymous
208 assert !anon.new_record?
209 assert_kind_of AnonymousUser, anon
210 end
211
212 should_have_one :rss_token
213
214 def test_rss_key
215 assert_nil @jsmith.rss_token
216 key = @jsmith.rss_key
217 assert_equal 40, key.length
218
219 @jsmith.reload
220 assert_equal key, @jsmith.rss_key
221 end
222
223
224 should_have_one :api_token
225
226 context "User#api_key" do
227 should "generate a new one if the user doesn't have one" do
228 user = User.generate_with_protected!(:api_token => nil)
229 assert_nil user.api_token
230
231 key = user.api_key
232 assert_equal 40, key.length
233 user.reload
234 assert_equal key, user.api_key
235 end
236
237 should "return the existing api token value" do
238 user = User.generate_with_protected!
239 token = Token.generate!(:action => 'api')
240 user.api_token = token
241 assert user.save
242
243 assert_equal token.value, user.api_key
244 end
245 end
246
247 context "User#find_by_api_key" do
248 should "return nil if no matching key is found" do
249 assert_nil User.find_by_api_key('zzzzzzzzz')
250 end
251
252 should "return nil if the key is found for an inactive user" do
253 user = User.generate_with_protected!(:status => User::STATUS_LOCKED)
254 token = Token.generate!(:action => 'api')
255 user.api_token = token
256 user.save
257
258 assert_nil User.find_by_api_key(token.value)
259 end
260
261 should "return the user if the key is found for an active user" do
262 user = User.generate_with_protected!(:status => User::STATUS_ACTIVE)
263 token = Token.generate!(:action => 'api')
264 user.api_token = token
265 user.save
266
267 assert_equal user, User.find_by_api_key(token.value)
268 end
269 end
270
271 def test_roles_for_project
272 # user with a role
273 roles = @jsmith.roles_for_project(Project.find(1))
274 assert_kind_of Role, roles.first
275 assert_equal "Manager", roles.first.name
276
277 # user with no role
278 assert_nil @dlopper.roles_for_project(Project.find(2)).detect {|role| role.member?}
279 end
280
281 def test_mail_notification_all
282 @jsmith.mail_notification = true
283 @jsmith.notified_project_ids = []
284 @jsmith.save
285 @jsmith.reload
286 assert @jsmith.projects.first.recipients.include?(@jsmith.mail)
287 end
288
289 def test_mail_notification_selected
290 @jsmith.mail_notification = false
291 @jsmith.notified_project_ids = [1]
292 @jsmith.save
293 @jsmith.reload
294 assert Project.find(1).recipients.include?(@jsmith.mail)
295 end
296
297 def test_mail_notification_none
298 @jsmith.mail_notification = false
299 @jsmith.notified_project_ids = []
300 @jsmith.save
301 @jsmith.reload
302 assert !@jsmith.projects.first.recipients.include?(@jsmith.mail)
303 end
304
305 def test_comments_sorting_preference
306 assert !@jsmith.wants_comments_in_reverse_order?
307 @jsmith.pref.comments_sorting = 'asc'
308 assert !@jsmith.wants_comments_in_reverse_order?
309 @jsmith.pref.comments_sorting = 'desc'
310 assert @jsmith.wants_comments_in_reverse_order?
311 end
312
313 def test_find_by_mail_should_be_case_insensitive
314 u = User.find_by_mail('JSmith@somenet.foo')
315 assert_not_nil u
316 assert_equal 'jsmith@somenet.foo', u.mail
317 end
318
319 def test_random_password
320 u = User.new
321 u.random_password
322 assert !u.password.blank?
323 assert !u.password_confirmation.blank?
324 end
325
326 context "#change_password_allowed?" do
327 should "be allowed if no auth source is set" do
328 user = User.generate_with_protected!
329 assert user.change_password_allowed?
330 end
331
332 should "delegate to the auth source" do
333 user = User.generate_with_protected!
334
335 allowed_auth_source = AuthSource.generate!
336 def allowed_auth_source.allow_password_changes?; true; end
337
338 denied_auth_source = AuthSource.generate!
339 def denied_auth_source.allow_password_changes?; false; end
340
341 assert user.change_password_allowed?
342
343 user.auth_source = allowed_auth_source
344 assert user.change_password_allowed?, "User not allowed to change password, though auth source does"
345
346 user.auth_source = denied_auth_source
347 assert !user.change_password_allowed?, "User allowed to change password, though auth source does not"
348 end
349
350 end
351
352 if Object.const_defined?(:OpenID)
353
354 def test_setting_identity_url
355 normalized_open_id_url = 'http://example.com/'
356 u = User.new( :identity_url => 'http://example.com/' )
357 assert_equal normalized_open_id_url, u.identity_url
358 end
359
360 def test_setting_identity_url_without_trailing_slash
361 normalized_open_id_url = 'http://example.com/'
362 u = User.new( :identity_url => 'http://example.com' )
363 assert_equal normalized_open_id_url, u.identity_url
364 end
365
366 def test_setting_identity_url_without_protocol
367 normalized_open_id_url = 'http://example.com/'
368 u = User.new( :identity_url => 'example.com' )
369 assert_equal normalized_open_id_url, u.identity_url
370 end
371
372 def test_setting_blank_identity_url
373 u = User.new( :identity_url => 'example.com' )
374 u.identity_url = ''
375 assert u.identity_url.blank?
376 end
377
378 def test_setting_invalid_identity_url
379 u = User.new( :identity_url => 'this is not an openid url' )
380 assert u.identity_url.blank?
381 end
382
383 else
384 puts "Skipping openid tests."
385 end
386
387 end