Commit e4e5f091 authored by David O'Regan's avatar David O'Regan Committed by Gabriel Mazetto

Implement Opsgenie MVC in AlertsService

This is just an MVC and we already know that it's unlikely that
future iterations will be using any of store data.

Therefor, we decided to store the data needed as service properties
and not in a separate database table to avoid churn.
parent 842f1257
<script> <script>
import { GlEmptyState, GlButton } from '@gitlab/ui'; import { GlEmptyState, GlButton } from '@gitlab/ui';
import { s__ } from '~/locale';
export default { export default {
i18n: {
emptyState: {
opsgenie: {
title: s__('AlertManagement|Opsgenie is enabled'),
info: s__(
'AlertManagement|You have enabled the Opsgenie integration. Your alerts will be visible directly in Opsgenie.',
),
buttonText: s__('AlertManagement|View alerts in Opsgenie'),
},
gitlab: {
title: s__('AlertManagement|Surface alerts in GitLab'),
info: s__(
'AlertManagement|Display alerts from all your monitoring tools directly within GitLab. Streamline the investigation of your alerts and the escalation of alerts to incidents.',
),
buttonText: s__('AlertManagement|Authorize external service'),
},
},
moreInformation: s__('AlertManagement|More information'),
},
components: { components: {
GlEmptyState, GlEmptyState,
GlButton, GlButton,
...@@ -19,29 +39,49 @@ export default { ...@@ -19,29 +39,49 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
opsgenieMvcEnabled: {
type: Boolean,
required: false,
default: false,
},
opsgenieMvcTargetUrl: {
type: String,
required: false,
default: '',
},
},
computed: {
emptyState() {
return {
...(this.opsgenieMvcEnabled
? this.$options.i18n.emptyState.opsgenie
: this.$options.i18n.emptyState.gitlab),
link: this.opsgenieMvcEnabled ? this.opsgenieMvcTargetUrl : this.enableAlertManagementPath,
};
},
alertsCanBeEnabled() {
return this.userCanEnableAlertManagement || this.opsgenieMvcEnabled;
},
}, },
}; };
</script> </script>
<template> <template>
<div> <div>
<gl-empty-state <gl-empty-state :title="emptyState.title" :svg-path="emptyAlertSvgPath">
:title="s__('AlertManagement|Surface alerts in GitLab')"
:svg-path="emptyAlertSvgPath"
>
<template #description> <template #description>
<div class="d-block"> <div class="gl-display-block">
<span>{{ <span>{{ emptyState.info }}</span>
s__( <a
'AlertManagement|Display alerts from all your monitoring tools directly within GitLab. Streamline the investigation of your alerts and the escalation of alerts to incidents.', v-if="!opsgenieMvcEnabled"
) href="/help/user/project/operations/alert_management.html"
}}</span> target="_blank"
<a href="/help/user/project/operations/alert_management.html" target="_blank"> >
{{ s__('AlertManagement|More information') }} {{ $options.i18n.moreInformation }}
</a> </a>
</div> </div>
<div v-if="userCanEnableAlertManagement" class="d-block center pt-4"> <div v-if="alertsCanBeEnabled" class="gl-display-block center gl-pt-4">
<gl-button category="primary" variant="success" :href="enableAlertManagementPath"> <gl-button category="primary" variant="success" :href="emptyState.link">
{{ s__('AlertManagement|Authorize external service') }} {{ emptyState.buttonText }}
</gl-button> </gl-button>
</div> </div>
</template> </template>
......
...@@ -34,6 +34,16 @@ export default { ...@@ -34,6 +34,16 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
opsgenieMvcEnabled: {
type: Boolean,
required: false,
default: false,
},
opsgenieMvcTargetUrl: {
type: String,
required: false,
default: '',
},
}, },
mounted() { mounted() {
this.trackPageViews(); this.trackPageViews();
...@@ -58,6 +68,8 @@ export default { ...@@ -58,6 +68,8 @@ export default {
:empty-alert-svg-path="emptyAlertSvgPath" :empty-alert-svg-path="emptyAlertSvgPath"
:enable-alert-management-path="enableAlertManagementPath" :enable-alert-management-path="enableAlertManagementPath"
:user-can-enable-alert-management="userCanEnableAlertManagement" :user-can-enable-alert-management="userCanEnableAlertManagement"
:opsgenie-mvc-enabled="opsgenieMvcEnabled"
:opsgenie-mvc-target-url="opsgenieMvcTargetUrl"
/> />
</div> </div>
</template> </template>
...@@ -16,11 +16,13 @@ export default () => { ...@@ -16,11 +16,13 @@ export default () => {
enableAlertManagementPath, enableAlertManagementPath,
emptyAlertSvgPath, emptyAlertSvgPath,
populatingAlertsHelpUrl, populatingAlertsHelpUrl,
opsgenieMvcTargetUrl,
} = domEl.dataset; } = domEl.dataset;
let { alertManagementEnabled, userCanEnableAlertManagement } = domEl.dataset; let { alertManagementEnabled, userCanEnableAlertManagement, opsgenieMvcEnabled } = domEl.dataset;
alertManagementEnabled = parseBoolean(alertManagementEnabled); alertManagementEnabled = parseBoolean(alertManagementEnabled);
userCanEnableAlertManagement = parseBoolean(userCanEnableAlertManagement); userCanEnableAlertManagement = parseBoolean(userCanEnableAlertManagement);
opsgenieMvcEnabled = parseBoolean(opsgenieMvcEnabled);
const apolloProvider = new VueApollo({ const apolloProvider = new VueApollo({
defaultClient: createDefaultClient( defaultClient: createDefaultClient(
...@@ -54,6 +56,8 @@ export default () => { ...@@ -54,6 +56,8 @@ export default () => {
emptyAlertSvgPath, emptyAlertSvgPath,
alertManagementEnabled, alertManagementEnabled,
userCanEnableAlertManagement, userCanEnableAlertManagement,
opsgenieMvcTargetUrl,
opsgenieMvcEnabled,
}, },
}); });
}, },
......
...@@ -16,7 +16,6 @@ export const i18n = { ...@@ -16,7 +16,6 @@ export const i18n = {
errorApiUrlMsg: s__( errorApiUrlMsg: s__(
'AlertSettings|There was an error while trying to enable the alert settings. Please ensure you are using a valid URL.', 'AlertSettings|There was an error while trying to enable the alert settings. Please ensure you are using a valid URL.',
), ),
prometheusApiPlaceholder: s__('AlertSettings|http://prometheus.example.com/'),
restKeyInfo: s__( restKeyInfo: s__(
'AlertSettings|Resetting the authorization key for this project will require updating the authorization key in every alert source it is enabled in.', 'AlertSettings|Resetting the authorization key for this project will require updating the authorization key in every alert source it is enabled in.',
), ),
...@@ -29,7 +28,7 @@ export const i18n = { ...@@ -29,7 +28,7 @@ export const i18n = {
resetKey: s__('AlertSettings|Reset key'), resetKey: s__('AlertSettings|Reset key'),
copyToClipboard: s__('AlertSettings|Copy'), copyToClipboard: s__('AlertSettings|Copy'),
integrationsLabel: s__('AlertSettings|Integrations'), integrationsLabel: s__('AlertSettings|Integrations'),
apiBaseUrlLabel: s__('AlertSettings|Prometheus API Base URL'), apiBaseUrlLabel: s__('AlertSettings|API URL'),
authKeyLabel: s__('AlertSettings|Authorization key'), authKeyLabel: s__('AlertSettings|Authorization key'),
urlLabel: s__('AlertSettings|Webhook URL'), urlLabel: s__('AlertSettings|Webhook URL'),
activeLabel: s__('AlertSettings|Active'), activeLabel: s__('AlertSettings|Active'),
...@@ -47,6 +46,10 @@ export const i18n = { ...@@ -47,6 +46,10 @@ export const i18n = {
export const serviceOptions = [ export const serviceOptions = [
{ value: 'generic', text: s__('AlertSettings|Generic') }, { value: 'generic', text: s__('AlertSettings|Generic') },
{ value: 'prometheus', text: s__('AlertSettings|External Prometheus') }, { value: 'prometheus', text: s__('AlertSettings|External Prometheus') },
{ value: 'opsgenie', text: s__('AlertSettings|Opsgenie') },
]; ];
export const JSON_VALIDATE_DELAY = 250; export const JSON_VALIDATE_DELAY = 250;
export const targetPrometheusUrlPlaceholder = 'http://prometheus.example.com/';
export const targetOpsgenieUrlPlaceholder = 'https://app.opsgenie.com/alert/list/';
...@@ -20,33 +20,47 @@ export default el => { ...@@ -20,33 +20,47 @@ export default el => {
formPath, formPath,
authorizationKey, authorizationKey,
url, url,
opsgenieMvcAvailable,
opsgenieMvcFormPath,
opsgenieMvcEnabled,
opsgenieMvcTargetUrl,
} = el.dataset; } = el.dataset;
const activated = parseBoolean(activatedStr); const genericActivated = parseBoolean(activatedStr);
const prometheusIsActivated = parseBoolean(prometheusActivated); const prometheusIsActivated = parseBoolean(prometheusActivated);
const opsgenieMvcActivated = parseBoolean(opsgenieMvcEnabled);
const opsgenieMvcIsAvailable = parseBoolean(opsgenieMvcAvailable);
const props = {
prometheus: {
activated: prometheusIsActivated,
prometheusUrl,
prometheusAuthorizationKey,
prometheusFormPath,
prometheusResetKeyPath,
prometheusApiUrl,
},
generic: {
alertsSetupUrl,
alertsUsageUrl,
activated: genericActivated,
formPath,
initialAuthorizationKey: authorizationKey,
url,
},
opsgenie: {
formPath: opsgenieMvcFormPath,
activated: opsgenieMvcActivated,
opsgenieMvcTargetUrl,
opsgenieMvcIsAvailable,
},
};
return new Vue({ return new Vue({
el, el,
render(createElement) { render(createElement) {
return createElement(AlertSettingsForm, { return createElement(AlertSettingsForm, {
props: { props,
prometheus: {
prometheusIsActivated,
prometheusUrl,
prometheusAuthorizationKey,
prometheusFormPath,
prometheusResetKeyPath,
prometheusApiUrl,
},
generic: {
alertsSetupUrl,
alertsUsageUrl,
initialActivated: activated,
formPath,
initialAuthorizationKey: authorizationKey,
url,
},
},
}); });
}, },
}); });
......
...@@ -27,3 +27,5 @@ module Projects::AlertManagementHelper ...@@ -27,3 +27,5 @@ module Projects::AlertManagementHelper
!!(project.alerts_service_activated? || project.prometheus_service_active?) !!(project.alerts_service_activated? || project.prometheus_service_active?)
end end
end end
Projects::AlertManagementHelper.prepend_if_ee('EE::Projects::AlertManagementHelper')
...@@ -78,3 +78,5 @@ class AlertsService < Service ...@@ -78,3 +78,5 @@ class AlertsService < Service
Gitlab::Routing.url_helpers Gitlab::Routing.url_helpers
end end
end end
AlertsService.prepend_if_ee('EE::AlertsService')
...@@ -10,6 +10,8 @@ module EE ...@@ -10,6 +10,8 @@ module EE
:multiproject_enabled, :multiproject_enabled,
:pass_unstable, :pass_unstable,
:project_name, :project_name,
:opsgenie_mvc_enabled,
:opsgenie_mvc_target_url,
:repository_url, :repository_url,
:static_context :static_context
].freeze ].freeze
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
module EE module EE
module OperationsHelper module OperationsHelper
extend ::Gitlab::Utils::Override
def operations_data def operations_data
{ {
'add-path' => add_operations_project_path, 'add-path' => add_operations_project_path,
...@@ -32,5 +34,23 @@ module EE ...@@ -32,5 +34,23 @@ module EE
'aws-secret-key' => status_page_setting.masked_aws_secret_key 'aws-secret-key' => status_page_setting.masked_aws_secret_key
} }
end end
override :alerts_settings_data
def alerts_settings_data(disabled: false)
super.merge(opsgenie_mvc_data)
end
private
def opsgenie_mvc_data
return {} unless alerts_service.opsgenie_mvc_available?
{
'opsgenie_mvc_available' => 'true',
'opsgenie_mvc_form_path' => scoped_integration_path(alerts_service),
'opsgenie_mvc_enabled' => alerts_service.opsgenie_mvc_enabled?.to_s,
'opsgenie_mvc_target_url' => alerts_service.opsgenie_mvc_target_url.to_s
}
end
end end
end end
# frozen_string_literal: true
module EE
module Projects
module AlertManagementHelper
extend ::Gitlab::Utils::Override
override :alert_management_data
def alert_management_data(current_user, project)
super.merge(
alert_management_opsgenie_mvc_data(project.alerts_service)
)
end
private
def alert_management_opsgenie_mvc_data(alerts_service)
return {} unless alerts_service&.opsgenie_mvc_available?
{
'opsgenie_mvc_available' => 'true',
'opsgenie_mvc_enabled' => alerts_service.opsgenie_mvc_enabled?.to_s,
'opsgenie_mvc_target_url' => alerts_service.opsgenie_mvc_target_url.to_s
}
end
end
end
end
# frozen_string_literal: true
module EE
module AlertsService
extend ActiveSupport::Concern
prepended do
boolean_accessor :opsgenie_mvc_enabled
prop_accessor :opsgenie_mvc_target_url
validates :opsgenie_mvc_target_url, presence: true, public_url: true,
if: :opsgenie_mvc_enabled?
end
def opsgenie_mvc_available?
return false if instance? || template?
project.feature_available?(:opsgenie_integration)
end
end
end
...@@ -92,6 +92,7 @@ class License < ApplicationRecord ...@@ -92,6 +92,7 @@ class License < ApplicationRecord
multiple_group_issue_boards multiple_group_issue_boards
object_storage object_storage
operations_dashboard operations_dashboard
opsgenie_integration
packages packages
pages_size_limit pages_size_limit
productivity_analytics productivity_analytics
......
---
title: Add MVC for Opsgenie integration
merge_request: 36199
author:
type: added
...@@ -2,16 +2,20 @@ ...@@ -2,16 +2,20 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe OperationsHelper do RSpec.describe OperationsHelper, :routing do
let_it_be(:project) { create(:project, :private) }
before do
helper.instance_variable_set(:@project, project)
end
describe '#status_page_settings_data' do describe '#status_page_settings_data' do
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :private) }
let_it_be(:status_page_setting) { project.build_status_page_setting } let_it_be(:status_page_setting) { project.build_status_page_setting }
subject { helper.status_page_settings_data } subject { helper.status_page_settings_data }
before do before do
helper.instance_variable_set(:@project, project)
allow(helper).to receive(:status_page_setting) { status_page_setting } allow(helper).to receive(:status_page_setting) { status_page_setting }
allow(helper).to receive(:current_user) { user } allow(helper).to receive(:current_user) { user }
allow(helper) allow(helper)
...@@ -52,7 +56,7 @@ RSpec.describe OperationsHelper do ...@@ -52,7 +56,7 @@ RSpec.describe OperationsHelper do
end end
context 'setting exists' do context 'setting exists' do
let(:status_page_setting) { create(:status_page_setting) } let(:status_page_setting) { create(:status_page_setting, project: project) }
it 'returns the correct values' do it 'returns the correct values' do
expect(subject).to eq( expect(subject).to eq(
...@@ -67,4 +71,49 @@ RSpec.describe OperationsHelper do ...@@ -67,4 +71,49 @@ RSpec.describe OperationsHelper do
end end
end end
end end
describe '#alerts_settings_data' do
subject { helper.alerts_settings_data }
describe 'Opsgenie MVC attributes' do
let_it_be(:alerts_service) do
create(:alerts_service,
project: project,
opsgenie_mvc_enabled: false,
opsgenie_mvc_target_url: 'https://appname.app.opsgenie.com/alert/list'
)
end
let_it_be(:prometheus_service) { build_stubbed(:prometheus_service) }
before do
allow(helper).to receive(:alerts_service).and_return(alerts_service)
allow(helper).to receive(:prometheus_service).and_return(prometheus_service)
allow(alerts_service).to receive(:opsgenie_mvc_available?).and_return(opsgenie_available)
end
context 'when available' do
let(:opsgenie_available) { true }
it do
is_expected.to include(
'opsgenie_mvc_available' => 'true',
'opsgenie_mvc_form_path' => project_service_path(project, alerts_service),
'opsgenie_mvc_enabled' => 'false',
'opsgenie_mvc_target_url' => 'https://appname.app.opsgenie.com/alert/list'
)
end
end
context 'when not available' do
let(:opsgenie_keys) do
%w[opsgenie_mvc_available opsgenie_mvc_enabled opsgenie_mvc_form_path opsgenie_mvc_target_url]
end
let(:opsgenie_available) { false }
it { is_expected.not_to include(opsgenie_keys) }
end
end
end
end end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Projects::AlertManagementHelper do
let(:project) { build_stubbed(:project) }
let(:current_user) { build_stubbed(:user) }
before do
allow(helper).to receive(:can?)
.with(current_user, :admin_operations, project) { true }
end
describe '#alert_management_data' do
let(:alerts_service) do
build_stubbed(:alerts_service,
project: project,
opsgenie_mvc_enabled: false,
opsgenie_mvc_target_url: 'https://appname.app.opsgenie.com/alert/list'
)
end
subject { helper.alert_management_data(current_user, project) }
before do
allow(project).to receive(:alerts_service).and_return(alerts_service)
allow(alerts_service).to receive(:opsgenie_mvc_available?)
.and_return(opsgenie_available)
end
context 'when available' do
let(:opsgenie_available) { true }
it do
is_expected.to include(
'opsgenie_mvc_available' => 'true',
'opsgenie_mvc_enabled' => 'false',
'opsgenie_mvc_target_url' => 'https://appname.app.opsgenie.com/alert/list'
)
end
end
context 'when not available' do
let(:opsgenie_keys) do
%w[opsgenie_mvc_available opsgenie_mvc_enabled opsgenie_mvc_target_url]
end
let(:opsgenie_available) { false }
it { is_expected.not_to include(opsgenie_keys) }
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe AlertsService do
let(:service) { build_stubbed(:alerts_service) }
describe 'Opsgenie MVC' do
describe '#opsgenie_mvc_target_url' do
context 'when enabled' do
before do
service.opsgenie_mvc_enabled = true
end
it 'validates presence' do
expect(service).to validate_presence_of(:opsgenie_mvc_target_url)
end
describe 'enforces public urls' do
where(:url, :valid) do
[
['https://appname.app.opsgenie.com/alert/list', true],
['https://example.com', true],
['http://example.com', true],
['http://0.0.0.0', false],
['http://127.0.0.1', false],
['ftp://example.com', false],
['invalid url', false]
]
end
with_them do
before do
service.opsgenie_mvc_target_url = url
end
if params[:valid]
it { expect(service).to be_valid }
else
it { expect(service).to be_invalid }
end
end
end
end
context 'when disabled' do
before do
service.opsgenie_mvc_enabled = false
end
it 'does not validate presence' do
expect(service).not_to validate_presence_of(:opsgenie_mvc_target_url)
end
it 'allows any value' do
service.opsgenie_mvc_target_url = 'any value'
expect(service).to be_valid
end
end
end
describe '#opsgenie_mvc_available?' do
subject { service.opsgenie_mvc_available? }
before do
stub_licensed_features(opsgenie_integration: true)
end
context 'when license is available' do
it { is_expected.to eq(true) }
end
context 'when license is not available' do
before do
stub_licensed_features(opsgenie_integration: false)
end
it { is_expected.to eq(false) }
end
context 'when template service' do
let(:service) { build_stubbed(:alerts_service, :template) }
it { is_expected.to eq(false) }
end
context 'when instance service' do
let(:service) { build_stubbed(:alerts_service, :instance) }
it { is_expected.to eq(false) }
end
end
end
end
...@@ -2060,6 +2060,9 @@ msgstr "" ...@@ -2060,6 +2060,9 @@ msgstr ""
msgid "AlertManagement|Open" msgid "AlertManagement|Open"
msgstr "" msgstr ""
msgid "AlertManagement|Opsgenie is enabled"
msgstr ""
msgid "AlertManagement|Overview" msgid "AlertManagement|Overview"
msgstr "" msgstr ""
...@@ -2117,15 +2120,24 @@ msgstr "" ...@@ -2117,15 +2120,24 @@ msgstr ""
msgid "AlertManagement|Unknown" msgid "AlertManagement|Unknown"
msgstr "" msgstr ""
msgid "AlertManagement|View alerts in Opsgenie"
msgstr ""
msgid "AlertManagement|View issue" msgid "AlertManagement|View issue"
msgstr "" msgstr ""
msgid "AlertManagement|You have enabled the Opsgenie integration. Your alerts will be visible directly in Opsgenie."
msgstr ""
msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint." msgid "AlertService|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
msgstr "" msgstr ""
msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page." msgid "AlertService|You must provide this URL and authorization key to authorize an external service to send alerts to GitLab. You can provide this URL and key to multiple services. After configuring an external service, alerts from your service will display on the GitLab %{linkStart}Alerts%{linkEnd} page."
msgstr "" msgstr ""
msgid "AlertSettings|API URL"
msgstr ""
msgid "AlertSettings|Active" msgid "AlertSettings|Active"
msgstr "" msgstr ""
...@@ -2162,7 +2174,7 @@ msgstr "" ...@@ -2162,7 +2174,7 @@ msgstr ""
msgid "AlertSettings|Learn more about our %{linkStart}upcoming integrations%{linkEnd}" msgid "AlertSettings|Learn more about our %{linkStart}upcoming integrations%{linkEnd}"
msgstr "" msgstr ""
msgid "AlertSettings|Prometheus API Base URL" msgid "AlertSettings|Opsgenie"
msgstr "" msgstr ""
msgid "AlertSettings|Reset key" msgid "AlertSettings|Reset key"
...@@ -2207,9 +2219,6 @@ msgstr "" ...@@ -2207,9 +2219,6 @@ msgstr ""
msgid "AlertSettings|Your changes were successfully updated." msgid "AlertSettings|Your changes were successfully updated."
msgstr "" msgstr ""
msgid "AlertSettings|http://prometheus.example.com/"
msgstr ""
msgid "Alerts" msgid "Alerts"
msgstr "" msgstr ""
......
...@@ -10,6 +10,7 @@ describe('AlertManagementEmptyState', () => { ...@@ -10,6 +10,7 @@ describe('AlertManagementEmptyState', () => {
alertManagementEnabled: false, alertManagementEnabled: false,
userCanEnableAlertManagement: false, userCanEnableAlertManagement: false,
}, },
stubs = {},
} = {}) { } = {}) {
wrapper = shallowMount(AlertManagementEmptyState, { wrapper = shallowMount(AlertManagementEmptyState, {
propsData: { propsData: {
...@@ -17,6 +18,7 @@ describe('AlertManagementEmptyState', () => { ...@@ -17,6 +18,7 @@ describe('AlertManagementEmptyState', () => {
emptyAlertSvgPath: 'illustration/path', emptyAlertSvgPath: 'illustration/path',
...props, ...props,
}, },
stubs,
}); });
} }
...@@ -30,9 +32,23 @@ describe('AlertManagementEmptyState', () => { ...@@ -30,9 +32,23 @@ describe('AlertManagementEmptyState', () => {
} }
}); });
const EmptyState = () => wrapper.find(GlEmptyState);
describe('Empty state', () => { describe('Empty state', () => {
it('shows empty state', () => { it('shows empty state', () => {
expect(wrapper.find(GlEmptyState).exists()).toBe(true); expect(EmptyState().exists()).toBe(true);
});
it('show OpsGenie integration state when OpsGenie mcv is true', () => {
mountComponent({
props: {
alertManagementEnabled: false,
userCanEnableAlertManagement: false,
opsgenieMvcEnabled: true,
opsgenieMvcTargetUrl: 'https://opsgenie-url.com',
},
});
expect(EmptyState().props('title')).toBe('Opsgenie is enabled');
}); });
}); });
}); });
...@@ -13,20 +13,20 @@ exports[`AlertsSettingsForm with default values renders the initial template 1`] ...@@ -13,20 +13,20 @@ exports[`AlertsSettingsForm with default values renders the initial template 1`]
</div> </div>
<gl-form-stub> <gl-form-stub>
<gl-form-group-stub label=\\"Integrations\\" label-for=\\"integrations\\" label-class=\\"label-bold\\"> <gl-form-group-stub label=\\"Integrations\\" label-for=\\"integrations\\" label-class=\\"label-bold\\">
<gl-form-select-stub options=\\"[object Object],[object Object]\\" data-testid=\\"alert-settings-select\\" value=\\"generic\\"></gl-form-select-stub> <span class=\\"gl-text-gray-400\\"><gl-sprintf-stub message=\\"Learn more about our %{linkStart}upcoming integrations%{linkEnd}\\"></gl-sprintf-stub></span> <gl-form-select-stub options=\\"[object Object],[object Object],[object Object]\\" data-testid=\\"alert-settings-select\\" value=\\"generic\\"></gl-form-select-stub> <span class=\\"gl-text-gray-400\\"><gl-sprintf-stub message=\\"Learn more about our %{linkStart}upcoming integrations%{linkEnd}\\"></gl-sprintf-stub></span>
</gl-form-group-stub> </gl-form-group-stub>
<gl-form-group-stub label=\\"Active\\" label-for=\\"activated\\" label-class=\\"label-bold\\"> <gl-form-group-stub label=\\"Active\\" label-for=\\"activated\\" label-class=\\"label-bold\\">
<toggle-button-stub id=\\"activated\\"></toggle-button-stub> <toggle-button-stub id=\\"activated\\"></toggle-button-stub>
</gl-form-group-stub> </gl-form-group-stub>
<!----> <!---->
<gl-form-group-stub label=\\"Webhook URL\\" label-for=\\"url\\" label-class=\\"label-bold\\"> <gl-form-group-stub label=\\"Webhook URL\\" label-for=\\"url\\" label-class=\\"label-bold\\">
<gl-form-input-group-stub value=\\"/alerts/notify.json\\" predefinedoptions=\\"[object Object]\\" id=\\"url\\" readonly=\\"true\\"></gl-form-input-group-stub> <span class=\\"gl-text-gray-400\\"> <gl-form-input-group-stub value=\\"/alerts/notify.json\\" predefinedoptions=\\"[object Object]\\" id=\\"url\\" readonly=\\"\\"></gl-form-input-group-stub> <span class=\\"gl-text-gray-400\\">
</span> </span>
</gl-form-group-stub> </gl-form-group-stub>
<gl-form-group-stub label=\\"Authorization key\\" label-for=\\"authorization-key\\" label-class=\\"label-bold\\"> <gl-form-group-stub label=\\"Authorization key\\" label-for=\\"authorization-key\\" label-class=\\"label-bold\\">
<gl-form-input-group-stub value=\\"abcedfg123\\" predefinedoptions=\\"[object Object]\\" id=\\"authorization-key\\" readonly=\\"true\\" class=\\"gl-mb-2\\"></gl-form-input-group-stub> <gl-form-input-group-stub value=\\"abcedfg123\\" predefinedoptions=\\"[object Object]\\" id=\\"authorization-key\\" readonly=\\"\\" class=\\"gl-mb-2\\"></gl-form-input-group-stub>
<gl-button-stub category=\\"tertiary\\" variant=\\"default\\" size=\\"medium\\" icon=\\"\\" class=\\"gl-mt-3\\" role=\\"button\\" tabindex=\\"0\\">Reset key</gl-button-stub> <gl-button-stub category=\\"tertiary\\" variant=\\"default\\" size=\\"medium\\" icon=\\"\\" disabled=\\"true\\" class=\\"gl-mt-3\\" role=\\"button\\" tabindex=\\"0\\">Reset key</gl-button-stub>
<gl-modal-stub modalid=\\"authKeyModal\\" titletag=\\"h4\\" modalclass=\\"\\" size=\\"md\\" title=\\"Reset key\\" ok-title=\\"Reset key\\" ok-variant=\\"danger\\"> <gl-modal-stub modalid=\\"authKeyModal\\" titletag=\\"h4\\" modalclass=\\"\\" size=\\"md\\" title=\\"Reset key\\" ok-title=\\"Reset key\\" ok-variant=\\"danger\\">
Resetting the authorization key for this project will require updating the authorization key in every alert source it is enabled in. Resetting the authorization key for this project will require updating the authorization key in every alert source it is enabled in.
</gl-modal-stub> </gl-modal-stub>
...@@ -36,10 +36,10 @@ exports[`AlertsSettingsForm with default values renders the initial template 1`] ...@@ -36,10 +36,10 @@ exports[`AlertsSettingsForm with default values renders the initial template 1`]
</gl-form-group-stub> </gl-form-group-stub>
<gl-button-stub category=\\"tertiary\\" variant=\\"default\\" size=\\"medium\\" icon=\\"\\" disabled=\\"true\\">Test alert payload</gl-button-stub> <gl-button-stub category=\\"tertiary\\" variant=\\"default\\" size=\\"medium\\" icon=\\"\\" disabled=\\"true\\">Test alert payload</gl-button-stub>
<div class=\\"footer-block row-content-block gl-display-flex gl-justify-content-space-between\\"> <div class=\\"footer-block row-content-block gl-display-flex gl-justify-content-space-between\\">
<gl-button-stub category=\\"primary\\" variant=\\"success\\" size=\\"medium\\" icon=\\"\\" disabled=\\"true\\" type=\\"submit\\"> <gl-button-stub category=\\"primary\\" variant=\\"success\\" size=\\"medium\\" icon=\\"\\" disabled=\\"true\\">
Save changes Save changes
</gl-button-stub> </gl-button-stub>
<gl-button-stub category=\\"primary\\" variant=\\"default\\" size=\\"medium\\" icon=\\"\\" type=\\"reset\\"> <gl-button-stub category=\\"primary\\" variant=\\"default\\" size=\\"medium\\" icon=\\"\\" disabled=\\"true\\">
Cancel Cancel
</gl-button-stub> </gl-button-stub>
</div> </div>
......
...@@ -18,13 +18,19 @@ const defaultProps = { ...@@ -18,13 +18,19 @@ const defaultProps = {
url: GENERIC_URL, url: GENERIC_URL,
alertsSetupUrl: INVALID_URL, alertsSetupUrl: INVALID_URL,
alertsUsageUrl: INVALID_URL, alertsUsageUrl: INVALID_URL,
initialActivated: ACTIVATED, activated: ACTIVATED,
}, },
prometheus: { prometheus: {
prometheusAuthorizationKey: KEY, prometheusAuthorizationKey: KEY,
prometheusFormPath: INVALID_URL, prometheusFormPath: INVALID_URL,
prometheusUrl: PROMETHEUS_URL, prometheusUrl: PROMETHEUS_URL,
prometheusIsActivated: ACTIVATED, activated: ACTIVATED,
},
opsgenie: {
opsgenieMvcIsAvailable: true,
formPath: INVALID_URL,
activated: ACTIVATED,
opsgenieMvcTargetUrl: GENERIC_URL,
}, },
}; };
...@@ -139,7 +145,9 @@ describe('AlertsSettingsForm', () => { ...@@ -139,7 +145,9 @@ describe('AlertsSettingsForm', () => {
createComponent( createComponent(
{ prometheus: { ...defaultProps.prometheus, prometheusIsActivated: true } }, { prometheus: { ...defaultProps.prometheus, prometheusIsActivated: true } },
{}, {},
true, {
selectedEndpoint: 'prometheus',
},
); );
}); });
...@@ -151,12 +159,27 @@ describe('AlertsSettingsForm', () => { ...@@ -151,12 +159,27 @@ describe('AlertsSettingsForm', () => {
expect(findApiUrl().exists()).toBe(true); expect(findApiUrl().exists()).toBe(true);
}); });
it('show a valid Alert URL', () => { it('shows the correct default API URL', () => {
expect(findUrl().exists()).toBe(true);
expect(findUrl().attributes('value')).toBe(PROMETHEUS_URL); expect(findUrl().attributes('value')).toBe(PROMETHEUS_URL);
}); });
}); });
describe('opsgenie is active', () => {
beforeEach(() => {
createComponent(
{ opsgenie: { ...defaultProps.opsgenie, opsgenieMvcActivated: true } },
{},
{
selectedEndpoint: 'opsgenie',
},
);
});
it('shows a input for the opsgenie target URL', () => {
expect(findApiUrl().exists()).toBe(true);
});
});
describe('trigger test alert', () => { describe('trigger test alert', () => {
beforeEach(() => { beforeEach(() => {
createComponent({ generic: { ...defaultProps.generic, initialActivated: true } }, {}, true); createComponent({ generic: { ...defaultProps.generic, initialActivated: true } }, {}, true);
...@@ -168,7 +191,7 @@ describe('AlertsSettingsForm', () => { ...@@ -168,7 +191,7 @@ describe('AlertsSettingsForm', () => {
}); });
it('should validate JSON input', () => { it('should validate JSON input', () => {
createComponent({ generic: { ...defaultProps.generic } }, {}, true, { createComponent({ generic: { ...defaultProps.generic } }, true, {
testAlertJson: '{ "value": "test" }', testAlertJson: '{ "value": "test" }',
}); });
...@@ -186,7 +209,7 @@ describe('AlertsSettingsForm', () => { ...@@ -186,7 +209,7 @@ describe('AlertsSettingsForm', () => {
createComponent({ generic: { ...defaultProps.generic, formPath } }); createComponent({ generic: { ...defaultProps.generic, formPath } });
return wrapper.vm.toggleGenericActivated(toggleService).then(() => { return wrapper.vm.toggleActivated(toggleService).then(() => {
expect(wrapper.find(GlAlert).attributes('variant')).toBe('info'); expect(wrapper.find(GlAlert).attributes('variant')).toBe('info');
}); });
}); });
...@@ -198,7 +221,7 @@ describe('AlertsSettingsForm', () => { ...@@ -198,7 +221,7 @@ describe('AlertsSettingsForm', () => {
createComponent({ generic: { ...defaultProps.generic, formPath } }); createComponent({ generic: { ...defaultProps.generic, formPath } });
return wrapper.vm.toggleGenericActivated(toggleService).then(() => { return wrapper.vm.toggleActivated(toggleService).then(() => {
expect(wrapper.find(GlAlert).attributes('variant')).toBe('danger'); expect(wrapper.find(GlAlert).attributes('variant')).toBe('danger');
}); });
}); });
......
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