summaryrefslogtreecommitdiff
path: root/spec/mailers
diff options
context:
space:
mode:
Diffstat (limited to 'spec/mailers')
-rw-r--r--spec/mailers/abuse_report_mailer_spec.rb10
-rw-r--r--spec/mailers/emails/merge_requests_spec.rb33
-rw-r--r--spec/mailers/emails/projects_spec.rb119
-rw-r--r--spec/mailers/notify_spec.rb118
4 files changed, 219 insertions, 61 deletions
diff --git a/spec/mailers/abuse_report_mailer_spec.rb b/spec/mailers/abuse_report_mailer_spec.rb
index 4eb616722ac..061f972fd35 100644
--- a/spec/mailers/abuse_report_mailer_spec.rb
+++ b/spec/mailers/abuse_report_mailer_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe AbuseReportMailer do
describe '.notify' do
before do
- stub_application_setting(admin_notification_email: 'admin@example.com')
+ stub_application_setting(abuse_notification_email: 'admin@example.com')
end
let(:report) { create(:abuse_report) }
@@ -17,8 +17,8 @@ RSpec.describe AbuseReportMailer do
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
- context 'with admin_notification_email set' do
- it 'sends to the admin_notification_email' do
+ context 'with abuse_notification_email set' do
+ it 'sends to the abuse_notification_email' do
is_expected.to deliver_to 'admin@example.com'
end
@@ -27,9 +27,9 @@ RSpec.describe AbuseReportMailer do
end
end
- context 'with no admin_notification_email set' do
+ context 'with no abuse_notification_email set' do
it 'returns early' do
- stub_application_setting(admin_notification_email: nil)
+ stub_application_setting(abuse_notification_email: nil)
expect { described_class.notify(spy).deliver_now }
.not_to change { ActionMailer::Base.deliveries.count }
diff --git a/spec/mailers/emails/merge_requests_spec.rb b/spec/mailers/emails/merge_requests_spec.rb
index 477fb16400a..9235a946394 100644
--- a/spec/mailers/emails/merge_requests_spec.rb
+++ b/spec/mailers/emails/merge_requests_spec.rb
@@ -33,4 +33,37 @@ RSpec.describe Emails::MergeRequests do
expect(subject).to have_content current_user.name
end
end
+
+ describe '#merge_requests_csv_email' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let(:merge_requests) { create_list(:merge_request, 10) }
+ let(:export_status) do
+ {
+ rows_expected: 10,
+ rows_written: 10,
+ truncated: false
+ }
+ end
+
+ let(:csv_data) { MergeRequests::ExportCsvService.new(MergeRequest.all, project).csv_data }
+
+ subject { Notify.merge_requests_csv_email(user, project, csv_data, export_status) }
+
+ it { expect(subject.subject).to eq("#{project.name} | Exported merge requests") }
+ it { expect(subject.to).to contain_exactly(user.notification_email_for(project.group)) }
+ it { expect(subject).to have_content('Your CSV export of 10 merge requests from project')}
+
+ context 'when truncated' do
+ let(:export_status) do
+ {
+ rows_expected: 10,
+ rows_written: 10,
+ truncated: true
+ }
+ end
+
+ it { expect(subject).to have_content('This attachment has been truncated to avoid exceeding the maximum allowed attachment size of 15MB.') }
+ end
+ end
end
diff --git a/spec/mailers/emails/projects_spec.rb b/spec/mailers/emails/projects_spec.rb
index 599f62a8113..aa5947bf68e 100644
--- a/spec/mailers/emails/projects_spec.rb
+++ b/spec/mailers/emails/projects_spec.rb
@@ -30,107 +30,118 @@ RSpec.describe Emails::Projects do
let_it_be(:user) { create(:user) }
describe '#prometheus_alert_fired_email' do
+ let(:default_title) { Gitlab::AlertManagement::Payload::Generic::DEFAULT_TITLE }
+ let(:payload) { { 'startsAt' => Time.now.rfc3339 } }
+ let(:alert_attributes) { build(:alert_management_alert, :from_payload, payload: payload, project: project).attributes }
+
subject do
- Notify.prometheus_alert_fired_email(project.id, user.id, alert_params)
+ Notify.prometheus_alert_fired_email(project.id, user.id, alert_attributes)
end
- let(:alert_params) do
- { 'startsAt' => Time.now.rfc3339 }
+ context 'missing required attributes' do
+ let(:alert_attributes) { build(:alert_management_alert, :prometheus, :from_payload, payload: payload, project: project).attributes }
+
+ it_behaves_like 'no email'
end
- context 'with a gitlab alert' do
- before do
- alert_params['labels'] = { 'gitlab_alert_id' => alert.prometheus_metric_id.to_s }
- end
+ context 'with minimum required attributes' do
+ let(:payload) { {} }
- let(:title) do
- "#{alert.title} #{alert.computed_operator} #{alert.threshold}"
- end
+ 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'
- let(:metrics_url) do
- metrics_project_environment_url(project, environment)
+ it 'has expected subject' do
+ is_expected.to have_subject("#{project.name} | Alert: #{default_title}")
end
- let(:environment) { alert.environment }
+ it 'has expected content' do
+ is_expected.to have_body_text('An alert has been triggered')
+ is_expected.to have_body_text(project.full_path)
+ is_expected.not_to have_body_text('Description:')
+ is_expected.not_to have_body_text('Environment:')
+ is_expected.not_to have_body_text('Metric:')
+ end
+ end
- let!(:alert) { create(:prometheus_alert, project: project) }
+ context 'with description' do
+ let(:payload) { { 'description' => 'alert description' } }
it_behaves_like 'an email sent from GitLab'
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like 'a user cannot unsubscribe through footer link'
it 'has expected subject' do
- is_expected.to have_subject("#{project.name} | Alert: #{environment.name}: #{title} for 5 minutes")
+ is_expected.to have_subject("#{project.name} | Alert: #{default_title}")
end
it 'has expected content' do
is_expected.to have_body_text('An alert has been triggered')
is_expected.to have_body_text(project.full_path)
- is_expected.to have_body_text('Environment:')
- is_expected.to have_body_text(environment.name)
- is_expected.to have_body_text('Metric:')
- is_expected.to have_body_text(alert.full_query)
- is_expected.to have_body_text(metrics_url)
+ is_expected.to have_body_text('Description:')
+ is_expected.to have_body_text('alert description')
+ is_expected.not_to have_body_text('Environment:')
+ is_expected.not_to have_body_text('Metric:')
end
-
- it_behaves_like 'shows the incident issues url'
end
- context 'with no payload' do
- let(:alert_params) { {} }
+ context 'with environment' do
+ let_it_be(:environment) { create(:environment, project: project) }
+ let(:payload) { { 'gitlab_environment_name' => environment.name } }
+ let(:metrics_url) { metrics_project_environment_url(project, environment) }
- it_behaves_like 'no email'
- end
+ 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'
- context 'with an unknown alert' do
- before do
- alert_params['labels'] = { 'gitlab_alert_id' => 'unknown' }
+ it 'has expected subject' do
+ is_expected.to have_subject("#{project.name} | Alert: #{environment.name}: #{default_title}")
end
- it_behaves_like 'no email'
+ it 'has expected content' do
+ is_expected.to have_body_text('An alert has been triggered')
+ is_expected.to have_body_text(project.full_path)
+ is_expected.to have_body_text('Environment:')
+ is_expected.to have_body_text(environment.name)
+ is_expected.not_to have_body_text('Description:')
+ is_expected.not_to have_body_text('Metric:')
+ end
end
- context 'with an external alert' do
- let(:title) { 'alert title' }
+ context 'with gitlab alerting rule' do
+ let_it_be(:prometheus_alert) { create(:prometheus_alert, project: project) }
+ let_it_be(:environment) { prometheus_alert.environment }
- let(:metrics_url) do
- metrics_project_environments_url(project)
- end
+ let(:alert_attributes) { build(:alert_management_alert, :prometheus, :from_payload, payload: payload, project: project).attributes }
+ let(:title) { "#{prometheus_alert.title} #{prometheus_alert.computed_operator} #{prometheus_alert.threshold}" }
+ let(:metrics_url) { metrics_project_environment_url(project, environment) }
before do
- alert_params['annotations'] = { 'title' => title }
- alert_params['generatorURL'] = 'http://localhost:9090/graph?g0.expr=vector%281%29&g0.tab=1'
+ payload['labels'] = {
+ 'gitlab_alert_id' => prometheus_alert.prometheus_metric_id,
+ 'alertname' => prometheus_alert.title
+ }
end
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 'shows the incident issues url'
it 'has expected subject' do
- is_expected.to have_subject("#{project.name} | Alert: #{title}")
+ is_expected.to have_subject("#{project.name} | Alert: #{environment.name}: #{title} for 5 minutes")
end
it 'has expected content' do
is_expected.to have_body_text('An alert has been triggered')
is_expected.to have_body_text(project.full_path)
+ is_expected.to have_body_text('Environment:')
+ is_expected.to have_body_text(environment.name)
+ is_expected.to have_body_text('Metric:')
+ is_expected.to have_body_text(prometheus_alert.full_query)
+ is_expected.to have_body_text(metrics_url)
is_expected.not_to have_body_text('Description:')
- is_expected.not_to have_body_text('Environment:')
end
-
- context 'with annotated description' do
- let(:description) { 'description' }
-
- before do
- alert_params['annotations']['description'] = description
- end
-
- it 'shows the description' do
- is_expected.to have_body_text('Description:')
- is_expected.to have_body_text(description)
- end
- end
-
- it_behaves_like 'shows the incident issues url'
end
end
end
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index b9f95a9eb00..8604939ead9 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -1508,12 +1508,44 @@ RSpec.describe Notify do
)
end
- describe 'group invitation' do
+ describe 'invitations' do
let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } }
let(:group_member) { invite_to_group(group, inviter: inviter) }
let(:inviter) { owner }
- subject { described_class.member_invited_email('group', group_member.id, group_member.invite_token) }
+ subject { described_class.member_invited_email('Group', group_member.id, group_member.invite_token) }
+
+ shared_examples "tracks the 'sent' event for the invitation reminders experiment" do
+ before do
+ stub_experiment(invitation_reminders: true)
+ allow(Gitlab::Experimentation).to receive(:enabled_for_attribute?).with(:invitation_reminders, group_member.invite_email).and_return(experimental_group)
+ end
+
+ it "tracks the 'sent' event", :snowplow do
+ subject.deliver_now
+
+ expect_snowplow_event(
+ category: 'Growth::Acquisition::Experiment::InvitationReminders',
+ label: Digest::MD5.hexdigest(group_member.to_global_id.to_s),
+ property: experimental_group ? 'experimental_group' : 'control_group',
+ action: 'sent'
+ )
+ end
+ end
+
+ describe 'tracking for the invitation reminders experiment' do
+ context 'when invite email is in the experimental group' do
+ let(:experimental_group) { true }
+
+ it_behaves_like "tracks the 'sent' event for the invitation reminders experiment"
+ end
+
+ context 'when invite email is in the control group' do
+ let(:experimental_group) { false }
+
+ it_behaves_like "tracks the 'sent' event for the invitation reminders experiment"
+ end
+ end
context 'when invite_email_experiment is disabled' do
before do
@@ -1608,6 +1640,88 @@ RSpec.describe Notify do
end
end
+ 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
+
describe 'group invitation accepted' do
let(:invited_user) { create(:user, name: 'invited user') }
let(:owner) { create(:user).tap { |u| group.add_user(u, Gitlab::Access::OWNER) } }