]> git.openstreetmap.org Git - rails.git/blob - test/controllers/users_controller_test.rb
Merge remote-tracking branch 'upstream/pull/6913'
[rails.git] / test / controllers / users_controller_test.rb
1 # frozen_string_literal: true
2
3 require "test_helper"
4
5 class UsersControllerTest < ActionDispatch::IntegrationTest
6   ##
7   # test all routes which lead to this controller
8   def test_routes
9     assert_routing(
10       { :path => "/user/new", :method => :get },
11       { :controller => "users", :action => "new" }
12     )
13
14     assert_routing(
15       { :path => "/user", :method => :post },
16       { :controller => "users", :action => "create" }
17     )
18
19     assert_routing(
20       { :path => "/user/go_public", :method => :post },
21       { :controller => "users", :action => "go_public" }
22     )
23
24     assert_routing(
25       { :path => "/user/suspended", :method => :get },
26       { :controller => "users", :action => "suspended" }
27     )
28
29     assert_routing(
30       { :path => "/user/username", :method => :get },
31       { :controller => "users", :action => "show", :display_name => "username" }
32     )
33   end
34
35   # The user creation page loads
36   def test_new
37     get new_user_path
38     assert_redirected_to new_user_path(:cookie_test => "true")
39
40     get new_user_path, :params => { :cookie_test => "true" }
41     assert_response :success
42
43     assert_no_match(/img-src \* data:;/, @response.headers["Content-Security-Policy-Report-Only"])
44
45     assert_select "html", :count => 1 do
46       assert_select "head", :count => 1 do
47         assert_select "title", :text => /Sign Up/, :count => 1
48       end
49       assert_select "body", :count => 1 do
50         assert_select "div#content", :count => 1 do
51           assert_select "form[action='/user'][method='post']", :count => 1 do
52             assert_select "input[id='user_email']", :count => 1
53             assert_select "input[id='user_display_name']", :count => 1
54             assert_select "input[id='user_pass_crypt'][type='password']", :count => 1
55             assert_select "input[id='user_pass_crypt_confirmation'][type='password']", :count => 1
56             assert_select "input[type='submit'][value='Sign Up']", :count => 1
57           end
58         end
59       end
60     end
61   end
62
63   def test_new_logged_in
64     session_for(create(:user))
65
66     get new_user_path
67     assert_redirected_to root_path
68
69     get new_user_path, :params => { :referer => "/test" }
70     assert_redirected_to "/test"
71   end
72
73   def test_create_success
74     user = build(:user, :pending)
75
76     assert_difference "User.count", 1 do
77       assert_difference "ActionMailer::Base.deliveries.size", 1 do
78         perform_enqueued_jobs do
79           post users_path, :params => { :user => user.attributes }
80         end
81       end
82     end
83
84     # Check the e-mail
85     register_email = ActionMailer::Base.deliveries.first
86
87     assert_equal register_email.to[0], user.email
88     assert_match(/#{@url}/, register_email.body.to_s)
89
90     # Check the page
91     assert_redirected_to :controller => :confirmations, :action => :confirm, :display_name => user.display_name
92   end
93
94   def test_create_duplicate_email
95     user = build(:user, :pending)
96     create(:user, :email => user.email)
97
98     assert_no_difference "User.count" do
99       assert_no_difference "ActionMailer::Base.deliveries.size" do
100         perform_enqueued_jobs do
101           post users_path, :params => { :user => user.attributes }
102         end
103       end
104     end
105
106     assert_response :success
107     assert_template "new"
108     assert_select "form > div > input.is-invalid#user_email"
109   end
110
111   def test_create_duplicate_email_uppercase
112     user = build(:user, :pending)
113     create(:user, :email => user.email.upcase)
114
115     assert_no_difference "User.count" do
116       assert_no_difference "ActionMailer::Base.deliveries.size" do
117         perform_enqueued_jobs do
118           post users_path, :params => { :user => user.attributes }
119         end
120       end
121     end
122
123     assert_response :success
124     assert_template "new"
125     assert_select "form > div > input.is-invalid#user_email"
126   end
127
128   def test_create_duplicate_name
129     user = build(:user, :pending)
130     create(:user, :display_name => user.display_name)
131
132     assert_no_difference "User.count" do
133       assert_no_difference "ActionMailer::Base.deliveries.size" do
134         perform_enqueued_jobs do
135           post users_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_display_name"
143   end
144
145   def test_create_duplicate_name_uppercase
146     user = build(:user, :pending)
147     create(:user, :display_name => user.display_name.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 users_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_display_name"
160   end
161
162   def test_create_blocked_domain
163     user = build(:user, :pending, :email => "user@example.net")
164
165     # Now block that domain
166     create(:acl, :domain => "example.net", :k => "no_account_creation")
167
168     # Check that the second half of registration fails
169     assert_no_difference "User.count" do
170       assert_no_difference "ActionMailer::Base.deliveries.size" do
171         perform_enqueued_jobs do
172           post users_path, :params => { :user => user.attributes }
173         end
174       end
175     end
176
177     assert_response :success
178     assert_template "blocked"
179   end
180
181   def test_create_referer_params
182     user = build(:user, :pending)
183
184     assert_difference "User.count", 1 do
185       assert_difference "ActionMailer::Base.deliveries.size", 1 do
186         post users_path, :params => { :user => user.attributes, :referer => "/edit?editor=id#map=1/2/3" }
187         assert_enqueued_with :job => ActionMailer::MailDeliveryJob,
188                              :args => proc { |args| args[3][:params][:referer] == welcome_path(:editor => "id", :zoom => 1, :lat => 2, :lon => 3) }
189         perform_enqueued_jobs
190       end
191     end
192   end
193
194   def test_create_turnstile_success
195     user = build(:user, :pending)
196
197     stub_request(:post, "https://challenges.cloudflare.com/turnstile/v0/siteverify")
198       .with(:body => { "remoteip" => "127.0.0.1", "response" => "turnstile_response", "secret" => "turnstile_secret" })
199       .to_return(:body => JSON.generate(:success => true))
200
201     with_settings(:turnstile_site_key => "turnstile_site",
202                   :turnstile_secret_key => "turnstile_secret") do
203       assert_difference "User.count", 1 do
204         assert_difference "ActionMailer::Base.deliveries.size", 1 do
205           perform_enqueued_jobs do
206             post users_path, :params => { :user => user.attributes, "cf-turnstile-response" => "turnstile_response" }
207           end
208         end
209       end
210     end
211   end
212
213   def test_create_turnstile_failure
214     user = build(:user, :pending)
215
216     stub_request(:post, "https://challenges.cloudflare.com/turnstile/v0/siteverify")
217       .with(:body => { "remoteip" => "127.0.0.1", "response" => "turnstile_response", "secret" => "turnstile_secret" })
218       .to_return(:body => JSON.generate(:success => false))
219
220     with_settings(:turnstile_site_key => "turnstile_site",
221                   :turnstile_secret_key => "turnstile_secret") do
222       assert_no_difference "User.count" do
223         assert_no_difference "ActionMailer::Base.deliveries.size" do
224           perform_enqueued_jobs do
225             post users_path, :params => { :user => user.attributes, "cf-turnstile-response" => "turnstile_response" }
226           end
227         end
228       end
229     end
230   end
231
232   def test_go_public
233     user = create(:user, :data_public => false)
234     session_for(user)
235
236     post user_go_public_path
237
238     assert_redirected_to account_path
239     assert User.find(user.id).data_public
240   end
241
242   # Check that the user account page will display and contains some relevant
243   # information for the user
244   def test_show
245     # Test a non-existent user
246     get user_path("unknown")
247     assert_response :not_found
248
249     # Test a normal user
250     user = create(:user)
251
252     get user_path(user)
253     assert_response :success
254     assert_match(/img-src \* data:;/, @response.headers["Content-Security-Policy-Report-Only"])
255     assert_select "div.content-heading" do
256       assert_select "a[href^='/user/#{ERB::Util.u(user.display_name)}/history']", 1
257       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/traces']", 1
258       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary']", 1
259       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary_comments']", 1
260       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/account']", 0
261       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks']", 0
262       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks_by']", 0
263       assert_select "a[href='/user_blocks/new/#{ERB::Util.u(user.display_name)}']", 0
264     end
265
266     # Test a user who has been blocked
267     blocked_user = create(:user)
268     create(:user_block, :user => blocked_user)
269     get user_path(blocked_user)
270     assert_response :success
271     assert_select "div.content-heading" do
272       assert_select "a[href^='/user/#{ERB::Util.u(blocked_user.display_name)}/history']", 1
273       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/traces']", 1
274       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/diary']", 1
275       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/diary_comments']", 1
276       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/account']", 0
277       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/blocks']", 1
278       assert_select "a[href='/user/#{ERB::Util.u(blocked_user.display_name)}/blocks_by']", 0
279       assert_select "a[href='/user_blocks/new/#{ERB::Util.u(blocked_user.display_name)}']", 0
280     end
281
282     # Test a moderator who has applied blocks
283     moderator_user = create(:moderator_user)
284     create(:user_block, :creator => moderator_user)
285     get user_path(moderator_user)
286     assert_response :success
287     assert_select "div.content-heading" do
288       assert_select "a[href^='/user/#{ERB::Util.u(moderator_user.display_name)}/history']", 1
289       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/traces']", 1
290       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/diary']", 1
291       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/diary_comments']", 1
292       assert_select "a[href='/account']", 0
293       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/blocks']", 0
294       assert_select "a[href='/user/#{ERB::Util.u(moderator_user.display_name)}/blocks_by']", 1
295       assert_select "a[href='/user_blocks/new/#{ERB::Util.u(moderator_user.display_name)}']", 0
296     end
297
298     # Login as a normal user
299     session_for(user)
300
301     # Test the normal user
302     get user_path(user)
303     assert_response :success
304     assert_select "div.content-heading" do
305       assert_select "a[href^='/user/#{ERB::Util.u(user.display_name)}/history']", 1
306       assert_select "a[href='/traces/mine']", 1
307       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary']", 1
308       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary_comments']", 1
309       assert_select "a[href='/account']", 1
310       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks']", 0
311       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks_by']", 0
312       assert_select "a[href='/user_blocks/new/#{ERB::Util.u(user.display_name)}']", 0
313       assert_select "a[href='/api/0.6/user/#{ERB::Util.u(user.id)}']", 0
314     end
315
316     # Login as a moderator
317     session_for(create(:moderator_user))
318
319     # Test the normal user
320     get user_path(user)
321     assert_response :success
322     assert_select "div.content-heading" do
323       assert_select "a[href^='/user/#{ERB::Util.u(user.display_name)}/history']", 1
324       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/traces']", 1
325       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary']", 1
326       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/diary_comments']", 1
327       assert_select "a[href='/account']", 0
328       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks']", 0
329       assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/blocks_by']", 0
330       assert_select "a[href='/user_blocks/new/#{ERB::Util.u(user.display_name)}']", 1
331       assert_select "a[href='/api/0.6/user/#{ERB::Util.u(user.id)}']", 1
332     end
333   end
334
335   # Test whether information about contributor terms is shown for users who haven't agreed
336   def test_terms_not_agreed
337     agreed_user = create(:user, :terms_agreed => 3.days.ago)
338     seen_user = create(:user, :terms_seen => true, :terms_agreed => nil)
339     not_seen_user = create(:user, :terms_seen => false, :terms_agreed => nil)
340
341     get user_path(agreed_user)
342     assert_response :success
343     assert_select "div.content-heading" do
344       assert_select "dt", :count => 0, :text => /Contributor terms/
345     end
346
347     get user_path(seen_user)
348     assert_response :success
349     assert_select "div.content-heading" do
350       assert_select "dt", :count => 1, :text => /Contributor terms/
351       assert_select "dd", /Declined/
352     end
353
354     get user_path(not_seen_user)
355     assert_response :success
356     assert_select "div.content-heading" do
357       assert_select "dt", :count => 1, :text => /Contributor terms/
358       assert_select "dd", /Undecided/
359     end
360   end
361
362   def test_auth_failure_callback
363     get auth_failure_path
364     assert_redirected_to login_path
365
366     get auth_failure_path, :params => { :origin => "/" }
367     assert_redirected_to root_path
368
369     get auth_failure_path, :params => { :origin => "http://www.google.com" }
370     assert_redirected_to login_path
371   end
372
373   def test_show_profile_diaries
374     user = create(:user)
375     create(:language, :code => "en")
376     create(:diary_entry, :user => user, :title => "First Entry", :body => "First body")
377     create(:diary_entry, :user => user, :title => "Second Entry", :body => "Second body")
378     create(:diary_entry, :user => user, :title => "Third Entry", :body => "Third body")
379     create(:diary_entry, :user => user, :title => "Fourth Entry", :body => "Fourth body")
380     create(:diary_entry, :user => user, :title => "Fifth Entry", :body => "Fifth body")
381
382     get user_path(user)
383     assert_response :success
384
385     # Should only show the 4 most recent entries
386     assert_select ".profile-diary-card", 4
387     assert_select ".card-title a", "Fifth Entry"
388     assert_select ".card-title a", "Fourth Entry"
389     assert_select ".card-title a", "Third Entry"
390     assert_select ".card-title a", "Second Entry"
391     assert_select ".card-title a", { :text => "First Entry", :count => 0 }
392   end
393
394   def test_show_profile_diaries_with_comments
395     user = create(:user)
396     create(:language, :code => "en")
397     entry = create(:diary_entry, :user => user, :title => "Entry with Comments")
398     create(:diary_comment, :diary_entry => entry)
399     create(:diary_comment, :diary_entry => entry)
400
401     get user_path(user)
402     assert_response :success
403
404     assert_select ".profile-diary-card" do
405       assert_select ".card-title a", "Entry with Comments"
406       assert_select "small.text-body-secondary", /2 comments/
407     end
408   end
409
410   def test_show_profile_diaries_empty
411     user = create(:user)
412     get user_path(user)
413     assert_response :success
414     assert_select ".profile-diary-card", 0
415   end
416
417   def test_heatmap_visibility
418     edit_heatmap_button_selector = ".edit_heatmap_button"
419     heatmap_selector = ".heatmap_frame"
420     protagonist = create(:user)
421
422     # Testing unauthenticated user first
423
424     protagonist.update(:public_heatmap => true)
425     get user_path(protagonist)
426     assert_select heatmap_selector
427     refute_select edit_heatmap_button_selector
428
429     protagonist.update(:public_heatmap => false)
430     get user_path(protagonist)
431     refute_select heatmap_selector
432     refute_select edit_heatmap_button_selector
433
434     session_for(protagonist)
435
436     protagonist.update(:public_heatmap => true)
437     get user_path(protagonist)
438     assert_select heatmap_selector
439     assert_select edit_heatmap_button_selector
440
441     protagonist.update(:public_heatmap => false)
442     get user_path(protagonist)
443     refute_select heatmap_selector
444     assert_select edit_heatmap_button_selector
445
446     antagonist = create(:user)
447     session_for(antagonist)
448
449     protagonist.update(:public_heatmap => true)
450     get user_path(protagonist)
451     assert_select heatmap_selector
452     refute_select edit_heatmap_button_selector
453
454     protagonist.update(:public_heatmap => false)
455     get user_path(protagonist)
456     refute_select heatmap_selector
457     refute_select edit_heatmap_button_selector
458
459     moderator = create(:moderator_user)
460     session_for(moderator)
461
462     protagonist.update(:public_heatmap => true)
463     get user_path(protagonist)
464     assert_select heatmap_selector
465     refute_select edit_heatmap_button_selector
466
467     protagonist.update(:public_heatmap => false)
468     get user_path(protagonist)
469     refute_select heatmap_selector
470     refute_select edit_heatmap_button_selector
471
472     admin = create(:administrator_user)
473     session_for(admin)
474
475     protagonist.update(:public_heatmap => true)
476     get user_path(protagonist)
477     assert_select heatmap_selector
478     refute_select edit_heatmap_button_selector
479
480     protagonist.update(:public_heatmap => false)
481     get user_path(protagonist)
482     refute_select heatmap_selector
483     refute_select edit_heatmap_button_selector
484   end
485 end