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