From b45f3d3024438976130778685ac1012a6000e738 Mon Sep 17 00:00:00 2001 From: ktmouk Date: Tue, 17 Oct 2023 03:14:04 +0900 Subject: [PATCH] Fix code block rendering not working inside details (#20229) --- app/liquid_tags/details_tag.rb | 3 +- spec/liquid_tags/details_tag_spec.rb | 137 +++++++++++++++++++++++++-- 2 files changed, 131 insertions(+), 9 deletions(-) diff --git a/app/liquid_tags/details_tag.rb b/app/liquid_tags/details_tag.rb index 6c377b154..19ea1cac1 100644 --- a/app/liquid_tags/details_tag.rb +++ b/app/liquid_tags/details_tag.rb @@ -12,8 +12,7 @@ class DetailsTag < Liquid::Block content = Nokogiri::HTML.parse(super) parsed_content = sanitize( content.xpath("//html/body").inner_html, - tags: MarkdownProcessor::AllowedTags::RENDERED_MARKDOWN_SCRUBBER, - attributes: MarkdownProcessor::AllowedAttributes::RENDERED_MARKDOWN_SCRUBBER, + scrubber: RenderedMarkdownScrubber.new, ) ApplicationController.render( diff --git a/spec/liquid_tags/details_tag_spec.rb b/spec/liquid_tags/details_tag_spec.rb index 5509840c1..83b8f591c 100644 --- a/spec/liquid_tags/details_tag_spec.rb +++ b/spec/liquid_tags/details_tag_spec.rb @@ -2,19 +2,142 @@ require "rails_helper" RSpec.describe DetailsTag, type: :liquid_tag do describe "#render" do - let(:summary) { "Click to see the answer!" } - let(:content) { "The answer is Forem!" } - def generate_details_liquid(summary, content) Liquid::Template.register_tag("details", described_class) Liquid::Template.parse("{% details #{summary} %} #{content} {% enddetails %}") end - it "generates proper details div with summary" do - rendered = generate_details_liquid(summary, content).render + context "when content has simple text" do + let(:summary) { "Click to see the answer!" } + let(:content) { "The answer is Forem!" } - expect(rendered).to include("Click to see the answer!') # rubocop:disable Style/StringLiterals + it "generates proper details div with summary" do + rendered = generate_details_liquid(summary, content).render + + expect(rendered).to include("Click to see the answer!") + end + end + + context "when content has a strong tag" do + let(:summary) { "Click to see the answer!" } + let(:content) { "foo" } + + it "accepts a strong tag" do + rendered = generate_details_liquid(summary, content).render + + expect(rendered).to include("foo") + expect(rendered).to include("Click to see the answer!") + end + end + + context "when content has a link tag" do + let(:summary) { "Click to see the answer!" } + let(:content) { "link" } + + it "accepts a link tag" do + rendered = generate_details_liquid(summary, content).render + + expect(rendered).to include("link") + expect(rendered).to include("Click to see the answer!") + end + end + + context "when content has a h2 tag" do + let(:summary) { "Click to see the answer!" } + let(:content) { "

heading

" } + + it "accepts a h2 tag" do + rendered = generate_details_liquid(summary, content).render + + expect(rendered).to include("

heading

") + expect(rendered).to include("Click to see the answer!") + end + end + + context "when content has a list" do + let(:summary) { "Click to see the answer!" } + let(:content) { "
  1. one
  2. two
" } + + it "accepts a list tag" do + rendered = generate_details_liquid(summary, content).render + + expect(rendered).to include("
  • one
  • ") + expect(rendered).to include("
  • two
  • ") + expect(rendered).to include("Click to see the answer!") + end + end + + context "when content has an img tag" do + let(:summary) { "Click to see the answer!" } + let(:content) { "\"\"" } + + it "accepts an img tag" do + rendered = generate_details_liquid(summary, content).render + + expect(rendered).to include("\"\"") + expect(rendered).to include("Click to see the answer!") + end + end + + context "when content has a code tag" do + let(:summary) { "Click to see the answer!" } + let(:content) { "aaaa" } + + it "accepts a code tag" do + rendered = generate_details_liquid(summary, content).render + + expect(rendered).to include("aaaa") + expect(rendered).to include("Click to see the answer!") + end + end + + context "when content has a div tag" do + let(:summary) { "Click to see the answer!" } + let(:content) { "
    foo
    " } + + it "removes a div tag" do + rendered = generate_details_liquid(summary, content).render + expect(rendered).not_to include("div") + expect(rendered).to include("Click to see the answer!") + end + end + + context "when content has unpermitted tags" do + let(:summary) { "Click to see the answer!" } + let(:content) { "foo" } + + it "removes unpermitted tags" do + rendered = generate_details_liquid(summary, content).render + expect(rendered).not_to include("script") + expect(rendered).not_to include("object") + expect(rendered).to include("Click to see the answer!") + end + end + + context "when content has an unpermitted attribute" do + let(:summary) { "Click to see the answer!" } + let(:content) { "

    foo

    " } + + it "removes an unpermitted attribute" do + rendered = generate_details_liquid(summary, content).render + expect(rendered).not_to include("onclick") + expect(rendered).to include("

    foo

    ") + expect(rendered).to include("Click to see the answer!") + end + end + + context "when content has tags for creating a code block" do + let(:summary) { "Click to see the answer!" } + let(:content) { "
    foo
    " } + + it "accepts these tags" do + rendered = generate_details_liquid(summary, content).render + expect(rendered).to include( + "
    foo
    ", + ) + expect(rendered).to include("Click to see the answer!") + end end end end