annotate test/unit/helpers/application_helper_test.rb @ 8:0c83d98252d9 yuya

* Add custom repo prefix and proper auth realm, remove auth cache (seems like an unwise feature), pass DB handle around, various other bits of tidying
author Chris Cannam
date Thu, 12 Aug 2010 15:31:37 +0100
parents 513646585e45
children 1d32c0a0efbf
rev   line source
Chris@0 1 # Redmine - project management software
Chris@0 2 # Copyright (C) 2006-2009 Jean-Philippe Lang
Chris@0 3 #
Chris@0 4 # This program is free software; you can redistribute it and/or
Chris@0 5 # modify it under the terms of the GNU General Public License
Chris@0 6 # as published by the Free Software Foundation; either version 2
Chris@0 7 # of the License, or (at your option) any later version.
Chris@0 8 #
Chris@0 9 # This program is distributed in the hope that it will be useful,
Chris@0 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@0 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@0 12 # GNU General Public License for more details.
Chris@0 13 #
Chris@0 14 # You should have received a copy of the GNU General Public License
Chris@0 15 # along with this program; if not, write to the Free Software
Chris@0 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Chris@0 17
Chris@0 18 require File.dirname(__FILE__) + '/../../test_helper'
Chris@0 19
Chris@0 20 class ApplicationHelperTest < HelperTestCase
Chris@0 21 include ApplicationHelper
Chris@0 22 include ActionView::Helpers::TextHelper
Chris@0 23 include ActionView::Helpers::DateHelper
Chris@0 24
Chris@0 25 fixtures :projects, :roles, :enabled_modules, :users,
Chris@0 26 :repositories, :changesets,
Chris@0 27 :trackers, :issue_statuses, :issues, :versions, :documents,
Chris@0 28 :wikis, :wiki_pages, :wiki_contents,
Chris@0 29 :boards, :messages,
Chris@0 30 :attachments,
Chris@0 31 :enumerations
Chris@0 32
Chris@0 33 def setup
Chris@0 34 super
Chris@0 35 end
Chris@0 36
Chris@0 37 def test_auto_links
Chris@0 38 to_test = {
Chris@0 39 'http://foo.bar' => '<a class="external" href="http://foo.bar">http://foo.bar</a>',
Chris@0 40 'http://foo.bar/~user' => '<a class="external" href="http://foo.bar/~user">http://foo.bar/~user</a>',
Chris@0 41 'http://foo.bar.' => '<a class="external" href="http://foo.bar">http://foo.bar</a>.',
Chris@0 42 'https://foo.bar.' => '<a class="external" href="https://foo.bar">https://foo.bar</a>.',
Chris@0 43 'This is a link: http://foo.bar.' => 'This is a link: <a class="external" href="http://foo.bar">http://foo.bar</a>.',
Chris@0 44 'A link (eg. http://foo.bar).' => 'A link (eg. <a class="external" href="http://foo.bar">http://foo.bar</a>).',
Chris@0 45 'http://foo.bar/foo.bar#foo.bar.' => '<a class="external" href="http://foo.bar/foo.bar#foo.bar">http://foo.bar/foo.bar#foo.bar</a>.',
Chris@0 46 'http://www.foo.bar/Test_(foobar)' => '<a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>',
Chris@0 47 '(see inline link : http://www.foo.bar/Test_(foobar))' => '(see inline link : <a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>)',
Chris@0 48 '(see inline link : http://www.foo.bar/Test)' => '(see inline link : <a class="external" href="http://www.foo.bar/Test">http://www.foo.bar/Test</a>)',
Chris@0 49 '(see inline link : http://www.foo.bar/Test).' => '(see inline link : <a class="external" href="http://www.foo.bar/Test">http://www.foo.bar/Test</a>).',
Chris@0 50 '(see "inline link":http://www.foo.bar/Test_(foobar))' => '(see <a href="http://www.foo.bar/Test_(foobar)" class="external">inline link</a>)',
Chris@0 51 '(see "inline link":http://www.foo.bar/Test)' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>)',
Chris@0 52 '(see "inline link":http://www.foo.bar/Test).' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>).',
Chris@0 53 'www.foo.bar' => '<a class="external" href="http://www.foo.bar">www.foo.bar</a>',
Chris@0 54 'http://foo.bar/page?p=1&t=z&s=' => '<a class="external" href="http://foo.bar/page?p=1&#38;t=z&#38;s=">http://foo.bar/page?p=1&#38;t=z&#38;s=</a>',
Chris@0 55 'http://foo.bar/page#125' => '<a class="external" href="http://foo.bar/page#125">http://foo.bar/page#125</a>',
Chris@0 56 'http://foo@www.bar.com' => '<a class="external" href="http://foo@www.bar.com">http://foo@www.bar.com</a>',
Chris@0 57 'http://foo:bar@www.bar.com' => '<a class="external" href="http://foo:bar@www.bar.com">http://foo:bar@www.bar.com</a>',
Chris@0 58 'ftp://foo.bar' => '<a class="external" href="ftp://foo.bar">ftp://foo.bar</a>',
Chris@0 59 'ftps://foo.bar' => '<a class="external" href="ftps://foo.bar">ftps://foo.bar</a>',
Chris@0 60 'sftp://foo.bar' => '<a class="external" href="sftp://foo.bar">sftp://foo.bar</a>',
Chris@0 61 # two exclamation marks
Chris@0 62 'http://example.net/path!602815048C7B5C20!302.html' => '<a class="external" href="http://example.net/path!602815048C7B5C20!302.html">http://example.net/path!602815048C7B5C20!302.html</a>',
Chris@0 63 # escaping
Chris@0 64 'http://foo"bar' => '<a class="external" href="http://foo&quot;bar">http://foo"bar</a>',
Chris@0 65 }
Chris@0 66 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
Chris@0 67 end
Chris@0 68
Chris@0 69 def test_auto_mailto
Chris@0 70 assert_equal '<p><a class="email" href="mailto:test@foo.bar">test@foo.bar</a></p>',
Chris@0 71 textilizable('test@foo.bar')
Chris@0 72 end
Chris@0 73
Chris@0 74 def test_inline_images
Chris@0 75 to_test = {
Chris@0 76 '!http://foo.bar/image.jpg!' => '<img src="http://foo.bar/image.jpg" alt="" />',
Chris@0 77 'floating !>http://foo.bar/image.jpg!' => 'floating <div style="float:right"><img src="http://foo.bar/image.jpg" alt="" /></div>',
Chris@0 78 'with class !(some-class)http://foo.bar/image.jpg!' => 'with class <img src="http://foo.bar/image.jpg" class="some-class" alt="" />',
Chris@0 79 # inline styles should be stripped
Chris@0 80 'with style !{width:100px;height100px}http://foo.bar/image.jpg!' => 'with style <img src="http://foo.bar/image.jpg" alt="" />',
Chris@0 81 'with title !http://foo.bar/image.jpg(This is a title)!' => 'with title <img src="http://foo.bar/image.jpg" title="This is a title" alt="This is a title" />',
Chris@0 82 'with title !http://foo.bar/image.jpg(This is a double-quoted "title")!' => 'with title <img src="http://foo.bar/image.jpg" title="This is a double-quoted &quot;title&quot;" alt="This is a double-quoted &quot;title&quot;" />',
Chris@0 83 }
Chris@0 84 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
Chris@0 85 end
Chris@0 86
Chris@0 87 def test_inline_images_inside_tags
Chris@0 88 raw = <<-RAW
Chris@0 89 h1. !foo.png! Heading
Chris@0 90
Chris@0 91 Centered image:
Chris@0 92
Chris@0 93 p=. !bar.gif!
Chris@0 94 RAW
Chris@0 95
Chris@0 96 assert textilizable(raw).include?('<img src="foo.png" alt="" />')
Chris@0 97 assert textilizable(raw).include?('<img src="bar.gif" alt="" />')
Chris@0 98 end
Chris@0 99
Chris@0 100 def test_acronyms
Chris@0 101 to_test = {
Chris@0 102 'this is an acronym: GPL(General Public License)' => 'this is an acronym: <acronym title="General Public License">GPL</acronym>',
Chris@0 103 'GPL(This is a double-quoted "title")' => '<acronym title="This is a double-quoted &quot;title&quot;">GPL</acronym>',
Chris@0 104 }
Chris@0 105 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
Chris@0 106
Chris@0 107 end
Chris@0 108
Chris@0 109 def test_attached_images
Chris@0 110 to_test = {
Chris@0 111 'Inline image: !logo.gif!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
Chris@0 112 'Inline image: !logo.GIF!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
Chris@0 113 'No match: !ogo.gif!' => 'No match: <img src="ogo.gif" alt="" />',
Chris@0 114 'No match: !ogo.GIF!' => 'No match: <img src="ogo.GIF" alt="" />',
Chris@0 115 # link image
Chris@0 116 '!logo.gif!:http://foo.bar/' => '<a href="http://foo.bar/"><img src="/attachments/download/3" title="This is a logo" alt="This is a logo" /></a>',
Chris@0 117 }
Chris@0 118 attachments = Attachment.find(:all)
Chris@0 119 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
Chris@0 120 end
Chris@0 121
Chris@0 122 def test_textile_external_links
Chris@0 123 to_test = {
Chris@0 124 'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
Chris@0 125 'This is an intern "link":/foo/bar' => 'This is an intern <a href="/foo/bar">link</a>',
Chris@0 126 '"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>',
Chris@0 127 '"link (Link title with "double-quotes")":http://foo.bar' => '<a href="http://foo.bar" title="Link title with &quot;double-quotes&quot;" class="external">link</a>',
Chris@0 128 "This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":</p>\n\n\n\t<p>Another paragraph",
Chris@0 129 # no multiline link text
Chris@0 130 "This is a double quote \"on the first line\nand another on a second line\":test" => "This is a double quote \"on the first line<br />and another on a second line\":test",
Chris@0 131 # mailto link
Chris@0 132 "\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "<a href=\"mailto:sysadmin@example.com?subject=redmine%20permissions\">system administrator</a>",
Chris@0 133 # two exclamation marks
Chris@0 134 '"a link":http://example.net/path!602815048C7B5C20!302.html' => '<a href="http://example.net/path!602815048C7B5C20!302.html" class="external">a link</a>',
Chris@0 135 # escaping
Chris@0 136 '"test":http://foo"bar' => '<a href="http://foo&quot;bar" class="external">test</a>',
Chris@0 137 }
Chris@0 138 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
Chris@0 139 end
Chris@0 140
Chris@0 141 def test_redmine_links
Chris@0 142 issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
Chris@0 143 :class => 'issue status-1 priority-1 overdue', :title => 'Error 281 when updating a recipe (New)')
Chris@0 144
Chris@0 145 changeset_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
Chris@0 146 :class => 'changeset', :title => 'My very first commit')
Chris@0 147 changeset_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
Chris@0 148 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
Chris@0 149
Chris@0 150 document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
Chris@0 151 :class => 'document')
Chris@0 152
Chris@0 153 version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
Chris@0 154 :class => 'version')
Chris@0 155
Chris@0 156 message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
Chris@0 157
Chris@0 158 project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
Chris@0 159
Chris@0 160 source_url = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}
Chris@0 161 source_url_with_ext = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file.ext']}
Chris@0 162
Chris@0 163 to_test = {
Chris@0 164 # tickets
Chris@0 165 '#3, [#3], (#3) and #3.' => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
Chris@0 166 # changesets
Chris@0 167 'r1' => changeset_link,
Chris@0 168 'r1.' => "#{changeset_link}.",
Chris@0 169 'r1, r2' => "#{changeset_link}, #{changeset_link2}",
Chris@0 170 'r1,r2' => "#{changeset_link},#{changeset_link2}",
Chris@0 171 # documents
Chris@0 172 'document#1' => document_link,
Chris@0 173 'document:"Test document"' => document_link,
Chris@0 174 # versions
Chris@0 175 'version#2' => version_link,
Chris@0 176 'version:1.0' => version_link,
Chris@0 177 'version:"1.0"' => version_link,
Chris@0 178 # source
Chris@0 179 'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'),
Chris@0 180 'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".",
Chris@0 181 'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
Chris@0 182 'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".",
Chris@0 183 'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
Chris@0 184 'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",",
Chris@0 185 'source:/some/file@52' => link_to('source:/some/file@52', source_url.merge(:rev => 52), :class => 'source'),
Chris@0 186 'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_ext.merge(:rev => 52), :class => 'source'),
Chris@0 187 'source:/some/file#L110' => link_to('source:/some/file#L110', source_url.merge(:anchor => 'L110'), :class => 'source'),
Chris@0 188 'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext.merge(:anchor => 'L110'), :class => 'source'),
Chris@0 189 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url.merge(:rev => 52, :anchor => 'L110'), :class => 'source'),
Chris@0 190 'export:/some/file' => link_to('export:/some/file', source_url.merge(:format => 'raw'), :class => 'source download'),
Chris@0 191 # message
Chris@0 192 'message#4' => link_to('Post 2', message_url, :class => 'message'),
Chris@0 193 'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5'), :class => 'message'),
Chris@0 194 # project
Chris@0 195 'project#3' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
Chris@0 196 'project:subproject1' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
Chris@0 197 'project:"eCookbook subProject 1"' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
Chris@0 198 # escaping
Chris@0 199 '!#3.' => '#3.',
Chris@0 200 '!r1' => 'r1',
Chris@0 201 '!document#1' => 'document#1',
Chris@0 202 '!document:"Test document"' => 'document:"Test document"',
Chris@0 203 '!version#2' => 'version#2',
Chris@0 204 '!version:1.0' => 'version:1.0',
Chris@0 205 '!version:"1.0"' => 'version:"1.0"',
Chris@0 206 '!source:/some/file' => 'source:/some/file',
Chris@0 207 # not found
Chris@0 208 '#0123456789' => '#0123456789',
Chris@0 209 # invalid expressions
Chris@0 210 'source:' => 'source:',
Chris@0 211 # url hash
Chris@0 212 "http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
Chris@0 213 }
Chris@0 214 @project = Project.find(1)
Chris@0 215 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
Chris@0 216 end
Chris@0 217
Chris@0 218 def test_attachment_links
Chris@0 219 attachment_link = link_to('error281.txt', {:controller => 'attachments', :action => 'download', :id => '1'}, :class => 'attachment')
Chris@0 220 to_test = {
Chris@0 221 'attachment:error281.txt' => attachment_link
Chris@0 222 }
Chris@0 223 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
Chris@0 224 end
Chris@0 225
Chris@0 226 def test_wiki_links
Chris@0 227 to_test = {
Chris@0 228 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
Chris@0 229 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
Chris@0 230 # link with anchor
Chris@0 231 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
Chris@0 232 '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
Chris@0 233 # page that doesn't exist
Chris@0 234 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
Chris@0 235 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
Chris@0 236 # link to another project wiki
Chris@0 237 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki/" class="wiki-page">onlinestore</a>',
Chris@0 238 '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki/" class="wiki-page">Wiki</a>',
Chris@0 239 '[[onlinestore:Start page]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Start page</a>',
Chris@0 240 '[[onlinestore:Start page|Text]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Text</a>',
Chris@0 241 '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
Chris@0 242 # striked through link
Chris@0 243 '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
Chris@0 244 '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
Chris@0 245 # escaping
Chris@0 246 '![[Another page|Page]]' => '[[Another page|Page]]',
Chris@0 247 # project does not exist
Chris@0 248 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
Chris@0 249 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
Chris@0 250 }
Chris@0 251 @project = Project.find(1)
Chris@0 252 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
Chris@0 253 end
Chris@0 254
Chris@0 255 def test_html_tags
Chris@0 256 to_test = {
Chris@0 257 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
Chris@0 258 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
Chris@0 259 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
Chris@0 260 # do not escape pre/code tags
Chris@0 261 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
Chris@0 262 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
Chris@0 263 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
Chris@0 264 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
Chris@0 265 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
Chris@0 266 # remove attributes except class
Chris@0 267 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
Chris@0 268 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
Chris@0 269 }
Chris@0 270 to_test.each { |text, result| assert_equal result, textilizable(text) }
Chris@0 271 end
Chris@0 272
Chris@0 273 def test_allowed_html_tags
Chris@0 274 to_test = {
Chris@0 275 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
Chris@0 276 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
Chris@0 277 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
Chris@0 278 }
Chris@0 279 to_test.each { |text, result| assert_equal result, textilizable(text) }
Chris@0 280 end
Chris@0 281
Chris@0 282 def test_pre_tags
Chris@0 283 raw = <<-RAW
Chris@0 284 Before
Chris@0 285
Chris@0 286 <pre>
Chris@0 287 <prepared-statement-cache-size>32</prepared-statement-cache-size>
Chris@0 288 </pre>
Chris@0 289
Chris@0 290 After
Chris@0 291 RAW
Chris@0 292
Chris@0 293 expected = <<-EXPECTED
Chris@0 294 <p>Before</p>
Chris@0 295 <pre>
Chris@0 296 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
Chris@0 297 </pre>
Chris@0 298 <p>After</p>
Chris@0 299 EXPECTED
Chris@0 300
Chris@0 301 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
Chris@0 302 end
Chris@0 303
Chris@0 304 def test_pre_content_should_not_parse_wiki_and_redmine_links
Chris@0 305 raw = <<-RAW
Chris@0 306 [[CookBook documentation]]
Chris@0 307
Chris@0 308 #1
Chris@0 309
Chris@0 310 <pre>
Chris@0 311 [[CookBook documentation]]
Chris@0 312
Chris@0 313 #1
Chris@0 314 </pre>
Chris@0 315 RAW
Chris@0 316
Chris@0 317 expected = <<-EXPECTED
Chris@0 318 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
Chris@0 319 <p><a href="/issues/1" class="issue status-1 priority-1" title="Can't print recipes (New)">#1</a></p>
Chris@0 320 <pre>
Chris@0 321 [[CookBook documentation]]
Chris@0 322
Chris@0 323 #1
Chris@0 324 </pre>
Chris@0 325 EXPECTED
Chris@0 326
Chris@0 327 @project = Project.find(1)
Chris@0 328 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
Chris@0 329 end
Chris@0 330
Chris@0 331 def test_non_closing_pre_blocks_should_be_closed
Chris@0 332 raw = <<-RAW
Chris@0 333 <pre><code>
Chris@0 334 RAW
Chris@0 335
Chris@0 336 expected = <<-EXPECTED
Chris@0 337 <pre><code>
Chris@0 338 </code></pre>
Chris@0 339 EXPECTED
Chris@0 340
Chris@0 341 @project = Project.find(1)
Chris@0 342 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
Chris@0 343 end
Chris@0 344
Chris@0 345 def test_syntax_highlight
Chris@0 346 raw = <<-RAW
Chris@0 347 <pre><code class="ruby">
Chris@0 348 # Some ruby code here
Chris@0 349 </code></pre>
Chris@0 350 RAW
Chris@0 351
Chris@0 352 expected = <<-EXPECTED
Chris@0 353 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="no">1</span> <span class="c"># Some ruby code here</span></span>
Chris@0 354 </code></pre>
Chris@0 355 EXPECTED
Chris@0 356
Chris@0 357 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
Chris@0 358 end
Chris@0 359
Chris@0 360 def test_wiki_links_in_tables
Chris@0 361 to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
Chris@0 362 '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
Chris@0 363 '<td><a href="/projects/ecookbook/wiki/Other_Page" class="wiki-page new">Other title</a></td>' +
Chris@0 364 '</tr><tr><td>Cell 21</td><td><a href="/projects/ecookbook/wiki/Last_page" class="wiki-page new">Last page</a></td></tr>'
Chris@0 365 }
Chris@0 366 @project = Project.find(1)
Chris@0 367 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
Chris@0 368 end
Chris@0 369
Chris@0 370 def test_text_formatting
Chris@0 371 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
Chris@0 372 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
Chris@0 373 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
Chris@0 374 'a H *umane* W *eb* T *ext* G *enerator*' => 'a H <strong>umane</strong> W <strong>eb</strong> T <strong>ext</strong> G <strong>enerator</strong>',
Chris@0 375 'a *H* umane *W* eb *T* ext *G* enerator' => 'a <strong>H</strong> umane <strong>W</strong> eb <strong>T</strong> ext <strong>G</strong> enerator',
Chris@0 376 }
Chris@0 377 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
Chris@0 378 end
Chris@0 379
Chris@0 380 def test_wiki_horizontal_rule
Chris@0 381 assert_equal '<hr />', textilizable('---')
Chris@0 382 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
Chris@0 383 end
Chris@0 384
Chris@0 385 def test_acronym
Chris@0 386 assert_equal '<p>This is an acronym: <acronym title="American Civil Liberties Union">ACLU</acronym>.</p>',
Chris@0 387 textilizable('This is an acronym: ACLU(American Civil Liberties Union).')
Chris@0 388 end
Chris@0 389
Chris@0 390 def test_footnotes
Chris@0 391 raw = <<-RAW
Chris@0 392 This is some text[1].
Chris@0 393
Chris@0 394 fn1. This is the foot note
Chris@0 395 RAW
Chris@0 396
Chris@0 397 expected = <<-EXPECTED
Chris@0 398 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
Chris@0 399 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
Chris@0 400 EXPECTED
Chris@0 401
Chris@0 402 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
Chris@0 403 end
Chris@0 404
Chris@0 405 def test_table_of_content
Chris@0 406 raw = <<-RAW
Chris@0 407 {{toc}}
Chris@0 408
Chris@0 409 h1. Title
Chris@0 410
Chris@0 411 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
Chris@0 412
Chris@0 413 h2. Subtitle with a [[Wiki]] link
Chris@0 414
Chris@0 415 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
Chris@0 416
Chris@0 417 h2. Subtitle with [[Wiki|another Wiki]] link
Chris@0 418
Chris@0 419 h2. Subtitle with %{color:red}red text%
Chris@0 420
Chris@0 421 h1. Another title
Chris@0 422
Chris@0 423 h2. An "Internet link":http://www.redmine.org/ inside subtitle
Chris@0 424
Chris@0 425 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
Chris@0 426
Chris@0 427 RAW
Chris@0 428
Chris@0 429 expected = '<ul class="toc">' +
Chris@0 430 '<li class="heading1"><a href="#Title">Title</a></li>' +
Chris@0 431 '<li class="heading2"><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
Chris@0 432 '<li class="heading2"><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
Chris@0 433 '<li class="heading2"><a href="#Subtitle-with-red-text">Subtitle with red text</a></li>' +
Chris@0 434 '<li class="heading1"><a href="#Another-title">Another title</a></li>' +
Chris@0 435 '<li class="heading2"><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
Chris@0 436 '<li class="heading2"><a href="#Project-Name">Project Name</a></li>' +
Chris@0 437 '</ul>'
Chris@0 438
Chris@0 439 assert textilizable(raw).gsub("\n", "").include?(expected)
Chris@0 440 end
Chris@0 441
Chris@0 442 def test_blockquote
Chris@0 443 # orig raw text
Chris@0 444 raw = <<-RAW
Chris@0 445 John said:
Chris@0 446 > Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
Chris@0 447 > Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
Chris@0 448 > * Donec odio lorem,
Chris@0 449 > * sagittis ac,
Chris@0 450 > * malesuada in,
Chris@0 451 > * adipiscing eu, dolor.
Chris@0 452 >
Chris@0 453 > >Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.
Chris@0 454 > Proin a tellus. Nam vel neque.
Chris@0 455
Chris@0 456 He's right.
Chris@0 457 RAW
Chris@0 458
Chris@0 459 # expected html
Chris@0 460 expected = <<-EXPECTED
Chris@0 461 <p>John said:</p>
Chris@0 462 <blockquote>
Chris@0 463 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
Chris@0 464 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
Chris@0 465 <ul>
Chris@0 466 <li>Donec odio lorem,</li>
Chris@0 467 <li>sagittis ac,</li>
Chris@0 468 <li>malesuada in,</li>
Chris@0 469 <li>adipiscing eu, dolor.</li>
Chris@0 470 </ul>
Chris@0 471 <blockquote>
Chris@0 472 <p>Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.</p>
Chris@0 473 </blockquote>
Chris@0 474 <p>Proin a tellus. Nam vel neque.</p>
Chris@0 475 </blockquote>
Chris@0 476 <p>He's right.</p>
Chris@0 477 EXPECTED
Chris@0 478
Chris@0 479 assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
Chris@0 480 end
Chris@0 481
Chris@0 482 def test_table
Chris@0 483 raw = <<-RAW
Chris@0 484 This is a table with empty cells:
Chris@0 485
Chris@0 486 |cell11|cell12||
Chris@0 487 |cell21||cell23|
Chris@0 488 |cell31|cell32|cell33|
Chris@0 489 RAW
Chris@0 490
Chris@0 491 expected = <<-EXPECTED
Chris@0 492 <p>This is a table with empty cells:</p>
Chris@0 493
Chris@0 494 <table>
Chris@0 495 <tr><td>cell11</td><td>cell12</td><td></td></tr>
Chris@0 496 <tr><td>cell21</td><td></td><td>cell23</td></tr>
Chris@0 497 <tr><td>cell31</td><td>cell32</td><td>cell33</td></tr>
Chris@0 498 </table>
Chris@0 499 EXPECTED
Chris@0 500
Chris@0 501 assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
Chris@0 502 end
Chris@0 503
Chris@0 504 def test_table_with_line_breaks
Chris@0 505 raw = <<-RAW
Chris@0 506 This is a table with line breaks:
Chris@0 507
Chris@0 508 |cell11
Chris@0 509 continued|cell12||
Chris@0 510 |-cell21-||cell23
Chris@0 511 cell23 line2
Chris@0 512 cell23 *line3*|
Chris@0 513 |cell31|cell32
Chris@0 514 cell32 line2|cell33|
Chris@0 515
Chris@0 516 RAW
Chris@0 517
Chris@0 518 expected = <<-EXPECTED
Chris@0 519 <p>This is a table with line breaks:</p>
Chris@0 520
Chris@0 521 <table>
Chris@0 522 <tr>
Chris@0 523 <td>cell11<br />continued</td>
Chris@0 524 <td>cell12</td>
Chris@0 525 <td></td>
Chris@0 526 </tr>
Chris@0 527 <tr>
Chris@0 528 <td><del>cell21</del></td>
Chris@0 529 <td></td>
Chris@0 530 <td>cell23<br/>cell23 line2<br/>cell23 <strong>line3</strong></td>
Chris@0 531 </tr>
Chris@0 532 <tr>
Chris@0 533 <td>cell31</td>
Chris@0 534 <td>cell32<br/>cell32 line2</td>
Chris@0 535 <td>cell33</td>
Chris@0 536 </tr>
Chris@0 537 </table>
Chris@0 538 EXPECTED
Chris@0 539
Chris@0 540 assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
Chris@0 541 end
Chris@0 542
Chris@0 543 def test_textile_should_not_mangle_brackets
Chris@0 544 assert_equal '<p>[msg1][msg2]</p>', textilizable('[msg1][msg2]')
Chris@0 545 end
Chris@0 546
Chris@0 547 def test_default_formatter
Chris@0 548 Setting.text_formatting = 'unknown'
Chris@0 549 text = 'a *link*: http://www.example.net/'
Chris@0 550 assert_equal '<p>a *link*: <a href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
Chris@0 551 Setting.text_formatting = 'textile'
Chris@0 552 end
Chris@0 553
Chris@0 554 def test_due_date_distance_in_words
Chris@0 555 to_test = { Date.today => 'Due in 0 days',
Chris@0 556 Date.today + 1 => 'Due in 1 day',
Chris@0 557 Date.today + 100 => 'Due in about 3 months',
Chris@0 558 Date.today + 20000 => 'Due in over 54 years',
Chris@0 559 Date.today - 1 => '1 day late',
Chris@0 560 Date.today - 100 => 'about 3 months late',
Chris@0 561 Date.today - 20000 => 'over 54 years late',
Chris@0 562 }
Chris@0 563 to_test.each do |date, expected|
Chris@0 564 assert_equal expected, due_date_distance_in_words(date)
Chris@0 565 end
Chris@0 566 end
Chris@0 567
Chris@0 568 def test_avatar
Chris@0 569 # turn on avatars
Chris@0 570 Setting.gravatar_enabled = '1'
Chris@0 571 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
Chris@0 572 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
Chris@0 573 assert_nil avatar('jsmith')
Chris@0 574 assert_nil avatar(nil)
Chris@0 575
Chris@0 576 # turn off avatars
Chris@0 577 Setting.gravatar_enabled = '0'
Chris@0 578 assert_nil avatar(User.find_by_mail('jsmith@somenet.foo'))
Chris@0 579 end
Chris@0 580
Chris@0 581 def test_link_to_user
Chris@0 582 user = User.find(2)
Chris@0 583 t = link_to_user(user)
Chris@0 584 assert_equal "<a href=\"/users/2\">#{ user.name }</a>", t
Chris@0 585 end
Chris@0 586
Chris@0 587 def test_link_to_user_should_not_link_to_locked_user
Chris@0 588 user = User.find(5)
Chris@0 589 assert user.locked?
Chris@0 590 t = link_to_user(user)
Chris@0 591 assert_equal user.name, t
Chris@0 592 end
Chris@0 593
Chris@0 594 def test_link_to_user_should_not_link_to_anonymous
Chris@0 595 user = User.anonymous
Chris@0 596 assert user.anonymous?
Chris@0 597 t = link_to_user(user)
Chris@0 598 assert_equal ::I18n.t(:label_user_anonymous), t
Chris@0 599 end
Chris@0 600 end