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
37405ed1
Commit
37405ed1
authored
May 23, 2021
by
Olena Horal-Koretska
Committed by
Simon Knox
May 23, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add escalation policy modal layout
parent
7316c9a7
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
629 additions
and
37 deletions
+629
-37
app/assets/stylesheets/page_bundles/escalation_policies.scss
app/assets/stylesheets/page_bundles/escalation_policies.scss
+14
-0
config/application.rb
config/application.rb
+1
-0
ee/app/assets/javascripts/escalation_policies/components/add_edit_escalation_policy_form.vue
...n_policies/components/add_edit_escalation_policy_form.vue
+107
-0
ee/app/assets/javascripts/escalation_policies/components/add_edit_escalation_policy_modal.vue
..._policies/components/add_edit_escalation_policy_modal.vue
+90
-0
ee/app/assets/javascripts/escalation_policies/components/escalation_policies_wrapper.vue
...ation_policies/components/escalation_policies_wrapper.vue
+22
-17
ee/app/assets/javascripts/escalation_policies/components/escalation_rule.vue
...cripts/escalation_policies/components/escalation_rule.vue
+98
-0
ee/app/assets/javascripts/escalation_policies/constants.js
ee/app/assets/javascripts/escalation_policies/constants.js
+22
-0
ee/app/assets/javascripts/escalation_policies/index.js
ee/app/assets/javascripts/escalation_policies/index.js
+2
-1
ee/app/assets/javascripts/escalation_policies/utils.js
ee/app/assets/javascripts/escalation_policies/utils.js
+9
-0
ee/app/assets/javascripts/oncall_schedules/components/add_edit_schedule_form.vue
...ts/oncall_schedules/components/add_edit_schedule_form.vue
+2
-7
ee/app/assets/javascripts/oncall_schedules/components/add_edit_schedule_modal.vue
...s/oncall_schedules/components/add_edit_schedule_modal.vue
+0
-1
ee/app/views/projects/incident_management/escalation_policies/index.html.haml
...s/incident_management/escalation_policies/index.html.haml
+1
-0
ee/spec/frontend/escalation_policies/add_edit_escalation_policy_form_spec.js
...calation_policies/add_edit_escalation_policy_form_spec.js
+78
-0
ee/spec/frontend/escalation_policies/add_edit_escalation_policy_modal_spec.js
...alation_policies/add_edit_escalation_policy_modal_spec.js
+67
-0
ee/spec/frontend/escalation_policies/escalation_policy_wrapper_spec.js
...end/escalation_policies/escalation_policy_wrapper_spec.js
+2
-2
ee/spec/frontend/escalation_policies/escalation_rule_spec.js
ee/spec/frontend/escalation_policies/escalation_rule_spec.js
+79
-0
ee/spec/frontend/escalation_policies/mocks/mockPolicy.json
ee/spec/frontend/escalation_policies/mocks/mockPolicy.json
+6
-0
ee/spec/frontend/oncall_schedule/__snapshots__/add_edit_schedule_form_spec.js.snap
...chedule/__snapshots__/add_edit_schedule_form_spec.js.snap
+4
-6
ee/spec/frontend/oncall_schedule/add_edit_schedule_form_spec.js
...c/frontend/oncall_schedule/add_edit_schedule_form_spec.js
+1
-3
locale/gitlab.pot
locale/gitlab.pot
+24
-0
No files found.
app/assets/stylesheets/page_bundles/escalation_policies.scss
0 → 100644
View file @
37405ed1
.escalation-policy-modal
{
width
:
640px
;
}
.escalation-policy-rules
{
.rule-control
{
width
:
240px
;
}
.rule-elapsed-minutes
{
width
:
56px
;
}
}
config/application.rb
View file @
37405ed1
...
@@ -214,6 +214,7 @@ module Gitlab
...
@@ -214,6 +214,7 @@ module Gitlab
config
.
assets
.
precompile
<<
"page_bundles/milestone.css"
config
.
assets
.
precompile
<<
"page_bundles/milestone.css"
config
.
assets
.
precompile
<<
"page_bundles/new_namespace.css"
config
.
assets
.
precompile
<<
"page_bundles/new_namespace.css"
config
.
assets
.
precompile
<<
"page_bundles/oncall_schedules.css"
config
.
assets
.
precompile
<<
"page_bundles/oncall_schedules.css"
config
.
assets
.
precompile
<<
"page_bundles/escalation_policies.css"
config
.
assets
.
precompile
<<
"page_bundles/pipeline.css"
config
.
assets
.
precompile
<<
"page_bundles/pipeline.css"
config
.
assets
.
precompile
<<
"page_bundles/pipeline_schedules.css"
config
.
assets
.
precompile
<<
"page_bundles/pipeline_schedules.css"
config
.
assets
.
precompile
<<
"page_bundles/pipelines.css"
config
.
assets
.
precompile
<<
"page_bundles/pipelines.css"
...
...
ee/app/assets/javascripts/escalation_policies/components/add_edit_escalation_policy_form.vue
0 → 100644
View file @
37405ed1
<
script
>
import
{
GlLink
,
GlForm
,
GlFormGroup
,
GlFormInput
}
from
'
@gitlab/ui
'
;
import
{
cloneDeep
}
from
'
lodash
'
;
import
{
s__
,
__
}
from
'
~/locale
'
;
import
{
defaultEscalationRule
}
from
'
../constants
'
;
import
EscalationRule
from
'
./escalation_rule.vue
'
;
export
const
i18n
=
{
fields
:
{
name
:
{
title
:
__
(
'
Name
'
),
validation
:
{
empty
:
__
(
"
Can't be empty
"
),
},
},
description
:
{
title
:
__
(
'
Description (optional)
'
)
},
rules
:
{
title
:
s__
(
'
EscalationPolicies|Escalation rules
'
),
},
},
addRule
:
s__
(
'
EscalationPolicies|+ Add an additional rule
'
),
};
export
default
{
i18n
,
components
:
{
GlLink
,
GlForm
,
GlFormGroup
,
GlFormInput
,
EscalationRule
,
},
props
:
{
form
:
{
type
:
Object
,
required
:
true
,
},
validationState
:
{
type
:
Object
,
required
:
true
,
},
},
data
()
{
return
{
rules
:
[
cloneDeep
(
defaultEscalationRule
)],
};
},
methods
:
{
addRule
()
{
this
.
rules
.
push
(
cloneDeep
(
defaultEscalationRule
));
},
},
};
</
script
>
<
template
>
<gl-form>
<div
class=
"w-75 gl-xs-w-full!"
>
<gl-form-group
data-testid=
"escalation-policy-name"
:label=
"$options.i18n.fields.name.title"
:invalid-feedback=
"$options.i18n.fields.name.validation.empty"
label-size=
"sm"
label-for=
"escalation-policy-name"
:state=
"validationState.name"
required
>
<gl-form-input
id=
"escalation-policy-name"
:value=
"form.name"
@
blur=
"
$emit('update-escalation-policy-form',
{ field: 'name', value: $event.target.value })
"
/>
</gl-form-group>
<gl-form-group
:label=
"$options.i18n.fields.description.title"
label-size=
"sm"
label-for=
"escalation-policy-description"
>
<gl-form-input
id=
"escalation-policy-description"
:value=
"form.description"
@
blur=
"
$emit('update-escalation-policy-form',
{
field: 'description',
value: $event.target.value,
})
"
/>
</gl-form-group>
</div>
<gl-form-group
class=
"escalation-policy-rules"
:label=
"$options.i18n.fields.rules.title"
label-size=
"sm"
:state=
"validationState.rules"
>
<escalation-rule
v-for=
"(rule, index) in rules"
:key=
"index"
:rule=
"rule"
/>
</gl-form-group>
<gl-link
@
click=
"addRule"
>
<span>
{{
$options
.
i18n
.
addRule
}}
</span>
</gl-link>
</gl-form>
</
template
>
ee/app/assets/javascripts/escalation_policies/components/add_edit_escalation_policy_modal.vue
0 → 100644
View file @
37405ed1
<
script
>
import
{
GlModal
}
from
'
@gitlab/ui
'
;
import
{
set
}
from
'
lodash
'
;
import
{
s__
,
__
}
from
'
~/locale
'
;
import
{
addEscalationPolicyModalId
}
from
'
../constants
'
;
import
{
isNameFieldValid
}
from
'
../utils
'
;
import
AddEditEscalationPolicyForm
from
'
./add_edit_escalation_policy_form.vue
'
;
export
const
i18n
=
{
cancel
:
__
(
'
Cancel
'
),
addEscalationPolicy
:
s__
(
'
EscalationPolicies|Add escalation policy
'
),
editEscalationPolicy
:
s__
(
'
EscalationPolicies|Edit escalation policy
'
),
};
export
default
{
i18n
,
addEscalationPolicyModalId
,
components
:
{
GlModal
,
AddEditEscalationPolicyForm
,
},
props
:
{
escalationPolicy
:
{
type
:
Object
,
required
:
false
,
default
:
()
=>
({}),
},
},
data
()
{
return
{
loading
:
false
,
form
:
{
name
:
this
.
escalationPolicy
.
name
,
description
:
this
.
escalationPolicy
.
description
,
},
validationState
:
{
name
:
true
,
rules
:
true
,
},
};
},
computed
:
{
actionsProps
()
{
return
{
primary
:
{
text
:
i18n
.
addEscalationPolicy
,
attributes
:
[
{
variant
:
'
info
'
},
{
loading
:
this
.
loading
},
{
disabled
:
!
this
.
isFormValid
},
],
},
cancel
:
{
text
:
i18n
.
cancel
,
},
};
},
isFormValid
()
{
return
Object
.
values
(
this
.
validationState
).
every
(
Boolean
);
},
},
methods
:
{
updateForm
({
field
,
value
})
{
set
(
this
.
form
,
field
,
value
);
this
.
validateForm
(
field
);
},
validateForm
(
field
)
{
if
(
field
===
'
name
'
)
{
this
.
validationState
.
name
=
isNameFieldValid
(
this
.
form
.
name
);
}
},
},
};
</
script
>
<
template
>
<gl-modal
class=
"escalation-policy-modal"
:modal-id=
"$options.addEscalationPolicyModalId"
:title=
"$options.i18n.addEscalationPolicy"
:action-primary=
"actionsProps.primary"
:action-cancel=
"actionsProps.cancel"
>
<add-edit-escalation-policy-form
:validation-state=
"validationState"
:form=
"form"
@
update-escalation-policy-form=
"updateForm"
/>
</gl-modal>
</
template
>
ee/app/assets/javascripts/escalation_policies/components/escalation_policies_wrapper.vue
View file @
37405ed1
<
script
>
<
script
>
import
{
GlEmptyState
,
GlButton
}
from
'
@gitlab/ui
'
;
import
{
GlEmptyState
,
GlButton
,
GlModalDirective
}
from
'
@gitlab/ui
'
;
import
{
s__
}
from
'
~/locale
'
;
import
{
s__
}
from
'
~/locale
'
;
import
{
addEscalationPolicyModalId
}
from
'
../constants
'
;
import
AddEscalationPolicyModal
from
'
./add_edit_escalation_policy_modal.vue
'
;
export
const
i18n
=
{
export
const
i18n
=
{
emptyState
:
{
emptyState
:
{
...
@@ -14,29 +16,32 @@ export const i18n = {
...
@@ -14,29 +16,32 @@ export const i18n = {
export
default
{
export
default
{
i18n
,
i18n
,
addEscalationPolicyModalId
,
components
:
{
components
:
{
GlEmptyState
,
GlEmptyState
,
GlButton
,
GlButton
,
AddEscalationPolicyModal
,
},
},
inject
:
[
'
emptyEscalationPoliciesSvgPath
'
],
directives
:
{
methods
:
{
GlModal
:
GlModalDirective
,
addEscalationPolicy
()
{
// TODO: Add method as part of https://gitlab.com/gitlab-org/gitlab/-/issues/268356
},
},
},
inject
:
[
'
emptyEscalationPoliciesSvgPath
'
],
};
};
</
script
>
</
script
>
<
template
>
<
template
>
<gl-empty-state
<div>
:title=
"$options.i18n.emptyState.title"
<gl-empty-state
:description=
"$options.i18n.emptyState.description"
:title=
"$options.i18n.emptyState.title"
:svg-path=
"emptyEscalationPoliciesSvgPath"
:description=
"$options.i18n.emptyState.description"
>
:svg-path=
"emptyEscalationPoliciesSvgPath"
<template
#actions
>
>
<gl-button
variant=
"info"
@
click=
"addEscalationPolicy"
>
{{
<template
#actions
>
$options
.
i18n
.
emptyState
.
button
<gl-button
v-gl-modal=
"$options.addEscalationPolicyModalId"
variant=
"confirm"
>
}}
</gl-button>
{{
$options
.
i18n
.
emptyState
.
button
}}
</
template
>
</gl-button>
</gl-empty-state>
</
template
>
</gl-empty-state>
<add-escalation-policy-modal
/>
</div>
</template>
</template>
ee/app/assets/javascripts/escalation_policies/components/escalation_rule.vue
0 → 100644
View file @
37405ed1
<
script
>
import
{
GlFormInput
,
GlDropdown
,
GlDropdownItem
,
GlCard
,
GlSprintf
}
from
'
@gitlab/ui
'
;
import
{
s__
}
from
'
~/locale
'
;
import
{
ACTIONS
,
ALERT_STATUSES
}
from
'
../constants
'
;
export
const
i18n
=
{
fields
:
{
rules
:
{
condition
:
s__
(
'
EscalationPolicies|IF alert is not %{alertStatus} in %{minutes} minutes
'
),
action
:
s__
(
'
EscalationPolicies|THEN %{doAction} %{schedule}
'
),
selectSchedule
:
s__
(
'
EscalationPolicies|Select schedule
'
),
},
},
};
export
default
{
i18n
,
ALERT_STATUSES
,
ACTIONS
,
components
:
{
GlFormInput
,
GlDropdown
,
GlDropdownItem
,
GlCard
,
GlSprintf
,
},
props
:
{
rule
:
{
type
:
Object
,
required
:
true
,
},
schedules
:
{
type
:
Array
,
required
:
false
,
default
:
()
=>
[],
},
},
};
</
script
>
<
template
>
<gl-card
class=
"gl-border-gray-400 gl-bg-gray-10 gl-mb-3"
>
<div
class=
"gl-display-flex gl-align-items-center"
>
<gl-sprintf
:message=
"$options.i18n.fields.rules.condition"
>
<template
#alertStatus
>
<gl-dropdown
class=
"rule-control gl-mx-3"
:text=
"$options.ALERT_STATUSES[rule.status]"
data-testid=
"alert-status-dropdown"
>
<gl-dropdown-item
v-for=
"(label, status) in $options.ALERT_STATUSES"
:key=
"status"
:is-checked=
"rule.status === status"
is-check-item
>
{{
label
}}
</gl-dropdown-item>
</gl-dropdown>
</
template
>
<
template
#minutes
>
<gl-form-input
class=
"gl-mx-3 rule-elapsed-minutes"
:value=
"0"
/>
</
template
>
</gl-sprintf>
</div>
<div
class=
"gl-display-flex gl-align-items-center gl-mt-3"
>
<gl-sprintf
:message=
"$options.i18n.fields.rules.action"
>
<
template
#doAction
>
<gl-dropdown
class=
"rule-control gl-mx-3"
:text=
"$options.ACTIONS[rule.action]"
data-testid=
"action-dropdown"
>
<gl-dropdown-item
v-for=
"(label, action) in $options.ACTIONS"
:key=
"action"
:is-checked=
"rule.action === action"
is-check-item
>
{{
label
}}
</gl-dropdown-item>
</gl-dropdown>
</
template
>
<
template
#schedule
>
<gl-dropdown
class=
"rule-control gl-mx-3"
:text=
"$options.i18n.fields.rules.selectSchedule"
data-testid=
"schedules-dropdown"
>
<gl-dropdown-item
v-for=
"schedule in schedules"
:key=
"schedule.id"
is-check-item
>
{{
schedule
.
name
}}
</gl-dropdown-item>
</gl-dropdown>
</
template
>
</gl-sprintf>
</div>
</gl-card>
</template>
ee/app/assets/javascripts/escalation_policies/constants.js
0 → 100644
View file @
37405ed1
import
{
s__
}
from
'
~/locale
'
;
export
const
ALERT_STATUSES
=
{
ACKNOWLEDGED
:
s__
(
'
AlertManagement|Acknowledged
'
),
RESOLVED
:
s__
(
'
AlertManagement|Resolved
'
),
};
export
const
ACTIONS
=
{
EMAIL_ONCALL_SCHEDULE_USER
:
s__
(
'
EscalationPolicies|Email on-call user in schedule
'
),
};
export
const
defaultEscalationRule
=
{
status
:
'
ACKNOWLEDGED
'
,
elapsedTimeSeconds
:
0
,
action
:
'
EMAIL_ONCALL_SCHEDULE_USER
'
,
oncallSchedule
:
{
iid
:
null
,
name
:
null
,
},
};
export
const
addEscalationPolicyModalId
=
'
addEscalationPolicyModal
'
;
ee/app/assets/javascripts/escalation_policies/index.js
View file @
37405ed1
...
@@ -6,11 +6,12 @@ export default () => {
...
@@ -6,11 +6,12 @@ export default () => {
if
(
!
el
)
return
null
;
if
(
!
el
)
return
null
;
const
{
emptyEscalationPoliciesSvgPath
}
=
el
.
dataset
;
const
{
emptyEscalationPoliciesSvgPath
,
projectPath
=
''
}
=
el
.
dataset
;
return
new
Vue
({
return
new
Vue
({
el
,
el
,
provide
:
{
provide
:
{
projectPath
,
emptyEscalationPoliciesSvgPath
,
emptyEscalationPoliciesSvgPath
,
},
},
render
(
createElement
)
{
render
(
createElement
)
{
...
...
ee/app/assets/javascripts/escalation_policies/utils.js
0 → 100644
View file @
37405ed1
/**
* Returns `true` for non-empty string, otherwise returns `false`
* @param {String} name
*
* @returns {Boolean}
*/
export
const
isNameFieldValid
=
(
name
)
=>
{
return
Boolean
(
name
?.
length
);
};
ee/app/assets/javascripts/oncall_schedules/components/add_edit_schedule_form.vue
View file @
37405ed1
...
@@ -62,11 +62,6 @@ export default {
...
@@ -62,11 +62,6 @@ export default {
type
:
Object
,
type
:
Object
,
required
:
true
,
required
:
true
,
},
},
schedule
:
{
type
:
Object
,
required
:
false
,
default
:
()
=>
({}),
},
},
},
data
()
{
data
()
{
return
{
return
{
...
@@ -112,7 +107,7 @@ export default {
...
@@ -112,7 +107,7 @@ export default {
label-size=
"sm"
label-size=
"sm"
label-for=
"schedule-name"
label-for=
"schedule-name"
:state=
"validationState.name"
:state=
"validationState.name"
requ
ri
ed
requ
ir
ed
>
>
<gl-form-input
<gl-form-input
id=
"schedule-name"
id=
"schedule-name"
...
@@ -140,7 +135,7 @@ export default {
...
@@ -140,7 +135,7 @@ export default {
:description=
"$options.i18n.fields.timezone.description"
:description=
"$options.i18n.fields.timezone.description"
:state=
"validationState.timezone"
:state=
"validationState.timezone"
:invalid-feedback=
"$options.i18n.fields.timezone.validation.empty"
:invalid-feedback=
"$options.i18n.fields.timezone.validation.empty"
requ
ri
ed
requ
ir
ed
>
>
<gl-dropdown
<gl-dropdown
id=
"schedule-timezone"
id=
"schedule-timezone"
...
...
ee/app/assets/javascripts/oncall_schedules/components/add_edit_schedule_modal.vue
View file @
37405ed1
...
@@ -215,7 +215,6 @@ export default {
...
@@ -215,7 +215,6 @@ export default {
<add-edit-schedule-form
<add-edit-schedule-form
:validation-state=
"validationState"
:validation-state=
"validationState"
:form=
"form"
:form=
"form"
:schedule=
"schedule"
@
update-schedule-form=
"updateScheduleForm"
@
update-schedule-form=
"updateScheduleForm"
/>
/>
</gl-modal>
</gl-modal>
...
...
ee/app/views/projects/incident_management/escalation_policies/index.html.haml
View file @
37405ed1
-
page_title
_
(
'Escalation policies'
)
-
page_title
_
(
'Escalation policies'
)
-
add_page_specific_style
'page_bundles/escalation_policies'
.js-escalation-policies
{
data:
escalation_policy_data
}
.js-escalation-policies
{
data:
escalation_policy_data
}
ee/spec/frontend/escalation_policies/add_edit_escalation_policy_form_spec.js
0 → 100644
View file @
37405ed1
import
{
GlLink
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
AddEscalationPolicyForm
,
{
i18n
,
}
from
'
ee/escalation_policies/components/add_edit_escalation_policy_form.vue
'
;
import
EscalationRule
from
'
ee/escalation_policies/components/escalation_rule.vue
'
;
import
{
defaultEscalationRule
}
from
'
ee/escalation_policies/constants
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
import
mockPolicy
from
'
./mocks/mockPolicy.json
'
;
describe
(
'
AddEscalationPolicyForm
'
,
()
=>
{
let
wrapper
;
const
projectPath
=
'
group/project
'
;
const
createComponent
=
({
props
=
{}
}
=
{})
=>
{
wrapper
=
extendedWrapper
(
shallowMount
(
AddEscalationPolicyForm
,
{
propsData
:
{
form
:
{
name
:
mockPolicy
.
name
,
description
:
mockPolicy
.
description
,
},
validationState
:
{
name
:
true
,
},
...
props
,
},
provide
:
{
projectPath
,
},
}),
);
};
beforeEach
(()
=>
{
createComponent
();
});
afterEach
(()
=>
{
wrapper
.
destroy
();
});
const
findPolicyName
=
()
=>
wrapper
.
findByTestId
(
'
escalation-policy-name
'
);
const
findRules
=
()
=>
wrapper
.
findAllComponents
(
EscalationRule
);
const
findAddRuleLink
=
()
=>
wrapper
.
findComponent
(
GlLink
);
describe
(
'
Escalation policy form validation
'
,
()
=>
{
it
(
'
should show feedback for an invalid name input validation state
'
,
async
()
=>
{
createComponent
({
props
:
{
validationState
:
{
name
:
false
},
},
});
expect
(
findPolicyName
().
attributes
(
'
state
'
)).
toBeFalsy
();
});
});
describe
(
'
Escalation rules
'
,
()
=>
{
it
(
'
should render one default rule
'
,
()
=>
{
expect
(
findRules
().
length
).
toBe
(
1
);
});
it
(
'
should contain a link to add escalation rules
'
,
()
=>
{
const
link
=
findAddRuleLink
();
expect
(
link
.
exists
()).
toBe
(
true
);
expect
(
link
.
text
()).
toMatchInterpolatedText
(
i18n
.
addRule
);
});
it
(
'
should add an empty rule to the rules list on click
'
,
async
()
=>
{
findAddRuleLink
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$nextTick
();
const
rules
=
findRules
();
expect
(
rules
.
length
).
toBe
(
2
);
expect
(
rules
.
at
(
1
).
props
(
'
rule
'
)).
toEqual
(
defaultEscalationRule
);
});
});
});
ee/spec/frontend/escalation_policies/add_edit_escalation_policy_modal_spec.js
0 → 100644
View file @
37405ed1
import
{
GlModal
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
AddEscalationPolicyForm
from
'
ee/escalation_policies/components/add_edit_escalation_policy_form.vue
'
;
import
AddEscalationPolicyModal
,
{
i18n
,
}
from
'
ee/escalation_policies/components/add_edit_escalation_policy_modal.vue
'
;
describe
(
'
AddEscalationPolicyModal
'
,
()
=>
{
let
wrapper
;
const
projectPath
=
'
group/project
'
;
const
createComponent
=
({
escalationPolicy
,
data
}
=
{})
=>
{
wrapper
=
shallowMount
(
AddEscalationPolicyModal
,
{
data
()
{
return
{
...
data
,
};
},
propsData
:
{
escalationPolicy
,
},
provide
:
{
projectPath
,
},
});
};
beforeEach
(()
=>
{
createComponent
();
});
afterEach
(()
=>
{
wrapper
.
destroy
();
});
const
findModal
=
()
=>
wrapper
.
findComponent
(
GlModal
);
const
findEscalationPolicyForm
=
()
=>
wrapper
.
findComponent
(
AddEscalationPolicyForm
);
describe
(
'
renders create modal with the correct information
'
,
()
=>
{
it
(
'
renders modal title
'
,
()
=>
{
expect
(
findModal
().
attributes
(
'
title
'
)).
toBe
(
i18n
.
addEscalationPolicy
);
});
it
(
'
renders the form inside the modal
'
,
()
=>
{
expect
(
findEscalationPolicyForm
().
exists
()).
toBe
(
true
);
});
});
describe
(
'
modal buttons
'
,
()
=>
{
it
(
'
should disable primary button when form is invalid
'
,
async
()
=>
{
findEscalationPolicyForm
().
vm
.
$emit
(
'
update-escalation-policy-form
'
,
{
field
:
'
name
'
,
value
:
''
,
});
await
wrapper
.
vm
.
$nextTick
();
expect
(
findModal
().
props
(
'
actionPrimary
'
).
attributes
).
toContainEqual
({
disabled
:
true
});
});
it
(
'
should enable primary button when form is valid
'
,
async
()
=>
{
findEscalationPolicyForm
().
vm
.
$emit
(
'
update-escalation-policy-form
'
,
{
field
:
'
name
'
,
value
:
'
Some policy name
'
,
});
await
wrapper
.
vm
.
$nextTick
();
expect
(
findModal
().
props
(
'
actionPrimary
'
).
attributes
).
toContainEqual
({
disabled
:
false
});
});
});
});
ee/spec/frontend/escalation_polic
y
/escalation_policy_wrapper_spec.js
→
ee/spec/frontend/escalation_polic
ies
/escalation_policy_wrapper_spec.js
View file @
37405ed1
import
{
GlEmptyState
}
from
'
@gitlab/ui
'
;
import
{
GlEmptyState
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
OnCallSchedule
Wrapper
,
{
import
EscalationPolicies
Wrapper
,
{
i18n
,
i18n
,
}
from
'
ee/escalation_policies/components/escalation_policies_wrapper.vue
'
;
}
from
'
ee/escalation_policies/components/escalation_policies_wrapper.vue
'
;
...
@@ -9,7 +9,7 @@ describe('AlertManagementEmptyState', () => {
...
@@ -9,7 +9,7 @@ describe('AlertManagementEmptyState', () => {
const
emptyEscalationPoliciesSvgPath
=
'
illustration/path.svg
'
;
const
emptyEscalationPoliciesSvgPath
=
'
illustration/path.svg
'
;
function
mountComponent
()
{
function
mountComponent
()
{
wrapper
=
shallowMount
(
OnCallSchedule
Wrapper
,
{
wrapper
=
shallowMount
(
EscalationPolicies
Wrapper
,
{
provide
:
{
provide
:
{
emptyEscalationPoliciesSvgPath
,
emptyEscalationPoliciesSvgPath
,
},
},
...
...
ee/spec/frontend/escalation_policies/escalation_rule_spec.js
0 → 100644
View file @
37405ed1
import
{
GlDropdownItem
,
GlSprintf
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
cloneDeep
}
from
'
lodash
'
;
import
EscalationRule
from
'
ee/escalation_policies/components/escalation_rule.vue
'
;
import
{
defaultEscalationRule
,
ACTIONS
,
ALERT_STATUSES
}
from
'
ee/escalation_policies/constants
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
const
mockSchedules
=
[
{
id
:
1
,
name
:
'
schedule1
'
},
{
id
:
2
,
name
:
'
schedule2
'
},
{
id
:
3
,
name
:
'
schedule3
'
},
];
describe
(
'
EscalationRule
'
,
()
=>
{
let
wrapper
;
const
createComponent
=
({
props
=
{}
}
=
{})
=>
{
wrapper
=
extendedWrapper
(
shallowMount
(
EscalationRule
,
{
propsData
:
{
rule
:
cloneDeep
(
defaultEscalationRule
),
schedules
:
mockSchedules
,
...
props
,
},
stubs
:
{
GlSprintf
,
},
}),
);
};
beforeEach
(()
=>
{
createComponent
();
});
afterEach
(()
=>
{
wrapper
.
destroy
();
});
const
findStatusDropdown
=
()
=>
wrapper
.
findByTestId
(
'
alert-status-dropdown
'
);
const
findStatusDropdownOptions
=
()
=>
findStatusDropdown
().
findAll
(
GlDropdownItem
);
const
findActionDropdown
=
()
=>
wrapper
.
findByTestId
(
'
action-dropdown
'
);
const
findActionDropdownOptions
=
()
=>
findActionDropdown
().
findAll
(
GlDropdownItem
);
const
findSchedulesDropdown
=
()
=>
wrapper
.
findByTestId
(
'
schedules-dropdown
'
);
const
findSchedulesDropdownOptions
=
()
=>
findSchedulesDropdown
().
findAll
(
GlDropdownItem
);
describe
(
'
Status dropdown
'
,
()
=>
{
it
(
'
should have correct alert status options
'
,
()
=>
{
expect
(
findStatusDropdownOptions
().
wrappers
.
map
((
w
)
=>
w
.
text
())).
toStrictEqual
(
Object
.
values
(
ALERT_STATUSES
),
);
});
it
(
'
should have default status selected
'
,
async
()
=>
{
expect
(
findStatusDropdownOptions
().
at
(
0
).
props
(
'
isChecked
'
)).
toBe
(
true
);
});
});
describe
(
'
Actions dropdown
'
,
()
=>
{
it
(
'
should have correct action options
'
,
()
=>
{
expect
(
findActionDropdownOptions
().
wrappers
.
map
((
w
)
=>
w
.
text
())).
toStrictEqual
(
Object
.
values
(
ACTIONS
),
);
});
it
(
'
should have default action selected
'
,
async
()
=>
{
expect
(
findActionDropdownOptions
().
at
(
0
).
props
(
'
isChecked
'
)).
toBe
(
true
);
});
});
describe
(
'
Schedules dropdown
'
,
()
=>
{
it
(
'
should have correct schedules options
'
,
()
=>
{
expect
(
findSchedulesDropdownOptions
().
wrappers
.
map
((
w
)
=>
w
.
text
())).
toStrictEqual
(
mockSchedules
.
map
(({
name
})
=>
name
),
);
});
});
});
ee/spec/frontend/escalation_policies/mocks/mockPolicy.json
0 → 100644
View file @
37405ed1
{
"iid"
:
"37"
,
"name"
:
"Test ecsaltion policy"
,
"description"
:
"Description 1 lives here"
,
"rules"
:
[]
}
ee/spec/frontend/oncall_schedule/__snapshots__/add_edit_schedule_form_spec.js.snap
View file @
37405ed1
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`AddEditScheduleForm renders modal layout 1`] = `
exports[`AddEditScheduleForm renders form layout 1`] = `
<gl-form-stub
<gl-form-stub>
modalid="modalId"
>
<gl-form-group-stub
<gl-form-group-stub
invalid-feedback="Can't be empty"
invalid-feedback="Can't be empty"
label="Name"
label="Name"
label-for="schedule-name"
label-for="schedule-name"
label-size="sm"
label-size="sm"
requ
ri
ed=""
requ
ir
ed=""
state="true"
state="true"
>
>
<gl-form-input-stub
<gl-form-input-stub
...
@@ -35,7 +33,7 @@ exports[`AddEditScheduleForm renders modal layout 1`] = `
...
@@ -35,7 +33,7 @@ exports[`AddEditScheduleForm renders modal layout 1`] = `
label="Timezone"
label="Timezone"
label-for="schedule-timezone"
label-for="schedule-timezone"
label-size="sm"
label-size="sm"
requ
ri
ed=""
requ
ir
ed=""
state="true"
state="true"
>
>
<gl-dropdown-stub
<gl-dropdown-stub
...
...
ee/spec/frontend/oncall_schedule/add_edit_schedule_form_spec.js
View file @
37405ed1
...
@@ -16,7 +16,6 @@ describe('AddEditScheduleForm', () => {
...
@@ -16,7 +16,6 @@ describe('AddEditScheduleForm', () => {
const
createComponent
=
({
props
=
{}
}
=
{})
=>
{
const
createComponent
=
({
props
=
{}
}
=
{})
=>
{
wrapper
=
shallowMount
(
AddEditScheduleForm
,
{
wrapper
=
shallowMount
(
AddEditScheduleForm
,
{
propsData
:
{
propsData
:
{
modalId
:
'
modalId
'
,
form
:
{
form
:
{
name
:
mockSchedule
.
name
,
name
:
mockSchedule
.
name
,
description
:
mockSchedule
.
description
,
description
:
mockSchedule
.
description
,
...
@@ -26,7 +25,6 @@ describe('AddEditScheduleForm', () => {
...
@@ -26,7 +25,6 @@ describe('AddEditScheduleForm', () => {
name
:
true
,
name
:
true
,
timezone
:
true
,
timezone
:
true
,
},
},
schedule
:
mockSchedule
,
...
props
,
...
props
,
},
},
provide
:
{
provide
:
{
...
@@ -54,7 +52,7 @@ describe('AddEditScheduleForm', () => {
...
@@ -54,7 +52,7 @@ describe('AddEditScheduleForm', () => {
const
findTimezoneSearchBox
=
()
=>
wrapper
.
find
(
GlSearchBoxByType
);
const
findTimezoneSearchBox
=
()
=>
wrapper
.
find
(
GlSearchBoxByType
);
const
findScheduleName
=
()
=>
wrapper
.
find
(
GlFormGroup
);
const
findScheduleName
=
()
=>
wrapper
.
find
(
GlFormGroup
);
it
(
'
renders
modal
layout
'
,
()
=>
{
it
(
'
renders
form
layout
'
,
()
=>
{
expect
(
wrapper
.
element
).
toMatchSnapshot
();
expect
(
wrapper
.
element
).
toMatchSnapshot
();
});
});
...
...
locale/gitlab.pot
View file @
37405ed1
...
@@ -13090,15 +13090,39 @@ msgstr ""
...
@@ -13090,15 +13090,39 @@ msgstr ""
msgid "Escalation policies"
msgid "Escalation policies"
msgstr ""
msgstr ""
msgid "EscalationPolicies|+ Add an additional rule"
msgstr ""
msgid "EscalationPolicies|Add an escalation policy"
msgid "EscalationPolicies|Add an escalation policy"
msgstr ""
msgstr ""
msgid "EscalationPolicies|Add escalation policy"
msgstr ""
msgid "EscalationPolicies|Create an escalation policy in GitLab"
msgid "EscalationPolicies|Create an escalation policy in GitLab"
msgstr ""
msgstr ""
msgid "EscalationPolicies|Edit escalation policy"
msgstr ""
msgid "EscalationPolicies|Email on-call user in schedule"
msgstr ""
msgid "EscalationPolicies|Escalation rules"
msgstr ""
msgid "EscalationPolicies|IF alert is not %{alertStatus} in %{minutes} minutes"
msgstr ""
msgid "EscalationPolicies|Select schedule"
msgstr ""
msgid "EscalationPolicies|Set up escalation policies to define who is paged, and when, in the event the first users paged don't respond."
msgid "EscalationPolicies|Set up escalation policies to define who is paged, and when, in the event the first users paged don't respond."
msgstr ""
msgstr ""
msgid "EscalationPolicies|THEN %{doAction} %{schedule}"
msgstr ""
msgid "Estimate"
msgid "Estimate"
msgstr ""
msgstr ""
...
...
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