##// END OF EJS Templates
fix typo at test/unit/helpers/application_helper_test.rb...
Toshi MARUYAMA -
r12818:a581f35dff23
parent child
Show More
@@ -1,1508 +1,1508
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_link_to_issue_subject
439 def test_link_to_issue_subject
440 issue = Issue.generate!(:subject => "01234567890123456789")
440 issue = Issue.generate!(:subject => "01234567890123456789")
441 str = link_to_issue(issue, :truncate => 10)
441 str = link_to_issue(issue, :truncate => 10)
442 result = link_to("Bug ##{issue.id}", "/issues/#{issue.id}", :class => issue.css_classes)
442 result = link_to("Bug ##{issue.id}", "/issues/#{issue.id}", :class => issue.css_classes)
443 assert_equal "#{result}: 0123456...", str
443 assert_equal "#{result}: 0123456...", str
444
444
445 issue = Issue.generate!(:subject => "<&>")
445 issue = Issue.generate!(:subject => "<&>")
446 str = link_to_issue(issue)
446 str = link_to_issue(issue)
447 result = link_to("Bug ##{issue.id}", "/issues/#{issue.id}", :class => issue.css_classes)
447 result = link_to("Bug ##{issue.id}", "/issues/#{issue.id}", :class => issue.css_classes)
448 assert_equal "#{result}: &lt;&amp;&gt;", str
448 assert_equal "#{result}: &lt;&amp;&gt;", str
449
449
450 issue = Issue.generate!(:subject => "<&>0123456789012345")
450 issue = Issue.generate!(:subject => "<&>0123456789012345")
451 str = link_to_issue(issue, :truncate => 10)
451 str = link_to_issue(issue, :truncate => 10)
452 result = link_to("Bug ##{issue.id}", "/issues/#{issue.id}", :class => issue.css_classes)
452 result = link_to("Bug ##{issue.id}", "/issues/#{issue.id}", :class => issue.css_classes)
453 assert_equal "#{result}: &lt;&amp;&gt;0123...", str
453 assert_equal "#{result}: &lt;&amp;&gt;0123...", str
454 end
454 end
455
455
456 def test_link_to_issue_title
456 def test_link_to_issue_title
457 long_str = "0123456789" * 5
457 long_str = "0123456789" * 5
458
458
459 issue = Issue.generate!(:subject => "#{long_str}01234567890123456789")
459 issue = Issue.generate!(:subject => "#{long_str}01234567890123456789")
460 str = link_to_issue(issue, :subject => false)
460 str = link_to_issue(issue, :subject => false)
461 result = link_to("Bug ##{issue.id}", "/issues/#{issue.id}",
461 result = link_to("Bug ##{issue.id}", "/issues/#{issue.id}",
462 :class => issue.css_classes,
462 :class => issue.css_classes,
463 :title => "#{long_str}0123456...")
463 :title => "#{long_str}0123456...")
464 assert_equal result, str
464 assert_equal result, str
465
465
466 issue = Issue.generate!(:subject => "<&>#{long_str}01234567890123456789")
466 issue = Issue.generate!(:subject => "<&>#{long_str}01234567890123456789")
467 str = link_to_issue(issue, :subject => false)
467 str = link_to_issue(issue, :subject => false)
468 result = link_to("Bug ##{issue.id}", "/issues/#{issue.id}",
468 result = link_to("Bug ##{issue.id}", "/issues/#{issue.id}",
469 :class => issue.css_classes,
469 :class => issue.css_classes,
470 :title => "<&>#{long_str}0123...")
470 :title => "<&>#{long_str}0123...")
471 assert_equal result, str
471 assert_equal result, str
472 end
472 end
473
473
474 def test_multiple_repositories_redmine_links
474 def test_multiple_repositories_redmine_links
475 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn_repo-1', :url => 'file:///foo/hg')
475 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn_repo-1', :url => 'file:///foo/hg')
476 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
476 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
477 hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
477 hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
478 Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
478 Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
479
479
480 changeset_link = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
480 changeset_link = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
481 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
481 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
482 svn_changeset_link = link_to('svn_repo-1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn_repo-1', :rev => 123},
482 svn_changeset_link = link_to('svn_repo-1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn_repo-1', :rev => 123},
483 :class => 'changeset', :title => '')
483 :class => 'changeset', :title => '')
484 hg_changeset_link = link_to('hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
484 hg_changeset_link = link_to('hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
485 :class => 'changeset', :title => '')
485 :class => 'changeset', :title => '')
486
486
487 source_link = link_to('source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
487 source_link = link_to('source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
488 hg_source_link = link_to('source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source')
488 hg_source_link = link_to('source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source')
489
489
490 to_test = {
490 to_test = {
491 'r2' => changeset_link,
491 'r2' => changeset_link,
492 'svn_repo-1|r123' => svn_changeset_link,
492 'svn_repo-1|r123' => svn_changeset_link,
493 'invalid|r123' => 'invalid|r123',
493 'invalid|r123' => 'invalid|r123',
494 'commit:hg1|abcd' => hg_changeset_link,
494 'commit:hg1|abcd' => hg_changeset_link,
495 'commit:invalid|abcd' => 'commit:invalid|abcd',
495 'commit:invalid|abcd' => 'commit:invalid|abcd',
496 # source
496 # source
497 'source:some/file' => source_link,
497 'source:some/file' => source_link,
498 'source:hg1|some/file' => hg_source_link,
498 'source:hg1|some/file' => hg_source_link,
499 'source:invalid|some/file' => 'source:invalid|some/file',
499 'source:invalid|some/file' => 'source:invalid|some/file',
500 }
500 }
501
501
502 @project = Project.find(1)
502 @project = Project.find(1)
503 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
503 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
504 end
504 end
505
505
506 def test_cross_project_multiple_repositories_redmine_links
506 def test_cross_project_multiple_repositories_redmine_links
507 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn1', :url => 'file:///foo/hg')
507 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn1', :url => 'file:///foo/hg')
508 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
508 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
509 hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
509 hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
510 Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
510 Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
511
511
512 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
512 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
513 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
513 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
514 svn_changeset_link = link_to('ecookbook:svn1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn1', :rev => 123},
514 svn_changeset_link = link_to('ecookbook:svn1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn1', :rev => 123},
515 :class => 'changeset', :title => '')
515 :class => 'changeset', :title => '')
516 hg_changeset_link = link_to('ecookbook:hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
516 hg_changeset_link = link_to('ecookbook:hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
517 :class => 'changeset', :title => '')
517 :class => 'changeset', :title => '')
518
518
519 source_link = link_to('ecookbook:source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
519 source_link = link_to('ecookbook:source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
520 hg_source_link = link_to('ecookbook:source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source')
520 hg_source_link = link_to('ecookbook:source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source')
521
521
522 to_test = {
522 to_test = {
523 'ecookbook:r2' => changeset_link,
523 'ecookbook:r2' => changeset_link,
524 'ecookbook:svn1|r123' => svn_changeset_link,
524 'ecookbook:svn1|r123' => svn_changeset_link,
525 'ecookbook:invalid|r123' => 'ecookbook:invalid|r123',
525 'ecookbook:invalid|r123' => 'ecookbook:invalid|r123',
526 'ecookbook:commit:hg1|abcd' => hg_changeset_link,
526 'ecookbook:commit:hg1|abcd' => hg_changeset_link,
527 'ecookbook:commit:invalid|abcd' => 'ecookbook:commit:invalid|abcd',
527 'ecookbook:commit:invalid|abcd' => 'ecookbook:commit:invalid|abcd',
528 'invalid:commit:invalid|abcd' => 'invalid:commit:invalid|abcd',
528 'invalid:commit:invalid|abcd' => 'invalid:commit:invalid|abcd',
529 # source
529 # source
530 'ecookbook:source:some/file' => source_link,
530 'ecookbook:source:some/file' => source_link,
531 'ecookbook:source:hg1|some/file' => hg_source_link,
531 'ecookbook:source:hg1|some/file' => hg_source_link,
532 'ecookbook:source:invalid|some/file' => 'ecookbook:source:invalid|some/file',
532 'ecookbook:source:invalid|some/file' => 'ecookbook:source:invalid|some/file',
533 'invalid:source:invalid|some/file' => 'invalid:source:invalid|some/file',
533 'invalid:source:invalid|some/file' => 'invalid:source:invalid|some/file',
534 }
534 }
535
535
536 @project = Project.find(3)
536 @project = Project.find(3)
537 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
537 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
538 end
538 end
539
539
540 def test_redmine_links_git_commit
540 def test_redmine_links_git_commit
541 changeset_link = link_to('abcd',
541 changeset_link = link_to('abcd',
542 {
542 {
543 :controller => 'repositories',
543 :controller => 'repositories',
544 :action => 'revision',
544 :action => 'revision',
545 :id => 'subproject1',
545 :id => 'subproject1',
546 :rev => 'abcd',
546 :rev => 'abcd',
547 },
547 },
548 :class => 'changeset', :title => 'test commit')
548 :class => 'changeset', :title => 'test commit')
549 to_test = {
549 to_test = {
550 'commit:abcd' => changeset_link,
550 'commit:abcd' => changeset_link,
551 }
551 }
552 @project = Project.find(3)
552 @project = Project.find(3)
553 r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
553 r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
554 assert r
554 assert r
555 c = Changeset.new(:repository => r,
555 c = Changeset.new(:repository => r,
556 :committed_on => Time.now,
556 :committed_on => Time.now,
557 :revision => 'abcd',
557 :revision => 'abcd',
558 :scmid => 'abcd',
558 :scmid => 'abcd',
559 :comments => 'test commit')
559 :comments => 'test commit')
560 assert( c.save )
560 assert( c.save )
561 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
561 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
562 end
562 end
563
563
564 # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
564 # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
565 def test_redmine_links_darcs_commit
565 def test_redmine_links_darcs_commit
566 changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
566 changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
567 {
567 {
568 :controller => 'repositories',
568 :controller => 'repositories',
569 :action => 'revision',
569 :action => 'revision',
570 :id => 'subproject1',
570 :id => 'subproject1',
571 :rev => '123',
571 :rev => '123',
572 },
572 },
573 :class => 'changeset', :title => 'test commit')
573 :class => 'changeset', :title => 'test commit')
574 to_test = {
574 to_test = {
575 'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
575 'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
576 }
576 }
577 @project = Project.find(3)
577 @project = Project.find(3)
578 r = Repository::Darcs.create!(
578 r = Repository::Darcs.create!(
579 :project => @project, :url => '/tmp/test/darcs',
579 :project => @project, :url => '/tmp/test/darcs',
580 :log_encoding => 'UTF-8')
580 :log_encoding => 'UTF-8')
581 assert r
581 assert r
582 c = Changeset.new(:repository => r,
582 c = Changeset.new(:repository => r,
583 :committed_on => Time.now,
583 :committed_on => Time.now,
584 :revision => '123',
584 :revision => '123',
585 :scmid => '20080308225258-98289-abcd456efg.gz',
585 :scmid => '20080308225258-98289-abcd456efg.gz',
586 :comments => 'test commit')
586 :comments => 'test commit')
587 assert( c.save )
587 assert( c.save )
588 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
588 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
589 end
589 end
590
590
591 def test_redmine_links_mercurial_commit
591 def test_redmine_links_mercurial_commit
592 changeset_link_rev = link_to('r123',
592 changeset_link_rev = link_to('r123',
593 {
593 {
594 :controller => 'repositories',
594 :controller => 'repositories',
595 :action => 'revision',
595 :action => 'revision',
596 :id => 'subproject1',
596 :id => 'subproject1',
597 :rev => '123' ,
597 :rev => '123' ,
598 },
598 },
599 :class => 'changeset', :title => 'test commit')
599 :class => 'changeset', :title => 'test commit')
600 changeset_link_commit = link_to('abcd',
600 changeset_link_commit = link_to('abcd',
601 {
601 {
602 :controller => 'repositories',
602 :controller => 'repositories',
603 :action => 'revision',
603 :action => 'revision',
604 :id => 'subproject1',
604 :id => 'subproject1',
605 :rev => 'abcd' ,
605 :rev => 'abcd' ,
606 },
606 },
607 :class => 'changeset', :title => 'test commit')
607 :class => 'changeset', :title => 'test commit')
608 to_test = {
608 to_test = {
609 'r123' => changeset_link_rev,
609 'r123' => changeset_link_rev,
610 'commit:abcd' => changeset_link_commit,
610 'commit:abcd' => changeset_link_commit,
611 }
611 }
612 @project = Project.find(3)
612 @project = Project.find(3)
613 r = Repository::Mercurial.create!(:project => @project, :url => '/tmp/test')
613 r = Repository::Mercurial.create!(:project => @project, :url => '/tmp/test')
614 assert r
614 assert r
615 c = Changeset.new(:repository => r,
615 c = Changeset.new(:repository => r,
616 :committed_on => Time.now,
616 :committed_on => Time.now,
617 :revision => '123',
617 :revision => '123',
618 :scmid => 'abcd',
618 :scmid => 'abcd',
619 :comments => 'test commit')
619 :comments => 'test commit')
620 assert( c.save )
620 assert( c.save )
621 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
621 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
622 end
622 end
623
623
624 def test_attachment_links
624 def test_attachment_links
625 text = 'attachment:error281.txt'
625 text = 'attachment:error281.txt'
626 result = link_to("error281.txt", "/attachments/download/1/error281.txt",
626 result = link_to("error281.txt", "/attachments/download/1/error281.txt",
627 :class => "attachment")
627 :class => "attachment")
628 assert_equal "<p>#{result}</p>",
628 assert_equal "<p>#{result}</p>",
629 textilizable(text,
629 textilizable(text,
630 :attachments => Issue.find(3).attachments),
630 :attachments => Issue.find(3).attachments),
631 "#{text} failed"
631 "#{text} failed"
632 end
632 end
633
633
634 def test_attachment_link_should_link_to_latest_attachment
634 def test_attachment_link_should_link_to_latest_attachment
635 set_tmp_attachments_directory
635 set_tmp_attachments_directory
636 a1 = Attachment.generate!(:filename => "test.txt", :created_on => 1.hour.ago)
636 a1 = Attachment.generate!(:filename => "test.txt", :created_on => 1.hour.ago)
637 a2 = Attachment.generate!(:filename => "test.txt")
637 a2 = Attachment.generate!(:filename => "test.txt")
638 result = link_to("test.txt", "/attachments/download/#{a2.id}/test.txt",
638 result = link_to("test.txt", "/attachments/download/#{a2.id}/test.txt",
639 :class => "attachment")
639 :class => "attachment")
640 assert_equal "<p>#{result}</p>",
640 assert_equal "<p>#{result}</p>",
641 textilizable('attachment:test.txt', :attachments => [a1, a2])
641 textilizable('attachment:test.txt', :attachments => [a1, a2])
642 end
642 end
643
643
644 def test_wiki_links
644 def test_wiki_links
645 russian_eacape = CGI.escape(@russian_test)
645 russian_eacape = CGI.escape(@russian_test)
646 to_test = {
646 to_test = {
647 '[[CookBook documentation]]' =>
647 '[[CookBook documentation]]' =>
648 link_to("CookBook documentation",
648 link_to("CookBook documentation",
649 "/projects/ecookbook/wiki/CookBook_documentation",
649 "/projects/ecookbook/wiki/CookBook_documentation",
650 :class => "wiki-page"),
650 :class => "wiki-page"),
651 '[[Another page|Page]]' =>
651 '[[Another page|Page]]' =>
652 link_to("Page",
652 link_to("Page",
653 "/projects/ecookbook/wiki/Another_page",
653 "/projects/ecookbook/wiki/Another_page",
654 :class => "wiki-page"),
654 :class => "wiki-page"),
655 # title content should be formatted
655 # title content should be formatted
656 '[[Another page|With _styled_ *title*]]' =>
656 '[[Another page|With _styled_ *title*]]' =>
657 link_to("With <em>styled</em> <strong>title</strong>".html_safe,
657 link_to("With <em>styled</em> <strong>title</strong>".html_safe,
658 "/projects/ecookbook/wiki/Another_page",
658 "/projects/ecookbook/wiki/Another_page",
659 :class => "wiki-page"),
659 :class => "wiki-page"),
660 '[[Another page|With title containing <strong>HTML entities &amp; markups</strong>]]' =>
660 '[[Another page|With title containing <strong>HTML entities &amp; markups</strong>]]' =>
661 link_to("With title containing &lt;strong&gt;HTML entities &amp; markups&lt;/strong&gt;".html_safe,
661 link_to("With title containing &lt;strong&gt;HTML entities &amp; markups&lt;/strong&gt;".html_safe,
662 "/projects/ecookbook/wiki/Another_page",
662 "/projects/ecookbook/wiki/Another_page",
663 :class => "wiki-page"),
663 :class => "wiki-page"),
664 # link with anchor
664 # link with anchor
665 '[[CookBook documentation#One-section]]' =>
665 '[[CookBook documentation#One-section]]' =>
666 link_to("CookBook documentation",
666 link_to("CookBook documentation",
667 "/projects/ecookbook/wiki/CookBook_documentation#One-section",
667 "/projects/ecookbook/wiki/CookBook_documentation#One-section",
668 :class => "wiki-page"),
668 :class => "wiki-page"),
669 '[[Another page#anchor|Page]]' =>
669 '[[Another page#anchor|Page]]' =>
670 link_to("Page",
670 link_to("Page",
671 "/projects/ecookbook/wiki/Another_page#anchor",
671 "/projects/ecookbook/wiki/Another_page#anchor",
672 :class => "wiki-page"),
672 :class => "wiki-page"),
673 # UTF8 anchor
673 # UTF8 anchor
674 "[[Another_page##{@russian_test}|#{@russian_test}]]" =>
674 "[[Another_page##{@russian_test}|#{@russian_test}]]" =>
675 link_to(@russian_test,
675 link_to(@russian_test,
676 "/projects/ecookbook/wiki/Another_page##{russian_eacape}",
676 "/projects/ecookbook/wiki/Another_page##{russian_eacape}",
677 :class => "wiki-page"),
677 :class => "wiki-page"),
678 # page that doesn't exist
678 # page that doesn't exist
679 '[[Unknown page]]' =>
679 '[[Unknown page]]' =>
680 link_to("Unknown page",
680 link_to("Unknown page",
681 "/projects/ecookbook/wiki/Unknown_page",
681 "/projects/ecookbook/wiki/Unknown_page",
682 :class => "wiki-page new"),
682 :class => "wiki-page new"),
683 '[[Unknown page|404]]' =>
683 '[[Unknown page|404]]' =>
684 link_to("404",
684 link_to("404",
685 "/projects/ecookbook/wiki/Unknown_page",
685 "/projects/ecookbook/wiki/Unknown_page",
686 :class => "wiki-page new"),
686 :class => "wiki-page new"),
687 # link to another project wiki
687 # link to another project wiki
688 '[[onlinestore:]]' =>
688 '[[onlinestore:]]' =>
689 link_to("onlinestore",
689 link_to("onlinestore",
690 "/projects/onlinestore/wiki",
690 "/projects/onlinestore/wiki",
691 :class => "wiki-page"),
691 :class => "wiki-page"),
692 '[[onlinestore:|Wiki]]' =>
692 '[[onlinestore:|Wiki]]' =>
693 link_to("Wiki",
693 link_to("Wiki",
694 "/projects/onlinestore/wiki",
694 "/projects/onlinestore/wiki",
695 :class => "wiki-page"),
695 :class => "wiki-page"),
696 '[[onlinestore:Start page]]' =>
696 '[[onlinestore:Start page]]' =>
697 link_to("Start page",
697 link_to("Start page",
698 "/projects/onlinestore/wiki/Start_page",
698 "/projects/onlinestore/wiki/Start_page",
699 :class => "wiki-page"),
699 :class => "wiki-page"),
700 '[[onlinestore:Start page|Text]]' =>
700 '[[onlinestore:Start page|Text]]' =>
701 link_to("Text",
701 link_to("Text",
702 "/projects/onlinestore/wiki/Start_page",
702 "/projects/onlinestore/wiki/Start_page",
703 :class => "wiki-page"),
703 :class => "wiki-page"),
704 '[[onlinestore:Unknown page]]' =>
704 '[[onlinestore:Unknown page]]' =>
705 link_to("Unknown page",
705 link_to("Unknown page",
706 "/projects/onlinestore/wiki/Unknown_page",
706 "/projects/onlinestore/wiki/Unknown_page",
707 :class => "wiki-page new"),
707 :class => "wiki-page new"),
708 # striked through link
708 # struck through link
709 '-[[Another page|Page]]-' =>
709 '-[[Another page|Page]]-' =>
710 "<del>".html_safe +
710 "<del>".html_safe +
711 link_to("Page",
711 link_to("Page",
712 "/projects/ecookbook/wiki/Another_page",
712 "/projects/ecookbook/wiki/Another_page",
713 :class => "wiki-page").html_safe +
713 :class => "wiki-page").html_safe +
714 "</del>".html_safe,
714 "</del>".html_safe,
715 '-[[Another page|Page]] link-' =>
715 '-[[Another page|Page]] link-' =>
716 "<del>".html_safe +
716 "<del>".html_safe +
717 link_to("Page",
717 link_to("Page",
718 "/projects/ecookbook/wiki/Another_page",
718 "/projects/ecookbook/wiki/Another_page",
719 :class => "wiki-page").html_safe +
719 :class => "wiki-page").html_safe +
720 " link</del>".html_safe,
720 " link</del>".html_safe,
721 # escaping
721 # escaping
722 '![[Another page|Page]]' => '[[Another page|Page]]',
722 '![[Another page|Page]]' => '[[Another page|Page]]',
723 # project does not exist
723 # project does not exist
724 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
724 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
725 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
725 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
726 }
726 }
727 @project = Project.find(1)
727 @project = Project.find(1)
728 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
728 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
729 end
729 end
730
730
731 def test_wiki_links_within_local_file_generation_context
731 def test_wiki_links_within_local_file_generation_context
732 to_test = {
732 to_test = {
733 # link to a page
733 # link to a page
734 '[[CookBook documentation]]' =>
734 '[[CookBook documentation]]' =>
735 link_to("CookBook documentation", "CookBook_documentation.html",
735 link_to("CookBook documentation", "CookBook_documentation.html",
736 :class => "wiki-page"),
736 :class => "wiki-page"),
737 '[[CookBook documentation|documentation]]' =>
737 '[[CookBook documentation|documentation]]' =>
738 link_to("documentation", "CookBook_documentation.html",
738 link_to("documentation", "CookBook_documentation.html",
739 :class => "wiki-page"),
739 :class => "wiki-page"),
740 '[[CookBook documentation#One-section]]' =>
740 '[[CookBook documentation#One-section]]' =>
741 link_to("CookBook documentation", "CookBook_documentation.html#One-section",
741 link_to("CookBook documentation", "CookBook_documentation.html#One-section",
742 :class => "wiki-page"),
742 :class => "wiki-page"),
743 '[[CookBook documentation#One-section|documentation]]' =>
743 '[[CookBook documentation#One-section|documentation]]' =>
744 link_to("documentation", "CookBook_documentation.html#One-section",
744 link_to("documentation", "CookBook_documentation.html#One-section",
745 :class => "wiki-page"),
745 :class => "wiki-page"),
746 # page that doesn't exist
746 # page that doesn't exist
747 '[[Unknown page]]' =>
747 '[[Unknown page]]' =>
748 link_to("Unknown page", "Unknown_page.html",
748 link_to("Unknown page", "Unknown_page.html",
749 :class => "wiki-page new"),
749 :class => "wiki-page new"),
750 '[[Unknown page|404]]' =>
750 '[[Unknown page|404]]' =>
751 link_to("404", "Unknown_page.html",
751 link_to("404", "Unknown_page.html",
752 :class => "wiki-page new"),
752 :class => "wiki-page new"),
753 '[[Unknown page#anchor]]' =>
753 '[[Unknown page#anchor]]' =>
754 link_to("Unknown page", "Unknown_page.html#anchor",
754 link_to("Unknown page", "Unknown_page.html#anchor",
755 :class => "wiki-page new"),
755 :class => "wiki-page new"),
756 '[[Unknown page#anchor|404]]' =>
756 '[[Unknown page#anchor|404]]' =>
757 link_to("404", "Unknown_page.html#anchor",
757 link_to("404", "Unknown_page.html#anchor",
758 :class => "wiki-page new"),
758 :class => "wiki-page new"),
759 }
759 }
760 @project = Project.find(1)
760 @project = Project.find(1)
761 to_test.each do |text, result|
761 to_test.each do |text, result|
762 assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :local)
762 assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :local)
763 end
763 end
764 end
764 end
765
765
766 def test_wiki_links_within_wiki_page_context
766 def test_wiki_links_within_wiki_page_context
767 page = WikiPage.find_by_title('Another_page' )
767 page = WikiPage.find_by_title('Another_page' )
768 to_test = {
768 to_test = {
769 '[[CookBook documentation]]' =>
769 '[[CookBook documentation]]' =>
770 link_to("CookBook documentation",
770 link_to("CookBook documentation",
771 "/projects/ecookbook/wiki/CookBook_documentation",
771 "/projects/ecookbook/wiki/CookBook_documentation",
772 :class => "wiki-page"),
772 :class => "wiki-page"),
773 '[[CookBook documentation|documentation]]' =>
773 '[[CookBook documentation|documentation]]' =>
774 link_to("documentation",
774 link_to("documentation",
775 "/projects/ecookbook/wiki/CookBook_documentation",
775 "/projects/ecookbook/wiki/CookBook_documentation",
776 :class => "wiki-page"),
776 :class => "wiki-page"),
777 '[[CookBook documentation#One-section]]' =>
777 '[[CookBook documentation#One-section]]' =>
778 link_to("CookBook documentation",
778 link_to("CookBook documentation",
779 "/projects/ecookbook/wiki/CookBook_documentation#One-section",
779 "/projects/ecookbook/wiki/CookBook_documentation#One-section",
780 :class => "wiki-page"),
780 :class => "wiki-page"),
781 '[[CookBook documentation#One-section|documentation]]' =>
781 '[[CookBook documentation#One-section|documentation]]' =>
782 link_to("documentation",
782 link_to("documentation",
783 "/projects/ecookbook/wiki/CookBook_documentation#One-section",
783 "/projects/ecookbook/wiki/CookBook_documentation#One-section",
784 :class => "wiki-page"),
784 :class => "wiki-page"),
785 # link to the current page
785 # link to the current page
786 '[[Another page]]' =>
786 '[[Another page]]' =>
787 link_to("Another page",
787 link_to("Another page",
788 "/projects/ecookbook/wiki/Another_page",
788 "/projects/ecookbook/wiki/Another_page",
789 :class => "wiki-page"),
789 :class => "wiki-page"),
790 '[[Another page|Page]]' =>
790 '[[Another page|Page]]' =>
791 link_to("Page",
791 link_to("Page",
792 "/projects/ecookbook/wiki/Another_page",
792 "/projects/ecookbook/wiki/Another_page",
793 :class => "wiki-page"),
793 :class => "wiki-page"),
794 '[[Another page#anchor]]' =>
794 '[[Another page#anchor]]' =>
795 link_to("Another page",
795 link_to("Another page",
796 "#anchor",
796 "#anchor",
797 :class => "wiki-page"),
797 :class => "wiki-page"),
798 '[[Another page#anchor|Page]]' =>
798 '[[Another page#anchor|Page]]' =>
799 link_to("Page",
799 link_to("Page",
800 "#anchor",
800 "#anchor",
801 :class => "wiki-page"),
801 :class => "wiki-page"),
802 # page that doesn't exist
802 # page that doesn't exist
803 '[[Unknown page]]' =>
803 '[[Unknown page]]' =>
804 link_to("Unknown page",
804 link_to("Unknown page",
805 "/projects/ecookbook/wiki/Unknown_page?parent=Another_page",
805 "/projects/ecookbook/wiki/Unknown_page?parent=Another_page",
806 :class => "wiki-page new"),
806 :class => "wiki-page new"),
807 '[[Unknown page|404]]' =>
807 '[[Unknown page|404]]' =>
808 link_to("404",
808 link_to("404",
809 "/projects/ecookbook/wiki/Unknown_page?parent=Another_page",
809 "/projects/ecookbook/wiki/Unknown_page?parent=Another_page",
810 :class => "wiki-page new"),
810 :class => "wiki-page new"),
811 '[[Unknown page#anchor]]' =>
811 '[[Unknown page#anchor]]' =>
812 link_to("Unknown page",
812 link_to("Unknown page",
813 "/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor",
813 "/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor",
814 :class => "wiki-page new"),
814 :class => "wiki-page new"),
815 '[[Unknown page#anchor|404]]' =>
815 '[[Unknown page#anchor|404]]' =>
816 link_to("404",
816 link_to("404",
817 "/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor",
817 "/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor",
818 :class => "wiki-page new"),
818 :class => "wiki-page new"),
819 }
819 }
820 @project = Project.find(1)
820 @project = Project.find(1)
821 to_test.each do |text, result|
821 to_test.each do |text, result|
822 assert_equal "<p>#{result}</p>",
822 assert_equal "<p>#{result}</p>",
823 textilizable(WikiContent.new( :text => text, :page => page ), :text)
823 textilizable(WikiContent.new( :text => text, :page => page ), :text)
824 end
824 end
825 end
825 end
826
826
827 def test_wiki_links_anchor_option_should_prepend_page_title_to_href
827 def test_wiki_links_anchor_option_should_prepend_page_title_to_href
828 to_test = {
828 to_test = {
829 # link to a page
829 # link to a page
830 '[[CookBook documentation]]' =>
830 '[[CookBook documentation]]' =>
831 link_to("CookBook documentation",
831 link_to("CookBook documentation",
832 "#CookBook_documentation",
832 "#CookBook_documentation",
833 :class => "wiki-page"),
833 :class => "wiki-page"),
834 '[[CookBook documentation|documentation]]' =>
834 '[[CookBook documentation|documentation]]' =>
835 link_to("documentation",
835 link_to("documentation",
836 "#CookBook_documentation",
836 "#CookBook_documentation",
837 :class => "wiki-page"),
837 :class => "wiki-page"),
838 '[[CookBook documentation#One-section]]' =>
838 '[[CookBook documentation#One-section]]' =>
839 link_to("CookBook documentation",
839 link_to("CookBook documentation",
840 "#CookBook_documentation_One-section",
840 "#CookBook_documentation_One-section",
841 :class => "wiki-page"),
841 :class => "wiki-page"),
842 '[[CookBook documentation#One-section|documentation]]' =>
842 '[[CookBook documentation#One-section|documentation]]' =>
843 link_to("documentation",
843 link_to("documentation",
844 "#CookBook_documentation_One-section",
844 "#CookBook_documentation_One-section",
845 :class => "wiki-page"),
845 :class => "wiki-page"),
846 # page that doesn't exist
846 # page that doesn't exist
847 '[[Unknown page]]' =>
847 '[[Unknown page]]' =>
848 link_to("Unknown page",
848 link_to("Unknown page",
849 "#Unknown_page",
849 "#Unknown_page",
850 :class => "wiki-page new"),
850 :class => "wiki-page new"),
851 '[[Unknown page|404]]' =>
851 '[[Unknown page|404]]' =>
852 link_to("404",
852 link_to("404",
853 "#Unknown_page",
853 "#Unknown_page",
854 :class => "wiki-page new"),
854 :class => "wiki-page new"),
855 '[[Unknown page#anchor]]' =>
855 '[[Unknown page#anchor]]' =>
856 link_to("Unknown page",
856 link_to("Unknown page",
857 "#Unknown_page_anchor",
857 "#Unknown_page_anchor",
858 :class => "wiki-page new"),
858 :class => "wiki-page new"),
859 '[[Unknown page#anchor|404]]' =>
859 '[[Unknown page#anchor|404]]' =>
860 link_to("404",
860 link_to("404",
861 "#Unknown_page_anchor",
861 "#Unknown_page_anchor",
862 :class => "wiki-page new"),
862 :class => "wiki-page new"),
863 }
863 }
864 @project = Project.find(1)
864 @project = Project.find(1)
865 to_test.each do |text, result|
865 to_test.each do |text, result|
866 assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :anchor)
866 assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :anchor)
867 end
867 end
868 end
868 end
869
869
870 def test_html_tags
870 def test_html_tags
871 to_test = {
871 to_test = {
872 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
872 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
873 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
873 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
874 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
874 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
875 # do not escape pre/code tags
875 # do not escape pre/code tags
876 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
876 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
877 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
877 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
878 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
878 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
879 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
879 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
880 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
880 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
881 # remove attributes except class
881 # remove attributes except class
882 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
882 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
883 '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
883 '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
884 "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
884 "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
885 '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
885 '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
886 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
886 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
887 # xss
887 # xss
888 '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
888 '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
889 '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
889 '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
890 }
890 }
891 to_test.each { |text, result| assert_equal result, textilizable(text) }
891 to_test.each { |text, result| assert_equal result, textilizable(text) }
892 end
892 end
893
893
894 def test_allowed_html_tags
894 def test_allowed_html_tags
895 to_test = {
895 to_test = {
896 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
896 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
897 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
897 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
898 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
898 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
899 }
899 }
900 to_test.each { |text, result| assert_equal result, textilizable(text) }
900 to_test.each { |text, result| assert_equal result, textilizable(text) }
901 end
901 end
902
902
903 def test_pre_tags
903 def test_pre_tags
904 raw = <<-RAW
904 raw = <<-RAW
905 Before
905 Before
906
906
907 <pre>
907 <pre>
908 <prepared-statement-cache-size>32</prepared-statement-cache-size>
908 <prepared-statement-cache-size>32</prepared-statement-cache-size>
909 </pre>
909 </pre>
910
910
911 After
911 After
912 RAW
912 RAW
913
913
914 expected = <<-EXPECTED
914 expected = <<-EXPECTED
915 <p>Before</p>
915 <p>Before</p>
916 <pre>
916 <pre>
917 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
917 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
918 </pre>
918 </pre>
919 <p>After</p>
919 <p>After</p>
920 EXPECTED
920 EXPECTED
921
921
922 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
922 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
923 end
923 end
924
924
925 def test_pre_content_should_not_parse_wiki_and_redmine_links
925 def test_pre_content_should_not_parse_wiki_and_redmine_links
926 raw = <<-RAW
926 raw = <<-RAW
927 [[CookBook documentation]]
927 [[CookBook documentation]]
928
928
929 #1
929 #1
930
930
931 <pre>
931 <pre>
932 [[CookBook documentation]]
932 [[CookBook documentation]]
933
933
934 #1
934 #1
935 </pre>
935 </pre>
936 RAW
936 RAW
937
937
938 result1 = link_to("CookBook documentation",
938 result1 = link_to("CookBook documentation",
939 "/projects/ecookbook/wiki/CookBook_documentation",
939 "/projects/ecookbook/wiki/CookBook_documentation",
940 :class => "wiki-page")
940 :class => "wiki-page")
941 result2 = link_to('#1',
941 result2 = link_to('#1',
942 "/issues/1",
942 "/issues/1",
943 :class => Issue.find(1).css_classes,
943 :class => Issue.find(1).css_classes,
944 :title => "Can't print recipes (New)")
944 :title => "Can't print recipes (New)")
945
945
946 expected = <<-EXPECTED
946 expected = <<-EXPECTED
947 <p>#{result1}</p>
947 <p>#{result1}</p>
948 <p>#{result2}</p>
948 <p>#{result2}</p>
949 <pre>
949 <pre>
950 [[CookBook documentation]]
950 [[CookBook documentation]]
951
951
952 #1
952 #1
953 </pre>
953 </pre>
954 EXPECTED
954 EXPECTED
955
955
956 @project = Project.find(1)
956 @project = Project.find(1)
957 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
957 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
958 end
958 end
959
959
960 def test_non_closing_pre_blocks_should_be_closed
960 def test_non_closing_pre_blocks_should_be_closed
961 raw = <<-RAW
961 raw = <<-RAW
962 <pre><code>
962 <pre><code>
963 RAW
963 RAW
964
964
965 expected = <<-EXPECTED
965 expected = <<-EXPECTED
966 <pre><code>
966 <pre><code>
967 </code></pre>
967 </code></pre>
968 EXPECTED
968 EXPECTED
969
969
970 @project = Project.find(1)
970 @project = Project.find(1)
971 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
971 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
972 end
972 end
973
973
974 def test_syntax_highlight
974 def test_syntax_highlight
975 raw = <<-RAW
975 raw = <<-RAW
976 <pre><code class="ruby">
976 <pre><code class="ruby">
977 # Some ruby code here
977 # Some ruby code here
978 </code></pre>
978 </code></pre>
979 RAW
979 RAW
980
980
981 expected = <<-EXPECTED
981 expected = <<-EXPECTED
982 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="comment"># Some ruby code here</span></span>
982 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="comment"># Some ruby code here</span></span>
983 </code></pre>
983 </code></pre>
984 EXPECTED
984 EXPECTED
985
985
986 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
986 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
987 end
987 end
988
988
989 def test_to_path_param
989 def test_to_path_param
990 assert_equal 'test1/test2', to_path_param('test1/test2')
990 assert_equal 'test1/test2', to_path_param('test1/test2')
991 assert_equal 'test1/test2', to_path_param('/test1/test2/')
991 assert_equal 'test1/test2', to_path_param('/test1/test2/')
992 assert_equal 'test1/test2', to_path_param('//test1/test2/')
992 assert_equal 'test1/test2', to_path_param('//test1/test2/')
993 assert_equal nil, to_path_param('/')
993 assert_equal nil, to_path_param('/')
994 end
994 end
995
995
996 def test_wiki_links_in_tables
996 def test_wiki_links_in_tables
997 text = "|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|"
997 text = "|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|"
998 link1 = link_to("Link title", "/projects/ecookbook/wiki/Page", :class => "wiki-page new")
998 link1 = link_to("Link title", "/projects/ecookbook/wiki/Page", :class => "wiki-page new")
999 link2 = link_to("Other title", "/projects/ecookbook/wiki/Other_Page", :class => "wiki-page new")
999 link2 = link_to("Other title", "/projects/ecookbook/wiki/Other_Page", :class => "wiki-page new")
1000 link3 = link_to("Last page", "/projects/ecookbook/wiki/Last_page", :class => "wiki-page new")
1000 link3 = link_to("Last page", "/projects/ecookbook/wiki/Last_page", :class => "wiki-page new")
1001 result = "<tr><td>#{link1}</td>" +
1001 result = "<tr><td>#{link1}</td>" +
1002 "<td>#{link2}</td>" +
1002 "<td>#{link2}</td>" +
1003 "</tr><tr><td>Cell 21</td><td>#{link3}</td></tr>"
1003 "</tr><tr><td>Cell 21</td><td>#{link3}</td></tr>"
1004 @project = Project.find(1)
1004 @project = Project.find(1)
1005 assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '')
1005 assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '')
1006 end
1006 end
1007
1007
1008 def test_text_formatting
1008 def test_text_formatting
1009 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
1009 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
1010 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
1010 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
1011 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
1011 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
1012 '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>',
1012 '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>',
1013 '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',
1013 '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',
1014 }
1014 }
1015 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
1015 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
1016 end
1016 end
1017
1017
1018 def test_wiki_horizontal_rule
1018 def test_wiki_horizontal_rule
1019 assert_equal '<hr />', textilizable('---')
1019 assert_equal '<hr />', textilizable('---')
1020 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
1020 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
1021 end
1021 end
1022
1022
1023 def test_footnotes
1023 def test_footnotes
1024 raw = <<-RAW
1024 raw = <<-RAW
1025 This is some text[1].
1025 This is some text[1].
1026
1026
1027 fn1. This is the foot note
1027 fn1. This is the foot note
1028 RAW
1028 RAW
1029
1029
1030 expected = <<-EXPECTED
1030 expected = <<-EXPECTED
1031 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
1031 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
1032 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
1032 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
1033 EXPECTED
1033 EXPECTED
1034
1034
1035 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
1035 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
1036 end
1036 end
1037
1037
1038 def test_headings
1038 def test_headings
1039 raw = 'h1. Some heading'
1039 raw = 'h1. Some heading'
1040 expected = %|<a name="Some-heading"></a>\n<h1 >Some heading<a href="#Some-heading" class="wiki-anchor">&para;</a></h1>|
1040 expected = %|<a name="Some-heading"></a>\n<h1 >Some heading<a href="#Some-heading" class="wiki-anchor">&para;</a></h1>|
1041
1041
1042 assert_equal expected, textilizable(raw)
1042 assert_equal expected, textilizable(raw)
1043 end
1043 end
1044
1044
1045 def test_headings_with_special_chars
1045 def test_headings_with_special_chars
1046 # This test makes sure that the generated anchor names match the expected
1046 # This test makes sure that the generated anchor names match the expected
1047 # ones even if the heading text contains unconventional characters
1047 # ones even if the heading text contains unconventional characters
1048 raw = 'h1. Some heading related to version 0.5'
1048 raw = 'h1. Some heading related to version 0.5'
1049 anchor = sanitize_anchor_name("Some-heading-related-to-version-0.5")
1049 anchor = sanitize_anchor_name("Some-heading-related-to-version-0.5")
1050 expected = %|<a name="#{anchor}"></a>\n<h1 >Some heading related to version 0.5<a href="##{anchor}" class="wiki-anchor">&para;</a></h1>|
1050 expected = %|<a name="#{anchor}"></a>\n<h1 >Some heading related to version 0.5<a href="##{anchor}" class="wiki-anchor">&para;</a></h1>|
1051
1051
1052 assert_equal expected, textilizable(raw)
1052 assert_equal expected, textilizable(raw)
1053 end
1053 end
1054
1054
1055 def test_headings_in_wiki_single_page_export_should_be_prepended_with_page_title
1055 def test_headings_in_wiki_single_page_export_should_be_prepended_with_page_title
1056 page = WikiPage.new( :title => 'Page Title', :wiki_id => 1 )
1056 page = WikiPage.new( :title => 'Page Title', :wiki_id => 1 )
1057 content = WikiContent.new( :text => 'h1. Some heading', :page => page )
1057 content = WikiContent.new( :text => 'h1. Some heading', :page => page )
1058
1058
1059 expected = %|<a name="Page_Title_Some-heading"></a>\n<h1 >Some heading<a href="#Page_Title_Some-heading" class="wiki-anchor">&para;</a></h1>|
1059 expected = %|<a name="Page_Title_Some-heading"></a>\n<h1 >Some heading<a href="#Page_Title_Some-heading" class="wiki-anchor">&para;</a></h1>|
1060
1060
1061 assert_equal expected, textilizable(content, :text, :wiki_links => :anchor )
1061 assert_equal expected, textilizable(content, :text, :wiki_links => :anchor )
1062 end
1062 end
1063
1063
1064 def test_table_of_content
1064 def test_table_of_content
1065 raw = <<-RAW
1065 raw = <<-RAW
1066 {{toc}}
1066 {{toc}}
1067
1067
1068 h1. Title
1068 h1. Title
1069
1069
1070 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
1070 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
1071
1071
1072 h2. Subtitle with a [[Wiki]] link
1072 h2. Subtitle with a [[Wiki]] link
1073
1073
1074 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
1074 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
1075
1075
1076 h2. Subtitle with [[Wiki|another Wiki]] link
1076 h2. Subtitle with [[Wiki|another Wiki]] link
1077
1077
1078 h2. Subtitle with %{color:red}red text%
1078 h2. Subtitle with %{color:red}red text%
1079
1079
1080 <pre>
1080 <pre>
1081 some code
1081 some code
1082 </pre>
1082 </pre>
1083
1083
1084 h3. Subtitle with *some* _modifiers_
1084 h3. Subtitle with *some* _modifiers_
1085
1085
1086 h3. Subtitle with @inline code@
1086 h3. Subtitle with @inline code@
1087
1087
1088 h1. Another title
1088 h1. Another title
1089
1089
1090 h3. An "Internet link":http://www.redmine.org/ inside subtitle
1090 h3. An "Internet link":http://www.redmine.org/ inside subtitle
1091
1091
1092 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
1092 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
1093
1093
1094 RAW
1094 RAW
1095
1095
1096 expected = '<ul class="toc">' +
1096 expected = '<ul class="toc">' +
1097 '<li><a href="#Title">Title</a>' +
1097 '<li><a href="#Title">Title</a>' +
1098 '<ul>' +
1098 '<ul>' +
1099 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
1099 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
1100 '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
1100 '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
1101 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
1101 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
1102 '<ul>' +
1102 '<ul>' +
1103 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
1103 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
1104 '<li><a href="#Subtitle-with-inline-code">Subtitle with inline code</a></li>' +
1104 '<li><a href="#Subtitle-with-inline-code">Subtitle with inline code</a></li>' +
1105 '</ul>' +
1105 '</ul>' +
1106 '</li>' +
1106 '</li>' +
1107 '</ul>' +
1107 '</ul>' +
1108 '</li>' +
1108 '</li>' +
1109 '<li><a href="#Another-title">Another title</a>' +
1109 '<li><a href="#Another-title">Another title</a>' +
1110 '<ul>' +
1110 '<ul>' +
1111 '<li>' +
1111 '<li>' +
1112 '<ul>' +
1112 '<ul>' +
1113 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
1113 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
1114 '</ul>' +
1114 '</ul>' +
1115 '</li>' +
1115 '</li>' +
1116 '<li><a href="#Project-Name">Project Name</a></li>' +
1116 '<li><a href="#Project-Name">Project Name</a></li>' +
1117 '</ul>' +
1117 '</ul>' +
1118 '</li>' +
1118 '</li>' +
1119 '</ul>'
1119 '</ul>'
1120
1120
1121 @project = Project.find(1)
1121 @project = Project.find(1)
1122 assert textilizable(raw).gsub("\n", "").include?(expected)
1122 assert textilizable(raw).gsub("\n", "").include?(expected)
1123 end
1123 end
1124
1124
1125 def test_table_of_content_should_generate_unique_anchors
1125 def test_table_of_content_should_generate_unique_anchors
1126 raw = <<-RAW
1126 raw = <<-RAW
1127 {{toc}}
1127 {{toc}}
1128
1128
1129 h1. Title
1129 h1. Title
1130
1130
1131 h2. Subtitle
1131 h2. Subtitle
1132
1132
1133 h2. Subtitle
1133 h2. Subtitle
1134 RAW
1134 RAW
1135
1135
1136 expected = '<ul class="toc">' +
1136 expected = '<ul class="toc">' +
1137 '<li><a href="#Title">Title</a>' +
1137 '<li><a href="#Title">Title</a>' +
1138 '<ul>' +
1138 '<ul>' +
1139 '<li><a href="#Subtitle">Subtitle</a></li>' +
1139 '<li><a href="#Subtitle">Subtitle</a></li>' +
1140 '<li><a href="#Subtitle-2">Subtitle</a></li>'
1140 '<li><a href="#Subtitle-2">Subtitle</a></li>'
1141 '</ul>'
1141 '</ul>'
1142 '</li>' +
1142 '</li>' +
1143 '</ul>'
1143 '</ul>'
1144
1144
1145 @project = Project.find(1)
1145 @project = Project.find(1)
1146 result = textilizable(raw).gsub("\n", "")
1146 result = textilizable(raw).gsub("\n", "")
1147 assert_include expected, result
1147 assert_include expected, result
1148 assert_include '<a name="Subtitle">', result
1148 assert_include '<a name="Subtitle">', result
1149 assert_include '<a name="Subtitle-2">', result
1149 assert_include '<a name="Subtitle-2">', result
1150 end
1150 end
1151
1151
1152 def test_table_of_content_should_contain_included_page_headings
1152 def test_table_of_content_should_contain_included_page_headings
1153 raw = <<-RAW
1153 raw = <<-RAW
1154 {{toc}}
1154 {{toc}}
1155
1155
1156 h1. Included
1156 h1. Included
1157
1157
1158 {{include(Child_1)}}
1158 {{include(Child_1)}}
1159 RAW
1159 RAW
1160
1160
1161 expected = '<ul class="toc">' +
1161 expected = '<ul class="toc">' +
1162 '<li><a href="#Included">Included</a></li>' +
1162 '<li><a href="#Included">Included</a></li>' +
1163 '<li><a href="#Child-page-1">Child page 1</a></li>' +
1163 '<li><a href="#Child-page-1">Child page 1</a></li>' +
1164 '</ul>'
1164 '</ul>'
1165
1165
1166 @project = Project.find(1)
1166 @project = Project.find(1)
1167 assert textilizable(raw).gsub("\n", "").include?(expected)
1167 assert textilizable(raw).gsub("\n", "").include?(expected)
1168 end
1168 end
1169
1169
1170 def test_toc_with_textile_formatting_should_be_parsed
1170 def test_toc_with_textile_formatting_should_be_parsed
1171 with_settings :text_formatting => 'textile' do
1171 with_settings :text_formatting => 'textile' do
1172 assert_select_in textilizable("{{toc}}\n\nh1. Heading"), 'ul.toc li', :text => 'Heading'
1172 assert_select_in textilizable("{{toc}}\n\nh1. Heading"), 'ul.toc li', :text => 'Heading'
1173 assert_select_in textilizable("{{<toc}}\n\nh1. Heading"), 'ul.toc.left li', :text => 'Heading'
1173 assert_select_in textilizable("{{<toc}}\n\nh1. Heading"), 'ul.toc.left li', :text => 'Heading'
1174 assert_select_in textilizable("{{>toc}}\n\nh1. Heading"), 'ul.toc.right li', :text => 'Heading'
1174 assert_select_in textilizable("{{>toc}}\n\nh1. Heading"), 'ul.toc.right li', :text => 'Heading'
1175 end
1175 end
1176 end
1176 end
1177
1177
1178 if Object.const_defined?(:Redcarpet)
1178 if Object.const_defined?(:Redcarpet)
1179 def test_toc_with_markdown_formatting_should_be_parsed
1179 def test_toc_with_markdown_formatting_should_be_parsed
1180 with_settings :text_formatting => 'markdown' do
1180 with_settings :text_formatting => 'markdown' do
1181 assert_select_in textilizable("{{toc}}\n\n# Heading"), 'ul.toc li', :text => 'Heading'
1181 assert_select_in textilizable("{{toc}}\n\n# Heading"), 'ul.toc li', :text => 'Heading'
1182 assert_select_in textilizable("{{<toc}}\n\n# Heading"), 'ul.toc.left li', :text => 'Heading'
1182 assert_select_in textilizable("{{<toc}}\n\n# Heading"), 'ul.toc.left li', :text => 'Heading'
1183 assert_select_in textilizable("{{>toc}}\n\n# Heading"), 'ul.toc.right li', :text => 'Heading'
1183 assert_select_in textilizable("{{>toc}}\n\n# Heading"), 'ul.toc.right li', :text => 'Heading'
1184 end
1184 end
1185 end
1185 end
1186 end
1186 end
1187
1187
1188 def test_section_edit_links
1188 def test_section_edit_links
1189 raw = <<-RAW
1189 raw = <<-RAW
1190 h1. Title
1190 h1. Title
1191
1191
1192 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
1192 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
1193
1193
1194 h2. Subtitle with a [[Wiki]] link
1194 h2. Subtitle with a [[Wiki]] link
1195
1195
1196 h2. Subtitle with *some* _modifiers_
1196 h2. Subtitle with *some* _modifiers_
1197
1197
1198 h2. Subtitle with @inline code@
1198 h2. Subtitle with @inline code@
1199
1199
1200 <pre>
1200 <pre>
1201 some code
1201 some code
1202
1202
1203 h2. heading inside pre
1203 h2. heading inside pre
1204
1204
1205 <h2>html heading inside pre</h2>
1205 <h2>html heading inside pre</h2>
1206 </pre>
1206 </pre>
1207
1207
1208 h2. Subtitle after pre tag
1208 h2. Subtitle after pre tag
1209 RAW
1209 RAW
1210
1210
1211 @project = Project.find(1)
1211 @project = Project.find(1)
1212 set_language_if_valid 'en'
1212 set_language_if_valid 'en'
1213 result = textilizable(raw, :edit_section_links => {:controller => 'wiki', :action => 'edit', :project_id => '1', :id => 'Test'}).gsub("\n", "")
1213 result = textilizable(raw, :edit_section_links => {:controller => 'wiki', :action => 'edit', :project_id => '1', :id => 'Test'}).gsub("\n", "")
1214
1214
1215 # heading that contains inline code
1215 # heading that contains inline code
1216 assert_match Regexp.new('<div class="contextual" id="section-4" title="Edit this section">' +
1216 assert_match Regexp.new('<div class="contextual" id="section-4" title="Edit this section">' +
1217 '<a href="/projects/1/wiki/Test/edit\?section=4"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
1217 '<a href="/projects/1/wiki/Test/edit\?section=4"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
1218 '<a name="Subtitle-with-inline-code"></a>' +
1218 '<a name="Subtitle-with-inline-code"></a>' +
1219 '<h2 >Subtitle with <code>inline code</code><a href="#Subtitle-with-inline-code" class="wiki-anchor">&para;</a></h2>'),
1219 '<h2 >Subtitle with <code>inline code</code><a href="#Subtitle-with-inline-code" class="wiki-anchor">&para;</a></h2>'),
1220 result
1220 result
1221
1221
1222 # last heading
1222 # last heading
1223 assert_match Regexp.new('<div class="contextual" id="section-5" title="Edit this section">' +
1223 assert_match Regexp.new('<div class="contextual" id="section-5" title="Edit this section">' +
1224 '<a href="/projects/1/wiki/Test/edit\?section=5"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
1224 '<a href="/projects/1/wiki/Test/edit\?section=5"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
1225 '<a name="Subtitle-after-pre-tag"></a>' +
1225 '<a name="Subtitle-after-pre-tag"></a>' +
1226 '<h2 >Subtitle after pre tag<a href="#Subtitle-after-pre-tag" class="wiki-anchor">&para;</a></h2>'),
1226 '<h2 >Subtitle after pre tag<a href="#Subtitle-after-pre-tag" class="wiki-anchor">&para;</a></h2>'),
1227 result
1227 result
1228 end
1228 end
1229
1229
1230 def test_default_formatter
1230 def test_default_formatter
1231 with_settings :text_formatting => 'unknown' do
1231 with_settings :text_formatting => 'unknown' do
1232 text = 'a *link*: http://www.example.net/'
1232 text = 'a *link*: http://www.example.net/'
1233 assert_equal '<p>a *link*: <a class="external" href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
1233 assert_equal '<p>a *link*: <a class="external" href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
1234 end
1234 end
1235 end
1235 end
1236
1236
1237 def test_due_date_distance_in_words
1237 def test_due_date_distance_in_words
1238 to_test = { Date.today => 'Due in 0 days',
1238 to_test = { Date.today => 'Due in 0 days',
1239 Date.today + 1 => 'Due in 1 day',
1239 Date.today + 1 => 'Due in 1 day',
1240 Date.today + 100 => 'Due in about 3 months',
1240 Date.today + 100 => 'Due in about 3 months',
1241 Date.today + 20000 => 'Due in over 54 years',
1241 Date.today + 20000 => 'Due in over 54 years',
1242 Date.today - 1 => '1 day late',
1242 Date.today - 1 => '1 day late',
1243 Date.today - 100 => 'about 3 months late',
1243 Date.today - 100 => 'about 3 months late',
1244 Date.today - 20000 => 'over 54 years late',
1244 Date.today - 20000 => 'over 54 years late',
1245 }
1245 }
1246 ::I18n.locale = :en
1246 ::I18n.locale = :en
1247 to_test.each do |date, expected|
1247 to_test.each do |date, expected|
1248 assert_equal expected, due_date_distance_in_words(date)
1248 assert_equal expected, due_date_distance_in_words(date)
1249 end
1249 end
1250 end
1250 end
1251
1251
1252 def test_avatar_enabled
1252 def test_avatar_enabled
1253 with_settings :gravatar_enabled => '1' do
1253 with_settings :gravatar_enabled => '1' do
1254 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
1254 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
1255 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
1255 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
1256 # Default size is 50
1256 # Default size is 50
1257 assert avatar('jsmith <jsmith@somenet.foo>').include?('size=50')
1257 assert avatar('jsmith <jsmith@somenet.foo>').include?('size=50')
1258 assert avatar('jsmith <jsmith@somenet.foo>', :size => 24).include?('size=24')
1258 assert avatar('jsmith <jsmith@somenet.foo>', :size => 24).include?('size=24')
1259 # Non-avatar options should be considered html options
1259 # Non-avatar options should be considered html options
1260 assert avatar('jsmith <jsmith@somenet.foo>', :title => 'John Smith').include?('title="John Smith"')
1260 assert avatar('jsmith <jsmith@somenet.foo>', :title => 'John Smith').include?('title="John Smith"')
1261 # The default class of the img tag should be gravatar
1261 # The default class of the img tag should be gravatar
1262 assert avatar('jsmith <jsmith@somenet.foo>').include?('class="gravatar"')
1262 assert avatar('jsmith <jsmith@somenet.foo>').include?('class="gravatar"')
1263 assert !avatar('jsmith <jsmith@somenet.foo>', :class => 'picture').include?('class="gravatar"')
1263 assert !avatar('jsmith <jsmith@somenet.foo>', :class => 'picture').include?('class="gravatar"')
1264 assert_nil avatar('jsmith')
1264 assert_nil avatar('jsmith')
1265 assert_nil avatar(nil)
1265 assert_nil avatar(nil)
1266 end
1266 end
1267 end
1267 end
1268
1268
1269 def test_avatar_disabled
1269 def test_avatar_disabled
1270 with_settings :gravatar_enabled => '0' do
1270 with_settings :gravatar_enabled => '0' do
1271 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
1271 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
1272 end
1272 end
1273 end
1273 end
1274
1274
1275 def test_link_to_user
1275 def test_link_to_user
1276 user = User.find(2)
1276 user = User.find(2)
1277 result = link_to("John Smith", "/users/2", :class => "user active")
1277 result = link_to("John Smith", "/users/2", :class => "user active")
1278 assert_equal result, link_to_user(user)
1278 assert_equal result, link_to_user(user)
1279 end
1279 end
1280
1280
1281 def test_link_to_user_should_not_link_to_locked_user
1281 def test_link_to_user_should_not_link_to_locked_user
1282 with_current_user nil do
1282 with_current_user nil do
1283 user = User.find(5)
1283 user = User.find(5)
1284 assert user.locked?
1284 assert user.locked?
1285 assert_equal 'Dave2 Lopper2', link_to_user(user)
1285 assert_equal 'Dave2 Lopper2', link_to_user(user)
1286 end
1286 end
1287 end
1287 end
1288
1288
1289 def test_link_to_user_should_link_to_locked_user_if_current_user_is_admin
1289 def test_link_to_user_should_link_to_locked_user_if_current_user_is_admin
1290 with_current_user User.find(1) do
1290 with_current_user User.find(1) do
1291 user = User.find(5)
1291 user = User.find(5)
1292 assert user.locked?
1292 assert user.locked?
1293 result = link_to("Dave2 Lopper2", "/users/5", :class => "user locked")
1293 result = link_to("Dave2 Lopper2", "/users/5", :class => "user locked")
1294 assert_equal result, link_to_user(user)
1294 assert_equal result, link_to_user(user)
1295 end
1295 end
1296 end
1296 end
1297
1297
1298 def test_link_to_user_should_not_link_to_anonymous
1298 def test_link_to_user_should_not_link_to_anonymous
1299 user = User.anonymous
1299 user = User.anonymous
1300 assert user.anonymous?
1300 assert user.anonymous?
1301 t = link_to_user(user)
1301 t = link_to_user(user)
1302 assert_equal ::I18n.t(:label_user_anonymous), t
1302 assert_equal ::I18n.t(:label_user_anonymous), t
1303 end
1303 end
1304
1304
1305 def test_link_to_attachment
1305 def test_link_to_attachment
1306 a = Attachment.find(3)
1306 a = Attachment.find(3)
1307 assert_equal '<a href="/attachments/3/logo.gif">logo.gif</a>',
1307 assert_equal '<a href="/attachments/3/logo.gif">logo.gif</a>',
1308 link_to_attachment(a)
1308 link_to_attachment(a)
1309 assert_equal '<a href="/attachments/3/logo.gif">Text</a>',
1309 assert_equal '<a href="/attachments/3/logo.gif">Text</a>',
1310 link_to_attachment(a, :text => 'Text')
1310 link_to_attachment(a, :text => 'Text')
1311 result = link_to("logo.gif", "/attachments/3/logo.gif", :class => "foo")
1311 result = link_to("logo.gif", "/attachments/3/logo.gif", :class => "foo")
1312 assert_equal result,
1312 assert_equal result,
1313 link_to_attachment(a, :class => 'foo')
1313 link_to_attachment(a, :class => 'foo')
1314 assert_equal '<a href="/attachments/download/3/logo.gif">logo.gif</a>',
1314 assert_equal '<a href="/attachments/download/3/logo.gif">logo.gif</a>',
1315 link_to_attachment(a, :download => true)
1315 link_to_attachment(a, :download => true)
1316 assert_equal '<a href="http://test.host/attachments/3/logo.gif">logo.gif</a>',
1316 assert_equal '<a href="http://test.host/attachments/3/logo.gif">logo.gif</a>',
1317 link_to_attachment(a, :only_path => false)
1317 link_to_attachment(a, :only_path => false)
1318 end
1318 end
1319
1319
1320 def test_thumbnail_tag
1320 def test_thumbnail_tag
1321 a = Attachment.find(3)
1321 a = Attachment.find(3)
1322 assert_equal '<a href="/attachments/3/logo.gif" title="logo.gif"><img alt="3" src="/attachments/thumbnail/3" /></a>',
1322 assert_equal '<a href="/attachments/3/logo.gif" title="logo.gif"><img alt="3" src="/attachments/thumbnail/3" /></a>',
1323 thumbnail_tag(a)
1323 thumbnail_tag(a)
1324 end
1324 end
1325
1325
1326 def test_link_to_project
1326 def test_link_to_project
1327 project = Project.find(1)
1327 project = Project.find(1)
1328 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
1328 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
1329 link_to_project(project)
1329 link_to_project(project)
1330 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
1330 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
1331 link_to_project(project, :action => 'settings')
1331 link_to_project(project, :action => 'settings')
1332 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
1332 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
1333 link_to_project(project, {:only_path => false, :jump => 'blah'})
1333 link_to_project(project, {:only_path => false, :jump => 'blah'})
1334 result = link_to("eCookbook", "/projects/ecookbook/settings", :class => "project")
1334 result = link_to("eCookbook", "/projects/ecookbook/settings", :class => "project")
1335 assert_equal result,
1335 assert_equal result,
1336 link_to_project(project, {:action => 'settings'}, :class => "project")
1336 link_to_project(project, {:action => 'settings'}, :class => "project")
1337 end
1337 end
1338
1338
1339 def test_link_to_project_settings
1339 def test_link_to_project_settings
1340 project = Project.find(1)
1340 project = Project.find(1)
1341 assert_equal '<a href="/projects/ecookbook/settings">eCookbook</a>', link_to_project_settings(project)
1341 assert_equal '<a href="/projects/ecookbook/settings">eCookbook</a>', link_to_project_settings(project)
1342
1342
1343 project.status = Project::STATUS_CLOSED
1343 project.status = Project::STATUS_CLOSED
1344 assert_equal '<a href="/projects/ecookbook">eCookbook</a>', link_to_project_settings(project)
1344 assert_equal '<a href="/projects/ecookbook">eCookbook</a>', link_to_project_settings(project)
1345
1345
1346 project.status = Project::STATUS_ARCHIVED
1346 project.status = Project::STATUS_ARCHIVED
1347 assert_equal 'eCookbook', link_to_project_settings(project)
1347 assert_equal 'eCookbook', link_to_project_settings(project)
1348 end
1348 end
1349
1349
1350 def test_link_to_legacy_project_with_numerical_identifier_should_use_id
1350 def test_link_to_legacy_project_with_numerical_identifier_should_use_id
1351 # numeric identifier are no longer allowed
1351 # numeric identifier are no longer allowed
1352 Project.where(:id => 1).update_all(:identifier => 25)
1352 Project.where(:id => 1).update_all(:identifier => 25)
1353 assert_equal '<a href="/projects/1">eCookbook</a>',
1353 assert_equal '<a href="/projects/1">eCookbook</a>',
1354 link_to_project(Project.find(1))
1354 link_to_project(Project.find(1))
1355 end
1355 end
1356
1356
1357 def test_principals_options_for_select_with_users
1357 def test_principals_options_for_select_with_users
1358 User.current = nil
1358 User.current = nil
1359 users = [User.find(2), User.find(4)]
1359 users = [User.find(2), User.find(4)]
1360 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>),
1360 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>),
1361 principals_options_for_select(users)
1361 principals_options_for_select(users)
1362 end
1362 end
1363
1363
1364 def test_principals_options_for_select_with_selected
1364 def test_principals_options_for_select_with_selected
1365 User.current = nil
1365 User.current = nil
1366 users = [User.find(2), User.find(4)]
1366 users = [User.find(2), User.find(4)]
1367 assert_equal %(<option value="2">John Smith</option><option value="4" selected="selected">Robert Hill</option>),
1367 assert_equal %(<option value="2">John Smith</option><option value="4" selected="selected">Robert Hill</option>),
1368 principals_options_for_select(users, User.find(4))
1368 principals_options_for_select(users, User.find(4))
1369 end
1369 end
1370
1370
1371 def test_principals_options_for_select_with_users_and_groups
1371 def test_principals_options_for_select_with_users_and_groups
1372 User.current = nil
1372 User.current = nil
1373 users = [User.find(2), Group.find(11), User.find(4), Group.find(10)]
1373 users = [User.find(2), Group.find(11), User.find(4), Group.find(10)]
1374 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>) +
1374 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>) +
1375 %(<optgroup label="Groups"><option value="10">A Team</option><option value="11">B Team</option></optgroup>),
1375 %(<optgroup label="Groups"><option value="10">A Team</option><option value="11">B Team</option></optgroup>),
1376 principals_options_for_select(users)
1376 principals_options_for_select(users)
1377 end
1377 end
1378
1378
1379 def test_principals_options_for_select_with_empty_collection
1379 def test_principals_options_for_select_with_empty_collection
1380 assert_equal '', principals_options_for_select([])
1380 assert_equal '', principals_options_for_select([])
1381 end
1381 end
1382
1382
1383 def test_principals_options_for_select_should_include_me_option_when_current_user_is_in_collection
1383 def test_principals_options_for_select_should_include_me_option_when_current_user_is_in_collection
1384 users = [User.find(2), User.find(4)]
1384 users = [User.find(2), User.find(4)]
1385 User.current = User.find(4)
1385 User.current = User.find(4)
1386 assert_include '<option value="4">&lt;&lt; me &gt;&gt;</option>', principals_options_for_select(users)
1386 assert_include '<option value="4">&lt;&lt; me &gt;&gt;</option>', principals_options_for_select(users)
1387 end
1387 end
1388
1388
1389 def test_stylesheet_link_tag_should_pick_the_default_stylesheet
1389 def test_stylesheet_link_tag_should_pick_the_default_stylesheet
1390 assert_match 'href="/stylesheets/styles.css"', stylesheet_link_tag("styles")
1390 assert_match 'href="/stylesheets/styles.css"', stylesheet_link_tag("styles")
1391 end
1391 end
1392
1392
1393 def test_stylesheet_link_tag_for_plugin_should_pick_the_plugin_stylesheet
1393 def test_stylesheet_link_tag_for_plugin_should_pick_the_plugin_stylesheet
1394 assert_match 'href="/plugin_assets/foo/stylesheets/styles.css"', stylesheet_link_tag("styles", :plugin => :foo)
1394 assert_match 'href="/plugin_assets/foo/stylesheets/styles.css"', stylesheet_link_tag("styles", :plugin => :foo)
1395 end
1395 end
1396
1396
1397 def test_image_tag_should_pick_the_default_image
1397 def test_image_tag_should_pick_the_default_image
1398 assert_match 'src="/images/image.png"', image_tag("image.png")
1398 assert_match 'src="/images/image.png"', image_tag("image.png")
1399 end
1399 end
1400
1400
1401 def test_image_tag_should_pick_the_theme_image_if_it_exists
1401 def test_image_tag_should_pick_the_theme_image_if_it_exists
1402 theme = Redmine::Themes.themes.last
1402 theme = Redmine::Themes.themes.last
1403 theme.images << 'image.png'
1403 theme.images << 'image.png'
1404
1404
1405 with_settings :ui_theme => theme.id do
1405 with_settings :ui_theme => theme.id do
1406 assert_match %|src="/themes/#{theme.dir}/images/image.png"|, image_tag("image.png")
1406 assert_match %|src="/themes/#{theme.dir}/images/image.png"|, image_tag("image.png")
1407 assert_match %|src="/images/other.png"|, image_tag("other.png")
1407 assert_match %|src="/images/other.png"|, image_tag("other.png")
1408 end
1408 end
1409 ensure
1409 ensure
1410 theme.images.delete 'image.png'
1410 theme.images.delete 'image.png'
1411 end
1411 end
1412
1412
1413 def test_image_tag_sfor_plugin_should_pick_the_plugin_image
1413 def test_image_tag_sfor_plugin_should_pick_the_plugin_image
1414 assert_match 'src="/plugin_assets/foo/images/image.png"', image_tag("image.png", :plugin => :foo)
1414 assert_match 'src="/plugin_assets/foo/images/image.png"', image_tag("image.png", :plugin => :foo)
1415 end
1415 end
1416
1416
1417 def test_javascript_include_tag_should_pick_the_default_javascript
1417 def test_javascript_include_tag_should_pick_the_default_javascript
1418 assert_match 'src="/javascripts/scripts.js"', javascript_include_tag("scripts")
1418 assert_match 'src="/javascripts/scripts.js"', javascript_include_tag("scripts")
1419 end
1419 end
1420
1420
1421 def test_javascript_include_tag_for_plugin_should_pick_the_plugin_javascript
1421 def test_javascript_include_tag_for_plugin_should_pick_the_plugin_javascript
1422 assert_match 'src="/plugin_assets/foo/javascripts/scripts.js"', javascript_include_tag("scripts", :plugin => :foo)
1422 assert_match 'src="/plugin_assets/foo/javascripts/scripts.js"', javascript_include_tag("scripts", :plugin => :foo)
1423 end
1423 end
1424
1424
1425 def test_raw_json_should_escape_closing_tags
1425 def test_raw_json_should_escape_closing_tags
1426 s = raw_json(["<foo>bar</foo>"])
1426 s = raw_json(["<foo>bar</foo>"])
1427 assert_equal '["<foo>bar<\/foo>"]', s
1427 assert_equal '["<foo>bar<\/foo>"]', s
1428 end
1428 end
1429
1429
1430 def test_raw_json_should_be_html_safe
1430 def test_raw_json_should_be_html_safe
1431 s = raw_json(["foo"])
1431 s = raw_json(["foo"])
1432 assert s.html_safe?
1432 assert s.html_safe?
1433 end
1433 end
1434
1434
1435 def test_html_title_should_app_title_if_not_set
1435 def test_html_title_should_app_title_if_not_set
1436 assert_equal 'Redmine', html_title
1436 assert_equal 'Redmine', html_title
1437 end
1437 end
1438
1438
1439 def test_html_title_should_join_items
1439 def test_html_title_should_join_items
1440 html_title 'Foo', 'Bar'
1440 html_title 'Foo', 'Bar'
1441 assert_equal 'Foo - Bar - Redmine', html_title
1441 assert_equal 'Foo - Bar - Redmine', html_title
1442 end
1442 end
1443
1443
1444 def test_html_title_should_append_current_project_name
1444 def test_html_title_should_append_current_project_name
1445 @project = Project.find(1)
1445 @project = Project.find(1)
1446 html_title 'Foo', 'Bar'
1446 html_title 'Foo', 'Bar'
1447 assert_equal 'Foo - Bar - eCookbook - Redmine', html_title
1447 assert_equal 'Foo - Bar - eCookbook - Redmine', html_title
1448 end
1448 end
1449
1449
1450 def test_title_should_return_a_h2_tag
1450 def test_title_should_return_a_h2_tag
1451 assert_equal '<h2>Foo</h2>', title('Foo')
1451 assert_equal '<h2>Foo</h2>', title('Foo')
1452 end
1452 end
1453
1453
1454 def test_title_should_set_html_title
1454 def test_title_should_set_html_title
1455 title('Foo')
1455 title('Foo')
1456 assert_equal 'Foo - Redmine', html_title
1456 assert_equal 'Foo - Redmine', html_title
1457 end
1457 end
1458
1458
1459 def test_title_should_turn_arrays_into_links
1459 def test_title_should_turn_arrays_into_links
1460 assert_equal '<h2><a href="/foo">Foo</a></h2>', title(['Foo', '/foo'])
1460 assert_equal '<h2><a href="/foo">Foo</a></h2>', title(['Foo', '/foo'])
1461 assert_equal 'Foo - Redmine', html_title
1461 assert_equal 'Foo - Redmine', html_title
1462 end
1462 end
1463
1463
1464 def test_title_should_join_items
1464 def test_title_should_join_items
1465 assert_equal '<h2>Foo &#187; Bar</h2>', title('Foo', 'Bar')
1465 assert_equal '<h2>Foo &#187; Bar</h2>', title('Foo', 'Bar')
1466 assert_equal 'Bar - Foo - Redmine', html_title
1466 assert_equal 'Bar - Foo - Redmine', html_title
1467 end
1467 end
1468
1468
1469 def test_favicon_path
1469 def test_favicon_path
1470 assert_match %r{^/favicon\.ico}, favicon_path
1470 assert_match %r{^/favicon\.ico}, favicon_path
1471 end
1471 end
1472
1472
1473 def test_favicon_path_with_suburi
1473 def test_favicon_path_with_suburi
1474 Redmine::Utils.relative_url_root = '/foo'
1474 Redmine::Utils.relative_url_root = '/foo'
1475 assert_match %r{^/foo/favicon\.ico}, favicon_path
1475 assert_match %r{^/foo/favicon\.ico}, favicon_path
1476 ensure
1476 ensure
1477 Redmine::Utils.relative_url_root = ''
1477 Redmine::Utils.relative_url_root = ''
1478 end
1478 end
1479
1479
1480 def test_favicon_url
1480 def test_favicon_url
1481 assert_match %r{^http://test\.host/favicon\.ico}, favicon_url
1481 assert_match %r{^http://test\.host/favicon\.ico}, favicon_url
1482 end
1482 end
1483
1483
1484 def test_favicon_url_with_suburi
1484 def test_favicon_url_with_suburi
1485 Redmine::Utils.relative_url_root = '/foo'
1485 Redmine::Utils.relative_url_root = '/foo'
1486 assert_match %r{^http://test\.host/foo/favicon\.ico}, favicon_url
1486 assert_match %r{^http://test\.host/foo/favicon\.ico}, favicon_url
1487 ensure
1487 ensure
1488 Redmine::Utils.relative_url_root = ''
1488 Redmine::Utils.relative_url_root = ''
1489 end
1489 end
1490
1490
1491 def test_truncate_single_line
1491 def test_truncate_single_line
1492 str = "01234"
1492 str = "01234"
1493 result = truncate_single_line_raw("#{str}\n#{str}", 10)
1493 result = truncate_single_line_raw("#{str}\n#{str}", 10)
1494 assert_equal "01234 0...", result
1494 assert_equal "01234 0...", result
1495 assert !result.html_safe?
1495 assert !result.html_safe?
1496 result = truncate_single_line_raw("#{str}<&#>\n#{str}#{str}", 16)
1496 result = truncate_single_line_raw("#{str}<&#>\n#{str}#{str}", 16)
1497 assert_equal "01234<&#> 012...", result
1497 assert_equal "01234<&#> 012...", result
1498 assert !result.html_safe?
1498 assert !result.html_safe?
1499 end
1499 end
1500
1500
1501 def test_truncate_single_line_non_ascii
1501 def test_truncate_single_line_non_ascii
1502 ja = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"
1502 ja = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"
1503 ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding)
1503 ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding)
1504 result = truncate_single_line_raw("#{ja}\n#{ja}\n#{ja}", 10)
1504 result = truncate_single_line_raw("#{ja}\n#{ja}\n#{ja}", 10)
1505 assert_equal "#{ja} #{ja}...", result
1505 assert_equal "#{ja} #{ja}...", result
1506 assert !result.html_safe?
1506 assert !result.html_safe?
1507 end
1507 end
1508 end
1508 end
General Comments 0
You need to be logged in to leave comments. Login now