mirror of
https://github.com/opf/openproject.git
synced 2026-06-13 19:20:00 +00:00
[#73827] Adapt email notifications for project-based work package identifiers
https://community.openproject.org/wp/73827
This commit is contained in:
@@ -75,7 +75,7 @@ class Reminders::NotificationMailer < ApplicationMailer
|
||||
end
|
||||
|
||||
def work_package_subject_text_wrapper
|
||||
"=" * ("# #{@work_package.id}#{@work_package.subject}".length + 4)
|
||||
"=" * ("#{@work_package.formatted_id} #{@work_package.subject}".length + 4)
|
||||
end
|
||||
|
||||
def text_email_wrapper
|
||||
|
||||
@@ -49,7 +49,7 @@ class SharingMailer < ApplicationMailer
|
||||
send_localized_mail(@shared_with_user) do
|
||||
@role_rights = derive_role_rights(role)
|
||||
@allowed_work_package_actions = derive_allowed_work_package_actions(role)
|
||||
I18n.t("mail.sharing.work_packages.subject", id: @work_package.id)
|
||||
I18n.t("mail.sharing.work_packages.subject", id: @work_package.formatted_id)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class WorkPackageMailer < ApplicationMailer
|
||||
send_localized_mail(recipient) do
|
||||
I18n.t(:"mail.mention.subject",
|
||||
user_name: author.name,
|
||||
id: @work_package.id,
|
||||
id: @work_package.formatted_id,
|
||||
subject: @work_package.subject)
|
||||
end
|
||||
end
|
||||
@@ -73,7 +73,7 @@ class WorkPackageMailer < ApplicationMailer
|
||||
|
||||
def subject_for_work_package(work_package)
|
||||
"#{work_package.project.name} - #{work_package.status.name} #{work_package.type.name} " +
|
||||
"##{work_package.id}: #{work_package.subject}"
|
||||
"#{work_package.formatted_id}: #{work_package.subject}"
|
||||
end
|
||||
|
||||
def set_work_package_headers(work_package)
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
<% @aggregated_notifications.first(DigestMailer::MAX_SHOWN_WORK_PACKAGES).each do |work_package, notifications_by_work_package| %>
|
||||
|
||||
<%= "=" * (("# " + work_package.id.to_s + work_package.subject).length + 4) %>
|
||||
= #<%= work_package.id %> <%= work_package.subject %> =
|
||||
<%= "=" * (("# " + work_package.id.to_s + work_package.subject).length + 4) %>
|
||||
<%= "=" * ((work_package.formatted_id + " " + work_package.subject).length + 4) %>
|
||||
= <%= work_package.formatted_id %> <%= work_package.subject %> =
|
||||
<%= "=" * ((work_package.formatted_id + " " + work_package.subject).length + 4) %>
|
||||
|
||||
<% unique_reasons = unique_reasons_of_notifications(notifications_by_work_package) %>
|
||||
<% unique_reasons.each_with_index do |reason, index| %><%= I18n.t(:"mail.work_packages.reason.#{reason || :unknown}", default: "-") %><%= ", " unless unique_reasons.size - 1 == index %><% end %>: <% if notifications_by_work_package.first.date_alert? %>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
</td>
|
||||
<%= placeholder_cell("8px", vertical: true) %>
|
||||
<td width="100%" style="color: #878787;">
|
||||
#<%= work_package.id %> - <%= work_package.project %>
|
||||
<%= work_package.formatted_id %> - <%= work_package.project %>
|
||||
<%= " - " unless unique_reasons.length === 1 && unique_reasons.first.nil? %>
|
||||
<% unique_reasons.each_with_index do |reason, index| %>
|
||||
<%= I18n.t(
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<%= text_email_wrapper %>
|
||||
|
||||
<%= work_package_subject_text_wrapper %>
|
||||
= #<%= @work_package.id %> <%= @work_package.subject %> =
|
||||
= <%= @work_package.formatted_id %> <%= @work_package.subject %> =
|
||||
<%= work_package_subject_text_wrapper %>
|
||||
|
||||
<%= reminder_timestamp_text %>
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
<%= "-" * 100 %>
|
||||
|
||||
|
||||
<%= "=" * (("# " + @work_package.id.to_s + @work_package.subject).length + 4) %>
|
||||
= #<%= @work_package.id %> <%= @work_package.subject %> =
|
||||
<%= "=" * (("# " + @work_package.id.to_s + @work_package.subject).length + 4) %>
|
||||
<%= "=" * ((@work_package.formatted_id + " " + @work_package.subject).length + 4) %>
|
||||
= <%= @work_package.formatted_id %> <%= @work_package.subject %> =
|
||||
<%= "=" * ((@work_package.formatted_id + " " + @work_package.subject).length + 4) %>
|
||||
|
||||
<%= I18n.t(:label_comment_added) %>:
|
||||
<%= strip_tags @journal.notes %>
|
||||
|
||||
@@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
See COPYRIGHT and LICENSE files for more details.
|
||||
|
||||
++#%>
|
||||
<%= t("text_work_package_watcher_#{@action}", id: "##{@work_package.id}", watcher_changer: @watcher_changer) %>
|
||||
<%= t("text_work_package_watcher_#{@action}", id: @work_package.formatted_id, watcher_changer: @watcher_changer) %>
|
||||
<hr>
|
||||
<%= render partial: "work_package_details", locals: { work_package: @work_package } %>
|
||||
<p>
|
||||
|
||||
@@ -27,7 +27,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
|
||||
++#%>
|
||||
|
||||
<%= t("text_work_package_watcher_#{@action}", id: "##{@work_package.id}", watcher_changer: @watcher_changer) %>
|
||||
<%= t("text_work_package_watcher_#{@action}", id: @work_package.formatted_id, watcher_changer: @watcher_changer) %>
|
||||
|
||||
----------------------------------------
|
||||
<%= render partial: "work_package_details", locals: { work_package: @work_package } %>
|
||||
|
||||
@@ -4615,7 +4615,7 @@ en:
|
||||
you_have: "You have"
|
||||
logo_alt_text: "Logo"
|
||||
mention:
|
||||
subject: "%{user_name} mentioned you in #%{id} - %{subject}"
|
||||
subject: "%{user_name} mentioned you in %{id} - %{subject}"
|
||||
notification:
|
||||
center: "To notification center"
|
||||
see_in_center: "See comment in notification center"
|
||||
@@ -4653,7 +4653,7 @@ en:
|
||||
allowed_actions_html: "You have the following permissions on this work package: %{allowed_actions}. This can change depending on your project role and permissions."
|
||||
create_account: "To access this work package, you will need to create and activate an account on %{instance}."
|
||||
open_work_package: "Open work package"
|
||||
subject: "Work package #%{id} was shared with you"
|
||||
subject: "Work package %{id} was shared with you"
|
||||
enterprise_text: "Share work packages with users who are not members of the project."
|
||||
summary:
|
||||
user: "%{user} shared a work package with you with %{role_rights} rights"
|
||||
|
||||
@@ -49,7 +49,7 @@ FactoryBot.define do
|
||||
workspace_type { "project" }
|
||||
|
||||
sequence(:name) { |n| "My Project No. #{n}" }
|
||||
sequence(:identifier) { |n| "myproject_no_#{n}" }
|
||||
sequence(:identifier) { |n| Setting::WorkPackageIdentifier.semantic_mode_active? ? "MPN#{n}" : "myproject_no_#{n}" }
|
||||
|
||||
# Use this trait for specs that exercise semantic-mode behaviour.
|
||||
# Produces a deterministic uppercase identifier that satisfies
|
||||
|
||||
@@ -104,7 +104,7 @@ RSpec.describe "Immediate reminder settings", :js do
|
||||
expect(ActionMailer::Base.deliveries.first.subject)
|
||||
.to eql I18n.t(:"mail.mention.subject",
|
||||
user_name: current_user.name,
|
||||
id: work_package.id,
|
||||
id: "##{work_package.id}",
|
||||
subject: work_package.subject)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -89,13 +89,26 @@ RSpec.describe DigestMailer do
|
||||
expected_notification_subject = "#{work_package.type.name.upcase} #{work_package.subject}"
|
||||
expect(mail_body).to have_text(expected_notification_subject, normalize_ws: true)
|
||||
|
||||
expected_notification_header = "#{work_package.status.name} ##{work_package.id} - #{work_package.project}"
|
||||
expect(mail_body).to have_text(expected_notification_header, normalize_ws: true)
|
||||
|
||||
expected_text = "#{journal.initial? ? 'Created' : 'Updated'} at #{time_stamp} by #{recipient.name}"
|
||||
expect(mail_body).to have_text(expected_text, normalize_ws: true)
|
||||
end
|
||||
|
||||
context "with classic mode", with_settings: { work_packages_identifier: "classic" } do
|
||||
it "shows the # prefixed numeric id in the notification header" do
|
||||
expected = "#{work_package.status.name} ##{work_package.id} - #{work_package.project}"
|
||||
expect(mail_body).to have_text(expected, normalize_ws: true)
|
||||
end
|
||||
end
|
||||
|
||||
context "with semantic mode",
|
||||
with_flag: { semantic_work_package_ids: true },
|
||||
with_settings: { work_packages_identifier: "semantic" } do
|
||||
it "shows the semantic identifier without # prefix in the notification header" do
|
||||
expected = "#{work_package.status.name} #{work_package.identifier} - #{work_package.project}"
|
||||
expect(mail_body).to have_text(expected, normalize_ws: true)
|
||||
end
|
||||
end
|
||||
|
||||
it "includes a reference to the notification center if there are more than the maximum number of shown work packages" do
|
||||
stub_const("DigestMailer::MAX_SHOWN_WORK_PACKAGES", 0)
|
||||
|
||||
|
||||
@@ -81,5 +81,24 @@ RSpec.describe Reminders::NotificationMailer do
|
||||
it "mail body includes the reminder note" do
|
||||
expect(mail_body).to include("Note: “This is an important reminder”")
|
||||
end
|
||||
|
||||
context "with classic mode", with_settings: { work_packages_identifier: "classic" } do
|
||||
it "shows the # prefixed numeric id in the mail body" do
|
||||
expect(mail_body).to include("##{work_package.id}")
|
||||
end
|
||||
end
|
||||
|
||||
context "with semantic mode",
|
||||
with_flag: { semantic_work_package_ids: true },
|
||||
with_settings: { work_packages_identifier: "semantic" } do
|
||||
let(:work_package) do
|
||||
build_stubbed(:work_package, identifier: "PROJ-42", sequence_number: 42)
|
||||
end
|
||||
|
||||
it "shows the semantic identifier without # prefix in the mail body" do
|
||||
expect(mail_body).to include("PROJ-42")
|
||||
expect(mail_body).not_to include("#PROJ-42")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -59,10 +59,29 @@ RSpec.describe SharingMailer do
|
||||
.to contain_exactly(shared_with_user.mail)
|
||||
end
|
||||
|
||||
it "sets the appropriate subject" do
|
||||
expect(mail.subject)
|
||||
.to eq(I18n.t("mail.sharing.work_packages.subject",
|
||||
id: work_package.id))
|
||||
context "with classic mode", with_settings: { work_packages_identifier: "classic" } do
|
||||
it "sets the subject with # prefixed numeric id" do
|
||||
expect(mail.subject)
|
||||
.to eq(I18n.t("mail.sharing.work_packages.subject", id: "##{work_package.id}"))
|
||||
end
|
||||
end
|
||||
|
||||
context "with semantic mode",
|
||||
with_flag: { semantic_work_package_ids: true },
|
||||
with_settings: { work_packages_identifier: "semantic" } do
|
||||
let(:work_package) do
|
||||
build_stubbed(:work_package,
|
||||
type: build_stubbed(:type_standard),
|
||||
author: build_stubbed(:user),
|
||||
project:,
|
||||
identifier: "PROJ-42",
|
||||
sequence_number: 42)
|
||||
end
|
||||
|
||||
it "sets the subject with the semantic identifier without # prefix" do
|
||||
expect(mail.subject)
|
||||
.to eq(I18n.t("mail.sharing.work_packages.subject", id: "PROJ-42"))
|
||||
end
|
||||
end
|
||||
|
||||
it "has a project header" do
|
||||
|
||||
@@ -55,12 +55,35 @@ RSpec.describe WorkPackageMailer do
|
||||
describe "#mentioned" do
|
||||
subject(:mail) { described_class.mentioned(recipient, journal) }
|
||||
|
||||
it "has a subject" do
|
||||
expect(mail.subject)
|
||||
.to eql I18n.t(:"mail.mention.subject",
|
||||
user_name: author.name,
|
||||
id: work_package.id,
|
||||
subject: work_package.subject)
|
||||
context "with classic mode", with_settings: { work_packages_identifier: "classic" } do
|
||||
it "has a subject with # prefixed numeric id" do
|
||||
expect(mail.subject)
|
||||
.to eql I18n.t(:"mail.mention.subject",
|
||||
user_name: author.name,
|
||||
id: "##{work_package.id}",
|
||||
subject: work_package.subject)
|
||||
end
|
||||
end
|
||||
|
||||
context "with semantic mode",
|
||||
with_flag: { semantic_work_package_ids: true },
|
||||
with_settings: { work_packages_identifier: "semantic" } do
|
||||
let(:work_package) do
|
||||
build_stubbed(:work_package,
|
||||
type: build_stubbed(:type_standard),
|
||||
project:,
|
||||
assigned_to: assignee,
|
||||
identifier: "PROJ-42",
|
||||
sequence_number: 42)
|
||||
end
|
||||
|
||||
it "has a subject with semantic identifier and no # prefix" do
|
||||
expect(mail.subject)
|
||||
.to eql I18n.t(:"mail.mention.subject",
|
||||
user_name: author.name,
|
||||
id: "PROJ-42",
|
||||
subject: work_package.subject)
|
||||
end
|
||||
end
|
||||
|
||||
it "is sent to the recipient" do
|
||||
@@ -122,6 +145,30 @@ RSpec.describe WorkPackageMailer do
|
||||
.to include(work_package.subject)
|
||||
end
|
||||
|
||||
context "with classic mode", with_settings: { work_packages_identifier: "classic" } do
|
||||
it "includes the # prefixed numeric id in the subject" do
|
||||
expect(mail.subject).to include("##{work_package.id}")
|
||||
end
|
||||
end
|
||||
|
||||
context "with semantic mode",
|
||||
with_flag: { semantic_work_package_ids: true },
|
||||
with_settings: { work_packages_identifier: "semantic" } do
|
||||
let(:work_package) do
|
||||
build_stubbed(:work_package,
|
||||
type: build_stubbed(:type_standard),
|
||||
project:,
|
||||
assigned_to: assignee,
|
||||
identifier: "PROJ-42",
|
||||
sequence_number: 42)
|
||||
end
|
||||
|
||||
it "includes the semantic identifier without # prefix in the subject" do
|
||||
expect(mail.subject).to include("PROJ-42")
|
||||
expect(mail.subject).not_to match(/#PROJ-42/)
|
||||
end
|
||||
end
|
||||
|
||||
it "has a references header" do
|
||||
expect(mail.references)
|
||||
.to eql "op.work_package-#{work_package.id}@example.net"
|
||||
@@ -136,6 +183,30 @@ RSpec.describe WorkPackageMailer do
|
||||
.to include(work_package.subject)
|
||||
end
|
||||
|
||||
context "with classic mode", with_settings: { work_packages_identifier: "classic" } do
|
||||
it "includes the # prefixed numeric id in the subject" do
|
||||
expect(mail.subject).to include("##{work_package.id}")
|
||||
end
|
||||
end
|
||||
|
||||
context "with semantic mode",
|
||||
with_flag: { semantic_work_package_ids: true },
|
||||
with_settings: { work_packages_identifier: "semantic" } do
|
||||
let(:work_package) do
|
||||
build_stubbed(:work_package,
|
||||
type: build_stubbed(:type_standard),
|
||||
project:,
|
||||
assigned_to: assignee,
|
||||
identifier: "PROJ-42",
|
||||
sequence_number: 42)
|
||||
end
|
||||
|
||||
it "includes the semantic identifier without # prefix in the subject" do
|
||||
expect(mail.subject).to include("PROJ-42")
|
||||
expect(mail.subject).not_to match(/#PROJ-42/)
|
||||
end
|
||||
end
|
||||
|
||||
it "has a references header" do
|
||||
expect(mail.references)
|
||||
.to eql "op.work_package-#{work_package.id}@example.net"
|
||||
|
||||
Reference in New Issue
Block a user