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