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