Commit 5226c013 authored by Olena Horal-Koretska's avatar Olena Horal-Koretska

Merge branch '330819-change-license-compliance-icons' into 'master'

Update license compliance icons

See merge request gitlab-org/gitlab!64584
parents 4ee6db7d d75c43ee
import IssueStatusIcon from '~/reports/components/issue_status_icon.vue';
import AccessibilityIssueBody from '../accessibility_report/components/accessibility_issue_body.vue'; import AccessibilityIssueBody from '../accessibility_report/components/accessibility_issue_body.vue';
import CodequalityIssueBody from '../codequality_report/components/codequality_issue_body.vue'; import CodequalityIssueBody from '../codequality_report/components/codequality_issue_body.vue';
import TestIssueBody from '../grouped_test_report/components/test_issue_body.vue'; import TestIssueBody from '../grouped_test_report/components/test_issue_body.vue';
...@@ -13,3 +14,11 @@ export const componentNames = { ...@@ -13,3 +14,11 @@ export const componentNames = {
CodequalityIssueBody: CodequalityIssueBody.name, CodequalityIssueBody: CodequalityIssueBody.name,
TestIssueBody: TestIssueBody.name, TestIssueBody: TestIssueBody.name,
}; };
export const iconComponents = {
IssueStatusIcon,
};
export const iconComponentNames = {
IssueStatusIcon: IssueStatusIcon.name,
};
<script> <script>
import { components, componentNames } from 'ee_else_ce/reports/components/issue_body'; import {
import IssueStatusIcon from '~/reports/components/issue_status_icon.vue'; components,
componentNames,
iconComponents,
iconComponentNames,
} from 'ee_else_ce/reports/components/issue_body';
export default { export default {
name: 'ReportItem', name: 'ReportItem',
components: { components: {
IssueStatusIcon,
...components, ...components,
...iconComponents,
}, },
props: { props: {
issue: { issue: {
...@@ -19,6 +23,12 @@ export default { ...@@ -19,6 +23,12 @@ export default {
default: '', default: '',
validator: (value) => value === '' || Object.values(componentNames).includes(value), validator: (value) => value === '' || Object.values(componentNames).includes(value),
}, },
iconComponent: {
type: String,
required: false,
default: iconComponentNames.IssueStatusIcon,
validator: (value) => Object.values(iconComponentNames).includes(value),
},
// failed || success // failed || success
status: { status: {
type: String, type: String,
...@@ -48,11 +58,12 @@ export default { ...@@ -48,11 +58,12 @@ export default {
class="report-block-list-issue align-items-center" class="report-block-list-issue align-items-center"
data-qa-selector="report_item_row" data-qa-selector="report_item_row"
> >
<issue-status-icon <component
:is="iconComponent"
v-if="showReportSectionStatusIcon" v-if="showReportSectionStatusIcon"
:status="status" :status="status"
:status-icon-size="statusIconSize" :status-icon-size="statusIconSize"
class="gl-mr-3" class="gl-mr-2"
/> />
<component :is="component" v-if="component" :issue="issue" :status="status" :is-new="isNew" /> <component :is="component" v-if="component" :issue="issue" :status="status" :is-new="isNew" />
......
...@@ -2,11 +2,14 @@ import BlockingMergeRequestsBody from 'ee/vue_merge_request_widget/components/bl ...@@ -2,11 +2,14 @@ import BlockingMergeRequestsBody from 'ee/vue_merge_request_widget/components/bl
import PerformanceIssueBody from 'ee/vue_merge_request_widget/components/performance_issue_body.vue'; import PerformanceIssueBody from 'ee/vue_merge_request_widget/components/performance_issue_body.vue';
import StatusCheckIssueBody from 'ee/vue_merge_request_widget/components/status_check_issue_body.vue'; import StatusCheckIssueBody from 'ee/vue_merge_request_widget/components/status_check_issue_body.vue';
import LicenseIssueBody from 'ee/vue_shared/license_compliance/components/license_issue_body.vue'; import LicenseIssueBody from 'ee/vue_shared/license_compliance/components/license_issue_body.vue';
import LicenseStatusIcon from 'ee/vue_shared/license_compliance/components/license_status_icon.vue';
import MetricsReportsIssueBody from 'ee/vue_shared/metrics_reports/components/metrics_reports_issue_body.vue'; import MetricsReportsIssueBody from 'ee/vue_shared/metrics_reports/components/metrics_reports_issue_body.vue';
import SecurityIssueBody from 'ee/vue_shared/security_reports/components/security_issue_body.vue'; import SecurityIssueBody from 'ee/vue_shared/security_reports/components/security_issue_body.vue';
import { import {
components as componentsCE, components as componentsCE,
componentNames as componentNamesCE, componentNames as componentNamesCE,
iconComponents as iconComponentsCE,
iconComponentNames as iconComponentNamesCE,
} from '~/reports/components/issue_body'; } from '~/reports/components/issue_body';
export const components = { export const components = {
...@@ -28,3 +31,13 @@ export const componentNames = { ...@@ -28,3 +31,13 @@ export const componentNames = {
MetricsReportsIssueBody: MetricsReportsIssueBody.name, MetricsReportsIssueBody: MetricsReportsIssueBody.name,
BlockingMergeRequestsBody: BlockingMergeRequestsBody.name, BlockingMergeRequestsBody: BlockingMergeRequestsBody.name,
}; };
export const iconComponents = {
...iconComponentsCE,
LicenseStatusIcon,
};
export const iconComponentNames = {
...iconComponentNamesCE,
LicenseStatusIcon: LicenseStatusIcon.name,
};
<script>
import { GlIcon } from '@gitlab/ui';
import { STATUS_FAILED, STATUS_NEUTRAL, STATUS_SUCCESS } from '~/reports/constants';
export default {
name: 'LicenseStatusIcon',
components: {
GlIcon,
},
props: {
status: {
type: String,
required: true,
},
statusIconSize: {
type: Number,
required: false,
default: 12,
},
},
computed: {
iconName() {
if (this.isStatusFailed) {
return 'status-failed';
} else if (this.isStatusSuccess) {
return 'status-success';
}
return 'status-alert';
},
isStatusFailed() {
return this.status === STATUS_FAILED;
},
isStatusSuccess() {
return this.status === STATUS_SUCCESS;
},
isStatusNeutral() {
return this.status === STATUS_NEUTRAL;
},
},
};
</script>
<template>
<div
:class="{
failed: isStatusFailed,
success: isStatusSuccess,
neutral: isStatusNeutral,
}"
class="report-block-list-icon"
>
<gl-icon
class="gl-mb-1"
:name="iconName"
:size="statusIconSize"
:data-qa-selector="`status_${status}_icon`"
/>
</div>
</template>
<script> <script>
import { GlLink, GlIcon, GlButton } from '@gitlab/ui'; import { GlLink, GlIcon, GlButton } from '@gitlab/ui';
import { mapState, mapGetters, mapActions } from 'vuex'; import { mapState, mapGetters, mapActions } from 'vuex';
import { componentNames } from 'ee/reports/components/issue_body'; import { componentNames, iconComponentNames } from 'ee/reports/components/issue_body';
import { LICENSE_MANAGEMENT } from 'ee/vue_shared/license_compliance/store/constants'; import { LICENSE_MANAGEMENT } from 'ee/vue_shared/license_compliance/store/constants';
import reportsMixin from 'ee/vue_shared/security_reports/mixins/reports_mixin'; import reportsMixin from 'ee/vue_shared/security_reports/mixins/reports_mixin';
import ReportItem from '~/reports/components/report_item.vue'; import ReportItem from '~/reports/components/report_item.vue';
...@@ -14,6 +14,7 @@ const store = createStore(); ...@@ -14,6 +14,7 @@ const store = createStore();
export default { export default {
name: 'MrWidgetLicenses', name: 'MrWidgetLicenses',
componentNames, componentNames,
iconComponentNames,
store, store,
components: { components: {
GlButton, GlButton,
...@@ -156,10 +157,12 @@ export default { ...@@ -156,10 +157,12 @@ export default {
v-for="license in licenseReportGroup.licenses" v-for="license in licenseReportGroup.licenses"
:key="license.name" :key="license.name"
:issue="license" :issue="license"
:status-icon-size="12"
:status="license.status" :status="license.status"
:component="$options.componentNames.LicenseIssueBody" :component="$options.componentNames.LicenseIssueBody"
:icon-component="$options.iconComponentNames.LicenseStatusIcon"
:show-report-section-status-icon="true" :show-report-section-status-icon="true"
class="my-1" class="gl-m-2"
/> />
</template> </template>
</smart-virtual-list> </smart-virtual-list>
......
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue'; import Vue from 'vue';
import { componentNames } from 'ee/reports/components/issue_body'; import { componentNames, iconComponentNames } from 'ee/reports/components/issue_body';
import LicenseIssueBody from 'ee/vue_shared/license_compliance/components/license_issue_body.vue';
import LicenseStatusIcon from 'ee/vue_shared/license_compliance/components/license_status_icon.vue';
import store from 'ee/vue_shared/security_reports/store'; import store from 'ee/vue_shared/security_reports/store';
import { codequalityParsedIssues } from 'ee_jest/vue_mr_widget/mock_data'; import { codequalityParsedIssues } from 'ee_jest/vue_mr_widget/mock_data';
import { import {
...@@ -7,13 +10,15 @@ import { ...@@ -7,13 +10,15 @@ import {
dockerReportParsed, dockerReportParsed,
parsedDast, parsedDast,
secretScanningParsedIssues, secretScanningParsedIssues,
licenseComplianceParsedIssues,
} from 'ee_jest/vue_shared/security_reports/mock_data'; } from 'ee_jest/vue_shared/security_reports/mock_data';
import mountComponent, { mountComponentWithStore } from 'helpers/vue_mount_component_helper'; import mountComponent, { mountComponentWithStore } from 'helpers/vue_mount_component_helper';
import reportIssue from '~/reports/components/report_item.vue'; import reportIssue from '~/reports/components/report_item.vue';
import { STATUS_FAILED, STATUS_SUCCESS } from '~/reports/constants'; import { STATUS_FAILED, STATUS_SUCCESS, STATUS_NEUTRAL } from '~/reports/constants';
describe('Report issue', () => { describe('Report issue', () => {
let vm; let vm;
let wrapper;
let ReportIssue; let ReportIssue;
beforeEach(() => { beforeEach(() => {
...@@ -149,6 +154,22 @@ describe('Report issue', () => { ...@@ -149,6 +154,22 @@ describe('Report issue', () => {
}); });
}); });
describe('for license compliance issue', () => {
it('renders LicenseIssueBody & LicenseStatusIcon', () => {
wrapper = shallowMount(ReportIssue, {
propsData: {
issue: licenseComplianceParsedIssues[0],
component: componentNames.LicenseIssueBody,
iconComponent: iconComponentNames.LicenseStatusIcon,
status: STATUS_NEUTRAL,
},
});
expect(wrapper.findComponent(LicenseIssueBody).exists()).toBe(true);
expect(wrapper.findComponent(LicenseStatusIcon).exists()).toBe(true);
});
});
describe('showReportSectionStatusIcon', () => { describe('showReportSectionStatusIcon', () => {
it('does not render CI Status Icon when showReportSectionStatusIcon is false', () => { it('does not render CI Status Icon when showReportSectionStatusIcon is false', () => {
vm = mountComponentWithStore(ReportIssue, { vm = mountComponentWithStore(ReportIssue, {
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`LicenseStatusIcon renders "failed" state correctly 1`] = `
<div
class="report-block-list-icon failed"
>
<gl-icon-stub
class="gl-mb-1"
data-qa-selector="status_failed_icon"
name="status-failed"
size="12"
/>
</div>
`;
exports[`LicenseStatusIcon renders "neutral" state correctly 1`] = `
<div
class="report-block-list-icon neutral"
>
<gl-icon-stub
class="gl-mb-1"
data-qa-selector="status_neutral_icon"
name="status-alert"
size="12"
/>
</div>
`;
exports[`LicenseStatusIcon renders "success" state correctly 1`] = `
<div
class="report-block-list-icon success"
>
<gl-icon-stub
class="gl-mb-1"
data-qa-selector="status_success_icon"
name="status-success"
size="12"
/>
</div>
`;
import { shallowMount } from '@vue/test-utils';
import ReportItem from 'ee/vue_shared/license_compliance/components/license_status_icon.vue';
import { STATUS_FAILED, STATUS_NEUTRAL, STATUS_SUCCESS } from '~/reports/constants';
describe('LicenseStatusIcon', () => {
let wrapper;
const createComponent = ({ status }) => {
wrapper = shallowMount(ReportItem, {
propsData: {
status,
},
});
};
afterEach(() => {
wrapper.destroy();
});
it.each([STATUS_SUCCESS, STATUS_NEUTRAL, STATUS_FAILED])(
'renders "%s" state correctly',
(status) => {
createComponent({ status });
expect(wrapper.element).toMatchSnapshot();
},
);
});
...@@ -15,6 +15,26 @@ export const sastParsedIssues = [ ...@@ -15,6 +15,26 @@ export const sastParsedIssues = [
}, },
]; ];
export const licenseComplianceParsedIssues = [
{
name: 'New BSD',
dependencies: [
{ name: 'pg', version: null, package_manager: null, blob_path: null },
{ name: 'puma', version: null, package_manager: null, blob_path: null },
],
url: 'http://opensource.org/licenses/BSD-3-Clause',
classification: { id: null, name: 'New BSD', approval_status: 'unclassified' },
count: 2,
approvalStatus: 'unclassified',
id: null,
packages: [
{ name: 'pg', version: null, package_manager: null, blob_path: null },
{ name: 'puma', version: null, package_manager: null, blob_path: null },
],
status: 'neutral',
},
];
export const dependencyScanningIssues = [ export const dependencyScanningIssues = [
{ {
id: null, id: null,
......
...@@ -14,6 +14,7 @@ Object { ...@@ -14,6 +14,7 @@ Object {
exports[`Grouped Issues List with data renders a report item with the correct props 1`] = ` exports[`Grouped Issues List with data renders a report item with the correct props 1`] = `
Object { Object {
"component": "TestIssueBody", "component": "TestIssueBody",
"iconComponent": "IssueStatusIcon",
"isNew": false, "isNew": false,
"issue": Object { "issue": Object {
"name": "foo", "name": "foo",
......
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