Commit 48a0d70d authored by David Pisek's avatar David Pisek Committed by Paul Slaughter

Add tooltip to unknown-status on severity badge

This commit adds a tooltip, which explains the "unknown" status, to
the severity-badge Vue component.
parent 00e3bdf7
<script> <script>
import { s__ } from '~/locale';
import { SEVERITY_LEVELS } from 'ee/security_dashboard/store/constants'; import { SEVERITY_LEVELS } from 'ee/security_dashboard/store/constants';
import { GlIcon } from '@gitlab/ui'; import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
export const CLASS_NAME_MAP = { export const CLASS_NAME_MAP = {
critical: 'text-danger-800', critical: 'text-danger-800',
...@@ -11,11 +12,20 @@ export const CLASS_NAME_MAP = { ...@@ -11,11 +12,20 @@ export const CLASS_NAME_MAP = {
unknown: 'text-secondary-400', unknown: 'text-secondary-400',
}; };
export const TOOLTIP_TITLE_MAP = {
unknown: s__(
`SecurityReports|The rating "unknown" indicates that the underlying scanner doesn’t contain or provide a severity rating.`,
),
};
export default { export default {
name: 'SeverityBadge', name: 'SeverityBadge',
components: { components: {
GlIcon, GlIcon,
}, },
directives: {
tooltip: GlTooltipDirective,
},
props: { props: {
severity: { severity: {
type: String, type: String,
...@@ -38,13 +48,18 @@ export default { ...@@ -38,13 +48,18 @@ export default {
severityTitle() { severityTitle() {
return SEVERITY_LEVELS[this.severityKey] || this.severity; return SEVERITY_LEVELS[this.severityKey] || this.severity;
}, },
tooltipTitle() {
return TOOLTIP_TITLE_MAP[this.severityKey];
},
}, },
}; };
</script> </script>
<template> <template>
<div v-if="hasSeverityBadge" class="severity-badge text-left text-nowrap gl-text-gray-900"> <div v-if="hasSeverityBadge" class="severity-badge text-left text-nowrap gl-text-gray-900">
<span :class="className"><gl-icon :name="iconName" :size="12" class="gl-mr-3"/></span <span :class="className"
>{{ severityTitle }} ><gl-icon v-tooltip="tooltipTitle" :name="iconName" :size="12" class="gl-mr-3"
/></span>
{{ severityTitle }}
</div> </div>
</template> </template>
---
title: Add tooltip with description to unknown severity badge icon
merge_request: 33131
author:
type: changed
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import SeverityBadge, { import SeverityBadge, {
CLASS_NAME_MAP, CLASS_NAME_MAP,
TOOLTIP_TITLE_MAP,
} from 'ee/vue_shared/security_reports/components/severity_badge.vue'; } from 'ee/vue_shared/security_reports/components/severity_badge.vue';
import { GlIcon } from '@gitlab/ui'; import { GlIcon } from '@gitlab/ui';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
describe('Severity Badge', () => { describe('Severity Badge', () => {
const SEVERITY_LEVELS = ['critical', 'high', 'medium', 'low', 'info', 'unknown'];
let wrapper; let wrapper;
const factory = (propsData = {}) => const createWrapper = (propsData = {}) => {
shallowMount(SeverityBadge, { wrapper = shallowMount(SeverityBadge, {
propsData: { ...propsData }, propsData: { ...propsData },
directives: {
tooltip: createMockDirective(),
},
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
const findIcon = () => wrapper.find(GlIcon);
const findTooltip = () => getBinding(findIcon().element, 'tooltip').value;
describe.each(SEVERITY_LEVELS)('given a valid severity "%s"', severity => {
beforeEach(() => {
createWrapper({ severity });
}); });
describe.each(Object.keys(CLASS_NAME_MAP))('given a valid severity %s', severity => {
const className = CLASS_NAME_MAP[severity]; const className = CLASS_NAME_MAP[severity];
it(`renders the component with ${severity} badge`, () => { it(`renders the component with ${severity} badge`, () => {
wrapper = factory({ severity });
expect(wrapper.find(`.${className}`).exists()).toBe(true); expect(wrapper.find(`.${className}`).exists()).toBe(true);
}); });
it('renders gl-icon with correct name', () => { it('renders gl-icon with correct name', () => {
wrapper = factory({ severity }); expect(findIcon().props('name')).toBe(`severity-${severity}`);
const icon = wrapper.find(GlIcon);
expect(icon.props('name')).toBe(`severity-${severity}`);
}); });
it(`renders the component label`, () => { it(`renders the component label`, () => {
wrapper = factory({ severity }); const severityFirstLetterUpper = `${severity.charAt(0).toUpperCase()}${severity.slice(1)}`;
expect(wrapper.text()).toBe(severityFirstLetterUpper);
});
expect(wrapper.text()).toMatch(new RegExp(severity, 'i')); it('renders tooltip', () => {
expect(findTooltip()).toBe(TOOLTIP_TITLE_MAP[severity]);
}); });
}); });
describe.each(['foo', '', ' '])('given an invalid severity "%s"', invalidSeverity => { describe.each(['foo', '', ' '])('given an invalid severity "%s"', invalidSeverity => {
it(`renders an empty component`, () => { beforeEach(() => {
wrapper = factory({ severity: invalidSeverity }); createWrapper({ severity: invalidSeverity });
});
it(`renders an empty component`, () => {
expect(wrapper.isEmpty()).toBe(true); expect(wrapper.isEmpty()).toBe(true);
}); });
}); });
......
...@@ -19361,6 +19361,9 @@ msgstr "" ...@@ -19361,6 +19361,9 @@ msgstr ""
msgid "SecurityReports|Status" msgid "SecurityReports|Status"
msgstr "" msgstr ""
msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
msgstr ""
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects." msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
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