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
0499b49c
Commit
0499b49c
authored
Dec 13, 2017
by
Filipa Lacerda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Parses docker report into the needed data strucutre
Adds tests Adds links
parent
24d4e462
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
338 additions
and
61 deletions
+338
-61
app/assets/stylesheets/pages/merge_requests.scss
app/assets/stylesheets/pages/merge_requests.scss
+4
-0
ee/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_report_collapsible_section.vue
...idget/components/mr_widget_report_collapsible_section.vue
+20
-9
ee/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_report_issues.vue
...rge_request_widget/components/mr_widget_report_issues.vue
+25
-3
ee/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js
...javascripts/vue_merge_request_widget/mr_widget_options.js
+25
-15
ee/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
...cripts/vue_merge_request_widget/stores/mr_widget_store.js
+9
-3
spec/javascripts/vue_mr_widget/components/mr_widget_report_collapsible_section_spec.js
...t/components/mr_widget_report_collapsible_section_spec.js
+0
-1
spec/javascripts/vue_mr_widget/components/mr_widget_report_issues_spec.js
.../vue_mr_widget/components/mr_widget_report_issues_spec.js
+39
-1
spec/javascripts/vue_mr_widget/ee_mr_widget_options_spec.js
spec/javascripts/vue_mr_widget/ee_mr_widget_options_spec.js
+79
-28
spec/javascripts/vue_mr_widget/mock_data.js
spec/javascripts/vue_mr_widget/mock_data.js
+88
-1
spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js
.../javascripts/vue_mr_widget/stores/mr_widget_store_spec.js
+49
-0
No files found.
app/assets/stylesheets/pages/merge_requests.scss
View file @
0499b49c
...
@@ -784,6 +784,10 @@
...
@@ -784,6 +784,10 @@
background-color
:
$gray-light
;
background-color
:
$gray-light
;
margin
:
$gl-padding
-16px
-16px
;
margin
:
$gl-padding
-16px
-16px
;
.mr-widget-code-quality-info
{
padding-left
:
12px
;
}
.mr-widget-code-quality-list
{
.mr-widget-code-quality-list
{
list-style
:
none
;
list-style
:
none
;
padding
:
0
12px
;
padding
:
0
12px
;
...
...
ee/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_report_collapsible_section.vue
View file @
0499b49c
...
@@ -7,7 +7,7 @@ export default {
...
@@ -7,7 +7,7 @@ export default {
name
:
'
MRWidgetCodeQuality
'
,
name
:
'
MRWidgetCodeQuality
'
,
props
:
{
props
:
{
// security | codequality | performance
// security | codequality | performance
| docker
type
:
{
type
:
{
type
:
String
,
type
:
String
,
required
:
true
,
required
:
true
,
...
@@ -44,6 +44,10 @@ export default {
...
@@ -44,6 +44,10 @@ export default {
required
:
false
,
required
:
false
,
default
:
()
=>
[],
default
:
()
=>
[],
},
},
infoText
:
{
type
:
String
,
required
:
false
,
},
},
},
components
:
{
components
:
{
...
@@ -128,12 +132,19 @@ export default {
...
@@ -128,12 +132,19 @@ export default {
class=
"code-quality-container"
class=
"code-quality-container"
v-if=
"hasIssues"
v-if=
"hasIssues"
v-show=
"!isCollapsed"
>
v-show=
"!isCollapsed"
>
<p
v-if=
"type === 'docker' && infoText"
v-html=
"infoText"
class=
"js-mr-code-quality-info mr-widget-code-quality-info"
>
</p>
<issues-block
<issues-block
class=
"js-mr-code-
resolved
-issues"
class=
"js-mr-code-
new
-issues"
v-if=
"resolvedIssues.length"
v-if=
"
un
resolvedIssues.length"
:type=
"type"
:type=
"type"
status=
"
success
"
status=
"
failed
"
:issues=
"resolvedIssues"
:issues=
"
un
resolvedIssues"
/>
/>
<issues-block
<issues-block
...
@@ -145,11 +156,11 @@ export default {
...
@@ -145,11 +156,11 @@ export default {
/>
/>
<issues-block
<issues-block
class=
"js-mr-code-
new
-issues"
class=
"js-mr-code-
resolved
-issues"
v-if=
"
un
resolvedIssues.length"
v-if=
"resolvedIssues.length"
:type=
"type"
:type=
"type"
status=
"
failed
"
status=
"
success
"
:issues=
"
un
resolvedIssues"
:issues=
"resolvedIssues"
/>
/>
</div>
</div>
<div
<div
...
...
ee/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_report_issues.vue
View file @
0499b49c
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
type
:
Array
,
type
:
Array
,
required
:
true
,
required
:
true
,
},
},
// security || codequality || performance
// security || codequality || performance
|| docker
type
:
{
type
:
{
type
:
String
,
type
:
String
,
required
:
true
,
required
:
true
,
...
@@ -41,6 +41,14 @@
...
@@ -41,6 +41,14 @@
isTypeSecurity
()
{
isTypeSecurity
()
{
return
this
.
type
===
'
security
'
;
return
this
.
type
===
'
security
'
;
},
},
isTypeDocker
()
{
return
this
.
type
===
'
docker
'
;
},
},
methods
:
{
shouldRenderPriority
(
issue
)
{
return
(
this
.
isTypeSecurity
||
this
.
isTypeDocker
)
&&
issue
.
priority
;
},
},
},
};
};
</
script
>
</
script
>
...
@@ -60,9 +68,23 @@
...
@@ -60,9 +68,23 @@
</span>
</span>
<template
v-if=
"isStatusSuccess && isTypeQuality"
>
Fixed:
</
template
>
<template
v-if=
"isStatusSuccess && isTypeQuality"
>
Fixed:
</
template
>
<
template
v-if=
"
isTypeSecurity && issue.priority
"
>
{{
issue
.
priority
}}
:
</
template
>
<
template
v-if=
"
shouldRenderPriority(issue)
"
>
{{
issue
.
priority
}}
:
</
template
>
<
template
v-if=
"isTypeDocker"
>
<a
v-if=
"issue.nameLink"
:href=
"issue.nameLink"
target=
"_blank"
rel=
"noopener noreferrer nofollow"
>
{{
issue
.
name
}}
</a>
<template
v-else
>
{{
issue
.
name
}}
</
template
>
</template>
<
template
v-else
>
{{
issue
.
name
}}
<template
v-if=
"issue.score"
>
:
<strong>
{{
issue
.
score
}}
</strong></
template
>
{{
issue
.
name
}}
<template
v-if=
"issue.score"
>
:
<strong>
{{
issue
.
score
}}
</strong></
template
>
</template>
<
template
v-if=
"isTypePerformance && issue.delta != null"
>
<
template
v-if=
"isTypePerformance && issue.delta != null"
>
(
{{
issue
.
delta
>=
0
?
'
+
'
:
''
}}{{
issue
.
delta
}}
)
(
{{
issue
.
delta
>=
0
?
'
+
'
:
''
}}{{
issue
.
delta
}}
)
...
...
ee/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js
View file @
0499b49c
import
{
n__
,
s__
}
from
'
~/locale
'
;
import
{
n__
,
s__
,
sprintf
}
from
'
~/locale
'
;
import
CEWidgetOptions
from
'
~/vue_merge_request_widget/mr_widget_options
'
;
import
CEWidgetOptions
from
'
~/vue_merge_request_widget/mr_widget_options
'
;
import
WidgetApprovals
from
'
./components/approvals/mr_widget_approvals
'
;
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
'
;
...
@@ -128,15 +128,13 @@ export default {
...
@@ -128,15 +128,13 @@ export default {
return
s__
(
'
ciReport|No vulnerabilities were found
'
);
return
s__
(
'
ciReport|No vulnerabilities were found
'
);
}
}
if
(
!
unapproved
.
length
)
{
if
(
!
unapproved
.
length
&&
approved
.
length
)
{
return
n__
(
return
n__
(
'
Found %d approved vulnerability
'
,
'
Found %d approved vulnerability
'
,
'
Found %d approved vulnerabilities
'
,
'
Found %d approved vulnerabilities
'
,
approved
.
length
,
approved
.
length
,
);
);
}
}
else
if
(
unapproved
.
length
&&
!
approved
.
length
)
{
if
(
unapproved
.
length
&&
!
approved
.
length
)
{
return
n__
(
return
n__
(
'
Found %d vulnerability
'
,
'
Found %d vulnerability
'
,
'
Found %d vulnerabilities
'
,
'
Found %d vulnerabilities
'
,
...
@@ -147,7 +145,7 @@ export default {
...
@@ -147,7 +145,7 @@ export default {
return
`
${
n__
(
return
`
${
n__
(
'
Found %d vulnerability,
'
,
'
Found %d vulnerability,
'
,
'
Found %d vulnerabilities,
'
,
'
Found %d vulnerabilities,
'
,
unapproved
.
length
,
vulnerabilities
.
length
,
)}
${
n__
(
)}
${
n__
(
'
of which %d is approved
'
,
'
of which %d is approved
'
,
'
of which %d are approved
'
,
'
of which %d are approved
'
,
...
@@ -170,6 +168,17 @@ export default {
...
@@ -170,6 +168,17 @@ export default {
dockerStatus
()
{
dockerStatus
()
{
return
this
.
checkReportStatus
(
this
.
isLoadingDocker
,
this
.
loadingDockerFailed
);
return
this
.
checkReportStatus
(
this
.
isLoadingDocker
,
this
.
loadingDockerFailed
);
},
},
dockerInformationText
()
{
return
sprintf
(
_
.
escape
(
s__
(
'
ciReport|Unapproved vulnerabilities (red) can be marked as approved. %{helpLink}
'
)),
{
helpLink
:
`<a href="todo" _target="blank" >
${
_
.
escape
(
s__
(
'
ciReport|Learn more about whitelisting
'
))}
</a>`
,
},
false
,
);
},
},
},
methods
:
{
methods
:
{
checkReportStatus
(
loading
,
error
)
{
checkReportStatus
(
loading
,
error
)
{
...
@@ -294,8 +303,8 @@ export default {
...
@@ -294,8 +303,8 @@ export default {
loading-text="Loading codeclimate report"
loading-text="Loading codeclimate report"
error-text="Failed to load codeclimate report"
error-text="Failed to load codeclimate report"
:success-text="codequalityText"
:success-text="codequalityText"
:unresolved
I
ssues="mr.codeclimateMetrics.newIssues"
:unresolved
-i
ssues="mr.codeclimateMetrics.newIssues"
:resolved
I
ssues="mr.codeclimateMetrics.resolvedIssues"
:resolved
-i
ssues="mr.codeclimateMetrics.resolvedIssues"
/>
/>
<collapsible-section
<collapsible-section
class="js-performance-widget"
class="js-performance-widget"
...
@@ -305,9 +314,9 @@ export default {
...
@@ -305,9 +314,9 @@ export default {
loading-text="Loading performance report"
loading-text="Loading performance report"
error-text="Failed to load performance report"
error-text="Failed to load performance report"
:success-text="performanceText"
:success-text="performanceText"
:unresolved
I
ssues="mr.performanceMetrics.degraded"
:unresolved
-i
ssues="mr.performanceMetrics.degraded"
:resolved
I
ssues="mr.performanceMetrics.improved"
:resolved
-i
ssues="mr.performanceMetrics.improved"
:neutral
I
ssues="mr.performanceMetrics.neutral"
:neutral
-i
ssues="mr.performanceMetrics.neutral"
/>
/>
<collapsible-section
<collapsible-section
class="js-sast-widget"
class="js-sast-widget"
...
@@ -317,18 +326,19 @@ export default {
...
@@ -317,18 +326,19 @@ export default {
loading-text="Loading security report"
loading-text="Loading security report"
error-text="Failed to load security report"
error-text="Failed to load security report"
:success-text="securityText"
:success-text="securityText"
:unresolved
I
ssues="mr.securityReport"
:unresolved
-i
ssues="mr.securityReport"
/>
/>
<collapsible-section
<collapsible-section
class="js-docker-widget"
class="js-docker-widget"
v-if="shouldRenderDockerReport"
v-if="shouldRenderDockerReport"
type="
codequality
"
type="
docker
"
:status="dockerStatus"
:status="dockerStatus"
loading-text="Loading clair report"
loading-text="Loading clair report"
error-text="Failed to load clair report"
error-text="Failed to load clair report"
:success-text="dockerText"
:success-text="dockerText"
:unresolvedIssues="mr.dockerReport.unapproved"
:unresolved-issues="mr.dockerReport.unapproved"
:resolvedIssues="mr.dockerReport.approved"
:neutral-issues="mr.dockerReport.approved"
:info-text="dockerInformationText"
/>
/>
<div class="mr-widget-section">
<div class="mr-widget-section">
<component
<component
...
...
ee/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
View file @
0499b49c
...
@@ -91,20 +91,26 @@ export default class MergeRequestStore extends CEMergeRequestStore {
...
@@ -91,20 +91,26 @@ export default class MergeRequestStore extends CEMergeRequestStore {
this
.
dockerReport
.
vulnerabilities
=
parsedVulnerabilities
||
[];
this
.
dockerReport
.
vulnerabilities
=
parsedVulnerabilities
||
[];
// There is a typo in the original repo:
// https://github.com/arminc/clair-scanner/pull/39/files
// Fix this when the above PR is accepted
const
unapproved
=
data
.
unapproved
||
data
.
unaproved
||
[];
// Approved can be calculated by subtracting unapproved from vulnerabilities.
// Approved can be calculated by subtracting unapproved from vulnerabilities.
this
.
dockerReport
.
approved
=
parsedVulnerabilities
this
.
dockerReport
.
approved
=
parsedVulnerabilities
.
filter
(
item
=>
!
data
.
unapproved
.
find
(
el
=>
el
===
item
.
vulnerability
))
||
[];
.
filter
(
item
=>
!
unapproved
.
find
(
el
=>
el
===
item
.
vulnerability
))
||
[];
this
.
dockerReport
.
unapproved
=
parsedVulnerabilities
this
.
dockerReport
.
unapproved
=
parsedVulnerabilities
.
filter
(
item
=>
data
.
unapproved
.
find
(
el
=>
el
===
item
.
vulnerability
))
||
[];
.
filter
(
item
=>
unapproved
.
find
(
el
=>
el
===
item
.
vulnerability
))
||
[];
}
}
// TODO: Add links
static
parseDockerVulnerabilities
(
data
)
{
static
parseDockerVulnerabilities
(
data
)
{
return
data
.
map
(
el
=>
({
return
data
.
map
(
el
=>
({
name
:
el
.
vulnerability
,
name
:
el
.
vulnerability
,
priority
:
el
.
severity
,
priority
:
el
.
severity
,
path
:
el
.
namespace
,
path
:
el
.
namespace
,
// external link to provide better description
nameLink
:
`https://cve.mitre.org/cgi-bin/cvename.cgi?name=
${
el
.
vulnerability
}
`
,
...
el
,
...
el
,
}));
}));
}
}
...
...
spec/javascripts/vue_mr_widget/components/mr_widget_report_collapsible_section_spec.js
View file @
0499b49c
...
@@ -95,7 +95,6 @@ describe('Merge Request collapsible section', () => {
...
@@ -95,7 +95,6 @@ describe('Merge Request collapsible section', () => {
errorText
:
'
Failed to load codeclimate report
'
,
errorText
:
'
Failed to load codeclimate report
'
,
successText
:
'
Code quality improved on 1 point and degraded on 1 point
'
,
successText
:
'
Code quality improved on 1 point and degraded on 1 point
'
,
});
});
expect
(
vm
.
$el
.
textContent
.
trim
()).
toEqual
(
'
Failed to load codeclimate report
'
);
expect
(
vm
.
$el
.
textContent
.
trim
()).
toEqual
(
'
Failed to load codeclimate report
'
);
});
});
});
});
...
...
spec/javascripts/vue_mr_widget/components/mr_widget_report_issues_spec.js
View file @
0499b49c
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
mrWidgetCodeQualityIssues
from
'
ee/vue_merge_request_widget/components/mr_widget_report_issues.vue
'
;
import
mrWidgetCodeQualityIssues
from
'
ee/vue_merge_request_widget/components/mr_widget_report_issues.vue
'
;
import
mountComponent
from
'
../../helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
../../helpers/vue_mount_component_helper
'
;
import
{
securityParsedIssues
,
codequalityParsedIssues
}
from
'
../mock_data
'
;
import
{
securityParsedIssues
,
codequalityParsedIssues
,
dockerReportParsed
,
}
from
'
../mock_data
'
;
describe
(
'
merge request report issues
'
,
()
=>
{
describe
(
'
merge request report issues
'
,
()
=>
{
let
vm
;
let
vm
;
...
@@ -101,4 +105,38 @@ describe('merge request report issues', () => {
...
@@ -101,4 +105,38 @@ describe('merge request report issues', () => {
expect
(
vm
.
$el
.
querySelector
(
'
.mr-widget-code-quality-list li a
'
)).
toEqual
(
null
);
expect
(
vm
.
$el
.
querySelector
(
'
.mr-widget-code-quality-list li a
'
)).
toEqual
(
null
);
});
});
});
});
describe
(
'
for docker issues
'
,
()
=>
{
beforeEach
(()
=>
{
vm
=
mountComponent
(
MRWidgetCodeQualityIssues
,
{
issues
:
dockerReportParsed
.
unapproved
,
type
:
'
docker
'
,
status
:
'
failed
'
,
});
});
it
(
'
renders priority
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.mr-widget-code-quality-list li
'
).
textContent
.
trim
(),
).
toContain
(
dockerReportParsed
.
unapproved
[
0
].
priority
);
});
it
(
'
renders CVE link
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.mr-widget-code-quality-list a
'
).
getAttribute
(
'
href
'
),
).
toEqual
(
dockerReportParsed
.
unapproved
[
0
].
nameLink
);
expect
(
vm
.
$el
.
querySelector
(
'
.mr-widget-code-quality-list a
'
).
textContent
.
trim
(),
).
toEqual
(
dockerReportParsed
.
unapproved
[
0
].
name
);
});
it
(
'
renders namespace
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.mr-widget-code-quality-list li
'
).
textContent
.
trim
(),
).
toContain
(
dockerReportParsed
.
unapproved
[
0
].
path
);
expect
(
vm
.
$el
.
querySelector
(
'
.mr-widget-code-quality-list li
'
).
textContent
.
trim
(),
).
toContain
(
'
in
'
);
});
});
});
});
spec/javascripts/vue_mr_widget/ee_mr_widget_options_spec.js
View file @
0499b49c
...
@@ -8,6 +8,8 @@ import mockData, {
...
@@ -8,6 +8,8 @@ import mockData, {
basePerformance
,
basePerformance
,
headPerformance
,
headPerformance
,
securityIssues
,
securityIssues
,
dockerReport
,
dockerReportParsed
,
}
from
'
./mock_data
'
;
}
from
'
./mock_data
'
;
import
mountComponent
from
'
../helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
../helpers/vue_mount_component_helper
'
;
...
@@ -437,6 +439,19 @@ describe('ee merge request widget options', () => {
...
@@ -437,6 +439,19 @@ describe('ee merge request widget options', () => {
});
});
describe
(
'
docker report
'
,
()
=>
{
describe
(
'
docker report
'
,
()
=>
{
beforeEach
(()
=>
{
gl
.
mrWidgetData
=
{
...
mockData
,
clair
:
{
path
:
'
clair.json
'
,
blob_path
:
'
blob_path
'
,
},
};
Component
.
mr
=
new
MRWidgetStore
(
gl
.
mrWidgetData
);
Component
.
service
=
new
MRWidgetService
({});
});
describe
(
'
when it is loading
'
,
()
=>
{
describe
(
'
when it is loading
'
,
()
=>
{
it
(
'
should render loading indicator
'
,
()
=>
{
it
(
'
should render loading indicator
'
,
()
=>
{
vm
=
mountComponent
(
Component
);
vm
=
mountComponent
(
Component
);
...
@@ -447,13 +462,74 @@ describe('ee merge request widget options', () => {
...
@@ -447,13 +462,74 @@ describe('ee merge request widget options', () => {
});
});
describe
(
'
with successful request
'
,
()
=>
{
describe
(
'
with successful request
'
,
()
=>
{
it
(
'
should render provided data
'
,
()
=>
{
const
interceptor
=
(
request
,
next
)
=>
{
if
(
request
.
url
===
'
clair.json
'
)
{
next
(
request
.
respondWith
(
JSON
.
stringify
(
dockerReport
),
{
status
:
200
,
}));
}
};
beforeEach
(()
=>
{
Vue
.
http
.
interceptors
.
push
(
interceptor
);
vm
=
mountComponent
(
Component
);
});
afterEach
(()
=>
{
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptors
,
interceptor
);
});
it
(
'
should render provided data
'
,
(
done
)
=>
{
setTimeout
(()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.js-docker-widget .js-code-text
'
).
textContent
.
trim
(),
).
toEqual
(
'
Found 3 vulnerabilities, of which 1 is approved
'
);
vm
.
$el
.
querySelector
(
'
.js-docker-widget button
'
).
click
();
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.js-docker-widget .mr-widget-code-quality-info
'
).
textContent
.
trim
(),
).
toContain
(
'
Unapproved vulnerabilities (red) can be marked as approved.
'
);
expect
(
vm
.
$el
.
querySelector
(
'
.js-docker-widget .mr-widget-code-quality-info a
'
).
textContent
.
trim
(),
).
toContain
(
'
Learn more about whitelisting
'
);
const
firstVulnerability
=
vm
.
$el
.
querySelector
(
'
.js-docker-widget .mr-widget-code-quality-list
'
).
textContent
.
trim
();
expect
(
firstVulnerability
).
toContain
(
dockerReportParsed
.
unapproved
[
0
].
name
);
expect
(
firstVulnerability
).
toContain
(
dockerReportParsed
.
unapproved
[
0
].
path
);
done
();
});
},
0
);
});
});
});
});
describe
(
'
with failed request
'
,
()
=>
{
describe
(
'
with failed request
'
,
()
=>
{
it
(
'
should render error indicator
'
,
()
=>
{
const
interceptor
=
(
request
,
next
)
=>
{
if
(
request
.
url
===
'
clair.json
'
)
{
next
(
request
.
respondWith
({},
{
status
:
500
,
}));
}
};
beforeEach
(()
=>
{
Vue
.
http
.
interceptors
.
push
(
interceptor
);
vm
=
mountComponent
(
Component
);
});
afterEach
(()
=>
{
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptors
,
interceptor
);
});
it
(
'
should render error indicator
'
,
(
done
)
=>
{
setTimeout
(()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.js-docker-widget
'
).
textContent
.
trim
(),
).
toContain
(
'
Failed to load clair report
'
);
done
();
},
0
);
});
});
});
});
});
});
...
@@ -497,31 +573,6 @@ describe('ee merge request widget options', () => {
...
@@ -497,31 +573,6 @@ describe('ee merge request widget options', () => {
});
});
});
});
describe
(
'
shouldRenderDockerReport
'
,
()
=>
{
it
(
'
returns undefined when clair is not set up
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
mrData
:
{
...
mockData
,
},
});
expect
(
vm
.
shouldRenderDockerReport
).
toEqual
(
undefined
);
});
it
(
'
returns clair object when clair is set up
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
mrData
:
{
...
mockData
,
clair
:
{
path
:
'
foo
'
,
},
},
});
expect
(
vm
.
shouldRenderDockerReport
).
toEqual
({
path
:
'
foo
'
});
});
});
describe
(
'
dockerText
'
,
()
=>
{
describe
(
'
dockerText
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
vm
=
mountComponent
(
Component
,
{
vm
=
mountComponent
(
Component
,
{
...
@@ -555,7 +606,7 @@ describe('ee merge request widget options', () => {
...
@@ -555,7 +606,7 @@ describe('ee merge request widget options', () => {
}],
}],
unapproved
:
[],
unapproved
:
[],
};
};
expect
(
vm
.
dockerText
).
toEqual
(
'
Found 1 vulnerability
'
);
expect
(
vm
.
dockerText
).
toEqual
(
'
Found 1
approved
vulnerability
'
);
});
});
it
(
'
returns approved information - plural
'
,
()
=>
{
it
(
'
returns approved information - plural
'
,
()
=>
{
...
...
spec/javascripts/vue_mr_widget/mock_data.js
View file @
0499b49c
...
@@ -215,7 +215,7 @@ export default {
...
@@ -215,7 +215,7 @@ export default {
"
head_blob_path
"
:
"
/root/acets-app/blob/abcdef
"
,
"
head_blob_path
"
:
"
/root/acets-app/blob/abcdef
"
,
"
base_path
"
:
"
base.json
"
,
"
base_path
"
:
"
base.json
"
,
"
base_blob_path
"
:
"
/root/acets-app/blob/abcdef
"
"
base_blob_path
"
:
"
/root/acets-app/blob/abcdef
"
}
}
,
};
};
export
const
headIssues
=
[
export
const
headIssues
=
[
...
@@ -428,3 +428,90 @@ export const parsedSecurityIssuesStore = [
...
@@ -428,3 +428,90 @@ export const parsedSecurityIssuesStore = [
urlPath
:
'
path/Gemfile.lock
'
,
urlPath
:
'
path/Gemfile.lock
'
,
},
},
];
];
export
const
dockerReport
=
{
unapproved
:
[
'
CVE-2017-12944
'
,
'
CVE-2017-16232
'
],
vulnerabilities
:
[
{
vulnerability
:
'
CVE-2017-12944
'
,
namespace
:
'
debian:8
'
,
severity
:
'
Medium
'
},
{
vulnerability
:
'
CVE-2017-16232
'
,
namespace
:
'
debian:8
'
,
severity
:
'
Negligible
'
},
{
vulnerability
:
'
CVE-2014-8130
'
,
namespace
:
'
debian:8
'
,
severity
:
'
Negligible
'
}
]
};
export
const
dockerReportParsed
=
{
unapproved
:
[
{
vulnerability
:
'
CVE-2017-12944
'
,
namespace
:
'
debian:8
'
,
severity
:
'
Medium
'
,
name
:
'
CVE-2017-12944
'
,
priority
:
'
Medium
'
,
path
:
'
debian:8
'
,
nameLink
:
'
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-12944
'
},
{
vulnerability
:
'
CVE-2017-16232
'
,
namespace
:
'
debian:8
'
,
severity
:
'
Negligible
'
,
name
:
'
CVE-2017-16232
'
,
priority
:
'
Negligible
'
,
path
:
'
debian:8
'
,
nameLink
:
'
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-16232
'
},
],
approved
:
[
{
vulnerability
:
'
CVE-2014-8130
'
,
namespace
:
'
debian:8
'
,
severity
:
'
Negligible
'
,
name
:
'
CVE-2014-8130
'
,
priority
:
'
Negligible
'
,
path
:
'
debian:8
'
,
nameLink
:
'
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-8130
'
},
],
vulnerabilities
:
[
{
vulnerability
:
'
CVE-2017-12944
'
,
namespace
:
'
debian:8
'
,
severity
:
'
Medium
'
,
name
:
'
CVE-2017-12944
'
,
priority
:
'
Medium
'
,
path
:
'
debian:8
'
,
nameLink
:
'
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-12944
'
},
{
vulnerability
:
'
CVE-2017-16232
'
,
namespace
:
'
debian:8
'
,
severity
:
'
Negligible
'
,
name
:
'
CVE-2017-16232
'
,
priority
:
'
Negligible
'
,
path
:
'
debian:8
'
,
nameLink
:
'
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-16232
'
},
{
vulnerability
:
'
CVE-2014-8130
'
,
namespace
:
'
debian:8
'
,
severity
:
'
Negligible
'
,
name
:
'
CVE-2014-8130
'
,
priority
:
'
Negligible
'
,
path
:
'
debian:8
'
,
nameLink
:
'
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-8130
'
}
]
};
spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js
View file @
0499b49c
...
@@ -6,6 +6,8 @@ import mockData, {
...
@@ -6,6 +6,8 @@ import mockData, {
parsedBaseIssues
,
parsedBaseIssues
,
parsedHeadIssues
,
parsedHeadIssues
,
parsedSecurityIssuesStore
,
parsedSecurityIssuesStore
,
dockerReport
,
dockerReportParsed
,
}
from
'
../mock_data
'
;
}
from
'
../mock_data
'
;
describe
(
'
MergeRequestStore
'
,
()
=>
{
describe
(
'
MergeRequestStore
'
,
()
=>
{
...
@@ -95,4 +97,51 @@ describe('MergeRequestStore', () => {
...
@@ -95,4 +97,51 @@ describe('MergeRequestStore', () => {
expect
(
security
.
path
).
toEqual
(
securityIssues
[
0
].
file
);
expect
(
security
.
path
).
toEqual
(
securityIssues
[
0
].
file
);
});
});
});
});
describe
(
'
initDockerReport
'
,
()
=>
{
it
(
'
sets the defaults
'
,
()
=>
{
store
.
initDockerReport
({
clair
:
{
path
:
'
clair.json
'
}
});
expect
(
store
.
clair
).
toEqual
({
path
:
'
clair.json
'
});
expect
(
store
.
dockerReport
).
toEqual
({
approved
:
[],
unapproved
:
[],
vulnerabilities
:
[],
});
});
});
describe
(
'
setDockerReport
'
,
()
=>
{
it
(
'
sets docker report with approved and unapproved vulnerabilities parsed
'
,
()
=>
{
store
.
setDockerReport
(
dockerReport
);
expect
(
store
.
dockerReport
.
vulnerabilities
).
toEqual
(
dockerReportParsed
.
vulnerabilities
);
expect
(
store
.
dockerReport
.
approved
).
toEqual
(
dockerReportParsed
.
approved
);
expect
(
store
.
dockerReport
.
unapproved
).
toEqual
(
dockerReportParsed
.
unapproved
);
});
it
(
'
handles unaproved typo
'
,
()
=>
{
store
.
setDockerReport
({
vulnerabilities
:
[
{
vulnerability
:
'
CVE-2017-12944
'
,
namespace
:
'
debian:8
'
,
severity
:
'
Medium
'
,
},
],
unaproved
:
[
'
CVE-2017-12944
'
],
});
expect
(
store
.
dockerReport
.
unapproved
[
0
].
vulnerability
).
toEqual
(
'
CVE-2017-12944
'
);
});
});
describe
(
'
parseDockerVulnerabilities
'
,
()
=>
{
it
(
'
parses docker report
'
,
()
=>
{
expect
(
MergeRequestStore
.
parseDockerVulnerabilities
(
dockerReport
.
vulnerabilities
),
).
toEqual
(
dockerReportParsed
.
vulnerabilities
,
);
});
});
});
});
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