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