Rename Tasks to Todos
This commit is contained in:
parent
408e010d65
commit
3d52e139b1
45 changed files with 604 additions and 602 deletions
|
@ -65,7 +65,7 @@ v 8.5.0 (unreleased)
|
|||
- Fix broken link to project in build notification emails
|
||||
- Ability to see and sort on vote count from Issues and MR lists
|
||||
- Fix builds scheduler when first build in stage was allowed to fail
|
||||
- User project limit is reached notice is hidden if the projects limit is zero
|
||||
- User project limit is reached notice is hidden if the projects limit is zero
|
||||
- Add API support for managing runners and project's runners
|
||||
- Allow SAML users to login with no previous account without having to allow
|
||||
all Omniauth providers to do so.
|
||||
|
@ -75,7 +75,7 @@ v 8.5.0 (unreleased)
|
|||
- Emoji comment on diffs are not award emoji
|
||||
- Add label description (Nuttanart Pornprasitsakul)
|
||||
- Show label row when filtering issues or merge requests by label (Nuttanart Pornprasitsakul)
|
||||
- Add Task Queue
|
||||
- Add Todos
|
||||
|
||||
v 8.4.4
|
||||
- Update omniauth-saml gem to 1.4.2
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
/**
|
||||
* Dashboard tasks queue
|
||||
* Dashboard Todos
|
||||
*
|
||||
*/
|
||||
|
||||
.navbar-nav {
|
||||
li {
|
||||
.badge.tasks-pending-count {
|
||||
.badge.todos-pending-count {
|
||||
background-color: #7f8fa4;
|
||||
margin-top: -5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tasks {
|
||||
.todos {
|
||||
.panel {
|
||||
border-top: none;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.task-item {
|
||||
.todo-item {
|
||||
font-size: $gl-font-size;
|
||||
padding: $gl-padding-top 0 $gl-padding-top ($gl-avatar-size + $gl-padding-top);
|
||||
border-bottom: 1px solid $table-border-color;
|
||||
color: #7f8fa4;
|
||||
|
||||
&.task-inline {
|
||||
&.todo-inline {
|
||||
.avatar {
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.task-title {
|
||||
.todo-title {
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@
|
|||
margin-left: -($gl-avatar-size + $gl-padding-top);
|
||||
}
|
||||
|
||||
.task-title {
|
||||
.todo-title {
|
||||
@include str-truncated(calc(100% - 174px));
|
||||
font-weight: 600;
|
||||
|
||||
|
@ -53,10 +53,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.task-body {
|
||||
.todo-body {
|
||||
margin-right: 174px;
|
||||
|
||||
.task-note {
|
||||
.todo-note {
|
||||
word-wrap: break-word;
|
||||
|
||||
.md {
|
||||
|
@ -89,7 +89,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.task-note-icon {
|
||||
.todo-note-icon {
|
||||
color: #777;
|
||||
float: left;
|
||||
font-size: $gl-font-size;
|
||||
|
@ -102,10 +102,10 @@
|
|||
}
|
||||
|
||||
@media (max-width: $screen-xs-max) {
|
||||
.task-item {
|
||||
.todo-item {
|
||||
padding-left: $gl-padding;
|
||||
|
||||
.task-title {
|
||||
.todo-title {
|
||||
white-space: normal;
|
||||
overflow: visible;
|
||||
max-width: 100%;
|
||||
|
@ -115,7 +115,7 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
.task-body {
|
||||
.todo-body {
|
||||
margin: 0;
|
||||
border-left: 2px solid #DDD;
|
||||
padding-left: 10px;
|
|
@ -1,21 +0,0 @@
|
|||
class Dashboard::TasksController < Dashboard::ApplicationController
|
||||
def index
|
||||
@tasks = TasksFinder.new(current_user, params).execute
|
||||
@tasks = @tasks.page(params[:page]).per(PER_PAGE)
|
||||
end
|
||||
|
||||
def destroy
|
||||
task.done!
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to dashboard_tasks_path, notice: 'Task was successfully marked as done.' }
|
||||
format.js { render nothing: true }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def task
|
||||
@task ||= current_user.tasks.find(params[:id])
|
||||
end
|
||||
end
|
23
app/controllers/dashboard/todos_controller.rb
Normal file
23
app/controllers/dashboard/todos_controller.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
class Dashboard::TodosController < Dashboard::ApplicationController
|
||||
def index
|
||||
@todos = TodosFinder.new(current_user, params).execute
|
||||
@todos = @todos.page(params[:page]).per(PER_PAGE)
|
||||
end
|
||||
|
||||
def destroy
|
||||
todo.done!
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to dashboard_todos_path, notice: 'Todo was successfully marked as done.' }
|
||||
format.js { render nothing: true }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def todo
|
||||
@todo ||= current_user.todos.find(params[:id])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -181,7 +181,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
|||
return
|
||||
end
|
||||
|
||||
TaskService.new.merge_merge_request(merge_request, current_user)
|
||||
TodoService.new.merge_merge_request(merge_request, current_user)
|
||||
|
||||
@merge_request.update(merge_error: nil)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# TasksFinder
|
||||
# TodosFinder
|
||||
#
|
||||
# Used to filter Tasks by set of params
|
||||
# Used to filter Todos by set of params
|
||||
#
|
||||
# Arguments:
|
||||
# current_user - which user use
|
||||
|
@ -12,7 +12,7 @@
|
|||
# type: 'Issue' or 'MergeRequest'
|
||||
#
|
||||
|
||||
class TasksFinder
|
||||
class TodosFinder
|
||||
NONE = '0'
|
||||
|
||||
attr_accessor :current_user, :params
|
||||
|
@ -23,7 +23,7 @@ class TasksFinder
|
|||
end
|
||||
|
||||
def execute
|
||||
items = current_user.tasks
|
||||
items = current_user.todos
|
||||
items = by_action_id(items)
|
||||
items = by_author(items)
|
||||
items = by_project(items)
|
||||
|
@ -36,7 +36,7 @@ class TasksFinder
|
|||
private
|
||||
|
||||
def action_id?
|
||||
action_id.present? && [Task::ASSIGNED, Task::MENTIONED].include?(action_id.to_i)
|
||||
action_id.present? && [Todo::ASSIGNED, Todo::MENTIONED].include?(action_id.to_i)
|
||||
end
|
||||
|
||||
def action_id
|
|
@ -1,69 +0,0 @@
|
|||
module TasksHelper
|
||||
def link_to_author(task)
|
||||
author = task.author
|
||||
|
||||
if author
|
||||
link_to author.name, user_path(author.username)
|
||||
else
|
||||
task.author_name
|
||||
end
|
||||
end
|
||||
|
||||
def tasks_pending_count
|
||||
current_user.tasks.pending.count
|
||||
end
|
||||
|
||||
def tasks_done_count
|
||||
current_user.tasks.done.count
|
||||
end
|
||||
|
||||
def task_action_name(task)
|
||||
target = task.target_type.titleize.downcase
|
||||
|
||||
[task.action_name, target].join(" ")
|
||||
end
|
||||
|
||||
def task_target_link_html(task)
|
||||
link_to "##{task.target_iid}", task_target_path(task)
|
||||
end
|
||||
|
||||
def task_target_path(task)
|
||||
anchor = dom_id(task.note) if task.note.present?
|
||||
|
||||
polymorphic_path([task.project.namespace.becomes(Namespace),
|
||||
task.project, task.target], anchor: anchor)
|
||||
end
|
||||
|
||||
def task_actions_options
|
||||
actions = [
|
||||
OpenStruct.new(id: '', title: 'Any Action'),
|
||||
OpenStruct.new(id: Task::ASSIGNED, title: 'Assigned'),
|
||||
OpenStruct.new(id: Task::MENTIONED, title: 'Mentioned')
|
||||
]
|
||||
|
||||
options_from_collection_for_select(actions, 'id', 'title', params[:action_id])
|
||||
end
|
||||
|
||||
def task_projects_options
|
||||
projects = current_user.authorized_projects.sorted_by_activity.non_archived
|
||||
projects = projects.includes(:namespace)
|
||||
|
||||
projects = projects.map do |project|
|
||||
OpenStruct.new(id: project.id, title: project.name_with_namespace)
|
||||
end
|
||||
|
||||
projects.unshift(OpenStruct.new(id: '', title: 'Any Project'))
|
||||
|
||||
options_from_collection_for_select(projects, 'id', 'title', params[:project_id])
|
||||
end
|
||||
|
||||
def task_types_options
|
||||
types = [
|
||||
OpenStruct.new(title: 'Any Type', name: ''),
|
||||
OpenStruct.new(title: 'Issue', name: 'Issue'),
|
||||
OpenStruct.new(title: 'Merge Request', name: 'MergeRequest')
|
||||
]
|
||||
|
||||
options_from_collection_for_select(types, 'name', 'title', params[:type])
|
||||
end
|
||||
end
|
59
app/helpers/todos_helper.rb
Normal file
59
app/helpers/todos_helper.rb
Normal file
|
@ -0,0 +1,59 @@
|
|||
module TodosHelper
|
||||
def todos_pending_count
|
||||
current_user.todos.pending.count
|
||||
end
|
||||
|
||||
def todos_done_count
|
||||
current_user.todos.done.count
|
||||
end
|
||||
|
||||
def todo_action_name(todo)
|
||||
target = todo.target_type.titleize.downcase
|
||||
|
||||
[todo.action_name, target].join(" ")
|
||||
end
|
||||
|
||||
def todo_target_link_html(todo)
|
||||
link_to "##{todo.target_iid}", todo_target_path(todo)
|
||||
end
|
||||
|
||||
def todo_target_path(todo)
|
||||
anchor = dom_id(todo.note) if todo.note.present?
|
||||
|
||||
polymorphic_path([todo.project.namespace.becomes(Namespace),
|
||||
todo.project, todo.target], anchor: anchor)
|
||||
end
|
||||
|
||||
def todo_actions_options
|
||||
actions = [
|
||||
OpenStruct.new(id: '', title: 'Any Action'),
|
||||
OpenStruct.new(id: Todo::ASSIGNED, title: 'Assigned'),
|
||||
OpenStruct.new(id: Todo::MENTIONED, title: 'Mentioned')
|
||||
]
|
||||
|
||||
options_from_collection_for_select(actions, 'id', 'title', params[:action_id])
|
||||
end
|
||||
|
||||
def todo_projects_options
|
||||
projects = current_user.authorized_projects.sorted_by_activity.non_archived
|
||||
projects = projects.includes(:namespace)
|
||||
|
||||
projects = projects.map do |project|
|
||||
OpenStruct.new(id: project.id, title: project.name_with_namespace)
|
||||
end
|
||||
|
||||
projects.unshift(OpenStruct.new(id: '', title: 'Any Project'))
|
||||
|
||||
options_from_collection_for_select(projects, 'id', 'title', params[:project_id])
|
||||
end
|
||||
|
||||
def todo_types_options
|
||||
types = [
|
||||
OpenStruct.new(title: 'Any Type', name: ''),
|
||||
OpenStruct.new(title: 'Issue', name: 'Issue'),
|
||||
OpenStruct.new(title: 'Merge Request', name: 'MergeRequest')
|
||||
]
|
||||
|
||||
options_from_collection_for_select(types, 'name', 'title', params[:type])
|
||||
end
|
||||
end
|
|
@ -37,7 +37,7 @@ class Note < ActiveRecord::Base
|
|||
belongs_to :author, class_name: "User"
|
||||
belongs_to :updated_by, class_name: "User"
|
||||
|
||||
has_many :tasks, dependent: :destroy
|
||||
has_many :todos, dependent: :destroy
|
||||
|
||||
delegate :name, to: :project, prefix: true
|
||||
delegate :name, :email, to: :author, prefix: true
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: tasks
|
||||
# Table name: todos
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer not null
|
||||
|
@ -15,7 +15,7 @@
|
|||
# updated_at :datetime
|
||||
#
|
||||
|
||||
class Task < ActiveRecord::Base
|
||||
class Todo < ActiveRecord::Base
|
||||
ASSIGNED = 1
|
||||
MENTIONED = 2
|
||||
|
|
@ -140,7 +140,7 @@ class User < ActiveRecord::Base
|
|||
has_one :abuse_report, dependent: :destroy
|
||||
has_many :spam_logs, dependent: :destroy
|
||||
has_many :builds, dependent: :nullify, class_name: 'Ci::Build'
|
||||
has_many :tasks, dependent: :destroy
|
||||
has_many :todos, dependent: :destroy
|
||||
|
||||
#
|
||||
# Validations
|
||||
|
|
|
@ -23,8 +23,8 @@ class BaseService
|
|||
EventCreateService.new
|
||||
end
|
||||
|
||||
def task_service
|
||||
TaskService.new
|
||||
def todo_service
|
||||
TodoService.new
|
||||
end
|
||||
|
||||
def log_info(message)
|
||||
|
|
|
@ -3,7 +3,7 @@ module Issues
|
|||
def execute(issue, commit = nil)
|
||||
if project.jira_tracker? && project.jira_service.active
|
||||
project.jira_service.execute(commit, issue)
|
||||
task_service.close_issue(issue, current_user)
|
||||
todo_service.close_issue(issue, current_user)
|
||||
return issue
|
||||
end
|
||||
|
||||
|
@ -11,7 +11,7 @@ module Issues
|
|||
event_service.close_issue(issue, current_user)
|
||||
create_note(issue, commit)
|
||||
notification_service.close_issue(issue, current_user)
|
||||
task_service.close_issue(issue, current_user)
|
||||
todo_service.close_issue(issue, current_user)
|
||||
execute_hooks(issue, 'close')
|
||||
end
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ module Issues
|
|||
if issue.save
|
||||
issue.update_attributes(label_ids: label_params)
|
||||
notification_service.new_issue(issue, current_user)
|
||||
task_service.new_issue(issue, current_user)
|
||||
todo_service.new_issue(issue, current_user)
|
||||
event_service.open_issue(issue, current_user)
|
||||
issue.create_cross_references!(current_user)
|
||||
execute_hooks(issue, 'open')
|
||||
|
|
|
@ -6,12 +6,12 @@ module Issues
|
|||
|
||||
def handle_changes(issue, options = {})
|
||||
if has_changes?(issue, options)
|
||||
task_service.mark_pending_tasks_as_done(issue, current_user)
|
||||
todo_service.mark_pending_todos_as_done(issue, current_user)
|
||||
end
|
||||
|
||||
if issue.previous_changes.include?('title') ||
|
||||
issue.previous_changes.include?('description')
|
||||
task_service.update_issue(issue, current_user)
|
||||
todo_service.update_issue(issue, current_user)
|
||||
end
|
||||
|
||||
if issue.previous_changes.include?('milestone_id')
|
||||
|
@ -21,7 +21,7 @@ module Issues
|
|||
if issue.previous_changes.include?('assignee_id')
|
||||
create_assignee_note(issue)
|
||||
notification_service.reassigned_issue(issue, current_user)
|
||||
task_service.reassigned_issue(issue, current_user)
|
||||
todo_service.reassigned_issue(issue, current_user)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ module MergeRequests
|
|||
event_service.close_mr(merge_request, current_user)
|
||||
create_note(merge_request)
|
||||
notification_service.close_mr(merge_request, current_user)
|
||||
task_service.close_merge_request(merge_request, current_user)
|
||||
todo_service.close_merge_request(merge_request, current_user)
|
||||
execute_hooks(merge_request, 'close')
|
||||
end
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ module MergeRequests
|
|||
merge_request.update_attributes(label_ids: label_params)
|
||||
event_service.open_mr(merge_request, current_user)
|
||||
notification_service.new_merge_request(merge_request, current_user)
|
||||
task_service.new_merge_request(merge_request, current_user)
|
||||
todo_service.new_merge_request(merge_request, current_user)
|
||||
merge_request.create_cross_references!(current_user)
|
||||
execute_hooks(merge_request)
|
||||
end
|
||||
|
|
|
@ -16,12 +16,12 @@ module MergeRequests
|
|||
|
||||
def handle_changes(merge_request, options = {})
|
||||
if has_changes?(merge_request, options)
|
||||
task_service.mark_pending_tasks_as_done(merge_request, current_user)
|
||||
todo_service.mark_pending_todos_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)
|
||||
todo_service.update_merge_request(merge_request, current_user)
|
||||
end
|
||||
|
||||
if merge_request.previous_changes.include?('target_branch')
|
||||
|
@ -37,7 +37,7 @@ module MergeRequests
|
|||
if merge_request.previous_changes.include?('assignee_id')
|
||||
create_assignee_note(merge_request)
|
||||
notification_service.reassigned_merge_request(merge_request, current_user)
|
||||
task_service.reassigned_merge_request(merge_request, current_user)
|
||||
todo_service.reassigned_merge_request(merge_request, current_user)
|
||||
end
|
||||
|
||||
if merge_request.previous_changes.include?('target_branch') ||
|
||||
|
|
|
@ -8,7 +8,7 @@ module Notes
|
|||
if note.save
|
||||
# Finish the harder work in the background
|
||||
NewNoteWorker.perform_in(2.seconds, note.id, params)
|
||||
TaskService.new.new_note(note, current_user)
|
||||
TodoService.new.new_note(note, current_user)
|
||||
end
|
||||
|
||||
note
|
||||
|
|
|
@ -8,7 +8,7 @@ module Notes
|
|||
note.reset_events_cache
|
||||
|
||||
if note.previous_changes.include?('note')
|
||||
TaskService.new.update_note(note, current_user)
|
||||
TodoService.new.update_note(note, current_user)
|
||||
end
|
||||
|
||||
note
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
# TaskService class
|
||||
# TodoService class
|
||||
#
|
||||
# Used for creating tasks on task queue after certain user action
|
||||
# Used for creating todos after certain user actions
|
||||
#
|
||||
# Ex.
|
||||
# TaskService.new.new_issue(issue, current_user)
|
||||
# TodoService.new.new_issue(issue, current_user)
|
||||
#
|
||||
class TaskService
|
||||
class TodoService
|
||||
# When create an issue we should:
|
||||
#
|
||||
# * create a task for assignee if issue is assigned
|
||||
# * create a task for each mentioned user on issue
|
||||
# * create a todo for assignee if issue is assigned
|
||||
# * create a todo for each mentioned user on issue
|
||||
#
|
||||
def new_issue(issue, current_user)
|
||||
new_issuable(issue, current_user)
|
||||
|
@ -17,32 +17,32 @@ class TaskService
|
|||
|
||||
# When update an issue we should:
|
||||
#
|
||||
# * mark all pending tasks related to the issue for the current user as done
|
||||
# * mark all pending todos related to the issue for the current user as done
|
||||
#
|
||||
def update_issue(issue, current_user)
|
||||
create_mention_tasks(issue.project, issue, current_user)
|
||||
create_mention_todos(issue.project, issue, current_user)
|
||||
end
|
||||
|
||||
# When close an issue we should:
|
||||
#
|
||||
# * mark all pending tasks related to the target for the current user as done
|
||||
# * mark all pending todos related to the target for the current user as done
|
||||
#
|
||||
def close_issue(issue, current_user)
|
||||
mark_pending_tasks_as_done(issue, current_user)
|
||||
mark_pending_todos_as_done(issue, current_user)
|
||||
end
|
||||
|
||||
# When we reassign an issue we should:
|
||||
#
|
||||
# * create a pending task for new assignee if issue is assigned
|
||||
# * create a pending todo for new assignee if issue is assigned
|
||||
#
|
||||
def reassigned_issue(issue, current_user)
|
||||
create_assignment_task(issue, current_user)
|
||||
create_assignment_todo(issue, current_user)
|
||||
end
|
||||
|
||||
# When create a merge request we should:
|
||||
#
|
||||
# * creates a pending task for assignee if merge request is assigned
|
||||
# * create a task for each mentioned user on merge request
|
||||
# * creates a pending todo for assignee if merge request is assigned
|
||||
# * create a todo for each mentioned user on merge request
|
||||
#
|
||||
def new_merge_request(merge_request, current_user)
|
||||
new_issuable(merge_request, current_user)
|
||||
|
@ -50,40 +50,40 @@ class TaskService
|
|||
|
||||
# When update a merge request we should:
|
||||
#
|
||||
# * create a task for each mentioned user on merge request
|
||||
# * create a todo for each mentioned user on merge request
|
||||
#
|
||||
def update_merge_request(merge_request, current_user)
|
||||
create_mention_tasks(merge_request.project, merge_request, current_user)
|
||||
create_mention_todos(merge_request.project, merge_request, current_user)
|
||||
end
|
||||
|
||||
# When close a merge request we should:
|
||||
#
|
||||
# * mark all pending tasks related to the target for the current user as done
|
||||
# * mark all pending todos related to the target for the current user as done
|
||||
#
|
||||
def close_merge_request(merge_request, current_user)
|
||||
mark_pending_tasks_as_done(merge_request, current_user)
|
||||
mark_pending_todos_as_done(merge_request, current_user)
|
||||
end
|
||||
|
||||
# When we reassign a merge request we should:
|
||||
#
|
||||
# * creates a pending task for new assignee if merge request is assigned
|
||||
# * creates a pending todo for new assignee if merge request is assigned
|
||||
#
|
||||
def reassigned_merge_request(merge_request, current_user)
|
||||
create_assignment_task(merge_request, current_user)
|
||||
create_assignment_todo(merge_request, current_user)
|
||||
end
|
||||
|
||||
# When merge a merge request we should:
|
||||
#
|
||||
# * mark all pending tasks related to the target for the current user as done
|
||||
# * mark all pending todos related to the target for the current user as done
|
||||
#
|
||||
def merge_merge_request(merge_request, current_user)
|
||||
mark_pending_tasks_as_done(merge_request, current_user)
|
||||
mark_pending_todos_as_done(merge_request, current_user)
|
||||
end
|
||||
|
||||
# When create a note we should:
|
||||
#
|
||||
# * mark all pending tasks related to the noteable for the note author as done
|
||||
# * create a task for each mentioned user on note
|
||||
# * mark all pending todos related to the noteable for the note author as done
|
||||
# * create a todo for each mentioned user on note
|
||||
#
|
||||
def new_note(note, current_user)
|
||||
handle_note(note, current_user)
|
||||
|
@ -91,28 +91,28 @@ class TaskService
|
|||
|
||||
# When update a note we should:
|
||||
#
|
||||
# * mark all pending tasks related to the noteable for the current user as done
|
||||
# * create a task for each new user mentioned on note
|
||||
# * mark all pending todos related to the noteable for the current user as done
|
||||
# * create a todo 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:
|
||||
# When marking pending todos as done we should:
|
||||
#
|
||||
# * mark all pending tasks related to the target for the current user as done
|
||||
# * mark all pending todos 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)
|
||||
def mark_pending_todos_as_done(target, user)
|
||||
pending_todos(user, target.project, target).update_all(state: :done)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_tasks(project, target, author, users, action, note = nil)
|
||||
def create_todos(project, target, author, users, action, note = nil)
|
||||
Array(users).each do |user|
|
||||
next if pending_tasks(user, project, target).exists?
|
||||
next if pending_todos(user, project, target).exists?
|
||||
|
||||
Task.create(
|
||||
Todo.create(
|
||||
project: project,
|
||||
user_id: user.id,
|
||||
author_id: author.id,
|
||||
|
@ -125,8 +125,8 @@ class TaskService
|
|||
end
|
||||
|
||||
def new_issuable(issuable, author)
|
||||
create_assignment_task(issuable, author)
|
||||
create_mention_tasks(issuable.project, issuable, author)
|
||||
create_assignment_todo(issuable, author)
|
||||
create_mention_todos(issuable.project, issuable, author)
|
||||
end
|
||||
|
||||
def handle_note(note, author)
|
||||
|
@ -136,19 +136,19 @@ class TaskService
|
|||
project = note.project
|
||||
target = note.noteable
|
||||
|
||||
mark_pending_tasks_as_done(target, author)
|
||||
create_mention_tasks(project, target, author, note)
|
||||
mark_pending_todos_as_done(target, author)
|
||||
create_mention_todos(project, target, author, note)
|
||||
end
|
||||
|
||||
def create_assignment_task(issuable, author)
|
||||
def create_assignment_todo(issuable, author)
|
||||
if issuable.assignee && issuable.assignee != author
|
||||
create_tasks(issuable.project, issuable, author, issuable.assignee, Task::ASSIGNED)
|
||||
create_todos(issuable.project, issuable, author, issuable.assignee, Todo::ASSIGNED)
|
||||
end
|
||||
end
|
||||
|
||||
def create_mention_tasks(project, issuable, author, note = nil)
|
||||
def create_mention_todos(project, issuable, author, note = nil)
|
||||
mentioned_users = filter_mentioned_users(project, note || issuable, author)
|
||||
create_tasks(project, issuable, author, mentioned_users, Task::MENTIONED, note)
|
||||
create_todos(project, issuable, author, mentioned_users, Todo::MENTIONED, note)
|
||||
end
|
||||
|
||||
def filter_mentioned_users(project, target, author)
|
||||
|
@ -160,8 +160,8 @@ class TaskService
|
|||
mentioned_users.uniq
|
||||
end
|
||||
|
||||
def pending_tasks(user, project, target)
|
||||
user.tasks.pending.where(
|
||||
def pending_todos(user, project, target)
|
||||
user.todos.pending.where(
|
||||
project_id: project.id,
|
||||
target_id: target.id,
|
||||
target_type: target.class.name
|
|
@ -1,21 +0,0 @@
|
|||
%li{class: "task task-#{task.done? ? 'done' : 'pending'}", id: dom_id(task) }
|
||||
.task-item{class: 'task-block'}
|
||||
= image_tag avatar_icon(task.author_email, 40), class: 'avatar s40', alt:''
|
||||
|
||||
.task-title
|
||||
%span.author_name
|
||||
= link_to_author task
|
||||
%span.task_label
|
||||
= task_action_name(task)
|
||||
= task_target_link_html(task)
|
||||
|
||||
· #{time_ago_with_tooltip(task.created_at)}
|
||||
|
||||
- if task.pending?
|
||||
.task-actions.pull-right
|
||||
= link_to 'Done', [:dashboard, task], method: :delete, class: 'btn'
|
||||
|
||||
.task-body
|
||||
.task-note
|
||||
.md
|
||||
= event_note(task.body, project: task.project)
|
21
app/views/dashboard/todos/_todo.html.haml
Normal file
21
app/views/dashboard/todos/_todo.html.haml
Normal file
|
@ -0,0 +1,21 @@
|
|||
%li{class: "todo todo-#{todo.done? ? 'done' : 'pending'}", id: dom_id(todo) }
|
||||
.todo-item{class: 'todo-block'}
|
||||
= image_tag avatar_icon(todo.author_email, 40), class: 'avatar s40', alt:''
|
||||
|
||||
.todo-title
|
||||
%span.author_name
|
||||
= link_to_author todo
|
||||
%span.todo_label
|
||||
= todo_action_name(todo)
|
||||
= todo_target_link_html(todo)
|
||||
|
||||
· #{time_ago_with_tooltip(todo.created_at)}
|
||||
|
||||
- if todo.pending?
|
||||
.todo-actions.pull-right
|
||||
= link_to 'Done', [:dashboard, todo], method: :delete, class: 'btn'
|
||||
|
||||
.todo-body
|
||||
.todo-note
|
||||
.md
|
||||
= event_note(todo.body, project: todo.project)
|
|
@ -1,53 +1,53 @@
|
|||
- page_title "Tasks"
|
||||
- header_title "Tasks", dashboard_tasks_path
|
||||
- page_title "Todos"
|
||||
- header_title "Todos", dashboard_todos_path
|
||||
|
||||
.top-area
|
||||
%ul.nav-links
|
||||
%li{class: ('active' if params[:state].blank? || params[:state] == 'pending')}
|
||||
= link_to page_filter_path(state: 'pending') do
|
||||
%span
|
||||
Tasks
|
||||
Todos
|
||||
%span{class: 'badge'}
|
||||
= tasks_pending_count
|
||||
= todos_pending_count
|
||||
%li{class: ('active' if params[:state] == 'done')}
|
||||
= link_to page_filter_path(state: 'done') do
|
||||
%span
|
||||
Done
|
||||
%span{class: 'badge'}
|
||||
= tasks_done_count
|
||||
= todos_done_count
|
||||
|
||||
.tasks-filters
|
||||
.todos-filters
|
||||
.gray-content-block.second-block
|
||||
= form_tag page_filter_path(without: [:assignee_id, :milestone_title, :label_name, :scope, :sort]), method: :get, class: 'filter-form' do
|
||||
.filter-item.inline
|
||||
= select_tag('project_id', task_projects_options,
|
||||
= select_tag('project_id', todo_projects_options,
|
||||
class: 'select2 trigger-submit', include_blank: true,
|
||||
data: {placeholder: 'Project'})
|
||||
.filter-item.inline
|
||||
= users_select_tag(:author_id, selected: params[:author_id],
|
||||
placeholder: 'Author', class: 'trigger-submit', any_user: "Any Author", first_user: true, current_user: true)
|
||||
.filter-item.inline
|
||||
= select_tag('type', task_types_options,
|
||||
= select_tag('type', todo_types_options,
|
||||
class: 'select2 trigger-submit', include_blank: true,
|
||||
data: {placeholder: 'Type'})
|
||||
.filter-item.inline.actions-filter
|
||||
= select_tag('action_id', task_actions_options,
|
||||
= select_tag('action_id', todo_actions_options,
|
||||
class: 'select2 trigger-submit', include_blank: true,
|
||||
data: {placeholder: 'Action'})
|
||||
|
||||
.prepend-top-default
|
||||
- if @tasks.any?
|
||||
- @tasks.group_by(&:project).each do |group|
|
||||
- if @todos.any?
|
||||
- @todos.group_by(&:project).each do |group|
|
||||
.panel.panel-default.panel-small
|
||||
- project = group[0]
|
||||
.panel-heading
|
||||
= link_to project.name_with_namespace, namespace_project_path(project.namespace, project)
|
||||
|
||||
%ul.well-list.tasks-list
|
||||
%ul.well-list.todos-list
|
||||
= render group[1]
|
||||
= paginate @tasks, theme: "gitlab"
|
||||
= paginate @todos, theme: "gitlab"
|
||||
- else
|
||||
.nothing-here-block No tasks to show
|
||||
.nothing-here-block No todos to show
|
||||
|
||||
:javascript
|
||||
new UsersSelect();
|
|
@ -22,9 +22,9 @@
|
|||
= link_to admin_root_path, title: 'Admin Area', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
|
||||
= icon('wrench fw')
|
||||
%li
|
||||
= link_to dashboard_tasks_path, title: 'Tasks', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
|
||||
%span.badge.tasks-pending-count
|
||||
= tasks_pending_count
|
||||
= link_to dashboard_todos_path, title: 'Todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
|
||||
%span.badge.todos-pending-count
|
||||
= todos_pending_count
|
||||
- if current_user.can_create_project?
|
||||
%li
|
||||
= link_to new_project_path, title: 'New project', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
= icon('home fw')
|
||||
%span
|
||||
Projects
|
||||
= nav_link(controller: :tasks) do
|
||||
= link_to dashboard_tasks_path, title: 'Tasks' do
|
||||
= nav_link(controller: :todos) do
|
||||
= link_to dashboard_todos_path, title: 'Todos' do
|
||||
= icon('bell fw')
|
||||
%span
|
||||
Tasks
|
||||
%span.count= number_with_delimiter(tasks_pending_count)
|
||||
Todos
|
||||
%span.count= number_with_delimiter(todos_pending_count)
|
||||
= nav_link(path: 'dashboard#activity') do
|
||||
= link_to activity_dashboard_path, class: 'shortcuts-activity', title: 'Activity' do
|
||||
= icon('dashboard fw')
|
||||
|
|
|
@ -333,7 +333,7 @@ Rails.application.routes.draw do
|
|||
|
||||
resources :groups, only: [:index]
|
||||
resources :snippets, only: [:index]
|
||||
resources :tasks, only: [:index, :destroy]
|
||||
resources :todos, only: [:index, :destroy]
|
||||
|
||||
resources :projects, only: [:index] do
|
||||
collection do
|
||||
|
|
5
db/migrate/20160220123949_rename_tasks_to_todos.rb
Normal file
5
db/migrate/20160220123949_rename_tasks_to_todos.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class RenameTasksToTodos < ActiveRecord::Migration
|
||||
def change
|
||||
rename_table :tasks, :todos
|
||||
end
|
||||
end
|
16
db/schema.rb
16
db/schema.rb
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20160217174422) do
|
||||
ActiveRecord::Schema.define(version: 20160220123949) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
@ -824,7 +824,7 @@ ActiveRecord::Schema.define(version: 20160217174422) do
|
|||
|
||||
add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree
|
||||
|
||||
create_table "tasks", force: :cascade do |t|
|
||||
create_table "todos", force: :cascade do |t|
|
||||
t.integer "user_id", null: false
|
||||
t.integer "project_id", null: false
|
||||
t.integer "target_id", null: false
|
||||
|
@ -837,12 +837,12 @@ ActiveRecord::Schema.define(version: 20160217174422) do
|
|||
t.integer "note_id"
|
||||
end
|
||||
|
||||
add_index "tasks", ["author_id"], name: "index_tasks_on_author_id", using: :btree
|
||||
add_index "tasks", ["note_id"], name: "index_tasks_on_note_id", using: :btree
|
||||
add_index "tasks", ["project_id"], name: "index_tasks_on_project_id", using: :btree
|
||||
add_index "tasks", ["state"], name: "index_tasks_on_state", using: :btree
|
||||
add_index "tasks", ["target_type", "target_id"], name: "index_tasks_on_target_type_and_target_id", using: :btree
|
||||
add_index "tasks", ["user_id"], name: "index_tasks_on_user_id", using: :btree
|
||||
add_index "todos", ["author_id"], name: "index_todos_on_author_id", using: :btree
|
||||
add_index "todos", ["note_id"], name: "index_todos_on_note_id", using: :btree
|
||||
add_index "todos", ["project_id"], name: "index_todos_on_project_id", using: :btree
|
||||
add_index "todos", ["state"], name: "index_todos_on_state", using: :btree
|
||||
add_index "todos", ["target_type", "target_id"], name: "index_todos_on_target_type_and_target_id", using: :btree
|
||||
add_index "todos", ["user_id"], name: "index_todos_on_user_id", using: :btree
|
||||
|
||||
create_table "users", force: :cascade do |t|
|
||||
t.string "email", default: "", null: false
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
@dashboard
|
||||
Feature: Dashboard Tasks
|
||||
Feature: Dashboard Todos
|
||||
Background:
|
||||
Given I sign in as a user
|
||||
And I own project "Shop"
|
||||
|
@ -7,32 +7,32 @@ Feature: Dashboard Tasks
|
|||
And "Mary Jane" is a developer of project "Shop"
|
||||
And "Mary Jane" owns private project "Enterprise"
|
||||
And I am a developer of project "Enterprise"
|
||||
And I have pending tasks
|
||||
And I visit dashboard task queue page
|
||||
And I have todos
|
||||
And I visit dashboard todos page
|
||||
|
||||
@javascript
|
||||
Scenario: I mark pending tasks as done
|
||||
Then I should see pending tasks assigned to me
|
||||
And I mark the pending task as done
|
||||
Scenario: I mark todos as done
|
||||
Then I should see todos assigned to me
|
||||
And I mark the todo as done
|
||||
And I click on the "Done" tab
|
||||
Then I should see all tasks marked as done
|
||||
Then I should see all todos marked as done
|
||||
|
||||
@javascript
|
||||
Scenario: I filter by project
|
||||
Given I filter by "Enterprise"
|
||||
Then I should not see tasks
|
||||
Then I should not see todos
|
||||
|
||||
@javascript
|
||||
Scenario: I filter by author
|
||||
Given I filter by "John Doe"
|
||||
Then I should not see tasks related to "Mary Jane" in the list
|
||||
Then I should not see todos related to "Mary Jane" in the list
|
||||
|
||||
@javascript
|
||||
Scenario: I filter by type
|
||||
Given I filter by "Issue"
|
||||
Then I should not see tasks related to "Merge Requests" in the list
|
||||
Then I should not see todos related to "Merge Requests" in the list
|
||||
|
||||
@javascript
|
||||
Scenario: I filter by action
|
||||
Given I filter by "Mentioned"
|
||||
Then I should not see tasks related to "Assignments" in the list
|
||||
Then I should not see todos related to "Assignments" in the list
|
|
@ -1,4 +1,4 @@
|
|||
class Spinach::Features::DashboardTasks < Spinach::FeatureSteps
|
||||
class Spinach::Features::DashboardTodos < Spinach::FeatureSteps
|
||||
include SharedAuthentication
|
||||
include SharedPaths
|
||||
include SharedProject
|
||||
|
@ -17,43 +17,43 @@ class Spinach::Features::DashboardTasks < Spinach::FeatureSteps
|
|||
project.team << [john_doe, :developer]
|
||||
end
|
||||
|
||||
step 'I have pending tasks' do
|
||||
create(:task, user: current_user, project: project, author: mary_jane, target: issue, action: Task::MENTIONED)
|
||||
create(:task, user: current_user, project: project, author: john_doe, target: issue, action: Task::ASSIGNED)
|
||||
step 'I have todos' do
|
||||
create(:todo, user: current_user, project: project, author: mary_jane, target: issue, action: Todo::MENTIONED)
|
||||
create(:todo, user: current_user, project: project, author: john_doe, target: issue, action: Todo::ASSIGNED)
|
||||
note = create(:note, author: john_doe, noteable: issue, note: "#{current_user.to_reference} Wdyt?")
|
||||
create(:task, user: current_user, project: project, author: john_doe, target: issue, action: Task::MENTIONED, note: note)
|
||||
create(:task, user: current_user, project: project, author: john_doe, target: merge_request, action: Task::ASSIGNED)
|
||||
create(:todo, user: current_user, project: project, author: john_doe, target: issue, action: Todo::MENTIONED, note: note)
|
||||
create(:todo, user: current_user, project: project, author: john_doe, target: merge_request, action: Todo::ASSIGNED)
|
||||
end
|
||||
|
||||
step 'I should see pending tasks assigned to me' do
|
||||
expect(page).to have_content 'Tasks 4'
|
||||
step 'I should see todos assigned to me' do
|
||||
expect(page).to have_content 'Todos 4'
|
||||
expect(page).to have_content 'Done 0'
|
||||
|
||||
expect(page).to have_link project.name_with_namespace
|
||||
should_see_task(1, "John Doe assigned merge request ##{merge_request.iid}", merge_request.title)
|
||||
should_see_task(2, "John Doe mentioned you on issue ##{issue.iid}", "#{current_user.to_reference} Wdyt?")
|
||||
should_see_task(3, "John Doe assigned issue ##{issue.iid}", issue.title)
|
||||
should_see_task(4, "Mary Jane mentioned you on issue ##{issue.iid}", issue.title)
|
||||
should_see_todo(1, "John Doe assigned merge request ##{merge_request.iid}", merge_request.title)
|
||||
should_see_todo(2, "John Doe mentioned you on issue ##{issue.iid}", "#{current_user.to_reference} Wdyt?")
|
||||
should_see_todo(3, "John Doe assigned issue ##{issue.iid}", issue.title)
|
||||
should_see_todo(4, "Mary Jane mentioned you on issue ##{issue.iid}", issue.title)
|
||||
end
|
||||
|
||||
step 'I mark the pending task as done' do
|
||||
page.within('.task:nth-child(1)') do
|
||||
step 'I mark the todo as done' do
|
||||
page.within('.todo:nth-child(1)') do
|
||||
click_link 'Done'
|
||||
end
|
||||
|
||||
expect(page).to have_content 'Task was successfully marked as done.'
|
||||
expect(page).to have_content 'Tasks 3'
|
||||
expect(page).to have_content 'Todo was successfully marked as done.'
|
||||
expect(page).to have_content 'Todos 3'
|
||||
expect(page).to have_content 'Done 1'
|
||||
should_not_see_task "John Doe assigned merge request ##{merge_request.iid}"
|
||||
should_not_see_todo "John Doe assigned merge request ##{merge_request.iid}"
|
||||
end
|
||||
|
||||
step 'I click on the "Done" tab' do
|
||||
click_link 'Done 1'
|
||||
end
|
||||
|
||||
step 'I should see all tasks marked as done' do
|
||||
step 'I should see all todos marked as done' do
|
||||
expect(page).to have_link project.name_with_namespace
|
||||
should_see_task(1, "John Doe assigned merge request ##{merge_request.iid}", merge_request.title, false)
|
||||
should_see_todo(1, "John Doe assigned merge request ##{merge_request.iid}", merge_request.title, false)
|
||||
end
|
||||
|
||||
step 'I filter by "Enterprise"' do
|
||||
|
@ -69,28 +69,28 @@ class Spinach::Features::DashboardTasks < Spinach::FeatureSteps
|
|||
end
|
||||
|
||||
step 'I filter by "Mentioned"' do
|
||||
select2("#{Task::MENTIONED}", from: '#action_id')
|
||||
select2("#{Todo::MENTIONED}", from: '#action_id')
|
||||
end
|
||||
|
||||
step 'I should not see tasks' do
|
||||
expect(page).to have_content 'No tasks to show'
|
||||
step 'I should not see todos' do
|
||||
expect(page).to have_content 'No todos to show'
|
||||
end
|
||||
|
||||
step 'I should not see tasks related to "Mary Jane" in the list' do
|
||||
should_not_see_task "Mary Jane mentioned you on issue ##{issue.iid}"
|
||||
step 'I should not see todos related to "Mary Jane" in the list' do
|
||||
should_not_see_todo "Mary Jane mentioned you on issue ##{issue.iid}"
|
||||
end
|
||||
|
||||
step 'I should not see tasks related to "Merge Requests" in the list' do
|
||||
should_not_see_task "John Doe assigned merge request ##{merge_request.iid}"
|
||||
step 'I should not see todos related to "Merge Requests" in the list' do
|
||||
should_not_see_todo "John Doe assigned merge request ##{merge_request.iid}"
|
||||
end
|
||||
|
||||
step 'I should not see tasks related to "Assignments" in the list' do
|
||||
should_not_see_task "John Doe assigned merge request ##{merge_request.iid}"
|
||||
should_not_see_task "John Doe assigned issue ##{issue.iid}"
|
||||
step 'I should not see todos related to "Assignments" in the list' do
|
||||
should_not_see_todo "John Doe assigned merge request ##{merge_request.iid}"
|
||||
should_not_see_todo "John Doe assigned issue ##{issue.iid}"
|
||||
end
|
||||
|
||||
def should_see_task(position, title, body, pending = true)
|
||||
page.within(".task:nth-child(#{position})") do
|
||||
def should_see_todo(position, title, body, pending = true)
|
||||
page.within(".todo:nth-child(#{position})") do
|
||||
expect(page).to have_content title
|
||||
expect(page).to have_content body
|
||||
|
||||
|
@ -102,7 +102,7 @@ class Spinach::Features::DashboardTasks < Spinach::FeatureSteps
|
|||
end
|
||||
end
|
||||
|
||||
def should_not_see_task(title)
|
||||
def should_not_see_todo(title)
|
||||
expect(page).not_to have_content title
|
||||
end
|
||||
|
|
@ -103,8 +103,8 @@ module SharedPaths
|
|||
visit dashboard_groups_path
|
||||
end
|
||||
|
||||
step 'I visit dashboard task queue page' do
|
||||
visit dashboard_tasks_path
|
||||
step 'I visit dashboard todos page' do
|
||||
visit dashboard_todos_path
|
||||
end
|
||||
|
||||
step 'I should be redirected to the dashboard groups page' do
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: tasks
|
||||
# Table name: todos
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer not null
|
||||
|
@ -16,19 +16,19 @@
|
|||
#
|
||||
|
||||
FactoryGirl.define do
|
||||
factory :task do
|
||||
factory :todo do
|
||||
project
|
||||
author
|
||||
user
|
||||
target factory: :issue
|
||||
action { Task::ASSIGNED }
|
||||
action { Todo::ASSIGNED }
|
||||
|
||||
trait :assigned do
|
||||
action { Task::ASSIGNED }
|
||||
action { Todo::ASSIGNED }
|
||||
end
|
||||
|
||||
trait :mentioned do
|
||||
action { Task::MENTIONED }
|
||||
action { Todo::MENTIONED }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -27,7 +27,7 @@ describe Note, models: true do
|
|||
it { is_expected.to belong_to(:noteable) }
|
||||
it { is_expected.to belong_to(:author).class_name('User') }
|
||||
|
||||
it { is_expected.to have_many(:tasks).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:todos).dependent(:destroy) }
|
||||
end
|
||||
|
||||
describe 'validation' do
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: tasks
|
||||
# Table name: todos
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer not null
|
||||
|
@ -17,7 +17,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Task, models: true do
|
||||
describe Todo, models: true do
|
||||
describe 'relationships' do
|
||||
it { is_expected.to belong_to(:author).class_name("User") }
|
||||
it { is_expected.to belong_to(:note) }
|
||||
|
@ -39,13 +39,13 @@ describe Task, models: true do
|
|||
|
||||
describe '#action_name' do
|
||||
it 'returns proper message when action is an assigment' do
|
||||
subject.action = Task::ASSIGNED
|
||||
subject.action = Todo::ASSIGNED
|
||||
|
||||
expect(subject.action_name).to eq 'assigned'
|
||||
end
|
||||
|
||||
it 'returns proper message when action is a mention' do
|
||||
subject.action = Task::MENTIONED
|
||||
subject.action = Todo::MENTIONED
|
||||
|
||||
expect(subject.action_name).to eq 'mentioned you on'
|
||||
end
|
|
@ -92,7 +92,7 @@ describe User, models: true do
|
|||
it { is_expected.to have_many(:identities).dependent(:destroy) }
|
||||
it { is_expected.to have_one(:abuse_report) }
|
||||
it { is_expected.to have_many(:spam_logs).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:tasks).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:todos).dependent(:destroy) }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
|
|
|
@ -5,7 +5,7 @@ describe Issues::CloseService, services: true do
|
|||
let(:user2) { create(:user) }
|
||||
let(:issue) { create(:issue, assignee: user2) }
|
||||
let(:project) { issue.project }
|
||||
let!(:pending_task) { create(:task, :assigned, user: user, project: project, target: issue, author: user2) }
|
||||
let!(:todo) { create(:todo, :assigned, user: user, project: project, target: issue, author: user2) }
|
||||
|
||||
before do
|
||||
project.team << [user, :master]
|
||||
|
@ -34,8 +34,8 @@ describe Issues::CloseService, services: true do
|
|||
expect(note.note).to include "Status changed to closed"
|
||||
end
|
||||
|
||||
it 'marks pending tasks as done' do
|
||||
expect(pending_task.reload).to be_done
|
||||
it 'marks todos as done' do
|
||||
expect(todo.reload).to be_done
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -47,7 +47,7 @@ describe Issues::CloseService, services: true do
|
|||
|
||||
it { expect(@issue).to be_valid }
|
||||
it { expect(@issue).to be_opened }
|
||||
it { expect(pending_task.reload).to be_pending }
|
||||
it { expect(todo.reload).to be_pending }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,17 +24,18 @@ describe Issues::CreateService, services: true do
|
|||
it { expect(@issue.title).to eq('Awesome issue') }
|
||||
it { expect(@issue.assignee).to eq assignee }
|
||||
|
||||
it 'creates a pending task for new assignee' do
|
||||
it 'creates a pending todo for new assignee' do
|
||||
attributes = {
|
||||
project: project,
|
||||
author: user,
|
||||
user: assignee,
|
||||
target: @issue,
|
||||
action: Task::ASSIGNED,
|
||||
target_id: @issue.id,
|
||||
target_type: @issue.class.name,
|
||||
action: Todo::ASSIGNED,
|
||||
state: :pending
|
||||
}
|
||||
|
||||
expect(Task.where(attributes).count).to eq 1
|
||||
expect(Todo.where(attributes).count).to eq 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -80,16 +80,16 @@ describe Issues::UpdateService, services: true do
|
|||
end
|
||||
end
|
||||
|
||||
context 'task queue' do
|
||||
let!(:pending_task) { create(:task, :assigned, user: user, project: project, target: issue, author: user2) }
|
||||
context 'todos' do
|
||||
let!(:todo) { create(:todo, :assigned, user: user, project: project, target: issue, author: user2) }
|
||||
|
||||
context 'when the title change' do
|
||||
before do
|
||||
update_issue({ title: 'New title' })
|
||||
end
|
||||
|
||||
it 'marks pending tasks as done' do
|
||||
expect(pending_task.reload.done?).to eq true
|
||||
it 'marks pending todos as done' do
|
||||
expect(todo.reload.done?).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -98,8 +98,8 @@ describe Issues::UpdateService, services: true do
|
|||
update_issue({ description: 'Also please fix' })
|
||||
end
|
||||
|
||||
it 'marks pending tasks as done' do
|
||||
expect(pending_task.reload.done?).to eq true
|
||||
it 'marks todos as done' do
|
||||
expect(todo.reload.done?).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -108,21 +108,22 @@ describe Issues::UpdateService, services: true do
|
|||
update_issue({ assignee: user2 })
|
||||
end
|
||||
|
||||
it 'marks previous assignee pending tasks as done' do
|
||||
expect(pending_task.reload.done?).to eq true
|
||||
it 'marks previous assignee todos as done' do
|
||||
expect(todo.reload.done?).to eq true
|
||||
end
|
||||
|
||||
it 'creates a pending task for new assignee' do
|
||||
it 'creates a todo for new assignee' do
|
||||
attributes = {
|
||||
project: project,
|
||||
author: user,
|
||||
user: user2,
|
||||
target: issue,
|
||||
action: Task::ASSIGNED,
|
||||
target_id: issue.id,
|
||||
target_type: issue.class.name,
|
||||
action: Todo::ASSIGNED,
|
||||
state: :pending
|
||||
}
|
||||
|
||||
expect(Task.where(attributes).count).to eq 1
|
||||
expect(Todo.where(attributes).count).to eq 1
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -131,8 +132,8 @@ describe Issues::UpdateService, services: true do
|
|||
update_issue({ milestone: create(:milestone) })
|
||||
end
|
||||
|
||||
it 'marks pending tasks as done' do
|
||||
expect(pending_task.reload.done?).to eq true
|
||||
it 'marks todos as done' do
|
||||
expect(todo.reload.done?).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -141,8 +142,8 @@ describe Issues::UpdateService, services: true do
|
|||
update_issue({ label_ids: [label.id] })
|
||||
end
|
||||
|
||||
it 'marks pending tasks as done' do
|
||||
expect(pending_task.reload.done?).to eq true
|
||||
it 'marks todos as done' do
|
||||
expect(todo.reload.done?).to eq true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ describe MergeRequests::CloseService, services: true do
|
|||
let(:user2) { create(:user) }
|
||||
let(:merge_request) { create(:merge_request, assignee: user2) }
|
||||
let(:project) { merge_request.project }
|
||||
let!(:pending_task) { create(:task, :assigned, user: user, project: project, target: merge_request, author: user2) }
|
||||
let!(:todo) { create(:todo, :assigned, user: user, project: project, target: merge_request, author: user2) }
|
||||
|
||||
before do
|
||||
project.team << [user, :master]
|
||||
|
@ -43,8 +43,8 @@ describe MergeRequests::CloseService, services: true do
|
|||
expect(note.note).to include 'Status changed to closed'
|
||||
end
|
||||
|
||||
it 'marks pending tasks as done' do
|
||||
expect(pending_task.reload).to be_done
|
||||
it 'marks todos as done' do
|
||||
expect(todo.reload).to be_done
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -34,13 +34,14 @@ describe MergeRequests::CreateService, services: true do
|
|||
expect(service).to have_received(:execute_hooks).with(@merge_request)
|
||||
end
|
||||
|
||||
it 'does not creates a pending task' do
|
||||
it 'does not creates todos' do
|
||||
attributes = {
|
||||
project: project,
|
||||
target: @merge_request
|
||||
target_id: @merge_request.id,
|
||||
target_type: @merge_request.class.name
|
||||
}
|
||||
|
||||
expect(Task.where(attributes).count).to be_zero
|
||||
expect(Todo.where(attributes).count).to be_zero
|
||||
end
|
||||
|
||||
context 'when merge request is assigned to someone' do
|
||||
|
@ -56,17 +57,18 @@ describe MergeRequests::CreateService, services: true do
|
|||
|
||||
it { expect(@merge_request.assignee).to eq assignee }
|
||||
|
||||
it 'creates a pending task for new assignee' do
|
||||
it 'creates a todo for new assignee' do
|
||||
attributes = {
|
||||
project: project,
|
||||
author: user,
|
||||
user: assignee,
|
||||
target: @merge_request,
|
||||
action: Task::ASSIGNED,
|
||||
target_id: @merge_request.id,
|
||||
target_type: @merge_request.class.name,
|
||||
action: Todo::ASSIGNED,
|
||||
state: :pending
|
||||
}
|
||||
|
||||
expect(Task.where(attributes).count).to eq 1
|
||||
expect(Todo.where(attributes).count).to eq 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -98,16 +98,16 @@ describe MergeRequests::UpdateService, services: true do
|
|||
end
|
||||
end
|
||||
|
||||
context 'task queue' do
|
||||
let!(:pending_task) { create(:task, :assigned, user: user, project: project, target: merge_request, author: user2) }
|
||||
context 'todos' do
|
||||
let!(:pending_todo) { create(:todo, :assigned, user: user, project: project, target: merge_request, author: user2) }
|
||||
|
||||
context 'when the title change' do
|
||||
before do
|
||||
update_merge_request({ title: 'New title' })
|
||||
end
|
||||
|
||||
it 'marks pending tasks as done' do
|
||||
expect(pending_task.reload).to be_done
|
||||
it 'marks pending todos as done' do
|
||||
expect(pending_todo.reload).to be_done
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -116,8 +116,8 @@ describe MergeRequests::UpdateService, services: true do
|
|||
update_merge_request({ description: 'Also please fix' })
|
||||
end
|
||||
|
||||
it 'marks pending tasks as done' do
|
||||
expect(pending_task.reload).to be_done
|
||||
it 'marks pending todos as done' do
|
||||
expect(pending_todo.reload).to be_done
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -126,21 +126,22 @@ describe MergeRequests::UpdateService, services: true do
|
|||
update_merge_request({ assignee: user2 })
|
||||
end
|
||||
|
||||
it 'marks previous assignee pending tasks as done' do
|
||||
expect(pending_task.reload).to be_done
|
||||
it 'marks previous assignee pending todos as done' do
|
||||
expect(pending_todo.reload).to be_done
|
||||
end
|
||||
|
||||
it 'creates a pending task for new assignee' do
|
||||
it 'creates a pending todo for new assignee' do
|
||||
attributes = {
|
||||
project: project,
|
||||
author: user,
|
||||
user: user2,
|
||||
target: merge_request,
|
||||
action: Task::ASSIGNED,
|
||||
target_id: merge_request.id,
|
||||
target_type: merge_request.class.name,
|
||||
action: Todo::ASSIGNED,
|
||||
state: :pending
|
||||
}
|
||||
|
||||
expect(Task.where(attributes).count).to eq 1
|
||||
expect(Todo.where(attributes).count).to eq 1
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -149,8 +150,8 @@ describe MergeRequests::UpdateService, services: true do
|
|||
update_merge_request({ milestone: create(:milestone) })
|
||||
end
|
||||
|
||||
it 'marks pending tasks as done' do
|
||||
expect(pending_task.reload).to be_done
|
||||
it 'marks pending todos as done' do
|
||||
expect(pending_todo.reload).to be_done
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -159,8 +160,8 @@ describe MergeRequests::UpdateService, services: true do
|
|||
update_merge_request({ label_ids: [label.id] })
|
||||
end
|
||||
|
||||
it 'marks pending tasks as done' do
|
||||
expect(pending_task.reload).to be_done
|
||||
it 'marks pending todos as done' do
|
||||
expect(pending_todo.reload).to be_done
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -169,8 +170,8 @@ describe MergeRequests::UpdateService, services: true do
|
|||
update_merge_request({ target_branch: 'target' })
|
||||
end
|
||||
|
||||
it 'marks pending tasks as done' do
|
||||
expect(pending_task.reload).to be_done
|
||||
it 'marks pending todos as done' do
|
||||
expect(pending_todo.reload).to be_done
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,16 +18,16 @@ describe Notes::UpdateService, services: true do
|
|||
@note.reload
|
||||
end
|
||||
|
||||
context 'task queue' do
|
||||
let!(:pending_task) { create(:task, :assigned, user: user, project: project, target: issue, author: user2) }
|
||||
context 'todos' do
|
||||
let!(:todo) { create(:todo, :assigned, user: user, project: project, target: issue, author: user2) }
|
||||
|
||||
context 'when the note change' do
|
||||
before do
|
||||
update_note({ note: 'New note' })
|
||||
end
|
||||
|
||||
it 'marks pending tasks as done' do
|
||||
expect(pending_task.reload).to be_done
|
||||
it 'marks todos as done' do
|
||||
expect(todo.reload).to be_done
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -36,8 +36,8 @@ describe Notes::UpdateService, services: true do
|
|||
update_note({ note: 'Old note' })
|
||||
end
|
||||
|
||||
it 'keep pending tasks' do
|
||||
expect(pending_task.reload).to be_pending
|
||||
it 'keep todos' do
|
||||
expect(todo.reload).to be_pending
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,264 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe TaskService, services: true do
|
||||
let(:author) { create(:user) }
|
||||
let(:john_doe) { create(:user, username: 'john_doe') }
|
||||
let(:michael) { create(:user, username: 'michael') }
|
||||
let(:stranger) { create(:user, username: 'stranger') }
|
||||
let(:project) { create(:project) }
|
||||
let(:mentions) { [author.to_reference, john_doe.to_reference, michael.to_reference, stranger.to_reference].join(' ') }
|
||||
let(:service) { described_class.new }
|
||||
|
||||
before do
|
||||
project.team << [author, :developer]
|
||||
project.team << [john_doe, :developer]
|
||||
project.team << [michael, :developer]
|
||||
end
|
||||
|
||||
describe 'Issues' do
|
||||
let(:issue) { create(:issue, project: project, assignee: john_doe, author: author, description: mentions) }
|
||||
let(:unassigned_issue) { create(:issue, project: project, assignee: nil) }
|
||||
|
||||
describe '#new_issue' do
|
||||
it 'creates a task if assigned' do
|
||||
service.new_issue(issue, author)
|
||||
|
||||
should_create_task(user: john_doe, target: issue, action: Task::ASSIGNED)
|
||||
end
|
||||
|
||||
it 'does not create a task if unassigned' do
|
||||
should_not_create_any_task { service.new_issue(unassigned_issue, author) }
|
||||
end
|
||||
|
||||
it 'does not create a task if assignee is the current user' do
|
||||
should_not_create_any_task { service.new_issue(unassigned_issue, john_doe) }
|
||||
end
|
||||
|
||||
it 'creates a task for each valid mentioned user' do
|
||||
service.new_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
|
||||
|
||||
describe '#update_issue' do
|
||||
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_create_task(user: john_doe, target: issue, action: Task::MENTIONED)
|
||||
should_not_create_task(user: author, target: issue, action: Task::MENTIONED)
|
||||
should_not_create_task(user: stranger, target: issue, action: Task::MENTIONED)
|
||||
end
|
||||
|
||||
it 'does not create a task if user was already mentioned' do
|
||||
create(:task, :mentioned, user: michael, project: project, target: issue, author: author)
|
||||
|
||||
expect { service.update_issue(issue, author) }.not_to change(michael.tasks, :count)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#close_issue' 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)
|
||||
|
||||
expect(first_task.reload).to be_done
|
||||
expect(second_task.reload).to be_done
|
||||
end
|
||||
end
|
||||
|
||||
describe '#reassigned_issue' do
|
||||
it 'creates a pending task for new assignee' do
|
||||
unassigned_issue.update_attribute(:assignee, john_doe)
|
||||
service.reassigned_issue(unassigned_issue, author)
|
||||
|
||||
should_create_task(user: john_doe, target: unassigned_issue, action: Task::ASSIGNED)
|
||||
end
|
||||
|
||||
it 'does not create a task if unassigned' do
|
||||
issue.update_attribute(:assignee, nil)
|
||||
|
||||
should_not_create_any_task { service.reassigned_issue(issue, author) }
|
||||
end
|
||||
|
||||
it 'does not create a task if new assignee is the current user' do
|
||||
unassigned_issue.update_attribute(:assignee, john_doe)
|
||||
|
||||
should_not_create_any_task { service.reassigned_issue(unassigned_issue, john_doe) }
|
||||
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) }
|
||||
let(:note) { create(:note, project: project, noteable: issue, author: john_doe, note: mentions) }
|
||||
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) }
|
||||
|
||||
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, 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, 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, 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, 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)
|
||||
should_not_create_task(user: john_doe, target: issue, author: john_doe, action: Task::MENTIONED, note: note)
|
||||
should_not_create_task(user: stranger, target: issue, author: john_doe, action: Task::MENTIONED, note: note)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Merge Requests' do
|
||||
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) }
|
||||
|
||||
describe '#new_merge_request' do
|
||||
it 'creates a pending task if assigned' do
|
||||
service.new_merge_request(mr_assigned, author)
|
||||
|
||||
should_create_task(user: john_doe, target: mr_assigned, action: Task::ASSIGNED)
|
||||
end
|
||||
|
||||
it 'does not create a task if unassigned' do
|
||||
should_not_create_any_task { service.new_merge_request(mr_unassigned, author) }
|
||||
end
|
||||
|
||||
it 'does not create a task if assignee is the current user' do
|
||||
should_not_create_any_task { service.new_merge_request(mr_unassigned, john_doe) }
|
||||
end
|
||||
|
||||
it 'creates a task for each valid mentioned user' do
|
||||
service.new_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
|
||||
|
||||
describe '#update_merge_request' do
|
||||
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_create_task(user: john_doe, target: mr_assigned, action: Task::MENTIONED)
|
||||
should_not_create_task(user: author, target: mr_assigned, action: Task::MENTIONED)
|
||||
should_not_create_task(user: stranger, target: mr_assigned, action: Task::MENTIONED)
|
||||
end
|
||||
|
||||
it 'does not create a task if user was already mentioned' do
|
||||
create(:task, :mentioned, user: michael, project: project, target: mr_assigned, author: author)
|
||||
|
||||
expect { service.update_merge_request(mr_assigned, author) }.not_to change(michael.tasks, :count)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#close_merge_request' 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)
|
||||
|
||||
expect(first_task.reload).to be_done
|
||||
expect(second_task.reload).to be_done
|
||||
end
|
||||
end
|
||||
|
||||
describe '#reassigned_merge_request' do
|
||||
it 'creates a pending task for new assignee' do
|
||||
mr_unassigned.update_attribute(:assignee, john_doe)
|
||||
service.reassigned_merge_request(mr_unassigned, author)
|
||||
|
||||
should_create_task(user: john_doe, target: mr_unassigned, action: Task::ASSIGNED)
|
||||
end
|
||||
|
||||
it 'does not create a task if unassigned' do
|
||||
mr_assigned.update_attribute(:assignee, nil)
|
||||
|
||||
should_not_create_any_task { service.reassigned_merge_request(mr_assigned, author) }
|
||||
end
|
||||
|
||||
it 'does not create a task if new assignee is the current user' do
|
||||
mr_assigned.update_attribute(:assignee, john_doe)
|
||||
|
||||
should_not_create_any_task { service.reassigned_merge_request(mr_assigned, john_doe) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#merge_merge_request' 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)
|
||||
|
||||
expect(first_task.reload).to be_done
|
||||
expect(second_task.reload).to be_done
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def should_create_task(attributes = {})
|
||||
attributes.reverse_merge!(
|
||||
project: project,
|
||||
author: author,
|
||||
state: :pending
|
||||
)
|
||||
|
||||
expect(Task.where(attributes).count).to eq 1
|
||||
end
|
||||
|
||||
def should_not_create_task(attributes = {})
|
||||
attributes.reverse_merge!(
|
||||
project: project,
|
||||
author: author,
|
||||
state: :pending
|
||||
)
|
||||
|
||||
expect(Task.where(attributes).count).to eq 0
|
||||
end
|
||||
|
||||
def should_not_create_any_task
|
||||
expect { yield }.not_to change(Task, :count)
|
||||
end
|
||||
end
|
264
spec/services/todo_service_spec.rb
Normal file
264
spec/services/todo_service_spec.rb
Normal file
|
@ -0,0 +1,264 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe TodoService, services: true do
|
||||
let(:author) { create(:user) }
|
||||
let(:john_doe) { create(:user, username: 'john_doe') }
|
||||
let(:michael) { create(:user, username: 'michael') }
|
||||
let(:stranger) { create(:user, username: 'stranger') }
|
||||
let(:project) { create(:project) }
|
||||
let(:mentions) { [author.to_reference, john_doe.to_reference, michael.to_reference, stranger.to_reference].join(' ') }
|
||||
let(:service) { described_class.new }
|
||||
|
||||
before do
|
||||
project.team << [author, :developer]
|
||||
project.team << [john_doe, :developer]
|
||||
project.team << [michael, :developer]
|
||||
end
|
||||
|
||||
describe 'Issues' do
|
||||
let(:issue) { create(:issue, project: project, assignee: john_doe, author: author, description: mentions) }
|
||||
let(:unassigned_issue) { create(:issue, project: project, assignee: nil) }
|
||||
|
||||
describe '#new_issue' do
|
||||
it 'creates a todo if assigned' do
|
||||
service.new_issue(issue, author)
|
||||
|
||||
should_create_todo(user: john_doe, target: issue, action: Todo::ASSIGNED)
|
||||
end
|
||||
|
||||
it 'does not create a todo if unassigned' do
|
||||
should_not_create_any_todo { service.new_issue(unassigned_issue, author) }
|
||||
end
|
||||
|
||||
it 'does not create a todo if assignee is the current user' do
|
||||
should_not_create_any_todo { service.new_issue(unassigned_issue, john_doe) }
|
||||
end
|
||||
|
||||
it 'creates a todo for each valid mentioned user' do
|
||||
service.new_issue(issue, author)
|
||||
|
||||
should_create_todo(user: michael, target: issue, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: author, target: issue, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: john_doe, target: issue, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: stranger, target: issue, action: Todo::MENTIONED)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#update_issue' do
|
||||
it 'creates a todo for each valid mentioned user' do
|
||||
service.update_issue(issue, author)
|
||||
|
||||
should_create_todo(user: michael, target: issue, action: Todo::MENTIONED)
|
||||
should_create_todo(user: john_doe, target: issue, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: author, target: issue, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: stranger, target: issue, action: Todo::MENTIONED)
|
||||
end
|
||||
|
||||
it 'does not create a todo if user was already mentioned' do
|
||||
create(:todo, :mentioned, user: michael, project: project, target: issue, author: author)
|
||||
|
||||
expect { service.update_issue(issue, author) }.not_to change(michael.todos, :count)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#close_issue' do
|
||||
it 'marks related pending todos to the target for the user as done' do
|
||||
first_todo = create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author)
|
||||
second_todo = create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author)
|
||||
|
||||
service.close_issue(issue, john_doe)
|
||||
|
||||
expect(first_todo.reload).to be_done
|
||||
expect(second_todo.reload).to be_done
|
||||
end
|
||||
end
|
||||
|
||||
describe '#reassigned_issue' do
|
||||
it 'creates a pending todo for new assignee' do
|
||||
unassigned_issue.update_attribute(:assignee, john_doe)
|
||||
service.reassigned_issue(unassigned_issue, author)
|
||||
|
||||
should_create_todo(user: john_doe, target: unassigned_issue, action: Todo::ASSIGNED)
|
||||
end
|
||||
|
||||
it 'does not create a todo if unassigned' do
|
||||
issue.update_attribute(:assignee, nil)
|
||||
|
||||
should_not_create_any_todo { service.reassigned_issue(issue, author) }
|
||||
end
|
||||
|
||||
it 'does not create a todo if new assignee is the current user' do
|
||||
unassigned_issue.update_attribute(:assignee, john_doe)
|
||||
|
||||
should_not_create_any_todo { service.reassigned_issue(unassigned_issue, john_doe) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#mark_pending_todos_as_done' do
|
||||
it 'marks related pending todos to the target for the user as done' do
|
||||
first_todo = create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author)
|
||||
second_todo = create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author)
|
||||
|
||||
service.mark_pending_todos_as_done(issue, john_doe)
|
||||
|
||||
expect(first_todo.reload).to be_done
|
||||
expect(second_todo.reload).to be_done
|
||||
end
|
||||
end
|
||||
|
||||
describe '#new_note' do
|
||||
let!(:first_todo) { create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author) }
|
||||
let!(:second_todo) { create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author) }
|
||||
let(:note) { create(:note, project: project, noteable: issue, author: john_doe, note: mentions) }
|
||||
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) }
|
||||
|
||||
it 'mark related pending todos to the noteable for the note author as done' do
|
||||
first_todo = create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author)
|
||||
second_todo = create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author)
|
||||
|
||||
service.new_note(note, john_doe)
|
||||
|
||||
expect(first_todo.reload).to be_done
|
||||
expect(second_todo.reload).to be_done
|
||||
end
|
||||
|
||||
it 'mark related pending todos to the noteable for the award note author as done' do
|
||||
service.new_note(award_note, john_doe)
|
||||
|
||||
expect(first_todo.reload).to be_done
|
||||
expect(second_todo.reload).to be_done
|
||||
end
|
||||
|
||||
it 'does not mark related pending todos it is a system note' do
|
||||
service.new_note(system_note, john_doe)
|
||||
|
||||
expect(first_todo.reload).to be_pending
|
||||
expect(second_todo.reload).to be_pending
|
||||
end
|
||||
|
||||
it 'creates a todo for each valid mentioned user' do
|
||||
service.new_note(note, john_doe)
|
||||
|
||||
should_create_todo(user: michael, target: issue, author: john_doe, action: Todo::MENTIONED, note: note)
|
||||
should_create_todo(user: author, target: issue, author: john_doe, action: Todo::MENTIONED, note: note)
|
||||
should_not_create_todo(user: john_doe, target: issue, author: john_doe, action: Todo::MENTIONED, note: note)
|
||||
should_not_create_todo(user: stranger, target: issue, author: john_doe, action: Todo::MENTIONED, note: note)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Merge Requests' do
|
||||
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) }
|
||||
|
||||
describe '#new_merge_request' do
|
||||
it 'creates a pending todo if assigned' do
|
||||
service.new_merge_request(mr_assigned, author)
|
||||
|
||||
should_create_todo(user: john_doe, target: mr_assigned, action: Todo::ASSIGNED)
|
||||
end
|
||||
|
||||
it 'does not create a todo if unassigned' do
|
||||
should_not_create_any_todo { service.new_merge_request(mr_unassigned, author) }
|
||||
end
|
||||
|
||||
it 'does not create a todo if assignee is the current user' do
|
||||
should_not_create_any_todo { service.new_merge_request(mr_unassigned, john_doe) }
|
||||
end
|
||||
|
||||
it 'creates a todo for each valid mentioned user' do
|
||||
service.new_merge_request(mr_assigned, author)
|
||||
|
||||
should_create_todo(user: michael, target: mr_assigned, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: author, target: mr_assigned, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: john_doe, target: mr_assigned, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: stranger, target: mr_assigned, action: Todo::MENTIONED)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#update_merge_request' do
|
||||
it 'creates a todo for each valid mentioned user' do
|
||||
service.update_merge_request(mr_assigned, author)
|
||||
|
||||
should_create_todo(user: michael, target: mr_assigned, action: Todo::MENTIONED)
|
||||
should_create_todo(user: john_doe, target: mr_assigned, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: author, target: mr_assigned, action: Todo::MENTIONED)
|
||||
should_not_create_todo(user: stranger, target: mr_assigned, action: Todo::MENTIONED)
|
||||
end
|
||||
|
||||
it 'does not create a todo if user was already mentioned' do
|
||||
create(:todo, :mentioned, user: michael, project: project, target: mr_assigned, author: author)
|
||||
|
||||
expect { service.update_merge_request(mr_assigned, author) }.not_to change(michael.todos, :count)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#close_merge_request' do
|
||||
it 'marks related pending todos to the target for the user as done' do
|
||||
first_todo = create(:todo, :assigned, user: john_doe, project: project, target: mr_assigned, author: author)
|
||||
second_todo = create(:todo, :assigned, user: john_doe, project: project, target: mr_assigned, author: author)
|
||||
service.close_merge_request(mr_assigned, john_doe)
|
||||
|
||||
expect(first_todo.reload).to be_done
|
||||
expect(second_todo.reload).to be_done
|
||||
end
|
||||
end
|
||||
|
||||
describe '#reassigned_merge_request' do
|
||||
it 'creates a pending todo for new assignee' do
|
||||
mr_unassigned.update_attribute(:assignee, john_doe)
|
||||
service.reassigned_merge_request(mr_unassigned, author)
|
||||
|
||||
should_create_todo(user: john_doe, target: mr_unassigned, action: Todo::ASSIGNED)
|
||||
end
|
||||
|
||||
it 'does not create a todo if unassigned' do
|
||||
mr_assigned.update_attribute(:assignee, nil)
|
||||
|
||||
should_not_create_any_todo { service.reassigned_merge_request(mr_assigned, author) }
|
||||
end
|
||||
|
||||
it 'does not create a todo if new assignee is the current user' do
|
||||
mr_assigned.update_attribute(:assignee, john_doe)
|
||||
|
||||
should_not_create_any_todo { service.reassigned_merge_request(mr_assigned, john_doe) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#merge_merge_request' do
|
||||
it 'marks related pending todos to the target for the user as done' do
|
||||
first_todo = create(:todo, :assigned, user: john_doe, project: project, target: mr_assigned, author: author)
|
||||
second_todo = create(:todo, :assigned, user: john_doe, project: project, target: mr_assigned, author: author)
|
||||
service.merge_merge_request(mr_assigned, john_doe)
|
||||
|
||||
expect(first_todo.reload).to be_done
|
||||
expect(second_todo.reload).to be_done
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def should_create_todo(attributes = {})
|
||||
attributes.reverse_merge!(
|
||||
project: project,
|
||||
author: author,
|
||||
state: :pending
|
||||
)
|
||||
|
||||
expect(Todo.where(attributes).count).to eq 1
|
||||
end
|
||||
|
||||
def should_not_create_todo(attributes = {})
|
||||
attributes.reverse_merge!(
|
||||
project: project,
|
||||
author: author,
|
||||
state: :pending
|
||||
)
|
||||
|
||||
expect(Todo.where(attributes).count).to eq 0
|
||||
end
|
||||
|
||||
def should_not_create_any_todo
|
||||
expect { yield }.not_to change(Todo, :count)
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue