Ensure that we only have one task per issue/mr

parent 44656136
...@@ -6,6 +6,11 @@ module Issues ...@@ -6,6 +6,11 @@ module Issues
def handle_changes(issue, options = {}) def handle_changes(issue, options = {})
if have_changes?(issue, options) if have_changes?(issue, options)
task_service.mark_pending_tasks_as_done(issue, current_user)
end
if issue.previous_changes.include?('title') ||
issue.previous_changes.include?('description')
task_service.update_issue(issue, current_user) task_service.update_issue(issue, current_user)
end end
......
...@@ -16,6 +16,11 @@ module MergeRequests ...@@ -16,6 +16,11 @@ module MergeRequests
def handle_changes(merge_request, options = {}) def handle_changes(merge_request, options = {})
if have_changes?(merge_request, options) if have_changes?(merge_request, options)
task_service.mark_pending_tasks_as_done(merge_request, current_user)
end
if merge_request.previous_changes.include?('title') ||
merge_request.previous_changes.include?('description')
task_service.update_merge_request(merge_request, current_user) task_service.update_merge_request(merge_request, current_user)
end end
......
...@@ -18,10 +18,9 @@ class TaskService ...@@ -18,10 +18,9 @@ class TaskService
# When update an issue we should: # When update an issue we should:
# #
# * mark all pending tasks related to the issue for the current user as done # * mark all pending tasks related to the issue for the current user as done
# * create a task for each new user mentioned on issue
# #
def update_issue(issue, current_user) def update_issue(issue, current_user)
update_issuable(issue, current_user) create_mention_tasks(issue.project, issue, current_user)
end end
# When close an issue we should: # When close an issue we should:
...@@ -37,7 +36,7 @@ class TaskService ...@@ -37,7 +36,7 @@ class TaskService
# * create a pending task for new assignee if issue is assigned # * create a pending task for new assignee if issue is assigned
# #
def reassigned_issue(issue, current_user) def reassigned_issue(issue, current_user)
reassigned_issuable(issue, current_user) create_assignment_task(issue, current_user)
end end
# When create a merge request we should: # When create a merge request we should:
...@@ -51,11 +50,10 @@ class TaskService ...@@ -51,11 +50,10 @@ class TaskService
# When update a merge request we should: # When update a merge request we should:
# #
# * mark all pending tasks related to the merge request for the current user as done # * create a task for each mentioned user on merge request
# * create a task for each new user mentioned on merge request
# #
def update_merge_request(merge_request, current_user) def update_merge_request(merge_request, current_user)
update_issuable(merge_request, current_user) create_mention_tasks(merge_request.project, merge_request, current_user)
end end
# When close a merge request we should: # When close a merge request we should:
...@@ -71,7 +69,7 @@ class TaskService ...@@ -71,7 +69,7 @@ class TaskService
# * creates a pending task for new assignee if merge request is assigned # * creates a pending task for new assignee if merge request is assigned
# #
def reassigned_merge_request(merge_request, current_user) def reassigned_merge_request(merge_request, current_user)
reassigned_issuable(merge_request, current_user) create_assignment_task(merge_request, current_user)
end end
# When merge a merge request we should: # When merge a merge request we should:
...@@ -87,21 +85,8 @@ class TaskService ...@@ -87,21 +85,8 @@ class TaskService
# * mark all pending tasks related to the noteable for the note author as done # * mark all pending tasks related to the noteable for the note author as done
# * create a task for each mentioned user on note # * create a task for each mentioned user on note
# #
def new_note(note) def new_note(note, current_user)
# Skip system notes, like status changes and cross-references handle_note(note, current_user)
return if note.system
project = note.project
target = note.noteable
author = note.author
mark_pending_tasks_as_done(target, author)
mentioned_users = build_mentioned_users(project, note, author)
mentioned_users.each do |user|
create_task(project, target, author, user, Task::MENTIONED, note)
end
end end
# When update a note we should: # When update a note we should:
...@@ -110,28 +95,24 @@ class TaskService ...@@ -110,28 +95,24 @@ class TaskService
# * create a task for each new user mentioned on note # * create a task for each new user mentioned on note
# #
def update_note(note, current_user) def update_note(note, current_user)
# Skip system notes, like status changes and cross-references handle_note(note, current_user)
return if note.system
project = note.project
target = note.noteable
author = current_user
mark_pending_tasks_as_done(target, author)
mentioned_users = build_mentioned_users(project, note, author)
mentioned_users.each do |user|
unless pending_tasks(mentioned_user, project, target, note: note, action: Task::MENTIONED).exists?
create_task(project, target, author, user, Task::MENTIONED, note)
end
end end
# When marking pending tasks as done we should:
#
# * mark all pending tasks related to the target for the current user as done
#
def mark_pending_tasks_as_done(target, user)
pending_tasks(user, target.project, target).update_all(state: :done)
end end
private private
def create_task(project, target, author, user, action, note = nil) def create_tasks(project, target, author, users, action, note = nil)
attributes = { Array(users).each do |user|
next if pending_tasks(user, project, target).exists?
Task.create(
project: project, project: project,
user_id: user.id, user_id: user.id,
author_id: author.id, author_id: author.id,
...@@ -139,68 +120,51 @@ class TaskService ...@@ -139,68 +120,51 @@ class TaskService
target_type: target.class.name, target_type: target.class.name,
action: action, action: action,
note: note note: note
} )
Task.create(attributes)
end
def build_mentioned_users(project, target, author)
mentioned_users = target.mentioned_users.select do |user|
user.can?(:read_project, project)
end end
mentioned_users.delete(author)
mentioned_users.uniq
end end
def mark_pending_tasks_as_done(target, user) def new_issuable(issuable, author)
pending_tasks(user, target.project, target).update_all(state: :done) create_assignment_task(issuable, author)
create_mention_tasks(issuable.project, issuable, author)
end end
def pending_tasks(user, project, target, options = {}) def handle_note(note, author)
options.reverse_merge( # Skip system notes, like status changes and cross-references
project: project, return if note.system
target: target
)
user.tasks.pending.where(options)
end
def new_issuable(issuable, current_user) project = note.project
project = issuable.project target = note.noteable
target = issuable
author = issuable.author
if target.is_assigned? && target.assignee != current_user mark_pending_tasks_as_done(target, author)
create_task(project, target, author, target.assignee, Task::ASSIGNED) create_mention_tasks(project, target, author, note)
end end
mentioned_users = build_mentioned_users(project, target, author) def create_assignment_task(issuable, author)
mentioned_users.delete(issuable.assignee) if issuable.assignee && issuable.assignee != author
create_tasks(issuable.project, issuable, author, issuable.assignee, Task::ASSIGNED)
mentioned_users.each do |mentioned_user|
create_task(project, target, author, mentioned_user, Task::MENTIONED)
end end
end end
def update_issuable(issuable, current_user) def create_mention_tasks(project, issuable, author, note = nil)
project = issuable.project mentioned_users = filter_mentioned_users(project, note || issuable, author)
author = current_user create_tasks(project, issuable, author, mentioned_users, Task::MENTIONED, note)
mark_pending_tasks_as_done(issuable, author)
mentioned_users = build_mentioned_users(project, issuable, author)
mentioned_users.each do |mentioned_user|
unless pending_tasks(mentioned_user, project, issuable, action: Task::MENTIONED).exists?
create_task(project, issuable, author, mentioned_user, Task::MENTIONED)
end
end end
def filter_mentioned_users(project, target, author)
mentioned_users = target.mentioned_users.select do |user|
user.can?(:read_project, project)
end end
def reassigned_issuable(issuable, current_user) mentioned_users.delete(author)
if issuable.assignee && issuable.assignee != current_user mentioned_users.uniq
create_task(issuable.project, issuable, current_user, issuable.assignee, Task::ASSIGNED)
end end
def pending_tasks(user, project, target)
user.tasks.pending.where(
project_id: project.id,
target_id: target.id,
target_type: target.class.name
)
end end
end end
...@@ -45,13 +45,6 @@ describe TaskService, services: true do ...@@ -45,13 +45,6 @@ describe TaskService, services: true do
end end
describe '#update_issue' do describe '#update_issue' do
it 'marks pending tasks to the issue for the user as done' do
pending_task = create(:task, :assigned, user: john_doe, project: project, target: issue, author: author)
service.update_issue(issue, john_doe)
expect(pending_task.reload).to be_done
end
it 'creates a task for each valid mentioned user' do it 'creates a task for each valid mentioned user' do
service.update_issue(issue, author) service.update_issue(issue, author)
...@@ -101,6 +94,18 @@ describe TaskService, services: true do ...@@ -101,6 +94,18 @@ describe TaskService, services: true do
end end
end end
describe '#mark_pending_tasks_as_done' do
it 'marks related pending tasks to the target for the user as done' do
first_task = create(:task, :assigned, user: john_doe, project: project, target: issue, author: author)
second_task = create(:task, :assigned, user: john_doe, project: project, target: issue, author: author)
service.mark_pending_tasks_as_done(issue, john_doe)
expect(first_task.reload).to be_done
expect(second_task.reload).to be_done
end
end
describe '#new_note' do describe '#new_note' do
let!(:first_task) { create(:task, :assigned, user: john_doe, project: project, target: issue, author: author) } let!(:first_task) { create(:task, :assigned, user: john_doe, project: project, target: issue, author: author) }
let!(:second_task) { create(:task, :assigned, user: john_doe, project: project, target: issue, author: author) } let!(:second_task) { create(:task, :assigned, user: john_doe, project: project, target: issue, author: author) }
...@@ -112,28 +117,28 @@ describe TaskService, services: true do ...@@ -112,28 +117,28 @@ describe TaskService, services: true do
first_task = create(:task, :assigned, user: john_doe, project: project, target: issue, author: author) first_task = create(:task, :assigned, user: john_doe, project: project, target: issue, author: author)
second_task = create(:task, :assigned, user: john_doe, project: project, target: issue, author: author) second_task = create(:task, :assigned, user: john_doe, project: project, target: issue, author: author)
service.new_note(note) service.new_note(note, john_doe)
expect(first_task.reload).to be_done expect(first_task.reload).to be_done
expect(second_task.reload).to be_done expect(second_task.reload).to be_done
end end
it 'mark related pending tasks to the noteable for the award note author as done' do it 'mark related pending tasks to the noteable for the award note author as done' do
service.new_note(award_note) service.new_note(award_note, john_doe)
expect(first_task.reload).to be_done expect(first_task.reload).to be_done
expect(second_task.reload).to be_done expect(second_task.reload).to be_done
end end
it 'does not mark related pending tasks it is a system note' do it 'does not mark related pending tasks it is a system note' do
service.new_note(system_note) service.new_note(system_note, john_doe)
expect(first_task.reload).to be_pending expect(first_task.reload).to be_pending
expect(second_task.reload).to be_pending expect(second_task.reload).to be_pending
end end
it 'creates a task for each valid mentioned user' do it 'creates a task for each valid mentioned user' do
service.new_note(note) service.new_note(note, john_doe)
should_create_task(user: michael, target: issue, author: john_doe, action: Task::MENTIONED, note: note) should_create_task(user: michael, target: issue, author: john_doe, action: Task::MENTIONED, note: note)
should_create_task(user: author, target: issue, author: john_doe, action: Task::MENTIONED, note: note) should_create_task(user: author, target: issue, author: john_doe, action: Task::MENTIONED, note: note)
...@@ -173,13 +178,6 @@ describe TaskService, services: true do ...@@ -173,13 +178,6 @@ describe TaskService, services: true do
end end
describe '#update_merge_request' do describe '#update_merge_request' do
it 'marks pending tasks to the merge request for the user as done' do
pending_task = create(:task, :assigned, user: john_doe, project: project, target: mr_assigned, author: author)
service.update_merge_request(mr_assigned, john_doe)
expect(pending_task.reload).to be_done
end
it 'creates a task for each valid mentioned user' do it 'creates a task for each valid mentioned user' do
service.update_merge_request(mr_assigned, author) service.update_merge_request(mr_assigned, author)
......
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