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
817f6d4d
Commit
817f6d4d
authored
4 years ago
by
Ezekiel Kigbo
Committed by
Illya Klymov
4 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move custom stage specs to folder
Moves the specs specifically for custom stages into a separate dir
parent
f35bf8cb
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
590 additions
and
426 deletions
+590
-426
ee/app/assets/javascripts/analytics/cycle_analytics/components/base.vue
...javascripts/analytics/cycle_analytics/components/base.vue
+4
-18
ee/app/assets/javascripts/analytics/cycle_analytics/components/custom_stage_form.vue
...nalytics/cycle_analytics/components/custom_stage_form.vue
+66
-76
ee/app/assets/javascripts/analytics/cycle_analytics/components/stage_table_nav.vue
.../analytics/cycle_analytics/components/stage_table_nav.vue
+1
-5
ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/actions.js
...cs/cycle_analytics/store/modules/custom_stages/actions.js
+4
-1
ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/mutation_types.js
...e_analytics/store/modules/custom_stages/mutation_types.js
+2
-1
ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/mutations.js
.../cycle_analytics/store/modules/custom_stages/mutations.js
+6
-1
ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/state.js
...tics/cycle_analytics/store/modules/custom_stages/state.js
+1
-0
ee/spec/frontend/analytics/cycle_analytics/components/custom_stage_form_spec.js
...tics/cycle_analytics/components/custom_stage_form_spec.js
+149
-94
ee/spec/frontend/analytics/cycle_analytics/mock_data.js
ee/spec/frontend/analytics/cycle_analytics/mock_data.js
+2
-2
ee/spec/frontend/analytics/cycle_analytics/store/actions_spec.js
.../frontend/analytics/cycle_analytics/store/actions_spec.js
+0
-164
ee/spec/frontend/analytics/cycle_analytics/store/modules/custom_stages/actions_spec.js
...cle_analytics/store/modules/custom_stages/actions_spec.js
+261
-0
ee/spec/frontend/analytics/cycle_analytics/store/modules/custom_stages/getters_spec.js
...cle_analytics/store/modules/custom_stages/getters_spec.js
+15
-0
ee/spec/frontend/analytics/cycle_analytics/store/modules/custom_stages/mutations_spec.js
...e_analytics/store/modules/custom_stages/mutations_spec.js
+78
-0
ee/spec/frontend/analytics/cycle_analytics/store/mutations_spec.js
...rontend/analytics/cycle_analytics/store/mutations_spec.js
+1
-64
No files found.
ee/app/assets/javascripts/analytics/cycle_analytics/components/base.vue
View file @
817f6d4d
...
...
@@ -70,14 +70,9 @@ export default {
'
endDate
'
,
'
medians
'
,
]),
...
mapState
(
'
customStages
'
,
[
'
isSavingCustomStage
'
,
'
isCreatingCustomStage
'
,
'
isEditingCustomStage
'
,
'
formEvents
'
,
'
formErrors
'
,
'
formInitialData
'
,
]),
// NOTE: formEvents are fetched in the same request as the list of stages (fetchGroupStagesAndEvents)
// so i think its ok to bind formEvents here even though its only used as a prop to the custom-stage-form
...
mapState
(
'
customStages
'
,
[
'
isCreatingCustomStage
'
,
'
formEvents
'
]),
...
mapGetters
([
'
hasNoAccessError
'
,
'
currentGroupPath
'
,
...
...
@@ -106,9 +101,6 @@ export default {
isLoadingTypeOfWork
()
{
return
this
.
isLoadingTasksByTypeChartTopLabels
||
this
.
isLoadingTasksByTypeChart
;
},
isUpdatingCustomStage
()
{
return
this
.
isEditingCustomStage
&&
this
.
isSavingCustomStage
;
},
hasDateRangeSet
()
{
return
this
.
startDate
&&
this
.
endDate
;
},
...
...
@@ -169,6 +161,7 @@ export default {
this
.
showCreateForm
();
},
onShowEditStageForm
(
initData
=
{})
{
this
.
setSelectedStage
(
initData
);
this
.
showEditForm
(
initData
);
},
onCreateCustomStage
(
data
)
{
...
...
@@ -299,7 +292,6 @@ export default {
:stages=
"activeStages"
:medians=
"medians"
:is-creating-custom-stage=
"isCreatingCustomStage"
:custom-stage-form-active=
"customStageFormActive"
:can-edit-stages=
"true"
:custom-ordering=
"enableCustomOrdering"
@
reorderStage=
"onStageReorder"
...
...
@@ -311,14 +303,8 @@ export default {
/>
</
template
>
<
template
v-if=
"customStageFormActive"
#content
>
<gl-loading-icon
v-if=
"isUpdatingCustomStage"
class=
"mt-4"
size=
"md"
/>
<custom-stage-form
v-else
:events=
"formEvents"
:is-saving-custom-stage=
"isSavingCustomStage"
:initial-fields=
"formInitialData"
:is-editing-custom-stage=
"isEditingCustomStage"
:errors=
"formErrors"
@
createStage=
"onCreateCustomStage"
@
updateStage=
"onUpdateCustomStage"
@
clearErrors=
"$emit('clearFormErrors')"
...
...
This diff is collapsed.
Click to expand it.
ee/app/assets/javascripts/analytics/cycle_analytics/components/custom_stage_form.vue
View file @
817f6d4d
<
script
>
import
{
mapGetters
}
from
'
vuex
'
;
import
{
mapGetters
,
mapState
}
from
'
vuex
'
;
import
{
isEqual
}
from
'
lodash
'
;
import
{
GlFormGroup
,
...
...
@@ -33,23 +33,37 @@ const defaultFields = {
endEventLabelId
:
null
,
};
export
const
initializeFormData
=
({
emptyFieldState
,
initialFields
,
errors
})
=>
{
const
defaultErrors
=
initialFields
?.
endEventIdentifier
?
{
...
emptyFieldState
,
endEventIdentifier
:
null
}
const
defaultErrors
=
{
id
:
[],
name
:
[],
startEventIdentifier
:
[],
startEventLabelId
:
[],
endEventIdentifier
:
[],
endEventLabelId
:
[],
};
const
ERRORS
=
{
START_EVENT_REQUIRED
:
s__
(
'
CustomCycleAnalytics|Please select a start event first
'
),
STAGE_NAME_EXISTS
:
s__
(
'
CustomCycleAnalytics|Stage name already exists
'
),
INVALID_EVENT_PAIRS
:
s__
(
'
CustomCycleAnalytics|Start event changed, please select a valid stop event
'
,
),
};
export
const
initializeFormData
=
({
emptyFieldState
=
defaultFields
,
fields
,
errors
})
=>
{
const
initErrors
=
fields
?.
endEventIdentifier
?
defaultErrors
:
{
...
emptyFieldState
,
endEventIdentifier
:
initialFields
&&
!
initialFields
.
startEventIdentifier
?
[
s__
(
'
CustomCycleAnalytics|Please select a start event first
'
)]
:
null
,
...
defaultErrors
,
endEventIdentifier
:
!
fields
?.
startEventIdentifier
?
[
ERRORS
.
START_EVENT_REQUIRED
]
:
[],
};
return
{
fields
:
{
...
emptyFieldState
,
...
initialF
ields
,
...
f
ields
,
},
fieldE
rrors
:
{
...
defaul
tErrors
,
e
rrors
:
{
...
ini
tErrors
,
...
errors
,
},
};
...
...
@@ -72,42 +86,23 @@ export default {
type
:
Array
,
required
:
true
,
},
initialFields
:
{
type
:
Object
,
required
:
false
,
default
:
()
=>
{},
},
isSavingCustomStage
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
isEditingCustomStage
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
errors
:
{
type
:
Object
,
required
:
false
,
default
:
null
,
},
},
data
()
{
const
{
initialFields
=
{},
errors
=
null
}
=
this
;
const
{
fields
,
fieldErrors
}
=
initializeFormData
({
emptyFieldState
:
defaultFields
,
initialFields
,
errors
,
});
return
{
labelEvents
:
getLabelEventsIdentifiers
(
this
.
events
),
fields
,
fieldErrors
,
fields
:
{}
,
errors
:
[]
,
};
},
computed
:
{
...
mapGetters
([
'
hiddenStages
'
]),
...
mapState
(
'
customStages
'
,
[
'
isLoading
'
,
'
isSavingCustomStage
'
,
'
isEditingCustomStage
'
,
'
formInitialData
'
,
'
formErrors
'
,
]),
startEventOptions
()
{
return
[
{
value
:
null
,
text
:
s__
(
'
CustomCycleAnalytics|Select start event
'
)
},
...
...
@@ -132,8 +127,7 @@ export default {
},
hasErrors
()
{
return
(
this
.
eventMismatchError
||
Object
.
values
(
this
.
fieldErrors
).
some
(
errArray
=>
errArray
?.
length
)
this
.
eventMismatchError
||
Object
.
values
(
this
.
errors
).
some
(
errArray
=>
errArray
?.
length
)
);
},
isComplete
()
{
...
...
@@ -162,7 +156,7 @@ export default {
);
},
isDirty
()
{
return
!
isEqual
(
this
.
initialFields
,
this
.
fields
)
&&
!
isEqual
(
defaultFields
,
this
.
f
ields
);
return
!
isEqual
(
this
.
fields
,
this
.
formInitialData
||
defaultF
ields
);
},
eventMismatchError
()
{
const
{
...
...
@@ -188,35 +182,39 @@ export default {
},
},
watch
:
{
initialFields
(
newFields
)
{
formInitialData
(
newFields
=
{}
)
{
this
.
fields
=
{
...
defaultFields
,
...
newFields
,
};
},
errors
(
newErrors
)
{
this
.
fieldErrors
=
{
...
defaultFields
,
formErrors
(
newErrors
=
{})
{
this
.
errors
=
{
...
newErrors
,
};
},
},
mounted
()
{
this
.
resetFields
();
},
methods
:
{
handleCancel
()
{
const
{
initialFields
=
{},
errors
=
null
}
=
this
;
const
formData
=
initializeFormData
({
emptyFieldState
:
defaultFields
,
initialFields
,
errors
,
resetFields
()
{
const
{
formInitialData
,
formErrors
}
=
this
;
const
{
fields
,
errors
}
=
initializeFormData
({
fields
:
formInitialData
,
errors
:
formErrors
,
});
this
.
$set
(
this
,
'
fields
'
,
formData
.
fields
);
this
.
$set
(
this
,
'
fieldErrors
'
,
formData
.
fieldErrors
);
this
.
fields
=
{
...
fields
};
this
.
errors
=
{
...
errors
};
},
handleCancel
()
{
this
.
resetFields
();
this
.
$emit
(
'
cancel
'
);
},
handleSave
()
{
const
data
=
convertObjectPropsToSnakeCase
(
this
.
fields
);
if
(
this
.
isEditingCustomStage
)
{
const
{
id
}
=
this
.
initialF
ields
;
const
{
id
}
=
this
.
f
ields
;
this
.
$emit
(
STAGE_ACTIONS
.
UPDATE
,
{
...
data
,
id
});
}
else
{
this
.
$emit
(
STAGE_ACTIONS
.
CREATE
,
data
);
...
...
@@ -229,31 +227,22 @@ export default {
this
.
fields
[
key
]
=
null
;
},
hasFieldErrors
(
key
)
{
return
this
.
fieldE
rrors
[
key
]?.
length
>
0
;
return
this
.
e
rrors
[
key
]?.
length
>
0
;
},
fieldErrorMessage
(
key
)
{
return
this
.
fieldE
rrors
[
key
]?.
join
(
'
\n
'
);
return
this
.
e
rrors
[
key
]?.
join
(
'
\n
'
);
},
onUpdateNameField
()
{
if
(
DEFAULT_STAGE_NAMES
.
includes
(
this
.
fields
.
name
.
toLowerCase
()))
{
this
.
$set
(
this
.
fieldErrors
,
'
name
'
,
[
s__
(
'
CustomCycleAnalytics|Stage name already exists
'
),
]);
}
else
{
this
.
$set
(
this
.
fieldErrors
,
'
name
'
,
[]);
}
this
.
errors
.
name
=
DEFAULT_STAGE_NAMES
.
includes
(
this
.
fields
.
name
.
toLowerCase
())
?
[
ERRORS
.
STAGE_NAME_EXISTS
]
:
[];
},
onUpdateStartEventField
()
{
const
initVal
=
this
.
initialFields
?.
endEventIdentifier
?
this
.
initialFields
.
endEventIdentifier
:
null
;
this
.
$set
(
this
.
fields
,
'
endEventIdentifier
'
,
initVal
);
this
.
$set
(
this
.
fieldErrors
,
'
endEventIdentifier
'
,
[
s__
(
'
CustomCycleAnalytics|Start event changed, please select a valid stop event
'
),
]);
this
.
fields
.
endEventIdentifier
=
null
;
this
.
errors
.
endEventIdentifier
=
[
ERRORS
.
INVALID_EVENT_PAIRS
];
},
onUpdateEndEventField
()
{
this
.
$set
(
this
.
fieldErrors
,
'
endEventIdentifier
'
,
null
)
;
this
.
errors
.
endEventIdentifier
=
[]
;
},
handleRecoverStage
(
id
)
{
this
.
$emit
(
STAGE_ACTIONS
.
UPDATE
,
{
id
,
hidden
:
false
});
...
...
@@ -262,7 +251,10 @@ export default {
};
</
script
>
<
template
>
<form
class=
"custom-stage-form m-4 mt-0"
>
<div
v-if=
"isLoading"
>
<gl-loading-icon
class=
"mt-4"
size=
"md"
/>
</div>
<form
v-else
class=
"custom-stage-form m-4 mt-0"
>
<div
class=
"mb-1 d-flex flex-row justify-content-between"
>
<h4>
{{
formTitle
}}
</h4>
<gl-dropdown
:text=
"__('Recover hidden stage')"
class=
"js-recover-hidden-stage-dropdown"
>
...
...
@@ -366,7 +358,6 @@ export default {
</gl-form-group>
</div>
</div>
<div
class=
"custom-stage-form-actions"
>
<button
:disabled=
"!isDirty"
...
...
@@ -386,7 +377,6 @@ export default {
{{ saveStageText }}
</button>
</div>
<div
class=
"mt-2"
>
<gl-sprintf
:message=
"
...
...
This diff is collapsed.
Click to expand it.
ee/app/assets/javascripts/analytics/cycle_analytics/components/stage_table_nav.vue
View file @
817f6d4d
...
...
@@ -29,10 +29,6 @@ export default {
type
:
Boolean
,
required
:
true
,
},
customStageFormActive
:
{
type
:
Boolean
,
required
:
true
,
},
canEditStages
:
{
type
:
Boolean
,
required
:
true
,
...
...
@@ -106,7 +102,7 @@ export default {
<add-stage-button
v-if=
"canEditStages"
:class=
"$options.noDragClass"
:active=
"
customStageFormActiv
e"
:active=
"
isCreatingCustomStag
e"
@
showform=
"$emit('showAddStageForm')"
/>
</ul>
...
...
This diff is collapsed.
Click to expand it.
ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/actions.js
View file @
817f6d4d
...
...
@@ -15,15 +15,18 @@ export const hideForm = ({ commit }) => {
};
export
const
showCreateForm
=
({
commit
})
=>
{
commit
(
types
.
SET_LOADING
);
commit
(
types
.
SET_FORM_INITIAL_DATA
);
commit
(
types
.
SHOW_CREATE_FORM
);
removeFlash
();
};
export
const
showEditForm
=
({
commit
,
dispatch
},
selectedStage
=
{})
=>
{
commit
(
types
.
SET_LOADING
);
commit
(
types
.
SET_FORM_INITIAL_DATA
,
selectedStage
);
commit
(
types
.
SHOW_EDIT_FORM
);
dispatch
(
'
setSelectedStage
'
,
selectedStage
,
{
root
:
true
});
dispatch
(
'
clearSavingCustomStage
'
);
commit
(
types
.
SHOW_EDIT_FORM
);
removeFlash
();
};
...
...
This diff is collapsed.
Click to expand it.
ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/mutation_types.js
View file @
817f6d4d
export
const
SET_LOADING
=
'
SET_LOADING
'
;
export
const
SET_STAGE_EVENTS
=
'
SET_STAGE_EVENTS
'
;
export
const
SET_STAGE_FORM_ERRORS
=
'
SET_STAGE_FORM_ERRORS
'
;
export
const
SET_FORM_INITIAL_DATA
=
'
SET_FORM_INITIAL_DATA
'
;
export
const
SET_SAVING_CUSTOM_STAGE
=
'
SET_SAVING_CUSTOM_STAGE
'
;
export
const
CLEAR_SAVING_CUSTOM_STAGE
=
'
CLEAR_SAVING_CUSTOM_STAGE
'
;
export
const
HIDE_FORM
=
'
SHOW
_FORM
'
;
export
const
HIDE_FORM
=
'
HIDE
_FORM
'
;
export
const
SHOW_CREATE_FORM
=
'
SHOW_CREATE_FORM
'
;
export
const
SHOW_EDIT_FORM
=
'
SHOW_EDIT_FORM
'
;
export
const
CLEAR_FORM_ERRORS
=
'
CLEAR_FORM_ERRORS
'
;
...
...
This diff is collapsed.
Click to expand it.
ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/mutations.js
View file @
817f6d4d
...
...
@@ -31,21 +31,26 @@ export default {
state
.
formErrors
=
convertObjectPropsToCamelCase
(
errors
,
{
deep
:
true
});
},
[
types
.
SET_FORM_INITIAL_DATA
](
state
,
rawStageData
=
null
)
{
state
.
formInitialData
=
extractFormFields
(
rawStageData
)
;
state
.
formInitialData
=
rawStageData
?
extractFormFields
(
rawStageData
)
:
null
;
},
[
types
.
SET_SAVING_CUSTOM_STAGE
](
state
)
{
state
.
isSavingCustomStage
=
true
;
},
[
types
.
SET_LOADING
](
state
)
{
state
.
isLoadingCustomStage
=
true
;
},
[
types
.
CLEAR_SAVING_CUSTOM_STAGE
](
state
)
{
state
.
isSavingCustomStage
=
false
;
},
[
types
.
SHOW_CREATE_FORM
](
state
)
{
state
.
isLoadingCustomStage
=
false
;
state
.
isEditingCustomStage
=
false
;
state
.
isCreatingCustomStage
=
true
;
state
.
formInitialData
=
null
;
state
.
formErrors
=
null
;
},
[
types
.
SHOW_EDIT_FORM
](
state
)
{
state
.
isLoadingCustomStage
=
false
;
state
.
isCreatingCustomStage
=
false
;
state
.
isEditingCustomStage
=
true
;
state
.
formErrors
=
null
;
...
...
This diff is collapsed.
Click to expand it.
ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/state.js
View file @
817f6d4d
export
default
()
=>
({
isLoadingCustomStage
:
false
,
isSavingCustomStage
:
false
,
isCreatingCustomStage
:
false
,
isEditingCustomStage
:
false
,
...
...
This diff is collapsed.
Click to expand it.
ee/spec/frontend/analytics/cycle_analytics/components/custom_stage_form_spec.js
View file @
817f6d4d
import
Vue
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
axios
from
'
axios
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
c
reateStore
from
'
ee/analytics/cycle_analytics/store
'
;
import
c
ustomStagesStore
from
'
ee/analytics/cycle_analytics/store/modules/custom_stages
'
;
import
{
createLocalVue
,
mount
}
from
'
@vue/test-utils
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
CustomStageForm
,
{
...
...
@@ -20,7 +19,7 @@ import {
customStageFormErrors
,
}
from
'
../mock_data
'
;
const
init
Data
=
{
const
formInitial
Data
=
{
id
:
74
,
name
:
'
Cool stage pre
'
,
startEventIdentifier
:
labelStartEvent
.
identifier
,
...
...
@@ -32,16 +31,37 @@ const initData = {
const
MERGE_REQUEST_CREATED
=
'
merge_request_created
'
;
const
MERGE_REQUEST_CLOSED
=
'
merge_request_closed
'
;
let
store
=
null
;
const
localVue
=
createLocalVue
();
localVue
.
use
(
Vuex
);
const
fakeStore
=
({
initialState
,
initialRootGetters
})
=>
new
Vuex
.
Store
({
getters
:
{
currentGroupPath
:
()
=>
'
fake
'
,
hiddenStages
:
()
=>
[],
...
initialRootGetters
,
},
modules
:
{
customStages
:
{
...
customStagesStore
,
state
:
{
isLoading
:
false
,
...
initialState
,
},
},
},
});
describe
(
'
CustomStageForm
'
,
()
=>
{
function
createComponent
(
props
=
{},
stubs
=
{})
{
store
=
createStore
();
function
createComponent
({
initialState
=
{},
initialRootGetters
=
{},
stubs
=
{},
props
=
{},
}
=
{})
{
return
mount
(
CustomStageForm
,
{
localVue
,
store
,
store
:
fakeStore
({
initialState
,
initialRootGetters
})
,
propsData
:
{
events
,
...
props
,
...
...
@@ -98,7 +118,7 @@ describe('CustomStageForm', () => {
stopEventDropdownIndex
=
mergeRequestClosedDropdownIndex
,
}
=
{})
{
selectDropdownOption
(
wrapper
,
sel
.
startEvent
,
startEventDropdownIndex
);
return
Vue
.
nextTick
().
then
(()
=>
{
return
wrapper
.
vm
.
$
nextTick
().
then
(()
=>
{
selectDropdownOption
(
wrapper
,
sel
.
endEvent
,
stopEventDropdownIndex
);
});
}
...
...
@@ -117,7 +137,7 @@ describe('CustomStageForm', () => {
beforeEach
(()
=>
{
mock
=
mockGroupLabelsRequest
();
wrapper
=
createComponent
(
{}
);
wrapper
=
createComponent
();
});
afterEach
(()
=>
{
...
...
@@ -155,7 +175,7 @@ describe('CustomStageForm', () => {
describe
(
'
Name
'
,
()
=>
{
describe
(
'
with a reserved name
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createComponent
(
{}
);
wrapper
=
createComponent
();
return
setNameField
(
wrapper
,
'
issue
'
);
});
...
...
@@ -174,7 +194,7 @@ describe('CustomStageForm', () => {
describe
(
'
Start event
'
,
()
=>
{
describe
(
'
with events
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createComponent
(
{}
);
wrapper
=
createComponent
();
});
afterEach
(()
=>
{
...
...
@@ -229,7 +249,7 @@ describe('CustomStageForm', () => {
},
});
return
Vue
.
nextTick
().
then
(()
=>
{
return
wrapper
.
vm
.
$
nextTick
().
then
(()
=>
{
expect
(
wrapper
.
find
(
sel
.
startEventLabel
).
exists
()).
toEqual
(
true
);
});
});
...
...
@@ -246,7 +266,7 @@ describe('CustomStageForm', () => {
.
findAll
(
'
.dropdown-item
'
)
.
at
(
1
)
// item at index 0 is 'select a label'
.
trigger
(
'
click
'
);
return
Vue
.
nextTick
();
return
wrapper
.
vm
.
$
nextTick
();
})
.
then
(()
=>
{
expect
(
wrapper
.
vm
.
fields
.
startEventLabelId
).
toEqual
(
selectedLabelId
);
...
...
@@ -265,12 +285,14 @@ describe('CustomStageForm', () => {
});
it
(
'
notifies that a start event needs to be selected first
'
,
()
=>
{
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
expect
(
wrapper
.
text
()).
toContain
(
'
Please select a start event first
'
);
});
});
it
(
'
clears notification when a start event is selected
'
,
()
=>
{
selectDropdownOption
(
wrapper
,
sel
.
startEvent
,
startEventDropdownIndex
);
return
Vue
.
nextTick
().
then
(()
=>
{
return
wrapper
.
vm
.
$
nextTick
().
then
(()
=>
{
expect
(
wrapper
.
text
()).
not
.
toContain
(
'
Please select a start event first
'
);
});
});
...
...
@@ -280,7 +302,7 @@ describe('CustomStageForm', () => {
expect
(
el
.
attributes
(
'
disabled
'
)).
toEqual
(
'
disabled
'
);
selectDropdownOption
(
wrapper
,
sel
.
startEvent
,
startEventDropdownIndex
);
return
Vue
.
nextTick
().
then
(()
=>
{
return
wrapper
.
vm
.
$
nextTick
().
then
(()
=>
{
expect
(
el
.
attributes
(
'
disabled
'
)).
toBeUndefined
();
});
});
...
...
@@ -292,7 +314,7 @@ describe('CustomStageForm', () => {
selectDropdownOption
(
wrapper
,
sel
.
startEvent
,
startEventDropdownIndex
);
return
Vue
.
nextTick
().
then
(()
=>
{
return
wrapper
.
vm
.
$
nextTick
().
then
(()
=>
{
stopOptions
=
wrapper
.
find
(
sel
.
endEvent
);
selectedStartEvent
.
allowedEndEvents
.
forEach
(
identifier
=>
{
expect
(
stopOptions
.
html
()).
toContain
(
identifier
);
...
...
@@ -308,7 +330,7 @@ describe('CustomStageForm', () => {
selectDropdownOption
(
wrapper
,
sel
.
startEvent
,
startEventDropdownIndex
);
return
Vue
.
nextTick
().
then
(()
=>
{
return
wrapper
.
vm
.
$
nextTick
().
then
(()
=>
{
stopOptions
=
wrapper
.
find
(
sel
.
endEvent
);
possibleEndEvents
.
forEach
(({
name
,
identifier
})
=>
{
...
...
@@ -325,7 +347,7 @@ describe('CustomStageForm', () => {
selectDropdownOption
(
wrapper
,
sel
.
startEvent
,
startEventArrayIndex
+
1
);
return
Vue
.
nextTick
().
then
(()
=>
{
return
wrapper
.
vm
.
$
nextTick
().
then
(()
=>
{
stopOptions
=
wrapper
.
find
(
sel
.
endEvent
);
excludedEndEvents
.
forEach
(({
name
,
identifier
})
=>
{
...
...
@@ -355,10 +377,16 @@ describe('CustomStageForm', () => {
wrapper
.
destroy
();
});
it
(
'
notifies that a start event needs to be selected first
'
,
()
=>
{
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
expect
(
wrapper
.
text
()).
toContain
(
'
Please select a start event first
'
);
});
});
it
(
'
will notify if the current start and stop event pair is not valid
'
,
()
=>
{
selectDropdownOption
(
wrapper
,
sel
.
startEvent
,
2
);
return
Vue
.
nextTick
().
then
(()
=>
{
return
wrapper
.
vm
.
$
nextTick
().
then
(()
=>
{
expect
(
wrapper
.
find
(
sel
.
invalidFeedback
).
exists
()).
toEqual
(
true
);
expect
(
wrapper
.
find
(
sel
.
invalidFeedback
).
text
()).
toContain
(
'
Start event changed, please select a valid stop event
'
,
...
...
@@ -369,14 +397,14 @@ describe('CustomStageForm', () => {
it
(
'
will update the list of stop events
'
,
()
=>
{
const
se
=
wrapper
.
vm
.
endEventOptions
;
selectDropdownOption
(
wrapper
,
sel
.
startEvent
,
2
);
return
Vue
.
nextTick
().
then
(()
=>
{
return
wrapper
.
vm
.
$
nextTick
().
then
(()
=>
{
expect
(
se
[
1
].
value
).
not
.
toEqual
(
wrapper
.
vm
.
endEventOptions
[
1
].
value
);
});
});
it
(
'
will disable the submit button until a valid endEvent is selected
'
,
()
=>
{
selectDropdownOption
(
wrapper
,
sel
.
startEvent
,
2
);
return
Vue
.
nextTick
().
then
(()
=>
{
return
wrapper
.
vm
.
$
nextTick
().
then
(()
=>
{
expect
(
wrapper
.
find
(
sel
.
submit
).
attributes
(
'
disabled
'
)).
toEqual
(
'
disabled
'
);
});
});
...
...
@@ -384,7 +412,7 @@ describe('CustomStageForm', () => {
describe
(
'
Stop event label
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createComponent
(
{}
);
wrapper
=
createComponent
();
});
afterEach
(()
=>
{
...
...
@@ -405,7 +433,7 @@ describe('CustomStageForm', () => {
},
});
return
Vue
.
nextTick
().
then
(()
=>
{
return
wrapper
.
vm
.
$
nextTick
().
then
(()
=>
{
expect
(
wrapper
.
find
(
sel
.
endEventLabel
).
exists
()).
toEqual
(
true
);
});
});
...
...
@@ -429,7 +457,7 @@ describe('CustomStageForm', () => {
.
at
(
2
)
// item at index 0 is 'select a label'
.
trigger
(
'
click
'
);
return
Vue
.
nextTick
();
return
wrapper
.
vm
.
$
nextTick
();
})
.
then
(()
=>
{
expect
(
wrapper
.
vm
.
fields
.
endEventLabelId
).
toEqual
(
selectedLabelId
);
...
...
@@ -440,7 +468,7 @@ describe('CustomStageForm', () => {
describe
(
'
Add stage button
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createComponent
(
{}
);
wrapper
=
createComponent
();
});
afterEach
(()
=>
{
...
...
@@ -468,11 +496,11 @@ describe('CustomStageForm', () => {
const
stopEventDropdownIndex
=
1
;
beforeEach
(()
=>
{
wrapper
=
createComponent
(
{}
);
wrapper
=
createComponent
();
wrapper
.
find
(
sel
.
name
).
setValue
(
'
Cool stage
'
);
return
Vue
.
nextTick
().
then
(()
=>
setEventDropdowns
({
startEventDropdownIndex
,
stopEventDropdownIndex
}),
);
return
wrapper
.
vm
.
$nextTick
()
.
then
(()
=>
setEventDropdowns
({
startEventDropdownIndex
,
stopEventDropdownIndex
})
);
});
afterEach
(()
=>
{
...
...
@@ -485,7 +513,7 @@ describe('CustomStageForm', () => {
wrapper
.
find
(
sel
.
submit
).
trigger
(
'
click
'
);
return
Vue
.
nextTick
().
then
(()
=>
{
return
wrapper
.
vm
.
$
nextTick
().
then
(()
=>
{
event
=
findEvent
(
STAGE_ACTIONS
.
CREATE
);
expect
(
event
).
toBeTruthy
();
expect
(
event
).
toHaveLength
(
1
);
...
...
@@ -510,7 +538,7 @@ describe('CustomStageForm', () => {
];
wrapper
.
find
(
sel
.
submit
).
trigger
(
'
click
'
);
return
Vue
.
nextTick
().
then
(()
=>
{
return
wrapper
.
vm
.
$
nextTick
().
then
(()
=>
{
event
=
findEvent
(
STAGE_ACTIONS
.
CREATE
);
expect
(
event
[
0
]).
toEqual
(
res
);
});
...
...
@@ -520,7 +548,7 @@ describe('CustomStageForm', () => {
describe
(
'
Cancel button
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createComponent
(
{}
);
wrapper
=
createComponent
();
});
afterEach
(()
=>
{
...
...
@@ -533,7 +561,7 @@ describe('CustomStageForm', () => {
expect
(
btn
.
attributes
(
'
disabled
'
)).
toEqual
(
'
disabled
'
);
wrapper
.
find
(
sel
.
name
).
setValue
(
'
Cool stage
'
);
return
Vue
.
nextTick
().
then
(()
=>
{
return
wrapper
.
vm
.
$
nextTick
().
then
(()
=>
{
expect
(
btn
.
attributes
(
'
disabled
'
)).
toBeUndefined
();
});
});
...
...
@@ -547,11 +575,12 @@ describe('CustomStageForm', () => {
},
});
return
Vue
.
nextTick
()
return
wrapper
.
vm
.
$nextTick
()
.
then
(()
=>
{
wrapper
.
find
(
sel
.
cancel
).
trigger
(
'
click
'
);
return
Vue
.
nextTick
();
return
wrapper
.
vm
.
$
nextTick
();
})
.
then
(()
=>
{
expect
(
wrapper
.
vm
.
fields
).
toEqual
({
...
...
@@ -575,10 +604,11 @@ describe('CustomStageForm', () => {
},
});
return
Vue
.
nextTick
()
return
wrapper
.
vm
.
$nextTick
()
.
then
(()
=>
{
wrapper
.
find
(
sel
.
cancel
).
trigger
(
'
click
'
);
return
Vue
.
nextTick
();
return
wrapper
.
vm
.
$
nextTick
();
})
.
then
(()
=>
{
ev
=
findEvent
(
'
cancel
'
);
...
...
@@ -590,12 +620,12 @@ describe('CustomStageForm', () => {
describe
(
'
isSavingCustomStage=true
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createComponent
(
{
wrapper
=
createComponent
(
{
initialState
:
{
isSavingCustomStage
:
true
,
},
false
,
);
});
return
wrapper
.
vm
.
$nextTick
(
);
});
it
(
'
displays a loading icon
'
,
()
=>
{
...
...
@@ -606,19 +636,13 @@ describe('CustomStageForm', () => {
describe
(
'
Editing a custom stage
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createComponent
({
initialState
:
{
isEditingCustomStage
:
true
,
initialFields
:
{
...
initData
,
formInitialData
,
},
});
wrapper
.
setData
({
fields
:
{
...
initData
,
},
});
return
Vue
.
nextTick
();
return
wrapper
.
vm
.
$nextTick
();
});
afterEach
(()
=>
{
...
...
@@ -635,13 +659,14 @@ describe('CustomStageForm', () => {
},
});
return
Vue
.
nextTick
()
return
wrapper
.
vm
.
$nextTick
()
.
then
(()
=>
{
wrapper
.
find
(
sel
.
cancel
).
trigger
(
'
click
'
);
return
Vue
.
nextTick
();
return
wrapper
.
vm
.
$
nextTick
();
})
.
then
(()
=>
{
expect
(
wrapper
.
vm
.
fields
).
toEqual
({
...
init
Data
});
expect
(
wrapper
.
vm
.
fields
).
toEqual
({
...
formInitial
Data
});
});
});
});
...
...
@@ -662,7 +687,7 @@ describe('CustomStageForm', () => {
},
});
return
Vue
.
nextTick
().
then
(()
=>
{
return
wrapper
.
vm
.
$
nextTick
().
then
(()
=>
{
expect
(
wrapper
.
find
(
sel
.
submit
).
attributes
(
'
disabled
'
)).
toBeUndefined
();
});
});
...
...
@@ -674,7 +699,7 @@ describe('CustomStageForm', () => {
},
});
return
Vue
.
nextTick
().
then
(()
=>
{
return
wrapper
.
vm
.
$
nextTick
().
then
(()
=>
{
expect
(
wrapper
.
find
(
sel
.
submit
).
attributes
(
'
disabled
'
)).
toEqual
(
'
disabled
'
);
});
});
...
...
@@ -689,10 +714,11 @@ describe('CustomStageForm', () => {
},
});
return
Vue
.
nextTick
()
return
wrapper
.
vm
.
$nextTick
()
.
then
(()
=>
{
wrapper
.
find
(
sel
.
submit
).
trigger
(
'
click
'
);
return
Vue
.
nextTick
();
return
wrapper
.
vm
.
$
nextTick
();
})
.
then
(()
=>
{
ev
=
findEvent
(
STAGE_ACTIONS
.
UPDATE
);
...
...
@@ -708,17 +734,18 @@ describe('CustomStageForm', () => {
},
});
return
Vue
.
nextTick
()
return
wrapper
.
vm
.
$nextTick
()
.
then
(()
=>
{
wrapper
.
find
(
sel
.
submit
).
trigger
(
'
click
'
);
return
Vue
.
nextTick
();
return
wrapper
.
vm
.
$
nextTick
();
})
.
then
(()
=>
{
const
submitted
=
findEvent
(
STAGE_ACTIONS
.
UPDATE
)[
0
];
expect
(
submitted
).
not
.
toEqual
([
init
Data
]);
expect
(
submitted
).
not
.
toEqual
([
formInitial
Data
]);
expect
(
submitted
).
toEqual
([
{
id
:
init
Data
.
id
,
id
:
formInitial
Data
.
id
,
start_event_identifier
:
labelStartEvent
.
identifier
,
start_event_label_id
:
groupLabels
[
0
].
id
,
end_event_identifier
:
labelStopEvent
.
identifier
,
...
...
@@ -733,11 +760,10 @@ describe('CustomStageForm', () => {
describe
(
'
isSavingCustomStage=true
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createComponent
({
initialState
:
{
isEditingCustomStage
:
true
,
initialFields
:
{
...
initData
,
},
isSavingCustomStage
:
true
,
},
});
});
it
(
'
displays a loading icon
'
,
()
=>
{
...
...
@@ -749,11 +775,12 @@ describe('CustomStageForm', () => {
describe
(
'
With errors
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createComponent
({
initialFields
:
initData
,
errors
:
customStageFormErrors
,
initialState
:
{
formErrors
:
customStageFormErrors
,
},
});
return
Vue
.
nextTick
();
return
wrapper
.
vm
.
$
nextTick
();
});
afterEach
(()
=>
{
...
...
@@ -775,7 +802,9 @@ describe('CustomStageForm', () => {
};
beforeEach
(()
=>
{
wrapper
=
createComponent
({},
formFieldStubs
);
wrapper
=
createComponent
({
stubs
:
formFieldStubs
,
});
});
describe
(
'
without hidden stages
'
,
()
=>
{
...
...
@@ -795,8 +824,12 @@ describe('CustomStageForm', () => {
describe
(
'
with hidden stages
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createComponent
({},
formFieldStubs
);
store
.
state
.
stages
=
[{
id
:
'
my-stage
'
,
title
:
'
My default stage
'
,
hidden
:
true
}];
wrapper
=
createComponent
({
stubs
:
formFieldStubs
,
initialRootGetters
:
{
hiddenStages
:
()
=>
[{
id
:
'
my-stage
'
,
title
:
'
My default stage
'
,
hidden
:
true
}],
},
});
});
it
(
'
has stages available to recover
'
,
()
=>
{
...
...
@@ -825,26 +858,46 @@ describe('CustomStageForm', () => {
});
describe
(
'
initializeFormData
'
,
()
=>
{
const
emptyFieldState
=
{
id
:
null
,
name
:
null
,
startEventIdentifier
:
null
,
startEventLabelId
:
null
,
endEventIdentifier
:
null
,
endEventLabelId
:
null
,
};
const
emptyErrorsState
=
{
id
:
[],
name
:
[],
startEventIdentifier
:
[],
startEventLabelId
:
[],
endEventIdentifier
:
[],
endEventLabelId
:
[],
};
describe
(
'
without a startEventIdentifier
'
,
()
=>
{
it
(
'
with no errors
'
,
()
=>
{
const
res
=
initializeFormData
({
initialFields
:
{},
emptyFieldState
,
fields
:
{},
});
expect
(
res
.
fields
).
toEqual
(
{}
);
expect
(
res
.
fieldErrors
).
toEqual
({
expect
(
res
.
fields
).
toEqual
(
emptyFieldState
);
expect
(
res
.
errors
).
toMatchObject
({
endEventIdentifier
:
[
'
Please select a start event first
'
],
});
});
it
(
'
with field errors
'
,
()
=>
{
const
res
=
initializeFormData
({
initialFields
:
{},
emptyFieldState
,
fields
:
{},
errors
:
{
name
:
[
'
is reserved
'
],
},
});
expect
(
res
.
fields
).
toEqual
(
{}
);
expect
(
res
.
fieldErrors
).
toEqual
({
expect
(
res
.
fields
).
toEqual
(
emptyFieldState
);
expect
(
res
.
errors
).
toMatchObject
({
endEventIdentifier
:
[
'
Please select a start event first
'
],
name
:
[
'
is reserved
'
],
});
...
...
@@ -854,29 +907,31 @@ describe('CustomStageForm', () => {
describe
(
'
with a startEventIdentifier
'
,
()
=>
{
it
(
'
with no errors
'
,
()
=>
{
const
res
=
initializeFormData
({
initialFields
:
{
emptyFieldState
,
fields
:
{
startEventIdentifier
:
'
start-event
'
,
},
errors
:
{},
});
expect
(
res
.
fields
).
toEqual
({
startEventIdentifier
:
'
start-event
'
});
expect
(
res
.
fieldErrors
).
toEqual
({
endEventIdentifier
:
null
,
expect
(
res
.
fields
).
toEqual
({
...
emptyFieldState
,
startEventIdentifier
:
'
start-event
'
});
expect
(
res
.
errors
).
toMatchObject
({
endEventIdentifier
:
[]
,
});
});
it
(
'
with field errors
'
,
()
=>
{
const
res
=
initializeFormData
({
initialFields
:
{
emptyFieldState
,
fields
:
{
startEventIdentifier
:
'
start-event
'
,
},
errors
:
{
name
:
[
'
is reserved
'
],
},
});
expect
(
res
.
fields
).
toEqual
({
startEventIdentifier
:
'
start-event
'
});
expect
(
res
.
fieldErrors
).
toEqual
({
endEventIdentifier
:
null
,
expect
(
res
.
fields
).
toEqual
({
...
emptyFieldState
,
startEventIdentifier
:
'
start-event
'
});
expect
(
res
.
errors
).
toMatchObject
({
endEventIdentifier
:
[]
,
name
:
[
'
is reserved
'
],
});
});
...
...
@@ -885,7 +940,8 @@ describe('CustomStageForm', () => {
describe
(
'
with all fields set
'
,
()
=>
{
it
(
'
with no errors
'
,
()
=>
{
const
res
=
initializeFormData
({
initialFields
:
{
emptyFieldState
,
fields
:
{
id
:
1
,
name
:
'
cool-stage
'
,
startEventIdentifier
:
'
start-event
'
,
...
...
@@ -903,14 +959,13 @@ describe('CustomStageForm', () => {
startEventLabelId
:
10
,
endEventLabelId
:
20
,
});
expect
(
res
.
fieldErrors
).
toEqual
({
endEventIdentifier
:
null
,
});
expect
(
res
.
errors
).
toEqual
(
emptyErrorsState
);
});
it
(
'
with field errors
'
,
()
=>
{
const
res
=
initializeFormData
({
initialFields
:
{
emptyFieldState
,
fields
:
{
id
:
1
,
name
:
'
cool-stage
'
,
startEventIdentifier
:
'
start-event
'
,
...
...
@@ -922,6 +977,7 @@ describe('CustomStageForm', () => {
name
:
[
'
is reserved
'
],
},
});
expect
(
res
.
fields
).
toEqual
({
id
:
1
,
name
:
'
cool-stage
'
,
...
...
@@ -930,8 +986,7 @@ describe('CustomStageForm', () => {
startEventLabelId
:
10
,
endEventLabelId
:
20
,
});
expect
(
res
.
fieldErrors
).
toEqual
({
endEventIdentifier
:
null
,
expect
(
res
.
errors
).
toMatchObject
({
name
:
[
'
is reserved
'
],
});
});
...
...
This diff is collapsed.
Click to expand it.
ee/spec/frontend/analytics/cycle_analytics/mock_data.js
View file @
817f6d4d
...
...
@@ -130,8 +130,8 @@ export const rawCustomStage = {
export
const
medians
=
stageMedians
;
const
{
events
:
rawCustomStageEvents
}
=
customizableStagesAndE
vents
;
const
camelCasedStageEvents
=
rawCustomStageEvents
.
map
(
deepCamelCase
);
export
const
rawCustomStageEvents
=
customizableStagesAndEvents
.
e
vents
;
export
const
camelCasedStageEvents
=
rawCustomStageEvents
.
map
(
deepCamelCase
);
export
const
customStageLabelEvents
=
camelCasedStageEvents
.
filter
(
ev
=>
ev
.
type
===
'
label
'
);
export
const
customStageStartEvents
=
camelCasedStageEvents
.
filter
(
ev
=>
ev
.
canBeStartEvent
);
...
...
This diff is collapsed.
Click to expand it.
ee/spec/frontend/analytics/cycle_analytics/store/actions_spec.js
View file @
817f6d4d
...
...
@@ -4,8 +4,6 @@ import testAction from 'helpers/vuex_action_helper';
import
*
as
getters
from
'
ee/analytics/cycle_analytics/store/getters
'
;
import
*
as
actions
from
'
ee/analytics/cycle_analytics/store/actions
'
;
import
*
as
types
from
'
ee/analytics/cycle_analytics/store/mutation_types
'
;
import
*
as
customStageActions
from
'
ee/analytics/cycle_analytics/store/modules/custom_stages/actions
'
;
import
*
as
customStageTypes
from
'
ee/analytics/cycle_analytics/store/modules/custom_stages/mutation_types
'
;
import
createFlash
from
'
~/flash
'
;
import
httpStatusCodes
from
'
~/lib/utils/http_status
'
;
import
{
...
...
@@ -684,136 +682,6 @@ describe('Cycle analytics actions', () => {
});
});
describe
(
'
createStage
'
,
()
=>
{
describe
(
'
with valid data
'
,
()
=>
{
const
customStageData
=
{
startEventIdentifier
:
'
start_event
'
,
endEventIdentifier
:
'
end_event
'
,
name
:
'
cool-new-stage
'
,
};
beforeEach
(()
=>
{
state
=
{
...
state
,
selectedGroup
};
mock
.
onPost
(
endpoints
.
baseStagesEndpointstageData
).
reply
(
201
,
customStageData
);
});
it
(
`dispatches the 'receiveCreateStageSuccess' action`
,
()
=>
testAction
(
customStageActions
.
createStage
,
customStageData
,
state
,
[],
[
{
type
:
'
clearFormErrors
'
},
{
type
:
'
setSavingCustomStage
'
},
{
type
:
'
receiveCreateStageSuccess
'
,
payload
:
{
data
:
customStageData
,
status
:
201
},
},
],
));
});
describe
(
'
with errors
'
,
()
=>
{
const
message
=
'
failed
'
;
const
errors
=
{
endEventIdentifier
:
[
'
Cant be blank
'
],
};
const
customStageData
=
{
startEventIdentifier
:
'
start_event
'
,
endEventIdentifier
:
''
,
name
:
'
cool-new-stage
'
,
};
beforeEach
(()
=>
{
state
=
{
...
state
,
selectedGroup
};
mock
.
onPost
(
endpoints
.
baseStagesEndpointstageData
)
.
reply
(
httpStatusCodes
.
UNPROCESSABLE_ENTITY
,
{
message
,
errors
,
});
});
it
(
`dispatches the 'receiveCreateStageError' action`
,
()
=>
testAction
(
customStageActions
.
createStage
,
customStageData
,
state
,
[],
[
{
type
:
'
clearFormErrors
'
},
{
type
:
'
setSavingCustomStage
'
},
{
type
:
'
receiveCreateStageError
'
,
payload
:
{
data
:
customStageData
,
errors
,
message
,
status
:
httpStatusCodes
.
UNPROCESSABLE_ENTITY
,
},
},
],
));
});
});
describe
(
'
receiveCreateStageError
'
,
()
=>
{
const
response
=
{
data
:
{
name
:
'
uh oh
'
},
};
beforeEach
(()
=>
{});
it
(
'
will commit the RECEIVE_CREATE_STAGE_ERROR mutation
'
,
()
=>
testAction
(
customStageActions
.
receiveCreateStageError
,
response
,
state
,
[{
type
:
customStageTypes
.
RECEIVE_CREATE_STAGE_ERROR
}],
[
{
type
:
'
setStageFormErrors
'
,
payload
:
{},
},
],
));
it
(
'
will flash an error message
'
,
()
=>
{
return
customStageActions
.
receiveCreateStageError
(
{
dispatch
:
()
=>
Promise
.
resolve
(),
commit
:
()
=>
{},
},
response
,
)
.
then
(()
=>
{
shouldFlashAMessage
(
'
There was a problem saving your custom stage, please try again
'
);
});
});
describe
(
'
with a stage name error
'
,
()
=>
{
it
(
'
will flash an error message
'
,
()
=>
{
return
customStageActions
.
receiveCreateStageError
(
{
dispatch
:
()
=>
Promise
.
resolve
(),
commit
:
()
=>
{},
},
{
...
response
,
status
:
httpStatusCodes
.
UNPROCESSABLE_ENTITY
,
errors
:
{
name
:
[
'
is reserved
'
]
},
},
)
.
then
(()
=>
{
shouldFlashAMessage
(
"
'uh oh' stage already exists
"
);
});
});
});
});
describe
(
'
initializeCycleAnalytics
'
,
()
=>
{
let
mockDispatch
;
let
mockCommit
;
...
...
@@ -873,38 +741,6 @@ describe('Cycle analytics actions', () => {
));
});
describe
(
'
receiveCreateStageSuccess
'
,
()
=>
{
const
response
=
{
data
:
{
title
:
'
COOL
'
,
},
};
it
(
'
will dispatch fetchGroupStagesAndEvents
'
,
()
=>
testAction
(
customStageActions
.
receiveCreateStageSuccess
,
response
,
state
,
[{
type
:
customStageTypes
.
RECEIVE_CREATE_STAGE_SUCCESS
}],
[{
type
:
'
fetchGroupStagesAndEvents
'
,
payload
:
null
},
{
type
:
'
clearSavingCustomStage
'
}],
));
describe
(
'
with an error
'
,
()
=>
{
it
(
'
will flash an error message
'
,
()
=>
customStageActions
.
receiveCreateStageSuccess
(
{
dispatch
:
()
=>
Promise
.
reject
(),
commit
:
()
=>
{},
},
response
,
)
.
then
(()
=>
{
shouldFlashAMessage
(
'
There was a problem refreshing the data, please try again
'
);
}));
});
});
describe
(
'
reorderStage
'
,
()
=>
{
const
stageId
=
'
cool-stage
'
;
const
payload
=
{
id
:
stageId
,
move_after_id
:
'
2
'
,
move_before_id
:
'
8
'
};
...
...
This diff is collapsed.
Click to expand it.
ee/spec/frontend/analytics/cycle_analytics/store/modules/custom_stages/actions_spec.js
0 → 100644
View file @
817f6d4d
import
axios
from
'
axios
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
testAction
from
'
helpers/vuex_action_helper
'
;
import
*
as
actions
from
'
ee/analytics/cycle_analytics/store/modules/custom_stages/actions
'
;
import
*
as
types
from
'
ee/analytics/cycle_analytics/store/modules/custom_stages/mutation_types
'
;
import
createFlash
from
'
~/flash
'
;
import
httpStatusCodes
from
'
~/lib/utils/http_status
'
;
import
{
selectedGroup
,
endpoints
,
rawCustomStage
}
from
'
../../../mock_data
'
;
jest
.
mock
(
'
~/flash
'
);
describe
(
'
Custom stage actions
'
,
()
=>
{
let
state
;
let
mock
;
const
selectedStage
=
rawCustomStage
;
const
shouldFlashAMessage
=
(
msg
,
type
=
null
)
=>
{
const
args
=
type
?
[
msg
,
type
]
:
[
msg
];
expect
(
createFlash
).
toHaveBeenCalledWith
(...
args
);
};
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
state
=
{
selectedGroup
:
null
};
});
describe
(
'
createStage
'
,
()
=>
{
describe
(
'
with valid data
'
,
()
=>
{
const
customStageData
=
{
startEventIdentifier
:
'
start_event
'
,
endEventIdentifier
:
'
end_event
'
,
name
:
'
cool-new-stage
'
,
};
beforeEach
(()
=>
{
state
=
{
...
state
,
selectedGroup
};
mock
.
onPost
(
endpoints
.
baseStagesEndpointstageData
).
reply
(
201
,
customStageData
);
});
it
(
`dispatches the 'receiveCreateStageSuccess' action`
,
()
=>
testAction
(
actions
.
createStage
,
customStageData
,
state
,
[],
[
{
type
:
'
clearFormErrors
'
},
{
type
:
'
setSavingCustomStage
'
},
{
type
:
'
receiveCreateStageSuccess
'
,
payload
:
{
data
:
customStageData
,
status
:
201
},
},
],
));
});
describe
(
'
with errors
'
,
()
=>
{
const
message
=
'
failed
'
;
const
errors
=
{
endEventIdentifier
:
[
'
Cant be blank
'
],
};
const
customStageData
=
{
startEventIdentifier
:
'
start_event
'
,
endEventIdentifier
:
''
,
name
:
'
cool-new-stage
'
,
};
beforeEach
(()
=>
{
state
=
{
...
state
,
selectedGroup
};
mock
.
onPost
(
endpoints
.
baseStagesEndpointstageData
)
.
reply
(
httpStatusCodes
.
UNPROCESSABLE_ENTITY
,
{
message
,
errors
,
});
});
it
(
`dispatches the 'receiveCreateStageError' action`
,
()
=>
testAction
(
actions
.
createStage
,
customStageData
,
state
,
[],
[
{
type
:
'
clearFormErrors
'
},
{
type
:
'
setSavingCustomStage
'
},
{
type
:
'
receiveCreateStageError
'
,
payload
:
{
data
:
customStageData
,
errors
,
message
,
status
:
httpStatusCodes
.
UNPROCESSABLE_ENTITY
,
},
},
],
));
});
});
describe
(
'
receiveCreateStageError
'
,
()
=>
{
const
response
=
{
data
:
{
name
:
'
uh oh
'
},
};
beforeEach
(()
=>
{});
it
(
'
will commit the RECEIVE_CREATE_STAGE_ERROR mutation
'
,
()
=>
testAction
(
actions
.
receiveCreateStageError
,
response
,
state
,
[{
type
:
types
.
RECEIVE_CREATE_STAGE_ERROR
}],
[{
type
:
'
setStageFormErrors
'
,
payload
:
{}
}],
));
it
(
'
will flash an error message
'
,
()
=>
{
return
actions
.
receiveCreateStageError
(
{
dispatch
:
()
=>
Promise
.
resolve
(),
commit
:
()
=>
{},
},
response
,
)
.
then
(()
=>
{
shouldFlashAMessage
(
'
There was a problem saving your custom stage, please try again
'
);
});
});
describe
(
'
with a stage name error
'
,
()
=>
{
it
(
'
will flash an error message
'
,
()
=>
{
return
actions
.
receiveCreateStageError
(
{
dispatch
:
()
=>
Promise
.
resolve
(),
commit
:
()
=>
{},
},
{
...
response
,
status
:
httpStatusCodes
.
UNPROCESSABLE_ENTITY
,
errors
:
{
name
:
[
'
is reserved
'
]
},
},
)
.
then
(()
=>
{
shouldFlashAMessage
(
"
'uh oh' stage already exists
"
);
});
});
});
});
describe
(
'
receiveCreateStageSuccess
'
,
()
=>
{
const
response
=
{
data
:
{
title
:
'
COOL
'
,
},
};
it
(
'
will dispatch fetchGroupStagesAndEvents
'
,
()
=>
testAction
(
actions
.
receiveCreateStageSuccess
,
response
,
state
,
[{
type
:
types
.
RECEIVE_CREATE_STAGE_SUCCESS
}],
[{
type
:
'
fetchGroupStagesAndEvents
'
,
payload
:
null
},
{
type
:
'
clearSavingCustomStage
'
}],
));
describe
(
'
with an error
'
,
()
=>
{
it
(
'
will flash an error message
'
,
()
=>
actions
.
receiveCreateStageSuccess
(
{
dispatch
:
()
=>
Promise
.
reject
(),
commit
:
()
=>
{},
},
response
,
)
.
then
(()
=>
{
shouldFlashAMessage
(
'
There was a problem refreshing the data, please try again
'
);
}));
});
});
describe
(
'
setStageFormErrors
'
,
()
=>
{
it
(
'
commits the "SET_STAGE_FORM_ERRORS" mutation
'
,
()
=>
{
return
testAction
(
actions
.
setStageFormErrors
,
[],
state
,
[{
type
:
types
.
SET_STAGE_FORM_ERRORS
,
payload
:
[]
}],
[],
);
});
});
describe
(
'
clearFormErrors
'
,
()
=>
{
it
(
'
commits the "CLEAR_FORM_ERRORS" mutation
'
,
()
=>
{
return
testAction
(
actions
.
clearFormErrors
,
[],
state
,
[{
type
:
types
.
CLEAR_FORM_ERRORS
}],
[],
);
});
});
describe
(
'
setStageEvents
'
,
()
=>
{
it
(
'
commits the "SET_STAGE_EVENTS" mutation
'
,
()
=>
{
return
testAction
(
actions
.
setStageEvents
,
[],
state
,
[{
type
:
types
.
SET_STAGE_EVENTS
,
payload
:
[]
}],
[],
);
});
});
describe
(
'
hideForm
'
,
()
=>
{
it
(
'
commits the "HIDE_FORM" mutation
'
,
()
=>
{
return
testAction
(
actions
.
hideForm
,
null
,
state
,
[{
type
:
types
.
HIDE_FORM
}],
[]);
});
});
describe
(
'
showCreateForm
'
,
()
=>
{
it
(
'
commits the "SHOW_CREATE_FORM" mutation
'
,
()
=>
{
return
testAction
(
actions
.
showCreateForm
,
null
,
state
,
[
{
type
:
types
.
SET_LOADING
},
{
type
:
types
.
SET_FORM_INITIAL_DATA
},
{
type
:
types
.
SHOW_CREATE_FORM
},
],
[],
);
});
});
describe
(
'
showEditForm
'
,
()
=>
{
it
(
'
commits the "SHOW_EDIT_FORM" mutation with initial data
'
,
()
=>
{
return
testAction
(
actions
.
showEditForm
,
selectedStage
,
state
,
[
{
type
:
types
.
SET_LOADING
},
{
type
:
types
.
SET_FORM_INITIAL_DATA
,
payload
:
rawCustomStage
},
{
type
:
types
.
SHOW_EDIT_FORM
},
],
[{
type
:
'
setSelectedStage
'
,
payload
:
rawCustomStage
},
{
type
:
'
clearSavingCustomStage
'
}],
);
});
});
});
This diff is collapsed.
Click to expand it.
ee/spec/frontend/analytics/cycle_analytics/store/modules/custom_stages/getters_spec.js
0 → 100644
View file @
817f6d4d
import
*
as
getters
from
'
ee/analytics/cycle_analytics/store/modules/custom_stages/getters
'
;
describe
(
'
Custom stages getters
'
,
()
=>
{
describe
.
each
`
state | result
${{
isCreatingCustomStage
:
true
,
isEditingCustomStage
:
true
}
} |
${
true
}
${{
isCreatingCustomStage
:
false
,
isEditingCustomStage
:
true
}
} |
${
true
}
${{
isCreatingCustomStage
:
true
,
isEditingCustomStage
:
false
}
} |
${
true
}
${{
isCreatingCustomStage
:
false
,
isEditingCustomStage
:
false
}
} |
${
false
}
`
(
'
customStageFormActive
'
,
({
state
,
result
})
=>
{
it
(
`with state
${
state
}
returns
${
result
}
`
,
()
=>
{
expect
(
getters
.
customStageFormActive
(
state
)).
toEqual
(
result
);
});
});
});
This diff is collapsed.
Click to expand it.
ee/spec/frontend/analytics/cycle_analytics/store/modules/custom_stages/mutations_spec.js
0 → 100644
View file @
817f6d4d
import
mutations
from
'
ee/analytics/cycle_analytics/store/modules/custom_stages/mutations
'
;
import
*
as
types
from
'
ee/analytics/cycle_analytics/store/modules/custom_stages/mutation_types
'
;
import
{
convertObjectPropsToCamelCase
}
from
'
~/lib/utils/common_utils
'
;
import
{
rawCustomStageEvents
,
camelCasedStageEvents
,
rawCustomStage
}
from
'
../../../mock_data
'
;
let
state
=
null
;
describe
(
'
Custom stage mutations
'
,
()
=>
{
beforeEach
(()
=>
{
state
=
{};
});
afterEach
(()
=>
{
state
=
null
;
});
it
.
each
`
mutation | stateKey | value
${
types
.
HIDE_FORM
}
|
${
'
isCreatingCustomStage
'
}
|
${
false
}
${
types
.
HIDE_FORM
}
|
${
'
isEditingCustomStage
'
}
|
${
false
}
${
types
.
HIDE_FORM
}
|
${
'
formErrors
'
}
|
${
null
}
${
types
.
HIDE_FORM
}
|
${
'
formInitialData
'
}
|
${
null
}
${
types
.
CLEAR_FORM_ERRORS
}
|
${
'
formErrors
'
}
|
${
null
}
${
types
.
SHOW_CREATE_FORM
}
|
${
'
isCreatingCustomStage
'
}
|
${
true
}
${
types
.
SHOW_CREATE_FORM
}
|
${
'
isEditingCustomStage
'
}
|
${
false
}
${
types
.
SHOW_CREATE_FORM
}
|
${
'
formErrors
'
}
|
${
null
}
${
types
.
SHOW_CREATE_FORM
}
|
${
'
formInitialData
'
}
|
${
null
}
${
types
.
SHOW_EDIT_FORM
}
|
${
'
isEditingCustomStage
'
}
|
${
true
}
${
types
.
SHOW_EDIT_FORM
}
|
${
'
isCreatingCustomStage
'
}
|
${
false
}
${
types
.
SHOW_EDIT_FORM
}
|
${
'
formErrors
'
}
|
${
null
}
${
types
.
RECEIVE_CREATE_STAGE_SUCCESS
}
|
${
'
formErrors
'
}
|
${
null
}
${
types
.
RECEIVE_CREATE_STAGE_SUCCESS
}
|
${
'
formInitialData
'
}
|
${
null
}
${
types
.
RECEIVE_CREATE_STAGE_ERROR
}
|
${
'
isSavingCustomStage
'
}
|
${
false
}
${
types
.
SET_SAVING_CUSTOM_STAGE
}
|
${
'
isSavingCustomStage
'
}
|
${
true
}
${
types
.
CLEAR_SAVING_CUSTOM_STAGE
}
|
${
'
isSavingCustomStage
'
}
|
${
false
}
${
types
.
SET_LOADING
}
|
${
'
isLoadingCustomStage
'
}
|
${
true
}
`
(
'
$mutation will set $stateKey=$value
'
,
({
mutation
,
stateKey
,
value
})
=>
{
mutations
[
mutation
](
state
);
expect
(
state
[
stateKey
]).
toEqual
(
value
);
});
describe
(
`
${
types
.
SET_STAGE_EVENTS
}
`
,
()
=>
{
it
(
'
will set formEvents
'
,
()
=>
{
state
=
{};
mutations
[
types
.
SET_STAGE_EVENTS
](
state
,
rawCustomStageEvents
);
expect
(
state
.
formEvents
).
toEqual
(
camelCasedStageEvents
);
});
});
describe
(
`
${
types
.
SET_STAGE_FORM_ERRORS
}
`
,
()
=>
{
const
mockFormError
=
{
start_identifier
:
[
'
Cant be blank
'
]
};
it
(
'
will set formErrors
'
,
()
=>
{
state
=
{};
mutations
[
types
.
SET_STAGE_FORM_ERRORS
](
state
,
mockFormError
);
expect
(
state
.
formErrors
).
toEqual
(
convertObjectPropsToCamelCase
(
mockFormError
));
});
});
describe
(
`
${
types
.
SET_FORM_INITIAL_DATA
}
`
,
()
=>
{
const
mockStage
=
{
endEventIdentifier
:
'
issue_first_added_to_board
'
,
endEventLabelId
:
null
,
id
:
18
,
name
:
'
Coolest beans stage
'
,
startEventIdentifier
:
'
issue_first_mentioned_in_commit
'
,
startEventLabelId
:
null
,
};
it
(
'
will set formInitialData
'
,
()
=>
{
state
=
{};
mutations
[
types
.
SET_FORM_INITIAL_DATA
](
state
,
rawCustomStage
);
expect
(
state
.
formInitialData
).
toEqual
(
mockStage
);
});
});
});
This diff is collapsed.
Click to expand it.
ee/spec/frontend/analytics/cycle_analytics/store/mutations_spec.js
View file @
817f6d4d
import
mutations
from
'
ee/analytics/cycle_analytics/store/mutations
'
;
import
*
as
types
from
'
ee/analytics/cycle_analytics/store/mutation_types
'
;
import
customStageMutations
from
'
ee/analytics/cycle_analytics/store/modules/custom_stages/mutations
'
;
import
*
as
customStageTypes
from
'
ee/analytics/cycle_analytics/store/modules/custom_stages/mutation_types
'
;
import
{
convertObjectPropsToCamelCase
}
from
'
~/lib/utils/common_utils
'
;
import
{
issueStage
,
...
...
@@ -13,9 +10,8 @@ import {
totalStage
,
startDate
,
endDate
,
customizableStagesAndEvents
,
selectedProjects
,
rawCustomStage
,
customizableStagesAndEvents
,
}
from
'
../mock_data
'
;
let
state
=
null
;
...
...
@@ -70,65 +66,6 @@ describe('Cycle analytics mutations', () => {
},
);
describe
(
'
Custom stage mutations
'
,
()
=>
{
beforeEach
(()
=>
{
state
=
{};
});
afterEach
(()
=>
{
state
=
null
;
});
it
.
each
`
mutation | stateKey | value
${
customStageTypes
.
HIDE_FORM
}
|
${
'
isCreatingCustomStage
'
}
|
${
false
}
${
customStageTypes
.
HIDE_FORM
}
|
${
'
isEditingCustomStage
'
}
|
${
false
}
${
customStageTypes
.
HIDE_FORM
}
|
${
'
formErrors
'
}
|
${
null
}
${
customStageTypes
.
HIDE_FORM
}
|
${
'
formInitialData
'
}
|
${
null
}
${
customStageTypes
.
SHOW_CREATE_FORM
}
|
${
'
isCreatingCustomStage
'
}
|
${
true
}
${
customStageTypes
.
SHOW_CREATE_FORM
}
|
${
'
isEditingCustomStage
'
}
|
${
false
}
${
customStageTypes
.
SHOW_CREATE_FORM
}
|
${
'
formErrors
'
}
|
${
null
}
${
customStageTypes
.
SHOW_EDIT_FORM
}
|
${
'
isEditingCustomStage
'
}
|
${
true
}
${
customStageTypes
.
SHOW_EDIT_FORM
}
|
${
'
isCreatingCustomStage
'
}
|
${
false
}
${
customStageTypes
.
SHOW_EDIT_FORM
}
|
${
'
formErrors
'
}
|
${
null
}
${
customStageTypes
.
RECEIVE_CREATE_STAGE_ERROR
}
|
${
'
isSavingCustomStage
'
}
|
${
false
}
${
customStageTypes
.
SET_SAVING_CUSTOM_STAGE
}
|
${
'
isSavingCustomStage
'
}
|
${
true
}
${
customStageTypes
.
CLEAR_SAVING_CUSTOM_STAGE
}
|
${
'
isSavingCustomStage
'
}
|
${
false
}
`
(
'
$mutation will set $stateKey=$value
'
,
({
mutation
,
stateKey
,
value
})
=>
{
customStageMutations
[
mutation
](
state
);
expect
(
state
[
stateKey
]).
toEqual
(
value
);
});
describe
(
`
${
customStageTypes
.
SET_STAGE_FORM_ERRORS
}
`
,
()
=>
{
const
mockFormError
=
{
start_identifier
:
[
'
Cant be blank
'
]
};
it
(
'
will set formErrors
'
,
()
=>
{
state
=
{};
customStageMutations
[
customStageTypes
.
SET_STAGE_FORM_ERRORS
](
state
,
mockFormError
);
expect
(
state
.
formErrors
).
toEqual
(
convertObjectPropsToCamelCase
(
mockFormError
));
});
});
describe
(
`
${
customStageTypes
.
SET_FORM_INITIAL_DATA
}
`
,
()
=>
{
const
mockStage
=
{
id
:
18
,
name
:
'
Coolest beans stage
'
,
startEventIdentifier
:
'
issue_first_mentioned_in_commit
'
,
startEventLabelId
:
null
,
endEventIdentifier
:
'
issue_first_added_to_board
'
,
endEventLabelId
:
null
,
};
it
(
'
will set formInitialData
'
,
()
=>
{
state
=
{};
customStageMutations
[
customStageTypes
.
SET_FORM_INITIAL_DATA
](
state
,
rawCustomStage
);
expect
(
state
.
formInitialData
).
toEqual
(
mockStage
);
});
});
});
describe
(
`
${
types
.
RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS
}
`
,
()
=>
{
it
(
'
will set isLoading=false and errorCode=null
'
,
()
=>
{
mutations
[
types
.
RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS
](
state
,
{
...
...
This diff is collapsed.
Click to expand it.
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