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
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],
null: false,
description: 'Updated to-do items.'
def resolve
def resolve(**args)
authorize!(current_user)
updated_ids = mark_all_todos_done
updated_ids = mark_all_todos_done(**args)
{
todos: Todo.id_in(updated_ids),
......@@ -24,10 +32,23 @@ module Mutations
private
def mark_all_todos_done
def mark_all_todos_done(**args)
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)
end
......
......@@ -4631,6 +4631,7 @@ Input type: `TodosMarkAllDoneInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <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
......@@ -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))
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
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