diff test/unit/helpers/application_helper_test.rb @ 524:1248a47e81b3 feature_36

Merge from branch "luisf"
author luisf <luis.figueira@eecs.qmul.ac.uk>
date Mon, 25 Jul 2011 14:39:38 +0100
parents 753f1380d6bc
children 5e80956cc792
line wrap: on
line diff
--- a/test/unit/helpers/application_helper_test.rb	Fri Jul 15 17:21:05 2011 +0100
+++ b/test/unit/helpers/application_helper_test.rb	Mon Jul 25 14:39:38 2011 +0100
@@ -1,26 +1,26 @@
 # Redmine - project management software
-# Copyright (C) 2006-2010  Jean-Philippe Lang
+# Copyright (C) 2006-2011  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
 # as published by the Free Software Foundation; either version 2
 # of the License, or (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
-require File.dirname(__FILE__) + '/../../test_helper'
+require File.expand_path('../../../test_helper', __FILE__)
 
 class ApplicationHelperTest < ActionView::TestCase
-  
+
   fixtures :projects, :roles, :enabled_modules, :users,
-                      :repositories, :changesets, 
+                      :repositories, :changesets,
                       :trackers, :issue_statuses, :issues, :versions, :documents,
                       :wikis, :wiki_pages, :wiki_contents,
                       :boards, :messages,
@@ -35,11 +35,11 @@
     context "authorized user" do
       should "be tested"
     end
-    
+
     context "unauthorized user" do
       should "be tested"
     end
-    
+
     should "allow using the :controller and :action for the target link" do
       User.current = User.find_by_login('admin')
 
@@ -48,9 +48,9 @@
                                        {:controller => 'issues', :action => 'edit', :id => Issue.first.id})
       assert_match /href/, response
     end
-    
+
   end
-  
+
   def test_auto_links
     to_test = {
       'http://foo.bar' => '<a class="external" href="http://foo.bar">http://foo.bar</a>',
@@ -84,12 +84,12 @@
     }
     to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
   end
-  
+
   def test_auto_mailto
-    assert_equal '<p><a class="email" href="mailto:test@foo.bar">test@foo.bar</a></p>', 
+    assert_equal '<p><a class="email" href="mailto:test@foo.bar">test@foo.bar</a></p>',
       textilizable('test@foo.bar')
   end
-  
+
   def test_inline_images
     to_test = {
       '!http://foo.bar/image.jpg!' => '<img src="http://foo.bar/image.jpg" alt="" />',
@@ -102,7 +102,7 @@
     }
     to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
   end
-  
+
   def test_inline_images_inside_tags
     raw = <<-RAW
 h1. !foo.png! Heading
@@ -115,7 +115,7 @@
     assert textilizable(raw).include?('<img src="foo.png" alt="" />')
     assert textilizable(raw).include?('<img src="bar.gif" alt="" />')
   end
-  
+
   def test_attached_images
     to_test = {
       'Inline image: !logo.gif!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
@@ -128,7 +128,7 @@
     attachments = Attachment.find(:all)
     to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
   end
-  
+
   def test_textile_external_links
     to_test = {
       'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
@@ -147,29 +147,29 @@
     }
     to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
   end
-  
+
   def test_redmine_links
-    issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3}, 
+    issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
                                :class => 'issue status-1 priority-1 overdue', :title => 'Error 281 when updating a recipe (New)')
-    
+
     changeset_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
                                    :class => 'changeset', :title => 'My very first commit')
     changeset_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
                                     :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
-    
+
     document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
                                              :class => 'document')
-    
+
     version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
                                   :class => 'version')
 
     message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
-    
+
     project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
-    
+
     source_url = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}
     source_url_with_ext = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file.ext']}
