]> git.openstreetmap.org Git - rails.git/blob - test/controllers/users_controller_test.rb
Merge remote-tracking branch 'upstream/pull/5276'
[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/go_public", :method => :post },
29       { :controller => "users", :action => "go_public" }
30     )
31
32     assert_routing(
33       { :path => "/user/suspended", :method => :get },
34       { :controller => "users", :action => "suspended" }
35     )
36
37     assert_routing(
38       { :path => "/user/username", :method => :get },
39       { :controller => "users", :action => "show", :display_name => "username" }
40     )
41
42     assert_routing(
43       { :path => "/user/username/set_status", :method => :post },
44       { :controller => "users", :action => "set_status", :display_name => "username" }
45     )
46     assert_routing(
47       { :path => "/user/username", :method => :delete },
48       { :controller => "users", :action => "destroy", :display_name => "username" }
49     )
50
51     assert_routing(
52       { :path => "/users", :method => :get },
53       { :controller => "users", :action => "index" }
54     )
55     assert_routing(
56       { :path => "/users", :method => :post },
57       { :controller => "users", :action => "index" }
58     )
59     assert_routing(
60       { :path => "/users/status", :method => :get },
61       { :controller => "users", :action => "index", :status => "status" }
62     )
63     assert_routing(
64       { :path => "/users/status", :method => :post },
65       { :controller => "users", :action => "index", :status => "status" }
66     )
67   end
68
69   # The user creation page loads
70   def test_new_view
71     get user_new_path
72     assert_redirected_to user_new_path(:cookie_test => "true")
73
74     get user_new_path, :params => { :cookie_test => "true" }
75     assert_response :success
76
77     assert_select "html", :count => 1 do
78       assert_select "head", :count => 1 do
79         assert_select "title", :text => /Sign Up/, :count => 1
80       end
81       assert_select "body", :count => 1 do
82         assert_select "div#content", :count => 1 do
83           assert_select "form[action='/user/new'][method='post']", :count => 1 do
84             assert_select "input[id='user_email']", :count => 1
85             assert_select "input[id='user_display_name']", :count => 1
86             assert_select "input[id='user_pass_crypt'][type='password']", :count => 1
87             assert_select "input[id='user_pass_crypt_confirmation'][type='password']", :count => 1
88             assert_select "input[type='submit'][value='Sign Up']", :count => 1
89           end
90         end
91       end
92     end
93   end
94
95   def test_new_view_logged_in
96     session_for(create(:user))
97
98     get user_new_path
99     assert_redirected_to root_path
100
101     get user_new_path, :params => { :referer => "/test" }
102     assert_redirected_to "/test"
103   end
104
105   def test_new_success
106     user = build(:user, :pending)
107
108     assert_difference "User.count", 1 do
109       assert_difference "ActionMailer::Base.deliveries.size", 1 do
110         perform_enqueued_jobs do
111           post user_new_path, :params => { :user => user.attributes }
112         end
113       end
114     end
115
116     # Check the e-mail
117     register_email = ActionMailer::Base.deliveries.first
118
119     assert_equal register_email.to[0], user.email
120     assert_match(/#{@url}/, register_email.body.to_s)
121
122     # Check the page
123     assert_redirected_to :controller => :confirmations, :action => :confirm, :display_name => user.display_name
124
125     ActionMailer::Base.deliveries.clear
126   end
127
128   def test_new_duplicate_email
129     user = build(:user, :pending)
130     create(:user, :email => user.email)
131
132     assert_no_difference "User.count" do
133       assert_no_difference "ActionMailer::Base.deliveries.size" do
134         perform_enqueued_jobs do
135           post user_new_path, :params => { :user => user.attributes }
136         end
137       end
138     end
139
140     assert_response :success
141     assert_template "new"
142     assert_select "form > div > input.is-invalid#user_email"
143   end
144
145   def test_new_duplicate_email_uppercase
146     user = build(:user, :pending)
147     create(:user, :email => user.email.upcase)
148
149     assert_no_difference "User.count" do
150       assert_no_difference "ActionMailer::Base.deliveries.size" do
151         perform_enqueued_jobs do
152           post user_new_path, :params => { :user => user.attributes }
153         end
154       end
155     end
156
157     assert_response :success
158     assert_template "new"
159     assert_select "form > div > input.is-invalid#user_email"
160   end
161
162   def test_new_duplicate_name
163     user = build(:user, :pending)
164     create(:user, :display_name => user.display_name)
165
166     assert_no_difference "User.count" do
167       assert_no_difference "ActionMailer::Base.deliveries.size" do
168         perform_enqueued_jobs do
169           post user_new_path, :params => { :user => user.attributes }
170         end
171       end
172     end
173
174     assert_response :success
175     assert_template "new"
176     assert_select "form > div > input.is-invalid#user_display_name"
177   end
178
179   def test_new_duplicate_name_uppercase
180     user = build(:user, :pending)
181     create(:user, :display_name => user.display_name.upcase)
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 > input.is-invalid#user_display_name"
194   end
195
196   def test_new_blocked_domain
197     user = build(:user, :pending, :email => "user@example.net")
198
199     # Now block that domain
200     create(:acl, :domain => "example.net", :k => "no_account_creation")
201
202     # Check that the second half of registration fails
203     assert_no_difference "User.count" do
204       assert_no_difference "ActionMailer::Base.deliveries.size" do
205         perform_enqueued_jobs do
206           post user_new_path, :params => { :user => user.attributes }
207         end
208       end
209     end
210
211     assert_response :success
212     assert_template "blocked"
213   end
214
215   def test_save_referer_params
216     user = build(:user, :pending)
217
218     assert_difference "User.count", 1 do
219       assert_difference "ActionMailer::Base.deliveries.size", 1 do
220         post user_new_path, :params => { :user => user.attributes, :referer => "/edit?editor=id#map=1/2/3" }
221         assert_enqueued_with :job => ActionMailer::MailDeliveryJob,
222                              :args => proc { |args| args[3][:args][2] == welcome_path(:editor => "id", :zoom => 1, :lat => 2, :lon => 3) }
223         perform_enqueued_jobs
224       end
225     end
226
227     ActionMailer::Base.deliveries.clear
228   end
229
230   def test_terms_agreed
231     user = create(:user, :terms_seen => true, :terms_agreed => Date.yesterday)
232
233     session_for(user)
234
235     get user_terms_path
236     assert_redirected_to edit_account_path
237   end
238
239   def test_terms_not_seen_without_referer
240     user = create(:user, :terms_seen => false, :terms_agreed => nil)
241
242     session_for(user)
243
244     get user_terms_path
245     assert_response :success
246     assert_template :terms
247
248     post user_save_path, :params => { :user => { :consider_pd => true }, :read_ct => 1, :read_tou => 1 }
249     assert_redirected_to edit_account_path
250     assert_equal "Thanks for accepting the new contributor terms!", flash[:notice]
251
252     user.reload
253
254     assert user.consider_pd
255     assert_not_nil user.terms_agreed
256     assert user.terms_seen
257   end
258
259   def test_terms_not_seen_with_referer
260     user = create(:user, :terms_seen => false, :terms_agreed => nil)
261
262     session_for(user)
263
264     get user_terms_path, :params => { :referer => "/test" }
265     assert_response :success
266     assert_template :terms
267
268     post user_save_path, :params => { :user => { :consider_pd => true }, :referer => "/test", :read_ct => 1, :read_tou => 1 }
269     assert_redirected_to "/test"
270     assert_equal "Thanks for accepting the new contributor terms!", flash[:notice]
271
272     user.reload
273
274     assert user.consider_pd
275     assert_not_nil user.terms_agreed
276     assert user.terms_seen
277   end
278
279   # Check that if you haven't seen the terms, and make a request that requires authentication,
280   # that your request is redirected to view the terms
281   def test_terms_not_seen_redirection
282     user = create(:user, :terms_seen => false, :terms_agreed => nil)
283     session_for(user)
284
285     get edit_account_path
286     assert_redirected_to :controller => :users, :action => :terms, :referer => "/account/edit"
287   end
288
289   def test_terms_not_logged_in
290     get user_terms_path
291
292     assert_redirected_to login_path(:referer => "/user/terms")
293   end
294
295   def test_go_public
296     user = create(:user, :data_public => false)
297     session_for(user)
298
299     post user_go_public_path
300
301     assert_redirected_to edit_account_path
302     assert User.find(user.id).data_public
303   end
304
305   # Check that the user account page will display and contains some relevant
306   # information for the user
307   def test_show
308     # Test a non-existent user
309     get user_path("unknown")
310     assert_response :not_found
311
312     # Test a normal user
313     user = create(:user)
314
315     get user_path(user)
316     assert_response :success
317     assert_select "div.content-heading" do
318       assert_select "a[href^='/user/#{ERB::Util.u(user.display_name)}/history']", 1
319       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/traces']", 1
320       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary']", 1
321       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary/comments']", 1
322       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/account']", 0
323       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks']", 0
324       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks_by']", 0
325       assert_select "a[href='/blocks/new/#{ERB::Util.u(user.display_name)}']", 0
326     end
327
328     # Test a user who has been blocked
329     blocked_user = create(:user)
330     create(:user_block, :user => blocked_user)
331     get user_path(blocked_user)
332     assert_response :success
333     assert_select "div.content-heading" do
334       assert_select "a[href^='/user/#{ERB::Util.u(blocked_user.display_name)}/history']", 1
335       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/traces']", 1
336       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/diary']", 1
337       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/diary/comments']", 1
338       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/account']", 0
339       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/blocks']", 1
340       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/blocks_by']", 0
341       assert_select "a[href='/blocks/new/#{ERB::Util.u(blocked_user.display_name)}']", 0
342     end
343
344     # Test a moderator who has applied blocks
345     moderator_user = create(:moderator_user)
346     create(:user_block, :creator => moderator_user)
347     get user_path(moderator_user)
348     assert_response :success
349     assert_select "div.content-heading" do
350       assert_select "a[href^='/user/#{ERB::Util.u(moderator_user.display_name)}/history']", 1
351       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/traces']", 1
352       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/diary']", 1
353       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/diary/comments']", 1
354       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/account']", 0
355       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/blocks']", 0
356       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/blocks_by']", 1
357       assert_select "a[href='/blocks/new/#{ERB::Util.u(moderator_user.display_name)}']", 0
358     end
359
360     # Login as a normal user
361     session_for(user)
362
363     # Test the normal user
364     get user_path(user)
365     assert_response :success
366     assert_select "div.content-heading" do
367       assert_select "a[href^='/user/#{ERB::Util.u(user.display_name)}/history']", 1
368       assert_select "a[href='/traces/mine']", 1
369       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary']", 1
370       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary/comments']", 1
371       assert_select "a[href='/account/edit']", 1
372       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks']", 0
373       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks_by']", 0
374       assert_select "a[href='/blocks/new/#{ERB::Util.u(user.display_name)}']", 0
375       assert_select "a[href='/api/0.6/user/#{ERB::Util.u(user.id)}']", 0
376     end
377
378     # Login as a moderator
379     session_for(create(:moderator_user))
380
381     # Test the normal user
382     get user_path(user)
383     assert_response :success
384     assert_select "div.content-heading" do
385       assert_select "a[href^='/user/#{ERB::Util.u(user.display_name)}/history']", 1
386       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/traces']", 1
387       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary']", 1
388       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary/comments']", 1
389       assert_select "a[href='/account/edit']", 0
390       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks']", 0
391       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks_by']", 0
392       assert_select "a[href='/blocks/new/#{ERB::Util.u(user.display_name)}']", 1
393       assert_select "a[href='/api/0.6/user/#{ERB::Util.u(user.id)}']", 1
394     end
395   end
396
397   # Test whether information about contributor terms is shown for users who haven't agreed
398   def test_terms_not_agreed
399     agreed_user = create(:user, :terms_agreed => 3.days.ago)
400     seen_user = create(:user, :terms_seen => true, :terms_agreed => nil)
401     not_seen_user = create(:user, :terms_seen => false, :terms_agreed => nil)
402
403     get user_path(agreed_user)
404     assert_response :success
405     assert_select "div.content-heading" do
406       assert_select "dt", :count => 0, :text => /Contributor terms/
407     end
408
409     get user_path(seen_user)
410     assert_response :success
411     assert_select "div.content-heading" do
412       assert_select "dt", :count => 1, :text => /Contributor terms/
413       assert_select "dd", /Declined/
414     end
415
416     get user_path(not_seen_user)
417     assert_response :success
418     assert_select "div.content-heading" do
419       assert_select "dt", :count => 1, :text => /Contributor terms/
420       assert_select "dd", /Undecided/
421     end
422   end
423
424   def test_set_status
425     user = create(:user)
426
427     # Try without logging in
428     post set_status_user_path(user), :params => { :event => "confirm" }
429     assert_response :forbidden
430
431     # Now try as a normal user
432     session_for(user)
433     post set_status_user_path(user), :params => { :event => "confirm" }
434     assert_redirected_to :controller => :errors, :action => :forbidden
435
436     # Finally try as an administrator
437     session_for(create(:administrator_user))
438     post set_status_user_path(user), :params => { :event => "confirm" }
439     assert_redirected_to :action => :show, :display_name => user.display_name
440     assert_equal "confirmed", User.find(user.id).status
441   end
442
443   def test_destroy
444     user = create(:user, :home_lat => 12.1, :home_lon => 12.1, :description => "test")
445
446     # Try without logging in
447     delete user_path(user)
448     assert_response :forbidden
449
450     # Now try as a normal user
451     session_for(user)
452     delete user_path(user)
453     assert_redirected_to :controller => :errors, :action => :forbidden
454
455     # Finally try as an administrator
456     session_for(create(:administrator_user))
457     delete user_path(user)
458     assert_redirected_to :action => :show, :display_name => user.display_name
459
460     # Check that the user was deleted properly
461     user.reload
462     assert_equal "user_#{user.id}", user.display_name
463     assert_equal "", user.description
464     assert_nil user.home_lat
465     assert_nil user.home_lon
466     assert_not user.avatar.attached?
467     assert_not user.email_valid
468     assert_nil user.new_email
469     assert_nil user.auth_provider
470     assert_nil user.auth_uid
471     assert_equal "deleted", user.status
472   end
473
474   def test_index_get
475     user = create(:user)
476     moderator_user = create(:moderator_user)
477     administrator_user = create(:administrator_user)
478     _suspended_user = create(:user, :suspended)
479     _ip_user = create(:user, :creation_address => "1.2.3.4")
480
481     # There are now 7 users - the five above, plus two extra "granters" for the
482     # moderator_user and administrator_user
483     assert_equal 7, User.count
484
485     # Shouldn't work when not logged in
486     get users_path
487     assert_redirected_to login_path(:referer => users_path)
488
489     session_for(user)
490
491     # Shouldn't work when logged in as a normal user
492     get users_path
493     assert_redirected_to :controller => :errors, :action => :forbidden
494
495     session_for(moderator_user)
496
497     # Shouldn't work when logged in as a moderator
498     get users_path
499     assert_redirected_to :controller => :errors, :action => :forbidden
500
501     session_for(administrator_user)
502
503     # Note there is a header row, so all row counts are users + 1
504     # Should work when logged in as an administrator
505     get users_path
506     assert_response :success
507     assert_template :index
508     assert_select "table#user_list tbody tr", :count => 7
509
510     # Should be able to limit by status
511     get users_path, :params => { :status => "suspended" }
512     assert_response :success
513     assert_template :index
514     assert_select "table#user_list tbody tr", :count => 1
515
516     # Should be able to limit by IP address
517     get users_path, :params => { :ip => "1.2.3.4" }
518     assert_response :success
519     assert_template :index
520     assert_select "table#user_list tbody tr", :count => 1
521   end
522
523   def test_index_get_paginated
524     1.upto(100).each do |n|
525       User.create(:display_name => "extra_#{n}",
526                   :email => "extra#{n}@example.com",
527                   :pass_crypt => "extraextra")
528     end
529
530     session_for(create(:administrator_user))
531
532     # 100 examples, an administrator, and a granter for the admin.
533     assert_equal 102, User.count
534     next_path = users_path
535
536     get next_path
537     assert_response :success
538     assert_template :index
539     assert_select "table#user_list tbody tr", :count => 50
540     check_no_page_link "Newer Users"
541     next_path = check_page_link "Older Users"
542
543     get next_path
544     assert_response :success
545     assert_template :index
546     assert_select "table#user_list tbody tr", :count => 50
547     check_page_link "Newer Users"
548     next_path = check_page_link "Older Users"
549
550     get next_path
551     assert_response :success
552     assert_template :index
553     assert_select "table#user_list tbody tr", :count => 2
554     check_page_link "Newer Users"
555     check_no_page_link "Older Users"
556   end
557
558   def test_index_get_invalid_paginated
559     session_for(create(:administrator_user))
560
561     %w[-1 0 fred].each do |id|
562       get users_path(:before => id)
563       assert_redirected_to :controller => :errors, :action => :bad_request
564
565       get users_path(:after => id)
566       assert_redirected_to :controller => :errors, :action => :bad_request
567     end
568   end
569
570   private
571
572   def check_no_page_link(name)
573     assert_select "a.page-link", { :text => /#{Regexp.quote(name)}/, :count => 0 }, "unexpected #{name} page link"
574   end
575
576   def check_page_link(name)
577     assert_select "a.page-link", { :text => /#{Regexp.quote(name)}/ }, "missing #{name} page link" do |buttons|
578       return buttons.first.attributes["href"].value
579     end
580   end
581
582   public
583
584   def test_index_post_confirm
585     inactive_user = create(:user, :pending)
586     suspended_user = create(:user, :suspended)
587
588     # Shouldn't work when not logged in
589     assert_no_difference "User.active.count" do
590       post users_path, :params => { :confirm => 1, :user => { inactive_user.id => 1, suspended_user.id => 1 } }
591     end
592     assert_response :forbidden
593
594     assert_equal "pending", inactive_user.reload.status
595     assert_equal "suspended", suspended_user.reload.status
596
597     session_for(create(:user))
598
599     # Shouldn't work when logged in as a normal user
600     assert_no_difference "User.active.count" do
601       post users_path, :params => { :confirm => 1, :user => { inactive_user.id => 1, suspended_user.id => 1 } }
602     end
603     assert_redirected_to :controller => :errors, :action => :forbidden
604     assert_equal "pending", inactive_user.reload.status
605     assert_equal "suspended", suspended_user.reload.status
606
607     session_for(create(:moderator_user))
608
609     # Shouldn't work when logged in as a moderator
610     assert_no_difference "User.active.count" do
611       post users_path, :params => { :confirm => 1, :user => { inactive_user.id => 1, suspended_user.id => 1 } }
612     end
613     assert_redirected_to :controller => :errors, :action => :forbidden
614     assert_equal "pending", inactive_user.reload.status
615     assert_equal "suspended", suspended_user.reload.status
616
617     session_for(create(:administrator_user))
618
619     # Should work when logged in as an administrator
620     assert_difference "User.active.count", 2 do
621       post users_path, :params => { :confirm => 1, :user => { inactive_user.id => 1, suspended_user.id => 1 } }
622     end
623     assert_redirected_to :action => :index
624     assert_equal "confirmed", inactive_user.reload.status
625     assert_equal "confirmed", suspended_user.reload.status
626   end
627
628   def test_index_post_hide
629     normal_user = create(:user)
630     confirmed_user = create(:user, :confirmed)
631
632     # Shouldn't work when not logged in
633     assert_no_difference "User.active.count" do
634       post users_path, :params => { :hide => 1, :user => { normal_user.id => 1, confirmed_user.id => 1 } }
635     end
636     assert_response :forbidden
637
638     assert_equal "active", normal_user.reload.status
639     assert_equal "confirmed", confirmed_user.reload.status
640
641     session_for(create(:user))
642
643     # Shouldn't work when logged in as a normal user
644     assert_no_difference "User.active.count" do
645       post users_path, :params => { :hide => 1, :user => { normal_user.id => 1, confirmed_user.id => 1 } }
646     end
647     assert_redirected_to :controller => :errors, :action => :forbidden
648     assert_equal "active", normal_user.reload.status
649     assert_equal "confirmed", confirmed_user.reload.status
650
651     session_for(create(:moderator_user))
652
653     # Shouldn't work when logged in as a moderator
654     assert_no_difference "User.active.count" do
655       post users_path, :params => { :hide => 1, :user => { normal_user.id => 1, confirmed_user.id => 1 } }
656     end
657     assert_redirected_to :controller => :errors, :action => :forbidden
658     assert_equal "active", normal_user.reload.status
659     assert_equal "confirmed", confirmed_user.reload.status
660
661     session_for(create(:administrator_user))
662
663     # Should work when logged in as an administrator
664     assert_difference "User.active.count", -2 do
665       post users_path, :params => { :hide => 1, :user => { normal_user.id => 1, confirmed_user.id => 1 } }
666     end
667     assert_redirected_to :action => :index
668     assert_equal "deleted", normal_user.reload.status
669     assert_equal "deleted", confirmed_user.reload.status
670   end
671
672   def test_auth_failure_callback
673     get auth_failure_path
674     assert_redirected_to login_path
675
676     get auth_failure_path, :params => { :origin => "/" }
677     assert_redirected_to root_path
678
679     get auth_failure_path, :params => { :origin => "http://www.google.com" }
680     assert_redirected_to login_path
681   end
682 end