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
0100d939
Commit
0100d939
authored
Aug 03, 2020
by
Allison Browne
Committed by
Adam Hegyi
Aug 03, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support getting a todo for an alert in graphql api
parent
dc6fa046
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
337 additions
and
9 deletions
+337
-9
app/finders/todos_finder.rb
app/finders/todos_finder.rb
+9
-1
app/graphql/resolvers/todo_resolver.rb
app/graphql/resolvers/todo_resolver.rb
+13
-3
app/graphql/types/alert_management/alert_type.rb
app/graphql/types/alert_management/alert_type.rb
+6
-0
app/helpers/todos_helper.rb
app/helpers/todos_helper.rb
+2
-1
changelogs/unreleased/graphql-get-alert-todo.yml
changelogs/unreleased/graphql-get-alert-todo.yml
+5
-0
doc/api/graphql/reference/gitlab_schema.graphql
doc/api/graphql/reference/gitlab_schema.graphql
+55
-0
doc/api/graphql/reference/gitlab_schema.json
doc/api/graphql/reference/gitlab_schema.json
+161
-0
spec/finders/todos_finder_spec.rb
spec/finders/todos_finder_spec.rb
+22
-2
spec/graphql/resolvers/todo_resolver_spec.rb
spec/graphql/resolvers/todo_resolver_spec.rb
+12
-2
spec/graphql/types/alert_management/alert_type_spec.rb
spec/graphql/types/alert_management/alert_type_spec.rb
+1
-0
spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb
.../api/graphql/project/alert_management/alert/todos_spec.rb
+51
-0
No files found.
app/finders/todos_finder.rb
View file @
0100d939
...
...
@@ -10,6 +10,7 @@
# action_id: integer
# author_id: integer
# project_id; integer
# target_id; integer
# state: 'pending' (default) or 'done'
# type: 'Issue' or 'MergeRequest' or ['Issue', 'MergeRequest']
#
...
...
@@ -23,7 +24,7 @@ class TodosFinder
NONE
=
'0'
TODO_TYPES
=
Set
.
new
(
%w(Issue MergeRequest DesignManagement::Design)
).
freeze
TODO_TYPES
=
Set
.
new
(
%w(Issue MergeRequest DesignManagement::Design
AlertManagement::Alert
)
).
freeze
attr_accessor
:current_user
,
:params
...
...
@@ -47,6 +48,7 @@ class TodosFinder
items
=
by_action
(
items
)
items
=
by_author
(
items
)
items
=
by_state
(
items
)
items
=
by_target_id
(
items
)
items
=
by_types
(
items
)
items
=
by_group
(
items
)
# Filtering by project HAS TO be the last because we use
...
...
@@ -198,6 +200,12 @@ class TodosFinder
items
.
with_states
(
params
[
:state
])
end
def
by_target_id
(
items
)
return
items
if
params
[
:target_id
].
blank?
items
.
for_target
(
params
[
:target_id
])
end
def
by_types
(
items
)
if
types
.
any?
items
.
for_type
(
types
)
...
...
app/graphql/resolvers/todo_resolver.rb
View file @
0100d939
...
...
@@ -4,7 +4,7 @@ module Resolvers
class
TodoResolver
<
BaseResolver
type
Types
::
TodoType
,
null:
true
alias_method
:
user
,
:object
alias_method
:
target
,
:object
argument
:action
,
[
Types
::
TodoActionEnum
],
required:
false
,
...
...
@@ -31,9 +31,10 @@ module Resolvers
description:
'The type of the todo'
def
resolve
(
**
args
)
return
Todo
.
none
if
user
!=
context
[
:current_user
]
return
Todo
.
none
unless
current_user
.
present?
&&
target
.
present?
return
Todo
.
none
if
target
.
is_a?
(
User
)
&&
target
!=
current_user
TodosFinder
.
new
(
user
,
todo_finder_params
(
args
)).
execute
TodosFinder
.
new
(
current_
user
,
todo_finder_params
(
args
)).
execute
end
private
...
...
@@ -46,6 +47,15 @@ module Resolvers
author_id:
args
[
:author_id
],
action_id:
args
[
:action
],
project_id:
args
[
:project_id
]
}.
merge
(
target_params
)
end
def
target_params
return
{}
unless
TodosFinder
::
TODO_TYPES
.
include?
(
target
.
class
.
name
)
{
type:
target
.
class
.
name
,
target_id:
target
.
id
}
end
end
...
...
app/graphql/types/alert_management/alert_type.rb
View file @
0100d939
...
...
@@ -97,6 +97,12 @@ module Types
description:
'URL for metrics embed for the alert'
,
resolve:
->
(
alert
,
_args
,
_context
)
{
alert
.
present
.
metrics_dashboard_url
}
field
:todos
,
Types
::
TodoType
.
connection_type
,
null:
true
,
description:
'Todos of the current user for the alert'
,
resolver:
Resolvers
::
TodoResolver
def
notes
object
.
ordered_notes
end
...
...
app/helpers/todos_helper.rb
View file @
0100d939
...
...
@@ -163,7 +163,8 @@ module TodosHelper
{
id:
''
,
text:
'Any Type'
},
{
id:
'Issue'
,
text:
'Issue'
},
{
id:
'MergeRequest'
,
text:
'Merge Request'
},
{
id:
'DesignManagement::Design'
,
text:
'Design'
}
{
id:
'DesignManagement::Design'
,
text:
'Design'
},
{
id:
'AlertManagement::Alert'
,
text:
'Alert'
}
]
end
...
...
changelogs/unreleased/graphql-get-alert-todo.yml
0 → 100644
View file @
0100d939
---
title
:
Support getting a todo for an alert in GraphQL API
merge_request
:
34789
author
:
type
:
added
doc/api/graphql/reference/gitlab_schema.graphql
View file @
0100d939
...
...
@@ -319,6 +319,61 @@ type AlertManagementAlert implements Noteable {
"""
title
:
String
"""
Todos
of
the
current
user
for
the
alert
"""
todos
(
"""
The
action
to
be
filtered
"""
action
:
[
TodoActionEnum
!]
"""
Returns
the
elements
in
the
list
that
come
after
the
specified
cursor
.
"""
after
:
String
"""
The
ID
of
an
author
"""
authorId
:
[
ID
!]
"""
Returns
the
elements
in
the
list
that
come
before
the
specified
cursor
.
"""
before
:
String
"""
Returns
the
first
_n_
elements
from
the
list
.
"""
first
:
Int
"""
The
ID
of
a
group
"""
groupId
:
[
ID
!]
"""
Returns
the
last
_n_
elements
from
the
list
.
"""
last
:
Int
"""
The
ID
of
a
project
"""
projectId
:
[
ID
!]
"""
The
state
of
the
todo
"""
state
:
[
TodoStateEnum
!]
"""
The
type
of
the
todo
"""
type
:
[
TodoTargetEnum
!]
):
TodoConnection
"""
Timestamp
the
alert
was
last
updated
"""
...
...
doc/api/graphql/reference/gitlab_schema.json
View file @
0100d939
...
...
@@ -871,6 +871,167 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "todos",
"description": "Todos of the current user for the alert",
"args": [
{
"name": "action",
"description": "The action to be filtered",
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "TodoActionEnum",
"ofType": null
}
}
},
"defaultValue": null
},
{
"name": "authorId",
"description": "The ID of an author",
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
}
},
"defaultValue": null
},
{
"name": "projectId",
"description": "The ID of a project",
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
}
},
"defaultValue": null
},
{
"name": "groupId",
"description": "The ID of a group",
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
}
},
"defaultValue": null
},
{
"name": "state",
"description": "The state of the todo",
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "TodoStateEnum",
"ofType": null
}
}
},
"defaultValue": null
},
{
"name": "type",
"description": "The type of the todo",
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "TodoTargetEnum",
"ofType": null
}
}
},
"defaultValue": null
},
{
"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": "TodoConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "updatedAt",
"description": "Timestamp the alert was last updated",
spec/finders/todos_finder_spec.rb
View file @
0100d939
...
...
@@ -232,6 +232,26 @@ RSpec.describe TodosFinder do
expect
(
todos
).
to
match_array
([
todo2
,
todo1
])
end
end
context
'when filtering by target id'
do
it
'returns the expected todos for the target'
do
todos
=
finder
.
new
(
user
,
{
target_id:
issue
.
id
}).
execute
expect
(
todos
).
to
match_array
([
todo1
])
end
it
'returns the expected todos for multiple target ids'
do
todos
=
finder
.
new
(
user
,
{
target_id:
[
issue
.
id
,
merge_request
.
id
]
}).
execute
expect
(
todos
).
to
match_array
([
todo1
,
todo2
])
end
it
'returns the expected todos for empty target id collection'
do
todos
=
finder
.
new
(
user
,
{
target_id:
[]
}).
execute
expect
(
todos
).
to
match_array
([
todo1
,
todo2
])
end
end
end
context
'external authorization'
do
...
...
@@ -307,9 +327,9 @@ RSpec.describe TodosFinder do
it
'returns the expected types'
do
expected_result
=
if
Gitlab
.
ee?
%w[Epic Issue MergeRequest DesignManagement::Design]
%w[Epic Issue MergeRequest DesignManagement::Design
AlertManagement::Alert
]
else
%w[Issue MergeRequest DesignManagement::Design]
%w[Issue MergeRequest DesignManagement::Design
AlertManagement::Alert
]
end
expect
(
described_class
.
todo_types
).
to
contain_exactly
(
*
expected_result
)
...
...
spec/graphql/resolvers/todo_resolver_spec.rb
View file @
0100d939
...
...
@@ -99,7 +99,7 @@ RSpec.describe Resolvers::TodoResolver do
end
end
context
'when no
user
is provided'
do
context
'when no
target
is provided'
do
it
'returns no todos'
do
todos
=
resolve
(
described_class
,
obj:
nil
,
args:
{},
ctx:
{
current_user:
current_user
})
...
...
@@ -107,7 +107,7 @@ RSpec.describe Resolvers::TodoResolver do
end
end
context
'when
provided user is not
current user'
do
context
'when
target user is not the
current user'
do
it
'returns no todos'
do
other_user
=
create
(
:user
)
...
...
@@ -116,6 +116,16 @@ RSpec.describe Resolvers::TodoResolver do
expect
(
todos
).
to
be_empty
end
end
context
'when request is for a todo target'
do
it
'returns only the todos for the target'
do
target
=
issue_todo_pending
.
target
todos
=
resolve
(
described_class
,
obj:
target
,
args:
{},
ctx:
{
current_user:
current_user
})
expect
(
todos
).
to
contain_exactly
(
issue_todo_pending
)
end
end
end
def
resolve_todos
(
args
=
{},
context
=
{
current_user:
current_user
})
...
...
spec/graphql/types/alert_management/alert_type_spec.rb
View file @
0100d939
...
...
@@ -28,6 +28,7 @@ RSpec.describe GitlabSchema.types['AlertManagementAlert'] do
notes
discussions
metrics_dashboard_url
todos
]
expect
(
described_class
).
to
have_graphql_fields
(
*
expected_fields
)
...
...
spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb
0 → 100644
View file @
0100d939
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
'getting Alert Management Alert Assignees'
do
include
GraphqlHelpers
let_it_be
(
:project
)
{
create
(
:project
)
}
let_it_be
(
:current_user
)
{
create
(
:user
)
}
let_it_be
(
:alert
)
{
create
(
:alert_management_alert
,
project:
project
)
}
let_it_be
(
:other_alert
)
{
create
(
:alert_management_alert
,
project:
project
)
}
let_it_be
(
:todo
)
{
create
(
:todo
,
:pending
,
target:
alert
,
user:
current_user
,
project:
project
)
}
let_it_be
(
:other_todo
)
{
create
(
:todo
,
:pending
,
target:
other_alert
,
user:
current_user
,
project:
project
)
}
let
(
:fields
)
do
<<~
QUERY
nodes {
iid
todos {
nodes {
id
}
}
}
QUERY
end
let
(
:graphql_query
)
do
graphql_query_for
(
'project'
,
{
'fullPath'
=>
project
.
full_path
},
query_graphql_field
(
'alertManagementAlerts'
,
{},
fields
)
)
end
let
(
:gql_alerts
)
{
graphql_data
.
dig
(
'project'
,
'alertManagementAlerts'
,
'nodes'
)
}
let
(
:gql_todos
)
{
gql_alerts
.
map
{
|
gql_alert
|
[
gql_alert
[
'iid'
],
gql_alert
[
'todos'
][
'nodes'
]]
}.
to_h
}
let
(
:gql_alert_todo
)
{
gql_todos
[
alert
.
iid
.
to_s
].
first
}
let
(
:gql_other_alert_todo
)
{
gql_todos
[
other_alert
.
iid
.
to_s
].
first
}
before
do
project
.
add_developer
(
current_user
)
end
it
'includes the correct metrics dashboard url'
do
post_graphql
(
graphql_query
,
current_user:
current_user
)
expect
(
gql_alert_todo
[
'id'
]).
to
eq
(
todo
.
to_global_id
.
to_s
)
expect
(
gql_other_alert_todo
[
'id'
]).
to
eq
(
other_todo
.
to_global_id
.
to_s
)
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