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