From 5742dfaf73fb44f027e53cac98cf179c65c20a35 Mon Sep 17 00:00:00 2001 From: Rosa Gutierrez Date: Fri, 11 Sep 2026 18:33:06 +0200 Subject: [PATCH] Cover markup-only OpenGraph title and description in link previews Link previews fetch a page's OpenGraph title and description, and Opengraph::Metadata strips tags from both before the values reach the browser. When a field consists entirely of a markup tag, stripping leaves it blank, the metadata fails its presence validation, and the unfurl endpoint returns no content, so no preview is produced. Add regression tests at the model and controller layers that pin this: a title or description made only of a markup tag is stripped to blank and rejected, and the endpoint answers 204. The existing sanitize tests only cover fields that keep non-blank text after stripping, so this blank-and-rejected path was previously untested. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_0186eyzivcTn6wqjEE4Wnxdt --- .../unfurl_links_controller_test.rb | 15 ++++++++++++ test/models/opengraph/metadata_test.rb | 23 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/test/controllers/unfurl_links_controller_test.rb b/test/controllers/unfurl_links_controller_test.rb index af04625..a97d045 100644 --- a/test/controllers/unfurl_links_controller_test.rb +++ b/test/controllers/unfurl_links_controller_test.rb @@ -37,6 +37,21 @@ class UnfurlLinksControllerTest < ActionDispatch::IntegrationTest assert_response :no_content end + test "create returns no content when the title and description are only a markup tag" do + image_tag = "" + body = "" \ + "" \ + "" \ + "" \ + "" \ + "" + WebMock.stub_request(:get, "https://www.example.com/").to_return(status: 200, body: body, headers: { content_type: "text/html" }) + WebMock.stub_request(:head, "https://example.com/image.png").to_return(status: 200, headers: { content_type: "image/png" }) + + post unfurl_link_url, params: { url: "https://www.example.com" } + assert_response :no_content + end + test "create with a missing URL" do assert_raise ActionController::ParameterMissing do post unfurl_link_url, params: { url: "" } diff --git a/test/models/opengraph/metadata_test.rb b/test/models/opengraph/metadata_test.rb index 1d9baf7..1b83d64 100644 --- a/test/models/opengraph/metadata_test.rb +++ b/test/models/opengraph/metadata_test.rb @@ -147,6 +147,29 @@ class Opengraph::MetadataTest < ActiveSupport::TestCase assert_equal "Hello", metadata.description end + test "a title or description that is entirely a markup tag is stripped to blank and rejected" do + body = <<~HTML + + + + + + + + HTML + + WebMock.stub_request(:get, "https://www.example.com/").to_return(status: 200, body: body, headers: { content_type: "text/html" }) + WebMock.stub_request(:head, "https://example.com/image.png").to_return(status: 200, headers: { content_type: "image/png" }) + + metadata = Opengraph::Metadata.from_url("https://www.example.com") + + assert_not metadata.valid? + assert_equal "", metadata.title + assert_equal "", metadata.description + assert_includes metadata.errors.full_messages, "Title can't be blank" + assert_includes metadata.errors.full_messages, "Description can't be blank" + end + test "does not allow SVG content type for preview image" do body = <<~HTML