Skip to content

Commit

Permalink
AO3-6017 Add role of commenter to comment notification emails (#4683)
Browse files Browse the repository at this point in the history
* AO3-6017 Add username and role of commenter to comment notification emails

* AO3-6017 Use same locale as guest comment name

* AO3-6017 Fix that color was set twice on the pseud

* AO3-6017 Add tests for guest and anon comment mails

* AO3-6017 Change anon comment case to guard clause

* AO3-6017 Rubocop

* AO3-6017 Apply suggestions from code review

Co-authored-by: Brian Austin <13002992+brianjaustin@users.noreply.github.com>

* AO3-6017 Apply suggestions from code review everywhere

Would have been nice if GitHub allowed me to do that in my browser

* AO3-6017 Add tests for registered user with default pseud

* AO3-6017 Add previews for comment reply sent and anon comment reply

* AO3-6017 Rubocop

* AO3-6017 Fix copy paste error

* AO3-6017 Deduplicate comment notification tests in admin mailer spec

* AO3-6017 Remove mistakenly added indentation

In text mails the indentation ends up in the emails,
which is not desired

* AO3-6017 Improve locale keys

* AO3-6017 Add comments to mailer previews

* AO3-6017 Merge fix

---------

Co-authored-by: Brian Austin <13002992+brianjaustin@users.noreply.github.com>
  • Loading branch information
Bilka2 and brianjaustin authored May 17, 2024
1 parent 9719025 commit 3ae1433
Show file tree
Hide file tree
Showing 8 changed files with 526 additions and 118 deletions.
19 changes: 11 additions & 8 deletions app/helpers/mailer_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -181,22 +181,25 @@ def style_work_tag_metadata(tags)
end

def commenter_pseud_or_name_link(comment)
return style_bold(t("roles.anonymous_creator")) if comment.by_anonymous_creator?

if comment.comment_owner.nil?
t("roles.guest_commenter_name_html", name: style_bold(comment.comment_owner_name), role: style_role(t("roles.guest_with_parens")))
elsif comment.by_anonymous_creator?
style_bold(t("roles.anonymous_creator"))
t("roles.commenter_name.html", name: style_bold(comment.comment_owner_name), role_with_parens: style_role(t("roles.guest_with_parens")))
else
style_pseud_link(comment.pseud)
role = comment.user.official ? t("roles.official_with_parens") : t("roles.registered_with_parens")
pseud_link = style_link(comment.pseud.byline, user_pseud_url(comment.user, comment.pseud))
t("roles.commenter_name.html", name: tag.strong(pseud_link), role_with_parens: style_role(role))
end
end

def commenter_pseud_or_name_text(comment)
return t("roles.anonymous_creator") if comment.by_anonymous_creator?

if comment.comment_owner.nil?
t("roles.guest_commenter_name_text", name: comment.comment_owner_name, role: t("roles.guest_with_parens"))
elsif comment.by_anonymous_creator?
t("roles.anonymous_creator")
t("roles.commenter_name.text", name: comment.comment_owner_name, role_with_parens: t("roles.guest_with_parens"))
else
text_pseud(comment.pseud)
role = comment.user.official ? t("roles.official_with_parens") : t("roles.registered_with_parens")
t("roles.commenter_name.text", name: text_pseud(comment.pseud), role_with_parens: role)
end
end

Expand Down
2 changes: 1 addition & 1 deletion app/views/admin_mailer/comment_notification.text.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<% content_for :message do %>
<%= commenter_pseud_or_name_text(@comment) %> left the following comment on
<%= commenter_pseud_or_name_text(@comment) %> left the following comment on
<% if @comment.ultimate_parent.is_a?(Tag) then %>the tag "<%= @comment.ultimate_parent.commentable_name %>" (<%= url_for(:controller => :tags, :action => :show, :id => @comment.ultimate_parent, :only_path => false) %>) <% else %>"<%= @comment.ultimate_parent.commentable_name.html_safe %>" (<%= polymorphic_url(@comment.ultimate_parent, :only_path => false) %>)<% end %>:
<%= text_divider %>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<% content_for :message do %>
<%= commenter_pseud_or_name_text(@comment) %> edited the following comment on
<%= commenter_pseud_or_name_text(@comment) %> edited the following comment on
<% if @comment.ultimate_parent.is_a?(Tag) then %>the tag "<%= @comment.ultimate_parent.commentable_name %>" (<%= url_for(:controller => :tags, :action => :show, :id => @comment.ultimate_parent, :only_path => false) %>) <% else %>"<%= @comment.ultimate_parent.commentable_name.html_safe %>" (<%= polymorphic_url(@comment.ultimate_parent, :only_path => false) %>)<% end %>:
<%= text_divider %>

Expand Down
7 changes: 5 additions & 2 deletions config/locales/mailers/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,12 @@ en:
support: The AO3 Support team
roles:
anonymous_creator: Anonymous Creator
guest_commenter_name_html: "%{name} %{role}"
guest_commenter_name_text: "%{name} %{role}"
commenter_name:
html: "%{name} %{role_with_parens}"
text: "%{name} %{role_with_parens}"
guest_with_parens: "(Guest)"
official_with_parens: "(Official)"
registered_with_parens: "(Registered User)"
user_mailer:
abuse_report:
copy:
Expand Down
294 changes: 206 additions & 88 deletions spec/mailers/admin_mailer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,93 +3,7 @@
require "spec_helper"

describe AdminMailer do
describe "#comment_notification" do
let(:email) { described_class.comment_notification(comment.id) }

context "when the comment is on an admin post" do
let(:comment) { create(:comment, :on_admin_post) }

context "and the comment's contents contain an image" do
let(:image_url) { "an_image.png" }
let(:image_tag) { "<img src=\"#{image_url}\" />" }

before do
comment.comment_content += image_tag
comment.save!
end

context "when image safety mode is enabled for admin post comments" do
before { allow(ArchiveConfig).to receive(:PARENTS_WITH_IMAGE_SAFETY_MODE).and_return(["AdminPost"]) }

it "strips the image from the email message but leaves its URL" do
expect(email).not_to have_html_part_content(image_tag)
expect(email).not_to have_text_part_content(image_tag)
expect(email).to have_html_part_content(image_url)
expect(email).to have_text_part_content(image_url)
end
end

context "when image safety mode is not enabled for admin post comments" do
it "embeds the image when image safety mode is completely disabled" do
allow(ArchiveConfig).to receive(:PARENTS_WITH_IMAGE_SAFETY_MODE).and_return([])
expect(email).to have_html_part_content(image_tag)
expect(email).not_to have_text_part_content(image_url)
end

it "embeds the image when image safety mode is enabled for other types of comments" do
allow(ArchiveConfig).to receive(:PARENTS_WITH_IMAGE_SAFETY_MODE).and_return(%w[Chapter Tag])
expect(email).to have_html_part_content(image_tag)
expect(email).not_to have_text_part_content(image_url)
end
end
end
end
end

describe "#edited_comment_notification" do
let(:email) { described_class.edited_comment_notification(comment.id) }

context "when the comment is on an admin post" do
let(:comment) { create(:comment, :on_admin_post) }

context "with an image in the comment content" do
let(:image_url) { "an_image.png" }
let(:image_tag) { "<img src=\"#{image_url}\" />" }

before do
comment.comment_content += image_tag
comment.save!
end

context "when image safety mode is enabled for admin post comments" do
before { allow(ArchiveConfig).to receive(:PARENTS_WITH_IMAGE_SAFETY_MODE).and_return(["AdminPost"]) }

it "strips the image from the email message but leaves its URL" do
expect(email).not_to have_html_part_content(image_tag)
expect(email).not_to have_text_part_content(image_tag)
expect(email).to have_html_part_content(image_url)
expect(email).to have_text_part_content(image_url)
end
end

context "when image safety mode is not enabled for admin post comments" do
it "embeds the image in the HTML email when image safety mode is completely disabled" do
allow(ArchiveConfig).to receive(:PARENTS_WITH_IMAGE_SAFETY_MODE).and_return([])
expect(email).to have_html_part_content(image_tag)
expect(email).not_to have_text_part_content(image_url)
end

it "embeds the image in the HTML email when image safety mode is enabled for other types of comments" do
allow(ArchiveConfig).to receive(:PARENTS_WITH_IMAGE_SAFETY_MODE).and_return(%w[Chapter Tag])
expect(email).to have_html_part_content(image_tag)
expect(email).not_to have_text_part_content(image_url)
end
end
end
end
end

describe "send_spam_alert" do
describe "#send_spam_alert" do
let(:spam_user) { create(:user) }

let(:spam1) do
Expand Down Expand Up @@ -216,7 +130,7 @@
end
end

describe "set_password_notification" do
describe "#set_password_notification" do
subject(:email) { AdminMailer.set_password_notification(admin, token) }

let(:admin) { create(:admin) }
Expand Down Expand Up @@ -258,4 +172,208 @@
end
end
end

let(:commenter) { create(:user, login: "Accumulator") }
let(:commenter_pseud) { create(:pseud, user: commenter, name: "Blueprint") }
let(:comment) { create(:comment, :on_admin_post, pseud: commenter_pseud) }

shared_examples "a notification email with the commenter's pseud and username" do
describe "HTML email" do
it "has the pseud and username of the commenter" do
expect(email).to have_html_part_content(">Blueprint (Accumulator)</a></strong> <em><strong>(Registered User)</strong></em>")
expect(subject.html_part).to have_xpath(
"//a[@href=\"#{user_pseud_url(commenter, commenter_pseud)}\"]",
text: "Blueprint (Accumulator)"
)
end
end

describe "text email" do
it "has the pseud and username of the commenter" do
expect(subject).to have_text_part_content(
"Blueprint (Accumulator) (#{user_pseud_url(commenter, commenter_pseud)}) (Registered User)"
)
end
end
end

shared_examples "a notification email that marks the commenter as official" do
describe "HTML email" do
it "has the username of the commenter and the official role" do
expect(email).to have_html_part_content(">Centrifuge</a></strong> <em><strong>(Official)</strong></em>")
expect(subject.html_part).to have_xpath(
"//a[@href=\"#{user_pseud_url(commenter, commenter.default_pseud)}\"]",
text: "Centrifuge"
)
end
end

describe "text email" do
it "has the username of the commenter and the official role" do
expect(subject).to have_text_part_content(
"Centrifuge (#{user_pseud_url(commenter, commenter.default_pseud)}) (Official)"
)
end
end
end

shared_examples "a notification email with only the commenter's username" do
describe "HTML email" do
it "has only the username of the commenter" do
expect(email).to have_html_part_content(">Exoskeleton</a></strong> <em><strong>(Registered User)</strong></em>")
expect(subject.html_part).to have_xpath(
"//a[@href=\"#{user_pseud_url(commenter, commenter.default_pseud)}\"]",
text: "Exoskeleton"
)
expect(email).not_to have_html_part_content(">Exoskeleton (Exoskeleton)")
end
end

describe "text email" do
it "has only the username of the commenter" do
expect(subject).to have_text_part_content(
"Exoskeleton (#{user_pseud_url(commenter, commenter.default_pseud)}) (Registered User)"
)
expect(subject).not_to have_text_part_content("Exoskeleton (Exoskeleton)")
end
end
end

describe "#comment_notification" do
subject(:email) { AdminMailer.comment_notification(comment.id) }

it_behaves_like "an email with a valid sender"
it_behaves_like "a multipart email"
it_behaves_like "a notification email with the commenter's pseud and username"

context "when the comment is on an admin post" do
let(:comment) { create(:comment, :on_admin_post) }

context "and the comment's contents contain an image" do
let(:image_url) { "an_image.png" }
let(:image_tag) { "<img src=\"#{image_url}\" />" }

before do
comment.comment_content += image_tag
comment.save!
end

context "when image safety mode is enabled for admin post comments" do
before { allow(ArchiveConfig).to receive(:PARENTS_WITH_IMAGE_SAFETY_MODE).and_return(["AdminPost"]) }

it "strips the image from the email message but leaves its URL" do
expect(email).not_to have_html_part_content(image_tag)
expect(email).not_to have_text_part_content(image_tag)
expect(email).to have_html_part_content(image_url)
expect(email).to have_text_part_content(image_url)
end
end

context "when image safety mode is not enabled for admin post comments" do
it "embeds the image when image safety mode is completely disabled" do
allow(ArchiveConfig).to receive(:PARENTS_WITH_IMAGE_SAFETY_MODE).and_return([])
expect(email).to have_html_part_content(image_tag)
expect(email).not_to have_text_part_content(image_url)
end

it "embeds the image when image safety mode is enabled for other types of comments" do
allow(ArchiveConfig).to receive(:PARENTS_WITH_IMAGE_SAFETY_MODE).and_return(%w[Chapter Tag])
expect(email).to have_html_part_content(image_tag)
expect(email).not_to have_text_part_content(image_url)
end
end
end
end

context "when the comment is by an official user using their default pseud" do
let(:commenter) { create(:official_user, login: "Centrifuge") }
let(:comment) { create(:comment, :on_admin_post, pseud: commenter.default_pseud) }

it_behaves_like "a notification email that marks the commenter as official"
end

context "when the commenter is a guest" do
let(:comment) { create(:comment, :on_admin_post, pseud: nil, name: "Defender", email: Faker::Internet.email) }

describe "HTML email" do
it "has the name of the guest and the guest role" do
expect(email).to have_html_part_content(">Defender</b> <em><strong>(Guest)</strong></em>")
end
end

describe "text email" do
it "has the name of the guest and the guest role" do
expect(subject).to have_text_part_content("Defender (Guest)")
end
end
end

context "when the comment is by a registered user using their default pseud" do
let(:commenter) { create(:user, login: "Exoskeleton") }
let(:comment) { create(:comment, pseud: commenter.default_pseud) }

it_behaves_like "a notification email with only the commenter's username"
end
end

describe "#comment_edited_notification" do
subject(:email) { AdminMailer.edited_comment_notification(comment.id) }

it_behaves_like "an email with a valid sender"
it_behaves_like "a multipart email"
it_behaves_like "a notification email with the commenter's pseud and username"

context "when the comment is on an admin post" do
let(:comment) { create(:comment, :on_admin_post) }

context "with an image in the comment content" do
let(:image_url) { "an_image.png" }
let(:image_tag) { "<img src=\"#{image_url}\" />" }

before do
comment.comment_content += image_tag
comment.save!
end

context "when image safety mode is enabled for admin post comments" do
before { allow(ArchiveConfig).to receive(:PARENTS_WITH_IMAGE_SAFETY_MODE).and_return(["AdminPost"]) }

it "strips the image from the email message but leaves its URL" do
expect(email).not_to have_html_part_content(image_tag)
expect(email).not_to have_text_part_content(image_tag)
expect(email).to have_html_part_content(image_url)
expect(email).to have_text_part_content(image_url)
end
end

context "when image safety mode is not enabled for admin post comments" do
it "embeds the image in the HTML email when image safety mode is completely disabled" do
allow(ArchiveConfig).to receive(:PARENTS_WITH_IMAGE_SAFETY_MODE).and_return([])
expect(email).to have_html_part_content(image_tag)
expect(email).not_to have_text_part_content(image_url)
end

it "embeds the image in the HTML email when image safety mode is enabled for other types of comments" do
allow(ArchiveConfig).to receive(:PARENTS_WITH_IMAGE_SAFETY_MODE).and_return(%w[Chapter Tag])
expect(email).to have_html_part_content(image_tag)
expect(email).not_to have_text_part_content(image_url)
end
end
end
end

context "when the comment is by an official user using their default pseud" do
let(:commenter) { create(:official_user, login: "Centrifuge") }
let(:comment) { create(:comment, :on_admin_post, pseud: commenter.default_pseud) }

it_behaves_like "a notification email that marks the commenter as official"
end

context "when the comment is by a registered user using their default pseud" do
let(:commenter) { create(:user, login: "Exoskeleton") }
let(:comment) { create(:comment, :on_admin_post, pseud: commenter.default_pseud) }

it_behaves_like "a notification email with only the commenter's username"
end
end
end
Loading

0 comments on commit 3ae1433

Please sign in to comment.