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