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