-    
+
     to_test = {
       # tickets
       '#3, [#3], (#3) and #3.'      => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
@@ -200,7 +200,7 @@
       'export:/some/file'           => link_to('export:/some/file', source_url.merge(:format => 'raw'), :class => 'source download'),
       # message
       'message#4'                   => link_to('Post 2', message_url, :class => 'message'),
-      'message#5'                   => link_to('RE: post 2', message_url.merge(:anchor => 'message-5'), :class => 'message'),
+      'message#5'                   => link_to('RE: post 2', message_url.merge(:anchor => 'message-5', :r => 5), :class => 'message'),
       # project
       'project#3'                   => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
       'project:subproject1'         => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
@@ -224,7 +224,120 @@
     @project = Project.find(1)
     to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
   end
-  
+
+  def test_cross_project_redmine_links
+    source_link = link_to('ecookbook:source:/some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']},
+      :class => 'source')
+
+    changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
+      :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
+
+    to_test = {
+      # documents
+      'document:"Test document"'              => 'document:"Test document"',
+      'ecookbook:document:"Test document"'    => '<a href="/documents/1" class="document">Test document</a>',
+      'invalid:document:"Test document"'      => 'invalid:document:"Test document"',
+      # versions
+      'version:"1.0"'                         => 'version:"1.0"',
+      'ecookbook:version:"1.0"'               => '<a href="/versions/show/2" class="version">1.0</a>',
+      'invalid:version:"1.0"'                 => 'invalid:version:"1.0"',
+      # changeset
+      'r2'                                    => 'r2',
+      'ecookbook:r2'                          => changeset_link,
+      'invalid:r2'                            => 'invalid:r2',
+      # source
+      'source:/some/file'                     => 'source:/some/file',
+      'ecookbook:source:/some/file'           => source_link,
+      'invalid:source:/some/file'             => 'invalid:source:/some/file',
+    }
+    @project = Project.find(3)
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
+  end
+
+  def test_redmine_links_git_commit
+    changeset_link = link_to('abcd',
+                               {
+                                 :controller => 'repositories',
+                                 :action     => 'revision',
+                                 :id         => 'subproject1',
+                                 :rev        => 'abcd',
+                                },
+                              :class => 'changeset', :title => 'test commit')
+    to_test = {
+      'commit:abcd' => changeset_link,
+     }
+    @project = Project.find(3)
+    r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
+    assert r
+    c = Changeset.new(:repository => r,
+                      :committed_on => Time.now,
+                      :revision => 'abcd',
+                      :scmid => 'abcd',
+                      :comments => 'test commit')
+    assert( c.save )
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
+  end
+
+  # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
+  def test_redmine_links_darcs_commit
+    changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
+                               {
+                                 :controller => 'repositories',
+                                 :action     => 'revision',
+                                 :id         => 'subproject1',
+                                 :rev        => '123',
+                                },
+                              :class => 'changeset', :title => 'test commit')
+    to_test = {
+      'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
+     }
+    @project = Project.find(3)
+    r = Repository::Darcs.create!(
+            :project => @project, :url => '/tmp/test/darcs',
+            :log_encoding => 'UTF-8')
+    assert r
+    c = Changeset.new(:repository => r,
+                      :committed_on => Time.now,
+                      :revision => '123',
+                      :scmid => '20080308225258-98289-abcd456efg.gz',
+                      :comments => 'test commit')
+    assert( c.save )
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
+  end
+
+  def test_redmine_links_mercurial_commit
+    changeset_link_rev = link_to('r123',
+                                  {
+                                     :controller => 'repositories',
+                                     :action     => 'revision',
+                                     :id         => 'subproject1',
+                                     :rev        => '123' ,
+                                  },
+                              :class => 'changeset', :title => 'test commit')
+    changeset_link_commit = link_to('abcd',
+                                  {
+                                        :controller => 'repositories',
+                                        :action     => 'revision',
+                                        :id         => 'subproject1',
+                                        :rev        => 'abcd' ,
+                                  },
+                              :class => 'changeset', :title => 'test commit')
+    to_test = {
+      'r123' => changeset_link_rev,
+      'commit:abcd' => changeset_link_commit,
+     }
+    @project = Project.find(3)
+    r = Repository::Mercurial.create!(:project => @project, :url => '/tmp/test')
+    assert r
+    c = Changeset.new(:repository => r,
+                      :committed_on => Time.now,
+                      :revision => '123',
+                      :scmid => 'abcd',
+                      :comments => 'test commit')
+    assert( c.save )
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
+  end
+
   def test_attachment_links
     attachment_link = link_to('error281.txt', {:controller => 'attachments', :action => 'download', :id => '1'}, :class => 'attachment')
     to_test = {
@@ -232,7 +345,7 @@
     }
     to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
   end
