Commit bcd808ed authored by Sam Beckham's avatar Sam Beckham Committed by Kushal Pandya

Adds a popover to vulnerability-check approvals

- Creates a vulnerability_check_popover component
- Conditionally loads it based on the name of the approval group
- Adds the option to link the the documentation
parent a358f569
...@@ -3,21 +3,28 @@ import { mapState } from 'vuex'; ...@@ -3,21 +3,28 @@ import { mapState } from 'vuex';
import { n__, sprintf } from '~/locale'; import { n__, sprintf } from '~/locale';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import UserAvatarList from '~/vue_shared/components/user_avatar/user_avatar_list.vue'; import UserAvatarList from '~/vue_shared/components/user_avatar/user_avatar_list.vue';
import VulnerabilityCheckPopover from '../vulnerability_check_popover.vue';
import Rules from '../rules.vue'; import Rules from '../rules.vue';
import RuleControls from '../rule_controls.vue'; import RuleControls from '../rule_controls.vue';
const VULNERABILITY_CHECK_NAME = 'Vulnerability-Check';
export default { export default {
components: { components: {
Icon, Icon,
UserAvatarList,
Rules,
RuleControls, RuleControls,
Rules,
UserAvatarList,
VulnerabilityCheckPopover,
}, },
computed: { computed: {
...mapState(['settings']), ...mapState(['settings']),
...mapState({ ...mapState({
rules: state => state.approvals.rules, rules: state => state.approvals.rules,
}), }),
reportApproverRulesAreEnabled() {
return Boolean(gon && gon.features && gon.features.reportApproverRules);
},
}, },
methods: { methods: {
summaryText(rule) { summaryText(rule) {
...@@ -54,6 +61,9 @@ export default { ...@@ -54,6 +61,9 @@ export default {
{ name: rule.name, count: rule.approvalsRequired }, { name: rule.name, count: rule.approvalsRequired },
); );
}, },
showVulnerabilityCheckPopover(rule) {
return this.reportApproverRulesAreEnabled && rule.name === VULNERABILITY_CHECK_NAME;
},
}, },
}; };
</script> </script>
...@@ -72,6 +82,7 @@ export default { ...@@ -72,6 +82,7 @@ export default {
<td class="d-table-cell d-sm-none js-summary">{{ summaryText(rule) }}</td> <td class="d-table-cell d-sm-none js-summary">{{ summaryText(rule) }}</td>
<td v-if="settings.allowMultiRule" class="d-none d-sm-table-cell js-name"> <td v-if="settings.allowMultiRule" class="d-none d-sm-table-cell js-name">
{{ rule.name }} {{ rule.name }}
<vulnerability-check-popover v-if="showVulnerabilityCheckPopover(rule)" />
</td> </td>
<td class="d-none d-sm-table-cell js-members"> <td class="d-none d-sm-table-cell js-members">
<user-avatar-list :items="rule.approvers" :img-size="24" /> <user-avatar-list :items="rule.approvers" :img-size="24" />
......
<script>
import { GlLink, GlPopover } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
export default {
name: 'VulnerabilityCheckPopover',
components: {
GlLink,
GlPopover,
Icon,
},
props: {
documentationLink: {
type: String,
required: false,
default: '',
},
},
};
</script>
<template>
<span class="vertical-align-middle text-muted js-help">
<icon id="reports-info" name="question" :aria-label="__('help')" :size="14" />
<gl-popover
target="reports-info"
placement="top"
triggers="click"
:title="
__(
'Vulnerability-Check requires one or more merge request approvals only if high or critical security vulnerabilities are detected.',
)
"
>
<gl-link v-if="documentationLink" target="_blank" :href="documentationLink">
<span class="vertical-align-middle">{{ __('Learn more about vulnerability check') }}</span>
<icon name="external-link" class="vertical-align-middle" />
</gl-link>
</gl-popover>
</span>
</template>
---
title: Adds a popover to vulnerability-check approvals
merge_request: 14038
author:
type: other
...@@ -98,4 +98,54 @@ describe('Approvals ProjectRules', () => { ...@@ -98,4 +98,54 @@ describe('Approvals ProjectRules', () => {
); );
}); });
}); });
describe('when the Vulnerability-Check group is used', () => {
let rows;
beforeEach(() => {
const rules = createProjectRules();
rules[0].name = 'Vulnerability-Check';
store.modules.approvals.state.rules = rules;
store.state.settings.allowMultiRule = true;
});
describe('when the `reportApproverRules` feature flag is enabled', () => {
beforeEach(() => {
gon.features = { reportApproverRules: true };
factory();
rows = wrapper.findAll('tbody tr');
});
it('should render the popover for the Vulnerability-Check group', () => {
const firstRow = rows.at(0);
const nameCell = findCell(firstRow, 'name');
expect(nameCell.find('.js-help').exists()).toBeTruthy();
});
it('should not render the popover for a standard approval group', () => {
const secondRow = rows.at(1);
const nameCell = findCell(secondRow, 'name');
expect(nameCell.find('.js-help').exists()).toBeFalsy();
});
});
describe('when the `reportApproverRules` feature flag is disabled', () => {
beforeEach(() => {
gon.features = { reportApproverRules: false };
factory();
rows = wrapper.findAll('tbody tr');
});
it('should not render the popover for the Vulnerability-Check group', () => {
const firstRow = rows.at(0);
const nameCell = findCell(firstRow, 'name');
expect(nameCell.find('.js-help').exists()).toBeFalsy();
});
});
});
}); });
import Vue from 'vue';
import { mount, createLocalVue } from '@vue/test-utils';
import { GlPopover } from '@gitlab/ui';
import { TEST_HOST } from 'spec/test_constants';
import component from 'ee/approvals/components/vulnerability_check_popover.vue';
describe('Vulnerability Check Popover', () => {
let wrapper;
beforeEach(() => {
const localVue = createLocalVue();
wrapper = mount(component, {
localVue,
sync: false,
});
});
describe('with a documentation link', () => {
const documentationLink = `${TEST_HOST}/documentation`;
beforeEach(done => {
wrapper.setProps({ documentationLink });
Vue.nextTick(done);
});
it('should render the documentation link', () => {
expect(
wrapper
.find(GlPopover)
.find('a')
.attributes('href'),
).toBe(documentationLink);
});
});
describe('without a documentation link', () => {
it('should not render the documentation link', () => {
expect(
wrapper
.find(GlPopover)
.find('a')
.exists(),
).toBeFalsy();
});
});
});
...@@ -8064,6 +8064,9 @@ msgstr "" ...@@ -8064,6 +8064,9 @@ msgstr ""
msgid "Learn more about the dependency list" msgid "Learn more about the dependency list"
msgstr "" msgstr ""
msgid "Learn more about vulnerability check"
msgstr ""
msgid "Learn more in the" msgid "Learn more in the"
msgstr "" msgstr ""
...@@ -15718,6 +15721,9 @@ msgstr "" ...@@ -15718,6 +15721,9 @@ msgstr ""
msgid "Vulnerability List" msgid "Vulnerability List"
msgstr "" msgstr ""
msgid "Vulnerability-Check requires one or more merge request approvals only if high or critical security vulnerabilities are detected."
msgstr ""
msgid "Vulnerability|Class" msgid "Vulnerability|Class"
msgstr "" msgstr ""
...@@ -16936,6 +16942,9 @@ msgstr "" ...@@ -16936,6 +16942,9 @@ msgstr ""
msgid "has already been taken" msgid "has already been taken"
msgstr "" msgstr ""
msgid "help"
msgstr ""
msgid "here" msgid "here"
msgstr "" 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