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
ec5f9c24
Commit
ec5f9c24
authored
May 11, 2021
by
Ezekiel Kigbo
Committed by
Luke Duncalfe
May 11, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove `value_stream_analytics_path_navigation` feature flag
https://gitlab.com/gitlab-org/gitlab/-/issues/323982
parent
1622d29a
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
93 additions
and
921 deletions
+93
-921
doc/user/group/value_stream_analytics/index.md
doc/user/group/value_stream_analytics/index.md
+1
-11
ee/app/assets/javascripts/analytics/cycle_analytics/components/base.vue
...javascripts/analytics/cycle_analytics/components/base.vue
+21
-87
ee/app/assets/javascripts/analytics/cycle_analytics/index.js
ee/app/assets/javascripts/analytics/cycle_analytics/index.js
+2
-5
ee/app/assets/javascripts/analytics/cycle_analytics/store/actions.js
...ts/javascripts/analytics/cycle_analytics/store/actions.js
+3
-32
ee/app/assets/javascripts/analytics/cycle_analytics/store/mutations.js
.../javascripts/analytics/cycle_analytics/store/mutations.js
+1
-11
ee/app/controllers/groups/analytics/cycle_analytics_controller.rb
...ontrollers/groups/analytics/cycle_analytics_controller.rb
+0
-1
ee/changelogs/unreleased/323982-remove-enable-value-stream-analytics-horizontal-navigation-ff.yml
...nable-value-stream-analytics-horizontal-navigation-ff.yml
+5
-0
ee/config/feature_flags/development/value_stream_analytics_path_navigation.yml
...gs/development/value_stream_analytics_path_navigation.yml
+0
-8
ee/spec/features/groups/analytics/cycle_analytics/charts_spec.rb
.../features/groups/analytics/cycle_analytics/charts_spec.rb
+0
-31
ee/spec/features/groups/analytics/cycle_analytics/customizable_cycle_analytics_spec.rb
...tics/cycle_analytics/customizable_cycle_analytics_spec.rb
+0
-285
ee/spec/features/groups/analytics/cycle_analytics/cycle_analytics_spec.rb
.../groups/analytics/cycle_analytics/cycle_analytics_spec.rb
+1
-16
ee/spec/features/groups/analytics/cycle_analytics/filters_and_data_spec.rb
...groups/analytics/cycle_analytics/filters_and_data_spec.rb
+0
-38
ee/spec/frontend/analytics/cycle_analytics/components/base_spec.js
...rontend/analytics/cycle_analytics/components/base_spec.js
+29
-232
ee/spec/frontend/analytics/cycle_analytics/store/actions_spec.js
.../frontend/analytics/cycle_analytics/store/actions_spec.js
+20
-129
ee/spec/frontend/analytics/cycle_analytics/store/mutations_spec.js
...rontend/analytics/cycle_analytics/store/mutations_spec.js
+10
-29
locale/gitlab.pot
locale/gitlab.pot
+0
-6
No files found.
doc/user/group/value_stream_analytics/index.md
View file @
ec5f9c24
...
...
@@ -189,9 +189,7 @@ GitLab allows users to create multiple value streams, hide default stages and cr
### Stage path
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/210315) in GitLab 13.0.
> - It's [deployed behind a feature flag](../../feature_flags.md), enabled by default.
> - It's enabled on GitLab.com.
> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](../../../administration/feature_flags.md). **(FREE SELF)**
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/323982) in GitLab 13.12.
![
Value stream path navigation
](
img/vsa_path_nav_v13_11.png
"Value stream path navigation"
)
...
...
@@ -213,14 +211,6 @@ Hovering over a stage item displays a popover with the following information:
-
Start event description for the given stage
-
End event description
Horizontal path navigation is enabled by default. If you have a self-managed instance, an
administrator can
[
open a Rails console
](
../../../administration/troubleshooting/navigating_gitlab_via_rails_console.md
)
and disable it with the following command:
```
ruby
Feature
.
disable
(
:value_stream_analytics_path_navigation
)
```
### Adding a stage
In the following example we're creating a new stage that measures and tracks issues from creation
...
...
ee/app/assets/javascripts/analytics/cycle_analytics/components/base.vue
View file @
ec5f9c24
...
...
@@ -7,13 +7,10 @@ import ProjectsDropdownFilter from '../../shared/components/projects_dropdown_fi
import
{
DATE_RANGE_LIMIT
}
from
'
../../shared/constants
'
;
import
{
toYmd
}
from
'
../../shared/utils
'
;
import
{
PROJECTS_PER_PAGE
,
OVERVIEW_STAGE_ID
}
from
'
../constants
'
;
import
CustomStageForm
from
'
./custom_stage_form.vue
'
;
import
DurationChart
from
'
./duration_chart.vue
'
;
import
FilterBar
from
'
./filter_bar.vue
'
;
import
Metrics
from
'
./metrics.vue
'
;
import
PathNavigation
from
'
./path_navigation.vue
'
;
import
StageTable
from
'
./stage_table.vue
'
;
import
StageTableNav
from
'
./stage_table_nav.vue
'
;
import
StageTableNew
from
'
./stage_table_new.vue
'
;
import
TypeOfWorkCharts
from
'
./type_of_work_charts.vue
'
;
import
ValueStreamSelect
from
'
./value_stream_select.vue
'
;
...
...
@@ -25,10 +22,7 @@ export default {
DurationChart
,
GlEmptyState
,
ProjectsDropdownFilter
,
StageTable
,
TypeOfWorkCharts
,
CustomStageForm
,
StageTableNav
,
StageTableNew
,
PathNavigation
,
FilterBar
,
...
...
@@ -89,31 +83,14 @@ export default {
return
!
this
.
currentGroup
&&
!
this
.
isLoading
;
},
shouldDisplayFilters
()
{
return
!
this
.
errorCode
;
return
!
this
.
errorCode
&&
!
this
.
hasNoAccessError
;
},
shouldDisplayDurationChart
()
{
return
(
!
this
.
featureFlags
.
hasPathNavigation
||
(
this
.
featureFlags
.
hasDurationChart
&&
this
.
isOverviewStageSelected
&&
!
this
.
hasNoAccessError
)
);
},
shouldDisplayTypeOfWorkCharts
()
{
return
(
!
this
.
featureFlags
.
hasPathNavigation
||
(
this
.
isOverviewStageSelected
&&
!
this
.
hasNoAccessError
)
);
return
this
.
featureFlags
.
hasDurationChart
;
},
selectedStageReady
()
{
return
!
this
.
hasNoAccessError
&&
this
.
selectedStage
;
},
shouldDisplayPathNavigation
()
{
return
this
.
featureFlags
.
hasPathNavigation
&&
this
.
selectedStageReady
;
},
shouldDisplayVerticalNavigation
()
{
return
!
this
.
featureFlags
.
hasPathNavigation
&&
this
.
selectedStageReady
;
},
shouldDisplayCreateMultipleValueStreams
()
{
return
Boolean
(
!
this
.
shouldRenderEmptyState
&&
!
this
.
isLoadingValueStreams
);
},
...
...
@@ -122,12 +99,6 @@ export default {
},
query
()
{
const
selectedProjectIds
=
this
.
selectedProjectIds
?.
length
?
this
.
selectedProjectIds
:
null
;
const
stageParams
=
this
.
featureFlags
.
hasPathNavigation
?
{
sort
:
(
!
this
.
isOverviewStageSelected
&&
this
.
pagination
?.
sort
)
||
null
,
direction
:
(
!
this
.
isOverviewStageSelected
&&
this
.
pagination
?.
direction
)
||
null
,
}
:
{};
return
{
value_stream_id
:
this
.
selectedValueStream
?.
id
||
null
,
...
...
@@ -135,7 +106,8 @@ export default {
created_after
:
toYmd
(
this
.
startDate
),
created_before
:
toYmd
(
this
.
endDate
),
stage_id
:
(
!
this
.
isOverviewStageSelected
&&
this
.
selectedStage
?.
id
)
||
null
,
// the `overview` stage is always the default, so dont persist the id if its selected
...
stageParams
,
sort
:
(
!
this
.
isOverviewStageSelected
&&
this
.
pagination
?.
sort
)
||
null
,
direction
:
(
!
this
.
isOverviewStageSelected
&&
this
.
pagination
?.
direction
)
||
null
,
};
},
stageCount
()
{
...
...
@@ -224,7 +196,7 @@ export default {
/>
<div
v-if=
"!shouldRenderEmptyState"
class=
"gl-max-w-full"
>
<path-navigation
v-if=
"s
houldDisplayPathNavigation
"
v-if=
"s
electedStageReady
"
:key=
"`path_navigation_key_$
{pathNavigationData.length}`"
class="js-path-navigation gl-w-full gl-pb-2"
:loading="isLoading"
...
...
@@ -276,14 +248,17 @@ export default {
"
/>
<template
v-else
>
<metrics
v-if=
"!featureFlags.hasPathNavigation || isOverviewStageSelected"
:group-path=
"currentGroupPath"
:request-params=
"cycleAnalyticsRequestParams"
<template
v-if=
"isOverviewStageSelected"
>
<metrics
:group-path=
"currentGroupPath"
:request-params=
"cycleAnalyticsRequestParams"
/>
<duration-chart
v-if=
"shouldDisplayDurationChart"
class=
"gl-mt-3"
:stages=
"activeStages"
/>
<template
v-if=
"featureFlags.hasPathNavigation"
>
<type-of-work-charts
/>
</
template
>
<stage-table-new
v-if=
"!isLoading && !isOverviewStageSelected"
v-else
:is-loading=
"isLoading || isLoadingStage"
:stage-events=
"currentStageEvents"
:selected-stage=
"selectedStage"
...
...
@@ -292,49 +267,8 @@ export default {
:pagination=
"pagination"
@
handleUpdatePagination=
"onHandleUpdatePagination"
/>
<url-sync
v-if=
"selectedStageReady"
:query=
"query"
/>
</template>
<stage-table
v-else
:key=
"stageCount"
class=
"js-stage-table"
:current-stage=
"selectedStage"
:is-loading=
"isLoading"
:is-loading-stage=
"isLoadingStage"
:is-empty-stage=
"isEmptyStage"
:custom-stage-form-active=
"customStageFormActive"
:current-stage-events=
"currentStageEvents"
:no-data-svg-path=
"noDataSvgPath"
:empty-state-message=
"selectedStageError"
:has-path-navigation=
"featureFlags.hasPathNavigation"
>
<
template
v-if=
"shouldDisplayVerticalNavigation"
#nav
>
<stage-table-nav
:current-stage=
"selectedStage"
:stages=
"activeStages"
:medians=
"medians"
:is-creating-custom-stage=
"isCreatingCustomStage"
:custom-ordering=
"enableCustomOrdering"
@
reorderStage=
"onStageReorder"
@
selectStage=
"onStageSelect"
@
editStage=
"onShowEditStageForm"
@
showAddStageForm=
"onShowAddStageForm"
@
hideStage=
"onUpdateCustomStage"
@
removeStage=
"onRemoveStage"
/>
</
template
>
<
template
v-if=
"customStageFormActive"
#content
>
<custom-stage-form
:events=
"formEvents"
@
createStage=
"onCreateCustomStage"
@
updateStage=
"onUpdateCustomStage"
@
clearErrors=
"$emit('clear-form-errors')"
/>
</
template
>
</stage-table>
<url-sync
:query=
"query"
/>
</template>
<duration-chart
v-if=
"shouldDisplayDurationChart"
class=
"gl-mt-3"
:stages=
"activeStages"
/>
<type-of-work-charts
v-if=
"shouldDisplayTypeOfWorkCharts"
/>
</div>
</div>
</template>
ee/app/assets/javascripts/analytics/cycle_analytics/index.js
View file @
ec5f9c24
...
...
@@ -19,10 +19,7 @@ export default () => {
const
{
emptyStateSvgPath
,
noDataSvgPath
,
noAccessSvgPath
}
=
el
.
dataset
;
const
initialData
=
buildCycleAnalyticsInitialData
(
el
.
dataset
);
const
store
=
createStore
();
const
{
cycleAnalyticsScatterplotEnabled
:
hasDurationChart
=
false
,
valueStreamAnalyticsPathNavigation
:
hasPathNavigation
=
false
,
}
=
gon
?.
features
;
const
{
cycleAnalyticsScatterplotEnabled
:
hasDurationChart
=
false
}
=
gon
?.
features
;
const
{
author_username
=
null
,
...
...
@@ -39,7 +36,7 @@ export default () => {
selectedMilestone
:
milestone_title
,
selectedAssigneeList
:
assignee_username
,
selectedLabelList
:
label_name
,
featureFlags
:
{
hasDurationChart
,
hasPathNavigation
},
featureFlags
:
{
hasDurationChart
},
pagination
:
{
sort
:
sort
?.
value
||
null
,
direction
:
direction
?.
value
||
null
},
});
...
...
ee/app/assets/javascripts/analytics/cycle_analytics/store/actions.js
View file @
ec5f9c24
...
...
@@ -172,41 +172,12 @@ export const receiveGroupStagesError = ({ commit }, error) => {
});
};
export
const
setDefaultSelectedStage
=
({
state
:
{
featureFlags
},
dispatch
,
getters
})
=>
{
const
{
activeStages
=
[]
}
=
getters
;
export
const
setDefaultSelectedStage
=
({
dispatch
})
=>
dispatch
(
'
setSelectedStage
'
,
OVERVIEW_STAGE_CONFIG
)
;
if
(
featureFlags
?.
hasPathNavigation
)
{
return
dispatch
(
'
setSelectedStage
'
,
OVERVIEW_STAGE_CONFIG
);
}
if
(
activeStages
?.
length
)
{
const
[
firstActiveStage
]
=
activeStages
;
return
Promise
.
all
([
dispatch
(
'
setSelectedStage
'
,
firstActiveStage
),
dispatch
(
'
fetchStageData
'
,
firstActiveStage
.
slug
),
]);
}
createFlash
({
message
:
__
(
'
There was an error while fetching value stream analytics data.
'
),
});
return
Promise
.
resolve
();
};
export
const
receiveGroupStagesSuccess
=
(
{
state
:
{
featureFlags
},
commit
,
dispatch
},
stages
,
)
=>
{
export
const
receiveGroupStagesSuccess
=
({
commit
},
stages
)
=>
commit
(
types
.
RECEIVE_GROUP_STAGES_SUCCESS
,
stages
);
if
(
!
featureFlags
?.
hasPathNavigation
)
{
return
dispatch
(
'
setDefaultSelectedStage
'
);
}
return
Promise
.
resolve
();
};
export
const
fetchGroupStagesAndEvents
=
({
dispatch
,
getters
})
=>
{
const
{
currentValueStreamId
:
valueStreamId
,
...
...
ee/app/assets/javascripts/analytics/cycle_analytics/store/mutations.js
View file @
ec5f9c24
...
...
@@ -51,17 +51,7 @@ export default {
state
.
medians
=
{};
},
[
types
.
RECEIVE_STAGE_MEDIANS_SUCCESS
](
state
,
medians
=
[])
{
if
(
state
?.
featureFlags
?.
hasPathNavigation
)
{
state
.
medians
=
formatMedianValuesWithOverview
(
medians
);
}
else
{
state
.
medians
=
medians
.
reduce
(
(
acc
,
{
id
,
value
,
error
=
null
})
=>
({
...
acc
,
[
id
]:
{
value
,
error
},
}),
{},
);
}
},
[
types
.
RECEIVE_STAGE_MEDIANS_ERROR
](
state
)
{
state
.
medians
=
{};
...
...
ee/app/controllers/groups/analytics/cycle_analytics_controller.rb
View file @
ec5f9c24
...
...
@@ -14,7 +14,6 @@ class Groups::Analytics::CycleAnalyticsController < Groups::Analytics::Applicati
before_action
do
push_frontend_feature_flag
(
:cycle_analytics_scatterplot_enabled
,
default_enabled:
true
)
push_frontend_feature_flag
(
:value_stream_analytics_path_navigation
,
@group
,
default_enabled: :yaml
)
render_403
unless
can?
(
current_user
,
:read_group_cycle_analytics
,
@group
)
end
...
...
ee/changelogs/unreleased/323982-remove-enable-value-stream-analytics-horizontal-navigation-ff.yml
0 → 100644
View file @
ec5f9c24
---
title
:
Remove the value_stream_analytics_path_navigation feature flag
merge_request
:
60449
author
:
type
:
changed
ee/config/feature_flags/development/value_stream_analytics_path_navigation.yml
deleted
100644 → 0
View file @
1622d29a
---
name
:
value_stream_analytics_path_navigation
introduced_by_url
:
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31069
rollout_issue_url
:
https://gitlab.com/gitlab-org/gitlab/-/issues/323982
milestone
:
'
13.0'
type
:
development
group
:
group::optimize
default_enabled
:
true
ee/spec/features/groups/analytics/cycle_analytics/charts_spec.rb
View file @
ec5f9c24
...
...
@@ -42,11 +42,8 @@ RSpec.describe 'Value stream analytics charts', :js do
context
'Duration chart'
do
duration_stage_selector
=
'.js-dropdown-stages'
stage_nav_selector
=
'.stage-nav'
stage_table_selector
=
'.js-stage-table'
let
(
:duration_chart_dropdown
)
{
page
.
find
(
duration_stage_selector
)
}
let
(
:first_default_stage
)
{
page
.
find
(
'.stage-nav-item-cell'
,
text:
'Issue'
).
ancestor
(
'.stage-nav-item'
)
}
let
(
:custom_value_stream_name
)
{
"New created value stream"
}
let_it_be
(
:translated_default_stage_names
)
do
...
...
@@ -93,34 +90,6 @@ RSpec.describe 'Value stream analytics charts', :js do
expect
(
duration_chart_stages
).
not_to
include
(
first_stage_name
)
end
context
'With the path navigation feature flag disabled'
do
let
(
:nav
)
{
page
.
find
(
stage_nav_selector
)
}
before
do
stub_feature_flags
(
value_stream_analytics_path_navigation:
false
)
select_group
(
group
,
stage_table_selector
)
end
it_behaves_like
'has all the default stages'
context
'hidden stage'
do
before
do
toggle_more_options
(
first_default_stage
)
click_button
(
_
(
'Hide stage'
))
end
it
'will not appear in the duration chart dropdown'
do
# wait for the stage list to laod
expect
(
nav
).
to
have_content
(
s_
(
'CycleAnalyticsStage|Plan'
))
toggle_duration_chart_dropdown
expect
(
duration_chart_stages
).
not_to
include
(
s_
(
'CycleAnalyticsStage|Issue'
))
end
end
end
end
describe
'Tasks by type chart'
,
:js
do
...
...
ee/spec/features/groups/analytics/cycle_analytics/customizable_cycle_analytics_spec.rb
View file @
ec5f9c24
...
...
@@ -41,7 +41,6 @@ RSpec.describe 'Customizable Group Value Stream Analytics', :js do
start_field_label
=
'custom-stage-start-event-label-0'
end_field_label
=
'custom-stage-end-event-label-0'
name_field
=
'custom-stage-name-0'
stage_table_selector
=
'.js-stage-table'
let
(
:add_stage_button
)
{
'.js-add-stage-button'
}
let
(
:params
)
{
{
name:
custom_stage_name
,
start_event_identifier:
start_event_identifier
,
end_event_identifier:
end_event_identifier
}
}
...
...
@@ -84,77 +83,6 @@ RSpec.describe 'Customizable Group Value Stream Analytics', :js do
sign_in
(
user
)
end
context
'Manual ordering'
do
before
do
stub_feature_flags
(
value_stream_analytics_path_navigation:
false
)
select_group
(
group
,
stage_table_selector
)
end
let
(
:default_stage_order
)
{
%w[Issue Plan Code Test Review Staging]
.
freeze
}
def
confirm_stage_order
(
stages
)
page
.
within
(
'.stage-nav>ul'
)
do
stages
.
each_with_index
do
|
stage
,
index
|
expect
(
find
(
"li:nth-child(
#{
index
+
1
}
)"
)).
to
have_content
(
stage
)
end
end
end
context
'with only default stages'
do
it
'does not allow stages to be draggable'
,
:js
do
confirm_stage_order
(
default_stage_order
)
drag_from_index_to_index
(
0
,
1
)
confirm_stage_order
(
default_stage_order
)
end
end
context
'with at least one custom stage'
,
quarantine:
'https://gitlab.com/gitlab-org/gitlab/-/issues/216745'
do
default_custom_stage_order
=
%w[Issue Plan Code Test Review Staging Cool\ beans]
.
freeze
stages_near_middle_swapped
=
%w[Issue Plan Test Code Review Staging Cool\ beans]
.
freeze
stage_dragged_to_top
=
%w[Review Issue Plan Code Test Staging Cool\ beans]
.
freeze
stage_dragged_to_bottom
=
%w[Issue Plan Code Test Staging Cool\ beans Review]
.
freeze
shared_examples
'draggable stage'
do
|
original_order
,
updated_order
,
start_index
,
end_index
,
|
before
do
page
.
driver
.
browser
.
manage
.
window
.
resize_to
(
1650
,
1150
)
create_custom_stage
select_group
(
group
)
end
it
'allows a stage to be dragged'
do
confirm_stage_order
(
original_order
)
drag_from_index_to_index
(
start_index
,
end_index
)
confirm_stage_order
(
updated_order
)
end
it
'persists the order when a group is selected'
do
drag_from_index_to_index
(
start_index
,
end_index
)
select_group
(
group
)
confirm_stage_order
(
updated_order
)
end
end
context
'dragging a stage to the top'
,
:js
do
it_behaves_like
'draggable stage'
,
default_custom_stage_order
,
stage_dragged_to_top
,
4
,
0
end
context
'dragging a stage to the bottom'
,
:js
do
it_behaves_like
'draggable stage'
,
default_custom_stage_order
,
stage_dragged_to_bottom
,
4
,
7
end
context
'dragging stages in the middle'
,
:js
do
it_behaves_like
'draggable stage'
,
default_custom_stage_order
,
stages_near_middle_swapped
,
2
,
3
end
end
end
shared_examples
'submits custom stage form successfully'
do
|
stage_name
|
it
'custom stage is saved with confirmation message'
do
fill_in
name_field
,
with:
stage_name
...
...
@@ -291,217 +219,4 @@ RSpec.describe 'Customizable Group Value Stream Analytics', :js do
end
end
end
context
'With the path navigation feature flag disabled'
do
before
do
stub_feature_flags
(
value_stream_analytics_path_navigation:
false
)
end
context
'with a group'
do
context
'selected'
do
before
do
select_group
(
group
,
stage_table_selector
)
end
it_behaves_like
'can create custom stages'
do
let
(
:first_label
)
{
group_label1
}
let
(
:second_label
)
{
group_label2
}
let
(
:other_label
)
{
label
}
end
end
context
'with a custom stage created'
,
quarantine:
'https://gitlab.com/gitlab-org/gitlab/-/issues/273045'
do
before
do
create_custom_stage
select_group
(
group
,
stage_table_selector
)
expect
(
page
).
to
have_text
custom_stage_name
end
it_behaves_like
'can edit custom stages'
end
end
context
'with a sub group'
do
context
'selected'
do
before
do
select_group
(
sub_group
,
stage_table_selector
)
end
it_behaves_like
'can create custom stages'
do
let
(
:first_label
)
{
sub_group_label1
}
let
(
:second_label
)
{
sub_group_label2
}
let
(
:other_label
)
{
label
}
end
end
context
'with a custom stage created'
do
before
do
create_custom_stage
(
sub_group
)
select_group
(
sub_group
,
stage_table_selector
)
expect
(
page
).
to
have_text
custom_stage_name
end
it_behaves_like
'can edit custom stages'
end
end
context
'Add a stage button'
do
before
do
stub_feature_flags
(
value_stream_analytics_path_navigation:
false
)
select_group
(
group
,
stage_table_selector
)
end
it
'displays the custom stage form when clicked'
do
expect
(
page
).
not_to
have_text
(
s_
(
'CustomCycleAnalytics|New stage'
))
expect
(
page
).
to
have_selector
(
add_stage_button
,
visible:
true
)
expect
(
page
).
to
have_text
(
s_
(
'CustomCycleAnalytics|Add a stage'
))
expect
(
page
).
not_to
have_selector
(
"
#{
add_stage_button
}
.active"
)
page
.
find
(
add_stage_button
).
click
expect
(
page
).
to
have_selector
(
"
#{
add_stage_button
}
.active"
)
expect
(
page
).
to
have_text
(
s_
(
'CustomCycleAnalytics|New stage'
))
end
end
context
'default stages'
do
def
open_recover_stage_dropdown
find
(
add_stage_button
).
click
click_button
(
_
(
'Recover hidden stage'
))
end
def
active_stages
page
.
all
(
'.stage-nav .stage-name'
).
collect
(
&
:text
)
end
before
do
stub_feature_flags
(
value_stream_analytics_path_navigation:
false
)
select_group
(
group
,
stage_table_selector
)
toggle_more_options
(
first_default_stage
)
end
it
"can be hidden, can't be edited or removed"
do
expect
(
find_stage_actions_btn
(
first_default_stage
)).
to
have_text
(
_
(
'Hide stage'
))
expect
(
find_stage_actions_btn
(
first_default_stage
)).
not_to
have_text
(
_
(
'Edit stage'
))
expect
(
find_stage_actions_btn
(
first_default_stage
)).
not_to
have_text
(
_
(
'Remove stage'
))
end
context
'Hide stage'
do
before
do
click_button
(
_
(
'Hide stage'
))
# wait for the stage list to load
expect
(
nav
).
to
have_content
(
s_
(
'CycleAnalyticsStage|Plan'
))
end
it
'disappears from the stage table & can be recovered'
do
expect
(
active_stages
).
not_to
include
(
s_
(
'CycleAnalyticsStage|Issue'
))
open_recover_stage_dropdown
expect
(
page
.
find
(
"[data-testid='recover-hidden-stage-dropdown']"
)).
to
have_text
(
s_
(
'CycleAnalyticsStage|Issue'
))
end
end
context
'Recover stage'
do
before
do
click_button
(
_
(
'Hide stage'
))
# wait for the stage list to load
expect
(
nav
).
to
have_content
(
s_
(
'CycleAnalyticsStage|Plan'
))
end
it
'recovers the stage back to the stage table'
do
open_recover_stage_dropdown
click_button
(
s_
(
'CycleAnalyticsStage|Issue'
))
# wait for the stage list to load
expect
(
nav
).
to
have_content
(
s_
(
'CycleAnalyticsStage|Plan'
))
expect
(
page
.
find
(
'.flash-notice'
)).
to
have_content
(
_
(
'Stage data updated'
))
expect
(
active_stages
).
to
include
(
s_
(
'CycleAnalyticsStage|Issue'
))
end
end
end
context
'custom stages'
do
before
do
stub_feature_flags
(
value_stream_analytics_path_navigation:
false
)
create_custom_stage
select_group
(
group
,
stage_table_selector
)
expect
(
page
).
to
have_text
custom_stage_name
toggle_more_options
(
first_custom_stage
)
end
it
'can not be hidden, can be edited or removed'
do
expect
(
find_stage_actions_btn
(
first_custom_stage
)).
not_to
have_text
(
_
(
'Hide stage'
))
expect
(
find_stage_actions_btn
(
first_custom_stage
)).
to
have_text
(
_
(
'Edit stage'
))
expect
(
find_stage_actions_btn
(
first_custom_stage
)).
to
have_text
(
_
(
'Remove stage'
))
end
it
'disappears from the stage table after being removed'
do
nav
=
page
.
find
(
stage_nav_selector
)
expect
(
nav
).
to
have_text
(
custom_stage_name
)
click_button
(
_
(
'Remove stage'
))
expect
(
page
.
find
(
'.flash-notice'
)).
to
have_text
(
_
(
'Stage removed'
))
expect
(
nav
).
not_to
have_text
(
custom_stage_name
)
end
end
end
context
'Duration chart'
do
let
(
:duration_chart_dropdown
)
{
page
.
find
(
duration_stage_selector
)
}
let_it_be
(
:translated_default_stage_names
)
do
Gitlab
::
Analytics
::
CycleAnalytics
::
DefaultStages
.
names
.
map
do
|
name
|
stage
=
Analytics
::
CycleAnalytics
::
GroupStage
.
new
(
name:
name
)
Analytics
::
CycleAnalytics
::
StagePresenter
.
new
(
stage
).
title
end
.
freeze
end
def
duration_chart_stages
duration_chart_dropdown
.
all
(
'.dropdown-item'
).
collect
(
&
:text
)
end
def
toggle_duration_chart_dropdown
duration_chart_dropdown
.
click
end
before
do
select_group
(
group
)
end
it
'has all the default stages'
do
toggle_duration_chart_dropdown
expect
(
duration_chart_stages
).
to
eq
(
translated_default_stage_names
)
end
context
'hidden stage'
do
before
do
stub_feature_flags
(
value_stream_analytics_path_navigation:
false
)
select_group
(
group
,
stage_table_selector
)
toggle_more_options
(
first_default_stage
)
click_button
(
_
(
'Hide stage'
))
# wait for the stage list to load
expect
(
nav
).
to
have_content
(
s_
(
'CycleAnalyticsStage|Plan'
))
end
it
'will not appear in the duration chart dropdown'
do
toggle_duration_chart_dropdown
expect
(
duration_chart_stages
).
not_to
include
(
s_
(
'CycleAnalyticsStage|Issue'
))
end
end
end
end
ee/spec/features/groups/analytics/cycle_analytics/cycle_analytics_spec.rb
View file @
ec5f9c24
...
...
@@ -17,21 +17,6 @@ RSpec.describe 'Group value stream analytics' do
it
'pushes frontend feature flags'
do
visit
group_analytics_cycle_analytics_path
(
group
)
expect
(
page
).
to
have_pushed_frontend_feature_flags
(
cycleAnalyticsScatterplotEnabled:
true
,
valueStreamAnalyticsPathNavigation:
true
)
end
context
'when `value_stream_analytics_path_navigation` is disabled for a group'
do
before
do
stub_feature_flags
(
value_stream_analytics_path_navigation:
false
,
thing:
group
)
end
it
'pushes disabled feature flag to the frontend'
do
visit
group_analytics_cycle_analytics_path
(
group
)
expect
(
page
).
to
have_pushed_frontend_feature_flags
(
valueStreamAnalyticsPathNavigation:
false
)
end
expect
(
page
).
to
have_pushed_frontend_feature_flags
(
cycleAnalyticsScatterplotEnabled:
true
)
end
end
ee/spec/features/groups/analytics/cycle_analytics/filters_and_data_spec.rb
View file @
ec5f9c24
...
...
@@ -172,44 +172,6 @@ RSpec.describe 'Group value stream analytics filters and data', :js do
end
end
context
'with path navigation feature flag disabled'
do
before
do
stub_feature_flags
(
value_stream_analytics_path_navigation:
false
)
select_group
(
group
,
'.js-stage-table'
)
end
it
'does not show the path navigation'
do
expect
(
page
).
not_to
have_selector
(
path_nav_selector
)
end
it
'shows the vertical stage navigation'
do
expect
(
page
).
to
have_selector
(
stage_nav_selector
,
visible:
true
)
end
it
'displays the default list of stages'
do
stage_nav
=
page
.
find
(
stage_nav_selector
)
%w[Issue Plan Code Test Review Staging]
.
each
do
|
item
|
string_id
=
"CycleAnalytics|
#{
item
}
"
expect
(
stage_nav
).
to
have_content
(
s_
(
string_id
))
end
end
it
'each stage will have median values'
,
:sidekiq_might_not_need_inline
do
stage_medians
=
page
.
all
(
'.stage-nav .stage-median'
).
collect
(
&
:text
)
expect
(
stage_medians
).
to
eq
([
"Not enough data"
]
*
6
)
end
it
'displays the stage table headers'
do
expect
(
page
).
to
have_selector
(
'.stage-header'
,
visible:
true
)
expect
(
page
).
to
have_selector
(
'.median-header'
,
visible:
true
)
expect
(
page
).
to
have_selector
(
'.event-header'
,
visible:
true
)
expect
(
page
).
to
have_selector
(
'.total-time-header'
,
visible:
true
)
end
end
context
'without valid query parameters set'
do
context
'with created_after date > created_before date'
do
before
do
...
...
ee/spec/frontend/analytics/cycle_analytics/components/base_spec.js
View file @
ec5f9c24
...
...
@@ -3,16 +3,11 @@ import { createLocalVue, shallowMount, mount } from '@vue/test-utils';
import
axios
from
'
axios
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
Vuex
from
'
vuex
'
;
import
AddStageButton
from
'
ee/analytics/cycle_analytics/components/add_stage_button.vue
'
;
import
Component
from
'
ee/analytics/cycle_analytics/components/base.vue
'
;
import
CustomStageForm
from
'
ee/analytics/cycle_analytics/components/custom_stage_form.vue
'
;
import
DurationChart
from
'
ee/analytics/cycle_analytics/components/duration_chart.vue
'
;
import
FilterBar
from
'
ee/analytics/cycle_analytics/components/filter_bar.vue
'
;
import
Metrics
from
'
ee/analytics/cycle_analytics/components/metrics.vue
'
;
import
PathNavigation
from
'
ee/analytics/cycle_analytics/components/path_navigation.vue
'
;
import
StageNavItem
from
'
ee/analytics/cycle_analytics/components/stage_nav_item.vue
'
;
import
StageTable
from
'
ee/analytics/cycle_analytics/components/stage_table.vue
'
;
import
StageTableNav
from
'
ee/analytics/cycle_analytics/components/stage_table_nav.vue
'
;
import
StageTableNew
from
'
ee/analytics/cycle_analytics/components/stage_table_new.vue
'
;
import
TypeOfWorkCharts
from
'
ee/analytics/cycle_analytics/components/type_of_work_charts.vue
'
;
import
ValueStreamSelect
from
'
ee/analytics/cycle_analytics/components/value_stream_select.vue
'
;
...
...
@@ -55,7 +50,6 @@ const defaultStubs = {
const
defaultFeatureFlags
=
{
hasDurationChart
:
true
,
hasPathNavigation
:
false
,
};
const
[
selectedValueStream
]
=
mockData
.
valueStreams
;
...
...
@@ -122,6 +116,7 @@ describe('Value Stream Analytics component', () => {
featureFlags
=
{},
initialState
=
initialCycleAnalyticsState
,
props
=
{},
selectedStage
=
null
,
}
=
options
;
store
=
createStore
();
...
...
@@ -152,15 +147,16 @@ describe('Value Stream Analytics component', () => {
'
receiveGroupStagesSuccess
'
,
mockData
.
customizableStagesAndEvents
.
stages
,
);
if
(
selectedStage
)
{
await
store
.
dispatch
(
'
setSelectedStage
'
,
selectedStage
);
await
store
.
dispatch
(
'
fetchStageData
'
,
selectedStage
.
slug
);
}
else
{
await
store
.
dispatch
(
'
setDefaultSelectedStage
'
);
}
}
return
comp
;
}
const
findStageNavItemAtIndex
=
(
index
)
=>
wrapper
.
find
(
StageTableNav
).
findAll
(
StageNavItem
).
at
(
index
);
const
findAddStageButton
=
()
=>
wrapper
.
find
(
AddStageButton
);
const
displaysProjectsDropdownFilter
=
(
flag
)
=>
{
expect
(
wrapper
.
find
(
ProjectsDropdownFilter
).
exists
()).
toBe
(
flag
);
};
...
...
@@ -173,8 +169,8 @@ describe('Value Stream Analytics component', () => {
expect
(
wrapper
.
find
(
Metrics
).
exists
()).
toBe
(
flag
);
};
const
displaysStageTable
=
(
flag
,
component
=
StageTable
)
=>
{
expect
(
wrapper
.
find
(
component
).
exists
()).
toBe
(
flag
);
const
displaysStageTable
=
(
flag
)
=>
{
expect
(
wrapper
.
find
(
StageTableNew
).
exists
()).
toBe
(
flag
);
};
const
displaysDurationChart
=
(
flag
)
=>
{
...
...
@@ -189,10 +185,6 @@ describe('Value Stream Analytics component', () => {
expect
(
wrapper
.
find
(
PathNavigation
).
exists
()).
toBe
(
flag
);
};
const
displaysAddStageButton
=
(
flag
)
=>
{
expect
(
wrapper
.
find
(
AddStageButton
).
exists
()).
toBe
(
flag
);
};
const
displaysFilterBar
=
(
flag
)
=>
{
expect
(
wrapper
.
find
(
FilterBar
).
exists
()).
toBe
(
flag
);
};
...
...
@@ -205,12 +197,7 @@ describe('Value Stream Analytics component', () => {
beforeEach
(
async
()
=>
{
const
{
group
,
...
stateWithoutGroup
}
=
initialCycleAnalyticsState
;
mock
=
new
MockAdapter
(
axios
);
wrapper
=
await
createComponent
({
featureFlags
:
{
hasPathNavigation
:
true
,
},
initialState
:
stateWithoutGroup
,
});
wrapper
=
await
createComponent
({
initialState
:
stateWithoutGroup
});
});
afterEach
(()
=>
{
...
...
@@ -240,17 +227,12 @@ describe('Value Stream Analytics component', () => {
it
(
'
does not display the stage table
'
,
()
=>
{
displaysStageTable
(
false
);
displaysStageTable
(
false
,
StageTableNew
);
});
it
(
'
does not display the duration chart
'
,
()
=>
{
displaysDurationChart
(
false
);
});
it
(
'
does not display the add stage button
'
,
()
=>
{
displaysAddStageButton
(
false
);
});
it
(
'
does not display the path navigation
'
,
()
=>
{
displaysPathNavigation
(
false
);
});
...
...
@@ -265,11 +247,7 @@ describe('Value Stream Analytics component', () => {
mock
=
new
MockAdapter
(
axios
);
mockRequiredRoutes
(
mock
);
wrapper
=
await
createComponent
({
featureFlags
:
{
hasPathNavigation
:
true
,
},
});
wrapper
=
await
createComponent
();
await
store
.
dispatch
(
'
receiveCycleAnalyticsDataError
'
,
{
response
:
{
status
:
httpStatusCodes
.
FORBIDDEN
},
...
...
@@ -297,11 +275,6 @@ describe('Value Stream Analytics component', () => {
it
(
'
does not display the stage table
'
,
()
=>
{
displaysStageTable
(
false
);
displaysStageTable
(
false
,
StageTableNew
);
});
it
(
'
does not display the add stage button
'
,
()
=>
{
displaysAddStageButton
(
false
);
});
it
(
'
does not display the tasks by type chart
'
,
()
=>
{
...
...
@@ -312,48 +285,16 @@ describe('Value Stream Analytics component', () => {
displaysDurationChart
(
false
);
});
describe
(
'
path navigation
'
,
()
=>
{
describe
(
'
disabled
'
,
()
=>
{
it
(
'
does not display the path navigation
'
,
()
=>
{
displaysPathNavigation
(
false
);
});
});
describe
(
'
enabled
'
,
()
=>
{
beforeEach
(
async
()
=>
{
wrapper
=
await
createComponent
({
withStageSelected
:
true
,
pathNavigationEnabled
:
true
,
});
mock
=
new
MockAdapter
(
axios
);
mockRequiredRoutes
(
mock
);
mock
.
onAny
().
reply
(
httpStatusCodes
.
FORBIDDEN
);
await
waitForPromises
();
});
afterEach
(()
=>
{
mock
.
restore
();
});
it
(
'
does not display the path navigation
'
,
()
=>
{
displaysPathNavigation
(
false
);
});
});
});
});
describe
(
'
the user has access to the group
'
,
()
=>
{
beforeEach
(
async
()
=>
{
mock
=
new
MockAdapter
(
axios
);
mockRequiredRoutes
(
mock
);
wrapper
=
await
createComponent
({
withStageSelected
:
true
,
featureFlags
:
{
hasPathNavigation
:
true
,
},
});
wrapper
=
await
createComponent
({
withStageSelected
:
true
});
});
afterEach
(()
=>
{
...
...
@@ -403,11 +344,6 @@ describe('Value Stream Analytics component', () => {
it
(
'
hides the stage table
'
,
()
=>
{
displaysStageTable
(
false
);
displaysStageTable
(
false
,
StageTableNew
);
});
it
(
'
hides the add stage button
'
,
()
=>
{
displaysAddStageButton
(
false
);
});
describe
(
'
Without the overview stage selected
'
,
()
=>
{
...
...
@@ -416,107 +352,12 @@ describe('Value Stream Analytics component', () => {
mockRequiredRoutes
(
mock
);
wrapper
=
await
createComponent
({
withStageSelected
:
true
,
featureFlags
:
{
hasPathNavigation
:
true
,
},
selectedStage
:
mockData
.
issueStage
,
});
await
store
.
dispatch
(
'
setSelectedStage
'
,
mockData
.
issueStage
);
await
wrapper
.
vm
.
$nextTick
();
});
it
(
'
displays the stage table
'
,
()
=>
{
displaysStageTable
(
true
,
StageTableNew
);
});
it
(
'
does not display the add stage button
'
,
()
=>
{
displaysAddStageButton
(
false
);
});
});
describe
(
'
path navigation
'
,
()
=>
{
describe
(
'
disabled
'
,
()
=>
{
beforeEach
(
async
()
=>
{
wrapper
=
await
createComponent
({
withStageSelected
:
true
,
featureFlags
:
{
hasPathNavigation
:
false
,
},
});
});
it
(
'
does not display the path navigation
'
,
()
=>
{
displaysPathNavigation
(
false
);
});
describe
(
'
StageTable
'
,
()
=>
{
beforeEach
(
async
()
=>
{
mock
=
new
MockAdapter
(
axios
);
mockRequiredRoutes
(
mock
);
wrapper
=
await
createComponent
({
opts
:
{
stubs
:
{
StageTable
,
StageTableNav
,
StageNavItem
,
},
},
withStageSelected
:
true
,
});
});
it
(
'
has the first stage selected by default
'
,
()
=>
{
const
first
=
findStageNavItemAtIndex
(
0
);
const
second
=
findStageNavItemAtIndex
(
1
);
expect
(
first
.
props
(
'
isActive
'
)).
toBe
(
true
);
expect
(
second
.
props
(
'
isActive
'
)).
toBe
(
false
);
});
it
(
'
can navigate to different stages
'
,
async
()
=>
{
findStageNavItemAtIndex
(
2
).
trigger
(
'
click
'
);
await
wrapper
.
vm
.
$nextTick
();
const
first
=
findStageNavItemAtIndex
(
0
);
const
third
=
findStageNavItemAtIndex
(
2
);
expect
(
third
.
props
(
'
isActive
'
)).
toBe
(
true
);
expect
(
first
.
props
(
'
isActive
'
)).
toBe
(
false
);
});
describe
(
'
Add stage button
'
,
()
=>
{
beforeEach
(
async
()
=>
{
wrapper
=
await
createComponent
({
opts
:
{
stubs
:
{
StageTable
,
StageTableNav
,
AddStageButton
,
},
},
withStageSelected
:
true
,
});
});
it
(
'
can navigate to the custom stage form
'
,
async
()
=>
{
expect
(
wrapper
.
find
(
CustomStageForm
).
exists
()).
toBe
(
false
);
findAddStageButton
().
trigger
(
'
click
'
);
await
wrapper
.
vm
.
$nextTick
();
expect
(
wrapper
.
find
(
CustomStageForm
).
exists
()).
toBe
(
true
);
});
});
});
});
describe
(
'
enabled
'
,
()
=>
{
beforeEach
(
async
()
=>
{
wrapper
=
await
createComponent
({
withStageSelected
:
true
,
featureFlags
:
{
hasPathNavigation
:
true
,
},
});
displaysStageTable
(
true
);
});
it
(
'
displays the path navigation
'
,
()
=>
{
...
...
@@ -524,7 +365,6 @@ describe('Value Stream Analytics component', () => {
});
});
});
});
describe
(
'
with failed requests while loading
'
,
()
=>
{
beforeEach
(
async
()
=>
{
...
...
@@ -532,11 +372,7 @@ describe('Value Stream Analytics component', () => {
mock
=
new
MockAdapter
(
axios
);
mockRequiredRoutes
(
mock
);
wrapper
=
await
createComponent
({
featureFlags
:
{
hasPathNavigation
:
true
,
},
});
wrapper
=
await
createComponent
();
});
afterEach
(()
=>
{
...
...
@@ -568,7 +404,8 @@ describe('Value Stream Analytics component', () => {
mock
.
onGet
(
mockData
.
endpoints
.
stageData
)
.
reply
(
httpStatusCodes
.
NOT_FOUND
,
{
response
:
{
status
:
httpStatusCodes
.
NOT_FOUND
}
});
await
createComponent
();
await
createComponent
({
withStageSelected
:
true
,
selectedStage
:
mockData
.
issueStage
});
await
findError
(
'
There was an error fetching data for the selected stage
'
);
});
...
...
@@ -615,8 +452,10 @@ describe('Value Stream Analytics component', () => {
value_stream_id
:
selectedValueStream
.
id
,
created_after
:
toYmd
(
mockData
.
startDate
),
created_before
:
toYmd
(
mockData
.
endDate
),
stage_id
:
1
,
stage_id
:
null
,
project_ids
:
null
,
sort
:
null
,
direction
:
null
,
};
const
selectedProjectIds
=
mockData
.
selectedProjects
.
map
(({
id
})
=>
getIdFromGraphQLId
(
id
));
...
...
@@ -681,7 +520,7 @@ describe('Value Stream Analytics component', () => {
created_after
:
toYmd
(
mockData
.
startDate
),
created_before
:
toYmd
(
mockData
.
endDate
),
project_ids
:
selectedProjectIds
,
stage_id
:
1
,
stage_id
:
null
,
});
});
});
...
...
@@ -693,47 +532,6 @@ describe('Value Stream Analytics component', () => {
await
wrapper
.
vm
.
$nextTick
();
});
it
(
'
sets the stage_id url parameter
'
,
async
()
=>
{
await
shouldMergeUrlParams
(
wrapper
,
{
...
defaultParams
,
created_after
:
toYmd
(
mockData
.
startDate
),
created_before
:
toYmd
(
mockData
.
endDate
),
project_ids
:
null
,
stage_id
:
2
,
});
});
});
describe
(
'
with hasPathNavigation=true
'
,
()
=>
{
it
(
'
does not set the sort and direction parameters
'
,
async
()
=>
{
wrapper
=
await
createComponent
({
featureFlags
:
{
hasPathNavigation
:
true
,
},
});
await
store
.
dispatch
(
'
initializeCycleAnalytics
'
,
initialCycleAnalyticsState
);
await
wrapper
.
vm
.
$nextTick
();
await
shouldMergeUrlParams
(
wrapper
,
{
...
defaultParams
,
created_after
:
toYmd
(
mockData
.
startDate
),
created_before
:
toYmd
(
mockData
.
endDate
),
project_ids
:
null
,
});
});
describe
(
'
with a stage selected
'
,
()
=>
{
beforeEach
(
async
()
=>
{
wrapper
=
await
createComponent
({
featureFlags
:
{
hasPathNavigation
:
true
,
},
});
await
store
.
dispatch
(
'
setSelectedStage
'
,
selectedStage
);
await
wrapper
.
vm
.
$nextTick
();
});
it
(
'
sets the stage, sort and direction parameters
'
,
async
()
=>
{
await
shouldMergeUrlParams
(
wrapper
,
{
...
defaultParams
,
...
...
@@ -744,5 +542,4 @@ describe('Value Stream Analytics component', () => {
});
});
});
});
});
ee/spec/frontend/analytics/cycle_analytics/store/actions_spec.js
View file @
ec5f9c24
...
...
@@ -394,17 +394,6 @@ describe('Value Stream Analytics actions', () => {
});
describe
(
'
receiveGroupStagesSuccess
'
,
()
=>
{
describe
(
'
when the `hasPathNavigation` feature flag is enabled
'
,
()
=>
{
beforeEach
(()
=>
{
state
=
{
...
state
,
featureFlags
:
{
...
state
.
featureFlags
,
hasPathNavigation
:
true
,
},
};
});
it
(
`commits the
${
types
.
RECEIVE_GROUP_STAGES_SUCCESS
}
mutation'`
,
()
=>
{
return
testAction
(
actions
.
receiveGroupStagesSuccess
,
...
...
@@ -421,50 +410,7 @@ describe('Value Stream Analytics actions', () => {
});
});
describe
(
'
when the `hasPathNavigation` feature flag is disabled
'
,
()
=>
{
beforeEach
(()
=>
{
state
=
{
...
state
,
featureFlags
:
{
...
state
.
featureFlags
,
hasPathNavigation
:
false
,
},
};
});
it
(
`commits the
${
types
.
RECEIVE_GROUP_STAGES_SUCCESS
}
mutation and dispatches 'setDefaultSelectedStage`
,
()
=>
{
return
testAction
(
actions
.
receiveGroupStagesSuccess
,
{
...
customizableStagesAndEvents
.
stages
},
state
,
[
{
type
:
types
.
RECEIVE_GROUP_STAGES_SUCCESS
,
payload
:
{
...
customizableStagesAndEvents
.
stages
},
},
],
[{
type
:
'
setDefaultSelectedStage
'
}],
);
});
});
});
describe
(
'
setDefaultSelectedStage
'
,
()
=>
{
describe
(
'
when the `hasPathNavigation` feature flag is enabled
'
,
()
=>
{
beforeEach
(()
=>
{
state
=
{
...
state
,
featureFlags
:
{
...
state
.
featureFlags
,
hasPathNavigation
:
true
,
},
};
});
afterEach
(()
=>
{
mock
.
restore
();
});
it
(
"
dispatches the 'setSelectedStage' with the overview stage
"
,
()
=>
{
return
testAction
(
actions
.
setDefaultSelectedStage
,
...
...
@@ -476,61 +422,6 @@ describe('Value Stream Analytics actions', () => {
});
});
describe
(
'
when the `hasPathNavigation` feature flag is disabled
'
,
()
=>
{
beforeEach
(()
=>
{
state
=
{
...
state
,
featureFlags
:
{
...
state
.
featureFlags
,
hasPathNavigation
:
false
,
},
};
});
afterEach
(()
=>
{
mock
.
restore
();
});
it
(
"
dispatches the 'fetchStageData' action
"
,
()
=>
{
return
testAction
(
actions
.
setDefaultSelectedStage
,
null
,
state
,
[],
[
{
type
:
'
setSelectedStage
'
,
payload
:
selectedStage
},
{
type
:
'
fetchStageData
'
,
payload
:
selectedStageSlug
},
],
);
});
it
.
each
`
data
${[]}
${
null
}
`
(
'
with $data will flash an error
'
,
({
data
})
=>
{
actions
.
setDefaultSelectedStage
(
{
state
,
getters
:
{
activeStages
:
data
},
dispatch
:
()
=>
{}
},
{},
);
expect
(
createFlash
).
toHaveBeenCalledWith
({
message
:
flashErrorMessage
});
});
it
(
'
will select the first active stage
'
,
()
=>
{
return
testAction
(
actions
.
setDefaultSelectedStage
,
null
,
state
,
[],
[
{
type
:
'
setSelectedStage
'
,
payload
:
stages
[
1
]
},
{
type
:
'
fetchStageData
'
,
payload
:
stages
[
1
].
slug
},
],
);
});
});
});
describe
(
'
updateStage
'
,
()
=>
{
const
stageId
=
'
cool-stage
'
;
const
payload
=
{
hidden
:
true
};
...
...
ee/spec/frontend/analytics/cycle_analytics/store/mutations_spec.js
View file @
ec5f9c24
...
...
@@ -177,26 +177,8 @@ describe('Value Stream Analytics mutations', () => {
});
describe
(
`
${
types
.
RECEIVE_STAGE_MEDIANS_SUCCESS
}
`
,
()
=>
{
it
(
'
sets each id as a key in the median object with the corresponding value and error
'
,
()
=>
{
const
stateWithData
=
{
medians
:
{},
};
mutations
[
types
.
RECEIVE_STAGE_MEDIANS_SUCCESS
](
stateWithData
,
[
{
id
:
1
,
value
:
20
},
{
id
:
2
,
value
:
10
},
]);
expect
(
stateWithData
.
medians
).
toEqual
({
1
:
{
value
:
20
,
error
:
null
},
2
:
{
value
:
10
,
error
:
null
},
});
});
describe
(
'
with hasPathNavigation set to true
'
,
()
=>
{
beforeEach
(()
=>
{
state
=
{
featureFlags
:
{
hasPathNavigation
:
true
},
medians
:
{},
};
...
...
@@ -214,7 +196,6 @@ describe('Value Stream Analytics mutations', () => {
expect
(
state
.
medians
).
toMatchObject
({
overview
:
'
5d
'
});
});
});
});
describe
(
`
${
types
.
INITIALIZE_VSA
}
`
,
()
=>
{
const
initialData
=
{
...
...
locale/gitlab.pot
View file @
ec5f9c24
...
...
@@ -9748,9 +9748,6 @@ msgstr ""
msgid "CustomCycleAnalytics|End event label"
msgstr ""
msgid "CustomCycleAnalytics|New stage"
msgstr ""
msgid "CustomCycleAnalytics|Stage name already exists"
msgstr ""
...
...
@@ -26710,9 +26707,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
msgid "Recover hidden stage"
msgstr ""
msgid "Recovering projects"
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