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