Commit 66649862 authored by Mark Florian's avatar Mark Florian

Merge branch 'auto-fix-light-bulb' into 'master'

Add AutoFix Indicator to the Vulnerability Report Page

See merge request gitlab-org/gitlab!48251
parents 55b92a6b 20061f40
<script>
import produce from 'immer';
import { GlAlert, GlLoadingIcon, GlIntersectionObserver } from '@gitlab/ui';
import produce from 'immer';
import { __ } from '~/locale';
import VulnerabilityList from './vulnerability_list.vue';
import vulnerabilitiesQuery from '../graphql/project_vulnerabilities.graphql';
import securityScannersQuery from '../graphql/project_security_scanners.graphql';
import { VULNERABILITIES_PER_PAGE } from '../store/constants';
import vulnerabilitiesQuery from '../graphql/project_vulnerabilities.query.graphql';
import vulnerabilitiesQueryAutoFix from '../graphql/project_vulnerabilities_autofix.query.graphql';
import { preparePageInfo } from '../helpers';
import { VULNERABILITIES_PER_PAGE } from '../store/constants';
import VulnerabilityList from './vulnerability_list.vue';
const query = gon?.features?.secureVulnerabilityAutofixIndicator
? vulnerabilitiesQueryAutoFix
: vulnerabilitiesQuery;
export default {
name: 'ProjectVulnerabilitiesApp',
......@@ -36,7 +41,7 @@ export default {
},
apollo: {
vulnerabilities: {
query: vulnerabilitiesQuery,
query,
variables() {
return {
fullPath: this.projectFullPath,
......
......@@ -8,6 +8,7 @@ import {
GlSkeletonLoading,
GlTooltipDirective,
GlTable,
GlBadge,
} from '@gitlab/ui';
import RemediatedBadge from 'ee/vulnerabilities/components/remediated_badge.vue';
import FiltersProducedNoResults from 'ee/security_dashboard/components/empty_states/filters_produced_no_results.vue';
......@@ -36,6 +37,7 @@ export default {
GlSkeletonLoading,
GlSprintf,
GlTable,
GlBadge,
GlTruncate,
IssuesBadge,
LocalStorageSync,
......@@ -433,6 +435,14 @@ export default {
<template #cell(activity)="{ item }">
<div class="gl-display-flex gl-justify-content-end">
<gl-badge
v-if="item.solutions"
v-gl-tooltip
data-testid="vulnerability-solutions-bulb"
variant="neutral"
icon="bulb"
:title="s__('AutoRemediation|Auto-fix solution available')"
/>
<issues-badge v-if="issues(item).length > 0" :issues="issues(item)" />
<remediated-badge v-if="item.resolvedOnDefaultBranch" class="gl-ml-3" />
</div>
......
#import "~/graphql_shared/fragments/pageInfoCursorsOnly.fragment.graphql"
#import "./vulnerability.fragment.graphql"
query project(
$fullPath: ID!
$after: String
$first: Int
$severity: [VulnerabilitySeverity!]
$reportType: [VulnerabilityReportType!]
$scanner: [String!]
$state: [VulnerabilityState!]
$sort: VulnerabilitySort
) {
project(fullPath: $fullPath) {
vulnerabilities(
after: $after
first: $first
severity: $severity
reportType: $reportType
scanner: $scanner
state: $state
sort: $sort
) {
nodes {
...Vulnerability
solutions
}
pageInfo {
...PageInfo
}
}
}
}
......@@ -5,6 +5,10 @@ module Projects
class VulnerabilityReportController < Projects::ApplicationController
include SecurityDashboardsPermissions
before_action do
push_frontend_feature_flag(:secure_vulnerability_autofix_indicator, @project)
end
feature_category :vulnerability_management
alias_method :vulnerable, :project
......
---
name: secure_vulnerability_autofix_indicator
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48251/
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/288347
milestone: '13.7'
type: development
group: group::composition analysis
default_enabled: false
......@@ -2,6 +2,7 @@ export const generateVulnerabilities = () => [
{
id: 'id_0',
detectedAt: '2020-07-29T15:36:54Z',
solutions: true,
identifiers: [
{
externalType: 'cve',
......@@ -34,6 +35,7 @@ export const generateVulnerabilities = () => [
{
id: 'id_1',
detectedAt: '2020-07-22T19:31:24Z',
solutions: false,
identifiers: [
{
externalType: 'gemnasium',
......
......@@ -47,6 +47,7 @@ describe('Vulnerability list component', () => {
const findRows = () => wrapper.findAll('tbody tr');
const findRow = (index = 0) => findRows().at(index);
const findRowById = id => wrapper.find(`tbody tr[data-pk="${id}"`);
const findAutoFixBulbInRow = row => row.find('[data-testid="vulnerability-solutions-bulb"]');
const findIssuesBadge = (index = 0) => wrapper.findAll(IssuesBadge).at(index);
const findRemediatedBadge = () => wrapper.find(RemediatedBadge);
const findSecurityScannerAlert = () => wrapper.find(SecurityScannerAlert);
......@@ -105,6 +106,14 @@ describe('Vulnerability list component', () => {
expect(findRemediatedBadge().exists()).toBe(true);
});
it('should display autoFixIcon for first Item', () => {
expect(findAutoFixBulbInRow(findRow(0)).exists()).toBe(true);
});
it('should not display autoFixIcon for second Item', () => {
expect(findAutoFixBulbInRow(findRow(1)).exists()).toBe(false);
});
it('should correctly render the identifier cell', () => {
const identifiers = findDataCells('vulnerability-identifier');
const extraIdentifierCounts = findDataCells('vulnerability-more-identifiers');
......
......@@ -4099,6 +4099,9 @@ msgstr ""
msgid "AutoRemediation|%{mrsCount} ready for review"
msgstr ""
msgid "AutoRemediation|Auto-fix solution available"
msgstr ""
msgid "AutoRemediation|Auto-fix solutions"
msgstr ""
......
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