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