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