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