]> git.openstreetmap.org Git - rails.git/blob - test/controllers/diary_entries_controller_test.rb
Add unsubscribe link to changeset notification mails
[rails.git] / test / controllers / diary_entries_controller_test.rb
1 require "test_helper"
2
3 class DiaryEntriesControllerTest < ActionDispatch::IntegrationTest
4   include ActionView::Helpers::NumberHelper
5
6   def setup
7     super
8     # Create the default language for diary entries
9     create(:language, :code => "en")
10     # Stub nominatim response for diary entry locations
11     stub_request(:get, %r{^https://nominatim\.openstreetmap\.org/reverse\?})
12       .to_return(:status => 404)
13   end
14
15   ##
16   # test all routes which lead to this controller
17   def test_routes
18     assert_routing(
19       { :path => "/diary", :method => :get },
20       { :controller => "diary_entries", :action => "index" }
21     )
22     assert_routing(
23       { :path => "/diary/language", :method => :get },
24       { :controller => "diary_entries", :action => "index", :language => "language" }
25     )
26     assert_routing(
27       { :path => "/user/username/diary", :method => :get },
28       { :controller => "diary_entries", :action => "index", :display_name => "username" }
29     )
30     assert_routing(
31       { :path => "/diary/friends", :method => :get },
32       { :controller => "diary_entries", :action => "index", :friends => true }
33     )
34     assert_routing(
35       { :path => "/diary/nearby", :method => :get },
36       { :controller => "diary_entries", :action => "index", :nearby => true }
37     )
38
39     assert_routing(
40       { :path => "/diary/rss", :method => :get },
41       { :controller => "diary_entries", :action => "rss", :format => :rss }
42     )
43     assert_routing(
44       { :path => "/diary/language/rss", :method => :get },
45       { :controller => "diary_entries", :action => "rss", :language => "language", :format => :rss }
46     )
47     assert_routing(
48       { :path => "/user/username/diary/rss", :method => :get },
49       { :controller => "diary_entries", :action => "rss", :display_name => "username", :format => :rss }
50     )
51
52     assert_routing(
53       { :path => "/user/username/diary/comments", :method => :get },
54       { :controller => "diary_entries", :action => "comments", :display_name => "username" }
55     )
56     assert_routing(
57       { :path => "/user/username/diary/comments/1", :method => :get },
58       { :controller => "diary_entries", :action => "comments", :display_name => "username", :page => "1" }
59     )
60
61     assert_routing(
62       { :path => "/diary/new", :method => :get },
63       { :controller => "diary_entries", :action => "new" }
64     )
65     assert_routing(
66       { :path => "/diary", :method => :post },
67       { :controller => "diary_entries", :action => "create" }
68     )
69     assert_routing(
70       { :path => "/user/username/diary/1", :method => :get },
71       { :controller => "diary_entries", :action => "show", :display_name => "username", :id => "1" }
72     )
73     assert_routing(
74       { :path => "/user/username/diary/1/edit", :method => :get },
75       { :controller => "diary_entries", :action => "edit", :display_name => "username", :id => "1" }
76     )
77     assert_routing(
78       { :path => "/user/username/diary/1", :method => :put },
79       { :controller => "diary_entries", :action => "update", :display_name => "username", :id => "1" }
80     )
81     assert_routing(
82       { :path => "/user/username/diary/1/newcomment", :method => :post },
83       { :controller => "diary_entries", :action => "comment", :display_name => "username", :id => "1" }
84     )
85     assert_routing(
86       { :path => "/user/username/diary/1/hide", :method => :post },
87       { :controller => "diary_entries", :action => "hide", :display_name => "username", :id => "1" }
88     )
89     assert_routing(
90       { :path => "/user/username/diary/1/unhide", :method => :post },
91       { :controller => "diary_entries", :action => "unhide", :display_name => "username", :id => "1" }
92     )
93     assert_routing(
94       { :path => "/user/username/diary/1/hidecomment/2", :method => :post },
95       { :controller => "diary_entries", :action => "hidecomment", :display_name => "username", :id => "1", :comment => "2" }
96     )
97     assert_routing(
98       { :path => "/user/username/diary/1/unhidecomment/2", :method => :post },
99       { :controller => "diary_entries", :action => "unhidecomment", :display_name => "username", :id => "1", :comment => "2" }
100     )
101     assert_routing(
102       { :path => "/user/username/diary/1/subscribe", :method => :get },
103       { :controller => "diary_entries", :action => "subscribe", :display_name => "username", :id => "1" }
104     )
105     assert_routing(
106       { :path => "/user/username/diary/1/subscribe", :method => :post },
107       { :controller => "diary_entries", :action => "subscribe", :display_name => "username", :id => "1" }
108     )
109     assert_routing(
110       { :path => "/user/username/diary/1/unsubscribe", :method => :get },
111       { :controller => "diary_entries", :action => "unsubscribe", :display_name => "username", :id => "1" }
112     )
113     assert_routing(
114       { :path => "/user/username/diary/1/unsubscribe", :method => :post },
115       { :controller => "diary_entries", :action => "unsubscribe", :display_name => "username", :id => "1" }
116     )
117   end
118
119   def test_new_no_login
120     # Make sure that you are redirected to the login page when you
121     # are not logged in
122     get new_diary_entry_path
123     assert_response :redirect
124     assert_redirected_to login_path(:referer => "/diary/new")
125   end
126
127   def test_new_form
128     # Now try again when logged in
129     session_for(create(:user))
130     get new_diary_entry_path
131     assert_response :success
132     assert_select "title", :text => /New Diary Entry/, :count => 1
133     assert_select "div.content-heading", :count => 1 do
134       assert_select "h1", :text => /New Diary Entry/, :count => 1
135     end
136     assert_select "div#content", :count => 1 do
137       assert_select "form[action='/diary'][method=post]", :count => 1 do
138         assert_select "input#diary_entry_title[name='diary_entry[title]']", :count => 1
139         assert_select "textarea#diary_entry_body[name='diary_entry[body]']", :text => "", :count => 1
140         assert_select "select#diary_entry_language_code", :count => 1
141         assert_select "input#latitude[name='diary_entry[latitude]']", :count => 1
142         assert_select "input#longitude[name='diary_entry[longitude]']", :count => 1
143         assert_select "input[name=commit][type=submit][value=Publish]", :count => 1
144         assert_select "input[name=commit][type=submit][value=Edit]", :count => 1
145         assert_select "input[name=commit][type=submit][value=Preview]", :count => 1
146         assert_select "input", :count => 6
147       end
148     end
149   end
150
151   def test_new_get_with_params
152     # Now try creating a diary entry using get
153     session_for(create(:user))
154     assert_difference "DiaryEntry.count", 0 do
155       get new_diary_entry_path(:commit => "save",
156                                :diary_entry => { :title => "New Title", :body => "This is a new body for the diary entry", :latitude => "1.1",
157                                                  :longitude => "2.2", :language_code => "en" })
158     end
159     assert_response :success
160     assert_template :new
161   end
162
163   def test_create_no_body
164     # Now try creating a invalid diary entry with an empty body
165     user = create(:user)
166     session_for(user)
167     assert_no_difference "DiaryEntry.count" do
168       post diary_entries_path(:commit => "save",
169                               :diary_entry => { :title => "New Title", :body => "", :latitude => "1.1",
170                                                 :longitude => "2.2", :language_code => "en" })
171     end
172     assert_response :success
173     assert_template :new
174
175     assert_nil UserPreference.find_by(:user => user, :k => "diary.default_language")
176   end
177
178   def test_create
179     # Now try creating a diary entry
180     user = create(:user)
181     session_for(user)
182     assert_difference "DiaryEntry.count", 1 do
183       post diary_entries_path(:commit => "save",
184                               :diary_entry => { :title => "New Title", :body => "This is a new body for the diary entry", :latitude => "1.1",
185                                                 :longitude => "2.2", :language_code => "en" })
186     end
187     assert_response :redirect
188     assert_redirected_to :action => :index, :display_name => user.display_name
189     entry = DiaryEntry.order(:id).last
190     assert_equal user.id, entry.user_id
191     assert_equal "New Title", entry.title
192     assert_equal "This is a new body for the diary entry", entry.body
193     assert_equal "1.1".to_f, entry.latitude
194     assert_equal "2.2".to_f, entry.longitude
195     assert_equal "en", entry.language_code
196
197     # checks if user was subscribed
198     assert_equal 1, entry.subscribers.length
199
200     assert_equal "en", UserPreference.find_by(:user => user, :k => "diary.default_language").v
201   end
202
203   def test_create_german
204     create(:language, :code => "de")
205     user = create(:user)
206     session_for(user)
207
208     # Now try creating a diary entry in a different language
209     assert_difference "DiaryEntry.count", 1 do
210       post diary_entries_path(:commit => "save",
211                               :diary_entry => { :title => "New Title", :body => "This is a new body for the diary entry", :latitude => "1.1",
212                                                 :longitude => "2.2", :language_code => "de" })
213     end
214     assert_response :redirect
215     assert_redirected_to :action => :index, :display_name => user.display_name
216     entry = DiaryEntry.order(:id).last
217     assert_equal user.id, entry.user_id
218     assert_equal "New Title", entry.title
219     assert_equal "This is a new body for the diary entry", entry.body
220     assert_equal "1.1".to_f, entry.latitude
221     assert_equal "2.2".to_f, entry.longitude
222     assert_equal "de", entry.language_code
223
224     # checks if user was subscribed
225     assert_equal 1, entry.subscribers.length
226
227     assert_equal "de", UserPreference.find_by(:user => user, :k => "diary.default_language").v
228   end
229
230   def test_new_spammy
231     user = create(:user)
232     session_for(user)
233
234     # Generate some spammy content
235     spammy_title = "Spam Spam Spam Spam Spam"
236     spammy_body = 1.upto(50).map { |n| "http://example.com/spam#{n}" }.join(" ")
237
238     # Try creating a spammy diary entry
239     assert_difference "DiaryEntry.count", 1 do
240       post diary_entries_path(:commit => "save",
241                               :diary_entry => { :title => spammy_title, :body => spammy_body, :language_code => "en" })
242     end
243     assert_response :redirect
244     assert_redirected_to :action => :index, :display_name => user.display_name
245     entry = DiaryEntry.order(:id).last
246     assert_equal user.id, entry.user_id
247     assert_equal spammy_title, entry.title
248     assert_equal spammy_body, entry.body
249     assert_equal "en", entry.language_code
250     assert_equal "suspended", User.find(user.id).status
251
252     # Follow the redirect
253     get diary_entries_path(:display_name => user.display_name)
254     assert_response :redirect
255     assert_redirected_to :controller => :users, :action => :suspended
256   end
257
258   def test_edit
259     user = create(:user)
260     other_user = create(:user)
261
262     entry = create(:diary_entry, :user => user)
263
264     # Make sure that you are redirected to the login page when you are
265     # not logged in, without and with the id of the entry you want to edit
266     get edit_diary_entry_path(:display_name => entry.user.display_name, :id => entry)
267     assert_response :redirect
268     assert_redirected_to login_path(:referer => "/user/#{ERB::Util.u(entry.user.display_name)}/diary/#{entry.id}/edit")
269
270     session_for(other_user)
271
272     # Verify that you get redirected to show if you are not the user
273     # that created the entry
274     get edit_diary_entry_path(:display_name => entry.user.display_name, :id => entry)
275     assert_response :redirect
276     assert_redirected_to :action => :show, :display_name => entry.user.display_name, :id => entry.id
277
278     session_for(entry.user)
279
280     # Verify that you get a not found error, when you pass a bogus id
281     get edit_diary_entry_path(:display_name => entry.user.display_name, :id => 9999)
282     assert_response :not_found
283     assert_select "div.content-heading", :count => 1 do
284       assert_select "h1", :text => "No entry with the id: 9999", :count => 1
285     end
286
287     # Now pass the id, and check that you can edit it, when using the same
288     # user as the person who created the entry
289     get edit_diary_entry_path(:display_name => entry.user.display_name, :id => entry)
290     assert_response :success
291     assert_select "title", :text => /Edit Diary Entry/, :count => 1
292     assert_select "div.content-heading", :count => 1 do
293       assert_select "h1", :text => /Edit Diary Entry/, :count => 1
294     end
295     assert_select "div#content", :count => 1 do
296       assert_select "form[action='/user/#{ERB::Util.u(entry.user.display_name)}/diary/#{entry.id}'][method=post]", :count => 1 do
297         assert_select "input#diary_entry_title[name='diary_entry[title]'][value='#{entry.title}']", :count => 1
298         assert_select "textarea#diary_entry_body[name='diary_entry[body]']", :text => entry.body, :count => 1
299         assert_select "select#diary_entry_language_code", :count => 1
300         assert_select "input#latitude[name='diary_entry[latitude]']", :count => 1
301         assert_select "input#longitude[name='diary_entry[longitude]']", :count => 1
302         assert_select "input[name=commit][type=submit][value=Update]", :count => 1
303         assert_select "input[name=commit][type=submit][value=Edit]", :count => 1
304         assert_select "input[name=commit][type=submit][value=Preview]", :count => 1
305         assert_select "input", :count => 7
306       end
307     end
308
309     # Now lets see if you can edit the diary entry
310     new_title = "New Title"
311     new_body = "This is a new body for the diary entry"
312     new_latitude = "1.1"
313     new_longitude = "2.2"
314     new_language_code = "en"
315     put diary_entry_path(:display_name => entry.user.display_name, :id => entry, :commit => "save",
316                          :diary_entry => { :title => new_title, :body => new_body, :latitude => new_latitude,
317                                            :longitude => new_longitude, :language_code => new_language_code })
318     assert_response :redirect
319     assert_redirected_to :action => :show, :display_name => entry.user.display_name, :id => entry.id
320
321     # Now check that the new data is rendered, when logged in
322     get diary_entry_path(:display_name => entry.user.display_name, :id => entry)
323     assert_response :success
324     assert_template "show"
325     assert_select "title", :text => /Users' Diaries | /, :count => 1
326     assert_select "div.content-heading", :count => 1 do
327       assert_select "h1", :text => /#{entry.user.display_name}'s Diary/, :count => 1
328     end
329     assert_select "div#content", :count => 1 do
330       assert_select "h2", :text => /#{new_title}/, :count => 1
331       # This next line won't work if the text has been run through the htmlize function
332       # due to formatting that could be introduced
333       assert_select "p", :text => /#{new_body}/, :count => 1
334       assert_select "abbr[class='geo'][title='#{number_with_precision(new_latitude, :precision => 4)}; #{number_with_precision(new_longitude, :precision => 4)}']", :count => 1
335       # As we're not logged in, check that you cannot edit
336       assert_select "a[href='/user/#{ERB::Util.u(entry.user.display_name)}/diary/#{entry.id}/edit']", :text => "Edit this entry", :count => 1
337     end
338
339     # and when not logged in as the user who wrote the entry
340     session_for(create(:user))
341     get diary_entry_path(:display_name => entry.user.display_name, :id => entry)
342     assert_response :success
343     assert_template "show"
344     assert_select "title", :text => /Users' Diaries | /, :count => 1
345     assert_select "div.content-heading", :count => 1 do
346       assert_select "h1", :text => /#{entry.user.display_name}'s Diary/, :count => 1
347     end
348     assert_select "div#content", :count => 1 do
349       assert_select "h2", :text => /#{new_title}/, :count => 1
350       # This next line won't work if the text has been run through the htmlize function
351       # due to formatting that could be introduced
352       assert_select "p", :text => /#{new_body}/, :count => 1
353       assert_select "abbr[class=geo][title='#{number_with_precision(new_latitude, :precision => 4)}; #{number_with_precision(new_longitude, :precision => 4)}']", :count => 1
354       # As we're not logged in, check that you cannot edit
355       assert_select "a[href='/user/#{ERB::Util.u(entry.user.display_name)}/diary/#{entry.id}/edit']", false
356     end
357   end
358
359   def test_edit_i18n
360     user = create(:user)
361     diary_entry = create(:diary_entry, :language_code => "en", :user => user)
362     session_for(user)
363     get edit_diary_entry_path(:display_name => user.display_name, :id => diary_entry)
364     assert_response :success
365     assert_select "span[class=translation_missing]", false, "Missing translation in edit diary entry"
366   end
367
368   def test_comment
369     user = create(:user)
370     other_user = create(:user)
371     entry = create(:diary_entry, :user => user)
372     create(:diary_entry_subscription, :diary_entry => entry, :user => user)
373
374     # Make sure that you are denied when you are not logged in
375     post comment_diary_entry_path(:display_name => entry.user.display_name, :id => entry)
376     assert_response :forbidden
377
378     session_for(other_user)
379
380     # Verify that you get a not found error, when you pass a bogus id
381     post comment_diary_entry_path(:display_name => entry.user.display_name, :id => 9999)
382     assert_response :not_found
383     assert_select "div.content-heading", :count => 1 do
384       assert_select "h1", :text => "No entry with the id: 9999", :count => 1
385     end
386
387     # Now try an invalid comment with an empty body
388     assert_no_difference "ActionMailer::Base.deliveries.size" do
389       assert_no_difference "DiaryComment.count" do
390         assert_no_difference "entry.subscribers.count" do
391           perform_enqueued_jobs do
392             post comment_diary_entry_path(:display_name => entry.user.display_name, :id => entry, :diary_comment => { :body => "" })
393           end
394         end
395       end
396     end
397     assert_response :success
398     assert_template :show
399
400     # Now try again with the right id
401     assert_difference "ActionMailer::Base.deliveries.size", entry.subscribers.count do
402       assert_difference "DiaryComment.count", 1 do
403         assert_difference "entry.subscribers.count", 1 do
404           perform_enqueued_jobs do
405             post comment_diary_entry_path(:display_name => entry.user.display_name, :id => entry, :diary_comment => { :body => "New comment" })
406           end
407         end
408       end
409     end
410     assert_response :redirect
411     assert_redirected_to :action => :show, :display_name => entry.user.display_name, :id => entry.id
412     email = ActionMailer::Base.deliveries.first
413     assert_equal [user.email], email.to
414     assert_equal "[OpenStreetMap] #{other_user.display_name} commented on a diary entry", email.subject
415     assert_match(/New comment/, email.text_part.decoded)
416     assert_match(/New comment/, email.html_part.decoded)
417     ActionMailer::Base.deliveries.clear
418     comment = DiaryComment.order(:id).last
419     assert_equal entry.id, comment.diary_entry_id
420     assert_equal other_user.id, comment.user_id
421     assert_equal "New comment", comment.body
422
423     # Now show the diary entry, and check the new comment is present
424     get diary_entry_path(:display_name => entry.user.display_name, :id => entry)
425     assert_response :success
426     assert_select ".diary-comment", :count => 1 do
427       assert_select "#comment#{comment.id}", :count => 1 do
428         assert_select "a[href='/user/#{ERB::Util.u(other_user.display_name)}']", :text => other_user.display_name, :count => 1
429       end
430       assert_select ".richtext", :text => /New comment/, :count => 1
431     end
432   end
433
434   def test_comment_spammy
435     user = create(:user)
436     other_user = create(:user)
437     entry = create(:diary_entry, :user => user)
438     create(:diary_entry_subscription, :diary_entry => entry, :user => user)
439
440     session_for(other_user)
441
442     # Generate some spammy content
443     spammy_text = 1.upto(50).map { |n| "http://example.com/spam#{n}" }.join(" ")
444
445     # Try creating a spammy comment
446     assert_difference "ActionMailer::Base.deliveries.size", 1 do
447       assert_difference "DiaryComment.count", 1 do
448         perform_enqueued_jobs do
449           post comment_diary_entry_path(:display_name => entry.user.display_name, :id => entry, :diary_comment => { :body => spammy_text })
450         end
451       end
452     end
453     assert_response :redirect
454     assert_redirected_to :action => :show, :display_name => entry.user.display_name, :id => entry.id
455     email = ActionMailer::Base.deliveries.first
456     assert_equal [user.email], email.to
457     assert_equal "[OpenStreetMap] #{other_user.display_name} commented on a diary entry", email.subject
458     assert_match %r{http://example.com/spam}, email.text_part.decoded
459     assert_match %r{http://example.com/spam}, email.html_part.decoded
460     ActionMailer::Base.deliveries.clear
461     comment = DiaryComment.order(:id).last
462     assert_equal entry.id, comment.diary_entry_id
463     assert_equal other_user.id, comment.user_id
464     assert_equal spammy_text, comment.body
465     assert_equal "suspended", User.find(other_user.id).status
466
467     # Follow the redirect
468     get diary_entries_path(:display_name => user.display_name)
469     assert_response :redirect
470     assert_redirected_to :controller => :users, :action => :suspended
471
472     # Now show the diary entry, and check the new comment is not present
473     get diary_entry_path(:display_name => entry.user.display_name, :id => entry)
474     assert_response :success
475     assert_select ".diary-comment", :count => 0
476   end
477
478   def test_index_all
479     diary_entry = create(:diary_entry)
480     geo_entry = create(:diary_entry, :latitude => 51.50763, :longitude => -0.10781)
481     public_entry = create(:diary_entry, :user => create(:user))
482
483     # Try a list of all diary entries
484     get diary_entries_path
485     check_diary_index diary_entry, geo_entry, public_entry
486   end
487
488   def test_index_user
489     user = create(:user)
490     other_user = create(:user)
491
492     diary_entry = create(:diary_entry, :user => user)
493     geo_entry = create(:diary_entry, :user => user, :latitude => 51.50763, :longitude => -0.10781)
494     _other_entry = create(:diary_entry, :user => other_user)
495
496     # Try a list of diary entries for a valid user
497     get diary_entries_path(:display_name => user.display_name)
498     check_diary_index diary_entry, geo_entry
499
500     # Try a list of diary entries for an invalid user
501     get diary_entries_path(:display_name => "No Such User")
502     assert_response :not_found
503     assert_template "users/no_such_user"
504   end
505
506   def test_index_friends
507     user = create(:user)
508     other_user = create(:user)
509     friendship = create(:friendship, :befriender => user)
510     diary_entry = create(:diary_entry, :user => friendship.befriendee)
511     _other_entry = create(:diary_entry, :user => other_user)
512
513     # Try a list of diary entries for your friends when not logged in
514     get friends_diary_entries_path
515     assert_response :redirect
516     assert_redirected_to login_path(:referer => "/diary/friends")
517
518     # Try a list of diary entries for your friends when logged in
519     session_for(user)
520     get friends_diary_entries_path
521     check_diary_index diary_entry
522     session_for(other_user)
523     get friends_diary_entries_path
524     check_diary_index
525   end
526
527   def test_index_nearby
528     user = create(:user, :home_lat => 12, :home_lon => 12)
529     nearby_user = create(:user, :home_lat => 11.9, :home_lon => 12.1)
530
531     diary_entry = create(:diary_entry, :user => user)
532
533     # Try a list of diary entries for nearby users when not logged in
534     get nearby_diary_entries_path
535     assert_response :redirect
536     assert_redirected_to login_path(:referer => "/diary/nearby")
537
538     # Try a list of diary entries for nearby users when logged in
539     session_for(nearby_user)
540     get nearby_diary_entries_path
541     check_diary_index diary_entry
542     session_for(user)
543     get nearby_diary_entries_path
544     check_diary_index
545   end
546
547   def test_index_language
548     create(:language, :code => "de")
549     create(:language, :code => "sl")
550     diary_entry_en = create(:diary_entry, :language_code => "en")
551     diary_entry_en2 = create(:diary_entry, :language_code => "en")
552     diary_entry_de = create(:diary_entry, :language_code => "de")
553
554     # Try a list of diary entries in english
555     get diary_entries_path(:language => "en")
556     check_diary_index diary_entry_en, diary_entry_en2
557
558     # Try a list of diary entries in german
559     get diary_entries_path(:language => "de")
560     check_diary_index diary_entry_de
561
562     # Try a list of diary entries in slovenian
563     get diary_entries_path(:language => "sl")
564     check_diary_index
565   end
566
567   def test_index_paged
568     # Create several pages worth of diary entries
569     create_list(:diary_entry, 50)
570
571     # Try and get the index
572     get diary_entries_path
573     assert_response :success
574     assert_select "article.diary_post", :count => 20
575     assert_select "li.page-item a.page-link", :text => "Older Entries", :count => 1
576     assert_select "li.page-item.disabled span.page-link", :text => "Newer Entries", :count => 1
577
578     # Try and get the second page
579     get css_select("li.page-item .page-link").last["href"]
580     assert_response :success
581     assert_select "article.diary_post", :count => 20
582     assert_select "li.page-item a.page-link", :text => "Older Entries", :count => 1
583     assert_select "li.page-item a.page-link", :text => "Newer Entries", :count => 1
584
585     # Try and get the third page
586     get css_select("li.page-item .page-link").last["href"]
587     assert_response :success
588     assert_select "article.diary_post", :count => 10
589     assert_select "li.page-item.disabled span.page-link", :text => "Older Entries", :count => 1
590     assert_select "li.page-item a.page-link", :text => "Newer Entries", :count => 1
591
592     # Go back to the second page
593     get css_select("li.page-item .page-link").first["href"]
594     assert_response :success
595     assert_select "article.diary_post", :count => 20
596     assert_select "li.page-item a.page-link", :text => "Older Entries", :count => 1
597     assert_select "li.page-item a.page-link", :text => "Newer Entries", :count => 1
598
599     # Go back to the first page
600     get css_select("li.page-item .page-link").first["href"]
601     assert_response :success
602     assert_select "article.diary_post", :count => 20
603     assert_select "li.page-item a.page-link", :text => "Older Entries", :count => 1
604     assert_select "li.page-item.disabled span.page-link", :text => "Newer Entries", :count => 1
605   end
606
607   def test_rss
608     create(:language, :code => "de")
609     create(:diary_entry, :language_code => "en")
610     create(:diary_entry, :language_code => "en")
611     create(:diary_entry, :language_code => "de")
612
613     get diary_rss_path
614     assert_response :success, "Should be able to get a diary RSS"
615     assert_select "rss", :count => 1 do
616       assert_select "channel", :count => 1 do
617         assert_select "channel>title", :count => 1
618         assert_select "image", :count => 1
619         assert_select "channel>item", :count => 3
620       end
621     end
622   end
623
624   def test_rss_language
625     create(:language, :code => "de")
626     create(:diary_entry, :language_code => "en")
627     create(:diary_entry, :language_code => "en")
628     create(:diary_entry, :language_code => "de")
629
630     get diary_rss_path(:language => "en")
631     assert_response :success, "Should be able to get a specific language diary RSS"
632     assert_select "rss>channel>item", :count => 2 # , "Diary entries should be filtered by language"
633   end
634
635   #  def test_rss_nonexisting_language
636   #    get :rss, :params => { :language => 'xx', :format => :rss }
637   #    assert_response :not_found, "Should not be able to get a nonexisting language diary RSS"
638   #  end
639
640   def test_rss_language_with_no_entries
641     create(:language, :code => "sl")
642     create(:diary_entry, :language_code => "en")
643
644     get diary_rss_path(:language => "sl")
645     assert_response :success, "Should be able to get a specific language diary RSS"
646     assert_select "rss>channel>item", :count => 0 # , "Diary entries should be filtered by language"
647   end
648
649   def test_rss_user
650     user = create(:user)
651     other_user = create(:user)
652     create(:diary_entry, :user => user)
653     create(:diary_entry, :user => user)
654     create(:diary_entry, :user => other_user)
655
656     get diary_rss_path(:display_name => user.display_name)
657     assert_response :success, "Should be able to get a specific users diary RSS"
658     assert_select "rss>channel>item", :count => 2 # , "Diary entries should be filtered by user"
659   end
660
661   def test_rss_nonexisting_user
662     # Try a user that has never existed
663     get diary_rss_path(:display_name => "fakeUsername76543")
664     assert_response :not_found, "Should not be able to get a nonexisting users diary RSS"
665
666     # Try a suspended user
667     get diary_rss_path(:display_name => create(:user, :suspended).display_name)
668     assert_response :not_found, "Should not be able to get a suspended users diary RSS"
669
670     # Try a deleted user
671     get diary_rss_path(:display_name => create(:user, :deleted).display_name)
672     assert_response :not_found, "Should not be able to get a deleted users diary RSS"
673   end
674
675   def test_rss_character_escaping
676     create(:diary_entry, :title => "<script>")
677     get diary_rss_path
678
679     assert_match "<title>&lt;script&gt;</title>", response.body
680   end
681
682   def test_feed_delay
683     create(:diary_entry, :created_at => 7.hours.ago)
684     create(:diary_entry, :created_at => 5.hours.ago)
685     get diary_rss_path
686     assert_select "rss>channel>item", :count => 2
687
688     with_settings(:diary_feed_delay => 6) do
689       get diary_rss_path
690       assert_select "rss>channel>item", :count => 1
691     end
692   end
693
694   def test_show
695     user = create(:user)
696     suspended_user = create(:user, :suspended)
697     deleted_user = create(:user, :deleted)
698
699     # Try a normal entry that should work
700     diary_entry = create(:diary_entry, :user => user)
701     get diary_entry_path(:display_name => user.display_name, :id => diary_entry)
702     assert_response :success
703     assert_template :show
704
705     # Try a non-integer ID
706     get "/user/#{CGI.escape(user.display_name)}/diary/#{diary_entry.id})"
707     assert_response :not_found
708     assert_template "rescues/routing_error"
709
710     # Try a deleted entry
711     diary_entry_deleted = create(:diary_entry, :user => user, :visible => false)
712     get diary_entry_path(:display_name => user.display_name, :id => diary_entry_deleted)
713     assert_response :not_found
714
715     # Try an entry by a suspended user
716     diary_entry_suspended_user = create(:diary_entry, :user => suspended_user)
717     get diary_entry_path(:display_name => suspended_user.display_name, :id => diary_entry_suspended_user)
718     assert_response :not_found
719
720     # Try an entry by a deleted user
721     diary_entry_deleted_user = create(:diary_entry, :user => deleted_user)
722     get diary_entry_path(:display_name => deleted_user.display_name, :id => diary_entry_deleted_user)
723     assert_response :not_found
724
725     # Now try as a moderator
726     session_for(create(:moderator_user))
727     get diary_entry_path(:display_name => user.display_name, :id => diary_entry_deleted)
728     assert_response :success
729     assert_template :show
730
731     # Finally try as an administrator
732     session_for(create(:administrator_user))
733     get diary_entry_path(:display_name => user.display_name, :id => diary_entry_deleted)
734     assert_response :success
735     assert_template :show
736   end
737
738   def test_show_hidden_comments
739     # Get a diary entry that has hidden comments
740     user = create(:user)
741     diary_entry = create(:diary_entry, :user => user)
742     visible_comment = create(:diary_comment, :diary_entry => diary_entry)
743     suspended_user_comment = create(:diary_comment, :diary_entry => diary_entry, :user => create(:user, :suspended))
744     deleted_user_comment = create(:diary_comment, :diary_entry => diary_entry, :user => create(:user, :deleted))
745     hidden_comment = create(:diary_comment, :diary_entry => diary_entry, :visible => false)
746
747     get diary_entry_path(:display_name => user.display_name, :id => diary_entry)
748     assert_response :success
749     assert_template :show
750     assert_select "div.comments" do
751       assert_select "p#comment#{visible_comment.id}", :count => 1
752       assert_select "p#comment#{suspended_user_comment.id}", :count => 0
753       assert_select "p#comment#{deleted_user_comment.id}", :count => 0
754       assert_select "p#comment#{hidden_comment.id}", :count => 0
755     end
756   end
757
758   def test_hide
759     user = create(:user)
760     diary_entry = create(:diary_entry, :user => user)
761
762     # Try without logging in
763     post hide_diary_entry_path(:display_name => user.display_name, :id => diary_entry)
764     assert_response :forbidden
765     assert DiaryEntry.find(diary_entry.id).visible
766
767     # Now try as a normal user
768     session_for(user)
769     post hide_diary_entry_path(:display_name => user.display_name, :id => diary_entry)
770     assert_response :redirect
771     assert_redirected_to :controller => :errors, :action => :forbidden
772     assert DiaryEntry.find(diary_entry.id).visible
773
774     # Now try as a moderator
775     session_for(create(:moderator_user))
776     post hide_diary_entry_path(:display_name => user.display_name, :id => diary_entry)
777     assert_response :redirect
778     assert_redirected_to :action => :index, :display_name => user.display_name
779     assert_not DiaryEntry.find(diary_entry.id).visible
780
781     # Reset
782     diary_entry.reload.update(:visible => true)
783
784     # Finally try as an administrator
785     session_for(create(:administrator_user))
786     post hide_diary_entry_path(:display_name => user.display_name, :id => diary_entry)
787     assert_response :redirect
788     assert_redirected_to :action => :index, :display_name => user.display_name
789     assert_not DiaryEntry.find(diary_entry.id).visible
790   end
791
792   def test_unhide
793     user = create(:user)
794
795     # Try without logging in
796     diary_entry = create(:diary_entry, :user => user, :visible => false)
797     post unhide_diary_entry_path(:display_name => user.display_name, :id => diary_entry)
798     assert_response :forbidden
799     assert_not DiaryEntry.find(diary_entry.id).visible
800
801     # Now try as a normal user
802     session_for(user)
803     post unhide_diary_entry_path(:display_name => user.display_name, :id => diary_entry)
804     assert_response :redirect
805     assert_redirected_to :controller => :errors, :action => :forbidden
806     assert_not DiaryEntry.find(diary_entry.id).visible
807
808     # Now try as a moderator
809     session_for(create(:moderator_user))
810     post unhide_diary_entry_path(:display_name => user.display_name, :id => diary_entry)
811     assert_response :redirect
812     assert_redirected_to :action => :index, :display_name => user.display_name
813     assert DiaryEntry.find(diary_entry.id).visible
814
815     # Reset
816     diary_entry.reload.update(:visible => true)
817
818     # Finally try as an administrator
819     session_for(create(:administrator_user))
820     post unhide_diary_entry_path(:display_name => user.display_name, :id => diary_entry)
821     assert_response :redirect
822     assert_redirected_to :action => :index, :display_name => user.display_name
823     assert DiaryEntry.find(diary_entry.id).visible
824   end
825
826   def test_hidecomment
827     user = create(:user)
828     diary_entry = create(:diary_entry, :user => user)
829     diary_comment = create(:diary_comment, :diary_entry => diary_entry)
830
831     # Try without logging in
832     post hide_diary_comment_path(:display_name => user.display_name, :id => diary_entry, :comment => diary_comment)
833     assert_response :forbidden
834     assert DiaryComment.find(diary_comment.id).visible
835
836     # Now try as a normal user
837     session_for(user)
838     post hide_diary_comment_path(:display_name => user.display_name, :id => diary_entry, :comment => diary_comment)
839     assert_response :redirect
840     assert_redirected_to :controller => :errors, :action => :forbidden
841     assert DiaryComment.find(diary_comment.id).visible
842
843     # Try as a moderator
844     session_for(create(:moderator_user))
845     post hide_diary_comment_path(:display_name => user.display_name, :id => diary_entry, :comment => diary_comment)
846     assert_response :redirect
847     assert_redirected_to :action => :show, :display_name => user.display_name, :id => diary_entry.id
848     assert_not DiaryComment.find(diary_comment.id).visible
849
850     # Reset
851     diary_comment.reload.update(:visible => true)
852
853     # Finally try as an administrator
854     session_for(create(:administrator_user))
855     post hide_diary_comment_path(:display_name => user.display_name, :id => diary_entry, :comment => diary_comment)
856     assert_response :redirect
857     assert_redirected_to :action => :show, :display_name => user.display_name, :id => diary_entry.id
858     assert_not DiaryComment.find(diary_comment.id).visible
859   end
860
861   def test_unhidecomment
862     user = create(:user)
863     diary_entry = create(:diary_entry, :user => user)
864     diary_comment = create(:diary_comment, :diary_entry => diary_entry, :visible => false)
865
866     # Try without logging in
867     post unhide_diary_comment_path(:display_name => user.display_name, :id => diary_entry, :comment => diary_comment)
868     assert_response :forbidden
869     assert_not DiaryComment.find(diary_comment.id).visible
870
871     # Now try as a normal user
872     session_for(user)
873     post unhide_diary_comment_path(:display_name => user.display_name, :id => diary_entry, :comment => diary_comment)
874     assert_response :redirect
875     assert_redirected_to :controller => :errors, :action => :forbidden
876     assert_not DiaryComment.find(diary_comment.id).visible
877
878     # Now try as a moderator
879     session_for(create(:moderator_user))
880     post unhide_diary_comment_path(:display_name => user.display_name, :id => diary_entry, :comment => diary_comment)
881     assert_response :redirect
882     assert_redirected_to :action => :show, :display_name => user.display_name, :id => diary_entry.id
883     assert DiaryComment.find(diary_comment.id).visible
884
885     # Reset
886     diary_comment.reload.update(:visible => true)
887
888     # Finally try as an administrator
889     session_for(create(:administrator_user))
890     post unhide_diary_comment_path(:display_name => user.display_name, :id => diary_entry, :comment => diary_comment)
891     assert_response :redirect
892     assert_redirected_to :action => :show, :display_name => user.display_name, :id => diary_entry.id
893     assert DiaryComment.find(diary_comment.id).visible
894   end
895
896   def test_comments
897     user = create(:user)
898     other_user = create(:user)
899     suspended_user = create(:user, :suspended)
900     deleted_user = create(:user, :deleted)
901
902     # Test a user with no comments
903     get diary_comments_path(:display_name => user.display_name)
904     assert_response :success
905     assert_template :comments
906     assert_select "h4", :html => "No diary comments"
907
908     # Test a user with a comment
909     create(:diary_comment, :user => other_user)
910
911     get diary_comments_path(:display_name => other_user.display_name)
912     assert_response :success
913     assert_template :comments
914     assert_select "table.table-striped" do
915       assert_select "tr", :count => 2 # header and one comment
916     end
917
918     # Test a suspended user
919     get diary_comments_path(:display_name => suspended_user.display_name)
920     assert_response :not_found
921
922     # Test a deleted user
923     get diary_comments_path(:display_name => deleted_user.display_name)
924     assert_response :not_found
925   end
926
927   def test_subscribe_page
928     user = create(:user)
929     other_user = create(:user)
930     diary_entry = create(:diary_entry, :user => user)
931     path = diary_entry_subscribe_path(:id => diary_entry, :display_name => user.display_name)
932
933     get path
934     assert_response :redirect
935     assert_redirected_to login_path(:referer => path)
936
937     session_for(other_user)
938     get path
939     assert_response :success
940     assert_dom ".content-body" do
941       assert_dom "a[href='#{diary_entry_path(:id => diary_entry, :display_name => user.display_name)}']", :text => diary_entry.title
942       assert_dom "a[href='#{user_path(user)}']", :text => user.display_name
943     end
944   end
945
946   def test_subscribe_success
947     user = create(:user)
948     other_user = create(:user)
949     diary_entry = create(:diary_entry, :user => user)
950
951     session_for(other_user)
952     assert_difference "diary_entry.subscribers.count", 1 do
953       post diary_entry_subscribe_path(:id => diary_entry, :display_name => diary_entry.user.display_name)
954     end
955     assert_response :redirect
956   end
957
958   def test_subscribe_fail
959     user = create(:user)
960     other_user = create(:user)
961
962     diary_entry = create(:diary_entry, :user => user)
963
964     # not signed in
965     assert_no_difference "diary_entry.subscribers.count" do
966       post diary_entry_subscribe_path(:id => diary_entry, :display_name => diary_entry.user.display_name)
967     end
968     assert_response :forbidden
969
970     session_for(other_user)
971
972     # bad diary id
973     post diary_entry_subscribe_path(:id => 999111, :display_name => "username")
974     assert_response :not_found
975
976     # trying to subscribe when already subscribed
977     post diary_entry_subscribe_path(:id => diary_entry, :display_name => diary_entry.user.display_name)
978     assert_no_difference "diary_entry.subscribers.count" do
979       post diary_entry_subscribe_path(:id => diary_entry, :display_name => diary_entry.user.display_name)
980     end
981   end
982
983   def test_unsubscribe_page
984     user = create(:user)
985     other_user = create(:user)
986     diary_entry = create(:diary_entry, :user => user)
987     path = diary_entry_unsubscribe_path(:id => diary_entry, :display_name => user.display_name)
988
989     get path
990     assert_response :redirect
991     assert_redirected_to login_path(:referer => path)
992
993     session_for(other_user)
994     get path
995     assert_response :success
996     assert_dom ".content-body" do
997       assert_dom "a[href='#{diary_entry_path(:id => diary_entry, :display_name => user.display_name)}']", :text => diary_entry.title
998       assert_dom "a[href='#{user_path(user)}']", :text => user.display_name
999     end
1000   end
1001
1002   def test_unsubscribe_success
1003     user = create(:user)
1004     other_user = create(:user)
1005
1006     diary_entry = create(:diary_entry, :user => user)
1007     create(:diary_entry_subscription, :diary_entry => diary_entry, :user => other_user)
1008
1009     session_for(other_user)
1010     assert_difference "diary_entry.subscribers.count", -1 do
1011       post diary_entry_unsubscribe_path(:id => diary_entry, :display_name => diary_entry.user.display_name)
1012     end
1013     assert_response :redirect
1014   end
1015
1016   def test_unsubscribe_fail
1017     user = create(:user)
1018     other_user = create(:user)
1019
1020     diary_entry = create(:diary_entry, :user => user)
1021
1022     # not signed in
1023     assert_no_difference "diary_entry.subscribers.count" do
1024       post diary_entry_unsubscribe_path(:id => diary_entry, :display_name => diary_entry.user.display_name)
1025     end
1026     assert_response :forbidden
1027
1028     session_for(other_user)
1029
1030     # bad diary id
1031     post diary_entry_unsubscribe_path(:id => 999111, :display_name => "username")
1032     assert_response :not_found
1033
1034     # trying to unsubscribe when not subscribed
1035     assert_no_difference "diary_entry.subscribers.count" do
1036       post diary_entry_unsubscribe_path(:id => diary_entry, :display_name => diary_entry.user.display_name)
1037     end
1038   end
1039
1040   private
1041
1042   def check_diary_index(*entries)
1043     assert_response :success
1044     assert_template "index"
1045     assert_no_missing_translations
1046     assert_select "article.diary_post", entries.count
1047
1048     entries.each do |entry|
1049       assert_select "a[href=?]", "/user/#{ERB::Util.u(entry.user.display_name)}/diary/#{entry.id}"
1050     end
1051   end
1052 end