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