Create a pending task when a user is mentioned when edit a issue/mr/note

parent 4120b794
...@@ -6,7 +6,7 @@ module Issues ...@@ -6,7 +6,7 @@ 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) task_service.update_issue(issue, current_user)
end end
if issue.previous_changes.include?('milestone_id') if issue.previous_changes.include?('milestone_id')
......
...@@ -16,7 +16,7 @@ module MergeRequests ...@@ -16,7 +16,7 @@ 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) task_service.update_merge_request(merge_request, current_user)
end end
if merge_request.previous_changes.include?('target_branch') if merge_request.previous_changes.include?('target_branch')
......
...@@ -8,12 +8,22 @@ ...@@ -8,12 +8,22 @@
class TaskService class TaskService
# When create an issue we should: # When create an issue we should:
# #
# * creates a pending task for assignee if issue is assigned # * create a task for assignee if issue is assigned
# * create a task for each mentioned user on issue
# #
def new_issue(issue, current_user) def new_issue(issue, current_user)
new_issuable(issue, current_user) new_issuable(issue, current_user)
end end
# 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)
end
# When close an issue we should: # When close an issue we should:
# #
# * mark all pending tasks related to the target for the current user as done # * mark all pending tasks related to the target for the current user as done
...@@ -24,7 +34,7 @@ class TaskService ...@@ -24,7 +34,7 @@ class TaskService
# When we reassign an issue we should: # When we reassign an issue we should:
# #
# * creates 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) reassigned_issuable(issue, current_user)
...@@ -33,11 +43,21 @@ class TaskService ...@@ -33,11 +43,21 @@ class TaskService
# When create a merge request we should: # When create a merge request we should:
# #
# * creates a pending task for assignee if merge request is assigned # * creates a pending task for assignee if merge request is assigned
# * create a task for each mentioned user on merge request
# #
def new_merge_request(merge_request, current_user) def new_merge_request(merge_request, current_user)
new_issuable(merge_request, current_user) new_issuable(merge_request, current_user)
end end
# 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
#
def update_merge_request(merge_request, current_user)
update_issuable(merge_request, current_user)
end
# When close a merge request we should: # When close a merge request we should:
# #
# * mark all pending tasks related to the target for the current user as done # * mark all pending tasks related to the target for the current user as done
...@@ -62,17 +82,10 @@ class TaskService ...@@ -62,17 +82,10 @@ class TaskService
mark_pending_tasks_as_done(merge_request, current_user) mark_pending_tasks_as_done(merge_request, current_user)
end end
# When we mark a task as done we should:
#
# * mark all pending tasks related to the target for the user as done
#
def mark_pending_tasks_as_done(target, user)
pending_tasks(user, target.project, target).update_all(state: :done)
end
# When create a note we should: # When create a note we should:
# #
# * 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
# #
def new_note(note) def new_note(note)
# Skip system notes, like status changes and cross-references # Skip system notes, like status changes and cross-references
...@@ -94,11 +107,24 @@ class TaskService ...@@ -94,11 +107,24 @@ class TaskService
# When update a note we should: # When update a note we should:
# #
# * mark all pending tasks related to the noteable for the current user as done # * mark all pending tasks related to the noteable for the current user as done
# * 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 # Skip system notes, like status changes and cross-references
unless note.system unless note.system
mark_pending_tasks_as_done(note.noteable, current_user) 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 end
end end
...@@ -128,8 +154,17 @@ class TaskService ...@@ -128,8 +154,17 @@ class TaskService
mentioned_users.uniq mentioned_users.uniq
end end
def pending_tasks(user, project, target) def mark_pending_tasks_as_done(target, user)
user.tasks.pending.where(project: project, target: target) 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
})
user.tasks.pending.where(options)
end end
def new_issuable(issuable, current_user) def new_issuable(issuable, current_user)
...@@ -148,8 +183,24 @@ class TaskService ...@@ -148,8 +183,24 @@ class TaskService
end end
end end
def update_issuable(issuable, current_user)
project = issuable.project
target = issuable
author = current_user
mark_pending_tasks_as_done(target, author)
mentioned_users = build_mentioned_users(project, target, author)
mentioned_users.each do |mentioned_user|
unless pending_tasks(mentioned_user, project, target, action: Task::MENTIONED).exists?
create_task(project, target, author, mentioned_user, Task::MENTIONED)
end
end
end
def reassigned_issuable(issuable, current_user) def reassigned_issuable(issuable, current_user)
if issuable.is_assigned? && issuable.assignee != current_user if issuable.assignee && issuable.assignee != current_user
create_task(issuable.project, issuable, current_user, issuable.assignee, Task::ASSIGNED) create_task(issuable.project, issuable, current_user, issuable.assignee, Task::ASSIGNED)
end end
end end
......
...@@ -20,14 +20,12 @@ FactoryGirl.define do ...@@ -20,14 +20,12 @@ FactoryGirl.define do
author author
user user
factory :pending_assigned_task, traits: [:assgined, :pending] trait :assigned do
trait :assgined do
action { Task::ASSIGNED } action { Task::ASSIGNED }
end end
trait :pending do trait :mentioned do
state { :pending } action { Task::MENTIONED }
end end
end end
end end
...@@ -5,9 +5,7 @@ describe Issues::CloseService, services: true do ...@@ -5,9 +5,7 @@ describe Issues::CloseService, services: true do
let(:user2) { create(:user) } let(:user2) { create(:user) }
let(:issue) { create(:issue, assignee: user2) } let(:issue) { create(:issue, assignee: user2) }
let(:project) { issue.project } let(:project) { issue.project }
let!(:pending_task) do let!(:pending_task) { create(:task, :assigned, user: user, project: project, target: issue, author: user2) }
create(:pending_assigned_task, user: user, project: project, target: issue, author: user2)
end
before do before do
project.team << [user, :master] project.team << [user, :master]
......
...@@ -81,9 +81,7 @@ describe Issues::UpdateService, services: true do ...@@ -81,9 +81,7 @@ describe Issues::UpdateService, services: true do
end end
context 'task queue' do context 'task queue' do
let!(:pending_task) do let!(:pending_task) { create(:task, :assigned, user: user, project: project, target: issue, author: user2) }
create(:pending_assigned_task, user: user, project: project, target: issue, author: user2)
end
context 'when the title change' do context 'when the title change' do
before do before do
......
...@@ -5,9 +5,7 @@ describe MergeRequests::CloseService, services: true do ...@@ -5,9 +5,7 @@ describe MergeRequests::CloseService, services: true do
let(:user2) { create(:user) } let(:user2) { create(:user) }
let(:merge_request) { create(:merge_request, assignee: user2) } let(:merge_request) { create(:merge_request, assignee: user2) }
let(:project) { merge_request.project } let(:project) { merge_request.project }
let!(:pending_task) do let!(:pending_task) { create(:task, :assigned, user: user, project: project, target: merge_request, author: user2) }
create(:pending_assigned_task, user: user, project: project, target: merge_request, author: user2)
end
before do before do
project.team << [user, :master] project.team << [user, :master]
......
...@@ -99,9 +99,7 @@ describe MergeRequests::UpdateService, services: true do ...@@ -99,9 +99,7 @@ describe MergeRequests::UpdateService, services: true do
end end
context 'task queue' do context 'task queue' do
let!(:pending_task) do let!(:pending_task) { create(:task, :assigned, user: user, project: project, target: merge_request, author: user2) }
create(:pending_assigned_task, user: user, project: project, target: merge_request, author: user2)
end
context 'when the title change' do context 'when the title change' do
before do before do
......
...@@ -19,7 +19,7 @@ describe Notes::UpdateService, services: true do ...@@ -19,7 +19,7 @@ describe Notes::UpdateService, services: true do
end end
context 'task queue' do context 'task queue' do
let!(:task) { create(:pending_assigned_task, user: user, project: project, target: issue, author: user2) } let!(:pending_task) { create(:task, :assigned, user: user, project: project, target: issue, author: user2) }
context 'when the note change' do context 'when the note change' do
before do before do
...@@ -27,7 +27,7 @@ describe Notes::UpdateService, services: true do ...@@ -27,7 +27,7 @@ describe Notes::UpdateService, services: true do
end end
it 'marks pending tasks as done' do it 'marks pending tasks as done' do
expect(task.reload).to be_done expect(pending_task.reload).to be_done
end end
end end
...@@ -37,7 +37,7 @@ describe Notes::UpdateService, services: true do ...@@ -37,7 +37,7 @@ describe Notes::UpdateService, services: true do
end end
it 'keep pending tasks' do it 'keep pending tasks' do
expect(task.reload).to be_pending expect(pending_task.reload).to be_pending
end end
end end
end end
......
...@@ -16,7 +16,7 @@ describe TaskService, services: true do ...@@ -16,7 +16,7 @@ describe TaskService, services: true do
end end
describe 'Issues' do describe 'Issues' do
let(:issue) { create(:issue, project: project, assignee: john_doe, author: author) } let(:issue) { create(:issue, project: project, assignee: john_doe, author: author, description: mentions) }
let(:unassigned_issue) { create(:issue, project: project, assignee: nil) } let(:unassigned_issue) { create(:issue, project: project, assignee: nil) }
describe '#new_issue' do describe '#new_issue' do
...@@ -35,8 +35,6 @@ describe TaskService, services: true do ...@@ -35,8 +35,6 @@ describe TaskService, services: true do
end end
it 'creates a task for each valid mentioned user' do it 'creates a task for each valid mentioned user' do
issue.update_attribute(:description, mentions)
service.new_issue(issue, author) service.new_issue(issue, author)
should_create_task(user: michael, target: issue, action: Task::MENTIONED) should_create_task(user: michael, target: issue, action: Task::MENTIONED)
...@@ -46,20 +44,39 @@ describe TaskService, services: true do ...@@ -46,20 +44,39 @@ describe TaskService, services: true do
end end
end end
describe '#close_issue' do describe '#update_issue' do
let!(:first_pending_task) do it 'marks pending tasks to the issue for the user as done' do
create(:pending_assigned_task, user: john_doe, project: project, target: issue, author: author) 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)
should_create_task(user: michael, target: issue, action: Task::MENTIONED)
should_not_create_task(user: author, target: issue, action: Task::MENTIONED)
should_not_create_task(user: john_doe, target: issue, action: Task::MENTIONED)
should_not_create_task(user: stranger, target: issue, action: Task::MENTIONED)
end end
let!(:second_pending_task) do it 'does not create a task if user was already mentioned' do
create(:pending_assigned_task, user: john_doe, project: project, target: issue, author: author) create(:task, :mentioned, user: michael, project: project, target: issue, author: author)
should_not_create_any_task { service.update_issue(issue, author) }
end end
end
describe '#close_issue' do
it 'marks related pending tasks to the target for the user 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.close_issue(issue, john_doe) service.close_issue(issue, john_doe)
expect(first_pending_task.reload).to be_done expect(first_task.reload).to be_done
expect(second_pending_task.reload).to be_done expect(second_task.reload).to be_done
end end
end end
...@@ -84,60 +101,38 @@ describe TaskService, services: true do ...@@ -84,60 +101,38 @@ describe TaskService, services: true do
end end
end end
describe '#mark_pending_tasks_as_done' do
let!(:first_pending_task) do
create(:pending_assigned_task, user: john_doe, project: project, target: issue, author: author)
end
let!(:second_pending_task) do
create(:pending_assigned_task, user: john_doe, project: project, target: issue, author: author)
end
it 'marks related pending tasks to the target for the user as done' do
service.mark_pending_tasks_as_done(issue, john_doe)
expect(first_pending_task.reload).to be_done
expect(second_pending_task.reload).to be_done
end
end
describe '#new_note' do describe '#new_note' do
let!(:first_pending_task) do let!(:first_task) { create(:task, :assigned, user: john_doe, project: project, target: issue, author: author) }
create(:pending_assigned_task, user: john_doe, project: project, target: issue, author: author) let!(:second_task) { create(:task, :assigned, user: john_doe, project: project, target: issue, author: author) }
end let(:note) { create(:note, project: project, noteable: issue, author: john_doe, note: mentions) }
let!(:second_pending_task) do
create(:pending_assigned_task, user: john_doe, project: project, target: issue, author: author)
end
let(:note) { create(:note, project: project, noteable: issue, author: john_doe) }
let(:award_note) { create(:note, :award, project: project, noteable: issue, author: john_doe, note: 'thumbsup') } let(:award_note) { create(:note, :award, project: project, noteable: issue, author: john_doe, note: 'thumbsup') }
let(:system_note) { create(:system_note, project: project, noteable: issue) } let(:system_note) { create(:system_note, project: project, noteable: issue) }
it 'mark related pending tasks to the noteable for the note author as done' do it 'mark related pending tasks to the noteable for the note author 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.new_note(note) service.new_note(note)
expect(first_pending_task.reload).to be_done expect(first_task.reload).to be_done
expect(second_pending_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)
expect(first_pending_task.reload).to be_done expect(first_task.reload).to be_done
expect(second_pending_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)
expect(first_pending_task.reload).to be_pending expect(first_task.reload).to be_pending
expect(second_pending_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
note.update_attribute(:note, mentions)
service.new_note(note) service.new_note(note)
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)
...@@ -149,7 +144,7 @@ describe TaskService, services: true do ...@@ -149,7 +144,7 @@ describe TaskService, services: true do
end end
describe 'Merge Requests' do describe 'Merge Requests' do
let(:mr_assigned) { create(:merge_request, source_project: project, author: author, assignee: john_doe) } let(:mr_assigned) { create(:merge_request, source_project: project, author: author, assignee: john_doe, description: mentions) }
let(:mr_unassigned) { create(:merge_request, source_project: project, author: author, assignee: nil) } let(:mr_unassigned) { create(:merge_request, source_project: project, author: author, assignee: nil) }
describe '#new_merge_request' do describe '#new_merge_request' do
...@@ -168,8 +163,6 @@ describe TaskService, services: true do ...@@ -168,8 +163,6 @@ describe TaskService, services: true do
end end
it 'creates a task for each valid mentioned user' do it 'creates a task for each valid mentioned user' do
mr_assigned.update_attribute(:description, mentions)
service.new_merge_request(mr_assigned, author) service.new_merge_request(mr_assigned, author)
should_create_task(user: michael, target: mr_assigned, action: Task::MENTIONED) should_create_task(user: michael, target: mr_assigned, action: Task::MENTIONED)
...@@ -179,20 +172,38 @@ describe TaskService, services: true do ...@@ -179,20 +172,38 @@ describe TaskService, services: true do
end end
end end
describe '#close_merge_request' do describe '#update_merge_request' do
let!(:first_pending_task) do it 'marks pending tasks to the merge request for the user as done' do
create(:pending_assigned_task, user: john_doe, project: project, target: mr_assigned, author: author) 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)
should_create_task(user: michael, target: mr_assigned, action: Task::MENTIONED)
should_not_create_task(user: author, target: mr_assigned, action: Task::MENTIONED)
should_not_create_task(user: john_doe, target: mr_assigned, action: Task::MENTIONED)
should_not_create_task(user: stranger, target: mr_assigned, action: Task::MENTIONED)
end end
let!(:second_pending_task) do it 'does not create a task if user was already mentioned' do
create(:pending_assigned_task, user: john_doe, project: project, target: mr_assigned, author: author) create(:task, :mentioned, user: michael, project: project, target: mr_assigned, author: author)
should_not_create_any_task { service.update_merge_request(mr_assigned, author) }
end end
end
describe '#close_merge_request' do
it 'marks related pending tasks to the target for the user 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: mr_assigned, author: author)
second_task = create(:task, :assigned, user: john_doe, project: project, target: mr_assigned, author: author)
service.close_merge_request(mr_assigned, john_doe) service.close_merge_request(mr_assigned, john_doe)
expect(first_pending_task.reload).to be_done expect(first_task.reload).to be_done
expect(second_pending_task.reload).to be_done expect(second_task.reload).to be_done
end end
end end
...@@ -218,19 +229,13 @@ describe TaskService, services: true do ...@@ -218,19 +229,13 @@ describe TaskService, services: true do
end end
describe '#merge_merge_request' do describe '#merge_merge_request' do
let!(:first_pending_task) do
create(:pending_assigned_task, user: john_doe, project: project, target: mr_assigned, author: author)
end
let!(:second_pending_task) do
create(:pending_assigned_task, user: john_doe, project: project, target: mr_assigned, author: author)
end
it 'marks related pending tasks to the target for the user 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: mr_assigned, author: author)
second_task = create(:task, :assigned, user: john_doe, project: project, target: mr_assigned, author: author)
service.merge_merge_request(mr_assigned, john_doe) service.merge_merge_request(mr_assigned, john_doe)
expect(first_pending_task.reload).to be_done expect(first_task.reload).to be_done
expect(second_pending_task.reload).to be_done expect(second_task.reload).to be_done
end end
end end
end end
......
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