Commit f70d8fe5 authored by Nicolò Maria Mezzopera's avatar Nicolò Maria Mezzopera

Merge branch 'jnnkl-sec-config-graphql-error' into 'master'

Add ErrorHandling for Network Errors on Secure-Config Page

See merge request gitlab-org/gitlab!72680
parents 8cd2e168 2b25c045
<script>
import { GlTab, GlTabs, GlSprintf, GlLink } from '@gitlab/ui';
import { GlTab, GlTabs, GlSprintf, GlLink, GlAlert } from '@gitlab/ui';
import { __, s__ } from '~/locale';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
import UserCalloutDismisser from '~/vue_shared/components/user_callout_dismisser.vue';
......@@ -31,6 +31,7 @@ export default {
AutoDevOpsAlert,
AutoDevOpsEnabledAlert,
FeatureCard,
GlAlert,
GlLink,
GlSprintf,
GlTab,
......@@ -79,6 +80,7 @@ export default {
data() {
return {
autoDevopsEnabledAlertDismissedProjects: [],
errorMessage: '',
};
},
computed: {
......@@ -106,6 +108,12 @@ export default {
dismissedProjects.add(this.projectPath);
this.autoDevopsEnabledAlertDismissedProjects = Array.from(dismissedProjects);
},
onError(message) {
this.errorMessage = message;
},
dismissAlert() {
this.errorMessage = '';
},
},
autoDevopsEnabledAlertStorageKey: AUTO_DEVOPS_ENABLED_ALERT_DISMISSED_STORAGE_KEY,
};
......@@ -113,6 +121,16 @@ export default {
<template>
<article>
<gl-alert
v-if="errorMessage"
sticky
class="gl-top-8 gl-z-index-1"
data-testid="manage-via-mr-error-alert"
variant="danger"
@dismiss="dismissAlert"
>
{{ errorMessage }}
</gl-alert>
<local-storage-sync
v-model="autoDevopsEnabledAlertDismissedProjects"
:storage-key="$options.autoDevopsEnabledAlertStorageKey"
......@@ -174,6 +192,7 @@ export default {
data-testid="security-testing-card"
:feature="feature"
class="gl-mb-6"
@error="onError"
/>
</template>
</section-layout>
......@@ -207,6 +226,7 @@ export default {
:key="feature.type"
:feature="feature"
class="gl-mb-6"
@error="onError"
/>
</template>
</section-layout>
......
......@@ -66,6 +66,11 @@ export default {
return Boolean(name && description && configurationText);
},
},
methods: {
onError(message) {
this.$emit('error', message);
},
},
i18n: {
enabled: s__('SecurityConfiguration|Enabled'),
notEnabled: s__('SecurityConfiguration|Not enabled'),
......@@ -129,6 +134,7 @@ export default {
category="primary"
class="gl-mt-5"
:data-qa-selector="`${feature.type}_mr_button`"
@error="onError"
/>
<gl-button
......
import { GlTab } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import { makeMockUserCalloutDismisser } from 'helpers/mock_user_callout_dismisser';
import stubChildren from 'helpers/stub_children';
......@@ -70,6 +71,7 @@ describe('App component', () => {
const findTabs = () => wrapper.findAllComponents(GlTab);
const findByTestId = (id) => wrapper.findByTestId(id);
const findFeatureCards = () => wrapper.findAllComponents(FeatureCard);
const findManageViaMRErrorAlert = () => wrapper.findByTestId('manage-via-mr-error-alert');
const findLink = ({ href, text, container = wrapper }) => {
const selector = `a[href="${href}"]`;
const link = container.find(selector);
......@@ -173,6 +175,43 @@ describe('App component', () => {
});
});
describe('Manage via MR Error Alert', () => {
beforeEach(() => {
createComponent({
augmentedSecurityFeatures: securityFeaturesMock,
augmentedComplianceFeatures: complianceFeaturesMock,
});
});
describe('on initial load', () => {
it('should not show Manage via MR Error Alert', () => {
expect(findManageViaMRErrorAlert().exists()).toBe(false);
});
});
describe('when error occurs', () => {
it('should show Alert with error Message', async () => {
expect(findManageViaMRErrorAlert().exists()).toBe(false);
findFeatureCards().at(1).vm.$emit('error', 'There was a manage via MR error');
await nextTick();
expect(findManageViaMRErrorAlert().exists()).toBe(true);
expect(findManageViaMRErrorAlert().text()).toEqual('There was a manage via MR error');
});
it('should hide Alert when it is dismissed', async () => {
findFeatureCards().at(1).vm.$emit('error', 'There was a manage via MR error');
await nextTick();
expect(findManageViaMRErrorAlert().exists()).toBe(true);
findManageViaMRErrorAlert().vm.$emit('dismiss');
await nextTick();
expect(findManageViaMRErrorAlert().exists()).toBe(false);
});
});
});
describe('Auto DevOps hint alert', () => {
describe('given the right props', () => {
beforeEach(() => {
......
......@@ -80,7 +80,11 @@ describe('FeatureCard component', () => {
describe('basic structure', () => {
beforeEach(() => {
feature = makeFeature();
feature = makeFeature({
type: 'sast',
available: true,
canEnableByMergeRequest: true,
});
createComponent({ feature });
});
......@@ -97,6 +101,11 @@ describe('FeatureCard component', () => {
expect(links.exists()).toBe(true);
expect(links).toHaveLength(1);
});
it('should catch and emit manage-via-mr-error', () => {
findManageViaMr().vm.$emit('error', 'There was a manage via MR error');
expect(wrapper.emitted('error')).toEqual([['There was a manage via MR error']]);
});
});
describe('status', () => {
......
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