2019-10-21 09:06:22 +00:00
# frozen_string_literal: true
2012-05-14 18:05:32 +00:00
require 'spec_helper'
2015-05-21 22:41:31 +00:00
require 'email_spec'
2012-05-14 18:05:32 +00:00
2020-06-24 18:09:03 +00:00
RSpec . describe Notify do
2012-05-14 18:05:32 +00:00
include EmailSpec :: Helpers
include EmailSpec :: Matchers
2018-12-11 12:33:27 +00:00
include EmailHelpers
2014-08-01 12:18:17 +00:00
include RepoHelpers
2012-05-14 18:05:32 +00:00
2016-02-12 12:20:21 +00:00
include_context 'gitlab email notification'
2015-12-09 10:59:25 +00:00
2019-01-15 14:22:26 +00:00
let ( :current_user_sanitized ) { 'www_example_com' }
2020-03-26 18:08:03 +00:00
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-03-02 06:10:53 +00:00
let_it_be ( :reviewer , reload : true ) { create ( :user , email : 'reviewer@example.com' , name : 'Jane Doe' ) }
2017-09-01 10:34:20 +00:00
2020-02-18 15:08:51 +00:00
let_it_be ( :merge_request ) do
2017-09-01 10:34:20 +00:00
create ( :merge_request , source_project : project ,
target_project : project ,
author : current_user ,
2019-04-07 18:35:16 +00:00
assignees : [ assignee ] ,
2021-03-02 06:10:53 +00:00
reviewers : [ reviewer ] ,
2017-09-01 10:34:20 +00:00
description : 'Awesome description' )
end
2020-02-18 15:08:51 +00:00
let_it_be ( :issue , reload : true ) do
2017-09-01 10:34:20 +00:00
create ( :issue , author : current_user ,
assignees : [ assignee ] ,
project : project ,
description : 'My awesome description!' )
end
2019-04-03 12:49:06 +00:00
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
2017-09-01 10:34:20 +00:00
2020-08-05 21:09:40 +00:00
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
2012-05-14 22:03:30 +00:00
context 'for a project' do
2017-10-09 12:59:10 +00:00
shared_examples 'an assignee email' do
2019-06-24 09:20:10 +00:00
let ( :recipient ) { assignee }
2019-02-15 17:56:13 +00:00
it_behaves_like 'an email sent to a user'
2017-10-09 12:59:10 +00:00
it 'is sent to the assignee as the author' do
aggregate_failures do
2021-03-19 12:09:03 +00:00
expect_sender ( current_user )
2019-06-24 09:20:10 +00:00
expect ( subject ) . to deliver_to ( recipient . notification_email )
2017-10-09 12:59:10 +00:00
end
end
end
2012-05-14 18:05:32 +00:00
2017-10-09 12:59:10 +00:00
context 'for issues' do
describe 'that are new' do
subject { described_class . new_issue_email ( issue . assignees . first . id , issue . id ) }
2014-02-17 17:49:42 +00:00
2017-10-09 12:59:10 +00:00
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-13 18:08:47 +00:00
2017-10-09 12:59:10 +00:00
it_behaves_like 'it should show Gmail Actions View Issue link'
it_behaves_like 'an unsubscribeable thread'
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2017-10-09 12:59:10 +00:00
it 'has the correct subject and body' do
2017-03-21 22:49:45 +00:00
aggregate_failures do
2017-10-09 12:59:10 +00:00
is_expected . to have_referable_subject ( issue )
is_expected . to have_body_text ( project_issue_path ( project , issue ) )
2017-03-21 22:49:45 +00:00
end
2012-05-14 22:03:30 +00:00
end
2012-05-14 18:05:32 +00:00
2017-10-09 12:59:10 +00:00
it 'contains the description' do
2018-06-03 13:22:50 +00:00
is_expected . to have_body_text issue . description
2017-10-09 12:59:10 +00:00
end
2012-05-14 18:05:32 +00:00
2017-12-28 17:25:02 +00:00
it 'does not add a reason header' do
is_expected . not_to have_header ( 'X-GitLab-NotificationReason' , / .+ / )
end
context 'when sent with a reason' do
subject { described_class . new_issue_email ( issue . assignees . first . id , issue . id , NotificationReason :: ASSIGNED ) }
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2017-12-28 17:25:02 +00:00
it 'includes the reason in a header' do
is_expected . to have_header ( 'X-GitLab-NotificationReason' , NotificationReason :: ASSIGNED )
end
end
2019-04-19 18:10:52 +00:00
it 'contains a link to issue author' do
is_expected . to have_body_text ( issue . author_name )
2021-04-22 21:09:53 +00:00
is_expected . to have_body_text 'created an issue:'
2020-07-03 09:08:53 +00:00
is_expected . to have_link ( issue . to_reference , href : project_issue_url ( issue . project , issue ) )
2020-05-26 21:07:45 +00:00
end
it 'contains a link to the issue' do
is_expected . to have_body_text ( issue . to_reference ( full : false ) )
2017-10-09 12:59:10 +00:00
end
end
2017-09-01 10:34:20 +00:00
2017-10-09 12:59:10 +00:00
describe 'that are reassigned' do
let ( :previous_assignee ) { create ( :user , name : 'Previous Assignee' ) }
2019-12-17 18:07:48 +00:00
2017-10-09 12:59:10 +00:00
subject { described_class . reassigned_issue_email ( recipient . id , issue . id , [ previous_assignee . id ] , current_user . id ) }
2016-01-26 13:34:42 +00:00
2017-10-09 12:59:10 +00:00
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 }
2012-05-14 22:03:30 +00:00
end
2020-05-13 18:08:47 +00:00
2017-10-09 12:59:10 +00:00
it_behaves_like 'it should show Gmail Actions View Issue link'
it_behaves_like 'an unsubscribeable thread'
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2012-05-14 18:05:32 +00:00
2017-10-09 12:59:10 +00:00
it 'is sent as the author' do
2021-03-19 12:09:03 +00:00
expect_sender ( current_user )
2017-10-09 12:59:10 +00:00
end
2012-05-14 22:03:30 +00:00
2017-10-09 12:59:10 +00:00
it 'has the correct subject and body' do
aggregate_failures do
is_expected . to have_referable_subject ( issue , reply : true )
2018-06-03 13:22:50 +00:00
is_expected . to have_body_text ( previous_assignee . name )
is_expected . to have_body_text ( assignee . name )
2017-10-09 12:59:10 +00:00
is_expected . to have_body_text ( project_issue_path ( project , issue ) )
2016-03-17 19:03:51 +00:00
end
2017-10-09 12:59:10 +00:00
end
2017-12-28 17:25:02 +00:00
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 ) }
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2017-12-28 17:25:02 +00:00
it 'includes the reason in a header' do
is_expected . to have_header ( 'X-GitLab-NotificationReason' , NotificationReason :: ASSIGNED )
end
end
2017-10-09 12:59:10 +00:00
end
2012-05-14 22:03:30 +00:00
2017-10-09 12:59:10 +00:00
describe 'that have been relabeled' do
subject { described_class . relabeled_issue_email ( recipient . id , issue . id , %w[ foo bar baz ] , current_user . id ) }
2014-02-17 17:49:42 +00:00
2017-10-09 12:59:10 +00:00
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 }
2012-05-14 22:03:30 +00:00
end
2020-05-13 18:08:47 +00:00
2017-10-09 12:59:10 +00:00
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-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2012-08-29 06:49:39 +00:00
2017-10-09 12:59:10 +00:00
it 'is sent as the author' do
2021-03-19 12:09:03 +00:00
expect_sender ( current_user )
2017-10-09 12:59:10 +00:00
end
2016-03-01 16:33:13 +00:00
2017-10-09 12:59:10 +00:00
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-03-17 19:03:51 +00:00
end
2017-10-09 12:59:10 +00:00
end
2016-03-01 16:33:13 +00:00
2017-10-09 12:59:10 +00:00
context 'with a preferred language' do
before do
Gitlab :: I18n . locale = :es
2016-03-01 16:33:13 +00:00
end
2017-10-09 12:59:10 +00:00
after do
Gitlab :: I18n . use_default_locale
2016-03-01 16:33:13 +00:00
end
2017-05-25 15:22:45 +00:00
2017-10-09 12:59:10 +00:00
it 'always generates the email using the default language' do
is_expected . to have_body_text ( 'foo, bar, and baz' )
2017-05-25 15:22:45 +00:00
end
2016-03-01 16:33:13 +00:00
end
2017-10-09 12:59:10 +00:00
end
2016-03-01 16:33:13 +00:00
2019-08-28 08:17:41 +00:00
describe 'that are due soon' do
subject { described_class . issue_due_email ( recipient . id , issue . id ) }
before do
issue . update ( due_date : Date . tomorrow )
end
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { issue }
end
2020-05-13 18:08:47 +00:00
2020-12-31 15:10:32 +00:00
it 'contains a link to the issue' do
is_expected . to have_body_text ( issue . to_reference ( full : false ) )
end
2019-08-28 08:17:41 +00:00
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
2017-10-09 12:59:10 +00:00
describe 'status changed' do
let ( :status ) { 'closed' }
2019-12-17 18:07:48 +00:00
2017-10-09 12:59:10 +00:00
subject { described_class . issue_status_changed_email ( recipient . id , issue . id , status , current_user . id ) }
2012-11-06 03:31:55 +00:00
2017-10-09 12:59:10 +00:00
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { issue }
end
2020-05-13 18:08:47 +00:00
2017-10-09 12:59:10 +00:00
it_behaves_like 'it should show Gmail Actions View Issue link'
it_behaves_like 'an unsubscribeable thread'
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2014-02-24 11:12:29 +00:00
2017-10-09 12:59:10 +00:00
it 'is sent as the author' do
2021-03-19 12:09:03 +00:00
expect_sender ( current_user )
2017-10-09 12:59:10 +00:00
end
2014-02-17 17:49:42 +00:00
2017-10-09 12:59:10 +00:00
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-01-15 14:22:26 +00:00
is_expected . to have_body_text ( current_user_sanitized )
2020-03-27 12:07:43 +00:00
is_expected . to have_body_text ( project_issue_path ( project , issue ) )
2012-08-29 06:49:39 +00:00
end
2015-11-25 12:27:31 +00:00
end
2017-10-09 12:59:10 +00:00
end
2016-03-15 10:35:40 +00:00
2017-10-09 12:59:10 +00:00
describe 'moved to another project' do
let ( :new_issue ) { create ( :issue ) }
2019-12-17 18:07:48 +00:00
2017-10-09 12:59:10 +00:00
subject { described_class . issue_moved_email ( recipient , issue , new_issue , current_user ) }
2016-03-15 10:35:40 +00:00
2019-02-13 10:50:24 +00:00
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-13 18:08:47 +00:00
2019-02-13 10:50:24 +00:00
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-03-15 10:35:40 +00:00
2019-02-13 10:50:24 +00:00
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
2016-03-15 10:35:40 +00:00
2019-02-13 10:50:24 +00:00
it 'contains the issue title' do
is_expected . to have_body_text new_issue . title
end
2017-10-09 12:59:10 +00:00
end
2016-03-15 10:35:40 +00:00
2019-02-13 10:50:24 +00:00
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-03-15 10:35:40 +00:00
2019-02-13 10:50:24 +00:00
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-03-15 10:35:40 +00:00
end
end
2012-05-14 22:03:30 +00:00
end
2017-10-09 12:59:10 +00:00
end
2012-05-14 22:03:30 +00:00
2017-10-09 12:59:10 +00:00
context 'for merge requests' do
describe 'that are new' do
2019-04-07 18:35:16 +00:00
subject { described_class . new_merge_request_email ( merge_request . assignee_ids . first , merge_request . id ) }
2017-10-09 12:59:10 +00:00
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-13 18:08:47 +00:00
2017-10-09 12:59:10 +00:00
it_behaves_like 'it should show Gmail Actions View Merge request link'
it_behaves_like 'an unsubscribeable thread'
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2012-05-14 22:03:30 +00:00
2017-10-09 12:59:10 +00:00
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-03-02 06:10:53 +00:00
is_expected . to have_body_text ( reviewer . name )
2016-03-17 19:03:51 +00:00
end
2017-10-09 12:59:10 +00:00
end
it 'contains the description' do
2018-06-03 13:22:50 +00:00
is_expected . to have_body_text merge_request . description
2017-10-09 12:59:10 +00:00
end
2017-12-28 17:25:02 +00:00
context 'when sent with a reason' do
2019-04-07 18:35:16 +00:00
subject { described_class . new_merge_request_email ( merge_request . assignee_ids . first , merge_request . id , NotificationReason :: ASSIGNED ) }
2017-12-28 17:25:02 +00:00
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2017-12-28 17:25:02 +00:00
it 'includes the reason in a header' do
is_expected . to have_header ( 'X-GitLab-NotificationReason' , NotificationReason :: ASSIGNED )
end
end
2019-04-19 18:10:52 +00:00
it 'contains a link to merge request author' do
is_expected . to have_body_text merge_request . author_name
2021-04-22 21:09:53 +00:00
is_expected . to have_body_text 'created a merge request:'
2021-03-11 00:09:38 +00:00
end
it 'contains a link to the merge request url' do
2021-04-22 21:09:53 +00:00
is_expected . to have_link ( merge_request . to_reference , href : project_merge_request_url ( merge_request . target_project , merge_request ) )
2017-10-09 12:59:10 +00:00
end
end
2017-09-01 10:34:20 +00:00
2017-10-09 12:59:10 +00:00
describe 'that are reassigned' do
let ( :previous_assignee ) { create ( :user , name : 'Previous Assignee' ) }
2019-12-17 18:07:48 +00:00
2019-04-07 18:35:16 +00:00
subject { described_class . reassigned_merge_request_email ( recipient . id , merge_request . id , [ previous_assignee . id ] , current_user . id ) }
2016-01-26 13:34:42 +00:00
2017-10-09 12:59:10 +00:00
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 }
2012-05-14 22:03:30 +00:00
end
2020-05-13 18:08:47 +00:00
2017-10-09 12:59:10 +00:00
it_behaves_like 'it should show Gmail Actions View Merge request link'
it_behaves_like " an unsubscribeable thread "
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2012-05-14 22:03:30 +00:00
2017-10-09 12:59:10 +00:00
it 'is sent as the author' do
2021-03-19 12:09:03 +00:00
expect_sender ( current_user )
2017-10-09 12:59:10 +00:00
end
2012-05-14 22:03:30 +00:00
2017-10-09 12:59:10 +00:00
it 'has the correct subject and body' do
aggregate_failures do
is_expected . to have_referable_subject ( merge_request , reply : true )
2018-06-03 13:22:50 +00:00
is_expected . to have_body_text ( previous_assignee . name )
2017-10-09 12:59:10 +00:00
is_expected . to have_body_text ( project_merge_request_path ( project , merge_request ) )
2018-06-03 13:22:50 +00:00
is_expected . to have_body_text ( assignee . name )
2016-03-17 19:03:51 +00:00
end
2017-10-09 12:59:10 +00:00
end
2017-12-28 17:25:02 +00:00
context 'when sent with a reason' do
2019-04-07 18:35:16 +00:00
subject { described_class . reassigned_merge_request_email ( recipient . id , merge_request . id , [ previous_assignee . id ] , current_user . id , NotificationReason :: ASSIGNED ) }
2017-12-28 17:25:02 +00:00
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2017-12-28 17:25:02 +00:00
it 'includes the reason in a header' do
is_expected . to have_header ( 'X-GitLab-NotificationReason' , NotificationReason :: ASSIGNED )
end
it 'includes the reason in the footer' do
text = EmailsHelper . instance_method ( :notification_reason_text ) . bind ( self ) . call ( NotificationReason :: ASSIGNED )
is_expected . to have_body_text ( text )
2019-04-07 18:35:16 +00:00
new_subject = described_class . reassigned_merge_request_email ( recipient . id , merge_request . id , [ previous_assignee . id ] , current_user . id , NotificationReason :: MENTIONED )
2017-12-28 17:25:02 +00:00
text = EmailsHelper . instance_method ( :notification_reason_text ) . bind ( self ) . call ( NotificationReason :: MENTIONED )
expect ( new_subject ) . to have_body_text ( text )
2019-04-07 18:35:16 +00:00
new_subject = described_class . reassigned_merge_request_email ( recipient . id , merge_request . id , [ previous_assignee . id ] , current_user . id , nil )
2017-12-28 17:25:02 +00:00
text = EmailsHelper . instance_method ( :notification_reason_text ) . bind ( self ) . call ( nil )
expect ( new_subject ) . to have_body_text ( text )
end
end
2017-10-09 12:59:10 +00:00
end
2012-05-14 22:03:30 +00:00
2018-07-09 17:49:50 +00:00
describe 'that are new with a description' do
2019-04-07 18:35:16 +00:00
subject { described_class . new_merge_request_email ( merge_request . assignee_ids . first , merge_request . id ) }
2018-07-09 17:49:50 +00:00
it_behaves_like 'it should show Gmail Actions View Merge request link'
it_behaves_like " an unsubscribeable thread "
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2018-07-09 17:49:50 +00:00
it 'contains the description' do
is_expected . to have_body_text ( merge_request . description )
end
end
2017-10-09 12:59:10 +00:00
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 ) }
2014-02-17 17:49:42 +00:00
2017-10-09 12:59:10 +00:00
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-03-24 14:11:35 +00:00
end
2020-05-13 18:08:47 +00:00
2017-10-09 12:59:10 +00:00
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-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2014-03-24 14:11:35 +00:00
2017-10-09 12:59:10 +00:00
it 'is sent as the author' do
2021-03-19 12:09:03 +00:00
expect_sender ( current_user )
2017-10-09 12:59:10 +00:00
end
2016-03-01 16:33:13 +00:00
2017-10-09 12:59:10 +00:00
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
2016-03-01 16:33:13 +00:00
2018-04-08 05:37:32 +00:00
shared_examples 'a push to an existing merge request' do
2018-04-03 11:51:09 +00:00
let ( :push_user ) { create ( :user ) }
subject do
2018-04-08 05:37:32 +00:00
described_class . push_to_merge_request_email ( recipient . id , merge_request . id , push_user . id , new_commits : merge_request . commits , existing_commits : existing_commits )
2018-04-03 11:51:09 +00:00
end
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-13 18:08:47 +00:00
2018-04-03 11:51:09 +00:00
it_behaves_like 'it should show Gmail Actions View Merge request link'
it_behaves_like 'an unsubscribeable thread'
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2018-04-03 11:51:09 +00:00
it 'is sent as the push user' do
2021-03-19 12:09:03 +00:00
expect_sender ( push_user )
2018-04-03 11:51:09 +00:00
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-03 09:08:53 +00:00
is_expected . to have_link ( merge_request . to_reference , href : project_merge_request_url ( merge_request . target_project , merge_request ) )
2018-04-03 11:51:09 +00:00
end
end
end
2018-04-08 05:37:32 +00:00
describe 'that have new commits' do
let ( :existing_commits ) { [ ] }
it_behaves_like 'a push to an existing merge request'
end
describe 'that have new commits on top of an existing one' do
let ( :existing_commits ) { [ merge_request . commits . first ] }
it_behaves_like 'a push to an existing merge request'
end
2017-10-09 12:59:10 +00:00
end
2014-07-08 11:56:37 +00:00
2019-08-21 19:23:27 +00:00
describe '#mail_thread' do
2020-02-18 15:08:51 +00:00
let_it_be ( :mail_thread_note ) { create ( :note ) }
2019-08-21 19:23:27 +00:00
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 )
2020-10-22 12:08:41 +00:00
mailer . instance_variable_set ( :@target_url , " https://some.link " )
2019-08-21 19:23:27 +00:00
mailer
end
context 'the model has no namespace' do
class TopLevelThing
include Referable
include Noteable
def to_reference ( * _args )
'tlt-ref'
end
def id
'tlt-id'
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
module Namespaced
class Thing
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
2017-12-08 21:45:57 +00:00
context 'for issue notes' do
let ( :host ) { Gitlab . config . gitlab . host }
context 'in discussion' do
2020-02-18 15:08:51 +00:00
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 ) }
2017-12-08 21:45:57 +00:00
subject { described_class . note_issue_email ( recipient . id , third_note . id ) }
2019-06-24 09:20:10 +00:00
it_behaves_like 'an email sent to a user'
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2017-12-08 21:45:57 +00:00
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
expect ( subject . header [ 'References' ] . message_ids ) . to include ( " issue_ #{ first_note . noteable . id } @ #{ host } " ,
" note_ #{ first_note . id } @ #{ host } " ,
" note_ #{ second_note . id } @ #{ host } " )
end
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-02-18 15:08:51 +00:00
let_it_be ( :note ) { create ( :note_on_issue , project : project ) }
2017-12-08 21:45:57 +00:00
subject { described_class . note_issue_email ( recipient . id , note . id ) }
2019-06-24 09:20:10 +00:00
it_behaves_like 'an email sent to a user'
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2017-12-08 21:45:57 +00:00
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
end
end
2017-10-09 12:59:10 +00:00
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 ) }
2014-03-24 14:11:35 +00:00
2020-01-23 12:08:38 +00:00
subject { described_class . note_snippet_email ( project_snippet_note . author_id , project_snippet_note . id ) }
2014-03-24 14:11:35 +00:00
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2017-10-09 12:59:10 +00:00
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { project_snippet }
end
2020-05-13 18:08:47 +00:00
2017-10-09 12:59:10 +00:00
it_behaves_like 'a user cannot unsubscribe through footer link'
2014-03-24 14:11:35 +00:00
2020-01-23 12:08:38 +00:00
it 'has the correct subject' do
2019-07-01 08:23:11 +00:00
is_expected . to have_referable_subject ( project_snippet , reply : true )
2020-01-23 12:08:38 +00:00
end
it 'has the correct body' do
2018-06-03 13:22:50 +00:00
is_expected . to have_body_text project_snippet_note . note
2012-05-14 22:03:30 +00:00
end
2020-01-23 12:08:38 +00:00
it 'links to the project snippet' do
target_url = project_snippet_url ( project ,
project_snippet_note . noteable ,
{ anchor : " note_ #{ project_snippet_note . id } " } )
is_expected . to have_body_text target_url
end
2012-05-14 18:05:32 +00:00
end
2020-05-12 00:10:11 +00:00
describe 'for design notes' do
let_it_be ( :design ) { create ( :design , :with_file ) }
let_it_be ( :recipient ) { create ( :user ) }
let_it_be ( :note ) do
create ( :diff_note_on_design ,
noteable : design ,
note : " Hello #{ recipient . to_reference } " )
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
2013-06-22 07:56:51 +00:00
describe 'project was moved' do
2019-06-24 09:20:10 +00:00
let ( :recipient ) { user }
2019-12-17 18:07:48 +00:00
2017-05-01 15:13:33 +00:00
subject { described_class . project_was_moved_email ( project . id , user . id , " gitlab/gitlab " ) }
2013-06-22 07:56:51 +00:00
2019-02-15 17:56:13 +00:00
it_behaves_like 'an email sent to a user'
2014-02-17 17:49:42 +00:00
it_behaves_like 'an email sent from GitLab'
2015-11-25 12:27:31 +00:00
it_behaves_like 'it should not have Gmail Actions links'
2016-01-09 18:32:03 +00:00
it_behaves_like " a user cannot unsubscribe through footer link "
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2014-02-17 17:49:42 +00:00
2017-03-21 22:49:45 +00:00
it 'has the correct subject and body' do
is_expected . to have_subject ( " #{ project . name } | Project was moved " )
2018-06-03 13:22:50 +00:00
is_expected . to have_body_text project . full_name
2017-03-21 22:49:45 +00:00
is_expected . to have_body_text ( project . ssh_url_to_repo )
2013-06-22 07:56:51 +00:00
end
end
2016-04-18 16:53:32 +00:00
describe 'project access requested' do
2018-02-19 17:47:08 +00:00
let ( :project ) do
2019-10-16 12:06:32 +00:00
create ( :project , :public ) do | project |
2018-07-11 14:36:08 +00:00
project . add_maintainer ( project . owner )
2016-06-20 10:10:37 +00:00
end
2016-04-18 16:53:32 +00:00
end
2018-02-19 17:47:08 +00:00
let ( :project_member ) do
project . request_access ( user )
project . requesters . find_by ( user_id : user . id )
end
2019-12-17 18:07:48 +00:00
2019-07-24 03:36:07 +00:00
subject { described_class . member_access_requested_email ( 'project' , project_member . id , recipient . id ) }
2016-04-18 16:53:32 +00:00
2018-02-19 17:47:08 +00:00
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-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2016-06-20 10:10:37 +00:00
2018-02-19 17:47:08 +00:00
it 'contains all the useful information' do
to_emails = subject . header [ :to ] . addrs . map ( & :address )
expect ( to_emails ) . to eq ( [ recipient . notification_email ] )
2016-06-20 10:10:37 +00:00
2018-03-05 14:15:26 +00:00
is_expected . to have_subject " Request to join the #{ project . full_name } project "
2018-06-03 13:22:50 +00:00
is_expected . to have_body_text project . full_name
2018-02-19 17:47:08 +00:00
is_expected . to have_body_text project_project_members_url ( project )
is_expected . to have_body_text project_member . human_access
2016-06-02 16:05:06 +00:00
end
2016-04-18 16:53:32 +00:00
end
describe 'project access denied' do
2019-10-16 12:06:32 +00:00
let ( :project ) { create ( :project , :public ) }
2016-04-18 16:53:32 +00:00
let ( :project_member ) do
project . request_access ( user )
2016-06-27 14:20:57 +00:00
project . requesters . find_by ( user_id : user . id )
2016-04-18 16:53:32 +00:00
end
2019-12-17 18:07:48 +00:00
2017-05-01 15:13:33 +00:00
subject { described_class . member_access_denied_email ( 'project' , project . id , user . id ) }
2016-04-18 16:53:32 +00:00
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-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2016-04-18 16:53:32 +00:00
2016-06-02 16:05:06 +00:00
it 'contains all the useful information' do
2018-03-05 14:15:26 +00:00
is_expected . to have_subject " Access to the #{ project . full_name } project was denied "
2018-06-03 13:22:50 +00:00
is_expected . to have_body_text project . full_name
2017-03-14 12:56:07 +00:00
is_expected . to have_body_text project . web_url
2016-06-02 16:05:06 +00:00
end
2016-04-18 16:53:32 +00:00
end
2012-08-26 21:13:03 +00:00
describe 'project access changed' do
2017-03-16 09:56:39 +00:00
let ( :owner ) { create ( :user , name : " Chang O'Keefe " ) }
2019-10-16 12:06:32 +00:00
let ( :project ) { create ( :project , :public , namespace : owner . namespace ) }
2015-06-22 20:00:54 +00:00
let ( :project_member ) { create ( :project_member , project : project , user : user ) }
2019-12-17 18:07:48 +00:00
2017-05-01 15:13:33 +00:00
subject { described_class . member_access_granted_email ( 'project' , project_member . id ) }
2014-02-17 17:49:42 +00:00
it_behaves_like 'an email sent from GitLab'
2015-11-25 12:27:31 +00:00
it_behaves_like 'it should not have Gmail Actions links'
2016-01-09 18:32:03 +00:00
it_behaves_like " a user cannot unsubscribe through footer link "
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2014-02-17 17:49:42 +00:00
2016-06-02 16:05:06 +00:00
it 'contains all the useful information' do
2018-03-05 14:15:26 +00:00
is_expected . to have_subject " Access to the #{ project . full_name } project was granted "
2018-06-03 13:22:50 +00:00
is_expected . to have_body_text project . full_name
2017-03-14 12:56:07 +00:00
is_expected . to have_body_text project . web_url
is_expected . to have_body_text project_member . human_access
2019-04-29 11:22:25 +00:00
is_expected . to have_body_text 'leave the project'
is_expected . to have_body_text project_url ( project , leave : 1 )
2016-06-02 16:05:06 +00:00
end
2016-06-02 14:14:02 +00:00
end
2015-11-25 12:27:31 +00:00
2020-08-25 18:10:49 +00:00
def invite_to_project ( project , inviter : , user : nil )
2016-09-16 15:54:21 +00:00
create (
:project_member ,
:developer ,
project : project ,
invite_token : '1234' ,
invite_email : 'toto@example.com' ,
2020-08-25 18:10:49 +00:00
user : user ,
2016-09-16 15:54:21 +00:00
created_by : inviter
2016-08-02 18:37:22 +00:00
)
2016-06-02 14:14:02 +00:00
end
describe 'project invitation' do
2018-07-11 14:36:08 +00:00
let ( :maintainer ) { create ( :user ) . tap { | u | project . add_maintainer ( u ) } }
2020-08-25 18:10:49 +00:00
let ( :project_member ) { invite_to_project ( project , inviter : inviter ) }
let ( :inviter ) { maintainer }
2016-06-02 14:14:02 +00:00
2017-05-01 15:13:33 +00:00
subject { described_class . member_invited_email ( 'project' , project_member . id , project_member . invite_token ) }
2016-06-02 14:14:02 +00:00
2020-10-20 12:08:54 +00:00
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_behaves_like 'does not render a manage notifications link'
2020-08-25 18:10:49 +00:00
2021-06-15 15:10:04 +00:00
context 'when there is an inviter' , :aggregate_failures do
2020-08-25 18:10:49 +00:00
it 'contains all the useful information' do
2020-10-20 12:08:54 +00:00
is_expected . to have_subject " #{ inviter . name } invited you to join GitLab "
2020-08-25 18:10:49 +00:00
is_expected . to have_body_text project . full_name
2020-10-20 12:08:54 +00:00
is_expected . to have_body_text project_member . human_access . downcase
2020-08-25 18:10:49 +00:00
is_expected . to have_body_text project_member . invite_token
2021-02-03 15:09:24 +00:00
is_expected . to have_link ( 'Join now' , href : invite_url ( project_member . invite_token , invite_type : Members :: InviteEmailExperiment :: INVITE_TYPE ) )
end
2021-06-15 15:10:04 +00:00
it 'contains invite link for the group activity' do
stub_experiments ( 'members/invite_email' : :activity )
2021-02-03 15:09:24 +00:00
2021-06-15 15:10:04 +00:00
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-02-03 15:09:24 +00:00
is_expected . not_to have_content ( 'You are invited!' )
2021-02-12 21:09:01 +00:00
is_expected . not_to have_body_text 'What is a GitLab'
end
2021-02-03 15:09:24 +00:00
it 'has invite link for the control group' do
stub_experiments ( 'members/invite_email' : :control )
is_expected . to have_content ( 'You are invited!' )
2020-08-25 18:10:49 +00:00
end
end
2021-06-15 15:10:04 +00:00
context 'when there is no inviter' , :aggregate_failures do
2020-10-20 12:08:54 +00:00
let ( :inviter ) { nil }
2020-08-25 18:10:49 +00:00
2020-10-20 12:08:54 +00:00
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
2020-08-25 18:10:49 +00:00
end
2016-06-02 16:05:06 +00:00
end
2021-05-26 12:10:41 +00:00
2021-07-28 06:09:29 +00:00
context 'when mailgun events are enabled' do
2021-05-26 12:10:41 +00:00
before do
2021-07-28 06:09:29 +00:00
stub_application_setting ( mailgun_events_enabled : true )
2021-05-26 12:10:41 +00:00
end
it 'has custom headers' do
aggregate_failures do
2021-07-28 06:09:29 +00:00
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-05-26 12:10:41 +00:00
end
end
end
2016-06-02 14:14:02 +00:00
end
describe 'project invitation accepted' do
2016-09-16 15:54:21 +00:00
let ( :invited_user ) { create ( :user , name : 'invited user' ) }
2019-07-24 03:36:07 +00:00
let ( :recipient ) { create ( :user ) . tap { | u | project . add_maintainer ( u ) } }
2016-06-02 14:14:02 +00:00
let ( :project_member ) do
2019-07-24 03:36:07 +00:00
invitee = invite_to_project ( project , inviter : recipient )
2016-06-02 14:14:02 +00:00
invitee . accept_invite! ( invited_user )
invitee
2012-08-26 21:13:03 +00:00
end
2015-11-25 12:27:31 +00:00
2017-05-01 15:13:33 +00:00
subject { described_class . member_invite_accepted_email ( 'project' , project_member . id ) }
2016-06-02 14:14:02 +00:00
it_behaves_like 'an email sent from GitLab'
2019-07-24 03:36:07 +00:00
it_behaves_like 'an email sent to a user'
2016-06-02 14:14:02 +00:00
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like " a user cannot unsubscribe through footer link "
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2016-06-02 14:14:02 +00:00
2016-06-02 16:05:06 +00:00
it 'contains all the useful information' do
is_expected . to have_subject 'Invitation accepted'
2018-06-03 13:22:50 +00:00
is_expected . to have_body_text project . full_name
2017-03-14 12:56:07 +00:00
is_expected . to have_body_text project . web_url
is_expected . to have_body_text project_member . invite_email
2018-06-03 13:17:36 +00:00
is_expected . to have_body_text invited_user . name
2016-06-02 16:05:06 +00:00
end
2016-06-02 14:14:02 +00:00
end
describe 'project invitation declined' do
2019-07-24 03:36:07 +00:00
let ( :recipient ) { create ( :user ) . tap { | u | project . add_maintainer ( u ) } }
2016-06-02 14:14:02 +00:00
let ( :project_member ) do
2019-07-24 03:36:07 +00:00
invitee = invite_to_project ( project , inviter : recipient )
2016-06-02 14:14:02 +00:00
invitee . decline_invite!
invitee
2012-08-26 21:13:03 +00:00
end
2016-06-02 14:14:02 +00:00
2019-07-24 03:36:07 +00:00
subject { described_class . member_invite_declined_email ( 'Project' , project . id , project_member . invite_email , recipient . id ) }
2016-06-02 14:14:02 +00:00
it_behaves_like 'an email sent from GitLab'
2019-07-24 03:36:07 +00:00
it_behaves_like 'an email sent to a user'
2016-06-02 14:14:02 +00:00
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like " a user cannot unsubscribe through footer link "
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2016-06-02 14:14:02 +00:00
2016-06-02 16:05:06 +00:00
it 'contains all the useful information' do
is_expected . to have_subject 'Invitation declined'
2018-06-03 13:22:50 +00:00
is_expected . to have_body_text project . full_name
2017-03-14 12:56:07 +00:00
is_expected . to have_body_text project . web_url
is_expected . to have_body_text project_member . invite_email
2016-06-02 16:05:06 +00:00
end
2012-08-26 21:13:03 +00:00
end
2012-05-14 22:03:30 +00:00
context 'items that are noteable, the email for a note' do
2012-11-06 03:31:55 +00:00
let ( :note_author ) { create ( :user , name : 'author_name' ) }
let ( :note ) { create ( :note , project : project , author : note_author ) }
2012-05-14 22:03:30 +00:00
2017-08-10 22:31:42 +00:00
before do
2016-08-23 05:36:30 +00:00
allow ( Note ) . to receive ( :find ) . with ( note . id ) . and_return ( note )
2012-05-15 22:48:00 +00:00
end
2012-05-14 22:03:30 +00:00
describe 'on a commit' do
2015-04-21 13:13:40 +00:00
let ( :commit ) { project . commit }
2013-01-15 14:36:35 +00:00
2017-06-14 18:18:56 +00:00
before do
allow ( note ) . to receive ( :noteable ) . and_return ( commit )
end
2012-05-14 22:03:30 +00:00
2017-05-01 15:13:33 +00:00
subject { described_class . note_commit_email ( recipient . id , note . id ) }
2012-05-14 22:03:30 +00:00
it_behaves_like 'a note email'
2016-03-17 19:03:51 +00:00
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { commit }
end
2020-05-13 18:08:47 +00:00
2015-11-25 12:59:03 +00:00
it_behaves_like 'it should show Gmail Actions View Commit link'
2016-03-17 19:03:51 +00:00
it_behaves_like 'a user cannot unsubscribe through footer link'
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2012-05-14 22:03:30 +00:00
2017-03-21 22:49:45 +00:00
it 'has the correct subject and body' do
aggregate_failures do
2019-07-01 08:23:11 +00:00
is_expected . to have_subject ( " Re: #{ project . name } | #{ commit . title } ( #{ commit . short_id } ) " )
2017-03-21 22:49:45 +00:00
is_expected . to have_body_text ( commit . short_id )
end
2012-05-14 22:03:30 +00:00
end
end
describe 'on a merge request' do
2017-06-29 17:06:35 +00:00
let ( :note_on_merge_request_path ) { project_merge_request_path ( project , merge_request , anchor : " note_ #{ note . id } " ) }
2017-06-14 18:18:56 +00:00
before do
allow ( note ) . to receive ( :noteable ) . and_return ( merge_request )
end
2012-05-14 22:03:30 +00:00
2017-05-01 15:13:33 +00:00
subject { described_class . note_merge_request_email ( recipient . id , note . id ) }
2016-11-23 16:25:31 +00:00
2012-05-14 22:03:30 +00:00
it_behaves_like 'a note email'
2016-03-17 19:03:51 +00:00
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { merge_request }
end
2020-05-13 18:08:47 +00:00
2015-11-25 12:59:03 +00:00
it_behaves_like 'it should show Gmail Actions View Merge request link'
2015-12-09 10:59:25 +00:00
it_behaves_like 'an unsubscribeable thread'
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2012-05-14 22:03:30 +00:00
2017-03-21 22:49:45 +00:00
it 'has the correct subject and body' do
aggregate_failures do
2019-07-01 08:23:11 +00:00
is_expected . to have_referable_subject ( merge_request , reply : true )
2017-03-21 22:49:45 +00:00
is_expected . to have_body_text note_on_merge_request_path
end
2012-05-14 22:03:30 +00:00
end
end
describe 'on an issue' do
2017-06-29 17:06:35 +00:00
let ( :note_on_issue_path ) { project_issue_path ( project , issue , anchor : " note_ #{ note . id } " ) }
2017-06-14 18:18:56 +00:00
before do
allow ( note ) . to receive ( :noteable ) . and_return ( issue )
end
2012-05-15 22:50:36 +00:00
2017-05-01 15:13:33 +00:00
subject { described_class . note_issue_email ( recipient . id , note . id ) }
2012-05-14 22:03:30 +00:00
it_behaves_like 'a note email'
2016-03-17 19:03:51 +00:00
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { issue }
end
2020-05-13 18:08:47 +00:00
2015-11-25 12:59:03 +00:00
it_behaves_like 'it should show Gmail Actions View Issue link'
2015-12-09 10:59:25 +00:00
it_behaves_like 'an unsubscribeable thread'
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2012-05-14 22:03:30 +00:00
2017-03-21 22:49:45 +00:00
it 'has the correct subject and body' do
aggregate_failures do
2019-07-01 08:23:11 +00:00
is_expected . to have_referable_subject ( issue , reply : true )
2017-03-21 22:49:45 +00:00
is_expected . to have_body_text ( note_on_issue_path )
end
2012-05-14 22:03:30 +00:00
end
end
2012-05-14 18:05:32 +00:00
end
Change diff highlight/truncate for reusability
Previously the `truncated_diff_lines` method for outputting a discussion diff took in already highlighted lines, which meant it wasn't reuseable for truncating ANY lines. In the way it was used, it also meant that for any email truncation, the whole diff was being highlighted before being truncated, meaning wasted time highlighting lines that wouldn't even be used (granted, they were being memoized, so perhaps this wasn't that great of an issue). I refactored truncation away from highlighting, in order to truncate formatted diffs for text templates in email, using `>`s to designate each line, but otherwise retaining the parsing already done to create `diff_lines`.
Additionally, while notes on merge requests or commits had already been tested, there was no existing test for notes on a diff on an MR or commit. Added mailer tests for such, and a unit test for truncating diff lines.
2016-08-25 16:38:07 +00:00
2017-03-17 19:25:52 +00:00
context 'items that are noteable, the email for a discussion note' do
Change diff highlight/truncate for reusability
Previously the `truncated_diff_lines` method for outputting a discussion diff took in already highlighted lines, which meant it wasn't reuseable for truncating ANY lines. In the way it was used, it also meant that for any email truncation, the whole diff was being highlighted before being truncated, meaning wasted time highlighting lines that wouldn't even be used (granted, they were being memoized, so perhaps this wasn't that great of an issue). I refactored truncation away from highlighting, in order to truncate formatted diffs for text templates in email, using `>`s to designate each line, but otherwise retaining the parsing already done to create `diff_lines`.
Additionally, while notes on merge requests or commits had already been tested, there was no existing test for notes on a diff on an MR or commit. Added mailer tests for such, and a unit test for truncating diff lines.
2016-08-25 16:38:07 +00:00
let ( :note_author ) { create ( :user , name : 'author_name' ) }
2017-08-10 22:31:42 +00:00
before do
Change diff highlight/truncate for reusability
Previously the `truncated_diff_lines` method for outputting a discussion diff took in already highlighted lines, which meant it wasn't reuseable for truncating ANY lines. In the way it was used, it also meant that for any email truncation, the whole diff was being highlighted before being truncated, meaning wasted time highlighting lines that wouldn't even be used (granted, they were being memoized, so perhaps this wasn't that great of an issue). I refactored truncation away from highlighting, in order to truncate formatted diffs for text templates in email, using `>`s to designate each line, but otherwise retaining the parsing already done to create `diff_lines`.
Additionally, while notes on merge requests or commits had already been tested, there was no existing test for notes on a diff on an MR or commit. Added mailer tests for such, and a unit test for truncating diff lines.
2016-08-25 16:38:07 +00:00
allow ( Note ) . to receive ( :find ) . with ( note . id ) . and_return ( note )
end
2017-03-17 19:25:52 +00:00
shared_examples 'a discussion note email' do | model |
it_behaves_like 'it should have Gmail Actions links'
2017-04-04 22:27:23 +00:00
it 'is sent to the given recipient as the author' do
aggregate_failures do
2021-03-19 12:09:03 +00:00
expect_sender ( note_author )
2017-04-04 22:27:23 +00:00
expect ( subject ) . to deliver_to ( recipient . notification_email )
end
2017-03-17 19:25:52 +00:00
end
it 'contains the message from the note' do
is_expected . to have_body_text note . note
end
it 'contains an introduction' do
2019-04-19 18:10:52 +00:00
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-03-17 19:25:52 +00:00
end
context 'when a comment on an existing discussion' do
2019-11-21 09:06:16 +00:00
let ( :first_note ) { create_note }
let ( :note ) { create ( model , author : note_author , noteable : nil , in_reply_to : first_note ) }
2017-03-17 19:25:52 +00:00
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 }
2019-11-21 09:06:16 +00:00
let ( :note ) { create_note }
def create_note
create ( :discussion_note_on_commit , commit_id : commit . id , project : project , author : note_author )
end
2017-03-17 19:25:52 +00:00
2017-06-14 18:18:56 +00:00
before do
allow ( note ) . to receive ( :noteable ) . and_return ( commit )
end
2017-03-17 19:25:52 +00:00
2017-05-01 15:13:33 +00:00
subject { described_class . note_commit_email ( recipient . id , note . id ) }
2017-03-17 19:25:52 +00:00
it_behaves_like 'a discussion note email' , :discussion_note_on_commit
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { commit }
end
2020-05-13 18:08:47 +00:00
2017-03-17 19:25:52 +00:00
it_behaves_like 'it should show Gmail Actions View Commit link'
it_behaves_like 'a user cannot unsubscribe through footer link'
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2017-03-17 19:25:52 +00:00
it 'has the correct subject' do
2019-07-01 08:23:11 +00:00
is_expected . to have_subject " Re: #{ project . name } | #{ commit . title } ( #{ commit . short_id } ) "
2017-03-17 19:25:52 +00:00
end
it 'contains a link to the commit' do
is_expected . to have_body_text commit . short_id
end
end
describe 'on a merge request' do
2019-11-21 09:06:16 +00:00
let ( :note ) { create_note }
2017-06-29 17:06:35 +00:00
let ( :note_on_merge_request_path ) { project_merge_request_path ( project , merge_request , anchor : " note_ #{ note . id } " ) }
2017-06-14 18:18:56 +00:00
2019-11-21 09:06:16 +00:00
def create_note
create ( :discussion_note_on_merge_request , noteable : merge_request , project : project , author : note_author )
end
2017-06-14 18:18:56 +00:00
before do
allow ( note ) . to receive ( :noteable ) . and_return ( merge_request )
end
2017-03-17 19:25:52 +00:00
2017-05-01 15:13:33 +00:00
subject { described_class . note_merge_request_email ( recipient . id , note . id ) }
2017-03-17 19:25:52 +00:00
it_behaves_like 'a discussion note email' , :discussion_note_on_merge_request
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { merge_request }
end
2020-05-13 18:08:47 +00:00
2017-03-17 19:25:52 +00:00
it_behaves_like 'it should show Gmail Actions View Merge request link'
it_behaves_like 'an unsubscribeable thread'
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2017-03-17 19:25:52 +00:00
it 'has the correct subject' do
2019-07-01 08:23:11 +00:00
is_expected . to have_referable_subject ( merge_request , reply : true )
2017-03-17 19:25:52 +00:00
end
it 'contains a link to the merge request note' do
is_expected . to have_body_text note_on_merge_request_path
end
end
describe 'on an issue' do
2019-11-21 09:06:16 +00:00
let ( :note ) { create_note }
2017-06-29 17:06:35 +00:00
let ( :note_on_issue_path ) { project_issue_path ( project , issue , anchor : " note_ #{ note . id } " ) }
2017-06-14 18:18:56 +00:00
2019-11-21 09:06:16 +00:00
def create_note
create ( :discussion_note_on_issue , noteable : issue , project : project , author : note_author )
end
2017-06-14 18:18:56 +00:00
before do
allow ( note ) . to receive ( :noteable ) . and_return ( issue )
end
2017-03-17 19:25:52 +00:00
2017-05-01 15:13:33 +00:00
subject { described_class . note_issue_email ( recipient . id , note . id ) }
2017-03-17 19:25:52 +00:00
it_behaves_like 'a discussion note email' , :discussion_note_on_issue
it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do
let ( :model ) { issue }
end
2020-05-13 18:08:47 +00:00
2017-03-17 19:25:52 +00:00
it_behaves_like 'it should show Gmail Actions View Issue link'
it_behaves_like 'an unsubscribeable thread'
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2017-03-17 19:25:52 +00:00
it 'has the correct subject' do
2019-07-01 08:23:11 +00:00
is_expected . to have_referable_subject ( issue , reply : true )
2017-03-17 19:25:52 +00:00
end
it 'contains a link to the issue note' do
is_expected . to have_body_text note_on_issue_path
end
end
end
context 'items that are noteable, the email for a diff discussion note' do
let ( :note_author ) { create ( :user , name : 'author_name' ) }
2017-08-10 22:31:42 +00:00
before do
2017-03-17 19:25:52 +00:00
allow ( Note ) . to receive ( :find ) . with ( note . id ) . and_return ( note )
end
2019-01-16 12:09:29 +00:00
shared_examples 'an email for a note on a diff discussion' do | model |
2017-03-31 21:52:38 +00:00
let ( :note ) { create ( model , author : note_author ) }
Change diff highlight/truncate for reusability
Previously the `truncated_diff_lines` method for outputting a discussion diff took in already highlighted lines, which meant it wasn't reuseable for truncating ANY lines. In the way it was used, it also meant that for any email truncation, the whole diff was being highlighted before being truncated, meaning wasted time highlighting lines that wouldn't even be used (granted, they were being memoized, so perhaps this wasn't that great of an issue). I refactored truncation away from highlighting, in order to truncate formatted diffs for text templates in email, using `>`s to designate each line, but otherwise retaining the parsing already done to create `diff_lines`.
Additionally, while notes on merge requests or commits had already been tested, there was no existing test for notes on a diff on an MR or commit. Added mailer tests for such, and a unit test for truncating diff lines.
2016-08-25 16:38:07 +00:00
2018-12-20 14:26:07 +00:00
context 'when note is not on text' do
2017-11-09 19:59:39 +00:00
before do
2020-07-16 12:09:22 +00:00
allow ( note . discussion ) . to receive ( :on_text? ) . and_return ( false )
2017-11-09 19:59:39 +00:00
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-03-14 12:56:07 +00:00
is_expected . to have_body_text '<span class="p">}</span></span>'
Change diff highlight/truncate for reusability
Previously the `truncated_diff_lines` method for outputting a discussion diff took in already highlighted lines, which meant it wasn't reuseable for truncating ANY lines. In the way it was used, it also meant that for any email truncation, the whole diff was being highlighted before being truncated, meaning wasted time highlighting lines that wouldn't even be used (granted, they were being memoized, so perhaps this wasn't that great of an issue). I refactored truncation away from highlighting, in order to truncate formatted diffs for text templates in email, using `>`s to designate each line, but otherwise retaining the parsing already done to create `diff_lines`.
Additionally, while notes on merge requests or commits had already been tested, there was no existing test for notes on a diff on an MR or commit. Added mailer tests for such, and a unit test for truncating diff lines.
2016-08-25 16:38:07 +00:00
end
it 'contains a link to the diff file' do
2017-03-14 12:56:07 +00:00
is_expected . to have_body_text note . diff_file . file_path
Change diff highlight/truncate for reusability
Previously the `truncated_diff_lines` method for outputting a discussion diff took in already highlighted lines, which meant it wasn't reuseable for truncating ANY lines. In the way it was used, it also meant that for any email truncation, the whole diff was being highlighted before being truncated, meaning wasted time highlighting lines that wouldn't even be used (granted, they were being memoized, so perhaps this wasn't that great of an issue). I refactored truncation away from highlighting, in order to truncate formatted diffs for text templates in email, using `>`s to designate each line, but otherwise retaining the parsing already done to create `diff_lines`.
Additionally, while notes on merge requests or commits had already been tested, there was no existing test for notes on a diff on an MR or commit. Added mailer tests for such, and a unit test for truncating diff lines.
2016-08-25 16:38:07 +00:00
end
it_behaves_like 'it should have Gmail Actions links'
2017-03-21 22:49:45 +00:00
it 'is sent to the given recipient as the author' do
aggregate_failures do
2021-03-19 12:09:03 +00:00
expect_sender ( note_author )
2017-03-21 22:49:45 +00:00
expect ( subject ) . to deliver_to ( recipient . notification_email )
end
Change diff highlight/truncate for reusability
Previously the `truncated_diff_lines` method for outputting a discussion diff took in already highlighted lines, which meant it wasn't reuseable for truncating ANY lines. In the way it was used, it also meant that for any email truncation, the whole diff was being highlighted before being truncated, meaning wasted time highlighting lines that wouldn't even be used (granted, they were being memoized, so perhaps this wasn't that great of an issue). I refactored truncation away from highlighting, in order to truncate formatted diffs for text templates in email, using `>`s to designate each line, but otherwise retaining the parsing already done to create `diff_lines`.
Additionally, while notes on merge requests or commits had already been tested, there was no existing test for notes on a diff on an MR or commit. Added mailer tests for such, and a unit test for truncating diff lines.
2016-08-25 16:38:07 +00:00
end
it 'contains the message from the note' do
2018-06-03 13:17:36 +00:00
is_expected . to have_body_text note . note
Change diff highlight/truncate for reusability
Previously the `truncated_diff_lines` method for outputting a discussion diff took in already highlighted lines, which meant it wasn't reuseable for truncating ANY lines. In the way it was used, it also meant that for any email truncation, the whole diff was being highlighted before being truncated, meaning wasted time highlighting lines that wouldn't even be used (granted, they were being memoized, so perhaps this wasn't that great of an issue). I refactored truncation away from highlighting, in order to truncate formatted diffs for text templates in email, using `>`s to designate each line, but otherwise retaining the parsing already done to create `diff_lines`.
Additionally, while notes on merge requests or commits had already been tested, there was no existing test for notes on a diff on an MR or commit. Added mailer tests for such, and a unit test for truncating diff lines.
2016-08-25 16:38:07 +00:00
end
2017-03-17 19:25:52 +00:00
it 'contains an introduction' do
is_expected . to have_body_text 'started a new discussion on'
Change diff highlight/truncate for reusability
Previously the `truncated_diff_lines` method for outputting a discussion diff took in already highlighted lines, which meant it wasn't reuseable for truncating ANY lines. In the way it was used, it also meant that for any email truncation, the whole diff was being highlighted before being truncated, meaning wasted time highlighting lines that wouldn't even be used (granted, they were being memoized, so perhaps this wasn't that great of an issue). I refactored truncation away from highlighting, in order to truncate formatted diffs for text templates in email, using `>`s to designate each line, but otherwise retaining the parsing already done to create `diff_lines`.
Additionally, while notes on merge requests or commits had already been tested, there was no existing test for notes on a diff on an MR or commit. Added mailer tests for such, and a unit test for truncating diff lines.
2016-08-25 16:38:07 +00:00
end
2017-03-17 19:25:52 +00:00
context 'when a comment on an existing discussion' do
2019-11-21 09:06:16 +00:00
let ( :first_note ) { create ( model ) }
let ( :note ) { create ( model , author : note_author , noteable : nil , in_reply_to : first_note ) }
Change diff highlight/truncate for reusability
Previously the `truncated_diff_lines` method for outputting a discussion diff took in already highlighted lines, which meant it wasn't reuseable for truncating ANY lines. In the way it was used, it also meant that for any email truncation, the whole diff was being highlighted before being truncated, meaning wasted time highlighting lines that wouldn't even be used (granted, they were being memoized, so perhaps this wasn't that great of an issue). I refactored truncation away from highlighting, in order to truncate formatted diffs for text templates in email, using `>`s to designate each line, but otherwise retaining the parsing already done to create `diff_lines`.
Additionally, while notes on merge requests or commits had already been tested, there was no existing test for notes on a diff on an MR or commit. Added mailer tests for such, and a unit test for truncating diff lines.
2016-08-25 16:38:07 +00:00
2017-03-17 19:25:52 +00:00
it 'contains an introduction' do
is_expected . to have_body_text 'commented on a discussion on'
Change diff highlight/truncate for reusability
Previously the `truncated_diff_lines` method for outputting a discussion diff took in already highlighted lines, which meant it wasn't reuseable for truncating ANY lines. In the way it was used, it also meant that for any email truncation, the whole diff was being highlighted before being truncated, meaning wasted time highlighting lines that wouldn't even be used (granted, they were being memoized, so perhaps this wasn't that great of an issue). I refactored truncation away from highlighting, in order to truncate formatted diffs for text templates in email, using `>`s to designate each line, but otherwise retaining the parsing already done to create `diff_lines`.
Additionally, while notes on merge requests or commits had already been tested, there was no existing test for notes on a diff on an MR or commit. Added mailer tests for such, and a unit test for truncating diff lines.
2016-08-25 16:38:07 +00:00
end
end
end
describe 'on a commit' do
let ( :commit ) { project . commit }
let ( :note ) { create ( :diff_note_on_commit ) }
2017-05-01 15:13:33 +00:00
subject { described_class . note_commit_email ( recipient . id , note . id ) }
Change diff highlight/truncate for reusability
Previously the `truncated_diff_lines` method for outputting a discussion diff took in already highlighted lines, which meant it wasn't reuseable for truncating ANY lines. In the way it was used, it also meant that for any email truncation, the whole diff was being highlighted before being truncated, meaning wasted time highlighting lines that wouldn't even be used (granted, they were being memoized, so perhaps this wasn't that great of an issue). I refactored truncation away from highlighting, in order to truncate formatted diffs for text templates in email, using `>`s to designate each line, but otherwise retaining the parsing already done to create `diff_lines`.
Additionally, while notes on merge requests or commits had already been tested, there was no existing test for notes on a diff on an MR or commit. Added mailer tests for such, and a unit test for truncating diff lines.
2016-08-25 16:38:07 +00:00
2017-03-17 19:25:52 +00:00
it_behaves_like 'an email for a note on a diff discussion' , :diff_note_on_commit
Change diff highlight/truncate for reusability
Previously the `truncated_diff_lines` method for outputting a discussion diff took in already highlighted lines, which meant it wasn't reuseable for truncating ANY lines. In the way it was used, it also meant that for any email truncation, the whole diff was being highlighted before being truncated, meaning wasted time highlighting lines that wouldn't even be used (granted, they were being memoized, so perhaps this wasn't that great of an issue). I refactored truncation away from highlighting, in order to truncate formatted diffs for text templates in email, using `>`s to designate each line, but otherwise retaining the parsing already done to create `diff_lines`.
Additionally, while notes on merge requests or commits had already been tested, there was no existing test for notes on a diff on an MR or commit. Added mailer tests for such, and a unit test for truncating diff lines.
2016-08-25 16:38:07 +00:00
it_behaves_like 'it should show Gmail Actions View Commit link'
it_behaves_like 'a user cannot unsubscribe through footer link'
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
Change diff highlight/truncate for reusability
Previously the `truncated_diff_lines` method for outputting a discussion diff took in already highlighted lines, which meant it wasn't reuseable for truncating ANY lines. In the way it was used, it also meant that for any email truncation, the whole diff was being highlighted before being truncated, meaning wasted time highlighting lines that wouldn't even be used (granted, they were being memoized, so perhaps this wasn't that great of an issue). I refactored truncation away from highlighting, in order to truncate formatted diffs for text templates in email, using `>`s to designate each line, but otherwise retaining the parsing already done to create `diff_lines`.
Additionally, while notes on merge requests or commits had already been tested, there was no existing test for notes on a diff on an MR or commit. Added mailer tests for such, and a unit test for truncating diff lines.
2016-08-25 16:38:07 +00:00
end
describe 'on a merge request' do
let ( :note ) { create ( :diff_note_on_merge_request ) }
2017-05-01 15:13:33 +00:00
subject { described_class . note_merge_request_email ( recipient . id , note . id ) }
Change diff highlight/truncate for reusability
Previously the `truncated_diff_lines` method for outputting a discussion diff took in already highlighted lines, which meant it wasn't reuseable for truncating ANY lines. In the way it was used, it also meant that for any email truncation, the whole diff was being highlighted before being truncated, meaning wasted time highlighting lines that wouldn't even be used (granted, they were being memoized, so perhaps this wasn't that great of an issue). I refactored truncation away from highlighting, in order to truncate formatted diffs for text templates in email, using `>`s to designate each line, but otherwise retaining the parsing already done to create `diff_lines`.
Additionally, while notes on merge requests or commits had already been tested, there was no existing test for notes on a diff on an MR or commit. Added mailer tests for such, and a unit test for truncating diff lines.
2016-08-25 16:38:07 +00:00
2017-03-17 19:25:52 +00:00
it_behaves_like 'an email for a note on a diff discussion' , :diff_note_on_merge_request
Change diff highlight/truncate for reusability
Previously the `truncated_diff_lines` method for outputting a discussion diff took in already highlighted lines, which meant it wasn't reuseable for truncating ANY lines. In the way it was used, it also meant that for any email truncation, the whole diff was being highlighted before being truncated, meaning wasted time highlighting lines that wouldn't even be used (granted, they were being memoized, so perhaps this wasn't that great of an issue). I refactored truncation away from highlighting, in order to truncate formatted diffs for text templates in email, using `>`s to designate each line, but otherwise retaining the parsing already done to create `diff_lines`.
Additionally, while notes on merge requests or commits had already been tested, there was no existing test for notes on a diff on an MR or commit. Added mailer tests for such, and a unit test for truncating diff lines.
2016-08-25 16:38:07 +00:00
it_behaves_like 'it should show Gmail Actions View Merge request link'
it_behaves_like 'an unsubscribeable thread'
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
Change diff highlight/truncate for reusability
Previously the `truncated_diff_lines` method for outputting a discussion diff took in already highlighted lines, which meant it wasn't reuseable for truncating ANY lines. In the way it was used, it also meant that for any email truncation, the whole diff was being highlighted before being truncated, meaning wasted time highlighting lines that wouldn't even be used (granted, they were being memoized, so perhaps this wasn't that great of an issue). I refactored truncation away from highlighting, in order to truncate formatted diffs for text templates in email, using `>`s to designate each line, but otherwise retaining the parsing already done to create `diff_lines`.
Additionally, while notes on merge requests or commits had already been tested, there was no existing test for notes on a diff on an MR or commit. Added mailer tests for such, and a unit test for truncating diff lines.
2016-08-25 16:38:07 +00:00
end
end
2020-07-14 15:09:05 +00:00
context 'for service desk issues' do
before do
2020-11-28 00:09:43 +00:00
issue . update! ( external_author : 'service.desk@example.com' )
2021-03-15 15:09:07 +00:00
issue . issue_email_participants . create! ( email : 'service.desk@example.com' )
2020-07-14 15:09:05 +00:00
end
describe 'thank you email' do
subject { described_class . service_desk_thank_you_email ( issue . id ) }
it_behaves_like 'an unsubscribeable thread'
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-03-19 12:09:03 +00:00
expect_sender ( User . support_bot )
2020-07-14 15:09:05 +00:00
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-03-19 12:09:03 +00:00
sender = subject . header [ :from ] . addrs [ 0 ]
expect ( sender . display_name ) . to eq ( 'some custom name' )
expect ( sender . address ) . to eq ( gitlab_sender )
2020-07-14 15:09:05 +00:00
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-03-19 12:09:03 +00:00
expect_sender ( User . support_bot )
2020-07-14 15:09:05 +00:00
end
end
end
describe 'new note email' do
let_it_be ( :first_note ) { create ( :discussion_note_on_issue , note : 'Hello world' ) }
2021-03-15 15:09:07 +00:00
subject { described_class . service_desk_new_note_email ( issue . id , first_note . id , 'service.desk@example.com' ) }
2020-07-14 15:09:05 +00:00
it_behaves_like 'an unsubscribeable thread'
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-03-19 12:09:03 +00:00
expect_sender ( first_note . author )
2020-07-14 15:09:05 +00:00
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
end
end
2012-05-14 18:05:32 +00:00
end
2013-09-12 16:00:32 +00:00
2016-06-02 14:14:02 +00:00
context 'for a group' do
describe 'group access requested' do
2019-10-16 12:06:32 +00:00
let ( :group ) { create ( :group , :public ) }
2016-06-02 14:14:02 +00:00
let ( :group_member ) do
group . request_access ( user )
2016-06-27 14:20:57 +00:00
group . requesters . find_by ( user_id : user . id )
2016-06-02 14:14:02 +00:00
end
2019-12-17 18:07:48 +00:00
2019-07-24 03:36:07 +00:00
subject { described_class . member_access_requested_email ( 'group' , group_member . id , recipient . id ) }
2016-04-18 16:53:32 +00:00
2016-06-02 14:14:02 +00:00
it_behaves_like 'an email sent from GitLab'
2019-07-24 03:36:07 +00:00
it_behaves_like 'an email sent to a user'
2016-06-02 14:14:02 +00:00
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like " a user cannot unsubscribe through footer link "
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2016-04-18 16:53:32 +00:00
2016-06-02 16:05:06 +00:00
it 'contains all the useful information' do
2018-02-19 17:47:08 +00:00
to_emails = subject . header [ :to ] . addrs . map ( & :address )
expect ( to_emails ) . to eq ( [ recipient . notification_email ] )
2016-06-02 16:05:06 +00:00
is_expected . to have_subject " Request to join the #{ group . name } group "
2018-06-03 13:17:36 +00:00
is_expected . to have_body_text group . name
2017-03-14 12:56:07 +00:00
is_expected . to have_body_text group_group_members_url ( group )
is_expected . to have_body_text group_member . human_access
2016-06-02 16:05:06 +00:00
end
2016-04-18 16:53:32 +00:00
end
2016-06-02 14:14:02 +00:00
describe 'group access denied' do
let ( :group_member ) do
group . request_access ( user )
2016-06-27 14:20:57 +00:00
group . requesters . find_by ( user_id : user . id )
2016-06-02 14:14:02 +00:00
end
2020-08-11 03:11:00 +00:00
2019-07-24 03:36:07 +00:00
let ( :recipient ) { user }
2019-12-17 18:07:48 +00:00
2017-05-01 15:13:33 +00:00
subject { described_class . member_access_denied_email ( 'group' , group . id , user . id ) }
2016-04-18 16:53:32 +00:00
2016-06-02 14:14:02 +00:00
it_behaves_like 'an email sent from GitLab'
2019-07-24 03:36:07 +00:00
it_behaves_like 'an email sent to a user'
2016-06-02 14:14:02 +00:00
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like " a user cannot unsubscribe through footer link "
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2016-04-18 16:53:32 +00:00
2016-06-02 16:05:06 +00:00
it 'contains all the useful information' do
is_expected . to have_subject " Access to the #{ group . name } group was denied "
2018-06-03 13:17:36 +00:00
is_expected . to have_body_text group . name
2017-03-14 12:56:07 +00:00
is_expected . to have_body_text group . web_url
2016-06-02 16:05:06 +00:00
end
2016-04-18 16:53:32 +00:00
end
2016-06-02 14:14:02 +00:00
describe 'group access changed' do
let ( :group_member ) { create ( :group_member , group : group , user : user ) }
2019-07-24 03:36:07 +00:00
let ( :recipient ) { user }
2016-04-18 16:53:32 +00:00
2017-05-01 15:13:33 +00:00
subject { described_class . member_access_granted_email ( 'group' , group_member . id ) }
2016-06-02 14:14:02 +00:00
it_behaves_like 'an email sent from GitLab'
2019-07-24 03:36:07 +00:00
it_behaves_like 'an email sent to a user'
2016-06-02 14:14:02 +00:00
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like " a user cannot unsubscribe through footer link "
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2020-08-05 21:09:40 +00:00
it_behaves_like 'it requires a group'
2016-06-02 14:14:02 +00:00
2016-06-02 16:05:06 +00:00
it 'contains all the useful information' do
is_expected . to have_subject " Access to the #{ group . name } group was granted "
2018-06-03 13:17:36 +00:00
is_expected . to have_body_text group . name
2017-03-14 12:56:07 +00:00
is_expected . to have_body_text group . web_url
is_expected . to have_body_text group_member . human_access
2019-04-29 11:22:25 +00:00
is_expected . to have_body_text 'leave the group'
is_expected . to have_body_text group_url ( group , leave : 1 )
2016-06-02 16:05:06 +00:00
end
2016-04-18 16:53:32 +00:00
end
2020-08-25 18:10:49 +00:00
def invite_to_group ( group , inviter : , user : nil )
2016-09-16 15:54:21 +00:00
create (
:group_member ,
:developer ,
group : group ,
invite_token : '1234' ,
invite_email : 'toto@example.com' ,
2020-08-25 18:10:49 +00:00
user : user ,
2016-09-16 15:54:21 +00:00
created_by : inviter
2016-08-02 18:37:22 +00:00
)
2016-04-18 16:53:32 +00:00
end
2020-09-28 09:09:35 +00:00
describe 'invitations' do
2016-06-02 14:14:02 +00:00
let ( :owner ) { create ( :user ) . tap { | u | group . add_user ( u , Gitlab :: Access :: OWNER ) } }
2020-08-25 18:10:49 +00:00
let ( :group_member ) { invite_to_group ( group , inviter : inviter ) }
let ( :inviter ) { owner }
2013-09-12 16:00:32 +00:00
2020-09-28 09:09:35 +00:00
subject { described_class . member_invited_email ( 'Group' , group_member . id , group_member . invite_token ) }
2020-10-20 12:08:54 +00:00
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_behaves_like 'it requires a group'
it_behaves_like 'does not render a manage notifications link'
2020-08-25 18:10:49 +00:00
2020-10-20 12:08:54 +00:00
context 'when there is an inviter' do
2020-08-25 18:10:49 +00:00
it 'contains all the useful information' do
2020-10-20 12:08:54 +00:00
is_expected . to have_subject " #{ group_member . created_by . name } invited you to join GitLab "
2020-08-25 18:10:49 +00:00
is_expected . to have_body_text group . name
2020-10-20 12:08:54 +00:00
is_expected . to have_body_text group_member . human_access . downcase
2020-08-25 18:10:49 +00:00
is_expected . to have_body_text group_member . invite_token
end
end
2020-10-20 12:08:54 +00:00
context 'when there is no inviter' do
let ( :inviter ) { nil }
2020-08-25 18:10:49 +00:00
2020-10-20 12:08:54 +00:00
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-08-25 18:10:49 +00:00
end
2016-06-02 16:05:06 +00:00
end
2013-09-12 16:00:32 +00:00
end
2020-10-05 18:08:51 +00:00
describe 'group invitation reminders' do
let_it_be ( :inviter ) { create ( :user ) . tap { | u | group . add_user ( u , Gitlab :: Access :: OWNER ) } }
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
group_member . update ( created_by : nil )
end
it_behaves_like 'no email is sent'
end
context 'member is a known user' do
before do
group_member . update ( user : create ( :user ) )
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-02 14:14:02 +00:00
describe 'group invitation accepted' do
2016-09-16 15:54:21 +00:00
let ( :invited_user ) { create ( :user , name : 'invited user' ) }
2016-06-02 14:14:02 +00:00
let ( :owner ) { create ( :user ) . tap { | u | group . add_user ( u , Gitlab :: Access :: OWNER ) } }
let ( :group_member ) do
2016-09-16 15:54:21 +00:00
invitee = invite_to_group ( group , inviter : owner )
2016-06-02 14:14:02 +00:00
invitee . accept_invite! ( invited_user )
invitee
end
2017-05-01 15:13:33 +00:00
subject { described_class . member_invite_accepted_email ( 'group' , group_member . id ) }
2016-06-02 14:14:02 +00:00
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-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2020-08-05 21:09:40 +00:00
it_behaves_like 'it requires a group'
2016-06-02 14:14:02 +00:00
2016-06-02 16:05:06 +00:00
it 'contains all the useful information' do
is_expected . to have_subject 'Invitation accepted'
2018-06-03 13:17:36 +00:00
is_expected . to have_body_text group . name
2017-03-14 12:56:07 +00:00
is_expected . to have_body_text group . web_url
is_expected . to have_body_text group_member . invite_email
2018-06-03 13:17:36 +00:00
is_expected . to have_body_text invited_user . name
2016-06-02 16:05:06 +00:00
end
2013-09-12 16:00:32 +00:00
end
2016-06-02 14:14:02 +00:00
describe 'group invitation declined' do
let ( :owner ) { create ( :user ) . tap { | u | group . add_user ( u , Gitlab :: Access :: OWNER ) } }
let ( :group_member ) do
2016-09-16 15:54:21 +00:00
invitee = invite_to_group ( group , inviter : owner )
2016-06-02 14:14:02 +00:00
invitee . decline_invite!
invitee
end
2017-05-01 15:13:33 +00:00
subject { described_class . member_invite_declined_email ( 'group' , group . id , group_member . invite_email , owner . id ) }
2016-06-02 14:14:02 +00:00
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-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2016-06-02 14:14:02 +00:00
2016-06-02 16:05:06 +00:00
it 'contains all the useful information' do
is_expected . to have_subject 'Invitation declined'
2018-06-03 13:17:36 +00:00
is_expected . to have_body_text group . name
2017-03-14 12:56:07 +00:00
is_expected . to have_body_text group . web_url
is_expected . to have_body_text group_member . invite_email
2016-06-02 16:05:06 +00:00
end
2013-09-12 16:00:32 +00:00
end
2021-01-14 18:10:59 +00:00
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-07-12 15:09:19 +00:00
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
2013-09-12 16:00:32 +00:00
end
2013-11-08 16:29:26 +00:00
describe 'confirmation if email changed' do
let ( :example_site_path ) { root_path }
let ( :user ) { create ( :user , email : 'old-email@mail.com' ) }
before do
2016-09-30 09:46:37 +00:00
stub_config_setting ( email_subject_suffix : 'A Nice Suffix' )
2015-12-03 08:33:38 +00:00
perform_enqueued_jobs do
user . email = " new-email@mail.com "
user . save
end
2013-11-08 16:29:26 +00:00
end
subject { ActionMailer :: Base . deliveries . last }
2014-02-17 17:49:42 +00:00
it_behaves_like 'an email sent from GitLab'
2016-01-09 18:32:03 +00:00
it_behaves_like " a user cannot unsubscribe through footer link "
2014-02-17 17:49:42 +00:00
2013-11-08 16:29:26 +00:00
it 'is sent to the new user' do
2015-02-12 18:17:35 +00:00
is_expected . to deliver_to 'new-email@mail.com'
2013-11-08 16:29:26 +00:00
end
2017-03-21 22:49:45 +00:00
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
2013-11-08 16:29:26 +00:00
end
end
2013-12-18 11:30:04 +00:00
2015-03-17 12:55:39 +00:00
describe 'email on push for a created branch' do
let ( :example_site_path ) { root_path }
2017-06-29 17:06:35 +00:00
let ( :tree_path ) { project_tree_path ( project , " empty-branch " ) }
2015-03-17 12:55:39 +00:00
2017-05-01 15:13:33 +00:00
subject { described_class . repository_push_email ( project . id , author_id : user . id , ref : 'refs/heads/empty-branch' , action : :create ) }
2015-03-17 12:55:39 +00:00
2015-11-25 12:27:31 +00:00
it_behaves_like 'it should not have Gmail Actions links'
2016-07-13 23:56:54 +00:00
it_behaves_like 'a user cannot unsubscribe through footer link'
2015-12-19 19:04:40 +00:00
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-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2015-11-25 12:27:31 +00:00
2015-03-17 12:55:39 +00:00
it 'is sent as the author' do
2021-03-19 12:09:03 +00:00
expect_sender ( user )
2015-03-17 12:55:39 +00:00
end
2017-03-21 22:49:45 +00:00
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-03-17 12:55:39 +00:00
end
end
describe 'email on push for a created tag' do
let ( :example_site_path ) { root_path }
2017-06-29 17:06:35 +00:00
let ( :tree_path ) { project_tree_path ( project , " v1.0 " ) }
2015-03-17 12:55:39 +00:00
2017-05-01 15:13:33 +00:00
subject { described_class . repository_push_email ( project . id , author_id : user . id , ref : 'refs/tags/v1.0' , action : :create ) }
2015-03-17 12:55:39 +00:00
2015-11-25 12:27:31 +00:00
it_behaves_like 'it should not have Gmail Actions links'
2016-01-09 18:32:03 +00:00
it_behaves_like " a user cannot unsubscribe through footer link "
2015-12-19 19:04:40 +00:00
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-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2015-11-25 12:27:31 +00:00
2015-03-17 12:55:39 +00:00
it 'is sent as the author' do
2021-03-19 12:09:03 +00:00
expect_sender ( user )
2015-03-17 12:55:39 +00:00
end
2017-03-21 22:49:45 +00:00
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-03-17 12:55:39 +00:00
end
end
describe 'email on push for a deleted branch' do
let ( :example_site_path ) { root_path }
2017-05-01 15:13:33 +00:00
subject { described_class . repository_push_email ( project . id , author_id : user . id , ref : 'refs/heads/master' , action : :delete ) }
2015-03-17 12:55:39 +00:00
2015-11-25 12:27:31 +00:00
it_behaves_like 'it should not have Gmail Actions links'
2016-07-13 23:56:54 +00:00
it_behaves_like 'a user cannot unsubscribe through footer link'
2015-12-19 19:04:40 +00:00
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-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2015-11-25 12:27:31 +00:00
2015-03-17 12:55:39 +00:00
it 'is sent as the author' do
2021-03-19 12:09:03 +00:00
expect_sender ( user )
2015-03-17 12:55:39 +00:00
end
it 'has the correct subject' do
2017-03-14 12:56:07 +00:00
is_expected . to have_subject " [Git][ #{ project . full_path } ] Deleted branch master "
2015-03-17 12:55:39 +00:00
end
end
describe 'email on push for a deleted tag' do
let ( :example_site_path ) { root_path }
2017-05-01 15:13:33 +00:00
subject { described_class . repository_push_email ( project . id , author_id : user . id , ref : 'refs/tags/v1.0' , action : :delete ) }
2015-03-17 12:55:39 +00:00
2015-11-25 12:27:31 +00:00
it_behaves_like 'it should not have Gmail Actions links'
2016-07-13 23:56:54 +00:00
it_behaves_like 'a user cannot unsubscribe through footer link'
2015-12-19 19:04:40 +00:00
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-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2015-11-25 12:27:31 +00:00
2015-03-17 12:55:39 +00:00
it 'is sent as the author' do
2021-03-19 12:09:03 +00:00
expect_sender ( user )
2015-03-17 12:55:39 +00:00
end
it 'has the correct subject' do
2017-03-14 12:56:07 +00:00
is_expected . to have_subject " [Git][ #{ project . full_path } ] Deleted tag v1.0 "
2015-03-17 12:55:39 +00:00
end
end
2014-04-10 16:41:20 +00:00
describe 'email on push with multiple commits' do
2013-12-18 11:30:04 +00:00
let ( :example_site_path ) { root_path }
2016-07-27 11:09:52 +00:00
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-06-29 17:06:35 +00:00
let ( :diff_path ) { project_compare_path ( project , from : Commit . new ( compare . base , project ) , to : Commit . new ( compare . head , project ) ) }
2015-02-25 13:05:45 +00:00
let ( :send_from_committer_email ) { false }
2016-06-20 16:51:48 +00:00
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 ) }
2013-12-18 11:30:04 +00:00
2017-05-01 15:13:33 +00:00
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 ) }
2013-12-18 11:30:04 +00:00
2015-11-25 12:27:31 +00:00
it_behaves_like 'it should not have Gmail Actions links'
2016-07-13 23:56:54 +00:00
it_behaves_like 'a user cannot unsubscribe through footer link'
2015-12-19 19:04:40 +00:00
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-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2015-11-25 12:27:31 +00:00
2014-02-17 17:49:42 +00:00
it 'is sent as the author' do
2021-03-19 12:09:03 +00:00
expect_sender ( user )
2014-02-17 17:49:42 +00:00
end
2017-03-21 22:49:45 +00:00
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-02-20 16:44:13 +00:00
end
2015-02-25 13:05:45 +00:00
context " when set to send from committer email if domain matches " do
let ( :send_from_committer_email ) { true }
2015-02-25 14:49:40 +00:00
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
2015-02-25 13:05:45 +00:00
before do
2015-02-25 14:49:40 +00:00
user . update_attribute ( :email , " user@company.com " )
2015-09-20 01:15:13 +00:00
user . confirm
2015-02-25 13:05:45 +00:00
end
it " is sent from the committer email " do
2017-03-21 22:49:45 +00:00
from = subject . header [ :from ] . addrs . first
reply = subject . header [ :reply_to ] . addrs . first
2015-04-14 10:52:33 +00:00
2017-03-21 22:49:45 +00:00
aggregate_failures do
expect ( from . address ) . to eq ( user . email )
expect ( reply . address ) . to eq ( user . email )
end
2015-04-14 10:52:33 +00:00
end
2015-02-25 13:05:45 +00:00
end
2015-02-25 14:49:40 +00:00
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-20 01:15:13 +00:00
user . confirm
2015-02-25 14:49:40 +00:00
end
it " is sent from the default email " do
2017-03-21 22:49:45 +00:00
from = subject . header [ :from ] . addrs . first
reply = subject . header [ :reply_to ] . addrs . first
2015-04-14 10:52:33 +00:00
2017-03-21 22:49:45 +00:00
aggregate_failures do
expect ( from . address ) . to eq ( gitlab_sender )
expect ( reply . address ) . to eq ( gitlab_sender_reply_to )
end
2015-04-14 10:52:33 +00:00
end
2015-02-25 14:49:40 +00:00
end
context " when the committer email domain is outside the GitLab domain " do
before do
user . update_attribute ( :email , " user@mpany.com " )
2015-09-20 01:15:13 +00:00
user . confirm
2015-02-25 14:49:40 +00:00
end
2015-02-25 13:05:45 +00:00
it " is sent from the default email " do
2017-03-21 22:49:45 +00:00
from = subject . header [ :from ] . addrs . first
reply = subject . header [ :reply_to ] . addrs . first
2015-04-14 10:52:33 +00:00
2017-03-21 22:49:45 +00:00
aggregate_failures do
expect ( from . address ) . to eq ( gitlab_sender )
expect ( reply . address ) . to eq ( gitlab_sender_reply_to )
end
2015-04-14 10:52:33 +00:00
end
2015-02-25 13:05:45 +00:00
end
end
2013-12-18 11:30:04 +00:00
end
2014-04-10 16:41:20 +00:00
describe 'email on push with a single commit' do
let ( :example_site_path ) { root_path }
2016-07-27 11:09:52 +00:00
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-06-29 17:06:35 +00:00
let ( :diff_path ) { project_commit_path ( project , commits . first ) }
2016-06-20 16:51:48 +00:00
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-04-10 16:41:20 +00:00
2017-05-01 15:13:33 +00:00
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-04-10 16:41:20 +00:00
2015-11-25 12:59:03 +00:00
it_behaves_like 'it should show Gmail Actions View Commit link'
2016-07-13 23:56:54 +00:00
it_behaves_like 'a user cannot unsubscribe through footer link'
2015-12-19 19:04:40 +00:00
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-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2015-11-25 12:27:31 +00:00
2014-04-10 16:41:20 +00:00
it 'is sent as the author' do
2021-03-19 12:09:03 +00:00
expect_sender ( user )
2014-04-10 16:41:20 +00:00
end
2017-03-21 22:49:45 +00:00
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-04-10 16:41:20 +00:00
end
end
2016-11-28 22:00:03 +00:00
describe 'HTML emails setting' do
2017-05-01 15:13:33 +00:00
let ( :multipart_mail ) { described_class . project_was_moved_email ( project . id , user . id , " gitlab/gitlab " ) }
2016-11-28 22:00:03 +00:00
2019-02-20 15:18:15 +00:00
subject { multipart_mail }
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2016-11-28 22:00:03 +00:00
context 'when disabled' do
it 'only sends the text template' do
stub_application_setting ( html_emails_enabled : false )
2018-07-16 11:46:00 +00:00
Gitlab :: Email :: Hook :: EmailTemplateInterceptor
. delivering_email ( multipart_mail )
2016-11-28 22:00:03 +00:00
expect ( multipart_mail ) . to have_part_with ( 'text/plain' )
expect ( multipart_mail ) . not_to have_part_with ( 'text/html' )
end
end
context 'when enabled' do
it 'sends a multipart message' do
stub_application_setting ( html_emails_enabled : true )
2018-07-16 11:46:00 +00:00
Gitlab :: Email :: Hook :: EmailTemplateInterceptor
. delivering_email ( multipart_mail )
2016-11-28 22:00:03 +00:00
expect ( multipart_mail ) . to have_part_with ( 'text/plain' )
expect ( multipart_mail ) . to have_part_with ( 'text/html' )
end
end
matcher :have_part_with do | expected |
match do | actual |
2018-01-27 05:35:53 +00:00
actual . body . parts . any? { | part | part . content_type . try ( :match , / #{ expected } / ) }
2016-11-28 22:00:03 +00:00
end
end
end
2017-10-09 12:59:10 +00:00
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-01-23 12:08:38 +00:00
subject { described_class . note_snippet_email ( personal_snippet_note . author_id , personal_snippet_note . id ) }
2017-10-09 12:59:10 +00:00
it_behaves_like 'a user cannot unsubscribe through footer link'
2019-02-20 15:18:15 +00:00
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
2017-10-09 12:59:10 +00:00
2020-01-23 12:08:38 +00:00
it 'has the correct subject' do
2017-10-09 12:59:10 +00:00
is_expected . to have_referable_subject ( personal_snippet , reply : true )
2020-01-23 12:08:38 +00:00
end
it 'has the correct body' do
2018-06-03 13:22:50 +00:00
is_expected . to have_body_text personal_snippet_note . note
2017-10-09 12:59:10 +00:00
end
2020-01-23 12:08:38 +00:00
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
2017-10-09 12:59:10 +00:00
end
2020-05-27 18:08:14 +00:00
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-03-19 12:09:03 +00:00
expect_sender ( review . author )
2020-05-27 18:08:14 +00:00
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 ) }
it 'links to notes' do
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 } " )
)
end
end
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-03-19 12:09:03 +00:00
2021-07-06 09:07:05 +00:00
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
2021-03-19 12:09:03 +00:00
def expect_sender ( user )
sender = subject . header [ :from ] . addrs [ 0 ]
expect ( sender . display_name ) . to eq ( " #{ user . name } (@ #{ user . username } ) " )
expect ( sender . address ) . to eq ( gitlab_sender )
end
2012-05-14 18:05:32 +00:00
end