diff --git a/Gemfile b/Gemfile index d7ea765b5..fd6c43127 100644 --- a/Gemfile +++ b/Gemfile @@ -36,6 +36,9 @@ gem 'rqrcode' gem "html-pipeline", "~> 2.13.2" gem "sanitize", "~> 6.0" +gem "commonmarker", '~> 2.3.0' +gem 'deckar01-task_list', '2.3.2' + # Optional gem for LDAP authentication group :ldap do gem 'net-ldap', '~> 0.17.0' @@ -46,12 +49,6 @@ group :minimagick do gem 'mini_magick', '~> 5.2.0' end -# Optional CommonMark support, not for JRuby -group :common_mark do - gem "commonmarker", '~> 2.3.0' - gem 'deckar01-task_list', '2.3.2' -end - # Include database gems for the adapters found in the database # configuration file database_file = File.join(File.dirname(__FILE__), "config/database.yml") diff --git a/lib/redmine.rb b/lib/redmine.rb index 95b3b7f3f..78a1a6d8c 100644 --- a/lib/redmine.rb +++ b/lib/redmine.rb @@ -24,11 +24,6 @@ begin rescue LoadError # MiniMagick is not available end -begin - require 'commonmarker' unless Object.const_defined?(:Commonmarker) -rescue LoadError - # CommonMarker is not available -end module Redmine end diff --git a/lib/redmine/preparation.rb b/lib/redmine/preparation.rb index 822662e11..a31204904 100644 --- a/lib/redmine/preparation.rb +++ b/lib/redmine/preparation.rb @@ -408,9 +408,7 @@ module Redmine WikiFormatting.map do |format| format.register :textile - if Object.const_defined?(:Commonmarker) - format.register :common_mark, label: 'CommonMark Markdown (GitHub Flavored)' - end + format.register :common_mark, label: 'CommonMark Markdown (GitHub Flavored)' end ActionView::Template.register_template_handler :rsb, Views::ApiTemplateHandler diff --git a/test/helpers/application_helper_test.rb b/test/helpers/application_helper_test.rb index f959744e2..e0653828e 100644 --- a/test/helpers/application_helper_test.rb +++ b/test/helpers/application_helper_test.rb @@ -252,8 +252,6 @@ class ApplicationHelperTest < Redmine::HelperTest end def test_attached_images_with_markdown_and_non_ascii_filename - skip unless Object.const_defined?(:CommonMarker) - to_test = { 'CAFÉ.JPG' => 'CAF%C3%89.JPG', 'crème.jpg' => 'cr%C3%A8me.jpg', @@ -1658,13 +1656,11 @@ class ApplicationHelperTest < Redmine::HelperTest end end - if Object.const_defined?(:Commonmarker) - def test_toc_with_markdown_formatting_should_be_parsed - with_settings :text_formatting => 'common_mark' do - assert_select_in textilizable("{{toc}}\n\n# Heading"), 'ul.toc li', :text => 'Heading' - assert_select_in textilizable("{{ 'Heading' - assert_select_in textilizable("{{>toc}}\n\n# Heading"), 'ul.toc.right li', :text => 'Heading' - end + def test_toc_with_markdown_formatting_should_be_parsed + with_settings :text_formatting => 'common_mark' do + assert_select_in textilizable("{{toc}}\n\n# Heading"), 'ul.toc li', :text => 'Heading' + assert_select_in textilizable("{{ 'Heading' + assert_select_in textilizable("{{>toc}}\n\n# Heading"), 'ul.toc.right li', :text => 'Heading' end end diff --git a/test/unit/lib/redmine/wiki_formatting/common_mark/application_helper_test.rb b/test/unit/lib/redmine/wiki_formatting/common_mark/application_helper_test.rb index 4ecc3e62a..d8e937bb1 100644 --- a/test/unit/lib/redmine/wiki_formatting/common_mark/application_helper_test.rb +++ b/test/unit/lib/redmine/wiki_formatting/common_mark/application_helper_test.rb @@ -20,63 +20,60 @@ require_relative '../../../../../test_helper' class Redmine::WikiFormatting::CommonMark::ApplicationHelperTest < Redmine::HelperTest - if Object.const_defined?(:Commonmarker) + include ERB::Util - include ERB::Util - - def setup - super - set_tmp_attachments_directory - end + def setup + super + set_tmp_attachments_directory + end - def test_attached_images_with_markdown_and_non_ascii_filename - to_test = { - 'CAFÉ.JPG' => 'CAF%C3%89.JPG', - 'crème.jpg' => 'cr%C3%A8me.jpg', - } - with_settings :text_formatting => 'common_mark' do - to_test.each do |filename, result| - attachment = Attachment.generate!(:filename => filename) - assert_include %(), textilizable("![](#{filename})", :attachments => [attachment]) - end + def test_attached_images_with_markdown_and_non_ascii_filename + to_test = { + 'CAFÉ.JPG' => 'CAF%C3%89.JPG', + 'crème.jpg' => 'cr%C3%A8me.jpg', + } + with_settings :text_formatting => 'common_mark' do + to_test.each do |filename, result| + attachment = Attachment.generate!(:filename => filename) + assert_include %(), textilizable("![](#{filename})", :attachments => [attachment]) end end + end - def test_toc_with_markdown_formatting_should_be_parsed - with_settings :text_formatting => 'common_mark' do - assert_select_in textilizable("{{toc}}\n\n# Heading"), 'ul.toc li', :text => 'Heading' - assert_select_in textilizable("{{ 'Heading' - assert_select_in textilizable("{{>toc}}\n\n# Heading"), 'ul.toc.right li', :text => 'Heading' - end + def test_toc_with_markdown_formatting_should_be_parsed + with_settings :text_formatting => 'common_mark' do + assert_select_in textilizable("{{toc}}\n\n# Heading"), 'ul.toc li', :text => 'Heading' + assert_select_in textilizable("{{ 'Heading' + assert_select_in textilizable("{{>toc}}\n\n# Heading"), 'ul.toc.right li', :text => 'Heading' end + end - def test_attached_image_alt_attribute_with_madkrown - attachments = Attachment.all - with_settings text_formatting: 'common_mark' do - # When alt text is set - assert_match %r[alt text], - textilizable('![alt text](logo.gif)', attachments: attachments) + def test_attached_image_alt_attribute_with_madkrown + attachments = Attachment.all + with_settings text_formatting: 'common_mark' do + # When alt text is set + assert_match %r[alt text], + textilizable('![alt text](logo.gif)', attachments: attachments) - # When alt text is not set - assert_match %r[This is a logo], - textilizable('![](logo.gif)', attachments: attachments) + # When alt text is not set + assert_match %r[This is a logo], + textilizable('![](logo.gif)', attachments: attachments) - # When alt text is not set and the attachment has no description - assert_match %r[], - textilizable('![](testfile.PNG)', attachments: attachments) + # When alt text is not set and the attachment has no description + assert_match %r[], + textilizable('![](testfile.PNG)', attachments: attachments) - # When no matching attachments are found - assert_match %r[], - textilizable('![](no-match.jpg)', attachments: attachments) - assert_match %r[alt text], - textilizable('![alt text](no-match.jpg)', attachments: attachments) + # When no matching attachments are found + assert_match %r[], + textilizable('![](no-match.jpg)', attachments: attachments) + assert_match %r[alt text], + textilizable('![alt text](no-match.jpg)', attachments: attachments) - # When no attachment is registered - assert_match %r[], - textilizable('![](logo.gif)', attachments: []) - assert_match %r[alt text], - textilizable('![alt text](logo.gif)', attachments: []) - end + # When no attachment is registered + assert_match %r[], + textilizable('![](logo.gif)', attachments: []) + assert_match %r[alt text], + textilizable('![alt text](logo.gif)', attachments: []) end end end diff --git a/test/unit/lib/redmine/wiki_formatting/common_mark/external_links_filter_test.rb b/test/unit/lib/redmine/wiki_formatting/common_mark/external_links_filter_test.rb index cde6381b8..c777615e4 100644 --- a/test/unit/lib/redmine/wiki_formatting/common_mark/external_links_filter_test.rb +++ b/test/unit/lib/redmine/wiki_formatting/common_mark/external_links_filter_test.rb @@ -18,48 +18,45 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. require_relative '../../../../../test_helper' +require 'redmine/wiki_formatting/common_mark/external_links_filter' -if Object.const_defined?(:Commonmarker) - require 'redmine/wiki_formatting/common_mark/external_links_filter' - - class Redmine::WikiFormatting::CommonMark::ExternalLinksFilterTest < ActiveSupport::TestCase - def filter(html) - Redmine::WikiFormatting::CommonMark::ExternalLinksFilter.to_html(html, @options) - end +class Redmine::WikiFormatting::CommonMark::ExternalLinksFilterTest < ActiveSupport::TestCase + def filter(html) + Redmine::WikiFormatting::CommonMark::ExternalLinksFilter.to_html(html, @options) + end - def setup - @options = { } - end + def setup + @options = { } + end - def test_external_links_should_have_external_css_class - assert_equal %(link), filter(%(link)) - end + def test_external_links_should_have_external_css_class + assert_equal %(link), filter(%(link)) + end - def test_locals_links_should_not_have_external_css_class - assert_equal %(home), filter(%(home)) - assert_equal %(relative), filter(%(relative)) - assert_equal %(anchor), filter(%(anchor)) - end + def test_locals_links_should_not_have_external_css_class + assert_equal %(home), filter(%(home)) + assert_equal %(relative), filter(%(relative)) + assert_equal %(anchor), filter(%(anchor)) + end - def test_mailto_links_should_have_email_class - assert_equal %(), filter(%(user)) - end + def test_mailto_links_should_have_email_class + assert_equal %(), filter(%(user)) + end - def test_malformed_uri_should_not_cause_exception - assert_nothing_raised do - filter(%(Malformed URI)) - end + def test_malformed_uri_should_not_cause_exception + assert_nothing_raised do + filter(%(Malformed URI)) end + end - def test_external_links_with_target_get_rel_noopener - assert_equal( - %(link), - filter(%(link)) - ) - assert_equal( - %(link), - filter(%(link)) - ) - end + def test_external_links_with_target_get_rel_noopener + assert_equal( + %(link), + filter(%(link)) + ) + assert_equal( + %(link), + filter(%(link)) + ) end end diff --git a/test/unit/lib/redmine/wiki_formatting/common_mark/fixup_auto_links_filter_test.rb b/test/unit/lib/redmine/wiki_formatting/common_mark/fixup_auto_links_filter_test.rb index 1b093d718..6a45c64bc 100644 --- a/test/unit/lib/redmine/wiki_formatting/common_mark/fixup_auto_links_filter_test.rb +++ b/test/unit/lib/redmine/wiki_formatting/common_mark/fixup_auto_links_filter_test.rb @@ -18,33 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. require_relative '../../../../../test_helper' +require 'redmine/wiki_formatting/common_mark/fixup_auto_links_filter' -if Object.const_defined?(:Commonmarker) - require 'redmine/wiki_formatting/common_mark/fixup_auto_links_filter' - - class Redmine::WikiFormatting::CommonMark::FixupAutoLinksFilterTest < ActiveSupport::TestCase - def filter(html) - Redmine::WikiFormatting::CommonMark::FixupAutoLinksFilter.to_html(html, @options) - end +class Redmine::WikiFormatting::CommonMark::FixupAutoLinksFilterTest < ActiveSupport::TestCase + def filter(html) + Redmine::WikiFormatting::CommonMark::FixupAutoLinksFilter.to_html(html, @options) + end - def format(markdown) - Redmine::WikiFormatting::CommonMark::MarkdownFilter.to_html(markdown, Redmine::WikiFormatting::CommonMark::PIPELINE_CONFIG) - end + def format(markdown) + Redmine::WikiFormatting::CommonMark::MarkdownFilter.to_html(markdown, Redmine::WikiFormatting::CommonMark::PIPELINE_CONFIG) + end - def setup - @options = { } - end + def setup + @options = { } + end - def test_should_fixup_autolinked_user_references - text = "user:user@example.org" - assert_equal "