-  
+
   def test_wiki_links
     to_test = {
       '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
@@ -261,7 +374,7 @@
     @project = Project.find(1)
     to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
   end
-  
+
   def test_html_tags
     to_test = {
       "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
@@ -275,11 +388,17 @@
       "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
       # remove attributes except class
       "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
+      '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
+      "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
+      '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
       "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
+      # xss
+      '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
+      '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
     }
     to_test.each { |text, result| assert_equal result, textilizable(text) }
   end
-  
+
   def test_allowed_html_tags
     to_test = {
       "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
@@ -288,7 +407,7 @@
     }
     to_test.each { |text, result| assert_equal result, textilizable(text) }
   end
-  
+
   def test_pre_tags
     raw = <<-RAW
 Before
@@ -307,10 +426,10 @@
 </pre>
 <p>After</p>
 EXPECTED
-    
+
     assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
   end
-  
+
   def test_pre_content_should_not_parse_wiki_and_redmine_links
     raw = <<-RAW
 [[CookBook documentation]]
@@ -333,11 +452,11 @@
 #1
 </pre>
 EXPECTED
-                                 
+
     @project = Project.find(1)
     assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
   end
-  
+
   def test_non_closing_pre_blocks_should_be_closed
     raw = <<-RAW
 <pre><code>
@@ -347,11 +466,11 @@
 <pre><code>
 </code></pre>
 EXPECTED
-                                 
+
     @project = Project.find(1)
     assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
   end
-  
+
   def test_syntax_highlight
     raw = <<-RAW
 <pre><code class="ruby">
@@ -366,7 +485,7 @@
 
     assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
   end
-  
+
   def test_wiki_links_in_tables
     to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
                  '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
@@ -376,7 +495,7 @@
     @project = Project.find(1)
     to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
   end
-  
+
   def test_text_formatting
     to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
                '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
@@ -386,12 +505,12 @@
               }
     to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
   end
-  
+
   def test_wiki_horizontal_rule
     assert_equal '<hr />', textilizable('---')
     assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
   end
-  
+
   def test_footnotes
     raw = <<-RAW
 This is some text[1].
@@ -406,7 +525,14 @@
 
     assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
   end
-  
+
+  def test_headings
+    raw = 'h1. Some heading'
+    expected = %|<a name="Some-heading"></a>\n<h1 >Some heading<a href="#Some-heading" class="wiki-anchor">&para;</a></h1>|
+
+    assert_equal expected, textilizable(raw)
+  end
+
   def test_table_of_content
     raw = <<-RAW
 {{toc}}
@@ -422,7 +548,11 @@
 h2. Subtitle with [[Wiki|another Wiki]] link
 
 h2. Subtitle with %{color:red}red text%
-    
+
+<pre>
+some code
+</pre>
+
 h3. Subtitle with *some* _modifiers_
 
 h1. Another title
@@ -436,8 +566,8 @@
     expected =  '<ul class="toc">' +
                   '<li><a href="#Title">Title</a>' +
                     '<ul>' +
-                      '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' + 
-                      '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' + 
+                      '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
+                      '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
                       '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
                         '<ul>' +
                           '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
@@ -458,9 +588,9 @@
                '</ul>'
 
     @project = Project.find(1)
-    assert textilizable(raw).gsub("\n", "").include?(expected)
+    assert textilizable(raw).gsub("\n", "").include?(expected), textilizable(raw)
   end
-  
+
   def test_table_of_content_should_contain_included_page_headings
     raw = <<-RAW
 {{toc}}
@@ -472,125 +602,20 @@
 
     expected = '<ul class="toc">' +
                '<li><a href="#Included">Included</a></li>' +
-               '<li><a href="#Child-page-1">Child page 1</a></li>' + 
+               '<li><a href="#Child-page-1">Child page 1</a></li>' +
                '</ul>'
 
     @project = Project.find(1)
     assert textilizable(raw).gsub("\n", "").include?(expected)
   end
