diff --git a/app/mailers/emails/groups.rb b/app/mailers/emails/groups.rb deleted file mode 100644 index fe218bfbe05..00000000000 --- a/app/mailers/emails/groups.rb +++ /dev/null @@ -1,73 +0,0 @@ -module Emails - module Groups - def group_access_requested_email(group_member_id) - setup_group_member_mail(group_member_id) - - @requester = @group_member.created_by - - group_admins = User.where(id: @group.group_members.admins.pluck(:user_id)).pluck(:notification_email) - - mail(to: group_admins, - subject: subject("Request to join #{@group.name} group")) - end - - def group_access_granted_email(group_member_id) - setup_group_member_mail(group_member_id) - - @current_user = @group_member.user - - mail(to: @current_user.notification_email, - subject: subject("Access to #{@group.name} group was granted")) - end - - def group_access_denied_email(group_id, user_id) - @group = Group.find(group_id) - @current_user = User.find(user_id) - @target_url = group_url(@group) - - mail(to: @current_user.notification_email, - subject: subject("Access to #{@group.name} group was denied")) - end - - def group_member_invited_email(group_member_id, token) - setup_group_member_mail(group_member_id) - - @token = token - @current_user = @group_member.user - - mail(to: @group_member.invite_email, - subject: "Invitation to join group #{@group.name}") - end - - def group_invite_accepted_email(group_member_id) - setup_group_member_mail(group_member_id) - return if @group_member.created_by.nil? - - @current_user = @group_member.created_by - - mail(to: @current_user.notification_email, - subject: subject("Invitation accepted")) - end - - def group_invite_declined_email(group_id, invite_email, access_level, created_by_id) - return if created_by_id.nil? - - @group = Group.find(group_id) - @current_user = @created_by = User.find(created_by_id) - @access_level = access_level - @invite_email = invite_email - - @target_url = group_url(@group) - mail(to: @created_by.notification_email, - subject: subject("Invitation declined")) - end - - private - - def setup_group_member_mail(group_member_id) - @group_member = GroupMember.find(group_member_id) - @group = @group_member.group - @target_url = group_url(@group) - end - end -end diff --git a/app/mailers/emails/members.rb b/app/mailers/emails/members.rb new file mode 100644 index 00000000000..5fd55c149df --- /dev/null +++ b/app/mailers/emails/members.rb @@ -0,0 +1,104 @@ +module Emails + module Members + extend ActiveSupport::Concern + + included do + attr_reader :member_target_type + helper_method :member, :access_requester, :member_target_type, :member_target_name, :member_target_url + end + + def member_access_requested_email(member_target_type, member_id) + @member_target_type = member_target_type + @member_id = member_id + + admins = User.where(id: target.public_send(members_association).admins.pluck(:user_id)).pluck(:notification_email) + + mail(to: admins, + subject: subject("Request to join the #{member_target_name} #{member_target_type}")) + end + + def member_access_granted_email(member_target_type, member_id) + @member_target_type = member_target_type + @member_id = member_id + + mail(to: member.user.notification_email, + subject: subject("Access to the #{member_target_name} #{member_target_type} was granted")) + end + + def member_access_denied_email(member_target_type, target_id, user_id) + @member_target_type = member_target_type + @target = target_class.find(target_id) + + mail(to: User.find(user_id).notification_email, + subject: subject("Access to the #{member_target_name} #{member_target_type} was denied")) + end + + def member_invited_email(member_target_type, member_id, token) + @member_target_type = member_target_type + @member_id = member_id + @token = token + + mail(to: member.invite_email, + subject: "Invitation to join the #{member_target_name} #{member_target_type}") + end + + def member_invite_accepted_email(member_target_type, member_id) + @member_target_type = member_target_type + @member_id = member_id + return if access_requester.nil? + + mail(to: access_requester.notification_email, + subject: subject('Invitation accepted')) + end + + def member_invite_declined_email(member_target_type, target_id, invite_email, created_by_id) + return if created_by_id.nil? + + @member_target_type = member_target_type + @target = target_class.find(target_id) + @invite_email = invite_email + + mail(to: User.find(created_by_id).notification_email, + subject: subject('Invitation declined')) + end + + def member + @member ||= member_class.find(@member_id) + end + + def access_requester + @access_requester ||= member.created_by + end + + def member_target_name + case member_target_type + when 'project' + target.name_with_namespace + else + target.name + end + end + + def member_target_url + @member_target_url ||= target.web_url + end + + private + + def target + @target ||= member.public_send(member_target_type) + end + + def target_class + @target_class ||= member_target_type.classify.constantize + end + + def member_class + @member_class ||= "#{member_target_type.classify}Member".constantize + end + + def members_association + @members_association ||= member_class.to_s.tableize + end + end +end diff --git a/app/mailers/emails/projects.rb b/app/mailers/emails/projects.rb index 43a2a7e80a8..689fb3e0ffb 100644 --- a/app/mailers/emails/projects.rb +++ b/app/mailers/emails/projects.rb @@ -1,68 +1,5 @@ module Emails module Projects - def project_access_requested_email(project_member_id) - setup_project_member_mail(project_member_id) - - @requester = @project_member.created_by - - project_admins = User.where(id: @project.project_members.admins.pluck(:user_id)).pluck(:notification_email) - - mail(to: project_admins, - subject: subject("Request to join #{@project.name_with_namespace} project")) - end - - def project_access_granted_email(project_member_id) - setup_project_member_mail(project_member_id) - - @current_user = @project_member.user - - mail(to: @current_user.notification_email, - subject: subject("Access to #{@project.name_with_namespace} project was granted")) - end - - def project_access_denied_email(project_id, user_id) - @project = Project.find(project_id) - @current_user = User.find(user_id) - @target_url = namespace_project_url(@project.namespace, @project) - - mail(to: @current_user.notification_email, - subject: subject("Access to #{@project.name_with_namespace} project was denied")) - end - - def project_member_invited_email(project_member_id, token) - setup_project_member_mail(project_member_id) - - @token = token - @current_user = @project_member.user - - mail(to: @project_member.invite_email, - subject: "Invitation to join project #{@project.name_with_namespace}") - end - - def project_invite_accepted_email(project_member_id) - setup_project_member_mail(project_member_id) - return if @project_member.created_by.nil? - - @current_user = @project_member.created_by - - mail(to: @project_member.created_by.notification_email, - subject: subject("Invitation accepted")) - end - - def project_invite_declined_email(project_id, invite_email, access_level, created_by_id) - return if created_by_id.nil? - - @project = Project.find(project_id) - @current_user = @created_by = User.find(created_by_id) - @access_level = access_level - @invite_email = invite_email - - @target_url = namespace_project_url(@project.namespace, @project) - - mail(to: @created_by.notification_email, - subject: subject("Invitation declined")) - end - def project_was_moved_email(project_id, user_id, old_path_with_namespace) @current_user = @user = User.find user_id @project = Project.find project_id @@ -88,13 +25,5 @@ module Emails reply_to: @message.reply_to, subject: @message.subject) end - - private - - def setup_project_member_mail(project_member_id) - @project_member = ProjectMember.find(project_member_id) - @project = @project_member.project - @target_url = namespace_project_url(@project.namespace, @project) - end end end diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb index 1c663bdd521..bd5c6788cce 100644 --- a/app/mailers/notify.rb +++ b/app/mailers/notify.rb @@ -6,8 +6,8 @@ class Notify < BaseMailer include Emails::Notes include Emails::Projects include Emails::Profile - include Emails::Groups include Emails::Builds + include Emails::Members add_template_helper MergeRequestsHelper add_template_helper DiffHelper diff --git a/app/models/group.rb b/app/models/group.rb index b6929112cba..520cbd0283c 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -59,6 +59,10 @@ class Group < Namespace "#{self.class.reference_prefix}#{name}" end + def web_url + Gitlab::Routing.url_helpers.group_url(self) + end + def human_name name end diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index cd11feb9d7a..259199f6e2b 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -175,23 +175,24 @@ class NotificationService # Project access request def new_project_access_request(project_member) - mailer.project_access_requested_email(project_member.id).deliver_later + mailer.member_access_requested_email('project', project_member.id).deliver_later end def decline_project_access_request(project, user) - mailer.project_access_denied_email(project.id, user.id).deliver_later + mailer.member_access_denied_email('project', project.id, user.id).deliver_later end def invite_project_member(project_member, token) - mailer.project_member_invited_email(project_member.id, token).deliver_later + mailer.member_invited_email('project', project_member.id, token).deliver_later end def accept_project_invite(project_member) - mailer.project_invite_accepted_email(project_member.id).deliver_later + mailer.member_invite_accepted_email('project', project_member.id).deliver_later end def decline_project_invite(project_member) - mailer.project_invite_declined_email( + mailer.member_invite_declined_email( + 'project', project_member.project.id, project_member.invite_email, project_member.access_level, @@ -200,32 +201,33 @@ class NotificationService end def new_project_member(project_member) - mailer.project_access_granted_email(project_member.id).deliver_later + mailer.member_access_granted_email('project', project_member.id).deliver_later end def update_project_member(project_member) - mailer.project_access_granted_email(project_member.id).deliver_later + mailer.member_access_granted_email('project', project_member.id).deliver_later end # Group access request def new_group_access_request(group_member) - mailer.group_access_requested_email(group_member.id).deliver_later + mailer.member_access_requested_email('group', group_member.id).deliver_later end def decline_group_access_request(group, user) - mailer.group_access_denied_email(group.id, user.id).deliver_later + mailer.member_access_denied_email('group', group.id, user.id).deliver_later end def invite_group_member(group_member, token) - mailer.group_member_invited_email(group_member.id, token).deliver_later + mailer.member_invited_email('group', group_member.id, token).deliver_later end def accept_group_invite(group_member) - mailer.group_invite_accepted_email(group_member.id).deliver_later + mailer.member_invite_accepted_email(group_member.id).deliver_later end def decline_group_invite(group_member) - mailer.group_invite_declined_email( + mailer.member_invite_declined_email( + 'group', group_member.group.id, group_member.invite_email, group_member.access_level, @@ -234,11 +236,11 @@ class NotificationService end def new_group_member(group_member) - mailer.group_access_granted_email(group_member.id).deliver_later + mailer.member_access_granted_email('group', group_member.id).deliver_later end def update_group_member(group_member) - mailer.group_access_granted_email(group_member.id).deliver_later + mailer.member_access_granted_email('group', group_member.id).deliver_later end def project_was_moved(project, old_path_with_namespace) diff --git a/app/views/notify/group_access_denied_email.html.haml b/app/views/notify/group_access_denied_email.html.haml deleted file mode 100644 index 4edfd4e4793..00000000000 --- a/app/views/notify/group_access_denied_email.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -%p - Your request to join group #{link_to @group.name, @target_url} has been denied. diff --git a/app/views/notify/group_access_denied_email.text.erb b/app/views/notify/group_access_denied_email.text.erb deleted file mode 100644 index cb32177e826..00000000000 --- a/app/views/notify/group_access_denied_email.text.erb +++ /dev/null @@ -1,3 +0,0 @@ -Your request to join group <%= @group.name %> has been denied. - -<%= @target_url %> diff --git a/app/views/notify/group_access_requested_email.html.haml b/app/views/notify/group_access_requested_email.html.haml deleted file mode 100644 index 4fbcedabae0..00000000000 --- a/app/views/notify/group_access_requested_email.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -%p - #{link_to @requester.name, @requester} requested #{@group_member.human_access} - access to group #{link_to @group.name, @target_url}. diff --git a/app/views/notify/group_access_requested_email.text.erb b/app/views/notify/group_access_requested_email.text.erb deleted file mode 100644 index 2f9d293a79e..00000000000 --- a/app/views/notify/group_access_requested_email.text.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= @requester.name %> (<%= user_url(@requester) %>) requested <%= @group_member.human_access %> access to group <%= @group.name %> - -<%= @target_url %> diff --git a/app/views/notify/member_access_denied_email.html.haml b/app/views/notify/member_access_denied_email.html.haml new file mode 100644 index 00000000000..a25af24d783 --- /dev/null +++ b/app/views/notify/member_access_denied_email.html.haml @@ -0,0 +1,4 @@ +%p + Your request to join the + #{link_to member_target_name, member_target_url} #{member_target_type} + has been denied. diff --git a/app/views/notify/member_access_denied_email.text.erb b/app/views/notify/member_access_denied_email.text.erb new file mode 100644 index 00000000000..eb204458d9d --- /dev/null +++ b/app/views/notify/member_access_denied_email.text.erb @@ -0,0 +1,3 @@ +Your request to join the <%= member_target_name %> <%= member_target_type %> has been denied. + +<%= member_target_url %> diff --git a/app/views/notify/member_access_granted_email.html.haml b/app/views/notify/member_access_granted_email.html.haml new file mode 100644 index 00000000000..62837d74555 --- /dev/null +++ b/app/views/notify/member_access_granted_email.html.haml @@ -0,0 +1,3 @@ +%p + You have been granted #{member.human_access} access to the + #{link_to member_target_name, member_target_url} #{member_target_type}. diff --git a/app/views/notify/member_access_granted_email.text.erb b/app/views/notify/member_access_granted_email.text.erb new file mode 100644 index 00000000000..be9bb5ee948 --- /dev/null +++ b/app/views/notify/member_access_granted_email.text.erb @@ -0,0 +1,3 @@ +You have been granted <%= member.human_access %> access to the <%= member_target_name %> <%= member_target_type %>. + +<%= member_target_url %> diff --git a/app/views/notify/member_access_requested_email.html.haml b/app/views/notify/member_access_requested_email.html.haml new file mode 100644 index 00000000000..96e92a069f2 --- /dev/null +++ b/app/views/notify/member_access_requested_email.html.haml @@ -0,0 +1,3 @@ +%p + #{link_to access_requester.name, access_requester} requested #{member.human_access} + access to the #{link_to member_target_name, member_target_url} #{member_target_type}. diff --git a/app/views/notify/member_access_requested_email.text.erb b/app/views/notify/member_access_requested_email.text.erb new file mode 100644 index 00000000000..3b5de8c2abe --- /dev/null +++ b/app/views/notify/member_access_requested_email.text.erb @@ -0,0 +1,3 @@ +<%= access_requester.name %> (<%= user_url(access_requester) %>) requested <%= member.human_access %> access to the <%= member_target_name %> <%= member_target_type %>. + +<%= member_target_url %> diff --git a/app/views/notify/member_invite_accepted_email.html.haml b/app/views/notify/member_invite_accepted_email.html.haml new file mode 100644 index 00000000000..c420a8a7b3c --- /dev/null +++ b/app/views/notify/member_invite_accepted_email.html.haml @@ -0,0 +1,5 @@ +%p + #{member.invite_email}, now known as + #{link_to member.user.name, user_url(member.user)}, + has accepted your invitation to join the + #{link_to member_target_name, member_target_url} #{member_target_type}. diff --git a/app/views/notify/member_invite_accepted_email.text.erb b/app/views/notify/member_invite_accepted_email.text.erb new file mode 100644 index 00000000000..a1616163ceb --- /dev/null +++ b/app/views/notify/member_invite_accepted_email.text.erb @@ -0,0 +1,3 @@ +<%= member.invite_email %>, now known as <%= member.user.name %>, has accepted your invitation to join the <%= member_target_name %> <%= member_target_type %>. + +<%= member_target_url %> diff --git a/app/views/notify/member_invite_declined_email.html.haml b/app/views/notify/member_invite_declined_email.html.haml new file mode 100644 index 00000000000..5a30ac31b3c --- /dev/null +++ b/app/views/notify/member_invite_declined_email.html.haml @@ -0,0 +1,4 @@ +%p + #{@invite_email} + has declined your invitation to join the + #{link_to member_target_name, member_target_url} #{member_target_type}. diff --git a/app/views/notify/member_invite_declined_email.text.erb b/app/views/notify/member_invite_declined_email.text.erb new file mode 100644 index 00000000000..301287946d4 --- /dev/null +++ b/app/views/notify/member_invite_declined_email.text.erb @@ -0,0 +1,3 @@ +<%= @invite_email %> has declined your invitation to join the <%= member_target_name %> <%= member_target_type %>. + +<%= member_target_url %> diff --git a/app/views/notify/member_invited_email.html.haml b/app/views/notify/member_invited_email.html.haml new file mode 100644 index 00000000000..a8e58df9ac8 --- /dev/null +++ b/app/views/notify/member_invited_email.html.haml @@ -0,0 +1,13 @@ +%p + You have been invited + - if access_requester + by + = link_to access_requester.name, user_url(access_requester) + to join the + = link_to member_target_name, member_target_url + #{member_target_type} as #{member.human_access}. + +%p + = link_to 'Accept invitation', invite_url(@token) + or + = link_to 'decline', decline_invite_url(@token) diff --git a/app/views/notify/member_invited_email.text.erb b/app/views/notify/member_invited_email.text.erb new file mode 100644 index 00000000000..1b6897ee2ec --- /dev/null +++ b/app/views/notify/member_invited_email.text.erb @@ -0,0 +1,4 @@ +You have been invited <%= "by #{access_requester.name} " if access_requester %>to join the <%= member_target_name %> <%= member_target_type %> as <%= member.human_access %>. + +Accept invitation: <%= invite_url(@token) %> +Decline invitation: <%= decline_invite_url(@token) %> diff --git a/app/views/notify/project_access_denied_email.html.haml b/app/views/notify/project_access_denied_email.html.haml deleted file mode 100644 index cecdaf24f39..00000000000 --- a/app/views/notify/project_access_denied_email.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -%p - Your request to join project #{link_to @project.name_with_namespace, @target_url} - has been denied. diff --git a/app/views/notify/project_access_denied_email.text.erb b/app/views/notify/project_access_denied_email.text.erb deleted file mode 100644 index 24357e059d2..00000000000 --- a/app/views/notify/project_access_denied_email.text.erb +++ /dev/null @@ -1,3 +0,0 @@ -Your request to join project <%= @project.name_with_namespace %> has been denied. - -<%= @target_url %> diff --git a/app/views/notify/project_access_granted_email.html.haml b/app/views/notify/project_access_granted_email.html.haml deleted file mode 100644 index 88873e7fe52..00000000000 --- a/app/views/notify/project_access_granted_email.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -%p - You have been granted #{@project_member.human_access} access to project - #{link_to @project.name_with_namespace, @target_url}. diff --git a/app/views/notify/project_access_granted_email.text.erb b/app/views/notify/project_access_granted_email.text.erb deleted file mode 100644 index f5e4b313858..00000000000 --- a/app/views/notify/project_access_granted_email.text.erb +++ /dev/null @@ -1,3 +0,0 @@ -You have been granted <%= @project_member.human_access %> access to project <%= @project.name_with_namespace %>. - -<%= @target_url %> diff --git a/app/views/notify/project_access_requested_email.html.haml b/app/views/notify/project_access_requested_email.html.haml deleted file mode 100644 index 2a705ad3b0a..00000000000 --- a/app/views/notify/project_access_requested_email.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -%p - #{link_to @requester.name, @requester} requested #{@project_member.human_access} - access to project #{link_to @project.name_with_namespace, @target_url}. diff --git a/app/views/notify/project_access_requested_email.text.erb b/app/views/notify/project_access_requested_email.text.erb deleted file mode 100644 index 2437fa4ee86..00000000000 --- a/app/views/notify/project_access_requested_email.text.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= @requester.name %> (<%= user_url(@requester) %>) requested <%= @project_member.human_access %> access to project <%= @project.name_with_namespace %>. - -<%= @target_url %> diff --git a/app/views/notify/project_invite_accepted_email.html.haml b/app/views/notify/project_invite_accepted_email.html.haml deleted file mode 100644 index 7e58d30b10a..00000000000 --- a/app/views/notify/project_invite_accepted_email.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -%p - #{@project_member.invite_email}, now known as - #{link_to @project_member.user.name, user_url(@project_member.user)}, - has accepted your invitation to join project - #{link_to @project.name_with_namespace, namespace_project_url(@project.namespace, @project)}. - diff --git a/app/views/notify/project_invite_accepted_email.text.erb b/app/views/notify/project_invite_accepted_email.text.erb deleted file mode 100644 index fcbe752114d..00000000000 --- a/app/views/notify/project_invite_accepted_email.text.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= @project_member.invite_email %>, now known as <%= @project_member.user.name %>, has accepted your invitation to join project <%= @project.name_with_namespace %>. - -<%= namespace_project_url(@project.namespace, @project) %> diff --git a/app/views/notify/project_invite_declined_email.html.haml b/app/views/notify/project_invite_declined_email.html.haml deleted file mode 100644 index c2d7e6f6e3a..00000000000 --- a/app/views/notify/project_invite_declined_email.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -%p - #{@invite_email} - has declined your invitation to join project - #{link_to @project.name_with_namespace, namespace_project_url(@project.namespace, @project)}. - diff --git a/app/views/notify/project_invite_declined_email.text.erb b/app/views/notify/project_invite_declined_email.text.erb deleted file mode 100644 index 484687fa51c..00000000000 --- a/app/views/notify/project_invite_declined_email.text.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= @invite_email %> has declined your invitation to join project <%= @project.name_with_namespace %>. - -<%= namespace_project_url(@project.namespace, @project) %> diff --git a/app/views/notify/project_member_invited_email.html.haml b/app/views/notify/project_member_invited_email.html.haml deleted file mode 100644 index 79eb89616de..00000000000 --- a/app/views/notify/project_member_invited_email.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -%p - You have been invited - - if inviter = @project_member.created_by - by - = link_to inviter.name, user_url(inviter) - to join project - = link_to @project.name_with_namespace, namespace_project_url(@project.namespace, @project) - as #{@project_member.human_access}. - -%p - = link_to 'Accept invitation', invite_url(@token) - or - = link_to 'decline', decline_invite_url(@token) diff --git a/app/views/notify/project_member_invited_email.text.erb b/app/views/notify/project_member_invited_email.text.erb deleted file mode 100644 index e0706272115..00000000000 --- a/app/views/notify/project_member_invited_email.text.erb +++ /dev/null @@ -1,4 +0,0 @@ -You have been invited <%= "by #{@project_member.created_by.name} " if @project_member.created_by %>to join project <%= @project.name_with_namespace %> as <%= @project_member.human_access %>. - -Accept invitation: <%= invite_url(@token) %> -Decline invitation: <%= decline_invite_url(@token) %> diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index 2d86038030e..a86ec865b5d 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -407,23 +407,16 @@ describe Notify do project.request_access(user) project.project_members.find_by(created_by_id: user.id) end - subject { Notify.project_access_requested_email(project_member.id) } + subject { Notify.member_access_requested_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 'has the correct subject' do - is_expected.to have_subject /Request to join #{project.name_with_namespace} project/ - end - - it 'contains name of project' do - is_expected.to have_body_text /#{project.name}/ - end - - it 'contains new user role' do - is_expected.to have_body_text /#{project_member.human_access}/ - end + it { is_expected.to have_subject "Request to join the #{project.name_with_namespace} project" } + it { is_expected.to have_body_text /#{project.name_with_namespace}/ } + it { is_expected.to have_body_text /#{project.web_url}/ } + it { is_expected.to have_body_text /#{project_member.human_access}/ } end describe 'project access denied' do @@ -433,42 +426,99 @@ describe Notify do project.request_access(user) project.project_members.find_by(created_by_id: user.id) end - subject { Notify.project_access_denied_email(project.id, user.id) } + subject { Notify.member_access_denied_email('project', project.id, user.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 'has the correct subject' do - is_expected.to have_subject /Access to #{project.name_with_namespace} project was denied/ - end - - it 'contains name of project' do - is_expected.to have_body_text /#{project.name}/ - end + it { is_expected.to have_subject "Access to the #{project.name_with_namespace} project was denied" } + it { is_expected.to have_body_text /#{project.name_with_namespace}/ } + it { is_expected.to have_body_text /#{project.web_url}/ } end describe 'project access changed' do let(:project) { create(:project) } let(:user) { create(:user) } let(:project_member) { create(:project_member, project: project, user: user) } - subject { Notify.project_access_granted_email(project_member.id) } + subject { Notify.member_access_granted_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 'has the correct subject' do - is_expected.to have_subject /Access to #{project.name_with_namespace} project was granted/ + it { is_expected.to have_subject "Access to the #{project.name_with_namespace} project was granted" } + it { is_expected.to have_body_text /#{project.name_with_namespace}/ } + it { is_expected.to have_body_text /#{project.web_url}/ } + it { is_expected.to have_body_text /#{project_member.human_access}/ } + end + + def invite_to_project(project:, email:, inviter:) + ProjectMember.add_user(project.project_members, 'toto@example.com', Gitlab::Access::DEVELOPER, inviter) + + project.project_members.invite.last + end + + describe 'project invitation' do + let(:project) { create(:project) } + let(:master) { create(:user).tap { |u| project.team << [u, :master] } } + let(:project_member) { invite_to_project(project: project, email: 'toto@example.com', inviter: master) } + + subject { Notify.member_invited_email('project', project_member.id, project_member.invite_token) } + + 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 { is_expected.to have_subject "Invitation to join the #{project.name_with_namespace} project" } + it { is_expected.to have_body_text /#{project.name_with_namespace}/ } + it { is_expected.to have_body_text /#{project.web_url}/ } + it { is_expected.to have_body_text /#{project_member.human_access}/ } + it { is_expected.to have_body_text /#{project_member.invite_token}/ } + end + + describe 'project invitation accepted' do + let(:project) { create(:project) } + let(:invited_user) { create(:user) } + let(:master) { create(:user).tap { |u| project.team << [u, :master] } } + let(:project_member) do + invitee = invite_to_project(project: project, email: 'toto@example.com', inviter: master) + invitee.accept_invite!(invited_user) + invitee end - it 'contains name of project' do - is_expected.to have_body_text /#{project.name}/ + subject { Notify.member_invite_accepted_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 { is_expected.to have_subject 'Invitation accepted' } + it { is_expected.to have_body_text /#{project.name_with_namespace}/ } + it { is_expected.to have_body_text /#{project.web_url}/ } + it { is_expected.to have_body_text /#{project_member.invite_email}/ } + it { is_expected.to have_body_text /#{invited_user.name}/ } + end + + describe 'project invitation declined' do + let(:project) { create(:project) } + let(:master) { create(:user).tap { |u| project.team << [u, :master] } } + let(:project_member) do + invitee = invite_to_project(project: project, email: 'toto@example.com', inviter: master) + invitee.decline_invite! + invitee end - it 'contains new user role' do - is_expected.to have_body_text /#{project_member.human_access}/ - end + subject { Notify.member_invite_declined_email('project', project.id, project_member.invite_email, master.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 { is_expected.to have_subject 'Invitation declined' } + it { is_expected.to have_body_text /#{project.name_with_namespace}/ } + it { is_expected.to have_body_text /#{project.web_url}/ } + it { is_expected.to have_body_text /#{project_member.invite_email}/ } end context 'items that are noteable, the email for a note' do @@ -583,75 +633,127 @@ describe Notify do end end - describe 'group access requested' do - let(:group) { create(:group) } - let(:user) { create(:user) } - let(:group_member) do - group.request_access(user) - group.group_members.find_by(created_by_id: user.id) - end - subject { Notify.group_access_requested_email(group_member.id) } + context 'for a group' do + describe 'group access requested' do + let(:group) { create(:group) } + let(:user) { create(:user) } + let(:group_member) do + group.request_access(user) + group.group_members.find_by(created_by_id: user.id) + end + subject { Notify.member_access_requested_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 '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 'has the correct subject' do - is_expected.to have_subject /Request to join #{group.name} group/ + it { is_expected.to have_subject "Request to join the #{group.name} group" } + it { is_expected.to have_body_text /#{group.name}/ } + it { is_expected.to have_body_text /#{group.web_url}/ } + it { is_expected.to have_body_text /#{group_member.human_access}/ } end - it 'contains name of group' do - is_expected.to have_body_text /#{group.name}/ + describe 'group access denied' do + let(:group) { create(:group) } + let(:user) { create(:user) } + let(:group_member) do + group.request_access(user) + group.group_members.find_by(created_by_id: user.id) + end + subject { Notify.member_access_denied_email('group', group.id, user.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 { is_expected.to have_subject "Access to the #{group.name} group was denied" } + it { is_expected.to have_body_text /#{group.name}/ } + it { is_expected.to have_body_text /#{group.web_url}/ } end - it 'contains new user role' do - is_expected.to have_body_text /#{group_member.human_access}/ - end - end + describe 'group access changed' do + let(:group) { create(:group) } + let(:user) { create(:user) } + let(:group_member) { create(:group_member, group: group, user: user) } - describe 'group access denied' do - let(:group) { create(:group) } - let(:user) { create(:user) } - let(:group_member) do - group.request_access(user) - group.group_members.find_by(created_by_id: user.id) - end - subject { Notify.group_access_denied_email(group.id, user.id) } + subject { Notify.member_access_granted_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 '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 'has the correct subject' do - is_expected.to have_subject /Access to #{group.name} group was denied/ + it { is_expected.to have_subject "Access to the #{group.name} group was granted" } + it { is_expected.to have_body_text /#{group.name}/ } + it { is_expected.to have_body_text /#{group.web_url}/ } + it { is_expected.to have_body_text /#{group_member.human_access}/ } end - it 'contains name of group' do - is_expected.to have_body_text /#{group.name}/ - end - end + def invite_to_group(group:, email:, inviter:) + GroupMember.add_user(group.group_members, 'toto@example.com', Gitlab::Access::DEVELOPER, inviter) - describe 'group access changed' do - let(:group) { create(:group) } - let(:user) { create(:user) } - let(:membership) { create(:group_member, group: group, user: user) } - - subject { Notify.group_access_granted_email(membership.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 'has the correct subject' do - is_expected.to have_subject /Access to #{group.name} group was granted/ + group.group_members.invite.last end - it 'contains name of project' do - is_expected.to have_body_text /#{group.name}/ + describe 'group invitation' do + let(:group) { create(:group) } + let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } } + let(:group_member) { invite_to_group(group: group, email: 'toto@example.com', inviter: owner) } + + subject { Notify.member_invited_email('group', group_member.id, group_member.invite_token) } + + 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 { is_expected.to have_subject "Invitation to join the #{group.name} group" } + it { is_expected.to have_body_text /#{group.name}/ } + it { is_expected.to have_body_text /#{group.web_url}/ } + it { is_expected.to have_body_text /#{group_member.human_access}/ } + it { is_expected.to have_body_text /#{group_member.invite_token}/ } end - it 'contains new user role' do - is_expected.to have_body_text /#{membership.human_access}/ + describe 'group invitation accepted' do + let(:group) { create(:group) } + let(:invited_user) { create(:user) } + let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } } + let(:group_member) do + invitee = invite_to_group(group: group, email: 'toto@example.com', inviter: owner) + invitee.accept_invite!(invited_user) + invitee + end + + subject { Notify.member_invite_accepted_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 { is_expected.to have_subject 'Invitation accepted' } + it { is_expected.to have_body_text /#{group.name}/ } + it { is_expected.to have_body_text /#{group.web_url}/ } + it { is_expected.to have_body_text /#{group_member.invite_email}/ } + it { is_expected.to have_body_text /#{invited_user.name}/ } + end + + describe 'group invitation declined' do + let(:group) { create(:group) } + let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } } + let(:group_member) do + invitee = invite_to_group(group: group, email: 'toto@example.com', inviter: owner) + invitee.decline_invite! + invitee + end + + subject { Notify.member_invite_declined_email('group', group.id, group_member.invite_email, owner.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 { is_expected.to have_subject 'Invitation declined' } + it { is_expected.to have_body_text /#{group.name}/ } + it { is_expected.to have_body_text /#{group.web_url}/ } + it { is_expected.to have_body_text /#{group_member.invite_email}/ } end end