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
c4fe6bd9
Commit
c4fe6bd9
authored
Nov 27, 2020
by
Jan Provaznik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add graphql API for listing epic boards
Allows listing epic boards in GraphQL.
parent
d9aa0aae
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
654 additions
and
12 deletions
+654
-12
doc/api/graphql/reference/gitlab_schema.graphql
doc/api/graphql/reference/gitlab_schema.graphql
+90
-0
doc/api/graphql/reference/gitlab_schema.json
doc/api/graphql/reference/gitlab_schema.json
+247
-0
doc/api/graphql/reference/index.md
doc/api/graphql/reference/index.md
+11
-0
ee/app/finders/boards/epic_boards_finder.rb
ee/app/finders/boards/epic_boards_finder.rb
+27
-0
ee/app/graphql/ee/types/group_type.rb
ee/app/graphql/ee/types/group_type.rb
+10
-0
ee/app/graphql/resolvers/boards/epic_boards_resolver.rb
ee/app/graphql/resolvers/boards/epic_boards_resolver.rb
+34
-0
ee/app/graphql/types/boards/epic_board_type.rb
ee/app/graphql/types/boards/epic_board_type.rb
+19
-0
ee/app/models/boards/epic_board.rb
ee/app/models/boards/epic_board.rb
+2
-0
ee/app/policies/boards/epic_board_policy.rb
ee/app/policies/boards/epic_board_policy.rb
+7
-0
ee/app/policies/ee/group_policy.rb
ee/app/policies/ee/group_policy.rb
+4
-1
ee/config/feature_flags/development/epic_boards.yml
ee/config/feature_flags/development/epic_boards.yml
+8
-0
ee/spec/factories/boards/epic_boards.rb
ee/spec/factories/boards/epic_boards.rb
+0
-0
ee/spec/finders/boards/epic_boards_finder_spec.rb
ee/spec/finders/boards/epic_boards_finder_spec.rb
+29
-0
ee/spec/graphql/ee/types/group_type_spec.rb
ee/spec/graphql/ee/types/group_type_spec.rb
+3
-1
ee/spec/graphql/resolvers/boards/epic_boards_resolvers_spec.rb
...ec/graphql/resolvers/boards/epic_boards_resolvers_spec.rb
+60
-0
ee/spec/graphql/types/boards/epic_board_type_spec.rb
ee/spec/graphql/types/boards/epic_board_type_spec.rb
+15
-0
ee/spec/models/boards/epic_board_spec.rb
ee/spec/models/boards/epic_board_spec.rb
+10
-0
ee/spec/policies/group_policy_spec.rb
ee/spec/policies/group_policy_spec.rb
+12
-10
ee/spec/requests/api/graphql/boards/epic_boards_query_spec.rb
...pec/requests/api/graphql/boards/epic_boards_query_spec.rb
+66
-0
No files found.
doc/api/graphql/reference/gitlab_schema.graphql
View file @
c4fe6bd9
...
...
@@ -2195,6 +2195,11 @@ type BoardListUpdateLimitMetricsPayload {
list
:
BoardList
}
"""
Identifier of Boards::EpicBoard
"""
scalar
BoardsEpicBoardID
type
Branch
{
"""
Commit
for
the
branch
...
...
@@ -7868,6 +7873,56 @@ type EpicAddIssuePayload {
errors
:
[
String
!]!
}
"""
Represents an epic board
"""
type
EpicBoard
{
"""
Global
ID
of
the
board
"""
id
:
BoardsEpicBoardID
!
"""
Name
of
the
board
"""
name
:
String
}
"""
The connection type for EpicBoard.
"""
type
EpicBoardConnection
{
"""
A
list
of
edges
.
"""
edges
:
[
EpicBoardEdge
]
"""
A
list
of
nodes
.
"""
nodes
:
[
EpicBoard
]
"""
Information
to
aid
in
pagination
.
"""
pageInfo
:
PageInfo
!
}
"""
An edge in a connection.
"""
type
EpicBoardEdge
{
"""
A
cursor
for
use
in
pagination
.
"""
cursor
:
String
!
"""
The
item
at
the
end
of
the
edge
.
"""
node
:
EpicBoard
}
"""
The connection type for Epic.
"""
...
...
@@ -9162,6 +9217,41 @@ type Group {
timeframe
:
Timeframe
)
:
Epic
"""
Find
a
single
epic
board
"""
epicBoard
(
"""
Find
an
epic
board
by
ID
"""
id
:
BoardsEpicBoardID
!
):
EpicBoard
"""
Find
epic
boards
"""
epicBoards
(
"""
Returns
the
elements
in
the
list
that
come
after
the
specified
cursor
.
"""
after
:
String
"""
Returns
the
elements
in
the
list
that
come
before
the
specified
cursor
.
"""
before
:
String
"""
Returns
the
first
_n_
elements
from
the
list
.
"""
first
:
Int
"""
Returns
the
last
_n_
elements
from
the
list
.
"""
last
:
Int
):
EpicBoardConnection
"""
Find
epics
"""
...
...
doc/api/graphql/reference/gitlab_schema.json
View file @
c4fe6bd9
...
...
@@ -5842,6 +5842,16 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "SCALAR",
"name": "BoardsEpicBoardID",
"description": "Identifier of Boards::EpicBoard",
"fields": null,
"inputFields": null,
"interfaces": null,
"enumValues": null,
"possibleTypes": null
},
{
"kind": "SCALAR",
"name": "Boolean",
...
...
@@ -22003,6 +22013,163 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "EpicBoard",
"description": "Represents an epic board",
"fields": [
{
"name": "id",
"description": "Global ID of the board",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "BoardsEpicBoardID",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "name",
"description": "Name of the board",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "EpicBoardConnection",
"description": "The connection type for EpicBoard.",
"fields": [
{
"name": "edges",
"description": "A list of edges.",
"args": [
],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "EpicBoardEdge",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "nodes",
"description": "A list of nodes.",
"args": [
],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "EpicBoard",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "pageInfo",
"description": "Information to aid in pagination.",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "PageInfo",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "EpicBoardEdge",
"description": "An edge in a connection.",
"fields": [
{
"name": "cursor",
"description": "A cursor for use in pagination.",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "node",
"description": "The item at the end of the edge.",
"args": [
],
"type": {
"kind": "OBJECT",
"name": "EpicBoard",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "EpicConnection",
...
...
@@ -25464,6 +25631,86 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "epicBoard",
"description": "Find a single epic board",
"args": [
{
"name": "id",
"description": "Find an epic board by ID",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "BoardsEpicBoardID",
"ofType": null
}
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "EpicBoard",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "epicBoards",
"description": "Find epic boards",
"args": [
{
"name": "after",
"description": "Returns the elements in the list that come after the specified cursor.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "before",
"description": "Returns the elements in the list that come before the specified cursor.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "first",
"description": "Returns the first _n_ elements from the list.",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
},
{
"name": "last",
"description": "Returns the last _n_ elements from the list.",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "EpicBoardConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "epics",
"description": "Find epics",
doc/api/graphql/reference/index.md
View file @
c4fe6bd9
...
...
@@ -1333,6 +1333,15 @@ Autogenerated return type of EpicAddIssue.
|
`epicIssue`
| EpicIssue | The epic-issue relation |
|
`errors`
| String! => Array | Errors encountered during execution of the mutation. |
### EpicBoard
Represents an epic board.
| Field | Type | Description |
| ----- | ---- | ----------- |
|
`id`
| BoardsEpicBoardID! | Global ID of the board |
|
`name`
| String | Name of the board |
### EpicDescendantCount
Counts of descendent epics.
...
...
@@ -1513,6 +1522,8 @@ Autogenerated return type of EpicTreeReorder.
|
`descriptionHtml`
| String | The GitLab Flavored Markdown rendering of
`description`
|
|
`emailsDisabled`
| Boolean | Indicates if a group has email notifications disabled |
|
`epic`
| Epic | Find a single epic |
|
`epicBoard`
| EpicBoard | Find a single epic board |
|
`epicBoards`
| EpicBoardConnection | Find epic boards |
|
`epics`
| EpicConnection | Find epics |
|
`epicsEnabled`
| Boolean | Indicates if Epics are enabled for namespace |
|
`fullName`
| String! | Full name of the namespace |
...
...
ee/app/finders/boards/epic_boards_finder.rb
0 → 100644
View file @
c4fe6bd9
# frozen_string_literal: true
module
Boards
class
EpicBoardsFinder
attr_reader
:group
,
:params
def
initialize
(
group
,
params
=
{})
@group
=
group
@params
=
params
end
def
execute
relation
=
group
.
epic_boards
relation
=
by_id
(
relation
)
relation
.
order_by_name_asc
end
private
def
by_id
(
relation
)
return
relation
unless
params
[
:id
].
present?
relation
.
id_in
(
params
[
:id
])
end
end
end
ee/app/graphql/ee/types/group_type.rb
View file @
c4fe6bd9
...
...
@@ -25,6 +25,16 @@ module EE
max_page_size:
2000
,
resolver:
::
Resolvers
::
EpicsResolver
field
:epic_board
,
::
Types
::
Boards
::
EpicBoardType
,
null:
true
,
description:
'Find a single epic board'
,
resolver:
::
Resolvers
::
Boards
::
EpicBoardsResolver
.
single
field
:epic_boards
,
::
Types
::
Boards
::
EpicBoardType
.
connection_type
,
null:
true
,
description:
'Find epic boards'
,
resolver:
::
Resolvers
::
Boards
::
EpicBoardsResolver
field
:iterations
,
::
Types
::
IterationType
.
connection_type
,
null:
true
,
description:
'Find iterations'
,
resolver:
::
Resolvers
::
IterationsResolver
...
...
ee/app/graphql/resolvers/boards/epic_boards_resolver.rb
0 → 100644
View file @
c4fe6bd9
# frozen_string_literal: true
module
Resolvers
module
Boards
class
EpicBoardsResolver
<
BaseResolver
include
Gitlab
::
Graphql
::
Authorize
::
AuthorizeResource
type
Types
::
Boards
::
EpicBoardType
.
connection_type
,
null:
true
when_single
do
argument
:id
,
::
Types
::
GlobalIDType
[
::
Boards
::
EpicBoard
],
required:
true
,
description:
'Find an epic board by ID'
end
alias_method
:group
,
:object
def
resolve
(
id:
nil
)
return
unless
Feature
.
enabled?
(
:epic_boards
,
group
)
return
unless
group
.
feature_available?
(
:epics
)
authorize!
::
Boards
::
EpicBoardsFinder
.
new
(
group
,
id:
id
&
.
model_id
).
execute
end
private
def
authorize!
Ability
.
allowed?
(
context
[
:current_user
],
:read_epic_board
,
group
)
||
raise_resource_not_available_error!
end
end
end
end
ee/app/graphql/types/boards/epic_board_type.rb
0 → 100644
View file @
c4fe6bd9
# frozen_string_literal: true
module
Types
module
Boards
class
EpicBoardType
<
BaseObject
graphql_name
'EpicBoard'
description
'Represents an epic board'
accepts
::
Boards
::
EpicBoard
authorize
:read_epic_board
field
:id
,
type:
::
Types
::
GlobalIDType
[
::
Boards
::
EpicBoard
],
null:
false
,
description:
'Global ID of the board'
field
:name
,
type:
GraphQL
::
STRING_TYPE
,
null:
true
,
description:
'Name of the board'
end
end
end
ee/app/models/boards/epic_board.rb
View file @
c4fe6bd9
...
...
@@ -7,5 +7,7 @@ module Boards
has_many
:epic_board_positions
,
foreign_key: :epic_board_id
,
inverse_of: :epic_board
validates
:name
,
length:
{
maximum:
255
}
scope
:order_by_name_asc
,
->
{
order
(
arel_table
[
:name
].
lower
.
asc
).
order
(
id: :asc
)
}
end
end
ee/app/policies/boards/epic_board_policy.rb
0 → 100644
View file @
c4fe6bd9
# frozen_string_literal: true
module
Boards
class
EpicBoardPolicy
<
::
BasePolicy
delegate
{
subject
.
group
}
end
end
ee/app/policies/ee/group_policy.rb
View file @
c4fe6bd9
...
...
@@ -165,7 +165,10 @@ module EE
enable
:change_prevent_group_forking
end
rule
{
can?
(
:read_group
)
&
epics_available
}.
enable
:read_epic
rule
{
can?
(
:read_group
)
&
epics_available
}.
policy
do
enable
:read_epic
enable
:read_epic_board
end
rule
{
can?
(
:read_group
)
&
iterations_available
}.
enable
:read_iteration
...
...
ee/config/feature_flags/development/epic_boards.yml
0 → 100644
View file @
c4fe6bd9
---
name
:
epic_boards
introduced_by_url
:
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48893
rollout_issue_url
:
https://gitlab.com/gitlab-org/gitlab/-/issues/290039
milestone
:
'
13.7'
type
:
development
group
:
group::plan
default_enabled
:
false
ee/spec/factories/epic_boards.rb
→
ee/spec/factories/
boards/
epic_boards.rb
View file @
c4fe6bd9
File moved
ee/spec/finders/boards/epic_boards_finder_spec.rb
0 → 100644
View file @
c4fe6bd9
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Boards
::
EpicBoardsFinder
do
describe
'#execute'
do
let_it_be
(
:group
)
{
create
(
:group
)
}
let_it_be
(
:epic_board1
)
{
create
(
:epic_board
,
name:
'Acd'
,
group:
group
)
}
let_it_be
(
:epic_board2
)
{
create
(
:epic_board
,
name:
'abd'
,
group:
group
)
}
let_it_be
(
:epic_board3
)
{
create
(
:epic_board
,
name:
'Bbd'
,
group:
group
)
}
let_it_be
(
:epic_board4
)
{
create
(
:epic_board
)
}
let
(
:params
)
{
{}
}
subject
(
:result
)
{
described_class
.
new
(
group
,
params
).
execute
}
it
'finds all epic boards in the group ordered by case-insensitive name'
do
expect
(
result
).
to
eq
([
epic_board2
,
epic_board1
,
epic_board3
])
end
context
'when ID parameter is set'
do
let
(
:params
)
{
{
id:
epic_board2
.
id
}
}
it
'finds epic board by ID'
do
expect
(
result
).
to
eq
([
epic_board2
])
end
end
end
end
ee/spec/graphql/ee/types/group_type_spec.rb
View file @
c4fe6bd9
...
...
@@ -5,8 +5,10 @@ require 'spec_helper'
RSpec
.
describe
GitlabSchema
.
types
[
'Group'
]
do
describe
'nested epic request'
do
it
{
expect
(
described_class
).
to
have_graphql_field
(
:epicsEnabled
)
}
it
{
expect
(
described_class
).
to
have_graphql_field
(
:epics
)
}
it
{
expect
(
described_class
).
to
have_graphql_field
(
:epic
)
}
it
{
expect
(
described_class
).
to
have_graphql_field
(
:epics
)
}
it
{
expect
(
described_class
).
to
have_graphql_field
(
:epic_board
)
}
it
{
expect
(
described_class
).
to
have_graphql_field
(
:epic_boards
)
}
end
it
{
expect
(
described_class
).
to
have_graphql_field
(
:iterations
)
}
...
...
ee/spec/graphql/resolvers/boards/epic_boards_resolvers_spec.rb
0 → 100644
View file @
c4fe6bd9
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Resolvers
::
Boards
::
EpicBoardsResolver
do
include
GraphqlHelpers
let_it_be
(
:user
)
{
create
(
:user
)
}
let_it_be_with_refind
(
:group
)
{
create
(
:group
,
:private
)
}
let_it_be
(
:epic_board1
)
{
create
(
:epic_board
,
name:
'fooB'
,
group:
group
)
}
let_it_be
(
:epic_board2
)
{
create
(
:epic_board
,
name:
'fooA'
,
group:
group
)
}
specify
do
expect
(
described_class
).
to
have_nullable_graphql_type
(
Types
::
Boards
::
EpicBoardType
.
connection_type
)
end
describe
'#resolve'
do
subject
(
:result
)
{
resolve
(
described_class
,
ctx:
{
current_user:
user
},
obj:
group
)
}
context
'when epics are not available'
do
before
do
stub_licensed_features
(
epics:
false
)
end
it
'returns nil'
do
expect
(
result
).
to
be_nil
end
end
context
'when epics are available'
do
before
do
stub_licensed_features
(
epics:
true
)
end
it
'raises an error if user cannot read epic boards'
do
expect
{
result
}.
to
raise_error
(
Gitlab
::
Graphql
::
Errors
::
ResourceNotAvailable
)
end
context
'when user is member of the group'
do
before
do
group
.
add_reporter
(
user
)
end
it
'returns epic boards in the group ordered by name'
do
expect
(
result
).
to
match_array
([
epic_board2
,
epic_board1
])
end
context
'when epic_boards flag is disabled'
do
before
do
stub_feature_flags
(
epic_boards:
false
)
end
it
'returns nil'
do
expect
(
result
).
to
be_nil
end
end
end
end
end
end
ee/spec/graphql/types/boards/epic_board_type_spec.rb
0 → 100644
View file @
c4fe6bd9
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
GitlabSchema
.
types
[
'EpicBoard'
]
do
specify
{
expect
(
described_class
.
graphql_name
).
to
eq
(
'EpicBoard'
)
}
specify
{
expect
(
described_class
).
to
require_graphql_authorizations
(
:read_epic_board
)
}
it
'has specific fields'
do
expected_fields
=
%w[id name]
expect
(
described_class
).
to
include_graphql_fields
(
*
expected_fields
)
end
end
ee/spec/models/boards/epic_board_spec.rb
View file @
c4fe6bd9
...
...
@@ -12,4 +12,14 @@ RSpec.describe Boards::EpicBoard do
describe
'validations'
do
it
{
is_expected
.
to
validate_length_of
(
:name
).
is_at_most
(
255
)
}
end
describe
'.order_by_name_asc'
do
let_it_be
(
:board1
)
{
create
(
:epic_board
,
name:
'B'
)
}
let_it_be
(
:board2
)
{
create
(
:epic_board
,
name:
'a'
)
}
let_it_be
(
:board3
)
{
create
(
:epic_board
,
name:
'A'
)
}
it
'returns in case-insensitive alphabetical order and then by ascending ID'
do
expect
(
described_class
.
order_by_name_asc
).
to
eq
[
board2
,
board3
,
board1
]
end
end
end
ee/spec/policies/group_policy_spec.rb
View file @
c4fe6bd9
...
...
@@ -5,10 +5,12 @@ require 'spec_helper'
RSpec
.
describe
GroupPolicy
do
include_context
'GroupPolicy context'
let
(
:epic_rules
)
{
%i(read_epic create_epic admin_epic destroy_epic read_confidential_epic destroy_epic_link read_epic_board)
}
context
'when epics feature is disabled'
do
let
(
:current_user
)
{
owner
}
it
{
is_expected
.
to
be_disallowed
(
:read_epic
,
:create_epic
,
:admin_epic
,
:destroy_epic
,
:read_confidential_epic
,
:destroy_epic_link
)
}
it
{
is_expected
.
to
be_disallowed
(
*
epic_rules
)
}
end
context
'when epics feature is enabled'
do
...
...
@@ -19,53 +21,53 @@ RSpec.describe GroupPolicy do
context
'when user is owner'
do
let
(
:current_user
)
{
owner
}
it
{
is_expected
.
to
be_allowed
(
:read_epic
,
:create_epic
,
:admin_epic
,
:destroy_epic
,
:read_confidential_epic
,
:destroy_epic_link
)
}
it
{
is_expected
.
to
be_allowed
(
*
epic_rules
)
}
end
context
'when user is admin'
do
let
(
:current_user
)
{
admin
}
it
{
is_expected
.
to
be_allowed
(
:read_epic
,
:create_epic
,
:admin_epic
,
:destroy_epic
,
:read_confidential_epic
,
:destroy_epic_link
)
}
it
{
is_expected
.
to
be_allowed
(
*
epic_rules
)
}
end
context
'when user is maintainer'
do
let
(
:current_user
)
{
maintainer
}
it
{
is_expected
.
to
be_allowed
(
:read_epic
,
:create_epic
,
:admin_epic
,
:read_confidential_epic
,
:destroy_epic_link
)
}
it
{
is_expected
.
to
be_allowed
(
*
(
epic_rules
-
[
:destroy_epic
])
)
}
it
{
is_expected
.
to
be_disallowed
(
:destroy_epic
)
}
end
context
'when user is developer'
do
let
(
:current_user
)
{
developer
}
it
{
is_expected
.
to
be_allowed
(
:read_epic
,
:create_epic
,
:admin_epic
,
:read_confidential_epic
,
:destroy_epic_link
)
}
it
{
is_expected
.
to
be_allowed
(
*
(
epic_rules
-
[
:destroy_epic
])
)
}
it
{
is_expected
.
to
be_disallowed
(
:destroy_epic
)
}
end
context
'when user is reporter'
do
let
(
:current_user
)
{
reporter
}
it
{
is_expected
.
to
be_allowed
(
:read_epic
,
:create_epic
,
:admin_epic
,
:read_confidential_epic
,
:destroy_epic_link
)
}
it
{
is_expected
.
to
be_allowed
(
*
(
epic_rules
-
[
:destroy_epic
])
)
}
it
{
is_expected
.
to
be_disallowed
(
:destroy_epic
)
}
end
context
'when user is guest'
do
let
(
:current_user
)
{
guest
}
it
{
is_expected
.
to
be_allowed
(
:read_epic
)
}
it
{
is_expected
.
to
be_disallowed
(
:create_epic
,
:admin_epic
,
:destroy_epic
,
:read_confidential_epic
,
:destroy_epic_link
)
}
it
{
is_expected
.
to
be_allowed
(
:read_epic
,
:read_epic_board
)
}
it
{
is_expected
.
to
be_disallowed
(
*
(
epic_rules
-
[
:read_epic
,
:read_epic_board
])
)
}
end
context
'when user is not member'
do
let
(
:current_user
)
{
create
(
:user
)
}
it
{
is_expected
.
to
be_disallowed
(
:read_epic
,
:create_epic
,
:admin_epic
,
:destroy_epic
,
:read_confidential_epic
,
:destroy_epic_link
)
}
it
{
is_expected
.
to
be_disallowed
(
*
epic_rules
)
}
end
context
'when user is anonymous'
do
let
(
:current_user
)
{
nil
}
it
{
is_expected
.
to
be_disallowed
(
:read_epic
,
:create_epic
,
:admin_epic
,
:destroy_epic
,
:read_confidential_epic
,
:destroy_epic_link
)
}
it
{
is_expected
.
to
be_disallowed
(
*
epic_rules
)
}
end
end
...
...
ee/spec/requests/api/graphql/boards/epic_boards_query_spec.rb
0 → 100644
View file @
c4fe6bd9
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
'get list of epic boards'
do
include
GraphqlHelpers
let_it_be
(
:current_user
)
{
create
(
:user
)
}
let_it_be
(
:group
)
{
create
(
:group
,
:private
)
}
let_it_be
(
:board1
)
{
create
(
:epic_board
,
group:
group
,
name:
'B'
)
}
let_it_be
(
:board2
)
{
create
(
:epic_board
,
group:
group
,
name:
'A'
)
}
let_it_be
(
:board3
)
{
create
(
:epic_board
,
group:
group
,
name:
'a'
)
}
def
pagination_query
(
params
=
{})
graphql_query_for
(
:group
,
{
full_path:
group
.
full_path
},
query_nodes
(
:epicBoards
,
all_graphql_fields_for
(
'epic_boards'
.
classify
),
include_pagination_info:
true
,
args:
params
)
)
end
before
do
stub_licensed_features
(
epics:
true
)
end
context
'when the user does not have access to the epic board group'
do
it
'returns nil group'
do
post_graphql
(
pagination_query
,
current_user:
current_user
)
expect
(
graphql_data
[
'group'
]).
to
be_nil
end
end
context
'when user can access the epic board group'
do
before
do
group
.
add_developer
(
current_user
)
end
describe
'sorting and pagination'
do
let
(
:data_path
)
{
[
:group
,
:epicBoards
]
}
let
(
:expected_results
)
{
[
board2
.
to_global_id
.
to_s
,
board3
.
to_global_id
.
to_s
,
board1
.
to_global_id
.
to_s
]
}
def
pagination_results_data
(
nodes
)
nodes
.
map
{
|
board
|
board
[
'id'
]
}
end
it_behaves_like
'sorted paginated query'
do
# currently we don't support custom sorting for epic boards,
# nil value will be ignored by ::Graphql::Arguments
let
(
:sort_param
)
{
nil
}
let
(
:first_param
)
{
2
}
end
end
context
'when epic_boards flag is disabled'
do
before
do
stub_feature_flags
(
epic_boards:
false
)
end
it
'returns nil epic_boards'
do
post_graphql
(
pagination_query
,
current_user:
current_user
)
boards
=
graphql_data
.
dig
(
'group'
,
'epicBoards'
)
expect
(
boards
).
to
be_nil
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