Commit c01e12cc authored by Serena Fang's avatar Serena Fang Committed by Nick Thomas

Send user email when their group expiration date is changed

Doesn't work yet
parent 03f535c8
...@@ -214,6 +214,29 @@ module EmailsHelper ...@@ -214,6 +214,29 @@ module EmailsHelper
end end
end end
def group_membership_expiration_changed_text(member, group)
if member.expires?
days = (member.expires_at - Date.today).to_i
days_formatted = pluralize(days, 'day')
_('Your %{group} membership will now expire in %{days}.') % { group: group.human_name, days: days_formatted }
else
_('Your membership in %{group} no longer expires.') % { group: group.human_name }
end
end
def group_membership_expiration_changed_link(member, group, format: nil)
url = group_group_members_url(group, search: member.user.username)
case format
when :html
link_to = generate_link('group membership', url).html_safe
_('For additional information, review your %{link_to} or contact your group owner.').html_safe % { link_to: link_to }
else
_('For additional information, review your group membership: %{link_to} or contact your group owner.') % { link_to: url }
end
end
def instance_access_request_text(user, format: nil) def instance_access_request_text(user, format: nil)
gitlab_host = Gitlab.config.gitlab.host gitlab_host = Gitlab.config.gitlab.host
......
...@@ -114,6 +114,23 @@ module Emails ...@@ -114,6 +114,23 @@ module Emails
subject: subject('Invitation declined')) subject: subject('Invitation declined'))
end end
def member_expiration_date_updated_email(member_source_type, member_id)
@member_source_type = member_source_type
@member_id = member_id
return unless member_exists?
subject = if member.expires?
_('Group membership expiration date changed')
else
_('Group membership expiration date removed')
end
member_email_with_layout(
to: member.user.notification_email_for(notification_group),
subject: subject(subject))
end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def member def member
@member ||= Member.find_by(id: @member_id) @member ||= Member.find_by(id: @member_id)
......
...@@ -74,6 +74,10 @@ class GroupMember < Member ...@@ -74,6 +74,10 @@ class GroupMember < Member
run_after_commit { notification_service.update_group_member(self) } run_after_commit { notification_service.update_group_member(self) }
end end
if saved_change_to_expires_at?
run_after_commit { notification_service.updated_group_member_expiration(self) }
end
super super
end end
......
...@@ -481,6 +481,12 @@ class NotificationService ...@@ -481,6 +481,12 @@ class NotificationService
mailer.member_access_granted_email(group_member.real_source_type, group_member.id).deliver_later mailer.member_access_granted_email(group_member.real_source_type, group_member.id).deliver_later
end end
def updated_group_member_expiration(group_member)
return true unless group_member.notifiable?(:mention)
mailer.member_expiration_date_updated_email(group_member.real_source_type, group_member.id).deliver_later
end
def project_was_moved(project, old_path_with_namespace) def project_was_moved(project, old_path_with_namespace)
recipients = project_moved_recipients(project) recipients = project_moved_recipients(project)
recipients = notifiable_users(recipients, :custom, custom_action: :moved_project, project: project) recipients = notifiable_users(recipients, :custom, custom_action: :moved_project, project: project)
......
= email_default_heading(say_hi(@member.user))
%p
= group_membership_expiration_changed_text(@member, @member_source)
%p
= group_membership_expiration_changed_link(@member, @member_source, format: :html)
<%= say_hi(@member.user) %>
<%= group_membership_expiration_changed_text(@member, @member_source) %>
<%= group_membership_expiration_changed_link(@member, @member_source) %>
---
title: Send email when group member expiry is updated
merge_request: 50310
author:
type: added
...@@ -12614,6 +12614,12 @@ msgstr "" ...@@ -12614,6 +12614,12 @@ msgstr ""
msgid "For a faster browsing experience, some files are collapsed by default." msgid "For a faster browsing experience, some files are collapsed by default."
msgstr "" msgstr ""
msgid "For additional information, review your %{link_to} or contact your group owner."
msgstr ""
msgid "For additional information, review your group membership: %{link_to} or contact your group owner."
msgstr ""
msgid "For help setting up the Service Desk for your instance, please contact an administrator." msgid "For help setting up the Service Desk for your instance, please contact an administrator."
msgstr "" msgstr ""
...@@ -13709,6 +13715,12 @@ msgstr "" ...@@ -13709,6 +13715,12 @@ msgstr ""
msgid "Group members" msgid "Group members"
msgstr "" msgstr ""
msgid "Group membership expiration date changed"
msgstr ""
msgid "Group membership expiration date removed"
msgstr ""
msgid "Group milestone" msgid "Group milestone"
msgstr "" msgstr ""
...@@ -32591,6 +32603,9 @@ msgstr "" ...@@ -32591,6 +32603,9 @@ msgstr ""
msgid "YouTube URL or ID" msgid "YouTube URL or ID"
msgstr "" msgstr ""
msgid "Your %{group} membership will now expire in %{days}."
msgstr ""
msgid "Your %{host} account was signed in to from a new location" msgid "Your %{host} account was signed in to from a new location"
msgstr "" msgstr ""
...@@ -32789,6 +32804,9 @@ msgstr "" ...@@ -32789,6 +32804,9 @@ msgstr ""
msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your %{code_open}.gitlab-license%{code_close} file." msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your %{code_open}.gitlab-license%{code_close} file."
msgstr "" msgstr ""
msgid "Your membership in %{group} no longer expires."
msgstr ""
msgid "Your message here" msgid "Your message here"
msgstr "" msgstr ""
......
...@@ -1615,6 +1615,88 @@ RSpec.describe Notify do ...@@ -1615,6 +1615,88 @@ RSpec.describe Notify do
is_expected.to have_body_text group_member.invite_email is_expected.to have_body_text group_member.invite_email
end end
end end
describe 'group expiration date updated' do
let_it_be(:group_member) { create(:group_member, group: group, expires_at: 1.day.from_now) }
context 'when expiration date is changed' do
subject { described_class.member_expiration_date_updated_email('group', 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'
context 'when expiration date is one day away' do
it 'contains all the useful information' do
is_expected.to have_subject 'Group membership expiration date changed'
is_expected.to have_body_text group_member.user.name
is_expected.to have_body_text group.name
is_expected.to have_body_text group.web_url
is_expected.to have_body_text group_group_members_url(group, search: group_member.user.username)
is_expected.to have_body_text 'day.'
is_expected.not_to have_body_text 'days.'
end
end
context 'when expiration date is more than one day away' do
before do
group_member.update!(expires_at: 20.days.from_now)
end
it 'contains all the useful information' do
is_expected.to have_subject 'Group membership expiration date changed'
is_expected.to have_body_text group_member.user.name
is_expected.to have_body_text group.name
is_expected.to have_body_text group.web_url
is_expected.to have_body_text group_group_members_url(group, search: group_member.user.username)
is_expected.to have_body_text 'days.'
is_expected.not_to have_body_text 'day.'
end
end
context 'when a group member is newly given an expiration date' do
let_it_be(:group_member) { create(:group_member, group: group) }
before do
group_member.update!(expires_at: 5.days.from_now)
end
subject { described_class.member_expiration_date_updated_email('group', group_member.id) }
it 'contains all the useful information' do
is_expected.to have_subject 'Group membership expiration date changed'
is_expected.to have_body_text group_member.user.name
is_expected.to have_body_text group.name
is_expected.to have_body_text group.web_url
is_expected.to have_body_text group_group_members_url(group, search: group_member.user.username)
is_expected.to have_body_text 'days.'
is_expected.not_to have_body_text 'day.'
end
end
end
context 'when expiration date is removed' do
before do
group_member.update!(expires_at: nil)
end
subject { described_class.member_expiration_date_updated_email('group', 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 have_subject 'Group membership expiration date removed'
is_expected.to have_body_text group_member.user.name
is_expected.to have_body_text group.name
end
end
end
end end
describe 'confirmation if email changed' do describe 'confirmation if email changed' do
......
...@@ -123,4 +123,16 @@ RSpec.describe GroupMember do ...@@ -123,4 +123,16 @@ RSpec.describe GroupMember do
end end
end end
end end
context 'when group member expiration date is updated' do
let_it_be(:group_member) { create(:group_member) }
it 'emails the user that their group membership expiry has changed' do
expect_next_instance_of(NotificationService) do |notification|
allow(notification).to receive(:updated_group_member_expiration).with(group_member)
end
group_member.update!(expires_at: 5.days.from_now)
end
end
end end
...@@ -2455,6 +2455,18 @@ RSpec.describe NotificationService, :mailer do ...@@ -2455,6 +2455,18 @@ RSpec.describe NotificationService, :mailer do
let(:notification_trigger) { group.add_guest(added_user) } let(:notification_trigger) { group.add_guest(added_user) }
end end
end end
describe '#updated_group_member_expiration' do
let_it_be(:group_member) { create(:group_member) }
it 'emails the user that their group membership expiry has changed' do
expect_next_instance_of(NotificationService) do |notification|
allow(notification).to receive(:updated_group_member_expiration).with(group_member)
end
group_member.update!(expires_at: 5.days.from_now)
end
end
end end
describe 'ProjectMember', :deliver_mails_inline do describe 'ProjectMember', :deliver_mails_inline do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment