##// END OF EJS Templates
reset Attachment.storage_path at the end of attachment tests...
Toshi MARUYAMA -
r7791:be29227c12da
parent child
Show More
@@ -1,255 +1,272
1 1 # encoding: utf-8
2 2 #
3 3 # Redmine - project management software
4 4 # Copyright (C) 2006-2011 Jean-Philippe Lang
5 5 #
6 6 # This program is free software; you can redistribute it and/or
7 7 # modify it under the terms of the GNU General Public License
8 8 # as published by the Free Software Foundation; either version 2
9 9 # of the License, or (at your option) any later version.
10 10 #
11 11 # This program is distributed in the hope that it will be useful,
12 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14 # GNU General Public License for more details.
15 15 #
16 16 # You should have received a copy of the GNU General Public License
17 17 # along with this program; if not, write to the Free Software
18 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 19
20 20 require File.expand_path('../../test_helper', __FILE__)
21 21 require 'attachments_controller'
22 22
23 23 # Re-raise errors caught by the controller.
24 24 class AttachmentsController; def rescue_action(e) raise e end; end
25 25
26 26 class AttachmentsControllerTest < ActionController::TestCase
27 27 fixtures :users, :projects, :roles, :members, :member_roles,
28 28 :enabled_modules, :issues, :trackers, :attachments,
29 29 :versions, :wiki_pages, :wikis, :documents
30 30
31 31 def setup
32 32 @controller = AttachmentsController.new
33 33 @request = ActionController::TestRequest.new
34 34 @response = ActionController::TestResponse.new
35 35 Attachment.storage_path = "#{Rails.root}/test/fixtures/files"
36 36 User.current = nil
37 37 end
38 38
39 39 def test_show_diff
40 40 ['inline', 'sbs'].each do |dt|
41 41 # 060719210727_changeset_utf8.diff
42 42 get :show, :id => 14, :type => dt
43 43 assert_response :success
44 44 assert_template 'diff'
45 45 assert_equal 'text/html', @response.content_type
46 46 assert_tag 'th',
47 47 :attributes => {:class => /filename/},
48 48 :content => /issues_controller.rb\t\(rΓ©vision 1484\)/
49 49 assert_tag 'td',
50 50 :attributes => {:class => /line-code/},
51 51 :content => /Demande créée avec succès/
52 52 end
53 set_tmp_attachments_directory
53 54 end
54 55
55 56 def test_show_diff_replcace_cannot_convert_content
56 57 with_settings :repositories_encodings => 'UTF-8' do
57 58 ['inline', 'sbs'].each do |dt|
58 59 # 060719210727_changeset_iso8859-1.diff
59 60 get :show, :id => 5, :type => dt
60 61 assert_response :success
61 62 assert_template 'diff'
62 63 assert_equal 'text/html', @response.content_type
63 64 assert_tag 'th',
64 65 :attributes => {:class => "filename"},
65 66 :content => /issues_controller.rb\t\(r\?vision 1484\)/
66 67 assert_tag 'td',
67 68 :attributes => {:class => /line-code/},
68 69 :content => /Demande cr\?\?e avec succ\?s/
69 70 end
70 71 end
72 set_tmp_attachments_directory
71 73 end
72 74
73 75 def test_show_diff_latin_1
74 76 with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
75 77 ['inline', 'sbs'].each do |dt|
76 78 # 060719210727_changeset_iso8859-1.diff
77 79 get :show, :id => 5, :type => dt
78 80 assert_response :success
79 81 assert_template 'diff'
80 82 assert_equal 'text/html', @response.content_type
81 83 assert_tag 'th',
82 84 :attributes => {:class => "filename"},
83 85 :content => /issues_controller.rb\t\(rΓ©vision 1484\)/
84 86 assert_tag 'td',
85 87 :attributes => {:class => /line-code/},
86 88 :content => /Demande créée avec succès/
87 89 end
88 90 end
91 set_tmp_attachments_directory
89 92 end
90 93
91 94 def test_show_text_file
92 95 get :show, :id => 4
93 96 assert_response :success
94 97 assert_template 'file'
95 98 assert_equal 'text/html', @response.content_type
99 set_tmp_attachments_directory
96 100 end
97 101
98 102 def test_show_text_file_utf_8
99 103 set_tmp_attachments_directory
100 104 a = Attachment.new(:container => Issue.find(1),
101 105 :file => uploaded_test_file("japanese-utf-8.txt", "text/plain"),
102 106 :author => User.find(1))
103 107 assert a.save
104 108 assert_equal 'japanese-utf-8.txt', a.filename
105 109
106 110 str_japanese = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"
107 111 str_japanese.force_encoding('UTF-8') if str_japanese.respond_to?(:force_encoding)
108 112
109 113 get :show, :id => a.id
110 114 assert_response :success
111 115 assert_template 'file'
112 116 assert_equal 'text/html', @response.content_type
113 117 assert_tag :tag => 'th',
114 118 :content => '1',
115 119 :attributes => { :class => 'line-num' },
116 120 :sibling => { :tag => 'td', :content => /#{str_japanese}/ }
117 121 end
118 122
119 123 def test_show_text_file_replcace_cannot_convert_content
120 124 set_tmp_attachments_directory
121 125 with_settings :repositories_encodings => 'UTF-8' do
122 126 a = Attachment.new(:container => Issue.find(1),
123 127 :file => uploaded_test_file("iso8859-1.txt", "text/plain"),
124 128 :author => User.find(1))
125 129 assert a.save
126 130 assert_equal 'iso8859-1.txt', a.filename
127 131
128 132 get :show, :id => a.id
129 133 assert_response :success
130 134 assert_template 'file'
131 135 assert_equal 'text/html', @response.content_type
132 136 assert_tag :tag => 'th',
133 137 :content => '7',
134 138 :attributes => { :class => 'line-num' },
135 139 :sibling => { :tag => 'td', :content => /Demande cr\?\?e avec succ\?s/ }
136 140 end
137 141 end
138 142
139 143 def test_show_text_file_latin_1
140 144 set_tmp_attachments_directory
141 145 with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
142 146 a = Attachment.new(:container => Issue.find(1),
143 147 :file => uploaded_test_file("iso8859-1.txt", "text/plain"),
144 148 :author => User.find(1))
145 149 assert a.save
146 150 assert_equal 'iso8859-1.txt', a.filename
147 151
148 152 get :show, :id => a.id
149 153 assert_response :success
150 154 assert_template 'file'
151 155 assert_equal 'text/html', @response.content_type
152 156 assert_tag :tag => 'th',
153 157 :content => '7',
154 158 :attributes => { :class => 'line-num' },
155 159 :sibling => { :tag => 'td', :content => /Demande créée avec succès/ }
156 160 end
157 161 end
158 162
159 163 def test_show_text_file_should_send_if_too_big
160 164 Setting.file_max_size_displayed = 512
161 165 Attachment.find(4).update_attribute :filesize, 754.kilobyte
162 166
163 167 get :show, :id => 4
164 168 assert_response :success
165 169 assert_equal 'application/x-ruby', @response.content_type
170 set_tmp_attachments_directory
166 171 end
167 172
168 173 def test_show_other
169 174 get :show, :id => 6
170 175 assert_response :success
171 176 assert_equal 'application/octet-stream', @response.content_type
177 set_tmp_attachments_directory
172 178 end
173 179
174 180 def test_show_file_from_private_issue_without_permission
175 181 get :show, :id => 15
176 182 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2F15'
183 set_tmp_attachments_directory
177 184 end
178 185
179 186 def test_show_file_from_private_issue_with_permission
180 187 @request.session[:user_id] = 2
181 188 get :show, :id => 15
182 189 assert_response :success
183 190 assert_tag 'h2', :content => /private.diff/
191 set_tmp_attachments_directory
184 192 end
185 193
186 194 def test_download_text_file
187 195 get :download, :id => 4
188 196 assert_response :success
189 197 assert_equal 'application/x-ruby', @response.content_type
198 set_tmp_attachments_directory
190 199 end
191 200
192 201 def test_download_should_assign_content_type_if_blank
193 202 Attachment.find(4).update_attribute(:content_type, '')
194 203
195 204 get :download, :id => 4
196 205 assert_response :success
197 206 assert_equal 'text/x-ruby', @response.content_type
207 set_tmp_attachments_directory
198 208 end
199 209
200 210 def test_download_missing_file
201 211 get :download, :id => 2
202 212 assert_response 404
213 set_tmp_attachments_directory
203 214 end
204 215
205 216 def test_anonymous_on_private_private
206 217 get :download, :id => 7
207 218 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2Fdownload%2F7'
219 set_tmp_attachments_directory
208 220 end
209 221
210 222 def test_destroy_issue_attachment
211 223 issue = Issue.find(3)
212 224 @request.session[:user_id] = 2
213 225
214 226 assert_difference 'issue.attachments.count', -1 do
215 227 post :destroy, :id => 1
216 228 end
217 229 # no referrer
218 230 assert_redirected_to '/projects/ecookbook'
219 231 assert_nil Attachment.find_by_id(1)
220 232 j = issue.journals.find(:first, :order => 'created_on DESC')
221 233 assert_equal 'attachment', j.details.first.property
222 234 assert_equal '1', j.details.first.prop_key
223 235 assert_equal 'error281.txt', j.details.first.old_value
236 set_tmp_attachments_directory
224 237 end
225 238
226 239 def test_destroy_wiki_page_attachment
227 240 @request.session[:user_id] = 2
228 241 assert_difference 'Attachment.count', -1 do
229 242 post :destroy, :id => 3
230 243 assert_response 302
231 244 end
245 set_tmp_attachments_directory
232 246 end
233 247
234 248 def test_destroy_project_attachment
235 249 @request.session[:user_id] = 2
236 250 assert_difference 'Attachment.count', -1 do
237 251 post :destroy, :id => 8
238 252 assert_response 302
239 253 end
254 set_tmp_attachments_directory
240 255 end
241 256
242 257 def test_destroy_version_attachment
243 258 @request.session[:user_id] = 2
244 259 assert_difference 'Attachment.count', -1 do
245 260 post :destroy, :id => 9
246 261 assert_response 302
247 262 end
263 set_tmp_attachments_directory
248 264 end
249 265
250 266 def test_destroy_without_permission
251 267 post :destroy, :id => 3
252 268 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2Fdestroy%2F3'
253 269 assert Attachment.find_by_id(3)
270 set_tmp_attachments_directory
254 271 end
255 272 end
@@ -1,86 +1,86
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class ApiTest::AttachmentsTest < ActionController::IntegrationTest
21 21 fixtures :projects, :trackers, :issue_statuses, :issues,
22 22 :enumerations, :users, :issue_categories,
23 23 :projects_trackers,
24 24 :roles,
25 25 :member_roles,
26 26 :members,
27 27 :enabled_modules,
28 28 :workflows,
29 29 :attachments
30 30
31 31 def setup
32 32 Setting.rest_api_enabled = '1'
33 33 Attachment.storage_path = "#{Rails.root}/test/fixtures/files"
34 34 end
35 35
36 36 context "/attachments/:id" do
37 37 context "GET" do
38 38 should "return the attachment" do
39 39 get '/attachments/7.xml', {}, :authorization => credentials('jsmith')
40
41 40 assert_response :success
42 41 assert_equal 'application/xml', @response.content_type
43 42 assert_tag :tag => 'attachment',
44 43 :child => {
45 44 :tag => 'id',
46 45 :content => '7',
47 46 :sibling => {
48 47 :tag => 'filename',
49 48 :content => 'archive.zip',
50 49 :sibling => {
51 50 :tag => 'content_url',
52 51 :content => 'http://www.example.com/attachments/download/7/archive.zip'
53 52 }
54 53 }
55 54 }
56 55 end
57 56
58 57 should "deny access without credentials" do
59 58 get '/attachments/7.xml'
60
61 59 assert_response 401
60 set_tmp_attachments_directory
62 61 end
63 62 end
64 63 end
65 64
66 65 context "/attachments/download/:id/:filename" do
67 66 context "GET" do
68 67 should "return the attachment content" do
69 get '/attachments/download/7/archive.zip', {}, :authorization => credentials('jsmith')
70
68 get '/attachments/download/7/archive.zip',
69 {}, :authorization => credentials('jsmith')
71 70 assert_response :success
72 71 assert_equal 'application/octet-stream', @response.content_type
72 set_tmp_attachments_directory
73 73 end
74 74
75 75 should "deny access without credentials" do
76 76 get '/attachments/download/7/archive.zip'
77
78 77 assert_response 302
78 set_tmp_attachments_directory
79 79 end
80 80 end
81 81 end
82 82
83 83 def credentials(user, password=nil)
84 84 ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
85 85 end
86 86 end
@@ -1,145 +1,147
1 1 # encoding: utf-8
2 2 #
3 3 # Redmine - project management software
4 4 # Copyright (C) 2006-2011 Jean-Philippe Lang
5 5 #
6 6 # This program is free software; you can redistribute it and/or
7 7 # modify it under the terms of the GNU General Public License
8 8 # as published by the Free Software Foundation; either version 2
9 9 # of the License, or (at your option) any later version.
10 10 #
11 11 # This program is distributed in the hope that it will be useful,
12 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14 # GNU General Public License for more details.
15 15 #
16 16 # You should have received a copy of the GNU General Public License
17 17 # along with this program; if not, write to the Free Software
18 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 19
20 20 require File.expand_path('../../test_helper', __FILE__)
21 21
22 22 class AttachmentTest < ActiveSupport::TestCase
23 23 fixtures :users, :projects, :roles, :members, :member_roles,
24 24 :enabled_modules, :issues, :trackers, :attachments
25 25
26 26 def setup
27 27 set_tmp_attachments_directory
28 28 end
29 29
30 30 def test_create
31 31 a = Attachment.new(:container => Issue.find(1),
32 32 :file => uploaded_test_file("testfile.txt", "text/plain"),
33 33 :author => User.find(1))
34 34 assert a.save
35 35 assert_equal 'testfile.txt', a.filename
36 36 assert_equal 59, a.filesize
37 37 assert_equal 'text/plain', a.content_type
38 38 assert_equal 0, a.downloads
39 39 assert_equal '1478adae0d4eb06d35897518540e25d6', a.digest
40 40 assert File.exist?(a.diskfile)
41 41 assert_equal 59, File.size(a.diskfile)
42 42 end
43 43
44 44 def test_destroy
45 45 a = Attachment.new(:container => Issue.find(1),
46 46 :file => uploaded_test_file("testfile.txt", "text/plain"),
47 47 :author => User.find(1))
48 48 assert a.save
49 49 assert_equal 'testfile.txt', a.filename
50 50 assert_equal 59, a.filesize
51 51 assert_equal 'text/plain', a.content_type
52 52 assert_equal 0, a.downloads
53 53 assert_equal '1478adae0d4eb06d35897518540e25d6', a.digest
54 54 diskfile = a.diskfile
55 55 assert File.exist?(diskfile)
56 56 assert_equal 59, File.size(a.diskfile)
57 57 assert a.destroy
58 58 assert !File.exist?(diskfile)
59 59 end
60 60
61 61 def test_create_should_auto_assign_content_type
62 62 a = Attachment.new(:container => Issue.find(1),
63 63 :file => uploaded_test_file("testfile.txt", ""),
64 64 :author => User.find(1))
65 65 assert a.save
66 66 assert_equal 'text/plain', a.content_type
67 67 end
68 68
69 69 def test_identical_attachments_at_the_same_time_should_not_overwrite
70 70 a1 = Attachment.create!(:container => Issue.find(1),
71 71 :file => uploaded_test_file("testfile.txt", ""),
72 72 :author => User.find(1))
73 73 a2 = Attachment.create!(:container => Issue.find(1),
74 74 :file => uploaded_test_file("testfile.txt", ""),
75 75 :author => User.find(1))
76 76 assert a1.disk_filename != a2.disk_filename
77 77 end
78 78
79 79 def test_diskfilename
80 80 assert Attachment.disk_filename("test_file.txt") =~ /^\d{12}_test_file.txt$/
81 81 assert_equal 'test_file.txt', Attachment.disk_filename("test_file.txt")[13..-1]
82 82 assert_equal '770c509475505f37c2b8fb6030434d6b.txt', Attachment.disk_filename("test_accentuΓ©.txt")[13..-1]
83 83 assert_equal 'f8139524ebb8f32e51976982cd20a85d', Attachment.disk_filename("test_accentuΓ©")[13..-1]
84 84 assert_equal 'cbb5b0f30978ba03731d61f9f6d10011', Attachment.disk_filename("test_accentuΓ©.Γ§a")[13..-1]
85 85 end
86 86
87 87 context "Attachmnet.attach_files" do
88 88 should "attach the file" do
89 89 issue = Issue.first
90 90 assert_difference 'Attachment.count' do
91 91 Attachment.attach_files(issue,
92 92 '1' => {
93 93 'file' => uploaded_test_file('testfile.txt', 'text/plain'),
94 94 'description' => 'test'
95 95 })
96 96 end
97 97
98 98 attachment = Attachment.first(:order => 'id DESC')
99 99 assert_equal issue, attachment.container
100 100 assert_equal 'testfile.txt', attachment.filename
101 101 assert_equal 59, attachment.filesize
102 102 assert_equal 'test', attachment.description
103 103 assert_equal 'text/plain', attachment.content_type
104 104 assert File.exists?(attachment.diskfile)
105 105 assert_equal 59, File.size(attachment.diskfile)
106 106 end
107 107
108 108 should "add unsaved files to the object as unsaved attachments" do
109 109 # Max size of 0 to force Attachment creation failures
110 110 with_settings(:attachment_max_size => 0) do
111 111 @project = Project.generate!
112 112 response = Attachment.attach_files(@project, {
113 113 '1' => {'file' => mock_file, 'description' => 'test'},
114 114 '2' => {'file' => mock_file, 'description' => 'test'}
115 115 })
116 116
117 117 assert response[:unsaved].present?
118 118 assert_equal 2, response[:unsaved].length
119 119 assert response[:unsaved].first.new_record?
120 120 assert response[:unsaved].second.new_record?
121 121 assert_equal response[:unsaved], @project.unsaved_attachments
122 122 end
123 123 end
124 124 end
125 125
126 126 def test_latest_attach
127 127 Attachment.storage_path = "#{Rails.root}/test/fixtures/files"
128 128 a1 = Attachment.find(16)
129 129 assert_equal "testfile.png", a1.filename
130 130 assert a1.readable?
131 131 assert (! a1.visible?(User.anonymous))
132 132 assert a1.visible?(User.find(2))
133 133 a2 = Attachment.find(17)
134 134 assert_equal "testfile.PNG", a2.filename
135 135 assert a2.readable?
136 136 assert (! a2.visible?(User.anonymous))
137 137 assert a2.visible?(User.find(2))
138 138 assert a1.created_on < a2.created_on
139 139
140 140 la1 = Attachment.latest_attach([a1, a2], "testfile.png")
141 141 assert_equal 17, la1.id
142 142 la2 = Attachment.latest_attach([a1, a2], "Testfile.PNG")
143 143 assert_equal 17, la2.id
144
145 set_tmp_attachments_directory
144 146 end
145 147 end
@@ -1,877 +1,878
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class ApplicationHelperTest < ActionView::TestCase
21 21 fixtures :projects, :roles, :enabled_modules, :users,
22 22 :repositories, :changesets,
23 23 :trackers, :issue_statuses, :issues, :versions, :documents,
24 24 :wikis, :wiki_pages, :wiki_contents,
25 25 :boards, :messages, :news,
26 26 :attachments, :enumerations
27 27
28 28 def setup
29 29 super
30 30 set_tmp_attachments_directory
31 31 end
32 32
33 33 context "#link_to_if_authorized" do
34 34 context "authorized user" do
35 35 should "be tested"
36 36 end
37 37
38 38 context "unauthorized user" do
39 39 should "be tested"
40 40 end
41 41
42 42 should "allow using the :controller and :action for the target link" do
43 43 User.current = User.find_by_login('admin')
44 44
45 45 @project = Issue.first.project # Used by helper
46 46 response = link_to_if_authorized("By controller/action",
47 47 {:controller => 'issues', :action => 'edit', :id => Issue.first.id})
48 48 assert_match /href/, response
49 49 end
50 50
51 51 end
52 52
53 53 def test_auto_links
54 54 to_test = {
55 55 'http://foo.bar' => '<a class="external" href="http://foo.bar">http://foo.bar</a>',
56 56 'http://foo.bar/~user' => '<a class="external" href="http://foo.bar/~user">http://foo.bar/~user</a>',
57 57 'http://foo.bar.' => '<a class="external" href="http://foo.bar">http://foo.bar</a>.',
58 58 'https://foo.bar.' => '<a class="external" href="https://foo.bar">https://foo.bar</a>.',
59 59 'This is a link: http://foo.bar.' => 'This is a link: <a class="external" href="http://foo.bar">http://foo.bar</a>.',
60 60 'A link (eg. http://foo.bar).' => 'A link (eg. <a class="external" href="http://foo.bar">http://foo.bar</a>).',
61 61 '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>.',
62 62 'http://www.foo.bar/Test_(foobar)' => '<a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>',
63 63 '(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>)',
64 64 '(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>)',
65 65 '(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>).',
66 66 '(see "inline link":http://www.foo.bar/Test_(foobar))' => '(see <a href="http://www.foo.bar/Test_(foobar)" class="external">inline link</a>)',
67 67 '(see "inline link":http://www.foo.bar/Test)' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>)',
68 68 '(see "inline link":http://www.foo.bar/Test).' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>).',
69 69 'www.foo.bar' => '<a class="external" href="http://www.foo.bar">www.foo.bar</a>',
70 70 '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>',
71 71 'http://foo.bar/page#125' => '<a class="external" href="http://foo.bar/page#125">http://foo.bar/page#125</a>',
72 72 'http://foo@www.bar.com' => '<a class="external" href="http://foo@www.bar.com">http://foo@www.bar.com</a>',
73 73 'http://foo:bar@www.bar.com' => '<a class="external" href="http://foo:bar@www.bar.com">http://foo:bar@www.bar.com</a>',
74 74 'ftp://foo.bar' => '<a class="external" href="ftp://foo.bar">ftp://foo.bar</a>',
75 75 'ftps://foo.bar' => '<a class="external" href="ftps://foo.bar">ftps://foo.bar</a>',
76 76 'sftp://foo.bar' => '<a class="external" href="sftp://foo.bar">sftp://foo.bar</a>',
77 77 # two exclamation marks
78 78 '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>',
79 79 # escaping
80 80 'http://foo"bar' => '<a class="external" href="http://foo&quot;bar">http://foo"bar</a>',
81 81 # wrap in angle brackets
82 82 '<http://foo.bar>' => '&lt;<a class="external" href="http://foo.bar">http://foo.bar</a>&gt;'
83 83 }
84 84 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
85 85 end
86 86
87 87 def test_auto_mailto
88 88 assert_equal '<p><a class="email" href="mailto:test@foo.bar">test@foo.bar</a></p>',
89 89 textilizable('test@foo.bar')
90 90 end
91 91
92 92 def test_inline_images
93 93 to_test = {
94 94 '!http://foo.bar/image.jpg!' => '<img src="http://foo.bar/image.jpg" alt="" />',
95 95 'floating !>http://foo.bar/image.jpg!' => 'floating <div style="float:right"><img src="http://foo.bar/image.jpg" alt="" /></div>',
96 96 'with class !(some-class)http://foo.bar/image.jpg!' => 'with class <img src="http://foo.bar/image.jpg" class="some-class" alt="" />',
97 97 # inline styles should be stripped
98 98 'with style !{width:100px;height100px}http://foo.bar/image.jpg!' => 'with style <img src="http://foo.bar/image.jpg" alt="" />',
99 99 '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" />',
100 100 '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;" />',
101 101 }
102 102 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
103 103 end
104 104
105 105 def test_inline_images_inside_tags
106 106 raw = <<-RAW
107 107 h1. !foo.png! Heading
108 108
109 109 Centered image:
110 110
111 111 p=. !bar.gif!
112 112 RAW
113 113
114 114 assert textilizable(raw).include?('<img src="foo.png" alt="" />')
115 115 assert textilizable(raw).include?('<img src="bar.gif" alt="" />')
116 116 end
117 117
118 118 def test_attached_images
119 119 to_test = {
120 120 'Inline image: !logo.gif!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
121 121 'Inline image: !logo.GIF!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
122 122 'No match: !ogo.gif!' => 'No match: <img src="ogo.gif" alt="" />',
123 123 'No match: !ogo.GIF!' => 'No match: <img src="ogo.GIF" alt="" />',
124 124 # link image
125 125 '!logo.gif!:http://foo.bar/' => '<a href="http://foo.bar/"><img src="/attachments/download/3" title="This is a logo" alt="This is a logo" /></a>',
126 126 }
127 127 attachments = Attachment.find(:all)
128 128 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
129 129 end
130 130
131 131 def test_attached_images_filename_extension
132 132 set_tmp_attachments_directory
133 133 a1 = Attachment.new(
134 134 :container => Issue.find(1),
135 135 :file => mock_file_with_options({:original_filename => "testtest.JPG"}),
136 136 :author => User.find(1))
137 137 assert a1.save
138 138 assert_equal "testtest.JPG", a1.filename
139 139 assert_equal "image/jpeg", a1.content_type
140 140 assert a1.image?
141 141
142 142 a2 = Attachment.new(
143 143 :container => Issue.find(1),
144 144 :file => mock_file_with_options({:original_filename => "testtest.jpeg"}),
145 145 :author => User.find(1))
146 146 assert a2.save
147 147 assert_equal "testtest.jpeg", a2.filename
148 148 assert_equal "image/jpeg", a2.content_type
149 149 assert a2.image?
150 150
151 151 a3 = Attachment.new(
152 152 :container => Issue.find(1),
153 153 :file => mock_file_with_options({:original_filename => "testtest.JPE"}),
154 154 :author => User.find(1))
155 155 assert a3.save
156 156 assert_equal "testtest.JPE", a3.filename
157 157 assert_equal "image/jpeg", a3.content_type
158 158 assert a3.image?
159 159
160 160 a4 = Attachment.new(
161 161 :container => Issue.find(1),
162 162 :file => mock_file_with_options({:original_filename => "Testtest.BMP"}),
163 163 :author => User.find(1))
164 164 assert a4.save
165 165 assert_equal "Testtest.BMP", a4.filename
166 166 assert_equal "image/x-ms-bmp", a4.content_type
167 167 assert a4.image?
168 168
169 169 to_test = {
170 170 'Inline image: !testtest.jpg!' =>
171 171 'Inline image: <img src="/attachments/download/' + a1.id.to_s + '" alt="" />',
172 172 'Inline image: !testtest.jpeg!' =>
173 173 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '" alt="" />',
174 174 'Inline image: !testtest.jpe!' =>
175 175 'Inline image: <img src="/attachments/download/' + a3.id.to_s + '" alt="" />',
176 176 'Inline image: !testtest.bmp!' =>
177 177 'Inline image: <img src="/attachments/download/' + a4.id.to_s + '" alt="" />',
178 178 }
179 179
180 180 attachments = [a1, a2, a3, a4]
181 181 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
182 182 end
183 183
184 184 def test_attached_images_should_read_later
185 185 Attachment.storage_path = "#{Rails.root}/test/fixtures/files"
186 186 a1 = Attachment.find(16)
187 187 assert_equal "testfile.png", a1.filename
188 188 assert a1.readable?
189 189 assert (! a1.visible?(User.anonymous))
190 190 assert a1.visible?(User.find(2))
191 191 a2 = Attachment.find(17)
192 192 assert_equal "testfile.PNG", a2.filename
193 193 assert a2.readable?
194 194 assert (! a2.visible?(User.anonymous))
195 195 assert a2.visible?(User.find(2))
196 196 assert a1.created_on < a2.created_on
197 197
198 198 to_test = {
199 199 'Inline image: !testfile.png!' =>
200 200 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '" alt="" />',
201 201 'Inline image: !Testfile.PNG!' =>
202 202 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '" alt="" />',
203 203 }
204 204 attachments = [a1, a2]
205 205 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
206 set_tmp_attachments_directory
206 207 end
207 208
208 209 def test_textile_external_links
209 210 to_test = {
210 211 'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
211 212 'This is an intern "link":/foo/bar' => 'This is an intern <a href="/foo/bar">link</a>',
212 213 '"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>',
213 214 '"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>',
214 215 "This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":</p>\n\n\n\t<p>Another paragraph",
215 216 # no multiline link text
216 217 "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",
217 218 # mailto link
218 219 "\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "<a href=\"mailto:sysadmin@example.com?subject=redmine%20permissions\">system administrator</a>",
219 220 # two exclamation marks
220 221 '"a link":http://example.net/path!602815048C7B5C20!302.html' => '<a href="http://example.net/path!602815048C7B5C20!302.html" class="external">a link</a>',
221 222 # escaping
222 223 '"test":http://foo"bar' => '<a href="http://foo&quot;bar" class="external">test</a>',
223 224 }
224 225 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
225 226 end
226 227
227 228 def test_redmine_links
228 229 issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
229 230 :class => 'issue status-1 priority-1 overdue', :title => 'Error 281 when updating a recipe (New)')
230 231
231 232 changeset_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
232 233 :class => 'changeset', :title => 'My very first commit')
233 234 changeset_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
234 235 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
235 236
236 237 document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
237 238 :class => 'document')
238 239
239 240 version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
240 241 :class => 'version')
241 242
242 243 board_url = {:controller => 'boards', :action => 'show', :id => 2, :project_id => 'ecookbook'}
243 244
244 245 message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
245 246
246 247 news_url = {:controller => 'news', :action => 'show', :id => 1}
247 248
248 249 project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
249 250
250 251 source_url = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}
251 252 source_url_with_ext = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file.ext']}
252 253
253 254 to_test = {
254 255 # tickets
255 256 '#3, [#3], (#3) and #3.' => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
256 257 # changesets
257 258 'r1' => changeset_link,
258 259 'r1.' => "#{changeset_link}.",
259 260 'r1, r2' => "#{changeset_link}, #{changeset_link2}",
260 261 'r1,r2' => "#{changeset_link},#{changeset_link2}",
261 262 # documents
262 263 'document#1' => document_link,
263 264 'document:"Test document"' => document_link,
264 265 # versions
265 266 'version#2' => version_link,
266 267 'version:1.0' => version_link,
267 268 'version:"1.0"' => version_link,
268 269 # source
269 270 'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'),
270 271 'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".",
271 272 'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
272 273 'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".",
273 274 'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
274 275 'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",",
275 276 'source:/some/file@52' => link_to('source:/some/file@52', source_url.merge(:rev => 52), :class => 'source'),
276 277 'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_ext.merge(:rev => 52), :class => 'source'),
277 278 'source:/some/file#L110' => link_to('source:/some/file#L110', source_url.merge(:anchor => 'L110'), :class => 'source'),
278 279 'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext.merge(:anchor => 'L110'), :class => 'source'),
279 280 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url.merge(:rev => 52, :anchor => 'L110'), :class => 'source'),
280 281 'export:/some/file' => link_to('export:/some/file', source_url.merge(:format => 'raw'), :class => 'source download'),
281 282 # forum
282 283 'forum#2' => link_to('Discussion', board_url, :class => 'board'),
283 284 'forum:Discussion' => link_to('Discussion', board_url, :class => 'board'),
284 285 # message
285 286 'message#4' => link_to('Post 2', message_url, :class => 'message'),
286 287 'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5', :r => 5), :class => 'message'),
287 288 # news
288 289 'news#1' => link_to('eCookbook first release !', news_url, :class => 'news'),
289 290 'news:"eCookbook first release !"' => link_to('eCookbook first release !', news_url, :class => 'news'),
290 291 # project
291 292 'project#3' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
292 293 'project:subproject1' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
293 294 'project:"eCookbook subProject 1"' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
294 295 # escaping
295 296 '!#3.' => '#3.',
296 297 '!r1' => 'r1',
297 298 '!document#1' => 'document#1',
298 299 '!document:"Test document"' => 'document:"Test document"',
299 300 '!version#2' => 'version#2',
300 301 '!version:1.0' => 'version:1.0',
301 302 '!version:"1.0"' => 'version:"1.0"',
302 303 '!source:/some/file' => 'source:/some/file',
303 304 # not found
304 305 '#0123456789' => '#0123456789',
305 306 # invalid expressions
306 307 'source:' => 'source:',
307 308 # url hash
308 309 "http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
309 310 }
310 311 @project = Project.find(1)
311 312 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
312 313 end
313 314
314 315 def test_cross_project_redmine_links
315 316 source_link = link_to('ecookbook:source:/some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']},
316 317 :class => 'source')
317 318
318 319 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
319 320 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
320 321
321 322 to_test = {
322 323 # documents
323 324 'document:"Test document"' => 'document:"Test document"',
324 325 'ecookbook:document:"Test document"' => '<a href="/documents/1" class="document">Test document</a>',
325 326 'invalid:document:"Test document"' => 'invalid:document:"Test document"',
326 327 # versions
327 328 'version:"1.0"' => 'version:"1.0"',
328 329 'ecookbook:version:"1.0"' => '<a href="/versions/2" class="version">1.0</a>',
329 330 'invalid:version:"1.0"' => 'invalid:version:"1.0"',
330 331 # changeset
331 332 'r2' => 'r2',
332 333 'ecookbook:r2' => changeset_link,
333 334 'invalid:r2' => 'invalid:r2',
334 335 # source
335 336 'source:/some/file' => 'source:/some/file',
336 337 'ecookbook:source:/some/file' => source_link,
337 338 'invalid:source:/some/file' => 'invalid:source:/some/file',
338 339 }
339 340 @project = Project.find(3)
340 341 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
341 342 end
342 343
343 344 def test_redmine_links_git_commit
344 345 changeset_link = link_to('abcd',
345 346 {
346 347 :controller => 'repositories',
347 348 :action => 'revision',
348 349 :id => 'subproject1',
349 350 :rev => 'abcd',
350 351 },
351 352 :class => 'changeset', :title => 'test commit')
352 353 to_test = {
353 354 'commit:abcd' => changeset_link,
354 355 }
355 356 @project = Project.find(3)
356 357 r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
357 358 assert r
358 359 c = Changeset.new(:repository => r,
359 360 :committed_on => Time.now,
360 361 :revision => 'abcd',
361 362 :scmid => 'abcd',
362 363 :comments => 'test commit')
363 364 assert( c.save )
364 365 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
365 366 end
366 367
367 368 # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
368 369 def test_redmine_links_darcs_commit
369 370 changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
370 371 {
371 372 :controller => 'repositories',
372 373 :action => 'revision',
373 374 :id => 'subproject1',
374 375 :rev => '123',
375 376 },
376 377 :class => 'changeset', :title => 'test commit')
377 378 to_test = {
378 379 'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
379 380 }
380 381 @project = Project.find(3)
381 382 r = Repository::Darcs.create!(
382 383 :project => @project, :url => '/tmp/test/darcs',
383 384 :log_encoding => 'UTF-8')
384 385 assert r
385 386 c = Changeset.new(:repository => r,
386 387 :committed_on => Time.now,
387 388 :revision => '123',
388 389 :scmid => '20080308225258-98289-abcd456efg.gz',
389 390 :comments => 'test commit')
390 391 assert( c.save )
391 392 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
392 393 end
393 394
394 395 def test_redmine_links_mercurial_commit
395 396 changeset_link_rev = link_to('r123',
396 397 {
397 398 :controller => 'repositories',
398 399 :action => 'revision',
399 400 :id => 'subproject1',
400 401 :rev => '123' ,
401 402 },
402 403 :class => 'changeset', :title => 'test commit')
403 404 changeset_link_commit = link_to('abcd',
404 405 {
405 406 :controller => 'repositories',
406 407 :action => 'revision',
407 408 :id => 'subproject1',
408 409 :rev => 'abcd' ,
409 410 },
410 411 :class => 'changeset', :title => 'test commit')
411 412 to_test = {
412 413 'r123' => changeset_link_rev,
413 414 'commit:abcd' => changeset_link_commit,
414 415 }
415 416 @project = Project.find(3)
416 417 r = Repository::Mercurial.create!(:project => @project, :url => '/tmp/test')
417 418 assert r
418 419 c = Changeset.new(:repository => r,
419 420 :committed_on => Time.now,
420 421 :revision => '123',
421 422 :scmid => 'abcd',
422 423 :comments => 'test commit')
423 424 assert( c.save )
424 425 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
425 426 end
426 427
427 428 def test_attachment_links
428 429 attachment_link = link_to('error281.txt', {:controller => 'attachments', :action => 'download', :id => '1'}, :class => 'attachment')
429 430 to_test = {
430 431 'attachment:error281.txt' => attachment_link
431 432 }
432 433 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
433 434 end
434 435
435 436 def test_wiki_links
436 437 to_test = {
437 438 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
438 439 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
439 440 # title content should be formatted
440 441 '[[Another page|With _styled_ *title*]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">With <em>styled</em> <strong>title</strong></a>',
441 442 '[[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>',
442 443 # link with anchor
443 444 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
444 445 '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
445 446 # page that doesn't exist
446 447 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
447 448 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
448 449 # link to another project wiki
449 450 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
450 451 '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">Wiki</a>',
451 452 '[[onlinestore:Start page]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Start page</a>',
452 453 '[[onlinestore:Start page|Text]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Text</a>',
453 454 '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
454 455 # striked through link
455 456 '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
456 457 '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
457 458 # escaping
458 459 '![[Another page|Page]]' => '[[Another page|Page]]',
459 460 # project does not exist
460 461 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
461 462 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
462 463 }
463 464
464 465 @project = Project.find(1)
465 466 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
466 467 end
467 468
468 469 def test_wiki_links_within_local_file_generation_context
469 470
470 471 to_test = {
471 472 # link to a page
472 473 '[[CookBook documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">CookBook documentation</a>',
473 474 '[[CookBook documentation|documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">documentation</a>',
474 475 '[[CookBook documentation#One-section]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">CookBook documentation</a>',
475 476 '[[CookBook documentation#One-section|documentation]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">documentation</a>',
476 477 # page that doesn't exist
477 478 '[[Unknown page]]' => '<a href="Unknown_page.html" class="wiki-page new">Unknown page</a>',
478 479 '[[Unknown page|404]]' => '<a href="Unknown_page.html" class="wiki-page new">404</a>',
479 480 '[[Unknown page#anchor]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">Unknown page</a>',
480 481 '[[Unknown page#anchor|404]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">404</a>',
481 482 }
482 483
483 484 @project = Project.find(1)
484 485
485 486 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :local) }
486 487 end
487 488
488 489 def test_html_tags
489 490 to_test = {
490 491 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
491 492 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
492 493 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
493 494 # do not escape pre/code tags
494 495 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
495 496 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
496 497 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
497 498 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
498 499 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
499 500 # remove attributes except class
500 501 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
501 502 '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
502 503 "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
503 504 '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
504 505 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
505 506 # xss
506 507 '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
507 508 '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
508 509 }
509 510 to_test.each { |text, result| assert_equal result, textilizable(text) }
510 511 end
511 512
512 513 def test_allowed_html_tags
513 514 to_test = {
514 515 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
515 516 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
516 517 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
517 518 }
518 519 to_test.each { |text, result| assert_equal result, textilizable(text) }
519 520 end
520 521
521 522 def test_pre_tags
522 523 raw = <<-RAW
523 524 Before
524 525
525 526 <pre>
526 527 <prepared-statement-cache-size>32</prepared-statement-cache-size>
527 528 </pre>
528 529
529 530 After
530 531 RAW
531 532
532 533 expected = <<-EXPECTED
533 534 <p>Before</p>
534 535 <pre>
535 536 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
536 537 </pre>
537 538 <p>After</p>
538 539 EXPECTED
539 540
540 541 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
541 542 end
542 543
543 544 def test_pre_content_should_not_parse_wiki_and_redmine_links
544 545 raw = <<-RAW
545 546 [[CookBook documentation]]
546 547
547 548 #1
548 549
549 550 <pre>
550 551 [[CookBook documentation]]
551 552
552 553 #1
553 554 </pre>
554 555 RAW
555 556
556 557 expected = <<-EXPECTED
557 558 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
558 559 <p><a href="/issues/1" class="issue status-1 priority-1" title="Can't print recipes (New)">#1</a></p>
559 560 <pre>
560 561 [[CookBook documentation]]
561 562
562 563 #1
563 564 </pre>
564 565 EXPECTED
565 566
566 567 @project = Project.find(1)
567 568 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
568 569 end
569 570
570 571 def test_non_closing_pre_blocks_should_be_closed
571 572 raw = <<-RAW
572 573 <pre><code>
573 574 RAW
574 575
575 576 expected = <<-EXPECTED
576 577 <pre><code>
577 578 </code></pre>
578 579 EXPECTED
579 580
580 581 @project = Project.find(1)
581 582 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
582 583 end
583 584
584 585 def test_syntax_highlight
585 586 raw = <<-RAW
586 587 <pre><code class="ruby">
587 588 # Some ruby code here
588 589 </code></pre>
589 590 RAW
590 591
591 592 expected = <<-EXPECTED
592 593 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="line-numbers">1</span><span class="comment"># Some ruby code here</span></span>
593 594 </code></pre>
594 595 EXPECTED
595 596
596 597 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
597 598 end
598 599
599 600 def test_wiki_links_in_tables
600 601 to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
601 602 '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
602 603 '<td><a href="/projects/ecookbook/wiki/Other_Page" class="wiki-page new">Other title</a></td>' +
603 604 '</tr><tr><td>Cell 21</td><td><a href="/projects/ecookbook/wiki/Last_page" class="wiki-page new">Last page</a></td></tr>'
604 605 }
605 606 @project = Project.find(1)
606 607 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
607 608 end
608 609
609 610 def test_text_formatting
610 611 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
611 612 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
612 613 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
613 614 '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>',
614 615 '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',
615 616 }
616 617 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
617 618 end
618 619
619 620 def test_wiki_horizontal_rule
620 621 assert_equal '<hr />', textilizable('---')
621 622 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
622 623 end
623 624
624 625 def test_footnotes
625 626 raw = <<-RAW
626 627 This is some text[1].
627 628
628 629 fn1. This is the foot note
629 630 RAW
630 631
631 632 expected = <<-EXPECTED
632 633 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
633 634 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
634 635 EXPECTED
635 636
636 637 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
637 638 end
638 639
639 640 def test_headings
640 641 raw = 'h1. Some heading'
641 642 expected = %|<a name="Some-heading"></a>\n<h1 >Some heading<a href="#Some-heading" class="wiki-anchor">&para;</a></h1>|
642 643
643 644 assert_equal expected, textilizable(raw)
644 645 end
645 646
646 647 def test_headings_with_special_chars
647 648 # This test makes sure that the generated anchor names match the expected
648 649 # ones even if the heading text contains unconventional characters
649 650 raw = 'h1. Some heading related to version 0.5'
650 651 anchor = sanitize_anchor_name("Some-heading-related-to-version-0.5")
651 652 expected = %|<a name="#{anchor}"></a>\n<h1 >Some heading related to version 0.5<a href="##{anchor}" class="wiki-anchor">&para;</a></h1>|
652 653
653 654 assert_equal expected, textilizable(raw)
654 655 end
655 656
656 657 def test_wiki_links_within_wiki_page_context
657 658
658 659 page = WikiPage.find_by_title('Another_page' )
659 660
660 661 to_test = {
661 662 # link to another page
662 663 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
663 664 '[[CookBook documentation|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">documentation</a>',
664 665 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
665 666 '[[CookBook documentation#One-section|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">documentation</a>',
666 667 # link to the current page
667 668 '[[Another page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Another page</a>',
668 669 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
669 670 '[[Another page#anchor]]' => '<a href="#anchor" class="wiki-page">Another page</a>',
670 671 '[[Another page#anchor|Page]]' => '<a href="#anchor" class="wiki-page">Page</a>',
671 672 # page that doesn't exist
672 673 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
673 674 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
674 675 '[[Unknown page#anchor]]' => '<a href="/projects/ecookbook/wiki/Unknown_page#anchor" class="wiki-page new">Unknown page</a>',
675 676 '[[Unknown page#anchor|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page#anchor" class="wiki-page new">404</a>',
676 677 }
677 678
678 679 @project = Project.find(1)
679 680
680 681 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(WikiContent.generate!( :text => text, :page => page ), :text) }
681 682 end
682 683
683 684 def test_wiki_links_anchor_option_should_prepend_page_title_to_href
684 685
685 686 to_test = {
686 687 # link to a page
687 688 '[[CookBook documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">CookBook documentation</a>',
688 689 '[[CookBook documentation|documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">documentation</a>',
689 690 '[[CookBook documentation#One-section]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">CookBook documentation</a>',
690 691 '[[CookBook documentation#One-section|documentation]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">documentation</a>',
691 692 # page that doesn't exist
692 693 '[[Unknown page]]' => '<a href="#Unknown_page" class="wiki-page new">Unknown page</a>',
693 694 '[[Unknown page|404]]' => '<a href="#Unknown_page" class="wiki-page new">404</a>',
694 695 '[[Unknown page#anchor]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">Unknown page</a>',
695 696 '[[Unknown page#anchor|404]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">404</a>',
696 697 }
697 698
698 699 @project = Project.find(1)
699 700
700 701 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :anchor) }
701 702 end
702 703
703 704 def test_headings_in_wiki_single_page_export_should_be_prepended_with_page_title
704 705 page = WikiPage.generate!( :title => 'Page Title' )
705 706 content = WikiContent.generate!( :text => 'h1. Some heading', :page => page )
706 707
707 708 expected = %|<a name="Page_Title_Some-heading"></a>\n<h1 >Some heading<a href="#Page_Title_Some-heading" class="wiki-anchor">&para;</a></h1>|
708 709
709 710 assert_equal expected, textilizable(content, :text, :wiki_links => :anchor )
710 711 end
711 712
712 713 def test_table_of_content
713 714 raw = <<-RAW
714 715 {{toc}}
715 716
716 717 h1. Title
717 718
718 719 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
719 720
720 721 h2. Subtitle with a [[Wiki]] link
721 722
722 723 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
723 724
724 725 h2. Subtitle with [[Wiki|another Wiki]] link
725 726
726 727 h2. Subtitle with %{color:red}red text%
727 728
728 729 <pre>
729 730 some code
730 731 </pre>
731 732
732 733 h3. Subtitle with *some* _modifiers_
733 734
734 735 h1. Another title
735 736
736 737 h3. An "Internet link":http://www.redmine.org/ inside subtitle
737 738
738 739 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
739 740
740 741 RAW
741 742
742 743 expected = '<ul class="toc">' +
743 744 '<li><a href="#Title">Title</a>' +
744 745 '<ul>' +
745 746 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
746 747 '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
747 748 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
748 749 '<ul>' +
749 750 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
750 751 '</ul>' +
751 752 '</li>' +
752 753 '</ul>' +
753 754 '</li>' +
754 755 '<li><a href="#Another-title">Another title</a>' +
755 756 '<ul>' +
756 757 '<li>' +
757 758 '<ul>' +
758 759 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
759 760 '</ul>' +
760 761 '</li>' +
761 762 '<li><a href="#Project-Name">Project Name</a></li>' +
762 763 '</ul>' +
763 764 '</li>' +
764 765 '</ul>'
765 766
766 767 @project = Project.find(1)
767 768 assert textilizable(raw).gsub("\n", "").include?(expected), textilizable(raw)
768 769 end
769 770
770 771 def test_table_of_content_should_contain_included_page_headings
771 772 raw = <<-RAW
772 773 {{toc}}
773 774
774 775 h1. Included
775 776
776 777 {{include(Child_1)}}
777 778 RAW
778 779
779 780 expected = '<ul class="toc">' +
780 781 '<li><a href="#Included">Included</a></li>' +
781 782 '<li><a href="#Child-page-1">Child page 1</a></li>' +
782 783 '</ul>'
783 784
784 785 @project = Project.find(1)
785 786 assert textilizable(raw).gsub("\n", "").include?(expected)
786 787 end
787 788
788 789 def test_default_formatter
789 790 Setting.text_formatting = 'unknown'
790 791 text = 'a *link*: http://www.example.net/'
791 792 assert_equal '<p>a *link*: <a href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
792 793 Setting.text_formatting = 'textile'
793 794 end
794 795
795 796 def test_due_date_distance_in_words
796 797 to_test = { Date.today => 'Due in 0 days',
797 798 Date.today + 1 => 'Due in 1 day',
798 799 Date.today + 100 => 'Due in about 3 months',
799 800 Date.today + 20000 => 'Due in over 54 years',
800 801 Date.today - 1 => '1 day late',
801 802 Date.today - 100 => 'about 3 months late',
802 803 Date.today - 20000 => 'over 54 years late',
803 804 }
804 805 ::I18n.locale = :en
805 806 to_test.each do |date, expected|
806 807 assert_equal expected, due_date_distance_in_words(date)
807 808 end
808 809 end
809 810
810 811 def test_avatar
811 812 # turn on avatars
812 813 Setting.gravatar_enabled = '1'
813 814 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
814 815 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
815 816 assert_nil avatar('jsmith')
816 817 assert_nil avatar(nil)
817 818
818 819 # turn off avatars
819 820 Setting.gravatar_enabled = '0'
820 821 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
821 822 end
822 823
823 824 def test_link_to_user
824 825 user = User.find(2)
825 826 t = link_to_user(user)
826 827 assert_equal "<a href=\"/users/2\">#{ user.name }</a>", t
827 828 end
828 829
829 830 def test_link_to_user_should_not_link_to_locked_user
830 831 user = User.find(5)
831 832 assert user.locked?
832 833 t = link_to_user(user)
833 834 assert_equal user.name, t
834 835 end
835 836
836 837 def test_link_to_user_should_not_link_to_anonymous
837 838 user = User.anonymous
838 839 assert user.anonymous?
839 840 t = link_to_user(user)
840 841 assert_equal ::I18n.t(:label_user_anonymous), t
841 842 end
842 843
843 844 def test_link_to_project
844 845 project = Project.find(1)
845 846 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
846 847 link_to_project(project)
847 848 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
848 849 link_to_project(project, :action => 'settings')
849 850 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
850 851 link_to_project(project, {:only_path => false, :jump => 'blah'})
851 852 assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
852 853 link_to_project(project, {:action => 'settings'}, :class => "project")
853 854 end
854 855
855 856 def test_principals_options_for_select_with_users
856 857 users = [User.find(2), User.find(4)]
857 858 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>),
858 859 principals_options_for_select(users)
859 860 end
860 861
861 862 def test_principals_options_for_select_with_selected
862 863 users = [User.find(2), User.find(4)]
863 864 assert_equal %(<option value="2">John Smith</option><option value="4" selected="selected">Robert Hill</option>),
864 865 principals_options_for_select(users, User.find(4))
865 866 end
866 867
867 868 def test_principals_options_for_select_with_users_and_groups
868 869 users = [User.find(2), Group.find(11), User.find(4), Group.find(10)]
869 870 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>) +
870 871 %(<optgroup label="Groups"><option value="10">A Team</option><option value="11">B Team</option></optgroup>),
871 872 principals_options_for_select(users)
872 873 end
873 874
874 875 def test_principals_options_for_select_with_empty_collection
875 876 assert_equal '', principals_options_for_select([])
876 877 end
877 878 end
General Comments 0
You need to be logged in to leave comments. Login now