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