#{text}

", filter(format(text)) - text = "@user@example.org" - assert_equal "

#{text}

", filter(format(text)) - end + def test_should_fixup_autolinked_user_references + text = "user:user@example.org" + assert_equal "

#{text}

", filter(format(text)) + text = "@user@example.org" + assert_equal "

#{text}

", filter(format(text)) + end - def test_should_fixup_autolinked_hires_files - text = "printscreen@2x.png" - assert_equal "

#{text}

", filter(format(text)) - end + def test_should_fixup_autolinked_hires_files + text = "printscreen@2x.png" + assert_equal "

#{text}

", filter(format(text)) end end diff --git a/test/unit/lib/redmine/wiki_formatting/common_mark/formatter_test.rb b/test/unit/lib/redmine/wiki_formatting/common_mark/formatter_test.rb index 11d5913ce..bd0b6fe38 100644 --- a/test/unit/lib/redmine/wiki_formatting/common_mark/formatter_test.rb +++ b/test/unit/lib/redmine/wiki_formatting/common_mark/formatter_test.rb @@ -20,294 +20,291 @@ require_relative '../../../../../test_helper' class Redmine::WikiFormatting::CommonMark::FormatterTest < ActionView::TestCase - if Object.const_defined?(:Commonmarker) - - def setup - @formatter = Redmine::WikiFormatting::CommonMark::Formatter - end + def setup + @formatter = Redmine::WikiFormatting::CommonMark::Formatter + end - def to_html(text) - @formatter.new(text).to_html - end + def to_html(text) + @formatter.new(text).to_html + end - def test_should_render_hard_breaks - html ="

