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