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