Commit 8a099c11 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '218485-use-the-badge' into 'master'

Use gl-badge for vulnerability states

See merge request gitlab-org/gitlab!43253
parents c1cc71ab 6bcadcf9
<script> <script>
import { GlLoadingIcon, GlButton } from '@gitlab/ui'; import { GlLoadingIcon, GlButton, GlBadge } from '@gitlab/ui';
import Api from 'ee/api'; import Api from 'ee/api';
import { CancelToken } from 'axios'; import { CancelToken } from 'axios';
import SplitButton from 'ee/vue_shared/security_reports/components/split_button.vue'; import SplitButton from 'ee/vue_shared/security_reports/components/split_button.vue';
...@@ -20,6 +20,7 @@ export default { ...@@ -20,6 +20,7 @@ export default {
components: { components: {
GlLoadingIcon, GlLoadingIcon,
GlButton, GlButton,
GlBadge,
ResolutionAlert, ResolutionAlert,
VulnerabilityStateDropdown, VulnerabilityStateDropdown,
SplitButton, SplitButton,
...@@ -46,7 +47,16 @@ export default { ...@@ -46,7 +47,16 @@ export default {
}; };
}, },
badgeVariants: {
confirmed: 'danger',
resolved: 'success',
detected: 'warning',
},
computed: { computed: {
stateVariant() {
return this.$options.badgeVariants[this.vulnerability.state] || 'neutral';
},
actionButtons() { actionButtons() {
const buttons = []; const buttons = [];
...@@ -81,10 +91,6 @@ export default { ...@@ -81,10 +91,6 @@ export default {
this.hasRemediation this.hasRemediation
); );
}, },
statusBoxStyle() {
// Get the badge variant based on the vulnerability state, defaulting to 'expired'.
return VULNERABILITY_STATE_OBJECTS[this.vulnerability.state]?.statusBoxStyle || 'expired';
},
showResolutionAlert() { showResolutionAlert() {
return ( return (
this.vulnerability.resolved_on_default_branch && this.vulnerability.resolved_on_default_branch &&
...@@ -224,15 +230,9 @@ export default { ...@@ -224,15 +230,9 @@ export default {
<div class="detail-page-header"> <div class="detail-page-header">
<div class="detail-page-header-body align-items-center"> <div class="detail-page-header-body align-items-center">
<gl-loading-icon v-if="isLoadingVulnerability" class="mr-2" /> <gl-loading-icon v-if="isLoadingVulnerability" class="mr-2" />
<span <gl-badge v-else class="gl-mr-4 text-capitalize" :variant="stateVariant">
v-else
ref="badge"
:class="
`text-capitalize align-self-center issuable-status-box status-box status-box-${statusBoxStyle}`
"
>
{{ vulnerability.state }} {{ vulnerability.state }}
</span> </gl-badge>
<status-description <status-description
class="issuable-meta" class="issuable-meta"
......
...@@ -11,21 +11,18 @@ export const VULNERABILITY_STATE_OBJECTS = { ...@@ -11,21 +11,18 @@ export const VULNERABILITY_STATE_OBJECTS = {
dismissed: { dismissed: {
action: 'dismiss', action: 'dismiss',
state: 'dismissed', state: 'dismissed',
statusBoxStyle: 'upcoming',
displayName: s__('Dismiss'), displayName: s__('Dismiss'),
description: s__('VulnerabilityManagement|Will not fix or a false-positive'), description: s__('VulnerabilityManagement|Will not fix or a false-positive'),
}, },
confirmed: { confirmed: {
action: 'confirm', action: 'confirm',
state: 'confirmed', state: 'confirmed',
statusBoxStyle: 'closed',
displayName: s__('Confirm'), displayName: s__('Confirm'),
description: s__('VulnerabilityManagement|A true-positive and will fix'), description: s__('VulnerabilityManagement|A true-positive and will fix'),
}, },
resolved: { resolved: {
action: 'resolve', action: 'resolve',
state: 'resolved', state: 'resolved',
statusBoxStyle: 'open',
displayName: s__('Resolve'), displayName: s__('Resolve'),
description: s__('VulnerabilityManagement|Verified as fixed or mitigated'), description: s__('VulnerabilityManagement|Verified as fixed or mitigated'),
}, },
......
---
title: Use gl-badge for vulnerability states
merge_request: 43253
author:
type: changed
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { GlButton } from '@gitlab/ui'; import { GlButton, GlBadge } from '@gitlab/ui';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import UsersMockHelper from 'helpers/user_mock_data_helper'; import UsersMockHelper from 'helpers/user_mock_data_helper';
...@@ -69,7 +69,7 @@ describe('Vulnerability Header', () => { ...@@ -69,7 +69,7 @@ describe('Vulnerability Header', () => {
const findGlButton = () => wrapper.find(GlButton); const findGlButton = () => wrapper.find(GlButton);
const findSplitButton = () => wrapper.find(SplitButton); const findSplitButton = () => wrapper.find(SplitButton);
const findBadge = () => wrapper.find({ ref: 'badge' }); const findBadge = () => wrapper.find(GlBadge);
const findResolutionAlert = () => wrapper.find(ResolutionAlert); const findResolutionAlert = () => wrapper.find(ResolutionAlert);
const findStatusDescription = () => wrapper.find(StatusDescription); const findStatusDescription = () => wrapper.find(StatusDescription);
...@@ -78,6 +78,9 @@ describe('Vulnerability Header', () => { ...@@ -78,6 +78,9 @@ describe('Vulnerability Header', () => {
propsData: { propsData: {
initialVulnerability: { ...defaultVulnerability, ...vulnerability }, initialVulnerability: { ...defaultVulnerability, ...vulnerability },
}, },
stubs: {
GlBadge,
},
}); });
}; };
...@@ -107,7 +110,7 @@ describe('Vulnerability Header', () => { ...@@ -107,7 +110,7 @@ describe('Vulnerability Header', () => {
}); });
it('when the vulnerability state dropdown emits a change event, the state badge updates', () => { it('when the vulnerability state dropdown emits a change event, the state badge updates', () => {
const newState = 'dismiss'; const newState = 'dismissed';
mockAxios.onPost().reply(201, { state: newState }); mockAxios.onPost().reply(201, { state: newState });
expect(findBadge().text()).not.toBe(newState); expect(findBadge().text()).not.toBe(newState);
...@@ -121,7 +124,7 @@ describe('Vulnerability Header', () => { ...@@ -121,7 +124,7 @@ describe('Vulnerability Header', () => {
}); });
it('when the vulnerability state dropdown emits a change event, the vulnerabilities event bus event is emitted with the proper event', () => { it('when the vulnerability state dropdown emits a change event, the vulnerabilities event bus event is emitted with the proper event', () => {
const newState = 'dismiss'; const newState = 'dismissed';
mockAxios.onPost().reply(201, { state: newState }); mockAxios.onPost().reply(201, { state: newState });
expect(findBadge().text()).not.toBe(newState); expect(findBadge().text()).not.toBe(newState);
...@@ -253,12 +256,19 @@ describe('Vulnerability Header', () => { ...@@ -253,12 +256,19 @@ describe('Vulnerability Header', () => {
}); });
describe('state badge', () => { describe('state badge', () => {
it.each(vulnerabilityStateEntries)( const badgeVariants = {
confirmed: 'danger',
resolved: 'success',
detected: 'warning',
dismissed: 'neutral',
};
it.each(Object.entries(badgeVariants))(
'the vulnerability state badge has the correct style for the %s state', 'the vulnerability state badge has the correct style for the %s state',
(state, stateObject) => { (state, variant) => {
createWrapper({ state }); createWrapper({ state });
expect(findBadge().classes()).toContain(`status-box-${stateObject.statusBoxStyle}`); expect(findBadge().props('variant')).toBe(variant);
expect(findBadge().text()).toBe(state); expect(findBadge().text()).toBe(state);
}, },
); );
......
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