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