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