From f30ad3ff1f958ccb783f3fab68269e61f1a79b3d Mon Sep 17 00:00:00 2001
From: Jarka Kadlecova <jarka@gitlab.com>
Date: Wed, 18 Jan 2017 08:33:13 -0500
Subject: [PATCH] fix nested tasks in ordered list

---
 app/models/concerns/taskable.rb              |  2 +-
 changelogs/unreleased/24923_nested_tasks.yml |  4 ++
 doc/user/markdown.md                         | 20 +++++++--
 spec/features/task_lists_spec.rb             | 44 +++++++++++++++++++-
 spec/support/taskable_shared_examples.rb     | 24 +++++++++++
 5 files changed, 89 insertions(+), 5 deletions(-)
 create mode 100644 changelogs/unreleased/24923_nested_tasks.yml

diff --git a/app/models/concerns/taskable.rb b/app/models/concerns/taskable.rb
index ebc75100a54..68385dc47eb 100644
--- a/app/models/concerns/taskable.rb
+++ b/app/models/concerns/taskable.rb
@@ -11,7 +11,7 @@ module Taskable
   INCOMPLETE   = 'incomplete'.freeze
   ITEM_PATTERN = /
     ^
-    (?:\s*[-+*]|(?:\d+\.))? # optional list prefix
+    \s*(?:[-+*]|(?:\d+\.))? # optional list prefix
     \s*                     # optional whitespace prefix
     (\[\s\]|\[[xX]\])       # checkbox
     (\s.+)                  # followed by whitespace and some text.
diff --git a/changelogs/unreleased/24923_nested_tasks.yml b/changelogs/unreleased/24923_nested_tasks.yml
new file mode 100644
index 00000000000..de35cad3dd6
--- /dev/null
+++ b/changelogs/unreleased/24923_nested_tasks.yml
@@ -0,0 +1,4 @@
+---
+title: Fix nested tasks in ordered list
+merge_request: 8626
+author:
diff --git a/doc/user/markdown.md b/doc/user/markdown.md
index f6484688721..008872b59a7 100644
--- a/doc/user/markdown.md
+++ b/doc/user/markdown.md
@@ -300,6 +300,20 @@ You can add task lists to issues, merge requests and comments. To create a task
     - [x] Sub-task 2
     - [ ] Sub-task 3
 
+Tasks formatted as ordered lists are supported as well:
+
+```no-highlight
+1. [x] Completed task
+1. [ ] Incomplete task
+    1. [ ] Sub-task 1
+    1. [x] Sub-task 2
+```
+
+1. [x] Completed task
+1. [ ] Incomplete task
+    1. [ ] Sub-task 1
+    1. [x] Sub-task 2
+
 Task lists can only be created in descriptions, not in titles. Task item state can be managed by editing the description's Markdown or by toggling the rendered check boxes.
 
 ### Videos
@@ -650,7 +664,7 @@ This line is separated from the one above by two newlines, so it will be a *sepa
 This line is also a separate paragraph, but...
 This line is only separated by a single newline, so it's a separate line in the *same paragraph*.
 
