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
ae256731
Commit
ae256731
authored
Oct 18, 2019
by
Adam Hegyi
Committed by
Michael Kozono
Oct 18, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Expose CA stage services via API
- Add create, update, destroy actions - Implement delete service
parent
ee421052
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
357 additions
and
102 deletions
+357
-102
ee/app/controllers/analytics/cycle_analytics/stages_controller.rb
...ontrollers/analytics/cycle_analytics/stages_controller.rb
+43
-10
ee/app/serializers/analytics/cycle_analytics/stage_entity.rb
ee/app/serializers/analytics/cycle_analytics/stage_entity.rb
+2
-2
ee/app/services/analytics/cycle_analytics/stages/base_service.rb
...services/analytics/cycle_analytics/stages/base_service.rb
+36
-34
ee/app/services/analytics/cycle_analytics/stages/delete_service.rb
...rvices/analytics/cycle_analytics/stages/delete_service.rb
+23
-0
ee/config/routes/analytics.rb
ee/config/routes/analytics.rb
+1
-1
ee/spec/controllers/analytics/cycle_analytics/stages_controller_spec.rb
...llers/analytics/cycle_analytics/stages_controller_spec.rb
+114
-54
ee/spec/fixtures/api/schemas/analytics/cycle_analytics/stage.json
...fixtures/api/schemas/analytics/cycle_analytics/stage.json
+1
-1
ee/spec/fixtures/api/schemas/analytics/cycle_analytics/validation_error.json
...i/schemas/analytics/cycle_analytics/validation_error.json
+19
-0
ee/spec/services/analytics/cycle_analytics/stages/delete_service_spec.rb
...s/analytics/cycle_analytics/stages/delete_service_spec.rb
+39
-0
ee/spec/support/shared_examples/controllers/analytics/cycle_analytics/shared_stage_examples.rb
...ollers/analytics/cycle_analytics/shared_stage_examples.rb
+79
-0
No files found.
ee/app/controllers/analytics/cycle_analytics/stages_controller.rb
View file @
ae256731
...
@@ -6,10 +6,11 @@ module Analytics
...
@@ -6,10 +6,11 @@ module Analytics
check_feature_flag
Gitlab
::
Analytics
::
CYCLE_ANALYTICS_FEATURE_FLAG
check_feature_flag
Gitlab
::
Analytics
::
CYCLE_ANALYTICS_FEATURE_FLAG
before_action
:load_group
before_action
:load_group
before_action
:authorize_access!
def
index
def
index
result
=
stage_list_service
.
execute
return
render_403
unless
can?
(
current_user
,
:read_group_cycle_analytics
,
@group
)
result
=
list_service
.
execute
if
result
.
success?
if
result
.
success?
render
json:
cycle_analytics_configuration
(
result
.
payload
[
:stages
])
render
json:
cycle_analytics_configuration
(
result
.
payload
[
:stages
])
...
@@ -18,23 +19,55 @@ module Analytics
...
@@ -18,23 +19,55 @@ module Analytics
end
end
end
end
private
def
create
return
render_403
unless
can?
(
current_user
,
:create_group_stage
,
@group
)
render_stage_service_result
(
create_service
.
execute
)
end
def
update
return
render_403
unless
can?
(
current_user
,
:update_group_stage
,
@group
)
def
authorize_access!
render_stage_service_result
(
update_service
.
execute
)
render_403
unless
can?
(
current_user
,
:read_group_cycle_analytics
,
@group
)
end
end
def
destroy
return
render_403
unless
can?
(
current_user
,
:delete_group_stage
,
@group
)
render_stage_service_result
(
delete_service
.
execute
)
end
private
def
cycle_analytics_configuration
(
stages
)
def
cycle_analytics_configuration
(
stages
)
stage_presenters
=
stages
.
map
{
|
s
|
StagePresenter
.
new
(
s
)
}
stage_presenters
=
stages
.
map
{
|
s
|
StagePresenter
.
new
(
s
)
}
Analytics
::
CycleAnalytics
::
ConfigurationEntity
.
new
(
stages:
stage_presenters
)
Analytics
::
CycleAnalytics
::
ConfigurationEntity
.
new
(
stages:
stage_presenters
)
end
end
def
stage_list_service
def
list_service
Analytics
::
CycleAnalytics
::
Stages
::
ListService
.
new
(
Stages
::
ListService
.
new
(
parent:
@group
,
current_user:
current_user
)
parent:
@group
,
end
current_user:
current_user
)
def
create_service
Stages
::
CreateService
.
new
(
parent:
@group
,
current_user:
current_user
,
params:
params
.
permit
(
:name
,
:start_event_identifier
,
:end_event_identifier
))
end
def
update_service
Stages
::
UpdateService
.
new
(
parent:
@group
,
current_user:
current_user
,
params:
params
.
permit
(
:name
,
:start_event_identifier
,
:end_event_identifier
,
:id
))
end
def
delete_service
Stages
::
DeleteService
.
new
(
parent:
@group
,
current_user:
current_user
,
params:
params
.
permit
(
:id
))
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
else
render
json:
{
message:
result
.
message
,
errors:
result
.
payload
[
:errors
]
},
status:
result
.
http_status
end
end
end
end
end
end
end
...
...
ee/app/serializers/analytics/cycle_analytics/stage_entity.rb
View file @
ae256731
...
@@ -8,8 +8,8 @@ module Analytics
...
@@ -8,8 +8,8 @@ module Analytics
expose
:description
expose
:description
expose
:id
expose
:id
expose
:custom
expose
:custom
expose
:start_event_identifier
,
if:
:custom?
expose
:start_event_identifier
,
if:
->
(
s
)
{
s
.
custom?
}
expose
:end_event_identifier
,
if:
:custom?
expose
:end_event_identifier
,
if:
->
(
s
)
{
s
.
custom?
}
def
id
def
id
object
.
id
||
object
.
name
object
.
id
||
object
.
name
...
...
ee/app/services/analytics/cycle_analytics/stages/base_service.rb
View file @
ae256731
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
module
Analytics
module
Analytics
module
CycleAnalytics
module
CycleAnalytics
module
Stages
class
BaseService
class
BaseService
include
Gitlab
::
Allowable
include
Gitlab
::
Allowable
...
@@ -52,4 +53,5 @@ module Analytics
...
@@ -52,4 +53,5 @@ module Analytics
end
end
end
end
end
end
end
end
end
ee/app/services/analytics/cycle_analytics/stages/delete_service.rb
0 → 100644
View file @
ae256731
# frozen_string_literal: true
module
Analytics
module
CycleAnalytics
module
Stages
class
DeleteService
<
BaseService
def
initialize
(
parent
:,
current_user
:,
params
:)
super
@stage
=
Analytics
::
CycleAnalytics
::
StageFinder
.
new
(
parent:
parent
,
stage_id:
params
[
:id
]).
execute
end
def
execute
return
forbidden
if
!
can?
(
current_user
,
:delete_group_stage
,
parent
)
||
@stage
.
default_stage?
@stage
.
destroy!
success
(
@stage
,
:ok
)
end
end
end
end
end
ee/config/routes/analytics.rb
View file @
ae256731
...
@@ -10,7 +10,7 @@ namespace :analytics do
...
@@ -10,7 +10,7 @@ namespace :analytics do
constraints
(
::
Constraints
::
FeatureConstrainer
.
new
(
Gitlab
::
Analytics
::
CYCLE_ANALYTICS_FEATURE_FLAG
))
do
constraints
(
::
Constraints
::
FeatureConstrainer
.
new
(
Gitlab
::
Analytics
::
CYCLE_ANALYTICS_FEATURE_FLAG
))
do
resource
:cycle_analytics
,
only: :show
resource
:cycle_analytics
,
only: :show
namespace
:cycle_analytics
do
namespace
:cycle_analytics
do
resources
:stages
,
only:
[
:index
]
resources
:stages
,
only:
[
:index
,
:create
,
:update
,
:destroy
]
end
end
end
end
...
...
ee/spec/controllers/analytics/cycle_analytics/stages_controller_spec.rb
View file @
ae256731
...
@@ -3,12 +3,10 @@
...
@@ -3,12 +3,10 @@
require
'spec_helper'
require
'spec_helper'
describe
Analytics
::
CycleAnalytics
::
StagesController
do
describe
Analytics
::
CycleAnalytics
::
StagesController
do
let
(
:user
)
{
create
(
:user
)
}
let
_it_be
(
:user
)
{
create
(
:user
)
}
let
(
:group
)
{
create
(
:group
)
}
let
_it_be
(
:group
,
refind:
true
)
{
create
(
:group
)
}
let
(
:params
)
{
{
group_id:
group
.
full_path
}
}
let
(
:params
)
{
{
group_id:
group
.
full_path
}
}
subject
{
get
:index
,
params:
params
}
before
do
before
do
stub_feature_flags
(
Gitlab
::
Analytics
::
CYCLE_ANALYTICS_FEATURE_FLAG
=>
true
)
stub_feature_flags
(
Gitlab
::
Analytics
::
CYCLE_ANALYTICS_FEATURE_FLAG
=>
true
)
stub_licensed_features
(
cycle_analytics_for_groups:
true
)
stub_licensed_features
(
cycle_analytics_for_groups:
true
)
...
@@ -17,6 +15,9 @@ describe Analytics::CycleAnalytics::StagesController do
...
@@ -17,6 +15,9 @@ describe Analytics::CycleAnalytics::StagesController do
sign_in
(
user
)
sign_in
(
user
)
end
end
describe
'GET `index`'
do
subject
{
get
:index
,
params:
params
}
it
'succeeds'
do
it
'succeeds'
do
subject
subject
...
@@ -51,52 +52,111 @@ describe Analytics::CycleAnalytics::StagesController do
...
@@ -51,52 +52,111 @@ describe Analytics::CycleAnalytics::StagesController do
expect
(
response
).
to
be_successful
expect
(
response
).
to
be_successful
end
end
it
'renders 404 when group_id is not provided
'
do
it
'renders `forbidden` based on the response of the service object
'
do
params
[
:group_id
]
=
nil
expect_any_instance_of
(
Analytics
::
CycleAnalytics
::
Stages
::
ListService
).
to
receive
(
:can?
).
and_return
(
false
)
subject
subject
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
include_examples
'group permission check on the controller level'
end
end
it
'renders 404 when group is missing'
do
describe
'POST `create`'
do
params
[
:group_id
]
=
'missing_group'
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
subject
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
expect
(
response
).
to
be_successful
expect
(
response
).
to
match_response_schema
(
'analytics/cycle_analytics/stage'
,
dir:
'ee'
)
end
end
include_context
'when invalid stage parameters are given'
end
end
it
'renders 404 when feature flag is disabled'
do
describe
'PUT `update`'
do
stub_feature_flags
(
Gitlab
::
Analytics
::
CYCLE_ANALYTICS_FEATURE_FLAG
=>
false
)
let
(
:stage
)
{
create
(
:cycle_analytics_group_stage
,
parent:
group
)
}
subject
{
put
:update
,
params:
params
.
merge
(
id:
stage
.
id
)
}
subject
include_examples
'group permission check on the controller level'
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
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
end
it
'renders 403 when user has no reporter access'
do
it
'succeeds'
do
GroupMember
.
where
(
user:
user
).
delete_all
subject
group
.
add_guest
(
user
)
expect
(
response
).
to
be_successful
expect
(
response
).
to
match_response_schema
(
'analytics/cycle_analytics/stage'
,
dir:
'ee'
)
end
it
'updates the name attribute'
do
subject
subject
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
stage
.
reload
expect
(
stage
.
name
).
to
eq
(
params
[
:name
])
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
end
it
'renders 403 when feature is not available for the group'
do
include_examples
'group permission check on the controller level'
stub_licensed_features
(
cycle_analytics_for_groups:
false
)
context
'when persisted stage id is passed'
do
it
'succeeds'
do
subject
subject
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
expect
(
response
).
to
be_successful
end
end
it
'renders 403 based on the response of the service object'
do
it
'deletes the record'
do
expect_any_instance_of
(
Analytics
::
CycleAnalytics
::
Stages
::
ListService
).
to
receive
(
:can?
).
and_return
(
false
)
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
subject
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
end
end
end
end
end
ee/spec/fixtures/api/schemas/analytics/cycle_analytics/stage.json
View file @
ae256731
...
@@ -21,5 +21,5 @@
...
@@ -21,5 +21,5 @@
"type"
:
"boolean"
"type"
:
"boolean"
}
}
},
},
"additionalProperties"
:
fals
e
"additionalProperties"
:
tru
e
}
}
ee/spec/fixtures/api/schemas/analytics/cycle_analytics/validation_error.json
0 → 100644
View file @
ae256731
{
"type"
:
"object"
,
"properties"
:
{
"message"
:
{
"type"
:
"string"
},
"errors"
:
{
"type"
:
"object"
,
"additionalProperties"
:
{
"type"
:
"array"
,
"items"
:
{
"type"
:
"string"
}
}
}
},
"required"
:
[
"message"
,
"errors"
],
"additionalProperties"
:
false
}
ee/spec/services/analytics/cycle_analytics/stages/delete_service_spec.rb
0 → 100644
View file @
ae256731
# frozen_string_literal: true
require
'spec_helper'
describe
Analytics
::
CycleAnalytics
::
Stages
::
DeleteService
do
let_it_be
(
:group
,
refind:
true
)
{
create
(
:group
)
}
let_it_be
(
:user
,
refind:
true
)
{
create
(
:user
)
}
let_it_be
(
:stage
,
refind:
true
)
{
create
(
:cycle_analytics_group_stage
,
group:
group
)
}
let
(
:params
)
{
{
id:
stage
.
id
}
}
subject
{
described_class
.
new
(
parent:
group
,
params:
params
,
current_user:
user
).
execute
}
before_all
do
group
.
add_user
(
user
,
:reporter
)
end
before
do
stub_licensed_features
(
cycle_analytics_for_groups:
true
)
end
it_behaves_like
'permission check for cycle analytics stage services'
,
:cycle_analytics_for_groups
context
'when persisted stage is given'
do
it
{
expect
(
subject
).
to
be_success
}
it
'deletes the stage'
do
subject
expect
(
group
.
cycle_analytics_stages
.
find_by
(
id:
stage
.
id
)).
to
be_nil
end
end
context
'disallows deletion when default stage is given'
do
let_it_be
(
:stage
,
refind:
true
)
{
create
(
:cycle_analytics_group_stage
,
group:
group
,
custom:
false
)
}
it
{
expect
(
subject
).
not_to
be_success
}
it
{
expect
(
subject
.
http_status
).
to
eq
(
:forbidden
)
}
end
end
ee/spec/support/shared_examples/controllers/analytics/cycle_analytics/shared_stage_examples.rb
0 → 100644
View file @
ae256731
# frozen_string_literal: true
require
'spec_helper'
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'
end
it
'renders `not_found` when group is missing'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
context
'when feature flag is disabled'
do
before
do
stub_feature_flags
(
Gitlab
::
Analytics
::
CYCLE_ANALYTICS_FEATURE_FLAG
=>
false
)
end
it
'renders `not_found` response'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
context
'when user has no lower access level than `reporter`'
do
before
do
GroupMember
.
where
(
user:
user
).
delete_all
group
.
add_guest
(
user
)
end
it
'renders `forbidden` response'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
end
context
'when feature is not available for the group'
do
before
do
stub_licensed_features
(
cycle_analytics_for_groups:
false
)
end
it
'renders `forbidden` response'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
end
end
shared_context
'when invalid stage parameters are given'
do
before
do
params
[
:name
]
=
''
end
it
'renders the validation errors'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:unprocessable_entity
)
expect
(
response
).
to
match_response_schema
(
'analytics/cycle_analytics/validation_error'
,
dir:
'ee'
)
end
end
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