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
d16700bd
Commit
d16700bd
authored
Mar 25, 2020
by
Adam Hegyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Eliminate group_level_cycle_analytics FF
This commit removes the `group_level_cycle_analytics` feature flag.
parent
74e1447d
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
507 additions
and
585 deletions
+507
-585
ee/app/assets/javascripts/analytics/cycle_analytics/store/actions.js
...ts/javascripts/analytics/cycle_analytics/store/actions.js
+5
-11
ee/app/assets/javascripts/api.js
ee/app/assets/javascripts/api.js
+45
-38
ee/app/controllers/analytics/cycle_analytics/stages_controller.rb
...ontrollers/analytics/cycle_analytics/stages_controller.rb
+8
-8
ee/app/controllers/groups/analytics/cycle_analytics/stages_controller.rb
...ers/groups/analytics/cycle_analytics/stages_controller.rb
+10
-0
ee/app/controllers/groups/analytics/cycle_analytics/summary_controller.rb
...rs/groups/analytics/cycle_analytics/summary_controller.rb
+10
-0
ee/app/controllers/groups/analytics/tasks_by_type_controller.rb
.../controllers/groups/analytics/tasks_by_type_controller.rb
+4
-0
ee/app/controllers/groups/cycle_analytics/events_controller.rb
...p/controllers/groups/cycle_analytics/events_controller.rb
+0
-56
ee/app/controllers/groups/cycle_analytics_controller.rb
ee/app/controllers/groups/cycle_analytics_controller.rb
+0
-40
ee/config/routes/group.rb
ee/config/routes/group.rb
+24
-13
ee/spec/controllers/analytics/tasks_by_type_controller_spec.rb
...ec/controllers/analytics/tasks_by_type_controller_spec.rb
+2
-2
ee/spec/controllers/groups/analytics/cycle_analytics/stages_controller_spec.rb
...roups/analytics/cycle_analytics/stages_controller_spec.rb
+233
-0
ee/spec/controllers/groups/analytics/cycle_analytics_controller_spec.rb
...llers/groups/analytics/cycle_analytics_controller_spec.rb
+0
-39
ee/spec/controllers/groups/analytics/tasks_by_type_controller_spec.rb
...rollers/groups/analytics/tasks_by_type_controller_spec.rb
+148
-0
ee/spec/controllers/groups/cycle_analytics/events_controller_spec.rb
...trollers/groups/cycle_analytics/events_controller_spec.rb
+0
-76
ee/spec/controllers/groups/cycle_analytics_controller_spec.rb
...pec/controllers/groups/cycle_analytics_controller_spec.rb
+0
-77
ee/spec/frontend/analytics/cycle_analytics/store/actions_spec.js
.../frontend/analytics/cycle_analytics/store/actions_spec.js
+2
-1
ee/spec/frontend/api_spec.js
ee/spec/frontend/api_spec.js
+16
-19
ee/spec/frontend/fixtures/analytics.rb
ee/spec/frontend/fixtures/analytics.rb
+0
-45
ee/spec/requests/groups/cycle_analytics_events_spec.rb
ee/spec/requests/groups/cycle_analytics_events_spec.rb
+0
-148
ee/spec/support/shared_examples/controllers/analytics/cycle_analytics/shared_stage_shared_examples.rb
...analytics/cycle_analytics/shared_stage_shared_examples.rb
+0
-12
No files found.
ee/app/assets/javascripts/analytics/cycle_analytics/store/actions.js
View file @
d16700bd
...
...
@@ -89,7 +89,6 @@ export const fetchStageMedianValues = ({ state, dispatch, getters }) => {
const
{
stages
}
=
state
;
const
params
=
{
group_id
:
currentGroupPath
,
created_after
,
created_before
,
project_ids
,
...
...
@@ -191,8 +190,7 @@ export const fetchSummaryData = ({ state, dispatch, getters }) => {
selectedGroup
:
{
fullPath
},
}
=
state
;
return
Api
.
cycleAnalyticsSummaryData
({
group_id
:
fullPath
,
return
Api
.
cycleAnalyticsSummaryData
(
fullPath
,
{
created_after
,
created_before
,
project_ids
,
...
...
@@ -230,11 +228,10 @@ export const fetchTopRankedGroupLabels = ({
dispatch
(
'
requestTopRankedGroupLabels
'
);
const
{
subject
}
=
state
.
tasksByType
;
return
Api
.
cycleAnalyticsTopLabels
({
return
Api
.
cycleAnalyticsTopLabels
(
currentGroupPath
,
{
subject
,
created_after
,
created_before
,
group_id
:
currentGroupPath
,
})
.
then
(({
data
})
=>
dispatch
(
'
receiveTopRankedGroupLabelsSuccess
'
,
data
))
.
catch
(
error
=>
...
...
@@ -359,7 +356,6 @@ export const fetchTasksByTypeData = ({ dispatch, state, getters }) => {
// dont request if we have no labels selected...for now
if
(
selectedLabelIds
.
length
)
{
const
params
=
{
group_id
:
currentGroupPath
,
created_after
,
created_before
,
project_ids
,
...
...
@@ -369,7 +365,7 @@ export const fetchTasksByTypeData = ({ dispatch, state, getters }) => {
dispatch
(
'
requestTasksByTypeData
'
);
return
Api
.
cycleAnalyticsTasksByType
(
params
)
return
Api
.
cycleAnalyticsTasksByType
(
currentGroupPath
,
params
)
.
then
(({
data
})
=>
dispatch
(
'
receiveTasksByTypeDataSuccess
'
,
data
))
.
catch
(
error
=>
dispatch
(
'
receiveTasksByTypeDataError
'
,
error
));
}
...
...
@@ -472,8 +468,7 @@ export const fetchDurationData = ({ state, dispatch, getters }) => {
stages
.
map
(
stage
=>
{
const
{
slug
}
=
stage
;
return
Api
.
cycleAnalyticsDurationChart
(
slug
,
{
group_id
:
fullPath
,
return
Api
.
cycleAnalyticsDurationChart
(
fullPath
,
slug
,
{
created_after
,
created_before
,
project_ids
,
...
...
@@ -521,8 +516,7 @@ export const fetchDurationMedianData = ({ state, dispatch, getters }) => {
stages
.
map
(
stage
=>
{
const
{
slug
}
=
stage
;
return
Api
.
cycleAnalyticsDurationChart
(
slug
,
{
group_id
:
fullPath
,
return
Api
.
cycleAnalyticsDurationChart
(
fullPath
,
slug
,
{
created_after
:
dateFormat
(
offsetCreatedAfter
,
dateFormats
.
isoDate
),
created_before
:
dateFormat
(
offsetCreatedBefore
,
dateFormats
.
isoDate
),
project_ids
,
...
...
ee/app/assets/javascripts/api.js
View file @
d16700bd
...
...
@@ -13,15 +13,17 @@ export default {
groupPackagesPath
:
'
/api/:version/groups/:id/packages
'
,
projectPackagesPath
:
'
/api/:version/projects/:id/packages
'
,
projectPackagePath
:
'
/api/:version/projects/:id/packages/:package_id
'
,
cycleAnalyticsTasksByTypePath
:
'
/-/analytics/type_of_work/tasks_by_type
'
,
cycleAnalyticsTopLabelsPath
:
'
/-/analytics/type_of_work/tasks_by_type/top_labels
'
,
cycleAnalyticsSummaryDataPath
:
'
/-/analytics/value_stream_analytics/summary
'
,
cycleAnalyticsGroupStagesAndEventsPath
:
'
/-/analytics/value_stream_analytics/stages
'
,
cycleAnalyticsStageEventsPath
:
'
/-/analytics/value_stream_analytics/stages/:stage_id/records
'
,
cycleAnalyticsStageMedianPath
:
'
/-/analytics/value_stream_analytics/stages/:stage_id/median
'
,
cycleAnalyticsStagePath
:
'
/-/analytics/value_stream_analytics/stages/:stage_id
'
,
cycleAnalyticsTasksByTypePath
:
'
/groups/:id/-/analytics/type_of_work/tasks_by_type
'
,
cycleAnalyticsTopLabelsPath
:
'
/groups/:id/-/analytics/type_of_work/tasks_by_type/top_labels
'
,
cycleAnalyticsSummaryDataPath
:
'
/groups/:id/-/analytics/value_stream_analytics/summary
'
,
cycleAnalyticsGroupStagesAndEventsPath
:
'
/groups/:id/-/analytics/value_stream_analytics/stages
'
,
cycleAnalyticsStageEventsPath
:
'
/groups/:id/-/analytics/value_stream_analytics/stages/:stage_id/records
'
,
cycleAnalyticsStageMedianPath
:
'
/groups/:id/-/analytics/value_stream_analytics/stages/:stage_id/median
'
,
cycleAnalyticsStagePath
:
'
/groups/:id/-/analytics/value_stream_analytics/stages/:stage_id
'
,
cycleAnalyticsDurationChartPath
:
'
/-/analytics/value_stream_analytics/stages/:stage_id/duration_chart
'
,
'
/
groups/:id/
-/analytics/value_stream_analytics/stages/:stage_id/duration_chart
'
,
cycleAnalyticsGroupLabelsPath
:
'
/groups/:namespace_path/-/labels.json
'
,
codeReviewAnalyticsPath
:
'
/api/:version/analytics/code_review
'
,
groupActivityIssuesPath
:
'
/api/:version/analytics/group_activity/issues_count
'
,
...
...
@@ -131,69 +133,74 @@ export default {
return
axios
.
delete
(
url
);
},
cycleAnalyticsTasksByType
(
params
=
{})
{
const
url
=
Api
.
buildUrl
(
this
.
cycleAnalyticsTasksByTypePath
);
cycleAnalyticsTasksByType
(
groupId
,
params
=
{})
{
const
url
=
Api
.
buildUrl
(
this
.
cycleAnalyticsTasksByTypePath
).
replace
(
'
:id
'
,
groupId
);
return
axios
.
get
(
url
,
{
params
});
},
cycleAnalyticsTopLabels
(
params
=
{})
{
const
url
=
Api
.
buildUrl
(
this
.
cycleAnalyticsTopLabelsPath
);
cycleAnalyticsTopLabels
(
groupId
,
params
=
{})
{
const
url
=
Api
.
buildUrl
(
this
.
cycleAnalyticsTopLabelsPath
).
replace
(
'
:id
'
,
groupId
);
return
axios
.
get
(
url
,
{
params
});
},
cycleAnalyticsSummaryData
(
params
=
{})
{
const
url
=
Api
.
buildUrl
(
this
.
cycleAnalyticsSummaryDataPath
);
cycleAnalyticsSummaryData
(
groupId
,
params
=
{})
{
const
url
=
Api
.
buildUrl
(
this
.
cycleAnalyticsSummaryDataPath
).
replace
(
'
:id
'
,
groupId
);
return
axios
.
get
(
url
,
{
params
});
},
cycleAnalyticsGroupStagesAndEvents
(
groupId
,
params
=
{})
{
const
url
=
Api
.
buildUrl
(
this
.
cycleAnalyticsGroupStagesAndEventsPath
);
const
url
=
Api
.
buildUrl
(
this
.
cycleAnalyticsGroupStagesAndEventsPath
)
.
replace
(
'
:id
'
,
groupId
)
;
return
axios
.
get
(
url
,
{
params
:
{
group_id
:
groupId
,
...
params
},
});
return
axios
.
get
(
url
,
{
params
});
},
cycleAnalyticsStageEvents
(
groupId
,
stageId
,
params
=
{})
{
const
url
=
Api
.
buildUrl
(
this
.
cycleAnalyticsStageEventsPath
).
replace
(
'
:stage_id
'
,
stageId
);
return
axios
.
get
(
url
,
{
params
:
{
...
params
,
group_id
:
groupId
}
});
const
url
=
Api
.
buildUrl
(
this
.
cycleAnalyticsStageEventsPath
)
.
replace
(
'
:id
'
,
groupId
)
.
replace
(
'
:stage_id
'
,
stageId
);
return
axios
.
get
(
url
,
{
params
});
},
cycleAnalyticsStageMedian
(
groupId
,
stageId
,
params
=
{})
{
const
url
=
Api
.
buildUrl
(
this
.
cycleAnalyticsStageMedianPath
).
replace
(
'
:stage_id
'
,
stageId
);
return
axios
.
get
(
url
,
{
params
:
{
...
params
,
group_id
:
groupId
}
});
const
url
=
Api
.
buildUrl
(
this
.
cycleAnalyticsStageMedianPath
)
.
replace
(
'
:id
'
,
groupId
)
.
replace
(
'
:stage_id
'
,
stageId
);
return
axios
.
get
(
url
,
{
params
:
{
...
params
}
});
},
cycleAnalyticsCreateStage
(
groupId
,
data
)
{
const
url
=
Api
.
buildUrl
(
this
.
cycleAnalyticsGroupStagesAndEventsPath
);
const
url
=
Api
.
buildUrl
(
this
.
cycleAnalyticsGroupStagesAndEventsPath
)
.
replace
(
'
:id
'
,
groupId
)
;
return
axios
.
post
(
url
,
data
,
{
params
:
{
group_id
:
groupId
},
});
return
axios
.
post
(
url
,
data
);
},
cycleAnalyticsStageUrl
(
stageId
)
{
return
Api
.
buildUrl
(
this
.
cycleAnalyticsStagePath
).
replace
(
'
:stage_id
'
,
stageId
);
cycleAnalyticsStageUrl
(
stageId
,
groupId
)
{
return
Api
.
buildUrl
(
this
.
cycleAnalyticsStagePath
)
.
replace
(
'
:id
'
,
groupId
)
.
replace
(
'
:stage_id
'
,
stageId
);
},
cycleAnalyticsUpdateStage
(
stageId
,
groupId
,
data
)
{
const
url
=
this
.
cycleAnalyticsStageUrl
(
stageId
);
const
url
=
this
.
cycleAnalyticsStageUrl
(
stageId
,
groupId
);
return
axios
.
put
(
url
,
data
,
{
params
:
{
group_id
:
groupId
},
});
return
axios
.
put
(
url
,
data
);
},
cycleAnalyticsRemoveStage
(
stageId
,
groupId
)
{
const
url
=
this
.
cycleAnalyticsStageUrl
(
stageId
);
const
url
=
this
.
cycleAnalyticsStageUrl
(
stageId
,
groupId
);
return
axios
.
delete
(
url
,
{
params
:
{
group_id
:
groupId
},
});
return
axios
.
delete
(
url
);
},
cycleAnalyticsDurationChart
(
stageSlug
,
params
=
{})
{
const
url
=
Api
.
buildUrl
(
this
.
cycleAnalyticsDurationChartPath
).
replace
(
'
:stage_id
'
,
stageSlug
);
cycleAnalyticsDurationChart
(
groupId
,
stageSlug
,
params
=
{})
{
const
url
=
Api
.
buildUrl
(
this
.
cycleAnalyticsDurationChartPath
)
.
replace
(
'
:id
'
,
groupId
)
.
replace
(
'
:stage_id
'
,
stageSlug
);
return
axios
.
get
(
url
,
{
params
,
...
...
ee/app/controllers/analytics/cycle_analytics/stages_controller.rb
View file @
d16700bd
...
...
@@ -53,7 +53,7 @@ module Analytics
def
duration_chart
return
render_403
unless
can?
(
current_user
,
:read_group_stage
,
@group
)
render
json:
Analytics
::
CycleAnalytics
::
DurationChartItemEntity
.
represent
(
data_collector
.
duration_chart_data
)
render
json:
::
Analytics
::
CycleAnalytics
::
DurationChartItemEntity
.
represent
(
data_collector
.
duration_chart_data
)
end
private
...
...
@@ -81,35 +81,35 @@ module Analytics
end
def
stage
@stage
||=
Analytics
::
CycleAnalytics
::
StageFinder
.
new
(
parent:
@group
,
stage_id:
params
[
:id
]).
execute
@stage
||=
::
Analytics
::
CycleAnalytics
::
StageFinder
.
new
(
parent:
@group
,
stage_id:
params
[
:id
]).
execute
end
def
cycle_analytics_configuration
(
stages
)
stage_presenters
=
stages
.
map
{
|
s
|
StagePresenter
.
new
(
s
)
}
Analytics
::
CycleAnalytics
::
ConfigurationEntity
.
new
(
stages:
stage_presenters
)
::
Analytics
::
CycleAnalytics
::
ConfigurationEntity
.
new
(
stages:
stage_presenters
)
end
def
list_service
Stages
::
ListService
.
new
(
parent:
@group
,
current_user:
current_user
)
::
Analytics
::
CycleAnalytics
::
Stages
::
ListService
.
new
(
parent:
@group
,
current_user:
current_user
)
end
def
create_service
Stages
::
CreateService
.
new
(
parent:
@group
,
current_user:
current_user
,
params:
create_params
)
::
Analytics
::
CycleAnalytics
::
Stages
::
CreateService
.
new
(
parent:
@group
,
current_user:
current_user
,
params:
create_params
)
end
def
update_service
Stages
::
UpdateService
.
new
(
parent:
@group
,
current_user:
current_user
,
params:
update_params
)
::
Analytics
::
CycleAnalytics
::
Stages
::
UpdateService
.
new
(
parent:
@group
,
current_user:
current_user
,
params:
update_params
)
end
def
delete_service
Stages
::
DeleteService
.
new
(
parent:
@group
,
current_user:
current_user
,
params:
delete_params
)
::
Analytics
::
CycleAnalytics
::
Stages
::
DeleteService
.
new
(
parent:
@group
,
current_user:
current_user
,
params:
delete_params
)
end
def
render_stage_service_result
(
result
)
if
result
.
success?
stage
=
StagePresenter
.
new
(
result
.
payload
[
:stage
])
render
json:
Analytics
::
CycleAnalytics
::
StageEntity
.
new
(
stage
),
status:
result
.
http_status
render
json:
::
Analytics
::
CycleAnalytics
::
StageEntity
.
new
(
stage
),
status:
result
.
http_status
else
render
json:
{
message:
result
.
message
,
errors:
result
.
payload
[
:errors
]
},
status:
result
.
http_status
end
...
...
ee/app/controllers/groups/analytics/cycle_analytics/stages_controller.rb
0 → 100644
View file @
d16700bd
# frozen_string_literal: true
module
Groups
module
Analytics
module
CycleAnalytics
class
StagesController
<
::
Analytics
::
CycleAnalytics
::
StagesController
end
end
end
end
ee/app/controllers/groups/analytics/cycle_analytics/summary_controller.rb
0 → 100644
View file @
d16700bd
# frozen_string_literal: true
module
Groups
module
Analytics
module
CycleAnalytics
class
SummaryController
<
::
Analytics
::
CycleAnalytics
::
SummaryController
end
end
end
end
ee/app/controllers/groups/analytics/tasks_by_type_controller.rb
0 → 100644
View file @
d16700bd
# frozen_string_literal: true
class
Groups::Analytics::TasksByTypeController
<
::
Analytics
::
TasksByTypeController
end
ee/app/controllers/groups/cycle_analytics/events_controller.rb
deleted
100644 → 0
View file @
74e1447d
# frozen_string_literal: true
class
Groups::CycleAnalytics::EventsController
<
Groups
::
ApplicationController
include
ActionView
::
Helpers
::
DateHelper
include
ActionView
::
Helpers
::
TextHelper
include
CycleAnalyticsParams
before_action
:authorize_group_cycle_analytics!
def
issue
render_events
(
:issue
)
end
def
plan
render_events
(
:plan
)
end
def
code
render_events
(
:code
)
end
def
test
render_events
(
:test
)
end
def
review
render_events
(
:review
)
end
def
staging
render_events
(
:staging
)
end
def
production
render_events
(
:production
)
end
private
def
render_events
(
stage
)
respond_to
do
|
format
|
format
.
html
format
.
json
{
render
json:
{
events:
cycle_analytics
[
stage
].
events
}
}
end
end
def
cycle_analytics
@cycle_analytics
||=
::
CycleAnalytics
::
GroupLevel
.
new
(
group:
group
,
options:
options
(
cycle_analytics_group_params
))
end
def
authorize_group_cycle_analytics!
unless
can?
(
current_user
,
:read_group_cycle_analytics
,
group
)
render_403
end
end
end
ee/app/controllers/groups/cycle_analytics_controller.rb
deleted
100644 → 0
View file @
74e1447d
# frozen_string_literal: true
class
Groups::CycleAnalyticsController
<
Groups
::
ApplicationController
include
ActionView
::
Helpers
::
DateHelper
include
ActionView
::
Helpers
::
TextHelper
include
CycleAnalyticsParams
before_action
:whitelist_query_limiting
,
only:
[
:show
]
before_action
:authorize_group_cycle_analytics!
def
show
respond_to
do
|
format
|
format
.
json
{
render
json:
cycle_analytics_json
}
end
end
private
def
cycle_analytics_json
{
summary:
cycle_analytics_stats
.
summary
,
stats:
cycle_analytics_stats
.
stats
,
permissions:
cycle_analytics_stats
.
permissions
(
user:
current_user
)
}
end
def
cycle_analytics_stats
@cycle_analytics_stats
||=
::
CycleAnalytics
::
GroupLevel
.
new
(
group:
group
,
options:
options
(
cycle_analytics_group_params
))
end
def
whitelist_query_limiting
Gitlab
::
QueryLimiting
.
whitelist
(
'https://gitlab.com/gitlab-org/gitlab-foss/issues/42671'
)
end
def
authorize_group_cycle_analytics!
unless
can?
(
current_user
,
:read_group_cycle_analytics
,
group
)
render_403
end
end
end
ee/config/routes/group.rb
View file @
d16700bd
...
...
@@ -19,21 +19,32 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
get
'/analytics'
,
to:
redirect
(
'groups/%{group_id}/-/contribution_analytics'
)
resource
:contribution_analytics
,
only:
[
:show
]
resource
:cycle_analytics
,
only:
[
:show
],
path:
'value_stream_analytics'
scope
module: :cycle_analytics
,
as:
'cycle_analytics'
,
path:
'value_stream_analytics'
do
scope
:events
,
controller:
'events'
do
get
:issue
get
:plan
get
:code
get
:test
get
:review
get
:staging
get
:production
end
end
namespace
:analytics
do
resource
:productivity_analytics
,
only: :show
,
constraints:
->
(
req
)
{
Gitlab
::
Analytics
.
productivity_analytics_enabled?
}
resource
:cycle_analytics
,
path:
'value_stream_analytics'
,
only: :show
,
constraints:
->
(
req
)
{
Gitlab
::
Analytics
.
cycle_analytics_enabled?
}
constraints
(
::
Constraints
::
FeatureConstrainer
.
new
(
Gitlab
::
Analytics
::
CYCLE_ANALYTICS_FEATURE_FLAG
,
default_enabled:
Gitlab
::
Analytics
.
feature_enabled_by_default?
(
Gitlab
::
Analytics
::
CYCLE_ANALYTICS_FEATURE_FLAG
)))
do
resource
:cycle_analytics
,
only: :show
,
path:
'value_stream_analytics'
scope
module: :cycle_analytics
,
as:
'cycle_analytics'
,
path:
'value_stream_analytics'
do
resources
:stages
,
only:
[
:index
,
:create
,
:update
,
:destroy
]
do
member
do
get
:duration_chart
get
:median
get
:records
end
end
resource
:summary
,
controller: :summary
,
only: :show
end
get
'/cycle_analytics'
,
to:
redirect
(
'-/analytics/value_stream_analytics'
)
end
constraints
(
::
Constraints
::
FeatureConstrainer
.
new
(
Gitlab
::
Analytics
::
TASKS_BY_TYPE_CHART_FEATURE_FLAG
))
do
scope
:type_of_work
do
resource
:tasks_by_type
,
controller: :tasks_by_type
,
only: :show
do
get
:top_labels
end
end
end
end
resource
:ldap
,
only:
[]
do
...
...
ee/spec/controllers/analytics/tasks_by_type_controller_spec.rb
View file @
d16700bd
...
...
@@ -95,7 +95,7 @@ describe Analytics::TasksByTypeController do
it
'succeeds'
do
subject
expect
(
response
).
to
be_successful
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
).
to
match_response_schema
(
'analytics/tasks_by_type'
,
dir:
'ee'
)
end
...
...
@@ -128,7 +128,7 @@ describe Analytics::TasksByTypeController do
it
'succeeds'
do
subject
expect
(
response
).
to
be_successful
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
).
to
match_response_schema
(
'analytics/tasks_by_type_top_labels'
,
dir:
'ee'
)
end
...
...
ee/spec/controllers/groups/analytics/cycle_analytics/stages_controller_spec.rb
0 → 100644
View file @
d16700bd
# frozen_string_literal: true
require
'spec_helper'
describe
Groups
::
Analytics
::
CycleAnalytics
::
StagesController
do
let_it_be
(
:user
)
{
create
(
:user
)
}
let_it_be
(
:group
,
refind:
true
)
{
create
(
:group
)
}
let
(
:params
)
{
{
group_id:
group
}
}
before
do
stub_feature_flags
(
Gitlab
::
Analytics
::
CYCLE_ANALYTICS_FEATURE_FLAG
=>
true
)
stub_licensed_features
(
cycle_analytics_for_groups:
true
)
group
.
add_reporter
(
user
)
sign_in
(
user
)
end
describe
'GET #index'
do
subject
{
get
:index
,
params:
params
}
it
'succeeds'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
).
to
match_response_schema
(
'analytics/cycle_analytics/stages'
,
dir:
'ee'
)
end
it
'returns correct start events'
do
subject
response_start_events
=
json_response
[
'stages'
].
map
{
|
s
|
s
[
'start_event_identifier'
]
}
start_events
=
Gitlab
::
Analytics
::
CycleAnalytics
::
DefaultStages
.
all
.
map
{
|
s
|
s
[
'start_event_identifier'
]
}
expect
(
response_start_events
).
to
eq
(
start_events
)
end
it
'returns correct event names'
do
subject
response_event_names
=
json_response
[
'events'
].
map
{
|
s
|
s
[
'name'
]
}
event_names
=
Gitlab
::
Analytics
::
CycleAnalytics
::
StageEvents
.
events
.
map
(
&
:name
).
sort
expect
(
response_event_names
).
to
eq
(
event_names
)
end
it
'succeeds for subgroups'
do
subgroup
=
create
(
:group
,
parent:
group
)
params
[
:group_id
]
=
subgroup
.
full_path
subject
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
end
it
'renders `forbidden` based on the response of the service object'
do
expect_any_instance_of
(
Analytics
::
CycleAnalytics
::
Stages
::
ListService
).
to
receive
(
:can?
).
and_return
(
false
)
subject
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
include_examples
'group permission check on the controller level'
end
describe
'POST #create'
do
subject
{
post
:create
,
params:
params
}
include_examples
'group permission check on the controller level'
context
'when valid parameters are given'
do
before
do
params
.
merge!
({
name:
'my new stage'
,
start_event_identifier: :merge_request_created
,
end_event_identifier: :merge_request_merged
})
end
it
'creates the stage'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
response
).
to
match_response_schema
(
'analytics/cycle_analytics/stage'
,
dir:
'ee'
)
end
end
include_context
'when invalid stage parameters are given'
end
describe
'PUT #update'
do
let
(
:stage
)
{
create
(
:cycle_analytics_group_stage
,
parent:
group
,
relative_position:
15
)
}
subject
{
put
:update
,
params:
params
.
merge
(
id:
stage
.
id
)
}
include_examples
'group permission check on the controller level'
context
'when valid parameters are given'
do
before
do
params
.
merge!
({
name:
'my updated stage'
,
start_event_identifier: :merge_request_created
,
end_event_identifier: :merge_request_merged
})
end
it
'succeeds'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
).
to
match_response_schema
(
'analytics/cycle_analytics/stage'
,
dir:
'ee'
)
end
it
'updates the name attribute'
do
subject
stage
.
reload
expect
(
stage
.
name
).
to
eq
(
params
[
:name
])
end
context
'hidden attribute'
do
before
do
params
[
:hidden
]
=
true
end
it
'updates the hidden attribute'
do
subject
stage
.
reload
expect
(
stage
.
hidden
).
to
eq
(
true
)
end
end
context
'when positioning parameter is given'
do
before
do
params
[
:move_before_id
]
=
create
(
:cycle_analytics_group_stage
,
parent:
group
,
relative_position:
10
).
id
end
it
'moves the stage before the last place'
do
subject
before_last
=
group
.
cycle_analytics_stages
.
ordered
[
-
2
]
expect
(
before_last
.
id
).
to
eq
(
stage
.
id
)
end
end
end
include_context
'when invalid stage parameters are given'
end
describe
'DELETE #destroy'
do
let
(
:stage
)
{
create
(
:cycle_analytics_group_stage
,
parent:
group
)
}
subject
{
delete
:destroy
,
params:
params
}
before
do
params
[
:id
]
=
stage
.
id
end
include_examples
'group permission check on the controller level'
context
'when persisted stage id is passed'
do
it
'succeeds'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
end
it
'deletes the record'
do
subject
expect
(
group
.
reload
.
cycle_analytics_stages
.
find_by
(
id:
stage
.
id
)).
to
be_nil
end
end
context
'when default stage id is passed'
do
before
do
params
[
:id
]
=
Gitlab
::
Analytics
::
CycleAnalytics
::
DefaultStages
.
names
.
first
end
it
'fails with `forbidden` response'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
end
end
describe
'data endpoints'
do
let
(
:stage
)
{
create
(
:cycle_analytics_group_stage
,
parent:
group
)
}
before
do
params
[
:id
]
=
stage
.
id
end
describe
'GET #median'
do
subject
{
get
:median
,
params:
params
}
it
'matches the response schema'
do
subject
expect
(
response
).
to
match_response_schema
(
'analytics/cycle_analytics/median'
,
dir:
'ee'
)
end
include_examples
'cycle analytics data endpoint examples'
end
describe
'GET #records'
do
subject
{
get
:records
,
params:
params
}
include_examples
'cycle analytics data endpoint examples'
include_examples
'group permission check on the controller level'
end
describe
'GET #duration_chart'
do
subject
{
get
:duration_chart
,
params:
params
}
it
'matches the response schema'
do
fake_result
=
[
double
(
MergeRequest
,
duration_in_seconds:
10
,
finished_at:
Time
.
now
)]
expect_any_instance_of
(
Gitlab
::
Analytics
::
CycleAnalytics
::
DataForDurationChart
).
to
receive
(
:load
).
and_return
(
fake_result
)
subject
expect
(
response
).
to
match_response_schema
(
'analytics/cycle_analytics/duration_chart'
,
dir:
'ee'
)
end
include_examples
'cycle analytics data endpoint examples'
include_examples
'group permission check on the controller level'
end
end
end
ee/spec/controllers/groups/analytics/cycle_analytics_controller_spec.rb
deleted
100644 → 0
View file @
74e1447d
# frozen_string_literal: true
require
'spec_helper'
describe
Analytics
::
CycleAnalyticsController
do
let
(
:user
)
{
create
(
:user
)
}
before
do
sign_in
(
user
)
end
describe
'usage counter'
do
it
'increments usage counter'
do
expect
(
Gitlab
::
UsageDataCounters
::
CycleAnalyticsCounter
).
to
receive
(
:count
).
with
(
:views
)
get
(
:show
)
expect
(
response
).
to
be_successful
end
end
describe
'GET show'
do
it
'renders `show` template'
do
stub_feature_flags
(
Gitlab
::
Analytics
::
CYCLE_ANALYTICS_FEATURE_FLAG
=>
true
)
get
:show
expect
(
response
).
to
render_template
:show
end
it
'renders `404` when feature flag is disabled'
do
stub_feature_flags
(
Gitlab
::
Analytics
::
CYCLE_ANALYTICS_FEATURE_FLAG
=>
false
)
get
:show
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
end
ee/spec/controllers/groups/analytics/tasks_by_type_controller_spec.rb
0 → 100644
View file @
d16700bd
# frozen_string_literal: true
require
'spec_helper'
describe
Analytics
::
TasksByTypeController
do
let_it_be
(
:user
)
{
create
(
:user
)
}
let
(
:group
)
{
create
(
:group
)
}
let
(
:label
)
{
create
(
:group_label
,
group:
group
)
}
let!
(
:issue
)
{
create
(
:labeled_issue
,
created_at:
5
.
days
.
ago
,
project:
create
(
:project
,
group:
group
),
labels:
[
label
])
}
before
do
stub_licensed_features
(
type_of_work_analytics:
true
)
stub_feature_flags
(
Gitlab
::
Analytics
::
TASKS_BY_TYPE_CHART_FEATURE_FLAG
=>
true
)
group
.
add_reporter
(
user
)
sign_in
(
user
)
end
shared_examples
'expects unprocessable_entity response'
do
it
'returns unprocessable_entity as response'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:unprocessable_entity
)
end
end
shared_examples
'parameter validation'
do
context
'when user access level is lower than reporter'
do
before
do
group
.
add_guest
(
user
)
end
it
'returns forbidden as response'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
end
context
'when license is missing'
do
before
do
stub_licensed_features
(
type_of_work_analytics:
false
)
end
it
'returns forbidden as response'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
end
context
'when feature flag is disabled'
do
before
do
stub_feature_flags
(
Gitlab
::
Analytics
::
TASKS_BY_TYPE_CHART_FEATURE_FLAG
=>
false
)
end
it
'returns not_found as response'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
context
'when `created_after` parameter is invalid'
do
before
do
params
[
:created_after
]
=
'invalid_date'
end
it_behaves_like
'expects unprocessable_entity response'
end
context
'when `created_after` parameter is missing'
do
before
do
params
.
delete
(
:created_after
)
end
it_behaves_like
'expects unprocessable_entity response'
end
context
'when `created_after` date is later than `created_before` date'
do
before
do
params
[
:created_after
]
=
1
.
year
.
ago
.
to_date
params
[
:created_before
]
=
2
.
years
.
ago
.
to_date
end
it_behaves_like
'expects unprocessable_entity response'
end
end
describe
'GET #show'
do
let
(
:params
)
{
{
group_id:
group
,
label_ids:
[
label
.
id
],
created_after:
10
.
days
.
ago
,
subject:
'Issue'
}
}
subject
{
get
:show
,
params:
params
}
context
'when valid parameters are given'
do
it
'succeeds'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
).
to
match_response_schema
(
'analytics/tasks_by_type'
,
dir:
'ee'
)
end
it
'returns valid count'
do
subject
date
,
count
=
json_response
.
first
[
'series'
].
first
expect
(
Date
.
parse
(
date
)).
to
eq
(
issue
.
created_at
.
to_date
)
expect
(
count
).
to
eq
(
1
)
end
end
context
'when `label_id` is missing'
do
before
do
params
.
delete
(
:label_ids
)
end
it_behaves_like
'expects unprocessable_entity response'
end
it_behaves_like
'parameter validation'
end
describe
'GET #top_labels'
do
let
(
:params
)
{
{
group_id:
group
.
full_path
,
created_after:
10
.
days
.
ago
,
subject:
'Issue'
}
}
subject
{
get
:top_labels
,
params:
params
}
context
'when valid parameters are given'
do
it
'succeeds'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
).
to
match_response_schema
(
'analytics/tasks_by_type_top_labels'
,
dir:
'ee'
)
end
it
'returns valid count'
do
subject
label_item
=
json_response
.
first
expect
(
label_item
[
'title'
]).
to
eq
(
label
.
title
)
expect
(
json_response
.
count
).
to
eq
(
1
)
end
end
it_behaves_like
'parameter validation'
end
end
ee/spec/controllers/groups/cycle_analytics/events_controller_spec.rb
deleted
100644 → 0
View file @
74e1447d
# frozen_string_literal: true
require
'spec_helper'
RSpec
::
Matchers
.
define
:nested_hash_including
do
|
path_to_hash
,
value
|
match
{
|
actual
|
actual
.
dig
(
*
path_to_hash
)
==
value
}
end
describe
Groups
::
CycleAnalytics
::
EventsController
do
let
(
:group
)
{
create
(
:group
)
}
let
(
:project
)
{
create
(
:project
,
namespace:
group
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:group_service
)
{
instance_double
(
::
CycleAnalytics
::
GroupLevel
)
}
let
(
:events_service
)
{
double
}
before
do
stub_licensed_features
(
cycle_analytics_for_groups:
true
)
sign_in
(
user
)
end
describe
'cycle analytics'
do
context
'with proper permission'
do
before
do
group
.
add_owner
(
user
)
end
it
'calls service'
do
expect
(
events_service
).
to
receive
(
:events
)
expect
(
group_service
).
to
receive
(
:[]
).
and_return
(
events_service
)
expect
(
::
CycleAnalytics
::
GroupLevel
).
to
receive
(
:new
).
and_return
(
group_service
)
get
(
:issue
,
params:
{
group_id:
group
.
name
},
format: :json
)
expect
(
response
).
to
be_successful
end
it
'calls service with specific params'
do
expect
(
events_service
).
to
receive
(
:events
)
expect
(
group_service
).
to
receive
(
:[]
).
and_return
(
events_service
)
expect
(
::
CycleAnalytics
::
GroupLevel
).
to
receive
(
:new
)
.
with
(
nested_hash_including
([
:options
,
:projects
],
[
project
.
id
.
to_s
]))
.
and_return
(
group_service
)
get
(
:issue
,
params:
{
group_id:
group
.
name
,
project_ids:
[
project
.
id
]
},
format: :json
)
expect
(
response
).
to
be_successful
end
end
context
'as guest'
do
before
do
group
.
add_guest
(
user
)
end
it
'returns 403'
do
get
(
:issue
,
params:
{
group_id:
group
.
name
},
format: :json
)
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
end
end
end
ee/spec/controllers/groups/cycle_analytics_controller_spec.rb
deleted
100644 → 0
View file @
74e1447d
# frozen_string_literal: true
require
'spec_helper'
RSpec
::
Matchers
.
define
:nested_hash_including
do
|
path_to_hash
,
value
|
match
{
|
actual
|
actual
.
dig
(
*
path_to_hash
)
==
value
}
end
describe
Groups
::
CycleAnalyticsController
do
let
(
:group
)
{
create
(
:group
)
}
let
(
:project
)
{
create
(
:project
,
namespace:
group
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:group_service
)
{
instance_double
(
::
CycleAnalytics
::
GroupLevel
)
}
before
do
stub_licensed_features
(
cycle_analytics_for_groups:
true
)
sign_in
(
user
)
end
describe
'cycle analytics'
do
context
'with proper permission'
do
before
do
group
.
add_owner
(
user
)
end
it
'calls service'
do
expect
(
group_service
).
to
receive
(
:summary
)
expect
(
group_service
).
to
receive
(
:stats
)
expect
(
group_service
).
to
receive
(
:permissions
)
expect
(
::
CycleAnalytics
::
GroupLevel
).
to
receive
(
:new
).
and_return
(
group_service
)
get
(
:show
,
params:
{
group_id:
group
.
name
},
format: :json
)
expect
(
response
).
to
be_successful
end
it
'calls service with specific params'
do
expect
(
group_service
).
to
receive
(
:summary
)
expect
(
group_service
).
to
receive
(
:stats
)
expect
(
group_service
).
to
receive
(
:permissions
)
expect
(
::
CycleAnalytics
::
GroupLevel
).
to
receive
(
:new
)
.
with
(
nested_hash_including
([
:options
,
:projects
],
[
project
.
id
.
to_s
]))
.
and_return
(
group_service
)
get
(
:show
,
params:
{
group_id:
group
.
name
,
project_ids:
[
project
.
id
]
},
format: :json
)
expect
(
response
).
to
be_successful
end
end
context
'as guest'
do
before
do
group
.
add_guest
(
user
)
end
it
'returns 403'
do
get
(
:show
,
params:
{
group_id:
group
.
name
},
format: :json
)
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
end
end
end
ee/spec/frontend/analytics/cycle_analytics/store/actions_spec.js
View file @
d16700bd
...
...
@@ -33,7 +33,8 @@ const selectedGroup = { fullPath: group.path };
const
[
selectedStage
]
=
stages
;
const
selectedStageSlug
=
selectedStage
.
slug
;
const
stageEndpoint
=
({
stageId
})
=>
`/-/analytics/value_stream_analytics/stages/
${
stageId
}
`
;
const
stageEndpoint
=
({
stageId
})
=>
`/groups/
${
group
.
full_path
}
/-/analytics/value_stream_analytics/stages/
${
stageId
}
`
;
describe
(
'
Cycle analytics actions
'
,
()
=>
{
let
state
;
...
...
ee/spec/frontend/api_spec.js
View file @
d16700bd
...
...
@@ -276,8 +276,8 @@ describe('Api', () => {
const
createdBefore
=
'
2019-11-18
'
;
const
createdAfter
=
'
2019-08-18
'
;
const
stageId
=
'
thursday
'
;
const
dummyCycleAnalyticsUrlRoot
=
`
${
dummyUrlRoot
}
/groups/
${
groupId
}
`
;
const
defaultParams
=
{
group_id
:
groupId
,
created_after
:
createdAfter
,
created_before
:
createdBefore
,
};
...
...
@@ -321,7 +321,7 @@ describe('Api', () => {
const
expectedUrl
=
analyticsMockData
.
endpoints
.
tasksByTypeData
;
mock
.
onGet
(
expectedUrl
).
reply
(
200
,
tasksByTypeResponse
);
Api
.
cycleAnalyticsTasksByType
(
params
)
Api
.
cycleAnalyticsTasksByType
(
groupId
,
params
)
.
then
(({
data
,
config
:
{
params
:
reqParams
}
})
=>
{
expect
(
data
).
toEqual
(
tasksByTypeResponse
);
expect
(
reqParams
).
toEqual
(
params
);
...
...
@@ -345,7 +345,7 @@ describe('Api', () => {
const
expectedUrl
=
analyticsMockData
.
endpoints
.
tasksByTypeTopLabelsData
;
mock
.
onGet
(
expectedUrl
).
reply
(
200
,
response
);
Api
.
cycleAnalyticsTopLabels
(
params
)
Api
.
cycleAnalyticsTopLabels
(
groupId
,
params
)
.
then
(({
data
,
config
:
{
url
,
params
:
reqParams
}
})
=>
{
expect
(
data
).
toEqual
(
response
);
expect
(
url
).
toMatch
(
expectedUrl
);
...
...
@@ -363,10 +363,10 @@ describe('Api', () => {
...
defaultParams
,
};
const
expectedUrl
=
`
${
dummyUrlRoot
}
/-/analytics/value_stream_analytics/summary`
;
const
expectedUrl
=
`
${
dummy
CycleAnalytics
UrlRoot
}
/-/analytics/value_stream_analytics/summary`
;
mock
.
onGet
(
expectedUrl
).
reply
(
200
,
response
);
Api
.
cycleAnalyticsSummaryData
(
params
)
Api
.
cycleAnalyticsSummaryData
(
groupId
,
params
)
.
then
(
responseObj
=>
expectRequestWithCorrectParameters
(
responseObj
,
{
response
,
...
...
@@ -387,7 +387,7 @@ describe('Api', () => {
'
cycle_analytics[created_after]
'
:
createdAfter
,
'
cycle_analytics[created_before]
'
:
createdBefore
,
};
const
expectedUrl
=
`
${
dummyUrlRoot
}
/-/analytics/value_stream_analytics/stages`
;
const
expectedUrl
=
`
${
dummy
CycleAnalytics
UrlRoot
}
/-/analytics/value_stream_analytics/stages`
;
mock
.
onGet
(
expectedUrl
).
reply
(
200
,
response
);
Api
.
cycleAnalyticsGroupStagesAndEvents
(
groupId
,
params
)
...
...
@@ -409,7 +409,7 @@ describe('Api', () => {
const
params
=
{
...
defaultParams
,
};
const
expectedUrl
=
`
${
dummyUrlRoot
}
/-/analytics/value_stream_analytics/stages/
${
stageId
}
/records`
;
const
expectedUrl
=
`
${
dummy
CycleAnalytics
UrlRoot
}
/-/analytics/value_stream_analytics/stages/
${
stageId
}
/records`
;
mock
.
onGet
(
expectedUrl
).
reply
(
200
,
response
);
Api
.
cycleAnalyticsStageEvents
(
groupId
,
stageId
,
params
)
...
...
@@ -431,7 +431,7 @@ describe('Api', () => {
const
params
=
{
...
defaultParams
,
};
const
expectedUrl
=
`
${
dummyUrlRoot
}
/-/analytics/value_stream_analytics/stages/
${
stageId
}
/median`
;
const
expectedUrl
=
`
${
dummy
CycleAnalytics
UrlRoot
}
/-/analytics/value_stream_analytics/stages/
${
stageId
}
/median`
;
mock
.
onGet
(
expectedUrl
).
reply
(
200
,
response
);
Api
.
cycleAnalyticsStageMedian
(
groupId
,
stageId
,
params
)
...
...
@@ -457,13 +457,12 @@ describe('Api', () => {
end_event_identifier
:
'
issue_closed
'
,
end_event_label_id
:
null
,
};
const
expectedUrl
=
`
${
dummyUrlRoot
}
/-/analytics/value_stream_analytics/stages`
;
const
expectedUrl
=
`
${
dummy
CycleAnalytics
UrlRoot
}
/-/analytics/value_stream_analytics/stages`
;
mock
.
onPost
(
expectedUrl
).
reply
(
200
,
response
);
Api
.
cycleAnalyticsCreateStage
(
groupId
,
customStage
)
.
then
(({
data
,
config
:
{
params
:
reqParams
,
data
:
reqData
,
url
}
})
=>
{
.
then
(({
data
,
config
:
{
data
:
reqData
,
url
}
})
=>
{
expect
(
data
).
toEqual
(
response
);
expect
(
reqParams
).
toEqual
({
group_id
:
groupId
});
expect
(
JSON
.
parse
(
reqData
)).
toMatchObject
(
customStage
);
expect
(
url
).
toEqual
(
expectedUrl
);
})
...
...
@@ -479,13 +478,12 @@ describe('Api', () => {
name
:
'
nice-stage
'
,
hidden
:
true
,
};
const
expectedUrl
=
`
${
dummyUrlRoot
}
/-/analytics/value_stream_analytics/stages/
${
stageId
}
`
;
const
expectedUrl
=
`
${
dummy
CycleAnalytics
UrlRoot
}
/-/analytics/value_stream_analytics/stages/
${
stageId
}
`
;
mock
.
onPut
(
expectedUrl
).
reply
(
200
,
response
);
Api
.
cycleAnalyticsUpdateStage
(
stageId
,
groupId
,
stageData
)
.
then
(({
data
,
config
:
{
params
:
reqParams
,
data
:
reqData
,
url
}
})
=>
{
.
then
(({
data
,
config
:
{
data
:
reqData
,
url
}
})
=>
{
expect
(
data
).
toEqual
(
response
);
expect
(
reqParams
).
toEqual
({
group_id
:
groupId
});
expect
(
JSON
.
parse
(
reqData
)).
toMatchObject
(
stageData
);
expect
(
url
).
toEqual
(
expectedUrl
);
})
...
...
@@ -497,13 +495,12 @@ describe('Api', () => {
describe
(
'
cycleAnalyticsRemoveStage
'
,
()
=>
{
it
(
'
deletes the specified data
'
,
done
=>
{
const
response
=
{
id
:
stageId
,
hidden
:
true
,
custom
:
true
};
const
expectedUrl
=
`
${
dummyUrlRoot
}
/-/analytics/value_stream_analytics/stages/
${
stageId
}
`
;
const
expectedUrl
=
`
${
dummy
CycleAnalytics
UrlRoot
}
/-/analytics/value_stream_analytics/stages/
${
stageId
}
`
;
mock
.
onDelete
(
expectedUrl
).
reply
(
200
,
response
);
Api
.
cycleAnalyticsRemoveStage
(
stageId
,
groupId
)
.
then
(({
data
,
config
:
{
params
:
reqParams
,
url
}
})
=>
{
.
then
(({
data
,
config
:
{
url
}
})
=>
{
expect
(
data
).
toEqual
(
response
);
expect
(
reqParams
).
toEqual
({
group_id
:
groupId
});
expect
(
url
).
toEqual
(
expectedUrl
);
})
...
...
@@ -518,10 +515,10 @@ describe('Api', () => {
const
params
=
{
...
defaultParams
,
};
const
expectedUrl
=
`
${
dummyUrlRoot
}
/-/analytics/value_stream_analytics/stages/thursday/duration_chart`
;
const
expectedUrl
=
`
${
dummy
CycleAnalytics
UrlRoot
}
/-/analytics/value_stream_analytics/stages/thursday/duration_chart`
;
mock
.
onGet
(
expectedUrl
).
reply
(
200
,
response
);
Api
.
cycleAnalyticsDurationChart
(
stageId
,
params
)
Api
.
cycleAnalyticsDurationChart
(
groupId
,
stageId
,
params
)
.
then
(
responseObj
=>
expectRequestWithCorrectParameters
(
responseObj
,
{
response
,
...
...
ee/spec/frontend/fixtures/analytics.rb
View file @
d16700bd
...
...
@@ -125,51 +125,6 @@ describe 'Analytics (JavaScript fixtures)', :sidekiq_inline do
clean_frontend_fixtures
(
'cycle_analytics/'
)
end
default_stages
=
%w[issue plan review code test staging production]
describe
Groups
::
CycleAnalytics
::
EventsController
,
type: :controller
do
render_views
before
do
stub_licensed_features
(
cycle_analytics_for_groups:
true
)
prepare_cycle_analytics_data
create_deployment
sign_in
(
user
)
end
default_stages
.
each
do
|
endpoint
|
it
"value_stream_analytics/events/
#{
endpoint
}
.json"
do
get
endpoint
,
params:
{
group_id:
group
,
format: :json
}
expect
(
response
).
to
be_successful
end
end
end
describe
Groups
::
CycleAnalyticsController
,
type: :controller
do
render_views
before
do
stub_licensed_features
(
cycle_analytics_for_groups:
true
)
prepare_cycle_analytics_data
create_deployment
sign_in
(
user
)
end
it
'value_stream_analytics/mock_data.json'
do
get
(
:show
,
params:
{
group_id:
group
.
name
,
cycle_analytics:
{
start_date:
30
}
},
format: :json
)
expect
(
response
).
to
be_successful
end
end
describe
Analytics
::
CycleAnalytics
::
StagesController
,
type: :controller
do
render_views
...
...
ee/spec/requests/groups/cycle_analytics_events_spec.rb
deleted
100644 → 0
View file @
74e1447d
# frozen_string_literal: true
require
'spec_helper'
describe
'value stream analytics events'
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:group
)
{
create
(
:group
)}
let
(
:project
)
{
create
(
:project
,
:repository
,
namespace:
group
,
public_builds:
false
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project
,
created_at:
2
.
days
.
ago
)
}
describe
'GET /:namespace/-/value_stream_analytics/events/:stage'
do
before
do
stub_licensed_features
(
cycle_analytics_for_groups:
true
)
group
.
add_developer
(
user
)
project
.
add_developer
(
user
)
3
.
times
do
|
count
|
Timecop
.
freeze
(
Time
.
now
+
count
.
days
)
do
create_cycle
end
end
deploy_master
(
user
,
project
)
login_as
(
user
)
end
context
'when date range parameters are given'
do
it
'filter by `created_after`'
do
params
=
{
created_after:
issue
.
created_at
-
5
.
days
}
get
group_cycle_analytics_issue_path
(
group
,
params:
params
,
format: :json
)
expect
(
json_response
[
'events'
]).
not_to
be_empty
end
it
'filters by `created_after` where no events should be found'
do
params
=
{
created_after:
issue
.
created_at
+
5
.
days
}
get
group_cycle_analytics_issue_path
(
group
,
params:
params
,
format: :json
)
expect
(
json_response
[
'events'
]).
to
be_empty
end
it
'filter by `created_after` and `created_before`'
do
params
=
{
created_after:
issue
.
created_at
-
5
.
days
,
created_before:
issue
.
created_at
+
5
.
days
}
get
group_cycle_analytics_issue_path
(
group
,
params:
params
,
format: :json
)
expect
(
json_response
[
'events'
]).
not_to
be_empty
end
it
'raises error when date cannot be parsed'
do
params
=
{
created_after:
'invalid'
}
expect
do
get
group_cycle_analytics_issue_path
(
group
,
params:
params
,
format: :json
)
end
.
to
raise_error
(
ArgumentError
)
end
end
it
'lists the issue events'
do
get
group_cycle_analytics_issue_path
(
group
,
format: :json
)
first_issue_iid
=
project
.
issues
.
sort_by_attribute
(
:created_desc
).
pluck
(
:iid
).
first
.
to_s
expect
(
json_response
[
'events'
]).
not_to
be_empty
expect
(
json_response
[
'events'
].
first
[
'iid'
]).
to
eq
(
first_issue_iid
)
end
it
'lists the plan events'
do
get
group_cycle_analytics_plan_path
(
group
,
format: :json
)
first_issue_iid
=
project
.
issues
.
sort_by_attribute
(
:created_desc
).
pluck
(
:iid
).
first
.
to_s
expect
(
json_response
[
'events'
]).
not_to
be_empty
expect
(
json_response
[
'events'
].
first
[
'iid'
]).
to
eq
(
first_issue_iid
)
end
it
'lists the code events'
do
get
group_cycle_analytics_code_path
(
group
,
format: :json
)
expect
(
json_response
[
'events'
]).
not_to
be_empty
first_mr_iid
=
project
.
merge_requests
.
sort_by_attribute
(
:created_desc
).
pluck
(
:iid
).
first
.
to_s
expect
(
json_response
[
'events'
].
first
[
'iid'
]).
to
eq
(
first_mr_iid
)
end
it
'lists the test events'
,
:sidekiq_might_not_need_inline
do
get
group_cycle_analytics_test_path
(
group
,
format: :json
)
expect
(
json_response
[
'events'
]).
not_to
be_empty
expect
(
json_response
[
'events'
].
first
[
'date'
]).
not_to
be_empty
end
it
'lists the review events'
do
get
group_cycle_analytics_review_path
(
group
,
format: :json
)
first_mr_iid
=
project
.
merge_requests
.
sort_by_attribute
(
:created_desc
).
pluck
(
:iid
).
first
.
to_s
expect
(
json_response
[
'events'
]).
not_to
be_empty
expect
(
json_response
[
'events'
].
first
[
'iid'
]).
to
eq
(
first_mr_iid
)
end
it
'lists the staging events'
,
:sidekiq_might_not_need_inline
do
get
group_cycle_analytics_staging_path
(
group
,
format: :json
)
expect
(
json_response
[
'events'
]).
not_to
be_empty
expect
(
json_response
[
'events'
].
first
[
'date'
]).
not_to
be_empty
end
it
'lists the production events'
,
:sidekiq_might_not_need_inline
do
get
group_cycle_analytics_production_path
(
group
,
format: :json
)
first_issue_iid
=
project
.
issues
.
sort_by_attribute
(
:created_desc
).
pluck
(
:iid
).
first
.
to_s
expect
(
json_response
[
'events'
]).
not_to
be_empty
expect
(
json_response
[
'events'
].
first
[
'iid'
]).
to
eq
(
first_issue_iid
)
end
context
'specific branch'
do
it
'lists the test events'
,
:sidekiq_might_not_need_inline
do
branch
=
project
.
merge_requests
.
first
.
source_branch
get
group_cycle_analytics_test_path
(
group
,
format: :json
,
branch:
branch
)
expect
(
json_response
[
'events'
]).
not_to
be_empty
expect
(
json_response
[
'events'
].
first
[
'date'
]).
not_to
be_empty
end
end
end
def
create_cycle
milestone
=
create
(
:milestone
,
project:
project
)
issue
.
update
(
milestone:
milestone
)
mr
=
create_merge_request_closing_issue
(
user
,
project
,
issue
,
commit_message:
"References
#{
issue
.
to_reference
}
"
)
pipeline
=
create
(
:ci_empty_pipeline
,
status:
'created'
,
project:
project
,
ref:
mr
.
source_branch
,
sha:
mr
.
source_branch_sha
,
head_pipeline_of:
mr
)
pipeline
.
run
create
(
:ci_build
,
pipeline:
pipeline
,
status: :success
,
author:
user
)
create
(
:ci_build
,
pipeline:
pipeline
,
status: :success
,
author:
user
)
merge_merge_requests_closing_issue
(
user
,
project
,
issue
)
ProcessCommitWorker
.
new
.
perform
(
project
.
id
,
user
.
id
,
mr
.
commits
.
last
.
to_hash
)
end
end
ee/spec/support/shared_examples/controllers/analytics/cycle_analytics/shared_stage_shared_examples.rb
View file @
d16700bd
# frozen_string_literal: true
RSpec
.
shared_examples
'group permission check on the controller level'
do
context
'when `group_id` is not provided'
do
before
do
params
[
:group_id
]
=
nil
end
it
'renders `not_found` when group_id is not provided'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
context
'when `group_id` is not found'
do
before
do
params
[
:group_id
]
=
'missing_group'
...
...
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