From 909d70d15ea5c85da9ac8d3f06a785b55f54d729 Mon Sep 17 00:00:00 2001 From: Kiesha Herman Date: Fri, 17 Oct 2025 13:10:02 -0700 Subject: [PATCH 1/5] Move member about to expire into separate mailer Create new mailer preview Breakup notification service --- app/mailers/emails/members.rb | 40 +++++++++---------- app/mailers/members/about_to_expire_mailer.rb | 38 ++++++++++++++++++ .../members/about_to_expire_mailer_preview.rb | 23 +++++++++++ app/mailers/previews/notify_preview.rb | 12 +++--- app/services/notification_service.rb | 10 ++--- .../about_to_expire_mailer/email.html.haml} | 2 +- .../about_to_expire_mailer/email.text.erb} | 2 +- .../expiring_email_notification_worker.rb | 8 +--- locale/gitlab.pot | 3 -- 9 files changed, 95 insertions(+), 43 deletions(-) create mode 100644 app/mailers/members/about_to_expire_mailer.rb create mode 100644 app/mailers/previews/members/about_to_expire_mailer_preview.rb rename app/views/{notify/member_about_to_expire_email.html.haml => members/about_to_expire_mailer/email.html.haml} (77%) rename app/views/{notify/member_about_to_expire_email.text.erb => members/about_to_expire_mailer/email.text.erb} (82%) diff --git a/app/mailers/emails/members.rb b/app/mailers/emails/members.rb index 227b8f6695c195..601390853d7baf 100644 --- a/app/mailers/emails/members.rb +++ b/app/mailers/emails/members.rb @@ -39,26 +39,26 @@ def member_expiration_date_updated_email(member_source_type, member_id) subject: subject(subject)) end - def member_about_to_expire_email(member_source_type, member_id) - @member_source_type = member_source_type - @member_id = member_id - - return unless member_exists? - return unless member.expires_at - - @days_to_expire = (member.expires_at - Date.today).to_i - - return if @days_to_expire <= 0 - - email_with_layout( - to: member.user.notification_email_for(notification_group), - subject: subject( - s_("Your membership will expire in %{days_to_expire} days") % { - days_to_expire: @days_to_expire - } - ) - ) - end + # def member_about_to_expire_email(member_source_type, member_id) + # @member_source_type = member_source_type + # @member_id = member_id + # + # return unless member_exists? + # return unless member.expires_at + # + # @days_to_expire = (member.expires_at - Date.today).to_i + # + # return if @days_to_expire <= 0 + # + # email_with_layout( + # to: member.user.notification_email_for(notification_group), + # subject: subject( + # s_("Your membership will expire in %{days_to_expire} days") % { + # days_to_expire: @days_to_expire + # } + # ) + # ) + # end # rubocop: disable CodeReuse/ActiveRecord def member diff --git a/app/mailers/members/about_to_expire_mailer.rb b/app/mailers/members/about_to_expire_mailer.rb new file mode 100644 index 00000000000000..08910b00edd19e --- /dev/null +++ b/app/mailers/members/about_to_expire_mailer.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module Members + class AboutToExpireMailer < ApplicationMailer + helper EmailsHelper + + helper_method :member_source, :user, :days_to_expire + + layout 'mailer' + + def email + return if member.blank? || member.expires_at.blank? || days_to_expire <= 0 + return unless member.notifiable?(:mention) + + mail_with_locale( + to: user.notification_email_for(member_source.notification_group), + subject: EmailsHelper.subject_with_prefix_and_suffix([email_subject_text]) + ) + end + + private + + delegate :user, to: :member + delegate :source, to: :member, prefix: true + + def member + params[:member] + end + + def days_to_expire + @days_to_expire ||= (member.expires_at - Time.zone.today).to_i + end + + def email_subject_text + "Your membership will expire in #{days_to_expire} days" + end + end +end diff --git a/app/mailers/previews/members/about_to_expire_mailer_preview.rb b/app/mailers/previews/members/about_to_expire_mailer_preview.rb new file mode 100644 index 00000000000000..2744bde202afc1 --- /dev/null +++ b/app/mailers/previews/members/about_to_expire_mailer_preview.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Members + class AboutToExpireMailerPreview < ActionMailer::Preview + def email + Members::AboutToExpireMailer.with(member: member).email.message # rubocop:disable CodeReuse/ActiveRecord -- false positive + end + + private + + def member + project.add_member(user, Gitlab::Access::GUEST, expires_at: 7.days.from_now.to_date) + end + + def project + Project.first + end + + def user + User.last + end + end +end diff --git a/app/mailers/previews/notify_preview.rb b/app/mailers/previews/notify_preview.rb index 41977092ed5f01..06eda3945e0d8a 100644 --- a/app/mailers/previews/notify_preview.rb +++ b/app/mailers/previews/notify_preview.rb @@ -204,12 +204,12 @@ def member_access_granted_email Notify.member_access_granted_email(member.source_type, member.id).message end - def member_about_to_expire_email - cleanup do - member = project.add_member(user, Gitlab::Access::GUEST, expires_at: 7.days.from_now.to_date) - Notify.member_about_to_expire_email('project', member.id).message - end - end + # def member_about_to_expire_email + # cleanup do + # member = project.add_member(user, Gitlab::Access::GUEST, expires_at: 7.days.from_now.to_date) + # Notify.member_about_to_expire_email('project', member.id).message + # end + # end def pages_domain_enabled_email cleanup do diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 8001d5f3a989d2..972f673d234eb4 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -536,11 +536,11 @@ def updated_member_expiration(member) mailer.member_expiration_date_updated_email(member.real_source_type, member.id).deliver_later end - def member_about_to_expire(member) - return true unless member.notifiable?(:mention) - - mailer.member_about_to_expire_email(member.real_source_type, member.id).deliver_later - end + # def member_about_to_expire(member) + # return true unless member.notifiable?(:mention) + # + # mailer.member_about_to_expire_email(member.real_source_type, member.id).deliver_later + # end def project_was_moved(project, old_path_with_namespace) recipients = project_moved_recipients(project) diff --git a/app/views/notify/member_about_to_expire_email.html.haml b/app/views/members/about_to_expire_mailer/email.html.haml similarity index 77% rename from app/views/notify/member_about_to_expire_email.html.haml rename to app/views/members/about_to_expire_mailer/email.html.haml index a9f92d90ae639f..7b9dac3d644532 100644 --- a/app/views/notify/member_about_to_expire_email.html.haml +++ b/app/views/members/about_to_expire_mailer/email.html.haml @@ -1,4 +1,4 @@ -= email_default_heading(say_hi(@member.user)) += email_default_heading(say_hi(@user)) %p = member_about_to_expire_text(@member_source, @days_to_expire, format: :html) diff --git a/app/views/notify/member_about_to_expire_email.text.erb b/app/views/members/about_to_expire_mailer/email.text.erb similarity index 82% rename from app/views/notify/member_about_to_expire_email.text.erb rename to app/views/members/about_to_expire_mailer/email.text.erb index 0c6e78bf501724..0db9289028f1fc 100644 --- a/app/views/notify/member_about_to_expire_email.text.erb +++ b/app/views/members/about_to_expire_mailer/email.text.erb @@ -1,4 +1,4 @@ -<%= say_hi(@member.user) %> +<%= say_hi(@user) %> <%= member_about_to_expire_text(@member_source, @days_to_expire) %> diff --git a/app/workers/members/expiring_email_notification_worker.rb b/app/workers/members/expiring_email_notification_worker.rb index 9e86653032a1ed..6d40afb33fcdf3 100644 --- a/app/workers/members/expiring_email_notification_worker.rb +++ b/app/workers/members/expiring_email_notification_worker.rb @@ -18,7 +18,7 @@ def perform(member_id) return unless valid_for_notification?(member) with_context(user: member.user) do - notification_service.member_about_to_expire(member) + Members::AboutToExpireMailer.with(member).email.deliver_later # rubocop:disable CodeReuse/ActiveRecord -- false positive Gitlab::AppLogger.info(message: "Notifying user about expiring membership", member_id: member.id) member.update(expiry_notified_at: Time.current) @@ -31,11 +31,5 @@ def valid_for_notification?(member) member.user.active? && member.user.human? end - - private - - def notification_service - @notification_service ||= NotificationService.new - end end end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index bc490f6030be9b..2175a28434c7d4 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -77423,9 +77423,6 @@ msgstr "" msgid "Your membership in %{project_or_group} %{project_or_group_name} will expire in %{days_formatted}." msgstr "" -msgid "Your membership will expire in %{days_to_expire} days" -msgstr "" - msgid "Your merge requests" msgstr "" -- GitLab From b89eb734909eb2003724ea606cf45f575f1e21ce Mon Sep 17 00:00:00 2001 From: Kiesha Herman Date: Mon, 20 Oct 2025 18:23:24 -0700 Subject: [PATCH 2/5] Update notify spec Add mailer helper method user Add new mailer spec --- app/mailers/emails/members.rb | 21 ----- app/mailers/members/about_to_expire_mailer.rb | 2 +- app/mailers/previews/notify_preview.rb | 7 -- app/services/notification_service.rb | 6 -- .../about_to_expire_mailer/email.html.haml | 6 +- .../about_to_expire_mailer/email.text.erb | 6 +- .../members/about_to_expire_mailer_spec.rb | 83 +++++++++++++++++++ spec/mailers/notify_spec.rb | 62 -------------- 8 files changed, 90 insertions(+), 103 deletions(-) create mode 100644 spec/mailers/members/about_to_expire_mailer_spec.rb diff --git a/app/mailers/emails/members.rb b/app/mailers/emails/members.rb index 601390853d7baf..61262af40200b6 100644 --- a/app/mailers/emails/members.rb +++ b/app/mailers/emails/members.rb @@ -39,27 +39,6 @@ def member_expiration_date_updated_email(member_source_type, member_id) subject: subject(subject)) end - # def member_about_to_expire_email(member_source_type, member_id) - # @member_source_type = member_source_type - # @member_id = member_id - # - # return unless member_exists? - # return unless member.expires_at - # - # @days_to_expire = (member.expires_at - Date.today).to_i - # - # return if @days_to_expire <= 0 - # - # email_with_layout( - # to: member.user.notification_email_for(notification_group), - # subject: subject( - # s_("Your membership will expire in %{days_to_expire} days") % { - # days_to_expire: @days_to_expire - # } - # ) - # ) - # end - # rubocop: disable CodeReuse/ActiveRecord def member @member ||= Member.find_by(id: @member_id) diff --git a/app/mailers/members/about_to_expire_mailer.rb b/app/mailers/members/about_to_expire_mailer.rb index 08910b00edd19e..14e8e7db7195e0 100644 --- a/app/mailers/members/about_to_expire_mailer.rb +++ b/app/mailers/members/about_to_expire_mailer.rb @@ -4,7 +4,7 @@ module Members class AboutToExpireMailer < ApplicationMailer helper EmailsHelper - helper_method :member_source, :user, :days_to_expire + helper_method :member, :member_source, :user, :days_to_expire layout 'mailer' diff --git a/app/mailers/previews/notify_preview.rb b/app/mailers/previews/notify_preview.rb index 06eda3945e0d8a..b073c56061e2a9 100644 --- a/app/mailers/previews/notify_preview.rb +++ b/app/mailers/previews/notify_preview.rb @@ -204,13 +204,6 @@ def member_access_granted_email Notify.member_access_granted_email(member.source_type, member.id).message end - # def member_about_to_expire_email - # cleanup do - # member = project.add_member(user, Gitlab::Access::GUEST, expires_at: 7.days.from_now.to_date) - # Notify.member_about_to_expire_email('project', member.id).message - # end - # end - def pages_domain_enabled_email cleanup do Notify.pages_domain_enabled_email(pages_domain, user).message diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 972f673d234eb4..31f5c301d73259 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -536,12 +536,6 @@ def updated_member_expiration(member) mailer.member_expiration_date_updated_email(member.real_source_type, member.id).deliver_later end - # def member_about_to_expire(member) - # return true unless member.notifiable?(:mention) - # - # mailer.member_about_to_expire_email(member.real_source_type, member.id).deliver_later - # end - def project_was_moved(project, old_path_with_namespace) recipients = project_moved_recipients(project) recipients = notifiable_users(recipients, :custom, custom_action: :moved_project, project: project) diff --git a/app/views/members/about_to_expire_mailer/email.html.haml b/app/views/members/about_to_expire_mailer/email.html.haml index 7b9dac3d644532..f3ed21e1944257 100644 --- a/app/views/members/about_to_expire_mailer/email.html.haml +++ b/app/views/members/about_to_expire_mailer/email.html.haml @@ -1,6 +1,6 @@ -= email_default_heading(say_hi(@user)) += email_default_heading(say_hi(user)) %p - = member_about_to_expire_text(@member_source, @days_to_expire, format: :html) + = member_about_to_expire_text(member_source, days_to_expire, format: :html) %p - = member_about_to_expire_link(@member, @member_source, format: :html) + = member_about_to_expire_link(member, member_source, format: :html) diff --git a/app/views/members/about_to_expire_mailer/email.text.erb b/app/views/members/about_to_expire_mailer/email.text.erb index 0db9289028f1fc..3ad75d3e586ece 100644 --- a/app/views/members/about_to_expire_mailer/email.text.erb +++ b/app/views/members/about_to_expire_mailer/email.text.erb @@ -1,5 +1,5 @@ -<%= say_hi(@user) %> +<%= say_hi(user) %> -<%= member_about_to_expire_text(@member_source, @days_to_expire) %> +<%= member_about_to_expire_text(member_source, days_to_expire) %> -<%= member_about_to_expire_link(@member, @member_source) %> +<%= member_about_to_expire_link(member, member_source) %> diff --git a/spec/mailers/members/about_to_expire_mailer_spec.rb b/spec/mailers/members/about_to_expire_mailer_spec.rb new file mode 100644 index 00000000000000..65e864d028935f --- /dev/null +++ b/spec/mailers/members/about_to_expire_mailer_spec.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Members::AboutToExpireMailer, feature_category: :groups_and_projects do + include EmailSpec::Matchers + using RSpec::Parameterized::TableSyntax + + describe '#email' do + let(:recipient) { build(:recipient) } + let(:group) { build(:group) } + let(:group_member) { build(:group_member, source: group, user: recipient, expires_at: 7.days.from_now) } + let(:project) { build(:project, :public, group: group) } + let(:project_member) { build(:project_member, source: project, user: recipient, expires_at: 7.days.from_now) } + let(:notifiable) { true } + + before do + allow(member).to receive(:notifiable?).with(:mention).and_return(notifiable) + end + + subject(:email) { described_class.with(member: member).email } + + where(:member, :source, :type) do + ref(:group_member) | ref(:group) | 'group' + ref(:project_member) | ref(:project) | 'project' + end + + with_them do + it_behaves_like 'an email sent from GitLab' do + let(:gitlab_sender_display_name) { Gitlab.config.gitlab.email_display_name } + let(:gitlab_sender) { Gitlab.config.gitlab.email_from } + let(:gitlab_sender_reply_to) { Gitlab.config.gitlab.email_reply_to } + end + + it_behaves_like 'an email sent to a user' + it_behaves_like 'it should not have Gmail Actions links' + it_behaves_like 'a user cannot unsubscribe through footer link' + it_behaves_like 'appearance header and footer enabled' + it_behaves_like 'appearance header and footer not enabled' + + it 'contains all the useful information', :aggregate_failures do + is_expected.to deliver_to member.user.email + is_expected.to have_subject "Your membership will expire in 7 days" + is_expected.to have_body_text "#{type} will expire in 7 days." + is_expected.to have_body_text public_send(:"#{type}_url", source) + is_expected.to have_body_text public_send(:"#{type}_#{type}_members_url", source) + end + + # context "with expiry notified membership" do + # before do + # group_member.expiry_notified_at = Date.current + # project_member.expiry_notified_at = Date.current + # end + # + # it_behaves_like 'no email is sent' + # end + + context 'with no expiry on membership' do + before do + group_member.expires_at = nil + project_member.expires_at = nil + end + + it_behaves_like 'no email is sent' + end + + context 'with expired membership' do + before do + group_member.expires_at = Date.current + project_member.expires_at = Date.current + end + + it_behaves_like 'no email is sent' + end + + context 'when the recipient is not notifiable' do + let(:notifiable) { false } + + it_behaves_like 'no email is sent' + end + end + end +end diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index 280d785a960489..abcfb041c1ec92 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -1752,68 +1752,6 @@ def invite_to_group(group, inviter:, user: nil) end end - describe 'membership about to expire' do - context "with group membership" do - let_it_be(:group_member) { create(:group_member, source: group, expires_at: 7.days.from_now) } - - subject { described_class.member_about_to_expire_email("Namespace", group_member.id) } - - it_behaves_like 'an email sent from GitLab' - it_behaves_like 'it should not have Gmail Actions links' - it_behaves_like 'a user cannot unsubscribe through footer link' - it_behaves_like 'appearance header and footer enabled' - it_behaves_like 'appearance header and footer not enabled' - - it 'contains all the useful information' do - is_expected.to deliver_to group_member.user.email - is_expected.to have_subject "Your membership will expire in 7 days" - is_expected.to have_body_text "group will expire in 7 days." - is_expected.to have_body_text group_url(group) - is_expected.to have_body_text group_group_members_url(group) - end - end - - context "with project membership" do - let_it_be(:project_member) { create(:project_member, source: project, expires_at: 7.days.from_now) } - - subject { described_class.member_about_to_expire_email('Project', project_member.id) } - - it_behaves_like 'an email sent from GitLab' - it_behaves_like 'it should not have Gmail Actions links' - it_behaves_like 'a user cannot unsubscribe through footer link' - it_behaves_like 'appearance header and footer enabled' - it_behaves_like 'appearance header and footer not enabled' - - it 'contains all the useful information' do - is_expected.to deliver_to project_member.user.email - is_expected.to have_subject "Your membership will expire in 7 days" - is_expected.to have_body_text "project will expire in 7 days." - is_expected.to have_body_text project_url(project) - is_expected.to have_body_text project_project_members_url(project) - end - end - - context "with expired membership" do - let_it_be(:project_member) { create(:project_member, source: project, expires_at: Date.today) } - - subject { described_class.member_about_to_expire_email('Project', project_member.id) } - - it 'not deliver expiry email' do - should_not_email_anyone - end - end - - context "with expiry notified membership" do - let_it_be(:project_member) { create(:project_member, source: project, expires_at: 7.days.from_now, expiry_notified_at: Date.today) } - - subject { described_class.member_about_to_expire_email('Project', project_member.id) } - - it 'not deliver expiry email' do - should_not_email_anyone - end - end - end - describe 'admin notification' do let(:example_site_path) { root_path } let(:user) { create(:user) } -- GitLab From 52387bd6bcd3f3185ca62dbc8e6628b612acb0ac Mon Sep 17 00:00:00 2001 From: Kiesha Herman Date: Mon, 20 Oct 2025 20:17:25 -0700 Subject: [PATCH 3/5] Update notification specs notifications service expiring email notification worker --- .../members/about_to_expire_mailer_spec.rb | 9 -------- spec/services/notification_service_spec.rb | 21 ------------------- ...expiring_email_notification_worker_spec.rb | 16 +++++++------- 3 files changed, 9 insertions(+), 37 deletions(-) diff --git a/spec/mailers/members/about_to_expire_mailer_spec.rb b/spec/mailers/members/about_to_expire_mailer_spec.rb index 65e864d028935f..d74e0a1b318370 100644 --- a/spec/mailers/members/about_to_expire_mailer_spec.rb +++ b/spec/mailers/members/about_to_expire_mailer_spec.rb @@ -46,15 +46,6 @@ is_expected.to have_body_text public_send(:"#{type}_#{type}_members_url", source) end - # context "with expiry notified membership" do - # before do - # group_member.expiry_notified_at = Date.current - # project_member.expiry_notified_at = Date.current - # end - # - # it_behaves_like 'no email is sent' - # end - context 'with no expiry on membership' do before do group_member.expires_at = nil diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index bfa49bb1c982cf..b2f26407e89949 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -3962,27 +3962,6 @@ def commit_to_hash(commit) end end end - - describe '#member_about_to_expire' do - let_it_be(:group_member) { create(:group_member, expires_at: 7.days.from_now.to_date) } - let_it_be(:project_member) { create(:project_member, expires_at: 7.days.from_now.to_date) } - - context "with group member" do - it 'emails the user that their group membership will be expired' do - notification.member_about_to_expire(group_member) - - should_email(group_member.user) - end - end - - context "with project member" do - it 'emails the user that their project membership will be expired' do - notification.member_about_to_expire(project_member) - - should_email(project_member.user) - end - end - end end describe '#new_member', :deliver_mails_inline do diff --git a/spec/workers/members/expiring_email_notification_worker_spec.rb b/spec/workers/members/expiring_email_notification_worker_spec.rb index 547d291473d3fd..51cb20e729152a 100644 --- a/spec/workers/members/expiring_email_notification_worker_spec.rb +++ b/spec/workers/members/expiring_email_notification_worker_spec.rb @@ -26,12 +26,14 @@ create(:project_member, :guest, user: project_bot, expires_at: 7.days.from_now) end + before do + allow(Members::AboutToExpireMailer).to receive(:with).and_call_original + end + describe '#perform' do context "with not notified member" do it "notify member" do - expect_next_instance_of(NotificationService) do |notification_service| - expect(notification_service).to receive(:member_about_to_expire).with(member) - end + expect(Members::AboutToExpireMailer).to receive(:with).with(member) worker.perform(member.id) @@ -39,19 +41,19 @@ end it 'does not notify blocked member' do - expect(NotificationService).not_to receive(:new) + expect(Members::AboutToExpireMailer).not_to receive(:with) worker.perform(blocked_member.id) end it 'does not notify invited member' do - expect(NotificationService).not_to receive(:new) + expect(Members::AboutToExpireMailer).not_to receive(:with) worker.perform(invited_member.id) end it 'does not notify non-human members' do - expect(NotificationService).not_to receive(:new) + expect(Members::AboutToExpireMailer).not_to receive(:with) worker.perform(bot_member.id) end @@ -59,7 +61,7 @@ context "with notified member" do it "not notify member" do - expect(NotificationService).not_to receive(:new) + expect(Members::AboutToExpireMailer).not_to receive(:with) worker.perform(notified_member.id) end -- GitLab From 23293d8fddded8849f38fb97a41bb07574bba00c Mon Sep 17 00:00:00 2001 From: Kiesha Herman Date: Mon, 20 Oct 2025 20:31:37 -0700 Subject: [PATCH 4/5] Update mailer parameter --- app/workers/members/expiring_email_notification_worker.rb | 2 +- spec/workers/members/expiring_email_notification_worker_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/workers/members/expiring_email_notification_worker.rb b/app/workers/members/expiring_email_notification_worker.rb index 6d40afb33fcdf3..457e1881ac2abe 100644 --- a/app/workers/members/expiring_email_notification_worker.rb +++ b/app/workers/members/expiring_email_notification_worker.rb @@ -18,7 +18,7 @@ def perform(member_id) return unless valid_for_notification?(member) with_context(user: member.user) do - Members::AboutToExpireMailer.with(member).email.deliver_later # rubocop:disable CodeReuse/ActiveRecord -- false positive + Members::AboutToExpireMailer.with(member: member).email.deliver_later # rubocop:disable CodeReuse/ActiveRecord -- false positive Gitlab::AppLogger.info(message: "Notifying user about expiring membership", member_id: member.id) member.update(expiry_notified_at: Time.current) diff --git a/spec/workers/members/expiring_email_notification_worker_spec.rb b/spec/workers/members/expiring_email_notification_worker_spec.rb index 51cb20e729152a..40fda8c05bcca4 100644 --- a/spec/workers/members/expiring_email_notification_worker_spec.rb +++ b/spec/workers/members/expiring_email_notification_worker_spec.rb @@ -33,7 +33,7 @@ describe '#perform' do context "with not notified member" do it "notify member" do - expect(Members::AboutToExpireMailer).to receive(:with).with(member) + expect(Members::AboutToExpireMailer).to receive(:with).with(member: member) worker.perform(member.id) -- GitLab From 3e2b71284681daa28d4c85935d84751d689ce237 Mon Sep 17 00:00:00 2001 From: Kiesha Herman Date: Wed, 22 Oct 2025 09:49:31 -0700 Subject: [PATCH 5/5] Add translation on subject --- app/mailers/members/about_to_expire_mailer.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/mailers/members/about_to_expire_mailer.rb b/app/mailers/members/about_to_expire_mailer.rb index 14e8e7db7195e0..19afe01a2fb449 100644 --- a/app/mailers/members/about_to_expire_mailer.rb +++ b/app/mailers/members/about_to_expire_mailer.rb @@ -32,7 +32,8 @@ def days_to_expire end def email_subject_text - "Your membership will expire in #{days_to_expire} days" + subject = "Your membership will expire in #{days_to_expire} days" + s_(subject) end end end -- GitLab