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