2019-01-25 20:16:51 +00:00
|
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
2019-01-24 22:13:35 +00:00
|
|
|
|
require 'spec_helper'
|
|
|
|
|
|
2020-06-24 15:08:50 +00:00
|
|
|
|
RSpec.describe TaskListToggleService do
|
2019-01-31 15:33:38 +00:00
|
|
|
|
let(:markdown) do
|
|
|
|
|
<<-EOT.strip_heredoc
|
|
|
|
|
* [ ] Task 1
|
|
|
|
|
* [x] Task 2
|
2019-01-24 22:13:35 +00:00
|
|
|
|
|
2019-01-31 15:33:38 +00:00
|
|
|
|
A paragraph
|
2019-01-24 22:13:35 +00:00
|
|
|
|
|
2019-01-31 15:33:38 +00:00
|
|
|
|
1. [X] Item 1
|
|
|
|
|
- [ ] Sub-item 1
|
2019-02-12 22:22:21 +00:00
|
|
|
|
|
|
|
|
|
- [ ] loose list
|
|
|
|
|
|
|
|
|
|
with an embedded paragraph
|
2022-04-05 12:10:23 +00:00
|
|
|
|
|
|
|
|
|
+ [ ] No-break space (U+00A0)
|
2019-01-31 15:33:38 +00:00
|
|
|
|
EOT
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
let(:markdown_html) do
|
|
|
|
|
<<-EOT.strip_heredoc
|
|
|
|
|
<ul data-sourcepos="1:1-3:0" class="task-list" dir="auto">
|
|
|
|
|
<li data-sourcepos="1:1-1:12" class="task-list-item">
|
|
|
|
|
<input type="checkbox" class="task-list-item-checkbox" disabled> Task 1
|
|
|
|
|
</li>
|
|
|
|
|
<li data-sourcepos="2:1-3:0" class="task-list-item">
|
|
|
|
|
<input type="checkbox" class="task-list-item-checkbox" disabled checked> Task 2
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
<p data-sourcepos="4:1-4:11" dir="auto">A paragraph</p>
|
2019-02-12 22:22:21 +00:00
|
|
|
|
<ol data-sourcepos="6:1-8:0" class="task-list" dir="auto">
|
|
|
|
|
<li data-sourcepos="6:1-8:0" class="task-list-item">
|
|
|
|
|
<input type="checkbox" class="task-list-item-checkbox" checked="" disabled=""> Item 1
|
|
|
|
|
<ul data-sourcepos="7:4-8:0" class="task-list">
|
|
|
|
|
<li data-sourcepos="7:4-8:0" class="task-list-item">
|
|
|
|
|
<input type="checkbox" class="task-list-item-checkbox" disabled=""> Sub-item 1
|
2019-01-31 15:33:38 +00:00
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</li>
|
|
|
|
|
</ol>
|
2022-04-05 12:10:23 +00:00
|
|
|
|
<ul data-sourcepos="9:1-12:0" class="task-list" dir="auto">
|
|
|
|
|
<li data-sourcepos="9:1-12:0" class="task-list-item">
|
2019-02-12 22:22:21 +00:00
|
|
|
|
<p data-sourcepos="9:3-9:16"><input type="checkbox" class="task-list-item-checkbox" disabled=""> loose list</p>
|
|
|
|
|
<p data-sourcepos="11:3-11:28">with an embedded paragraph</p>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
2022-04-05 12:10:23 +00:00
|
|
|
|
<ul data-sourcepos="13:1-13:21" class="task-list" dir="auto">
|
|
|
|
|
<li data-sourcepos="13:1-13:21" class="task-list-item">
|
|
|
|
|
<input type="checkbox" class="task-list-item-checkbox" disabled=""> No-break space (U+00A0)
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
2019-01-31 15:33:38 +00:00
|
|
|
|
EOT
|
|
|
|
|
end
|
|
|
|
|
|
2019-01-31 08:58:23 +00:00
|
|
|
|
it 'checks Task 1' do
|
|
|
|
|
toggler = described_class.new(markdown, markdown_html,
|
|
|
|
|
toggle_as_checked: true,
|
|
|
|
|
line_source: '* [ ] Task 1', line_number: 1)
|
2019-01-31 15:33:38 +00:00
|
|
|
|
|
2019-01-31 08:58:23 +00:00
|
|
|
|
expect(toggler.execute).to be_truthy
|
|
|
|
|
expect(toggler.updated_markdown.lines[0]).to eq "* [x] Task 1\n"
|
|
|
|
|
expect(toggler.updated_markdown_html).to include('disabled checked> Task 1')
|
|
|
|
|
end
|
2019-01-24 22:13:35 +00:00
|
|
|
|
|
2019-01-31 08:58:23 +00:00
|
|
|
|
it 'unchecks Item 1' do
|
|
|
|
|
toggler = described_class.new(markdown, markdown_html,
|
|
|
|
|
toggle_as_checked: false,
|
|
|
|
|
line_source: '1. [X] Item 1', line_number: 6)
|
2019-01-31 15:33:38 +00:00
|
|
|
|
|
2019-01-31 08:58:23 +00:00
|
|
|
|
expect(toggler.execute).to be_truthy
|
|
|
|
|
expect(toggler.updated_markdown.lines[5]).to eq "1. [ ] Item 1\n"
|
|
|
|
|
expect(toggler.updated_markdown_html).to include('disabled> Item 1')
|
|
|
|
|
end
|
2019-01-29 19:10:36 +00:00
|
|
|
|
|
2019-02-12 22:22:21 +00:00
|
|
|
|
it 'checks task in loose list' do
|
|
|
|
|
toggler = described_class.new(markdown, markdown_html,
|
|
|
|
|
toggle_as_checked: true,
|
|
|
|
|
line_source: '- [ ] loose list', line_number: 9)
|
|
|
|
|
|
|
|
|
|
expect(toggler.execute).to be_truthy
|
|
|
|
|
expect(toggler.updated_markdown.lines[8]).to eq "- [x] loose list\n"
|
|
|
|
|
expect(toggler.updated_markdown_html).to include('disabled checked> loose list')
|
|
|
|
|
end
|
|
|
|
|
|
2022-04-05 12:10:23 +00:00
|
|
|
|
it 'checks task with no-break space' do
|
|
|
|
|
toggler = described_class.new(markdown, markdown_html,
|
|
|
|
|
toggle_as_checked: true,
|
|
|
|
|
line_source: '+ [ ] No-break space (U+00A0)', line_number: 13)
|
|
|
|
|
|
|
|
|
|
expect(toggler.execute).to be_truthy
|
|
|
|
|
expect(toggler.updated_markdown.lines[12]).to eq "+ [x] No-break space (U+00A0)"
|
|
|
|
|
expect(toggler.updated_markdown_html).to include('disabled checked> No-break space (U+00A0)')
|
|
|
|
|
end
|
|
|
|
|
|
2019-01-31 08:58:23 +00:00
|
|
|
|
it 'returns false if line_source does not match the text' do
|
|
|
|
|
toggler = described_class.new(markdown, markdown_html,
|
|
|
|
|
toggle_as_checked: false,
|
|
|
|
|
line_source: '* [x] Task Added', line_number: 2)
|
2019-01-31 15:33:38 +00:00
|
|
|
|
|
2019-01-31 08:58:23 +00:00
|
|
|
|
expect(toggler.execute).to be_falsey
|
2019-01-24 22:13:35 +00:00
|
|
|
|
end
|
2019-01-31 15:33:38 +00:00
|
|
|
|
|
2019-01-30 00:31:31 +00:00
|
|
|
|
it 'tolerates \r\n line endings' do
|
|
|
|
|
rn_markdown = markdown.gsub("\n", "\r\n")
|
|
|
|
|
toggler = described_class.new(rn_markdown, markdown_html,
|
|
|
|
|
toggle_as_checked: true,
|
|
|
|
|
line_source: '* [ ] Task 1', line_number: 1)
|
|
|
|
|
|
|
|
|
|
expect(toggler.execute).to be_truthy
|
|
|
|
|
expect(toggler.updated_markdown.lines[0]).to eq "* [x] Task 1\r\n"
|
|
|
|
|
expect(toggler.updated_markdown_html).to include('disabled checked> Task 1')
|
|
|
|
|
end
|
|
|
|
|
|
2019-01-31 08:58:23 +00:00
|
|
|
|
it 'returns false if markdown is nil' do
|
|
|
|
|
toggler = described_class.new(nil, markdown_html,
|
|
|
|
|
toggle_as_checked: false,
|
|
|
|
|
line_source: '* [x] Task Added', line_number: 2)
|
|
|
|
|
|
|
|
|
|
expect(toggler.execute).to be_falsey
|
2019-01-31 15:33:38 +00:00
|
|
|
|
end
|
|
|
|
|
|
2019-01-31 08:58:23 +00:00
|
|
|
|
it 'returns false if markdown_html is nil' do
|
|
|
|
|
toggler = described_class.new(markdown, nil,
|
|
|
|
|
toggle_as_checked: false,
|
|
|
|
|
line_source: '* [x] Task Added', line_number: 2)
|
2019-01-31 15:33:38 +00:00
|
|
|
|
|
2019-01-31 08:58:23 +00:00
|
|
|
|
expect(toggler.execute).to be_falsey
|
2019-01-31 15:33:38 +00:00
|
|
|
|
end
|
2019-04-03 13:42:23 +00:00
|
|
|
|
|
2019-07-19 16:37:35 +00:00
|
|
|
|
it 'properly handles tasks in a blockquote' do
|
|
|
|
|
markdown =
|
|
|
|
|
<<-EOT.strip_heredoc
|
|
|
|
|
> > * [ ] Task 1
|
|
|
|
|
> * [x] Task 2
|
2020-08-25 12:04:30 +00:00
|
|
|
|
EOT
|
2019-07-19 16:37:35 +00:00
|
|
|
|
|
2019-12-19 18:07:48 +00:00
|
|
|
|
markdown_html = parse_markdown(markdown)
|
2019-07-19 16:37:35 +00:00
|
|
|
|
toggler = described_class.new(markdown, markdown_html,
|
|
|
|
|
toggle_as_checked: true,
|
|
|
|
|
line_source: '> > * [ ] Task 1', line_number: 1)
|
|
|
|
|
|
|
|
|
|
expect(toggler.execute).to be_truthy
|
|
|
|
|
expect(toggler.updated_markdown.lines[0]).to eq "> > * [x] Task 1\n"
|
|
|
|
|
expect(toggler.updated_markdown_html).to include('disabled checked> Task 1')
|
|
|
|
|
end
|
|
|
|
|
|
2019-04-03 13:42:23 +00:00
|
|
|
|
it 'properly handles a GitLab blockquote' do
|
|
|
|
|
markdown =
|
|
|
|
|
<<-EOT.strip_heredoc
|
|
|
|
|
>>>
|
|
|
|
|
gitlab blockquote
|
|
|
|
|
>>>
|
|
|
|
|
|
|
|
|
|
* [ ] Task 1
|
|
|
|
|
* [x] Task 2
|
2020-08-25 12:04:30 +00:00
|
|
|
|
EOT
|
2019-04-03 13:42:23 +00:00
|
|
|
|
|
2019-12-19 18:07:48 +00:00
|
|
|
|
markdown_html = parse_markdown(markdown)
|
2019-04-03 13:42:23 +00:00
|
|
|
|
toggler = described_class.new(markdown, markdown_html,
|
|
|
|
|
toggle_as_checked: true,
|
|
|
|
|
line_source: '* [ ] Task 1', line_number: 5)
|
|
|
|
|
|
|
|
|
|
expect(toggler.execute).to be_truthy
|
|
|
|
|
expect(toggler.updated_markdown.lines[4]).to eq "* [x] Task 1\n"
|
|
|
|
|
expect(toggler.updated_markdown_html).to include('disabled checked> Task 1')
|
|
|
|
|
end
|
2019-12-19 18:07:48 +00:00
|
|
|
|
|
|
|
|
|
context 'when clicking an embedded subtask' do
|
|
|
|
|
it 'properly handles it inside an unordered list' do
|
|
|
|
|
markdown =
|
|
|
|
|
<<-EOT.strip_heredoc
|
|
|
|
|
- - [ ] Task 1
|
|
|
|
|
- [x] Task 2
|
2020-08-25 12:04:30 +00:00
|
|
|
|
EOT
|
2019-12-19 18:07:48 +00:00
|
|
|
|
|
|
|
|
|
markdown_html = parse_markdown(markdown)
|
|
|
|
|
toggler = described_class.new(markdown, markdown_html,
|
|
|
|
|
toggle_as_checked: true,
|
|
|
|
|
line_source: '- - [ ] Task 1', line_number: 1)
|
|
|
|
|
|
|
|
|
|
expect(toggler.execute).to be_truthy
|
|
|
|
|
expect(toggler.updated_markdown.lines[0]).to eq "- - [x] Task 1\n"
|
|
|
|
|
expect(toggler.updated_markdown_html).to include('disabled checked> Task 1')
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'properly handles it inside an ordered list' do
|
|
|
|
|
markdown =
|
|
|
|
|
<<-EOT.strip_heredoc
|
|
|
|
|
1. - [ ] Task 1
|
|
|
|
|
- [x] Task 2
|
2020-08-25 12:04:30 +00:00
|
|
|
|
EOT
|
2019-12-19 18:07:48 +00:00
|
|
|
|
|
|
|
|
|
markdown_html = parse_markdown(markdown)
|
|
|
|
|
toggler = described_class.new(markdown, markdown_html,
|
|
|
|
|
toggle_as_checked: true,
|
|
|
|
|
line_source: '1. - [ ] Task 1', line_number: 1)
|
|
|
|
|
|
|
|
|
|
expect(toggler.execute).to be_truthy
|
|
|
|
|
expect(toggler.updated_markdown.lines[0]).to eq "1. - [x] Task 1\n"
|
|
|
|
|
expect(toggler.updated_markdown_html).to include('disabled checked> Task 1')
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def parse_markdown(markdown)
|
|
|
|
|
Banzai::Pipeline::FullPipeline.call(markdown, project: nil)[:output].to_html
|
|
|
|
|
end
|
2019-01-24 22:13:35 +00:00
|
|
|
|
end
|