Merge remote-tracking branch 'openstreetmap/pull/1553'
[rails.git] / test / controllers / diary_entry_controller_test.rb
1 require "test_helper"
2
3 class DiaryEntryControllerTest < ActionController::TestCase
4   include ActionView::Helpers::NumberHelper
5
6   def setup
7     # Create the default language for diary entries
8     create(:language, :code => "en")
9     # Stub nominatim response for diary entry locations
10     stub_request(:get, %r{^http://nominatim\.openstreetmap\.org/reverse\?})
11       .to_return(:status => 404)
12   end
13
14   ##
15   # test all routes which lead to this controller
16   def test_routes
17     assert_routing(
18       { :path => "/diary", :method => :get },
19       { :controller => "diary_entry", :action => "list" }
20     )
21     assert_routing(
22       { :path => "/diary/language", :method => :get },
23       { :controller => "diary_entry", :action => "list", :language => "language" }
24     )
25     assert_routing(
26       { :path => "/user/username/diary", :method => :get },
27       { :controller => "diary_entry", :action => "list", :display_name => "username" }
28     )
29     assert_routing(
30       { :path => "/diary/friends", :method => :get },
31       { :controller => "diary_entry", :action => "list", :friends => true }
32     )
33     assert_routing(
34       { :path => "/diary/nearby", :method => :get },
35       { :controller => "diary_entry", :action => "list", :nearby => true }
36     )
37
38     assert_routing(
39       { :path => "/diary/rss", :method => :get },
40       { :controller => "diary_entry", :action => "rss", :format => :rss }
41     )
42     assert_routing(
43       { :path => "/diary/language/rss", :method => :get },
44       { :controller => "diary_entry", :action => "rss", :language => "language", :format => :rss }
45     )
46     assert_routing(
47       { :path => "/user/username/diary/rss", :method => :get },
48       { :controller => "diary_entry", :action => "rss", :display_name => "username", :format => :rss }
49     )
50
51     assert_routing(
52       { :path => "/user/username/diary/comments", :method => :get },
53       { :controller => "diary_entry", :action => "comments", :display_name => "username" }
54     )
55     assert_routing(
56       { :path => "/user/username/diary/comments/1", :method => :get },
57       { :controller => "diary_entry", :action => "comments", :display_name => "username", :page => "1" }
58     )
59
60     assert_routing(
61       { :path => "/diary/new", :method => :get },
62       { :controller => "diary_entry", :action => "new" }
63     )
64     assert_routing(
65       { :path => "/diary/new", :method => :post },
66       { :controller => "diary_entry", :action => "new" }
67     )
68     assert_routing(
69       { :path => "/user/username/diary/1", :method => :get },
70       { :controller => "diary_entry", :action => "view", :display_name => "username", :id => "1" }
71     )
72     assert_routing(
73       { :path => "/user/username/diary/1/edit", :method => :get },
74       { :controller => "diary_entry", :action => "edit", :display_name => "username", :id => "1" }
75     )
76     assert_routing(
77       { :path => "/user/username/diary/1/edit", :method => :post },
78       { :controller => "diary_entry", :action => "edit", :display_name => "username", :id => "1" }
79     )
80     assert_routing(
81       { :path => "/user/username/diary/1/newcomment", :method => :post },
82       { :controller => "diary_entry", :action => "comment", :display_name => "username", :id => "1" }
83     )
84     assert_routing(
85       { :path => "/user/username/diary/1/hide", :method => :post },
86       { :controller => "diary_entry", :action => "hide", :display_name => "username", :id => "1" }
87     )
88     assert_routing(
89       { :path => "/user/username/diary/1/hidecomment/2", :method => :post },
90       { :controller => "diary_entry", :action => "hidecomment", :display_name => "username", :id => "1", :comment => "2" }
91     )
92     assert_routing(
93       { :path => "/user/username/diary/1/subscribe", :method => :post },
94       { :controller => "diary_entry", :action => "subscribe", :display_name => "username", :id => "1" }
95     )
96     assert_routing(
97       { :path => "/user/username/diary/1/unsubscribe", :method => :post },
98       { :controller => "diary_entry", :action => "unsubscribe", :display_name => "username", :id => "1" }
99     )
100   end
101
102   def test_new_no_login
103     # Make sure that you are redirected to the login page when you
104     # are not logged in
105     get :new
106     assert_response :redirect
107     assert_redirected_to :controller => :user, :action => :login, :referer => "/diary/new"
108   end
109
110   def test_new_form
111     # Now try again when logged in
112     get :new, {}, { :user => create(:user) }
113     assert_response :success
114     assert_select "title", :text => /New Diary Entry/, :count => 1
115     assert_select "div.content-heading", :count => 1 do
116       assert_select "h1", :text => /New Diary Entry/, :count => 1
117     end
118     assert_select "div#content", :count => 1 do
119       assert_select "form[action='/diary/new'][method=post]", :count => 1 do
120         assert_select "input#diary_entry_title[name='diary_entry[title]']", :count => 1
121         assert_select "textarea#diary_entry_body[name='diary_entry[body]']", :text => "", :count => 1
122         assert_select "select#diary_entry_language_code", :count => 1
123         assert_select "input#latitude[name='diary_entry[latitude]']", :count => 1
124         assert_select "input#longitude[name='diary_entry[longitude]']", :count => 1
125         assert_select "input[name=commit][type=submit][value=Publish]", :count => 1
126         assert_select "input[name=commit][type=submit][value=Edit]", :count => 1
127         assert_select "input[name=commit][type=submit][value=Preview]", :count => 1
128         assert_select "input", :count => 7
129       end
130     end
131   end
132
133   def test_new_get_with_params
134     # Now try creating a diary entry using get
135     assert_difference "DiaryEntry.count", 0 do
136       get :new, { :commit => "save",
137                   :diary_entry => { :title => "New Title", :body => "This is a new body for the diary entry", :latitude => "1.1",
138                                     :longitude => "2.2", :language_code => "en" } },
139           { :user => create(:user).id }
140     end
141     assert_response :success
142     assert_template :edit
143   end
144
145   def test_new_no_body
146     # Now try creating a invalid diary entry with an empty body
147     user = create(:user)
148     assert_no_difference "DiaryEntry.count" do
149       post :new, { :commit => "save",
150                    :diary_entry => { :title => "New Title", :body => "", :latitude => "1.1",
151                                      :longitude => "2.2", :language_code => "en" } },
152            { :user => user.id }
153     end
154     assert_response :success
155     assert_template :edit
156
157     assert_nil UserPreference.where(:user_id => user.id, :k => "diary.default_language").first
158   end
159
160   def test_new_post
161     # Now try creating a diary entry
162     user = create(:user)
163     assert_difference "DiaryEntry.count", 1 do
164       post :new, { :commit => "save",
165                    :diary_entry => { :title => "New Title", :body => "This is a new body for the diary entry", :latitude => "1.1",
166                                      :longitude => "2.2", :language_code => "en" } },
167            { :user => user.id }
168     end
169     assert_response :redirect
170     assert_redirected_to :action => :list, :display_name => user.display_name
171     entry = DiaryEntry.order(:id).last
172     assert_equal user.id, entry.user_id
173     assert_equal "New Title", entry.title
174     assert_equal "This is a new body for the diary entry", entry.body
175     assert_equal "1.1".to_f, entry.latitude
176     assert_equal "2.2".to_f, entry.longitude
177     assert_equal "en", entry.language_code
178
179     # checks if user was subscribed
180     assert_equal 1, entry.subscribers.length
181
182     assert_equal "en", UserPreference.where(:user_id => user.id, :k => "diary.default_language").first.v
183   end
184
185   def test_new_german
186     create(:language, :code => "de")
187     user = create(:user)
188
189     # Now try creating a diary entry in a different language
190     assert_difference "DiaryEntry.count", 1 do
191       post :new, { :commit => "save",
192                    :diary_entry => { :title => "New Title", :body => "This is a new body for the diary entry", :latitude => "1.1",
193                                      :longitude => "2.2", :language_code => "de" } },
194            { :user => user.id }
195     end
196     assert_response :redirect
197     assert_redirected_to :action => :list, :display_name => user.display_name
198     entry = DiaryEntry.order(:id).last
199     assert_equal user.id, entry.user_id
200     assert_equal "New Title", entry.title
201     assert_equal "This is a new body for the diary entry", entry.body
202     assert_equal "1.1".to_f, entry.latitude
203     assert_equal "2.2".to_f, entry.longitude
204     assert_equal "de", entry.language_code
205
206     # checks if user was subscribed
207     assert_equal 1, entry.subscribers.length
208
209     assert_equal "de", UserPreference.where(:user_id => user.id, :k => "diary.default_language").first.v
210   end
211
212   def test_new_spammy
213     user = create(:user)
214     # Generate some spammy content
215     spammy_title = "Spam Spam Spam Spam Spam"
216     spammy_body = 1.upto(50).map { |n| "http://example.com/spam#{n}" }.join(" ")
217
218     # Try creating a spammy diary entry
219     assert_difference "DiaryEntry.count", 1 do
220       post :new, { :commit => "save",
221                    :diary_entry => { :title => spammy_title, :body => spammy_body, :language_code => "en" } },
222            { :user => user.id }
223     end
224     assert_response :redirect
225     assert_redirected_to :action => :list, :display_name => user.display_name
226     entry = DiaryEntry.order(:id).last
227     assert_equal user.id, entry.user_id
228     assert_equal spammy_title, entry.title
229     assert_equal spammy_body, entry.body
230     assert_equal "en", entry.language_code
231     assert_equal "suspended", User.find(user.id).status
232
233     # Follow the redirect
234     get :list, { :display_name => user.display_name }, { :user => user }
235     assert_response :redirect
236     assert_redirected_to :controller => :user, :action => :suspended
237   end
238
239   def test_edit
240     user = create(:user)
241     other_user = create(:user)
242
243     entry = create(:diary_entry, :user => user)
244
245     # Make sure that you are redirected to the login page when you are
246     # not logged in, without and with the id of the entry you want to edit
247     get :edit, :display_name => entry.user.display_name, :id => entry.id
248     assert_response :redirect
249     assert_redirected_to :controller => :user, :action => :login, :referer => "/user/#{URI.encode(entry.user.display_name)}/diary/#{entry.id}/edit"
250
251     # Verify that you get a not found error, when you pass a bogus id
252     get :edit, { :display_name => entry.user.display_name, :id => 9999 }, { :user => entry.user }
253     assert_response :not_found
254     assert_select "div.content-heading", :count => 1 do
255       assert_select "h2", :text => "No entry with the id: 9999", :count => 1
256     end
257
258     # Verify that you get redirected to view if you are not the user
259     # that created the entry
260     get :edit, { :display_name => entry.user.display_name, :id => entry.id }, { :user => other_user }
261     assert_response :redirect
262     assert_redirected_to :action => :view, :display_name => entry.user.display_name, :id => entry.id
263
264     # Now pass the id, and check that you can edit it, when using the same
265     # user as the person who created the entry
266     get :edit, { :display_name => entry.user.display_name, :id => entry.id }, { :user => entry.user }
267     assert_response :success
268     assert_select "title", :text => /Edit diary entry/, :count => 1
269     assert_select "div.content-heading", :count => 1 do
270       assert_select "h1", :text => /Edit diary entry/, :count => 1
271     end
272     assert_select "div#content", :count => 1 do
273       assert_select "form[action='/user/#{URI.encode(entry.user.display_name)}/diary/#{entry.id}/edit'][method=post]", :count => 1 do
274         assert_select "input#diary_entry_title[name='diary_entry[title]'][value='#{entry.title}']", :count => 1
275         assert_select "textarea#diary_entry_body[name='diary_entry[body]']", :text => entry.body, :count => 1
276         assert_select "select#diary_entry_language_code", :count => 1
277         assert_select "input#latitude[name='diary_entry[latitude]']", :count => 1
278         assert_select "input#longitude[name='diary_entry[longitude]']", :count => 1
279         assert_select "input[name=commit][type=submit][value=Save]", :count => 1
280         assert_select "input[name=commit][type=submit][value=Edit]", :count => 1
281         assert_select "input[name=commit][type=submit][value=Preview]", :count => 1
282         assert_select "input", :count => 7
283       end
284     end
285
286     # Now lets see if you can edit the diary entry
287     new_title = "New Title"
288     new_body = "This is a new body for the diary entry"
289     new_latitude = "1.1"
290     new_longitude = "2.2"
291     new_language_code = "en"
292     post :edit, { :display_name => entry.user.display_name, :id => entry.id, :commit => "save",
293                   :diary_entry => { :title => new_title, :body => new_body, :latitude => new_latitude,
294                                     :longitude => new_longitude, :language_code => new_language_code } },
295          { :user => entry.user.id }
296     assert_response :redirect
297     assert_redirected_to :action => :view, :display_name => entry.user.display_name, :id => entry.id
298
299     # Now check that the new data is rendered, when logged in
300     get :view, { :display_name => entry.user.display_name, :id => entry.id }, { :user => entry.user }
301     assert_response :success
302     assert_template "diary_entry/view"
303     assert_select "title", :text => /Users' diaries | /, :count => 1
304     assert_select "div.content-heading", :count => 1 do
305       assert_select "h2", :text => /#{entry.user.display_name}'s diary/, :count => 1
306     end
307     assert_select "div#content", :count => 1 do
308       assert_select "div.post_heading", :text => /#{new_title}/, :count => 1
309       # This next line won't work if the text has been run through the htmlize function
310       # due to formatting that could be introduced
311       assert_select "p", :text => /#{new_body}/, :count => 1
312       assert_select "abbr[class='geo'][title='#{number_with_precision(new_latitude, :precision => 4)}; #{number_with_precision(new_longitude, :precision => 4)}']", :count => 1
313       # As we're not logged in, check that you cannot edit
314       # print @response.body
315       assert_select "a[href='/user/#{URI.encode(entry.user.display_name)}/diary/#{entry.id}/edit']", :text => "Edit this entry", :count => 1
316     end
317
318     # and when not logged in as the user who wrote the entry
319     get :view, { :display_name => entry.user.display_name, :id => entry.id }, { :user => entry.user }
320     assert_response :success
321     assert_template "diary_entry/view"
322     assert_select "title", :text => /Users' diaries | /, :count => 1
323     assert_select "div.content-heading", :count => 1 do
324       assert_select "h2", :text => /#{entry.user.display_name}'s diary/, :count => 1
325     end
326     assert_select "div#content", :count => 1 do
327       assert_select "div.post_heading", :text => /#{new_title}/, :count => 1
328       # This next line won't work if the text has been run through the htmlize function
329       # due to formatting that could be introduced
330       assert_select "p", :text => /#{new_body}/, :count => 1
331       assert_select "abbr[class=geo][title='#{number_with_precision(new_latitude, :precision => 4)}; #{number_with_precision(new_longitude, :precision => 4)}']", :count => 1
332       # As we're not logged in, check that you cannot edit
333       assert_select "li[class='hidden show_if_user_#{entry.user.id}']", :count => 1 do
334         assert_select "a[href='/user/#{URI.encode(entry.user.display_name)}/diary/#{entry.id}/edit']", :text => "Edit this entry", :count => 1
335       end
336     end
337   end
338
339   def test_edit_i18n
340     user = create(:user)
341     diary_entry = create(:diary_entry, :language_code => "en", :user => user)
342     get :edit, { :display_name => user.display_name, :id => diary_entry.id }, { :user => user }
343     assert_response :success
344     assert_select "span[class=translation_missing]", false, "Missing translation in edit diary entry"
345   end
346
347   def test_comment
348     user = create(:user)
349     other_user = create(:user)
350     entry = create(:diary_entry, :user => user)
351
352     # Make sure that you are denied when you are not logged in
353     post :comment, :display_name => entry.user.display_name, :id => entry.id
354     assert_response :forbidden
355
356     # Verify that you get a not found error, when you pass a bogus id
357     post :comment, { :display_name => entry.user.display_name, :id => 9999 }, { :user => other_user }
358     assert_response :not_found
359     assert_select "div.content-heading", :count => 1 do
360       assert_select "h2", :text => "No entry with the id: 9999", :count => 1
361     end
362
363     post :subscribe, { :id => entry.id, :display_name => entry.user.display_name }, { :user => user }
364
365     # Now try an invalid comment with an empty body
366     assert_no_difference "ActionMailer::Base.deliveries.size" do
367       assert_no_difference "DiaryComment.count" do
368         assert_no_difference "entry.subscribers.count" do
369           post :comment, { :display_name => entry.user.display_name, :id => entry.id, :diary_comment => { :body => "" } }, { :user => other_user }
370         end
371       end
372     end
373     assert_response :success
374     assert_template :view
375
376     # Now try again with the right id
377     assert_difference "ActionMailer::Base.deliveries.size", entry.subscribers.count do
378       assert_difference "DiaryComment.count", 1 do
379         assert_difference "entry.subscribers.count", 1 do
380           post :comment, { :display_name => entry.user.display_name, :id => entry.id, :diary_comment => { :body => "New comment" } }, { :user => other_user }
381         end
382       end
383     end
384     assert_response :redirect
385     assert_redirected_to :action => :view, :display_name => entry.user.display_name, :id => entry.id
386     email = ActionMailer::Base.deliveries.first
387     assert_equal [user.email], email.to
388     assert_equal "[OpenStreetMap] #{other_user.display_name} commented on a diary entry", email.subject
389     assert_match /New comment/, email.text_part.decoded
390     assert_match /New comment/, email.html_part.decoded
391     ActionMailer::Base.deliveries.clear
392     comment = DiaryComment.order(:id).last
393     assert_equal entry.id, comment.diary_entry_id
394     assert_equal other_user.id, comment.user_id
395     assert_equal "New comment", comment.body
396
397     # Now view the diary entry, and check the new comment is present
398     get :view, :display_name => entry.user.display_name, :id => entry.id
399     assert_response :success
400     assert_select ".diary-comment", :count => 1 do
401       assert_select "#comment#{comment.id}", :count => 1 do
402         assert_select "a[href='/user/#{URI.encode(other_user.display_name)}']", :text => other_user.display_name, :count => 1
403       end
404       assert_select ".richtext", :text => /New comment/, :count => 1
405     end
406   end
407
408   def test_comment_spammy
409     user = create(:user)
410     other_user = create(:user)
411
412     # Find the entry to comment on
413     entry = create(:diary_entry, :user => user)
414     post :subscribe, { :id => entry.id, :display_name => entry.user.display_name }, { :user => user }
415
416     # Generate some spammy content
417     spammy_text = 1.upto(50).map { |n| "http://example.com/spam#{n}" }.join(" ")
418
419     # Try creating a spammy comment
420     assert_difference "ActionMailer::Base.deliveries.size", 1 do
421       assert_difference "DiaryComment.count", 1 do
422         post :comment, { :display_name => entry.user.display_name, :id => entry.id, :diary_comment => { :body => spammy_text } }, { :user => other_user }
423       end
424     end
425     assert_response :redirect
426     assert_redirected_to :action => :view, :display_name => entry.user.display_name, :id => entry.id
427     email = ActionMailer::Base.deliveries.first
428     assert_equal [user.email], email.to
429     assert_equal "[OpenStreetMap] #{other_user.display_name} commented on a diary entry", email.subject
430     assert_match %r{http://example.com/spam}, email.text_part.decoded
431     assert_match %r{http://example.com/spam}, email.html_part.decoded
432     ActionMailer::Base.deliveries.clear
433     comment = DiaryComment.order(:id).last
434     assert_equal entry.id, comment.diary_entry_id
435     assert_equal other_user.id, comment.user_id
436     assert_equal spammy_text, comment.body
437     assert_equal "suspended", User.find(other_user.id).status
438
439     # Follow the redirect
440     get :list, { :display_name => user.display_name }, { :user => other_user }
441     assert_response :redirect
442     assert_redirected_to :controller => :user, :action => :suspended
443
444     # Now view the diary entry, and check the new comment is not present
445     get :view, :display_name => entry.user.display_name, :id => entry.id
446     assert_response :success
447     assert_select ".diary-comment", :count => 0
448   end
449
450   def test_list_all
451     diary_entry = create(:diary_entry)
452     geo_entry = create(:diary_entry, :latitude => 51.50763, :longitude => -0.10781)
453     public_entry = create(:diary_entry, :user => create(:user))
454
455     # Try a list of all diary entries
456     get :list
457     check_diary_list diary_entry, geo_entry, public_entry
458   end
459
460   def test_list_user
461     user = create(:user)
462     other_user = create(:user)
463
464     diary_entry = create(:diary_entry, :user => user)
465     geo_entry = create(:diary_entry, :user => user, :latitude => 51.50763, :longitude => -0.10781)
466     _other_entry = create(:diary_entry, :user => other_user)
467
468     # Try a list of diary entries for a valid user
469     get :list, :display_name => user.display_name
470     check_diary_list diary_entry, geo_entry
471
472     # Try a list of diary entries for an invalid user
473     get :list, :display_name => "No Such User"
474     assert_response :not_found
475     assert_template "user/no_such_user"
476   end
477
478   def test_list_friends
479     user = create(:user)
480     other_user = create(:user)
481     friend = create(:friend, :befriender => user)
482     diary_entry = create(:diary_entry, :user => friend.befriendee)
483     _other_entry = create(:diary_entry, :user => other_user)
484
485     # Try a list of diary entries for your friends when not logged in
486     get :list, :friends => true
487     assert_response :redirect
488     assert_redirected_to :controller => :user, :action => :login, :referer => "/diary/friends"
489
490     # Try a list of diary entries for your friends when logged in
491     get :list, { :friends => true }, { :user => user }
492     check_diary_list diary_entry
493     get :list, { :friends => true }, { :user => other_user }
494     check_diary_list
495   end
496
497   def test_list_nearby
498     user = create(:user, :home_lat => 12, :home_lon => 12)
499     nearby_user = create(:user, :home_lat => 11.9, :home_lon => 12.1)
500
501     diary_entry = create(:diary_entry, :user => user)
502
503     # Try a list of diary entries for nearby users when not logged in
504     get :list, :nearby => true
505     assert_response :redirect
506     assert_redirected_to :controller => :user, :action => :login, :referer => "/diary/nearby"
507
508     # Try a list of diary entries for nearby users when logged in
509     get :list, { :nearby => true }, { :user => nearby_user }
510     check_diary_list diary_entry
511     get :list, { :nearby => true }, { :user => user }
512     check_diary_list
513   end
514
515   def test_list_language
516     create(:language, :code => "de")
517     create(:language, :code => "sl")
518     diary_entry_en = create(:diary_entry, :language_code => "en")
519     diary_entry_en2 = create(:diary_entry, :language_code => "en")
520     diary_entry_de = create(:diary_entry, :language_code => "de")
521
522     # Try a list of diary entries in english
523     get :list, :language => "en"
524     check_diary_list diary_entry_en, diary_entry_en2
525
526     # Try a list of diary entries in german
527     get :list, :language => "de"
528     check_diary_list diary_entry_de
529
530     # Try a list of diary entries in slovenian
531     get :list, :language => "sl"
532     check_diary_list
533   end
534
535   def test_rss
536     create(:language, :code => "de")
537     create(:diary_entry, :language_code => "en")
538     create(:diary_entry, :language_code => "en")
539     create(:diary_entry, :language_code => "de")
540
541     get :rss, :format => :rss
542     assert_response :success, "Should be able to get a diary RSS"
543     assert_select "rss", :count => 1 do
544       assert_select "channel", :count => 1 do
545         assert_select "channel>title", :count => 1
546         assert_select "image", :count => 1
547         assert_select "channel>item", :count => 3
548       end
549     end
550   end
551
552   def test_rss_language
553     create(:language, :code => "de")
554     create(:diary_entry, :language_code => "en")
555     create(:diary_entry, :language_code => "en")
556     create(:diary_entry, :language_code => "de")
557
558     get :rss, :language => "en", :format => :rss
559     assert_response :success, "Should be able to get a specific language diary RSS"
560     assert_select "rss>channel>item", :count => 2 # , "Diary entries should be filtered by language"
561   end
562
563   #  def test_rss_nonexisting_language
564   #    get :rss, {:language => 'xx', :format => :rss}
565   #    assert_response :not_found, "Should not be able to get a nonexisting language diary RSS"
566   #  end
567
568   def test_rss_language_with_no_entries
569     create(:language, :code => "sl")
570     create(:diary_entry, :language_code => "en")
571
572     get :rss, :language => "sl", :format => :rss
573     assert_response :success, "Should be able to get a specific language diary RSS"
574     assert_select "rss>channel>item", :count => 0 # , "Diary entries should be filtered by language"
575   end
576
577   def test_rss_user
578     user = create(:user)
579     other_user = create(:user)
580     create(:diary_entry, :user => user)
581     create(:diary_entry, :user => user)
582     create(:diary_entry, :user => other_user)
583
584     get :rss, :display_name => user.display_name, :format => :rss
585     assert_response :success, "Should be able to get a specific users diary RSS"
586     assert_select "rss>channel>item", :count => 2 # , "Diary entries should be filtered by user"
587   end
588
589   def test_rss_nonexisting_user
590     # Try a user that has never existed
591     get :rss, :display_name => "fakeUsername76543", :format => :rss
592     assert_response :not_found, "Should not be able to get a nonexisting users diary RSS"
593
594     # Try a suspended user
595     get :rss, :display_name => create(:user, :suspended).display_name, :format => :rss
596     assert_response :not_found, "Should not be able to get a suspended users diary RSS"
597
598     # Try a deleted user
599     get :rss, :display_name => create(:user, :deleted).display_name, :format => :rss
600     assert_response :not_found, "Should not be able to get a deleted users diary RSS"
601   end
602
603   def test_rss_character_escaping
604     create(:diary_entry, :title => "<script>")
605     get :rss, :format => :rss
606
607     assert_match "<title>&lt;script&gt;</title>", response.body
608   end
609
610   def test_view
611     user = create(:user)
612     suspended_user = create(:user, :suspended)
613     deleted_user = create(:user, :deleted)
614
615     # Try a normal entry that should work
616     diary_entry = create(:diary_entry, :user => user)
617     get :view, :display_name => user.display_name, :id => diary_entry.id
618     assert_response :success
619     assert_template :view
620
621     # Try a deleted entry
622     diary_entry_deleted = create(:diary_entry, :user => user, :visible => false)
623     get :view, :display_name => user.display_name, :id => diary_entry_deleted.id
624     assert_response :not_found
625
626     # Try an entry by a suspended user
627     diary_entry_suspended = create(:diary_entry, :user => suspended_user)
628     get :view, :display_name => suspended_user.display_name, :id => diary_entry_suspended.id
629     assert_response :not_found
630
631     # Try an entry by a deleted user
632     diary_entry_deleted = create(:diary_entry, :user => deleted_user)
633     get :view, :display_name => deleted_user.display_name, :id => diary_entry_deleted.id
634     assert_response :not_found
635   end
636
637   def test_view_hidden_comments
638     # Get a diary entry that has hidden comments
639     user = create(:user)
640     diary_entry = create(:diary_entry, :user => user)
641     visible_comment = create(:diary_comment, :diary_entry => diary_entry)
642     suspended_user_comment = create(:diary_comment, :diary_entry => diary_entry, :user => create(:user, :suspended))
643     deleted_user_comment = create(:diary_comment, :diary_entry => diary_entry, :user => create(:user, :deleted))
644     hidden_comment = create(:diary_comment, :diary_entry => diary_entry, :visible => false)
645
646     get :view, :display_name => user.display_name, :id => diary_entry.id
647     assert_response :success
648     assert_template :view
649     assert_select "div.comments" do
650       assert_select "p#comment#{visible_comment.id}", :count => 1
651       assert_select "p#comment#{suspended_user_comment.id}", :count => 0
652       assert_select "p#comment#{deleted_user_comment.id}", :count => 0
653       assert_select "p#comment#{hidden_comment.id}", :count => 0
654     end
655   end
656
657   def test_hide
658     user = create(:user)
659
660     # Try without logging in
661     diary_entry = create(:diary_entry, :user => user)
662     post :hide, :display_name => user.display_name, :id => diary_entry.id
663     assert_response :forbidden
664     assert_equal true, DiaryEntry.find(diary_entry.id).visible
665
666     # Now try as a normal user
667     post :hide, { :display_name => user.display_name, :id => diary_entry.id }, { :user => user }
668     assert_response :redirect
669     assert_redirected_to :action => :view, :display_name => user.display_name, :id => diary_entry.id
670     assert_equal true, DiaryEntry.find(diary_entry.id).visible
671
672     # Finally try as an administrator
673     post :hide, { :display_name => user.display_name, :id => diary_entry.id }, { :user => create(:administrator_user) }
674     assert_response :redirect
675     assert_redirected_to :action => :list, :display_name => user.display_name
676     assert_equal false, DiaryEntry.find(diary_entry.id).visible
677   end
678
679   def test_hidecomment
680     user = create(:user)
681     administrator_user = create(:administrator_user)
682     diary_entry = create(:diary_entry, :user => user)
683     diary_comment = create(:diary_comment, :diary_entry => diary_entry)
684     # Try without logging in
685     post :hidecomment, :display_name => user.display_name, :id => diary_entry.id, :comment => diary_comment.id
686     assert_response :forbidden
687     assert_equal true, DiaryComment.find(diary_comment.id).visible
688
689     # Now try as a normal user
690     post :hidecomment, { :display_name => user.display_name, :id => diary_entry.id, :comment => diary_comment.id }, { :user => user }
691     assert_response :redirect
692     assert_redirected_to :action => :view, :display_name => user.display_name, :id => diary_entry.id
693     assert_equal true, DiaryComment.find(diary_comment.id).visible
694
695     # Finally try as an administrator
696     post :hidecomment, { :display_name => user.display_name, :id => diary_entry.id, :comment => diary_comment.id }, { :user => administrator_user }
697     assert_response :redirect
698     assert_redirected_to :action => :view, :display_name => user.display_name, :id => diary_entry.id
699     assert_equal false, DiaryComment.find(diary_comment.id).visible
700   end
701
702   def test_comments
703     user = create(:user)
704     other_user = create(:user)
705     suspended_user = create(:user, :suspended)
706     deleted_user = create(:user, :deleted)
707     # Test a user with no comments
708     get :comments, :display_name => user.display_name
709     assert_response :success
710     assert_template :comments
711     assert_select "table.messages" do
712       assert_select "tr", :count => 1 # header, no comments
713     end
714
715     # Test a user with a comment
716     create(:diary_comment, :user => other_user)
717
718     get :comments, :display_name => other_user.display_name
719     assert_response :success
720     assert_template :comments
721     assert_select "table.messages" do
722       assert_select "tr", :count => 2 # header and one comment
723     end
724
725     # Test a suspended user
726     get :comments, :display_name => suspended_user.display_name
727     assert_response :not_found
728
729     # Test a deleted user
730     get :comments, :display_name => deleted_user.display_name
731     assert_response :not_found
732   end
733
734   def test_subscribe_success
735     user = create(:user)
736     other_user = create(:user)
737     diary_entry = create(:diary_entry, :user => user)
738
739     assert_difference "diary_entry.subscribers.count", 1 do
740       post :subscribe, { :id => diary_entry.id, :display_name => diary_entry.user.display_name }, { :user => other_user }
741     end
742     assert_response :redirect
743   end
744
745   def test_subscribe_fail
746     user = create(:user)
747     other_user = create(:user)
748
749     diary_entry = create(:diary_entry, :user => user)
750
751     # not signed in
752     assert_no_difference "diary_entry.subscribers.count" do
753       post :subscribe, :id => diary_entry.id, :display_name => diary_entry.user.display_name
754     end
755     assert_response :forbidden
756
757     # bad diary id
758     post :subscribe, { :id => 999111, :display_name => "username" }, { :user => other_user }
759     assert_response :not_found
760
761     # trying to subscribe when already subscribed
762     post :subscribe, { :id => diary_entry.id, :display_name => diary_entry.user.display_name }, { :user => other_user }
763     assert_no_difference "diary_entry.subscribers.count" do
764       post :subscribe, { :id => diary_entry.id, :display_name => diary_entry.user.display_name }, { :user => other_user }
765     end
766   end
767
768   def test_unsubscribe_success
769     user = create(:user)
770     other_user = create(:user)
771
772     diary_entry = create(:diary_entry, :user => user)
773
774     post :subscribe, { :id => diary_entry.id, :display_name => diary_entry.user.display_name }, { :user => other_user }
775     assert_difference "diary_entry.subscribers.count", -1 do
776       post :unsubscribe, { :id => diary_entry.id, :display_name => diary_entry.user.display_name }, { :user => other_user }
777     end
778     assert_response :redirect
779   end
780
781   def test_unsubscribe_fail
782     user = create(:user)
783     other_user = create(:user)
784
785     diary_entry = create(:diary_entry, :user => user)
786
787     # not signed in
788     assert_no_difference "diary_entry.subscribers.count" do
789       post :unsubscribe, :id => diary_entry.id, :display_name => diary_entry.user.display_name
790     end
791     assert_response :forbidden
792
793     # bad diary id
794     post :unsubscribe, { :id => 999111, :display_name => "username" }, { :user => other_user }
795     assert_response :not_found
796
797     # trying to unsubscribe when not subscribed
798     assert_no_difference "diary_entry.subscribers.count" do
799       post :unsubscribe, { :id => diary_entry.id, :display_name => diary_entry.user.display_name }, { :user => other_user }
800     end
801   end
802
803   private
804
805   def check_diary_list(*entries)
806     assert_response :success
807     assert_template "list"
808     assert_no_missing_translations
809     assert_select "div.diary_post", entries.count
810
811     entries.each do |entry|
812       assert_select "a[href=?]", "/user/#{URI.encode(entry.user.display_name)}/diary/#{entry.id}"
813     end
814   end
815 end