Commit aee58dce authored by Paul Slaughter's avatar Paul Slaughter

Merge branch '220290-security-dashboard-integration-tests' into 'master'

Create integration tests for security init files

See merge request gitlab-org/gitlab!45452
parents 2ea0535a 533993b9
1c4fdefdaf88730c025b5c7ba7ddc42c268043d4
940a45ca938b20031820a4976f936a5b6173de92
......@@ -318,7 +318,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
end
def export_csv
return render_404 unless Feature.enabled?(:export_merge_requests_as_csv, project)
return render_404 unless Feature.enabled?(:export_merge_requests_as_csv, project, default_enabled: true)
IssuableExportCsvWorker.perform_async(:merge_request, current_user.id, project.id, finder_options.to_h) # rubocop:disable CodeReuse/Worker
......
......@@ -118,8 +118,7 @@ module Types
resolver: Resolvers::MergeRequestPipelinesResolver
field :milestone, Types::MilestoneType, null: true,
description: 'The milestone of the merge request',
resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Milestone, obj.milestone_id).find }
description: 'The milestone of the merge request'
field :assignees, Types::UserType.connection_type, null: true, complexity: 5,
description: 'Assignees of the merge request'
field :author, Types::UserType, null: true,
......
......@@ -56,12 +56,9 @@ module Emails
subject: @message.subject)
end
def prometheus_alert_fired_email(project_id, user_id, alert_attributes)
@project = ::Project.find(project_id)
user = ::User.find(user_id)
@alert = AlertManagement::Alert.new(alert_attributes.with_indifferent_access).present
return unless @alert.parsed_payload.has_required_attributes?
def prometheus_alert_fired_email(project, user, alert)
@project = project
@alert = alert.present
subject_text = "Alert: #{@alert.email_title}"
mail(to: user.notification_email_for(@project.group), subject: subject(subject_text))
......
......@@ -9,6 +9,10 @@ module AlertManagement
return bad_request unless incoming_payload.has_required_attributes?
process_alert_management_alert
return bad_request unless alert.persisted?
process_incident_issues if process_issues?
send_alert_email if send_email?
ServiceResponse.success
end
......@@ -30,8 +34,6 @@ module AlertManagement
else
create_alert_management_alert
end
process_incident_issues if process_issues?
end
def reset_alert_management_alert_status
......@@ -85,12 +87,17 @@ module AlertManagement
end
def process_incident_issues
return unless alert.persisted?
return if alert.issue
return if alert.issue || alert.resolved?
IncidentManagement::ProcessAlertWorker.perform_async(nil, nil, alert.id)
end
def send_alert_email
notification_service
.async
.prometheus_alerts_fired(project, [alert])
end
def logger
@logger ||= Gitlab::AppLogger
end
......
......@@ -601,7 +601,7 @@ class NotificationService
return if project.emails_disabled?
owners_and_maintainers_without_invites(project).to_a.product(alerts).each do |recipient, alert|
mailer.prometheus_alert_fired_email(project.id, recipient.user.id, alert).deliver_later
mailer.prometheus_alert_fired_email(project, recipient.user, alert).deliver_later
end
end
......
......@@ -73,7 +73,7 @@ module Projects
end
def process_incident_issues
return if alert.issue
return if alert.issue || alert.resolved?
::IncidentManagement::ProcessAlertWorker.perform_async(nil, nil, alert.id)
end
......@@ -81,7 +81,7 @@ module Projects
def send_alert_email
notification_service
.async
.prometheus_alerts_fired(project, [alert.attributes])
.prometheus_alerts_fired(project, [alert])
end
def alert
......
......@@ -23,7 +23,6 @@ module Projects
return unauthorized unless valid_alert_manager_token?(token)
process_prometheus_alerts
send_alert_email if send_email?
ServiceResponse.success
end
......@@ -120,14 +119,6 @@ module Projects
ActiveSupport::SecurityUtils.secure_compare(expected, actual)
end
def send_alert_email
return unless firings.any?
notification_service
.async
.prometheus_alerts_fired(project, alerts_attributes)
end
def process_prometheus_alerts
alerts.each do |alert|
AlertManagement::ProcessPrometheusAlertService
......@@ -136,18 +127,6 @@ module Projects
end
end
def alerts_attributes
firings.map do |payload|
alert_params = Gitlab::AlertManagement::Payload.parse(
project,
payload,
monitoring_tool: Gitlab::AlertManagement::Payload::MONITORING_TOOLS[:prometheus]
).alert_params
AlertManagement::Alert.new(alert_params).attributes
end
end
def bad_request
ServiceResponse.error(message: 'Bad Request', http_status: :bad_request)
end
......
- body = @alert.resolved? ? _('An alert has been resolved in %{project_path}.') : _('An alert has been triggered in %{project_path}.')
%p
= body % { project_path: @alert.project.full_path }
%p
= _('An alert has been triggered in %{project_path}.') % { project_path: @alert.project.full_path }
= link_to(_('View alert details.'), @alert.details_url)
- if description = @alert.description
%p
......
<%= _('An alert has been triggered in %{project_path}.') % { project_path: @alert.project.full_path } %>.
<% body = @alert.resolved? ? _('An alert has been resolved in %{project_path}.') : _('An alert has been triggered in %{project_path}.') %>
<%= body % { project_path: @alert.project.full_path } %>
<%= _('View alert details at') %> <%= @alert.details_url %>
<% if description = @alert.description %>
<%= _('Description:') %> <%= description %>
......
- if Feature.enabled?(:export_merge_requests_as_csv, @project)
- if Feature.enabled?(:export_merge_requests_as_csv, @project, default_enabled: true)
.btn-group
= render 'shared/issuable/csv_export/button', issuable_type: 'merge-requests'
......@@ -8,5 +8,5 @@
= link_to new_merge_request_path, class: "gl-button btn btn-success", title: "New merge request" do
New merge request
- if Feature.enabled?(:export_merge_requests_as_csv, @project)
- if Feature.enabled?(:export_merge_requests_as_csv, @project, default_enabled: true)
= render 'shared/issuable/csv_export/modal', issuable_type: 'merge_requests'
---
title: Enable MR CSV export
merge_request: 46662
author:
type: added
---
title: Improve messaging for emails from alerts
merge_request: 43054
author:
type: changed
......@@ -4,4 +4,4 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/45130
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/267129
type: development
group: group::compliance
default_enabled: false
default_enabled: true
......@@ -142,7 +142,7 @@ context 'when the experiment is active and the user is in the experimental group
expect_snowplow_event(
category: 'Growth::Activation::Experiment::SignUpFlow',
action: 'action',
label: 'value',
value: 'value',
label: 'experimentation_subject_id',
property: 'experimental_group'
)
......@@ -254,7 +254,7 @@ For visibility, please also share any commands run against production in the `#s
#### RSpec
Use the folowing in RSpec to mock the experiment:
Use the following in RSpec to mock the experiment:
```ruby
context 'when the experiment is active' do
......
......@@ -21,20 +21,20 @@ TIP: **Tip:**
When you enable 2FA, don't forget to back up your [recovery codes](#recovery-codes)!
In addition to time-based one time passwords (TOTP), GitLab supports U2F
(universal 2nd factor) devices as the second factor of authentication. Once
(universal 2nd factor) and WebAuthn (experimental) devices as the second factor of authentication. Once
enabled, in addition to supplying your username and password to log in, you'll
be prompted to activate your U2F device (usually by pressing a button on it),
be prompted to activate your U2F / WebAuthn device (usually by pressing a button on it),
and it will perform secure authentication on your behalf.
It is highly recommended that you set up 2FA with both a
[one-time password authenticator](#one-time-password) or use [FortiAuthenticator](#one-time-password-via-fortiauthenticator)
and a [U2F device](#u2f-device), so you can still access your account if you
lose your U2F device.
and a [U2F device](#u2f-device) or a [WebAuthn device](#webauthn-device), so you can still access your account
if you lose your U2F / WebAuthn device.
## Enabling 2FA
There are two ways to enable two-factor authentication: via a one time password authenticator
or a U2F device.
There are multiple ways to enable two-factor authentication: via a one time password authenticator
or a U2F / WebAuthn device.
### One-time password
......@@ -174,10 +174,46 @@ To set up 2FA with a U2F device:
You will see a message indicating that your device was successfully set up.
Click on **Register U2F Device** to complete the process.
### WebAuthn device
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22506) in GitLab 13.4.
> - It's [deployed behind a feature flag](../../feature_flags.md), disabled by default.
> - It's disabled on GitLab.com.
> - It's not recommended for production use.
> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-webauthn). **(CORE ONLY)**
The WebAuthn workflow is [supported by](https://caniuse.com/#search=webauthn) the
following desktop browsers:
- Chrome
- Edge
- Firefox
- Opera
- Safari
and the following mobile browsers:
- Chrome for Android
- Firefox for Android
- iOS Safari (since iOS 13.3)
To set up 2FA with a WebAuthn compatible device:
1. Sign in to your GitLab account.
1. Go to your [**Profile settings**](../index.md#profile-settings).
1. Go to **Account**.
1. Select **Enable Two-Factor Authentication**.
1. Plug in your WebAuthn device.
1. Select **Set up New WebAuthn Device**.
1. Depending on your device, you might need to press a button or touch a sensor.
You will see a message indicating that your device was successfully set up.
Recovery codes are not generated for WebAuthn devices.
## Recovery codes
NOTE: **Note:**
Recovery codes are not generated for U2F devices.
Recovery codes are not generated for U2F / WebAuthn devices.
CAUTION: **Caution:**
Each code can be used only once to log in to your account.
......@@ -215,6 +251,14 @@ To log in via a U2F device:
You will see a message indicating that your device responded to the authentication
request and you will be automatically logged in.
### Log in via WebAuthn device
In supported browsers you should be automatically prompted to activate your WebAuthn device
(e.g. by touching/pressing its button) after entering your credentials.
You will see a message indicating that your device responded to the authentication
request and you will be automatically logged in.
## Disabling 2FA
If you ever need to disable 2FA:
......@@ -225,7 +269,7 @@ If you ever need to disable 2FA:
1. Click **Disable**, under **Two-Factor Authentication**.
This will clear all your two-factor authentication registrations, including mobile
applications and U2F devices.
applications and U2F / WebAuthn devices.
## Personal access tokens
......@@ -331,7 +375,8 @@ Sign in and re-enable two-factor authentication as soon as possible.
you may have cases where authorization always fails because of time differences.
- The GitLab U2F implementation does _not_ work when the GitLab instance is accessed from
multiple hostnames, or FQDNs. Each U2F registration is linked to the _current hostname_ at
the time of registration, and cannot be used for other hostnames/FQDNs.
the time of registration, and cannot be used for other hostnames/FQDNs. The same applies to
WebAuthn registrations.
For example, if a user is trying to access a GitLab instance from `first.host.xyz` and `second.host.xyz`:
......@@ -342,6 +387,25 @@ Sign in and re-enable two-factor authentication as soon as possible.
- To enforce 2FA at the system or group levels see [Enforce Two-factor Authentication](../../../security/two_factor_authentication.md).
## Enable or disable WebAuthn **(CORE ONLY)**
Support for WebAuthn is under development and not ready for production use. It is
deployed behind a feature flag that is **disabled by default**.
[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
can enable it.
To enable it:
```ruby
Feature.enable(:webauthn)
```
To disable it:
```ruby
Feature.disable(:webauthn)
```
## Troubleshooting
If you are receiving an `invalid pin code` error, this may indicate that there is a time sync issue between the authentication application and the GitLab instance itself.
......
......@@ -7,10 +7,12 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Export Merge Requests to CSV **(CORE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3619) in GitLab 13.6.
> - It's [deployed behind a feature flag](../../../administration/feature_flags.md), disabled by default.
> - It's disabled on GitLab.com.
> - It's not recommended for production use.
> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-export-merge-requests-to-csv). **(CORE ONLY)**
> - It was [deployed behind a feature flag](../../../administration/feature_flags.md), disabled by default.
> - Became enabled by default in GitLab 13.6.
> - It's enabled on GitLab.com.
> - It's recommended for production use.
> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-export-merge-requests-to-csv). **(CORE ONLY)**
> - It can be enabled or disabled for a single project.
CAUTION: **Warning:**
This feature might not be available to you. Check the **version history** note above for details.
......@@ -55,25 +57,25 @@ The following table shows what attributes will be present in the CSV.
### Enable or disable Export Merge Requests to CSV **(CORE ONLY)**
Export merge requests to CSV is under development and not ready for production use. It is
deployed behind a feature flag that is **disabled by default**.
Export merge requests to CSV is under development but ready for production use.
It is deployed behind a feature flag that is **enabled by default**.
[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
can enable it.
can opt to disable it.
To enable it:
```ruby
# For the instance
Feature.enable(:export_merge_requests_as_csv)
# For a single project
Feature.enable(:export_merge_requests_as_csv, Project.find(<project id>))
```
To disable it:
```ruby
Feature.enable(:export_merge_requests_as_csv)
```
Optionally, pass a project as an argument to enable for a single project.
```ruby
Feature.enable(:export_merge_requests_as_csv, project)
# For the instance
Feature.disable(:export_merge_requests_as_csv)
# For a single project
Feature.disable(:export_merge_requests_as_csv, Project.find(<project id>))
```
---
title: Rename "cycle analytics" with "value stream analytics" under /ee/spec
merge_request: 46745
author: Takuya Noguchi
type: other
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Cycle analytics utils transformRawStages retains all the stage properties 1`] = `
exports[`Value Stream Analytics utils transformRawStages retains all the stage properties 1`] = `
Array [
Object {
"custom": false,
......
......@@ -42,7 +42,7 @@ const stageEndpoint = ({ stageId }) =>
jest.mock('~/flash');
describe('Cycle analytics actions', () => {
describe('Value Stream Analytics actions', () => {
let state;
let mock;
......
......@@ -28,7 +28,7 @@ const milestoneValues = getFilterValues(filterMilestones);
const labelValues = getFilterValues(filterLabels);
const userValues = getFilterValues(filterUsers, { prop: 'name' });
describe('Cycle analytics getters', () => {
describe('Value Stream Analytics getters', () => {
describe('hasNoAccessError', () => {
beforeEach(() => {
state = {
......
......@@ -6,7 +6,7 @@ import { apiTasksByTypeData, rawTasksByTypeData } from '../../../mock_data';
let state = null;
describe('Cycle analytics mutations', () => {
describe('Value Stream Analytics mutations', () => {
beforeEach(() => {
state = {};
});
......
......@@ -16,7 +16,7 @@ import {
let state = null;
describe('Cycle analytics mutations', () => {
describe('Value Stream Analytics mutations', () => {
beforeEach(() => {
state = {};
});
......
......@@ -41,7 +41,7 @@ import {
const labelEventIds = labelEvents.map(ev => ev.identifier);
describe('Cycle analytics utils', () => {
describe('Value Stream Analytics utils', () => {
describe('isStartEvent', () => {
it('will return true for a valid start event', () => {
expect(isStartEvent(startEvents[0])).toEqual(true);
......
......@@ -200,7 +200,7 @@ describe('Api', () => {
});
});
describe('Cycle analytics', () => {
describe('Value Stream Analytics', () => {
const createdBefore = '2019-11-18';
const createdAfter = '2019-08-18';
const groupId = 'counting-54321';
......
......@@ -19,7 +19,6 @@ module Gitlab
# disable SSL check since any cert used here will likely be self-signed
def rewrite_env(env)
env["rack.ssl_verify_none"] = true
env["HTTP_HOST"] = @proxy_host
env
end
......
......@@ -2821,6 +2821,9 @@ msgstr ""
msgid "An administrator changed the password for your GitLab account on %{link_to}."
msgstr ""
msgid "An alert has been resolved in %{project_path}."
msgstr ""
msgid "An alert has been triggered in %{project_path}."
msgstr ""
......@@ -29435,6 +29438,12 @@ msgstr ""
msgid "View Documentation"
msgstr ""
msgid "View alert details at"
msgstr ""
msgid "View alert details."
msgstr ""
msgid "View all issues"
msgstr ""
......
......@@ -32,19 +32,13 @@ RSpec.describe Emails::Projects do
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 }
let(:alert) { create(:alert_management_alert, :from_payload, payload: payload, project: project) }
subject do
Notify.prometheus_alert_fired_email(project.id, user.id, alert_attributes)
Notify.prometheus_alert_fired_email(project, user, alert)
end
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 minimum required attributes' do
context 'with empty payload' do
let(:payload) { {} }
it_behaves_like 'an email sent from GitLab'
......@@ -58,6 +52,7 @@ RSpec.describe Emails::Projects do
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(alert.details_url)
is_expected.not_to have_body_text('Description:')
is_expected.not_to have_body_text('Environment:')
is_expected.not_to have_body_text('Metric:')
......@@ -78,6 +73,7 @@ RSpec.describe Emails::Projects do
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(alert.details_url)
is_expected.to have_body_text('Description:')
is_expected.to have_body_text('alert description')
is_expected.not_to have_body_text('Environment:')
......@@ -101,6 +97,7 @@ RSpec.describe Emails::Projects do
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(alert.details_url)
is_expected.to have_body_text('Environment:')
is_expected.to have_body_text(environment.name)
is_expected.not_to have_body_text('Description:')
......@@ -112,7 +109,7 @@ RSpec.describe Emails::Projects do
let_it_be(:prometheus_alert) { create(:prometheus_alert, project: project) }
let_it_be(:environment) { prometheus_alert.environment }
let(:alert_attributes) { build(:alert_management_alert, :prometheus, :from_payload, payload: payload, project: project).attributes }
let(:alert) { create(:alert_management_alert, :prometheus, :from_payload, payload: payload, project: project) }
let(:title) { "#{prometheus_alert.title} #{prometheus_alert.computed_operator} #{prometheus_alert.threshold}" }
let(:metrics_url) { metrics_project_environment_url(project, environment) }
......@@ -135,6 +132,7 @@ RSpec.describe Emails::Projects do
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(alert.details_url)
is_expected.to have_body_text('Environment:')
is_expected.to have_body_text(environment.name)
is_expected.to have_body_text('Metric:')
......@@ -143,5 +141,23 @@ RSpec.describe Emails::Projects do
is_expected.not_to have_body_text('Description:')
end
end
context 'resolved' do
let_it_be(:alert) { create(:alert_management_alert, :resolved, project: project) }
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: #{alert.title}")
end
it 'has expected content' do
is_expected.to have_body_text('An alert has been resolved')
is_expected.to have_body_text(project.full_path)
is_expected.to have_body_text(alert.details_url)
end
end
end
end
......@@ -11,9 +11,16 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
describe '#execute' do
let(:service) { described_class.new(project, nil, payload) }
let(:incident_management_setting) { double(auto_close_incident?: auto_close_incident, create_issue?: create_issue) }
let(:auto_close_incident) { true }
let(:create_issue) { true }
let(:send_email) { true }
let(:incident_management_setting) do
double(
auto_close_incident?: auto_close_incident,
create_issue?: create_issue,
send_email?: send_email
)
end
before do
allow(service)
......@@ -55,6 +62,7 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
it_behaves_like 'adds an alert management alert event'
it_behaves_like 'processes incident issues'
it_behaves_like 'Alert Notification Service sends notification email'
context 'existing alert is resolved' do
let!(:alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: fingerprint) }
......@@ -92,28 +100,48 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
end
end
context 'when auto-alert creation is disabled' do
context 'when auto-creation of issues is disabled' do
let(:create_issue) { false }
it_behaves_like 'does not process incident issues'
end
context 'when emails are disabled' do
let(:send_email) { false }
it 'does not send notification' do
expect(NotificationService).not_to receive(:new)
expect(subject).to be_success
end
end
end
context 'when alert does not exist' do
context 'when alert can be created' do
it_behaves_like 'creates an alert management alert'
it_behaves_like 'Alert Notification Service sends notification email'
it_behaves_like 'processes incident issues'
it 'creates a system note corresponding to alert creation' do
expect { subject }.to change(Note, :count).by(1)
end
it_behaves_like 'processes incident issues'
context 'when auto-alert creation is disabled' do
let(:create_issue) { false }
it_behaves_like 'does not process incident issues'
end
context 'when emails are disabled' do
let(:send_email) { false }
it 'does not send notification' do
expect(NotificationService).not_to receive(:new)
expect(subject).to be_success
end
end
end
context 'when alert cannot be created' do
......@@ -125,6 +153,9 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
allow(service).to receive_message_chain(:alert, :errors).and_return(errors)
end
it_behaves_like 'Alert Notification Service sends no notifications', http_status: :bad_request
it_behaves_like 'does not process incident issues due to error', http_status: :bad_request
it 'writes a warning to the log' do
expect(Gitlab::AppLogger).to receive(:warn).with(
message: 'Unable to create AlertManagement::Alert',
......@@ -134,8 +165,6 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
execute
end
it_behaves_like 'does not process incident issues'
end
it { is_expected.to be_success }
......@@ -148,6 +177,9 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
context 'when auto_resolve_incident set to true' do
context 'when status can be changed' do
it_behaves_like 'Alert Notification Service sends notification email'
it_behaves_like 'does not process incident issues'
it 'resolves an existing alert' do
expect { execute }.to change { alert.reload.resolved? }.to(true)
end
......@@ -185,6 +217,8 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
execute
end
it_behaves_like 'Alert Notification Service sends notification email'
end
it { is_expected.to be_success }
......@@ -197,6 +231,16 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
expect { execute }.not_to change { alert.reload.resolved? }
end
end
context 'when emails are disabled' do
let(:send_email) { false }
it 'does not send notification' do
expect(NotificationService).not_to receive(:new)
expect(subject).to be_success
end
end
end
context 'environment given' do
......
......@@ -3100,26 +3100,26 @@ RSpec.describe NotificationService, :mailer do
end
describe '#prometheus_alerts_fired' do
let!(:project) { create(:project) }
let!(:master) { create(:user) }
let!(:developer) { create(:user) }
let(:alert_attributes) { build(:alert_management_alert, project: project).attributes }
let_it_be(:project) { create(:project) }
let_it_be(:master) { create(:user) }
let_it_be(:developer) { create(:user) }
let_it_be(:alert) { create(:alert_management_alert, project: project) }
before do
project.add_maintainer(master)
end
it 'sends the email to owners and masters' do
expect(Notify).to receive(:prometheus_alert_fired_email).with(project.id, master.id, alert_attributes).and_call_original
expect(Notify).to receive(:prometheus_alert_fired_email).with(project.id, project.owner.id, alert_attributes).and_call_original
expect(Notify).not_to receive(:prometheus_alert_fired_email).with(project.id, developer.id, alert_attributes)
expect(Notify).to receive(:prometheus_alert_fired_email).with(project, master, alert).and_call_original
expect(Notify).to receive(:prometheus_alert_fired_email).with(project, project.owner, alert).and_call_original
expect(Notify).not_to receive(:prometheus_alert_fired_email).with(project, developer, alert)
subject.prometheus_alerts_fired(project, [alert_attributes])
subject.prometheus_alerts_fired(project, [alert])
end
it_behaves_like 'project emails are disabled' do
let(:notification_target) { project }
let(:notification_trigger) { subject.prometheus_alerts_fired(project, [alert_attributes]) }
let(:notification_trigger) { subject.prometheus_alerts_fired(project, [alert]) }
around do |example|
perform_enqueued_jobs { example.run }
......
......@@ -129,6 +129,12 @@ RSpec.describe Projects::Alerting::NotifyService do
it { expect { subject }.to change { issue.reload.state }.from('opened').to('closed') }
it { expect { subject }.to change(ResourceStateEvent, :count).by(1) }
end
context 'with issue enabled' do
let(:issue_enabled) { true }
it_behaves_like 'does not process incident issues'
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment