Commit 95756071 authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Merge branch 'auto-fix-indicator-second-iteration' into 'master'

Enhance AutoFix Indicator on Vulnerability Report Page

See merge request gitlab-org/gitlab!49479
parents 50646a85 686125bc
......@@ -92,7 +92,8 @@ the **Failed jobs** tab of the pipeline page.
The Vulnerability Report next displays the total number of vulnerabilities by severity (for example,
Critical, High, Medium, Low, Info, Unknown). Below this, a table shows each vulnerability's status, severity,
and description. Clicking a vulnerability takes you to its [Vulnerability Details](../vulnerabilities)
description and if there is a Merge Request related to it. Clicking a vulnerability takes you to its
[Vulnerability Details](../vulnerabilities)
page to view more information about that vulnerability.
![Project Vulnerability Report](img/project_security_dashboard_v13_5.png)
......
<script>
import { GlBadge, GlPopover, GlIcon } from '@gitlab/ui';
const ICONCOLOR = {
opened: 'gl-text-green-500',
closed: 'gl-text-red-500',
merged: 'gl-text-blue-500',
};
const ICON = {
opened: 'issue-open-m',
closed: 'issue-close',
merged: 'merge',
};
export default {
components: {
GlBadge,
GlIcon,
GlPopover,
},
props: {
mergeRequest: {
type: Object,
required: true,
},
},
methods: {
getIconColor(state) {
return ICONCOLOR[state] || 'gl-text-gray-500';
},
getIcon(state) {
return ICON[state] || 'issue-open-m';
},
},
};
</script>
<template>
<div ref="popover" data-testid="vulnerability-solutions-bulb">
<gl-badge ref="badge" variant="neutral" icon="merge-request" />
<gl-popover
data-testid="vulnerability-solutions-popover"
:target="() => $refs.popover"
placement="top"
triggers="hover focus"
>
<template #title>
<span>{{ s__('AutoRemediation| 1 Merge Request') }}</span>
</template>
<ul class="gl-list-style-none gl-pl-0 gl-mb-0">
<li class="gl-align-items-center gl-display-flex gl-mb-2">
<gl-icon
data-testid="vulnerability-solutions-popover-icon"
:name="getIcon(mergeRequest.state)"
:size="16"
:class="getIconColor(mergeRequest.state)"
/>
<a
data-testid="vulnerability-solutions-popover-link"
:href="mergeRequest.webUrl"
class="gl-ml-3"
>
<span data-testid="vulnerability-solutions-popover-link-id"
>!{{ mergeRequest.iid
}}<span
v-if="mergeRequest.securityAutoFix"
data-testid="vulnerability-solutions-popover-link-autofix"
>{{ s__('AutoRemediation|: Auto-fix') }}</span
></span
>
</a>
</li>
</ul>
</gl-popover>
</div>
</template>
......@@ -8,9 +8,9 @@ import {
GlSkeletonLoading,
GlTooltipDirective,
GlTable,
GlBadge,
} from '@gitlab/ui';
import RemediatedBadge from 'ee/vulnerabilities/components/remediated_badge.vue';
import AutoFixHelpText from 'ee/security_dashboard/components/auto_fix_help_text.vue';
import FiltersProducedNoResults from 'ee/security_dashboard/components/empty_states/filters_produced_no_results.vue';
import DashboardHasNoVulnerabilities from 'ee/security_dashboard/components/empty_states/dashboard_has_no_vulnerabilities.vue';
import SeverityBadge from 'ee/vue_shared/security_reports/components/severity_badge.vue';
......@@ -37,10 +37,10 @@ export default {
GlSkeletonLoading,
GlSprintf,
GlTable,
GlBadge,
GlTruncate,
IssuesBadge,
LocalStorageSync,
AutoFixHelpText,
RemediatedBadge,
SecurityScannerAlert,
SelectionSummary,
......@@ -439,14 +439,7 @@ export default {
<template #cell(activity)="{ item }">
<div class="gl-display-flex gl-justify-content-end">
<gl-badge
v-if="item.hasSolutions"
v-gl-tooltip
data-testid="vulnerability-solutions-bulb"
variant="neutral"
icon="bulb"
:title="s__('AutoRemediation|Auto-fix solution available')"
/>
<auto-fix-help-text v-if="item.hasSolutions" :merge-request="item.mergeRequest" />
<issues-badge v-if="issues(item).length > 0" :issues="issues(item)" />
<remediated-badge v-if="item.resolvedOnDefaultBranch" class="gl-ml-3" />
</div>
......
......@@ -24,6 +24,12 @@ query project(
nodes {
...Vulnerability
hasSolutions
mergeRequest {
webUrl
state
securityAutoFix
iid
}
}
pageInfo {
...PageInfo
......
import { mount } from '@vue/test-utils';
import AutoFixHelpText from 'ee/security_dashboard/components/auto_fix_help_text.vue';
const TEST_MERGE_REQUEST_DATA = {
webUrl: 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48820',
state: 'merged',
securityAutoFix: true,
iid: 48820,
};
describe('AutoFix Help Text component', () => {
let wrapper;
const createWrapper = ({ props = {} } = {}) => {
return mount(AutoFixHelpText, {
propsData: {
mergeRequest: TEST_MERGE_REQUEST_DATA,
...props,
},
stubs: {
GlPopover: true,
},
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
beforeEach(() => {
wrapper = createWrapper();
});
const findByTestId = id => wrapper.find(`[data-testid="${id}"]`);
it('popover should have wrapping div as target', () => {
expect(
findByTestId('vulnerability-solutions-popover')
.props()
.target()
.isSameNode(wrapper.find('[data-testid="vulnerability-solutions-bulb"]').element),
).toBe(true);
});
it('popover should contain Icon with passed status', () => {
expect(findByTestId('vulnerability-solutions-popover-icon').props().name).toBe('merge');
});
it('popover should contain Link with passed href', () => {
expect(findByTestId('vulnerability-solutions-popover-link').attributes('href')).toBe(
TEST_MERGE_REQUEST_DATA.webUrl,
);
});
it('popover should contain passed MergeRequest ID', () => {
expect(findByTestId('vulnerability-solutions-popover-link-id').text()).toContain(
`!${TEST_MERGE_REQUEST_DATA.iid}`,
);
});
it('popover should contain Autofix Indicator when available', () => {
expect(findByTestId('vulnerability-solutions-popover-link-autofix').text()).toBe(': Auto-fix');
});
describe('with autofix not available', () => {
beforeEach(() => {
wrapper = createWrapper({
props: {
mergeRequest: {
...TEST_MERGE_REQUEST_DATA,
securityAutoFix: false,
},
},
});
});
it('popover should not contain Autofix Indicator', () => {
expect(findByTestId('vulnerability-solutions-popover-link-autofix').exists()).toBe(false);
});
});
});
......@@ -3,6 +3,12 @@ export const generateVulnerabilities = () => [
id: 'id_0',
detectedAt: '2020-07-29T15:36:54Z',
hasSolutions: true,
mergeRequest: {
webUrl: 'www.testmr.com/1',
state: 'status_warning',
securityAutoFix: true,
iid: 1,
},
identifiers: [
{
externalType: 'cve',
......
......@@ -4175,10 +4175,13 @@ msgstr ""
msgid "AutoDevOps|The Auto DevOps pipeline has been enabled and will be used if no alternative CI configuration file is found."
msgstr ""
msgid "AutoRemediation| 1 Merge Request"
msgstr ""
msgid "AutoRemediation|%{mrsCount} ready for review"
msgstr ""
msgid "AutoRemediation|Auto-fix solution available"
msgid "AutoRemediation|: Auto-fix"
msgstr ""
msgid "AutoRemediation|Auto-fix solutions"
......
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