##// END OF EJS Templates
fix unit search test failure (#13405)...
Toshi MARUYAMA -
r11444:919d4589b9e1
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 6 scmid: 691322a8eb01e11fd7
7 7 id: 100
8 comments: 'do not escaping #<>&'
8 comments: 'My very first commit do not escaping #<>&'
9 9 repository_id: 10
10 10 committer: dlopper
11 11 user_id: 3
12 12 changesets_002:
13 13 commit_date: 2007-04-12
14 14 committed_on: 2007-04-12 15:14:44 +02:00
15 15 revision: 2
16 16 id: 101
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,1213
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 => 'do not escaping #<>&')
268 :class => 'changeset', :title => 'My very first commit 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 => 1},
273 :class => 'changeset', :title => 'do not escaping #<>&')
272 changeset_link2 = link_to('691322a8eb01e11fd7',
273 {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
274 :class => 'changeset', :title => 'My very first commit do not escaping #<>&')
274 275
275 276 document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
276 277 :class => 'document')
277 278
278 279 version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
279 280 :class => 'version')
280 281
281 282 board_url = {:controller => 'boards', :action => 'show', :id => 2, :project_id => 'ecookbook'}
282 283
283 284 message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
284 285
285 286 news_url = {:controller => 'news', :action => 'show', :id => 1}
286 287
287 288 project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
288 289
289 290 source_url = '/projects/ecookbook/repository/entry/some/file'
290 291 source_url_with_rev = '/projects/ecookbook/repository/revisions/52/entry/some/file'
291 292 source_url_with_ext = '/projects/ecookbook/repository/entry/some/file.ext'
292 293 source_url_with_rev_and_ext = '/projects/ecookbook/repository/revisions/52/entry/some/file.ext'
293 294 source_url_with_branch = '/projects/ecookbook/repository/revisions/branch/entry/some/file'
294 295
295 296 export_url = '/projects/ecookbook/repository/raw/some/file'
296 297 export_url_with_rev = '/projects/ecookbook/repository/revisions/52/raw/some/file'
297 298 export_url_with_ext = '/projects/ecookbook/repository/raw/some/file.ext'
298 299 export_url_with_rev_and_ext = '/projects/ecookbook/repository/revisions/52/raw/some/file.ext'
299 300 export_url_with_branch = '/projects/ecookbook/repository/revisions/branch/raw/some/file'
300 301
301 302 to_test = {
302 303 # tickets
303 304 '#3, [#3], (#3) and #3.' => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
304 305 # ticket notes
305 306 '#3-14' => note_link,
306 307 '#3#note-14' => note_link,
307 308 # should not ignore leading zero
308 309 '#03' => '#03',
309 310 # changesets
310 311 'r1' => revision_link,
311 312 'r1.' => "#{revision_link}.",
312 313 'r1, r2' => "#{revision_link}, #{revision_link2}",
313 314 'r1,r2' => "#{revision_link},#{revision_link2}",
314 315 'commit:691322a8eb01e11fd7' => changeset_link2,
315 316 # documents
316 317 'document#1' => document_link,
317 318 'document:"Test document"' => document_link,
318 319 # versions
319 320 'version#2' => version_link,
320 321 'version:1.0' => version_link,
321 322 'version:"1.0"' => version_link,
322 323 # source
323 324 'source:some/file' => link_to('source:some/file', source_url, :class => 'source'),
324 325 'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'),
325 326 'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".",
326 327 'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
327 328 'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".",
328 329 'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
329 330 'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",",
330 331 'source:/some/file@52' => link_to('source:/some/file@52', source_url_with_rev, :class => 'source'),
331 332 'source:/some/file@branch' => link_to('source:/some/file@branch', source_url_with_branch, :class => 'source'),
332 333 'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_rev_and_ext, :class => 'source'),
333 334 'source:/some/file#L110' => link_to('source:/some/file#L110', source_url + "#L110", :class => 'source'),
334 335 'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext + "#L110", :class => 'source'),
335 336 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url_with_rev + "#L110", :class => 'source'),
336 337 # export
337 338 'export:/some/file' => link_to('export:/some/file', export_url, :class => 'source download'),
338 339 'export:/some/file.ext' => link_to('export:/some/file.ext', export_url_with_ext, :class => 'source download'),
339 340 'export:/some/file@52' => link_to('export:/some/file@52', export_url_with_rev, :class => 'source download'),
340 341 'export:/some/file.ext@52' => link_to('export:/some/file.ext@52', export_url_with_rev_and_ext, :class => 'source download'),
341 342 'export:/some/file@branch' => link_to('export:/some/file@branch', export_url_with_branch, :class => 'source download'),
342 343 # forum
343 344 'forum#2' => link_to('Discussion', board_url, :class => 'board'),
344 345 'forum:Discussion' => link_to('Discussion', board_url, :class => 'board'),
345 346 # message
346 347 'message#4' => link_to('Post 2', message_url, :class => 'message'),
347 348 'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5', :r => 5), :class => 'message'),
348 349 # news
349 350 'news#1' => link_to('eCookbook first release !', news_url, :class => 'news'),
350 351 'news:"eCookbook first release !"' => link_to('eCookbook first release !', news_url, :class => 'news'),
351 352 # project
352 353 'project#3' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
353 354 'project:subproject1' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
354 355 'project:"eCookbook subProject 1"' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
355 356 # not found
356 357 '#0123456789' => '#0123456789',
357 358 # invalid expressions
358 359 'source:' => 'source:',
359 360 # url hash
360 361 "http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
361 362 }
362 363 @project = Project.find(1)
363 364 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
364 365 end
365 366
366 367 def test_redmine_links_with_a_different_project_before_current_project
367 368 vp1 = Version.generate!(:project_id => 1, :name => '1.4.4')
368 369 vp3 = Version.generate!(:project_id => 3, :name => '1.4.4')
369 370
370 371 @project = Project.find(3)
371 372 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 373 textilizable("ecookbook:version:1.4.4 version:1.4.4")
373 374 end
374 375
375 376 def test_escaped_redmine_links_should_not_be_parsed
376 377 to_test = [
377 378 '#3.',
378 379 '#3-14.',
379 380 '#3#-note14.',
380 381 'r1',
381 382 'document#1',
382 383 'document:"Test document"',
383 384 'version#2',
384 385 'version:1.0',
385 386 'version:"1.0"',
386 387 'source:/some/file'
387 388 ]
388 389 @project = Project.find(1)
389 390 to_test.each { |text| assert_equal "<p>#{text}</p>", textilizable("!" + text), "#{text} failed" }
390 391 end
391 392
392 393 def test_cross_project_redmine_links
393 394 source_link = link_to('ecookbook:source:/some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']},
394 395 :class => 'source')
395 396
396 397 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
397 398 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
398 399
399 400 to_test = {
400 401 # documents
401 402 'document:"Test document"' => 'document:"Test document"',
402 403 'ecookbook:document:"Test document"' => '<a href="/documents/1" class="document">Test document</a>',
403 404 'invalid:document:"Test document"' => 'invalid:document:"Test document"',
404 405 # versions
405 406 'version:"1.0"' => 'version:"1.0"',
406 407 'ecookbook:version:"1.0"' => '<a href="/versions/2" class="version">1.0</a>',
407 408 'invalid:version:"1.0"' => 'invalid:version:"1.0"',
408 409 # changeset
409 410 'r2' => 'r2',
410 411 'ecookbook:r2' => changeset_link,
411 412 'invalid:r2' => 'invalid:r2',
412 413 # source
413 414 'source:/some/file' => 'source:/some/file',
414 415 'ecookbook:source:/some/file' => source_link,
415 416 'invalid:source:/some/file' => 'invalid:source:/some/file',
416 417 }
417 418 @project = Project.find(3)
418 419 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
419 420 end
420 421
421 422 def test_multiple_repositories_redmine_links
422 423 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn_repo-1', :url => 'file:///foo/hg')
423 424 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
424 425 hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
425 426 Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
426 427
427 428 changeset_link = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
428 429 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
429 430 svn_changeset_link = link_to('svn_repo-1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn_repo-1', :rev => 123},
430 431 :class => 'changeset', :title => '')
431 432 hg_changeset_link = link_to('hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
432 433 :class => 'changeset', :title => '')
433 434
434 435 source_link = link_to('source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
435 436 hg_source_link = link_to('source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source')
436 437
437 438 to_test = {
438 439 'r2' => changeset_link,
439 440 'svn_repo-1|r123' => svn_changeset_link,
440 441 'invalid|r123' => 'invalid|r123',
441 442 'commit:hg1|abcd' => hg_changeset_link,
442 443 'commit:invalid|abcd' => 'commit:invalid|abcd',
443 444 # source
444 445 'source:some/file' => source_link,
445 446 'source:hg1|some/file' => hg_source_link,
446 447 'source:invalid|some/file' => 'source:invalid|some/file',
447 448 }
448 449
449 450 @project = Project.find(1)
450 451 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
451 452 end
452 453
453 454 def test_cross_project_multiple_repositories_redmine_links
454 455 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn1', :url => 'file:///foo/hg')
455 456 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
456 457 hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
457 458 Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
458 459
459 460 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
460 461 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
461 462 svn_changeset_link = link_to('ecookbook:svn1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn1', :rev => 123},
462 463 :class => 'changeset', :title => '')
463 464 hg_changeset_link = link_to('ecookbook:hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
464 465 :class => 'changeset', :title => '')
465 466
466 467 source_link = link_to('ecookbook:source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
467 468 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 469
469 470 to_test = {
470 471 'ecookbook:r2' => changeset_link,
471 472 'ecookbook:svn1|r123' => svn_changeset_link,
472 473 'ecookbook:invalid|r123' => 'ecookbook:invalid|r123',
473 474 'ecookbook:commit:hg1|abcd' => hg_changeset_link,
474 475 'ecookbook:commit:invalid|abcd' => 'ecookbook:commit:invalid|abcd',
475 476 'invalid:commit:invalid|abcd' => 'invalid:commit:invalid|abcd',
476 477 # source
477 478 'ecookbook:source:some/file' => source_link,
478 479 'ecookbook:source:hg1|some/file' => hg_source_link,
479 480 'ecookbook:source:invalid|some/file' => 'ecookbook:source:invalid|some/file',
480 481 'invalid:source:invalid|some/file' => 'invalid:source:invalid|some/file',
481 482 }
482 483
483 484 @project = Project.find(3)
484 485 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
485 486 end
486 487
487 488 def test_redmine_links_git_commit
488 489 changeset_link = link_to('abcd',
489 490 {
490 491 :controller => 'repositories',
491 492 :action => 'revision',
492 493 :id => 'subproject1',
493 494 :rev => 'abcd',
494 495 },
495 496 :class => 'changeset', :title => 'test commit')
496 497 to_test = {
497 498 'commit:abcd' => changeset_link,
498 499 }
499 500 @project = Project.find(3)
500 501 r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
501 502 assert r
502 503 c = Changeset.new(:repository => r,
503 504 :committed_on => Time.now,
504 505 :revision => 'abcd',
505 506 :scmid => 'abcd',
506 507 :comments => 'test commit')
507 508 assert( c.save )
508 509 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
509 510 end
510 511
511 512 # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
512 513 def test_redmine_links_darcs_commit
513 514 changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
514 515 {
515 516 :controller => 'repositories',
516 517 :action => 'revision',
517 518 :id => 'subproject1',
518 519 :rev => '123',
519 520 },
520 521 :class => 'changeset', :title => 'test commit')
521 522 to_test = {
522 523 'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
523 524 }
524 525 @project = Project.find(3)
525 526 r = Repository::Darcs.create!(
526 527 :project => @project, :url => '/tmp/test/darcs',
527 528 :log_encoding => 'UTF-8')
528 529 assert r
529 530 c = Changeset.new(:repository => r,
530 531 :committed_on => Time.now,
531 532 :revision => '123',
532 533 :scmid => '20080308225258-98289-abcd456efg.gz',
533 534 :comments => 'test commit')
534 535 assert( c.save )
535 536 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
536 537 end
537 538
538 539 def test_redmine_links_mercurial_commit
539 540 changeset_link_rev = link_to('r123',
540 541 {
541 542 :controller => 'repositories',
542 543 :action => 'revision',
543 544 :id => 'subproject1',
544 545 :rev => '123' ,
545 546 },
546 547 :class => 'changeset', :title => 'test commit')
547 548 changeset_link_commit = link_to('abcd',
548 549 {
549 550 :controller => 'repositories',
550 551 :action => 'revision',
551 552 :id => 'subproject1',
552 553 :rev => 'abcd' ,
553 554 },
554 555 :class => 'changeset', :title => 'test commit')
555 556 to_test = {
556 557 'r123' => changeset_link_rev,
557 558 'commit:abcd' => changeset_link_commit,
558 559 }
559 560 @project = Project.find(3)
560 561 r = Repository::Mercurial.create!(:project => @project, :url => '/tmp/test')
561 562 assert r
562 563 c = Changeset.new(:repository => r,
563 564 :committed_on => Time.now,
564 565 :revision => '123',
565 566 :scmid => 'abcd',
566 567 :comments => 'test commit')
567 568 assert( c.save )
568 569 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
569 570 end
570 571
571 572 def test_attachment_links
572 573 to_test = {
573 574 'attachment:error281.txt' => '<a href="/attachments/download/1/error281.txt" class="attachment">error281.txt</a>'
574 575 }
575 576 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
576 577 end
577 578
578 579 def test_attachment_link_should_link_to_latest_attachment
579 580 set_tmp_attachments_directory
580 581 a1 = Attachment.generate!(:filename => "test.txt", :created_on => 1.hour.ago)
581 582 a2 = Attachment.generate!(:filename => "test.txt")
582 583
583 584 assert_equal %(<p><a href="/attachments/download/#{a2.id}/test.txt" class="attachment">test.txt</a></p>),
584 585 textilizable('attachment:test.txt', :attachments => [a1, a2])
585 586 end
586 587
587 588 def test_wiki_links
588 589 to_test = {
589 590 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
590 591 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
591 592 # title content should be formatted
592 593 '[[Another page|With _styled_ *title*]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">With <em>styled</em> <strong>title</strong></a>',
593 594 '[[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 595 # link with anchor
595 596 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
596 597 '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
597 598 # UTF8 anchor
598 599 '[[Another_page#ВСст|ВСст]]' => %|<a href="/projects/ecookbook/wiki/Another_page##{CGI.escape 'ВСст'}" class="wiki-page">ВСст</a>|,
599 600 # page that doesn't exist
600 601 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
601 602 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
602 603 # link to another project wiki
603 604 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
604 605 '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">Wiki</a>',
605 606 '[[onlinestore:Start page]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Start page</a>',
606 607 '[[onlinestore:Start page|Text]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Text</a>',
607 608 '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
608 609 # striked through link
609 610 '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
610 611 '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
611 612 # escaping
612 613 '![[Another page|Page]]' => '[[Another page|Page]]',
613 614 # project does not exist
614 615 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
615 616 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
616 617 }
617 618
618 619 @project = Project.find(1)
619 620 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
620 621 end
621 622
622 623 def test_wiki_links_within_local_file_generation_context
623 624
624 625 to_test = {
625 626 # link to a page
626 627 '[[CookBook documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">CookBook documentation</a>',
627 628 '[[CookBook documentation|documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">documentation</a>',
628 629 '[[CookBook documentation#One-section]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">CookBook documentation</a>',
629 630 '[[CookBook documentation#One-section|documentation]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">documentation</a>',
630 631 # page that doesn't exist
631 632 '[[Unknown page]]' => '<a href="Unknown_page.html" class="wiki-page new">Unknown page</a>',
632 633 '[[Unknown page|404]]' => '<a href="Unknown_page.html" class="wiki-page new">404</a>',
633 634 '[[Unknown page#anchor]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">Unknown page</a>',
634 635 '[[Unknown page#anchor|404]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">404</a>',
635 636 }
636 637
637 638 @project = Project.find(1)
638 639
639 640 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :local) }
640 641 end
641 642
642 643 def test_wiki_links_within_wiki_page_context
643 644
644 645 page = WikiPage.find_by_title('Another_page' )
645 646
646 647 to_test = {
647 648 # link to another page
648 649 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
649 650 '[[CookBook documentation|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">documentation</a>',
650 651 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
651 652 '[[CookBook documentation#One-section|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">documentation</a>',
652 653 # link to the current page
653 654 '[[Another page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Another page</a>',
654 655 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
655 656 '[[Another page#anchor]]' => '<a href="#anchor" class="wiki-page">Another page</a>',
656 657 '[[Another page#anchor|Page]]' => '<a href="#anchor" class="wiki-page">Page</a>',
657 658 # page that doesn't exist
658 659 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page" class="wiki-page new">Unknown page</a>',
659 660 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page" class="wiki-page new">404</a>',
660 661 '[[Unknown page#anchor]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor" class="wiki-page new">Unknown page</a>',
661 662 '[[Unknown page#anchor|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor" class="wiki-page new">404</a>',
662 663 }
663 664
664 665 @project = Project.find(1)
665 666
666 667 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(WikiContent.new( :text => text, :page => page ), :text) }
667 668 end
668 669
669 670 def test_wiki_links_anchor_option_should_prepend_page_title_to_href
670 671
671 672 to_test = {
672 673 # link to a page
673 674 '[[CookBook documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">CookBook documentation</a>',
674 675 '[[CookBook documentation|documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">documentation</a>',
675 676 '[[CookBook documentation#One-section]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">CookBook documentation</a>',
676 677 '[[CookBook documentation#One-section|documentation]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">documentation</a>',
677 678 # page that doesn't exist
678 679 '[[Unknown page]]' => '<a href="#Unknown_page" class="wiki-page new">Unknown page</a>',
679 680 '[[Unknown page|404]]' => '<a href="#Unknown_page" class="wiki-page new">404</a>',
680 681 '[[Unknown page#anchor]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">Unknown page</a>',
681 682 '[[Unknown page#anchor|404]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">404</a>',
682 683 }
683 684
684 685 @project = Project.find(1)
685 686
686 687 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :anchor) }
687 688 end
688 689
689 690 def test_html_tags
690 691 to_test = {
691 692 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
692 693 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
693 694 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
694 695 # do not escape pre/code tags
695 696 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
696 697 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
697 698 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
698 699 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
699 700 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
700 701 # remove attributes except class
701 702 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
702 703 '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
703 704 "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
704 705 '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
705 706 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
706 707 # xss
707 708 '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
708 709 '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
709 710 }
710 711 to_test.each { |text, result| assert_equal result, textilizable(text) }
711 712 end
712 713
713 714 def test_allowed_html_tags
714 715 to_test = {
715 716 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
716 717 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
717 718 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
718 719 }
719 720 to_test.each { |text, result| assert_equal result, textilizable(text) }
720 721 end
721 722
722 723 def test_pre_tags
723 724 raw = <<-RAW
724 725 Before
725 726
726 727 <pre>
727 728 <prepared-statement-cache-size>32</prepared-statement-cache-size>
728 729 </pre>
729 730
730 731 After
731 732 RAW
732 733
733 734 expected = <<-EXPECTED
734 735 <p>Before</p>
735 736 <pre>
736 737 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
737 738 </pre>
738 739 <p>After</p>
739 740 EXPECTED
740 741
741 742 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
742 743 end
743 744
744 745 def test_pre_content_should_not_parse_wiki_and_redmine_links
745 746 raw = <<-RAW
746 747 [[CookBook documentation]]
747 748
748 749 #1
749 750
750 751 <pre>
751 752 [[CookBook documentation]]
752 753
753 754 #1
754 755 </pre>
755 756 RAW
756 757
757 758 expected = <<-EXPECTED
758 759 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
759 760 <p><a href="/issues/1" class="#{Issue.find(1).css_classes}" title="Can&#x27;t print recipes (New)">#1</a></p>
760 761 <pre>
761 762 [[CookBook documentation]]
762 763
763 764 #1
764 765 </pre>
765 766 EXPECTED
766 767
767 768 @project = Project.find(1)
768 769 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
769 770 end
770 771
771 772 def test_non_closing_pre_blocks_should_be_closed
772 773 raw = <<-RAW
773 774 <pre><code>
774 775 RAW
775 776
776 777 expected = <<-EXPECTED
777 778 <pre><code>
778 779 </code></pre>
779 780 EXPECTED
780 781
781 782 @project = Project.find(1)
782 783 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
783 784 end
784 785
785 786 def test_syntax_highlight
786 787 raw = <<-RAW
787 788 <pre><code class="ruby">
788 789 # Some ruby code here
789 790 </code></pre>
790 791 RAW
791 792
792 793 expected = <<-EXPECTED
793 794 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="comment"># Some ruby code here</span></span>
794 795 </code></pre>
795 796 EXPECTED
796 797
797 798 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
798 799 end
799 800
800 801 def test_to_path_param
801 802 assert_equal 'test1/test2', to_path_param('test1/test2')
802 803 assert_equal 'test1/test2', to_path_param('/test1/test2/')
803 804 assert_equal 'test1/test2', to_path_param('//test1/test2/')
804 805 assert_equal nil, to_path_param('/')
805 806 end
806 807
807 808 def test_wiki_links_in_tables
808 809 to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
809 810 '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
810 811 '<td><a href="/projects/ecookbook/wiki/Other_Page" class="wiki-page new">Other title</a></td>' +
811 812 '</tr><tr><td>Cell 21</td><td><a href="/projects/ecookbook/wiki/Last_page" class="wiki-page new">Last page</a></td></tr>'
812 813 }
813 814 @project = Project.find(1)
814 815 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
815 816 end
816 817
817 818 def test_text_formatting
818 819 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
819 820 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
820 821 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
821 822 '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 823 '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 824 }
824 825 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
825 826 end
826 827
827 828 def test_wiki_horizontal_rule
828 829 assert_equal '<hr />', textilizable('---')
829 830 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
830 831 end
831 832
832 833 def test_footnotes
833 834 raw = <<-RAW
834 835 This is some text[1].
835 836
836 837 fn1. This is the foot note
837 838 RAW
838 839
839 840 expected = <<-EXPECTED
840 841 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
841 842 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
842 843 EXPECTED
843 844
844 845 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
845 846 end
846 847
847 848 def test_headings
848 849 raw = 'h1. Some heading'
849 850 expected = %|<a name="Some-heading"></a>\n<h1 >Some heading<a href="#Some-heading" class="wiki-anchor">&para;</a></h1>|
850 851
851 852 assert_equal expected, textilizable(raw)
852 853 end
853 854
854 855 def test_headings_with_special_chars
855 856 # This test makes sure that the generated anchor names match the expected
856 857 # ones even if the heading text contains unconventional characters
857 858 raw = 'h1. Some heading related to version 0.5'
858 859 anchor = sanitize_anchor_name("Some-heading-related-to-version-0.5")
859 860 expected = %|<a name="#{anchor}"></a>\n<h1 >Some heading related to version 0.5<a href="##{anchor}" class="wiki-anchor">&para;</a></h1>|
860 861
861 862 assert_equal expected, textilizable(raw)
862 863 end
863 864
864 865 def test_headings_in_wiki_single_page_export_should_be_prepended_with_page_title
865 866 page = WikiPage.new( :title => 'Page Title', :wiki_id => 1 )
866 867 content = WikiContent.new( :text => 'h1. Some heading', :page => page )
867 868
868 869 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 870
870 871 assert_equal expected, textilizable(content, :text, :wiki_links => :anchor )
871 872 end
872 873
873 874 def test_table_of_content
874 875 raw = <<-RAW
875 876 {{toc}}
876 877
877 878 h1. Title
878 879
879 880 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
880 881
881 882 h2. Subtitle with a [[Wiki]] link
882 883
883 884 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
884 885
885 886 h2. Subtitle with [[Wiki|another Wiki]] link
886 887
887 888 h2. Subtitle with %{color:red}red text%
888 889
889 890 <pre>
890 891 some code
891 892 </pre>
892 893
893 894 h3. Subtitle with *some* _modifiers_
894 895
895 896 h3. Subtitle with @inline code@
896 897
897 898 h1. Another title
898 899
899 900 h3. An "Internet link":http://www.redmine.org/ inside subtitle
900 901
901 902 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
902 903
903 904 RAW
904 905
905 906 expected = '<ul class="toc">' +
906 907 '<li><a href="#Title">Title</a>' +
907 908 '<ul>' +
908 909 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
909 910 '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
910 911 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
911 912 '<ul>' +
912 913 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
913 914 '<li><a href="#Subtitle-with-inline-code">Subtitle with inline code</a></li>' +
914 915 '</ul>' +
915 916 '</li>' +
916 917 '</ul>' +
917 918 '</li>' +
918 919 '<li><a href="#Another-title">Another title</a>' +
919 920 '<ul>' +
920 921 '<li>' +
921 922 '<ul>' +
922 923 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
923 924 '</ul>' +
924 925 '</li>' +
925 926 '<li><a href="#Project-Name">Project Name</a></li>' +
926 927 '</ul>' +
927 928 '</li>' +
928 929 '</ul>'
929 930
930 931 @project = Project.find(1)
931 932 assert textilizable(raw).gsub("\n", "").include?(expected)
932 933 end
933 934
934 935 def test_table_of_content_should_generate_unique_anchors
935 936 raw = <<-RAW
936 937 {{toc}}
937 938
938 939 h1. Title
939 940
940 941 h2. Subtitle
941 942
942 943 h2. Subtitle
943 944 RAW
944 945
945 946 expected = '<ul class="toc">' +
946 947 '<li><a href="#Title">Title</a>' +
947 948 '<ul>' +
948 949 '<li><a href="#Subtitle">Subtitle</a></li>' +
949 950 '<li><a href="#Subtitle-2">Subtitle</a></li>'
950 951 '</ul>'
951 952 '</li>' +
952 953 '</ul>'
953 954
954 955 @project = Project.find(1)
955 956 result = textilizable(raw).gsub("\n", "")
956 957 assert_include expected, result
957 958 assert_include '<a name="Subtitle">', result
958 959 assert_include '<a name="Subtitle-2">', result
959 960 end
960 961
961 962 def test_table_of_content_should_contain_included_page_headings
962 963 raw = <<-RAW
963 964 {{toc}}
964 965
965 966 h1. Included
966 967
967 968 {{include(Child_1)}}
968 969 RAW
969 970
970 971 expected = '<ul class="toc">' +
971 972 '<li><a href="#Included">Included</a></li>' +
972 973 '<li><a href="#Child-page-1">Child page 1</a></li>' +
973 974 '</ul>'
974 975
975 976 @project = Project.find(1)
976 977 assert textilizable(raw).gsub("\n", "").include?(expected)
977 978 end
978 979
979 980 def test_section_edit_links
980 981 raw = <<-RAW
981 982 h1. Title
982 983
983 984 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
984 985
985 986 h2. Subtitle with a [[Wiki]] link
986 987
987 988 h2. Subtitle with *some* _modifiers_
988 989
989 990 h2. Subtitle with @inline code@
990 991
991 992 <pre>
992 993 some code
993 994
994 995 h2. heading inside pre
995 996
996 997 <h2>html heading inside pre</h2>
997 998 </pre>
998 999
999 1000 h2. Subtitle after pre tag
1000 1001 RAW
1001 1002
1002 1003 @project = Project.find(1)
1003 1004 set_language_if_valid 'en'
1004 1005 result = textilizable(raw, :edit_section_links => {:controller => 'wiki', :action => 'edit', :project_id => '1', :id => 'Test'}).gsub("\n", "")
1005 1006
1006 1007 # heading that contains inline code
1007 1008 assert_match Regexp.new('<div class="contextual" title="Edit this section">' +
1008 1009 '<a href="/projects/1/wiki/Test/edit\?section=4"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
1009 1010 '<a name="Subtitle-with-inline-code"></a>' +
1010 1011 '<h2 >Subtitle with <code>inline code</code><a href="#Subtitle-with-inline-code" class="wiki-anchor">&para;</a></h2>'),
1011 1012 result
1012 1013
1013 1014 # last heading
1014 1015 assert_match Regexp.new('<div class="contextual" title="Edit this section">' +
1015 1016 '<a href="/projects/1/wiki/Test/edit\?section=5"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
1016 1017 '<a name="Subtitle-after-pre-tag"></a>' +
1017 1018 '<h2 >Subtitle after pre tag<a href="#Subtitle-after-pre-tag" class="wiki-anchor">&para;</a></h2>'),
1018 1019 result
1019 1020 end
1020 1021
1021 1022 def test_default_formatter
1022 1023 with_settings :text_formatting => 'unknown' do
1023 1024 text = 'a *link*: http://www.example.net/'
1024 1025 assert_equal '<p>a *link*: <a class="external" href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
1025 1026 end
1026 1027 end
1027 1028
1028 1029 def test_due_date_distance_in_words
1029 1030 to_test = { Date.today => 'Due in 0 days',
1030 1031 Date.today + 1 => 'Due in 1 day',
1031 1032 Date.today + 100 => 'Due in about 3 months',
1032 1033 Date.today + 20000 => 'Due in over 54 years',
1033 1034 Date.today - 1 => '1 day late',
1034 1035 Date.today - 100 => 'about 3 months late',
1035 1036 Date.today - 20000 => 'over 54 years late',
1036 1037 }
1037 1038 ::I18n.locale = :en
1038 1039 to_test.each do |date, expected|
1039 1040 assert_equal expected, due_date_distance_in_words(date)
1040 1041 end
1041 1042 end
1042 1043
1043 1044 def test_avatar_enabled
1044 1045 with_settings :gravatar_enabled => '1' do
1045 1046 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
1046 1047 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
1047 1048 # Default size is 50
1048 1049 assert avatar('jsmith <jsmith@somenet.foo>').include?('size=50')
1049 1050 assert avatar('jsmith <jsmith@somenet.foo>', :size => 24).include?('size=24')
1050 1051 # Non-avatar options should be considered html options
1051 1052 assert avatar('jsmith <jsmith@somenet.foo>', :title => 'John Smith').include?('title="John Smith"')
1052 1053 # The default class of the img tag should be gravatar
1053 1054 assert avatar('jsmith <jsmith@somenet.foo>').include?('class="gravatar"')
1054 1055 assert !avatar('jsmith <jsmith@somenet.foo>', :class => 'picture').include?('class="gravatar"')
1055 1056 assert_nil avatar('jsmith')
1056 1057 assert_nil avatar(nil)
1057 1058 end
1058 1059 end
1059 1060
1060 1061 def test_avatar_disabled
1061 1062 with_settings :gravatar_enabled => '0' do
1062 1063 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
1063 1064 end
1064 1065 end
1065 1066
1066 1067 def test_link_to_user
1067 1068 user = User.find(2)
1068 1069 assert_equal '<a href="/users/2" class="user active">John Smith</a>', link_to_user(user)
1069 1070 end
1070 1071
1071 1072 def test_link_to_user_should_not_link_to_locked_user
1072 1073 with_current_user nil do
1073 1074 user = User.find(5)
1074 1075 assert user.locked?
1075 1076 assert_equal 'Dave2 Lopper2', link_to_user(user)
1076 1077 end
1077 1078 end
1078 1079
1079 1080 def test_link_to_user_should_link_to_locked_user_if_current_user_is_admin
1080 1081 with_current_user User.find(1) do
1081 1082 user = User.find(5)
1082 1083 assert user.locked?
1083 1084 assert_equal '<a href="/users/5" class="user locked">Dave2 Lopper2</a>', link_to_user(user)
1084 1085 end
1085 1086 end
1086 1087
1087 1088 def test_link_to_user_should_not_link_to_anonymous
1088 1089 user = User.anonymous
1089 1090 assert user.anonymous?
1090 1091 t = link_to_user(user)
1091 1092 assert_equal ::I18n.t(:label_user_anonymous), t
1092 1093 end
1093 1094
1094 1095 def test_link_to_attachment
1095 1096 a = Attachment.find(3)
1096 1097 assert_equal '<a href="/attachments/3/logo.gif">logo.gif</a>',
1097 1098 link_to_attachment(a)
1098 1099 assert_equal '<a href="/attachments/3/logo.gif">Text</a>',
1099 1100 link_to_attachment(a, :text => 'Text')
1100 1101 assert_equal '<a href="/attachments/3/logo.gif" class="foo">logo.gif</a>',
1101 1102 link_to_attachment(a, :class => 'foo')
1102 1103 assert_equal '<a href="/attachments/download/3/logo.gif">logo.gif</a>',
1103 1104 link_to_attachment(a, :download => true)
1104 1105 assert_equal '<a href="http://test.host/attachments/3/logo.gif">logo.gif</a>',
1105 1106 link_to_attachment(a, :only_path => false)
1106 1107 end
1107 1108
1108 1109 def test_thumbnail_tag
1109 1110 a = Attachment.find(3)
1110 1111 assert_equal '<a href="/attachments/3/logo.gif" title="logo.gif"><img alt="3" src="/attachments/thumbnail/3" /></a>',
1111 1112 thumbnail_tag(a)
1112 1113 end
1113 1114
1114 1115 def test_link_to_project
1115 1116 project = Project.find(1)
1116 1117 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
1117 1118 link_to_project(project)
1118 1119 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
1119 1120 link_to_project(project, :action => 'settings')
1120 1121 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
1121 1122 link_to_project(project, {:only_path => false, :jump => 'blah'})
1122 1123 assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
1123 1124 link_to_project(project, {:action => 'settings'}, :class => "project")
1124 1125 end
1125 1126
1126 1127 def test_link_to_project_settings
1127 1128 project = Project.find(1)
1128 1129 assert_equal '<a href="/projects/ecookbook/settings">eCookbook</a>', link_to_project_settings(project)
1129 1130
1130 1131 project.status = Project::STATUS_CLOSED
1131 1132 assert_equal '<a href="/projects/ecookbook">eCookbook</a>', link_to_project_settings(project)
1132 1133
1133 1134 project.status = Project::STATUS_ARCHIVED
1134 1135 assert_equal 'eCookbook', link_to_project_settings(project)
1135 1136 end
1136 1137
1137 1138 def test_link_to_legacy_project_with_numerical_identifier_should_use_id
1138 1139 # numeric identifier are no longer allowed
1139 1140 Project.update_all "identifier=25", "id=1"
1140 1141
1141 1142 assert_equal '<a href="/projects/1">eCookbook</a>',
1142 1143 link_to_project(Project.find(1))
1143 1144 end
1144 1145
1145 1146 def test_principals_options_for_select_with_users
1146 1147 User.current = nil
1147 1148 users = [User.find(2), User.find(4)]
1148 1149 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>),
1149 1150 principals_options_for_select(users)
1150 1151 end
1151 1152
1152 1153 def test_principals_options_for_select_with_selected
1153 1154 User.current = nil
1154 1155 users = [User.find(2), User.find(4)]
1155 1156 assert_equal %(<option value="2">John Smith</option><option value="4" selected="selected">Robert Hill</option>),
1156 1157 principals_options_for_select(users, User.find(4))
1157 1158 end
1158 1159
1159 1160 def test_principals_options_for_select_with_users_and_groups
1160 1161 User.current = nil
1161 1162 users = [User.find(2), Group.find(11), User.find(4), Group.find(10)]
1162 1163 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>) +
1163 1164 %(<optgroup label="Groups"><option value="10">A Team</option><option value="11">B Team</option></optgroup>),
1164 1165 principals_options_for_select(users)
1165 1166 end
1166 1167
1167 1168 def test_principals_options_for_select_with_empty_collection
1168 1169 assert_equal '', principals_options_for_select([])
1169 1170 end
1170 1171
1171 1172 def test_principals_options_for_select_should_include_me_option_when_current_user_is_in_collection
1172 1173 users = [User.find(2), User.find(4)]
1173 1174 User.current = User.find(4)
1174 1175 assert_include '<option value="4">&lt;&lt; me &gt;&gt;</option>', principals_options_for_select(users)
1175 1176 end
1176 1177
1177 1178 def test_stylesheet_link_tag_should_pick_the_default_stylesheet
1178 1179 assert_match 'href="/stylesheets/styles.css"', stylesheet_link_tag("styles")
1179 1180 end
1180 1181
1181 1182 def test_stylesheet_link_tag_for_plugin_should_pick_the_plugin_stylesheet
1182 1183 assert_match 'href="/plugin_assets/foo/stylesheets/styles.css"', stylesheet_link_tag("styles", :plugin => :foo)
1183 1184 end
1184 1185
1185 1186 def test_image_tag_should_pick_the_default_image
1186 1187 assert_match 'src="/images/image.png"', image_tag("image.png")
1187 1188 end
1188 1189
1189 1190 def test_image_tag_should_pick_the_theme_image_if_it_exists
1190 1191 theme = Redmine::Themes.themes.last
1191 1192 theme.images << 'image.png'
1192 1193
1193 1194 with_settings :ui_theme => theme.id do
1194 1195 assert_match %|src="/themes/#{theme.dir}/images/image.png"|, image_tag("image.png")
1195 1196 assert_match %|src="/images/other.png"|, image_tag("other.png")
1196 1197 end
1197 1198 ensure
1198 1199 theme.images.delete 'image.png'
1199 1200 end
1200 1201
1201 1202 def test_image_tag_sfor_plugin_should_pick_the_plugin_image
1202 1203 assert_match 'src="/plugin_assets/foo/images/image.png"', image_tag("image.png", :plugin => :foo)
1203 1204 end
1204 1205
1205 1206 def test_javascript_include_tag_should_pick_the_default_javascript
1206 1207 assert_match 'src="/javascripts/scripts.js"', javascript_include_tag("scripts")
1207 1208 end
1208 1209
1209 1210 def test_javascript_include_tag_for_plugin_should_pick_the_plugin_javascript
1210 1211 assert_match 'src="/plugin_assets/foo/javascripts/scripts.js"', javascript_include_tag("scripts", :plugin => :foo)
1211 1212 end
1212 1213 end
General Comments 0
You need to be logged in to leave comments. Login now