Commit 25ad8786 authored by Nicolò Maria Mezzopera's avatar Nicolò Maria Mezzopera

Merge branch 'alert-endpoint-trigger-test' into 'master'

Alert endpoint trigger test

See merge request gitlab-org/gitlab!35970
parents bc18b58b baf38c4e
......@@ -21,6 +21,7 @@ export const i18n = {
'AlertSettings|Resetting the authorization key for this project will require updating the authorization key in every alert source it is enabled in.',
),
endPointActivated: s__('AlertSettings|Alerts endpoint successfully activated.'),
changesSaved: s__('AlertSettings|Your changes were successfully updated.'),
prometheusInfo: s__('AlertSettings|Add URL and auth key to your Prometheus config file'),
integrationsInfo: s__(
'AlertSettings|Learn more about our %{linkStart}upcoming integrations%{linkEnd}',
......@@ -32,10 +33,20 @@ export const i18n = {
authKeyLabel: s__('AlertSettings|Authorization key'),
urlLabel: s__('AlertSettings|Webhook URL'),
activeLabel: s__('AlertSettings|Active'),
apiBaseUrlHelpText: s__(' AlertSettings|URL cannot be blank and must start with http or https'),
apiBaseUrlHelpText: s__('AlertSettings|URL cannot be blank and must start with http or https'),
testAlertInfo: s__('AlertSettings|Test alert payload'),
alertJson: s__('AlertSettings|Alert test payload'),
alertJsonPlaceholder: s__('AlertSettings|Enter test alert JSON....'),
testAlertFailed: s__('AlertSettings|Test failed. Do you still want to save your changes anyway?'),
testAlertSuccess: s__(
'AlertSettings|Test alert sent successfully. If you have made other changes, please save them now.',
),
authKeyRest: s__('AlertSettings|Authorization key has been successfully reset'),
};
export const serviceOptions = [
{ value: 'generic', text: s__('AlertSettings|Generic') },
{ value: 'prometheus', text: s__('AlertSettings|External Prometheus') },
];
export const JSON_VALIDATE_DELAY = 250;
/* eslint-disable @gitlab/require-i18n-strings */
import axios from '~/lib/utils/axios_utils';
export default {
......@@ -24,4 +25,12 @@ export default {
},
});
},
updateTestAlert({ endpoint, data, authKey }) {
return axios.post(endpoint, data, {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${authKey}`,
},
});
},
};
......@@ -17,7 +17,7 @@ module OperationsHelper
def alerts_settings_data
{
'prometheus_activated' => prometheus_service.activated?.to_s,
'prometheus_activated' => prometheus_service.manual_configuration?.to_s,
'activated' => alerts_service.activated?.to_s,
'prometheus_form_path' => scoped_integration_path(prometheus_service),
'form_path' => scoped_integration_path(alerts_service),
......
......@@ -16,9 +16,6 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
msgid " AlertSettings|URL cannot be blank and must start with http or https"
msgstr ""
msgid " %{start} to %{end}"
msgstr ""
......@@ -2086,15 +2083,24 @@ msgstr ""
msgid "AlertSettings|Add URL and auth key to your Prometheus config file"
msgstr ""
msgid "AlertSettings|Alert test payload"
msgstr ""
msgid "AlertSettings|Alerts endpoint successfully activated."
msgstr ""
msgid "AlertSettings|Authorization key"
msgstr ""
msgid "AlertSettings|Authorization key has been successfully reset"
msgstr ""
msgid "AlertSettings|Copy"
msgstr ""
msgid "AlertSettings|Enter test alert JSON...."
msgstr ""
msgid "AlertSettings|External Prometheus"
msgstr ""
......@@ -2119,6 +2125,15 @@ msgstr ""
msgid "AlertSettings|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 ""
msgid "AlertSettings|Test alert payload"
msgstr ""
msgid "AlertSettings|Test alert sent successfully. If you have made other changes, please save them now."
msgstr ""
msgid "AlertSettings|Test failed. Do you still want to save your changes anyway?"
msgstr ""
msgid "AlertSettings|There was an error updating the the alert settings. Please refresh the page to try again."
msgstr ""
......@@ -2128,6 +2143,9 @@ msgstr ""
msgid "AlertSettings|There was an error while trying to reset the key. Please refresh the page to try again."
msgstr ""
msgid "AlertSettings|URL cannot be blank and must start with http or https"
msgstr ""
msgid "AlertSettings|Webhook URL"
msgstr ""
......@@ -2137,6 +2155,9 @@ msgstr ""
msgid "AlertSettings|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 ""
msgid "AlertSettings|Your changes were successfully updated."
msgstr ""
msgid "AlertSettings|http://prometheus.example.com/"
msgstr ""
......@@ -19939,9 +19960,6 @@ msgstr ""
msgid "Save Changes"
msgstr ""
msgid "Save and test changes"
msgstr ""
msgid "Save anyway"
msgstr ""
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`AlertsSettingsForm prometheus is active renders a valid "select" 1`] = `"<gl-form-select-stub options=\\"[object Object],[object Object]\\" data-testid=\\"alert-settings-select\\" value=\\"prometheus\\"></gl-form-select-stub>"`;
exports[`AlertsSettingsForm with default values renders the initial template 1`] = `
"<div>
<!---->
......@@ -20,29 +18,20 @@ exports[`AlertsSettingsForm with default values renders the initial template 1`]
</gl-form-group-stub>
<!---->
<gl-form-group-stub label=\\"Webhook URL\\" label-for=\\"url\\" label-class=\\"label-bold\\">
<div class=\\"input-group\\">
<gl-form-input-stub id=\\"url\\" readonly=\\"true\\" value=\\"/alerts/notify.json\\"></gl-form-input-stub> <span class=\\"input-group-append\\"><clipboard-button-stub text=\\"/alerts/notify.json\\" title=\\"Copy\\" tooltipplacement=\\"top\\" cssclass=\\"btn-default\\"></clipboard-button-stub></span>
</div> <span class=\\"gl-text-gray-400\\">
<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\\">
</span>
</gl-form-group-stub>
<gl-form-group-stub label=\\"Authorization key\\" label-for=\\"authorization-key\\" label-class=\\"label-bold\\">
<div class=\\"input-group\\">
<gl-form-input-stub id=\\"authorization-key\\" readonly=\\"true\\" value=\\"abcedfg123\\"></gl-form-input-stub> <span class=\\"input-group-append\\"><clipboard-button-stub text=\\"abcedfg123\\" title=\\"Copy\\" tooltipplacement=\\"top\\" cssclass=\\"btn-default\\"></clipboard-button-stub></span>
</div>
<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-button-stub category=\\"tertiary\\" variant=\\"default\\" size=\\"medium\\" icon=\\"\\" 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\\">
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-form-group-stub>
<div class=\\"footer-block row-content-block gl-display-flex gl-justify-content-space-between d-none\\">
<gl-button-stub category=\\"primary\\" variant=\\"success\\" size=\\"medium\\" icon=\\"\\" type=\\"submit\\">
Save and test changes
</gl-button-stub>
<gl-button-stub category=\\"primary\\" variant=\\"default\\" size=\\"medium\\" icon=\\"\\" type=\\"reset\\">
Cancel
</gl-button-stub>
</div>
<!---->
<gl-button-stub category=\\"tertiary\\" variant=\\"default\\" size=\\"medium\\" icon=\\"\\" disabled=\\"true\\">Test alert payload</gl-button-stub>
<!---->
</gl-form-stub>
</div>"
`;
......@@ -36,8 +36,12 @@ describe('AlertsSettingsForm', () => {
props = defaultProps,
{ methods } = {},
alertIntegrationsDropdown = false,
data,
) => {
wrapper = shallowMount(AlertsSettingsForm, {
data() {
return { ...data };
},
propsData: {
...defaultProps,
...props,
......@@ -52,6 +56,7 @@ describe('AlertsSettingsForm', () => {
};
const findSelect = () => wrapper.find('[data-testid="alert-settings-select"]');
const findJsonInput = () => wrapper.find('#alert-json');
const findUrl = () => wrapper.find('#url');
const findAuthorizationKey = () => wrapper.find('#authorization-key');
const findApiUrl = () => wrapper.find('#api-url');
......@@ -115,13 +120,13 @@ describe('AlertsSettingsForm', () => {
describe('activate toggle', () => {
it('triggers toggleActivated method', () => {
const toggleActivated = jest.fn();
const methods = { toggleActivated };
const toggleService = jest.fn();
const methods = { toggleService };
createComponent(defaultProps, { methods });
wrapper.find(ToggleButton).vm.$emit('change', true);
expect(toggleActivated).toHaveBeenCalled();
expect(toggleService).toHaveBeenCalled();
});
describe('error is encountered', () => {
......@@ -149,7 +154,7 @@ describe('AlertsSettingsForm', () => {
});
it('renders a valid "select"', () => {
expect(findSelect().html()).toMatchSnapshot();
expect(findSelect().exists()).toBe(true);
});
it('shows the API URL input', () => {
......@@ -160,9 +165,53 @@ describe('AlertsSettingsForm', () => {
expect(findUrl().exists()).toBe(true);
expect(findUrl().attributes('value')).toBe(PROMETHEUS_URL);
});
});
describe('trigger test alert', () => {
beforeEach(() => {
createComponent({ generic: { ...defaultProps.generic, initialActivated: true } }, {}, true);
});
it('should enable the JSON input', () => {
expect(findJsonInput().exists()).toBe(true);
expect(findJsonInput().props('value')).toBe(null);
});
it('should validate JSON input', () => {
createComponent({ generic: { ...defaultProps.generic } }, {}, true, {
testAlertJson: '{ "value": "test" }',
});
findJsonInput().vm.$emit('change');
return wrapper.vm.$nextTick().then(() => {
expect(findJsonInput().attributes('state')).toBe('true');
});
});
it('should not show a footer block', () => {
expect(wrapper.find('.footer-block').classes('d-none')).toBe(true);
describe('alert service is toggled', () => {
it('should show a info alert if successful', () => {
const formPath = 'some/path';
const toggleService = true;
mockAxios.onPut(formPath).replyOnce(200);
createComponent({ generic: { ...defaultProps.generic, formPath } });
return wrapper.vm.toggleGenericActivated(toggleService).then(() => {
expect(wrapper.find(GlAlert).attributes('variant')).toBe('info');
});
});
it('should show a error alert if failed', () => {
const formPath = 'some/path';
const toggleService = true;
mockAxios.onPut(formPath).replyOnce(404);
createComponent({ generic: { ...defaultProps.generic, formPath } });
return wrapper.vm.toggleGenericActivated(toggleService).then(() => {
expect(wrapper.find(GlAlert).attributes('variant')).toBe('danger');
});
});
});
});
});
......@@ -45,7 +45,9 @@ RSpec.describe OperationsHelper do
end
context 'with external Prometheus configured' do
let_it_be(:prometheus_service, reload: true) { create(:prometheus_service, project: project) }
let_it_be(:prometheus_service, reload: true) do
create(:prometheus_service, project: project)
end
context 'with external Prometheus enabled' do
it 'returns the correct values' do
......@@ -57,16 +59,31 @@ RSpec.describe OperationsHelper do
end
context 'with external Prometheus disabled' do
shared_examples 'Prometheus is disabled' do
it 'returns the correct values' do
expect(subject).to include(
'prometheus_activated' => 'false',
'prometheus_api_url' => prometheus_service.api_url
)
end
end
let(:cluster_managed) { false }
before do
# Prometheus services uses manual_configuration as an alias for active, beware
allow(prometheus_service)
.to receive(:prometheus_available?)
.and_return(cluster_managed)
prometheus_service.update!(manual_configuration: false)
end
it 'returns the correct values' do
expect(subject).to include(
'prometheus_activated' => 'false',
'prometheus_api_url' => prometheus_service.api_url
)
include_examples 'Prometheus is disabled'
context 'when cluster managed' do
let(:cluster_managed) { true }
include_examples 'Prometheus is disabled'
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