Render markdown to html for notifications

This commit is contained in:
Benjamin Neff 2022-07-13 05:05:58 +02:00
parent 3c02a1f067
commit dd3bc39c97
No known key found for this signature in database
GPG key ID: 971464C3F1A90194
12 changed files with 62 additions and 50 deletions

View file

@ -4,17 +4,19 @@ module NotifierHelper
include PostsHelper
# @param post [Post] The post object.
# @param opts [Hash] Optional hash. Accepts :length parameters.
# @param opts [Hash] Optional hash. Accepts :html parameter.
# @return [String] The formatted post.
def post_message(post, opts={})
post.message&.plain_text_without_markdown.presence || post_page_title(post)
rendered = opts[:html] ? post.message&.markdownified_for_mail : post.message&.plain_text_without_markdown
rendered.presence || post_page_title(post)
end
# @param comment [Comment] The comment to process.
# @param opts [Hash] Optional hash. Accepts :html parameter.
# @return [String] The formatted comment.
def comment_message(comment, opts={})
if comment.post.public?
comment.message.plain_text_without_markdown
opts[:html] ? comment.message.markdownified_for_mail : comment.message.plain_text_without_markdown
else
I18n.translate "notifier.a_limited_post_comment"
end

View file

@ -1,5 +1,4 @@
%p
= comment_message(@notification.comment, process_newlines: true)
= comment_message(@notification.comment, html: true)
%p
= link_to t("notifier.comment_on_post.reply", name: @notification.comment.post.author_first_name),
post_url(@notification.comment.post, anchor: @notification.comment.guid)

View file

@ -1,5 +1,4 @@
%p
= comment_message(@notification.comment, process_newlines: true)
= comment_message(@notification.comment, html: true)
%p
= link_to t("notifier.comment_on_post.reply", name: @notification.comment.post.author_first_name),
post_url(@notification.comment.post, anchor: @notification.comment.guid)

View file

@ -1,8 +1,7 @@
- if @notification.like_target.public?
%p
#{t('.liked', name: @notification.sender_name)}:
%p
= post_message(@notification.like_target, process_newlines: true)
= post_message(@notification.like_target, html: true)
- else
%p
#{t('notifier.liked.limited_post', name: @notification.sender_name)}.

View file

@ -1,6 +1,5 @@
- if @notification.post.public?
%p
= post_message(@notification.post, process_newlines: true)
= post_message(@notification.post, html: true)
- else
%p
= t("notifier.mentioned.limited_post")

View file

@ -1,6 +1,5 @@
- if @notification.comment.public?
%p
= @notification.comment.message.plain_text_without_markdown
= @notification.comment.message.markdownified_for_mail
- else
%p
= t("notifier.mentioned_in_comment.limited_post")

View file

@ -1,6 +1,5 @@
%p
#{t('.reshared', name: @notification.sender_name)}:
%p
= post_message(@notification.reshare_root, process_newlines: true)
= post_message(@notification.reshare_root, html: true)
%p
= link_to t(".view_post"), post_url(@notification.reshare)

View file

@ -54,8 +54,9 @@ module Diaspora::Mentionable
#
# @param [String] message text
# @param [Array] allowed_people ids of people that are allowed to stay
# @param [Boolean] absolute_links (false) render mentions with absolute links
# @return [String] message text with filtered mentions
def self.filter_people(msg_text, allowed_people)
def self.filter_people(msg_text, allowed_people, absolute_links: false)
mentioned_ppl = people_from_string(msg_text)
msg_text.to_s.gsub(REGEX) {|match_str|
@ -65,7 +66,7 @@ module Diaspora::Mentionable
if person && allowed_people.include?(person.id)
match_str
else
"@#{MentionsInternal.profile_link(person, name, diaspora_id)}"
"@#{MentionsInternal.profile_link(person, name, diaspora_id, absolute: absolute_links)}"
end
}
end
@ -121,11 +122,14 @@ module Diaspora::Mentionable
#
# @param [Person] AR Person
# @param [String] display name
# @param [String] diaspora_id
# @param [Boolean] absolute (false) render absolute link
# @return [String] markdown person link
def self.profile_link(person, display_name, diaspora_id)
def self.profile_link(person, display_name, diaspora_id, absolute: false)
return display_name || diaspora_id unless person.present?
"[#{display_name || person.name}](#{Rails.application.routes.url_helpers.person_path(person)})"
url_helper = Rails.application.routes.url_helpers
"[#{display_name || person.name}](#{absolute ? url_helper.person_url(person) : url_helper.person_path(person)})"
end
end
end

View file

