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