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
a031673c
Commit
a031673c
authored
Nov 17, 2019
by
Patrick Derichs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add GraphQL mutation to restore a Todo
Also add specs
parent
34968253
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
382 additions
and
0 deletions
+382
-0
app/graphql/mutations/todos/restore.rb
app/graphql/mutations/todos/restore.rb
+36
-0
app/graphql/types/mutation_type.rb
app/graphql/types/mutation_type.rb
+1
-0
changelogs/unreleased/31914-graphql-todo-restore-pd.yml
changelogs/unreleased/31914-graphql-todo-restore-pd.yml
+5
-0
doc/api/graphql/reference/gitlab_schema.graphql
doc/api/graphql/reference/gitlab_schema.graphql
+36
-0
doc/api/graphql/reference/gitlab_schema.json
doc/api/graphql/reference/gitlab_schema.json
+133
-0
doc/api/graphql/reference/index.md
doc/api/graphql/reference/index.md
+8
-0
spec/graphql/mutations/todos/restore_spec.rb
spec/graphql/mutations/todos/restore_spec.rb
+66
-0
spec/requests/api/graphql/mutations/todos/restore_spec.rb
spec/requests/api/graphql/mutations/todos/restore_spec.rb
+97
-0
No files found.
app/graphql/mutations/todos/restore.rb
0 → 100644
View file @
a031673c
# frozen_string_literal: true
module
Mutations
module
Todos
class
Restore
<
::
Mutations
::
Todos
::
Base
graphql_name
'TodoRestore'
authorize
:update_todo
argument
:id
,
GraphQL
::
ID_TYPE
,
required:
true
,
description:
'The global id of the todo to restore'
field
:todo
,
Types
::
TodoType
,
null:
false
,
description:
'The requested todo'
def
resolve
(
id
:)
todo
=
authorized_find!
(
id:
id
)
restore
(
todo
.
id
)
if
todo
.
done?
{
todo:
todo
.
reset
,
errors:
errors_on_object
(
todo
)
}
end
private
def
restore
(
id
)
TodoService
.
new
.
mark_todos_as_pending_by_ids
([
id
],
current_user
)
end
end
end
end
app/graphql/types/mutation_type.rb
View file @
a031673c
...
@@ -21,6 +21,7 @@ module Types
...
@@ -21,6 +21,7 @@ module Types
mount_mutation
Mutations
::
Notes
::
Update
mount_mutation
Mutations
::
Notes
::
Update
mount_mutation
Mutations
::
Notes
::
Destroy
mount_mutation
Mutations
::
Notes
::
Destroy
mount_mutation
Mutations
::
Todos
::
MarkDone
mount_mutation
Mutations
::
Todos
::
MarkDone
mount_mutation
Mutations
::
Todos
::
Restore
end
end
end
end
...
...
changelogs/unreleased/31914-graphql-todo-restore-pd.yml
0 → 100644
View file @
a031673c
---
title
:
Add GraphQL mutation to restore a Todo
merge_request
:
20261
author
:
type
:
added
doc/api/graphql/reference/gitlab_schema.graphql
View file @
a031673c
...
@@ -3519,6 +3519,7 @@ type Mutation {
...
@@ -3519,6 +3519,7 @@ type Mutation {
mergeRequestSetWip
(
input
:
MergeRequestSetWipInput
!):
MergeRequestSetWipPayload
mergeRequestSetWip
(
input
:
MergeRequestSetWipInput
!):
MergeRequestSetWipPayload
removeAwardEmoji
(
input
:
RemoveAwardEmojiInput
!):
RemoveAwardEmojiPayload
removeAwardEmoji
(
input
:
RemoveAwardEmojiInput
!):
RemoveAwardEmojiPayload
todoMarkDone
(
input
:
TodoMarkDoneInput
!):
TodoMarkDonePayload
todoMarkDone
(
input
:
TodoMarkDoneInput
!):
TodoMarkDonePayload
todoRestore
(
input
:
TodoRestoreInput
!):
TodoRestorePayload
toggleAwardEmoji
(
input
:
ToggleAwardEmojiInput
!):
ToggleAwardEmojiPayload
toggleAwardEmoji
(
input
:
ToggleAwardEmojiInput
!):
ToggleAwardEmojiPayload
updateEpic
(
input
:
UpdateEpicInput
!):
UpdateEpicPayload
updateEpic
(
input
:
UpdateEpicInput
!):
UpdateEpicPayload
updateNote
(
input
:
UpdateNoteInput
!):
UpdateNotePayload
updateNote
(
input
:
UpdateNoteInput
!):
UpdateNotePayload
...
@@ -4992,6 +4993,41 @@ type TodoMarkDonePayload {
...
@@ -4992,6 +4993,41 @@ type TodoMarkDonePayload {
todo
:
Todo
!
todo
:
Todo
!
}
}
"""
Autogenerated input type of TodoRestore
"""
input
TodoRestoreInput
{
"""
A
unique
identifier
for
the
client
performing
the
mutation
.
"""
clientMutationId
:
String
"""
The
global
id
of
the
todo
to
restore
"""
id
:
ID
!
}
"""
Autogenerated return type of TodoRestore
"""
type
TodoRestorePayload
{
"""
A
unique
identifier
for
the
client
performing
the
mutation
.
"""
clientMutationId
:
String
"""
Reasons
why
the
mutation
failed
.
"""
errors
:
[
String
!]!
"""
The
requested
todo
"""
todo
:
Todo
!
}
enum
TodoStateEnum
{
enum
TodoStateEnum
{
done
done
pending
pending
...
...
doc/api/graphql/reference/gitlab_schema.json
View file @
a031673c
...
@@ -14328,6 +14328,33 @@
...
@@ -14328,6 +14328,33 @@
"isDeprecated"
:
false
,
"isDeprecated"
:
false
,
"deprecationReason"
:
null
"deprecationReason"
:
null
},
},
{
"name"
:
"todoRestore"
,
"description"
:
null
,
"args"
:
[
{
"name"
:
"input"
,
"description"
:
null
,
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"INPUT_OBJECT"
,
"name"
:
"TodoRestoreInput"
,
"ofType"
:
null
}
},
"defaultValue"
:
null
}
],
"type"
:
{
"kind"
:
"OBJECT"
,
"name"
:
"TodoRestorePayload"
,
"ofType"
:
null
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
{
"name"
:
"toggleAwardEmoji"
,
"name"
:
"toggleAwardEmoji"
,
"description"
:
null
,
"description"
:
null
,
...
@@ -16692,6 +16719,112 @@
...
@@ -16692,6 +16719,112 @@
"enumValues"
:
null
,
"enumValues"
:
null
,
"possibleTypes"
:
null
"possibleTypes"
:
null
},
},
{
"kind"
:
"OBJECT"
,
"name"
:
"TodoRestorePayload"
,
"description"
:
"Autogenerated return type of TodoRestore"
,
"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"
:
"Reasons why the mutation failed."
,
"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"
:
"todo"
,
"description"
:
"The requested todo"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"OBJECT"
,
"name"
:
"Todo"
,
"ofType"
:
null
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
}
],
"inputFields"
:
null
,
"interfaces"
:
[
],
"enumValues"
:
null
,
"possibleTypes"
:
null
},
{
"kind"
:
"INPUT_OBJECT"
,
"name"
:
"TodoRestoreInput"
,
"description"
:
"Autogenerated input type of TodoRestore"
,
"fields"
:
null
,
"inputFields"
:
[
{
"name"
:
"id"
,
"description"
:
"The global id of the todo to restore"
,
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"ID"
,
"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"
,
"kind"
:
"OBJECT"
,
"name"
:
"DesignManagementUploadPayload"
,
"name"
:
"DesignManagementUploadPayload"
,
...
...
doc/api/graphql/reference/index.md
View file @
a031673c
...
@@ -777,6 +777,14 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
...
@@ -777,6 +777,14 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
|
`errors`
| String! => Array | Reasons why the mutation failed. |
|
`errors`
| String! => Array | Reasons why the mutation failed. |
|
`todo`
| Todo! | The requested todo |
|
`todo`
| Todo! | The requested todo |
### TodoRestorePayload
| Name | Type | Description |
| --- | ---- | ---------- |
|
`clientMutationId`
| String | A unique identifier for the client performing the mutation. |
|
`errors`
| String! => Array | Reasons why the mutation failed. |
|
`todo`
| Todo! | The requested todo |
### ToggleAwardEmojiPayload
### ToggleAwardEmojiPayload
| Name | Type | Description |
| Name | Type | Description |
...
...
spec/graphql/mutations/todos/restore_spec.rb
0 → 100644
View file @
a031673c
# frozen_string_literal: true
require
'spec_helper'
describe
Mutations
::
Todos
::
Restore
do
let_it_be
(
:current_user
)
{
create
(
:user
)
}
let_it_be
(
:author
)
{
create
(
:user
)
}
let_it_be
(
:other_user
)
{
create
(
:user
)
}
let_it_be
(
:todo1
)
{
create
(
:todo
,
user:
current_user
,
author:
author
,
state: :done
)
}
let_it_be
(
:todo2
)
{
create
(
:todo
,
user:
current_user
,
author:
author
,
state: :pending
)
}
let_it_be
(
:other_user_todo
)
{
create
(
:todo
,
user:
other_user
,
author:
author
,
state: :done
)
}
let
(
:mutation
)
{
described_class
.
new
(
object:
nil
,
context:
{
current_user:
current_user
})
}
describe
'#resolve'
do
it
'restores a single todo'
do
result
=
restore_mutation
(
todo1
)
expect
(
todo1
.
reload
.
state
).
to
eq
(
'pending'
)
expect
(
todo2
.
reload
.
state
).
to
eq
(
'pending'
)
expect
(
other_user_todo
.
reload
.
state
).
to
eq
(
'done'
)
todo
=
result
[
:todo
]
expect
(
todo
.
id
).
to
eq
(
todo1
.
id
)
expect
(
todo
.
state
).
to
eq
(
'pending'
)
end
it
'handles a todo which is already pending as expected'
do
result
=
restore_mutation
(
todo2
)
expect
(
todo1
.
reload
.
state
).
to
eq
(
'done'
)
expect
(
todo2
.
reload
.
state
).
to
eq
(
'pending'
)
expect
(
other_user_todo
.
reload
.
state
).
to
eq
(
'done'
)
todo
=
result
[
:todo
]
expect
(
todo
.
id
).
to
eq
(
todo2
.
id
)
expect
(
todo
.
state
).
to
eq
(
'pending'
)
end
it
'ignores requests for todos which do not belong to the current user'
do
expect
{
restore_mutation
(
other_user_todo
)
}.
to
raise_error
(
Gitlab
::
Graphql
::
Errors
::
ResourceNotAvailable
)
expect
(
todo1
.
reload
.
state
).
to
eq
(
'done'
)
expect
(
todo2
.
reload
.
state
).
to
eq
(
'pending'
)
expect
(
other_user_todo
.
reload
.
state
).
to
eq
(
'done'
)
end
it
'ignores invalid GIDs'
do
expect
{
mutation
.
resolve
(
id:
'invalid_gid'
)
}.
to
raise_error
(
Gitlab
::
Graphql
::
Errors
::
ArgumentError
)
expect
(
todo1
.
reload
.
state
).
to
eq
(
'done'
)
expect
(
todo2
.
reload
.
state
).
to
eq
(
'pending'
)
expect
(
other_user_todo
.
reload
.
state
).
to
eq
(
'done'
)
end
end
def
restore_mutation
(
todo
)
mutation
.
resolve
(
id:
global_id_of
(
todo
))
end
def
global_id_of
(
todo
)
todo
.
to_global_id
.
to_s
end
end
spec/requests/api/graphql/mutations/todos/restore_spec.rb
0 → 100644
View file @
a031673c
# frozen_string_literal: true
require
'spec_helper'
describe
'Restoring Todos'
do
include
GraphqlHelpers
let_it_be
(
:current_user
)
{
create
(
:user
)
}
let_it_be
(
:author
)
{
create
(
:user
)
}
let_it_be
(
:other_user
)
{
create
(
:user
)
}
let_it_be
(
:todo1
)
{
create
(
:todo
,
user:
current_user
,
author:
author
,
state: :done
)
}
let_it_be
(
:todo2
)
{
create
(
:todo
,
user:
current_user
,
author:
author
,
state: :pending
)
}
let_it_be
(
:other_user_todo
)
{
create
(
:todo
,
user:
other_user
,
author:
author
,
state: :done
)
}
let
(
:input
)
{
{
id:
todo1
.
to_global_id
.
to_s
}
}
let
(
:mutation
)
do
graphql_mutation
(
:todo_restore
,
input
,
<<-
QL
.
strip_heredoc
clientMutationId
errors
todo {
id
state
}
QL
)
end
def
mutation_response
graphql_mutation_response
(
:todo_restore
)
end
it
'restores a single todo'
do
post_graphql_mutation
(
mutation
,
current_user:
current_user
)
expect
(
todo1
.
reload
.
state
).
to
eq
(
'pending'
)
expect
(
todo2
.
reload
.
state
).
to
eq
(
'pending'
)
expect
(
other_user_todo
.
reload
.
state
).
to
eq
(
'done'
)
todo
=
mutation_response
[
'todo'
]
expect
(
todo
[
'id'
]).
to
eq
(
todo1
.
to_global_id
.
to_s
)
expect
(
todo
[
'state'
]).
to
eq
(
'pending'
)
end
context
'when todo is already marked pending'
do
let
(
:input
)
{
{
id:
todo2
.
to_global_id
.
to_s
}
}
it
'has the expected response'
do
post_graphql_mutation
(
mutation
,
current_user:
current_user
)
expect
(
todo1
.
reload
.
state
).
to
eq
(
'done'
)
expect
(
todo2
.
reload
.
state
).
to
eq
(
'pending'
)
expect
(
other_user_todo
.
reload
.
state
).
to
eq
(
'done'
)
todo
=
mutation_response
[
'todo'
]
expect
(
todo
[
'id'
]).
to
eq
(
todo2
.
to_global_id
.
to_s
)
expect
(
todo
[
'state'
]).
to
eq
(
'pending'
)
end
end
context
'when todo does not belong to requesting user'
do
let
(
:input
)
{
{
id:
other_user_todo
.
to_global_id
.
to_s
}
}
let
(
:access_error
)
{
'The resource that you are attempting to access does not exist or you don\'t have permission to perform this action'
}
it
'contains the expected error'
do
post_graphql_mutation
(
mutation
,
current_user:
current_user
)
errors
=
json_response
[
'errors'
]
expect
(
errors
).
not_to
be_blank
expect
(
errors
.
first
[
'message'
]).
to
eq
(
access_error
)
expect
(
todo1
.
reload
.
state
).
to
eq
(
'done'
)
expect
(
todo2
.
reload
.
state
).
to
eq
(
'pending'
)
expect
(
other_user_todo
.
reload
.
state
).
to
eq
(
'done'
)
end
end
context
'when using an invalid gid'
do
let
(
:input
)
{
{
id:
'invalid_gid'
}
}
let
(
:invalid_gid_error
)
{
'invalid_gid is not a valid GitLab id.'
}
it
'contains the expected error'
do
post_graphql_mutation
(
mutation
,
current_user:
current_user
)
errors
=
json_response
[
'errors'
]
expect
(
errors
).
not_to
be_blank
expect
(
errors
.
first
[
'message'
]).
to
eq
(
invalid_gid_error
)
expect
(
todo1
.
reload
.
state
).
to
eq
(
'done'
)
expect
(
todo2
.
reload
.
state
).
to
eq
(
'pending'
)
expect
(
other_user_todo
.
reload
.
state
).
to
eq
(
'done'
)
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