From 36a4194ee3013dfa834aa8d4d57b0bfacf724a1a Mon Sep 17 00:00:00 2001 From: erdgeist Date: Thu, 30 Jul 2026 04:41:07 +0200 Subject: Emit per-page Open Graph metadata Replaces one hardcoded German description and an unrenderable SVG with per-page title, description, canonical URL, locale and publication date, plus the card variant or a site-wide default. --- test/controllers/content_controller_test.rb | 76 ++++++++++++++++++++++ .../controllers/shared_previews_controller_test.rb | 15 +++++ 2 files changed, 91 insertions(+) (limited to 'test/controllers') diff --git a/test/controllers/content_controller_test.rb b/test/controllers/content_controller_test.rb index 9731d082..304fd921 100644 --- a/test/controllers/content_controller_test.rb +++ b/test/controllers/content_controller_test.rb @@ -114,6 +114,82 @@ class ContentControllerTest < ActionController::TestCase assert_response :success end + + test "a published page emits article social metadata" do + node = create_node_under_root "og_article_test" + draft = find_or_create_draft(node, @user1) + draft.title = "Offener Brief" + draft.abstract = "Wir veröffentlichen den Wortlaut eines Offenen Briefes." + draft.save + node.publish_draft! + + get :render_page, params: { :locale => "de", :page_path => ["og_article_test"] } + + assert_response :success + assert_select "meta[property='og:type'][content=?]", "article" + assert_select "meta[property='og:title'][content=?]", "Offener Brief" + assert_select "meta[property='og:site_name'][content=?]", "Chaos Computer Club" + assert_select "meta[property='og:locale'][content=?]", "de_DE" + assert_select "meta[property='article:published_time']" + + # og:title carries the bare title; page_title's "CCC | " prefix belongs + # to only, since platforms render og:site_name separately. + assert_select "title", :text => "CCC | Offener Brief" + + # A canonical URL must not carry a query string. + canonical = css_select("link[rel=canonical]").first["href"] + assert_match %r{/og_article_test\z}, canonical + + assert_select "meta[name=robots]", false, "a public page must be indexable" + end + + test "a page without a headline asset falls back to the default card" do + node = create_node_under_root "og_fallback_test" + find_or_create_draft(node, @user1).update!(:title => "Ohne Aufmacher") + node.publish_draft! + + get :render_page, params: { :locale => "de", :page_path => ["og_fallback_test"] } + + assert_response :success + assert_select "meta[property='og:image'][content=?]", + "http://test.host/images/social_default.png" + assert_select "meta[property='og:image:width'][content=?]", "1200" + assert_select "meta[property='og:image:height'][content=?]", "630" + end + + test "a page with a headline asset points at its social card" do + node = create_node_under_root "og_variant_test" + draft = find_or_create_draft(node, @user1) + draft.title = "Mit Aufmacher" + draft.save + node.publish_draft! + node.reload + + asset = Asset.create!(:name => "aufmacher", + :upload_file_name => "aufmacher.png", + :upload_content_type => "image/png", + :upload_updated_at => Time.at(1_700_000_000)) + node.attach_asset!(asset, :user => @user1, :headline => true) + + # has_variant? only tests File.exist?, so touching the path is enough + # and no ImageMagick runs in the suite. image/png takes .jpg for the + # card, per variant_filename's per-style rule. + card = Rails.root.join("tmp", "test_uploads", asset.id.to_s, "og", "aufmacher.jpg") + + begin + FileUtils.mkdir_p(File.dirname(card)) + FileUtils.touch(card) + + get :render_page, params: { :locale => "de", :page_path => ["og_variant_test"] } + + assert_response :success + assert_select "meta[property='og:image'][content=?]", + "http://test.host/system/uploads/#{asset.id}/og/aufmacher.jpg?v=1700000000" + assert_select "meta[property='og:image:alt'][content=?]", "aufmacher" + ensure + FileUtils.rm_rf(Rails.root.join("tmp", "test_uploads", asset.id.to_s)) + end + end protected diff --git a/test/controllers/shared_previews_controller_test.rb b/test/controllers/shared_previews_controller_test.rb index 4ebc785f..6d4588a8 100644 --- a/test/controllers/shared_previews_controller_test.rb +++ b/test/controllers/shared_previews_controller_test.rb @@ -32,4 +32,19 @@ class SharedPreviewsControllerTest < ActionController::TestCase assert_redirected_to node.head.public_link end + + test "a shared preview emits no social metadata and is not indexable" do + node = Node.root.children.create!(:slug => "shared_preview_no_og_test") + node.draft.update!(:title => "Unveröffentlichter Entwurf") + node.draft.ensure_preview_token! + + get :show, params: { :token => node.draft.preview_token } + + assert_response :success + + # An unfurled preview link would otherwise hand the draft's title, + # abstract and headline image to everyone in the chat room. + assert_select "meta[property^='og:']", false, "a preview must emit no og tags" + assert_select "meta[name=robots][content=?]", "noindex, nofollow" + end end -- cgit v1.3