2019-12-26 22:10:19 +05:30
# frozen_string_literal: true
2014-09-02 18:07:02 +05:30
require 'spec_helper'
2015-09-11 14:41:01 +05:30
require 'email_spec'
2014-09-02 18:07:02 +05:30
2020-07-28 23:09:34 +05:30
RSpec . describe Notify do
2014-09-02 18:07:02 +05:30
include EmailSpec :: Helpers
include EmailSpec :: Matchers
2019-02-15 15:39:39 +05:30
include EmailHelpers
2022-08-13 15:12:31 +05:30
include EmailsHelper
2014-09-02 18:07:02 +05:30
include RepoHelpers
2021-12-11 22:18:48 +05:30
include MembersHelper
2014-09-02 18:07:02 +05:30
2016-04-02 18:10:28 +05:30
include_context 'gitlab email notification'
2014-09-02 18:07:02 +05:30
2019-02-15 15:39:39 +05:30
let ( :current_user_sanitized ) { 'www_example_com' }
2020-04-22 19:07:51 +05:30
let_it_be ( :user , reload : true ) { create ( :user ) }
let_it_be ( :current_user , reload : true ) { create ( :user , email : " current@email.com " , name : 'www.example.com' ) }
let_it_be ( :assignee , reload : true ) { create ( :user , email : 'assignee@example.com' , name : 'John Doe' ) }
2021-04-17 20:07:23 +05:30
let_it_be ( :reviewer , reload : true ) { create ( :user , email : 'reviewer@example.com' , name : 'Jane Doe' ) }
2017-09-10 17:25:29 +05:30
2020-04-08 14:13:33 +05:30
let_it_be ( :merge_request ) do
2023-07-09 08:55:56 +05:30
create (
:merge_request ,
source_project : project ,
target_project : project ,
author : current_user ,
assignees : [ assignee ] ,
reviewers : [ reviewer ] ,
description : 'Awesome description'
)
2017-09-10 17:25:29 +05:30
end
2020-04-08 14:13:33 +05:30
let_it_be ( :issue , reload : true ) do
2023-07-09 08:55:56 +05:30
create (
:issue ,
author : current_user ,
assignees : [ assignee ] ,
project : project ,
description : 'My awesome description!'
)
2017-09-10 17:25:29 +05:30
end
2019-07-07 11:18:12 +05:30
describe 'with HTML-encoded entities' do
before do
described_class . test_email ( 'test@test.com' , 'Subject' , 'Some body with —' ) . deliver
end
subject { ActionMailer :: Base . deliveries . last }
it 'retains 7bit encoding' do
expect ( subject . body . ascii_only? ) . to eq ( true )
expect ( subject . body . encoding ) . to eq ( '7bit' )
end
end
2020-08-18 19:51:02 +05:30
shared_examples 'it requires a group' do
context 'when given an deleted group' do
before do
# destroy group and group member
group_member . destroy!
group . destroy!
end
it 'returns NullMail type message' do
expect ( Gitlab :: AppLogger ) . to receive ( :info )
expect ( subject . message ) . to be_a ( ActionMailer :: Base :: NullMail )
end
end
end
2014-09-02 18:07:02 +05:30
context 'for a project' do
2018-03-17 18:26:18 +05:30
shared_examples 'an assignee email' do
2019-09-04 21:01:54 +05:30
let ( :recipient ) { assignee }
it_behaves_like 'an email sent to a user'
2018-03-17 18:26:18 +05:30
it 'is sent to the assignee as the author' do
aggregate_failures do
2021-04-29 21:17:54 +05:30
expect_sender ( current_user )
2021-11-11 11:23:49 +05:30
expect ( subject ) . to deliver_to ( recipient . notification_email_or_default )
2018-03-17 18:26:18 +05:30
end
end
end
2023-06-20 00:43:36 +05:30
context 'for issues' , feature_category : :team_planning do
2018-03-17 18:26:18 +05:30
describe 'that are new' do
subject { described_class . new_issue_email ( issue . assignees . first . id , issue . id ) }
2014-09-02 18:07:02 +05:30
2018-03-17 18:26:18 +05:30
it_behaves_like 'an assignee email'
it_behaves_like 'an email starting a new thread with reply-by-email enabled' do
let ( :model ) { issue }
end
2020-05-24 23:13:21 +05:30
2018-03-17 18:26:18 +05:30
it_behaves_like 'it should show Gmail Actions View Issue link'
it_behaves_like 'an unsubscribeable thread'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2014-09-02 18:07:02 +05:30
2018-03-17 18:26:18 +05:30
it 'has the correct subject and body' do
2017-08-17 22:00:37 +05:30
aggregate_failures do
2018-03-17 18:26:18 +05:30
is_expected . to have_referable_subject ( issue )
is_expected . to have_body_text ( project_issue_path ( project , issue ) )
2017-08-17 22:00:37 +05:30
end
2014-09-02 18:07:02 +05:30
end
2018-03-17 18:26:18 +05:30
it 'contains the description' do
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text issue . description
2018-03-17 18:26:18 +05:30
end
it 'does not add a reason header' do
is_expected . not_to have_header ( 'X-GitLab-NotificationReason' , / .+ / )
end
2014-09-02 18:07:02 +05:30
2018-03-17 18:26:18 +05:30
context 'when sent with a reason' do
subject { described_class . new_issue_email ( issue . assignees . first . id , issue . id , NotificationReason :: ASSIGNED ) }
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2018-03-17 18:26:18 +05:30
it 'includes the reason in a header' do
is_expected . to have_header ( 'X-GitLab-NotificationReason' , NotificationReason :: ASSIGNED )
2016-06-02 11:05:42 +05:30
end
2018-03-17 18:26:18 +05:30
end
2019-09-30 21:07:59 +05:30
it 'contains a link to issue author' do
is_expected . to have_body_text ( issue . author_name )
2021-06-08 01:23:25 +05:30
is_expected . to have_body_text 'created an issue:'
2020-07-28 23:09:34 +05:30
is_expected . to have_link ( issue . to_reference , href : project_issue_url ( issue . project , issue ) )
2020-06-23 00:09:42 +05:30
end
it 'contains a link to the issue' do
is_expected . to have_body_text ( issue . to_reference ( full : false ) )
2018-03-17 18:26:18 +05:30
end
end
2017-09-10 17:25:29 +05:30
2018-03-17 18:26:18 +05:30
describe 'that are reassigned' do
let ( :previous_assignee ) { create ( :user , name : 'Previous Assignee' ) }
2020-01-01 13:55:28 +05:30
2018-03-17 18:26:18 +05:30
subject { described_class . reassigned_issue_email ( recipient . id , issue . id , [ previous_assignee . id ] , current_user . id ) }
2016-04-02 18:10:28 +05:30
2018-03-17 18:26:18 +05:30
it_behaves_like 'a multiple recipients email'
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { issue }
2014-09-02 18:07:02 +05:30
end
2020-05-24 23:13:21 +05:30
2018-03-17 18:26:18 +05:30
it_behaves_like 'it should show Gmail Actions View Issue link'
it_behaves_like 'an unsubscribeable thread'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2023-06-20 00:43:36 +05:30
it_behaves_like 'email with default notification reason'
it_behaves_like 'email with link to issue'
2014-09-02 18:07:02 +05:30
2018-03-17 18:26:18 +05:30
it 'is sent as the author' do
2021-04-29 21:17:54 +05:30
expect_sender ( current_user )
2018-03-17 18:26:18 +05:30
end
2014-09-02 18:07:02 +05:30
2018-03-17 18:26:18 +05:30
it 'has the correct subject and body' do
aggregate_failures do
is_expected . to have_referable_subject ( issue , reply : true )
2023-06-20 00:43:36 +05:30
is_expected . to have_body_text ( " Assignee changed from <strong> #{ previous_assignee . name } </strong> to <strong> #{ assignee . name } </strong> " )
is_expected . to have_plain_text_content ( " Assignee changed from #{ previous_assignee . name } to #{ assignee . name } " )
end
end
context 'without new assignee' do
before do
issue . update! ( assignees : [ ] )
end
it_behaves_like 'email with default notification reason'
it_behaves_like 'email with link to issue'
it 'uses "Unassigned" placeholder' do
is_expected . to have_body_text ( " Assignee changed from <strong> #{ previous_assignee . name } </strong> to <strong>Unassigned</strong> " )
is_expected . to have_plain_text_content ( " Assignee changed from #{ previous_assignee . name } to Unassigned " )
end
end
context 'without previous assignees' do
subject { described_class . reassigned_issue_email ( recipient . id , issue . id , [ ] , current_user . id ) }
it_behaves_like 'email with default notification reason'
it_behaves_like 'email with link to issue'
it 'uses short text' do
is_expected . to have_body_text ( " Assignee changed to <strong> #{ assignee . name } </strong> " )
is_expected . to have_plain_text_content ( " Assignee changed to #{ assignee . name } " )
2016-06-02 11:05:42 +05:30
end
2018-03-17 18:26:18 +05:30
end
2014-09-02 18:07:02 +05:30
2018-03-17 18:26:18 +05:30
context 'when sent with a reason' do
subject { described_class . reassigned_issue_email ( recipient . id , issue . id , [ previous_assignee . id ] , current_user . id , NotificationReason :: ASSIGNED ) }
2014-09-02 18:07:02 +05:30
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2018-03-17 18:26:18 +05:30
it 'includes the reason in a header' do
is_expected . to have_header ( 'X-GitLab-NotificationReason' , NotificationReason :: ASSIGNED )
2014-09-02 18:07:02 +05:30
end
end
2022-10-11 01:57:18 +05:30
context 'when sent with a non default locale' do
let ( :email_obj ) { create ( :email , :confirmed , user_id : recipient . id , email : '123@abc' ) }
let ( :recipient ) { create ( :user , preferred_language : :zh_CN ) }
it 'is translated into zh_CN' do
recipient . notification_email = email_obj . email
recipient . save!
is_expected . to have_body_text '指派人从 <strong>Previous Assignee</strong> 更改为 <strong>John Doe</strong>'
end
end
2018-03-17 18:26:18 +05:30
end
describe 'that have been relabeled' do
subject { described_class . relabeled_issue_email ( recipient . id , issue . id , %w[ foo bar baz ] , current_user . id ) }
it_behaves_like 'a multiple recipients email'
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { issue }
end
2020-05-24 23:13:21 +05:30
2018-03-17 18:26:18 +05:30
it_behaves_like 'it should show Gmail Actions View Issue link'
it_behaves_like 'a user cannot unsubscribe through footer link'
it_behaves_like 'an email with a labels subscriptions link in its footer'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2014-09-02 18:07:02 +05:30
2018-03-17 18:26:18 +05:30
it 'is sent as the author' do
2021-04-29 21:17:54 +05:30
expect_sender ( current_user )
2018-03-17 18:26:18 +05:30
end
2016-06-02 11:05:42 +05:30
2018-03-17 18:26:18 +05:30
it 'has the correct subject and body' do
aggregate_failures do
is_expected . to have_referable_subject ( issue , reply : true )
is_expected . to have_body_text ( 'foo, bar, and baz' )
is_expected . to have_body_text ( project_issue_path ( project , issue ) )
2016-06-02 11:05:42 +05:30
end
2018-03-17 18:26:18 +05:30
end
2016-06-02 11:05:42 +05:30
2018-03-17 18:26:18 +05:30
context 'with a preferred language' do
before do
Gitlab :: I18n . locale = :es
2016-06-02 11:05:42 +05:30
end
2018-03-17 18:26:18 +05:30
after do
Gitlab :: I18n . use_default_locale
2017-09-10 17:25:29 +05:30
end
2018-03-17 18:26:18 +05:30
it 'always generates the email using the default language' do
is_expected . to have_body_text ( 'foo, bar, and baz' )
end
end
end
2017-09-10 17:25:29 +05:30
2019-12-04 20:38:33 +05:30
describe 'that are due soon' do
subject { described_class . issue_due_email ( recipient . id , issue . id ) }
before do
2022-03-02 08:16:31 +05:30
issue . update! ( due_date : Date . tomorrow )
2019-12-04 20:38:33 +05:30
end
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { issue }
end
2020-05-24 23:13:21 +05:30
2021-03-08 18:12:59 +05:30
it 'contains a link to the issue' do
is_expected . to have_body_text ( issue . to_reference ( full : false ) )
end
2019-12-04 20:38:33 +05:30
it_behaves_like 'it should show Gmail Actions View Issue link'
it_behaves_like 'an unsubscribeable thread'
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
end
2018-03-17 18:26:18 +05:30
describe 'status changed' do
let ( :status ) { 'closed' }
2020-01-01 13:55:28 +05:30
2018-03-17 18:26:18 +05:30
subject { described_class . issue_status_changed_email ( recipient . id , issue . id , status , current_user . id ) }
2017-09-10 17:25:29 +05:30
2018-03-17 18:26:18 +05:30
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { issue }
2016-06-02 11:05:42 +05:30
end
2020-05-24 23:13:21 +05:30
2018-03-17 18:26:18 +05:30
it_behaves_like 'it should show Gmail Actions View Issue link'
it_behaves_like 'an unsubscribeable thread'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2016-06-02 11:05:42 +05:30
2018-03-17 18:26:18 +05:30
it 'is sent as the author' do
2021-04-29 21:17:54 +05:30
expect_sender ( current_user )
2018-03-17 18:26:18 +05:30
end
2014-09-02 18:07:02 +05:30
2018-03-17 18:26:18 +05:30
it 'has the correct subject and body' do
aggregate_failures do
is_expected . to have_referable_subject ( issue , reply : true )
is_expected . to have_body_text ( status )
2019-02-15 15:39:39 +05:30
is_expected . to have_body_text ( current_user_sanitized )
2020-04-22 19:07:51 +05:30
is_expected . to have_body_text ( project_issue_path ( project , issue ) )
2016-06-02 11:05:42 +05:30
end
2018-03-17 18:26:18 +05:30
end
end
2014-09-02 18:07:02 +05:30
2023-06-20 00:43:36 +05:30
describe 'closed' do
subject { described_class . closed_issue_email ( recipient . id , issue . id , current_user . id ) }
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { issue }
end
it_behaves_like 'it should show Gmail Actions View Issue link'
it_behaves_like 'an unsubscribeable thread'
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
it_behaves_like 'email with default notification reason'
it_behaves_like 'email with link to issue'
it 'is sent as the author' do
expect_sender ( current_user )
end
it 'has the correct subject and body' do
aggregate_failures do
is_expected . to have_referable_subject ( issue , reply : true )
is_expected . to have_body_text ( " Issue was closed by #{ current_user_sanitized } " )
is_expected . to have_plain_text_content ( " Issue was closed by #{ current_user_sanitized } " )
end
end
context 'via commit' do
let ( :closing_commit ) { project . commit }
subject { described_class . closed_issue_email ( recipient . id , issue . id , current_user . id , closed_via : closing_commit . id ) }
before do
allow ( Ability ) . to receive ( :allowed? ) . with ( recipient , :mark_note_as_internal , anything ) . and_return ( true )
allow ( Ability ) . to receive ( :allowed? ) . with ( recipient , :download_code , project ) . and_return ( true )
end
it_behaves_like 'email with default notification reason'
it_behaves_like 'email with link to issue'
it 'has the correct subject and body' do
aggregate_failures do
is_expected . to have_referable_subject ( issue , reply : true )
is_expected . to have_body_text ( " Issue was closed by #{ current_user_sanitized } via #{ closing_commit . id } " )
is_expected . to have_plain_text_content ( " Issue was closed by #{ current_user_sanitized } via #{ closing_commit . id } " )
end
end
end
context 'via merge request' do
let ( :closing_merge_request ) { merge_request }
subject { described_class . closed_issue_email ( recipient . id , issue . id , current_user . id , closed_via : closing_merge_request ) }
before do
allow ( Ability ) . to receive ( :allowed? ) . with ( recipient , :read_cross_project , :global ) . and_return ( true )
allow ( Ability ) . to receive ( :allowed? ) . with ( recipient , :mark_note_as_internal , anything ) . and_return ( true )
allow ( Ability ) . to receive ( :allowed? ) . with ( recipient , :read_merge_request , anything ) . and_return ( true )
end
it_behaves_like 'email with default notification reason'
it_behaves_like 'email with link to issue'
it 'has the correct subject and body' do
aggregate_failures do
url = project_merge_request_url ( project , closing_merge_request )
is_expected . to have_referable_subject ( issue , reply : true )
is_expected . to have_body_text ( " Issue was closed by #{ current_user_sanitized } via merge request " +
%( <a href=" #{ url } "> #{ closing_merge_request . to_reference } </a> ) )
is_expected . to have_plain_text_content ( " Issue was closed by #{ current_user_sanitized } via merge request " \
" #{ closing_merge_request . to_reference } ( #{ url } ) " )
end
end
end
end
2018-03-17 18:26:18 +05:30
describe 'moved to another project' do
let ( :new_issue ) { create ( :issue ) }
2020-01-01 13:55:28 +05:30
2018-03-17 18:26:18 +05:30
subject { described_class . issue_moved_email ( recipient , issue , new_issue , current_user ) }
2014-09-02 18:07:02 +05:30
2019-03-13 22:55:13 +05:30
context 'when a user has permissions to access the new issue' do
before do
new_issue . project . add_developer ( recipient )
end
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { issue }
end
2020-05-24 23:13:21 +05:30
2019-03-13 22:55:13 +05:30
it_behaves_like 'it should show Gmail Actions View Issue link'
it_behaves_like 'an unsubscribeable thread'
it 'contains description about action taken' do
is_expected . to have_body_text 'Issue was moved to another project'
end
it 'has the correct subject and body' do
new_issue_url = project_issue_path ( new_issue . project , new_issue )
2016-06-02 11:05:42 +05:30
2019-03-13 22:55:13 +05:30
aggregate_failures do
is_expected . to have_referable_subject ( issue , reply : true )
is_expected . to have_body_text ( new_issue_url )
is_expected . to have_body_text ( project_issue_path ( project , issue ) )
end
end
it 'contains the issue title' do
is_expected . to have_body_text new_issue . title
end
2018-03-17 18:26:18 +05:30
end
2016-06-02 11:05:42 +05:30
2019-03-13 22:55:13 +05:30
context 'when a user does not permissions to access the new issue' do
it 'has the correct subject and body' do
new_issue_url = project_issue_path ( new_issue . project , new_issue )
2016-06-02 11:05:42 +05:30
2019-03-13 22:55:13 +05:30
aggregate_failures do
is_expected . to have_referable_subject ( issue , reply : true )
is_expected . not_to have_body_text ( new_issue_url )
is_expected . to have_body_text ( project_issue_path ( project , issue ) )
end
end
it 'does not contain the issue title' do
is_expected . not_to have_body_text new_issue . title
end
it 'contains information about missing permissions' do
is_expected . to have_body_text " You don't have access to the project. "
2016-06-02 11:05:42 +05:30
end
2018-03-17 18:26:18 +05:30
end
end
end
2016-06-02 11:05:42 +05:30
2018-03-17 18:26:18 +05:30
context 'for merge requests' do
2022-06-21 17:19:12 +05:30
let ( :push_user ) { create ( :user ) }
let ( :commit_limit ) { NotificationService :: NEW_COMMIT_EMAIL_DISPLAY_LIMIT }
2018-03-17 18:26:18 +05:30
describe 'that are new' do
2019-07-31 22:56:46 +05:30
subject { described_class . new_merge_request_email ( merge_request . assignee_ids . first , merge_request . id ) }
2016-06-02 11:05:42 +05:30
2018-03-17 18:26:18 +05:30
it_behaves_like 'an assignee email'
it_behaves_like 'an email starting a new thread with reply-by-email enabled' do
let ( :model ) { merge_request }
end
2020-05-24 23:13:21 +05:30
2018-03-17 18:26:18 +05:30
it_behaves_like 'it should show Gmail Actions View Merge request link'
it_behaves_like 'an unsubscribeable thread'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2018-03-17 18:26:18 +05:30
it 'has the correct subject and body' do
aggregate_failures do
is_expected . to have_referable_subject ( merge_request )
is_expected . to have_body_text ( project_merge_request_path ( project , merge_request ) )
is_expected . to have_body_text ( merge_request . source_branch )
is_expected . to have_body_text ( merge_request . target_branch )
2021-04-17 20:07:23 +05:30
is_expected . to have_body_text ( reviewer . name )
2016-06-02 11:05:42 +05:30
end
end
2014-09-02 18:07:02 +05:30
2018-03-17 18:26:18 +05:30
it 'contains the description' do
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text merge_request . description
2018-03-17 18:26:18 +05:30
end
context 'when sent with a reason' do
2019-07-31 22:56:46 +05:30
subject { described_class . new_merge_request_email ( merge_request . assignee_ids . first , merge_request . id , NotificationReason :: ASSIGNED ) }
2014-09-02 18:07:02 +05:30
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2018-03-17 18:26:18 +05:30
it 'includes the reason in a header' do
is_expected . to have_header ( 'X-GitLab-NotificationReason' , NotificationReason :: ASSIGNED )
2016-06-02 11:05:42 +05:30
end
2018-03-17 18:26:18 +05:30
end
2019-09-30 21:07:59 +05:30
it 'contains a link to merge request author' do
is_expected . to have_body_text merge_request . author_name
2021-06-08 01:23:25 +05:30
is_expected . to have_body_text 'created a merge request:'
2021-04-17 20:07:23 +05:30
end
it 'contains a link to the merge request url' do
2021-06-08 01:23:25 +05:30
is_expected . to have_link ( merge_request . to_reference , href : project_merge_request_url ( merge_request . target_project , merge_request ) )
2018-03-17 18:26:18 +05:30
end
end
2017-09-10 17:25:29 +05:30
2018-03-17 18:26:18 +05:30
describe 'that are reassigned' do
let ( :previous_assignee ) { create ( :user , name : 'Previous Assignee' ) }
2020-01-01 13:55:28 +05:30
2019-07-31 22:56:46 +05:30
subject { described_class . reassigned_merge_request_email ( recipient . id , merge_request . id , [ previous_assignee . id ] , current_user . id ) }
2016-04-02 18:10:28 +05:30
2018-03-17 18:26:18 +05:30
it_behaves_like 'a multiple recipients email'
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { merge_request }
2014-09-02 18:07:02 +05:30
end
2020-05-24 23:13:21 +05:30
2018-03-17 18:26:18 +05:30
it_behaves_like 'it should show Gmail Actions View Merge request link'
it_behaves_like " an unsubscribeable thread "
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2014-09-02 18:07:02 +05:30
2018-03-17 18:26:18 +05:30
it 'is sent as the author' do
2021-04-29 21:17:54 +05:30
expect_sender ( current_user )
2018-03-17 18:26:18 +05:30
end
2014-09-02 18:07:02 +05:30
2018-03-17 18:26:18 +05:30
it 'has the correct subject and body' do
aggregate_failures do
is_expected . to have_referable_subject ( merge_request , reply : true )
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text ( previous_assignee . name )
2018-03-17 18:26:18 +05:30
is_expected . to have_body_text ( project_merge_request_path ( project , merge_request ) )
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text ( assignee . name )
2016-06-02 11:05:42 +05:30
end
2018-03-17 18:26:18 +05:30
end
2014-09-02 18:07:02 +05:30
2022-08-13 15:12:31 +05:30
context 'when sent with a reason' , type : :helper do
2019-07-31 22:56:46 +05:30
subject { described_class . reassigned_merge_request_email ( recipient . id , merge_request . id , [ previous_assignee . id ] , current_user . id , NotificationReason :: ASSIGNED ) }
2018-03-17 18:26:18 +05:30
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2018-03-17 18:26:18 +05:30
it 'includes the reason in a header' do
is_expected . to have_header ( 'X-GitLab-NotificationReason' , NotificationReason :: ASSIGNED )
2014-09-02 18:07:02 +05:30
end
2018-03-17 18:26:18 +05:30
it 'includes the reason in the footer' do
2023-03-04 22:38:38 +05:30
text = EmailsHelper . instance_method ( :notification_reason_text ) . bind_call ( self , reason : NotificationReason :: ASSIGNED , format : :html )
2018-03-17 18:26:18 +05:30
is_expected . to have_body_text ( text )
2019-07-31 22:56:46 +05:30
new_subject = described_class . reassigned_merge_request_email ( recipient . id , merge_request . id , [ previous_assignee . id ] , current_user . id , NotificationReason :: MENTIONED )
2023-03-04 22:38:38 +05:30
text = EmailsHelper . instance_method ( :notification_reason_text ) . bind_call ( self , reason : NotificationReason :: MENTIONED , format : :html )
2018-03-17 18:26:18 +05:30
expect ( new_subject ) . to have_body_text ( text )
2019-07-31 22:56:46 +05:30
new_subject = described_class . reassigned_merge_request_email ( recipient . id , merge_request . id , [ previous_assignee . id ] , current_user . id , nil )
2023-03-04 22:38:38 +05:30
text = EmailsHelper . instance_method ( :notification_reason_text ) . bind_call ( self , format : :html )
2018-03-17 18:26:18 +05:30
expect ( new_subject ) . to have_body_text ( text )
2014-09-02 18:07:02 +05:30
end
end
2018-03-17 18:26:18 +05:30
end
2014-09-02 18:07:02 +05:30
2018-11-18 11:00:15 +05:30
describe 'that are new with a description' do
2019-07-31 22:56:46 +05:30
subject { described_class . new_merge_request_email ( merge_request . assignee_ids . first , merge_request . id ) }
2018-11-18 11:00:15 +05:30
it_behaves_like 'it should show Gmail Actions View Merge request link'
it_behaves_like " an unsubscribeable thread "
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2018-11-18 11:00:15 +05:30
it 'contains the description' do
is_expected . to have_body_text ( merge_request . description )
end
end
2018-03-17 18:26:18 +05:30
describe 'that have been relabeled' do
subject { described_class . relabeled_merge_request_email ( recipient . id , merge_request . id , %w[ foo bar baz ] , current_user . id ) }
2016-06-02 11:05:42 +05:30
2018-03-17 18:26:18 +05:30
it_behaves_like 'a multiple recipients email'
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { merge_request }
end
2020-05-24 23:13:21 +05:30
2018-03-17 18:26:18 +05:30
it_behaves_like 'it should show Gmail Actions View Merge request link'
it_behaves_like 'a user cannot unsubscribe through footer link'
it_behaves_like 'an email with a labels subscriptions link in its footer'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2016-06-02 11:05:42 +05:30
2018-03-17 18:26:18 +05:30
it 'is sent as the author' do
2021-04-29 21:17:54 +05:30
expect_sender ( current_user )
2018-03-17 18:26:18 +05:30
end
it 'has the correct subject and body' do
is_expected . to have_referable_subject ( merge_request , reply : true )
is_expected . to have_body_text ( 'foo, bar, and baz' )
is_expected . to have_body_text ( project_merge_request_path ( project , merge_request ) )
end
end
2018-05-09 12:01:36 +05:30
shared_examples 'a push to an existing merge request' do
it_behaves_like 'a multiple recipients email'
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { merge_request }
end
2020-05-24 23:13:21 +05:30
2018-05-09 12:01:36 +05:30
it_behaves_like 'it should show Gmail Actions View Merge request link'
it_behaves_like 'an unsubscribeable thread'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2018-05-09 12:01:36 +05:30
it 'is sent as the push user' do
2021-04-29 21:17:54 +05:30
expect_sender ( push_user )
2018-05-09 12:01:36 +05:30
end
it 'has the correct subject and body' do
aggregate_failures do
is_expected . to have_referable_subject ( merge_request , reply : true )
is_expected . to have_body_text ( " #{ push_user . name } pushed new commits " )
is_expected . to have_body_text ( project_merge_request_path ( project , merge_request ) )
2020-07-28 23:09:34 +05:30
is_expected . to have_link ( merge_request . to_reference , href : project_merge_request_url ( merge_request . target_project , merge_request ) )
2018-05-09 12:01:36 +05:30
end
end
end
2022-06-21 17:19:12 +05:30
shared_examples 'shows the compare url between first and last commits' do | count |
it 'shows the compare url between first and last commits' do
commit_id_1 = existing_commits . first [ :short_id ]
commit_id_2 = existing_commits . last [ :short_id ]
is_expected . to have_link ( " #{ commit_id_1 } ... #{ commit_id_2 } " , href : project_compare_url ( project , from : commit_id_1 , to : commit_id_2 ) )
is_expected . to have_body_text ( " #{ count } commits from branch ` #{ merge_request . target_branch } ` " )
end
end
shared_examples 'shows new commit urls' do | count |
it 'shows new commit urls' do
displayed_new_commits . each do | commit |
is_expected . to have_link ( commit [ :short_id ] , href : project_commit_url ( project , commit [ :short_id ] ) )
is_expected . to have_body_text ( commit [ :title ] )
end
end
it 'does not show hidden new commit urls' do
hidden_new_commits . each do | commit |
is_expected . not_to have_link ( commit [ :short_id ] , href : project_commit_url ( project , commit [ :short_id ] ) )
is_expected . not_to have_body_text ( commit [ :title ] )
end
end
end
describe 'that have no new commits' do
subject do
described_class . push_to_merge_request_email ( recipient . id , merge_request . id , push_user . id , new_commits : [ ] , total_new_commits_count : 0 , existing_commits : [ ] , total_existing_commits_count : 0 )
end
2018-05-09 12:01:36 +05:30
it_behaves_like 'a push to an existing merge request'
end
2022-06-21 17:19:12 +05:30
describe 'that have fewer than the commit truncation limit' do
let ( :new_commits ) { merge_request . commits }
let ( :displayed_new_commits ) { new_commits }
let ( :hidden_new_commits ) { [ ] }
subject do
described_class . push_to_merge_request_email (
recipient . id , merge_request . id , push_user . id ,
new_commits : new_commits , total_new_commits_count : new_commits . length ,
existing_commits : [ ] , total_existing_commits_count : 0
)
end
it_behaves_like 'a push to an existing merge request'
it_behaves_like 'shows new commit urls'
end
describe 'that have more than the commit truncation limit' do
let ( :new_commits ) do
Array . new ( commit_limit + 10 ) do | i |
{
short_id : SecureRandom . hex ( 4 ) ,
title : " This is commit #{ i } "
}
end
end
let ( :displayed_new_commits ) { new_commits . first ( commit_limit ) }
let ( :hidden_new_commits ) { new_commits . last ( 10 ) }
subject do
described_class . push_to_merge_request_email (
recipient . id , merge_request . id , push_user . id ,
new_commits : displayed_new_commits , total_new_commits_count : commit_limit + 10 ,
existing_commits : [ ] , total_existing_commits_count : 0
)
end
it_behaves_like 'a push to an existing merge request'
it_behaves_like 'shows new commit urls'
it 'shows "and more" message' do
is_expected . to have_body_text ( " And 10 more " )
end
end
2018-05-09 12:01:36 +05:30
describe 'that have new commits on top of an existing one' do
let ( :existing_commits ) { [ merge_request . commits . first ] }
2022-06-21 17:19:12 +05:30
subject do
described_class . push_to_merge_request_email (
recipient . id , merge_request . id , push_user . id ,
new_commits : merge_request . commits , total_new_commits_count : merge_request . commits . length ,
existing_commits : existing_commits , total_existing_commits_count : existing_commits . length
)
end
it_behaves_like 'a push to an existing merge request'
it 'shows the existing commit' do
commit_id = existing_commits . first . short_id
is_expected . to have_link ( commit_id , href : project_commit_url ( project , commit_id ) )
is_expected . to have_body_text ( " 1 commit from branch ` #{ merge_request . target_branch } ` " )
end
end
describe 'that have new commits on top of two existing ones' do
let ( :existing_commits ) { [ merge_request . commits . first , merge_request . commits . second ] }
subject do
described_class . push_to_merge_request_email (
recipient . id , merge_request . id , push_user . id ,
new_commits : merge_request . commits , total_new_commits_count : merge_request . commits . length ,
existing_commits : existing_commits , total_existing_commits_count : existing_commits . length
)
end
it_behaves_like 'a push to an existing merge request'
it_behaves_like 'shows the compare url between first and last commits' , 2
end
describe 'that have new commits on top of more than two existing ones' do
let ( :existing_commits ) do
[ merge_request . commits . first ] + [ double ( :commit ) ] * 3 + [ merge_request . commits . second ]
end
subject do
described_class . push_to_merge_request_email (
recipient . id , merge_request . id , push_user . id ,
new_commits : merge_request . commits , total_new_commits_count : merge_request . commits . length ,
existing_commits : existing_commits , total_existing_commits_count : existing_commits . length
)
end
2018-05-09 12:01:36 +05:30
it_behaves_like 'a push to an existing merge request'
2022-06-21 17:19:12 +05:30
it_behaves_like 'shows the compare url between first and last commits' , 5
2018-05-09 12:01:36 +05:30
end
2018-03-17 18:26:18 +05:30
end
2014-09-02 18:07:02 +05:30
2019-12-04 20:38:33 +05:30
describe '#mail_thread' do
2020-04-08 14:13:33 +05:30
let_it_be ( :mail_thread_note ) { create ( :note ) }
2019-12-04 20:38:33 +05:30
let ( :headers ) do
{
from : 'someone@test.com' ,
to : 'someone-else@test.com' ,
subject : 'something' ,
template_name : '_note_email' # re-use this for testing
}
end
let ( :mailer ) do
mailer = described_class . new
mailer . instance_variable_set ( :@note , mail_thread_note )
2021-01-29 00:20:46 +05:30
mailer . instance_variable_set ( :@target_url , " https://some.link " )
2019-12-04 20:38:33 +05:30
mailer
end
context 'the model has no namespace' do
2023-03-04 22:38:38 +05:30
before do
stub_const ( 'TopLevelThing' , Class . new )
2019-12-04 20:38:33 +05:30
2023-03-04 22:38:38 +05:30
TopLevelThing . class_eval do
include Referable
include Noteable
2019-12-04 20:38:33 +05:30
2023-03-04 22:38:38 +05:30
def to_reference ( * _args )
'tlt-ref'
end
def id
'tlt-id'
end
2019-12-04 20:38:33 +05:30
end
end
subject do
mailer . send ( :mail_thread , TopLevelThing . new , headers )
end
it 'has X-GitLab-Namespaced-Thing-ID header' do
expect ( subject . header [ 'X-GitLab-TopLevelThing-ID' ] . value ) . to eq ( 'tlt-id' )
end
end
context 'the model has a namespace' do
2023-03-04 22:38:38 +05:30
before do
stub_const ( 'Namespaced::Thing' , Class . new )
Namespaced :: Thing . class_eval do
2019-12-04 20:38:33 +05:30
include Referable
include Noteable
def to_reference ( * _args )
'some-reference'
end
def id
'some-id'
end
end
end
subject do
mailer . send ( :mail_thread , Namespaced :: Thing . new , headers )
end
it 'has X-GitLab-Namespaced-Thing-ID header' do
expect ( subject . header [ 'X-GitLab-Namespaced-Thing-ID' ] . value ) . to eq ( 'some-id' )
end
end
end
2018-03-17 18:26:18 +05:30
context 'for issue notes' do
let ( :host ) { Gitlab . config . gitlab . host }
2014-09-02 18:07:02 +05:30
2018-03-17 18:26:18 +05:30
context 'in discussion' do
2020-04-08 14:13:33 +05:30
let_it_be ( :first_note ) { create ( :discussion_note_on_issue , project : project ) }
let_it_be ( :second_note ) { create ( :discussion_note_on_issue , in_reply_to : first_note , project : project ) }
let_it_be ( :third_note ) { create ( :discussion_note_on_issue , in_reply_to : second_note , project : project ) }
2014-09-02 18:07:02 +05:30
2018-03-17 18:26:18 +05:30
subject { described_class . note_issue_email ( recipient . id , third_note . id ) }
2014-09-02 18:07:02 +05:30
2019-09-04 21:01:54 +05:30
it_behaves_like 'an email sent to a user'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2018-03-17 18:26:18 +05:30
it 'has In-Reply-To header pointing to previous note in discussion' do
expect ( subject . header [ 'In-Reply-To' ] . message_ids ) . to eq ( [ " note_ #{ second_note . id } @ #{ host } " ] )
end
it 'has References header including the notes and issue of the discussion' do
2023-07-09 08:55:56 +05:30
expect ( subject . header [ 'References' ] . message_ids ) . to include (
" issue_ #{ first_note . noteable . id } @ #{ host } " ,
" note_ #{ first_note . id } @ #{ host } " ,
" note_ #{ second_note . id } @ #{ host } "
)
2014-09-02 18:07:02 +05:30
end
2018-03-17 18:26:18 +05:30
it 'has X-GitLab-Discussion-ID header' do
expect ( subject . header [ 'X-GitLab-Discussion-ID' ] . value ) . to eq ( third_note . discussion . id )
end
end
context 'individual issue comments' do
2020-04-08 14:13:33 +05:30
let_it_be ( :note ) { create ( :note_on_issue , project : project ) }
2018-03-17 18:26:18 +05:30
subject { described_class . note_issue_email ( recipient . id , note . id ) }
2019-09-04 21:01:54 +05:30
it_behaves_like 'an email sent to a user'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2018-03-17 18:26:18 +05:30
it 'has In-Reply-To header pointing to the issue' do
expect ( subject . header [ 'In-Reply-To' ] . message_ids ) . to eq ( [ " issue_ #{ note . noteable . id } @ #{ host } " ] )
end
it 'has References header including the notes and issue of the discussion' do
expect ( subject . header [ 'References' ] . message_ids ) . to include ( " issue_ #{ note . noteable . id } @ #{ host } " )
end
2022-01-26 12:08:38 +05:30
context 'with private references accessible to the recipient' do
let_it_be ( :private_project ) { create ( :project , :private ) }
let_it_be ( :private_issue ) { create ( :issue , :closed , project : private_project ) }
before_all do
private_project . add_guest ( recipient )
2023-01-13 00:05:48 +05:30
note . update! ( note : private_issue . to_reference ( full : true ) . to_s )
2022-01-26 12:08:38 +05:30
end
let ( :html_part ) { subject . body . parts . last . to_s }
it 'does not redact the reference' do
expect ( html_part ) . to include ( " data-reference-type= \" issue \" " )
expect ( html_part ) . to include ( " title= \" #{ private_issue . title } \" " )
end
it 'renders expanded issue references' do
expect ( html_part ) . to include ( " #{ private_issue . to_reference ( full : true ) } (closed) " )
end
end
2018-03-17 18:26:18 +05:30
end
end
context 'for snippet notes' do
let ( :project_snippet ) { create ( :project_snippet , project : project ) }
let ( :project_snippet_note ) { create ( :note_on_project_snippet , project : project , noteable : project_snippet ) }
2020-03-13 15:44:24 +05:30
subject { described_class . note_snippet_email ( project_snippet_note . author_id , project_snippet_note . id ) }
2018-03-17 18:26:18 +05:30
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2018-03-17 18:26:18 +05:30
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { project_snippet }
end
2020-05-24 23:13:21 +05:30
2018-03-17 18:26:18 +05:30
it_behaves_like 'a user cannot unsubscribe through footer link'
2020-03-13 15:44:24 +05:30
it 'has the correct subject' do
2019-09-30 21:07:59 +05:30
is_expected . to have_referable_subject ( project_snippet , reply : true )
2020-03-13 15:44:24 +05:30
end
it 'has the correct body' do
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text project_snippet_note . note
2014-09-02 18:07:02 +05:30
end
2020-03-13 15:44:24 +05:30
it 'links to the project snippet' do
2023-07-09 08:55:56 +05:30
target_url = project_snippet_url (
project ,
project_snippet_note . noteable ,
{ anchor : " note_ #{ project_snippet_note . id } " }
)
2020-03-13 15:44:24 +05:30
is_expected . to have_body_text target_url
end
2014-09-02 18:07:02 +05:30
end
2020-05-24 23:13:21 +05:30
describe 'for design notes' do
let_it_be ( :design ) { create ( :design , :with_file ) }
let_it_be ( :recipient ) { create ( :user ) }
let_it_be ( :note ) do
2023-07-09 08:55:56 +05:30
create ( :diff_note_on_design , noteable : design , note : " Hello #{ recipient . to_reference } " )
2020-05-24 23:13:21 +05:30
end
let ( :header_name ) { 'X-Gitlab-DesignManagement-Design-ID' }
let ( :refer_to_design ) do
have_attributes ( subject : a_string_including ( design . filename ) )
end
subject { described_class . note_design_email ( recipient . id , note . id ) }
it { is_expected . to have_header ( header_name , design . id . to_s ) }
it { is_expected . to have_body_text ( design . filename ) }
it { is_expected . to refer_to_design }
end
2014-09-02 18:07:02 +05:30
describe 'project was moved' do
2019-09-04 21:01:54 +05:30
let ( :recipient ) { user }
2020-01-01 13:55:28 +05:30
2017-08-17 22:00:37 +05:30
subject { described_class . project_was_moved_email ( project . id , user . id , " gitlab/gitlab " ) }
2014-09-02 18:07:02 +05:30
2019-09-04 21:01:54 +05:30
it_behaves_like 'an email sent to a user'
2014-09-02 18:07:02 +05:30
it_behaves_like 'an email sent from GitLab'
2015-12-23 02:04:40 +05:30
it_behaves_like 'it should not have Gmail Actions links'
2016-01-19 16:12:03 +05:30
it_behaves_like " a user cannot unsubscribe through footer link "
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2014-09-02 18:07:02 +05:30
2017-08-17 22:00:37 +05:30
it 'has the correct subject and body' do
is_expected . to have_subject ( " #{ project . name } | Project was moved " )
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text project . full_name
2017-08-17 22:00:37 +05:30
is_expected . to have_body_text ( project . ssh_url_to_repo )
2014-09-02 18:07:02 +05:30
end
end
2016-06-16 23:09:34 +05:30
describe 'project access requested' do
2018-03-27 19:54:05 +05:30
let ( :project ) do
2019-12-21 20:55:43 +05:30
create ( :project , :public ) do | project |
2022-04-04 11:22:00 +05:30
project . add_maintainer ( project . first_owner )
2016-06-22 15:30:34 +05:30
end
2016-06-16 23:09:34 +05:30
end
2018-03-27 19:54:05 +05:30
let ( :project_member ) do
project . request_access ( user )
project . requesters . find_by ( user_id : user . id )
end
2020-01-01 13:55:28 +05:30
2019-10-12 21:52:04 +05:30
subject { described_class . member_access_requested_email ( 'project' , project_member . id , recipient . id ) }
2016-06-16 23:09:34 +05:30
2018-03-27 19:54:05 +05:30
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 "
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2016-06-22 15:30:34 +05:30
2018-03-27 19:54:05 +05:30
it 'contains all the useful information' do
to_emails = subject . header [ :to ] . addrs . map ( & :address )
2021-11-11 11:23:49 +05:30
expect ( to_emails ) . to eq ( [ recipient . notification_email_or_default ] )
2016-06-22 15:30:34 +05:30
2018-03-27 19:54:05 +05:30
is_expected . to have_subject " Request to join the #{ project . full_name } project "
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text project . full_name
2018-03-27 19:54:05 +05:30
is_expected . to have_body_text project_project_members_url ( project )
is_expected . to have_body_text project_member . human_access
2016-06-16 23:09:34 +05:30
end
end
describe 'project access denied' do
2021-12-11 22:18:48 +05:30
let_it_be ( :project ) { create ( :project , :public ) }
let_it_be ( :project_member ) { create ( :project_member , :developer , :access_request , user : user , source : project ) }
2020-01-01 13:55:28 +05:30
2017-08-17 22:00:37 +05:30
subject { described_class . member_access_denied_email ( 'project' , project . id , user . id ) }
2016-06-16 23:09:34 +05:30
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 "
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2016-06-16 23:09:34 +05:30
it 'contains all the useful information' do
2018-03-27 19:54:05 +05:30
is_expected . to have_subject " Access to the #{ project . full_name } project was denied "
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text project . full_name
2017-08-17 22:00:37 +05:30
is_expected . to have_body_text project . web_url
2016-06-16 23:09:34 +05:30
end
2021-12-11 22:18:48 +05:30
context 'when user can not read project' do
let_it_be ( :project ) { create ( :project , :private ) }
it 'hides project name from subject and body' do
is_expected . to have_subject " Access to the Hidden project was denied "
is_expected . to have_body_text " Hidden project "
is_expected . not_to have_body_text project . full_name
is_expected . not_to have_body_text project . web_url
end
end
2016-06-16 23:09:34 +05:30
end
2014-09-02 18:07:02 +05:30
describe 'project access changed' do
2017-08-17 22:00:37 +05:30
let ( :owner ) { create ( :user , name : " Chang O'Keefe " ) }
2019-12-21 20:55:43 +05:30
let ( :project ) { create ( :project , :public , namespace : owner . namespace ) }
2015-09-11 14:41:01 +05:30
let ( :project_member ) { create ( :project_member , project : project , user : user ) }
2020-01-01 13:55:28 +05:30
2017-08-17 22:00:37 +05:30
subject { described_class . member_access_granted_email ( 'project' , project_member . id ) }
2014-09-02 18:07:02 +05:30
it_behaves_like 'an email sent from GitLab'
2015-12-23 02:04:40 +05:30
it_behaves_like 'it should not have Gmail Actions links'
2016-01-19 16:12:03 +05:30
it_behaves_like " a user cannot unsubscribe through footer link "
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2014-09-02 18:07:02 +05:30
2016-06-16 23:09:34 +05:30
it 'contains all the useful information' do
2018-03-27 19:54:05 +05:30
is_expected . to have_subject " Access to the #{ project . full_name } project was granted "
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text project . full_name
2017-08-17 22:00:37 +05:30
is_expected . to have_body_text project . web_url
is_expected . to have_body_text project_member . human_access
2019-07-31 22:56:46 +05:30
is_expected . to have_body_text 'leave the project'
is_expected . to have_body_text project_url ( project , leave : 1 )
2021-12-11 22:18:48 +05:30
is_expected . not_to have_body_text 'You were assigned the following tasks:'
end
context 'with tasks to be done present' do
let ( :project_member ) { create ( :project_member , project : project , user : user , tasks_to_be_done : [ :ci , :code ] ) }
it 'contains the assigned tasks to be done' do
is_expected . to have_body_text 'You were assigned the following tasks:'
is_expected . to have_body_text localized_tasks_to_be_done_choices [ :ci ]
is_expected . to have_body_text localized_tasks_to_be_done_choices [ :code ]
end
2014-09-02 18:07:02 +05:30
end
2016-06-16 23:09:34 +05:30
end
2015-12-23 02:04:40 +05:30
2021-12-11 22:18:48 +05:30
def invite_to_project ( project , inviter : , user : nil , tasks_to_be_done : [ ] )
2016-11-03 12:29:30 +05:30
create (
:project_member ,
:developer ,
project : project ,
invite_token : '1234' ,
invite_email : 'toto@example.com' ,
2020-11-24 15:15:51 +05:30
user : user ,
2021-12-11 22:18:48 +05:30
created_by : inviter ,
tasks_to_be_done : tasks_to_be_done
2016-09-13 17:45:13 +05:30
)
2016-06-16 23:09:34 +05:30
end
describe 'project invitation' do
2018-11-18 11:00:15 +05:30
let ( :maintainer ) { create ( :user ) . tap { | u | project . add_maintainer ( u ) } }
2020-11-24 15:15:51 +05:30
let ( :project_member ) { invite_to_project ( project , inviter : inviter ) }
let ( :inviter ) { maintainer }
2016-06-16 23:09:34 +05:30
2021-10-27 15:23:28 +05:30
subject ( :invite_email ) do
described_class . member_invited_email ( 'project' , project_member . id , project_member . invite_token )
end
2016-06-16 23:09:34 +05:30
2021-01-29 00:20:46 +05:30
it_behaves_like 'an email sent from GitLab'
2022-01-26 12:08:38 +05:30
it_behaves_like 'it should show Gmail Actions Join now link'
2021-01-29 00:20:46 +05:30
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_behaves_like 'does not render a manage notifications link'
2020-11-24 15:15:51 +05:30
2021-09-04 01:27:46 +05:30
context 'when there is an inviter' , :aggregate_failures do
2020-11-24 15:15:51 +05:30
it 'contains all the useful information' do
2021-01-29 00:20:46 +05:30
is_expected . to have_subject " #{ inviter . name } invited you to join GitLab "
2020-11-24 15:15:51 +05:30
is_expected . to have_body_text project . full_name
2021-01-29 00:20:46 +05:30
is_expected . to have_body_text project_member . human_access . downcase
2020-11-24 15:15:51 +05:30
is_expected . to have_body_text project_member . invite_token
2023-07-09 08:55:56 +05:30
is_expected . to have_link (
'Join now' ,
href : invite_url ( project_member . invite_token , invite_type : Emails :: Members :: INITIAL_INVITE )
)
2021-09-04 01:27:46 +05:30
is_expected . to have_content ( " #{ inviter . name } invited you to join the " )
is_expected . to have_content ( 'Project details' )
is_expected . to have_content ( " What's it about? " )
2021-12-11 22:18:48 +05:30
is_expected . not_to have_body_text 'and has assigned you the following tasks:'
2020-11-24 15:15:51 +05:30
end
end
2021-09-04 01:27:46 +05:30
context 'when there is no inviter' , :aggregate_failures do
2021-01-29 00:20:46 +05:30
let ( :inviter ) { nil }
2020-11-24 15:15:51 +05:30
2021-01-29 00:20:46 +05:30
it 'contains all the useful information' do
is_expected . to have_subject " Invitation to join the #{ project . full_name } project "
is_expected . to have_body_text project . full_name
is_expected . to have_body_text project_member . human_access . downcase
is_expected . to have_body_text project_member . invite_token
2023-07-09 08:55:56 +05:30
is_expected . to have_link (
'Join now' ,
href : invite_url ( project_member . invite_token , invite_type : Emails :: Members :: INITIAL_INVITE )
)
2021-10-27 15:23:28 +05:30
is_expected . to have_content ( 'Project details' )
is_expected . to have_content ( " What's it about? " )
end
end
context 'when invite email sent is tracked' , :snowplow do
it 'tracks the sent invite' do
invite_email . deliver_now
expect_snowplow_event (
category : 'Notify' ,
action : 'invite_email_sent' ,
label : 'invite_email' ,
property : project_member . id . to_s
)
2020-11-24 15:15:51 +05:30
end
2016-06-16 23:09:34 +05:30
end
2021-09-04 01:27:46 +05:30
2021-11-11 11:23:49 +05:30
context 'when mailgun events are enabled' do
2021-09-04 01:27:46 +05:30
before do
2021-11-11 11:23:49 +05:30
stub_application_setting ( mailgun_events_enabled : true )
2021-09-04 01:27:46 +05:30
end
it 'has custom headers' do
aggregate_failures do
2021-11-11 11:23:49 +05:30
expect ( subject ) . to have_header ( 'X-Mailgun-Tag' , :: Members :: Mailgun :: INVITE_EMAIL_TAG )
expect ( subject ) . to have_header ( 'X-Mailgun-Variables' , { :: Members :: Mailgun :: INVITE_EMAIL_TOKEN_KEY = > project_member . invite_token } . to_json )
2021-09-04 01:27:46 +05:30
end
end
end
2021-12-11 22:18:48 +05:30
context 'with tasks to be done present' , :aggregate_failures do
let ( :project_member ) { invite_to_project ( project , inviter : inviter , tasks_to_be_done : [ :ci , :code ] ) }
it 'contains the assigned tasks to be done' do
is_expected . to have_body_text 'and has assigned you the following tasks:'
is_expected . to have_body_text localized_tasks_to_be_done_choices [ :ci ]
is_expected . to have_body_text localized_tasks_to_be_done_choices [ :code ]
end
end
2016-06-16 23:09:34 +05:30
end
describe 'project invitation accepted' do
2016-11-03 12:29:30 +05:30
let ( :invited_user ) { create ( :user , name : 'invited user' ) }
2019-10-12 21:52:04 +05:30
let ( :recipient ) { create ( :user ) . tap { | u | project . add_maintainer ( u ) } }
2016-06-16 23:09:34 +05:30
let ( :project_member ) do
2019-10-12 21:52:04 +05:30
invitee = invite_to_project ( project , inviter : recipient )
2016-06-16 23:09:34 +05:30
invitee . accept_invite! ( invited_user )
invitee
end
2017-08-17 22:00:37 +05:30
subject { described_class . member_invite_accepted_email ( 'project' , project_member . id ) }
2016-06-16 23:09:34 +05:30
it_behaves_like 'an email sent from GitLab'
2019-10-12 21:52:04 +05:30
it_behaves_like 'an email sent to a user'
2016-06-16 23:09:34 +05:30
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like " a user cannot unsubscribe through footer link "
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2016-06-16 23:09:34 +05:30
it 'contains all the useful information' do
is_expected . to have_subject 'Invitation accepted'
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text project . full_name
2017-08-17 22:00:37 +05:30
is_expected . to have_body_text project . web_url
is_expected . to have_body_text project_member . invite_email
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text invited_user . name
2016-06-16 23:09:34 +05:30
end
end
describe 'project invitation declined' do
2019-10-12 21:52:04 +05:30
let ( :recipient ) { create ( :user ) . tap { | u | project . add_maintainer ( u ) } }
2016-06-16 23:09:34 +05:30
let ( :project_member ) do
2019-10-12 21:52:04 +05:30
invitee = invite_to_project ( project , inviter : recipient )
2016-06-16 23:09:34 +05:30
invitee . decline_invite!
invitee
end
2019-10-12 21:52:04 +05:30
subject { described_class . member_invite_declined_email ( 'Project' , project . id , project_member . invite_email , recipient . id ) }
2016-06-16 23:09:34 +05:30
it_behaves_like 'an email sent from GitLab'
2019-10-12 21:52:04 +05:30
it_behaves_like 'an email sent to a user'
2016-06-16 23:09:34 +05:30
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like " a user cannot unsubscribe through footer link "
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2016-06-16 23:09:34 +05:30
it 'contains all the useful information' do
is_expected . to have_subject 'Invitation declined'
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text project . full_name
2017-08-17 22:00:37 +05:30
is_expected . to have_body_text project . web_url
is_expected . to have_body_text project_member . invite_email
2014-09-02 18:07:02 +05:30
end
end
context 'items that are noteable, the email for a note' do
let ( :note_author ) { create ( :user , name : 'author_name' ) }
let ( :note ) { create ( :note , project : project , author : note_author ) }
2018-03-17 18:26:18 +05:30
before do
2015-04-26 12:48:37 +05:30
allow ( Note ) . to receive ( :find ) . with ( note . id ) . and_return ( note )
2014-09-02 18:07:02 +05:30
end
describe 'on a commit' do
2015-09-11 14:41:01 +05:30
let ( :commit ) { project . commit }
2014-09-02 18:07:02 +05:30
2017-09-10 17:25:29 +05:30
before do
allow ( note ) . to receive ( :noteable ) . and_return ( commit )
end
2014-09-02 18:07:02 +05:30
2017-08-17 22:00:37 +05:30
subject { described_class . note_commit_email ( recipient . id , note . id ) }
it_behaves_like 'a note email'
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { commit }
end
2020-05-24 23:13:21 +05:30
2017-08-17 22:00:37 +05:30
it_behaves_like 'it should show Gmail Actions View Commit link'
it_behaves_like 'a user cannot unsubscribe through footer link'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2017-08-17 22:00:37 +05:30
it 'has the correct subject and body' do
aggregate_failures do
2019-09-30 21:07:59 +05:30
is_expected . to have_subject ( " Re: #{ project . name } | #{ commit . title } ( #{ commit . short_id } ) " )
2017-08-17 22:00:37 +05:30
is_expected . to have_body_text ( commit . short_id )
end
end
end
describe 'on a merge request' do
2017-09-10 17:25:29 +05:30
let ( :note_on_merge_request_path ) { project_merge_request_path ( project , merge_request , anchor : " note_ #{ note . id } " ) }
before do
allow ( note ) . to receive ( :noteable ) . and_return ( merge_request )
end
2017-08-17 22:00:37 +05:30
subject { described_class . note_merge_request_email ( recipient . id , note . id ) }
it_behaves_like 'a note email'
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { merge_request }
end
2020-05-24 23:13:21 +05:30
2017-08-17 22:00:37 +05:30
it_behaves_like 'it should show Gmail Actions View Merge request link'
it_behaves_like 'an unsubscribeable thread'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2017-08-17 22:00:37 +05:30
it 'has the correct subject and body' do
aggregate_failures do
2019-09-30 21:07:59 +05:30
is_expected . to have_referable_subject ( merge_request , reply : true )
2017-08-17 22:00:37 +05:30
is_expected . to have_body_text note_on_merge_request_path
end
end
end
describe 'on an issue' do
2017-09-10 17:25:29 +05:30
let ( :note_on_issue_path ) { project_issue_path ( project , issue , anchor : " note_ #{ note . id } " ) }
before do
allow ( note ) . to receive ( :noteable ) . and_return ( issue )
end
2017-08-17 22:00:37 +05:30
subject { described_class . note_issue_email ( recipient . id , note . id ) }
2014-09-02 18:07:02 +05:30
it_behaves_like 'a note email'
2017-08-17 22:00:37 +05:30
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { issue }
end
2020-05-24 23:13:21 +05:30
2017-08-17 22:00:37 +05:30
it_behaves_like 'it should show Gmail Actions View Issue link'
it_behaves_like 'an unsubscribeable thread'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2017-08-17 22:00:37 +05:30
it 'has the correct subject and body' do
aggregate_failures do
2019-09-30 21:07:59 +05:30
is_expected . to have_referable_subject ( issue , reply : true )
2017-08-17 22:00:37 +05:30
is_expected . to have_body_text ( note_on_issue_path )
end
end
end
end
context 'items that are noteable, the email for a discussion note' do
let ( :note_author ) { create ( :user , name : 'author_name' ) }
2018-03-17 18:26:18 +05:30
before do
2017-08-17 22:00:37 +05:30
allow ( Note ) . to receive ( :find ) . with ( note . id ) . and_return ( note )
end
shared_examples 'a discussion note email' do | model |
it_behaves_like 'it should have Gmail Actions links'
it 'is sent to the given recipient as the author' do
aggregate_failures do
2021-04-29 21:17:54 +05:30
expect_sender ( note_author )
2021-11-11 11:23:49 +05:30
expect ( subject ) . to deliver_to ( recipient . notification_email_or_default )
2017-08-17 22:00:37 +05:30
end
end
it 'contains the message from the note' do
is_expected . to have_body_text note . note
end
it 'contains an introduction' do
2019-09-30 21:07:59 +05:30
issuable_url = " project_ #{ note . noteable_type . underscore } _url "
is_expected . to have_body_text " started a new <a href= \" #{ public_send ( issuable_url , project , note . noteable , anchor : " note_ #{ note . id } " ) } \" >discussion</a> "
2017-08-17 22:00:37 +05:30
end
context 'when a comment on an existing discussion' do
2020-01-01 13:55:28 +05:30
let ( :first_note ) { create_note }
let ( :note ) { create ( model , author : note_author , noteable : nil , in_reply_to : first_note ) }
2017-08-17 22:00:37 +05:30
it 'contains an introduction' do
is_expected . to have_body_text 'commented on a'
end
end
end
describe 'on a commit' do
let ( :commit ) { project . commit }
2020-01-01 13:55:28 +05:30
let ( :note ) { create_note }
def create_note
create ( :discussion_note_on_commit , commit_id : commit . id , project : project , author : note_author )
end
2017-08-17 22:00:37 +05:30
2017-09-10 17:25:29 +05:30
before do
allow ( note ) . to receive ( :noteable ) . and_return ( commit )
end
2017-08-17 22:00:37 +05:30
subject { described_class . note_commit_email ( recipient . id , note . id ) }
it_behaves_like 'a discussion note email' , :discussion_note_on_commit
2016-06-02 11:05:42 +05:30
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { commit }
end
2020-05-24 23:13:21 +05:30
2015-12-23 02:04:40 +05:30
it_behaves_like 'it should show Gmail Actions View Commit link'
2016-06-02 11:05:42 +05:30
it_behaves_like 'a user cannot unsubscribe through footer link'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2014-09-02 18:07:02 +05:30
it 'has the correct subject' do
2019-09-30 21:07:59 +05:30
is_expected . to have_subject " Re: #{ project . name } | #{ commit . title } ( #{ commit . short_id } ) "
2014-09-02 18:07:02 +05:30
end
it 'contains a link to the commit' do
2015-04-26 12:48:37 +05:30
is_expected . to have_body_text commit . short_id
2014-09-02 18:07:02 +05:30
end
end
describe 'on a merge request' do
2020-01-01 13:55:28 +05:30
let ( :note ) { create_note }
2017-09-10 17:25:29 +05:30
let ( :note_on_merge_request_path ) { project_merge_request_path ( project , merge_request , anchor : " note_ #{ note . id } " ) }
2020-01-01 13:55:28 +05:30
def create_note
create ( :discussion_note_on_merge_request , noteable : merge_request , project : project , author : note_author )
end
2017-09-10 17:25:29 +05:30
before do
allow ( note ) . to receive ( :noteable ) . and_return ( merge_request )
end
2014-09-02 18:07:02 +05:30
2017-08-17 22:00:37 +05:30
subject { described_class . note_merge_request_email ( recipient . id , note . id ) }
2014-09-02 18:07:02 +05:30
2017-08-17 22:00:37 +05:30
it_behaves_like 'a discussion note email' , :discussion_note_on_merge_request
2016-06-02 11:05:42 +05:30
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { merge_request }
end
2020-05-24 23:13:21 +05:30
2015-12-23 02:04:40 +05:30
it_behaves_like 'it should show Gmail Actions View Merge request link'
2016-01-19 16:12:03 +05:30
it_behaves_like 'an unsubscribeable thread'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2014-09-02 18:07:02 +05:30
it 'has the correct subject' do
2019-09-30 21:07:59 +05:30
is_expected . to have_referable_subject ( merge_request , reply : true )
2014-09-02 18:07:02 +05:30
end
it 'contains a link to the merge request note' do
2017-08-17 22:00:37 +05:30
is_expected . to have_body_text note_on_merge_request_path
2014-09-02 18:07:02 +05:30
end
end
describe 'on an issue' do
2020-01-01 13:55:28 +05:30
let ( :note ) { create_note }
2017-09-10 17:25:29 +05:30
let ( :note_on_issue_path ) { project_issue_path ( project , issue , anchor : " note_ #{ note . id } " ) }
2020-01-01 13:55:28 +05:30
def create_note
create ( :discussion_note_on_issue , noteable : issue , project : project , author : note_author )
end
2017-09-10 17:25:29 +05:30
before do
allow ( note ) . to receive ( :noteable ) . and_return ( issue )
end
2014-09-02 18:07:02 +05:30
2017-08-17 22:00:37 +05:30
subject { described_class . note_issue_email ( recipient . id , note . id ) }
2014-09-02 18:07:02 +05:30
2017-08-17 22:00:37 +05:30
it_behaves_like 'a discussion note email' , :discussion_note_on_issue
2016-06-02 11:05:42 +05:30
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { issue }
end
2020-05-24 23:13:21 +05:30
2015-12-23 02:04:40 +05:30
it_behaves_like 'it should show Gmail Actions View Issue link'
2016-01-19 16:12:03 +05:30
it_behaves_like 'an unsubscribeable thread'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2014-09-02 18:07:02 +05:30
it 'has the correct subject' do
2019-09-30 21:07:59 +05:30
is_expected . to have_referable_subject ( issue , reply : true )
2014-09-02 18:07:02 +05:30
end
it 'contains a link to the issue note' do
2017-08-17 22:00:37 +05:30
is_expected . to have_body_text note_on_issue_path
2014-09-02 18:07:02 +05:30
end
end
end
2017-08-17 22:00:37 +05:30
context 'items that are noteable, the email for a diff discussion note' do
let ( :note_author ) { create ( :user , name : 'author_name' ) }
2018-03-17 18:26:18 +05:30
before do
2017-08-17 22:00:37 +05:30
allow ( Note ) . to receive ( :find ) . with ( note . id ) . and_return ( note )
end
2019-03-02 22:35:43 +05:30
shared_examples 'an email for a note on a diff discussion' do | model |
2017-08-17 22:00:37 +05:30
let ( :note ) { create ( model , author : note_author ) }
2019-02-15 15:39:39 +05:30
context 'when note is not on text' do
2018-03-17 18:26:18 +05:30
before do
2020-07-28 23:09:34 +05:30
allow ( note . discussion ) . to receive ( :on_text? ) . and_return ( false )
2018-03-17 18:26:18 +05:30
end
it 'does not include diffs with character-level highlighting' do
is_expected . not_to have_body_text '<span class="p">}</span></span>'
end
end
it 'includes diffs with character-level highlighting' do
2017-08-17 22:00:37 +05:30
is_expected . to have_body_text '<span class="p">}</span></span>'
end
it 'contains a link to the diff file' do
is_expected . to have_body_text note . diff_file . file_path
end
it_behaves_like 'it should have Gmail Actions links'
it 'is sent to the given recipient as the author' do
aggregate_failures do
2021-04-29 21:17:54 +05:30
expect_sender ( note_author )
2021-11-11 11:23:49 +05:30
expect ( subject ) . to deliver_to ( recipient . notification_email_or_default )
2017-08-17 22:00:37 +05:30
end
end
it 'contains the message from the note' do
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text note . note
2017-08-17 22:00:37 +05:30
end
it 'contains an introduction' do
is_expected . to have_body_text 'started a new discussion on'
end
context 'when a comment on an existing discussion' do
2022-03-02 08:16:31 +05:30
let ( :first_note ) { create ( model ) } # rubocop:disable Rails/SaveBang
2020-01-01 13:55:28 +05:30
let ( :note ) { create ( model , author : note_author , noteable : nil , in_reply_to : first_note ) }
2017-08-17 22:00:37 +05:30
it 'contains an introduction' do
is_expected . to have_body_text 'commented on a discussion on'
end
end
end
describe 'on a commit' do
let ( :commit ) { project . commit }
let ( :note ) { create ( :diff_note_on_commit ) }
subject { described_class . note_commit_email ( recipient . id , note . id ) }
it_behaves_like 'an email for a note on a diff discussion' , :diff_note_on_commit
it_behaves_like 'it should show Gmail Actions View Commit link'
it_behaves_like 'a user cannot unsubscribe through footer link'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2017-08-17 22:00:37 +05:30
end
describe 'on a merge request' do
let ( :note ) { create ( :diff_note_on_merge_request ) }
subject { described_class . note_merge_request_email ( recipient . id , note . id ) }
it_behaves_like 'an email for a note on a diff discussion' , :diff_note_on_merge_request
it_behaves_like 'it should show Gmail Actions View Merge request link'
it_behaves_like 'an unsubscribeable thread'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2017-08-17 22:00:37 +05:30
end
end
2020-07-28 23:09:34 +05:30
context 'for service desk issues' do
before do
2023-04-23 21:23:45 +05:30
stub_feature_flags ( service_desk_custom_email : false )
2021-02-22 17:27:13 +05:30
issue . update! ( external_author : 'service.desk@example.com' )
2021-04-17 20:07:23 +05:30
issue . issue_email_participants . create! ( email : 'service.desk@example.com' )
2020-07-28 23:09:34 +05:30
end
2023-06-20 00:43:36 +05:30
describe 'thank you email' , feature_category : :service_desk do
2020-07-28 23:09:34 +05:30
subject { described_class . service_desk_thank_you_email ( issue . id ) }
it_behaves_like 'an unsubscribeable thread'
2023-04-23 21:23:45 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
it_behaves_like 'a mail with default delivery method'
2020-07-28 23:09:34 +05:30
it 'has the correct recipient' do
is_expected . to deliver_to ( 'service.desk@example.com' )
end
it 'has the correct subject and body' do
aggregate_failures do
is_expected . to have_referable_subject ( issue , include_project : false , reply : true )
is_expected . to have_body_text ( " Thank you for your support request! We are tracking your request as ticket #{ issue . to_reference } , and will respond as soon as we can. " )
end
end
it 'uses service bot name by default' do
2021-04-29 21:17:54 +05:30
expect_sender ( User . support_bot )
2020-07-28 23:09:34 +05:30
end
context 'when custom outgoing name is set' do
let_it_be ( :settings ) { create ( :service_desk_setting , project : project , outgoing_name : 'some custom name' ) }
it 'uses custom name in "from" header' do
2021-04-29 21:17:54 +05:30
sender = subject . header [ :from ] . addrs [ 0 ]
expect ( sender . display_name ) . to eq ( 'some custom name' )
expect ( sender . address ) . to eq ( gitlab_sender )
2020-07-28 23:09:34 +05:30
end
end
context 'when custom outgoing name is empty' do
let_it_be ( :settings ) { create ( :service_desk_setting , project : project , outgoing_name : '' ) }
it 'uses service bot name' do
2021-04-29 21:17:54 +05:30
expect_sender ( User . support_bot )
2020-07-28 23:09:34 +05:30
end
end
2023-04-23 21:23:45 +05:30
context 'when service_desk_custom_email is active' do
before do
stub_feature_flags ( service_desk_custom_email : true )
end
it_behaves_like 'a mail with default delivery method'
it 'uses service bot name by default' do
expect_sender ( User . support_bot )
end
context 'when custom email is enabled' do
2023-06-20 00:43:36 +05:30
let_it_be ( :credentials ) do
create (
:service_desk_custom_email_credential ,
project : project
)
end
2023-04-23 21:23:45 +05:30
let_it_be ( :settings ) do
create (
:service_desk_setting ,
project : project ,
custom_email_enabled : true ,
2023-06-20 00:43:36 +05:30
custom_email : 'supersupport@example.com'
2023-04-23 21:23:45 +05:30
)
end
it 'uses custom email and service bot name in "from" header' do
expect_sender ( User . support_bot , sender_email : 'supersupport@example.com' )
end
it 'uses SMTP delivery method and has correct settings' do
expect_service_desk_custom_email_delivery_options ( settings )
end
end
end
2020-07-28 23:09:34 +05:30
end
2023-06-20 00:43:36 +05:30
describe 'new note email' , feature_category : :service_desk do
2020-07-28 23:09:34 +05:30
let_it_be ( :first_note ) { create ( :discussion_note_on_issue , note : 'Hello world' ) }
2021-04-17 20:07:23 +05:30
subject { described_class . service_desk_new_note_email ( issue . id , first_note . id , 'service.desk@example.com' ) }
2020-07-28 23:09:34 +05:30
it_behaves_like 'an unsubscribeable thread'
2023-04-23 21:23:45 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
it_behaves_like 'a mail with default delivery method'
2020-07-28 23:09:34 +05:30
it 'has the correct recipient' do
is_expected . to deliver_to ( 'service.desk@example.com' )
end
it 'uses author\'s name in "from" header' do
2021-04-29 21:17:54 +05:30
expect_sender ( first_note . author )
2020-07-28 23:09:34 +05:30
end
it 'has the correct subject and body' do
aggregate_failures do
is_expected . to have_referable_subject ( issue , include_project : false , reply : true )
is_expected . to have_body_text ( first_note . note )
end
end
2023-04-23 21:23:45 +05:30
context 'when service_desk_custom_email is active' do
before do
stub_feature_flags ( service_desk_custom_email : true )
end
it_behaves_like 'a mail with default delivery method'
it 'uses author\'s name in "from" header' do
expect_sender ( first_note . author )
end
context 'when custom email is enabled' do
2023-06-20 00:43:36 +05:30
let_it_be ( :credentials ) do
create (
:service_desk_custom_email_credential ,
project : project
)
end
2023-04-23 21:23:45 +05:30
let_it_be ( :settings ) do
create (
:service_desk_setting ,
project : project ,
custom_email_enabled : true ,
2023-06-20 00:43:36 +05:30
custom_email : 'supersupport@example.com'
2023-04-23 21:23:45 +05:30
)
end
it 'uses custom email and author\'s name in "from" header' do
expect_sender ( first_note . author , sender_email : project . service_desk_setting . custom_email )
end
it 'uses SMTP delivery method and has correct settings' do
expect_service_desk_custom_email_delivery_options ( settings )
end
end
end
2020-07-28 23:09:34 +05:30
end
end
2014-09-02 18:07:02 +05:30
end
2016-06-16 23:09:34 +05:30
context 'for a group' do
describe 'group access requested' do
2019-12-21 20:55:43 +05:30
let ( :group ) { create ( :group , :public ) }
2016-06-16 23:09:34 +05:30
let ( :group_member ) do
group . request_access ( user )
2016-08-24 12:49:21 +05:30
group . requesters . find_by ( user_id : user . id )
2016-06-16 23:09:34 +05:30
end
2020-01-01 13:55:28 +05:30
2019-10-12 21:52:04 +05:30
subject { described_class . member_access_requested_email ( 'group' , group_member . id , recipient . id ) }
2014-09-02 18:07:02 +05:30
2016-06-16 23:09:34 +05:30
it_behaves_like 'an email sent from GitLab'
2019-10-12 21:52:04 +05:30
it_behaves_like 'an email sent to a user'
2016-06-16 23:09:34 +05:30
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like " a user cannot unsubscribe through footer link "
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2014-09-02 18:07:02 +05:30
2016-06-16 23:09:34 +05:30
it 'contains all the useful information' do
2018-03-27 19:54:05 +05:30
to_emails = subject . header [ :to ] . addrs . map ( & :address )
2021-11-11 11:23:49 +05:30
expect ( to_emails ) . to eq ( [ recipient . notification_email_or_default ] )
2018-03-27 19:54:05 +05:30
2016-06-16 23:09:34 +05:30
is_expected . to have_subject " Request to join the #{ group . name } group "
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text group . name
2017-08-17 22:00:37 +05:30
is_expected . to have_body_text group_group_members_url ( group )
is_expected . to have_body_text group_member . human_access
2016-06-16 23:09:34 +05:30
end
end
2014-09-02 18:07:02 +05:30
2016-06-16 23:09:34 +05:30
describe 'group access denied' do
2021-12-11 22:18:48 +05:30
let_it_be ( :group ) { create ( :group , :public ) }
let_it_be ( :group_member ) { create ( :group_member , :developer , :access_request , user : user , source : group ) }
2020-10-24 23:57:45 +05:30
2019-10-12 21:52:04 +05:30
let ( :recipient ) { user }
2020-01-01 13:55:28 +05:30
2017-08-17 22:00:37 +05:30
subject { described_class . member_access_denied_email ( 'group' , group . id , user . id ) }
2016-06-16 23:09:34 +05:30
it_behaves_like 'an email sent from GitLab'
2019-10-12 21:52:04 +05:30
it_behaves_like 'an email sent to a user'
2016-06-16 23:09:34 +05:30
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like " a user cannot unsubscribe through footer link "
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2016-06-16 23:09:34 +05:30
it 'contains all the useful information' do
is_expected . to have_subject " Access to the #{ group . name } group was denied "
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text group . name
2017-08-17 22:00:37 +05:30
is_expected . to have_body_text group . web_url
2016-06-16 23:09:34 +05:30
end
2021-12-11 22:18:48 +05:30
context 'when user can not read group' do
let_it_be ( :group ) { create ( :group , :private ) }
it 'hides group name from subject and body' do
is_expected . to have_subject " Access to the Hidden group was denied "
is_expected . to have_body_text " Hidden group "
is_expected . not_to have_body_text group . name
is_expected . not_to have_body_text group . web_url
end
end
2014-09-02 18:07:02 +05:30
end
2016-06-16 23:09:34 +05:30
describe 'group access changed' do
let ( :group_member ) { create ( :group_member , group : group , user : user ) }
2019-10-12 21:52:04 +05:30
let ( :recipient ) { user }
2016-06-16 23:09:34 +05:30
2017-08-17 22:00:37 +05:30
subject { described_class . member_access_granted_email ( 'group' , group_member . id ) }
2016-06-16 23:09:34 +05:30
it_behaves_like 'an email sent from GitLab'
2019-10-12 21:52:04 +05:30
it_behaves_like 'an email sent to a user'
2016-06-16 23:09:34 +05:30
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like " a user cannot unsubscribe through footer link "
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2020-08-18 19:51:02 +05:30
it_behaves_like 'it requires a group'
2016-06-16 23:09:34 +05:30
it 'contains all the useful information' do
is_expected . to have_subject " Access to the #{ group . name } group was granted "
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text group . name
2017-08-17 22:00:37 +05:30
is_expected . to have_body_text group . web_url
is_expected . to have_body_text group_member . human_access
2019-07-31 22:56:46 +05:30
is_expected . to have_body_text 'leave the group'
is_expected . to have_body_text group_url ( group , leave : 1 )
2016-06-16 23:09:34 +05:30
end
2014-09-02 18:07:02 +05:30
end
2021-12-11 22:18:48 +05:30
def invite_to_group ( group , inviter : , user : nil , tasks_to_be_done : [ ] )
2016-11-03 12:29:30 +05:30
create (
:group_member ,
:developer ,
group : group ,
invite_token : '1234' ,
invite_email : 'toto@example.com' ,
2020-11-24 15:15:51 +05:30
user : user ,
2021-12-11 22:18:48 +05:30
created_by : inviter ,
tasks_to_be_done : tasks_to_be_done
2016-09-13 17:45:13 +05:30
)
2016-06-16 23:09:34 +05:30
end
2021-01-03 14:25:43 +05:30
describe 'invitations' do
2022-08-13 15:12:31 +05:30
let ( :owner ) { create ( :user ) . tap { | u | group . add_member ( u , Gitlab :: Access :: OWNER ) } }
2020-11-24 15:15:51 +05:30
let ( :group_member ) { invite_to_group ( group , inviter : inviter ) }
let ( :inviter ) { owner }
2016-06-16 23:09:34 +05:30
2021-01-03 14:25:43 +05:30
subject { described_class . member_invited_email ( 'Group' , group_member . id , group_member . invite_token ) }
2021-01-29 00:20:46 +05:30
it_behaves_like 'an email sent from GitLab'
2022-01-26 12:08:38 +05:30
it_behaves_like 'it should show Gmail Actions Join now link'
2021-01-29 00:20:46 +05:30
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_behaves_like 'it requires a group'
it_behaves_like 'does not render a manage notifications link'
2020-11-24 15:15:51 +05:30
2021-01-29 00:20:46 +05:30
context 'when there is an inviter' do
2020-11-24 15:15:51 +05:30
it 'contains all the useful information' do
2021-01-29 00:20:46 +05:30
is_expected . to have_subject " #{ group_member . created_by . name } invited you to join GitLab "
2020-11-24 15:15:51 +05:30
is_expected . to have_body_text group . name
2021-01-29 00:20:46 +05:30
is_expected . to have_body_text group_member . human_access . downcase
2020-11-24 15:15:51 +05:30
is_expected . to have_body_text group_member . invite_token
2021-12-11 22:18:48 +05:30
is_expected . not_to have_body_text 'and has assigned you the following tasks:'
2020-11-24 15:15:51 +05:30
end
end
2021-01-29 00:20:46 +05:30
context 'when there is no inviter' do
let ( :inviter ) { nil }
2020-11-24 15:15:51 +05:30
2021-01-29 00:20:46 +05:30
it 'contains all the useful information' do
is_expected . to have_subject " Invitation to join the #{ group . name } group "
is_expected . to have_body_text group . name
is_expected . to have_body_text group_member . human_access . downcase
is_expected . to have_body_text group_member . invite_token
2020-11-24 15:15:51 +05:30
end
2016-06-16 23:09:34 +05:30
end
2021-12-11 22:18:48 +05:30
context 'with tasks to be done present' , :aggregate_failures do
let ( :group_member ) { invite_to_group ( group , inviter : inviter , tasks_to_be_done : [ :ci , :code ] ) }
it 'contains the assigned tasks to be done' do
is_expected . to have_body_text 'and has assigned you the following tasks:'
is_expected . to have_body_text localized_tasks_to_be_done_choices [ :ci ]
is_expected . to have_body_text localized_tasks_to_be_done_choices [ :code ]
end
context 'when there is no inviter' do
let ( :inviter ) { nil }
it 'does not contain the assigned tasks to be done' do
is_expected . not_to have_body_text 'and has assigned you the following tasks:'
end
end
end
2016-06-16 23:09:34 +05:30
end
2021-01-03 14:25:43 +05:30
describe 'group invitation reminders' do
2022-08-13 15:12:31 +05:30
let_it_be ( :inviter ) { create ( :user ) . tap { | u | group . add_member ( u , Gitlab :: Access :: OWNER ) } }
2021-01-03 14:25:43 +05:30
let ( :group_member ) { invite_to_group ( group , inviter : inviter ) }
subject { described_class . member_invited_reminder_email ( 'Group' , group_member . id , group_member . invite_token , reminder_index ) }
describe 'not sending a reminder' do
let ( :reminder_index ) { 0 }
context 'member does not exist' do
let ( :group_member ) { double ( id : nil , invite_token : nil ) }
it_behaves_like 'no email is sent'
end
context 'member is not created by a user' do
before do
2022-03-02 08:16:31 +05:30
group_member . update! ( created_by : nil )
2021-01-03 14:25:43 +05:30
end
it_behaves_like 'no email is sent'
end
context 'member is a known user' do
before do
2022-03-02 08:16:31 +05:30
group_member . update! ( user : create ( :user ) )
2021-01-03 14:25:43 +05:30
end
it_behaves_like 'no email is sent'
end
end
describe 'the first reminder' do
let ( :reminder_index ) { 0 }
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 'contains all the useful information' do
is_expected . to have_subject " #{ inviter . name } 's invitation to GitLab is pending "
is_expected . to have_body_text group . human_name
is_expected . to have_body_text group_member . human_access . downcase
is_expected . to have_body_text invite_url ( group_member . invite_token )
is_expected . to have_body_text decline_invite_url ( group_member . invite_token )
end
end
describe 'the second reminder' do
let ( :reminder_index ) { 1 }
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 'contains all the useful information' do
is_expected . to have_subject " #{ inviter . name } is waiting for you to join GitLab "
is_expected . to have_body_text group . human_name
is_expected . to have_body_text group_member . human_access . downcase
is_expected . to have_body_text invite_url ( group_member . invite_token )
is_expected . to have_body_text decline_invite_url ( group_member . invite_token )
end
end
describe 'the third reminder' do
let ( :reminder_index ) { 2 }
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 'contains all the useful information' do
is_expected . to have_subject " #{ inviter . name } is still waiting for you to join GitLab "
is_expected . to have_body_text group . human_name
is_expected . to have_body_text group_member . human_access . downcase
is_expected . to have_body_text invite_url ( group_member . invite_token )
is_expected . to have_body_text decline_invite_url ( group_member . invite_token )
end
end
end
2016-06-16 23:09:34 +05:30
describe 'group invitation accepted' do
2016-11-03 12:29:30 +05:30
let ( :invited_user ) { create ( :user , name : 'invited user' ) }
2022-08-13 15:12:31 +05:30
let ( :owner ) { create ( :user ) . tap { | u | group . add_member ( u , Gitlab :: Access :: OWNER ) } }
2016-06-16 23:09:34 +05:30
let ( :group_member ) do
2016-11-03 12:29:30 +05:30
invitee = invite_to_group ( group , inviter : owner )
2016-06-16 23:09:34 +05:30
invitee . accept_invite! ( invited_user )
invitee
end
2017-08-17 22:00:37 +05:30
subject { described_class . member_invite_accepted_email ( 'group' , group_member . id ) }
2016-06-16 23:09:34 +05:30
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 "
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2020-08-18 19:51:02 +05:30
it_behaves_like 'it requires a group'
2016-06-16 23:09:34 +05:30
it 'contains all the useful information' do
is_expected . to have_subject 'Invitation accepted'
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text group . name
2017-08-17 22:00:37 +05:30
is_expected . to have_body_text group . web_url
is_expected . to have_body_text group_member . invite_email
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text invited_user . name
2016-06-16 23:09:34 +05:30
end
end
describe 'group invitation declined' do
2022-08-13 15:12:31 +05:30
let ( :owner ) { create ( :user ) . tap { | u | group . add_member ( u , Gitlab :: Access :: OWNER ) } }
2016-06-16 23:09:34 +05:30
let ( :group_member ) do
2016-11-03 12:29:30 +05:30
invitee = invite_to_group ( group , inviter : owner )
2016-06-16 23:09:34 +05:30
invitee . decline_invite!
invitee
end
2017-08-17 22:00:37 +05:30
subject { described_class . member_invite_declined_email ( 'group' , group . id , group_member . invite_email , owner . id ) }
2016-06-16 23:09:34 +05:30
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 "
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2016-06-16 23:09:34 +05:30
it 'contains all the useful information' do
is_expected . to have_subject 'Invitation declined'
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text group . name
2017-08-17 22:00:37 +05:30
is_expected . to have_body_text group . web_url
is_expected . to have_body_text group_member . invite_email
2016-06-16 23:09:34 +05:30
end
2014-09-02 18:07:02 +05:30
end
2021-03-08 18:12:59 +05:30
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
2021-09-30 23:02:18 +05:30
describe 'admin notification' do
let ( :example_site_path ) { root_path }
let ( :user ) { create ( :user ) }
subject { @email = described_class . send_admin_notification ( user . id , 'Admin announcement' , 'Text' ) }
it 'is sent as the author' do
sender = subject . header [ :from ] . addrs [ 0 ]
expect ( sender . display_name ) . to eq ( " GitLab " )
expect ( sender . address ) . to eq ( gitlab_sender )
end
it 'is sent to recipient' do
is_expected . to deliver_to user . email
end
it 'has the correct subject' do
is_expected . to have_subject 'Admin announcement'
end
it 'includes unsubscribe link' do
unsubscribe_link = " http://localhost/unsubscribes/ #{ Base64 . urlsafe_encode64 ( user . email ) } "
is_expected . to have_body_text ( unsubscribe_link )
end
end
2014-09-02 18:07:02 +05:30
end
describe 'confirmation if email changed' do
let ( :example_site_path ) { root_path }
let ( :user ) { create ( :user , email : 'old-email@mail.com' ) }
before do
2016-11-03 12:29:30 +05:30
stub_config_setting ( email_subject_suffix : 'A Nice Suffix' )
2015-12-23 02:04:40 +05:30
perform_enqueued_jobs do
user . email = " new-email@mail.com "
2022-03-02 08:16:31 +05:30
user . save!
2015-12-23 02:04:40 +05:30
end
2014-09-02 18:07:02 +05:30
end
2022-07-23 23:45:48 +05:30
subject { ActionMailer :: Base . deliveries . first }
2014-09-02 18:07:02 +05:30
it_behaves_like 'an email sent from GitLab'
2016-01-19 16:12:03 +05:30
it_behaves_like " a user cannot unsubscribe through footer link "
2014-09-02 18:07:02 +05:30
it 'is sent to the new user' do
2015-04-26 12:48:37 +05:30
is_expected . to deliver_to 'new-email@mail.com'
2014-09-02 18:07:02 +05:30
end
2017-08-17 22:00:37 +05:30
it 'has the correct subject and body' do
aggregate_failures do
is_expected . to have_subject ( 'Confirmation instructions | A Nice Suffix' )
is_expected . to have_body_text ( example_site_path )
end
2015-04-26 12:48:37 +05:30
end
end
describe 'email on push for a created branch' do
let ( :example_site_path ) { root_path }
2017-09-10 17:25:29 +05:30
let ( :tree_path ) { project_tree_path ( project , " empty-branch " ) }
2015-04-26 12:48:37 +05:30
2017-08-17 22:00:37 +05:30
subject { described_class . repository_push_email ( project . id , author_id : user . id , ref : 'refs/heads/empty-branch' , action : :create ) }
2015-04-26 12:48:37 +05:30
2015-12-23 02:04:40 +05:30
it_behaves_like 'it should not have Gmail Actions links'
2016-09-29 09:46:39 +05:30
it_behaves_like 'a user cannot unsubscribe through footer link'
2016-01-29 22:53:50 +05:30
it_behaves_like 'an email with X-GitLab headers containing project details'
it_behaves_like 'an email that contains a header with author username'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2015-12-23 02:04:40 +05:30
2015-04-26 12:48:37 +05:30
it 'is sent as the author' do
2021-04-29 21:17:54 +05:30
expect_sender ( user )
2015-04-26 12:48:37 +05:30
end
2017-08-17 22:00:37 +05:30
it 'has the correct subject and body' do
aggregate_failures do
is_expected . to have_subject ( " [Git][ #{ project . full_path } ] Pushed new branch empty-branch " )
is_expected . to have_body_text ( tree_path )
end
2015-04-26 12:48:37 +05:30
end
end
describe 'email on push for a created tag' do
let ( :example_site_path ) { root_path }
2017-09-10 17:25:29 +05:30
let ( :tree_path ) { project_tree_path ( project , " v1.0 " ) }
2015-04-26 12:48:37 +05:30
2017-08-17 22:00:37 +05:30
subject { described_class . repository_push_email ( project . id , author_id : user . id , ref : 'refs/tags/v1.0' , action : :create ) }
2015-04-26 12:48:37 +05:30
2015-12-23 02:04:40 +05:30
it_behaves_like 'it should not have Gmail Actions links'
2016-01-19 16:12:03 +05:30
it_behaves_like " a user cannot unsubscribe through footer link "
2016-01-29 22:53:50 +05:30
it_behaves_like 'an email with X-GitLab headers containing project details'
it_behaves_like 'an email that contains a header with author username'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2015-12-23 02:04:40 +05:30
2015-04-26 12:48:37 +05:30
it 'is sent as the author' do
2021-04-29 21:17:54 +05:30
expect_sender ( user )
2015-04-26 12:48:37 +05:30
end
2017-08-17 22:00:37 +05:30
it 'has the correct subject and body' do
aggregate_failures do
is_expected . to have_subject ( " [Git][ #{ project . full_path } ] Pushed new tag v1.0 " )
is_expected . to have_body_text ( tree_path )
end
2015-04-26 12:48:37 +05:30
end
end
describe 'email on push for a deleted branch' do
let ( :example_site_path ) { root_path }
2017-08-17 22:00:37 +05:30
subject { described_class . repository_push_email ( project . id , author_id : user . id , ref : 'refs/heads/master' , action : :delete ) }
2015-04-26 12:48:37 +05:30
2015-12-23 02:04:40 +05:30
it_behaves_like 'it should not have Gmail Actions links'
2016-09-29 09:46:39 +05:30
it_behaves_like 'a user cannot unsubscribe through footer link'
2016-01-29 22:53:50 +05:30
it_behaves_like 'an email with X-GitLab headers containing project details'
it_behaves_like 'an email that contains a header with author username'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2015-12-23 02:04:40 +05:30
2015-04-26 12:48:37 +05:30
it 'is sent as the author' do
2021-04-29 21:17:54 +05:30
expect_sender ( user )
2015-04-26 12:48:37 +05:30
end
it 'has the correct subject' do
2017-08-17 22:00:37 +05:30
is_expected . to have_subject " [Git][ #{ project . full_path } ] Deleted branch master "
2015-04-26 12:48:37 +05:30
end
end
describe 'email on push for a deleted tag' do
let ( :example_site_path ) { root_path }
2017-08-17 22:00:37 +05:30
subject { described_class . repository_push_email ( project . id , author_id : user . id , ref : 'refs/tags/v1.0' , action : :delete ) }
2015-04-26 12:48:37 +05:30
2015-12-23 02:04:40 +05:30
it_behaves_like 'it should not have Gmail Actions links'
2016-09-29 09:46:39 +05:30
it_behaves_like 'a user cannot unsubscribe through footer link'
2016-01-29 22:53:50 +05:30
it_behaves_like 'an email with X-GitLab headers containing project details'
it_behaves_like 'an email that contains a header with author username'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2015-12-23 02:04:40 +05:30
2015-04-26 12:48:37 +05:30
it 'is sent as the author' do
2021-04-29 21:17:54 +05:30
expect_sender ( user )
2015-04-26 12:48:37 +05:30
end
it 'has the correct subject' do
2017-08-17 22:00:37 +05:30
is_expected . to have_subject " [Git][ #{ project . full_path } ] Deleted tag v1.0 "
2014-09-02 18:07:02 +05:30
end
end
describe 'email on push with multiple commits' do
let ( :example_site_path ) { root_path }
2016-09-13 17:45:13 +05:30
let ( :raw_compare ) { Gitlab :: Git :: Compare . new ( project . repository . raw_repository , sample_image_commit . id , sample_commit . id ) }
let ( :compare ) { Compare . decorate ( raw_compare , project ) }
let ( :commits ) { compare . commits }
2017-09-10 17:25:29 +05:30
let ( :diff_path ) { project_compare_path ( project , from : Commit . new ( compare . base , project ) , to : Commit . new ( compare . head , project ) ) }
2015-04-26 12:48:37 +05:30
let ( :send_from_committer_email ) { false }
2016-08-24 12:49:21 +05:30
let ( :diff_refs ) { Gitlab :: Diff :: DiffRefs . new ( base_sha : project . merge_base_commit ( sample_image_commit . id , sample_commit . id ) . id , head_sha : sample_commit . id ) }
2014-09-02 18:07:02 +05:30
2017-08-17 22:00:37 +05:30
subject { described_class . repository_push_email ( project . id , author_id : user . id , ref : 'refs/heads/master' , action : :push , compare : compare , reverse_compare : false , diff_refs : diff_refs , send_from_committer_email : send_from_committer_email ) }
2014-09-02 18:07:02 +05:30
2015-12-23 02:04:40 +05:30
it_behaves_like 'it should not have Gmail Actions links'
2016-09-29 09:46:39 +05:30
it_behaves_like 'a user cannot unsubscribe through footer link'
2016-01-29 22:53:50 +05:30
it_behaves_like 'an email with X-GitLab headers containing project details'
it_behaves_like 'an email that contains a header with author username'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2015-12-23 02:04:40 +05:30
2014-09-02 18:07:02 +05:30
it 'is sent as the author' do
2021-04-29 21:17:54 +05:30
expect_sender ( user )
2014-09-02 18:07:02 +05:30
end
2017-08-17 22:00:37 +05:30
it 'has the correct subject and body' do
aggregate_failures do
is_expected . to have_subject ( " [Git][ #{ project . full_path } ][master] #{ commits . length } commits: Ruby files modified " )
is_expected . to have_body_text ( 'Change some files' )
is_expected . to have_body_text ( 'def</span> <span class="nf">archive_formats_regex' )
is_expected . to have_body_text ( diff_path )
is_expected . not_to have_body_text ( 'you are a member of' )
end
2015-04-26 12:48:37 +05:30
end
context " when set to send from committer email if domain matches " do
let ( :send_from_committer_email ) { true }
before do
allow ( Gitlab . config . gitlab ) . to receive ( :host ) . and_return ( " gitlab.corp.company.com " )
end
context " when the committer email domain is within the GitLab domain " do
before do
user . update_attribute ( :email , " user@company.com " )
2015-09-25 12:07:36 +05:30
user . confirm
2015-04-26 12:48:37 +05:30
end
it " is sent from the committer email " do
2017-08-17 22:00:37 +05:30
from = subject . header [ :from ] . addrs . first
reply = subject . header [ :reply_to ] . addrs . first
2015-04-26 12:48:37 +05:30
2017-08-17 22:00:37 +05:30
aggregate_failures do
expect ( from . address ) . to eq ( user . email )
expect ( reply . address ) . to eq ( user . email )
end
2015-04-26 12:48:37 +05:30
end
end
context " when the committer email domain is not completely within the GitLab domain " do
before do
user . update_attribute ( :email , " user@something.company.com " )
2015-09-25 12:07:36 +05:30
user . confirm
2015-04-26 12:48:37 +05:30
end
it " is sent from the default email " do
2017-08-17 22:00:37 +05:30
from = subject . header [ :from ] . addrs . first
reply = subject . header [ :reply_to ] . addrs . first
2015-04-26 12:48:37 +05:30
2017-08-17 22:00:37 +05:30
aggregate_failures do
expect ( from . address ) . to eq ( gitlab_sender )
expect ( reply . address ) . to eq ( gitlab_sender_reply_to )
end
2015-04-26 12:48:37 +05:30
end
end
context " when the committer email domain is outside the GitLab domain " do
before do
user . update_attribute ( :email , " user@mpany.com " )
2015-09-25 12:07:36 +05:30
user . confirm
2015-04-26 12:48:37 +05:30
end
it " is sent from the default email " do
2017-08-17 22:00:37 +05:30
from = subject . header [ :from ] . addrs . first
reply = subject . header [ :reply_to ] . addrs . first
2015-04-26 12:48:37 +05:30
2017-08-17 22:00:37 +05:30
aggregate_failures do
expect ( from . address ) . to eq ( gitlab_sender )
expect ( reply . address ) . to eq ( gitlab_sender_reply_to )
end
2015-04-26 12:48:37 +05:30
end
end
2014-09-02 18:07:02 +05:30
end
end
describe 'email on push with a single commit' do
let ( :example_site_path ) { root_path }
2016-09-13 17:45:13 +05:30
let ( :raw_compare ) { Gitlab :: Git :: Compare . new ( project . repository . raw_repository , sample_commit . parent_id , sample_commit . id ) }
let ( :compare ) { Compare . decorate ( raw_compare , project ) }
let ( :commits ) { compare . commits }
2017-09-10 17:25:29 +05:30
let ( :diff_path ) { project_commit_path ( project , commits . first ) }
2016-08-24 12:49:21 +05:30
let ( :diff_refs ) { Gitlab :: Diff :: DiffRefs . new ( base_sha : project . merge_base_commit ( sample_image_commit . id , sample_commit . id ) . id , head_sha : sample_commit . id ) }
2014-09-02 18:07:02 +05:30
2017-08-17 22:00:37 +05:30
subject { described_class . repository_push_email ( project . id , author_id : user . id , ref : 'refs/heads/master' , action : :push , compare : compare , diff_refs : diff_refs ) }
2014-09-02 18:07:02 +05:30
2015-12-23 02:04:40 +05:30
it_behaves_like 'it should show Gmail Actions View Commit link'
2016-09-29 09:46:39 +05:30
it_behaves_like 'a user cannot unsubscribe through footer link'
2016-01-29 22:53:50 +05:30
it_behaves_like 'an email with X-GitLab headers containing project details'
it_behaves_like 'an email that contains a header with author username'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2015-12-23 02:04:40 +05:30
2014-09-02 18:07:02 +05:30
it 'is sent as the author' do
2021-04-29 21:17:54 +05:30
expect_sender ( user )
2014-09-02 18:07:02 +05:30
end
2017-08-17 22:00:37 +05:30
it 'has the correct subject and body' do
aggregate_failures do
is_expected . to have_subject ( " [Git][ #{ project . full_path } ][master] #{ commits . first . title } " )
is_expected . to have_body_text ( 'Change some files' )
is_expected . to have_body_text ( 'def</span> <span class="nf">archive_formats_regex' )
is_expected . to have_body_text ( diff_path )
end
2014-09-02 18:07:02 +05:30
end
2017-08-17 22:00:37 +05:30
end
describe 'HTML emails setting' do
let ( :multipart_mail ) { described_class . project_was_moved_email ( project . id , user . id , " gitlab/gitlab " ) }
2014-09-02 18:07:02 +05:30
2019-07-07 11:18:12 +05:30
subject { multipart_mail }
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2017-08-17 22:00:37 +05:30
context 'when disabled' do
it 'only sends the text template' do
stub_application_setting ( html_emails_enabled : false )
2018-11-18 11:00:15 +05:30
Gitlab :: Email :: Hook :: EmailTemplateInterceptor
. delivering_email ( multipart_mail )
2017-08-17 22:00:37 +05:30
expect ( multipart_mail ) . to have_part_with ( 'text/plain' )
expect ( multipart_mail ) . not_to have_part_with ( 'text/html' )
end
2014-09-02 18:07:02 +05:30
end
2017-08-17 22:00:37 +05:30
context 'when enabled' do
it 'sends a multipart message' do
stub_application_setting ( html_emails_enabled : true )
2018-11-18 11:00:15 +05:30
Gitlab :: Email :: Hook :: EmailTemplateInterceptor
. delivering_email ( multipart_mail )
2017-08-17 22:00:37 +05:30
expect ( multipart_mail ) . to have_part_with ( 'text/plain' )
expect ( multipart_mail ) . to have_part_with ( 'text/html' )
end
2014-09-02 18:07:02 +05:30
end
2017-08-17 22:00:37 +05:30
matcher :have_part_with do | expected |
match do | actual |
2018-03-17 18:26:18 +05:30
actual . body . parts . any? { | part | part . content_type . try ( :match , / #{ expected } / ) }
2017-08-17 22:00:37 +05:30
end
2014-09-02 18:07:02 +05:30
end
end
2018-03-17 18:26:18 +05:30
context 'for personal snippet notes' do
let ( :personal_snippet ) { create ( :personal_snippet ) }
let ( :personal_snippet_note ) { create ( :note_on_personal_snippet , noteable : personal_snippet ) }
2020-03-13 15:44:24 +05:30
subject { described_class . note_snippet_email ( personal_snippet_note . author_id , personal_snippet_note . id ) }
2018-03-17 18:26:18 +05:30
it_behaves_like 'a user cannot unsubscribe through footer link'
2019-07-07 11:18:12 +05:30
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2018-03-17 18:26:18 +05:30
2020-03-13 15:44:24 +05:30
it 'has the correct subject' do
2018-03-17 18:26:18 +05:30
is_expected . to have_referable_subject ( personal_snippet , reply : true )
2020-03-13 15:44:24 +05:30
end
it 'has the correct body' do
2018-11-08 19:23:39 +05:30
is_expected . to have_body_text personal_snippet_note . note
2018-03-17 18:26:18 +05:30
end
2020-03-13 15:44:24 +05:30
it 'links to the personal snippet' do
target_url = gitlab_snippet_url ( personal_snippet_note . noteable )
is_expected . to have_body_text target_url
end
2018-03-17 18:26:18 +05:30
end
2020-06-23 00:09:42 +05:30
describe 'merge request reviews' do
let! ( :review ) { create ( :review , project : project , merge_request : merge_request ) }
let! ( :notes ) { create_list ( :note , 3 , review : review , project : project , author : review . author , noteable : merge_request ) }
subject { described_class . new_review_email ( recipient . id , review . id ) }
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { review . merge_request }
end
it_behaves_like 'it should show Gmail Actions View Merge request link'
it_behaves_like 'an unsubscribeable thread'
it 'is sent to the given recipient as the author' do
aggregate_failures do
2021-04-29 21:17:54 +05:30
expect_sender ( review . author )
2020-06-23 00:09:42 +05:30
end
end
it 'contains the message from the notes of the review' do
review . notes . each do | note |
is_expected . to have_body_text note . note
end
end
context 'when diff note' do
let! ( :notes ) { create_list ( :diff_note_on_merge_request , 3 , review : review , project : project , author : review . author , noteable : merge_request ) }
2022-06-21 17:19:12 +05:30
it 'links to notes and discussions' , :aggregate_failures do
reply_note = create ( :diff_note_on_merge_request , review : review , project : project , author : review . author , noteable : merge_request , in_reply_to : notes . first )
2020-06-23 00:09:42 +05:30
review . notes . each do | note |
# Text part
expect ( subject . text_part . body . raw_source ) . to include (
project_merge_request_url ( project , merge_request , anchor : " note_ #{ note . id } " )
)
2022-06-21 17:19:12 +05:30
if note == reply_note
expect ( subject . text_part . body . raw_source ) . to include ( " commented on a discussion on #{ note . discussion . file_path } " )
else
expect ( subject . text_part . body . raw_source ) . to include ( " started a new discussion on #{ note . discussion . file_path } " )
end
2020-06-23 00:09:42 +05:30
end
end
2022-06-21 17:19:12 +05:30
it 'includes only one link to the highlighted_diff_email' do
expect ( subject . html_part . body . raw_source ) . to include ( 'assets/mailers/highlighted_diff_email' ) . once
end
it 'avoids N+1 cached queries when rendering html' , :use_sql_query_cache , :request_store do
control_count = ActiveRecord :: QueryRecorder . new ( query_recorder_debug : true , skip_cached : false ) do
subject . html_part
end
create_list ( :diff_note_on_merge_request , 3 , review : review , project : project , author : review . author , noteable : merge_request )
expect { described_class . new_review_email ( recipient . id , review . id ) . html_part } . not_to exceed_all_query_limit ( control_count )
end
it 'avoids N+1 cached queries when rendering text' , :use_sql_query_cache , :request_store do
control_count = ActiveRecord :: QueryRecorder . new ( query_recorder_debug : true , skip_cached : false ) do
subject . text_part
end
create_list ( :diff_note_on_merge_request , 3 , review : review , project : project , author : review . author , noteable : merge_request )
expect { described_class . new_review_email ( recipient . id , review . id ) . text_part } . not_to exceed_all_query_limit ( control_count )
end
2020-06-23 00:09:42 +05:30
end
it 'contains review author name' do
is_expected . to have_body_text review . author_name
end
it 'has the correct subject and body' do
aggregate_failures do
is_expected . to have_subject " Re: #{ project . name } | #{ merge_request . title } ( #{ merge_request . to_reference } ) "
is_expected . to have_body_text project_merge_request_path ( project , merge_request )
end
end
end
2021-04-29 21:17:54 +05:30
2021-09-30 23:02:18 +05:30
describe 'in product marketing' , :mailer do
let_it_be ( :group ) { create ( :group ) }
let ( :mail ) { ActionMailer :: Base . deliveries . last }
it 'does not raise error' do
described_class . in_product_marketing_email ( user . id , group . id , :trial , 0 ) . deliver
expect ( mail . subject ) . to eq ( 'Go farther with GitLab' )
expect ( mail . body . parts . first . to_s ) . to include ( 'Start a GitLab Ultimate trial today in less than one minute, no credit card required.' )
end
end
2014-09-02 18:07:02 +05:30
end