Rename Tasks to Todos
This commit is contained in:
parent
408e010d65
commit
3d52e139b1
|
|
@ -65,7 +65,7 @@ v 8.5.0 (unreleased)
|
||||||
- Fix broken link to project in build notification emails
|
- Fix broken link to project in build notification emails
|
||||||
- Ability to see and sort on vote count from Issues and MR lists
|
- 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
|
- 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
|
- Add API support for managing runners and project's runners
|
||||||
- Allow SAML users to login with no previous account without having to allow
|
- Allow SAML users to login with no previous account without having to allow
|
||||||
all Omniauth providers to do so.
|
all Omniauth providers to do so.
|
||||||
|
|
@ -75,7 +75,7 @@ v 8.5.0 (unreleased)
|
||||||
- Emoji comment on diffs are not award emoji
|
- Emoji comment on diffs are not award emoji
|
||||||
- Add label description (Nuttanart Pornprasitsakul)
|
- Add label description (Nuttanart Pornprasitsakul)
|
||||||
- Show label row when filtering issues or merge requests by label (Nuttanart Pornprasitsakul)
|
- Show label row when filtering issues or merge requests by label (Nuttanart Pornprasitsakul)
|
||||||
- Add Task Queue
|
- Add Todos
|
||||||
|
|
||||||
v 8.4.4
|
v 8.4.4
|
||||||
- Update omniauth-saml gem to 1.4.2
|
- Update omniauth-saml gem to 1.4.2
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,37 @@
|
||||||
/**
|
/**
|
||||||
* Dashboard tasks queue
|
* Dashboard Todos
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.navbar-nav {
|
.navbar-nav {
|
||||||
li {
|
li {
|
||||||
.badge.tasks-pending-count {
|
.badge.todos-pending-count {
|
||||||
background-color: #7f8fa4;
|
background-color: #7f8fa4;
|
||||||
margin-top: -5px;
|
margin-top: -5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tasks {
|
.todos {
|
||||||
.panel {
|
.panel {
|
||||||
border-top: none;
|
border-top: none;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.task-item {
|
.todo-item {
|
||||||
font-size: $gl-font-size;
|
font-size: $gl-font-size;
|
||||||
padding: $gl-padding-top 0 $gl-padding-top ($gl-avatar-size + $gl-padding-top);
|
padding: $gl-padding-top 0 $gl-padding-top ($gl-avatar-size + $gl-padding-top);
|
||||||
border-bottom: 1px solid $table-border-color;
|
border-bottom: 1px solid $table-border-color;
|
||||||
color: #7f8fa4;
|
color: #7f8fa4;
|
||||||
|
|
||||||
&.task-inline {
|
&.todo-inline {
|
||||||
.avatar {
|
.avatar {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: -2px;
|
top: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.task-title {
|
.todo-title {
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +44,7 @@
|
||||||
margin-left: -($gl-avatar-size + $gl-padding-top);
|
margin-left: -($gl-avatar-size + $gl-padding-top);
|
||||||
}
|
}
|
||||||
|
|
||||||
.task-title {
|
.todo-title {
|
||||||
@include str-truncated(calc(100% - 174px));
|
@include str-truncated(calc(100% - 174px));
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
|
||||||
|
|
@ -53,10 +53,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.task-body {
|
.todo-body {
|
||||||
margin-right: 174px;
|
margin-right: 174px;
|
||||||
|
|
||||||
.task-note {
|
.todo-note {
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
|
|
||||||
.md {
|
.md {
|
||||||
|
|
@ -89,7 +89,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.task-note-icon {
|
.todo-note-icon {
|
||||||
color: #777;
|
color: #777;
|
||||||
float: left;
|
float: left;
|
||||||
font-size: $gl-font-size;
|
font-size: $gl-font-size;
|
||||||
|
|
@ -102,10 +102,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: $screen-xs-max) {
|
@media (max-width: $screen-xs-max) {
|
||||||
.task-item {
|
.todo-item {
|
||||||
padding-left: $gl-padding;
|
padding-left: $gl-padding;
|
||||||
|
|
||||||
.task-title {
|
.todo-title {
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|
@ -115,7 +115,7 @@
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.task-body {
|
.todo-body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border-left: 2px solid #DDD;
|
border-left: 2px solid #DDD;
|
||||||
padding-left: 10px;
|
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
|
|
||||||
|
|
@ -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
|
return
|
||||||
end
|
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)
|
@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:
|
# Arguments:
|
||||||
# current_user - which user use
|
# current_user - which user use
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
# type: 'Issue' or 'MergeRequest'
|
# type: 'Issue' or 'MergeRequest'
|
||||||
#
|
#
|
||||||
|
|
||||||
class TasksFinder
|
class TodosFinder
|
||||||
NONE = '0'
|
NONE = '0'
|
||||||
|
|
||||||
attr_accessor :current_user, :params
|
attr_accessor :current_user, :params
|
||||||
|
|
@ -23,7 +23,7 @@ class TasksFinder
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
items = current_user.tasks
|
items = current_user.todos
|
||||||
items = by_action_id(items)
|
items = by_action_id(items)
|
||||||
items = by_author(items)
|
items = by_author(items)
|
||||||
items = by_project(items)
|
items = by_project(items)
|
||||||
|
|
@ -36,7 +36,7 @@ class TasksFinder
|
||||||
private
|
private
|
||||||
|
|
||||||
def action_id?
|
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
|
end
|
||||||
|
|
||||||
def action_id
|
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
|
|
||||||
|
|
@ -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 :author, class_name: "User"
|
||||||
belongs_to :updated_by, 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, to: :project, prefix: true
|
||||||
delegate :name, :email, to: :author, prefix: true
|
delegate :name, :email, to: :author, prefix: true
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# == Schema Information
|
# == Schema Information
|
||||||
#
|
#
|
||||||
# Table name: tasks
|
# Table name: todos
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# user_id :integer not null
|
# user_id :integer not null
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
# updated_at :datetime
|
# updated_at :datetime
|
||||||
#
|
#
|
||||||
|
|
||||||
class Task < ActiveRecord::Base
|
class Todo < ActiveRecord::Base
|
||||||
ASSIGNED = 1
|
ASSIGNED = 1
|
||||||
MENTIONED = 2
|
MENTIONED = 2
|
||||||
|
|
||||||
|
|
@ -140,7 +140,7 @@ class User < ActiveRecord::Base
|
||||||
has_one :abuse_report, dependent: :destroy
|
has_one :abuse_report, dependent: :destroy
|
||||||
has_many :spam_logs, dependent: :destroy
|
has_many :spam_logs, dependent: :destroy
|
||||||
has_many :builds, dependent: :nullify, class_name: 'Ci::Build'
|
has_many :builds, dependent: :nullify, class_name: 'Ci::Build'
|
||||||
has_many :tasks, dependent: :destroy
|
has_many :todos, dependent: :destroy
|
||||||
|
|
||||||
#
|
#
|
||||||
# Validations
|
# Validations
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ class BaseService
|
||||||
EventCreateService.new
|
EventCreateService.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def task_service
|
def todo_service
|
||||||
TaskService.new
|
TodoService.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def log_info(message)
|
def log_info(message)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ module Issues
|
||||||
def execute(issue, commit = nil)
|
def execute(issue, commit = nil)
|
||||||
if project.jira_tracker? && project.jira_service.active
|
if project.jira_tracker? && project.jira_service.active
|
||||||
project.jira_service.execute(commit, issue)
|
project.jira_service.execute(commit, issue)
|
||||||
task_service.close_issue(issue, current_user)
|
todo_service.close_issue(issue, current_user)
|
||||||
return issue
|
return issue
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -11,7 +11,7 @@ module Issues
|
||||||
event_service.close_issue(issue, current_user)
|
event_service.close_issue(issue, current_user)
|
||||||
create_note(issue, commit)
|
create_note(issue, commit)
|
||||||
notification_service.close_issue(issue, current_user)
|
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')
|
execute_hooks(issue, 'close')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ module Issues
|
||||||
if issue.save
|
if issue.save
|
||||||
issue.update_attributes(label_ids: label_params)
|
issue.update_attributes(label_ids: label_params)
|
||||||
notification_service.new_issue(issue, current_user)
|
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)
|
event_service.open_issue(issue, current_user)
|
||||||
issue.create_cross_references!(current_user)
|
issue.create_cross_references!(current_user)
|
||||||
execute_hooks(issue, 'open')
|
execute_hooks(issue, 'open')
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,12 @@ module Issues
|
||||||
|
|
||||||
def handle_changes(issue, options = {})
|
def handle_changes(issue, options = {})
|
||||||
if has_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
|
end
|
||||||
|
|
||||||
if issue.previous_changes.include?('title') ||
|
if issue.previous_changes.include?('title') ||
|
||||||
issue.previous_changes.include?('description')
|
issue.previous_changes.include?('description')
|
||||||
task_service.update_issue(issue, current_user)
|
todo_service.update_issue(issue, current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
if issue.previous_changes.include?('milestone_id')
|
if issue.previous_changes.include?('milestone_id')
|
||||||
|
|
@ -21,7 +21,7 @@ module Issues
|
||||||
if issue.previous_changes.include?('assignee_id')
|
if issue.previous_changes.include?('assignee_id')
|
||||||
create_assignee_note(issue)
|
create_assignee_note(issue)
|
||||||
notification_service.reassigned_issue(issue, current_user)
|
notification_service.reassigned_issue(issue, current_user)
|
||||||
task_service.reassigned_issue(issue, current_user)
|
todo_service.reassigned_issue(issue, current_user)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ module MergeRequests
|
||||||
event_service.close_mr(merge_request, current_user)
|
event_service.close_mr(merge_request, current_user)
|
||||||
create_note(merge_request)
|
create_note(merge_request)
|
||||||
notification_service.close_mr(merge_request, current_user)
|
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')
|
execute_hooks(merge_request, 'close')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ module MergeRequests
|
||||||
merge_request.update_attributes(label_ids: label_params)
|
merge_request.update_attributes(label_ids: label_params)
|
||||||
event_service.open_mr(merge_request, current_user)
|
event_service.open_mr(merge_request, current_user)
|
||||||
notification_service.new_merge_request(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)
|
merge_request.create_cross_references!(current_user)
|
||||||
execute_hooks(merge_request)
|
execute_hooks(merge_request)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,12 @@ module MergeRequests
|
||||||
|
|
||||||
def handle_changes(merge_request, options = {})
|
def handle_changes(merge_request, options = {})
|
||||||
if has_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
|
end
|
||||||
|
|
||||||
if merge_request.previous_changes.include?('title') ||
|
if merge_request.previous_changes.include?('title') ||
|
||||||
merge_request.previous_changes.include?('description')
|
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
|
end
|
||||||
|
|
||||||
if merge_request.previous_changes.include?('target_branch')
|
if merge_request.previous_changes.include?('target_branch')
|
||||||
|
|
@ -37,7 +37,7 @@ module MergeRequests
|
||||||
if merge_request.previous_changes.include?('assignee_id')
|
if merge_request.previous_changes.include?('assignee_id')
|
||||||
create_assignee_note(merge_request)
|
create_assignee_note(merge_request)
|
||||||
notification_service.reassigned_merge_request(merge_request, current_user)
|
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
|
end
|
||||||
|
|
||||||
if merge_request.previous_changes.include?('target_branch') ||
|
if merge_request.previous_changes.include?('target_branch') ||
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ module Notes
|
||||||
if note.save
|
if note.save
|
||||||
# Finish the harder work in the background
|
# Finish the harder work in the background
|
||||||
NewNoteWorker.perform_in(2.seconds, note.id, params)
|
NewNoteWorker.perform_in(2.seconds, note.id, params)
|
||||||
TaskService.new.new_note(note, current_user)
|
TodoService.new.new_note(note, current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ module Notes
|
||||||
note.reset_events_cache
|
note.reset_events_cache
|
||||||
|
|
||||||
if note.previous_changes.include?('note')
|
if note.previous_changes.include?('note')
|
||||||
TaskService.new.update_note(note, current_user)
|
TodoService.new.update_note(note, current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
note
|
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.
|
# 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:
|
# When create an issue we should:
|
||||||
#
|
#
|
||||||
# * create a task for assignee if issue is assigned
|
# * create a todo for assignee if issue is assigned
|
||||||
# * create a task for each mentioned user on issue
|
# * create a todo 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)
|
||||||
|
|
@ -17,32 +17,32 @@ class TaskService
|
||||||
|
|
||||||
# When update an issue we should:
|
# When update an issue we should:
|
||||||
#
|
#
|
||||||
# * mark all pending tasks related to the issue for the current user as done
|
# * mark all pending todos related to the issue for the current user as done
|
||||||
#
|
#
|
||||||
def update_issue(issue, current_user)
|
def update_issue(issue, current_user)
|
||||||
create_mention_tasks(issue.project, issue, current_user)
|
create_mention_todos(issue.project, issue, current_user)
|
||||||
end
|
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 todos related to the target for the current user as done
|
||||||
#
|
#
|
||||||
def close_issue(issue, current_user)
|
def close_issue(issue, current_user)
|
||||||
mark_pending_tasks_as_done(issue, current_user)
|
mark_pending_todos_as_done(issue, current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
# When we reassign an issue we should:
|
# 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)
|
def reassigned_issue(issue, current_user)
|
||||||
create_assignment_task(issue, current_user)
|
create_assignment_todo(issue, current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
# 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 todo for assignee if merge request is assigned
|
||||||
# * create a task for each mentioned user on merge request
|
# * create a todo 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)
|
||||||
|
|
@ -50,40 +50,40 @@ class TaskService
|
||||||
|
|
||||||
# When update a merge request we should:
|
# 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)
|
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
|
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 todos related to the target for the current user as done
|
||||||
#
|
#
|
||||||
def close_merge_request(merge_request, current_user)
|
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
|
end
|
||||||
|
|
||||||
# When we reassign a merge request we should:
|
# 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)
|
def reassigned_merge_request(merge_request, current_user)
|
||||||
create_assignment_task(merge_request, current_user)
|
create_assignment_todo(merge_request, current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
# When merge a merge request we should:
|
# 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)
|
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
|
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 todos related to the noteable for the note author as done
|
||||||
# * create a task for each mentioned user on note
|
# * create a todo for each mentioned user on note
|
||||||
#
|
#
|
||||||
def new_note(note, current_user)
|
def new_note(note, current_user)
|
||||||
handle_note(note, current_user)
|
handle_note(note, current_user)
|
||||||
|
|
@ -91,28 +91,28 @@ 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 todos related to the noteable for the current user as done
|
||||||
# * create a task for each new user mentioned on note
|
# * create a todo for each new user mentioned on note
|
||||||
#
|
#
|
||||||
def update_note(note, current_user)
|
def update_note(note, current_user)
|
||||||
handle_note(note, current_user)
|
handle_note(note, current_user)
|
||||||
end
|
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)
|
def mark_pending_todos_as_done(target, user)
|
||||||
pending_tasks(user, target.project, target).update_all(state: :done)
|
pending_todos(user, target.project, target).update_all(state: :done)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
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|
|
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,
|
project: project,
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
author_id: author.id,
|
author_id: author.id,
|
||||||
|
|
@ -125,8 +125,8 @@ class TaskService
|
||||||
end
|
end
|
||||||
|
|
||||||
def new_issuable(issuable, author)
|
def new_issuable(issuable, author)
|
||||||
create_assignment_task(issuable, author)
|
create_assignment_todo(issuable, author)
|
||||||
create_mention_tasks(issuable.project, issuable, author)
|
create_mention_todos(issuable.project, issuable, author)
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_note(note, author)
|
def handle_note(note, author)
|
||||||
|
|
@ -136,19 +136,19 @@ class TaskService
|
||||||
project = note.project
|
project = note.project
|
||||||
target = note.noteable
|
target = note.noteable
|
||||||
|
|
||||||
mark_pending_tasks_as_done(target, author)
|
mark_pending_todos_as_done(target, author)
|
||||||
create_mention_tasks(project, target, author, note)
|
create_mention_todos(project, target, author, note)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_assignment_task(issuable, author)
|
def create_assignment_todo(issuable, author)
|
||||||
if issuable.assignee && issuable.assignee != 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
|
||||||
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)
|
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
|
end
|
||||||
|
|
||||||
def filter_mentioned_users(project, target, author)
|
def filter_mentioned_users(project, target, author)
|
||||||
|
|
@ -160,8 +160,8 @@ class TaskService
|
||||||
mentioned_users.uniq
|
mentioned_users.uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
def pending_tasks(user, project, target)
|
def pending_todos(user, project, target)
|
||||||
user.tasks.pending.where(
|
user.todos.pending.where(
|
||||||
project_id: project.id,
|
project_id: project.id,
|
||||||
target_id: target.id,
|
target_id: target.id,
|
||||||
target_type: target.class.name
|
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)
|
|
||||||
|
|
@ -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"
|
- page_title "Todos"
|
||||||
- header_title "Tasks", dashboard_tasks_path
|
- header_title "Todos", dashboard_todos_path
|
||||||
|
|
||||||
.top-area
|
.top-area
|
||||||
%ul.nav-links
|
%ul.nav-links
|
||||||
%li{class: ('active' if params[:state].blank? || params[:state] == 'pending')}
|
%li{class: ('active' if params[:state].blank? || params[:state] == 'pending')}
|
||||||
= link_to page_filter_path(state: 'pending') do
|
= link_to page_filter_path(state: 'pending') do
|
||||||
%span
|
%span
|
||||||
Tasks
|
Todos
|
||||||
%span{class: 'badge'}
|
%span{class: 'badge'}
|
||||||
= tasks_pending_count
|
= todos_pending_count
|
||||||
%li{class: ('active' if params[:state] == 'done')}
|
%li{class: ('active' if params[:state] == 'done')}
|
||||||
= link_to page_filter_path(state: 'done') do
|
= link_to page_filter_path(state: 'done') do
|
||||||
%span
|
%span
|
||||||
Done
|
Done
|
||||||
%span{class: 'badge'}
|
%span{class: 'badge'}
|
||||||
= tasks_done_count
|
= todos_done_count
|
||||||
|
|
||||||
.tasks-filters
|
.todos-filters
|
||||||
.gray-content-block.second-block
|
.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
|
= form_tag page_filter_path(without: [:assignee_id, :milestone_title, :label_name, :scope, :sort]), method: :get, class: 'filter-form' do
|
||||||
.filter-item.inline
|
.filter-item.inline
|
||||||
= select_tag('project_id', task_projects_options,
|
= select_tag('project_id', todo_projects_options,
|
||||||
class: 'select2 trigger-submit', include_blank: true,
|
class: 'select2 trigger-submit', include_blank: true,
|
||||||
data: {placeholder: 'Project'})
|
data: {placeholder: 'Project'})
|
||||||
.filter-item.inline
|
.filter-item.inline
|
||||||
= users_select_tag(:author_id, selected: params[:author_id],
|
= users_select_tag(:author_id, selected: params[:author_id],
|
||||||
placeholder: 'Author', class: 'trigger-submit', any_user: "Any Author", first_user: true, current_user: true)
|
placeholder: 'Author', class: 'trigger-submit', any_user: "Any Author", first_user: true, current_user: true)
|
||||||
.filter-item.inline
|
.filter-item.inline
|
||||||
= select_tag('type', task_types_options,
|
= select_tag('type', todo_types_options,
|
||||||
class: 'select2 trigger-submit', include_blank: true,
|
class: 'select2 trigger-submit', include_blank: true,
|
||||||
data: {placeholder: 'Type'})
|
data: {placeholder: 'Type'})
|
||||||
.filter-item.inline.actions-filter
|
.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,
|
class: 'select2 trigger-submit', include_blank: true,
|
||||||
data: {placeholder: 'Action'})
|
data: {placeholder: 'Action'})
|
||||||
|
|
||||||
.prepend-top-default
|
.prepend-top-default
|
||||||
- if @tasks.any?
|
- if @todos.any?
|
||||||
- @tasks.group_by(&:project).each do |group|
|
- @todos.group_by(&:project).each do |group|
|
||||||
.panel.panel-default.panel-small
|
.panel.panel-default.panel-small
|
||||||
- project = group[0]
|
- project = group[0]
|
||||||
.panel-heading
|
.panel-heading
|
||||||
= link_to project.name_with_namespace, namespace_project_path(project.namespace, project)
|
= 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]
|
= render group[1]
|
||||||
= paginate @tasks, theme: "gitlab"
|
= paginate @todos, theme: "gitlab"
|
||||||
- else
|
- else
|
||||||
.nothing-here-block No tasks to show
|
.nothing-here-block No todos to show
|
||||||
|
|
||||||
:javascript
|
:javascript
|
||||||
new UsersSelect();
|
new UsersSelect();
|
||||||
|
|
@ -22,9 +22,9 @@
|
||||||
= link_to admin_root_path, title: 'Admin Area', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
|
= link_to admin_root_path, title: 'Admin Area', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
|
||||||
= icon('wrench fw')
|
= icon('wrench fw')
|
||||||
%li
|
%li
|
||||||
= link_to dashboard_tasks_path, title: 'Tasks', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
|
= link_to dashboard_todos_path, title: 'Todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
|
||||||
%span.badge.tasks-pending-count
|
%span.badge.todos-pending-count
|
||||||
= tasks_pending_count
|
= todos_pending_count
|
||||||
- if current_user.can_create_project?
|
- if current_user.can_create_project?
|
||||||
%li
|
%li
|
||||||
= link_to new_project_path, title: 'New project', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
|
= link_to new_project_path, title: 'New project', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,12 @@
|
||||||
= icon('home fw')
|
= icon('home fw')
|
||||||
%span
|
%span
|
||||||
Projects
|
Projects
|
||||||
= nav_link(controller: :tasks) do
|
= nav_link(controller: :todos) do
|
||||||
= link_to dashboard_tasks_path, title: 'Tasks' do
|
= link_to dashboard_todos_path, title: 'Todos' do
|
||||||
= icon('bell fw')
|
= icon('bell fw')
|
||||||
%span
|
%span
|
||||||
Tasks
|
Todos
|
||||||
%span.count= number_with_delimiter(tasks_pending_count)
|
%span.count= number_with_delimiter(todos_pending_count)
|
||||||
= nav_link(path: 'dashboard#activity') do
|
= nav_link(path: 'dashboard#activity') do
|
||||||
= link_to activity_dashboard_path, class: 'shortcuts-activity', title: 'Activity' do
|
= link_to activity_dashboard_path, class: 'shortcuts-activity', title: 'Activity' do
|
||||||
= icon('dashboard fw')
|
= icon('dashboard fw')
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,7 @@ Rails.application.routes.draw do
|
||||||
|
|
||||||
resources :groups, only: [:index]
|
resources :groups, only: [:index]
|
||||||
resources :snippets, only: [:index]
|
resources :snippets, only: [:index]
|
||||||
resources :tasks, only: [:index, :destroy]
|
resources :todos, only: [:index, :destroy]
|
||||||
|
|
||||||
resources :projects, only: [:index] do
|
resources :projects, only: [:index] do
|
||||||
collection do
|
collection do
|
||||||
|
|
|
||||||
|
|
@ -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.
|
# 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
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
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
|
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 "user_id", null: false
|
||||||
t.integer "project_id", null: false
|
t.integer "project_id", null: false
|
||||||
t.integer "target_id", null: false
|
t.integer "target_id", null: false
|
||||||
|
|
@ -837,12 +837,12 @@ ActiveRecord::Schema.define(version: 20160217174422) do
|
||||||
t.integer "note_id"
|
t.integer "note_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "tasks", ["author_id"], name: "index_tasks_on_author_id", using: :btree
|
add_index "todos", ["author_id"], name: "index_todos_on_author_id", using: :btree
|
||||||
add_index "tasks", ["note_id"], name: "index_tasks_on_note_id", using: :btree
|
add_index "todos", ["note_id"], name: "index_todos_on_note_id", using: :btree
|
||||||
add_index "tasks", ["project_id"], name: "index_tasks_on_project_id", using: :btree
|
add_index "todos", ["project_id"], name: "index_todos_on_project_id", using: :btree
|
||||||
add_index "tasks", ["state"], name: "index_tasks_on_state", using: :btree
|
add_index "todos", ["state"], name: "index_todos_on_state", using: :btree
|
||||||
add_index "tasks", ["target_type", "target_id"], name: "index_tasks_on_target_type_and_target_id", using: :btree
|
add_index "todos", ["target_type", "target_id"], name: "index_todos_on_target_type_and_target_id", using: :btree
|
||||||
add_index "tasks", ["user_id"], name: "index_tasks_on_user_id", using: :btree
|
add_index "todos", ["user_id"], name: "index_todos_on_user_id", using: :btree
|
||||||
|
|
||||||
create_table "users", force: :cascade do |t|
|
create_table "users", force: :cascade do |t|
|
||||||
t.string "email", default: "", null: false
|
t.string "email", default: "", null: false
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
@dashboard
|
@dashboard
|
||||||
Feature: Dashboard Tasks
|
Feature: Dashboard Todos
|
||||||
Background:
|
Background:
|
||||||
Given I sign in as a user
|
Given I sign in as a user
|
||||||
And I own project "Shop"
|
And I own project "Shop"
|
||||||
|
|
@ -7,32 +7,32 @@ Feature: Dashboard Tasks
|
||||||
And "Mary Jane" is a developer of project "Shop"
|
And "Mary Jane" is a developer of project "Shop"
|
||||||
And "Mary Jane" owns private project "Enterprise"
|
And "Mary Jane" owns private project "Enterprise"
|
||||||
And I am a developer of project "Enterprise"
|
And I am a developer of project "Enterprise"
|
||||||
And I have pending tasks
|
And I have todos
|
||||||
And I visit dashboard task queue page
|
And I visit dashboard todos page
|
||||||
|
|
||||||
@javascript
|
@javascript
|
||||||
Scenario: I mark pending tasks as done
|
Scenario: I mark todos as done
|
||||||
Then I should see pending tasks assigned to me
|
Then I should see todos assigned to me
|
||||||
And I mark the pending task as done
|
And I mark the todo as done
|
||||||
And I click on the "Done" tab
|
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
|
@javascript
|
||||||
Scenario: I filter by project
|
Scenario: I filter by project
|
||||||
Given I filter by "Enterprise"
|
Given I filter by "Enterprise"
|
||||||
Then I should not see tasks
|
Then I should not see todos
|
||||||
|
|
||||||
@javascript
|
@javascript
|
||||||
Scenario: I filter by author
|
Scenario: I filter by author
|
||||||
Given I filter by "John Doe"
|
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
|
@javascript
|
||||||
Scenario: I filter by type
|
Scenario: I filter by type
|
||||||
Given I filter by "Issue"
|
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
|
@javascript
|
||||||
Scenario: I filter by action
|
Scenario: I filter by action
|
||||||
Given I filter by "Mentioned"
|
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 SharedAuthentication
|
||||||
include SharedPaths
|
include SharedPaths
|
||||||
include SharedProject
|
include SharedProject
|
||||||
|
|
@ -17,43 +17,43 @@ class Spinach::Features::DashboardTasks < Spinach::FeatureSteps
|
||||||
project.team << [john_doe, :developer]
|
project.team << [john_doe, :developer]
|
||||||
end
|
end
|
||||||
|
|
||||||
step 'I have pending tasks' do
|
step 'I have todos' do
|
||||||
create(:task, user: current_user, project: project, author: mary_jane, target: issue, action: Task::MENTIONED)
|
create(:todo, user: current_user, project: project, author: mary_jane, target: issue, action: Todo::MENTIONED)
|
||||||
create(:task, user: current_user, project: project, author: john_doe, target: issue, action: Task::ASSIGNED)
|
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?")
|
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(:todo, user: current_user, project: project, author: john_doe, target: issue, action: Todo::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: merge_request, action: Todo::ASSIGNED)
|
||||||
end
|
end
|
||||||
|
|
||||||
step 'I should see pending tasks assigned to me' do
|
step 'I should see todos assigned to me' do
|
||||||
expect(page).to have_content 'Tasks 4'
|
expect(page).to have_content 'Todos 4'
|
||||||
expect(page).to have_content 'Done 0'
|
expect(page).to have_content 'Done 0'
|
||||||
|
|
||||||
expect(page).to have_link project.name_with_namespace
|
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_todo(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_todo(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_todo(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(4, "Mary Jane mentioned you on issue ##{issue.iid}", issue.title)
|
||||||
end
|
end
|
||||||
|
|
||||||
step 'I mark the pending task as done' do
|
step 'I mark the todo as done' do
|
||||||
page.within('.task:nth-child(1)') do
|
page.within('.todo:nth-child(1)') do
|
||||||
click_link 'Done'
|
click_link 'Done'
|
||||||
end
|
end
|
||||||
|
|
||||||
expect(page).to have_content 'Task was successfully marked as done.'
|
expect(page).to have_content 'Todo was successfully marked as done.'
|
||||||
expect(page).to have_content 'Tasks 3'
|
expect(page).to have_content 'Todos 3'
|
||||||
expect(page).to have_content 'Done 1'
|
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
|
end
|
||||||
|
|
||||||
step 'I click on the "Done" tab' do
|
step 'I click on the "Done" tab' do
|
||||||
click_link 'Done 1'
|
click_link 'Done 1'
|
||||||
end
|
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
|
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
|
end
|
||||||
|
|
||||||
step 'I filter by "Enterprise"' do
|
step 'I filter by "Enterprise"' do
|
||||||
|
|
@ -69,28 +69,28 @@ class Spinach::Features::DashboardTasks < Spinach::FeatureSteps
|
||||||
end
|
end
|
||||||
|
|
||||||
step 'I filter by "Mentioned"' do
|
step 'I filter by "Mentioned"' do
|
||||||
select2("#{Task::MENTIONED}", from: '#action_id')
|
select2("#{Todo::MENTIONED}", from: '#action_id')
|
||||||
end
|
end
|
||||||
|
|
||||||
step 'I should not see tasks' do
|
step 'I should not see todos' do
|
||||||
expect(page).to have_content 'No tasks to show'
|
expect(page).to have_content 'No todos to show'
|
||||||
end
|
end
|
||||||
|
|
||||||
step 'I should not see tasks related to "Mary Jane" in the list' do
|
step 'I should not see todos related to "Mary Jane" in the list' do
|
||||||
should_not_see_task "Mary Jane mentioned you on issue ##{issue.iid}"
|
should_not_see_todo "Mary Jane mentioned you on issue ##{issue.iid}"
|
||||||
end
|
end
|
||||||
|
|
||||||
step 'I should not see tasks related to "Merge Requests" in the list' do
|
step 'I should not see todos related to "Merge Requests" in the list' do
|
||||||
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
|
end
|
||||||
|
|
||||||
step 'I should not see tasks related to "Assignments" in the list' do
|
step 'I should not see todos related to "Assignments" in the list' do
|
||||||
should_not_see_task "John Doe assigned merge request ##{merge_request.iid}"
|
should_not_see_todo "John Doe assigned merge request ##{merge_request.iid}"
|
||||||
should_not_see_task "John Doe assigned issue ##{issue.iid}"
|
should_not_see_todo "John Doe assigned issue ##{issue.iid}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def should_see_task(position, title, body, pending = true)
|
def should_see_todo(position, title, body, pending = true)
|
||||||
page.within(".task:nth-child(#{position})") do
|
page.within(".todo:nth-child(#{position})") do
|
||||||
expect(page).to have_content title
|
expect(page).to have_content title
|
||||||
expect(page).to have_content body
|
expect(page).to have_content body
|
||||||
|
|
||||||
|
|
@ -102,7 +102,7 @@ class Spinach::Features::DashboardTasks < Spinach::FeatureSteps
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def should_not_see_task(title)
|
def should_not_see_todo(title)
|
||||||
expect(page).not_to have_content title
|
expect(page).not_to have_content title
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -103,8 +103,8 @@ module SharedPaths
|
||||||
visit dashboard_groups_path
|
visit dashboard_groups_path
|
||||||
end
|
end
|
||||||
|
|
||||||
step 'I visit dashboard task queue page' do
|
step 'I visit dashboard todos page' do
|
||||||
visit dashboard_tasks_path
|
visit dashboard_todos_path
|
||||||
end
|
end
|
||||||
|
|
||||||
step 'I should be redirected to the dashboard groups page' do
|
step 'I should be redirected to the dashboard groups page' do
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# == Schema Information
|
# == Schema Information
|
||||||
#
|
#
|
||||||
# Table name: tasks
|
# Table name: todos
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# user_id :integer not null
|
# user_id :integer not null
|
||||||
|
|
@ -16,19 +16,19 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
FactoryGirl.define do
|
FactoryGirl.define do
|
||||||
factory :task do
|
factory :todo do
|
||||||
project
|
project
|
||||||
author
|
author
|
||||||
user
|
user
|
||||||
target factory: :issue
|
target factory: :issue
|
||||||
action { Task::ASSIGNED }
|
action { Todo::ASSIGNED }
|
||||||
|
|
||||||
trait :assigned do
|
trait :assigned do
|
||||||
action { Task::ASSIGNED }
|
action { Todo::ASSIGNED }
|
||||||
end
|
end
|
||||||
|
|
||||||
trait :mentioned do
|
trait :mentioned do
|
||||||
action { Task::MENTIONED }
|
action { Todo::MENTIONED }
|
||||||
end
|
end
|
||||||
end
|
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(:noteable) }
|
||||||
it { is_expected.to belong_to(:author).class_name('User') }
|
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
|
end
|
||||||
|
|
||||||
describe 'validation' do
|
describe 'validation' do
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# == Schema Information
|
# == Schema Information
|
||||||
#
|
#
|
||||||
# Table name: tasks
|
# Table name: todos
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# user_id :integer not null
|
# user_id :integer not null
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Task, models: true do
|
describe Todo, models: true do
|
||||||
describe 'relationships' do
|
describe 'relationships' do
|
||||||
it { is_expected.to belong_to(:author).class_name("User") }
|
it { is_expected.to belong_to(:author).class_name("User") }
|
||||||
it { is_expected.to belong_to(:note) }
|
it { is_expected.to belong_to(:note) }
|
||||||
|
|
@ -39,13 +39,13 @@ describe Task, models: true do
|
||||||
|
|
||||||
describe '#action_name' do
|
describe '#action_name' do
|
||||||
it 'returns proper message when action is an assigment' 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'
|
expect(subject.action_name).to eq 'assigned'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns proper message when action is a mention' do
|
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'
|
expect(subject.action_name).to eq 'mentioned you on'
|
||||||
end
|
end
|
||||||
|
|
@ -92,7 +92,7 @@ describe User, models: true do
|
||||||
it { is_expected.to have_many(:identities).dependent(:destroy) }
|
it { is_expected.to have_many(:identities).dependent(:destroy) }
|
||||||
it { is_expected.to have_one(:abuse_report) }
|
it { is_expected.to have_one(:abuse_report) }
|
||||||
it { is_expected.to have_many(:spam_logs).dependent(:destroy) }
|
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
|
end
|
||||||
|
|
||||||
describe 'validations' do
|
describe 'validations' do
|
||||||
|
|
|
||||||
|
|
@ -5,7 +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) { 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
|
before do
|
||||||
project.team << [user, :master]
|
project.team << [user, :master]
|
||||||
|
|
@ -34,8 +34,8 @@ describe Issues::CloseService, services: true do
|
||||||
expect(note.note).to include "Status changed to closed"
|
expect(note.note).to include "Status changed to closed"
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'marks pending tasks as done' do
|
it 'marks todos as done' do
|
||||||
expect(pending_task.reload).to be_done
|
expect(todo.reload).to be_done
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -47,7 +47,7 @@ describe Issues::CloseService, services: true do
|
||||||
|
|
||||||
it { expect(@issue).to be_valid }
|
it { expect(@issue).to be_valid }
|
||||||
it { expect(@issue).to be_opened }
|
it { expect(@issue).to be_opened }
|
||||||
it { expect(pending_task.reload).to be_pending }
|
it { expect(todo.reload).to be_pending }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -24,17 +24,18 @@ describe Issues::CreateService, services: true do
|
||||||
it { expect(@issue.title).to eq('Awesome issue') }
|
it { expect(@issue.title).to eq('Awesome issue') }
|
||||||
it { expect(@issue.assignee).to eq assignee }
|
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 = {
|
attributes = {
|
||||||
project: project,
|
project: project,
|
||||||
author: user,
|
author: user,
|
||||||
user: assignee,
|
user: assignee,
|
||||||
target: @issue,
|
target_id: @issue.id,
|
||||||
action: Task::ASSIGNED,
|
target_type: @issue.class.name,
|
||||||
|
action: Todo::ASSIGNED,
|
||||||
state: :pending
|
state: :pending
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(Task.where(attributes).count).to eq 1
|
expect(Todo.where(attributes).count).to eq 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -80,16 +80,16 @@ describe Issues::UpdateService, services: true do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'task queue' do
|
context 'todos' do
|
||||||
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) }
|
||||||
|
|
||||||
context 'when the title change' do
|
context 'when the title change' do
|
||||||
before do
|
before do
|
||||||
update_issue({ title: 'New title' })
|
update_issue({ title: 'New title' })
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'marks pending tasks as done' do
|
it 'marks pending todos as done' do
|
||||||
expect(pending_task.reload.done?).to eq true
|
expect(todo.reload.done?).to eq true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -98,8 +98,8 @@ describe Issues::UpdateService, services: true do
|
||||||
update_issue({ description: 'Also please fix' })
|
update_issue({ description: 'Also please fix' })
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'marks pending tasks as done' do
|
it 'marks todos as done' do
|
||||||
expect(pending_task.reload.done?).to eq true
|
expect(todo.reload.done?).to eq true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -108,21 +108,22 @@ describe Issues::UpdateService, services: true do
|
||||||
update_issue({ assignee: user2 })
|
update_issue({ assignee: user2 })
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'marks previous assignee pending tasks as done' do
|
it 'marks previous assignee todos as done' do
|
||||||
expect(pending_task.reload.done?).to eq true
|
expect(todo.reload.done?).to eq true
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates a pending task for new assignee' do
|
it 'creates a todo for new assignee' do
|
||||||
attributes = {
|
attributes = {
|
||||||
project: project,
|
project: project,
|
||||||
author: user,
|
author: user,
|
||||||
user: user2,
|
user: user2,
|
||||||
target: issue,
|
target_id: issue.id,
|
||||||
action: Task::ASSIGNED,
|
target_type: issue.class.name,
|
||||||
|
action: Todo::ASSIGNED,
|
||||||
state: :pending
|
state: :pending
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(Task.where(attributes).count).to eq 1
|
expect(Todo.where(attributes).count).to eq 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -131,8 +132,8 @@ describe Issues::UpdateService, services: true do
|
||||||
update_issue({ milestone: create(:milestone) })
|
update_issue({ milestone: create(:milestone) })
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'marks pending tasks as done' do
|
it 'marks todos as done' do
|
||||||
expect(pending_task.reload.done?).to eq true
|
expect(todo.reload.done?).to eq true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -141,8 +142,8 @@ describe Issues::UpdateService, services: true do
|
||||||
update_issue({ label_ids: [label.id] })
|
update_issue({ label_ids: [label.id] })
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'marks pending tasks as done' do
|
it 'marks todos as done' do
|
||||||
expect(pending_task.reload.done?).to eq true
|
expect(todo.reload.done?).to eq true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -5,7 +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) { 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
|
before do
|
||||||
project.team << [user, :master]
|
project.team << [user, :master]
|
||||||
|
|
@ -43,8 +43,8 @@ describe MergeRequests::CloseService, services: true do
|
||||||
expect(note.note).to include 'Status changed to closed'
|
expect(note.note).to include 'Status changed to closed'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'marks pending tasks as done' do
|
it 'marks todos as done' do
|
||||||
expect(pending_task.reload).to be_done
|
expect(todo.reload).to be_done
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,14 @@ describe MergeRequests::CreateService, services: true do
|
||||||
expect(service).to have_received(:execute_hooks).with(@merge_request)
|
expect(service).to have_received(:execute_hooks).with(@merge_request)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not creates a pending task' do
|
it 'does not creates todos' do
|
||||||
attributes = {
|
attributes = {
|
||||||
project: project,
|
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
|
end
|
||||||
|
|
||||||
context 'when merge request is assigned to someone' do
|
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 { 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 = {
|
attributes = {
|
||||||
project: project,
|
project: project,
|
||||||
author: user,
|
author: user,
|
||||||
user: assignee,
|
user: assignee,
|
||||||
target: @merge_request,
|
target_id: @merge_request.id,
|
||||||
action: Task::ASSIGNED,
|
target_type: @merge_request.class.name,
|
||||||
|
action: Todo::ASSIGNED,
|
||||||
state: :pending
|
state: :pending
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(Task.where(attributes).count).to eq 1
|
expect(Todo.where(attributes).count).to eq 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -98,16 +98,16 @@ describe MergeRequests::UpdateService, services: true do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'task queue' do
|
context 'todos' do
|
||||||
let!(:pending_task) { create(:task, :assigned, user: user, project: project, target: merge_request, author: user2) }
|
let!(:pending_todo) { create(:todo, :assigned, user: user, project: project, target: merge_request, author: user2) }
|
||||||
|
|
||||||
context 'when the title change' do
|
context 'when the title change' do
|
||||||
before do
|
before do
|
||||||
update_merge_request({ title: 'New title' })
|
update_merge_request({ title: 'New title' })
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'marks pending tasks as done' do
|
it 'marks pending todos as done' do
|
||||||
expect(pending_task.reload).to be_done
|
expect(pending_todo.reload).to be_done
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -116,8 +116,8 @@ describe MergeRequests::UpdateService, services: true do
|
||||||
update_merge_request({ description: 'Also please fix' })
|
update_merge_request({ description: 'Also please fix' })
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'marks pending tasks as done' do
|
it 'marks pending todos as done' do
|
||||||
expect(pending_task.reload).to be_done
|
expect(pending_todo.reload).to be_done
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -126,21 +126,22 @@ describe MergeRequests::UpdateService, services: true do
|
||||||
update_merge_request({ assignee: user2 })
|
update_merge_request({ assignee: user2 })
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'marks previous assignee pending tasks as done' do
|
it 'marks previous assignee pending todos as done' do
|
||||||
expect(pending_task.reload).to be_done
|
expect(pending_todo.reload).to be_done
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates a pending task for new assignee' do
|
it 'creates a pending todo for new assignee' do
|
||||||
attributes = {
|
attributes = {
|
||||||
project: project,
|
project: project,
|
||||||
author: user,
|
author: user,
|
||||||
user: user2,
|
user: user2,
|
||||||
target: merge_request,
|
target_id: merge_request.id,
|
||||||
action: Task::ASSIGNED,
|
target_type: merge_request.class.name,
|
||||||
|
action: Todo::ASSIGNED,
|
||||||
state: :pending
|
state: :pending
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(Task.where(attributes).count).to eq 1
|
expect(Todo.where(attributes).count).to eq 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -149,8 +150,8 @@ describe MergeRequests::UpdateService, services: true do
|
||||||
update_merge_request({ milestone: create(:milestone) })
|
update_merge_request({ milestone: create(:milestone) })
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'marks pending tasks as done' do
|
it 'marks pending todos as done' do
|
||||||
expect(pending_task.reload).to be_done
|
expect(pending_todo.reload).to be_done
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -159,8 +160,8 @@ describe MergeRequests::UpdateService, services: true do
|
||||||
update_merge_request({ label_ids: [label.id] })
|
update_merge_request({ label_ids: [label.id] })
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'marks pending tasks as done' do
|
it 'marks pending todos as done' do
|
||||||
expect(pending_task.reload).to be_done
|
expect(pending_todo.reload).to be_done
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -169,8 +170,8 @@ describe MergeRequests::UpdateService, services: true do
|
||||||
update_merge_request({ target_branch: 'target' })
|
update_merge_request({ target_branch: 'target' })
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'marks pending tasks as done' do
|
it 'marks pending todos as done' do
|
||||||
expect(pending_task.reload).to be_done
|
expect(pending_todo.reload).to be_done
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -18,16 +18,16 @@ describe Notes::UpdateService, services: true do
|
||||||
@note.reload
|
@note.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'task queue' do
|
context 'todos' do
|
||||||
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) }
|
||||||
|
|
||||||
context 'when the note change' do
|
context 'when the note change' do
|
||||||
before do
|
before do
|
||||||
update_note({ note: 'New note' })
|
update_note({ note: 'New note' })
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'marks pending tasks as done' do
|
it 'marks todos as done' do
|
||||||
expect(pending_task.reload).to be_done
|
expect(todo.reload).to be_done
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -36,8 +36,8 @@ describe Notes::UpdateService, services: true do
|
||||||
update_note({ note: 'Old note' })
|
update_note({ note: 'Old note' })
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'keep pending tasks' do
|
it 'keep todos' do
|
||||||
expect(pending_task.reload).to be_pending
|
expect(todo.reload).to be_pending
|
||||||
end
|
end
|
||||||
end
|
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
|
|
||||||
|
|
@ -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 New Issue