-  
-  def test_blockquote
-    # orig raw text
-    raw = <<-RAW
-John said:
-> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
-> Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
-> * Donec odio lorem,
-> * sagittis ac,
-> * malesuada in,
-> * adipiscing eu, dolor.
->
-> >Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.
-> Proin a tellus. Nam vel neque.
 
-He's right.
-RAW
-    
-    # expected html
-    expected = <<-EXPECTED
-<p>John said:</p>
-<blockquote>
-Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
-Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
-<ul>
-  <li>Donec odio lorem,</li>
-  <li>sagittis ac,</li>
-  <li>malesuada in,</li>
-  <li>adipiscing eu, dolor.</li>
-</ul>
-<blockquote>
-<p>Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.</p>
-</blockquote>
-<p>Proin a tellus. Nam vel neque.</p>
-</blockquote>
-<p>He's right.</p>
-EXPECTED
-    
-    assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
-  end
-  
-  def test_table
-    raw = <<-RAW
-This is a table with empty cells:
-
-|cell11|cell12||
-|cell21||cell23|
-|cell31|cell32|cell33|
-RAW
-
-    expected = <<-EXPECTED
-<p>This is a table with empty cells:</p>
-
-<table>
-  <tr><td>cell11</td><td>cell12</td><td></td></tr>
-  <tr><td>cell21</td><td></td><td>cell23</td></tr>
-  <tr><td>cell31</td><td>cell32</td><td>cell33</td></tr>
-</table>
-EXPECTED
-
-    assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
-  end
-  
-  def test_table_with_line_breaks
-    raw = <<-RAW
-This is a table with line breaks:
-
-|cell11
-continued|cell12||
-|-cell21-||cell23
-cell23 line2
-cell23 *line3*|
-|cell31|cell32
-cell32 line2|cell33|
-
-RAW
-
-    expected = <<-EXPECTED
-<p>This is a table with line breaks:</p>
-
-<table>
-  <tr>
-    <td>cell11<br />continued</td>
-    <td>cell12</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td><del>cell21</del></td>
-    <td></td>
-    <td>cell23<br/>cell23 line2<br/>cell23 <strong>line3</strong></td>
-  </tr>
-  <tr>
-    <td>cell31</td>
-    <td>cell32<br/>cell32 line2</td>
-    <td>cell33</td>
-  </tr>
-</table>
-EXPECTED
-
-    assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
-  end
-  
-  def test_textile_should_not_mangle_brackets
-    assert_equal '<p>[msg1][msg2]</p>', textilizable('[msg1][msg2]')
-  end
-  
   def test_default_formatter
     Setting.text_formatting = 'unknown'
     text = 'a *link*: http://www.example.net/'
     assert_equal '<p>a *link*: <a href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
     Setting.text_formatting = 'textile'
   end
-  
+
   def test_due_date_distance_in_words
     to_test = { Date.today => 'Due in 0 days',
                 Date.today + 1 => 'Due in 1 day',
@@ -600,11 +625,12 @@
                 Date.today - 100 => 'about 3 months late',
                 Date.today - 20000 => 'over 54 years late',
                }
+    ::I18n.locale = :en
     to_test.each do |date, expected|
       assert_equal expected, due_date_distance_in_words(date)
     end
   end
-  
+
   def test_avatar
     # turn on avatars
     Setting.gravatar_enabled = '1'
@@ -612,25 +638,25 @@
     assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
     assert_nil avatar('jsmith')
     assert_nil avatar(nil)
-    
+
     # turn off avatars
     Setting.gravatar_enabled = '0'
     assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
   end
-  
+
   def test_link_to_user
     user = User.find(2)
     t = link_to_user(user)
     assert_equal "<a href=\"/users/2\">#{ user.name }</a>", t
   end
-                                      
+
   def test_link_to_user_should_not_link_to_locked_user
     user = User.find(5)
     assert user.locked?
     t = link_to_user(user)
     assert_equal user.name, t
   end
-                                                                          
+
   def test_link_to_user_should_not_link_to_anonymous
     user = User.anonymous
     assert user.anonymous?