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