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