FIX: elided content in email should always have an href

Not 100% sure why the changes in `PrettyText.format_for_email` raised this issue, but we were missing adding a link to the Discourse instance whenever we are replacing the elided part of a post with a link to either the post or the Discourse instance in the email.

Also reformated the specs using better variable names (sometimes a variable named `md` would contain some html) and used the `match_html` helper for all the tests.
This commit is contained in:
Régis Hanol 2024-05-22 10:42:58 +02:00
parent 8f7a3e5b29
commit d4af30f26d
2 changed files with 47 additions and 29 deletions

View File

@ -37,7 +37,7 @@ after_initialize do
.each do |el| .each do |el|
text = el.css("summary").text text = el.css("summary").text
link = fragment.document.create_element("a") link = fragment.document.create_element("a")
link["href"] = post.url if post link["href"] = post&.url.presence || Discourse.base_url
link.content = I18n.t("details.excerpt_details") link.content = I18n.t("details.excerpt_details")
el.replace CGI.escapeHTML(text) + " " + link.to_html el.replace CGI.escapeHTML(text) + " " + link.to_html
end end

View File

@ -6,43 +6,54 @@ RSpec.describe PrettyText do
let(:post) { Fabricate(:post) } let(:post) { Fabricate(:post) }
it "supports details tag" do it "supports details tag" do
cooked_html = <<~HTML.gsub("\n", "") cooked_html = PrettyText.cook <<~MARKDOWN
[details="foo"]
bar
[/details]
MARKDOWN
expect(cooked_html).to match_html <<~HTML
<details> <details>
<summary> <summary>foo</summary>
foo</summary> <p>bar</p>
<p>bar</p>
</details> </details>
HTML HTML
expect(cooked_html).to match_html(cooked_html)
expect(PrettyText.cook("[details=foo]\nbar\n[/details]").gsub("\n", "")).to match_html(
cooked_html,
)
end end
it "deletes elided content" do it "deletes elided content" do
cooked_html = PrettyText.cook("Hello World\n\n<details class='elided'>42</details>") cooked_html = PrettyText.cook <<~MARKDOWN
mail_html = "<p>Hello World</p>\n<a href=\"http://test.localhost\">(click for more details)</a>" Hello World
expect(PrettyText.format_for_email(cooked_html)).to match_html(mail_html) <details class='elided'>42</details>
MARKDOWN
email_html = PrettyText.format_for_email(cooked_html)
expect(email_html).to match_html <<~HTML
<p>Hello World</p>
<a href="#{Discourse.base_url}">#{I18n.t("details.excerpt_details")}</a>
HTML
end end
it "can replace spoilers in emails" do it "can replace spoilers in emails" do
md = PrettyText.cook(<<~MD) cooked_html = PrettyText.cook <<~MARKDOWN
hello hello
[details="Summary"] [details="Summary"]
world world
[/details] [/details]
MD MARKDOWN
md = PrettyText.format_for_email(md, post)
html = "<p>hello</p>\n\nSummary <a href=\"#{post.full_url}\">(click for more details)</a>"
expect(md).to eq(html) email_html = PrettyText.format_for_email(cooked_html, post)
expect(email_html).to match_html <<~HTML
<p>hello</p>
Summary <a href="#{post.full_url}">#{I18n.t("details.excerpt_details")}</a>
HTML
end end
it "properly handles multiple spoiler blocks in a post" do it "properly handles multiple spoiler blocks in a post" do
md = PrettyText.cook(<<~MD) cooked_html = PrettyText.cook <<~MARKDOWN
[details="First"] [details="First"]
body secret stuff very long body secret stuff very long
[/details] [/details]
@ -55,24 +66,31 @@ RSpec.describe PrettyText do
[details="Third"] [details="Third"]
body secret stuff very long body secret stuff very long
[/details] [/details]
MD MARKDOWN
md = PrettyText.format_for_email(md, post) email_html = PrettyText.format_for_email(cooked_html, post)
expect(md).not_to include("secret stuff")
expect(md.scan(/First/).size).to eq(1) expect(email_html).to match_html <<~HTML
expect(md.scan(/Third/).size).to eq(1) First <a href="#{post.full_url}">#{I18n.t("details.excerpt_details")}</a>
expect(md.scan(I18n.t("details.excerpt_details")).size).to eq(3) Second <a href="#{post.full_url}">#{I18n.t("details.excerpt_details")}</a>
<p>Hey there.</p>
Third <a href="#{post.full_url}">#{I18n.t("details.excerpt_details")}</a>
HTML
end end
it "escapes summary text" do it "escapes summary text" do
md = PrettyText.cook(<<~MD) cooked_html = PrettyText.cook <<~MARKDOWN
<script>alert('hello')</script> <script>alert('hello')</script>
[details="<script>alert('hello')</script>"] [details="<script>alert('hello')</script>"]
<script>alert('hello')</script> <script>alert('hello')</script>
[/details] [/details]
MD MARKDOWN
md = PrettyText.format_for_email(md, post)
expect(md).not_to include("<script>") email_html = PrettyText.format_for_email(cooked_html, post)
expect(email_html).to match_html <<~HTML
&lt;script&gt;alert('hello')&lt;/script&gt; <a href="#{post.full_url}">#{I18n.t("details.excerpt_details")}</a>
HTML
end end
end end