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
5b90f10c
Commit
5b90f10c
authored
Feb 09, 2021
by
Stan Hu
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'epic_board_list_create' into 'master'
Create epic board lists See merge request gitlab-org/gitlab!53125
parents
434970a8
8d2e1d05
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
709 additions
and
330 deletions
+709
-330
app/graphql/mutations/boards/lists/base_create.rb
app/graphql/mutations/boards/lists/base_create.rb
+55
-0
app/graphql/mutations/boards/lists/create.rb
app/graphql/mutations/boards/lists/create.rb
+12
-39
app/services/boards/lists/base_create_service.rb
app/services/boards/lists/base_create_service.rb
+71
-0
app/services/boards/lists/create_service.rb
app/services/boards/lists/create_service.rb
+1
-62
doc/api/graphql/reference/gitlab_schema.graphql
doc/api/graphql/reference/gitlab_schema.graphql
+47
-1
doc/api/graphql/reference/gitlab_schema.json
doc/api/graphql/reference/gitlab_schema.json
+164
-15
doc/api/graphql/reference/index.md
doc/api/graphql/reference/index.md
+11
-1
ee/app/graphql/ee/types/mutation_type.rb
ee/app/graphql/ee/types/mutation_type.rb
+1
-0
ee/app/graphql/mutations/boards/epic_lists/create.rb
ee/app/graphql/mutations/boards/epic_lists/create.rb
+35
-0
ee/app/policies/ee/group_policy.rb
ee/app/policies/ee/group_policy.rb
+2
-0
ee/app/services/boards/epic_lists/create_service.rb
ee/app/services/boards/epic_lists/create_service.rb
+18
-0
ee/spec/graphql/mutations/boards/epic_lists/create_spec.rb
ee/spec/graphql/mutations/boards/epic_lists/create_spec.rb
+14
-0
ee/spec/policies/group_policy_spec.rb
ee/spec/policies/group_policy_spec.rb
+2
-1
ee/spec/requests/api/graphql/mutations/boards/epic_lists/create_spec.rb
...ts/api/graphql/mutations/boards/epic_lists/create_spec.rb
+16
-0
ee/spec/services/boards/epic_lists/create_service_spec.rb
ee/spec/services/boards/epic_lists/create_service_spec.rb
+28
-0
spec/graphql/mutations/boards/lists/create_spec.rb
spec/graphql/mutations/boards/lists/create_spec.rb
+1
-77
spec/requests/api/graphql/mutations/boards/lists/create_spec.rb
...equests/api/graphql/mutations/boards/lists/create_spec.rb
+2
-44
spec/services/boards/lists/create_service_spec.rb
spec/services/boards/lists/create_service_spec.rb
+14
-90
spec/support/shared_examples/graphql/mutations/boards_list_create_shared_examples.rb
...s/graphql/mutations/boards_list_create_shared_examples.rb
+83
-0
spec/support/shared_examples/requests/api/graphql/mutations/create_list_shared_examples.rb
...ests/api/graphql/mutations/create_list_shared_examples.rb
+51
-0
spec/support/shared_examples/services/boards/lists_create_service_shared_examples.rb
...s/services/boards/lists_create_service_shared_examples.rb
+81
-0
No files found.
app/graphql/mutations/boards/lists/base_create.rb
0 → 100644
View file @
5b90f10c
# frozen_string_literal: true
module
Mutations
module
Boards
module
Lists
class
BaseCreate
<
BaseMutation
argument
:backlog
,
GraphQL
::
BOOLEAN_TYPE
,
required:
false
,
description:
'Create the backlog list.'
argument
:label_id
,
::
Types
::
GlobalIDType
[
::
Label
],
required:
false
,
description:
'Global ID of an existing label.'
def
ready?
(
**
args
)
if
args
.
slice
(
*
mutually_exclusive_args
).
size
!=
1
arg_str
=
mutually_exclusive_args
.
map
{
|
x
|
x
.
to_s
.
camelize
(
:lower
)
}.
join
(
' or '
)
raise
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
"one and only one of
#{
arg_str
}
is required"
end
super
end
def
resolve
(
**
args
)
board
=
authorized_find!
(
id:
args
[
:board_id
])
params
=
create_list_params
(
args
)
response
=
create_list
(
board
,
params
)
{
list:
response
.
success?
?
response
.
payload
[
:list
]
:
nil
,
errors:
response
.
errors
}
end
private
def
create_list
(
board
,
params
)
raise
NotImplementedError
end
def
create_list_params
(
args
)
params
=
args
.
slice
(
*
mutually_exclusive_args
).
with_indifferent_access
params
[
:label_id
]
&&=
::
GitlabSchema
.
parse_gid
(
params
[
:label_id
],
expected_type:
::
Label
).
model_id
params
end
def
mutually_exclusive_args
[
:backlog
,
:label_id
]
end
end
end
end
end
app/graphql/mutations/boards/lists/create.rb
View file @
5b90f10c
...
...
@@ -3,59 +3,32 @@
module
Mutations
module
Boards
module
Lists
class
Create
<
Base
class
Create
<
Base
Create
graphql_name
'BoardListCreate'
argument
:b
acklog
,
GraphQL
::
BOOLEAN_TYPE
,
required:
fals
e
,
description:
'
Create the backlog list
.'
argument
:b
oard_id
,
::
Types
::
GlobalIDType
[
::
Board
]
,
required:
tru
e
,
description:
'
Global ID of the issue board to mutate
.'
argument
:label_id
,
::
Types
::
GlobalIDType
[
::
Label
],
required:
false
,
description:
'Global ID of an existing label.'
field
:list
,
Types
::
BoardListType
,
null:
true
,
description:
'Issue list in the issue board.'
def
ready?
(
**
args
)
if
args
.
slice
(
*
mutually_exclusive_args
).
size
!=
1
arg_str
=
mutually_exclusive_args
.
map
{
|
x
|
x
.
to_s
.
camelize
(
:lower
)
}.
join
(
' or '
)
raise
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
"one and only one of
#{
arg_str
}
is required"
end
authorize
:admin_list
super
end
def
resolve
(
**
args
)
board
=
authorized_find!
(
id:
args
[
:board_id
])
params
=
create_list_params
(
args
)
response
=
create_list
(
board
,
params
)
private
{
list:
response
.
success?
?
response
.
payload
[
:list
]
:
nil
,
errors:
response
.
errors
}
def
find_object
(
id
:)
GitlabSchema
.
object_from_id
(
id
,
expected_type:
::
Board
)
end
private
def
create_list
(
board
,
params
)
create_list_service
=
::
Boards
::
Lists
::
CreateService
.
new
(
board
.
resource_parent
,
current_user
,
params
)
create_list_service
.
execute
(
board
)
end
# Overridden in EE
def
create_list_params
(
args
)
params
=
args
.
slice
(
*
mutually_exclusive_args
).
with_indifferent_access
params
[
:label_id
]
&&=
::
GitlabSchema
.
parse_gid
(
params
[
:label_id
],
expected_type:
::
Label
).
model_id
params
end
# Overridden in EE
def
mutually_exclusive_args
[
:backlog
,
:label_id
]
end
end
end
end
...
...
app/services/boards/lists/base_create_service.rb
0 → 100644
View file @
5b90f10c
# frozen_string_literal: true
module
Boards
module
Lists
# This class is used by issue and epic board lists
# for creating new list
class
BaseCreateService
<
Boards
::
BaseService
include
Gitlab
::
Utils
::
StrongMemoize
def
execute
(
board
)
list
=
case
type
when
:backlog
create_backlog
(
board
)
else
target
=
target
(
board
)
position
=
next_position
(
board
)
return
ServiceResponse
.
error
(
message:
_
(
'%{board_target} not found'
)
%
{
board_target:
type
.
to_s
.
capitalize
})
if
target
.
blank?
create_list
(
board
,
type
,
target
,
position
)
end
return
ServiceResponse
.
error
(
message:
list
.
errors
.
full_messages
)
unless
list
.
persisted?
ServiceResponse
.
success
(
payload:
{
list:
list
})
end
private
def
type
# We don't ever expect to have more than one list
# type param at once.
if
params
.
key?
(
'backlog'
)
:backlog
else
:label
end
end
def
target
(
board
)
strong_memoize
(
:target
)
do
available_labels
.
find_by
(
id:
params
[
:label_id
])
# rubocop: disable CodeReuse/ActiveRecord
end
end
def
available_labels
::
Labels
::
AvailableLabelsService
.
new
(
current_user
,
parent
,
{})
.
available_labels
end
def
next_position
(
board
)
max_position
=
board
.
lists
.
movable
.
maximum
(
:position
)
max_position
.
nil?
?
0
:
max_position
.
succ
end
def
create_list
(
board
,
type
,
target
,
position
)
board
.
lists
.
create
(
create_list_attributes
(
type
,
target
,
position
))
end
def
create_list_attributes
(
type
,
target
,
position
)
{
type
=>
target
,
list_type:
type
,
position:
position
}
end
def
create_backlog
(
board
)
return
board
.
lists
.
backlog
.
first
if
board
.
lists
.
backlog
.
exists?
board
.
lists
.
create
(
list_type: :backlog
,
position:
nil
)
end
end
end
end
app/services/boards/lists/create_service.rb
View file @
5b90f10c
...
...
@@ -2,68 +2,7 @@
module
Boards
module
Lists
class
CreateService
<
Boards
::
BaseService
include
Gitlab
::
Utils
::
StrongMemoize
def
execute
(
board
)
list
=
case
type
when
:backlog
create_backlog
(
board
)
else
target
=
target
(
board
)
position
=
next_position
(
board
)
return
ServiceResponse
.
error
(
message:
_
(
'%{board_target} not found'
)
%
{
board_target:
type
.
to_s
.
capitalize
})
if
target
.
blank?
create_list
(
board
,
type
,
target
,
position
)
end
return
ServiceResponse
.
error
(
message:
list
.
errors
.
full_messages
)
unless
list
.
persisted?
ServiceResponse
.
success
(
payload:
{
list:
list
})
end
private
def
type
# We don't ever expect to have more than one list
# type param at once.
if
params
.
key?
(
'backlog'
)
:backlog
else
:label
end
end
def
target
(
board
)
strong_memoize
(
:target
)
do
available_labels
.
find_by
(
id:
params
[
:label_id
])
# rubocop: disable CodeReuse/ActiveRecord
end
end
def
available_labels
::
Labels
::
AvailableLabelsService
.
new
(
current_user
,
parent
,
{})
.
available_labels
end
def
next_position
(
board
)
max_position
=
board
.
lists
.
movable
.
maximum
(
:position
)
max_position
.
nil?
?
0
:
max_position
.
succ
end
def
create_list
(
board
,
type
,
target
,
position
)
board
.
lists
.
create
(
create_list_attributes
(
type
,
target
,
position
))
end
def
create_list_attributes
(
type
,
target
,
position
)
{
type
=>
target
,
list_type:
type
,
position:
position
}
end
def
create_backlog
(
board
)
return
board
.
lists
.
backlog
.
first
if
board
.
lists
.
backlog
.
exists?
board
.
lists
.
create
(
list_type: :backlog
,
position:
nil
)
end
class
CreateService
<
Boards
::
Lists
::
BaseCreateService
end
end
end
...
...
doc/api/graphql/reference/gitlab_schema.graphql
View file @
5b90f10c
...
...
@@ -2361,7 +2361,7 @@ type BoardListCreatePayload {
errors
:
[
String
!]!
"""
List
of
the
issue
board
.
Issue
list
in
the
issue
board
.
"""
list
:
BoardList
}
...
...
@@ -9155,6 +9155,51 @@ type EpicBoardEdge {
node
:
EpicBoard
}
"""
Autogenerated input type of EpicBoardListCreate
"""
input
EpicBoardListCreateInput
{
"""
Create
the
backlog
list
.
"""
backlog
:
Boolean
"""
Global
ID
of
the
issue
board
to
mutate
.
"""
boardId
:
BoardsEpicBoardID
!
"""
A
unique
identifier
for
the
client
performing
the
mutation
.
"""
clientMutationId
:
String
"""
Global
ID
of
an
existing
label
.
"""
labelId
:
LabelID
}
"""
Autogenerated return type of EpicBoardListCreate
"""
type
EpicBoardListCreatePayload
{
"""
A
unique
identifier
for
the
client
performing
the
mutation
.
"""
clientMutationId
:
String
"""
Errors
encountered
during
execution
of
the
mutation
.
"""
errors
:
[
String
!]!
"""
Epic
list
in
the
epic
board
.
"""
list
:
EpicList
}
"""
The connection type for Epic.
"""
...
...
@@ -16235,6 +16280,7 @@ type Mutation {
environmentsCanaryIngressUpdate
(
input
:
EnvironmentsCanaryIngressUpdateInput
!):
EnvironmentsCanaryIngressUpdatePayload
epicAddIssue
(
input
:
EpicAddIssueInput
!):
EpicAddIssuePayload
epicBoardCreate
(
input
:
EpicBoardCreateInput
!):
EpicBoardCreatePayload
epicBoardListCreate
(
input
:
EpicBoardListCreateInput
!):
EpicBoardListCreatePayload
epicSetSubscription
(
input
:
EpicSetSubscriptionInput
!):
EpicSetSubscriptionPayload
epicTreeReorder
(
input
:
EpicTreeReorderInput
!):
EpicTreeReorderPayload
exportRequirements
(
input
:
ExportRequirementsInput
!):
ExportRequirementsPayload
...
...
doc/api/graphql/reference/gitlab_schema.json
View file @
5b90f10c
...
...
@@ -6045,20 +6045,6 @@
"description": "Autogenerated input type of BoardListCreate",
"fields": null,
"inputFields": [
{
"name": "boardId",
"description": "Global ID of the issue board to mutate.",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "BoardID",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "backlog",
"description": "Create the backlog list.",
...
...
@@ -6079,6 +6065,20 @@
},
"defaultValue": null
},
{
"name": "boardId",
"description": "Global ID of the issue board to mutate.",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "BoardID",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "milestoneId",
"description": "Global ID of an existing milestone.",
...
...
@@ -6171,7 +6171,7 @@
},
{
"name": "list",
"description": "
List of
the issue board.",
"description": "
Issue list in
the issue board.",
"args": [
],
...
...
@@ -25287,6 +25287,128 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "INPUT_OBJECT",
"name": "EpicBoardListCreateInput",
"description": "Autogenerated input type of EpicBoardListCreate",
"fields": null,
"inputFields": [
{
"name": "backlog",
"description": "Create the backlog list.",
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
},
"defaultValue": null
},
{
"name": "labelId",
"description": "Global ID of an existing label.",
"type": {
"kind": "SCALAR",
"name": "LabelID",
"ofType": null
},
"defaultValue": null
},
{
"name": "boardId",
"description": "Global ID of the issue board to mutate.",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "BoardsEpicBoardID",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "clientMutationId",
"description": "A unique identifier for the client performing the mutation.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
}
],
"interfaces": null,
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "EpicBoardListCreatePayload",
"description": "Autogenerated return type of EpicBoardListCreate",
"fields": [
{
"name": "clientMutationId",
"description": "A unique identifier for the client performing the mutation.",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "errors",
"description": "Errors encountered during execution of the mutation.",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
}
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "list",
"description": "Epic list in the epic board.",
"args": [
],
"type": {
"kind": "OBJECT",
"name": "EpicList",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "EpicConnection",
...
...
@@ -46077,6 +46199,33 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "epicBoardListCreate",
"description": null,
"args": [
{
"name": "input",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "INPUT_OBJECT",
"name": "EpicBoardListCreateInput",
"ofType": null
}
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "EpicBoardListCreatePayload",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "epicSetSubscription",
"description": null,
doc/api/graphql/reference/index.md
View file @
5b90f10c
...
...
@@ -357,7 +357,7 @@ Autogenerated return type of BoardListCreate.
| ----- | ---- | ----------- |
|
`clientMutationId`
| String | A unique identifier for the client performing the mutation. |
|
`errors`
| String! => Array | Errors encountered during execution of the mutation. |
|
`list`
| BoardList |
List of
the issue board. |
|
`list`
| BoardList |
Issue list in
the issue board. |
### BoardListUpdateLimitMetricsPayload
...
...
@@ -1482,6 +1482,16 @@ Autogenerated return type of EpicBoardCreate.
|
`epicBoard`
| EpicBoard | The created epic board. |
|
`errors`
| String! => Array | Errors encountered during execution of the mutation. |
### EpicBoardListCreatePayload
Autogenerated return type of EpicBoardListCreate.
| Field | Type | Description |
| ----- | ---- | ----------- |
|
`clientMutationId`
| String | A unique identifier for the client performing the mutation. |
|
`errors`
| String! => Array | Errors encountered during execution of the mutation. |
|
`list`
| EpicList | Epic list in the epic board. |
### EpicDescendantCount
Counts of descendent epics.
...
...
ee/app/graphql/ee/types/mutation_type.rb
View file @
5b90f10c
...
...
@@ -37,6 +37,7 @@ module EE
mount_mutation
::
Mutations
::
Boards
::
Update
mount_mutation
::
Mutations
::
Boards
::
UpdateEpicUserPreferences
mount_mutation
::
Mutations
::
Boards
::
EpicBoards
::
Create
mount_mutation
::
Mutations
::
Boards
::
EpicLists
::
Create
mount_mutation
::
Mutations
::
Boards
::
Lists
::
UpdateLimitMetrics
mount_mutation
::
Mutations
::
InstanceSecurityDashboard
::
AddProject
mount_mutation
::
Mutations
::
InstanceSecurityDashboard
::
RemoveProject
...
...
app/graphql/mutations/boards/lists/bas
e.rb
→
ee/app/graphql/mutations/boards/epic_lists/creat
e.rb
View file @
5b90f10c
...
...
@@ -2,25 +2,32 @@
module
Mutations
module
Boards
module
Lists
class
Base
<
BaseMutation
include
Mutations
::
ResolvesIssuable
module
Epic
Lists
class
Create
<
::
Mutations
::
Boards
::
Lists
::
BaseCreate
graphql_name
'EpicBoardListCreate'
argument
:board_id
,
::
Types
::
GlobalIDType
[
::
Board
],
argument
:board_id
,
::
Types
::
GlobalIDType
[
::
Board
s
::
EpicBoard
],
required:
true
,
description:
'Global ID of the issue board to mutate.'
field
:list
,
Types
::
BoardListType
,
Types
::
Board
s
::
Epic
ListType
,
null:
true
,
description:
'
List of the issue
board.'
description:
'
Epic list in the epic
board.'
authorize
:admin_list
authorize
:admin_
epic_
list
private
def
find_object
(
id
:)
GitlabSchema
.
object_from_id
(
id
,
expected_type:
::
Board
)
GitlabSchema
.
object_from_id
(
id
,
expected_type:
::
Boards
::
EpicBoard
)
end
def
create_list
(
board
,
params
)
create_list_service
=
::
Boards
::
EpicLists
::
CreateService
.
new
(
board
.
group
,
current_user
,
params
)
create_list_service
.
execute
(
board
)
end
end
end
...
...
ee/app/policies/ee/group_policy.rb
View file @
5b90f10c
...
...
@@ -198,6 +198,7 @@ module EE
enable
:read_confidential_epic
enable
:destroy_epic_link
enable
:admin_epic_board
enable
:admin_epic_list
end
rule
{
reporter
&
subepics_available
}.
policy
do
...
...
@@ -214,6 +215,7 @@ module EE
prevent
:admin_epic
prevent
:update_epic
prevent
:destroy_epic
prevent
:admin_epic_list
end
rule
{
auditor
}.
policy
do
...
...
ee/app/services/boards/epic_lists/create_service.rb
0 → 100644
View file @
5b90f10c
# frozen_string_literal: true
module
Boards
module
EpicLists
class
CreateService
<
::
Boards
::
Lists
::
BaseCreateService
extend
::
Gitlab
::
Utils
::
Override
override
:execute
def
execute
(
board
)
unless
Feature
.
enabled?
(
:epic_boards
,
board
.
group
)
return
ServiceResponse
.
error
(
message:
'Epic boards feature is not enabled.'
)
end
super
end
end
end
end
ee/spec/graphql/mutations/boards/epic_lists/create_spec.rb
0 → 100644
View file @
5b90f10c
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Mutations
::
Boards
::
EpicLists
::
Create
do
let_it_be
(
:group
)
{
create
(
:group
,
:private
)
}
let_it_be
(
:board
)
{
create
(
:epic_board
,
group:
group
)
}
before
do
stub_licensed_features
(
epics:
true
)
end
it_behaves_like
'board lists create mutation'
end
ee/spec/policies/group_policy_spec.rb
View file @
5b90f10c
...
...
@@ -7,7 +7,8 @@ RSpec.describe GroupPolicy do
let
(
:epic_rules
)
do
%i(read_epic create_epic admin_epic destroy_epic read_confidential_epic
destroy_epic_link read_epic_board read_epic_list admin_epic_board)
destroy_epic_link read_epic_board read_epic_list admin_epic_board
admin_epic_list)
end
context
'when epics feature is disabled'
do
...
...
ee/spec/requests/api/graphql/mutations/boards/epic_lists/create_spec.rb
0 → 100644
View file @
5b90f10c
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
'Create a label or backlog board list'
do
let_it_be
(
:group
)
{
create
(
:group
,
:private
)
}
let_it_be
(
:board
)
{
create
(
:epic_board
,
group:
group
)
}
before
do
stub_licensed_features
(
epics:
true
)
end
it_behaves_like
'board lists create request'
do
let
(
:mutation_name
)
{
:epic_board_list_create
}
end
end
ee/spec/services/boards/epic_lists/create_service_spec.rb
0 → 100644
View file @
5b90f10c
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Boards
::
EpicLists
::
CreateService
do
let_it_be
(
:parent
)
{
create
(
:group
)
}
let_it_be
(
:board
)
{
create
(
:epic_board
,
group:
parent
)
}
let_it_be
(
:label
)
{
create
(
:group_label
,
group:
parent
,
name:
'in-progress'
)
}
it_behaves_like
'board lists create service'
do
def
create_list
(
params
)
create
(
:epic_list
,
params
.
merge
(
epic_board:
board
))
end
end
context
'when epic_boards feature flag is disabled'
do
before
do
stub_feature_flags
(
epic_boards:
false
)
end
it
'returns an error'
do
response
=
described_class
.
new
(
parent
,
nil
).
execute
(
board
)
expect
(
response
.
success?
).
to
eq
(
false
)
expect
(
response
.
errors
).
to
include
(
"Epic boards feature is not enabled."
)
end
end
end
spec/graphql/mutations/boards/lists/create_spec.rb
View file @
5b90f10c
...
...
@@ -3,84 +3,8 @@
require
'spec_helper'
RSpec
.
describe
Mutations
::
Boards
::
Lists
::
Create
do
include
GraphqlHelpers
let_it_be
(
:group
)
{
create
(
:group
,
:private
)
}
let_it_be
(
:board
)
{
create
(
:board
,
group:
group
)
}
let_it_be
(
:user
)
{
create
(
:user
)
}
let_it_be
(
:guest
)
{
create
(
:user
)
}
let
(
:current_user
)
{
user
}
let
(
:mutation
)
{
described_class
.
new
(
object:
nil
,
context:
{
current_user:
current_user
},
field:
nil
)
}
let
(
:list_create_params
)
{
{}
}
before_all
do
group
.
add_reporter
(
user
)
group
.
add_guest
(
guest
)
end
subject
{
mutation
.
resolve
(
board_id:
board
.
to_global_id
.
to_s
,
**
list_create_params
)
}
describe
'#ready?'
do
it
'raises an error if required arguments are missing'
do
expect
{
mutation
.
ready?
(
board_id:
'some id'
)
}
.
to
raise_error
(
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
/one and only one of/
)
end
it
'raises an error if too many required arguments are specified'
do
expect
{
mutation
.
ready?
(
board_id:
'some id'
,
backlog:
true
,
label_id:
'some label'
)
}
.
to
raise_error
(
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
/one and only one of/
)
end
end
describe
'#resolve'
do
context
'with proper permissions'
do
describe
'backlog list'
do
let
(
:list_create_params
)
{
{
backlog:
true
}
}
it
'creates one and only one backlog'
do
expect
{
subject
}.
to
change
{
board
.
lists
.
backlog
.
count
}.
from
(
0
).
to
(
1
)
expect
(
board
.
lists
.
backlog
.
first
.
list_type
).
to
eq
'backlog'
backlog_id
=
board
.
lists
.
backlog
.
first
.
id
expect
{
subject
}.
not_to
change
{
board
.
lists
.
backlog
.
count
}
expect
(
board
.
lists
.
backlog
.
last
.
id
).
to
eq
backlog_id
end
end
describe
'label list'
do
let_it_be
(
:dev_label
)
do
create
(
:group_label
,
title:
'Development'
,
color:
'#FFAABB'
,
group:
group
)
end
let
(
:list_create_params
)
{
{
label_id:
dev_label
.
to_global_id
.
to_s
}
}
it
'creates a new issue board list for labels'
do
expect
{
subject
}.
to
change
{
board
.
lists
.
count
}.
from
(
1
).
to
(
2
)
new_list
=
subject
[
:list
]
expect
(
new_list
.
title
).
to
eq
dev_label
.
title
expect
(
new_list
.
position
).
to
eq
0
end
context
'when label not found'
do
let
(
:list_create_params
)
{
{
label_id:
"gid://gitlab/Label/
#{
non_existing_record_id
}
"
}
}
it
'returns an error'
do
expect
(
subject
[
:errors
]).
to
include
'Label not found'
end
end
end
end
context
'without proper permissions'
do
let
(
:current_user
)
{
guest
}
it
'raises an error'
do
expect
{
subject
}.
to
raise_error
(
Gitlab
::
Graphql
::
Errors
::
ResourceNotAvailable
)
end
end
end
it_behaves_like
'board lists create mutation'
end
spec/requests/api/graphql/mutations/boards/lists/create_spec.rb
View file @
5b90f10c
...
...
@@ -3,52 +3,10 @@
require
'spec_helper'
RSpec
.
describe
'Create a label or backlog board list'
do
include
GraphqlHelpers
let_it_be
(
:group
)
{
create
(
:group
,
:private
)
}
let_it_be
(
:board
)
{
create
(
:board
,
group:
group
)
}
let_it_be
(
:user
)
{
create
(
:user
)
}
let_it_be
(
:dev_label
)
do
create
(
:group_label
,
title:
'Development'
,
color:
'#FFAABB'
,
group:
group
)
end
let
(
:current_user
)
{
user
}
let
(
:mutation
)
{
graphql_mutation
(
:board_list_create
,
input
)
}
let
(
:mutation_response
)
{
graphql_mutation_response
(
:board_list_create
)
}
context
'the user is not allowed to read board lists'
do
let
(
:input
)
{
{
board_id:
board
.
to_global_id
.
to_s
,
backlog:
true
}
}
it_behaves_like
'a mutation that returns a top-level access error'
end
context
'when user has permissions to admin board lists'
do
before
do
group
.
add_reporter
(
current_user
)
end
describe
'backlog list'
do
let
(
:input
)
{
{
board_id:
board
.
to_global_id
.
to_s
,
backlog:
true
}
}
it
'creates the list'
do
post_graphql_mutation
(
mutation
,
current_user:
current_user
)
expect
(
response
).
to
have_gitlab_http_status
(
:success
)
expect
(
mutation_response
[
'list'
])
.
to
include
(
'position'
=>
nil
,
'listType'
=>
'backlog'
)
end
end
describe
'label list'
do
let
(
:input
)
{
{
board_id:
board
.
to_global_id
.
to_s
,
label_id:
dev_label
.
to_global_id
.
to_s
}
}
it
'creates the list'
do
post_graphql_mutation
(
mutation
,
current_user:
current_user
)
expect
(
response
).
to
have_gitlab_http_status
(
:success
)
expect
(
mutation_response
[
'list'
])
.
to
include
(
'position'
=>
0
,
'listType'
=>
'label'
,
'label'
=>
include
(
'title'
=>
'Development'
))
end
end
it_behaves_like
'board lists create request'
do
let
(
:mutation_name
)
{
:board_list_create
}
end
end
spec/services/boards/lists/create_service_spec.rb
View file @
5b90f10c
...
...
@@ -3,99 +3,23 @@
require
'spec_helper'
RSpec
.
describe
Boards
::
Lists
::
CreateService
do
describe
'#execute'
do
shared_examples
'creating board lists'
do
let_it_be
(
:user
)
{
create
(
:user
)
}
context
'when board parent is a project'
do
let_it_be
(
:parent
)
{
create
(
:project
)
}
let_it_be
(
:board
)
{
create
(
:board
,
project:
parent
)
}
let_it_be
(
:label
)
{
create
(
:label
,
project:
parent
,
name:
'in-progress'
)
}
before_all
do
parent
.
add_developer
(
user
)
end
subject
(
:service
)
{
described_class
.
new
(
parent
,
user
,
label_id:
label
.
id
)
}
context
'when board lists is empty'
do
it
'creates a new list at beginning of the list'
do
response
=
service
.
execute
(
board
)
expect
(
response
.
success?
).
to
eq
(
true
)
expect
(
response
.
payload
[
:list
].
position
).
to
eq
0
end
end
context
'when board lists has the done list'
do
it
'creates a new list at beginning of the list'
do
response
=
service
.
execute
(
board
)
expect
(
response
.
success?
).
to
eq
(
true
)
expect
(
response
.
payload
[
:list
].
position
).
to
eq
0
end
end
context
'when board lists has labels lists'
do
it
'creates a new list at end of the lists'
do
create
(
:list
,
board:
board
,
position:
0
)
create
(
:list
,
board:
board
,
position:
1
)
response
=
service
.
execute
(
board
)
expect
(
response
.
success?
).
to
eq
(
true
)
expect
(
response
.
payload
[
:list
].
position
).
to
eq
2
end
end
context
'when board lists has label and done lists'
do
it
'creates a new list at end of the label lists'
do
list1
=
create
(
:list
,
board:
board
,
position:
0
)
list2
=
service
.
execute
(
board
).
payload
[
:list
]
expect
(
list1
.
reload
.
position
).
to
eq
0
expect
(
list2
.
reload
.
position
).
to
eq
1
end
end
context
'when provided label does not belong to the parent'
do
it
'returns an error'
do
label
=
create
(
:label
,
name:
'in-development'
)
service
=
described_class
.
new
(
parent
,
user
,
label_id:
label
.
id
)
response
=
service
.
execute
(
board
)
expect
(
response
.
success?
).
to
eq
(
false
)
expect
(
response
.
errors
).
to
include
(
'Label not found'
)
end
end
context
'when backlog param is sent'
do
it
'creates one and only one backlog list'
do
service
=
described_class
.
new
(
parent
,
user
,
'backlog'
=>
true
)
list
=
service
.
execute
(
board
).
payload
[
:list
]
expect
(
list
.
list_type
).
to
eq
(
'backlog'
)
expect
(
list
.
position
).
to
be_nil
expect
(
list
).
to
be_valid
another_backlog
=
service
.
execute
(
board
).
payload
[
:list
]
expect
(
another_backlog
).
to
eq
list
end
end
end
context
'when board parent is a project'
do
let_it_be
(
:parent
)
{
create
(
:project
)
}
let_it_be
(
:board
)
{
create
(
:board
,
project:
parent
)
}
let_it_be
(
:label
)
{
create
(
:label
,
project:
parent
,
name:
'in-progress'
)
}
it_behaves_like
'board lists create service'
end
it_behaves_like
'creating board lists'
end
context
'when board parent is a group'
do
let_it_be
(
:parent
)
{
create
(
:group
)
}
let_it_be
(
:board
)
{
create
(
:board
,
group:
parent
)
}
let_it_be
(
:label
)
{
create
(
:group_label
,
group:
parent
,
name:
'in-progress'
)
}
context
'when board parent is a group'
do
let_it_be
(
:parent
)
{
create
(
:group
)
}
let_it_be
(
:board
)
{
create
(
:board
,
group:
parent
)
}
let_it_be
(
:label
)
{
create
(
:group_label
,
group:
parent
,
name:
'in-progress'
)
}
it_behaves_like
'board lists create service'
end
it_behaves_like
'creating board lists'
end
def
create_list
(
params
)
create
(
:list
,
params
.
merge
(
board:
board
))
end
end
spec/support/shared_examples/graphql/mutations/boards_list_create_shared_examples.rb
0 → 100644
View file @
5b90f10c
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
shared_examples
'board lists create mutation'
do
include
GraphqlHelpers
let_it_be
(
:user
)
{
create
(
:user
)
}
let
(
:mutation
)
{
described_class
.
new
(
object:
nil
,
context:
{
current_user:
user
},
field:
nil
)
}
let
(
:list_create_params
)
{
{}
}
subject
{
mutation
.
resolve
(
board_id:
board
.
to_global_id
.
to_s
,
**
list_create_params
)
}
describe
'#ready?'
do
it
'raises an error if required arguments are missing'
do
expect
{
mutation
.
ready?
(
board_id:
'some id'
)
}
.
to
raise_error
(
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
/one and only one of/
)
end
it
'raises an error if too many required arguments are specified'
do
expect
{
mutation
.
ready?
(
board_id:
'some id'
,
backlog:
true
,
label_id:
'some label'
)
}
.
to
raise_error
(
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
/one and only one of/
)
end
end
describe
'#resolve'
do
context
'with proper permissions'
do
before_all
do
group
.
add_reporter
(
user
)
end
describe
'backlog list'
do
let
(
:list_create_params
)
{
{
backlog:
true
}
}
it
'creates one and only one backlog'
do
expect
{
subject
}.
to
change
{
board
.
lists
.
backlog
.
count
}.
by
(
1
)
expect
(
board
.
lists
.
backlog
.
first
.
list_type
).
to
eq
'backlog'
backlog_id
=
board
.
lists
.
backlog
.
first
.
id
expect
{
subject
}.
not_to
change
{
board
.
lists
.
backlog
.
count
}
expect
(
board
.
lists
.
backlog
.
last
.
id
).
to
eq
backlog_id
end
end
describe
'label list'
do
let_it_be
(
:dev_label
)
do
create
(
:group_label
,
title:
'Development'
,
color:
'#FFAABB'
,
group:
group
)
end
let
(
:list_create_params
)
{
{
label_id:
dev_label
.
to_global_id
.
to_s
}
}
it
'creates a new label board list'
do
expect
{
subject
}.
to
change
{
board
.
lists
.
count
}.
by
(
1
)
new_list
=
subject
[
:list
]
expect
(
new_list
.
title
).
to
eq
dev_label
.
title
expect
(
new_list
.
position
).
to
eq
0
end
context
'when label not found'
do
let
(
:list_create_params
)
{
{
label_id:
"gid://gitlab/Label/
#{
non_existing_record_id
}
"
}
}
it
'returns an error'
do
expect
(
subject
[
:errors
]).
to
include
'Label not found'
end
end
end
end
context
'without proper permissions'
do
before_all
do
group
.
add_guest
(
user
)
end
it
'raises an error'
do
expect
{
subject
}.
to
raise_error
(
Gitlab
::
Graphql
::
Errors
::
ResourceNotAvailable
)
end
end
end
end
spec/support/shared_examples/requests/api/graphql/mutations/create_list_shared_examples.rb
0 → 100644
View file @
5b90f10c
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
shared_examples
'board lists create request'
do
include
GraphqlHelpers
let_it_be
(
:current_user
)
{
create
(
:user
)
}
let_it_be
(
:dev_label
)
do
create
(
:group_label
,
title:
'Development'
,
color:
'#FFAABB'
,
group:
group
)
end
let
(
:mutation
)
{
graphql_mutation
(
mutation_name
,
input
)
}
let
(
:mutation_response
)
{
graphql_mutation_response
(
mutation_name
)
}
context
'the user is not allowed to read board lists'
do
let
(
:input
)
{
{
board_id:
board
.
to_global_id
.
to_s
,
backlog:
true
}
}
it_behaves_like
'a mutation that returns a top-level access error'
end
context
'when user has permissions to admin board lists'
do
before
do
group
.
add_reporter
(
current_user
)
end
describe
'backlog list'
do
let
(
:input
)
{
{
board_id:
board
.
to_global_id
.
to_s
,
backlog:
true
}
}
it
'creates the list'
do
post_graphql_mutation
(
mutation
,
current_user:
current_user
)
expect
(
response
).
to
have_gitlab_http_status
(
:success
)
expect
(
mutation_response
[
'list'
])
.
to
include
(
'position'
=>
nil
,
'listType'
=>
'backlog'
)
end
end
describe
'label list'
do
let
(
:input
)
{
{
board_id:
board
.
to_global_id
.
to_s
,
label_id:
dev_label
.
to_global_id
.
to_s
}
}
it
'creates the list'
do
post_graphql_mutation
(
mutation
,
current_user:
current_user
)
expect
(
response
).
to
have_gitlab_http_status
(
:success
)
expect
(
mutation_response
[
'list'
])
.
to
include
(
'position'
=>
0
,
'listType'
=>
'label'
,
'label'
=>
include
(
'title'
=>
'Development'
))
end
end
end
end
spec/support/shared_examples/services/boards/lists_create_service_shared_examples.rb
0 → 100644
View file @
5b90f10c
# frozen_string_literal: true
RSpec
.
shared_examples
'board lists create service'
do
describe
'#execute'
do
let_it_be
(
:user
)
{
create
(
:user
)
}
before_all
do
parent
.
add_developer
(
user
)
end
subject
(
:service
)
{
described_class
.
new
(
parent
,
user
,
label_id:
label
.
id
)
}
context
'when board lists is empty'
do
it
'creates a new list at beginning of the list'
do
response
=
service
.
execute
(
board
)
expect
(
response
.
success?
).
to
eq
(
true
)
expect
(
response
.
payload
[
:list
].
position
).
to
eq
0
end
end
context
'when board lists has the done list'
do
it
'creates a new list at beginning of the list'
do
response
=
service
.
execute
(
board
)
expect
(
response
.
success?
).
to
eq
(
true
)
expect
(
response
.
payload
[
:list
].
position
).
to
eq
0
end
end
context
'when board lists has labels lists'
do
it
'creates a new list at end of the lists'
do
create_list
(
position:
0
)
create_list
(
position:
1
)
response
=
service
.
execute
(
board
)
expect
(
response
.
success?
).
to
eq
(
true
)
expect
(
response
.
payload
[
:list
].
position
).
to
eq
2
end
end
context
'when board lists has label and done lists'
do
it
'creates a new list at end of the label lists'
do
list1
=
create_list
(
position:
0
)
list2
=
service
.
execute
(
board
).
payload
[
:list
]
expect
(
list1
.
reload
.
position
).
to
eq
0
expect
(
list2
.
reload
.
position
).
to
eq
1
end
end
context
'when provided label does not belong to the parent'
do
it
'returns an error'
do
label
=
create
(
:label
,
name:
'in-development'
)
service
=
described_class
.
new
(
parent
,
user
,
label_id:
label
.
id
)
response
=
service
.
execute
(
board
)
expect
(
response
.
success?
).
to
eq
(
false
)
expect
(
response
.
errors
).
to
include
(
'Label not found'
)
end
end
context
'when backlog param is sent'
do
it
'creates one and only one backlog list'
do
service
=
described_class
.
new
(
parent
,
user
,
'backlog'
=>
true
)
list
=
service
.
execute
(
board
).
payload
[
:list
]
expect
(
list
.
list_type
).
to
eq
(
'backlog'
)
expect
(
list
.
position
).
to
be_nil
expect
(
list
).
to
be_valid
another_backlog
=
service
.
execute
(
board
).
payload
[
:list
]
expect
(
another_backlog
).
to
eq
list
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