@ -56,8 +56,8 @@ module Diaspora
@message = renderer.render(message).strip
end
def markdownify
renderer = Diaspora::Markdownify::HTML.new options[:markdown_render_options]
def markdownify(renderer_class=Diaspora::Markdownify::HTML)
renderer = renderer_class.new options[:markdown_render_options]
markdown = Redcarpet::Markdown.new renderer, options[:markdown_options]
@message = markdown.render message
@ -76,8 +76,8 @@ module Diaspora
@message = Diaspora::Mentionable.format message, options[:mentioned_people]
end
if options[:disable_hovercards] || options[:link_all_mentions]
@message = Diaspora::Mentionable.filter_people message, []
if options[:disable_hovercards]
@message = Diaspora::Mentionable.filter_people(message, [], absolute_links: true)
else
make_mentions_plain_text
end
@ -108,7 +108,6 @@ module Diaspora
end
DEFAULTS = {mentioned_people: [],
link_all_mentions: false,
disable_hovercards: false,
truncate: false,
append: nil,
@ -137,12 +136,8 @@ module Diaspora
# @param [Hash] opts Global options affecting output
# @option opts [Array<Person>] :mentioned_people ([]) List of people
# allowed to mention
# @option opts [Boolean] :link_all_mentions (false) Whether to link
# all mentions. This makes plain links to profiles for people not in
# :mentioned_people
# @option opts [Boolean] :disable_hovercards (true) Render all mentions
# as profile links. This implies :link_all_mentions and ignores
# :mentioned_people
# as absolute profile links. This ignores :mentioned_people
# @option opts [#to_i, Boolean] :truncate (false) Truncate message to
# the specified length
# @option opts [String] :append (nil) Append text to the end of
@ -205,7 +200,7 @@ module Diaspora
render_tags
squish
append_and_truncate
}.html_safe
}.html_safe # rubocop:disable Rails/OutputSafety
end
# @param [Hash] opts Override global output options, see {#initialize}
@ -220,7 +215,20 @@ module Diaspora
render_tags
squish
append_and_truncate
}.html_safe
}.html_safe # rubocop:disable Rails/OutputSafety
end
def markdownified_for_mail
process(disable_hovercards: true) {
process_newlines
normalize
diaspora_links
camo_urls if AppConfig.privacy.camo.proxy_markdown_images?
render_mentions
markdownify(Diaspora::Markdownify::Email)
squish
append_and_truncate
}.html_safe # rubocop:disable Rails/OutputSafety
end
# Get a short summary of the message

View file

@ -5,18 +5,23 @@
# the COPYRIGHT file.
describe NotifierHelper, :type => :helper do
describe '#post_message' do
describe "#post_message" do
before do
# post for markdown test
@markdown_post = FactoryGirl.create(:status_message,
text: "[link](http://diasporafoundation.org) **bold text** *other text*", public: true)
@striped_markdown_post = "link (http://diasporafoundation.org) bold text other text"
text: "[link](https://diasporafoundation.org) **bold text** *other text*",
public: true)
@striped_markdown_post = "link (https://diasporafoundation.org) bold text other text"
end
it 'strip markdown in the post' do
it "strip markdown in the post" do
expect(post_message(@markdown_post)).to eq(@striped_markdown_post)
end
it "renders markdown as html" do
expect(post_message(@markdown_post, html: true)).to include("<a href=\"https://diasporafoundation.org\">link</a>")
end
it "falls back to the title if the post has no text" do
photo = FactoryGirl.build(:photo, public: true)
photo_post = FactoryGirl.build(:status_message, author: photo.author, text: "", photos: [photo], public: true)
@ -32,13 +37,13 @@ describe NotifierHelper, :type => :helper do
end
end
describe '#comment_message' do
describe "#comment_message" do
before do
# comment for markdown test
@markdown_comment = FactoryGirl.create(:comment)
@markdown_comment.post.public = true
@markdown_comment.text = "[link](http://diasporafoundation.org) **bold text** *other text*"
@striped_markdown_comment = "link (http://diasporafoundation.org) bold text other text"
@markdown_comment.text = "[link](https://diasporafoundation.org) **bold text** *other text*"
@striped_markdown_comment = "link (https://diasporafoundation.org) bold text other text"
# comment for limited post
@limited_comment = FactoryGirl.create(:comment)
@ -46,11 +51,16 @@ describe NotifierHelper, :type => :helper do
@limited_comment.text = "This is top secret comment. Shhhhhhhh!!!"
end
it 'strip markdown in the comment' do
it "strip markdown in the comment" do
expect(comment_message(@markdown_comment)).to eq(@striped_markdown_comment)
end
it 'hides the private content' do
it "renders markdown as html" do
expect(comment_message(@markdown_comment, html: true))
.to include("<a href=\"https://diasporafoundation.org\">link</a>")
end
it "hides the private content" do
expect(comment_message(@limited_comment)).not_to include("secret comment")
end
end

View file

@ -78,12 +78,6 @@ describe Diaspora::MessageRenderer do
end
context 'linking all mentions' do
it 'makes plain links for people not in the post aspects' do
message = message("@{Bob; #{bob.person.diaspora_handle}}", link_all_mentions: true).html
expect(message).to_not include 'hovercard'
expect(message).to include "/people/#{bob.person.guid}"
end
it "makes no hovercards if they're disabled" do
message = message(
"@{Bob; #{bob.person.diaspora_handle}}",
@ -91,7 +85,7 @@ describe Diaspora::MessageRenderer do
disable_hovercards: true
).html
expect(message).to_not include 'hovercard'
expect(message).to include "/people/#{bob.person.guid}"
expect(message).to include AppConfig.url_to("/people/#{bob.person.guid}")
end
end
end

View file

@ -555,9 +555,9 @@ describe Notifier, type: :mailer do
describe "hashtags" do
it "escapes hashtags" do
mails = Notifier.admin("#Welcome to bureaucracy!", [bob])
expect(mails.length).to eq(1)
mail = mails.first
status = FactoryGirl.create(:status_message, author: alice.person, text: "#Welcome to bureaucracy!", public: true)
like = status.likes.create!(author: bob.person)
mail = Notifier.send_notification("liked", alice.id, like.author.id, like.id)
expect(mail.body.encoded).to match(
"<p><a href=\"#{AppConfig.url_to(tag_path('welcome'))}\">#Welcome</a> to bureaucracy!</p>"
)