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
648ff75a
Commit
648ff75a
authored
Nov 25, 2021
by
Daniel Tian
Committed by
Savas Vedova
Nov 25, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Change "Detected" to "Needs triage" on vulnerability report and details
parent
73845e96
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
80 additions
and
72 deletions
+80
-72
ee/app/assets/javascripts/security_dashboard/components/shared/status_dropdown.vue
.../security_dashboard/components/shared/status_dropdown.vue
+3
-3
ee/app/assets/javascripts/vulnerabilities/components/header.vue
.../assets/javascripts/vulnerabilities/components/header.vue
+11
-3
ee/app/assets/javascripts/vulnerabilities/components/vulnerability_state_dropdown.vue
...lnerabilities/components/vulnerability_state_dropdown.vue
+7
-7
ee/app/assets/javascripts/vulnerabilities/constants.js
ee/app/assets/javascripts/vulnerabilities/constants.js
+19
-16
ee/spec/frontend/security_dashboard/components/shared/status_dropdown_spec.js
...urity_dashboard/components/shared/status_dropdown_spec.js
+1
-2
ee/spec/frontend/vulnerabilities/header_spec.js
ee/spec/frontend/vulnerabilities/header_spec.js
+6
-2
ee/spec/frontend/vulnerabilities/vulnerability_state_dropdown_spec.js
...tend/vulnerabilities/vulnerability_state_dropdown_spec.js
+25
-33
ee/spec/frontend_integration/vulnerabilities/vulnerabilities_init_integration_spec.js
.../vulnerabilities/vulnerabilities_init_integration_spec.js
+3
-1
locale/gitlab.pot
locale/gitlab.pot
+5
-5
No files found.
ee/app/assets/javascripts/security_dashboard/components/shared/status_dropdown.vue
View file @
648ff75a
...
...
@@ -18,7 +18,7 @@ export default {
computed
:
{
dropdownPlaceholderText
()
{
return
this
.
selectedKey
?
this
.
$options
.
states
[
this
.
selectedKey
].
d
isplayName
?
this
.
$options
.
states
[
this
.
selectedKey
].
d
ropdownText
:
this
.
$options
.
i18n
.
defaultPlaceholder
;
},
},
...
...
@@ -46,8 +46,8 @@ export default {
is-check-item
@
click=
"setSelectedKey(state)"
>
<div
class=
"gl-font-weight-bold"
>
{{
state
.
d
isplayName
}}
</div>
<div>
{{
state
.
description
}}
</div>
<div
class=
"gl-font-weight-bold"
>
{{
state
.
d
ropdownText
}}
</div>
<div>
{{
state
.
d
ropdownD
escription
}}
</div>
</gl-dropdown-item>
</gl-dropdown>
</
template
>
ee/app/assets/javascripts/vulnerabilities/components/header.vue
View file @
648ff75a
...
...
@@ -11,7 +11,12 @@ import download from '~/lib/utils/downloader';
import
{
redirectTo
}
from
'
~/lib/utils/url_utility
'
;
import
UsersCache
from
'
~/lib/utils/users_cache
'
;
import
{
s__
}
from
'
~/locale
'
;
import
{
VULNERABILITY_STATE_OBJECTS
,
FEEDBACK_TYPES
,
HEADER_ACTION_BUTTONS
}
from
'
../constants
'
;
import
{
VULNERABILITY_STATES
,
VULNERABILITY_STATE_OBJECTS
,
FEEDBACK_TYPES
,
HEADER_ACTION_BUTTONS
,
}
from
'
../constants
'
;
import
{
normalizeGraphQLVulnerability
}
from
'
../helpers
'
;
import
ResolutionAlert
from
'
./resolution_alert.vue
'
;
import
StatusDescription
from
'
./status_description.vue
'
;
...
...
@@ -53,6 +58,9 @@ export default {
},
computed
:
{
stateName
()
{
return
VULNERABILITY_STATES
[
this
.
vulnerability
.
state
];
},
stateVariant
()
{
return
this
.
$options
.
badgeVariants
[
this
.
vulnerability
.
state
]
||
'
neutral
'
;
},
...
...
@@ -223,8 +231,8 @@ export default {
data-testid=
"vulnerability-detail-body"
>
<gl-loading-icon
v-if=
"isLoadingVulnerability"
size=
"sm"
class=
"mr-2"
/>
<gl-badge
v-else
class=
"gl-mr-4
text-capitalize
"
:variant=
"stateVariant"
>
{{
vulnerability
.
stat
e
}}
<gl-badge
v-else
class=
"gl-mr-4"
:variant=
"stateVariant"
>
{{
stateNam
e
}}
</gl-badge>
<status-description
...
...
ee/app/assets/javascripts/vulnerabilities/components/vulnerability_state_dropdown.vue
View file @
648ff75a
...
...
@@ -24,6 +24,9 @@ export default {
initialStateItem
()
{
return
VULNERABILITY_STATE_OBJECTS
[
this
.
initialState
];
},
buttonText
()
{
return
this
.
initialStateItem
?.
buttonText
;
},
},
watch
:
{
...
...
@@ -37,16 +40,13 @@ export default {
changeSelectedState
(
newState
)
{
this
.
selected
=
newState
;
},
closeDropdown
()
{
this
.
$refs
.
dropdown
.
hide
();
},
// Reset the selected dropdown item to what was passed in by the parent.
resetDropdown
()
{
this
.
selected
=
this
.
initialStateItem
;
},
saveState
(
selectedState
)
{
this
.
$emit
(
'
change
'
,
selectedState
);
this
.
closeDropdown
();
...
...
@@ -59,14 +59,14 @@ export default {
<gl-dropdown
ref=
"dropdown"
menu-class=
"gl-p-0 dropdown-extended-height"
toggle-class=
"text-capitalize"
:text=
"initialState"
:text=
"buttonText"
:right=
"true"
@
hide=
"resetDropdown"
>
<li
v-for=
"stateItem in $options.states"
:key=
"stateItem.action"
:data-testid=
"stateItem.state"
class=
"py-3 px-2 dropdown-item cursor-pointer border-bottom"
:class=
"
{ selected: selected === stateItem }"
@click="changeSelectedState(stateItem)"
...
...
@@ -78,9 +78,9 @@ export default {
name=
"status_success_borderless"
:size=
"24"
/>
<div
class=
"pl-4 font-weight-bold"
>
{{
stateItem
.
d
isplayName
}}
</div>
<div
class=
"pl-4 font-weight-bold"
>
{{
stateItem
.
d
ropdownText
}}
</div>
</div>
<div
class=
"pl-4"
>
{{
stateItem
.
description
}}
</div>
<div
class=
"pl-4"
>
{{
stateItem
.
d
ropdownD
escription
}}
</div>
</li>
<template
#footer
>
...
...
ee/app/assets/javascripts/vulnerabilities/constants.js
View file @
648ff75a
...
...
@@ -6,19 +6,27 @@ import {
const
falsePositiveMessage
=
s__
(
'
VulnerabilityManagement|Will not fix or a false-positive
'
);
export
const
VULNERABILITY_STATES
=
{
detected
:
s__
(
'
VulnerabilityStatusTypes|Needs triage
'
),
confirmed
:
s__
(
'
VulnerabilityStatusTypes|Confirmed
'
),
dismissed
:
s__
(
'
VulnerabilityStatusTypes|Dismissed
'
),
resolved
:
s__
(
'
VulnerabilityStatusTypes|Resolved
'
),
};
export
const
VULNERABILITY_STATE_OBJECTS
=
{
detected
:
{
action
:
'
revert
'
,
state
:
'
detected
'
,
statusBoxStyle
:
'
expired
'
,
d
isplayName
:
s__
(
'
VulnerabilityManagement|Detected
'
),
d
escription
:
s__
(
'
VulnerabilityManagement|Needs triage
'
),
buttonText
:
VULNERABILITY_STATES
.
detected
,
d
ropdownText
:
s__
(
'
VulnerabilityManagement|Needs triage
'
),
d
ropdownDescription
:
s__
(
'
VulnerabilityManagement|Requires assessment
'
),
},
dismissed
:
{
action
:
'
dismiss
'
,
state
:
'
dismissed
'
,
displayName
:
__
(
'
Dismiss
'
),
description
:
falsePositiveMessage
,
buttonText
:
VULNERABILITY_STATES
.
dismissed
,
dropdownText
:
__
(
'
Dismiss
'
),
dropdownDescription
:
falsePositiveMessage
,
payload
:
{
comment
:
falsePositiveMessage
,
},
...
...
@@ -26,24 +34,19 @@ export const VULNERABILITY_STATE_OBJECTS = {
confirmed
:
{
action
:
'
confirm
'
,
state
:
'
confirmed
'
,
displayName
:
__
(
'
Confirm
'
),
description
:
s__
(
'
VulnerabilityManagement|A true-positive and will fix
'
),
buttonText
:
VULNERABILITY_STATES
.
confirmed
,
dropdownText
:
__
(
'
Confirm
'
),
dropdownDescription
:
s__
(
'
VulnerabilityManagement|A true-positive and will fix
'
),
},
resolved
:
{
action
:
'
resolve
'
,
state
:
'
resolved
'
,
displayName
:
__
(
'
Resolve
'
),
description
:
s__
(
'
VulnerabilityManagement|Verified as fixed or mitigated
'
),
buttonText
:
VULNERABILITY_STATES
.
resolved
,
dropdownText
:
__
(
'
Resolve
'
),
dropdownDescription
:
s__
(
'
VulnerabilityManagement|Verified as fixed or mitigated
'
),
},
};
export
const
VULNERABILITY_STATES
=
{
detected
:
s__
(
'
VulnerabilityStatusTypes|Detected
'
),
confirmed
:
s__
(
'
VulnerabilityStatusTypes|Confirmed
'
),
dismissed
:
s__
(
'
VulnerabilityStatusTypes|Dismissed
'
),
resolved
:
s__
(
'
VulnerabilityStatusTypes|Resolved
'
),
};
export
const
HEADER_ACTION_BUTTONS
=
{
mergeRequestCreation
:
{
name
:
s__
(
'
ciReport|Resolve with merge request
'
),
...
...
ee/spec/frontend/security_dashboard/components/shared/status_dropdown_spec.js
View file @
648ff75a
...
...
@@ -24,7 +24,6 @@ describe('Status Dropdown component', () => {
afterEach
(()
=>
{
wrapper
.
destroy
();
wrapper
=
null
;
});
it
(
'
renders the correct placeholder
'
,
()
=>
{
...
...
@@ -38,7 +37,7 @@ describe('Status Dropdown component', () => {
it
(
`renders
${
state
}
`
,
()
=>
{
expect
(
findDropdownItems
().
at
(
index
).
text
()).
toBe
(
`
${
status
.
d
isplayName
}
${
status
.
d
escription
}
`
,
`
${
status
.
d
ropdownText
}
${
status
.
dropdownD
escription
}
`
,
);
});
...
...
ee/spec/frontend/vulnerabilities/header_spec.js
View file @
648ff75a
...
...
@@ -9,7 +9,11 @@ import Header from 'ee/vulnerabilities/components/header.vue';
import
ResolutionAlert
from
'
ee/vulnerabilities/components/resolution_alert.vue
'
;
import
StatusDescription
from
'
ee/vulnerabilities/components/status_description.vue
'
;
import
VulnerabilityStateDropdown
from
'
ee/vulnerabilities/components/vulnerability_state_dropdown.vue
'
;
import
{
FEEDBACK_TYPES
,
VULNERABILITY_STATE_OBJECTS
}
from
'
ee/vulnerabilities/constants
'
;
import
{
FEEDBACK_TYPES
,
VULNERABILITY_STATE_OBJECTS
,
VULNERABILITY_STATES
,
}
from
'
ee/vulnerabilities/constants
'
;
import
createMockApollo
from
'
helpers/mock_apollo_helper
'
;
import
UsersMockHelper
from
'
helpers/user_mock_data_helper
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
...
...
@@ -305,7 +309,7 @@ describe('Vulnerability Header', () => {
createWrapper
({
vulnerability
:
{
state
}
});
expect
(
findBadge
().
props
(
'
variant
'
)).
toBe
(
variant
);
expect
(
findBadge
().
text
()).
toBe
(
state
);
expect
(
findBadge
().
text
()).
toBe
(
VULNERABILITY_STATES
[
state
]
);
},
);
});
...
...
ee/spec/frontend/vulnerabilities/vulnerability_state_dropdown_spec.js
View file @
648ff75a
import
{
GlDropdown
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
shallowMount
Extended
}
from
'
helpers/vue_test_utils_helper
'
;
import
VulnerabilityStateDropdown
from
'
ee/vulnerabilities/components/vulnerability_state_dropdown.vue
'
;
import
{
VULNERABILITY_STATE_OBJECTS
}
from
'
ee/vulnerabilities/constants
'
;
const
vulnerabilityState
Entries
=
Object
.
entri
es
(
VULNERABILITY_STATE_OBJECTS
);
const
vulnerabilityState
Objects
=
Object
.
valu
es
(
VULNERABILITY_STATE_OBJECTS
);
describe
(
'
Vulnerability state dropdown component
'
,
()
=>
{
let
wrapper
;
const
createWrapper
=
(
initialState
=
vulnerabilityState
Entries
[
0
][
0
]
)
=>
{
const
createWrapper
=
(
initialState
=
vulnerabilityState
Objects
[
0
].
state
)
=>
{
// Create a dropdown that by default has the first vulnerability state selected.
wrapper
=
shallowMount
(
VulnerabilityStateDropdown
,
{
wrapper
=
shallowMount
Extended
(
VulnerabilityStateDropdown
,
{
propsData
:
{
initialState
},
stubs
:
{
GlDropdown
,
},
stubs
:
{
GlDropdown
},
});
// Mock out this function, it's called by some methods in the component.
wrapper
.
vm
.
$refs
.
dropdown
.
hide
=
jest
.
fn
();
};
// isSelected is designed to work with both single VueWrapper or WrapperArray
const
isSelected
=
(
items
)
=>
Boolean
((
items
.
wrappers
??
[
items
]).
find
((
w
)
=>
w
.
find
(
'
.selected-icon
'
).
exists
()));
const
isSelected
=
(
item
)
=>
item
.
find
(
'
.selected-icon
'
).
exists
();
// Item is selected if there's a checkmark icon.
const
isDisabled
=
(
item
)
=>
item
.
attributes
(
'
disabled
'
)
===
'
true
'
;
const
dropdownItems
=
()
=>
wrapper
.
findAll
(
'
.dropdown-item
'
);
const
firstUnselectedItem
=
()
=>
wrapper
.
find
(
'
.dropdown-item:not(.selected)
'
);
...
...
@@ -31,45 +27,41 @@ describe('Vulnerability state dropdown component', () => {
const
saveButton
=
()
=>
wrapper
.
find
({
ref
:
'
save-button
'
});
const
cancelButton
=
()
=>
wrapper
.
find
({
ref
:
'
cancel-button
'
});
const
innerDropdown
=
()
=>
wrapper
.
find
({
ref
:
'
dropdown
'
});
const
dropdownItemFor
=
(
stateEntry
)
=>
dropdownItems
().
wrappers
.
find
((
x
)
=>
{
const
text
=
x
.
text
();
return
text
.
includes
(
stateEntry
.
displayName
)
&&
text
.
includes
(
stateEntry
.
description
);
});
const
dropdownItemFor
=
(
state
)
=>
wrapper
.
findByTestId
(
state
);
afterEach
(()
=>
wrapper
.
destroy
());
describe
(
'
tests that need to manually create the wrapper
'
,
()
=>
{
it
.
each
(
vulnerabilityState
Entrie
s
)(
it
.
each
(
vulnerabilityState
Object
s
)(
'
dropdown is created with the %s state already selected
'
,
(
stateString
,
stateObject
)
=>
{
createWrapper
(
state
String
);
(
{
state
}
)
=>
{
createWrapper
(
state
);
expect
(
isSelected
(
dropdownItemFor
(
state
Object
))).
toBe
(
true
);
// Check that the dropdown item is selected.
expect
(
isSelected
(
dropdownItemFor
(
state
))).
toBe
(
true
);
// Check that the dropdown item is selected.
},
);
it
(
'
if an unknown state is passed in, nothing will be selected by default
'
,
()
=>
{
createWrapper
(
'
some unknown state
'
);
expect
(
isSelected
(
dropdownItems
())).
toBe
(
false
);
dropdownItems
().
wrappers
.
forEach
((
dropdownItem
)
=>
{
expect
(
isSelected
(
dropdownItem
)).
toBe
(
false
);
});
});
it
.
each
(
vulnerabilityState
Entrie
s
)(
it
.
each
(
vulnerabilityState
Object
s
)(
`when the %s dropdown item is clicked, it's the only one that's selected`
,
(
stateString
,
stateObject
)
=>
{
(
{
state
}
)
=>
{
// Start off with an unknown state so we can click through each item and see it change.
createWrapper
(
'
some unknown state
'
);
const
dropdownItem
=
dropdownItemFor
(
state
Object
);
const
dropdownItem
=
dropdownItemFor
(
state
);
dropdownItem
.
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
// Check that the clicked item is selected.
expect
(
isSelected
(
dropdownItem
)).
toBe
(
true
);
// Check that the other items aren't selected.
const
otherItems
=
wrapper
.
findAll
(
'
.dropdown-item:not(.selected)
'
);
expect
(
isSelected
(
otherItems
)).
toBe
(
false
);
dropdownItems
().
wrappers
.
forEach
((
item
)
=>
{
expect
(
isSelected
(
item
)).
toBe
(
item
.
attributes
(
'
data-testid
'
)
===
state
);
});
});
},
);
...
...
@@ -141,13 +133,13 @@ describe('Vulnerability state dropdown component', () => {
});
it
(
'
when the parent component changes the state, the dropdown will update its selected and initial item
'
,
()
=>
{
const
[
stateString
,
stateObject
]
=
vulnerabilityStateEntrie
s
[
1
];
const
stateObject
=
vulnerabilityStateObject
s
[
1
];
wrapper
.
setProps
({
initialState
:
state
String
});
// Change the state.
wrapper
.
setProps
({
initialState
:
state
Object
.
state
});
// Change the state.
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
expect
(
innerDropdown
().
props
(
'
text
'
)).
toBe
(
state
String
);
// Check that the dropdown button's value matches the initial state.
expect
(
selectedItem
().
text
()).
toMatch
(
new
RegExp
(
`^
${
stateObject
.
action
}
`
,
'
i
'
)
);
// Check that the selected item is the initial state.
expect
(
innerDropdown
().
props
(
'
text
'
)).
toBe
(
state
Object
.
buttonText
);
// Check that the dropdown button's value matches the initial state.
expect
(
selectedItem
().
text
()).
toMatch
(
stateObject
.
dropdownText
);
// Check that the selected item is the initial state.
expect
(
isDisabled
(
saveButton
())).
toBe
(
true
);
// Check that the save button is disabled.
});
});
...
...
ee/spec/frontend_integration/vulnerabilities/vulnerabilities_init_integration_spec.js
View file @
648ff75a
import
{
screen
,
within
}
from
'
@testing-library/dom
'
;
import
initVulnerabilities
from
'
ee/vulnerabilities/vulnerabilities_init
'
;
import
{
waitForText
}
from
'
helpers/wait_for_text
'
;
import
{
VULNERABILITY_STATES
}
from
'
ee/vulnerabilities/constants
'
;
import
{
mockIssueLink
}
from
'
../test_helpers/mock_data/vulnerabilities_mock_data
'
;
import
{
mockVulnerability
}
from
'
./mock_data
'
;
...
...
@@ -38,8 +39,9 @@ describe('Vulnerability Report', () => {
it
(
"
displays the vulnerability's status
"
,
()
=>
{
const
headerBody
=
screen
.
getByTestId
(
'
vulnerability-detail-body
'
);
const
stateName
=
VULNERABILITY_STATES
[
mockVulnerability
.
state
];
expect
(
within
(
headerBody
).
getByText
(
mockVulnerability
.
stat
e
)).
toBeInstanceOf
(
HTMLElement
);
expect
(
within
(
headerBody
).
getByText
(
stateNam
e
)).
toBeInstanceOf
(
HTMLElement
);
});
it
(
"
displays the vulnerability's severity
"
,
()
=>
{
...
...
locale/gitlab.pot
View file @
648ff75a
...
...
@@ -38513,9 +38513,6 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
msgid "VulnerabilityManagement|Detected"
msgstr ""
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
...
...
@@ -38531,6 +38528,9 @@ msgstr ""
msgid "VulnerabilityManagement|Related Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Requires assessment"
msgstr ""
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
...
...
@@ -38576,10 +38576,10 @@ msgstr ""
msgid "VulnerabilityStatusTypes|Confirmed"
msgstr ""
msgid "VulnerabilityStatusTypes|D
etect
ed"
msgid "VulnerabilityStatusTypes|D
ismiss
ed"
msgstr ""
msgid "VulnerabilityStatusTypes|
Dismissed
"
msgid "VulnerabilityStatusTypes|
Needs triage
"
msgstr ""
msgid "VulnerabilityStatusTypes|Resolved"
...
...
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