mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-21 10:36:04 +10:00
Ensure that we only have one task per issue/mr
This commit is contained in:
@@ -6,6 +6,11 @@ module Issues
|
||||
|
||||
def handle_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)
|
||||
end
|
||||
|
||||
|
||||
@@ -16,6 +16,11 @@ module MergeRequests
|
||||
|
||||
def handle_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)
|
||||
end
|
||||
|
||||
|
||||
@@ -18,10 +18,9 @@ class TaskService
|
||||
# When update an issue we should:
|
||||
#
|
||||
# * 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)
|
||||
update_issuable(issue, current_user)
|
||||
create_mention_tasks(issue.project, issue, current_user)
|
||||
end
|
||||
|
||||
# When close an issue we should:
|
||||
@@ -37,7 +36,7 @@ class TaskService
|
||||
# * create a pending task for new assignee if issue is assigned
|
||||
#
|
||||
def reassigned_issue(issue, current_user)
|
||||
reassigned_issuable(issue, current_user)
|
||||
create_assignment_task(issue, current_user)
|
||||
end
|
||||
|
||||
# When create a merge request we should:
|
||||
@@ -51,11 +50,10 @@ class TaskService
|
||||
|
||||
# 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 new user mentioned on merge request
|
||||
# * create a task for each mentioned user on merge request
|
||||
#
|
||||
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
|
||||
|
||||
# When close a merge request we should:
|
||||
@@ -71,7 +69,7 @@ class TaskService
|
||||
# * creates a pending task for new assignee if merge request is assigned
|
||||
#
|
||||
def reassigned_merge_request(merge_request, current_user)
|
||||
reassigned_issuable(merge_request, current_user)
|
||||
create_assignment_task(merge_request, current_user)
|
||||
end
|
||||
|
||||
# When merge a merge request we should:
|
||||
@@ -87,21 +85,8 @@ class TaskService
|
||||
# * mark all pending tasks related to the noteable for the note author as done
|
||||
# * create a task for each mentioned user on note
|
||||
#
|
||||
def new_note(note)
|
||||
# Skip system notes, like status changes and cross-references
|
||||
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
|
||||
def new_note(note, current_user)
|
||||
handle_note(note, current_user)
|
||||
end
|
||||
|
||||
# When update a note we should:
|
||||
@@ -110,41 +95,63 @@ class TaskService
|
||||
# * create a task for each new user mentioned on note
|
||||
#
|
||||
def update_note(note, current_user)
|
||||
handle_note(note, current_user)
|
||||
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
|
||||
|
||||
private
|
||||
|
||||
def create_tasks(project, target, author, users, action, note = nil)
|
||||
Array(users).each do |user|
|
||||
next if pending_tasks(user, project, target).exists?
|
||||
|
||||
Task.create(
|
||||
project: project,
|
||||
user_id: user.id,
|
||||
author_id: author.id,
|
||||
target_id: target.id,
|
||||
target_type: target.class.name,
|
||||
action: action,
|
||||
note: note
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def new_issuable(issuable, author)
|
||||
create_assignment_task(issuable, author)
|
||||
create_mention_tasks(issuable.project, issuable, author)
|
||||
end
|
||||
|
||||
def handle_note(note, author)
|
||||
# Skip system notes, like status changes and cross-references
|
||||
return if note.system
|
||||
|
||||
project = note.project
|
||||
target = note.noteable
|
||||
author = current_user
|
||||
|
||||
mark_pending_tasks_as_done(target, author)
|
||||
create_mention_tasks(project, target, author, note)
|
||||
end
|
||||
|
||||
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
|
||||
def create_assignment_task(issuable, author)
|
||||
if issuable.assignee && issuable.assignee != author
|
||||
create_tasks(issuable.project, issuable, author, issuable.assignee, Task::ASSIGNED)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_task(project, target, author, user, action, note = nil)
|
||||
attributes = {
|
||||
project: project,
|
||||
user_id: user.id,
|
||||
author_id: author.id,
|
||||
target_id: target.id,
|
||||
target_type: target.class.name,
|
||||
action: action,
|
||||
note: note
|
||||
}
|
||||
|
||||
Task.create(attributes)
|
||||
def create_mention_tasks(project, issuable, author, note = nil)
|
||||
mentioned_users = filter_mentioned_users(project, note || issuable, author)
|
||||
create_tasks(project, issuable, author, mentioned_users, Task::MENTIONED, note)
|
||||
end
|
||||
|
||||
def build_mentioned_users(project, target, author)
|
||||
def filter_mentioned_users(project, target, author)
|
||||
mentioned_users = target.mentioned_users.select do |user|
|
||||
user.can?(:read_project, project)
|
||||
end
|
||||
@@ -153,54 +160,11 @@ class TaskService
|
||||
mentioned_users.uniq
|
||||
end
|
||||
|
||||
def mark_pending_tasks_as_done(target, user)
|
||||
pending_tasks(user, target.project, target).update_all(state: :done)
|
||||
end
|
||||
|
||||
def pending_tasks(user, project, target, options = {})
|
||||
options.reverse_merge(
|
||||
project: project,
|
||||
target: target
|
||||
def pending_tasks(user, project, target)
|
||||
user.tasks.pending.where(
|
||||
project_id: project.id,
|
||||
target_id: target.id,
|
||||
target_type: target.class.name
|
||||
)
|
||||
|
||||
user.tasks.pending.where(options)
|
||||
end
|
||||
|
||||
def new_issuable(issuable, current_user)
|
||||
project = issuable.project
|
||||
target = issuable
|
||||
author = issuable.author
|
||||
|
||||
if target.is_assigned? && target.assignee != current_user
|
||||
create_task(project, target, author, target.assignee, Task::ASSIGNED)
|
||||
end
|
||||
|
||||
mentioned_users = build_mentioned_users(project, target, author)
|
||||
mentioned_users.delete(issuable.assignee)
|
||||
|
||||
mentioned_users.each do |mentioned_user|
|
||||
create_task(project, target, author, mentioned_user, Task::MENTIONED)
|
||||
end
|
||||
end
|
||||
|
||||
def update_issuable(issuable, current_user)
|
||||
project = issuable.project
|
||||
author = current_user
|
||||
|
||||
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 reassigned_issuable(issuable, current_user)
|
||||
if issuable.assignee && issuable.assignee != current_user
|
||||
create_task(issuable.project, issuable, current_user, issuable.assignee, Task::ASSIGNED)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -45,13 +45,6 @@ describe TaskService, services: true do
|
||||
end
|
||||
|
||||
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
|
||||
service.update_issue(issue, author)
|
||||
|
||||
@@ -101,6 +94,18 @@ describe TaskService, services: true do
|
||||
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
|
||||
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) }
|
||||
@@ -112,28 +117,28 @@ describe TaskService, services: true 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.new_note(note)
|
||||
service.new_note(note, john_doe)
|
||||
|
||||
expect(first_task.reload).to be_done
|
||||
expect(second_task.reload).to be_done
|
||||
end
|
||||
|
||||
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(second_task.reload).to be_done
|
||||
end
|
||||
|
||||
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(second_task.reload).to be_pending
|
||||
end
|
||||
|
||||
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: author, target: issue, author: john_doe, action: Task::MENTIONED, note: note)
|
||||
@@ -173,13 +178,6 @@ describe TaskService, services: true do
|
||||
end
|
||||
|
||||
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
|
||||
service.update_merge_request(mr_assigned, author)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user