##// END OF EJS Templates
Moved redmine links escaping assertions to their own test....
Jean-Philippe Lang -
r8758:3c7560197650
parent child
Show More
@@ -1,1040 +1,1046
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2011 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 fixtures :projects, :roles, :enabled_modules, :users,
22 22 :repositories, :changesets,
23 23 :trackers, :issue_statuses, :issues, :versions, :documents,
24 24 :wikis, :wiki_pages, :wiki_contents,
25 25 :boards, :messages, :news,
26 26 :attachments, :enumerations
27 27
28 28 def setup
29 29 super
30 30 set_tmp_attachments_directory
31 31 end
32 32
33 33 context "#link_to_if_authorized" do
34 34 context "authorized user" do
35 35 should "be tested"
36 36 end
37 37
38 38 context "unauthorized user" do
39 39 should "be tested"
40 40 end
41 41
42 42 should "allow using the :controller and :action for the target link" do
43 43 User.current = User.find_by_login('admin')
44 44
45 45 @project = Issue.first.project # Used by helper
46 46 response = link_to_if_authorized("By controller/action",
47 47 {:controller => 'issues', :action => 'edit', :id => Issue.first.id})
48 48 assert_match /href/, response
49 49 end
50 50
51 51 end
52 52
53 53 def test_auto_links
54 54 to_test = {
55 55 'http://foo.bar' => '<a class="external" href="http://foo.bar">http://foo.bar</a>',
56 56 'http://foo.bar/~user' => '<a class="external" href="http://foo.bar/~user">http://foo.bar/~user</a>',
57 57 'http://foo.bar.' => '<a class="external" href="http://foo.bar">http://foo.bar</a>.',
58 58 'https://foo.bar.' => '<a class="external" href="https://foo.bar">https://foo.bar</a>.',
59 59 'This is a link: http://foo.bar.' => 'This is a link: <a class="external" href="http://foo.bar">http://foo.bar</a>.',
60 60 'A link (eg. http://foo.bar).' => 'A link (eg. <a class="external" href="http://foo.bar">http://foo.bar</a>).',
61 61 '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>.',
62 62 'http://www.foo.bar/Test_(foobar)' => '<a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>',
63 63 '(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>)',
64 64 '(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>)',
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_(foobar))' => '(see <a href="http://www.foo.bar/Test_(foobar)" class="external">inline link</a>)',
67 67 '(see "inline link":http://www.foo.bar/Test)' => '(see <a href="http://www.foo.bar/Test" 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 'www.foo.bar' => '<a class="external" href="http://www.foo.bar">www.foo.bar</a>',
70 70 '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>',
71 71 'http://foo.bar/page#125' => '<a class="external" href="http://foo.bar/page#125">http://foo.bar/page#125</a>',
72 72 'http://foo@www.bar.com' => '<a class="external" href="http://foo@www.bar.com">http://foo@www.bar.com</a>',
73 73 'http://foo:bar@www.bar.com' => '<a class="external" href="http://foo:bar@www.bar.com">http://foo:bar@www.bar.com</a>',
74 74 'ftp://foo.bar' => '<a class="external" href="ftp://foo.bar">ftp://foo.bar</a>',
75 75 'ftps://foo.bar' => '<a class="external" href="ftps://foo.bar">ftps://foo.bar</a>',
76 76 'sftp://foo.bar' => '<a class="external" href="sftp://foo.bar">sftp://foo.bar</a>',
77 77 # two exclamation marks
78 78 '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>',
79 79 # escaping
80 80 'http://foo"bar' => '<a class="external" href="http://foo&quot;bar">http://foo"bar</a>',
81 81 # wrap in angle brackets
82 82 '<http://foo.bar>' => '&lt;<a class="external" href="http://foo.bar">http://foo.bar</a>&gt;'
83 83 }
84 84 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
85 85 end
86 86
87 87 def test_auto_mailto
88 88 assert_equal '<p><a class="email" href="mailto:test@foo.bar">test@foo.bar</a></p>',
89 89 textilizable('test@foo.bar')
90 90 end
91 91
92 92 def test_inline_images
93 93 to_test = {
94 94 '!http://foo.bar/image.jpg!' => '<img src="http://foo.bar/image.jpg" alt="" />',
95 95 'floating !>http://foo.bar/image.jpg!' => 'floating <div style="float:right"><img src="http://foo.bar/image.jpg" alt="" /></div>',
96 96 'with class !(some-class)http://foo.bar/image.jpg!' => 'with class <img src="http://foo.bar/image.jpg" class="some-class" alt="" />',
97 97 'with style !{width:100px;height:100px}http://foo.bar/image.jpg!' => 'with style <img src="http://foo.bar/image.jpg" style="width:100px;height:100px;" alt="" />',
98 98 '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" />',
99 99 '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;" />',
100 100 }
101 101 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
102 102 end
103 103
104 104 def test_inline_images_inside_tags
105 105 raw = <<-RAW
106 106 h1. !foo.png! Heading
107 107
108 108 Centered image:
109 109
110 110 p=. !bar.gif!
111 111 RAW
112 112
113 113 assert textilizable(raw).include?('<img src="foo.png" alt="" />')
114 114 assert textilizable(raw).include?('<img src="bar.gif" alt="" />')
115 115 end
116 116
117 117 def test_attached_images
118 118 to_test = {
119 119 'Inline image: !logo.gif!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
120 120 'Inline image: !logo.GIF!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
121 121 'No match: !ogo.gif!' => 'No match: <img src="ogo.gif" alt="" />',
122 122 'No match: !ogo.GIF!' => 'No match: <img src="ogo.GIF" alt="" />',
123 123 # link image
124 124 '!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>',
125 125 }
126 126 attachments = Attachment.find(:all)
127 127 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
128 128 end
129 129
130 130 def test_attached_images_filename_extension
131 131 set_tmp_attachments_directory
132 132 a1 = Attachment.new(
133 133 :container => Issue.find(1),
134 134 :file => mock_file_with_options({:original_filename => "testtest.JPG"}),
135 135 :author => User.find(1))
136 136 assert a1.save
137 137 assert_equal "testtest.JPG", a1.filename
138 138 assert_equal "image/jpeg", a1.content_type
139 139 assert a1.image?
140 140
141 141 a2 = Attachment.new(
142 142 :container => Issue.find(1),
143 143 :file => mock_file_with_options({:original_filename => "testtest.jpeg"}),
144 144 :author => User.find(1))
145 145 assert a2.save
146 146 assert_equal "testtest.jpeg", a2.filename
147 147 assert_equal "image/jpeg", a2.content_type
148 148 assert a2.image?
149 149
150 150 a3 = Attachment.new(
151 151 :container => Issue.find(1),
152 152 :file => mock_file_with_options({:original_filename => "testtest.JPE"}),
153 153 :author => User.find(1))
154 154 assert a3.save
155 155 assert_equal "testtest.JPE", a3.filename
156 156 assert_equal "image/jpeg", a3.content_type
157 157 assert a3.image?
158 158
159 159 a4 = Attachment.new(
160 160 :container => Issue.find(1),
161 161 :file => mock_file_with_options({:original_filename => "Testtest.BMP"}),
162 162 :author => User.find(1))
163 163 assert a4.save
164 164 assert_equal "Testtest.BMP", a4.filename
165 165 assert_equal "image/x-ms-bmp", a4.content_type
166 166 assert a4.image?
167 167
168 168 to_test = {
169 169 'Inline image: !testtest.jpg!' =>
170 170 'Inline image: <img src="/attachments/download/' + a1.id.to_s + '" alt="" />',
171 171 'Inline image: !testtest.jpeg!' =>
172 172 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '" alt="" />',
173 173 'Inline image: !testtest.jpe!' =>
174 174 'Inline image: <img src="/attachments/download/' + a3.id.to_s + '" alt="" />',
175 175 'Inline image: !testtest.bmp!' =>
176 176 'Inline image: <img src="/attachments/download/' + a4.id.to_s + '" alt="" />',
177 177 }
178 178
179 179 attachments = [a1, a2, a3, a4]
180 180 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
181 181 end
182 182
183 183 def test_attached_images_should_read_later
184 184 set_fixtures_attachments_directory
185 185 a1 = Attachment.find(16)
186 186 assert_equal "testfile.png", a1.filename
187 187 assert a1.readable?
188 188 assert (! a1.visible?(User.anonymous))
189 189 assert a1.visible?(User.find(2))
190 190 a2 = Attachment.find(17)
191 191 assert_equal "testfile.PNG", a2.filename
192 192 assert a2.readable?
193 193 assert (! a2.visible?(User.anonymous))
194 194 assert a2.visible?(User.find(2))
195 195 assert a1.created_on < a2.created_on
196 196
197 197 to_test = {
198 198 'Inline image: !testfile.png!' =>
199 199 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '" alt="" />',
200 200 'Inline image: !Testfile.PNG!' =>
201 201 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '" alt="" />',
202 202 }
203 203 attachments = [a1, a2]
204 204 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
205 205 set_tmp_attachments_directory
206 206 end
207 207
208 208 def test_textile_external_links
209 209 to_test = {
210 210 'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
211 211 'This is an intern "link":/foo/bar' => 'This is an intern <a href="/foo/bar">link</a>',
212 212 '"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>',
213 213 '"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>',
214 214 "This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":</p>\n\n\n\t<p>Another paragraph",
215 215 # no multiline link text
216 216 "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",
217 217 # mailto link
218 218 "\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "<a href=\"mailto:sysadmin@example.com?subject=redmine%20permissions\">system administrator</a>",
219 219 # two exclamation marks
220 220 '"a link":http://example.net/path!602815048C7B5C20!302.html' => '<a href="http://example.net/path!602815048C7B5C20!302.html" class="external">a link</a>',
221 221 # escaping
222 222 '"test":http://foo"bar' => '<a href="http://foo&quot;bar" class="external">test</a>',
223 223 }
224 224 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
225 225 end
226 226
227 227 def test_redmine_links
228 228 issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
229 229 :class => 'issue status-1 priority-1 overdue', :title => 'Error 281 when updating a recipe (New)')
230 230 note_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3, :anchor => 'note-14'},
231 231 :class => 'issue status-1 priority-1 overdue', :title => 'Error 281 when updating a recipe (New)')
232 232
233 233 changeset_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
234 234 :class => 'changeset', :title => 'My very first commit')
235 235 changeset_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
236 236 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
237 237
238 238 document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
239 239 :class => 'document')
240 240
241 241 version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
242 242 :class => 'version')
243 243
244 244 board_url = {:controller => 'boards', :action => 'show', :id => 2, :project_id => 'ecookbook'}
245 245
246 246 message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
247 247
248 248 news_url = {:controller => 'news', :action => 'show', :id => 1}
249 249
250 250 project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
251 251
252 252 source_url = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}
253 253 source_url_with_ext = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file.ext']}
254 254
255 255 to_test = {
256 256 # tickets
257 257 '#3, [#3], (#3) and #3.' => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
258 258 # ticket notes
259 259 '#3-14' => note_link,
260 260 '#3#note-14' => note_link,
261 261 # changesets
262 262 'r1' => changeset_link,
263 263 'r1.' => "#{changeset_link}.",
264 264 'r1, r2' => "#{changeset_link}, #{changeset_link2}",
265 265 'r1,r2' => "#{changeset_link},#{changeset_link2}",
266 266 # documents
267 267 'document#1' => document_link,
268 268 'document:"Test document"' => document_link,
269 269 # versions
270 270 'version#2' => version_link,
271 271 'version:1.0' => version_link,
272 272 'version:"1.0"' => version_link,
273 273 # source
274 274 'source:some/file' => link_to('source:some/file', source_url, :class => 'source'),
275 275 'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'),
276 276 'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".",
277 277 'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
278 278 'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".",
279 279 'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
280 280 'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",",
281 281 'source:/some/file@52' => link_to('source:/some/file@52', source_url.merge(:rev => 52), :class => 'source'),
282 282 'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_ext.merge(:rev => 52), :class => 'source'),
283 283 'source:/some/file#L110' => link_to('source:/some/file#L110', source_url.merge(:anchor => 'L110'), :class => 'source'),
284 284 'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext.merge(:anchor => 'L110'), :class => 'source'),
285 285 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url.merge(:rev => 52, :anchor => 'L110'), :class => 'source'),
286 286 'export:/some/file' => link_to('export:/some/file', source_url.merge(:format => 'raw'), :class => 'source download'),
287 287 # forum
288 288 'forum#2' => link_to('Discussion', board_url, :class => 'board'),
289 289 'forum:Discussion' => link_to('Discussion', board_url, :class => 'board'),
290 290 # message
291 291 'message#4' => link_to('Post 2', message_url, :class => 'message'),
292 292 'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5', :r => 5), :class => 'message'),
293 293 # news
294 294 'news#1' => link_to('eCookbook first release !', news_url, :class => 'news'),
295 295 'news:"eCookbook first release !"' => link_to('eCookbook first release !', news_url, :class => 'news'),
296 296 # project
297 297 'project#3' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
298 298 'project:subproject1' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
299 299 'project:"eCookbook subProject 1"' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
300 # escaping
301 '!#3.' => '#3.',
302 '!#3-14.' => '#3-14.',
303 '!#3#-note14.' => '#3#-note14.',
304 '!r1' => 'r1',
305 '!document#1' => 'document#1',
306 '!document:"Test document"' => 'document:"Test document"',
307 '!version#2' => 'version#2',
308 '!version:1.0' => 'version:1.0',
309 '!version:"1.0"' => 'version:"1.0"',
310 '!source:/some/file' => 'source:/some/file',
311 300 # not found
312 301 '#0123456789' => '#0123456789',
313 302 # invalid expressions
314 303 'source:' => 'source:',
315 304 # url hash
316 305 "http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
317 306 }
318 307 @project = Project.find(1)
319 308 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
320 309 end
321 310
311 def test_escaped_redmine_links_should_not_be_parsed
312 to_test = [
313 '#3.',
314 '#3-14.',
315 '#3#-note14.',
316 'r1',
317 'document#1',
318 'document:"Test document"',
319 'version#2',
320 'version:1.0',
321 'version:"1.0"',
322 'source:/some/file'
323 ]
324 @project = Project.find(1)
325 to_test.each { |text| assert_equal "<p>#{text}</p>", textilizable("!" + text), "#{text} failed" }
326 end
327
322 328 def test_cross_project_redmine_links
323 329 source_link = link_to('ecookbook:source:/some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']},
324 330 :class => 'source')
325 331
326 332 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
327 333 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
328 334
329 335 to_test = {
330 336 # documents
331 337 'document:"Test document"' => 'document:"Test document"',
332 338 'ecookbook:document:"Test document"' => '<a href="/documents/1" class="document">Test document</a>',
333 339 'invalid:document:"Test document"' => 'invalid:document:"Test document"',
334 340 # versions
335 341 'version:"1.0"' => 'version:"1.0"',
336 342 'ecookbook:version:"1.0"' => '<a href="/versions/2" class="version">1.0</a>',
337 343 'invalid:version:"1.0"' => 'invalid:version:"1.0"',
338 344 # changeset
339 345 'r2' => 'r2',
340 346 'ecookbook:r2' => changeset_link,
341 347 'invalid:r2' => 'invalid:r2',
342 348 # source
343 349 'source:/some/file' => 'source:/some/file',
344 350 'ecookbook:source:/some/file' => source_link,
345 351 'invalid:source:/some/file' => 'invalid:source:/some/file',
346 352 }
347 353 @project = Project.find(3)
348 354 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
349 355 end
350 356
351 357 def test_multiple_repositories_redmine_links
352 358 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn1', :url => 'file:///foo/hg')
353 359 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
354 360 hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
355 361 Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
356 362
357 363 changeset_link = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
358 364 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
359 365 svn_changeset_link = link_to('svn1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn1', :rev => 123},
360 366 :class => 'changeset', :title => '')
361 367 hg_changeset_link = link_to('hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
362 368 :class => 'changeset', :title => '')
363 369
364 370 source_link = link_to('source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
365 371 hg_source_link = link_to('source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source')
366 372
367 373 to_test = {
368 374 'r2' => changeset_link,
369 375 'svn1|r123' => svn_changeset_link,
370 376 'invalid|r123' => 'invalid|r123',
371 377 'commit:hg1|abcd' => hg_changeset_link,
372 378 'commit:invalid|abcd' => 'commit:invalid|abcd',
373 379 # source
374 380 'source:some/file' => source_link,
375 381 'source:hg1|some/file' => hg_source_link,
376 382 'source:invalid|some/file' => 'source:invalid|some/file',
377 383 }
378 384
379 385 @project = Project.find(1)
380 386 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
381 387 end
382 388
383 389 def test_cross_project_multiple_repositories_redmine_links
384 390 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn1', :url => 'file:///foo/hg')
385 391 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
386 392 hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
387 393 Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
388 394
389 395 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
390 396 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
391 397 svn_changeset_link = link_to('ecookbook:svn1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn1', :rev => 123},
392 398 :class => 'changeset', :title => '')
393 399 hg_changeset_link = link_to('ecookbook:hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
394 400 :class => 'changeset', :title => '')
395 401
396 402 source_link = link_to('ecookbook:source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
397 403 hg_source_link = link_to('ecookbook:source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source')
398 404
399 405 to_test = {
400 406 'ecookbook:r2' => changeset_link,
401 407 'ecookbook:svn1|r123' => svn_changeset_link,
402 408 'ecookbook:invalid|r123' => 'ecookbook:invalid|r123',
403 409 'ecookbook:commit:hg1|abcd' => hg_changeset_link,
404 410 'ecookbook:commit:invalid|abcd' => 'ecookbook:commit:invalid|abcd',
405 411 'invalid:commit:invalid|abcd' => 'invalid:commit:invalid|abcd',
406 412 # source
407 413 'ecookbook:source:some/file' => source_link,
408 414 'ecookbook:source:hg1|some/file' => hg_source_link,
409 415 'ecookbook:source:invalid|some/file' => 'ecookbook:source:invalid|some/file',
410 416 'invalid:source:invalid|some/file' => 'invalid:source:invalid|some/file',
411 417 }
412 418
413 419 @project = Project.find(3)
414 420 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
415 421 end
416 422
417 423 def test_redmine_links_git_commit
418 424 changeset_link = link_to('abcd',
419 425 {
420 426 :controller => 'repositories',
421 427 :action => 'revision',
422 428 :id => 'subproject1',
423 429 :rev => 'abcd',
424 430 },
425 431 :class => 'changeset', :title => 'test commit')
426 432 to_test = {
427 433 'commit:abcd' => changeset_link,
428 434 }
429 435 @project = Project.find(3)
430 436 r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
431 437 assert r
432 438 c = Changeset.new(:repository => r,
433 439 :committed_on => Time.now,
434 440 :revision => 'abcd',
435 441 :scmid => 'abcd',
436 442 :comments => 'test commit')
437 443 assert( c.save )
438 444 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
439 445 end
440 446
441 447 # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
442 448 def test_redmine_links_darcs_commit
443 449 changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
444 450 {
445 451 :controller => 'repositories',
446 452 :action => 'revision',
447 453 :id => 'subproject1',
448 454 :rev => '123',
449 455 },
450 456 :class => 'changeset', :title => 'test commit')
451 457 to_test = {
452 458 'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
453 459 }
454 460 @project = Project.find(3)
455 461 r = Repository::Darcs.create!(
456 462 :project => @project, :url => '/tmp/test/darcs',
457 463 :log_encoding => 'UTF-8')
458 464 assert r
459 465 c = Changeset.new(:repository => r,
460 466 :committed_on => Time.now,
461 467 :revision => '123',
462 468 :scmid => '20080308225258-98289-abcd456efg.gz',
463 469 :comments => 'test commit')
464 470 assert( c.save )
465 471 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
466 472 end
467 473
468 474 def test_redmine_links_mercurial_commit
469 475 changeset_link_rev = link_to('r123',
470 476 {
471 477 :controller => 'repositories',
472 478 :action => 'revision',
473 479 :id => 'subproject1',
474 480 :rev => '123' ,
475 481 },
476 482 :class => 'changeset', :title => 'test commit')
477 483 changeset_link_commit = link_to('abcd',
478 484 {
479 485 :controller => 'repositories',
480 486 :action => 'revision',
481 487 :id => 'subproject1',
482 488 :rev => 'abcd' ,
483 489 },
484 490 :class => 'changeset', :title => 'test commit')
485 491 to_test = {
486 492 'r123' => changeset_link_rev,
487 493 'commit:abcd' => changeset_link_commit,
488 494 }
489 495 @project = Project.find(3)
490 496 r = Repository::Mercurial.create!(:project => @project, :url => '/tmp/test')
491 497 assert r
492 498 c = Changeset.new(:repository => r,
493 499 :committed_on => Time.now,
494 500 :revision => '123',
495 501 :scmid => 'abcd',
496 502 :comments => 'test commit')
497 503 assert( c.save )
498 504 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
499 505 end
500 506
501 507 def test_attachment_links
502 508 attachment_link = link_to('error281.txt', {:controller => 'attachments', :action => 'download', :id => '1'}, :class => 'attachment')
503 509 to_test = {
504 510 'attachment:error281.txt' => attachment_link
505 511 }
506 512 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
507 513 end
508 514
509 515 def test_wiki_links
510 516 to_test = {
511 517 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
512 518 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
513 519 # title content should be formatted
514 520 '[[Another page|With _styled_ *title*]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">With <em>styled</em> <strong>title</strong></a>',
515 521 '[[Another page|With title containing <strong>HTML entities &amp; markups</strong>]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">With title containing &lt;strong&gt;HTML entities &amp; markups&lt;/strong&gt;</a>',
516 522 # link with anchor
517 523 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
518 524 '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
519 525 # page that doesn't exist
520 526 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
521 527 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
522 528 # link to another project wiki
523 529 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
524 530 '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">Wiki</a>',
525 531 '[[onlinestore:Start page]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Start page</a>',
526 532 '[[onlinestore:Start page|Text]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Text</a>',
527 533 '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
528 534 # striked through link
529 535 '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
530 536 '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
531 537 # escaping
532 538 '![[Another page|Page]]' => '[[Another page|Page]]',
533 539 # project does not exist
534 540 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
535 541 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
536 542 }
537 543
538 544 @project = Project.find(1)
539 545 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
540 546 end
541 547
542 548 def test_wiki_links_within_local_file_generation_context
543 549
544 550 to_test = {
545 551 # link to a page
546 552 '[[CookBook documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">CookBook documentation</a>',
547 553 '[[CookBook documentation|documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">documentation</a>',
548 554 '[[CookBook documentation#One-section]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">CookBook documentation</a>',
549 555 '[[CookBook documentation#One-section|documentation]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">documentation</a>',
550 556 # page that doesn't exist
551 557 '[[Unknown page]]' => '<a href="Unknown_page.html" class="wiki-page new">Unknown page</a>',
552 558 '[[Unknown page|404]]' => '<a href="Unknown_page.html" class="wiki-page new">404</a>',
553 559 '[[Unknown page#anchor]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">Unknown page</a>',
554 560 '[[Unknown page#anchor|404]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">404</a>',
555 561 }
556 562
557 563 @project = Project.find(1)
558 564
559 565 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :local) }
560 566 end
561 567
562 568 def test_wiki_links_within_wiki_page_context
563 569
564 570 page = WikiPage.find_by_title('Another_page' )
565 571
566 572 to_test = {
567 573 # link to another page
568 574 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
569 575 '[[CookBook documentation|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">documentation</a>',
570 576 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
571 577 '[[CookBook documentation#One-section|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">documentation</a>',
572 578 # link to the current page
573 579 '[[Another page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Another page</a>',
574 580 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
575 581 '[[Another page#anchor]]' => '<a href="#anchor" class="wiki-page">Another page</a>',
576 582 '[[Another page#anchor|Page]]' => '<a href="#anchor" class="wiki-page">Page</a>',
577 583 # page that doesn't exist
578 584 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page" class="wiki-page new">Unknown page</a>',
579 585 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page" class="wiki-page new">404</a>',
580 586 '[[Unknown page#anchor]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor" class="wiki-page new">Unknown page</a>',
581 587 '[[Unknown page#anchor|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor" class="wiki-page new">404</a>',
582 588 }
583 589
584 590 @project = Project.find(1)
585 591
586 592 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(WikiContent.new( :text => text, :page => page ), :text) }
587 593 end
588 594
589 595 def test_wiki_links_anchor_option_should_prepend_page_title_to_href
590 596
591 597 to_test = {
592 598 # link to a page
593 599 '[[CookBook documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">CookBook documentation</a>',
594 600 '[[CookBook documentation|documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">documentation</a>',
595 601 '[[CookBook documentation#One-section]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">CookBook documentation</a>',
596 602 '[[CookBook documentation#One-section|documentation]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">documentation</a>',
597 603 # page that doesn't exist
598 604 '[[Unknown page]]' => '<a href="#Unknown_page" class="wiki-page new">Unknown page</a>',
599 605 '[[Unknown page|404]]' => '<a href="#Unknown_page" class="wiki-page new">404</a>',
600 606 '[[Unknown page#anchor]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">Unknown page</a>',
601 607 '[[Unknown page#anchor|404]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">404</a>',
602 608 }
603 609
604 610 @project = Project.find(1)
605 611
606 612 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :anchor) }
607 613 end
608 614
609 615 def test_html_tags
610 616 to_test = {
611 617 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
612 618 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
613 619 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
614 620 # do not escape pre/code tags
615 621 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
616 622 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
617 623 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
618 624 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
619 625 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
620 626 # remove attributes except class
621 627 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
622 628 '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
623 629 "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
624 630 '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
625 631 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
626 632 # xss
627 633 '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
628 634 '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
629 635 }
630 636 to_test.each { |text, result| assert_equal result, textilizable(text) }
631 637 end
632 638
633 639 def test_allowed_html_tags
634 640 to_test = {
635 641 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
636 642 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
637 643 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
638 644 }
639 645 to_test.each { |text, result| assert_equal result, textilizable(text) }
640 646 end
641 647
642 648 def test_pre_tags
643 649 raw = <<-RAW
644 650 Before
645 651
646 652 <pre>
647 653 <prepared-statement-cache-size>32</prepared-statement-cache-size>
648 654 </pre>
649 655
650 656 After
651 657 RAW
652 658
653 659 expected = <<-EXPECTED
654 660 <p>Before</p>
655 661 <pre>
656 662 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
657 663 </pre>
658 664 <p>After</p>
659 665 EXPECTED
660 666
661 667 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
662 668 end
663 669
664 670 def test_pre_content_should_not_parse_wiki_and_redmine_links
665 671 raw = <<-RAW
666 672 [[CookBook documentation]]
667 673
668 674 #1
669 675
670 676 <pre>
671 677 [[CookBook documentation]]
672 678
673 679 #1
674 680 </pre>
675 681 RAW
676 682
677 683 expected = <<-EXPECTED
678 684 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
679 685 <p><a href="/issues/1" class="issue status-1 priority-1" title="Can't print recipes (New)">#1</a></p>
680 686 <pre>
681 687 [[CookBook documentation]]
682 688
683 689 #1
684 690 </pre>
685 691 EXPECTED
686 692
687 693 @project = Project.find(1)
688 694 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
689 695 end
690 696
691 697 def test_non_closing_pre_blocks_should_be_closed
692 698 raw = <<-RAW
693 699 <pre><code>
694 700 RAW
695 701
696 702 expected = <<-EXPECTED
697 703 <pre><code>
698 704 </code></pre>
699 705 EXPECTED
700 706
701 707 @project = Project.find(1)
702 708 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
703 709 end
704 710
705 711 def test_syntax_highlight
706 712 raw = <<-RAW
707 713 <pre><code class="ruby">
708 714 # Some ruby code here
709 715 </code></pre>
710 716 RAW
711 717
712 718 expected = <<-EXPECTED
713 719 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="line-numbers">1</span><span class="comment"># Some ruby code here</span></span>
714 720 </code></pre>
715 721 EXPECTED
716 722
717 723 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
718 724 end
719 725
720 726 def test_wiki_links_in_tables
721 727 to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
722 728 '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
723 729 '<td><a href="/projects/ecookbook/wiki/Other_Page" class="wiki-page new">Other title</a></td>' +
724 730 '</tr><tr><td>Cell 21</td><td><a href="/projects/ecookbook/wiki/Last_page" class="wiki-page new">Last page</a></td></tr>'
725 731 }
726 732 @project = Project.find(1)
727 733 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
728 734 end
729 735
730 736 def test_text_formatting
731 737 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
732 738 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
733 739 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
734 740 '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>',
735 741 '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',
736 742 }
737 743 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
738 744 end
739 745
740 746 def test_wiki_horizontal_rule
741 747 assert_equal '<hr />', textilizable('---')
742 748 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
743 749 end
744 750
745 751 def test_footnotes
746 752 raw = <<-RAW
747 753 This is some text[1].
748 754
749 755 fn1. This is the foot note
750 756 RAW
751 757
752 758 expected = <<-EXPECTED
753 759 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
754 760 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
755 761 EXPECTED
756 762
757 763 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
758 764 end
759 765
760 766 def test_headings
761 767 raw = 'h1. Some heading'
762 768 expected = %|<a name="Some-heading"></a>\n<h1 >Some heading<a href="#Some-heading" class="wiki-anchor">&para;</a></h1>|
763 769
764 770 assert_equal expected, textilizable(raw)
765 771 end
766 772
767 773 def test_headings_with_special_chars
768 774 # This test makes sure that the generated anchor names match the expected
769 775 # ones even if the heading text contains unconventional characters
770 776 raw = 'h1. Some heading related to version 0.5'
771 777 anchor = sanitize_anchor_name("Some-heading-related-to-version-0.5")
772 778 expected = %|<a name="#{anchor}"></a>\n<h1 >Some heading related to version 0.5<a href="##{anchor}" class="wiki-anchor">&para;</a></h1>|
773 779
774 780 assert_equal expected, textilizable(raw)
775 781 end
776 782
777 783 def test_headings_in_wiki_single_page_export_should_be_prepended_with_page_title
778 784 page = WikiPage.new( :title => 'Page Title', :wiki_id => 1 )
779 785 content = WikiContent.new( :text => 'h1. Some heading', :page => page )
780 786
781 787 expected = %|<a name="Page_Title_Some-heading"></a>\n<h1 >Some heading<a href="#Page_Title_Some-heading" class="wiki-anchor">&para;</a></h1>|
782 788
783 789 assert_equal expected, textilizable(content, :text, :wiki_links => :anchor )
784 790 end
785 791
786 792 def test_table_of_content
787 793 raw = <<-RAW
788 794 {{toc}}
789 795
790 796 h1. Title
791 797
792 798 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
793 799
794 800 h2. Subtitle with a [[Wiki]] link
795 801
796 802 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
797 803
798 804 h2. Subtitle with [[Wiki|another Wiki]] link
799 805
800 806 h2. Subtitle with %{color:red}red text%
801 807
802 808 <pre>
803 809 some code
804 810 </pre>
805 811
806 812 h3. Subtitle with *some* _modifiers_
807 813
808 814 h3. Subtitle with @inline code@
809 815
810 816 h1. Another title
811 817
812 818 h3. An "Internet link":http://www.redmine.org/ inside subtitle
813 819
814 820 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
815 821
816 822 RAW
817 823
818 824 expected = '<ul class="toc">' +
819 825 '<li><a href="#Title">Title</a>' +
820 826 '<ul>' +
821 827 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
822 828 '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
823 829 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
824 830 '<ul>' +
825 831 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
826 832 '<li><a href="#Subtitle-with-inline-code">Subtitle with inline code</a></li>' +
827 833 '</ul>' +
828 834 '</li>' +
829 835 '</ul>' +
830 836 '</li>' +
831 837 '<li><a href="#Another-title">Another title</a>' +
832 838 '<ul>' +
833 839 '<li>' +
834 840 '<ul>' +
835 841 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
836 842 '</ul>' +
837 843 '</li>' +
838 844 '<li><a href="#Project-Name">Project Name</a></li>' +
839 845 '</ul>' +
840 846 '</li>' +
841 847 '</ul>'
842 848
843 849 @project = Project.find(1)
844 850 assert textilizable(raw).gsub("\n", "").include?(expected)
845 851 end
846 852
847 853 def test_table_of_content_should_generate_unique_anchors
848 854 raw = <<-RAW
849 855 {{toc}}
850 856
851 857 h1. Title
852 858
853 859 h2. Subtitle
854 860
855 861 h2. Subtitle
856 862 RAW
857 863
858 864 expected = '<ul class="toc">' +
859 865 '<li><a href="#Title">Title</a>' +
860 866 '<ul>' +
861 867 '<li><a href="#Subtitle">Subtitle</a></li>' +
862 868 '<li><a href="#Subtitle-2">Subtitle</a></li>'
863 869 '</ul>'
864 870 '</li>' +
865 871 '</ul>'
866 872
867 873 @project = Project.find(1)
868 874 result = textilizable(raw).gsub("\n", "")
869 875 assert_include expected, result
870 876 assert_include '<a name="Subtitle">', result
871 877 assert_include '<a name="Subtitle-2">', result
872 878 end
873 879
874 880 def test_table_of_content_should_contain_included_page_headings
875 881 raw = <<-RAW
876 882 {{toc}}
877 883
878 884 h1. Included
879 885
880 886 {{include(Child_1)}}
881 887 RAW
882 888
883 889 expected = '<ul class="toc">' +
884 890 '<li><a href="#Included">Included</a></li>' +
885 891 '<li><a href="#Child-page-1">Child page 1</a></li>' +
886 892 '</ul>'
887 893
888 894 @project = Project.find(1)
889 895 assert textilizable(raw).gsub("\n", "").include?(expected)
890 896 end
891 897
892 898 def test_section_edit_links
893 899 raw = <<-RAW
894 900 h1. Title
895 901
896 902 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
897 903
898 904 h2. Subtitle with a [[Wiki]] link
899 905
900 906 h2. Subtitle with *some* _modifiers_
901 907
902 908 h2. Subtitle with @inline code@
903 909
904 910 <pre>
905 911 some code
906 912
907 913 h2. heading inside pre
908 914
909 915 <h2>html heading inside pre</h2>
910 916 </pre>
911 917
912 918 h2. Subtitle after pre tag
913 919 RAW
914 920
915 921 @project = Project.find(1)
916 922 set_language_if_valid 'en'
917 923 result = textilizable(raw, :edit_section_links => {:controller => 'wiki', :action => 'edit', :project_id => '1', :id => 'Test'}).gsub("\n", "")
918 924
919 925 # heading that contains inline code
920 926 assert_match Regexp.new('<div class="contextual" title="Edit this section">' +
921 927 '<a href="/projects/1/wiki/Test/edit\?section=4"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
922 928 '<a name="Subtitle-with-inline-code"></a>' +
923 929 '<h2 >Subtitle with <code>inline code</code><a href="#Subtitle-with-inline-code" class="wiki-anchor">&para;</a></h2>'),
924 930 result
925 931
926 932 # last heading
927 933 assert_match Regexp.new('<div class="contextual" title="Edit this section">' +
928 934 '<a href="/projects/1/wiki/Test/edit\?section=5"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
929 935 '<a name="Subtitle-after-pre-tag"></a>' +
930 936 '<h2 >Subtitle after pre tag<a href="#Subtitle-after-pre-tag" class="wiki-anchor">&para;</a></h2>'),
931 937 result
932 938 end
933 939
934 940 def test_default_formatter
935 941 with_settings :text_formatting => 'unknown' do
936 942 text = 'a *link*: http://www.example.net/'
937 943 assert_equal '<p>a *link*: <a href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
938 944 end
939 945 end
940 946
941 947 def test_due_date_distance_in_words
942 948 to_test = { Date.today => 'Due in 0 days',
943 949 Date.today + 1 => 'Due in 1 day',
944 950 Date.today + 100 => 'Due in about 3 months',
945 951 Date.today + 20000 => 'Due in over 54 years',
946 952 Date.today - 1 => '1 day late',
947 953 Date.today - 100 => 'about 3 months late',
948 954 Date.today - 20000 => 'over 54 years late',
949 955 }
950 956 ::I18n.locale = :en
951 957 to_test.each do |date, expected|
952 958 assert_equal expected, due_date_distance_in_words(date)
953 959 end
954 960 end
955 961
956 962 def test_avatar
957 963 # turn on avatars
958 964 Setting.gravatar_enabled = '1'
959 965 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
960 966 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
961 967 assert_nil avatar('jsmith')
962 968 assert_nil avatar(nil)
963 969
964 970 # turn off avatars
965 971 Setting.gravatar_enabled = '0'
966 972 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
967 973 end
968 974
969 975 def test_link_to_user
970 976 user = User.find(2)
971 977 t = link_to_user(user)
972 978 assert_equal "<a href=\"/users/2\">#{ user.name }</a>", t
973 979 end
974 980
975 981 def test_link_to_user_should_not_link_to_locked_user
976 982 user = User.find(5)
977 983 assert user.locked?
978 984 t = link_to_user(user)
979 985 assert_equal user.name, t
980 986 end
981 987
982 988 def test_link_to_user_should_not_link_to_anonymous
983 989 user = User.anonymous
984 990 assert user.anonymous?
985 991 t = link_to_user(user)
986 992 assert_equal ::I18n.t(:label_user_anonymous), t
987 993 end
988 994
989 995 def test_link_to_project
990 996 project = Project.find(1)
991 997 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
992 998 link_to_project(project)
993 999 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
994 1000 link_to_project(project, :action => 'settings')
995 1001 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
996 1002 link_to_project(project, {:only_path => false, :jump => 'blah'})
997 1003 assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
998 1004 link_to_project(project, {:action => 'settings'}, :class => "project")
999 1005 end
1000 1006
1001 1007 def test_link_to_legacy_project_with_numerical_identifier_should_use_id
1002 1008 # numeric identifier are no longer allowed
1003 1009 Project.update_all "identifier=25", "id=1"
1004 1010
1005 1011 assert_equal '<a href="/projects/1">eCookbook</a>',
1006 1012 link_to_project(Project.find(1))
1007 1013 end
1008 1014
1009 1015 def test_principals_options_for_select_with_users
1010 1016 User.current = nil
1011 1017 users = [User.find(2), User.find(4)]
1012 1018 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>),
1013 1019 principals_options_for_select(users)
1014 1020 end
1015 1021
1016 1022 def test_principals_options_for_select_with_selected
1017 1023 User.current = nil
1018 1024 users = [User.find(2), User.find(4)]
1019 1025 assert_equal %(<option value="2">John Smith</option><option value="4" selected="selected">Robert Hill</option>),
1020 1026 principals_options_for_select(users, User.find(4))
1021 1027 end
1022 1028
1023 1029 def test_principals_options_for_select_with_users_and_groups
1024 1030 User.current = nil
1025 1031 users = [User.find(2), Group.find(11), User.find(4), Group.find(10)]
1026 1032 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>) +
1027 1033 %(<optgroup label="Groups"><option value="10">A Team</option><option value="11">B Team</option></optgroup>),
1028 1034 principals_options_for_select(users)
1029 1035 end
1030 1036
1031 1037 def test_principals_options_for_select_with_empty_collection
1032 1038 assert_equal '', principals_options_for_select([])
1033 1039 end
1034 1040
1035 1041 def test_principals_options_for_select_should_include_me_option_when_current_user_is_in_collection
1036 1042 users = [User.find(2), User.find(4)]
1037 1043 User.current = User.find(4)
1038 1044 assert_include '<option value="4"><< me >></option>', principals_options_for_select(users)
1039 1045 end
1040 1046 end
General Comments 0
You need to be logged in to leave comments. Login now