]> git.openstreetmap.org Git - rails.git/blob - test/controllers/users_controller_test.rb
Merge pull request #4922 from tomhughes/geocoder-urls
[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     # Friends shouldn't be visible as we're not logged in
329     assert_select "div#friends-container", :count => 0
330
331     # Test a user who has been blocked
332     blocked_user = create(:user)
333     create(:user_block, :user => blocked_user)
334     get user_path(blocked_user)
335     assert_response :success
336     assert_select "div.content-heading" do
337       assert_select "a[href^='/user/#{ERB::Util.u(blocked_user.display_name)}/history']", 1
338       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/traces']", 1
339       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/diary']", 1
340       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/diary/comments']", 1
341       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/account']", 0
342       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/blocks']", 1
343       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/blocks_by']", 0
344       assert_select "a[href='/blocks/new/#{ERB::Util.u(blocked_user.display_name)}']", 0
345     end
346
347     # Test a moderator who has applied blocks
348     moderator_user = create(:moderator_user)
349     create(:user_block, :creator => moderator_user)
350     get user_path(moderator_user)
351     assert_response :success
352     assert_select "div.content-heading" do
353       assert_select "a[href^='/user/#{ERB::Util.u(moderator_user.display_name)}/history']", 1
354       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/traces']", 1
355       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/diary']", 1
356       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/diary/comments']", 1
357       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/account']", 0
358       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/blocks']", 0
359       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/blocks_by']", 1
360       assert_select "a[href='/blocks/new/#{ERB::Util.u(moderator_user.display_name)}']", 0
361     end
362
363     # Login as a normal user
364     session_for(user)
365
366     # Test the normal user
367     get user_path(user)
368     assert_response :success
369     assert_select "div.content-heading" do
370       assert_select "a[href^='/user/#{ERB::Util.u(user.display_name)}/history']", 1
371       assert_select "a[href='/traces/mine']", 1
372       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary']", 1
373       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary/comments']", 1
374       assert_select "a[href='/account/edit']", 1
375       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks']", 0
376       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks_by']", 0
377       assert_select "a[href='/blocks/new/#{ERB::Util.u(user.display_name)}']", 0
378       assert_select "a[href='/api/0.6/user/#{ERB::Util.u(user.id)}']", 0
379     end
380
381     # Login as a moderator
382     session_for(create(:moderator_user))
383
384     # Test the normal user
385     get user_path(user)
386     assert_response :success
387     assert_select "div.content-heading" do
388       assert_select "a[href^='/user/#{ERB::Util.u(user.display_name)}/history']", 1
389       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/traces']", 1
390       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary']", 1
391       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary/comments']", 1
392       assert_select "a[href='/account/edit']", 0
393       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks']", 0
394       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks_by']", 0
395       assert_select "a[href='/blocks/new/#{ERB::Util.u(user.display_name)}']", 1
396       assert_select "a[href='/api/0.6/user/#{ERB::Util.u(user.id)}']", 1
397     end
398   end
399
400   # Test whether information about contributor terms is shown for users who haven't agreed
401   def test_terms_not_agreed
402     agreed_user = create(:user, :terms_agreed => 3.days.ago)
403     seen_user = create(:user, :terms_seen => true, :terms_agreed => nil)
404     not_seen_user = create(:user, :terms_seen => false, :terms_agreed => nil)
405
406     get user_path(agreed_user)
407     assert_response :success
408     assert_select "div.content-heading" do
409       assert_select "dt", :count => 0, :text => /Contributor terms/
410     end
411
412     get user_path(seen_user)
413     assert_response :success
414     assert_select "div.content-heading" do
415       assert_select "dt", :count => 1, :text => /Contributor terms/
416       assert_select "dd", /Declined/
417     end
418
419     get user_path(not_seen_user)
420     assert_response :success
421     assert_select "div.content-heading" do
422       assert_select "dt", :count => 1, :text => /Contributor terms/
423       assert_select "dd", /Undecided/
424     end
425   end
426
427   def test_set_status
428     user = create(:user)
429
430     # Try without logging in
431     post set_status_user_path(user), :params => { :event => "confirm" }
432     assert_response :forbidden
433
434     # Now try as a normal user
435     session_for(user)
436     post set_status_user_path(user), :params => { :event => "confirm" }
437     assert_redirected_to :controller => :errors, :action => :forbidden
438
439     # Finally try as an administrator
440     session_for(create(:administrator_user))
441     post set_status_user_path(user), :params => { :event => "confirm" }
442     assert_redirected_to :action => :show, :display_name => user.display_name
443     assert_equal "confirmed", User.find(user.id).status
444   end
445
446   def test_destroy
447     user = create(:user, :home_lat => 12.1, :home_lon => 12.1, :description => "test")
448
449     # Try without logging in
450     delete user_path(user)
451     assert_response :forbidden
452
453     # Now try as a normal user
454     session_for(user)
455     delete user_path(user)
456     assert_redirected_to :controller => :errors, :action => :forbidden
457
458     # Finally try as an administrator
459     session_for(create(:administrator_user))
460     delete user_path(user)
461     assert_redirected_to :action => :show, :display_name => user.display_name
462
463     # Check that the user was deleted properly
464     user.reload
465     assert_equal "user_#{user.id}", user.display_name
466     assert_equal "", user.description
467     assert_nil user.home_lat
468     assert_nil user.home_lon
469     assert_not user.avatar.attached?
470     assert_not user.email_valid
471     assert_nil user.new_email
472     assert_nil user.auth_provider
473     assert_nil user.auth_uid
474     assert_equal "deleted", user.status
475   end
476
477   def test_index_get
478     user = create(:user)
479     moderator_user = create(:moderator_user)
480     administrator_user = create(:administrator_user)
481     _suspended_user = create(:user, :suspended)
482     _ip_user = create(:user, :creation_ip => "1.2.3.4")
483
484     # There are now 7 users - the five above, plus two extra "granters" for the
485     # moderator_user and administrator_user
486     assert_equal 7, User.count
487
488     # Shouldn't work when not logged in
489     get users_path
490     assert_redirected_to login_path(:referer => users_path)
491
492     session_for(user)
493
494     # Shouldn't work when logged in as a normal user
495     get users_path
496     assert_redirected_to :controller => :errors, :action => :forbidden
497
498     session_for(moderator_user)
499
500     # Shouldn't work when logged in as a moderator
501     get users_path
502     assert_redirected_to :controller => :errors, :action => :forbidden
503
504     session_for(administrator_user)
505
506     # Note there is a header row, so all row counts are users + 1
507     # Should work when logged in as an administrator
508     get users_path
509     assert_response :success
510     assert_template :index
511     assert_select "table#user_list tbody tr", :count => 7
512
513     # Should be able to limit by status
514     get users_path, :params => { :status => "suspended" }
515     assert_response :success
516     assert_template :index
517     assert_select "table#user_list tbody tr", :count => 1
518
519     # Should be able to limit by IP address
520     get users_path, :params => { :ip => "1.2.3.4" }
521     assert_response :success
522     assert_template :index
523     assert_select "table#user_list tbody tr", :count => 1
524   end
525
526   def test_index_get_paginated
527     1.upto(100).each do |n|
528       User.create(:display_name => "extra_#{n}",
529                   :email => "extra#{n}@example.com",
530                   :pass_crypt => "extraextra")
531     end
532
533     session_for(create(:administrator_user))
534
535     # 100 examples, an administrator, and a granter for the admin.
536     assert_equal 102, User.count
537     next_path = users_path
538
539     get next_path
540     assert_response :success
541     assert_template :index
542     assert_select "table#user_list tbody tr", :count => 50
543     check_no_page_link "Newer Users"
544     next_path = check_page_link "Older Users"
545
546     get next_path
547     assert_response :success
548     assert_template :index
549     assert_select "table#user_list tbody tr", :count => 50
550     check_page_link "Newer Users"
551     next_path = check_page_link "Older Users"
552
553     get next_path
554     assert_response :success
555     assert_template :index
556     assert_select "table#user_list tbody tr", :count => 2
557     check_page_link "Newer Users"
558     check_no_page_link "Older Users"
559   end
560
561   def test_index_get_invalid_paginated
562     session_for(create(:administrator_user))
563
564     %w[-1 0 fred].each do |id|
565       get users_path(:before => id)
566       assert_redirected_to :controller => :errors, :action => :bad_request
567
568       get users_path(:after => id)
569       assert_redirected_to :controller => :errors, :action => :bad_request
570     end
571   end
572
573   private
574
575   def check_no_page_link(name)
576     assert_select "a.page-link", { :text => /#{Regexp.quote(name)}/, :count => 0 }, "unexpected #{name} page link"
577   end
578
579   def check_page_link(name)
580     assert_select "a.page-link", { :text => /#{Regexp.quote(name)}/ }, "missing #{name} page link" do |buttons|
581       return buttons.first.attributes["href"].value
582     end
583   end
584
585   public
586
587   def test_index_post_confirm
588     inactive_user = create(:user, :pending)
589     suspended_user = create(:user, :suspended)
590
591     # Shouldn't work when not logged in
592     assert_no_difference "User.active.count" do
593       post users_path, :params => { :confirm => 1, :user => { inactive_user.id => 1, suspended_user.id => 1 } }
594     end
595     assert_response :forbidden
596
597     assert_equal "pending", inactive_user.reload.status
598     assert_equal "suspended", suspended_user.reload.status
599
600     session_for(create(:user))
601
602     # Shouldn't work when logged in as a normal user
603     assert_no_difference "User.active.count" do
604       post users_path, :params => { :confirm => 1, :user => { inactive_user.id => 1, suspended_user.id => 1 } }
605     end
606     assert_redirected_to :controller => :errors, :action => :forbidden
607     assert_equal "pending", inactive_user.reload.status
608     assert_equal "suspended", suspended_user.reload.status
609
610     session_for(create(:moderator_user))
611
612     # Shouldn't work when logged in as a moderator
613     assert_no_difference "User.active.count" do
614       post users_path, :params => { :confirm => 1, :user => { inactive_user.id => 1, suspended_user.id => 1 } }
615     end
616     assert_redirected_to :controller => :errors, :action => :forbidden
617     assert_equal "pending", inactive_user.reload.status
618     assert_equal "suspended", suspended_user.reload.status
619
620     session_for(create(:administrator_user))
621
622     # Should work when logged in as an administrator
623     assert_difference "User.active.count", 2 do
624       post users_path, :params => { :confirm => 1, :user => { inactive_user.id => 1, suspended_user.id => 1 } }
625     end
626     assert_redirected_to :action => :index
627     assert_equal "confirmed", inactive_user.reload.status
628     assert_equal "confirmed", suspended_user.reload.status
629   end
630
631   def test_index_post_hide
632     normal_user = create(:user)
633     confirmed_user = create(:user, :confirmed)
634
635     # Shouldn't work when not logged in
636     assert_no_difference "User.active.count" do
637       post users_path, :params => { :hide => 1, :user => { normal_user.id => 1, confirmed_user.id => 1 } }
638     end
639     assert_response :forbidden
640
641     assert_equal "active", normal_user.reload.status
642     assert_equal "confirmed", confirmed_user.reload.status
643
644     session_for(create(:user))
645
646     # Shouldn't work when logged in as a normal user
647     assert_no_difference "User.active.count" do
648       post users_path, :params => { :hide => 1, :user => { normal_user.id => 1, confirmed_user.id => 1 } }
649     end
650     assert_redirected_to :controller => :errors, :action => :forbidden
651     assert_equal "active", normal_user.reload.status
652     assert_equal "confirmed", confirmed_user.reload.status
653
654     session_for(create(:moderator_user))
655
656     # Shouldn't work when logged in as a moderator
657     assert_no_difference "User.active.count" do
658       post users_path, :params => { :hide => 1, :user => { normal_user.id => 1, confirmed_user.id => 1 } }
659     end
660     assert_redirected_to :controller => :errors, :action => :forbidden
661     assert_equal "active", normal_user.reload.status
662     assert_equal "confirmed", confirmed_user.reload.status
663
664     session_for(create(:administrator_user))
665
666     # Should work when logged in as an administrator
667     assert_difference "User.active.count", -2 do
668       post users_path, :params => { :hide => 1, :user => { normal_user.id => 1, confirmed_user.id => 1 } }
669     end
670     assert_redirected_to :action => :index
671     assert_equal "deleted", normal_user.reload.status
672     assert_equal "deleted", confirmed_user.reload.status
673   end
674
675   def test_auth_failure_callback
676     get auth_failure_path
677     assert_redirected_to login_path
678
679     get auth_failure_path, :params => { :origin => "/" }
680     assert_redirected_to root_path
681
682     get auth_failure_path, :params => { :origin => "http://www.google.com" }
683     assert_redirected_to login_path
684   end
685 end