-This line is also a separate paragraph, and...  
+This line is also a separate paragraph, and...
 This line is on its own line, because the previous line ends with two
 spaces.
 ```
@@ -662,7 +676,7 @@ This line is separated from the one above by two newlines, so it will be a *sepa
 This line is also begins a separate paragraph, but...
 This line is only separated by a single newline, so it's a separate line in the *same paragraph*.
 
-This line is also a separate paragraph, and...  
+This line is also a separate paragraph, and...
 This line is on its own line, because the previous line ends with two
 spaces.
 
@@ -800,4 +814,4 @@ A link starting with a `/` is relative to the wiki root.
 [redcarpet]: https://github.com/vmg/redcarpet "Redcarpet website"
 [katex]: https://github.com/Khan/KaTeX "KaTeX website"
 [katex-subset]: https://github.com/Khan/KaTeX/wiki/Function-Support-in-KaTeX "Macros supported by KaTeX"
-[asciidoctor-manual]: http://asciidoctor.org/docs/user-manual/#activating-stem-support "Asciidoctor user manual"
\ No newline at end of file
+[asciidoctor-manual]: http://asciidoctor.org/docs/user-manual/#activating-stem-support "Asciidoctor user manual"
diff --git a/spec/features/task_lists_spec.rb b/spec/features/task_lists_spec.rb
index abb27c90e0a..a5d14aa19f1 100644
--- a/spec/features/task_lists_spec.rb
+++ b/spec/features/task_lists_spec.rb
@@ -36,6 +36,19 @@ feature 'Task Lists', feature: true do
     MARKDOWN
   end
 
+  let(:nested_tasks_markdown) do
+    <<-EOT.strip_heredoc
+    - [ ] Task a
+      - [x] Task a.1
+      - [ ] Task a.2
+    - [ ] Task b
+
+    1. [ ] Task 1
+      1. [ ] Task 1.1
+      1. [x] Task 1.2
+    EOT
+  end
+
   before do
     Warden.test_mode!
 
@@ -123,6 +136,35 @@ feature 'Task Lists', feature: true do
         expect(page).to have_content("1 of 1 task completed")
       end
     end
+
+    describe 'nested tasks', js: true do
+      let(:issue) { create(:issue, description: nested_tasks_markdown, author: user, project: project) }
+
+      before { visit_issue(project, issue) }
+
+      it 'renders' do
+        expect(page).to have_selector('ul.task-list',      count: 2)
+        expect(page).to have_selector('li.task-list-item', count: 7)
+        expect(page).to have_selector('ul input[checked]', count: 1)
+        expect(page).to have_selector('ol input[checked]', count: 1)
+      end
+
+      it 'solves tasks' do
+        expect(page).to have_content("2 of 7 tasks completed")
+
+        page.find('li.task-list-item', text: 'Task b').find('input').click
+        page.find('li.task-list-item ul li.task-list-item', text: 'Task a.2').find('input').click
+        page.find('li.task-list-item ol li.task-list-item', text: 'Task 1.1').find('input').click
+
+        expect(page).to have_content("5 of 7 tasks completed")
+
+        visit_issue(project, issue) # reload to see new system notes
+
+        expect(page).to have_content('marked the task Task b as complete')
+        expect(page).to have_content('marked the task Task a.2 as complete')
+        expect(page).to have_content('marked the task Task 1.1 as complete')
+      end
+    end
   end
 
   describe 'for Notes' do
@@ -236,7 +278,7 @@ feature 'Task Lists', feature: true do
         expect(page).to have_content("2 of 6 tasks completed")
       end
     end
-    
+
     describe 'single incomplete task' do
       let!(:merge) { create(:merge_request, :simple, description: singleIncompleteMarkdown, author: user, source_project: project) }
 
diff --git a/spec/support/taskable_shared_examples.rb b/spec/support/taskable_shared_examples.rb
index ad1c783df4d..1b6c33248c9 100644
--- a/spec/support/taskable_shared_examples.rb
+++ b/spec/support/taskable_shared_examples.rb
@@ -33,6 +33,30 @@ shared_examples 'a Taskable' do
     end
   end
 
+  describe 'with nested tasks' do
+    before do
+      subject.description = <<-EOT.strip_heredoc
+        - [ ] Task a
+          - [x] Task a.1
+          - [ ] Task a.2
+        - [ ] Task b
+
+        1. [ ] Task 1
+          1. [ ] Task 1.1
+          1. [ ] Task 1.2
+        1. [x] Task 2
+          1. [x] Task 2.1
+      EOT
+    end
+
+    it 'returns the correct task status' do
+      expect(subject.task_status).to match('3 of')
+      expect(subject.task_status).to match('9 tasks completed')
+      expect(subject.task_status_short).to match('3/')
+      expect(subject.task_status_short).to match('9 tasks')
+    end
+  end
+
   describe 'with an incomplete task' do
     before do
       subject.description = <<-EOT.strip_heredoc
-- 
GitLab