foo
\nbar

" - assert_equal html, to_html("foo\\\nbar") - assert_equal html, to_html("foo \nbar") - end + def test_should_render_hard_breaks + html ="

foo
\nbar

" + assert_equal html, to_html("foo\\\nbar") + assert_equal html, to_html("foo \nbar") + end - def test_should_render_soft_breaks - assert_equal "

foo
\nbar

", to_html("foo\nbar") - end + def test_should_render_soft_breaks + assert_equal "

foo
\nbar

", to_html("foo\nbar") + end - def test_syntax_error_in_image_reference_should_not_raise_exception - assert to_html("!>[](foo.png)") - end + def test_syntax_error_in_image_reference_should_not_raise_exception + assert to_html("!>[](foo.png)") + end - def test_empty_image_should_not_raise_exception - assert to_html("![]()") - end + def test_empty_image_should_not_raise_exception + assert to_html("![]()") + end - def test_inline_style - assert_equal "

foo

", to_html("**foo**") - end + def test_inline_style + assert_equal "

foo

", to_html("**foo**") + end - def test_not_set_intra_emphasis - assert_equal "

foo_bar_baz

", to_html("foo_bar_baz") - end + def test_not_set_intra_emphasis + assert_equal "

foo_bar_baz

", to_html("foo_bar_baz") + end - def test_wiki_links_should_be_preserved - text = 'This is a wiki link: [[Foo]]' - assert_include '[[Foo]]', to_html(text) - end + def test_wiki_links_should_be_preserved + text = 'This is a wiki link: [[Foo]]' + assert_include '[[Foo]]', to_html(text) + end - def test_redmine_links_with_double_quotes_should_be_preserved - text = 'This is a redmine link: version:"1.0"' - assert_include 'version:"1.0"', to_html(text) - end + def test_redmine_links_with_double_quotes_should_be_preserved + text = 'This is a redmine link: version:"1.0"' + assert_include 'version:"1.0"', to_html(text) + end - def test_links_by_id_should_be_preserved - text = "[project#3]" - assert_equal "

#{text}

", to_html(text) - end + def test_links_by_id_should_be_preserved + text = "[project#3]" + assert_equal "

#{text}

", to_html(text) + end - def test_links_to_users_should_be_preserved - text = "[@login]" - assert_equal "

#{text}

", to_html(text) - text = "[user:login]" - assert_equal "

#{text}

", to_html(text) - text = "user:user@example.org" - assert_equal "

#{text}

", to_html(text) - text = "[user:user@example.org]" - assert_equal "

#{text}

", to_html(text) - text = "@user@example.org" - assert_equal "

#{text}

", to_html(text) - text = "[@user@example.org]" - assert_equal "

#{text}

", to_html(text) - end + def test_links_to_users_should_be_preserved + text = "[@login]" + assert_equal "

#{text}

", to_html(text) + text = "[user:login]" + assert_equal "

#{text}

", to_html(text) + text = "user:user@example.org" + assert_equal "

#{text}

", to_html(text) + text = "[user:user@example.org]" + assert_equal "

#{text}

", to_html(text) + text = "@user@example.org" + assert_equal "

#{text}

", to_html(text) + text = "[@user@example.org]" + assert_equal "

#{text}

", to_html(text) + end - def test_files_with_at_should_not_end_up_as_mailto_links - text = "printscreen@2x.png" - assert_equal "

#{text}

", to_html(text) - text = "[printscreen@2x.png]" - assert_equal "

#{text}

", to_html(text) - end + def test_files_with_at_should_not_end_up_as_mailto_links + text = "printscreen@2x.png" + assert_equal "

#{text}

", to_html(text) + text = "[printscreen@2x.png]" + assert_equal "

#{text}

", to_html(text) + end - def test_should_support_syntax_highlight - text = <<~STR - ~~~ruby - def foo - end - ~~~ - STR - assert_select_in to_html(text), 'pre code.ruby.syntaxhl' do - assert_select 'span.k', :text => 'def' - assert_select "[data-language='ruby']" + def test_should_support_syntax_highlight + text = <<~STR + ~~~ruby + def foo end + ~~~ + STR + assert_select_in to_html(text), 'pre code.ruby.syntaxhl' do + assert_select 'span.k', :text => 'def' + assert_select "[data-language='ruby']" end + end - def test_should_support_syntax_highlight_for_language_with_special_chars - text = <<~STR - ~~~c++ - int main() { - } - ~~~ - STR - - assert_select_in to_html(text), 'pre' do - assert_select 'code[class=?]', "c++ syntaxhl" - assert_select 'span.kt', :text => 'int' - assert_select "[data-language=?]", "c++" - end + def test_should_support_syntax_highlight_for_language_with_special_chars + text = <<~STR + ~~~c++ + int main() { + } + ~~~ + STR + + assert_select_in to_html(text), 'pre' do + assert_select 'code[class=?]', "c++ syntaxhl" + assert_select 'span.kt', :text => 'int' + assert_select "[data-language=?]", "c++" end + end - def test_external_links_should_have_external_css_class - text = 'This is a [link](http://example.net/)' - assert_equal '

This is a link

', to_html(text) - end + def test_external_links_should_have_external_css_class + text = 'This is a [link](http://example.net/)' + assert_equal '

This is a link

', to_html(text) + end - def test_locals_links_should_not_have_external_css_class - text = 'This is a [link](/issues)' - assert_equal '

This is a link

', to_html(text) - end + def test_locals_links_should_not_have_external_css_class + text = 'This is a [link](/issues)' + assert_equal '

This is a link

', to_html(text) + end - def test_markdown_should_not_require_surrounded_empty_line - text = <<-STR - This is a list: - * One - * Two - STR - assert_equal "

This is a list:

\n
    \n
  • One
  • \n
  • Two
  • \n
", to_html(text) - end + def test_markdown_should_not_require_surrounded_empty_line + text = <<~STR + This is a list: + * One + * Two + STR + assert_equal "

This is a list:

\n
    \n
  • One
  • \n
  • Two
  • \n
", to_html(text) + end - def test_footnotes - text = <<~STR - This is some text[^1]. + def test_footnotes + text = <<~STR + This is some text[^1]. - [^1]: This is the foot note - STR + [^1]: This is the foot note + STR - expected = <<~EXPECTED -

This is some text1.

-
    -
  1. -

    This is the foot note

    -
  2. -
- EXPECTED + expected = <<~EXPECTED +

This is some text1.

+
    +
  1. +

    This is the foot note

    +
  2. +
+ EXPECTED - assert_equal expected.gsub(%r{[\r\n\t]}, ''), to_html(text).gsub(%r{[\r\n\t]}, '').rstrip - end + assert_equal expected.gsub(%r{[\r\n\t]}, ''), to_html(text).gsub(%r{[\r\n\t]}, '').rstrip + end + + STR_WITH_PRE = [ + # 0 + <<~STR.chomp, + # Title - STR_WITH_PRE = [ - # 0 - <<~STR.chomp, - # Title - - Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero. - STR - # 1 - <<~STR.chomp, - ## Heading 2 - - ~~~ruby - def foo - end - ~~~ - - Morbi facilisis accumsan orci non pharetra. - - ~~~ ruby + Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero. + STR + # 1 + <<~STR.chomp, + ## Heading 2 + + ~~~ruby def foo end - ~~~ - - ``` - Pre Content: - - ## Inside pre - - inside pre block - - Morbi facilisis accumsan orci non pharetra. - ``` - STR - # 2 - <<~STR.chomp, - ### Heading 3 - - Nulla nunc nisi, egestas in ornare vel, posuere ac libero. - STR - ] - - def test_get_section_should_ignore_pre_content - text = STR_WITH_PRE.join("\n\n") - - assert_section_with_hash STR_WITH_PRE[1..2].join("\n\n"), text, 2 - assert_section_with_hash STR_WITH_PRE[2], text, 3 - end + ~~~ - def test_get_section_should_not_recognize_double_hash_issue_reference_as_heading - text = <<~STR - ## Section A + Morbi facilisis accumsan orci non pharetra. - This text is a part of Section A. + ~~~ ruby + def foo + end + ~~~ - ##1 : This is an issue reference, not an ATX heading. + ``` + Pre Content: - This text is also a part of Section A. - - STR + ## Inside pre - assert_section_with_hash text.chomp, text, 1 - end + inside pre block - def test_update_section_should_not_escape_pre_content_outside_section - text = STR_WITH_PRE.join("\n\n") - replacement = "New text" + Morbi facilisis accumsan orci non pharetra. + ``` + STR + # 2 + <<~STR.chomp, + ### Heading 3 - assert_equal [STR_WITH_PRE[0..1], "New text"].flatten.join("\n\n"), - @formatter.new(text).update_section(3, replacement) - end + Nulla nunc nisi, egestas in ornare vel, posuere ac libero. + STR + ] - def test_should_emphasize_text - text = 'This _text_ should be emphasized' - assert_equal '

This text should be emphasized

', to_html(text) - end + def test_get_section_should_ignore_pre_content + text = STR_WITH_PRE.join("\n\n") - def test_should_strike_through_text - text = 'This ~~text~~ should be striked through' - assert_equal '

This text should be striked through

', to_html(text) - end + assert_section_with_hash STR_WITH_PRE[1..2].join("\n\n"), text, 2 + assert_section_with_hash STR_WITH_PRE[2], text, 3 + end - def test_should_autolink_urls_and_emails - [ - ["http://example.org", '

http://example.org

'], - ["http://www.redmine.org/projects/redmine/issues?utf8=✓", - '

http://www.redmine.org/projects/redmine/issues?utf8=✓

'], - ['[Letters](https://yandex.ru/search/?text=кол-во)', '

Letters

'], - ["www.example.org", '

www.example.org

'], - ["user@example.org", '

'] - ].each do |text, html| - assert_equal html, to_html(text) - end - end + def test_get_section_should_not_recognize_double_hash_issue_reference_as_heading + text = <<~STR + ## Section A + + This text is a part of Section A. + + ##1 : This is an issue reference, not an ATX heading. + + This text is also a part of Section A. + + STR + + assert_section_with_hash text.chomp, text, 1 + end - def test_should_support_html_tables - text = '
Cell
' - assert_equal '
Cell
', to_html(text) + def test_update_section_should_not_escape_pre_content_outside_section + text = STR_WITH_PRE.join("\n\n") + replacement = "New text" + + assert_equal [STR_WITH_PRE[0..1], "New text"].flatten.join("\n\n"), + @formatter.new(text).update_section(3, replacement) + end + + def test_should_emphasize_text + text = 'This _text_ should be emphasized' + assert_equal '

This text should be emphasized

', to_html(text) + end + + def test_should_strike_through_text + text = 'This ~~text~~ should be striked through' + assert_equal '

This text should be striked through

', to_html(text) + end + + def test_should_autolink_urls_and_emails + [ + ["http://example.org", '

http://example.org

'], + ["http://www.redmine.org/projects/redmine/issues?utf8=✓", + '

http://www.redmine.org/projects/redmine/issues?utf8=✓

'], + ['[Letters](https://yandex.ru/search/?text=кол-во)', '

Letters

'], + ["www.example.org", '

www.example.org

'], + ["user@example.org", '

'] + ].each do |text, html| + assert_equal html, to_html(text) end + end - def test_should_remove_unsafe_uris - [ - ['', ''], - ['click me', '

click me

'], - ].each do |text, html| - assert_equal html, to_html(text) - end + def test_should_support_html_tables + text = '
Cell
' + assert_equal '
Cell
', to_html(text) + end + + def test_should_remove_unsafe_uris + [ + ['', ''], + ['click me', '

click me

'], + ].each do |text, html| + assert_equal html, to_html(text) end + end - def test_should_escape_unwanted_tags + def test_should_escape_unwanted_tags + [ [ - [ - %[

sit
amet <style>.foo { color: #fff; }</style> <script>alert("hello world");</script>

], - %[sit
amet ] - ] - ].each do |expected, input| - assert_equal expected, to_html(input) - end + %[

sit
amet <style>.foo { color: #fff; }</style> <script>alert("hello world");</script>

], + %[sit
amet ] + ] + ].each do |expected, input| + assert_equal expected, to_html(input) end + end - def test_should_support_task_list - text = <<~STR - Task list: - * [ ] Task 1 - * [x] Task 2 - STR - - expected = <<~EXPECTED -

Task list:

-
    -
  • - Task 1 -
  • -
  • - Task 2
  • -
- EXPECTED - - assert_equal expected.gsub(%r{[\r\n\t]}, ''), to_html(text).gsub(%r{[\r\n\t]}, '').rstrip - end + def test_should_support_task_list + text = <<~STR + Task list: + * [ ] Task 1 + * [x] Task 2 + STR + + expected = <<~EXPECTED +

Task list:

+
    +
  • + Task 1 +
  • +
  • + Task 2
  • +
+ EXPECTED + + assert_equal expected.gsub(%r{[\r\n\t]}, ''), to_html(text).gsub(%r{[\r\n\t]}, '').rstrip + end - private + private - def assert_section_with_hash(expected, text, index) - result = @formatter.new(text).get_section(index) + def assert_section_with_hash(expected, text, index) + result = @formatter.new(text).get_section(index) - assert_kind_of Array, result - assert_equal 2, result.size - assert_equal expected, result.first, "section content did not match" - assert_equal ActiveSupport::Digest.hexdigest(expected), result.last, "section hash did not match" - end + assert_kind_of Array, result + assert_equal 2, result.size + assert_equal expected, result.first, "section content did not match" + assert_equal ActiveSupport::Digest.hexdigest(expected), result.last, "section hash did not match" end end diff --git a/test/unit/lib/redmine/wiki_formatting/common_mark/markdown_filter_test.rb b/test/unit/lib/redmine/wiki_formatting/common_mark/markdown_filter_test.rb index d5e416d2c..28bf40581 100644 --- a/test/unit/lib/redmine/wiki_formatting/common_mark/markdown_filter_test.rb +++ b/test/unit/lib/redmine/wiki_formatting/common_mark/markdown_filter_test.rb @@ -18,18 +18,15 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. require_relative '../../../../../test_helper' +require 'redmine/wiki_formatting/common_mark/markdown_filter' -if Object.const_defined?(:Commonmarker) - require 'redmine/wiki_formatting/common_mark/markdown_filter' - - class Redmine::WikiFormatting::CommonMark::MarkdownFilterTest < ActiveSupport::TestCase - def filter(markdown) - Redmine::WikiFormatting::CommonMark::MarkdownFilter.to_html(markdown) - end +class Redmine::WikiFormatting::CommonMark::MarkdownFilterTest < ActiveSupport::TestCase + def filter(markdown) + Redmine::WikiFormatting::CommonMark::MarkdownFilter.to_html(markdown) + end - # just a basic sanity test. more formatting tests in the formatter_test - def test_should_render_markdown - assert_equal "

bold

", filter("**bold**") - end + # just a basic sanity test. more formatting tests in the formatter_test + def test_should_render_markdown + assert_equal "

bold

", filter("**bold**") end end diff --git a/test/unit/lib/redmine/wiki_formatting/common_mark/sanitization_filter_test.rb b/test/unit/lib/redmine/wiki_formatting/common_mark/sanitization_filter_test.rb index 4c0282f2d..a934c8176 100644 --- a/test/unit/lib/redmine/wiki_formatting/common_mark/sanitization_filter_test.rb +++ b/test/unit/lib/redmine/wiki_formatting/common_mark/sanitization_filter_test.rb @@ -18,216 +18,213 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. require_relative '../../../../../test_helper' +require 'redmine/wiki_formatting/common_mark/sanitization_filter' -if Object.const_defined?(:Commonmarker) - require 'redmine/wiki_formatting/common_mark/sanitization_filter' +class Redmine::WikiFormatting::CommonMark::SanitizationFilterTest < ActiveSupport::TestCase + def filter(html) + Redmine::WikiFormatting::CommonMark::SanitizationFilter.to_html(html, @options) + end - class Redmine::WikiFormatting::CommonMark::SanitizationFilterTest < ActiveSupport::TestCase - def filter(html) - Redmine::WikiFormatting::CommonMark::SanitizationFilter.to_html(html, @options) - end + def setup + @options = { } + end - def setup - @options = { } - end + def test_should_filter_tags + input = %( dont blink) + assert_equal %(foo dont blink), filter(input) + end - def test_should_filter_tags - input = %( dont blink) - assert_equal %(foo dont blink), filter(input) - end + def test_should_sanitize_attributes + input = %(link) + assert_equal %(link), filter(input) + end - def test_should_sanitize_attributes - input = %(link) - assert_equal %(link), filter(input) - end + def test_should_allow_relative_links + input = %(foo/bar) + assert_equal input, filter(input) + end - def test_should_allow_relative_links - input = %(foo/bar) - assert_equal input, filter(input) - end + def test_should_support_footnotes + input = %(foo) + assert_equal input, filter(input) + input = %(
  1. footnote
) + assert_equal input, filter(input) + end - def test_should_support_footnotes - input = %(foo) - assert_equal input, filter(input) - input = %(
  1. footnote
) - assert_equal input, filter(input) - end + def test_should_remove_invalid_ids + input = %(foo) + assert_equal %(foo), filter(input) + input = %(
  1. footnote
) + assert_equal %(
  1. footnote
), filter(input) + end - def test_should_remove_invalid_ids - input = %(foo) - assert_equal %(foo), filter(input) - input = %(
  1. footnote
) - assert_equal %(
  1. footnote
), filter(input) - end + def test_should_allow_class_on_code_only + input = %(

bar

) + assert_equal %(

bar

), filter(input) - def test_should_allow_class_on_code_only - input = %(

bar

) - assert_equal %(

bar

), filter(input) + input = %(foo) + assert_equal input, filter(input) - input = %(foo) - assert_equal input, filter(input) + input = %(foo) + assert_equal %(foo), filter(input) + end - input = %(foo) - assert_equal %(foo), filter(input) + def test_should_allow_links_with_safe_url_schemes + %w(http https ftp ssh foo).each do |scheme| + input = %(foo) + assert_equal input, filter(input) end + end - def test_should_allow_links_with_safe_url_schemes - %w(http https ftp ssh foo).each do |scheme| - input = %(foo) - assert_equal input, filter(input) - end - end + def test_should_allow_mailto_links + input = %(bar) + assert_equal input, filter(input) + end - def test_should_allow_mailto_links - input = %(bar) - assert_equal input, filter(input) - end + def test_should_remove_empty_link + input = %(bar) + assert_equal %(bar), filter(input) + input = %(bar) + assert_equal %(bar), filter(input) + end + + # samples taken from the Sanitize test suite + # rubocop:disable Layout/LineLength + STRINGS = [ + [ + 'hello"', + 'hello"' + ], + [ + '', + '' + ], + [ + 'Lorem ipsum dolor sit
amet ', + 'Lorem ipsum dolor sit
amet .foo { color: #fff; } ' + ], + [ + 'Lorem dolor sit
amet ', + 'Lorem ipsum dolor sit
amet <script>alert("hello world");' + ] + ] + # rubocop:enable Layout/LineLength - def test_should_remove_empty_link - input = %(bar) - assert_equal %(bar), filter(input) - input = %(bar) - assert_equal %(bar), filter(input) + def test_should_sanitize_html_strings + STRINGS.each do |input, expected| + assert_equal expected, filter(input) end + end + + # samples taken from the Sanitize test suite + PROTOCOLS = { + 'protocol-based JS injection: simple, no spaces' => [ + 'foo', + 'foo' + ], + + 'protocol-based JS injection: simple, spaces before' => [ + 'foo', + 'foo' + ], + + 'protocol-based JS injection: simple, spaces after' => [ + 'foo', + 'foo' + ], + + 'protocol-based JS injection: simple, spaces before and after' => [ + 'foo', + 'foo' + ], + + 'protocol-based JS injection: preceding colon' => [ + 'foo', + 'foo' + ], + + 'protocol-based JS injection: UTF-8 encoding' => [ + 'foo', + 'foo' + ], + + 'protocol-based JS injection: long UTF-8 encoding' => [ + 'foo', + 'foo' + ], - # samples taken from the Sanitize test suite # rubocop:disable Layout/LineLength - STRINGS = [ - [ - 'hello"', - 'hello"' - ], - [ - '', - '' - ], - [ - 'Lorem ipsum dolor sit
amet ', - 'Lorem ipsum dolor sit
amet .foo { color: #fff; } ' - ], - [ - 'Lorem dolor sit
amet ', - 'Lorem ipsum dolor sit
amet <script>alert("hello world");' - ] - ] + 'protocol-based JS injection: long UTF-8 encoding without semicolons' => [ + 'foo', + 'foo' + ], # rubocop:enable Layout/LineLength - def test_should_sanitize_html_strings - STRINGS.each do |input, expected| - assert_equal expected, filter(input) - end - end - - # samples taken from the Sanitize test suite - PROTOCOLS = { - 'protocol-based JS injection: simple, no spaces' => [ - 'foo', - 'foo' - ], - - 'protocol-based JS injection: simple, spaces before' => [ - 'foo', - 'foo' - ], - - 'protocol-based JS injection: simple, spaces after' => [ - 'foo', - 'foo' - ], - - 'protocol-based JS injection: simple, spaces before and after' => [ - 'foo', - 'foo' - ], - - 'protocol-based JS injection: preceding colon' => [ - 'foo', - 'foo' - ], - - 'protocol-based JS injection: UTF-8 encoding' => [ - 'foo', - 'foo' - ], - - 'protocol-based JS injection: long UTF-8 encoding' => [ - 'foo', - 'foo' - ], - - # rubocop:disable Layout/LineLength - 'protocol-based JS injection: long UTF-8 encoding without semicolons' => [ - 'foo', - 'foo' - ], - # rubocop:enable Layout/LineLength - - 'protocol-based JS injection: hex encoding' => [ - 'foo', - 'foo' - ], - - 'protocol-based JS injection: long hex encoding' => [ - 'foo', - 'foo' - ], - - 'protocol-based JS injection: hex encoding without semicolons' => [ - 'foo', - 'foo' - ], - - 'protocol-based JS injection: null char' => [ - "", - '' - # '' - ], - - 'protocol-based JS injection: invalid URL char' => [ - '', - '' - ], - - 'protocol-based JS injection: spaces and entities' => [ - '', - '' - # '' - ], - - 'protocol whitespace' => [ - '', - '' - ], - - 'data images sources' => [ - '', - '' - ], - - 'data URIs' => [ - 'XSS', - 'XSS' - ], - - 'vbscript URIs' => [ - 'XSS', - 'XSS' - ], - } - - PROTOCOLS.each do |name, strings| - test "should not allow #{name}" do - input, expected = *strings - assert_equal expected, filter(input) - end + 'protocol-based JS injection: hex encoding' => [ + 'foo', + 'foo' + ], + + 'protocol-based JS injection: long hex encoding' => [ + 'foo', + 'foo' + ], + + 'protocol-based JS injection: hex encoding without semicolons' => [ + 'foo', + 'foo' + ], + + 'protocol-based JS injection: null char' => [ + "", + '' + # '' + ], + + 'protocol-based JS injection: invalid URL char' => [ + '', + '' + ], + + 'protocol-based JS injection: spaces and entities' => [ + '', + '' + # '' + ], + + 'protocol whitespace' => [ + '', + '' + ], + + 'data images sources' => [ + '', + '' + ], + + 'data URIs' => [ + 'XSS', + 'XSS' + ], + + 'vbscript URIs' => [ + 'XSS', + 'XSS' + ], + } + + PROTOCOLS.each do |name, strings| + test "should not allow #{name}" do + input, expected = *strings + assert_equal expected, filter(input) end end end diff --git a/test/unit/lib/redmine/wiki_formatting/common_mark/syntax_highlight_filter_test.rb b/test/unit/lib/redmine/wiki_formatting/common_mark/syntax_highlight_filter_test.rb index 70cc95301..5d7479dda 100644 --- a/test/unit/lib/redmine/wiki_formatting/common_mark/syntax_highlight_filter_test.rb +++ b/test/unit/lib/redmine/wiki_formatting/common_mark/syntax_highlight_filter_test.rb @@ -18,72 +18,70 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. require_relative '../../../../../test_helper' -if Object.const_defined?(:Commonmarker) - require 'redmine/wiki_formatting/common_mark/syntax_highlight_filter' +require 'redmine/wiki_formatting/common_mark/syntax_highlight_filter' - class Redmine::WikiFormatting::CommonMark::SyntaxHighlightFilterTest < ActiveSupport::TestCase - def filter(html) - Redmine::WikiFormatting::CommonMark::SyntaxHighlightFilter.to_html(html, @options) - end +class Redmine::WikiFormatting::CommonMark::SyntaxHighlightFilterTest < ActiveSupport::TestCase + def filter(html) + Redmine::WikiFormatting::CommonMark::SyntaxHighlightFilter.to_html(html, @options) + end - def setup - @options = { } - end + def setup + @options = { } + end - def test_should_highlight_supported_language - input = <<~HTML -

-        def foo
-        end
-        
- HTML - expected = <<~HTML -

-        def foo
-        end
-        
- HTML - assert_equal expected, filter(input) - end + def test_should_highlight_supported_language + input = <<~HTML +

+      def foo
+      end
+      
+ HTML + expected = <<~HTML +

+      def foo
+      end
+      
+ HTML + assert_equal expected, filter(input) + end - def test_should_highlight_supported_language_with_special_chars - input = <<~HTML -

-        int i;
-        
- HTML - expected = <<~HTML -

-        int i;
-        
- HTML - assert_equal expected, filter(input) - end + def test_should_highlight_supported_language_with_special_chars + input = <<~HTML +

+      int i;
+      
+ HTML + expected = <<~HTML +

+      int i;
+      
+ HTML + assert_equal expected, filter(input) + end - def test_should_strip_code_class_and_preserve_data_language_attr_for_unknown_language - input = <<~HTML -

-        def foo
-        end
-        
- HTML - expected = <<~HTML -

-        def foo
-        end
-        
- HTML - assert_equal expected, filter(input) - end + def test_should_strip_code_class_and_preserve_data_language_attr_for_unknown_language + input = <<~HTML +

+      def foo
+      end
+      
+ HTML + expected = <<~HTML +

+      def foo
+      end
+      
+ HTML + assert_equal expected, filter(input) + end - def test_should_ignore_code_without_class - input = <<~HTML -

-        def foo
-        end
-        
- HTML - assert_equal input, filter(input) - end + def test_should_ignore_code_without_class + input = <<~HTML +

+      def foo
+      end
+      
+ HTML + assert_equal input, filter(input) end end