gitlab-org--gitlab-foss/app/models/concerns/taskable.rb
Patrick Derichs b70d23c25a Add task count and completed count to responses of Issue and MR
Add spec for task_completion_status

Add test cases for task_completion_status result

Extracted shared samples

Add new spec file for task completion status response

Fix style errors

Add changelog entry

Changed samples to Hashes

Remove test for successful request

Remove not nil expectation

Add task_completion_status to api documentation for issues

Add task_completion_status to api documentation for merge_requests

Refactor spec so it just requests one specific item

Add task_completion_status to Taskable

Simplified task completion status in entities

Refactor spec so it separates status code check and content check

Fix spec description text and field name
2019-06-07 11:15:55 +02:00

85 lines
2.5 KiB
Ruby

# frozen_string_literal: true
require 'task_list'
require 'task_list/filter'
# Contains functionality for objects that can have task lists in their
# descriptions. Task list items can be added with Markdown like "* [x] Fix
# bugs".
#
# Used by MergeRequest and Issue
module Taskable
COMPLETED = 'completed'.freeze
INCOMPLETE = 'incomplete'.freeze
COMPLETE_PATTERN = /(\[[xX]\])/.freeze
INCOMPLETE_PATTERN = /(\[[\s]\])/.freeze
ITEM_PATTERN = %r{
^
\s*(?:[-+*]|(?:\d+\.)) # list prefix required - task item has to be always in a list
\s+ # whitespace prefix has to be always presented for a list item
(\[\s\]|\[[xX]\]) # checkbox
(\s.+) # followed by whitespace and some text.
}x.freeze
def self.get_tasks(content)
content.to_s.scan(ITEM_PATTERN).map do |checkbox, label|
# ITEM_PATTERN strips out the hyphen, but Item requires it. Rabble rabble.
TaskList::Item.new("- #{checkbox}", label.strip)
end
end
def self.get_updated_tasks(old_content:, new_content:)
old_tasks, new_tasks = get_tasks(old_content), get_tasks(new_content)
new_tasks.select.with_index do |new_task, i|
old_task = old_tasks[i]
next unless old_task
new_task.source == old_task.source && new_task.complete? != old_task.complete?
end
end
# Called by `TaskList::Summary`
def task_list_items
return [] if description.blank?
@task_list_items ||= Taskable.get_tasks(description) # rubocop:disable Gitlab/ModuleWithInstanceVariables
end
def tasks
@tasks ||= TaskList.new(self)
end
# Return true if this object's description has any task list items.
def tasks?
tasks.summary.items?
end
# Return a string that describes the current state of this Taskable's task
# list items, e.g. "12 of 20 tasks completed"
def task_status(short: false)
return '' if description.blank?
prep, completed = if short
['/', '']
else
[' of ', ' completed']
end
sum = tasks.summary
"#{sum.complete_count}#{prep}#{sum.item_count} #{'task'.pluralize(sum.item_count)}#{completed}"
end
# Return a short string that describes the current state of this Taskable's
# task list items -- for small screens
def task_status_short
task_status(short: true)
end
def task_completion_status
@task_completion_status ||= {
count: tasks.summary.item_count,
completed_count: tasks.summary.complete_count
}
end
end