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
d1ec236d
Commit
d1ec236d
authored
Sep 10, 2019
by
Fernando Arias
Committed by
Paul Slaughter
Sep 10, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add toast messages for vuln dismissals
* Add toast message for add/edit/delete dismissal reasons
parent
f24ff741
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
261 additions
and
9 deletions
+261
-9
app/assets/javascripts/vue_shared/plugins/global_toast.js
app/assets/javascripts/vue_shared/plugins/global_toast.js
+8
-0
ee/app/assets/javascripts/security_dashboard/store/modules/vulnerabilities/actions.js
...curity_dashboard/store/modules/vulnerabilities/actions.js
+24
-3
ee/app/assets/javascripts/vue_shared/security_reports/store/actions.js
.../javascripts/vue_shared/security_reports/store/actions.js
+23
-2
ee/changelogs/unreleased/edit-delete-vuln-dismissal-toast-notication-vue-global.yml
...dit-delete-vuln-dismissal-toast-notication-vue-global.yml
+5
-0
ee/spec/javascripts/security_dashboard/store/vulnerabilities/actions_spec.js
.../security_dashboard/store/vulnerabilities/actions_spec.js
+85
-4
ee/spec/javascripts/vue_shared/security_reports/store/actions_spec.js
...scripts/vue_shared/security_reports/store/actions_spec.js
+80
-0
locale/gitlab.pot
locale/gitlab.pot
+12
-0
spec/frontend/vue_shared/plugins/global_toast_spec.js
spec/frontend/vue_shared/plugins/global_toast_spec.js
+24
-0
No files found.
app/assets/javascripts/vue_shared/plugins/global_toast.js
0 → 100644
View file @
d1ec236d
import
Vue
from
'
vue
'
;
import
{
GlToast
}
from
'
@gitlab/ui
'
;
Vue
.
use
(
GlToast
);
export
default
function
showGlobalToast
(...
args
)
{
return
Vue
.
toasted
.
show
(...
args
);
}
ee/app/assets/javascripts/security_dashboard/store/modules/vulnerabilities/actions.js
View file @
d1ec236d
import
$
from
'
jquery
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
downloadPatchHelper
from
'
ee/vue_shared/security_reports/store/utils/download_patch_helper
'
;
import
*
as
types
from
'
./mutation_types
'
;
import
{
parseIntPagination
,
normalizeHeaders
}
from
'
~/lib/utils/common_utils
'
;
import
{
s__
}
from
'
~/locale
'
;
import
{
s__
,
sprintf
}
from
'
~/locale
'
;
import
createFlash
from
'
~/flash
'
;
import
toast
from
'
~/vue_shared/plugins/global_toast
'
;
import
*
as
types
from
'
./mutation_types
'
;
/**
* A lot of this file has duplicate actions in
...
...
@@ -153,6 +154,10 @@ export const dismissVulnerability = (
)
=>
{
dispatch
(
'
requestDismissVulnerability
'
);
const
toastMsg
=
sprintf
(
s__
(
"
Security Reports|Dismissed '%{vulnerabilityName}'
"
),
{
vulnerabilityName
:
vulnerability
.
name
,
});
axios
.
post
(
vulnerability
.
create_vulnerability_feedback_dismissal_path
,
{
vulnerability_feedback
:
{
...
...
@@ -170,6 +175,7 @@ export const dismissVulnerability = (
.
then
(({
data
})
=>
{
dispatch
(
'
closeDismissalCommentBox
'
);
dispatch
(
'
receiveDismissVulnerabilitySuccess
'
,
{
vulnerability
,
data
});
toast
(
toastMsg
);
})
.
catch
(()
=>
{
dispatch
(
'
receiveDismissVulnerabilityError
'
,
{
flashError
});
...
...
@@ -198,10 +204,20 @@ export const receiveDismissVulnerabilityError = ({ commit }, { flashError }) =>
export
const
addDismissalComment
=
({
dispatch
},
{
vulnerability
,
comment
})
=>
{
dispatch
(
'
requestAddDismissalComment
'
);
const
{
dismissal_feedback
}
=
vulnerability
;
const
url
=
`
${
vulnerability
.
create_vulnerability_feedback_dismissal_path
}
/
${
dismissal_feedback
.
id
}
`
;
const
editingDismissalContent
=
dismissal_feedback
.
comment_details
&&
dismissal_feedback
.
comment_details
.
comment
;
const
toastMsg
=
editingDismissalContent
?
sprintf
(
s__
(
"
Security Reports|Comment edited on '%{vulnerabilityName}'
"
),
{
vulnerabilityName
:
vulnerability
.
name
,
})
:
sprintf
(
s__
(
"
Security Reports|Comment added to '%{vulnerabilityName}'
"
),
{
vulnerabilityName
:
vulnerability
.
name
,
});
axios
.
patch
(
url
,
{
project_id
:
dismissal_feedback
.
project_id
,
...
...
@@ -211,6 +227,7 @@ export const addDismissalComment = ({ dispatch }, { vulnerability, comment }) =>
.
then
(({
data
})
=>
{
dispatch
(
'
closeDismissalCommentBox
'
);
dispatch
(
'
receiveAddDismissalCommentSuccess
'
,
{
vulnerability
,
data
});
toast
(
toastMsg
);
})
.
catch
(()
=>
{
dispatch
(
'
receiveAddDismissalCommentError
'
);
...
...
@@ -222,6 +239,9 @@ export const deleteDismissalComment = ({ dispatch }, { vulnerability }) => {
const
{
dismissal_feedback
}
=
vulnerability
;
const
url
=
`
${
vulnerability
.
create_vulnerability_feedback_dismissal_path
}
/
${
dismissal_feedback
.
id
}
`
;
const
toastMsg
=
sprintf
(
s__
(
"
Security Reports|Comment deleted on '%{vulnerabilityName}'
"
),
{
vulnerabilityName
:
vulnerability
.
name
,
});
axios
.
patch
(
url
,
{
...
...
@@ -232,6 +252,7 @@ export const deleteDismissalComment = ({ dispatch }, { vulnerability }) => {
const
{
id
}
=
vulnerability
;
dispatch
(
'
closeDismissalCommentBox
'
);
dispatch
(
'
receiveDeleteDismissalCommentSuccess
'
,
{
id
,
data
});
toast
(
toastMsg
);
})
.
catch
(()
=>
{
dispatch
(
'
receiveDeleteDismissalCommentError
'
);
...
...
ee/app/assets/javascripts/vue_shared/security_reports/store/actions.js
View file @
d1ec236d
import
$
from
'
jquery
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
{
s__
}
from
'
~/locale
'
;
import
{
s__
,
sprintf
}
from
'
~/locale
'
;
import
{
visitUrl
}
from
'
~/lib/utils/url_utility
'
;
import
toast
from
'
~/vue_shared/plugins/global_toast
'
;
import
*
as
types
from
'
./mutation_types
'
;
import
downloadPatchHelper
from
'
./utils/download_patch_helper
'
;
import
{
pollUntilComplete
}
from
'
./utils
'
;
...
...
@@ -290,6 +291,10 @@ export const receiveDismissVulnerabilityError = ({ commit }, error) =>
export
const
dismissVulnerability
=
({
state
,
dispatch
},
comment
)
=>
{
dispatch
(
'
requestDismissVulnerability
'
);
const
toastMsg
=
sprintf
(
s__
(
"
Security Reports|Dismissed '%{vulnerabilityName}'
"
),
{
vulnerabilityName
:
state
.
modal
.
vulnerability
.
name
,
});
axios
.
post
(
state
.
createVulnerabilityFeedbackDismissalPath
,
{
vulnerability_feedback
:
{
...
...
@@ -310,8 +315,8 @@ export const dismissVulnerability = ({ state, dispatch }, comment) => {
dispatch
(
'
closeDismissalCommentBox
'
);
dispatch
(
'
receiveDismissVulnerability
'
,
updatedIssue
);
hideModal
();
toast
(
toastMsg
);
})
.
catch
(()
=>
{
dispatch
(
...
...
@@ -328,6 +333,17 @@ export const addDismissalComment = ({ state, dispatch }, { comment }) => {
const
{
dismissalFeedback
}
=
vulnerability
;
const
url
=
`
${
state
.
createVulnerabilityFeedbackDismissalPath
}
/
${
dismissalFeedback
.
id
}
`
;
const
editingDismissalContent
=
dismissalFeedback
.
comment_details
&&
dismissalFeedback
.
comment_details
.
comment
;
const
toastMsg
=
editingDismissalContent
?
sprintf
(
s__
(
"
Security Reports|Comment edited on '%{vulnerabilityName}'
"
),
{
vulnerabilityName
:
vulnerability
.
name
,
})
:
sprintf
(
s__
(
"
Security Reports|Comment added to '%{vulnerabilityName}'
"
),
{
vulnerabilityName
:
vulnerability
.
name
,
});
axios
.
patch
(
url
,
{
project_id
:
dismissalFeedback
.
project_id
,
...
...
@@ -337,6 +353,7 @@ export const addDismissalComment = ({ state, dispatch }, { comment }) => {
.
then
(({
data
})
=>
{
dispatch
(
'
closeDismissalCommentBox
'
);
dispatch
(
'
receiveAddDismissalCommentSuccess
'
,
{
data
});
toast
(
toastMsg
);
})
.
catch
(()
=>
{
dispatch
(
...
...
@@ -352,6 +369,9 @@ export const deleteDismissalComment = ({ state, dispatch }) => {
const
{
vulnerability
}
=
state
.
modal
;
const
{
dismissalFeedback
}
=
vulnerability
;
const
url
=
`
${
state
.
createVulnerabilityFeedbackDismissalPath
}
/
${
dismissalFeedback
.
id
}
`
;
const
toastMsg
=
sprintf
(
s__
(
"
Security Reports|Comment deleted on '%{vulnerabilityName}'
"
),
{
vulnerabilityName
:
vulnerability
.
name
,
});
axios
.
patch
(
url
,
{
...
...
@@ -361,6 +381,7 @@ export const deleteDismissalComment = ({ state, dispatch }) => {
.
then
(({
data
})
=>
{
dispatch
(
'
closeDismissalCommentBox
'
);
dispatch
(
'
receiveDeleteDismissalCommentSuccess
'
,
{
data
});
toast
(
toastMsg
);
})
.
catch
(()
=>
{
dispatch
(
...
...
ee/changelogs/unreleased/edit-delete-vuln-dismissal-toast-notication-vue-global.yml
0 → 100644
View file @
d1ec236d
---
title
:
Add browser notications to add/edit/delete vulnability dismissal reasons
merge_request
:
15015
author
:
type
:
changed
ee/spec/javascripts/security_dashboard/store/vulnerabilities/actions_spec.js
View file @
d1ec236d
import
Vue
from
'
vue
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
testAction
from
'
spec/helpers/vuex_action_helper
'
;
...
...
@@ -709,6 +710,31 @@ describe('vulnerability dismissal', () => {
done
,
);
});
it
(
'
should show the dismissal toast message
'
,
done
=>
{
spyOn
(
Vue
.
toasted
,
'
show
'
).
and
.
callThrough
();
const
checkToastMessage
=
()
=>
{
expect
(
Vue
.
toasted
.
show
).
toHaveBeenCalledTimes
(
1
);
done
();
};
testAction
(
actions
.
dismissVulnerability
,
{
vulnerability
,
comment
},
{},
[],
[
{
type
:
'
requestDismissVulnerability
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveDismissVulnerabilitySuccess
'
,
payload
:
{
data
,
vulnerability
},
},
],
checkToastMessage
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
...
...
@@ -811,9 +837,35 @@ describe('add vulnerability dismissal comment', () => {
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
const
checkPassedData
=
()
=>
{
const
{
project_id
,
id
}
=
vulnerability
.
dismissal_feedback
;
const
expected
=
{
project_id
,
id
,
comment
}
;
const
expected
=
JSON
.
stringify
({
project_id
,
id
,
comment
})
;
expect
(
mock
.
history
.
patch
[
0
].
data
).
toBe
(
JSON
.
stringify
(
expected
));
expect
(
mock
.
history
.
patch
[
0
].
data
).
toBe
(
expected
);
done
();
};
testAction
(
actions
.
addDismissalComment
,
{
vulnerability
,
comment
},
{},
[],
[
{
type
:
'
requestAddDismissalComment
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveAddDismissalCommentSuccess
'
,
payload
:
{
data
,
vulnerability
}
},
],
checkPassedData
,
);
});
it
(
'
should show the add dismissal toast message
'
,
done
=>
{
spyOn
(
Vue
.
toasted
,
'
show
'
).
and
.
callThrough
();
const
checkPassedData
=
()
=>
{
const
{
project_id
,
id
}
=
vulnerability
.
dismissal_feedback
;
const
expected
=
JSON
.
stringify
({
project_id
,
id
,
comment
});
expect
(
mock
.
history
.
patch
[
0
].
data
).
toBe
(
expected
);
expect
(
Vue
.
toasted
.
show
).
toHaveBeenCalledTimes
(
1
);
done
();
};
...
...
@@ -912,9 +964,38 @@ describe('add vulnerability dismissal comment', () => {
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
const
checkPassedData
=
()
=>
{
const
{
project_id
}
=
vulnerability
.
dismissal_feedback
;
const
expected
=
{
project_id
,
comment
};
const
expected
=
JSON
.
stringify
({
project_id
,
comment
});
expect
(
mock
.
history
.
patch
[
0
].
data
).
toBe
(
expected
);
done
();
};
testAction
(
actions
.
deleteDismissalComment
,
{
vulnerability
},
{},
[],
[
{
type
:
'
requestDeleteDismissalComment
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveDeleteDismissalCommentSuccess
'
,
payload
:
{
data
,
id
:
vulnerability
.
id
},
},
],
checkPassedData
,
);
});
it
(
'
should show the delete dismissal comment toast message
'
,
done
=>
{
spyOn
(
Vue
.
toasted
,
'
show
'
).
and
.
callThrough
();
const
checkPassedData
=
()
=>
{
const
{
project_id
}
=
vulnerability
.
dismissal_feedback
;
const
expected
=
JSON
.
stringify
({
project_id
,
comment
});
expect
(
mock
.
history
.
patch
[
0
].
data
).
toBe
(
JSON
.
stringify
(
expected
));
expect
(
mock
.
history
.
patch
[
0
].
data
).
toBe
(
expected
);
expect
(
Vue
.
toasted
.
show
).
toHaveBeenCalledTimes
(
1
);
done
();
};
...
...
ee/spec/javascripts/vue_shared/security_reports/store/actions_spec.js
View file @
d1ec236d
import
Vue
from
'
vue
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
actions
,
{
...
...
@@ -987,6 +988,35 @@ describe('security reports actions', () => {
done
,
);
});
it
(
'
show dismiss vulnerability toast message
'
,
done
=>
{
spyOn
(
Vue
.
toasted
,
'
show
'
);
const
checkToastMessage
=
()
=>
{
expect
(
Vue
.
toasted
.
show
).
toHaveBeenCalledTimes
(
1
);
done
();
};
testAction
(
dismissVulnerability
,
payload
,
mockedState
,
[],
[
{
type
:
'
requestDismissVulnerability
'
,
},
{
type
:
'
closeDismissalCommentBox
'
,
},
{
type
:
'
receiveDismissVulnerability
'
,
payload
,
},
],
checkToastMessage
,
);
});
});
it
(
'
with error should dispatch `receiveDismissVulnerabilityError`
'
,
done
=>
{
...
...
@@ -1044,6 +1074,31 @@ describe('security reports actions', () => {
done
,
);
});
it
(
'
should show added dismissal comment toast message
'
,
done
=>
{
spyOn
(
Vue
.
toasted
,
'
show
'
).
and
.
callThrough
();
const
checkToastMessage
=
()
=>
{
expect
(
Vue
.
toasted
.
show
).
toHaveBeenCalledTimes
(
1
);
done
();
};
testAction
(
addDismissalComment
,
{
comment
},
{
modal
:
{
vulnerability
}
},
[],
[
{
type
:
'
requestAddDismissalComment
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveAddDismissalCommentSuccess
'
,
payload
:
{
data
},
},
],
checkToastMessage
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
...
...
@@ -1146,6 +1201,31 @@ describe('security reports actions', () => {
done
,
);
});
it
(
'
should show deleted dismissal comment toast message
'
,
done
=>
{
spyOn
(
Vue
.
toasted
,
'
show
'
).
and
.
callThrough
();
const
checkToastMessage
=
()
=>
{
expect
(
Vue
.
toasted
.
show
).
toHaveBeenCalledTimes
(
1
);
done
();
};
testAction
(
deleteDismissalComment
,
{
comment
},
{
modal
:
{
vulnerability
}
},
[],
[
{
type
:
'
requestDeleteDismissalComment
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveDeleteDismissalCommentSuccess
'
,
payload
:
{
data
},
},
],
checkToastMessage
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
...
...
locale/gitlab.pot
View file @
d1ec236d
...
...
@@ -13494,12 +13494,24 @@ msgstr ""
msgid "Security Dashboard|Issue Created"
msgstr ""
msgid "Security Reports|Comment added to '%{vulnerabilityName}'"
msgstr ""
msgid "Security Reports|Comment deleted on '%{vulnerabilityName}'"
msgstr ""
msgid "Security Reports|Comment edited on '%{vulnerabilityName}'"
msgstr ""
msgid "Security Reports|Create issue"
msgstr ""
msgid "Security Reports|Dismiss vulnerability"
msgstr ""
msgid "Security Reports|Dismissed '%{vulnerabilityName}'"
msgstr ""
msgid "Security Reports|Either you don't have permission to view this dashboard or the dashboard has not been setup. Please check your permission settings with your administrator or check your dashboard configurations to proceed."
msgstr ""
...
...
spec/frontend/vue_shared/plugins/global_toast_spec.js
0 → 100644
View file @
d1ec236d
import
toast
from
'
~/vue_shared/plugins/global_toast
'
;
import
Vue
from
'
vue
'
;
describe
(
'
Global toast
'
,
()
=>
{
let
spyFunc
;
beforeEach
(()
=>
{
spyFunc
=
jest
.
spyOn
(
Vue
.
toasted
,
'
show
'
).
mockImplementation
(()
=>
{});
});
afterEach
(()
=>
{
spyFunc
.
mockRestore
();
});
it
(
'
should pass all args to Vue toasted
'
,
()
=>
{
const
arg1
=
'
TestMessage
'
;
const
arg2
=
{
className
:
'
foo
'
};
toast
(
arg1
,
arg2
);
expect
(
Vue
.
toasted
.
show
).
toHaveBeenCalledTimes
(
1
);
expect
(
Vue
.
toasted
.
show
).
toHaveBeenCalledWith
(
arg1
,
arg2
);
});
});
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