Commit 22e02af0 authored by Bob Van Landuyt's avatar Bob Van Landuyt

Merge branch 'graphql-todos-mark-all-done-for-target' into 'master'

Add GraphQL option to mark all todos of a specific target as done

See merge request gitlab-org/gitlab!83110
parents 50e7ad54 c8dccf44
...@@ -7,14 +7,22 @@ module Mutations ...@@ -7,14 +7,22 @@ module Mutations
authorize :update_user authorize :update_user
TodoableID = Types::GlobalIDType[Todoable]
argument :target_id,
TodoableID,
required: false,
description: "Global ID of the to-do item's parent. Issues, merge requests, designs, and epics are supported. " \
"If argument is omitted, all pending to-do items of the current user are marked as done."
field :todos, [::Types::TodoType], field :todos, [::Types::TodoType],
null: false, null: false,
description: 'Updated to-do items.' description: 'Updated to-do items.'
def resolve def resolve(**args)
authorize!(current_user) authorize!(current_user)
updated_ids = mark_all_todos_done updated_ids = mark_all_todos_done(**args)
{ {
todos: Todo.id_in(updated_ids), todos: Todo.id_in(updated_ids),
...@@ -24,10 +32,23 @@ module Mutations ...@@ -24,10 +32,23 @@ module Mutations
private private
def mark_all_todos_done def mark_all_todos_done(**args)
return [] unless current_user return [] unless current_user
todos = TodosFinder.new(current_user).execute finder_params = { state: :pending }
if args[:target_id].present?
target = Gitlab::Graphql::Lazy.force(
GitlabSchema.find_by_gid(TodoableID.coerce_isolated_input(args[:target_id]))
)
raise Gitlab::Graphql::Errors::ResourceNotAvailable, "Resource not available: #{args[:target_id]}" if target.nil?
finder_params[:type] = target.class.name
finder_params[:target_id] = target.id
end
todos = TodosFinder.new(current_user, finder_params).execute
TodoService.new.resolve_todos(todos, current_user, resolved_by_action: :api_all_done) TodoService.new.resolve_todos(todos, current_user, resolved_by_action: :api_all_done)
end end
......
...@@ -4631,6 +4631,7 @@ Input type: `TodosMarkAllDoneInput` ...@@ -4631,6 +4631,7 @@ Input type: `TodosMarkAllDoneInput`
| Name | Type | Description | | Name | Type | Description |
| ---- | ---- | ----------- | | ---- | ---- | ----------- |
| <a id="mutationtodosmarkalldoneclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | | <a id="mutationtodosmarkalldoneclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationtodosmarkalldonetargetid"></a>`targetId` | [`TodoableID`](#todoableid) | Global ID of the to-do item's parent. Issues, merge requests, designs, and epics are supported. If argument is omitted, all pending to-do items of the current user are marked as done. |
#### Fields #### Fields
...@@ -50,6 +50,37 @@ RSpec.describe 'Marking all todos done' do ...@@ -50,6 +50,37 @@ RSpec.describe 'Marking all todos done' do
expect(updated_todo_ids).to contain_exactly(global_id_of(todo1), global_id_of(todo3)) expect(updated_todo_ids).to contain_exactly(global_id_of(todo1), global_id_of(todo3))
end end
context 'when target_id is given', :aggregate_failures do
let_it_be(:target) { create(:issue, project: project) }
let_it_be(:target_todo1) { create(:todo, user: current_user, author: author, state: :pending, target: target) }
let_it_be(:target_todo2) { create(:todo, user: current_user, author: author, state: :pending, target: target) }
let(:input) { { 'targetId' => target.to_global_id.to_s } }
it 'marks all pending todos for the target as done' do
post_graphql_mutation(mutation, current_user: current_user)
expect(target_todo1.reload.state).to eq('done')
expect(target_todo2.reload.state).to eq('done')
expect(todo1.reload.state).to eq('pending')
expect(todo3.reload.state).to eq('pending')
updated_todo_ids = mutation_response['todos'].map { |todo| todo['id'] }
expect(updated_todo_ids).to contain_exactly(global_id_of(target_todo1), global_id_of(target_todo2))
end
context 'when target does not exist' do
let(:input) { { 'targetId' => "gid://gitlab/Issue/#{non_existing_record_id}" } }
it 'returns an error' do
post_graphql_mutation(mutation, current_user: current_user)
expect(graphql_errors).to include(a_hash_including('message' => include('Resource not available')))
end
end
end
it 'behaves as expected if there are no todos for the requesting user' do it 'behaves as expected if there are no todos for the requesting user' do
post_graphql_mutation(mutation, current_user: other_user2) post_graphql_mutation(mutation, current_user: other_user2)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment