]> git.openstreetmap.org Git - rails.git/blob - test/controllers/users_controller_test.rb
Split password reset functionality into PasswordsController
[rails.git] / test / controllers / users_controller_test.rb
1 require "test_helper"
2
3 class UsersControllerTest < ActionDispatch::IntegrationTest
4   ##
5   # test all routes which lead to this controller
6   def test_routes
7     assert_routing(
8       { :path => "/user/new", :method => :get },
9       { :controller => "users", :action => "new" }
10     )
11
12     assert_routing(
13       { :path => "/user/new", :method => :post },
14       { :controller => "users", :action => "create" }
15     )
16
17     assert_routing(
18       { :path => "/user/terms", :method => :get },
19       { :controller => "users", :action => "terms" }
20     )
21
22     assert_routing(
23       { :path => "/user/save", :method => :post },
24       { :controller => "users", :action => "save" }
25     )
26
27     assert_routing(
28       { :path => "/user/username/confirm", :method => :get },
29       { :controller => "users", :action => "confirm", :display_name => "username" }
30     )
31     assert_routing(
32       { :path => "/user/username/confirm", :method => :post },
33       { :controller => "users", :action => "confirm", :display_name => "username" }
34     )
35     assert_routing(
36       { :path => "/user/username/confirm/resend", :method => :get },
37       { :controller => "users", :action => "confirm_resend", :display_name => "username" }
38     )
39
40     assert_routing(
41       { :path => "/user/confirm", :method => :get },
42       { :controller => "users", :action => "confirm" }
43     )
44     assert_routing(
45       { :path => "/user/confirm", :method => :post },
46       { :controller => "users", :action => "confirm" }
47     )
48     assert_routing(
49       { :path => "/user/confirm-email", :method => :get },
50       { :controller => "users", :action => "confirm_email" }
51     )
52     assert_routing(
53       { :path => "/user/confirm-email", :method => :post },
54       { :controller => "users", :action => "confirm_email" }
55     )
56
57     assert_routing(
58       { :path => "/user/go_public", :method => :post },
59       { :controller => "users", :action => "go_public" }
60     )
61
62     assert_routing(
63       { :path => "/user/suspended", :method => :get },
64       { :controller => "users", :action => "suspended" }
65     )
66
67     assert_routing(
68       { :path => "/user/username", :method => :get },
69       { :controller => "users", :action => "show", :display_name => "username" }
70     )
71
72     assert_routing(
73       { :path => "/user/username/account", :method => :get },
74       { :controller => "users", :action => "account", :display_name => "username" }
75     )
76     assert_routing(
77       { :path => "/user/username/account", :method => :post },
78       { :controller => "users", :action => "account", :display_name => "username" }
79     )
80
81     assert_routing(
82       { :path => "/user/username/set_status", :method => :post },
83       { :controller => "users", :action => "set_status", :display_name => "username" }
84     )
85     assert_routing(
86       { :path => "/user/username", :method => :delete },
87       { :controller => "users", :action => "destroy", :display_name => "username" }
88     )
89
90     assert_routing(
91       { :path => "/users", :method => :get },
92       { :controller => "users", :action => "index" }
93     )
94     assert_routing(
95       { :path => "/users", :method => :post },
96       { :controller => "users", :action => "index" }
97     )
98     assert_routing(
99       { :path => "/users/status", :method => :get },
100       { :controller => "users", :action => "index", :status => "status" }
101     )
102     assert_routing(
103       { :path => "/users/status", :method => :post },
104       { :controller => "users", :action => "index", :status => "status" }
105     )
106   end
107
108   # The user creation page loads
109   def test_new_view
110     get user_new_path
111     assert_response :redirect
112     assert_redirected_to user_new_path(:cookie_test => "true")
113
114     get user_new_path, :params => { :cookie_test => "true" }
115     assert_response :success
116
117     assert_select "html", :count => 1 do
118       assert_select "head", :count => 1 do
119         assert_select "title", :text => /Sign Up/, :count => 1
120       end
121       assert_select "body", :count => 1 do
122         assert_select "div#content", :count => 1 do
123           assert_select "form[action='/user/new'][method='post']", :count => 1 do
124             assert_select "input[id='user_email']", :count => 1
125             assert_select "input[id='user_email_confirmation']", :count => 1
126             assert_select "input[id='user_display_name']", :count => 1
127             assert_select "input[id='user_pass_crypt'][type='password']", :count => 1
128             assert_select "input[id='user_pass_crypt_confirmation'][type='password']", :count => 1
129             assert_select "input[type='submit'][value='Sign Up']", :count => 1
130           end
131         end
132       end
133     end
134   end
135
136   def test_new_view_logged_in
137     session_for(create(:user))
138
139     get user_new_path
140     assert_response :redirect
141     assert_redirected_to root_path
142
143     get user_new_path, :params => { :referer => "/test" }
144     assert_response :redirect
145     assert_redirected_to "/test"
146   end
147
148   def test_new_success
149     user = build(:user, :pending)
150
151     assert_no_difference "User.count" do
152       assert_no_difference "ActionMailer::Base.deliveries.size" do
153         perform_enqueued_jobs do
154           post user_new_path, :params => { :user => user.attributes }
155         end
156       end
157     end
158
159     assert_difference "User.count", 1 do
160       assert_difference "ActionMailer::Base.deliveries.size", 1 do
161         perform_enqueued_jobs do
162           post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
163         end
164       end
165     end
166
167     # Check the e-mail
168     register_email = ActionMailer::Base.deliveries.first
169
170     assert_equal register_email.to[0], user.email
171     assert_match(/#{@url}/, register_email.body.to_s)
172
173     # Check the page
174     assert_redirected_to :action => "confirm", :display_name => user.display_name
175
176     ActionMailer::Base.deliveries.clear
177   end
178
179   def test_new_duplicate_email
180     user = build(:user, :pending)
181     create(:user, :email => user.email)
182
183     assert_no_difference "User.count" do
184       assert_no_difference "ActionMailer::Base.deliveries.size" do
185         perform_enqueued_jobs do
186           post user_new_path, :params => { :user => user.attributes }
187         end
188       end
189     end
190
191     assert_response :success
192     assert_template "new"
193     assert_select "form > div.form-group > input.is-invalid#user_email"
194   end
195
196   def test_save_duplicate_email
197     user = build(:user, :pending)
198
199     # Set up our user as being half-way through registration
200     assert_no_difference "User.count" do
201       assert_no_difference "ActionMailer::Base.deliveries.size" do
202         perform_enqueued_jobs do
203           post user_new_path, :params => { :user => user.attributes }
204         end
205       end
206     end
207
208     # Now create another user with that email
209     create(:user, :email => user.email)
210
211     # Check that the second half of registration fails
212     assert_no_difference "User.count" do
213       assert_no_difference "ActionMailer::Base.deliveries.size" do
214         perform_enqueued_jobs do
215           post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
216         end
217       end
218     end
219
220     assert_response :success
221     assert_template "new"
222     assert_select "form > div.form-group > input.is-invalid#user_email"
223   end
224
225   def test_save_duplicate_email_uppercase
226     user = build(:user, :pending)
227
228     # Set up our user as being half-way through registration
229     assert_no_difference "User.count" do
230       assert_no_difference "ActionMailer::Base.deliveries.size" do
231         perform_enqueued_jobs do
232           post user_new_path, :params => { :user => user.attributes }
233         end
234       end
235     end
236
237     # Now create another user with that email, but uppercased
238     create(:user, :email => user.email.upcase)
239
240     # Check that the second half of registration fails
241     assert_no_difference "User.count" do
242       assert_no_difference "ActionMailer::Base.deliveries.size" do
243         perform_enqueued_jobs do
244           post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
245         end
246       end
247     end
248
249     assert_response :success
250     assert_template "new"
251     assert_select "form > div.form-group > input.is-invalid#user_email"
252   end
253
254   def test_save_duplicate_name
255     user = build(:user, :pending)
256
257     # Set up our user as being half-way through registration
258     assert_no_difference "User.count" do
259       assert_no_difference "ActionMailer::Base.deliveries.size" do
260         perform_enqueued_jobs do
261           post user_new_path, :params => { :user => user.attributes }
262         end
263       end
264     end
265
266     # Now create another user with that display name
267     create(:user, :display_name => user.display_name)
268
269     # Check that the second half of registration fails
270     assert_no_difference "User.count" do
271       assert_no_difference "ActionMailer::Base.deliveries.size" do
272         perform_enqueued_jobs do
273           post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
274         end
275       end
276     end
277
278     assert_response :success
279     assert_template "new"
280     assert_select "form > div.form-group > input.is-invalid#user_display_name"
281   end
282
283   def test_save_duplicate_name_uppercase
284     user = build(:user, :pending)
285
286     # Set up our user as being half-way through registration
287     assert_no_difference "User.count" do
288       assert_no_difference "ActionMailer::Base.deliveries.size" do
289         perform_enqueued_jobs do
290           post user_new_path, :params => { :user => user.attributes }
291         end
292       end
293     end
294
295     # Now create another user with that display_name, but uppercased
296     create(:user, :display_name => user.display_name.upcase)
297
298     # Check that the second half of registration fails
299     assert_no_difference "User.count" do
300       assert_no_difference "ActionMailer::Base.deliveries.size" do
301         perform_enqueued_jobs do
302           post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
303         end
304       end
305     end
306
307     assert_response :success
308     assert_template "new"
309     assert_select "form > div.form-group > input.is-invalid#user_display_name"
310   end
311
312   def test_save_blocked_domain
313     user = build(:user, :pending, :email => "user@example.net")
314
315     # Set up our user as being half-way through registration
316     assert_no_difference "User.count" do
317       assert_no_difference "ActionMailer::Base.deliveries.size" do
318         perform_enqueued_jobs do
319           post user_new_path, :params => { :user => user.attributes }
320         end
321       end
322     end
323
324     # Now block that domain
325     create(:acl, :domain => "example.net", :k => "no_account_creation")
326
327     # Check that the second half of registration fails
328     assert_no_difference "User.count" do
329       assert_no_difference "ActionMailer::Base.deliveries.size" do
330         perform_enqueued_jobs do
331           post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
332         end
333       end
334     end
335
336     assert_response :success
337     assert_template "blocked"
338   end
339
340   def test_save_referer_params
341     user = build(:user, :pending)
342
343     # Set up our user as being half-way through registration
344     assert_no_difference "User.count" do
345       assert_no_difference "ActionMailer::Base.deliveries.size" do
346         perform_enqueued_jobs do
347           post user_new_path, :params => { :user => user.attributes, :referer => "/edit?editor=id#map=1/2/3" }
348         end
349       end
350     end
351
352     assert_difference "User.count", 1 do
353       assert_difference "ActionMailer::Base.deliveries.size", 1 do
354         perform_enqueued_jobs do
355           post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
356         end
357       end
358     end
359
360     assert_equal welcome_path(:editor => "id", :zoom => 1, :lat => 2, :lon => 3),
361                  User.find_by(:email => user.email).tokens.order("id DESC").first.referer
362
363     ActionMailer::Base.deliveries.clear
364   end
365
366   def test_confirm_get
367     user = build(:user, :pending)
368     post user_new_path, :params => { :user => user.attributes }
369     post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
370     confirm_string = User.find_by(:email => user.email).tokens.create.token
371
372     get user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string }
373     assert_response :success
374     assert_template :confirm
375   end
376
377   def test_confirm_get_already_confirmed
378     user = build(:user, :pending)
379     stub_gravatar_request(user.email)
380     post user_new_path, :params => { :user => user.attributes }
381     post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
382     confirm_string = User.find_by(:email => user.email).tokens.create.token
383
384     # Get the confirmation page
385     get user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string }
386     assert_response :success
387     assert_template :confirm
388
389     # Confirm the user
390     post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string }
391     assert_redirected_to welcome_path
392
393     # Now try to get the confirmation page again
394     get user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string }
395     assert_response :redirect
396     assert_redirected_to root_path
397   end
398
399   def test_confirm_success_no_token_no_referer
400     user = build(:user, :pending)
401     stub_gravatar_request(user.email)
402     post user_new_path, :params => { :user => user.attributes }
403     post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
404     confirm_string = User.find_by(:email => user.email).tokens.create.token
405
406     post logout_path
407
408     post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string }
409     assert_redirected_to login_path
410     assert_match(/Confirmed your account/, flash[:notice])
411   end
412
413   def test_confirm_success_good_token_no_referer
414     user = build(:user, :pending)
415     stub_gravatar_request(user.email)
416     post user_new_path, :params => { :user => user.attributes }
417     post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
418     confirm_string = User.find_by(:email => user.email).tokens.create.token
419
420     post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string }
421     assert_redirected_to welcome_path
422   end
423
424   def test_confirm_success_bad_token_no_referer
425     user = build(:user, :pending)
426     stub_gravatar_request(user.email)
427     post user_new_path, :params => { :user => user.attributes }
428     post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
429     confirm_string = User.find_by(:email => user.email).tokens.create.token
430
431     post logout_path
432     session_for(create(:user))
433
434     post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string }
435     assert_redirected_to login_path
436     assert_match(/Confirmed your account/, flash[:notice])
437   end
438
439   def test_confirm_success_no_token_with_referer
440     user = build(:user, :pending)
441     stub_gravatar_request(user.email)
442     post user_new_path, :params => { :user => user.attributes }
443     post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
444     confirm_string = User.find_by(:email => user.email).tokens.create(:referer => new_diary_entry_path).token
445
446     post logout_path
447
448     post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string }
449     assert_redirected_to login_path(:referer => new_diary_entry_path)
450     assert_match(/Confirmed your account/, flash[:notice])
451   end
452
453   def test_confirm_success_good_token_with_referer
454     user = build(:user, :pending)
455     stub_gravatar_request(user.email)
456     post user_new_path, :params => { :user => user.attributes }
457     post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
458     confirm_string = User.find_by(:email => user.email).tokens.create(:referer => new_diary_entry_path).token
459
460     post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string }
461     assert_redirected_to new_diary_entry_path
462   end
463
464   def test_confirm_success_bad_token_with_referer
465     user = build(:user, :pending)
466     stub_gravatar_request(user.email)
467     post user_new_path, :params => { :user => user.attributes }
468     post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
469     confirm_string = User.find_by(:email => user.email).tokens.create(:referer => new_diary_entry_path).token
470
471     post logout_path
472     session_for(create(:user))
473
474     post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string }
475     assert_redirected_to login_path(:referer => new_diary_entry_path)
476     assert_match(/Confirmed your account/, flash[:notice])
477   end
478
479   def test_confirm_expired_token
480     user = build(:user, :pending)
481     stub_gravatar_request(user.email)
482     post user_new_path, :params => { :user => user.attributes }
483     post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
484     confirm_string = User.find_by(:email => user.email).tokens.create(:expiry => 1.day.ago).token
485
486     post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string }
487     assert_redirected_to :action => "confirm"
488     assert_match(/confirmation code has expired/, flash[:error])
489   end
490
491   def test_confirm_already_confirmed
492     user = build(:user, :pending)
493     stub_gravatar_request(user.email)
494     post user_new_path, :params => { :user => user.attributes }
495     post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
496     confirm_string = User.find_by(:email => user.email).tokens.create(:referer => new_diary_entry_path).token
497
498     post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string }
499     assert_redirected_to new_diary_entry_path
500
501     post logout_path
502
503     confirm_string = User.find_by(:email => user.email).tokens.create(:referer => new_diary_entry_path).token
504     post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string }
505     assert_redirected_to login_path
506     assert_match(/already been confirmed/, flash[:error])
507   end
508
509   def test_confirm_deleted
510     user = build(:user, :pending)
511     stub_gravatar_request(user.email)
512     post user_new_path, :params => { :user => user.attributes }
513     post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
514     confirm_string = User.find_by(:email => user.email).tokens.create.token
515
516     User.find_by(:display_name => user.display_name).update(:status => "deleted")
517
518     # Get the confirmation page
519     get user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string }
520     assert_response :redirect
521     assert_redirected_to root_path
522
523     # Confirm the user
524     post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string }
525     assert_response :not_found
526     assert_template :no_such_user
527   end
528
529   def test_confirm_resend_success
530     user = build(:user, :pending)
531     post user_new_path, :params => { :user => user.attributes }
532     post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
533
534     assert_difference "ActionMailer::Base.deliveries.size", 1 do
535       perform_enqueued_jobs do
536         get user_confirm_resend_path(user)
537       end
538     end
539
540     assert_response :redirect
541     assert_redirected_to login_path
542     assert_match(/sent a new confirmation/, flash[:notice])
543
544     email = ActionMailer::Base.deliveries.last
545
546     assert_equal user.email, email.to.first
547
548     ActionMailer::Base.deliveries.clear
549   end
550
551   def test_confirm_resend_no_token
552     user = build(:user, :pending)
553     # only complete first half of registration
554     post user_new_path, :params => { :user => user.attributes }
555
556     assert_no_difference "ActionMailer::Base.deliveries.size" do
557       perform_enqueued_jobs do
558         get user_confirm_resend_path(user)
559       end
560     end
561
562     assert_response :redirect
563     assert_redirected_to login_path
564     assert_match "User #{user.display_name} not found.", flash[:error]
565   end
566
567   def test_confirm_resend_deleted
568     user = build(:user, :pending)
569     post user_new_path, :params => { :user => user.attributes }
570     post user_save_path, :params => { :read_ct => 1, :read_tou => 1 }
571
572     User.find_by(:display_name => user.display_name).update(:status => "deleted")
573
574     assert_no_difference "ActionMailer::Base.deliveries.size" do
575       perform_enqueued_jobs do
576         get user_confirm_resend_path(user)
577       end
578     end
579
580     assert_response :redirect
581     assert_redirected_to login_path
582     assert_match "User #{user.display_name} not found.", flash[:error]
583   end
584
585   def test_confirm_resend_unknown_user
586     assert_no_difference "ActionMailer::Base.deliveries.size" do
587       perform_enqueued_jobs do
588         get user_confirm_resend_path(:display_name => "No Such User")
589       end
590     end
591
592     assert_response :redirect
593     assert_redirected_to login_path
594     assert_match "User No Such User not found.", flash[:error]
595   end
596
597   def test_confirm_email_get
598     user = create(:user)
599     confirm_string = user.tokens.create.token
600
601     get user_confirm_email_path, :params => { :confirm_string => confirm_string }
602     assert_response :success
603     assert_template :confirm_email
604   end
605
606   def test_confirm_email_success
607     user = create(:user, :new_email => "test-new@example.com")
608     stub_gravatar_request(user.new_email)
609     confirm_string = user.tokens.create.token
610
611     post user_confirm_email_path, :params => { :confirm_string => confirm_string }
612     assert_response :redirect
613     assert_redirected_to :action => :account, :display_name => user.display_name
614     assert_match(/Confirmed your change of email address/, flash[:notice])
615   end
616
617   def test_confirm_email_already_confirmed
618     user = create(:user)
619     confirm_string = user.tokens.create.token
620
621     post user_confirm_email_path, :params => { :confirm_string => confirm_string }
622     assert_response :redirect
623     assert_redirected_to :action => :account, :display_name => user.display_name
624     assert_match(/already been confirmed/, flash[:error])
625   end
626
627   def test_confirm_email_bad_token
628     post user_confirm_email_path, :params => { :confirm_string => "XXXXX" }
629     assert_response :success
630     assert_template :confirm_email
631     assert_match(/confirmation code has expired or does not exist/, flash[:error])
632   end
633
634   ##
635   # test if testing for a gravatar works
636   # this happens when the email is actually changed
637   # which is triggered by the confirmation mail
638   def test_gravatar_auto_enable
639     # switch to email that has a gravatar
640     user = create(:user, :new_email => "test-new@example.com")
641     stub_gravatar_request(user.new_email, 200)
642     confirm_string = user.tokens.create.token
643     # precondition gravatar should be turned off
644     assert_not user.image_use_gravatar
645     post user_confirm_email_path, :params => { :confirm_string => confirm_string }
646     assert_response :redirect
647     assert_redirected_to :action => :account, :display_name => user.display_name
648     assert_match(/Confirmed your change of email address/, flash[:notice])
649     # gravatar use should now be enabled
650     assert User.find(user.id).image_use_gravatar
651   end
652
653   def test_gravatar_auto_disable
654     # switch to email without a gravatar
655     user = create(:user, :new_email => "test-new@example.com", :image_use_gravatar => true)
656     stub_gravatar_request(user.new_email, 404)
657     confirm_string = user.tokens.create.token
658     # precondition gravatar should be turned on
659     assert user.image_use_gravatar
660     post user_confirm_email_path, :params => { :confirm_string => confirm_string }
661     assert_response :redirect
662     assert_redirected_to :action => :account, :display_name => user.display_name
663     assert_match(/Confirmed your change of email address/, flash[:notice])
664     # gravatar use should now be disabled
665     assert_not User.find(user.id).image_use_gravatar
666   end
667
668   def test_terms_new_user
669     user = build(:user, :pending)
670
671     # Set up our user as being half-way through registration
672     assert_no_difference "User.count" do
673       assert_no_difference "ActionMailer::Base.deliveries.size" do
674         perform_enqueued_jobs do
675           post user_new_path, :params => { :user => user.attributes }
676         end
677       end
678     end
679
680     get user_terms_path
681
682     assert_response :success
683     assert_template :terms
684   end
685
686   def test_terms_agreed
687     user = create(:user, :terms_seen => true, :terms_agreed => Date.yesterday)
688
689     session_for(user)
690
691     get user_terms_path
692     assert_response :redirect
693     assert_redirected_to :action => :account, :display_name => user.display_name
694   end
695
696   def test_terms_not_seen_without_referer
697     user = create(:user, :terms_seen => false, :terms_agreed => nil)
698
699     session_for(user)
700
701     get user_terms_path
702     assert_response :success
703     assert_template :terms
704
705     post user_save_path, :params => { :user => { :consider_pd => true }, :read_ct => 1, :read_tou => 1 }
706     assert_response :redirect
707     assert_redirected_to :action => :account, :display_name => user.display_name
708     assert_equal "Thanks for accepting the new contributor terms!", flash[:notice]
709
710     user.reload
711
712     assert user.consider_pd
713     assert_not_nil user.terms_agreed
714     assert user.terms_seen
715   end
716
717   def test_terms_not_seen_with_referer
718     user = create(:user, :terms_seen => false, :terms_agreed => nil)
719
720     session_for(user)
721
722     get user_terms_path, :params => { :referer => "/test" }
723     assert_response :success
724     assert_template :terms
725
726     post user_save_path, :params => { :user => { :consider_pd => true }, :referer => "/test", :read_ct => 1, :read_tou => 1 }
727     assert_response :redirect
728     assert_redirected_to "/test"
729     assert_equal "Thanks for accepting the new contributor terms!", flash[:notice]
730
731     user.reload
732
733     assert user.consider_pd
734     assert_not_nil user.terms_agreed
735     assert user.terms_seen
736   end
737
738   # Check that if you haven't seen the terms, and make a request that requires authentication,
739   # that your request is redirected to view the terms
740   def test_terms_not_seen_redirection
741     user = create(:user, :terms_seen => false, :terms_agreed => nil)
742     session_for(user)
743
744     get user_account_path(user)
745     assert_response :redirect
746     assert_redirected_to :action => :terms, :referer => "/user/#{ERB::Util.u(user.display_name)}/account"
747   end
748
749   def test_go_public
750     user = create(:user, :data_public => false)
751     session_for(user)
752
753     post user_go_public_path
754
755     assert_response :redirect
756     assert_redirected_to :action => :account, :display_name => user.display_name
757     assert User.find(user.id).data_public
758   end
759
760   def test_account
761     # Get a user to work with - note that this user deliberately
762     # conflicts with uppercase_user in the email and display name
763     # fields to test that we can change other fields without any
764     # validation errors being reported
765     user = create(:user, :languages => [])
766     _uppercase_user = build(:user, :email => user.email.upcase, :display_name => user.display_name.upcase).tap { |u| u.save(:validate => false) }
767
768     # Make sure that you are redirected to the login page when
769     # you are not logged in
770     get user_account_path(user)
771     assert_response :redirect
772     assert_redirected_to login_path(:referer => "/user/#{ERB::Util.u(user.display_name)}/account")
773
774     # Make sure that you are blocked when not logged in as the right user
775     session_for(create(:user))
776     get user_account_path(user)
777     assert_response :forbidden
778
779     # Make sure we get the page when we are logged in as the right user
780     session_for(user)
781     get user_account_path(user)
782     assert_response :success
783     assert_template :account
784     assert_select "form#accountForm" do |form|
785       assert_equal "post", form.attr("method").to_s
786       assert_select "input[name='_method']", false
787       assert_equal "/user/#{ERB::Util.u(user.display_name)}/account", form.attr("action").to_s
788     end
789
790     # Updating the description using GET should fail
791     user.description = "new description"
792     user.preferred_editor = "default"
793     get user_account_path(user), :params => { :user => user.attributes }
794     assert_response :success
795     assert_template :account
796     assert_not_equal user.description, User.find(user.id).description
797
798     # Updating the description should work
799     user.description = "new description"
800     user.preferred_editor = "default"
801     post user_account_path(user), :params => { :user => user.attributes }
802     assert_response :redirect
803     assert_redirected_to user_account_url(user)
804     get user_account_path(user)
805     assert_response :success
806     assert_template :account
807     assert_select ".notice", /^User information updated successfully/
808     assert_select "form#accountForm > div.form-group > div#user_description_container > div#user_description_content > textarea#user_description", user.description
809
810     # Changing to a invalid editor should fail
811     user.preferred_editor = "unknown"
812     post user_account_path(user), :params => { :user => user.attributes }
813     assert_response :success
814     assert_template :account
815     assert_select ".notice", false
816     assert_select "form#accountForm > div.form-group > select#user_preferred_editor > option[selected]", false
817
818     # Changing to a valid editor should work
819     user.preferred_editor = "id"
820     post user_account_path(user), :params => { :user => user.attributes }
821     assert_response :redirect
822     assert_redirected_to user_account_url(user)
823     get user_account_path(user)
824     assert_response :success
825     assert_template :account
826     assert_select ".notice", /^User information updated successfully/
827     assert_select "form#accountForm > div.form-group > select#user_preferred_editor > option[selected][value=?]", "id"
828
829     # Changing to the default editor should work
830     user.preferred_editor = "default"
831     post user_account_path(user), :params => { :user => user.attributes }
832     assert_response :redirect
833     assert_redirected_to user_account_url(user)
834     get user_account_path(user)
835     assert_response :success
836     assert_template :account
837     assert_select ".notice", /^User information updated successfully/
838     assert_select "form#accountForm > div.form-group > select#user_preferred_editor > option[selected]", false
839
840     # Changing to an uploaded image should work
841     image = Rack::Test::UploadedFile.new("test/gpx/fixtures/a.gif", "image/gif")
842     post user_account_path(user), :params => { :avatar_action => "new", :user => user.attributes.merge(:avatar => image) }
843     assert_response :redirect
844     assert_redirected_to user_account_url(user)
845     get user_account_path(user)
846     assert_response :success
847     assert_template :account
848     assert_select ".notice", /^User information updated successfully/
849     assert_select "form#accountForm > fieldset.form-group > div.form-row > div.col-sm-10 > div.form-check > input[name=avatar_action][checked][value=?]", "keep"
850
851     # Changing to a gravatar image should work
852     post user_account_path(user), :params => { :avatar_action => "gravatar", :user => user.attributes }
853     assert_response :redirect
854     assert_redirected_to user_account_url(user)
855     get user_account_path(user)
856     assert_response :success
857     assert_template :account
858     assert_select ".notice", /^User information updated successfully/
859     assert_select "form#accountForm > fieldset.form-group > div.form-row > div.col-sm-10 > div.form-group > div.form-check > input[name=avatar_action][checked][value=?]", "gravatar"
860
861     # Removing the image should work
862     post user_account_path(user), :params => { :avatar_action => "delete", :user => user.attributes }
863     assert_response :redirect
864     assert_redirected_to user_account_url(user)
865     get user_account_path(user)
866     assert_response :success
867     assert_template :account
868     assert_select ".notice", /^User information updated successfully/
869     assert_select "form#accountForm > fieldset.form-group > div.form-row > div.col-sm-10 > div.form-check > input[name=avatar_action][checked]", false
870     assert_select "form#accountForm > fieldset.form-group > div.form-row > div.col-sm-10 > div.form-group > div.form-check > input[name=avatar_action][checked]", false
871
872     # Adding external authentication should redirect to the auth provider
873     post user_account_path(user), :params => { :user => user.attributes.merge(:auth_provider => "openid", :auth_uid => "gmail.com") }
874     assert_response :redirect
875     assert_redirected_to auth_path(:provider => "openid", :openid_url => "https://www.google.com/accounts/o8/id", :origin => "/user/#{ERB::Util.u(user.display_name)}/account")
876
877     # Changing name to one that exists should fail
878     new_attributes = user.attributes.dup.merge(:display_name => create(:user).display_name)
879     post user_account_path(user), :params => { :user => new_attributes }
880     assert_response :success
881     assert_template :account
882     assert_select ".notice", false
883     assert_select "form#accountForm > div.form-group > input.is-invalid#user_display_name"
884
885     # Changing name to one that exists should fail, regardless of case
886     new_attributes = user.attributes.dup.merge(:display_name => create(:user).display_name.upcase)
887     post user_account_path(user), :params => { :user => new_attributes }
888     assert_response :success
889     assert_template :account
890     assert_select ".notice", false
891     assert_select "form#accountForm > div.form-group > input.is-invalid#user_display_name"
892
893     # Changing name to one that doesn't exist should work
894     new_attributes = user.attributes.dup.merge(:display_name => "new tester")
895     post user_account_path(user), :params => { :user => new_attributes }
896     assert_response :redirect
897     assert_redirected_to user_account_url(:display_name => "new tester")
898     get user_account_path(:display_name => "new tester")
899     assert_response :success
900     assert_template :account
901     assert_select ".notice", /^User information updated successfully/
902     assert_select "form#accountForm > div.form-group > input#user_display_name[value=?]", "new tester"
903
904     # Record the change of name
905     user.display_name = "new tester"
906
907     # Changing email to one that exists should fail
908     user.new_email = create(:user).email
909     assert_no_difference "ActionMailer::Base.deliveries.size" do
910       perform_enqueued_jobs do
911         post user_account_path(user), :params => { :user => user.attributes }
912       end
913     end
914     assert_response :success
915     assert_template :account
916     assert_select ".notice", false
917     assert_select "form#accountForm > div.form-group > input.is-invalid#user_new_email"
918
919     # Changing email to one that exists should fail, regardless of case
920     user.new_email = create(:user).email.upcase
921     assert_no_difference "ActionMailer::Base.deliveries.size" do
922       perform_enqueued_jobs do
923         post user_account_path(user), :params => { :user => user.attributes }
924       end
925     end
926     assert_response :success
927     assert_template :account
928     assert_select ".notice", false
929     assert_select "form#accountForm > div.form-group > input.is-invalid#user_new_email"
930
931     # Changing email to one that doesn't exist should work
932     user.new_email = "new_tester@example.com"
933     assert_difference "ActionMailer::Base.deliveries.size", 1 do
934       perform_enqueued_jobs do
935         post user_account_path(user), :params => { :user => user.attributes }
936       end
937     end
938     assert_response :redirect
939     assert_redirected_to user_account_url(user)
940     get user_account_path(user)
941     assert_response :success
942     assert_template :account
943     assert_select ".notice", /^User information updated successfully/
944     assert_select "form#accountForm > div.form-group > input#user_new_email[value=?]", user.new_email
945     email = ActionMailer::Base.deliveries.first
946     assert_equal 1, email.to.count
947     assert_equal user.new_email, email.to.first
948     ActionMailer::Base.deliveries.clear
949   end
950
951   # Check that the user account page will display and contains some relevant
952   # information for the user
953   def test_show
954     # Test a non-existent user
955     get user_path(:display_name => "unknown")
956     assert_response :not_found
957
958     # Test a normal user
959     user = create(:user, :home_lon => 1.1, :home_lat => 1.1)
960     friend_user = create(:user, :home_lon => 1.2, :home_lat => 1.2)
961     create(:friendship, :befriender => user, :befriendee => friend_user)
962     create(:changeset, :user => friend_user)
963
964     get user_path(user)
965     assert_response :success
966     assert_select "div#userinformation" do
967       assert_select "a[href^='/user/#{ERB::Util.u(user.display_name)}/history']", 1
968       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/traces']", 1
969       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary']", 1
970       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary/comments']", 1
971       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/account']", 0
972       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks']", 0
973       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks_by']", 0
974       assert_select "a[href='/blocks/new/#{ERB::Util.u(user.display_name)}']", 0
975     end
976
977     # Friends shouldn't be visible as we're not logged in
978     assert_select "div#friends-container", :count => 0
979
980     # Test a user who has been blocked
981     blocked_user = create(:user)
982     create(:user_block, :user => blocked_user)
983     get user_path(blocked_user)
984     assert_response :success
985     assert_select "div#userinformation" do
986       assert_select "a[href^='/user/#{ERB::Util.u(blocked_user.display_name)}/history']", 1
987       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/traces']", 1
988       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/diary']", 1
989       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/diary/comments']", 1
990       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/account']", 0
991       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/blocks']", 1
992       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/blocks_by']", 0
993       assert_select "a[href='/blocks/new/#{ERB::Util.u(blocked_user.display_name)}']", 0
994     end
995
996     # Test a moderator who has applied blocks
997     moderator_user = create(:moderator_user)
998     create(:user_block, :creator => moderator_user)
999     get user_path(moderator_user)
1000     assert_response :success
1001     assert_select "div#userinformation" do
1002       assert_select "a[href^='/user/#{ERB::Util.u(moderator_user.display_name)}/history']", 1
1003       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/traces']", 1
1004       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/diary']", 1
1005       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/diary/comments']", 1
1006       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/account']", 0
1007       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/blocks']", 0
1008       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/blocks_by']", 1
1009       assert_select "a[href='/blocks/new/#{ERB::Util.u(moderator_user.display_name)}']", 0
1010     end
1011
1012     # Login as a normal user
1013     session_for(user)
1014
1015     # Test the normal user
1016     get user_path(user)
1017     assert_response :success
1018     assert_select "div#userinformation" do
1019       assert_select "a[href^='/user/#{ERB::Util.u(user.display_name)}/history']", 1
1020       assert_select "a[href='/traces/mine']", 1
1021       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary']", 1
1022       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary/comments']", 1
1023       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/account']", 1
1024       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks']", 0
1025       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks_by']", 0
1026       assert_select "a[href='/blocks/new/#{ERB::Util.u(user.display_name)}']", 0
1027     end
1028
1029     # Friends should be visible as we're now logged in
1030     assert_select "div#friends-container" do
1031       assert_select "div.contact-activity", :count => 1
1032     end
1033
1034     # Login as a moderator
1035     session_for(create(:moderator_user))
1036
1037     # Test the normal user
1038     get user_path(user)
1039     assert_response :success
1040     assert_select "div#userinformation" do
1041       assert_select "a[href^='/user/#{ERB::Util.u(user.display_name)}/history']", 1
1042       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/traces']", 1
1043       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary']", 1
1044       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary/comments']", 1
1045       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/account']", 0
1046       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks']", 0
1047       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks_by']", 0
1048       assert_select "a[href='/blocks/new/#{ERB::Util.u(user.display_name)}']", 1
1049     end
1050   end
1051
1052   # Test whether information about contributor terms is shown for users who haven't agreed
1053   def test_terms_not_agreed
1054     agreed_user = create(:user, :terms_agreed => 3.days.ago)
1055     seen_user = create(:user, :terms_seen => true, :terms_agreed => nil)
1056     not_seen_user = create(:user, :terms_seen => false, :terms_agreed => nil)
1057
1058     get user_path(agreed_user)
1059     assert_response :success
1060     assert_select "div#userinformation" do
1061       assert_select "p", :count => 0, :text => /Contributor terms/
1062     end
1063
1064     get user_path(seen_user)
1065     assert_response :success
1066     # put @response.body
1067     assert_select "div#userinformation" do
1068       assert_select "p", :count => 1, :text => /Contributor terms/
1069       assert_select "p", /Declined/
1070     end
1071
1072     get user_path(not_seen_user)
1073     assert_response :success
1074     assert_select "div#userinformation" do
1075       assert_select "p", :count => 1, :text => /Contributor terms/
1076       assert_select "p", /Undecided/
1077     end
1078   end
1079
1080   def test_set_status
1081     user = create(:user)
1082
1083     # Try without logging in
1084     post set_status_user_path(user), :params => { :status => "suspended" }
1085     assert_response :forbidden
1086
1087     # Now try as a normal user
1088     session_for(user)
1089     post set_status_user_path(user), :params => { :status => "suspended" }
1090     assert_response :redirect
1091     assert_redirected_to :controller => :errors, :action => :forbidden
1092
1093     # Finally try as an administrator
1094     session_for(create(:administrator_user))
1095     post set_status_user_path(user), :params => { :status => "suspended" }
1096     assert_response :redirect
1097     assert_redirected_to :action => :show, :display_name => user.display_name
1098     assert_equal "suspended", User.find(user.id).status
1099   end
1100
1101   def test_destroy
1102     user = create(:user, :home_lat => 12.1, :home_lon => 12.1, :description => "test")
1103
1104     # Try without logging in
1105     delete user_path(user), :params => { :status => "suspended" }
1106     assert_response :forbidden
1107
1108     # Now try as a normal user
1109     session_for(user)
1110     delete user_path(user), :params => { :status => "suspended" }
1111     assert_response :redirect
1112     assert_redirected_to :controller => :errors, :action => :forbidden
1113
1114     # Finally try as an administrator
1115     session_for(create(:administrator_user))
1116     delete user_path(user), :params => { :status => "suspended" }
1117     assert_response :redirect
1118     assert_redirected_to :action => :show, :display_name => user.display_name
1119
1120     # Check that the user was deleted properly
1121     user.reload
1122     assert_equal "user_#{user.id}", user.display_name
1123     assert_equal "", user.description
1124     assert_nil user.home_lat
1125     assert_nil user.home_lon
1126     assert_not user.avatar.attached?
1127     assert_not user.email_valid
1128     assert_nil user.new_email
1129     assert_nil user.auth_provider
1130     assert_nil user.auth_uid
1131     assert_equal "deleted", user.status
1132   end
1133
1134   def test_index_get
1135     user = create(:user)
1136     moderator_user = create(:moderator_user)
1137     administrator_user = create(:administrator_user)
1138     _suspended_user = create(:user, :suspended)
1139     _ip_user = create(:user, :creation_ip => "1.2.3.4")
1140
1141     # There are now 7 users - the five above, plus two extra "granters" for the
1142     # moderator_user and administrator_user
1143     assert_equal 7, User.count
1144
1145     # Shouldn't work when not logged in
1146     get users_path
1147     assert_response :redirect
1148     assert_redirected_to login_path(:referer => users_path)
1149
1150     session_for(user)
1151
1152     # Shouldn't work when logged in as a normal user
1153     get users_path
1154     assert_response :redirect
1155     assert_redirected_to :controller => :errors, :action => :forbidden
1156
1157     session_for(moderator_user)
1158
1159     # Shouldn't work when logged in as a moderator
1160     get users_path
1161     assert_response :redirect
1162     assert_redirected_to :controller => :errors, :action => :forbidden
1163
1164     session_for(administrator_user)
1165
1166     # Note there is a header row, so all row counts are users + 1
1167     # Should work when logged in as an administrator
1168     get users_path
1169     assert_response :success
1170     assert_template :index
1171     assert_select "table#user_list tr", :count => 7 + 1
1172
1173     # Should be able to limit by status
1174     get users_path, :params => { :status => "suspended" }
1175     assert_response :success
1176     assert_template :index
1177     assert_select "table#user_list tr", :count => 1 + 1
1178
1179     # Should be able to limit by IP address
1180     get users_path, :params => { :ip => "1.2.3.4" }
1181     assert_response :success
1182     assert_template :index
1183     assert_select "table#user_list tr", :count => 1 + 1
1184   end
1185
1186   def test_index_get_paginated
1187     1.upto(100).each do |n|
1188       User.create(:display_name => "extra_#{n}",
1189                   :email => "extra#{n}@example.com",
1190                   :pass_crypt => "extraextra")
1191     end
1192
1193     session_for(create(:administrator_user))
1194
1195     # 100 examples, an administrator, and a granter for the admin.
1196     assert_equal 102, User.count
1197
1198     get users_path
1199     assert_response :success
1200     assert_template :index
1201     assert_select "table#user_list tr", :count => 51
1202
1203     get users_path, :params => { :page => 2 }
1204     assert_response :success
1205     assert_template :index
1206     assert_select "table#user_list tr", :count => 51
1207
1208     get users_path, :params => { :page => 3 }
1209     assert_response :success
1210     assert_template :index
1211     assert_select "table#user_list tr", :count => 3
1212   end
1213
1214   def test_index_post_confirm
1215     inactive_user = create(:user, :pending)
1216     suspended_user = create(:user, :suspended)
1217
1218     # Shouldn't work when not logged in
1219     assert_no_difference "User.active.count" do
1220       post users_path, :params => { :confirm => 1, :user => { inactive_user.id => 1, suspended_user.id => 1 } }
1221     end
1222     assert_response :forbidden
1223
1224     assert_equal "pending", inactive_user.reload.status
1225     assert_equal "suspended", suspended_user.reload.status
1226
1227     session_for(create(:user))
1228
1229     # Shouldn't work when logged in as a normal user
1230     assert_no_difference "User.active.count" do
1231       post users_path, :params => { :confirm => 1, :user => { inactive_user.id => 1, suspended_user.id => 1 } }
1232     end
1233     assert_response :redirect
1234     assert_redirected_to :controller => :errors, :action => :forbidden
1235     assert_equal "pending", inactive_user.reload.status
1236     assert_equal "suspended", suspended_user.reload.status
1237
1238     session_for(create(:moderator_user))
1239
1240     # Shouldn't work when logged in as a moderator
1241     assert_no_difference "User.active.count" do
1242       post users_path, :params => { :confirm => 1, :user => { inactive_user.id => 1, suspended_user.id => 1 } }
1243     end
1244     assert_response :redirect
1245     assert_redirected_to :controller => :errors, :action => :forbidden
1246     assert_equal "pending", inactive_user.reload.status
1247     assert_equal "suspended", suspended_user.reload.status
1248
1249     session_for(create(:administrator_user))
1250
1251     # Should work when logged in as an administrator
1252     assert_difference "User.active.count", 2 do
1253       post users_path, :params => { :confirm => 1, :user => { inactive_user.id => 1, suspended_user.id => 1 } }
1254     end
1255     assert_response :redirect
1256     assert_redirected_to :action => :index
1257     assert_equal "confirmed", inactive_user.reload.status
1258     assert_equal "confirmed", suspended_user.reload.status
1259   end
1260
1261   def test_index_post_hide
1262     normal_user = create(:user)
1263     confirmed_user = create(:user, :confirmed)
1264
1265     # Shouldn't work when not logged in
1266     assert_no_difference "User.active.count" do
1267       post users_path, :params => { :hide => 1, :user => { normal_user.id => 1, confirmed_user.id => 1 } }
1268     end
1269     assert_response :forbidden
1270
1271     assert_equal "active", normal_user.reload.status
1272     assert_equal "confirmed", confirmed_user.reload.status
1273
1274     session_for(create(:user))
1275
1276     # Shouldn't work when logged in as a normal user
1277     assert_no_difference "User.active.count" do
1278       post users_path, :params => { :hide => 1, :user => { normal_user.id => 1, confirmed_user.id => 1 } }
1279     end
1280     assert_response :redirect
1281     assert_redirected_to :controller => :errors, :action => :forbidden
1282     assert_equal "active", normal_user.reload.status
1283     assert_equal "confirmed", confirmed_user.reload.status
1284
1285     session_for(create(:moderator_user))
1286
1287     # Shouldn't work when logged in as a moderator
1288     assert_no_difference "User.active.count" do
1289       post users_path, :params => { :hide => 1, :user => { normal_user.id => 1, confirmed_user.id => 1 } }
1290     end
1291     assert_response :redirect
1292     assert_redirected_to :controller => :errors, :action => :forbidden
1293     assert_equal "active", normal_user.reload.status
1294     assert_equal "confirmed", confirmed_user.reload.status
1295
1296     session_for(create(:administrator_user))
1297
1298     # Should work when logged in as an administrator
1299     assert_difference "User.active.count", -2 do
1300       post users_path, :params => { :hide => 1, :user => { normal_user.id => 1, confirmed_user.id => 1 } }
1301     end
1302     assert_response :redirect
1303     assert_redirected_to :action => :index
1304     assert_equal "deleted", normal_user.reload.status
1305     assert_equal "deleted", confirmed_user.reload.status
1306   end
1307 end