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
d1cea4d8
Commit
d1cea4d8
authored
Mar 15, 2021
by
Jan Provaznik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow to delete epic boards
Adds GraphQL mutation and epic board service for destroying epic boards.
parent
76ebd961
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
254 additions
and
40 deletions
+254
-40
app/services/boards/destroy_service.rb
app/services/boards/destroy_service.rb
+7
-1
doc/api/graphql/reference/index.md
doc/api/graphql/reference/index.md
+10
-0
ee/app/graphql/ee/types/mutation_type.rb
ee/app/graphql/ee/types/mutation_type.rb
+2
-1
ee/app/graphql/mutations/boards/epic_boards/destroy.rb
ee/app/graphql/mutations/boards/epic_boards/destroy.rb
+40
-0
ee/app/services/boards/epic_boards/destroy_service.rb
ee/app/services/boards/epic_boards/destroy_service.rb
+14
-0
ee/spec/graphql/mutations/boards/epic_boards/destroy_spec.rb
ee/spec/graphql/mutations/boards/epic_boards/destroy_spec.rb
+45
-0
ee/spec/requests/api/graphql/mutations/boards/epic_boards/destroy_spec.rb
.../api/graphql/mutations/boards/epic_boards/destroy_spec.rb
+74
-0
ee/spec/services/boards/destroy_service_spec.rb
ee/spec/services/boards/destroy_service_spec.rb
+0
-38
ee/spec/services/boards/epic_boards/destroy_service_spec.rb
ee/spec/services/boards/epic_boards/destroy_service_spec.rb
+11
-0
spec/services/boards/destroy_service_spec.rb
spec/services/boards/destroy_service_spec.rb
+21
-0
spec/support/shared_examples/boards/destroy_service_shared_examples.rb
...shared_examples/boards/destroy_service_shared_examples.rb
+30
-0
No files found.
app/services/boards/destroy_service.rb
View file @
d1cea4d8
...
...
@@ -3,7 +3,7 @@
module
Boards
class
DestroyService
<
Boards
::
BaseService
def
execute
(
board
)
if
parent
.
boards
.
size
==
1
if
boards
.
size
==
1
return
ServiceResponse
.
error
(
message:
"The board could not be deleted, because the parent doesn't have any other boards."
)
end
...
...
@@ -11,5 +11,11 @@ module Boards
ServiceResponse
.
success
end
private
def
boards
parent
.
boards
end
end
end
doc/api/graphql/reference/index.md
View file @
d1cea4d8
...
...
@@ -2372,6 +2372,16 @@ Autogenerated return type of DestroyContainerRepositoryTags.
|
`deletedTagNames`
|
[
`[String!]!`
](
#string
)
| Deleted container repository tags. |
|
`errors`
|
[
`[String!]!`
](
#string
)
| Errors encountered during execution of the mutation. |
### `DestroyEpicBoardPayload`
Autogenerated return type of DestroyEpicBoard.
| Field | Type | Description |
| ----- | ---- | ----------- |
|
`clientMutationId`
|
[
`String`
](
#string
)
| A unique identifier for the client performing the mutation. |
|
`epicBoard`
|
[
`EpicBoard`
](
#epicboard
)
| Epic board after mutation. |
|
`errors`
|
[
`[String!]!`
](
#string
)
| Errors encountered during execution of the mutation. |
### `DestroyNotePayload`
Autogenerated return type of DestroyNote.
...
...
ee/app/graphql/ee/types/mutation_type.rb
View file @
d1cea4d8
...
...
@@ -39,8 +39,9 @@ module EE
mount_mutation
::
Mutations
::
Boards
::
Update
mount_mutation
::
Mutations
::
Boards
::
UpdateEpicUserPreferences
mount_mutation
::
Mutations
::
Boards
::
EpicBoards
::
Create
mount_mutation
::
Mutations
::
Boards
::
EpicBoards
::
Update
mount_mutation
::
Mutations
::
Boards
::
EpicBoards
::
Destroy
mount_mutation
::
Mutations
::
Boards
::
EpicBoards
::
EpicMoveList
mount_mutation
::
Mutations
::
Boards
::
EpicBoards
::
Update
mount_mutation
::
Mutations
::
Boards
::
EpicLists
::
Create
mount_mutation
::
Mutations
::
Boards
::
Lists
::
UpdateLimitMetrics
mount_mutation
::
Mutations
::
InstanceSecurityDashboard
::
AddProject
...
...
ee/app/graphql/mutations/boards/epic_boards/destroy.rb
0 → 100644
View file @
d1cea4d8
# frozen_string_literal: true
module
Mutations
module
Boards
module
EpicBoards
class
Destroy
<
::
Mutations
::
BaseMutation
graphql_name
'DestroyEpicBoard'
field
:epic_board
,
Types
::
Boards
::
EpicBoardType
,
null:
true
,
description:
'Epic board after mutation.'
argument
:id
,
::
Types
::
GlobalIDType
[
::
Boards
::
EpicBoard
],
required:
true
,
description:
'Global ID of the board to destroy.'
authorize
:admin_epic_board
def
resolve
(
id
:)
board
=
authorized_find!
(
id:
id
)
response
=
::
Boards
::
EpicBoards
::
DestroyService
.
new
(
board
.
resource_parent
,
current_user
).
execute
(
board
)
{
epic_board:
response
.
success?
?
nil
:
board
,
errors:
response
.
errors
}
end
private
def
find_object
(
id
:)
GitlabSchema
.
find_by_gid
(
id
)
end
end
end
end
end
ee/app/services/boards/epic_boards/destroy_service.rb
0 → 100644
View file @
d1cea4d8
# frozen_string_literal: true
module
Boards
module
EpicBoards
class
DestroyService
<
::
Boards
::
DestroyService
extend
::
Gitlab
::
Utils
::
Override
override
:boards
def
boards
parent
.
epic_boards
end
end
end
end
ee/spec/graphql/mutations/boards/epic_boards/destroy_spec.rb
0 → 100644
View file @
d1cea4d8
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
::
Mutations
::
Boards
::
EpicBoards
::
Destroy
do
include
GraphqlHelpers
let_it_be
(
:current_user
)
{
create
(
:user
)
}
let_it_be
(
:group
)
{
create
(
:group
,
:private
)
}
let_it_be_with_reload
(
:board
)
{
create
(
:epic_board
,
group:
group
)
}
let_it_be
(
:another_board
)
{
create
(
:epic_board
,
group:
group
)
}
let
(
:mutation
)
{
described_class
.
new
(
object:
nil
,
context:
{
current_user:
current_user
},
field:
nil
)
}
subject
{
mutation
.
resolve
(
id:
board
.
to_global_id
)
}
context
'field tests'
do
subject
{
described_class
}
it
{
is_expected
.
to
have_graphql_arguments
(
:id
)
}
it
{
is_expected
.
to
have_graphql_fields
(
:epic_board
).
at_least
}
end
before
do
stub_licensed_features
(
epics:
true
)
end
it
'raises error when user does not have permission to destroy the board'
do
expect
{
subject
}
.
to
raise_error
(
Gitlab
::
Graphql
::
Errors
::
ResourceNotAvailable
)
end
context
'when user has permission to destroy the board'
do
before
do
group
.
add_reporter
(
current_user
)
end
it
'destroys the epic board'
do
result
=
mutation
.
resolve
(
id:
board
.
to_global_id
)
expect
(
result
[
:errors
]).
to
be_empty
expect
(
result
[
:epic_board
]).
to
be_nil
end
end
end
ee/spec/requests/api/graphql/mutations/boards/epic_boards/destroy_spec.rb
0 → 100644
View file @
d1cea4d8
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Mutations
::
Boards
::
EpicBoards
::
Destroy
do
include
GraphqlHelpers
let_it_be_with_reload
(
:current_user
)
{
create
(
:user
)
}
let_it_be_with_reload
(
:group
)
{
create
(
:group
)
}
let_it_be
(
:board
)
{
create
(
:epic_board
,
group:
group
)
}
let_it_be
(
:other_board
)
{
create
(
:epic_board
,
group:
group
)
}
let
(
:mutation
)
do
variables
=
{
id:
board
.
to_global_id
.
to_s
}
graphql_mutation
(
:destroy_epic_board
,
variables
)
end
subject
{
post_graphql_mutation
(
mutation
,
current_user:
current_user
)
}
def
mutation_response
graphql_mutation_response
(
:destroy_epic_board
)
end
before
do
stub_licensed_features
(
epics:
true
)
end
context
'when the user does not have permission'
do
it_behaves_like
'a mutation that returns a top-level access error'
it
'does not destroy the board'
do
expect
{
subject
}.
not_to
change
{
::
Boards
::
EpicBoard
.
count
}
end
end
context
'when the user has permission'
do
before
do
group
.
add_developer
(
current_user
)
end
context
'when everything is ok'
do
it
'destroys the board'
do
expect
{
subject
}.
to
change
{
::
Boards
::
EpicBoard
.
count
}.
by
(
-
1
)
end
it
'returns an empty board'
do
post_graphql_mutation
(
mutation
,
current_user:
current_user
)
expect
(
mutation_response
).
to
have_key
(
'epicBoard'
)
expect
(
mutation_response
[
'epicBoard'
]).
to
be_nil
end
end
context
'when there is only 1 board for the parent'
do
before
do
other_board
.
destroy!
end
it
'does not destroy the board'
do
expect
{
subject
}.
not_to
change
{
::
Boards
::
EpicBoard
.
count
}
end
it
'returns an error and not nil board'
do
subject
expect
(
mutation_response
[
'errors'
]).
not_to
be_empty
expect
(
mutation_response
[
'epicBoard'
]).
not_to
be_nil
end
end
end
end
ee/spec/services/boards/destroy_service_spec.rb
deleted
100644 → 0
View file @
76ebd961
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Boards
::
DestroyService
do
describe
'#execute'
do
let_it_be
(
:project
)
{
create
(
:project
)
}
let_it_be
(
:group
)
{
create
(
:group
)
}
shared_examples
'remove the board'
do
|
parent_name
|
let
(
:parent
)
{
public_send
(
parent_name
)
}
let!
(
:board
)
{
create
(
:board
,
parent_name
=>
parent
)
}
subject
(
:service
)
{
described_class
.
new
(
parent
,
double
)
}
context
"when
#{
parent_name
}
have more than one board"
do
it
"removes board from
#{
parent_name
}
"
do
create
(
:board
,
parent_name
=>
parent
)
expect
do
expect
(
service
.
execute
(
board
)).
to
be_success
end
.
to
change
(
parent
.
boards
,
:count
).
by
(
-
1
)
end
end
context
"when
#{
parent_name
}
have one board"
do
it
"does not remove board from
#{
parent_name
}
"
do
expect
do
expect
(
service
.
execute
(
board
)).
to
be_error
end
.
not_to
change
(
parent
.
boards
,
:count
)
end
end
end
it_behaves_like
'remove the board'
,
:group
it_behaves_like
'remove the board'
,
:project
end
end
ee/spec/services/boards/epic_boards/destroy_service_spec.rb
0 → 100644
View file @
d1cea4d8
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Boards
::
EpicBoards
::
DestroyService
do
let_it_be
(
:parent
)
{
create
(
:group
)
}
let
(
:boards
)
{
parent
.
epic_boards
}
let
(
:board_factory
)
{
:epic_board
}
it_behaves_like
'board destroy service'
end
spec/services/boards/destroy_service_spec.rb
0 → 100644
View file @
d1cea4d8
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Boards
::
DestroyService
do
context
'with project board'
do
let_it_be
(
:parent
)
{
create
(
:project
)
}
let
(
:boards
)
{
parent
.
boards
}
let
(
:board_factory
)
{
:board
}
it_behaves_like
'board destroy service'
end
context
'with group board'
do
let_it_be
(
:parent
)
{
create
(
:group
)
}
let
(
:boards
)
{
parent
.
boards
}
let
(
:board_factory
)
{
:board
}
it_behaves_like
'board destroy service'
end
end
spec/support/shared_examples/boards/destroy_service_shared_examples.rb
0 → 100644
View file @
d1cea4d8
# frozen_string_literal: true
RSpec
.
shared_examples
'board destroy service'
do
describe
'#execute'
do
let
(
:parent_type
)
{
parent
.
is_a?
(
Project
)
?
:project
:
:group
}
let!
(
:board
)
{
create
(
board_factory
,
parent_type
=>
parent
)
}
subject
(
:service
)
{
described_class
.
new
(
parent
,
double
)
}
context
'when there is more than one board'
do
let!
(
:board2
)
{
create
(
board_factory
,
parent_type
=>
parent
)
}
it
'destroys the board'
do
create
(
board_factory
,
parent_type
=>
parent
)
expect
do
expect
(
service
.
execute
(
board
)).
to
be_success
end
.
to
change
(
boards
,
:count
).
by
(
-
1
)
end
end
context
'when there is only one board'
do
it
'does not remove board'
do
expect
do
expect
(
service
.
execute
(
board
)).
to
be_error
end
.
not_to
change
(
boards
,
:count
)
end
end
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