1 # frozen_string_literal: true
 
   5 class DiaryEntriesControllerTest < ActionDispatch::IntegrationTest
 
   6   include ActionView::Helpers::NumberHelper
 
  10     # Create the default language for diary entries
 
  11     create(:language, :code => "en")
 
  12     # Stub nominatim response for diary entry locations
 
  13     stub_request(:get, %r{^https://nominatim\.openstreetmap\.org/reverse\?})
 
  14       .to_return(:status => 404)
 
  18   # test all routes which lead to this controller
 
  21       { :path => "/diary", :method => :get },
 
  22       { :controller => "diary_entries", :action => "index" }
 
  25       { :path => "/diary/language", :method => :get },
 
  26       { :controller => "diary_entries", :action => "index", :language => "language" }
 
  29       { :path => "/user/username/diary", :method => :get },
 
  30       { :controller => "diary_entries", :action => "index", :display_name => "username" }
 
  33       { :path => "/diary/friends", :method => :get },
 
  34       { :controller => "diary_entries", :action => "index", :friends => true }
 
  37       { :path => "/diary/nearby", :method => :get },
 
  38       { :controller => "diary_entries", :action => "index", :nearby => true }
 
  42       { :path => "/diary/rss", :method => :get },
 
  43       { :controller => "diary_entries", :action => "rss", :format => :rss }
 
  46       { :path => "/diary/language/rss", :method => :get },
 
  47       { :controller => "diary_entries", :action => "rss", :language => "language", :format => :rss }
 
  50       { :path => "/user/username/diary/rss", :method => :get },
 
  51       { :controller => "diary_entries", :action => "rss", :display_name => "username", :format => :rss }
 
  55       { :path => "/diary/new", :method => :get },
 
  56       { :controller => "diary_entries", :action => "new" }
 
  59       { :path => "/diary", :method => :post },
 
  60       { :controller => "diary_entries", :action => "create" }
 
  63       { :path => "/user/username/diary/1", :method => :get },
 
  64       { :controller => "diary_entries", :action => "show", :display_name => "username", :id => "1" }
 
  67       { :path => "/user/username/diary/1/edit", :method => :get },
 
  68       { :controller => "diary_entries", :action => "edit", :display_name => "username", :id => "1" }
 
  71       { :path => "/user/username/diary/1", :method => :put },
 
  72       { :controller => "diary_entries", :action => "update", :display_name => "username", :id => "1" }
 
  75       { :path => "/user/username/diary/1/hide", :method => :post },
 
  76       { :controller => "diary_entries", :action => "hide", :display_name => "username", :id => "1" }
 
  79       { :path => "/user/username/diary/1/unhide", :method => :post },
 
  80       { :controller => "diary_entries", :action => "unhide", :display_name => "username", :id => "1" }
 
  83       { :path => "/user/username/diary/1/subscribe", :method => :get },
 
  84       { :controller => "diary_entries", :action => "subscribe", :display_name => "username", :id => "1" }
 
  87       { :path => "/user/username/diary/1/subscribe", :method => :post },
 
  88       { :controller => "diary_entries", :action => "subscribe", :display_name => "username", :id => "1" }
 
  91       { :path => "/user/username/diary/1/unsubscribe", :method => :get },
 
  92       { :controller => "diary_entries", :action => "unsubscribe", :display_name => "username", :id => "1" }
 
  95       { :path => "/user/username/diary/1/unsubscribe", :method => :post },
 
  96       { :controller => "diary_entries", :action => "unsubscribe", :display_name => "username", :id => "1" }
 
 100   def test_new_no_login
 
 101     # Make sure that you are redirected to the login page when you
 
 103     get new_diary_entry_path
 
 104     assert_redirected_to login_path(:referer => "/diary/new")
 
 108     # Now try again when logged in
 
 109     session_for(create(:user, :languages => ["en"]))
 
 111     get new_diary_entry_path
 
 113     assert_response :success
 
 114     assert_dom "title", :text => /New Diary Entry/, :count => 1
 
 115     assert_dom "div.content-heading", :count => 1 do
 
 116       assert_dom "h1", :text => /New Diary Entry/, :count => 1
 
 118     assert_dom "div#content", :count => 1 do
 
 119       assert_dom "form[action='/diary'][method=post]", :count => 1 do
 
 120         assert_dom "input#diary_entry_title[name='diary_entry[title]']", :count => 1
 
 121         assert_dom "textarea#diary_entry_body[name='diary_entry[body]']", :text => "", :count => 1
 
 122         assert_dom "select#diary_entry_language_code", :count => 1 do
 
 123           assert_dom "option[selected]", :count => 1 do
 
 124             assert_dom "> @value", "en"
 
 127         assert_dom "input#latitude[name='diary_entry[latitude]']", :count => 1
 
 128         assert_dom "input#longitude[name='diary_entry[longitude]']", :count => 1
 
 129         assert_dom "input[name=commit][type=submit][value=Publish]", :count => 1
 
 130         assert_dom "button[type=button]", :text => "Edit", :count => 1
 
 131         assert_dom "button[type=button]", :text => "Preview", :count => 1
 
 132         assert_dom "input", :count => 4
 
 137   def test_new_get_with_params
 
 138     create(:language, :code => "fr")
 
 139     # Now try creating a diary entry using get
 
 140     session_for(create(:user, :languages => ["en"]))
 
 142     assert_difference "DiaryEntry.count", 0 do
 
 143       get new_diary_entry_path(:diary_entry => { :title => "New Title", :body => "This is a new body for the diary entry", :latitude => "1.1",
 
 144                                                  :longitude => "2.2", :language_code => "fr" })
 
 147     assert_response :success
 
 149     assert_dom "div#content", :count => 1 do
 
 150       assert_dom "form[action='/diary'][method=post]", :count => 1 do
 
 151         assert_dom "input#diary_entry_title[name='diary_entry[title]']", :count => 1 do
 
 152           assert_dom "> @value", "New Title"
 
 154         assert_dom "textarea#diary_entry_body[name='diary_entry[body]']", :count => 1, :text => "This is a new body for the diary entry"
 
 155         assert_dom "select#diary_entry_language_code", :count => 1 do
 
 156           assert_dom "option[selected]", :count => 1 do
 
 157             assert_dom "> @value", "fr"
 
 160         assert_dom "input#latitude[name='diary_entry[latitude]']", :count => 1 do
 
 161           assert_dom "> @value", "1.1"
 
 163         assert_dom "input#longitude[name='diary_entry[longitude]']", :count => 1 do
 
 164           assert_dom "> @value", "2.2"
 
 170   def test_create_no_body
 
 171     # Now try creating a invalid diary entry with an empty body
 
 174     assert_no_difference "DiaryEntry.count" do
 
 175       post diary_entries_path(:diary_entry => { :title => "New Title", :body => "", :latitude => "1.1",
 
 176                                                 :longitude => "2.2", :language_code => "en" })
 
 178     assert_response :success
 
 181     assert_nil UserPreference.find_by(:user => user, :k => "diary.default_language")
 
 185     # Now try creating a diary entry
 
 188     assert_difference "DiaryEntry.count", 1 do
 
 189       post diary_entries_path(:diary_entry => { :title => "New Title", :body => "This is a new body for the diary entry", :latitude => "1.1",
 
 190                                                 :longitude => "2.2", :language_code => "en" })
 
 192     entry = DiaryEntry.last
 
 193     assert_redirected_to diary_entry_path(user, entry)
 
 194     assert_equal user.id, entry.user_id
 
 195     assert_equal "New Title", entry.title
 
 196     assert_equal "This is a new body for the diary entry", entry.body
 
 197     assert_equal "1.1".to_f, entry.latitude
 
 198     assert_equal "2.2".to_f, entry.longitude
 
 199     assert_equal "en", entry.language_code
 
 201     # checks if user was subscribed
 
 202     assert_equal 1, entry.subscribers.length
 
 204     assert_equal "en", UserPreference.find_by(:user => user, :k => "diary.default_language").v
 
 207   def test_create_german
 
 208     create(:language, :code => "de")
 
 212     # Now try creating a diary entry in a different language
 
 213     assert_difference "DiaryEntry.count", 1 do
 
 214       post diary_entries_path(:diary_entry => { :title => "New Title", :body => "This is a new body for the diary entry", :latitude => "1.1",
 
 215                                                 :longitude => "2.2", :language_code => "de" })
 
 217     entry = DiaryEntry.last
 
 218     assert_redirected_to diary_entry_path(user, entry)
 
 219     assert_equal user.id, entry.user_id
 
 220     assert_equal "New Title", entry.title
 
 221     assert_equal "This is a new body for the diary entry", entry.body
 
 222     assert_equal "1.1".to_f, entry.latitude
 
 223     assert_equal "2.2".to_f, entry.longitude
 
 224     assert_equal "de", entry.language_code
 
 226     # checks if user was subscribed
 
 227     assert_equal 1, entry.subscribers.length
 
 229     assert_equal "de", UserPreference.find_by(:user => user, :k => "diary.default_language").v
 
 236     # Generate some spammy content
 
 237     spammy_title = "Spam Spam Spam Spam Spam"
 
 238     spammy_body = 1.upto(50).map { |n| "http://example.com/spam#{n}" }.join(" ")
 
 240     # Try creating a spammy diary entry
 
 241     assert_difference "DiaryEntry.count", 1 do
 
 242       post diary_entries_path(:diary_entry => { :title => spammy_title, :body => spammy_body, :language_code => "en" })
 
 244     entry = DiaryEntry.last
 
 245     assert_redirected_to diary_entry_path(user, entry)
 
 246     assert_equal user.id, entry.user_id
 
 247     assert_equal spammy_title, entry.title
 
 248     assert_equal spammy_body, entry.body
 
 249     assert_equal "en", entry.language_code
 
 250     assert_equal "suspended", User.find(user.id).status
 
 253     assert_redirected_to :controller => :users, :action => :suspended
 
 258     other_user = create(:user)
 
 260     entry = create(:diary_entry, :user => user)
 
 262     # Make sure that you are redirected to the login page when you are
 
 263     # not logged in, without and with the id of the entry you want to edit
 
 264     get edit_diary_entry_path(entry.user, entry)
 
 265     assert_redirected_to login_path(:referer => "/user/#{ERB::Util.u(entry.user.display_name)}/diary/#{entry.id}/edit")
 
 267     session_for(other_user)
 
 269     # Verify that you get redirected to show if you are not the user
 
 270     # that created the entry
 
 271     get edit_diary_entry_path(entry.user, entry)
 
 272     assert_redirected_to :action => :show, :display_name => entry.user.display_name, :id => entry.id
 
 274     session_for(entry.user)
 
 276     # Verify that you get a not found error, when you pass a bogus id
 
 277     get edit_diary_entry_path(entry.user, :id => 9999)
 
 278     assert_response :not_found
 
 279     assert_select "div.content-heading", :count => 1 do
 
 280       assert_select "h1", :text => "No entry with the id: 9999", :count => 1
 
 283     # Now pass the id, and check that you can edit it, when using the same
 
 284     # user as the person who created the entry
 
 285     get edit_diary_entry_path(entry.user, entry)
 
 286     assert_response :success
 
 287     assert_select "title", :text => /Edit Diary Entry/, :count => 1
 
 288     assert_select "div.content-heading", :count => 1 do
 
 289       assert_select "h1", :text => /Edit Diary Entry/, :count => 1
 
 291     assert_select "div#content", :count => 1 do
 
 292       assert_select "form[action='/user/#{ERB::Util.u(entry.user.display_name)}/diary/#{entry.id}'][method=post]", :count => 1 do
 
 293         assert_select "input#diary_entry_title[name='diary_entry[title]'][value='#{entry.title}']", :count => 1
 
 294         assert_select "textarea#diary_entry_body[name='diary_entry[body]']", :text => entry.body, :count => 1
 
 295         assert_select "select#diary_entry_language_code", :count => 1
 
 296         assert_select "input#latitude[name='diary_entry[latitude]']", :count => 1
 
 297         assert_select "input#longitude[name='diary_entry[longitude]']", :count => 1
 
 298         assert_select "input[name=commit][type=submit][value=Update]", :count => 1
 
 299         assert_select "button[type=button]", :text => "Edit", :count => 1
 
 300         assert_select "button[type=button]", :text => "Preview", :count => 1
 
 301         assert_select "input", :count => 5
 
 305     # Now lets see if you can edit the diary entry
 
 306     new_title = "New Title"
 
 307     new_body = "This is a new body for the diary entry"
 
 309     new_longitude = "2.2"
 
 310     new_language_code = "en"
 
 311     put diary_entry_path(entry.user, entry, :diary_entry => { :title => new_title, :body => new_body, :latitude => new_latitude,
 
 312                                                               :longitude => new_longitude, :language_code => new_language_code })
 
 313     assert_redirected_to :action => :show, :display_name => entry.user.display_name, :id => entry.id
 
 315     # Now check that the new data is rendered, when logged in
 
 316     get diary_entry_path(entry.user, entry)
 
 317     assert_response :success
 
 318     assert_template "show"
 
 319     assert_select "head title", :text => /Users' Diaries | /, :count => 1
 
 320     assert_select "div.content-heading", :count => 1 do
 
 321       assert_select "h1", :text => /#{entry.user.display_name}'s Diary/, :count => 1
 
 323     assert_select "div#content", :count => 1 do
 
 324       assert_select "h2", :text => /#{new_title}/, :count => 1
 
 325       # This next line won't work if the text has been run through the htmlize function
 
 326       # due to formatting that could be introduced
 
 327       assert_select "p", :text => /#{new_body}/, :count => 1
 
 328       assert_select "abbr[class='geo'][title='#{number_with_precision(new_latitude, :precision => 4)}; #{number_with_precision(new_longitude, :precision => 4)}']", :count => 1
 
 329       # As we're not logged in, check that you cannot edit
 
 330       assert_select "a[href='/user/#{ERB::Util.u(entry.user.display_name)}/diary/#{entry.id}/edit']", :text => "Edit this entry", :count => 1
 
 333     # and when not logged in as the user who wrote the entry
 
 334     session_for(create(:user))
 
 335     get diary_entry_path(entry.user, entry)
 
 336     assert_response :success
 
 337     assert_template "show"
 
 338     assert_select "head title", :text => /Users' Diaries | /, :count => 1
 
 339     assert_select "div.content-heading", :count => 1 do
 
 340       assert_select "h1", :text => /#{entry.user.display_name}'s Diary/, :count => 1
 
 342     assert_select "div#content", :count => 1 do
 
 343       assert_select "h2", :text => /#{new_title}/, :count => 1
 
 344       # This next line won't work if the text has been run through the htmlize function
 
 345       # due to formatting that could be introduced
 
 346       assert_select "p", :text => /#{new_body}/, :count => 1
 
 347       assert_select "abbr[class=geo][title='#{number_with_precision(new_latitude, :precision => 4)}; #{number_with_precision(new_longitude, :precision => 4)}']", :count => 1
 
 348       # As we're not logged in, check that you cannot edit
 
 349       assert_select "a[href='/user/#{ERB::Util.u(entry.user.display_name)}/diary/#{entry.id}/edit']", false
 
 355     diary_entry = create(:diary_entry, :language_code => "en", :user => user)
 
 357     get edit_diary_entry_path(user, diary_entry)
 
 358     assert_response :success
 
 359     assert_select "span[class=translation_missing]", false, "Missing translation in edit diary entry"
 
 364     other_user = create(:user)
 
 365     diary_entry = create(:diary_entry, :language_code => "en", :user => user, :title => "Original Title")
 
 367     put diary_entry_path(user, diary_entry, :diary_entry => { :title => "Updated Title" })
 
 368     assert_response :forbidden
 
 370     assert_equal "Original Title", diary_entry.title
 
 372     session_for(other_user)
 
 373     put diary_entry_path(user, diary_entry, :diary_entry => { :title => "Updated Title" })
 
 374     assert_redirected_to diary_entry_path(user, diary_entry)
 
 376     assert_equal "Original Title", diary_entry.title
 
 379     put diary_entry_path(user, diary_entry, :diary_entry => { :title => "Updated Title" })
 
 380     assert_redirected_to diary_entry_path(user, diary_entry)
 
 382     assert_equal "Updated Title", diary_entry.title
 
 386     diary_entry = create(:diary_entry)
 
 387     geo_entry = create(:diary_entry, :latitude => 51.50763, :longitude => -0.10781)
 
 388     public_entry = create(:diary_entry, :user => create(:user))
 
 390     # Try a list of all diary entries
 
 391     get diary_entries_path
 
 392     check_diary_index diary_entry, geo_entry, public_entry
 
 397     other_user = create(:user)
 
 399     diary_entry = create(:diary_entry, :user => user)
 
 400     geo_entry = create(:diary_entry, :user => user, :latitude => 51.50763, :longitude => -0.10781)
 
 401     _other_entry = create(:diary_entry, :user => other_user)
 
 403     # Try a list of diary entries for a valid user
 
 404     get diary_entries_path(:display_name => user.display_name)
 
 405     check_diary_index diary_entry, geo_entry
 
 407     # Try a list of diary entries for an invalid user
 
 408     get diary_entries_path(:display_name => "No Such User")
 
 409     assert_response :not_found
 
 410     assert_template "users/no_such_user"
 
 413   def test_index_friends
 
 415     other_user = create(:user)
 
 416     follow = create(:follow, :follower => user)
 
 417     diary_entry = create(:diary_entry, :user => follow.following)
 
 418     _other_entry = create(:diary_entry, :user => other_user)
 
 420     # Try a list of diary entries for your friends when not logged in
 
 421     get friends_diary_entries_path
 
 422     assert_redirected_to login_path(:referer => "/diary/friends")
 
 424     # Try a list of diary entries for your friends when logged in
 
 426     get friends_diary_entries_path
 
 427     check_diary_index diary_entry
 
 428     session_for(other_user)
 
 429     get friends_diary_entries_path
 
 433   def test_index_nearby
 
 434     user = create(:user, :home_lat => 12, :home_lon => 12)
 
 435     nearby_user = create(:user, :home_lat => 11.9, :home_lon => 12.1)
 
 437     diary_entry = create(:diary_entry, :user => user)
 
 439     # Try a list of diary entries for nearby users when not logged in
 
 440     get nearby_diary_entries_path
 
 441     assert_redirected_to login_path(:referer => "/diary/nearby")
 
 443     # Try a list of diary entries for nearby users when logged in
 
 444     session_for(nearby_user)
 
 445     get nearby_diary_entries_path
 
 446     check_diary_index diary_entry
 
 448     get nearby_diary_entries_path
 
 452   def test_index_language
 
 453     create(:language, :code => "de")
 
 454     create(:language, :code => "sl")
 
 455     diary_entry_en = create(:diary_entry, :language_code => "en")
 
 456     diary_entry_en2 = create(:diary_entry, :language_code => "en")
 
 457     diary_entry_de = create(:diary_entry, :language_code => "de")
 
 459     # Try a list of diary entries in english
 
 460     get diary_entries_path(:language => "en")
 
 461     check_diary_index diary_entry_en, diary_entry_en2
 
 463     # Try a list of diary entries in german
 
 464     get diary_entries_path(:language => "de")
 
 465     check_diary_index diary_entry_de
 
 467     # Try a list of diary entries in slovenian
 
 468     get diary_entries_path(:language => "sl")
 
 473     create_list(:diary_entry, 50)
 
 474     check_pagination_of_50_entries diary_entries_path
 
 477   def test_index_user_paged
 
 479     create_list(:diary_entry, 50, :user => user)
 
 481     check_pagination_of_50_entries user_diary_entries_path(user)
 
 484   def test_index_invalid_paged
 
 485     # Try some invalid paged accesses
 
 486     %w[-1 fred].each do |id|
 
 487       get diary_entries_path(:before => id)
 
 488       assert_redirected_to :controller => :errors, :action => :bad_request
 
 490       get diary_entries_path(:after => id)
 
 491       assert_redirected_to :controller => :errors, :action => :bad_request
 
 496     create(:language, :code => "de")
 
 497     create(:diary_entry, :language_code => "en")
 
 498     create(:diary_entry, :language_code => "en")
 
 499     create(:diary_entry, :language_code => "de")
 
 502     assert_response :success, "Should be able to get a diary RSS"
 
 503     assert_select "rss", :count => 1 do
 
 504       assert_select "channel", :count => 1 do
 
 505         assert_select "channel>title", :count => 1
 
 506         assert_select "image", :count => 1
 
 507         assert_select "channel>item", :count => 3
 
 512   def test_rss_language
 
 513     create(:language, :code => "de")
 
 514     create(:diary_entry, :language_code => "en")
 
 515     create(:diary_entry, :language_code => "en")
 
 516     create(:diary_entry, :language_code => "de")
 
 518     get diary_rss_path(:language => "en")
 
 519     assert_response :success, "Should be able to get a specific language diary RSS"
 
 520     assert_select "rss>channel>item", :count => 2 # , "Diary entries should be filtered by language"
 
 523   #  def test_rss_nonexisting_language
 
 524   #    get :rss, :params => { :language => 'xx', :format => :rss }
 
 525   #    assert_response :not_found, "Should not be able to get a nonexisting language diary RSS"
 
 528   def test_rss_language_with_no_entries
 
 529     create(:language, :code => "sl")
 
 530     create(:diary_entry, :language_code => "en")
 
 532     get diary_rss_path(:language => "sl")
 
 533     assert_response :success, "Should be able to get a specific language diary RSS"
 
 534     assert_select "rss>channel>item", :count => 0 # , "Diary entries should be filtered by language"
 
 539     other_user = create(:user)
 
 540     create(:diary_entry, :user => user)
 
 541     create(:diary_entry, :user => user)
 
 542     create(:diary_entry, :user => other_user)
 
 544     get diary_rss_path(:display_name => user.display_name)
 
 545     assert_response :success, "Should be able to get a specific users diary RSS"
 
 546     assert_select "rss>channel>item", :count => 2 # , "Diary entries should be filtered by user"
 
 549   def test_rss_nonexisting_user
 
 550     # Try a user that has never existed
 
 551     get diary_rss_path(:display_name => "fakeUsername76543")
 
 552     assert_response :not_found, "Should not be able to get a nonexisting users diary RSS"
 
 554     # Try a suspended user
 
 555     get diary_rss_path(:display_name => create(:user, :suspended).display_name)
 
 556     assert_response :not_found, "Should not be able to get a suspended users diary RSS"
 
 559     get diary_rss_path(:display_name => create(:user, :deleted).display_name)
 
 560     assert_response :not_found, "Should not be able to get a deleted users diary RSS"
 
 563   def test_rss_character_escaping
 
 564     create(:diary_entry, :title => "<script>")
 
 567     assert_match "<title><script></title>", response.body
 
 571     create(:diary_entry, :created_at => 7.hours.ago)
 
 572     create(:diary_entry, :created_at => 5.hours.ago)
 
 574     assert_select "rss>channel>item", :count => 2
 
 576     with_settings(:diary_feed_delay => 6) do
 
 578       assert_select "rss>channel>item", :count => 1
 
 584     suspended_user = create(:user, :suspended)
 
 585     deleted_user = create(:user, :deleted)
 
 587     # Try a normal entry that should work
 
 588     diary_entry = create(:diary_entry, :user => user)
 
 589     get diary_entry_path(user, diary_entry)
 
 590     assert_response :success
 
 591     assert_template :show
 
 593     # Try a non-integer ID
 
 594     get "/user/#{CGI.escape(user.display_name)}/diary/#{diary_entry.id})"
 
 595     assert_response :not_found
 
 596     assert_template "rescues/routing_error"
 
 598     # Try a deleted entry
 
 599     diary_entry_deleted = create(:diary_entry, :user => user, :visible => false)
 
 600     get diary_entry_path(user, diary_entry_deleted)
 
 601     assert_response :not_found
 
 603     # Try an entry by a suspended user
 
 604     diary_entry_suspended_user = create(:diary_entry, :user => suspended_user)
 
 605     get diary_entry_path(suspended_user, diary_entry_suspended_user)
 
 606     assert_response :not_found
 
 608     # Try an entry by a deleted user
 
 609     diary_entry_deleted_user = create(:diary_entry, :user => deleted_user)
 
 610     get diary_entry_path(deleted_user, diary_entry_deleted_user)
 
 611     assert_response :not_found
 
 613     # Now try as a moderator
 
 614     session_for(create(:moderator_user))
 
 615     get diary_entry_path(user, diary_entry_deleted)
 
 616     assert_response :success
 
 617     assert_template :show
 
 619     # Finally try as an administrator
 
 620     session_for(create(:administrator_user))
 
 621     get diary_entry_path(user, diary_entry_deleted)
 
 622     assert_response :success
 
 623     assert_template :show
 
 626   def test_show_hidden_comments
 
 627     # Get a diary entry that has hidden comments
 
 629     diary_entry = create(:diary_entry, :user => user)
 
 630     visible_comment = create(:diary_comment, :diary_entry => diary_entry)
 
 631     suspended_user_comment = create(:diary_comment, :diary_entry => diary_entry, :user => create(:user, :suspended))
 
 632     deleted_user_comment = create(:diary_comment, :diary_entry => diary_entry, :user => create(:user, :deleted))
 
 633     hidden_comment = create(:diary_comment, :diary_entry => diary_entry, :visible => false)
 
 635     get diary_entry_path(user, diary_entry)
 
 636     assert_response :success
 
 637     assert_template :show
 
 638     assert_select "div.comments" do
 
 639       assert_select "p#comment#{visible_comment.id}", :count => 1
 
 640       assert_select "p#comment#{suspended_user_comment.id}", :count => 0
 
 641       assert_select "p#comment#{deleted_user_comment.id}", :count => 0
 
 642       assert_select "p#comment#{hidden_comment.id}", :count => 0
 
 646   def test_show_og_title
 
 648     diary_entry = create(:diary_entry, :user => user, :title => "The Important Blog Post")
 
 650     get diary_entry_path(user, diary_entry)
 
 651     assert_response :success
 
 652     assert_dom "head meta[property='og:title']" do
 
 653       assert_dom "> @content", "The Important Blog Post"
 
 657   def test_show_og_image_with_no_image
 
 659     diary_entry = create(:diary_entry, :user => user, :body => "nothing")
 
 661     get diary_entry_path(user, diary_entry)
 
 662     assert_response :success
 
 663     assert_dom "head meta[property='og:image']" do
 
 664       assert_dom "> @content", ActionController::Base.helpers.image_url("osm_logo_256.png", :host => root_url)
 
 666     assert_dom "head meta[property='og:image:alt']" do
 
 667       assert_dom "> @content", "OpenStreetMap logo"
 
 671   def test_show_og_image
 
 673     diary_entry = create(:diary_entry, :user => user, :body => "")
 
 675     get diary_entry_path(user, diary_entry)
 
 676     assert_response :success
 
 677     assert_dom "head meta[property='og:image']" do
 
 678       assert_dom "> @content", "https://example.com/picture.jpg"
 
 680     assert_dom "head meta[property='og:image:alt']" do
 
 681       assert_dom "> @content", "some picture"
 
 685   def test_show_og_image_with_relative_uri
 
 687     diary_entry = create(:diary_entry, :user => user, :body => "")
 
 689     get diary_entry_path(user, diary_entry)
 
 690     assert_response :success
 
 691     assert_dom "head meta[property='og:image']" do
 
 692       assert_dom "> @content", "#{root_url}picture.jpg"
 
 694     assert_dom "head meta[property='og:image:alt']" do
 
 695       assert_dom "> @content", "some local picture"
 
 699   def test_show_og_image_with_spaces
 
 701     diary_entry = create(:diary_entry, :user => user, :body => "")
 
 703     get diary_entry_path(user, diary_entry)
 
 704     assert_response :success
 
 705     assert_dom "head meta[property='og:image']" do
 
 706       assert_dom "> @content", "https://example.com/the%20picture.jpg"
 
 708     assert_dom "head meta[property='og:image:alt']" do
 
 709       assert_dom "> @content", "some picture"
 
 713   def test_show_og_image_with_relative_uri_and_spaces
 
 715     diary_entry = create(:diary_entry, :user => user, :body => "")
 
 717     get diary_entry_path(user, diary_entry)
 
 718     assert_response :success
 
 719     assert_dom "head meta[property='og:image']" do
 
 720       assert_dom "> @content", "#{root_url}the%20picture.jpg"
 
 722     assert_dom "head meta[property='og:image:alt']" do
 
 723       assert_dom "> @content", "some local picture"
 
 727   def test_show_og_image_with_invalid_uri
 
 729     diary_entry = create(:diary_entry, :user => user, :body => "")
 
 731     get diary_entry_path(user, diary_entry)
 
 732     assert_response :success
 
 733     assert_dom "head meta[property='og:image']" do
 
 734       assert_dom "> @content", ActionController::Base.helpers.image_url("osm_logo_256.png", :host => root_url)
 
 736     assert_dom "head meta[property='og:image:alt']" do
 
 737       assert_dom "> @content", "OpenStreetMap logo"
 
 741   def test_show_og_image_without_alt
 
 743     diary_entry = create(:diary_entry, :user => user, :body => "<img src='https://example.com/no_alt.gif'>")
 
 745     get diary_entry_path(user, diary_entry)
 
 746     assert_response :success
 
 747     assert_dom "head meta[property='og:image']" do
 
 748       assert_dom "> @content", "https://example.com/no_alt.gif"
 
 750     assert_dom "head meta[property='og:image:alt']", :count => 0
 
 753   def test_show_no_og_description
 
 755     diary_entry = create(:diary_entry, :user => user, :body => "")
 
 757     get diary_entry_path(user, diary_entry)
 
 758     assert_response :success
 
 759     assert_dom "head meta[property='og:description']" do
 
 760       assert_dom "> @content", I18n.t("layouts.intro_text")
 
 764   def test_show_og_description
 
 766     diary_entry = create(:diary_entry, :user => user, :body => "# Hello\n\n\n\nFirst paragraph.\n\nSecond paragraph.")
 
 768     get diary_entry_path(user, diary_entry)
 
 769     assert_response :success
 
 770     assert_dom "head meta[property='og:description']" do
 
 771       assert_dom "> @content", "First paragraph."
 
 775   def test_show_article_published_time
 
 777     diary_entry = create(:diary_entry, :user => user, :created_at => "2020-03-04")
 
 779     get diary_entry_path(user, diary_entry)
 
 780     assert_response :success
 
 781     assert_dom "head meta[property='article:published_time']" do
 
 782       assert_dom "> @content", "2020-03-04T00:00:00Z"
 
 788     diary_entry = create(:diary_entry, :user => user)
 
 790     # Try without logging in
 
 791     post hide_diary_entry_path(user, diary_entry)
 
 792     assert_response :forbidden
 
 793     assert DiaryEntry.find(diary_entry.id).visible
 
 795     # Now try as a normal user
 
 797     post hide_diary_entry_path(user, diary_entry)
 
 798     assert_redirected_to :controller => :errors, :action => :forbidden
 
 799     assert DiaryEntry.find(diary_entry.id).visible
 
 801     # Now try as a moderator
 
 802     session_for(create(:moderator_user))
 
 803     post hide_diary_entry_path(user, diary_entry)
 
 804     assert_redirected_to :action => :index, :display_name => user.display_name
 
 805     assert_not DiaryEntry.find(diary_entry.id).visible
 
 808     diary_entry.reload.update(:visible => true)
 
 810     # Finally try as an administrator
 
 811     session_for(create(:administrator_user))
 
 812     post hide_diary_entry_path(user, diary_entry)
 
 813     assert_redirected_to :action => :index, :display_name => user.display_name
 
 814     assert_not DiaryEntry.find(diary_entry.id).visible
 
 820     # Try without logging in
 
 821     diary_entry = create(:diary_entry, :user => user, :visible => false)
 
 822     post unhide_diary_entry_path(user, diary_entry)
 
 823     assert_response :forbidden
 
 824     assert_not DiaryEntry.find(diary_entry.id).visible
 
 826     # Now try as a normal user
 
 828     post unhide_diary_entry_path(user, diary_entry)
 
 829     assert_redirected_to :controller => :errors, :action => :forbidden
 
 830     assert_not DiaryEntry.find(diary_entry.id).visible
 
 832     # Now try as a moderator
 
 833     session_for(create(:moderator_user))
 
 834     post unhide_diary_entry_path(user, diary_entry)
 
 835     assert_redirected_to :action => :index, :display_name => user.display_name
 
 836     assert DiaryEntry.find(diary_entry.id).visible
 
 839     diary_entry.reload.update(:visible => true)
 
 841     # Finally try as an administrator
 
 842     session_for(create(:administrator_user))
 
 843     post unhide_diary_entry_path(user, diary_entry)
 
 844     assert_redirected_to :action => :index, :display_name => user.display_name
 
 845     assert DiaryEntry.find(diary_entry.id).visible
 
 848   def test_subscribe_page
 
 850     other_user = create(:user)
 
 851     diary_entry = create(:diary_entry, :user => user)
 
 852     path = diary_entry_subscribe_path(user, diary_entry)
 
 855     assert_redirected_to login_path(:referer => path)
 
 857     session_for(other_user)
 
 859     assert_response :success
 
 860     assert_dom ".content-body" do
 
 861       assert_dom "a[href='#{diary_entry_path(user, diary_entry)}']", :text => diary_entry.title
 
 862       assert_dom "a[href='#{user_path(user)}']", :text => user.display_name
 
 866   def test_subscribe_success
 
 868     other_user = create(:user)
 
 869     diary_entry = create(:diary_entry, :user => user)
 
 871     session_for(other_user)
 
 872     assert_difference "diary_entry.subscribers.count", 1 do
 
 873       post diary_entry_subscribe_path(user, diary_entry)
 
 875     assert_response :redirect
 
 878   def test_subscribe_fail
 
 880     other_user = create(:user)
 
 882     diary_entry = create(:diary_entry, :user => user)
 
 885     assert_no_difference "diary_entry.subscribers.count" do
 
 886       post diary_entry_subscribe_path(user, diary_entry)
 
 888     assert_response :forbidden
 
 890     session_for(other_user)
 
 893     post diary_entry_subscribe_path("username", 999111)
 
 894     assert_response :not_found
 
 896     # trying to subscribe when already subscribed
 
 897     post diary_entry_subscribe_path(user, diary_entry)
 
 898     assert_no_difference "diary_entry.subscribers.count" do
 
 899       post diary_entry_subscribe_path(user, diary_entry)
 
 903   def test_unsubscribe_page
 
 905     other_user = create(:user)
 
 906     diary_entry = create(:diary_entry, :user => user)
 
 907     path = diary_entry_unsubscribe_path(user, diary_entry)
 
 910     assert_redirected_to login_path(:referer => path)
 
 912     session_for(other_user)
 
 914     assert_response :success
 
 915     assert_dom ".content-body" do
 
 916       assert_dom "a[href='#{diary_entry_path(user, diary_entry)}']", :text => diary_entry.title
 
 917       assert_dom "a[href='#{user_path(user)}']", :text => user.display_name
 
 921   def test_unsubscribe_success
 
 923     other_user = create(:user)
 
 925     diary_entry = create(:diary_entry, :user => user)
 
 926     create(:diary_entry_subscription, :diary_entry => diary_entry, :user => other_user)
 
 928     session_for(other_user)
 
 929     assert_difference "diary_entry.subscribers.count", -1 do
 
 930       post diary_entry_unsubscribe_path(user, diary_entry)
 
 932     assert_response :redirect
 
 935   def test_unsubscribe_fail
 
 937     other_user = create(:user)
 
 939     diary_entry = create(:diary_entry, :user => user)
 
 942     assert_no_difference "diary_entry.subscribers.count" do
 
 943       post diary_entry_unsubscribe_path(user, diary_entry)
 
 945     assert_response :forbidden
 
 947     session_for(other_user)
 
 950     post diary_entry_unsubscribe_path("username", 999111)
 
 951     assert_response :not_found
 
 953     # trying to unsubscribe when not subscribed
 
 954     assert_no_difference "diary_entry.subscribers.count" do
 
 955       post diary_entry_unsubscribe_path(user, diary_entry)
 
 961   def check_diary_index(*entries)
 
 962     assert_response :success
 
 963     assert_template "index"
 
 964     assert_no_missing_translations
 
 965     assert_select "article.diary_post", entries.count
 
 967     entries.each do |entry|
 
 968       assert_select "a[href=?]", "/user/#{ERB::Util.u(entry.user.display_name)}/diary/#{entry.id}"
 
 972   def check_pagination_of_50_entries(path)
 
 973     # Try and get the index
 
 975     assert_response :success
 
 976     assert_select "article.diary_post", :count => 20
 
 977     check_no_page_link "Newer Entries"
 
 978     path = check_page_link "Older Entries"
 
 980     # Try and get the second page
 
 982     assert_response :success
 
 983     assert_select "article.diary_post", :count => 20
 
 984     check_page_link "Newer Entries"
 
 985     path = check_page_link "Older Entries"
 
 987     # Try and get the third page
 
 989     assert_response :success
 
 990     assert_select "article.diary_post", :count => 10
 
 991     path = check_page_link "Newer Entries"
 
 992     check_no_page_link "Older Entries"
 
 994     # Go back to the second page
 
 996     assert_response :success
 
 997     assert_select "article.diary_post", :count => 20
 
 998     path = check_page_link "Newer Entries"
 
 999     check_page_link "Older Entries"
 
1001     # Go back to the first page
 
1003     assert_response :success
 
1004     assert_select "article.diary_post", :count => 20
 
1005     check_no_page_link "Newer Entries"
 
1006     check_page_link "Older Entries"
 
1009   def check_no_page_link(name)
 
1010     assert_select "a.page-link", { :text => /#{Regexp.quote(name)}/, :count => 0 }, "unexpected #{name} page link"
 
1013   def check_page_link(name)
 
1014     assert_select "a.page-link", { :text => /#{Regexp.quote(name)}/ }, "missing #{name} page link" do |buttons|
 
1015       return buttons.first.attributes["href"].value