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