Commit d9a1ba17 authored by Mark Florian's avatar Mark Florian

Extract VulnerabilityDetail functional component

Now that the details are rendered explicitly, the markup had a lot of
duplication. This abstracts that duplication into a functional
component.
parent bb5467cd
<script>
export default {
name: 'VulnerabilityDetail',
props: {
label: {
type: String,
required: true,
},
},
};
</script>
<template functional>
<div class="d-sm-flex my-sm-2 my-4">
<label class="col-sm-2 text-sm-right font-weight-bold pl-0">{{ props.label }}:</label>
<div class="col-sm-10 pl-0 text-secondary">
<slot></slot>
</div>
</div>
</template>
......@@ -5,6 +5,7 @@ import SafeLink from 'ee/vue_shared/components/safe_link.vue';
import Icon from '~/vue_shared/components/icon.vue';
import SeverityBadge from './severity_badge.vue';
import getFileLocation from '../store/utils/get_file_location';
import VulnerabilityDetail from './vulnerability_detail.vue';
export default {
name: 'VulnerabilityDetails2',
......@@ -13,6 +14,7 @@ export default {
Icon,
SafeLink,
SeverityBadge,
VulnerabilityDetail,
},
props: {
vulnerability: {
......@@ -78,184 +80,122 @@ export default {
<template>
<div class="border-white mb-0 px-3">
<div v-if="vulnerability.description" class="d-sm-flex my-sm-2 my-4">
<label class="col-sm-2 text-sm-right font-weight-bold pl-0"
>{{ s__('Vulnerability|Description') }}:</label
<vulnerability-detail
v-if="vulnerability.description"
:label="s__('Vulnerability|Description')"
>
<gl-friendly-wrap :text="vulnerability.description" />
</vulnerability-detail>
<vulnerability-detail v-if="vulnerability.project" :label="s__('Vulnerability|Project')">
<safe-link class="js-link-project" :href="vulnerability.project.full_path" target="_blank">
<gl-friendly-wrap :text="vulnerability.project.full_name" />
</safe-link>
</vulnerability-detail>
<vulnerability-detail v-if="url" :label="__('URL')">
<safe-link class="js-link-url" :href="url" target="_blank">
<gl-friendly-wrap :text="url" />
</safe-link>
</vulnerability-detail>
<vulnerability-detail v-if="file" :label="s__('Vulnerability|File')">
<safe-link
v-if="vulnerability.blob_path"
class="js-link-file"
:href="vulnerability.blob_path"
target="_blank"
>
<div class="col-sm-10 pl-0 text-secondary">
<gl-friendly-wrap :text="vulnerability.description" />
</div>
</div>
<div v-if="vulnerability.project" class="d-sm-flex my-sm-2 my-4">
<label class="col-sm-2 text-sm-right font-weight-bold pl-0"
>{{ s__('Vulnerability|Project') }}:</label
>
<div class="col-sm-10 pl-0 text-secondary">
<safe-link class="js-link-project" :href="vulnerability.project.full_path" target="_blank">
<gl-friendly-wrap :text="vulnerability.project.full_name" />
</safe-link>
</div>
</div>
<gl-friendly-wrap :text="file" />
</safe-link>
<gl-friendly-wrap v-else :text="file" />
</vulnerability-detail>
<div v-if="url" class="d-sm-flex my-sm-2 my-4">
<label class="col-sm-2 text-sm-right font-weight-bold pl-0">{{ __('URL') }}:</label>
<div class="col-sm-10 pl-0 text-secondary">
<safe-link class="js-link-url" :href="url" target="_blank">
<gl-friendly-wrap :text="url" />
</safe-link>
</div>
</div>
<div v-if="file" class="d-sm-flex my-sm-2 my-4">
<label class="col-sm-2 text-sm-right font-weight-bold pl-0"
>{{ s__('Vulnerability|File') }}:</label
>
<div class="col-sm-10 pl-0 text-secondary">
<vulnerability-detail v-if="identifiers" :label="s__('Vulnerability|Identifiers')">
<span v-for="(identifier, i) in identifiers" :key="i">
<safe-link
v-if="vulnerability.blob_path"
class="js-link-file"
:href="vulnerability.blob_path"
v-if="identifier.url"
class="js-link-identifiers"
:href="identifier.url"
target="_blank"
rel="noopener noreferrer"
>
<gl-friendly-wrap :text="file" />
{{ identifier.name }}
</safe-link>
<gl-friendly-wrap v-else :text="file" />
</div>
</div>
<div v-if="identifiers" class="d-sm-flex my-sm-2 my-4">
<label class="col-sm-2 text-sm-right font-weight-bold pl-0"
>{{ s__('Vulnerability|Identifiers') }}:</label
>
<div class="col-sm-10 pl-0 text-secondary">
<span v-for="(identifier, i) in identifiers" :key="i">
<safe-link
v-if="identifier.url"
class="js-link-identifiers"
:href="identifier.url"
target="_blank"
rel="noopener noreferrer"
>
{{ identifier.name }}
</safe-link>
<span v-else> {{ identifier.name }} </span>
<span v-if="hasMoreValues(i, identifiers)">,&nbsp;</span>
</span>
</div>
</div>
<div v-if="vulnerability.severity" class="d-sm-flex my-sm-2 my-4">
<label class="col-sm-2 text-sm-right font-weight-bold pl-0"
>{{ s__('Vulnerability|Severity') }}:</label
>
<div class="col-sm-10 pl-0 text-secondary">
<severity-badge :severity="vulnerability.severity" class="d-inline" />
</div>
</div>
<div v-if="vulnerability.report_type" class="d-sm-flex my-sm-2 my-4">
<label class="col-sm-2 text-sm-right font-weight-bold pl-0"
>{{ s__('Vulnerability|Report Type') }}:</label
>
<div class="col-sm-10 pl-0 text-secondary">
<gl-friendly-wrap :text="vulnerability.report_type" />
</div>
</div>
<div v-if="className" class="d-sm-flex my-sm-2 my-4">
<label class="col-sm-2 text-sm-right font-weight-bold pl-0"
>{{ s__('Vulnerability|Class') }}:</label
>
<div class="col-sm-10 pl-0 text-secondary">
<gl-friendly-wrap :text="className" />
</div>
</div>
<div v-if="methodName" class="d-sm-flex my-sm-2 my-4">
<label class="col-sm-2 text-sm-right font-weight-bold pl-0"
>{{ s__('Vulnerability|Method') }}:</label
>
<div class="col-sm-10 pl-0 text-secondary">
<gl-friendly-wrap :text="methodName" />
</div>
</div>
<div v-if="image" class="d-sm-flex my-sm-2 my-4">
<label class="col-sm-2 text-sm-right font-weight-bold pl-0"
>{{ s__('Vulnerability|Image') }}:</label
>
<div class="col-sm-10 pl-0 text-secondary">
<gl-friendly-wrap :text="image" />
</div>
</div>
<div v-if="namespace" class="d-sm-flex my-sm-2 my-4">
<label class="col-sm-2 text-sm-right font-weight-bold pl-0"
>{{ s__('Vulnerability|Namespace') }}:</label
>
<div class="col-sm-10 pl-0 text-secondary">
<gl-friendly-wrap :text="namespace" />
</div>
</div>
<div v-if="links" class="d-sm-flex my-sm-2 my-4">
<label class="col-sm-2 text-sm-right font-weight-bold pl-0"
>{{ s__('Vulnerability|Links') }}:</label
>
<div class="col-sm-10 pl-0 text-secondary">
<span v-for="(link, i) in links" :key="i">
<safe-link
class="js-link-links"
:href="link.url"
target="_blank"
rel="noopener noreferrer"
>
{{ link.value || link.url }}
</safe-link>
<span v-if="hasMoreValues(i, links)">,&nbsp;</span>
</span>
</div>
</div>
<div v-if="instances" class="d-sm-flex my-sm-2 my-4">
<label class="col-sm-2 text-sm-right font-weight-bold pl-0"
>{{ s__('Vulnerability|Instances') }}:</label
>
<div class="col-sm-10 pl-0 text-secondary">
<div v-if="instances" class="info-well">
<ul class="report-block-list">
<li v-for="(instance, i) in instances" :key="i" class="report-block-list-issue">
<div class="report-block-list-icon append-right-5 failed">
<icon :size="32" name="status_failed_borderless" />
<span v-else> {{ identifier.name }} </span>
<span v-if="hasMoreValues(i, identifiers)">,&nbsp;</span>
</span>
</vulnerability-detail>
<vulnerability-detail v-if="vulnerability.severity" :label="s__('Vulnerability|Severity')">
<severity-badge :severity="vulnerability.severity" class="d-inline" />
</vulnerability-detail>
<vulnerability-detail
v-if="vulnerability.report_type"
:label="s__('Vulnerability|Report Type')"
>
<gl-friendly-wrap :text="vulnerability.report_type" />
</vulnerability-detail>
<vulnerability-detail v-if="className" :label="s__('Vulnerability|Class')">
<gl-friendly-wrap :text="className" />
</vulnerability-detail>
<vulnerability-detail v-if="methodName" :label="s__('Vulnerability|Method')">
<gl-friendly-wrap :text="methodName" />
</vulnerability-detail>
<vulnerability-detail v-if="image" :label="s__('Vulnerability|Image')">
<gl-friendly-wrap :text="image" />
</vulnerability-detail>
<vulnerability-detail v-if="namespace" :label="s__('Vulnerability|Namespace')">
<gl-friendly-wrap :text="namespace" />
</vulnerability-detail>
<vulnerability-detail v-if="links" :label="s__('Vulnerability|Links')">
<span v-for="(link, i) in links" :key="i">
<safe-link class="js-link-links" :href="link.url" target="_blank" rel="noopener noreferrer">
{{ link.value || link.url }}
</safe-link>
<span v-if="hasMoreValues(i, links)">,&nbsp;</span>
</span>
</vulnerability-detail>
<vulnerability-detail v-if="instances" :label="s__('Vulnerability|Instances')">
<div class="info-well">
<ul class="report-block-list">
<li v-for="(instance, i) in instances" :key="i" class="report-block-list-issue">
<div class="report-block-list-icon append-right-5 failed">
<icon :size="32" name="status_failed_borderless" />
</div>
<div class="report-block-list-issue-description prepend-top-5 append-bottom-5">
<div class="report-block-list-issue-description-text">
{{ instance.method }}
</div>
<div class="report-block-list-issue-description prepend-top-5 append-bottom-5">
<div class="report-block-list-issue-description-text">
{{ instance.method }}
</div>
<div class="report-block-list-issue-description-link">
<safe-link
:href="instance.uri"
target="_blank"
rel="noopener noreferrer nofollow"
class="break-link"
>
{{ instance.uri }}
</safe-link>
</div>
<expand-button v-if="instance.evidence">
<pre
slot="expanded"
class="block report-block-dast-code prepend-top-10 report-block-issue-code"
>
{{ instance.evidence }}</pre
>
</expand-button>
<div class="report-block-list-issue-description-link">
<safe-link
:href="instance.uri"
target="_blank"
rel="noopener noreferrer nofollow"
class="break-link"
>
{{ instance.uri }}
</safe-link>
</div>
</li>
</ul>
</div>
<expand-button v-if="instance.evidence">
<pre
slot="expanded"
class="block report-block-dast-code prepend-top-10 report-block-issue-code"
>
{{ instance.evidence }}</pre
>
</expand-button>
</div>
</li>
</ul>
</div>
</div>
</vulnerability-detail>
</div>
</template>
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`VulnerabilityDetail component renders the label prop and default slot 1`] = `
<div
class="d-sm-flex my-sm-2 my-4"
>
<label
class="col-sm-2 text-sm-right font-weight-bold pl-0"
>
foo:
</label>
<div
class="col-sm-10 pl-0 text-secondary"
>
<p>
bar
</p>
</div>
</div>
`;
import { shallowMount } from '@vue/test-utils';
import VulnerabilityDetail from 'ee/vue_shared/security_reports/components/vulnerability_detail.vue';
describe('VulnerabilityDetail component', () => {
let wrapper;
const factory = ({ propsData, defaultSlot }) => {
wrapper = shallowMount(VulnerabilityDetail, {
propsData,
slots: {
default: defaultSlot,
},
});
};
afterEach(() => {
wrapper.destroy();
});
it('renders the label prop and default slot', () => {
factory({ propsData: { label: 'foo' }, defaultSlot: '<p>bar</p>' });
expect(wrapper.element).toMatchSnapshot();
});
});
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