Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
80d647df
Commit
80d647df
authored
Mar 20, 2018
by
Filipa Lacerda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Breaks security report issues into individual components
parent
2d3c3ab1
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
742 additions
and
104 deletions
+742
-104
ee/app/assets/javascripts/pipelines/components/security_reports/security_report_app.vue
...lines/components/security_reports/security_report_app.vue
+4
-5
ee/app/assets/javascripts/vue_merge_request_widget/components/codequality_issue_body.vue
...erge_request_widget/components/codequality_issue_body.vue
+40
-0
ee/app/assets/javascripts/vue_merge_request_widget/components/performance_issue_body.vue
...erge_request_widget/components/performance_issue_body.vue
+48
-0
ee/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js
...javascripts/vue_merge_request_widget/mr_widget_options.js
+15
-10
ee/app/assets/javascripts/vue_shared/security_reports/components/dast_issue_body.vue
...ue_shared/security_reports/components/dast_issue_body.vue
+48
-0
ee/app/assets/javascripts/vue_shared/security_reports/components/report_issues.vue
.../vue_shared/security_reports/components/report_issues.vue
+44
-76
ee/app/assets/javascripts/vue_shared/security_reports/components/report_link.vue
...ts/vue_shared/security_reports/components/report_link.vue
+29
-0
ee/app/assets/javascripts/vue_shared/security_reports/components/sast_container_issue_body.vue
...security_reports/components/sast_container_issue_body.vue
+46
-0
ee/app/assets/javascripts/vue_shared/security_reports/components/sast_issue_body.vue
...ue_shared/security_reports/components/sast_issue_body.vue
+36
-0
ee/app/assets/javascripts/vue_shared/security_reports/helpers/constants.js
...ascripts/vue_shared/security_reports/helpers/constants.js
+3
-0
spec/javascripts/vue_mr_widget/components/codequality_issue_body_spec.js
...s/vue_mr_widget/components/codequality_issue_body_spec.js
+69
-0
spec/javascripts/vue_mr_widget/components/performance_issue_body_spec.js
...s/vue_mr_widget/components/performance_issue_body_spec.js
+38
-0
spec/javascripts/vue_shared/security_reports/components/dast_issue_body_spec.js
...hared/security_reports/components/dast_issue_body_spec.js
+84
-0
spec/javascripts/vue_shared/security_reports/components/report_issues_spec.js
..._shared/security_reports/components/report_issues_spec.js
+5
-12
spec/javascripts/vue_shared/security_reports/components/report_link_spec.js
...ue_shared/security_reports/components/report_link_spec.js
+71
-0
spec/javascripts/vue_shared/security_reports/components/report_section_spec.js
...shared/security_reports/components/report_section_spec.js
+1
-1
spec/javascripts/vue_shared/security_reports/components/sast_container_issue_body_spec.js
...rity_reports/components/sast_container_issue_body_spec.js
+81
-0
spec/javascripts/vue_shared/security_reports/components/sast_issue_body_spec.js
...hared/security_reports/components/sast_issue_body_spec.js
+80
-0
No files found.
ee/app/assets/javascripts/pipelines/components/security_reports/security_report_app.vue
View file @
80d647df
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
import
ReportSection
from
'
ee/vue_shared/security_reports/components/report_section.vue
'
;
import
ReportSection
from
'
ee/vue_shared/security_reports/components/report_section.vue
'
;
import
securityMixin
from
'
ee/vue_shared/security_reports/mixins/security_report_mixin
'
;
import
securityMixin
from
'
ee/vue_shared/security_reports/mixins/security_report_mixin
'
;
import
LoadingIcon
from
'
~/vue_shared/components/loading_icon.vue
'
;
import
LoadingIcon
from
'
~/vue_shared/components/loading_icon.vue
'
;
import
{
SAST
}
from
'
ee/vue_shared/security_reports/helpers/constants
'
;
export
default
{
export
default
{
name
:
'
SecurityReportTab
'
,
name
:
'
SecurityReportTab
'
,
...
@@ -9,9 +10,8 @@
...
@@ -9,9 +10,8 @@
LoadingIcon
,
LoadingIcon
,
ReportSection
,
ReportSection
,
},
},
mixins
:
[
mixins
:
[
securityMixin
],
securityMixin
,
sast
:
SAST
,
],
props
:
{
props
:
{
securityReports
:
{
securityReports
:
{
type
:
Object
,
type
:
Object
,
...
@@ -24,7 +24,7 @@
...
@@ -24,7 +24,7 @@
<div
class=
"pipeline-tab-content"
>
<div
class=
"pipeline-tab-content"
>
<report-section
<report-section
class=
"js-sast-widget"
class=
"js-sast-widget"
type=
"security
"
:type=
"$options.sast
"
:status=
"checkReportStatus(securityReports.sast.isLoading, securityReports.sast.hasError)"
:status=
"checkReportStatus(securityReports.sast.isLoading, securityReports.sast.hasError)"
:loading-text=
"translateText('security').loading"
:loading-text=
"translateText('security').loading"
:error-text=
"translateText('security').error"
:error-text=
"translateText('security').error"
...
@@ -32,7 +32,6 @@
...
@@ -32,7 +32,6 @@
:unresolved-issues=
"securityReports.sast.newIssues"
:unresolved-issues=
"securityReports.sast.newIssues"
:resolved-issues=
"securityReports.sast.resolvedIssues"
:resolved-issues=
"securityReports.sast.resolvedIssues"
:all-issues=
"securityReports.sast.allIssues"
:all-issues=
"securityReports.sast.allIssues"
:has-priority=
"true"
:is-collapsible=
"false"
:is-collapsible=
"false"
/>
/>
</div>
</div>
...
...
ee/app/assets/javascripts/vue_merge_request_widget/components/codequality_issue_body.vue
0 → 100644
View file @
80d647df
<
script
>
/**
* Renders Code quality body text
* Fixed: [name] in [link]:[line]
*/
import
ReportLink
from
'
ee/vue_shared/security_reports/components/report_link.vue
'
;
export
default
{
name
:
'
CodequalityIssueBody
'
,
components
:
{
ReportLink
,
},
props
:
{
isStatusSuccess
:
{
type
:
Boolean
,
required
:
true
,
},
issue
:
{
type
:
Object
,
required
:
true
,
},
},
};
</
script
>
<
template
>
<div
class=
"report-block-list-issue-description prepend-top-5 append-bottom-5"
>
<div
class=
"report-block-list-issue-description-text append-right-5"
>
<template
v-if=
"isStatusSuccess"
>
{{
s__
(
'
ciReport|Fixed:
'
)
}}
</
template
>
{{ issue.name }}
</div>
<report-link
v-if=
"issue.path"
:issue=
"issue"
/>
</div>
</template>
ee/app/assets/javascripts/vue_merge_request_widget/components/performance_issue_body.vue
0 → 100644
View file @
80d647df
<
script
>
/**
* Renders Perfomance issue body text
* [name] :[score] [symbol] [delta] in [link]
*/
import
ReportLink
from
'
ee/vue_shared/security_reports/components/report_link.vue
'
;
export
default
{
name
:
'
PerformanceIssueBody
'
,
components
:
{
ReportLink
,
},
props
:
{
issue
:
{
type
:
Object
,
required
:
true
,
},
},
methods
:
{
formatScore
(
value
)
{
if
(
Math
.
floor
(
value
)
!==
value
)
{
return
parseFloat
(
value
).
toFixed
(
2
);
}
return
value
;
},
},
};
</
script
>
<
template
>
<div
class=
"report-block-list-issue-description prepend-top-5 append-bottom-5"
>
<div
class=
"report-block-list-issue-description-text append-right-5"
>
{{
issue
.
name
}}
<template
v-if=
"issue.score"
>
:
<strong>
{{
formatScore
(
issue
.
score
)
}}
</strong></
template
>
<
template
v-if=
"issue.delta != null"
>
(
{{
issue
.
delta
>=
0
?
'
+
'
:
''
}}{{
formatScore
(
issue
.
delta
)
}}
)
</
template
>
</div>
<report-link
v-if=
"issue.path"
:issue=
"issue"
/>
</div>
</template>
ee/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js
View file @
80d647df
...
@@ -4,6 +4,11 @@ import WidgetApprovals from './components/approvals/mr_widget_approvals';
...
@@ -4,6 +4,11 @@ import WidgetApprovals from './components/approvals/mr_widget_approvals';
import
GeoSecondaryNode
from
'
./components/states/mr_widget_secondary_geo_node
'
;
import
GeoSecondaryNode
from
'
./components/states/mr_widget_secondary_geo_node
'
;
import
ReportSection
from
'
../vue_shared/security_reports/components/report_section.vue
'
;
import
ReportSection
from
'
../vue_shared/security_reports/components/report_section.vue
'
;
import
securityMixin
from
'
../vue_shared/security_reports/mixins/security_report_mixin
'
;
import
securityMixin
from
'
../vue_shared/security_reports/mixins/security_report_mixin
'
;
import
{
SAST
,
DAST
,
SAST_CONTAINER
,
}
from
'
../vue_shared/security_reports/helpers/constants
'
;
export
default
{
export
default
{
extends
:
CEWidgetOptions
,
extends
:
CEWidgetOptions
,
...
@@ -15,6 +20,9 @@ export default {
...
@@ -15,6 +20,9 @@ export default {
mixins
:
[
mixins
:
[
securityMixin
,
securityMixin
,
],
],
dast
:
DAST
,
sast
:
SAST
,
sastContainer
:
SAST_CONTAINER
,
data
()
{
data
()
{
return
{
return
{
isLoadingCodequality
:
false
,
isLoadingCodequality
:
false
,
...
@@ -334,7 +342,7 @@ export default {
...
@@ -334,7 +342,7 @@ export default {
<report-section
<report-section
class="js-sast-widget"
class="js-sast-widget"
v-if="shouldRenderSecurityReport"
v-if="shouldRenderSecurityReport"
type="security
"
:type="$options.sast
"
:status="securityStatus"
:status="securityStatus"
:loading-text="translateText('security').loading"
:loading-text="translateText('security').loading"
:error-text="translateText('security').error"
:error-text="translateText('security').error"
...
@@ -342,12 +350,11 @@ export default {
...
@@ -342,12 +350,11 @@ export default {
:unresolved-issues="mr.securityReport.newIssues"
:unresolved-issues="mr.securityReport.newIssues"
:resolved-issues="mr.securityReport.resolvedIssues"
:resolved-issues="mr.securityReport.resolvedIssues"
:all-issues="mr.securityReport.allIssues"
:all-issues="mr.securityReport.allIssues"
:has-priority="true"
/>
/>
<report-section
<report-section
class="js-docker-widget"
class="js-docker-widget"
v-if="shouldRenderDockerReport"
v-if="shouldRenderDockerReport"
type="dock
er"
:type="$options.sastContain
er"
:status="dockerStatus"
:status="dockerStatus"
:loading-text="translateText('sast:container').loading"
:loading-text="translateText('sast:container').loading"
:error-text="translateText('sast:container').error"
:error-text="translateText('sast:container').error"
...
@@ -355,18 +362,16 @@ export default {
...
@@ -355,18 +362,16 @@ export default {
:unresolved-issues="mr.dockerReport.unapproved"
:unresolved-issues="mr.dockerReport.unapproved"
:neutral-issues="mr.dockerReport.approved"
:neutral-issues="mr.dockerReport.approved"
:info-text="sastContainerInformationText()"
:info-text="sastContainerInformationText()"
:has-priority="true"
/>
/>
<report-section
<report-section
class="js-dast-widget"
class="js-dast-widget"
v-if="shouldRenderDastReport"
v-if="shouldRenderDastReport"
type="
dast"
:type="$options.
dast"
:status="dastStatus"
:status="dastStatus"
:loading-text="translateText('DAST').loading"
:loading-text="translateText('DAST').loading"
:error-text="translateText('DAST').error"
:error-text="translateText('DAST').error"
:success-text="getDastText"
:success-text="getDastText"
:unresolved-issues="mr.dastReport"
:unresolved-issues="mr.dastReport"
:has-priority="true"
/>
/>
<div class="mr-widget-section">
<div class="mr-widget-section">
<component
<component
...
...
ee/app/assets/javascripts/vue_shared/security_reports/components/dast_issue_body.vue
0 → 100644
View file @
80d647df
<
script
>
/**
* Renders DAST body text
* [priority]: [name]
*/
export
default
{
name
:
'
SastIssueBody
'
,
props
:
{
issue
:
{
type
:
Object
,
required
:
true
,
},
issueIndex
:
{
type
:
Number
,
required
:
true
,
},
modalTargetId
:
{
type
:
String
,
required
:
true
,
},
},
methods
:
{
openDastModal
()
{
this
.
$emit
(
'
openDastModal
'
,
this
.
issue
,
this
.
issueIndex
);
},
},
};
</
script
>
<
template
>
<div
class=
"report-block-list-issue-description prepend-top-5 append-bottom-5"
>
<div
class=
"report-block-list-issue-description-text append-right-5"
>
<template
v-if=
"issue.priority"
>
{{
issue
.
priority
}}
:
</
template
>
<button
type=
"button"
@
click=
"openDastModal()"
data-toggle=
"modal"
class=
"js-modal-dast btn-link btn-blank text-left break-link"
:data-target=
"modalTargetId"
>
{{ issue.name }}
</button>
</div>
</div>
</template>
ee/app/assets/javascripts/vue_shared/security_reports/components/report_issues.vue
View file @
80d647df
<
script
>
<
script
>
import
$
from
'
jquery
'
;
import
$
from
'
jquery
'
;
import
{
s__
}
from
'
~/locale
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
Modal
from
'
~/vue_shared/components/gl_modal.vue
'
;
import
Modal
from
'
~/vue_shared/components/gl_modal.vue
'
;
import
ExpandButton
from
'
~/vue_shared/components/expand_button.vue
'
;
import
ExpandButton
from
'
~/vue_shared/components/expand_button.vue
'
;
import
PerformanceIssue
from
'
ee/vue_merge_request_widget/components/performance_issue_body.vue
'
;
import
CodequalityIssue
from
'
ee/vue_merge_request_widget/components/codequality_issue_body.vue
'
;
import
SastIssue
from
'
./sast_issue_body.vue
'
;
import
SastContainerIssue
from
'
./sast_container_issue_body.vue
'
;
import
DastIssue
from
'
./dast_issue_body.vue
'
;
import
{
SAST
,
DAST
,
SAST_CONTAINER
}
from
'
../helpers/constants
'
;
const
modalDefaultData
=
{
const
modalDefaultData
=
{
modalId
:
'
modal-mrwidget-issue
'
,
modalId
:
'
modal-mrwidget-issue
'
,
...
@@ -19,6 +25,11 @@
...
@@ -19,6 +25,11 @@
Modal
,
Modal
,
Icon
,
Icon
,
ExpandButton
,
ExpandButton
,
SastIssue
,
SastContainerIssue
,
DastIssue
,
PerformanceIssue
,
CodequalityIssue
,
},
},
props
:
{
props
:
{
issues
:
{
issues
:
{
...
@@ -35,19 +46,11 @@
...
@@ -35,19 +46,11 @@
type
:
String
,
type
:
String
,
required
:
true
,
required
:
true
,
},
},
hasPriority
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
},
},
data
()
{
data
()
{
return
modalDefaultData
;
return
modalDefaultData
;
},
},
computed
:
{
computed
:
{
fixedLabel
()
{
return
s__
(
'
ciReport|Fixed:
'
);
},
iconName
()
{
iconName
()
{
if
(
this
.
isStatusFailed
)
{
if
(
this
.
isStatusFailed
)
{
return
'
status_failed_borderless
'
;
return
'
status_failed_borderless
'
;
...
@@ -66,20 +69,20 @@
...
@@ -66,20 +69,20 @@
isStatusNeutral
()
{
isStatusNeutral
()
{
return
this
.
status
===
'
neutral
'
;
return
this
.
status
===
'
neutral
'
;
},
},
isType
Q
uality
()
{
isType
Codeq
uality
()
{
return
this
.
type
===
'
codequality
'
;
return
this
.
type
===
'
codequality
'
;
},
},
isTypePerformance
()
{
isTypePerformance
()
{
return
this
.
type
===
'
performance
'
;
return
this
.
type
===
'
performance
'
;
},
},
isTypeS
ecurity
()
{
isTypeS
ast
()
{
return
this
.
type
===
'
security
'
;
return
this
.
type
===
SAST
;
},
},
isType
Dock
er
()
{
isType
SastContain
er
()
{
return
this
.
type
===
'
docker
'
;
return
this
.
type
===
SAST_CONTAINER
;
},
},
isTypeDast
()
{
isTypeDast
()
{
return
this
.
type
===
'
dast
'
;
return
this
.
type
===
DAST
;
},
},
},
},
mounted
()
{
mounted
()
{
...
@@ -88,21 +91,12 @@
...
@@ -88,21 +91,12 @@
});
});
},
},
methods
:
{
methods
:
{
shouldRenderPriority
(
issue
)
{
return
this
.
hasPriority
&&
issue
.
priority
;
},
getmodalId
(
index
)
{
getmodalId
(
index
)
{
return
`modal-mrwidget-issue-
${
index
}
`
;
return
`modal-mrwidget-issue-
${
index
}
`
;
},
},
modalIdTarget
(
index
)
{
modalIdTarget
(
index
)
{
return
`#
${
this
.
getmodalId
(
index
)}
`
;
return
`#
${
this
.
getmodalId
(
index
)}
`
;
},
},
formatScore
(
value
)
{
if
(
Math
.
floor
(
value
)
!==
value
)
{
return
parseFloat
(
value
).
toFixed
(
2
);
}
return
value
;
},
openDastModal
(
issue
,
index
)
{
openDastModal
(
issue
,
index
)
{
this
.
modalId
=
this
.
getmodalId
(
index
);
this
.
modalId
=
this
.
getmodalId
(
index
);
this
.
modalTitle
=
`
${
issue
.
priority
}
:
${
issue
.
name
}
`
;
this
.
modalTitle
=
`
${
issue
.
priority
}
:
${
issue
.
name
}
`
;
...
@@ -145,61 +139,35 @@
...
@@ -145,61 +139,35 @@
:size=
"32"
:size=
"32"
/>
/>
</div>
</div>
<div
class=
"report-block-list-issue-description prepend-top-5 append-bottom-5"
>
<div
class=
"report-block-list-issue-description-text append-right-5"
>
<template
v-if=
"isStatusSuccess && isTypeQuality"
>
{{
fixedLabel
}}
</
template
>
<
template
v-if=
"shouldRenderPriority(issue)"
>
{{
issue
.
priority
}}
:
</
template
>
<
template
v-if=
"isTypeDocker"
>
<sast-issue
<a
v-if=
"isTypeSast"
v-if=
"issue.nameLink"
:issue=
"issue"
:href=
"issue.nameLink"
/>
target=
"_blank"
rel=
"noopener noreferrer nofollow"
>
{{
issue
.
name
}}
</a>
<template
v-else
>
{{
issue
.
name
}}
</
template
>
</template>
<
template
v-else-if=
"isTypeDast"
>
<button
type=
"button"
@
click=
"openDastModal(issue, index)"
data-toggle=
"modal"
class=
"js-modal-dast btn-link btn-blank text-left break-link"
:data-target=
"modalTargetId"
>
{{
issue
.
name
}}
</button>
</
template
>
<
template
v-else
>
{{
issue
.
name
}}
<template
v-if=
"issue.score"
>
:
<strong>
{{
formatScore
(
issue
.
score
)
}}
</strong></
template
>
</template>
<
template
v-if=
"isTypePerformance && issue.delta != null"
>
<dast-issue
(
{{
issue
.
delta
>=
0
?
'
+
'
:
''
}}{{
formatScore
(
issue
.
delta
)
}}
)
v-else-if=
"isTypeDast"
</
template
>
:issue=
"issue"
</div>
:issue-index=
"index"
<div
class=
"report-block-list-issue-description-link"
>
:modal-target-id=
"modalTargetId"
<
template
v-if=
"issue.path"
>
@
openDastModal=
"openDastModal"
in
/>
<a
<sast-container-issue
v-if=
"issue.urlPath
"
v-else-if=
"isTypeSastContainer
"
:href=
"issue.urlPath
"
:issue=
"issue
"
target=
"_blank"
/>
rel=
"noopener noreferrer nofollow"
class=
"break-link"
<codequality-issue
>
v-else-if=
"isTypeCodequality"
{{
issue
.
path
}}
<template
v-if=
"issue.line"
>
:
{{
issue
.
line
}}
</
template
>
:is-status-success=
"isStatusSuccess"
</a>
:issue=
"issue"
<
template
v-else
>
/
>
{{
issue
.
path
}}
<template
v-if=
"issue.line"
>
:
{{
issue
.
line
}}
</
template
>
</template>
<performance-issue
</template>
v-else-if=
"isTypePerformance"
</div>
:issue=
"issue"
</div
>
/
>
</li>
</li>
</ul>
</ul>
...
...
ee/app/assets/javascripts/vue_shared/security_reports/components/report_link.vue
0 → 100644
View file @
80d647df
<
script
>
export
default
{
name
:
'
ReportIssueLink
'
,
props
:
{
issue
:
{
type
:
Object
,
required
:
true
,
},
},
};
</
script
>
<
template
>
<div
class=
"report-block-list-issue-description-link"
>
in
<a
v-if=
"issue.urlPath"
:href=
"issue.urlPath"
target=
"_blank"
rel=
"noopener noreferrer nofollow"
class=
"break-link"
>
{{
issue
.
path
}}
<template
v-if=
"issue.line"
>
:
{{
issue
.
line
}}
</
template
>
</a>
<
template
v-else
>
{{
issue
.
path
}}
<template
v-if=
"issue.line"
>
:
{{
issue
.
line
}}
</
template
>
</template>
</div>
</template>
ee/app/assets/javascripts/vue_shared/security_reports/components/sast_container_issue_body.vue
0 → 100644
View file @
80d647df
<
script
>
/**
* Renders SAST CONTAINER body text
* [priority]: [name|link] in [link]:[line]
*/
import
ReportLink
from
'
./report_link.vue
'
;
export
default
{
name
:
'
SastContainerIssueBody
'
,
components
:
{
ReportLink
,
},
props
:
{
issue
:
{
type
:
Object
,
required
:
true
,
},
},
};
</
script
>
<
template
>
<div
class=
"report-block-list-issue-description prepend-top-5 append-bottom-5"
>
<div
class=
"report-block-list-issue-description-text append-right-5"
>
<template
v-if=
"issue.priority"
>
{{
issue
.
priority
}}
:
</
template
>
<a
v-if=
"issue.nameLink"
:href=
"issue.nameLink"
target=
"_blank"
rel=
"noopener noreferrer nofollow"
>
{{ issue.name }}
</a>
<
template
v-else
>
{{
issue
.
name
}}
</
template
>
</div>
<report-link
v-if=
"issue.path"
:issue=
"issue"
/>
</div>
</template>
ee/app/assets/javascripts/vue_shared/security_reports/components/sast_issue_body.vue
0 → 100644
View file @
80d647df
<
script
>
/**
* Renders SAST body text
* [priority]: [name] in [link] : [line]
*/
import
ReportLink
from
'
./report_link.vue
'
;
export
default
{
name
:
'
SastIssueBody
'
,
components
:
{
ReportLink
,
},
props
:
{
issue
:
{
type
:
Object
,
required
:
true
,
},
},
};
</
script
>
<
template
>
<div
class=
"report-block-list-issue-description prepend-top-5 append-bottom-5"
>
<div
class=
"report-block-list-issue-description-text append-right-5"
>
<template
v-if=
"issue.priority"
>
{{
issue
.
priority
}}
:
</
template
>
{{ issue.name }}
</div>
<report-link
v-if=
"issue.path"
:issue=
"issue"
/>
</div>
</template>
ee/app/assets/javascripts/vue_shared/security_reports/helpers/constants.js
0 → 100644
View file @
80d647df
export
const
SAST
=
'
SAST
'
;
export
const
DAST
=
'
DAST
'
;
export
const
SAST_CONTAINER
=
'
SAST_CONTAINER
'
;
spec/javascripts/vue_mr_widget/components/codequality_issue_body_spec.js
0 → 100644
View file @
80d647df
import
Vue
from
'
vue
'
;
import
component
from
'
ee/vue_merge_request_widget/components/codequality_issue_body.vue
'
;
import
mountComponent
from
'
../../helpers/vue_mount_component_helper
'
;
describe
(
'
sast issue body
'
,
()
=>
{
let
vm
;
const
Component
=
Vue
.
extend
(
component
);
const
codequalityIssue
=
{
name
:
'
rubygem-rest-client: session fixation vulnerability via Set-Cookie headers in 30x redirection responses
'
,
path
:
'
Gemfile.lock
'
,
severity
:
'
normal
'
,
type
:
'
Issue
'
,
urlPath
:
'
/Gemfile.lock#L22
'
,
};
afterEach
(()
=>
{
vm
.
$destroy
();
});
describe
(
'
with success
'
,
()
=>
{
it
(
'
renders fixed label
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
issue
:
codequalityIssue
,
isStatusSuccess
:
true
,
});
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
'
Fixed
'
);
});
});
describe
(
'
without success
'
,
()
=>
{
it
(
'
renders fixed label
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
issue
:
codequalityIssue
,
isStatusSuccess
:
false
,
});
expect
(
vm
.
$el
.
textContent
.
trim
()).
not
.
toContain
(
'
Fixed
'
);
});
});
describe
(
'
name
'
,
()
=>
{
it
(
'
renders name
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
issue
:
codequalityIssue
,
isStatusSuccess
:
false
,
});
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
codequalityIssue
.
name
);
});
});
describe
(
'
path
'
,
()
=>
{
it
(
'
renders name
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
issue
:
codequalityIssue
,
isStatusSuccess
:
false
,
});
expect
(
vm
.
$el
.
querySelector
(
'
a
'
).
getAttribute
(
'
href
'
)).
toEqual
(
codequalityIssue
.
urlPath
,
);
expect
(
vm
.
$el
.
querySelector
(
'
a
'
).
textContent
.
trim
()).
toEqual
(
codequalityIssue
.
path
,
);
});
});
});
spec/javascripts/vue_mr_widget/components/performance_issue_body_spec.js
0 → 100644
View file @
80d647df
import
Vue
from
'
vue
'
;
import
component
from
'
ee/vue_merge_request_widget/components/performance_issue_body.vue
'
;
import
mountComponent
from
'
../../helpers/vue_mount_component_helper
'
;
describe
(
'
performance issue body
'
,
()
=>
{
let
vm
;
const
Component
=
Vue
.
extend
(
component
);
const
performanceIssue
=
{
delta
:
0.1999999999998181
,
name
:
'
Transfer Size (KB)
'
,
path
:
'
/
'
,
score
:
4974.8
,
};
afterEach
(()
=>
{
vm
.
$destroy
();
});
beforeEach
(()
=>
{
vm
=
mountComponent
(
Component
,
{
issue
:
performanceIssue
,
});
});
it
(
'
renders issue name
'
,
()
=>
{
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
performanceIssue
.
name
);
});
it
(
'
renders issue score formatted
'
,
()
=>
{
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
'
4974.80
'
);
});
it
(
'
renders issue delta formatted
'
,
()
=>
{
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
'
(+0.20)
'
);
});
});
spec/javascripts/vue_shared/security_reports/components/dast_issue_body_spec.js
0 → 100644
View file @
80d647df
import
Vue
from
'
vue
'
;
import
component
from
'
ee/vue_shared/security_reports/components/dast_issue_body.vue
'
;
import
mountComponent
from
'
../../../helpers/vue_mount_component_helper
'
;
describe
(
'
dast issue body
'
,
()
=>
{
let
vm
;
const
Component
=
Vue
.
extend
(
component
);
const
dastIssue
=
{
alert
:
'
X-Content-Type-Options Header Missing
'
,
confidence
:
'
2
'
,
count
:
'
17
'
,
cweid
:
'
16
'
,
desc
:
'
<p>The Anti-MIME-Sniffing header X-Content-Type-Options was not set to "nosniff". </p>
'
,
name
:
'
X-Content-Type-Options Header Missing
'
,
parsedDescription
:
'
The Anti-MIME-Sniffing header X-Content-Type-Options was not set to "nosniff".
'
,
priority
:
'
Low (Medium)
'
,
reference
:
'
<p>http://msdn.microsoft.com/en-us/library/ie/gg622941%28v=vs.85%29.aspx</p><p>https://www.owasp.org/index.php/List_of_useful_HTTP_headers</p>
'
,
riskcode
:
'
1
'
,
riskdesc
:
'
Low (Medium)
'
,
};
afterEach
(()
=>
{
vm
.
$destroy
();
});
describe
(
'
with priority
'
,
()
=>
{
it
(
'
renders priority key
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
issue
:
dastIssue
,
issueIndex
:
1
,
modalTargetId
:
'
#modal-mrwidget-issue
'
,
});
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
dastIssue
.
priority
);
});
});
describe
(
'
without priority
'
,
()
=>
{
it
(
'
does not rendere priority key
'
,
()
=>
{
const
issueCopy
=
Object
.
assign
({},
dastIssue
);
delete
issueCopy
.
priority
;
vm
=
mountComponent
(
Component
,
{
issue
:
issueCopy
,
issueIndex
:
1
,
modalTargetId
:
'
#modal-mrwidget-issue
'
,
});
expect
(
vm
.
$el
.
textContent
.
trim
()).
not
.
toContain
(
dastIssue
.
priority
);
});
});
describe
(
'
issue name
'
,
()
=>
{
beforeEach
(()
=>
{
vm
=
mountComponent
(
Component
,
{
issue
:
dastIssue
,
issueIndex
:
1
,
modalTargetId
:
'
#modal-mrwidget-issue
'
,
});
});
it
(
'
renders issue name
'
,
()
=>
{
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
dastIssue
.
name
);
});
it
(
'
renders button to open modal box
'
,
()
=>
{
const
button
=
vm
.
$el
.
querySelector
(
'
.js-modal-dast
'
);
expect
(
button
.
getAttribute
(
'
data-toggle
'
)).
toEqual
(
'
modal
'
);
expect
(
button
.
getAttribute
(
'
data-target
'
)).
toEqual
(
'
#modal-mrwidget-issue
'
);
});
it
(
'
emits event when button is clicked
'
,
()
=>
{
spyOn
(
vm
,
'
$emit
'
);
vm
.
$el
.
querySelector
(
'
.js-modal-dast
'
).
click
();
expect
(
vm
.
$emit
).
toHaveBeenCalledWith
(
'
openDastModal
'
,
dastIssue
,
1
);
});
});
});
spec/javascripts/vue_shared/security_reports/components/report_issues_spec.js
View file @
80d647df
...
@@ -67,26 +67,21 @@ describe('Report issues', () => {
...
@@ -67,26 +67,21 @@ describe('Report issues', () => {
beforeEach
(()
=>
{
beforeEach
(()
=>
{
vm
=
mountComponent
(
ReportIssues
,
{
vm
=
mountComponent
(
ReportIssues
,
{
issues
:
sastParsedIssues
,
issues
:
sastParsedIssues
,
type
:
'
security
'
,
type
:
'
SAST
'
,
status
:
'
failed
'
,
status
:
'
failed
'
,
hasPriority
:
true
,
});
});
});
});
it
(
'
should render a list of unresolved issues
'
,
()
=>
{
it
(
'
should render a list of unresolved issues
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelectorAll
(
'
.report-block-list li
'
).
length
).
toEqual
(
sastParsedIssues
.
length
);
expect
(
vm
.
$el
.
querySelectorAll
(
'
.report-block-list li
'
).
length
).
toEqual
(
sastParsedIssues
.
length
);
});
});
it
(
'
should render priority
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.report-block-list li
'
).
textContent
).
toContain
(
sastParsedIssues
[
0
].
priority
);
});
});
});
describe
(
'
with location
'
,
()
=>
{
describe
(
'
with location
'
,
()
=>
{
it
(
'
should render location
'
,
()
=>
{
it
(
'
should render location
'
,
()
=>
{
vm
=
mountComponent
(
ReportIssues
,
{
vm
=
mountComponent
(
ReportIssues
,
{
issues
:
sastParsedIssues
,
issues
:
sastParsedIssues
,
type
:
'
security
'
,
type
:
'
SAST
'
,
status
:
'
failed
'
,
status
:
'
failed
'
,
});
});
...
@@ -101,7 +96,7 @@ describe('Report issues', () => {
...
@@ -101,7 +96,7 @@ describe('Report issues', () => {
issues
:
[{
issues
:
[{
name
:
'
foo
'
,
name
:
'
foo
'
,
}],
}],
type
:
'
security
'
,
type
:
'
SAST
'
,
status
:
'
failed
'
,
status
:
'
failed
'
,
});
});
...
@@ -114,9 +109,8 @@ describe('Report issues', () => {
...
@@ -114,9 +109,8 @@ describe('Report issues', () => {
beforeEach
(()
=>
{
beforeEach
(()
=>
{
vm
=
mountComponent
(
ReportIssues
,
{
vm
=
mountComponent
(
ReportIssues
,
{
issues
:
dockerReportParsed
.
unapproved
,
issues
:
dockerReportParsed
.
unapproved
,
type
:
'
docker
'
,
type
:
'
SAST_CONTAINER
'
,
status
:
'
failed
'
,
status
:
'
failed
'
,
hasPriority
:
true
,
});
});
});
});
...
@@ -149,9 +143,8 @@ describe('Report issues', () => {
...
@@ -149,9 +143,8 @@ describe('Report issues', () => {
beforeEach
(()
=>
{
beforeEach
(()
=>
{
vm
=
mountComponent
(
ReportIssues
,
{
vm
=
mountComponent
(
ReportIssues
,
{
issues
:
parsedDast
,
issues
:
parsedDast
,
type
:
'
dast
'
,
type
:
'
DAST
'
,
status
:
'
failed
'
,
status
:
'
failed
'
,
hasPriority
:
true
,
});
});
});
});
...
...
spec/javascripts/vue_shared/security_reports/components/report_link_spec.js
0 → 100644
View file @
80d647df
import
Vue
from
'
vue
'
;
import
component
from
'
ee/vue_shared/security_reports/components/report_link.vue
'
;
import
mountComponent
from
'
../../../helpers/vue_mount_component_helper
'
;
describe
(
'
report link
'
,
()
=>
{
let
vm
;
const
Component
=
Vue
.
extend
(
component
);
afterEach
(()
=>
{
vm
.
$destroy
();
});
describe
(
'
With url
'
,
()
=>
{
it
(
'
renders link
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
issue
:
{
path
:
'
Gemfile.lock
'
,
urlPath
:
'
/Gemfile.lock
'
,
},
});
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
'
in
'
);
expect
(
vm
.
$el
.
querySelector
(
'
a
'
).
getAttribute
(
'
href
'
)).
toEqual
(
'
/Gemfile.lock
'
);
expect
(
vm
.
$el
.
querySelector
(
'
a
'
).
textContent
.
trim
()).
toEqual
(
'
Gemfile.lock
'
);
});
});
describe
(
'
Without url
'
,
()
=>
{
it
(
'
does not render link
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
issue
:
{
path
:
'
Gemfile.lock
'
,
},
});
expect
(
vm
.
$el
.
querySelector
(
'
a
'
)).
toBeNull
();
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
'
in
'
);
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
'
Gemfile.lock
'
);
});
});
describe
(
'
with line
'
,
()
=>
{
it
(
'
renders line number
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
issue
:
{
path
:
'
Gemfile.lock
'
,
urlPath
:
'
https://groups.google.com/forum/#!topic/rubyonrails-security/335P1DcLG00
'
,
line
:
22
,
},
});
expect
(
vm
.
$el
.
querySelector
(
'
a
'
).
textContent
.
trim
()).
toContain
(
'
Gemfile.lock:22
'
);
});
});
describe
(
'
without line
'
,
()
=>
{
it
(
'
does not render line number
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
issue
:
{
path
:
'
Gemfile.lock
'
,
urlPath
:
'
https://groups.google.com/forum/#!topic/rubyonrails-security/335P1DcLG00
'
,
},
});
expect
(
vm
.
$el
.
querySelector
(
'
a
'
).
textContent
.
trim
()).
not
.
toContain
(
'
:22
'
);
});
});
});
spec/javascripts/vue_shared/security_reports/components/report_section_spec.js
View file @
80d647df
...
@@ -104,7 +104,7 @@ describe('Report section', () => {
...
@@ -104,7 +104,7 @@ describe('Report section', () => {
vm
=
mountComponent
(
ReportSection
,
{
vm
=
mountComponent
(
ReportSection
,
{
status
:
'
success
'
,
status
:
'
success
'
,
successText
:
'
SAST improved on 1 security vulnerability and degraded on 1 security vulnerability
'
,
successText
:
'
SAST improved on 1 security vulnerability and degraded on 1 security vulnerability
'
,
type
:
'
security
'
,
type
:
'
SAST
'
,
errorText
:
'
Failed to load security report
'
,
errorText
:
'
Failed to load security report
'
,
hasPriority
:
true
,
hasPriority
:
true
,
loadingText
:
'
Loading security report
'
,
loadingText
:
'
Loading security report
'
,
...
...
spec/javascripts/vue_shared/security_reports/components/sast_container_issue_body_spec.js
0 → 100644
View file @
80d647df
import
Vue
from
'
vue
'
;
import
component
from
'
ee/vue_shared/security_reports/components/sast_container_issue_body.vue
'
;
import
mountComponent
from
'
../../../helpers/vue_mount_component_helper
'
;
describe
(
'
sast container issue body
'
,
()
=>
{
let
vm
;
const
Component
=
Vue
.
extend
(
component
);
const
sastContainerIssue
=
{
name
:
'
CVE-2017-11671
'
,
nameLink
:
'
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-11671
'
,
namespace
:
'
debian:8
'
,
path
:
'
debian:8
'
,
priority
:
'
Low
'
,
severity
:
'
Low
'
,
vulnerability
:
'
CVE-2017-11671
'
,
};
afterEach
(()
=>
{
vm
.
$destroy
();
});
describe
(
'
with priority
'
,
()
=>
{
it
(
'
renders priority key
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
issue
:
sastContainerIssue
,
});
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
sastContainerIssue
.
priority
);
});
});
describe
(
'
without priority
'
,
()
=>
{
it
(
'
does not rendere priority key
'
,
()
=>
{
const
issueCopy
=
Object
.
assign
({},
sastContainerIssue
);
delete
issueCopy
.
priority
;
vm
=
mountComponent
(
Component
,
{
issue
:
issueCopy
,
});
expect
(
vm
.
$el
.
textContent
.
trim
()).
not
.
toContain
(
sastContainerIssue
.
priority
);
});
});
describe
(
'
with name link
'
,
()
=>
{
it
(
'
renders name link
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
issue
:
sastContainerIssue
,
});
expect
(
vm
.
$el
.
querySelector
(
'
a
'
).
getAttribute
(
'
href
'
)).
toEqual
(
sastContainerIssue
.
nameLink
);
expect
(
vm
.
$el
.
querySelector
(
'
a
'
).
textContent
.
trim
()).
toEqual
(
sastContainerIssue
.
name
);
});
});
describe
(
'
without name link
'
,
()
=>
{
it
(
'
does not render name link
'
,
()
=>
{
const
issueCopy
=
Object
.
assign
({},
sastContainerIssue
);
delete
issueCopy
.
nameLink
;
vm
=
mountComponent
(
Component
,
{
issue
:
issueCopy
,
});
expect
(
vm
.
$el
.
querySelector
(
'
a
'
)).
toBeNull
();
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
sastContainerIssue
.
name
);
});
});
describe
(
'
path
'
,
()
=>
{
it
(
'
renders path
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
issue
:
sastContainerIssue
,
});
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
sastContainerIssue
.
path
);
});
});
});
spec/javascripts/vue_shared/security_reports/components/sast_issue_body_spec.js
0 → 100644
View file @
80d647df
import
Vue
from
'
vue
'
;
import
component
from
'
ee/vue_shared/security_reports/components/sast_issue_body.vue
'
;
import
mountComponent
from
'
../../../helpers/vue_mount_component_helper
'
;
describe
(
'
sast issue body
'
,
()
=>
{
let
vm
;
const
Component
=
Vue
.
extend
(
component
);
const
sastIssue
=
{
cve
:
'
CVE-2016-9999
'
,
file
:
'
Gemfile.lock
'
,
message
:
'
Test Information Leak Vulnerability in Action View
'
,
name
:
'
Test Information Leak Vulnerability in Action View
'
,
path
:
'
Gemfile.lock
'
,
solution
:
'
upgrade to >= 5.0.0.beta1.1, >= 4.2.5.1, ~> 4.2.5, >= 4.1.14.1, ~> 4.1.14, ~> 3.2.22.1
'
,
tool
:
'
bundler_audit
'
,
url
:
'
https://groups.google.com/forum/#!topic/rubyonrails-security/335P1DcLG00
'
,
urlPath
:
'
/Gemfile.lock
'
,
priority
:
'
Low
'
,
};
afterEach
(()
=>
{
vm
.
$destroy
();
});
describe
(
'
with priority
'
,
()
=>
{
it
(
'
renders priority key
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
issue
:
sastIssue
,
});
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
sastIssue
.
priority
);
});
});
describe
(
'
without priority
'
,
()
=>
{
it
(
'
does not rendere priority key
'
,
()
=>
{
const
issueCopy
=
Object
.
assign
({},
sastIssue
);
delete
issueCopy
.
priority
;
vm
=
mountComponent
(
Component
,
{
issue
:
issueCopy
,
});
expect
(
vm
.
$el
.
textContent
.
trim
()).
not
.
toContain
(
sastIssue
.
priority
,
);
});
});
describe
(
'
name
'
,
()
=>
{
it
(
'
renders name
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
issue
:
sastIssue
,
});
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
sastIssue
.
name
,
);
});
});
describe
(
'
path
'
,
()
=>
{
it
(
'
renders name
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
issue
:
sastIssue
,
});
expect
(
vm
.
$el
.
querySelector
(
'
a
'
).
getAttribute
(
'
href
'
)).
toEqual
(
sastIssue
.
urlPath
,
);
expect
(
vm
.
$el
.
querySelector
(
'
a
'
).
textContent
.
trim
()).
toEqual
(
sastIssue
.
path
,
);
});
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment