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
4e08f02d
Commit
4e08f02d
authored
Sep 10, 2020
by
Olena Horal-Koretska
Committed by
Enrique Alcántara
Sep 10, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Incident severity widget
parent
4e24daa6
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
604 additions
and
1 deletion
+604
-1
app/assets/javascripts/sidebar/components/severity/constants.js
...sets/javascripts/sidebar/components/severity/constants.js
+43
-0
app/assets/javascripts/sidebar/components/severity/graphql/mutations/update_issuable_severity.mutation.graphql
...aphql/mutations/update_issuable_severity.mutation.graphql
+9
-0
app/assets/javascripts/sidebar/components/severity/severity.vue
...sets/javascripts/sidebar/components/severity/severity.vue
+42
-0
app/assets/javascripts/sidebar/components/severity/sidebar_severity.vue
...ascripts/sidebar/components/severity/sidebar_severity.vue
+195
-0
app/assets/javascripts/sidebar/mount_sidebar.js
app/assets/javascripts/sidebar/mount_sidebar.js
+32
-0
app/assets/stylesheets/pages/alert_management/severity-icons.scss
...ts/stylesheets/pages/alert_management/severity-icons.scss
+1
-0
app/helpers/issuables_helper.rb
app/helpers/issuables_helper.rb
+1
-0
app/models/concerns/issuable.rb
app/models/concerns/issuable.rb
+4
-0
app/serializers/issuable_sidebar_basic_entity.rb
app/serializers/issuable_sidebar_basic_entity.rb
+1
-0
app/serializers/issue_sidebar_basic_entity.rb
app/serializers/issue_sidebar_basic_entity.rb
+1
-0
app/views/shared/issuable/_sidebar.html.haml
app/views/shared/issuable/_sidebar.html.haml
+3
-0
changelogs/unreleased/229402-incidents-severity-widget.yml
changelogs/unreleased/229402-incidents-severity-widget.yml
+5
-0
locale/gitlab.pot
locale/gitlab.pot
+24
-0
spec/fixtures/api/schemas/entities/issue_sidebar.json
spec/fixtures/api/schemas/entities/issue_sidebar.json
+2
-1
spec/frontend/sidebar/components/severity/severity_spec.js
spec/frontend/sidebar/components/severity/severity_spec.js
+57
-0
spec/frontend/sidebar/components/severity/sidebar_severity_spec.js
...tend/sidebar/components/severity/sidebar_severity_spec.js
+166
-0
spec/models/concerns/issuable_spec.rb
spec/models/concerns/issuable_spec.rb
+18
-0
No files found.
app/assets/javascripts/sidebar/components/severity/constants.js
0 → 100644
View file @
4e08f02d
import
{
__
,
s__
}
from
'
~/locale
'
;
export
const
INCIDENT_SEVERITY
=
{
CRITICAL
:
{
value
:
'
CRITICAL
'
,
icon
:
'
critical
'
,
label
:
s__
(
'
IncidentManagement|Critical - S1
'
),
},
HIGH
:
{
value
:
'
HIGH
'
,
icon
:
'
high
'
,
label
:
s__
(
'
IncidentManagement|High - S2
'
),
},
MEDIUM
:
{
value
:
'
MEDIUM
'
,
icon
:
'
medium
'
,
label
:
s__
(
'
IncidentManagement|Medium - S3
'
),
},
LOW
:
{
value
:
'
LOW
'
,
icon
:
'
low
'
,
label
:
s__
(
'
IncidentManagement|Low - S4
'
),
},
UNKNOWN
:
{
value
:
'
UNKNOWN
'
,
icon
:
'
unknown
'
,
label
:
s__
(
'
IncidentManagement|Unknown
'
),
},
};
export
const
ISSUABLE_TYPES
=
{
INCIDENT
:
'
incident
'
,
};
export
const
SIDEBAR_ANIMATION_DURATION
=
300
;
export
const
I18N
=
{
UPDATE_SEVERITY_ERROR
:
s__
(
'
SeverityWidget|There was an error while updating severity.
'
),
TRY_AGAIN
:
__
(
'
Please try again
'
),
EDIT
:
__
(
'
Edit
'
),
SEVERITY
:
s__
(
'
SeverityWidget|Severity
'
),
SEVERITY_VALUE
:
s__
(
'
SeverityWidget|Severity: %{severity}
'
),
};
app/assets/javascripts/sidebar/components/severity/graphql/mutations/update_issuable_severity.mutation.graphql
0 → 100644
View file @
4e08f02d
mutation
updateIssuableSeverity
(
$projectPath
:
ID
!,
$severity
:
IssuableSeverity
!,
$iid
:
String
!)
{
issueSetSeverity
(
input
:
{
iid
:
$iid
,
severity
:
$severity
,
projectPath
:
$projectPath
})
{
errors
issue
{
iid
severity
}
}
}
app/assets/javascripts/sidebar/components/severity/severity.vue
0 → 100644
View file @
4e08f02d
<
script
>
import
{
GlIcon
}
from
'
@gitlab/ui
'
;
export
default
{
components
:
{
GlIcon
,
},
props
:
{
severity
:
{
type
:
Object
,
required
:
true
,
validator
(
severity
)
{
const
{
value
,
label
,
icon
}
=
severity
;
return
value
&&
label
&&
icon
;
},
},
iconSize
:
{
type
:
Number
,
required
:
false
,
default
:
12
,
},
iconOnly
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
},
};
</
script
>
<
template
>
<div
class=
"incident-severity gl-display-inline-flex gl-align-items-center gl-justify-content-between"
>
<gl-icon
:size=
"iconSize"
:name=
"`severity-$
{severity.icon}`"
:class="[`icon-${severity.icon}`, { 'gl-mr-3': !iconOnly }]"
/>
<span
v-if=
"!iconOnly"
>
{{
severity
.
label
}}
</span>
</div>
</
template
>
app/assets/javascripts/sidebar/components/severity/sidebar_severity.vue
0 → 100644
View file @
4e08f02d
<
script
>
import
{
GlDropdown
,
GlDropdownItem
,
GlLoadingIcon
,
GlTooltip
,
GlSprintf
,
GlLink
,
}
from
'
@gitlab/ui
'
;
import
{
INCIDENT_SEVERITY
,
ISSUABLE_TYPES
,
SIDEBAR_ANIMATION_DURATION
,
I18N
}
from
'
./constants
'
;
import
updateIssuableSeverity
from
'
./graphql/mutations/update_issuable_severity.mutation.graphql
'
;
import
SeverityToken
from
'
./severity.vue
'
;
import
createFlash
from
'
~/flash
'
;
export
default
{
i18n
:
I18N
,
components
:
{
GlLoadingIcon
,
GlTooltip
,
GlSprintf
,
GlDropdown
,
GlDropdownItem
,
GlLink
,
SeverityToken
,
},
props
:
{
projectPath
:
{
type
:
String
,
required
:
true
,
},
iid
:
{
type
:
String
,
required
:
true
,
},
initialSeverity
:
{
type
:
String
,
required
:
false
,
default
:
INCIDENT_SEVERITY
.
UNKNOWN
.
value
,
},
issuableType
:
{
type
:
String
,
required
:
false
,
default
:
ISSUABLE_TYPES
.
INCIDENT
,
validator
:
value
=>
{
// currently severity is supported only for incidents, but this list might be extended
return
[
ISSUABLE_TYPES
.
INCIDENT
].
includes
(
value
);
},
},
},
data
()
{
return
{
isDropdownShowing
:
false
,
isUpdating
:
false
,
severity
:
this
.
initialSeverity
,
};
},
computed
:
{
severitiesList
()
{
switch
(
this
.
issuableType
)
{
case
ISSUABLE_TYPES
.
INCIDENT
:
return
Object
.
values
(
INCIDENT_SEVERITY
);
default
:
return
[];
}
},
dropdownClass
()
{
return
this
.
isDropdownShowing
?
'
show
'
:
'
gl-display-none
'
;
},
selectedItem
()
{
return
this
.
severitiesList
.
find
(
severity
=>
severity
.
value
===
this
.
severity
);
},
},
mounted
()
{
document
.
addEventListener
(
'
click
'
,
this
.
handleOffClick
);
},
beforeDestroy
()
{
document
.
removeEventListener
(
'
click
'
,
this
.
handleOffClick
);
},
methods
:
{
handleOffClick
(
event
)
{
if
(
!
this
.
isDropdownShowing
)
{
return
;
}
if
(
!
this
.
$refs
.
sidebarSeverity
.
contains
(
event
.
target
))
{
this
.
hideDropdown
();
}
},
hideDropdown
()
{
this
.
isDropdownShowing
=
false
;
const
event
=
new
Event
(
'
hidden.gl.dropdown
'
);
this
.
$el
.
dispatchEvent
(
event
);
},
toggleFormDropdown
(
collapsedSidebar
)
{
this
.
isDropdownShowing
=
!
this
.
isDropdownShowing
;
const
timeout
=
collapsedSidebar
?
SIDEBAR_ANIMATION_DURATION
:
0
;
setTimeout
(()
=>
{
const
{
dropdown
}
=
this
.
$refs
;
if
(
dropdown
&&
this
.
isDropdownShowing
)
{
dropdown
.
show
();
}
},
timeout
);
},
updateSeverity
(
value
)
{
this
.
hideDropdown
();
this
.
isUpdating
=
true
;
this
.
$apollo
.
mutate
({
mutation
:
updateIssuableSeverity
,
variables
:
{
iid
:
this
.
iid
,
severity
:
value
,
projectPath
:
this
.
projectPath
,
},
})
.
then
(
resp
=>
{
const
{
data
:
{
issueSetSeverity
:
{
errors
=
[],
issue
:
{
severity
},
},
},
}
=
resp
;
if
(
errors
[
0
])
{
throw
errors
[
0
];
}
this
.
severity
=
severity
;
})
.
catch
(()
=>
createFlash
({
message
:
`
${
this
.
$options
.
i18n
.
UPDATE_SEVERITY_ERROR
}
${
this
.
$options
.
i18n
.
TRY_AGAIN
}
`
,
}),
)
.
finally
(()
=>
{
this
.
isUpdating
=
false
;
});
},
},
};
</
script
>
<
template
>
<div
ref=
"sidebarSeverity"
class=
"block"
>
<div
ref=
"severity"
class=
"sidebar-collapsed-icon"
@
click=
"toggleFormDropdown(true)"
>
<severity-token
:severity=
"selectedItem"
:icon-size=
"14"
:icon-only=
"true"
/>
<gl-tooltip
:target=
"() => $refs.severity"
boundary=
"viewport"
placement=
"left"
>
<gl-sprintf
:message=
"$options.i18n.SEVERITY_VALUE"
>
<template
#severity
>
{{
selectedItem
.
label
}}
</
template
>
</gl-sprintf>
</gl-tooltip>
</div>
<div
class=
"hide-collapsed"
>
<p
class=
"title gl-display-flex gl-justify-content-space-between"
>
{{ $options.i18n.SEVERITY }}
<gl-link
data-testid=
"editButton"
href=
"#"
@
click=
"toggleFormDropdown"
@
keydown.esc=
"hideDropdown"
>
{{ $options.i18n.EDIT }}
</gl-link>
</p>
<gl-dropdown
ref=
"dropdown"
:class=
"dropdownClass"
block
:text=
"selectedItem.label"
toggle-class=
"dropdown-menu-toggle gl-mb-2"
@
keydown.esc.native=
"hideDropdown"
>
<gl-dropdown-item
v-for=
"option in severitiesList"
:key=
"option.value"
data-testid=
"severityDropdownItem"
:is-check-item=
"true"
:is-checked=
"option.value === severity"
@
click=
"updateSeverity(option.value)"
>
<severity-token
:severity=
"option"
/>
</gl-dropdown-item>
</gl-dropdown>
<gl-loading-icon
v-if=
"isUpdating"
:inline=
"true"
/>
<severity-token
v-else-if=
"!isDropdownShowing"
:severity=
"selectedItem"
/>
</div>
</div>
</template>
app/assets/javascripts/sidebar/mount_sidebar.js
View file @
4e08f02d
...
@@ -8,6 +8,7 @@ import SidebarMoveIssue from './lib/sidebar_move_issue';
...
@@ -8,6 +8,7 @@ import SidebarMoveIssue from './lib/sidebar_move_issue';
import
IssuableLockForm
from
'
./components/lock/issuable_lock_form.vue
'
;
import
IssuableLockForm
from
'
./components/lock/issuable_lock_form.vue
'
;
import
sidebarParticipants
from
'
./components/participants/sidebar_participants.vue
'
;
import
sidebarParticipants
from
'
./components/participants/sidebar_participants.vue
'
;
import
sidebarSubscriptions
from
'
./components/subscriptions/sidebar_subscriptions.vue
'
;
import
sidebarSubscriptions
from
'
./components/subscriptions/sidebar_subscriptions.vue
'
;
import
SidebarSeverity
from
'
./components/severity/sidebar_severity.vue
'
;
import
Translate
from
'
../vue_shared/translate
'
;
import
Translate
from
'
../vue_shared/translate
'
;
import
createDefaultClient
from
'
~/lib/graphql
'
;
import
createDefaultClient
from
'
~/lib/graphql
'
;
import
{
store
}
from
'
~/notes/stores
'
;
import
{
store
}
from
'
~/notes/stores
'
;
...
@@ -159,6 +160,35 @@ function mountTimeTrackingComponent() {
...
@@ -159,6 +160,35 @@ function mountTimeTrackingComponent() {
});
});
}
}
function
mountSeverityComponent
()
{
const
severityContainerEl
=
document
.
querySelector
(
'
#js-severity
'
);
if
(
!
severityContainerEl
)
{
return
false
;
}
const
apolloProvider
=
new
VueApollo
({
defaultClient
:
createDefaultClient
(),
});
const
{
fullPath
,
iid
,
severity
}
=
getSidebarOptions
();
return
new
Vue
({
el
:
severityContainerEl
,
apolloProvider
,
components
:
{
SidebarSeverity
,
},
render
:
createElement
=>
createElement
(
'
sidebar-severity
'
,
{
props
:
{
projectPath
:
fullPath
,
iid
:
String
(
iid
),
initialSeverity
:
severity
.
toUpperCase
(),
},
}),
});
}
export
function
mountSidebar
(
mediator
)
{
export
function
mountSidebar
(
mediator
)
{
mountAssigneesComponent
(
mediator
);
mountAssigneesComponent
(
mediator
);
mountConfidentialComponent
(
mediator
);
mountConfidentialComponent
(
mediator
);
...
@@ -173,6 +203,8 @@ export function mountSidebar(mediator) {
...
@@ -173,6 +203,8 @@ export function mountSidebar(mediator) {
).
init
();
).
init
();
mountTimeTrackingComponent
();
mountTimeTrackingComponent
();
mountSeverityComponent
();
}
}
export
{
getSidebarOptions
};
export
{
getSidebarOptions
};
app/assets/stylesheets/pages/alert_management/severity-icons.scss
View file @
4e08f02d
.incident-severity
,
.incident-management-list
,
.incident-management-list
,
.alert-management-details
{
.alert-management-details
{
.icon-critical
{
.icon-critical
{
...
...
app/helpers/issuables_helper.rb
View file @
4e08f02d
...
@@ -465,6 +465,7 @@ module IssuablesHelper
...
@@ -465,6 +465,7 @@ module IssuablesHelper
rootPath:
root_path
,
rootPath:
root_path
,
fullPath:
issuable
[
:project_full_path
],
fullPath:
issuable
[
:project_full_path
],
iid:
issuable
[
:iid
],
iid:
issuable
[
:iid
],
severity:
issuable
[
:severity
],
timeTrackingLimitToHours:
Gitlab
::
CurrentSettings
.
time_tracking_limit_to_hours
timeTrackingLimitToHours:
Gitlab
::
CurrentSettings
.
time_tracking_limit_to_hours
}
}
end
end
...
...
app/models/concerns/issuable.rb
View file @
4e08f02d
...
@@ -185,6 +185,10 @@ module Issuable
...
@@ -185,6 +185,10 @@ module Issuable
is_a?
(
TimeTrackable
)
&&
!
incident?
is_a?
(
TimeTrackable
)
&&
!
incident?
end
end
def
supports_severity?
incident?
end
def
incident?
def
incident?
is_a?
(
Issue
)
&&
super
is_a?
(
Issue
)
&&
super
end
end
...
...
app/serializers/issuable_sidebar_basic_entity.rb
View file @
4e08f02d
...
@@ -105,6 +105,7 @@ class IssuableSidebarBasicEntity < Grape::Entity
...
@@ -105,6 +105,7 @@ class IssuableSidebarBasicEntity < Grape::Entity
expose
:supports_time_tracking?
,
as: :supports_time_tracking
expose
:supports_time_tracking?
,
as: :supports_time_tracking
expose
:supports_milestone?
,
as: :supports_milestone
expose
:supports_milestone?
,
as: :supports_milestone
expose
:supports_severity?
,
as: :supports_severity
private
private
...
...
app/serializers/issue_sidebar_basic_entity.rb
View file @
4e08f02d
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
class
IssueSidebarBasicEntity
<
IssuableSidebarBasicEntity
class
IssueSidebarBasicEntity
<
IssuableSidebarBasicEntity
expose
:due_date
expose
:due_date
expose
:confidential
expose
:confidential
expose
:severity
end
end
IssueSidebarBasicEntity
.
prepend_if_ee
(
'EE::IssueSidebarBasicEntity'
)
IssueSidebarBasicEntity
.
prepend_if_ee
(
'EE::IssueSidebarBasicEntity'
)
app/views/shared/issuable/_sidebar.html.haml
View file @
4e08f02d
...
@@ -133,6 +133,9 @@
...
@@ -133,6 +133,9 @@
=
render_if_exists
'shared/issuable/sidebar_weight'
,
issuable_sidebar:
issuable_sidebar
=
render_if_exists
'shared/issuable/sidebar_weight'
,
issuable_sidebar:
issuable_sidebar
-
if
issuable_sidebar
[
:supports_severity
]
#js-severity
-
if
issuable_sidebar
.
dig
(
:features_available
,
:health_status
)
-
if
issuable_sidebar
.
dig
(
:features_available
,
:health_status
)
.js-sidebar-status-entry-point
.js-sidebar-status-entry-point
...
...
changelogs/unreleased/229402-incidents-severity-widget.yml
0 → 100644
View file @
4e08f02d
---
title
:
Incident severity widget
merge_request
:
39859
author
:
type
:
added
locale/gitlab.pot
View file @
4e08f02d
...
@@ -13252,18 +13252,30 @@ msgstr ""
...
@@ -13252,18 +13252,30 @@ msgstr ""
msgid "IncidentManagement|Create incident"
msgid "IncidentManagement|Create incident"
msgstr ""
msgstr ""
msgid "IncidentManagement|Critical - S1"
msgstr ""
msgid "IncidentManagement|Date created"
msgid "IncidentManagement|Date created"
msgstr ""
msgstr ""
msgid "IncidentManagement|Display your incidents in a dedicated view"
msgid "IncidentManagement|Display your incidents in a dedicated view"
msgstr ""
msgstr ""
msgid "IncidentManagement|High - S2"
msgstr ""
msgid "IncidentManagement|Incident"
msgid "IncidentManagement|Incident"
msgstr ""
msgstr ""
msgid "IncidentManagement|Incidents"
msgid "IncidentManagement|Incidents"
msgstr ""
msgstr ""
msgid "IncidentManagement|Low - S4"
msgstr ""
msgid "IncidentManagement|Medium - S3"
msgstr ""
msgid "IncidentManagement|No incidents to display."
msgid "IncidentManagement|No incidents to display."
msgstr ""
msgstr ""
...
@@ -13285,6 +13297,9 @@ msgstr ""
...
@@ -13285,6 +13297,9 @@ msgstr ""
msgid "IncidentManagement|Unassigned"
msgid "IncidentManagement|Unassigned"
msgstr ""
msgstr ""
msgid "IncidentManagement|Unknown"
msgstr ""
msgid "IncidentManagement|Unpublished"
msgid "IncidentManagement|Unpublished"
msgstr ""
msgstr ""
...
@@ -22934,6 +22949,15 @@ msgstr ""
...
@@ -22934,6 +22949,15 @@ msgstr ""
msgid "Severity"
msgid "Severity"
msgstr ""
msgstr ""
msgid "SeverityWidget|Severity"
msgstr ""
msgid "SeverityWidget|Severity: %{severity}"
msgstr ""
msgid "SeverityWidget|There was an error while updating severity."
msgstr ""
msgid "Shards (%{shards})"
msgid "Shards (%{shards})"
msgstr ""
msgstr ""
...
...
spec/fixtures/api/schemas/entities/issue_sidebar.json
View file @
4e08f02d
...
@@ -44,6 +44,7 @@
...
@@ -44,6 +44,7 @@
"move_issue_path"
:
{
"type"
:
"string"
},
"move_issue_path"
:
{
"type"
:
"string"
},
"projects_autocomplete_path"
:
{
"type"
:
"string"
},
"projects_autocomplete_path"
:
{
"type"
:
"string"
},
"supports_time_tracking"
:
{
"type"
:
"boolean"
},
"supports_time_tracking"
:
{
"type"
:
"boolean"
},
"supports_milestone"
:
{
"type"
:
"boolean"
}
"supports_milestone"
:
{
"type"
:
"boolean"
},
"supports_severity"
:
{
"type"
:
"boolean"
}
}
}
}
}
spec/frontend/sidebar/components/severity/severity_spec.js
0 → 100644
View file @
4e08f02d
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
GlIcon
}
from
'
@gitlab/ui
'
;
import
SeverityToken
from
'
~/sidebar/components/severity/severity.vue
'
;
import
{
INCIDENT_SEVERITY
}
from
'
~/sidebar/components/severity/constants
'
;
describe
(
'
SeverityToken
'
,
()
=>
{
let
wrapper
;
function
createComponent
(
props
)
{
wrapper
=
shallowMount
(
SeverityToken
,
{
propsData
:
{
...
props
,
},
});
}
afterEach
(()
=>
{
if
(
wrapper
)
{
wrapper
.
destroy
();
wrapper
=
null
;
}
});
const
findIcon
=
()
=>
wrapper
.
find
(
GlIcon
);
it
(
'
renders severity token for each severity type
'
,
()
=>
{
Object
.
values
(
INCIDENT_SEVERITY
).
forEach
(
severity
=>
{
createComponent
({
severity
});
expect
(
findIcon
().
classes
()).
toContain
(
`icon-
${
severity
.
icon
}
`
);
expect
(
findIcon
().
attributes
(
'
name
'
)).
toBe
(
`severity-
${
severity
.
icon
}
`
);
expect
(
wrapper
.
text
()).
toBe
(
severity
.
label
);
});
});
it
(
'
renders only icon when `iconOnly` prop is set to `true`
'
,
()
=>
{
const
severity
=
INCIDENT_SEVERITY
.
CRITICAL
;
createComponent
({
severity
,
iconOnly
:
true
});
expect
(
findIcon
().
classes
()).
toContain
(
`icon-
${
severity
.
icon
}
`
);
expect
(
findIcon
().
attributes
(
'
name
'
)).
toBe
(
`severity-
${
severity
.
icon
}
`
);
expect
(
wrapper
.
text
()).
toBe
(
''
);
});
describe
(
'
icon size
'
,
()
=>
{
it
(
'
renders the icon in default size when other is not specified
'
,
()
=>
{
const
severity
=
INCIDENT_SEVERITY
.
HIGH
;
createComponent
({
severity
});
expect
(
findIcon
().
attributes
(
'
size
'
)).
toBe
(
'
12
'
);
});
it
(
'
renders the icon in provided size
'
,
()
=>
{
const
severity
=
INCIDENT_SEVERITY
.
HIGH
;
const
iconSize
=
14
;
createComponent
({
severity
,
iconSize
});
expect
(
findIcon
().
attributes
(
'
size
'
)).
toBe
(
`
${
iconSize
}
`
);
});
});
});
spec/frontend/sidebar/components/severity/sidebar_severity_spec.js
0 → 100644
View file @
4e08f02d
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
GlDropdown
,
GlDropdownItem
,
GlLoadingIcon
,
GlTooltip
,
GlSprintf
}
from
'
@gitlab/ui
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
createFlash
from
'
~/flash
'
;
import
SidebarSeverity
from
'
~/sidebar/components/severity/sidebar_severity.vue
'
;
import
SeverityToken
from
'
~/sidebar/components/severity/severity.vue
'
;
import
updateIssuableSeverity
from
'
~/sidebar/components/severity/graphql/mutations/update_issuable_severity.mutation.graphql
'
;
import
{
INCIDENT_SEVERITY
,
ISSUABLE_TYPES
}
from
'
~/sidebar/components/severity/constants
'
;
jest
.
mock
(
'
~/flash
'
);
describe
(
'
SidebarSeverity
'
,
()
=>
{
let
wrapper
;
let
mutate
;
const
projectPath
=
'
gitlab-org/gitlab-test
'
;
const
iid
=
'
1
'
;
const
severity
=
'
CRITICAL
'
;
function
createComponent
(
props
=
{})
{
const
propsData
=
{
projectPath
,
iid
,
issuableType
:
ISSUABLE_TYPES
.
INCIDENT
,
initialSeverity
:
severity
,
...
props
,
};
mutate
=
jest
.
fn
();
wrapper
=
shallowMount
(
SidebarSeverity
,
{
propsData
,
mocks
:
{
$apollo
:
{
mutate
,
},
},
stubs
:
{
GlSprintf
,
},
});
}
beforeEach
(()
=>
{
createComponent
();
});
afterEach
(()
=>
{
if
(
wrapper
)
{
wrapper
.
destroy
();
wrapper
=
null
;
}
});
const
findSeverityToken
=
()
=>
wrapper
.
findAll
(
SeverityToken
);
const
findEditBtn
=
()
=>
wrapper
.
find
(
'
[data-testid="editButton"]
'
);
const
findDropdown
=
()
=>
wrapper
.
find
(
GlDropdown
);
const
findCriticalSeverityDropdownItem
=
()
=>
wrapper
.
find
(
GlDropdownItem
);
const
findLoadingIcon
=
()
=>
wrapper
.
find
(
GlLoadingIcon
);
const
findTooltip
=
()
=>
wrapper
.
find
(
GlTooltip
);
const
findCollapsedSeverity
=
()
=>
wrapper
.
find
({
ref
:
'
severity
'
});
it
(
'
renders severity widget
'
,
()
=>
{
expect
(
findEditBtn
().
exists
()).
toBe
(
true
);
expect
(
findSeverityToken
().
exists
()).
toBe
(
true
);
expect
(
findDropdown
().
exists
()).
toBe
(
true
);
});
describe
(
'
Update severity
'
,
()
=>
{
it
(
'
calls `$apollo.mutate` with `updateIssuableSeverity`
'
,
()
=>
{
jest
.
spyOn
(
wrapper
.
vm
.
$apollo
,
'
mutate
'
)
.
mockResolvedValueOnce
({
data
:
{
issueSetSeverity
:
{
issue
:
{
severity
}
}
}
});
findCriticalSeverityDropdownItem
().
vm
.
$emit
(
'
click
'
);
expect
(
wrapper
.
vm
.
$apollo
.
mutate
).
toHaveBeenCalledWith
({
mutation
:
updateIssuableSeverity
,
variables
:
{
iid
,
projectPath
,
severity
,
},
});
});
it
(
'
shows error alert when severity update fails
'
,
()
=>
{
const
errorMsg
=
'
Something went wrong
'
;
jest
.
spyOn
(
wrapper
.
vm
.
$apollo
,
'
mutate
'
).
mockRejectedValueOnce
(
errorMsg
);
findCriticalSeverityDropdownItem
().
vm
.
$emit
(
'
click
'
);
setImmediate
(()
=>
{
expect
(
createFlash
).
toHaveBeenCalled
();
});
});
it
(
'
shows loading icon while updating
'
,
async
()
=>
{
let
resolvePromise
;
wrapper
.
vm
.
$apollo
.
mutate
=
jest
.
fn
(
()
=>
new
Promise
(
resolve
=>
{
resolvePromise
=
resolve
;
}),
);
findCriticalSeverityDropdownItem
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$nextTick
();
expect
(
findLoadingIcon
().
exists
()).
toBe
(
true
);
resolvePromise
();
await
waitForPromises
();
expect
(
findLoadingIcon
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
Switch between collapsed/expanded view of the sidebar
'
,
()
=>
{
const
HIDDDEN_CLASS
=
'
gl-display-none
'
;
const
SHOWN_CLASS
=
'
show
'
;
describe
(
'
collapsed
'
,
()
=>
{
it
(
'
should have collapsed icon class
'
,
()
=>
{
expect
(
findCollapsedSeverity
().
classes
(
'
sidebar-collapsed-icon
'
)).
toBe
(
true
);
});
it
(
'
should display only icon with a tooltip
'
,
()
=>
{
expect
(
findSeverityToken
()
.
at
(
0
)
.
attributes
(
'
icononly
'
),
).
toBe
(
'
true
'
);
expect
(
findSeverityToken
()
.
at
(
0
)
.
attributes
(
'
iconsize
'
),
).
toBe
(
'
14
'
);
expect
(
findTooltip
()
.
text
()
.
replace
(
/
\s
+/g
,
'
'
),
).
toContain
(
`Severity:
${
INCIDENT_SEVERITY
[
severity
].
label
}
`
);
});
it
(
'
should expand the dropdown on collapsed icon click
'
,
async
()
=>
{
wrapper
.
vm
.
isDropdownShowing
=
false
;
await
wrapper
.
vm
.
$nextTick
();
expect
(
findDropdown
().
classes
(
HIDDDEN_CLASS
)).
toBe
(
true
);
findCollapsedSeverity
().
trigger
(
'
click
'
);
await
wrapper
.
vm
.
$nextTick
();
expect
(
findDropdown
().
classes
(
SHOWN_CLASS
)).
toBe
(
true
);
});
});
describe
(
'
expanded
'
,
()
=>
{
it
(
'
toggles dropdown with edit button
'
,
async
()
=>
{
wrapper
.
vm
.
isDropdownShowing
=
false
;
await
wrapper
.
vm
.
$nextTick
();
expect
(
findDropdown
().
classes
(
HIDDDEN_CLASS
)).
toBe
(
true
);
findEditBtn
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$nextTick
();
expect
(
findDropdown
().
classes
(
SHOWN_CLASS
)).
toBe
(
true
);
findEditBtn
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$nextTick
();
expect
(
findDropdown
().
classes
(
HIDDDEN_CLASS
)).
toBe
(
true
);
});
});
});
});
spec/models/concerns/issuable_spec.rb
View file @
4e08f02d
...
@@ -837,6 +837,24 @@ RSpec.describe Issuable do
...
@@ -837,6 +837,24 @@ RSpec.describe Issuable do
end
end
end
end
describe
'#supports_severity?'
do
using
RSpec
::
Parameterized
::
TableSyntax
where
(
:issuable_type
,
:supports_severity
)
do
:issue
|
false
:incident
|
true
:merge_request
|
false
end
with_them
do
let
(
:issuable
)
{
build_stubbed
(
issuable_type
)
}
subject
{
issuable
.
supports_severity?
}
it
{
is_expected
.
to
eq
(
supports_severity
)
}
end
end
describe
'#incident?'
do
describe
'#incident?'
do
using
RSpec
::
Parameterized
::
TableSyntax
using
RSpec
::
Parameterized
::
TableSyntax
...
...
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