diff --git a/app/mailers/reminders/notification_mailer.rb b/app/mailers/reminders/notification_mailer.rb index d0a2e0ed116..8fa0a8d9eff 100644 --- a/app/mailers/reminders/notification_mailer.rb +++ b/app/mailers/reminders/notification_mailer.rb @@ -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 diff --git a/app/mailers/sharing_mailer.rb b/app/mailers/sharing_mailer.rb index 917714e0cb0..af5f409d15c 100644 --- a/app/mailers/sharing_mailer.rb +++ b/app/mailers/sharing_mailer.rb @@ -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 diff --git a/app/mailers/work_package_mailer.rb b/app/mailers/work_package_mailer.rb index 75a48ac27c5..f150e18834e 100644 --- a/app/mailers/work_package_mailer.rb +++ b/app/mailers/work_package_mailer.rb @@ -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) diff --git a/app/views/digest_mailer/work_packages.text.erb b/app/views/digest_mailer/work_packages.text.erb index 5c2983d8d13..5d3a4c3c8d6 100644 --- a/app/views/digest_mailer/work_packages.text.erb +++ b/app/views/digest_mailer/work_packages.text.erb @@ -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? %> diff --git a/app/views/mailer/_notification_row.html.erb b/app/views/mailer/_notification_row.html.erb index 040820e5bdc..66ba12de800 100644 --- a/app/views/mailer/_notification_row.html.erb +++ b/app/views/mailer/_notification_row.html.erb @@ -27,7 +27,7 @@ <%= placeholder_cell("8px", vertical: true) %>
diff --git a/app/views/work_package_mailer/watcher_changed.text.erb b/app/views/work_package_mailer/watcher_changed.text.erb index 289e99f6a79..7de3fc8bccc 100644 --- a/app/views/work_package_mailer/watcher_changed.text.erb +++ b/app/views/work_package_mailer/watcher_changed.text.erb @@ -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 } %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 0319501ef85..db283a32309 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -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" diff --git a/spec/factories/project_factory.rb b/spec/factories/project_factory.rb index 22566def703..0ada4e740bd 100644 --- a/spec/factories/project_factory.rb +++ b/spec/factories/project_factory.rb @@ -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 diff --git a/spec/features/notifications/settings/immediate_reminder_spec.rb b/spec/features/notifications/settings/immediate_reminder_spec.rb index e483ed632c4..dddb8678073 100644 --- a/spec/features/notifications/settings/immediate_reminder_spec.rb +++ b/spec/features/notifications/settings/immediate_reminder_spec.rb @@ -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 diff --git a/spec/mailers/digest_mailer_spec.rb b/spec/mailers/digest_mailer_spec.rb index 1723da82586..3ab8b3bebaa 100644 --- a/spec/mailers/digest_mailer_spec.rb +++ b/spec/mailers/digest_mailer_spec.rb @@ -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) diff --git a/spec/mailers/reminders/notification_mailer_spec.rb b/spec/mailers/reminders/notification_mailer_spec.rb index ad0a5de75da..294aa544dda 100644 --- a/spec/mailers/reminders/notification_mailer_spec.rb +++ b/spec/mailers/reminders/notification_mailer_spec.rb @@ -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 diff --git a/spec/mailers/sharing_mailer_spec.rb b/spec/mailers/sharing_mailer_spec.rb index 90be2256fd3..c0337fe757d 100644 --- a/spec/mailers/sharing_mailer_spec.rb +++ b/spec/mailers/sharing_mailer_spec.rb @@ -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 diff --git a/spec/mailers/work_package_mailer_spec.rb b/spec/mailers/work_package_mailer_spec.rb index 4446cb898c2..a2a73113885 100644 --- a/spec/mailers/work_package_mailer_spec.rb +++ b/spec/mailers/work_package_mailer_spec.rb @@ -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"