Commit f257ce76 authored by Vitali Tatarintev's avatar Vitali Tatarintev Committed by Peter Leitzen

Move Operations->ErrorTracking->Incidents to CE

Move Incidents view with OperationsController,
and ProjectIncidentManagementSetting from EE to CE
parent f5030f1e
import IntegrationSettingsForm from '~/integrations/integration_settings_form'; import IntegrationSettingsForm from '~/integrations/integration_settings_form';
import PrometheusMetrics from '~/prometheus_metrics/prometheus_metrics'; import PrometheusMetrics from '~/prometheus_metrics/prometheus_metrics';
import initAlertsSettings from '~/alerts_service_settings';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
const prometheusSettingsWrapper = document.querySelector('.js-prometheus-metrics-monitoring'); const prometheusSettingsWrapper = document.querySelector('.js-prometheus-metrics-monitoring');
...@@ -10,4 +11,6 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -10,4 +11,6 @@ document.addEventListener('DOMContentLoaded', () => {
const prometheusMetrics = new PrometheusMetrics('.js-prometheus-metrics-monitoring'); const prometheusMetrics = new PrometheusMetrics('.js-prometheus-metrics-monitoring');
prometheusMetrics.loadActiveMetrics(); prometheusMetrics.loadActiveMetrics();
} }
initAlertsSettings(document.querySelector('.js-alerts-service-settings'));
}); });
...@@ -2334,7 +2334,7 @@ class Project < ApplicationRecord ...@@ -2334,7 +2334,7 @@ class Project < ApplicationRecord
end end
def alerts_service_activated? def alerts_service_activated?
false alerts_service&.active?
end end
def self_monitoring? def self_monitoring?
......
...@@ -260,6 +260,7 @@ class Service < ApplicationRecord ...@@ -260,6 +260,7 @@ class Service < ApplicationRecord
def self.available_services_names def self.available_services_names
service_names = %w[ service_names = %w[
alerts
asana asana
assembla assembla
bamboo bamboo
......
- return unless @project&.alerts_service_available?
.js-alerts-service-settings{ data: { activated: @service.activated?.to_s, .js-alerts-service-settings{ data: { activated: @service.activated?.to_s,
form_path: project_service_path(@project, @service.to_param), form_path: project_service_path(@project, @service.to_param),
authorization_key: @service.token, url: @service.url, learn_more_url: 'https://docs.gitlab.com/ee/user/project/integrations/generic_alerts.html' } } authorization_key: @service.token, url: @service.url, learn_more_url: 'https://docs.gitlab.com/ee/user/project/integrations/generic_alerts.html' } }
---
title: Makes the generic alerts endpoint available with the free tier
merge_request: 23339
author:
type: changed
# Generic alerts integration **(ULTIMATE)** # Generic alerts integration
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/13203) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.4. > - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/13203) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.4.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/issues/42640) to [GitLab Core](https://about.gitlab.com/pricing/) in 12.8.
GitLab can accept alerts from any source via a generic webhook receiver. GitLab can accept alerts from any source via a generic webhook receiver.
When you set up the generic alerts integration, a unique endpoint will When you set up the generic alerts integration, a unique endpoint will
......
import PrometheusMetrics from 'ee/prometheus_metrics/prometheus_metrics'; import PrometheusMetrics from 'ee/prometheus_metrics/prometheus_metrics';
import PrometheusAlerts from 'ee/prometheus_alerts'; import PrometheusAlerts from 'ee/prometheus_alerts';
import initAlertsSettings from 'ee/alerts_service_settings';
import IntegrationSettingsForm from '~/integrations/integration_settings_form'; import IntegrationSettingsForm from '~/integrations/integration_settings_form';
import initAlertsSettings from '~/alerts_service_settings';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
const integrationSettingsForm = new IntegrationSettingsForm('.js-integration-settings-form'); const integrationSettingsForm = new IntegrationSettingsForm('.js-integration-settings-form');
...@@ -18,6 +18,5 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -18,6 +18,5 @@ document.addEventListener('DOMContentLoaded', () => {
} }
PrometheusAlerts(); PrometheusAlerts();
initAlertsSettings(document.querySelector('.js-alerts-service-settings')); initAlertsSettings(document.querySelector('.js-alerts-service-settings'));
}); });
...@@ -549,7 +549,6 @@ module EE ...@@ -549,7 +549,6 @@ module EE
[].tap do |services| [].tap do |services|
services.push('jenkins', 'jenkins_deprecated') unless feature_available?(:jenkins_integration) services.push('jenkins', 'jenkins_deprecated') unless feature_available?(:jenkins_integration)
services.push('github') unless feature_available?(:github_project_service_integration) services.push('github') unless feature_available?(:github_project_service_integration)
services.push('alerts') unless alerts_service_available?
end end
end end
end end
...@@ -683,15 +682,6 @@ module EE ...@@ -683,15 +682,6 @@ module EE
end end
end end
def alerts_service_available?
feature_available?(:incident_management)
end
override :alerts_service_activated?
def alerts_service_activated?
alerts_service_available? && alerts_service&.active?
end
def package_already_taken?(package_name) def package_already_taken?(package_name)
namespace.root_ancestor.all_projects namespace.root_ancestor.all_projects
.joins(:packages) .joins(:packages)
......
...@@ -13,7 +13,6 @@ module EE ...@@ -13,7 +13,6 @@ module EE
github github
jenkins jenkins
jenkins_deprecated jenkins_deprecated
alerts
] ]
if ::Gitlab.dev_env_or_com? if ::Gitlab.dev_env_or_com?
......
...@@ -12,7 +12,6 @@ module EE ...@@ -12,7 +12,6 @@ module EE
override :services override :services
def services def services
super.merge( super.merge(
'alerts' => [],
'github' => [ 'github' => [
{ {
required: true, required: true,
...@@ -88,7 +87,6 @@ module EE ...@@ -88,7 +87,6 @@ module EE
::GithubService, ::GithubService,
::JenkinsService, ::JenkinsService,
::JenkinsDeprecatedService, ::JenkinsDeprecatedService,
::AlertsService,
*super *super
] ]
end end
......
...@@ -135,7 +135,6 @@ module EE ...@@ -135,7 +135,6 @@ module EE
epics: count(::Epic), epics: count(::Epic),
feature_flags: count(Operations::FeatureFlag), feature_flags: count(Operations::FeatureFlag),
geo_nodes: count(::GeoNode), geo_nodes: count(::GeoNode),
incident_issues: count_incident_issues,
ldap_group_links: count(::LdapGroupLink), ldap_group_links: count(::LdapGroupLink),
ldap_keys: count(::LDAPKey), ldap_keys: count(::LDAPKey),
ldap_users: count(::User.ldap), ldap_users: count(::User.ldap),
...@@ -146,7 +145,6 @@ module EE ...@@ -146,7 +145,6 @@ module EE
projects_with_packages: count(::Packages::Package.select('distinct project_id')), projects_with_packages: count(::Packages::Package.select('distinct project_id')),
projects_with_prometheus_alerts: count(PrometheusAlert.distinct_projects), projects_with_prometheus_alerts: count(PrometheusAlert.distinct_projects),
projects_with_tracing_enabled: count(ProjectTracingSetting), projects_with_tracing_enabled: count(ProjectTracingSetting),
projects_with_alerts_service_enabled: count(AlertsService.active),
template_repositories: count(::Project.with_repos_templates) + count(::Project.with_groups_level_repos_templates) template_repositories: count(::Project.with_repos_templates) + count(::Project.with_groups_level_repos_templates)
}, },
service_desk_counts, service_desk_counts,
...@@ -168,12 +166,6 @@ module EE ...@@ -168,12 +166,6 @@ module EE
{ epics_deepest_relationship_level: ::Epic.deepest_relationship_level.to_i } { epics_deepest_relationship_level: ::Epic.deepest_relationship_level.to_i }
end end
def count_incident_issues
return 0 unless License.feature_available?(:incident_management)
count(::Issue.authored(::User.alert_bot))
end
# Source: https://gitlab.com/gitlab-data/analytics/blob/master/transform/snowflake-dbt/data/ping_metrics_to_stage_mapping_data.csv # Source: https://gitlab.com/gitlab-data/analytics/blob/master/transform/snowflake-dbt/data/ping_metrics_to_stage_mapping_data.csv
def usage_activity_by_stage def usage_activity_by_stage
{ {
......
...@@ -25,8 +25,6 @@ describe Gitlab::UsageData do ...@@ -25,8 +25,6 @@ describe Gitlab::UsageData do
create(:prometheus_alert, project: projects[0]) create(:prometheus_alert, project: projects[0])
create(:prometheus_alert, project: projects[1]) create(:prometheus_alert, project: projects[1])
create(:alerts_service, project: projects[0])
create(:alerts_service, :inactive, project: projects[1])
create(:service, project: projects[1], type: 'JenkinsService', active: true) create(:service, project: projects[1], type: 'JenkinsService', active: true)
create(:package, project: projects[0]) create(:package, project: projects[0])
...@@ -90,7 +88,6 @@ describe Gitlab::UsageData do ...@@ -90,7 +88,6 @@ describe Gitlab::UsageData do
projects_with_packages projects_with_packages
projects_with_prometheus_alerts projects_with_prometheus_alerts
projects_with_tracing_enabled projects_with_tracing_enabled
projects_with_alerts_service_enabled
sast_jobs sast_jobs
design_management_designs_create design_management_designs_create
design_management_designs_update design_management_designs_update
...@@ -104,7 +101,6 @@ describe Gitlab::UsageData do ...@@ -104,7 +101,6 @@ describe Gitlab::UsageData do
expect(count_data[:projects_with_prometheus_alerts]).to eq(2) expect(count_data[:projects_with_prometheus_alerts]).to eq(2)
expect(count_data[:projects_with_packages]).to eq(2) expect(count_data[:projects_with_packages]).to eq(2)
expect(count_data[:feature_flags]).to eq(1) expect(count_data[:feature_flags]).to eq(1)
expect(count_data[:projects_with_alerts_service_enabled]).to eq(1)
end end
it 'has integer value for epic relationship level' do it 'has integer value for epic relationship level' do
...@@ -248,45 +244,4 @@ describe Gitlab::UsageData do ...@@ -248,45 +244,4 @@ describe Gitlab::UsageData do
expect(subject[:operations_dashboard_users_with_projects_added]).to eq(2) expect(subject[:operations_dashboard_users_with_projects_added]).to eq(2)
end end
end end
describe 'count incident_issues' do
let(:project) { create(:project) }
subject { described_class.data.dig(:counts, :incident_issues) }
before do
::User.support_bot # create the support bot user beforehand, because otherwise it is created when gathering usage data.
create(:issue, project: project) # non incident issue
end
context 'when incident_management feature is available' do
before do
stub_licensed_features(incident_management: true)
end
context 'with incident issues' do
before do
create_list(:issue, 2, project: project, author: User.alert_bot)
end
it { is_expected.to eq(2) }
end
context 'without incident_issues' do
it { is_expected.to eq(0) }
it { expect { subject }.to change(User, :count).by(1) }
end
end
context 'when incident_management feature is not available' do
before do
stub_licensed_features(incident_management: false)
end
it { is_expected.to eq(0) }
it { expect { subject }.not_to change(User, :count) }
end
end
end end
...@@ -1286,42 +1286,6 @@ describe Project do ...@@ -1286,42 +1286,6 @@ describe Project do
end end
end end
describe '#alerts_service_activated?' do
let!(:project) { create(:project) }
subject { project.alerts_service_activated? }
context 'when incident management feature available' do
before do
stub_licensed_features(incident_management: true)
end
context 'when project has an activated alerts service' do
before do
create(:alerts_service, project: project)
end
it { is_expected.to be_truthy }
end
context 'when project has an inactive alerts service' do
before do
create(:alerts_service, :inactive, project: project)
end
it { is_expected.to be_falsey }
end
end
context 'when incident feature is not available' do
before do
stub_licensed_features(incident_management: false)
end
it { is_expected.to be_falsey }
end
end
describe '#disabled_services' do describe '#disabled_services' do
let(:project) { build(:project) } let(:project) { build(:project) }
...@@ -1330,7 +1294,6 @@ describe Project do ...@@ -1330,7 +1294,6 @@ describe Project do
where(:license_feature, :disabled_services) do where(:license_feature, :disabled_services) do
:jenkins_integration | %w(jenkins jenkins_deprecated) :jenkins_integration | %w(jenkins jenkins_deprecated)
:github_project_service_integration | %w(github) :github_project_service_integration | %w(github)
:incident_management | %w(alerts)
end end
with_them do with_them do
......
...@@ -9,7 +9,6 @@ describe Service do ...@@ -9,7 +9,6 @@ describe Service do
github github
jenkins jenkins
jenkins_deprecated jenkins_deprecated
alerts
) )
end end
......
...@@ -583,37 +583,6 @@ describe User do ...@@ -583,37 +583,6 @@ describe User do
end end
end end
describe 'internal methods' do
let!(:user) { create(:user) }
let!(:ghost) { described_class.ghost }
let!(:support_bot) { described_class.support_bot }
let!(:alert_bot) { described_class.alert_bot }
let!(:visual_review_bot) { described_class.visual_review_bot }
let!(:non_internal) { [user] }
let!(:internal) { [ghost, support_bot, alert_bot, visual_review_bot] }
it 'returns non internal users' do
expect(described_class.internal).to eq(internal)
expect(internal.all?(&:internal?)).to eq(true)
end
it 'returns internal users' do
expect(described_class.non_internal).to eq(non_internal)
expect(non_internal.all?(&:internal?)).to eq(false)
end
describe '#bot?' do
it 'marks bot users' do
expect(user.bot?).to eq(false)
expect(ghost.bot?).to eq(false)
expect(support_bot.bot?).to eq(true)
expect(alert_bot.bot?).to eq(true)
expect(visual_review_bot.bot?).to eq(true)
end
end
end
describe '#using_license_seat?' do describe '#using_license_seat?' do
let(:user) { create(:user) } let(:user) { create(:user) }
......
# frozen_string_literal: true
require 'spec_helper'
describe Projects::Alerting::NotifyService do
let_it_be(:project, reload: true) { create(:project) }
before do
# We use `let_it_be(:project)` so we make sure to clear caches
project.clear_memoization(:licensed_feature_available)
end
shared_examples 'processes incident issues' do |amount|
let(:create_incident_service) { spy }
it 'processes issues' do
expect(IncidentManagement::ProcessAlertWorker)
.to receive(:perform_async)
.with(project.id, kind_of(Hash))
.exactly(amount).times
Sidekiq::Testing.inline! do
expect(subject.status).to eq(:success)
end
end
end
shared_examples 'does not process incident issues' do |http_status:|
it 'does not process issues' do
expect(IncidentManagement::ProcessAlertWorker)
.not_to receive(:perform_async)
expect(subject.status).to eq(:error)
expect(subject.http_status).to eq(http_status)
end
end
describe '#execute' do
let(:token) { 'invalid-token' }
let(:starts_at) { Time.now.change(usec: 0) }
let(:service) { described_class.new(project, nil, payload) }
let(:payload_raw) do
{
'title' => 'alert title',
'start_time' => starts_at.rfc3339
}
end
let(:payload) { ActionController::Parameters.new(payload_raw).permit! }
subject { service.execute(token) }
context 'with license' do
before do
stub_licensed_features(incident_management: true)
end
context 'with activated Alerts Service' do
let!(:alerts_service) { create(:alerts_service, project: project) }
context 'with valid token' do
let(:token) { alerts_service.token }
context 'with a valid payload' do
it_behaves_like 'processes incident issues', 1
end
context 'with an invalid payload' do
before do
allow(Gitlab::Alerting::NotificationPayloadParser)
.to receive(:call)
.and_raise(Gitlab::Alerting::NotificationPayloadParser::BadPayloadError)
end
it_behaves_like 'does not process incident issues', http_status: 400
end
end
context 'with invalid token' do
it_behaves_like 'does not process incident issues', http_status: 401
end
end
context 'with deactivated Alerts Service' do
let!(:alerts_service) { create(:alerts_service, :inactive, project: project) }
it_behaves_like 'does not process incident issues', http_status: 403
end
end
context 'without license' do
before do
stub_licensed_features(incident_management: false)
end
it_behaves_like 'does not process incident issues', http_status: 403
end
end
end
...@@ -161,6 +161,7 @@ module API ...@@ -161,6 +161,7 @@ module API
def self.services def self.services
{ {
'alerts' => [],
'asana' => [ 'asana' => [
{ {
required: true, required: true,
...@@ -729,6 +730,7 @@ module API ...@@ -729,6 +730,7 @@ module API
def self.service_classes def self.service_classes
[ [
::AlertsService,
::AsanaService, ::AsanaService,
::AssemblaService, ::AssemblaService,
::BambooService, ::BambooService,
......
...@@ -87,6 +87,7 @@ module Gitlab ...@@ -87,6 +87,7 @@ module Gitlab
issues_with_associated_zoom_link: count(ZoomMeeting.added_to_issue), issues_with_associated_zoom_link: count(ZoomMeeting.added_to_issue),
issues_using_zoom_quick_actions: count(ZoomMeeting.select(:issue_id).distinct), issues_using_zoom_quick_actions: count(ZoomMeeting.select(:issue_id).distinct),
issues_with_embedded_grafana_charts_approx: ::Gitlab::GrafanaEmbedUsageData.issue_count, issues_with_embedded_grafana_charts_approx: ::Gitlab::GrafanaEmbedUsageData.issue_count,
incident_issues: count(::Issue.authored(::User.alert_bot)),
keys: count(Key), keys: count(Key),
label_lists: count(List.label), label_lists: count(List.label),
lfs_objects: count(LfsObject), lfs_objects: count(LfsObject),
...@@ -98,6 +99,7 @@ module Gitlab ...@@ -98,6 +99,7 @@ module Gitlab
projects_imported_from_github: count(Project.where(import_type: 'github')), projects_imported_from_github: count(Project.where(import_type: 'github')),
projects_with_repositories_enabled: count(ProjectFeature.where('repository_access_level > ?', ProjectFeature::DISABLED)), projects_with_repositories_enabled: count(ProjectFeature.where('repository_access_level > ?', ProjectFeature::DISABLED)),
projects_with_error_tracking_enabled: count(::ErrorTracking::ProjectErrorTrackingSetting.where(enabled: true)), projects_with_error_tracking_enabled: count(::ErrorTracking::ProjectErrorTrackingSetting.where(enabled: true)),
projects_with_alerts_service_enabled: count(AlertsService.active),
protected_branches: count(ProtectedBranch), protected_branches: count(ProtectedBranch),
releases: count(Release), releases: count(Release),
remote_mirrors: count(RemoteMirror), remote_mirrors: count(RemoteMirror),
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
describe 'User activates Alerts' do describe 'User activates Alerts', :js do
let_it_be(:project) { create(:project) } let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
...@@ -14,59 +14,37 @@ describe 'User activates Alerts' do ...@@ -14,59 +14,37 @@ describe 'User activates Alerts' do
project.add_maintainer(user) project.add_maintainer(user)
end end
shared_examples 'no service' do context 'when service is deactivated' do
it 'cannot see the service' do it 'activates service' do
visit_project_services visit_project_services
expect(page).not_to have_link(service_title) expect(page).to have_link(service_title)
end click_link(service_title)
end
context 'when feature available', :js do
before do
stub_licensed_features(incident_management: true)
end
context 'when service is deactivated' do
it 'activates service' do
visit_project_services
expect(page).to have_link(service_title)
click_link(service_title)
expect(page).not_to have_active_service
click_activate_service expect(page).not_to have_active_service
wait_for_requests
expect(page).to have_active_service click_activate_service
end wait_for_requests
end
context 'when service is activated' do
before do
visit_alerts_service
click_activate_service
end
it 're-generates key' do
expect(reset_key.value).to be_blank
click_reset_key
click_confirm_reset_key
wait_for_requests
expect(reset_key.value).to be_present expect(page).to have_active_service
end
end end
end end
context 'when feature unavailable' do context 'when service is activated' do
before do before do
stub_licensed_features(incident_management: false) visit_alerts_service
click_activate_service
end end
it_behaves_like 'no service' it 're-generates key' do
expect(reset_key.value).to be_blank
click_reset_key
click_confirm_reset_key
wait_for_requests
expect(reset_key.value).to be_present
end
end end
private private
......
...@@ -2,7 +2,7 @@ import axios from 'axios'; ...@@ -2,7 +2,7 @@ import axios from 'axios';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { GlModal } from '@gitlab/ui'; import { GlModal } from '@gitlab/ui';
import AlertsServiceForm from 'ee/alerts_service_settings/components/alerts_service_form.vue'; import AlertsServiceForm from '~/alerts_service_settings/components/alerts_service_form.vue';
import ToggleButton from '~/vue_shared/components/toggle_button.vue'; import ToggleButton from '~/vue_shared/components/toggle_button.vue';
import createFlash from '~/flash'; import createFlash from '~/flash';
......
...@@ -22,6 +22,10 @@ describe Gitlab::UsageData do ...@@ -22,6 +22,10 @@ describe Gitlab::UsageData do
create(:service, project: projects[2], type: 'CustomIssueTrackerService', active: true) create(:service, project: projects[2], type: 'CustomIssueTrackerService', active: true)
create(:project_error_tracking_setting, project: projects[0]) create(:project_error_tracking_setting, project: projects[0])
create(:project_error_tracking_setting, project: projects[1], enabled: false) create(:project_error_tracking_setting, project: projects[1], enabled: false)
create(:alerts_service, project: projects[0])
create(:alerts_service, :inactive, project: projects[1])
create_list(:issue, 2, project: projects[0], author: User.alert_bot)
create_list(:issue, 2, project: projects[1], author: User.alert_bot)
create_list(:issue, 4, project: projects[0]) create_list(:issue, 4, project: projects[0])
create(:zoom_meeting, project: projects[0], issue: projects[0].issues[0], issue_status: :added) create(:zoom_meeting, project: projects[0], issue: projects[0].issues[0], issue_status: :added)
create_list(:zoom_meeting, 2, project: projects[0], issue: projects[0].issues[1], issue_status: :removed) create_list(:zoom_meeting, 2, project: projects[0], issue: projects[0].issues[1], issue_status: :removed)
...@@ -159,6 +163,7 @@ describe Gitlab::UsageData do ...@@ -159,6 +163,7 @@ describe Gitlab::UsageData do
issues_with_associated_zoom_link issues_with_associated_zoom_link
issues_using_zoom_quick_actions issues_using_zoom_quick_actions
issues_with_embedded_grafana_charts_approx issues_with_embedded_grafana_charts_approx
incident_issues
keys keys
label_lists label_lists
labels labels
...@@ -183,6 +188,7 @@ describe Gitlab::UsageData do ...@@ -183,6 +188,7 @@ describe Gitlab::UsageData do
projects_prometheus_active projects_prometheus_active
projects_with_repositories_enabled projects_with_repositories_enabled
projects_with_error_tracking_enabled projects_with_error_tracking_enabled
projects_with_alerts_service_enabled
pages_domains pages_domains
protected_branches protected_branches
releases releases
...@@ -220,10 +226,12 @@ describe Gitlab::UsageData do ...@@ -220,10 +226,12 @@ describe Gitlab::UsageData do
expect(count_data[:projects_mattermost_active]).to eq(0) expect(count_data[:projects_mattermost_active]).to eq(0)
expect(count_data[:projects_with_repositories_enabled]).to eq(3) expect(count_data[:projects_with_repositories_enabled]).to eq(3)
expect(count_data[:projects_with_error_tracking_enabled]).to eq(1) expect(count_data[:projects_with_error_tracking_enabled]).to eq(1)
expect(count_data[:projects_with_alerts_service_enabled]).to eq(1)
expect(count_data[:issues_created_from_gitlab_error_tracking_ui]).to eq(1) expect(count_data[:issues_created_from_gitlab_error_tracking_ui]).to eq(1)
expect(count_data[:issues_with_associated_zoom_link]).to eq(2) expect(count_data[:issues_with_associated_zoom_link]).to eq(2)
expect(count_data[:issues_using_zoom_quick_actions]).to eq(3) expect(count_data[:issues_using_zoom_quick_actions]).to eq(3)
expect(count_data[:issues_with_embedded_grafana_charts_approx]).to eq(2) expect(count_data[:issues_with_embedded_grafana_charts_approx]).to eq(2)
expect(count_data[:incident_issues]).to eq(4)
expect(count_data[:clusters_enabled]).to eq(4) expect(count_data[:clusters_enabled]).to eq(4)
expect(count_data[:project_clusters_enabled]).to eq(3) expect(count_data[:project_clusters_enabled]).to eq(3)
......
...@@ -5607,7 +5607,21 @@ describe Project do ...@@ -5607,7 +5607,21 @@ describe Project do
subject { project.alerts_service_activated? } subject { project.alerts_service_activated? }
it { is_expected.to be_falsey } context 'when project has an activated alerts service' do
before do
create(:alerts_service, project: project)
end
it { is_expected.to be_truthy }
end
context 'when project has an inactive alerts service' do
before do
create(:alerts_service, :inactive, project: project)
end
it { is_expected.to be_falsey }
end
end end
describe '#self_monitoring?' do describe '#self_monitoring?' do
......
...@@ -5,6 +5,26 @@ require 'spec_helper' ...@@ -5,6 +5,26 @@ require 'spec_helper'
describe Projects::Alerting::NotifyService do describe Projects::Alerting::NotifyService do
let_it_be(:project, reload: true) { create(:project) } let_it_be(:project, reload: true) { create(:project) }
before do
# We use `let_it_be(:project)` so we make sure to clear caches
project.clear_memoization(:licensed_feature_available)
end
shared_examples 'processes incident issues' do |amount|
let(:create_incident_service) { spy }
it 'processes issues' do
expect(IncidentManagement::ProcessAlertWorker)
.to receive(:perform_async)
.with(project.id, kind_of(Hash))
.exactly(amount).times
Sidekiq::Testing.inline! do
expect(subject.status).to eq(:success)
end
end
end
shared_examples 'does not process incident issues' do |http_status:| shared_examples 'does not process incident issues' do |http_status:|
it 'does not process issues' do it 'does not process issues' do
expect(IncidentManagement::ProcessAlertWorker) expect(IncidentManagement::ProcessAlertWorker)
...@@ -29,6 +49,36 @@ describe Projects::Alerting::NotifyService do ...@@ -29,6 +49,36 @@ describe Projects::Alerting::NotifyService do
subject { service.execute(token) } subject { service.execute(token) }
it_behaves_like 'does not process incident issues', http_status: 403 context 'with activated Alerts Service' do
let!(:alerts_service) { create(:alerts_service, project: project) }
context 'with valid token' do
let(:token) { alerts_service.token }
context 'with a valid payload' do
it_behaves_like 'processes incident issues', 1
end
context 'with an invalid payload' do
before do
allow(Gitlab::Alerting::NotificationPayloadParser)
.to receive(:call)
.and_raise(Gitlab::Alerting::NotificationPayloadParser::BadPayloadError)
end
it_behaves_like 'does not process incident issues', http_status: 400
end
end
context 'with invalid token' do
it_behaves_like 'does not process incident issues', http_status: 401
end
end
context 'with deactivated Alerts Service' do
let!(:alerts_service) { create(:alerts_service, :inactive, project: project) }
it_behaves_like 'does not process incident issues', http_status: 403
end
end end
end end
...@@ -32,8 +32,7 @@ Service.available_services_names.each do |service| ...@@ -32,8 +32,7 @@ Service.available_services_names.each do |service|
{ {
'github' => :github_project_service_integration, 'github' => :github_project_service_integration,
'jenkins' => :jenkins_integration, 'jenkins' => :jenkins_integration,
'jenkins_deprecated' => :jenkins_integration, 'jenkins_deprecated' => :jenkins_integration
'alerts' => :incident_management
} }
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