Commit c8dccf44 authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Add target_id option to TodosMarkAllDone mutation

This allows marking all pending todos of a specific target object as
done. Previously, this mutation always marked all pending todos of the
current user.

Changelog: added
parent 962a98fc
...@@ -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