Rename Tasks to Todos

This commit is contained in:
Douglas Barbosa Alexandre 2016-02-20 11:59:59 -02:00
parent 408e010d65
commit 3d52e139b1
45 changed files with 604 additions and 602 deletions

View file

@ -65,7 +65,7 @@ v 8.5.0 (unreleased)
- Fix broken link to project in build notification emails
- Ability to see and sort on vote count from Issues and MR lists
- Fix builds scheduler when first build in stage was allowed to fail
- User project limit is reached notice is hidden if the projects limit is zero
- User project limit is reached notice is hidden if the projects limit is zero
- Add API support for managing runners and project's runners
- Allow SAML users to login with no previous account without having to allow
all Omniauth providers to do so.
@ -75,7 +75,7 @@ v 8.5.0 (unreleased)
- Emoji comment on diffs are not award emoji
- Add label description (Nuttanart Pornprasitsakul)
- Show label row when filtering issues or merge requests by label (Nuttanart Pornprasitsakul)
- Add Task Queue
- Add Todos
v 8.4.4
- Update omniauth-saml gem to 1.4.2

View file

@ -1,37 +1,37 @@
/**
* Dashboard tasks queue
* Dashboard Todos
*
*/
.navbar-nav {
li {
.badge.tasks-pending-count {
.badge.todos-pending-count {
background-color: #7f8fa4;
margin-top: -5px;
}
}
}
.tasks {
.todos {
.panel {
border-top: none;
margin-bottom: 0;
}
}
.task-item {
.todo-item {
font-size: $gl-font-size;
padding: $gl-padding-top 0 $gl-padding-top ($gl-avatar-size + $gl-padding-top);
border-bottom: 1px solid $table-border-color;
color: #7f8fa4;
&.task-inline {
&.todo-inline {
.avatar {
position: relative;
top: -2px;
}
.task-title {
.todo-title {
line-height: 40px;
}
}
@ -44,7 +44,7 @@
margin-left: -($gl-avatar-size + $gl-padding-top);
}
.task-title {
.todo-title {
@include str-truncated(calc(100% - 174px));
font-weight: 600;
@ -53,10 +53,10 @@
}
}
.task-body {
.todo-body {
margin-right: 174px;
.task-note {
.todo-note {
word-wrap: break-word;
.md {
@ -89,7 +89,7 @@
}
}
.task-note-icon {
.todo-note-icon {
color: #777;
float: left;
font-size: $gl-font-size;
@ -102,10 +102,10 @@
}
@media (max-width: $screen-xs-max) {
.task-item {
.todo-item {
padding-left: $gl-padding;
.task-title {
.todo-title {
white-space: normal;
overflow: visible;
max-width: 100%;
@ -115,7 +115,7 @@
display: none;
}
.task-body {
.todo-body {
margin: 0;
border-left: 2px solid #DDD;
padding-left: 10px;

View file

@ -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

View file

@ -0,0 +1,23 @@
class Dashboard::TodosController < Dashboard::ApplicationController
def index
@todos = TodosFinder.new(current_user, params).execute
@todos = @todos.page(params[:page]).per(PER_PAGE)
end
def destroy
todo.done!
respond_to do |format|
format.html { redirect_to dashboard_todos_path, notice: 'Todo was successfully marked as done.' }
format.js { render nothing: true }
end
end
private
def todo
@todo ||= current_user.todos.find(params[:id])
end
end

View file

@ -181,7 +181,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
return
end
TaskService.new.merge_merge_request(merge_request, current_user)
TodoService.new.merge_merge_request(merge_request, current_user)
@merge_request.update(merge_error: nil)

View file

@ -1,6 +1,6 @@
# TasksFinder
# TodosFinder
#
# Used to filter Tasks by set of params
# Used to filter Todos by set of params
#
# Arguments:
# current_user - which user use
@ -12,7 +12,7 @@
# type: 'Issue' or 'MergeRequest'
#
class TasksFinder
class TodosFinder
NONE = '0'
attr_accessor :current_user, :params
@ -23,7 +23,7 @@ class TasksFinder
end
def execute
items = current_user.tasks
items = current_user.todos
items = by_action_id(items)
items = by_author(items)
items = by_project(items)
@ -36,7 +36,7 @@ class TasksFinder
private
def action_id?
action_id.present? && [Task::ASSIGNED, Task::MENTIONED].include?(action_id.to_i)
action_id.present? && [Todo::ASSIGNED, Todo::MENTIONED].include?(action_id.to_i)
end
def action_id

View file

@ -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

View file

@ -0,0 +1,59 @@
module TodosHelper
def todos_pending_count
current_user.todos.pending.count
end
def todos_done_count
current_user.todos.done.count
end
def todo_action_name(todo)
target = todo.target_type.titleize.downcase
[todo.action_name, target].join(" ")
end
def todo_target_link_html(todo)
link_to "##{todo.target_iid}", todo_target_path(todo)
end
def todo_target_path(todo)
anchor = dom_id(todo.note) if todo.note.present?
polymorphic_path([todo.project.namespace.becomes(Namespace),
todo.project, todo.target], anchor: anchor)
end
def todo_actions_options
actions = [
OpenStruct.new(id: '', title: 'Any Action'),
OpenStruct.new(id: Todo::ASSIGNED, title: 'Assigned'),
OpenStruct.new(id: Todo::MENTIONED, title: 'Mentioned')
]
options_from_collection_for_select(actions, 'id', 'title', params[:action_id])
end
def todo_projects_options
projects = current_user.authorized_projects.sorted_by_activity.non_archived
projects = projects.includes(:namespace)
projects = projects.map do |project|
OpenStruct.new(id: project.id, title: project.name_with_namespace)
end
projects.unshift(OpenStruct.new(id: '', title: 'Any Project'))
options_from_collection_for_select(projects, 'id', 'title', params[:project_id])
end
def todo_types_options
types = [
OpenStruct.new(title: 'Any Type', name: ''),
OpenStruct.new(title: 'Issue', name: 'Issue'),
OpenStruct.new(title: 'Merge Request', name: 'MergeRequest')
]
options_from_collection_for_select(types, 'name', 'title', params[:type])
end
end

View file

@ -37,7 +37,7 @@ class Note < ActiveRecord::Base
belongs_to :author, class_name: "User"
belongs_to :updated_by, class_name: "User"
has_many :tasks, dependent: :destroy
has_many :todos, dependent: :destroy
delegate :name, to: :project, prefix: true
delegate :name, :email, to: :author, prefix: true

View file

@ -1,6 +1,6 @@
# == Schema Information
#
# Table name: tasks
# Table name: todos
#
# id :integer not null, primary key
# user_id :integer not null
@ -15,7 +15,7 @@
# updated_at :datetime
#
class Task < ActiveRecord::Base
class Todo < ActiveRecord::Base
ASSIGNED = 1
MENTIONED = 2

View file

@ -140,7 +140,7 @@ class User < ActiveRecord::Base
has_one :abuse_report, dependent: :destroy
has_many :spam_logs, dependent: :destroy
has_many :builds, dependent: :nullify, class_name: 'Ci::Build'
has_many :tasks, dependent: :destroy
has_many :todos, dependent: :destroy
#
# Validations

View file

@ -23,8 +23,8 @@ class BaseService
EventCreateService.new
end
def task_service
TaskService.new
def todo_service
TodoService.new
end
def log_info(message)

View file

@ -3,7 +3,7 @@ module Issues
def execute(issue, commit = nil)
if project.jira_tracker? && project.jira_service.active
project.jira_service.execute(commit, issue)
task_service.close_issue(issue, current_user)
todo_service.close_issue(issue, current_user)
return issue
end
@ -11,7 +11,7 @@ module Issues
event_service.close_issue(issue, current_user)
create_note(issue, commit)
notification_service.close_issue(issue, current_user)
task_service.close_issue(issue, current_user)
todo_service.close_issue(issue, current_user)
execute_hooks(issue, 'close')
end

View file

@ -9,7 +9,7 @@ module Issues
if issue.save
issue.update_attributes(label_ids: label_params)
notification_service.new_issue(issue, current_user)
task_service.new_issue(issue, current_user)
todo_service.new_issue(issue, current_user)
event_service.open_issue(issue, current_user)
issue.create_cross_references!(current_user)
execute_hooks(issue, 'open')

View file

@ -6,12 +6,12 @@ module Issues
def handle_changes(issue, options = {})
if has_changes?(issue, options)
task_service.mark_pending_tasks_as_done(issue, current_user)
todo_service.mark_pending_todos_as_done(issue, current_user)
end
if issue.previous_changes.include?('title') ||
issue.previous_changes.include?('description')
task_service.update_issue(issue, current_user)
todo_service.update_issue(issue, current_user)
end
if issue.previous_changes.include?('milestone_id')
@ -21,7 +21,7 @@ module Issues
if issue.previous_changes.include?('assignee_id')
create_assignee_note(issue)
notification_service.reassigned_issue(issue, current_user)
task_service.reassigned_issue(issue, current_user)
todo_service.reassigned_issue(issue, current_user)
end
end

View file

@ -9,7 +9,7 @@ module MergeRequests
event_service.close_mr(merge_request, current_user)
create_note(merge_request)
notification_service.close_mr(merge_request, current_user)
task_service.close_merge_request(merge_request, current_user)
todo_service.close_merge_request(merge_request, current_user)
execute_hooks(merge_request, 'close')
end

View file

@ -18,7 +18,7 @@ module MergeRequests
merge_request.update_attributes(label_ids: label_params)
event_service.open_mr(merge_request, current_user)
notification_service.new_merge_request(merge_request, current_user)
task_service.new_merge_request(merge_request, current_user)
todo_service.new_merge_request(merge_request, current_user)
merge_request.create_cross_references!(current_user)
execute_hooks(merge_request)
end

View file

@ -16,12 +16,12 @@ module MergeRequests
def handle_changes(merge_request, options = {})
if has_changes?(merge_request, options)
task_service.mark_pending_tasks_as_done(merge_request, current_user)
todo_service.mark_pending_todos_as_done(merge_request, current_user)
end
if merge_request.previous_changes.include?('title') ||
merge_request.previous_changes.include?('description')
task_service.update_merge_request(merge_request, current_user)
todo_service.update_merge_request(merge_request, current_user)
end
if merge_request.previous_changes.include?('target_branch')
@ -37,7 +37,7 @@ module MergeRequests
if merge_request.previous_changes.include?('assignee_id')
create_assignee_note(merge_request)
notification_service.reassigned_merge_request(merge_request, current_user)
task_service.reassigned_merge_request(merge_request, current_user)
todo_service.reassigned_merge_request(merge_request, current_user)
end
if merge_request.previous_changes.include?('target_branch') ||

View file

@ -8,7 +8,7 @@ module Notes
if note.save
# Finish the harder work in the background
NewNoteWorker.perform_in(2.seconds, note.id, params)
TaskService.new.new_note(note, current_user)
TodoService.new.new_note(note, current_user)
end
note

View file

@ -8,7 +8,7 @@ module Notes
note.reset_events_cache
if note.previous_changes.include?('note')
TaskService.new.update_note(note, current_user)
TodoService.new.update_note(note, current_user)
end
note

View file

@ -1,15 +1,15 @@
# TaskService class
# TodoService class
#
# Used for creating tasks on task queue after certain user action
# Used for creating todos after certain user actions
#
# Ex.
# TaskService.new.new_issue(issue, current_user)
# TodoService.new.new_issue(issue, current_user)
#
class TaskService
class TodoService
# When create an issue we should:
#
# * create a task for assignee if issue is assigned
# * create a task for each mentioned user on issue
# * create a todo for assignee if issue is assigned
# * create a todo for each mentioned user on issue
#
def new_issue(issue, current_user)
new_issuable(issue, current_user)
@ -17,32 +17,32 @@ class TaskService
# When update an issue we should:
#
# * mark all pending tasks related to the issue for the current user as done
# * mark all pending todos related to the issue for the current user as done
#
def update_issue(issue, current_user)
create_mention_tasks(issue.project, issue, current_user)
create_mention_todos(issue.project, issue, current_user)
end
# When close an issue we should:
#
# * mark all pending tasks related to the target for the current user as done
# * mark all pending todos related to the target for the current user as done
#
def close_issue(issue, current_user)
mark_pending_tasks_as_done(issue, current_user)
mark_pending_todos_as_done(issue, current_user)
end
# When we reassign an issue we should:
#
# * create a pending task for new assignee if issue is assigned
# * create a pending todo for new assignee if issue is assigned
#
def reassigned_issue(issue, current_user)
create_assignment_task(issue, current_user)
create_assignment_todo(issue, current_user)
end
# When create a merge request we should:
#
# * creates a pending task for assignee if merge request is assigned
# * create a task for each mentioned user on merge request
# * creates a pending todo for assignee if merge request is assigned
# * create a todo for each mentioned user on merge request
#
def new_merge_request(merge_request, current_user)
new_issuable(merge_request, current_user)
@ -50,40 +50,40 @@ class TaskService
# When update a merge request we should:
#
# * create a task for each mentioned user on merge request
# * create a todo for each mentioned user on merge request
#
def update_merge_request(merge_request, current_user)
create_mention_tasks(merge_request.project, merge_request, current_user)
create_mention_todos(merge_request.project, merge_request, current_user)
end
# When close a merge request we should:
#
# * mark all pending tasks related to the target for the current user as done
# * mark all pending todos related to the target for the current user as done
#
def close_merge_request(merge_request, current_user)
mark_pending_tasks_as_done(merge_request, current_user)
mark_pending_todos_as_done(merge_request, current_user)
end
# When we reassign a merge request we should:
#
# * creates a pending task for new assignee if merge request is assigned
# * creates a pending todo for new assignee if merge request is assigned
#
def reassigned_merge_request(merge_request, current_user)
create_assignment_task(merge_request, current_user)
create_assignment_todo(merge_request, current_user)
end
# When merge a merge request we should:
#
# * mark all pending tasks related to the target for the current user as done
# * mark all pending todos related to the target for the current user as done
#
def merge_merge_request(merge_request, current_user)
mark_pending_tasks_as_done(merge_request, current_user)
mark_pending_todos_as_done(merge_request, current_user)
end
# When create a note we should:
#
# * mark all pending tasks related to the noteable for the note author as done
# * create a task for each mentioned user on note
# * mark all pending todos related to the noteable for the note author as done
# * create a todo for each mentioned user on note
#
def new_note(note, current_user)
handle_note(note, current_user)
@ -91,28 +91,28 @@ class TaskService
# When update a note we should:
#
# * mark all pending tasks related to the noteable for the current user as done
# * create a task for each new user mentioned on note
# * mark all pending todos related to the noteable for the current user as done
# * create a todo for each new user mentioned on note
#
def update_note(note, current_user)
handle_note(note, current_user)
end
# When marking pending tasks as done we should:
# When marking pending todos as done we should:
#
# * mark all pending tasks related to the target for the current user as done
# * mark all pending todos related to the target for the current user as done
#
def mark_pending_tasks_as_done(target, user)
pending_tasks(user, target.project, target).update_all(state: :done)
def mark_pending_todos_as_done(target, user)
pending_todos(user, target.project, target).update_all(state: :done)
end
private
def create_tasks(project, target, author, users, action, note = nil)
def create_todos(project, target, author, users, action, note = nil)
Array(users).each do |user|
next if pending_tasks(user, project, target).exists?
next if pending_todos(user, project, target).exists?
Task.create(
Todo.create(
project: project,
user_id: user.id,
author_id: author.id,
@ -125,8 +125,8 @@ class TaskService
end
def new_issuable(issuable, author)
create_assignment_task(issuable, author)
create_mention_tasks(issuable.project, issuable, author)
create_assignment_todo(issuable, author)
create_mention_todos(issuable.project, issuable, author)
end
def handle_note(note, author)
@ -136,19 +136,19 @@ class TaskService
project = note.project
target = note.noteable
mark_pending_tasks_as_done(target, author)
create_mention_tasks(project, target, author, note)
mark_pending_todos_as_done(target, author)
create_mention_todos(project, target, author, note)
end
def create_assignment_task(issuable, author)
def create_assignment_todo(issuable, author)
if issuable.assignee && issuable.assignee != author
create_tasks(issuable.project, issuable, author, issuable.assignee, Task::ASSIGNED)
create_todos(issuable.project, issuable, author, issuable.assignee, Todo::ASSIGNED)
end
end
def create_mention_tasks(project, issuable, author, note = nil)
def create_mention_todos(project, issuable, author, note = nil)
mentioned_users = filter_mentioned_users(project, note || issuable, author)
create_tasks(project, issuable, author, mentioned_users, Task::MENTIONED, note)
create_todos(project, issuable, author, mentioned_users, Todo::MENTIONED, note)
end
def filter_mentioned_users(project, target, author)
@ -160,8 +160,8 @@ class TaskService
mentioned_users.uniq
end
def pending_tasks(user, project, target)
user.tasks.pending.where(
def pending_todos(user, project, target)
user.todos.pending.where(
project_id: project.id,
target_id: target.id,
target_type: target.class.name

View file

@ -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)
&middot; #{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)

View file

@ -0,0 +1,21 @@
%li{class: "todo todo-#{todo.done? ? 'done' : 'pending'}", id: dom_id(todo) }
.todo-item{class: 'todo-block'}
= image_tag avatar_icon(todo.author_email, 40), class: 'avatar s40', alt:''
.todo-title
%span.author_name
= link_to_author todo
%span.todo_label
= todo_action_name(todo)
= todo_target_link_html(todo)
&middot; #{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)

View file

@ -1,53 +1,53 @@
- page_title "Tasks"
- header_title "Tasks", dashboard_tasks_path
- page_title "Todos"
- header_title "Todos", dashboard_todos_path
.top-area
%ul.nav-links
%li{class: ('active' if params[:state].blank? || params[:state] == 'pending')}
= link_to page_filter_path(state: 'pending') do
%span
Tasks
Todos
%span{class: 'badge'}
= tasks_pending_count
= todos_pending_count
%li{class: ('active' if params[:state] == 'done')}
= link_to page_filter_path(state: 'done') do
%span
Done
%span{class: 'badge'}
= tasks_done_count
= todos_done_count
.tasks-filters
.todos-filters
.gray-content-block.second-block
= form_tag page_filter_path(without: [:assignee_id, :milestone_title, :label_name, :scope, :sort]), method: :get, class: 'filter-form' do
.filter-item.inline
= select_tag('project_id', task_projects_options,
= select_tag('project_id', todo_projects_options,
class: 'select2 trigger-submit', include_blank: true,
data: {placeholder: 'Project'})
.filter-item.inline
= users_select_tag(:author_id, selected: params[:author_id],
placeholder: 'Author', class: 'trigger-submit', any_user: "Any Author", first_user: true, current_user: true)
.filter-item.inline
= select_tag('type', task_types_options,
= select_tag('type', todo_types_options,
class: 'select2 trigger-submit', include_blank: true,
data: {placeholder: 'Type'})
.filter-item.inline.actions-filter
= select_tag('action_id', task_actions_options,
= select_tag('action_id', todo_actions_options,
class: 'select2 trigger-submit', include_blank: true,
data: {placeholder: 'Action'})
.prepend-top-default
- if @tasks.any?
- @tasks.group_by(&:project).each do |group|
- if @todos.any?
- @todos.group_by(&:project).each do |group|
.panel.panel-default.panel-small
- project = group[0]
.panel-heading
= link_to project.name_with_namespace, namespace_project_path(project.namespace, project)
%ul.well-list.tasks-list
%ul.well-list.todos-list
= render group[1]
= paginate @tasks, theme: "gitlab"
= paginate @todos, theme: "gitlab"
- else
.nothing-here-block No tasks to show
.nothing-here-block No todos to show
:javascript
new UsersSelect();

View file

@ -22,9 +22,9 @@
= link_to admin_root_path, title: 'Admin Area', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('wrench fw')
%li
= link_to dashboard_tasks_path, title: 'Tasks', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
%span.badge.tasks-pending-count
= tasks_pending_count
= link_to dashboard_todos_path, title: 'Todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
%span.badge.todos-pending-count
= todos_pending_count
- if current_user.can_create_project?
%li
= link_to new_project_path, title: 'New project', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do

View file

@ -4,12 +4,12 @@
= icon('home fw')
%span
Projects
= nav_link(controller: :tasks) do
= link_to dashboard_tasks_path, title: 'Tasks' do
= nav_link(controller: :todos) do
= link_to dashboard_todos_path, title: 'Todos' do
= icon('bell fw')
%span
Tasks
%span.count= number_with_delimiter(tasks_pending_count)
Todos
%span.count= number_with_delimiter(todos_pending_count)
= nav_link(path: 'dashboard#activity') do
= link_to activity_dashboard_path, class: 'shortcuts-activity', title: 'Activity' do
= icon('dashboard fw')

View file

@ -333,7 +333,7 @@ Rails.application.routes.draw do
resources :groups, only: [:index]
resources :snippets, only: [:index]
resources :tasks, only: [:index, :destroy]
resources :todos, only: [:index, :destroy]
resources :projects, only: [:index] do
collection do

View file

@ -0,0 +1,5 @@
class RenameTasksToTodos < ActiveRecord::Migration
def change
rename_table :tasks, :todos
end
end

View file

@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160217174422) do
ActiveRecord::Schema.define(version: 20160220123949) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -824,7 +824,7 @@ ActiveRecord::Schema.define(version: 20160217174422) do
add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree
create_table "tasks", force: :cascade do |t|
create_table "todos", force: :cascade do |t|
t.integer "user_id", null: false
t.integer "project_id", null: false
t.integer "target_id", null: false
@ -837,12 +837,12 @@ ActiveRecord::Schema.define(version: 20160217174422) do
t.integer "note_id"
end
add_index "tasks", ["author_id"], name: "index_tasks_on_author_id", using: :btree
add_index "tasks", ["note_id"], name: "index_tasks_on_note_id", using: :btree
add_index "tasks", ["project_id"], name: "index_tasks_on_project_id", using: :btree
add_index "tasks", ["state"], name: "index_tasks_on_state", using: :btree
add_index "tasks", ["target_type", "target_id"], name: "index_tasks_on_target_type_and_target_id", using: :btree
add_index "tasks", ["user_id"], name: "index_tasks_on_user_id", using: :btree
add_index "todos", ["author_id"], name: "index_todos_on_author_id", using: :btree
add_index "todos", ["note_id"], name: "index_todos_on_note_id", using: :btree
add_index "todos", ["project_id"], name: "index_todos_on_project_id", using: :btree
add_index "todos", ["state"], name: "index_todos_on_state", using: :btree
add_index "todos", ["target_type", "target_id"], name: "index_todos_on_target_type_and_target_id", using: :btree
add_index "todos", ["user_id"], name: "index_todos_on_user_id", using: :btree
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false

View file

@ -1,5 +1,5 @@
@dashboard
Feature: Dashboard Tasks
Feature: Dashboard Todos
Background:
Given I sign in as a user
And I own project "Shop"
@ -7,32 +7,32 @@ Feature: Dashboard Tasks
And "Mary Jane" is a developer of project "Shop"
And "Mary Jane" owns private project "Enterprise"
And I am a developer of project "Enterprise"
And I have pending tasks
And I visit dashboard task queue page
And I have todos
And I visit dashboard todos page
@javascript
Scenario: I mark pending tasks as done
Then I should see pending tasks assigned to me
And I mark the pending task as done
Scenario: I mark todos as done
Then I should see todos assigned to me
And I mark the todo as done
And I click on the "Done" tab
Then I should see all tasks marked as done
Then I should see all todos marked as done
@javascript
Scenario: I filter by project
Given I filter by "Enterprise"
Then I should not see tasks
Then I should not see todos
@javascript
Scenario: I filter by author
Given I filter by "John Doe"
Then I should not see tasks related to "Mary Jane" in the list
Then I should not see todos related to "Mary Jane" in the list
@javascript
Scenario: I filter by type
Given I filter by "Issue"
Then I should not see tasks related to "Merge Requests" in the list
Then I should not see todos related to "Merge Requests" in the list
@javascript
Scenario: I filter by action
Given I filter by "Mentioned"
Then I should not see tasks related to "Assignments" in the list
Then I should not see todos related to "Assignments" in the list

View file

@ -1,4 +1,4 @@
class Spinach::Features::DashboardTasks < Spinach::FeatureSteps
class Spinach::Features::DashboardTodos < Spinach::FeatureSteps
include SharedAuthentication
include SharedPaths
include SharedProject
@ -17,43 +17,43 @@ class Spinach::Features::DashboardTasks < Spinach::FeatureSteps
project.team << [john_doe, :developer]
end
step 'I have pending tasks' do
create(:task, user: current_user, project: project, author: mary_jane, target: issue, action: Task::MENTIONED)
create(:task, user: current_user, project: project, author: john_doe, target: issue, action: Task::ASSIGNED)
step 'I have todos' do
create(:todo, user: current_user, project: project, author: mary_jane, target: issue, action: Todo::MENTIONED)
create(:todo, user: current_user, project: project, author: john_doe, target: issue, action: Todo::ASSIGNED)
note = create(:note, author: john_doe, noteable: issue, note: "#{current_user.to_reference} Wdyt?")
create(:task, user: current_user, project: project, author: john_doe, target: issue, action: Task::MENTIONED, note: note)
create(:task, user: current_user, project: project, author: john_doe, target: merge_request, action: Task::ASSIGNED)
create(:todo, user: current_user, project: project, author: john_doe, target: issue, action: Todo::MENTIONED, note: note)
create(:todo, user: current_user, project: project, author: john_doe, target: merge_request, action: Todo::ASSIGNED)
end
step 'I should see pending tasks assigned to me' do
expect(page).to have_content 'Tasks 4'
step 'I should see todos assigned to me' do
expect(page).to have_content 'Todos 4'
expect(page).to have_content 'Done 0'
expect(page).to have_link project.name_with_namespace
should_see_task(1, "John Doe assigned merge request ##{merge_request.iid}", merge_request.title)
should_see_task(2, "John Doe mentioned you on issue ##{issue.iid}", "#{current_user.to_reference} Wdyt?")
should_see_task(3, "John Doe assigned issue ##{issue.iid}", issue.title)
should_see_task(4, "Mary Jane mentioned you on issue ##{issue.iid}", issue.title)
should_see_todo(1, "John Doe assigned merge request ##{merge_request.iid}", merge_request.title)
should_see_todo(2, "John Doe mentioned you on issue ##{issue.iid}", "#{current_user.to_reference} Wdyt?")
should_see_todo(3, "John Doe assigned issue ##{issue.iid}", issue.title)
should_see_todo(4, "Mary Jane mentioned you on issue ##{issue.iid}", issue.title)
end
step 'I mark the pending task as done' do
page.within('.task:nth-child(1)') do
step 'I mark the todo as done' do
page.within('.todo:nth-child(1)') do
click_link 'Done'
end
expect(page).to have_content 'Task was successfully marked as done.'
expect(page).to have_content 'Tasks 3'
expect(page).to have_content 'Todo was successfully marked as done.'
expect(page).to have_content 'Todos 3'
expect(page).to have_content 'Done 1'
should_not_see_task "John Doe assigned merge request ##{merge_request.iid}"
should_not_see_todo "John Doe assigned merge request ##{merge_request.iid}"
end
step 'I click on the "Done" tab' do
click_link 'Done 1'
end
step 'I should see all tasks marked as done' do
step 'I should see all todos marked as done' do
expect(page).to have_link project.name_with_namespace
should_see_task(1, "John Doe assigned merge request ##{merge_request.iid}", merge_request.title, false)
should_see_todo(1, "John Doe assigned merge request ##{merge_request.iid}", merge_request.title, false)
end
step 'I filter by "Enterprise"' do
@ -69,28 +69,28 @@ class Spinach::Features::DashboardTasks < Spinach::FeatureSteps
end
step 'I filter by "Mentioned"' do
select2("#{Task::MENTIONED}", from: '#action_id')
select2("#{Todo::MENTIONED}", from: '#action_id')
end
step 'I should not see tasks' do
expect(page).to have_content 'No tasks to show'
step 'I should not see todos' do
expect(page).to have_content 'No todos to show'
end
step 'I should not see tasks related to "Mary Jane" in the list' do
should_not_see_task "Mary Jane mentioned you on issue ##{issue.iid}"
step 'I should not see todos related to "Mary Jane" in the list' do
should_not_see_todo "Mary Jane mentioned you on issue ##{issue.iid}"
end
step 'I should not see tasks related to "Merge Requests" in the list' do
should_not_see_task "John Doe assigned merge request ##{merge_request.iid}"
step 'I should not see todos related to "Merge Requests" in the list' do
should_not_see_todo "John Doe assigned merge request ##{merge_request.iid}"
end
step 'I should not see tasks related to "Assignments" in the list' do
should_not_see_task "John Doe assigned merge request ##{merge_request.iid}"
should_not_see_task "John Doe assigned issue ##{issue.iid}"
step 'I should not see todos related to "Assignments" in the list' do
should_not_see_todo "John Doe assigned merge request ##{merge_request.iid}"
should_not_see_todo "John Doe assigned issue ##{issue.iid}"
end
def should_see_task(position, title, body, pending = true)
page.within(".task:nth-child(#{position})") do
def should_see_todo(position, title, body, pending = true)
page.within(".todo:nth-child(#{position})") do
expect(page).to have_content title
expect(page).to have_content body
@ -102,7 +102,7 @@ class Spinach::Features::DashboardTasks < Spinach::FeatureSteps
end
end
def should_not_see_task(title)
def should_not_see_todo(title)
expect(page).not_to have_content title
end

View file

@ -103,8 +103,8 @@ module SharedPaths
visit dashboard_groups_path
end
step 'I visit dashboard task queue page' do
visit dashboard_tasks_path
step 'I visit dashboard todos page' do
visit dashboard_todos_path
end
step 'I should be redirected to the dashboard groups page' do

View file

@ -1,6 +1,6 @@
# == Schema Information
#
# Table name: tasks
# Table name: todos
#
# id :integer not null, primary key
# user_id :integer not null
@ -16,19 +16,19 @@
#
FactoryGirl.define do
factory :task do
factory :todo do
project
author
user
target factory: :issue
action { Task::ASSIGNED }
action { Todo::ASSIGNED }
trait :assigned do
action { Task::ASSIGNED }
action { Todo::ASSIGNED }
end
trait :mentioned do
action { Task::MENTIONED }
action { Todo::MENTIONED }
end
end
end

View file

@ -27,7 +27,7 @@ describe Note, models: true do
it { is_expected.to belong_to(:noteable) }
it { is_expected.to belong_to(:author).class_name('User') }
it { is_expected.to have_many(:tasks).dependent(:destroy) }
it { is_expected.to have_many(:todos).dependent(:destroy) }
end
describe 'validation' do

View file

@ -1,6 +1,6 @@
# == Schema Information
#
# Table name: tasks
# Table name: todos
#
# id :integer not null, primary key
# user_id :integer not null
@ -17,7 +17,7 @@
require 'spec_helper'
describe Task, models: true do
describe Todo, models: true do
describe 'relationships' do
it { is_expected.to belong_to(:author).class_name("User") }
it { is_expected.to belong_to(:note) }
@ -39,13 +39,13 @@ describe Task, models: true do
describe '#action_name' do
it 'returns proper message when action is an assigment' do
subject.action = Task::ASSIGNED
subject.action = Todo::ASSIGNED
expect(subject.action_name).to eq 'assigned'
end
it 'returns proper message when action is a mention' do
subject.action = Task::MENTIONED
subject.action = Todo::MENTIONED
expect(subject.action_name).to eq 'mentioned you on'
end

View file

@ -92,7 +92,7 @@ describe User, models: true do
it { is_expected.to have_many(:identities).dependent(:destroy) }
it { is_expected.to have_one(:abuse_report) }
it { is_expected.to have_many(:spam_logs).dependent(:destroy) }
it { is_expected.to have_many(:tasks).dependent(:destroy) }
it { is_expected.to have_many(:todos).dependent(:destroy) }
end
describe 'validations' do

View file

@ -5,7 +5,7 @@ describe Issues::CloseService, services: true do
let(:user2) { create(:user) }
let(:issue) { create(:issue, assignee: user2) }
let(:project) { issue.project }
let!(:pending_task) { create(:task, :assigned, user: user, project: project, target: issue, author: user2) }
let!(:todo) { create(:todo, :assigned, user: user, project: project, target: issue, author: user2) }
before do
project.team << [user, :master]
@ -34,8 +34,8 @@ describe Issues::CloseService, services: true do
expect(note.note).to include "Status changed to closed"
end
it 'marks pending tasks as done' do
expect(pending_task.reload).to be_done
it 'marks todos as done' do
expect(todo.reload).to be_done
end
end
@ -47,7 +47,7 @@ describe Issues::CloseService, services: true do
it { expect(@issue).to be_valid }
it { expect(@issue).to be_opened }
it { expect(pending_task.reload).to be_pending }
it { expect(todo.reload).to be_pending }
end
end
end

View file

@ -24,17 +24,18 @@ describe Issues::CreateService, services: true do
it { expect(@issue.title).to eq('Awesome issue') }
it { expect(@issue.assignee).to eq assignee }
it 'creates a pending task for new assignee' do
it 'creates a pending todo for new assignee' do
attributes = {
project: project,
author: user,
user: assignee,
target: @issue,
action: Task::ASSIGNED,
target_id: @issue.id,
target_type: @issue.class.name,
action: Todo::ASSIGNED,
state: :pending
}
expect(Task.where(attributes).count).to eq 1
expect(Todo.where(attributes).count).to eq 1
end
end
end

View file

@ -80,16 +80,16 @@ describe Issues::UpdateService, services: true do
end
end
context 'task queue' do
let!(:pending_task) { create(:task, :assigned, user: user, project: project, target: issue, author: user2) }
context 'todos' do
let!(:todo) { create(:todo, :assigned, user: user, project: project, target: issue, author: user2) }
context 'when the title change' do
before do
update_issue({ title: 'New title' })
end
it 'marks pending tasks as done' do
expect(pending_task.reload.done?).to eq true
it 'marks pending todos as done' do
expect(todo.reload.done?).to eq true
end
end
@ -98,8 +98,8 @@ describe Issues::UpdateService, services: true do
update_issue({ description: 'Also please fix' })
end
it 'marks pending tasks as done' do
expect(pending_task.reload.done?).to eq true
it 'marks todos as done' do
expect(todo.reload.done?).to eq true
end
end
@ -108,21 +108,22 @@ describe Issues::UpdateService, services: true do
update_issue({ assignee: user2 })
end
it 'marks previous assignee pending tasks as done' do
expect(pending_task.reload.done?).to eq true
it 'marks previous assignee todos as done' do
expect(todo.reload.done?).to eq true
end
it 'creates a pending task for new assignee' do
it 'creates a todo for new assignee' do
attributes = {
project: project,
author: user,
user: user2,
target: issue,
action: Task::ASSIGNED,
target_id: issue.id,
target_type: issue.class.name,
action: Todo::ASSIGNED,
state: :pending
}
expect(Task.where(attributes).count).to eq 1
expect(Todo.where(attributes).count).to eq 1
end
end
@ -131,8 +132,8 @@ describe Issues::UpdateService, services: true do
update_issue({ milestone: create(:milestone) })
end
it 'marks pending tasks as done' do
expect(pending_task.reload.done?).to eq true
it 'marks todos as done' do
expect(todo.reload.done?).to eq true
end
end
@ -141,8 +142,8 @@ describe Issues::UpdateService, services: true do
update_issue({ label_ids: [label.id] })
end
it 'marks pending tasks as done' do
expect(pending_task.reload.done?).to eq true
it 'marks todos as done' do
expect(todo.reload.done?).to eq true
end
end
end

View file

@ -5,7 +5,7 @@ describe MergeRequests::CloseService, services: true do
let(:user2) { create(:user) }
let(:merge_request) { create(:merge_request, assignee: user2) }
let(:project) { merge_request.project }
let!(:pending_task) { create(:task, :assigned, user: user, project: project, target: merge_request, author: user2) }
let!(:todo) { create(:todo, :assigned, user: user, project: project, target: merge_request, author: user2) }
before do
project.team << [user, :master]
@ -43,8 +43,8 @@ describe MergeRequests::CloseService, services: true do
expect(note.note).to include 'Status changed to closed'
end
it 'marks pending tasks as done' do
expect(pending_task.reload).to be_done
it 'marks todos as done' do
expect(todo.reload).to be_done
end
end
end

View file

@ -34,13 +34,14 @@ describe MergeRequests::CreateService, services: true do
expect(service).to have_received(:execute_hooks).with(@merge_request)
end
it 'does not creates a pending task' do
it 'does not creates todos' do
attributes = {
project: project,
target: @merge_request
target_id: @merge_request.id,
target_type: @merge_request.class.name
}
expect(Task.where(attributes).count).to be_zero
expect(Todo.where(attributes).count).to be_zero
end
context 'when merge request is assigned to someone' do
@ -56,17 +57,18 @@ describe MergeRequests::CreateService, services: true do
it { expect(@merge_request.assignee).to eq assignee }
it 'creates a pending task for new assignee' do
it 'creates a todo for new assignee' do
attributes = {
project: project,
author: user,
user: assignee,
target: @merge_request,
action: Task::ASSIGNED,
target_id: @merge_request.id,
target_type: @merge_request.class.name,
action: Todo::ASSIGNED,
state: :pending
}
expect(Task.where(attributes).count).to eq 1
expect(Todo.where(attributes).count).to eq 1
end
end
end

View file

@ -98,16 +98,16 @@ describe MergeRequests::UpdateService, services: true do
end
end
context 'task queue' do
let!(:pending_task) { create(:task, :assigned, user: user, project: project, target: merge_request, author: user2) }
context 'todos' do
let!(:pending_todo) { create(:todo, :assigned, user: user, project: project, target: merge_request, author: user2) }
context 'when the title change' do
before do
update_merge_request({ title: 'New title' })
end
it 'marks pending tasks as done' do
expect(pending_task.reload).to be_done
it 'marks pending todos as done' do
expect(pending_todo.reload).to be_done
end
end
@ -116,8 +116,8 @@ describe MergeRequests::UpdateService, services: true do
update_merge_request({ description: 'Also please fix' })
end
it 'marks pending tasks as done' do
expect(pending_task.reload).to be_done
it 'marks pending todos as done' do
expect(pending_todo.reload).to be_done
end
end
@ -126,21 +126,22 @@ describe MergeRequests::UpdateService, services: true do
update_merge_request({ assignee: user2 })
end
it 'marks previous assignee pending tasks as done' do
expect(pending_task.reload).to be_done
it 'marks previous assignee pending todos as done' do
expect(pending_todo.reload).to be_done
end
it 'creates a pending task for new assignee' do
it 'creates a pending todo for new assignee' do
attributes = {
project: project,
author: user,
user: user2,
target: merge_request,
action: Task::ASSIGNED,
target_id: merge_request.id,
target_type: merge_request.class.name,
action: Todo::ASSIGNED,
state: :pending
}
expect(Task.where(attributes).count).to eq 1
expect(Todo.where(attributes).count).to eq 1
end
end
@ -149,8 +150,8 @@ describe MergeRequests::UpdateService, services: true do
update_merge_request({ milestone: create(:milestone) })
end
it 'marks pending tasks as done' do
expect(pending_task.reload).to be_done
it 'marks pending todos as done' do
expect(pending_todo.reload).to be_done
end
end
@ -159,8 +160,8 @@ describe MergeRequests::UpdateService, services: true do
update_merge_request({ label_ids: [label.id] })
end
it 'marks pending tasks as done' do
expect(pending_task.reload).to be_done
it 'marks pending todos as done' do
expect(pending_todo.reload).to be_done
end
end
@ -169,8 +170,8 @@ describe MergeRequests::UpdateService, services: true do
update_merge_request({ target_branch: 'target' })
end
it 'marks pending tasks as done' do
expect(pending_task.reload).to be_done
it 'marks pending todos as done' do
expect(pending_todo.reload).to be_done
end
end
end

View file

@ -18,16 +18,16 @@ describe Notes::UpdateService, services: true do
@note.reload
end
context 'task queue' do
let!(:pending_task) { create(:task, :assigned, user: user, project: project, target: issue, author: user2) }
context 'todos' do
let!(:todo) { create(:todo, :assigned, user: user, project: project, target: issue, author: user2) }
context 'when the note change' do
before do
update_note({ note: 'New note' })
end
it 'marks pending tasks as done' do
expect(pending_task.reload).to be_done
it 'marks todos as done' do
expect(todo.reload).to be_done
end
end
@ -36,8 +36,8 @@ describe Notes::UpdateService, services: true do
update_note({ note: 'Old note' })
end
it 'keep pending tasks' do
expect(pending_task.reload).to be_pending
it 'keep todos' do
expect(todo.reload).to be_pending
end
end
end

View file

@ -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

View file

@ -0,0 +1,264 @@
require 'spec_helper'
describe TodoService, services: true do
let(:author) { create(:user) }
let(:john_doe) { create(:user, username: 'john_doe') }
let(:michael) { create(:user, username: 'michael') }
let(:stranger) { create(:user, username: 'stranger') }
let(:project) { create(:project) }
let(:mentions) { [author.to_reference, john_doe.to_reference, michael.to_reference, stranger.to_reference].join(' ') }
let(:service) { described_class.new }
before do
project.team << [author, :developer]
project.team << [john_doe, :developer]
project.team << [michael, :developer]
end
describe 'Issues' do
let(:issue) { create(:issue, project: project, assignee: john_doe, author: author, description: mentions) }
let(:unassigned_issue) { create(:issue, project: project, assignee: nil) }
describe '#new_issue' do
it 'creates a todo if assigned' do
service.new_issue(issue, author)
should_create_todo(user: john_doe, target: issue, action: Todo::ASSIGNED)
end
it 'does not create a todo if unassigned' do
should_not_create_any_todo { service.new_issue(unassigned_issue, author) }
end
it 'does not create a todo if assignee is the current user' do
should_not_create_any_todo { service.new_issue(unassigned_issue, john_doe) }
end
it 'creates a todo for each valid mentioned user' do
service.new_issue(issue, author)
should_create_todo(user: michael, target: issue, action: Todo::MENTIONED)
should_not_create_todo(user: author, target: issue, action: Todo::MENTIONED)
should_not_create_todo(user: john_doe, target: issue, action: Todo::MENTIONED)
should_not_create_todo(user: stranger, target: issue, action: Todo::MENTIONED)
end
end
describe '#update_issue' do
it 'creates a todo for each valid mentioned user' do
service.update_issue(issue, author)
should_create_todo(user: michael, target: issue, action: Todo::MENTIONED)
should_create_todo(user: john_doe, target: issue, action: Todo::MENTIONED)
should_not_create_todo(user: author, target: issue, action: Todo::MENTIONED)
should_not_create_todo(user: stranger, target: issue, action: Todo::MENTIONED)
end
it 'does not create a todo if user was already mentioned' do
create(:todo, :mentioned, user: michael, project: project, target: issue, author: author)
expect { service.update_issue(issue, author) }.not_to change(michael.todos, :count)
end
end
describe '#close_issue' do
it 'marks related pending todos to the target for the user as done' do
first_todo = create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author)
second_todo = create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author)
service.close_issue(issue, john_doe)
expect(first_todo.reload).to be_done
expect(second_todo.reload).to be_done
end
end
describe '#reassigned_issue' do
it 'creates a pending todo for new assignee' do
unassigned_issue.update_attribute(:assignee, john_doe)
service.reassigned_issue(unassigned_issue, author)
should_create_todo(user: john_doe, target: unassigned_issue, action: Todo::ASSIGNED)
end
it 'does not create a todo if unassigned' do
issue.update_attribute(:assignee, nil)
should_not_create_any_todo { service.reassigned_issue(issue, author) }
end
it 'does not create a todo if new assignee is the current user' do
unassigned_issue.update_attribute(:assignee, john_doe)
should_not_create_any_todo { service.reassigned_issue(unassigned_issue, john_doe) }
end
end
describe '#mark_pending_todos_as_done' do
it 'marks related pending todos to the target for the user as done' do
first_todo = create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author)
second_todo = create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author)
service.mark_pending_todos_as_done(issue, john_doe)
expect(first_todo.reload).to be_done
expect(second_todo.reload).to be_done
end
end
describe '#new_note' do
let!(:first_todo) { create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author) }
let!(:second_todo) { create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author) }
let(:note) { create(:note, project: project, noteable: issue, author: john_doe, note: mentions) }
let(:award_note) { create(:note, :award, project: project, noteable: issue, author: john_doe, note: 'thumbsup') }
let(:system_note) { create(:system_note, project: project, noteable: issue) }
it 'mark related pending todos to the noteable for the note author as done' do
first_todo = create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author)
second_todo = create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author)
service.new_note(note, john_doe)
expect(first_todo.reload).to be_done
expect(second_todo.reload).to be_done
end
it 'mark related pending todos to the noteable for the award note author as done' do
service.new_note(award_note, john_doe)
expect(first_todo.reload).to be_done
expect(second_todo.reload).to be_done
end
it 'does not mark related pending todos it is a system note' do
service.new_note(system_note, john_doe)
expect(first_todo.reload).to be_pending
expect(second_todo.reload).to be_pending
end
it 'creates a todo for each valid mentioned user' do
service.new_note(note, john_doe)
should_create_todo(user: michael, target: issue, author: john_doe, action: Todo::MENTIONED, note: note)
should_create_todo(user: author, target: issue, author: john_doe, action: Todo::MENTIONED, note: note)
should_not_create_todo(user: john_doe, target: issue, author: john_doe, action: Todo::MENTIONED, note: note)
should_not_create_todo(user: stranger, target: issue, author: john_doe, action: Todo::MENTIONED, note: note)
end
end
end
describe 'Merge Requests' do
let(:mr_assigned) { create(:merge_request, source_project: project, author: author, assignee: john_doe, description: mentions) }
let(:mr_unassigned) { create(:merge_request, source_project: project, author: author, assignee: nil) }
describe '#new_merge_request' do
it 'creates a pending todo if assigned' do
service.new_merge_request(mr_assigned, author)
should_create_todo(user: john_doe, target: mr_assigned, action: Todo::ASSIGNED)
end
it 'does not create a todo if unassigned' do
should_not_create_any_todo { service.new_merge_request(mr_unassigned, author) }
end
it 'does not create a todo if assignee is the current user' do
should_not_create_any_todo { service.new_merge_request(mr_unassigned, john_doe) }
end
it 'creates a todo for each valid mentioned user' do
service.new_merge_request(mr_assigned, author)
should_create_todo(user: michael, target: mr_assigned, action: Todo::MENTIONED)
should_not_create_todo(user: author, target: mr_assigned, action: Todo::MENTIONED)
should_not_create_todo(user: john_doe, target: mr_assigned, action: Todo::MENTIONED)
should_not_create_todo(user: stranger, target: mr_assigned, action: Todo::MENTIONED)
end
end
describe '#update_merge_request' do
it 'creates a todo for each valid mentioned user' do
service.update_merge_request(mr_assigned, author)
should_create_todo(user: michael, target: mr_assigned, action: Todo::MENTIONED)
should_create_todo(user: john_doe, target: mr_assigned, action: Todo::MENTIONED)
should_not_create_todo(user: author, target: mr_assigned, action: Todo::MENTIONED)
should_not_create_todo(user: stranger, target: mr_assigned, action: Todo::MENTIONED)
end
it 'does not create a todo if user was already mentioned' do
create(:todo, :mentioned, user: michael, project: project, target: mr_assigned, author: author)
expect { service.update_merge_request(mr_assigned, author) }.not_to change(michael.todos, :count)
end
end
describe '#close_merge_request' do
it 'marks related pending todos to the target for the user as done' do
first_todo = create(:todo, :assigned, user: john_doe, project: project, target: mr_assigned, author: author)
second_todo = create(:todo, :assigned, user: john_doe, project: project, target: mr_assigned, author: author)
service.close_merge_request(mr_assigned, john_doe)
expect(first_todo.reload).to be_done
expect(second_todo.reload).to be_done
end
end
describe '#reassigned_merge_request' do
it 'creates a pending todo for new assignee' do
mr_unassigned.update_attribute(:assignee, john_doe)
service.reassigned_merge_request(mr_unassigned, author)
should_create_todo(user: john_doe, target: mr_unassigned, action: Todo::ASSIGNED)
end
it 'does not create a todo if unassigned' do
mr_assigned.update_attribute(:assignee, nil)
should_not_create_any_todo { service.reassigned_merge_request(mr_assigned, author) }
end
it 'does not create a todo if new assignee is the current user' do
mr_assigned.update_attribute(:assignee, john_doe)
should_not_create_any_todo { service.reassigned_merge_request(mr_assigned, john_doe) }
end
end
describe '#merge_merge_request' do
it 'marks related pending todos to the target for the user as done' do
first_todo = create(:todo, :assigned, user: john_doe, project: project, target: mr_assigned, author: author)
second_todo = create(:todo, :assigned, user: john_doe, project: project, target: mr_assigned, author: author)
service.merge_merge_request(mr_assigned, john_doe)
expect(first_todo.reload).to be_done
expect(second_todo.reload).to be_done
end
end
end
def should_create_todo(attributes = {})
attributes.reverse_merge!(
project: project,
author: author,
state: :pending
)
expect(Todo.where(attributes).count).to eq 1
end
def should_not_create_todo(attributes = {})
attributes.reverse_merge!(
project: project,
author: author,
state: :pending
)
expect(Todo.where(attributes).count).to eq 0
end
def should_not_create_any_todo
expect { yield }.not_to change(Todo, :count)
end
end