##// END OF EJS Templates
Fixed attachment fixture (should be attached to issue 3 because one of its journals references it), r13937....
Jean-Philippe Lang -
r13560:b50fa8fec19b
parent child
Show More
@@ -1,269 +1,269
1 1 ---
2 2 attachments_001:
3 3 created_on: 2006-07-19 21:07:27 +02:00
4 4 downloads: 0
5 5 content_type: text/plain
6 6 disk_filename: 060719210727_error281.txt
7 7 disk_directory: "2006/07"
8 8 container_id: 3
9 9 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
10 10 id: 1
11 11 container_type: Issue
12 12 filesize: 28
13 13 filename: error281.txt
14 14 author_id: 2
15 15 attachments_002:
16 16 created_on: 2007-01-27 15:08:27 +01:00
17 17 downloads: 0
18 18 content_type: text/plain
19 19 disk_filename: 060719210727_document.txt
20 20 disk_directory: "2006/07"
21 21 container_id: 1
22 22 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
23 23 id: 2
24 24 container_type: Document
25 25 filesize: 28
26 26 filename: document.txt
27 27 author_id: 2
28 28 attachments_003:
29 29 created_on: 2006-07-19 21:07:27 +02:00
30 30 downloads: 0
31 31 content_type: image/gif
32 32 disk_filename: 060719210727_logo.gif
33 33 disk_directory: "2006/07"
34 34 container_id: 4
35 35 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
36 36 id: 3
37 37 container_type: WikiPage
38 38 filesize: 280
39 39 filename: logo.gif
40 40 description: This is a logo
41 41 author_id: 2
42 42 attachments_004:
43 43 created_on: 2006-07-19 21:07:27 +02:00
44 44 container_type: Issue
45 container_id: 3
45 container_id: 2
46 46 downloads: 0
47 47 disk_filename: 060719210727_source.rb
48 48 disk_directory: "2006/07"
49 49 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
50 50 id: 4
51 51 filesize: 153
52 52 filename: source.rb
53 53 author_id: 2
54 54 description: This is a Ruby source file
55 55 content_type: application/x-ruby
56 56 attachments_005:
57 57 created_on: 2006-07-19 21:07:27 +02:00
58 58 container_type: Issue
59 59 container_id: 3
60 60 downloads: 0
61 61 disk_filename: 060719210727_changeset_iso8859-1.diff
62 62 disk_directory: "2006/07"
63 63 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
64 64 id: 5
65 65 filesize: 687
66 66 filename: changeset_iso8859-1.diff
67 67 author_id: 2
68 68 content_type: text/x-diff
69 69 attachments_006:
70 70 created_on: 2006-07-19 21:07:27 +02:00
71 71 container_type: Issue
72 72 container_id: 3
73 73 downloads: 0
74 74 disk_filename: 060719210727_archive.zip
75 75 disk_directory: "2006/07"
76 76 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
77 77 id: 6
78 78 filesize: 157
79 79 filename: archive.zip
80 80 author_id: 2
81 81 content_type: application/octet-stream
82 82 attachments_007:
83 83 created_on: 2006-07-19 21:07:27 +02:00
84 84 container_type: Issue
85 85 container_id: 4
86 86 downloads: 0
87 87 disk_filename: 060719210727_archive.zip
88 88 disk_directory: "2006/07"
89 89 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
90 90 id: 7
91 91 filesize: 157
92 92 filename: archive.zip
93 93 author_id: 1
94 94 content_type: application/octet-stream
95 95 attachments_008:
96 96 created_on: 2006-07-19 21:07:27 +02:00
97 97 container_type: Project
98 98 container_id: 1
99 99 downloads: 0
100 100 disk_filename: 060719210727_project_file.zip
101 101 disk_directory: "2006/07"
102 102 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
103 103 id: 8
104 104 filesize: 320
105 105 filename: project_file.zip
106 106 author_id: 2
107 107 content_type: application/octet-stream
108 108 attachments_009:
109 109 created_on: 2006-07-19 21:07:27 +02:00
110 110 container_type: Version
111 111 container_id: 1
112 112 downloads: 0
113 113 disk_filename: 060719210727_archive.zip
114 114 disk_directory: "2006/07"
115 115 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
116 116 id: 9
117 117 filesize: 452
118 118 filename: version_file.zip
119 119 author_id: 2
120 120 content_type: application/octet-stream
121 121 attachments_010:
122 122 created_on: 2006-07-19 21:07:27 +02:00
123 123 container_type: Issue
124 124 container_id: 2
125 125 downloads: 0
126 126 disk_filename: 060719210727_picture.jpg
127 127 disk_directory: "2006/07"
128 128 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
129 129 id: 10
130 130 filesize: 452
131 131 filename: picture.jpg
132 132 author_id: 2
133 133 content_type: image/jpeg
134 134 attachments_011:
135 135 created_on: 2007-02-12 15:08:27 +01:00
136 136 container_type: Document
137 137 container_id: 1
138 138 downloads: 0
139 139 disk_filename: 060719210727_picture.jpg
140 140 disk_directory: "2006/07"
141 141 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
142 142 id: 11
143 143 filesize: 452
144 144 filename: picture.jpg
145 145 author_id: 2
146 146 content_type: image/jpeg
147 147 attachments_012:
148 148 created_on: 2006-07-19 21:07:27 +02:00
149 149 container_type: Version
150 150 container_id: 1
151 151 downloads: 0
152 152 disk_filename: 060719210727_version_file.zip
153 153 disk_directory: "2006/07"
154 154 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
155 155 id: 12
156 156 filesize: 452
157 157 filename: version_file.zip
158 158 author_id: 2
159 159 content_type: application/octet-stream
160 160 attachments_013:
161 161 created_on: 2006-07-19 21:07:27 +02:00
162 162 container_type: Message
163 163 container_id: 1
164 164 downloads: 0
165 165 disk_filename: 060719210727_foo.zip
166 166 disk_directory: "2006/07"
167 167 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
168 168 id: 13
169 169 filesize: 452
170 170 filename: foo.zip
171 171 author_id: 2
172 172 content_type: application/octet-stream
173 173 attachments_014:
174 174 created_on: 2006-07-19 21:07:27 +02:00
175 175 container_type: Issue
176 176 container_id: 3
177 177 downloads: 0
178 178 disk_filename: 060719210727_changeset_utf8.diff
179 179 disk_directory: "2006/07"
180 180 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
181 181 id: 14
182 182 filesize: 687
183 183 filename: changeset_utf8.diff
184 184 author_id: 2
185 185 content_type: text/x-diff
186 186 attachments_015:
187 187 id: 15
188 188 created_on: 2010-07-19 21:07:27 +02:00
189 189 container_type: Issue
190 190 container_id: 14
191 191 downloads: 0
192 192 disk_filename: 060719210727_changeset_utf8.diff
193 193 disk_directory: "2006/07"
194 194 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
195 195 filesize: 687
196 196 filename: private.diff
197 197 author_id: 2
198 198 content_type: text/x-diff
199 199 description: attachement of a private issue
200 200 attachments_016:
201 201 content_type: image/png
202 202 downloads: 0
203 203 created_on: 2010-11-23 16:14:50 +09:00
204 204 disk_filename: 101123161450_testfile_1.png
205 205 disk_directory: "2010/11"
206 206 container_id: 14
207 207 digest: 8e0294de2441577c529f170b6fb8f638
208 208 id: 16
209 209 container_type: Issue
210 210 description: ""
211 211 filename: testfile.png
212 212 filesize: 2654
213 213 author_id: 2
214 214 attachments_017:
215 215 content_type: image/png
216 216 downloads: 0
217 217 created_on: 2010-12-23 16:14:50 +09:00
218 218 disk_filename: 101223161450_testfile_2.png
219 219 disk_directory: "2010/12"
220 220 container_id: 14
221 221 digest: 6bc2963e8d7ea0d3e68d12d1fba3d6ca
222 222 id: 17
223 223 container_type: Issue
224 224 description: ""
225 225 filename: testfile.PNG
226 226 filesize: 3582
227 227 author_id: 2
228 228 attachments_018:
229 229 content_type: image/png
230 230 downloads: 0
231 231 created_on: 2011-01-23 16:14:50 +09:00
232 232 disk_filename: 101123161450_testfile_1.png
233 233 disk_directory: "2010/11"
234 234 container_id: 14
235 235 digest: 8e0294de2441577c529f170b6fb8f638
236 236 id: 18
237 237 container_type: Issue
238 238 description: ""
239 239 filename: testγƒ†γ‚Ήγƒˆ.png
240 240 filesize: 2654
241 241 author_id: 2
242 242 attachments_019:
243 243 content_type: image/png
244 244 downloads: 0
245 245 created_on: 2011-02-23 16:14:50 +09:00
246 246 disk_filename: 101223161450_testfile_2.png
247 247 disk_directory: "2010/12"
248 248 container_id: 14
249 249 digest: 6bc2963e8d7ea0d3e68d12d1fba3d6ca
250 250 id: 19
251 251 container_type: Issue
252 252 description: ""
253 253 filename: Testγƒ†γ‚Ήγƒˆ.PNG
254 254 filesize: 3582
255 255 author_id: 2
256 256 attachments_020:
257 257 content_type: text/plain
258 258 downloads: 0
259 259 created_on: 2012-05-12 16:14:50 +09:00
260 260 disk_filename: 120512161450_root_attachment.txt
261 261 disk_directory:
262 262 container_id: 14
263 263 digest: b0fe2abdb2599743d554a61d7da7ff74
264 264 id: 20
265 265 container_type: Issue
266 266 description: ""
267 267 filename: root_attachment.txt
268 268 filesize: 54
269 269 author_id: 2
@@ -1,458 +1,458
1 1 # encoding: utf-8
2 2 #
3 3 # Redmine - project management software
4 4 # Copyright (C) 2006-2015 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 AttachmentsControllerTest < ActionController::TestCase
23 23 fixtures :users, :projects, :roles, :members, :member_roles,
24 24 :enabled_modules, :issues, :trackers, :attachments,
25 25 :versions, :wiki_pages, :wikis, :documents
26 26
27 27 def setup
28 28 User.current = nil
29 29 set_fixtures_attachments_directory
30 30 end
31 31
32 32 def teardown
33 33 set_tmp_attachments_directory
34 34 end
35 35
36 36 def test_show_diff
37 37 ['inline', 'sbs'].each do |dt|
38 38 # 060719210727_changeset_utf8.diff
39 39 get :show, :id => 14, :type => dt
40 40 assert_response :success
41 41 assert_template 'diff'
42 42 assert_equal 'text/html', @response.content_type
43 43 assert_select 'th.filename', :text => /issues_controller.rb\t\(rΓ©vision 1484\)/
44 44 assert_select 'td.line-code', :text => /Demande créée avec succès/
45 45 end
46 46 set_tmp_attachments_directory
47 47 end
48 48
49 49 def test_show_diff_replace_cannot_convert_content
50 50 with_settings :repositories_encodings => 'UTF-8' do
51 51 ['inline', 'sbs'].each do |dt|
52 52 # 060719210727_changeset_iso8859-1.diff
53 53 get :show, :id => 5, :type => dt
54 54 assert_response :success
55 55 assert_template 'diff'
56 56 assert_equal 'text/html', @response.content_type
57 57 assert_select 'th.filename', :text => /issues_controller.rb\t\(r\?vision 1484\)/
58 58 assert_select 'td.line-code', :text => /Demande cr\?\?e avec succ\?s/
59 59 end
60 60 end
61 61 set_tmp_attachments_directory
62 62 end
63 63
64 64 def test_show_diff_latin_1
65 65 with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
66 66 ['inline', 'sbs'].each do |dt|
67 67 # 060719210727_changeset_iso8859-1.diff
68 68 get :show, :id => 5, :type => dt
69 69 assert_response :success
70 70 assert_template 'diff'
71 71 assert_equal 'text/html', @response.content_type
72 72 assert_select 'th.filename', :text => /issues_controller.rb\t\(rΓ©vision 1484\)/
73 73 assert_select 'td.line-code', :text => /Demande créée avec succès/
74 74 end
75 75 end
76 76 set_tmp_attachments_directory
77 77 end
78 78
79 79 def test_save_diff_type
80 80 user1 = User.find(1)
81 81 user1.pref[:diff_type] = nil
82 82 user1.preference.save
83 83 user = User.find(1)
84 84 assert_nil user.pref[:diff_type]
85 85
86 86 @request.session[:user_id] = 1 # admin
87 87 get :show, :id => 5
88 88 assert_response :success
89 89 assert_template 'diff'
90 90 user.reload
91 91 assert_equal "inline", user.pref[:diff_type]
92 92 get :show, :id => 5, :type => 'sbs'
93 93 assert_response :success
94 94 assert_template 'diff'
95 95 user.reload
96 96 assert_equal "sbs", user.pref[:diff_type]
97 97 end
98 98
99 99 def test_diff_show_filename_in_mercurial_export
100 100 set_tmp_attachments_directory
101 101 a = Attachment.new(:container => Issue.find(1),
102 102 :file => uploaded_test_file("hg-export.diff", "text/plain"),
103 103 :author => User.find(1))
104 104 assert a.save
105 105 assert_equal 'hg-export.diff', a.filename
106 106
107 107 get :show, :id => a.id, :type => 'inline'
108 108 assert_response :success
109 109 assert_template 'diff'
110 110 assert_equal 'text/html', @response.content_type
111 111 assert_select 'th.filename', :text => 'test1.txt'
112 112 end
113 113
114 114 def test_show_text_file
115 115 get :show, :id => 4
116 116 assert_response :success
117 117 assert_template 'file'
118 118 assert_equal 'text/html', @response.content_type
119 119 set_tmp_attachments_directory
120 120 end
121 121
122 122 def test_show_text_file_utf_8
123 123 set_tmp_attachments_directory
124 124 a = Attachment.new(:container => Issue.find(1),
125 125 :file => uploaded_test_file("japanese-utf-8.txt", "text/plain"),
126 126 :author => User.find(1))
127 127 assert a.save
128 128 assert_equal 'japanese-utf-8.txt', a.filename
129 129
130 130 str_japanese = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e".force_encoding('UTF-8')
131 131
132 132 get :show, :id => a.id
133 133 assert_response :success
134 134 assert_template 'file'
135 135 assert_equal 'text/html', @response.content_type
136 136 assert_select 'tr#L1' do
137 137 assert_select 'th.line-num', :text => '1'
138 138 assert_select 'td', :text => /#{str_japanese}/
139 139 end
140 140 end
141 141
142 142 def test_show_text_file_replace_cannot_convert_content
143 143 set_tmp_attachments_directory
144 144 with_settings :repositories_encodings => 'UTF-8' do
145 145 a = Attachment.new(:container => Issue.find(1),
146 146 :file => uploaded_test_file("iso8859-1.txt", "text/plain"),
147 147 :author => User.find(1))
148 148 assert a.save
149 149 assert_equal 'iso8859-1.txt', a.filename
150 150
151 151 get :show, :id => a.id
152 152 assert_response :success
153 153 assert_template 'file'
154 154 assert_equal 'text/html', @response.content_type
155 155 assert_select 'tr#L7' do
156 156 assert_select 'th.line-num', :text => '7'
157 157 assert_select 'td', :text => /Demande cr\?\?e avec succ\?s/
158 158 end
159 159 end
160 160 end
161 161
162 162 def test_show_text_file_latin_1
163 163 set_tmp_attachments_directory
164 164 with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
165 165 a = Attachment.new(:container => Issue.find(1),
166 166 :file => uploaded_test_file("iso8859-1.txt", "text/plain"),
167 167 :author => User.find(1))
168 168 assert a.save
169 169 assert_equal 'iso8859-1.txt', a.filename
170 170
171 171 get :show, :id => a.id
172 172 assert_response :success
173 173 assert_template 'file'
174 174 assert_equal 'text/html', @response.content_type
175 175 assert_select 'tr#L7' do
176 176 assert_select 'th.line-num', :text => '7'
177 177 assert_select 'td', :text => /Demande créée avec succès/
178 178 end
179 179 end
180 180 end
181 181
182 182 def test_show_text_file_should_send_if_too_big
183 183 with_settings :file_max_size_displayed => 512 do
184 184 Attachment.find(4).update_attribute :filesize, 754.kilobyte
185 185 get :show, :id => 4
186 186 assert_response :success
187 187 assert_equal 'application/x-ruby', @response.content_type
188 188 end
189 189 set_tmp_attachments_directory
190 190 end
191 191
192 192 def test_show_other
193 193 get :show, :id => 6
194 194 assert_response :success
195 195 assert_equal 'application/octet-stream', @response.content_type
196 196 set_tmp_attachments_directory
197 197 end
198 198
199 199 def test_show_file_from_private_issue_without_permission
200 200 get :show, :id => 15
201 201 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2F15'
202 202 set_tmp_attachments_directory
203 203 end
204 204
205 205 def test_show_file_from_private_issue_with_permission
206 206 @request.session[:user_id] = 2
207 207 get :show, :id => 15
208 208 assert_response :success
209 209 assert_select 'h2', :text => /private.diff/
210 210 set_tmp_attachments_directory
211 211 end
212 212
213 213 def test_show_file_without_container_should_be_allowed_to_author
214 214 set_tmp_attachments_directory
215 215 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
216 216
217 217 @request.session[:user_id] = 2
218 218 get :show, :id => attachment.id
219 219 assert_response 200
220 220 end
221 221
222 222 def test_show_file_without_container_should_be_denied_to_other_users
223 223 set_tmp_attachments_directory
224 224 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
225 225
226 226 @request.session[:user_id] = 3
227 227 get :show, :id => attachment.id
228 228 assert_response 403
229 229 end
230 230
231 231 def test_show_invalid_should_respond_with_404
232 232 get :show, :id => 999
233 233 assert_response 404
234 234 end
235 235
236 236 def test_download_text_file
237 237 get :download, :id => 4
238 238 assert_response :success
239 239 assert_equal 'application/x-ruby', @response.content_type
240 240 etag = @response.etag
241 241 assert_not_nil etag
242 242
243 243 @request.env["HTTP_IF_NONE_MATCH"] = etag
244 244 get :download, :id => 4
245 245 assert_response 304
246 246
247 247 set_tmp_attachments_directory
248 248 end
249 249
250 250 def test_download_version_file_with_issue_tracking_disabled
251 251 Project.find(1).disable_module! :issue_tracking
252 252 get :download, :id => 9
253 253 assert_response :success
254 254 end
255 255
256 256 def test_download_should_assign_content_type_if_blank
257 257 Attachment.find(4).update_attribute(:content_type, '')
258 258
259 259 get :download, :id => 4
260 260 assert_response :success
261 261 assert_equal 'text/x-ruby', @response.content_type
262 262 set_tmp_attachments_directory
263 263 end
264 264
265 265 def test_download_missing_file
266 266 get :download, :id => 2
267 267 assert_response 404
268 268 set_tmp_attachments_directory
269 269 end
270 270
271 271 def test_download_should_be_denied_without_permission
272 272 get :download, :id => 7
273 273 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2Fdownload%2F7'
274 274 set_tmp_attachments_directory
275 275 end
276 276
277 277 if convert_installed?
278 278 def test_thumbnail
279 279 Attachment.clear_thumbnails
280 280 @request.session[:user_id] = 2
281 281 get :thumbnail, :id => 16
282 282 assert_response :success
283 283 assert_equal 'image/png', response.content_type
284 284
285 285 etag = @response.etag
286 286 assert_not_nil etag
287 287
288 288 @request.env["HTTP_IF_NONE_MATCH"] = etag
289 289 get :thumbnail, :id => 16
290 290 assert_response 304
291 291 end
292 292
293 293 def test_thumbnail_should_not_exceed_maximum_size
294 294 Redmine::Thumbnail.expects(:generate).with {|source, target, size| size == 800}
295 295
296 296 @request.session[:user_id] = 2
297 297 get :thumbnail, :id => 16, :size => 2000
298 298 end
299 299
300 300 def test_thumbnail_should_round_size
301 301 Redmine::Thumbnail.expects(:generate).with {|source, target, size| size == 250}
302 302
303 303 @request.session[:user_id] = 2
304 304 get :thumbnail, :id => 16, :size => 260
305 305 end
306 306
307 307 def test_thumbnail_should_return_404_for_non_image_attachment
308 308 @request.session[:user_id] = 2
309 309
310 310 get :thumbnail, :id => 15
311 311 assert_response 404
312 312 end
313 313
314 314 def test_thumbnail_should_return_404_if_thumbnail_generation_failed
315 315 Attachment.any_instance.stubs(:thumbnail).returns(nil)
316 316 @request.session[:user_id] = 2
317 317
318 318 get :thumbnail, :id => 16
319 319 assert_response 404
320 320 end
321 321
322 322 def test_thumbnail_should_be_denied_without_permission
323 323 get :thumbnail, :id => 16
324 324 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2Fthumbnail%2F16'
325 325 end
326 326 else
327 327 puts '(ImageMagick convert not available)'
328 328 end
329 329
330 330 def test_edit
331 331 @request.session[:user_id] = 2
332 get :edit, :object_type => 'issues', :object_id => '3'
332 get :edit, :object_type => 'issues', :object_id => '2'
333 333 assert_response :success
334 334 assert_template 'edit'
335 335
336 container = Issue.find(3)
336 container = Issue.find(2)
337 337 assert_equal container, assigns(:container)
338 338 assert_equal container.attachments.size, assigns(:attachments).size
339 339
340 assert_select 'form[action=?]', '/attachments/issues/3' do
340 assert_select 'form[action=?]', '/attachments/issues/2' do
341 341 assert_select 'tr#attachment-4' do
342 342 assert_select 'input[name=?][value=?]', 'attachments[4][filename]', 'source.rb'
343 343 assert_select 'input[name=?][value=?]', 'attachments[4][description]', 'This is a Ruby source file'
344 344 end
345 345 end
346 346 end
347 347
348 348 def test_edit_invalid_container_class_should_return_404
349 349 get :edit, :object_type => 'nuggets', :object_id => '3'
350 350 assert_response 404
351 351 end
352 352
353 353 def test_edit_invalid_object_should_return_404
354 354 get :edit, :object_type => 'issues', :object_id => '999'
355 355 assert_response 404
356 356 end
357 357
358 358 def test_edit_for_object_that_is_not_visible_should_return_403
359 359 get :edit, :object_type => 'issues', :object_id => '4'
360 360 assert_response 403
361 361 end
362 362
363 363 def test_update
364 364 @request.session[:user_id] = 2
365 patch :update, :object_type => 'issues', :object_id => '3', :attachments => {
365 patch :update, :object_type => 'issues', :object_id => '2', :attachments => {
366 366 '1' => {:filename => 'newname.text', :description => ''},
367 367 '4' => {:filename => 'newname.rb', :description => 'Renamed'},
368 368 }
369 369
370 370 assert_response 302
371 371 attachment = Attachment.find(4)
372 372 assert_equal 'newname.rb', attachment.filename
373 373 assert_equal 'Renamed', attachment.description
374 374 end
375 375
376 376 def test_update_with_failure
377 377 @request.session[:user_id] = 2
378 378 patch :update, :object_type => 'issues', :object_id => '3', :attachments => {
379 379 '1' => {:filename => '', :description => ''},
380 380 '4' => {:filename => 'newname.rb', :description => 'Renamed'},
381 381 }
382 382
383 383 assert_response :success
384 384 assert_template 'edit'
385 385 assert_select_error /file cannot be blank/i
386 386
387 387 # The other attachment should not be updated
388 388 attachment = Attachment.find(4)
389 389 assert_equal 'source.rb', attachment.filename
390 390 assert_equal 'This is a Ruby source file', attachment.description
391 391 end
392 392
393 393 def test_destroy_issue_attachment
394 394 set_tmp_attachments_directory
395 395 issue = Issue.find(3)
396 396 @request.session[:user_id] = 2
397 397
398 398 assert_difference 'issue.attachments.count', -1 do
399 399 assert_difference 'Journal.count' do
400 400 delete :destroy, :id => 1
401 401 assert_redirected_to '/projects/ecookbook'
402 402 end
403 403 end
404 404 assert_nil Attachment.find_by_id(1)
405 405 j = Journal.order('id DESC').first
406 406 assert_equal issue, j.journalized
407 407 assert_equal 'attachment', j.details.first.property
408 408 assert_equal '1', j.details.first.prop_key
409 409 assert_equal 'error281.txt', j.details.first.old_value
410 410 assert_equal User.find(2), j.user
411 411 end
412 412
413 413 def test_destroy_wiki_page_attachment
414 414 set_tmp_attachments_directory
415 415 @request.session[:user_id] = 2
416 416 assert_difference 'Attachment.count', -1 do
417 417 delete :destroy, :id => 3
418 418 assert_response 302
419 419 end
420 420 end
421 421
422 422 def test_destroy_project_attachment
423 423 set_tmp_attachments_directory
424 424 @request.session[:user_id] = 2
425 425 assert_difference 'Attachment.count', -1 do
426 426 delete :destroy, :id => 8
427 427 assert_response 302
428 428 end
429 429 end
430 430
431 431 def test_destroy_version_attachment
432 432 set_tmp_attachments_directory
433 433 @request.session[:user_id] = 2
434 434 assert_difference 'Attachment.count', -1 do
435 435 delete :destroy, :id => 9
436 436 assert_response 302
437 437 end
438 438 end
439 439
440 440 def test_destroy_version_attachment_with_issue_tracking_disabled
441 441 Project.find(1).disable_module! :issue_tracking
442 442 set_tmp_attachments_directory
443 443 @request.session[:user_id] = 2
444 444 assert_difference 'Attachment.count', -1 do
445 445 delete :destroy, :id => 9
446 446 assert_response 302
447 447 end
448 448 end
449 449
450 450 def test_destroy_without_permission
451 451 set_tmp_attachments_directory
452 452 assert_no_difference 'Attachment.count' do
453 453 delete :destroy, :id => 3
454 454 end
455 455 assert_response 302
456 456 assert Attachment.find_by_id(3)
457 457 end
458 458 end
@@ -1,650 +1,650
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2015 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 Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base
21 21 fixtures :projects,
22 22 :users,
23 23 :roles,
24 24 :members,
25 25 :member_roles,
26 26 :issues,
27 27 :issue_statuses,
28 28 :issue_relations,
29 29 :versions,
30 30 :trackers,
31 31 :projects_trackers,
32 32 :issue_categories,
33 33 :enabled_modules,
34 34 :enumerations,
35 35 :attachments,
36 36 :workflows,
37 37 :custom_fields,
38 38 :custom_values,
39 39 :custom_fields_projects,
40 40 :custom_fields_trackers,
41 41 :time_entries,
42 42 :journals,
43 43 :journal_details,
44 44 :queries,
45 45 :attachments
46 46
47 47 test "GET /issues.xml should contain metadata" do
48 48 get '/issues.xml'
49 49 assert_select 'issues[type=array][total_count=?][limit="25"][offset="0"]',
50 50 assigns(:issue_count).to_s
51 51 end
52 52
53 53 test "GET /issues.xml with nometa param should not contain metadata" do
54 54 get '/issues.xml?nometa=1'
55 55 assert_select 'issues[type=array]:not([total_count]):not([limit]):not([offset])'
56 56 end
57 57
58 58 test "GET /issues.xml with nometa header should not contain metadata" do
59 59 get '/issues.xml', {}, {'X-Redmine-Nometa' => '1'}
60 60 assert_select 'issues[type=array]:not([total_count]):not([limit]):not([offset])'
61 61 end
62 62
63 63 test "GET /issues.xml with offset and limit" do
64 64 get '/issues.xml?offset=2&limit=3'
65 65
66 66 assert_equal 3, assigns(:limit)
67 67 assert_equal 2, assigns(:offset)
68 68 assert_select 'issues issue', 3
69 69 end
70 70
71 71 test "GET /issues.xml with relations" do
72 72 get '/issues.xml?include=relations'
73 73
74 74 assert_response :success
75 75 assert_equal 'application/xml', @response.content_type
76 76
77 77 assert_select 'issue id', :text => '3' do
78 78 assert_select '~ relations relation', 1
79 79 assert_select '~ relations relation[id="2"][issue_id="2"][issue_to_id="3"][relation_type=relates]'
80 80 end
81 81
82 82 assert_select 'issue id', :text => '1' do
83 83 assert_select '~ relations'
84 84 assert_select '~ relations relation', 0
85 85 end
86 86 end
87 87
88 88 test "GET /issues.xml with invalid query params" do
89 89 get '/issues.xml', {:f => ['start_date'], :op => {:start_date => '='}}
90 90
91 91 assert_response :unprocessable_entity
92 92 assert_equal 'application/xml', @response.content_type
93 93 assert_select 'errors error', :text => "Start date cannot be blank"
94 94 end
95 95
96 96 test "GET /issues.xml with custom field filter" do
97 97 get '/issues.xml',
98 98 {:set_filter => 1, :f => ['cf_1'], :op => {:cf_1 => '='}, :v => {:cf_1 => ['MySQL']}}
99 99
100 100 expected_ids = Issue.visible.
101 101 joins(:custom_values).
102 102 where(:custom_values => {:custom_field_id => 1, :value => 'MySQL'}).map(&:id)
103 103 assert expected_ids.any?
104 104
105 105 assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
106 106 ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
107 107 end
108 108 end
109 109
110 110 test "GET /issues.xml with custom field filter (shorthand method)" do
111 111 get '/issues.xml', {:cf_1 => 'MySQL'}
112 112
113 113 expected_ids = Issue.visible.
114 114 joins(:custom_values).
115 115 where(:custom_values => {:custom_field_id => 1, :value => 'MySQL'}).map(&:id)
116 116 assert expected_ids.any?
117 117
118 118 assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
119 119 ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
120 120 end
121 121 end
122 122
123 123 def test_index_should_include_issue_attributes
124 124 get '/issues.xml'
125 125 assert_select 'issues>issue>is_private', :text => 'false'
126 126 end
127 127
128 128 def test_index_should_allow_timestamp_filtering
129 129 Issue.delete_all
130 130 Issue.generate!(:subject => '1').update_column(:updated_on, Time.parse("2014-01-02T10:25:00Z"))
131 131 Issue.generate!(:subject => '2').update_column(:updated_on, Time.parse("2014-01-02T12:13:00Z"))
132 132
133 133 get '/issues.xml',
134 134 {:set_filter => 1, :f => ['updated_on'], :op => {:updated_on => '<='},
135 135 :v => {:updated_on => ['2014-01-02T12:00:00Z']}}
136 136 assert_select 'issues>issue', :count => 1
137 137 assert_select 'issues>issue>subject', :text => '1'
138 138
139 139 get '/issues.xml',
140 140 {:set_filter => 1, :f => ['updated_on'], :op => {:updated_on => '>='},
141 141 :v => {:updated_on => ['2014-01-02T12:00:00Z']}}
142 142 assert_select 'issues>issue', :count => 1
143 143 assert_select 'issues>issue>subject', :text => '2'
144 144
145 145 get '/issues.xml',
146 146 {:set_filter => 1, :f => ['updated_on'], :op => {:updated_on => '>='},
147 147 :v => {:updated_on => ['2014-01-02T08:00:00Z']}}
148 148 assert_select 'issues>issue', :count => 2
149 149 end
150 150
151 151 test "GET /issues.xml with filter" do
152 152 get '/issues.xml?status_id=5'
153 153
154 154 expected_ids = Issue.visible.where(:status_id => 5).map(&:id)
155 155 assert expected_ids.any?
156 156
157 157 assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
158 158 ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
159 159 end
160 160 end
161 161
162 162 test "GET /issues.json with filter" do
163 163 get '/issues.json?status_id=5'
164 164
165 165 json = ActiveSupport::JSON.decode(response.body)
166 166 status_ids_used = json['issues'].collect {|j| j['status']['id'] }
167 167 assert_equal 3, status_ids_used.length
168 168 assert status_ids_used.all? {|id| id == 5 }
169 169 end
170 170
171 171 test "GET /issues/:id.xml with journals" do
172 172 get '/issues/1.xml?include=journals'
173 173
174 174 assert_select 'issue journals[type=array]' do
175 175 assert_select 'journal[id="1"]' do
176 176 assert_select 'details[type=array]' do
177 177 assert_select 'detail[name=status_id]' do
178 178 assert_select 'old_value', :text => '1'
179 179 assert_select 'new_value', :text => '2'
180 180 end
181 181 end
182 182 end
183 183 end
184 184 end
185 185
186 186 test "GET /issues/:id.xml with custom fields" do
187 187 get '/issues/3.xml'
188 188
189 189 assert_select 'issue custom_fields[type=array]' do
190 190 assert_select 'custom_field[id="1"]' do
191 191 assert_select 'value', :text => 'MySQL'
192 192 end
193 193 end
194 194 assert_nothing_raised do
195 195 Hash.from_xml(response.body).to_xml
196 196 end
197 197 end
198 198
199 199 test "GET /issues/:id.xml with multi custom fields" do
200 200 field = CustomField.find(1)
201 201 field.update_attribute :multiple, true
202 202 issue = Issue.find(3)
203 203 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
204 204 issue.save!
205 205
206 206 get '/issues/3.xml'
207 207 assert_response :success
208 208
209 209 assert_select 'issue custom_fields[type=array]' do
210 210 assert_select 'custom_field[id="1"]' do
211 211 assert_select 'value[type=array] value', 2
212 212 end
213 213 end
214 214 xml = Hash.from_xml(response.body)
215 215 custom_fields = xml['issue']['custom_fields']
216 216 assert_kind_of Array, custom_fields
217 217 field = custom_fields.detect {|f| f['id'] == '1'}
218 218 assert_kind_of Hash, field
219 219 assert_equal ['MySQL', 'Oracle'], field['value'].sort
220 220 end
221 221
222 222 test "GET /issues/:id.json with multi custom fields" do
223 223 field = CustomField.find(1)
224 224 field.update_attribute :multiple, true
225 225 issue = Issue.find(3)
226 226 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
227 227 issue.save!
228 228
229 229 get '/issues/3.json'
230 230 assert_response :success
231 231
232 232 json = ActiveSupport::JSON.decode(response.body)
233 233 custom_fields = json['issue']['custom_fields']
234 234 assert_kind_of Array, custom_fields
235 235 field = custom_fields.detect {|f| f['id'] == 1}
236 236 assert_kind_of Hash, field
237 237 assert_equal ['MySQL', 'Oracle'], field['value'].sort
238 238 end
239 239
240 240 test "GET /issues/:id.xml with empty value for multi custom field" do
241 241 field = CustomField.find(1)
242 242 field.update_attribute :multiple, true
243 243 issue = Issue.find(3)
244 244 issue.custom_field_values = {1 => ['']}
245 245 issue.save!
246 246
247 247 get '/issues/3.xml'
248 248
249 249 assert_select 'issue custom_fields[type=array]' do
250 250 assert_select 'custom_field[id="1"]' do
251 251 assert_select 'value[type=array]:empty'
252 252 end
253 253 end
254 254 xml = Hash.from_xml(response.body)
255 255 custom_fields = xml['issue']['custom_fields']
256 256 assert_kind_of Array, custom_fields
257 257 field = custom_fields.detect {|f| f['id'] == '1'}
258 258 assert_kind_of Hash, field
259 259 assert_equal [], field['value']
260 260 end
261 261
262 262 test "GET /issues/:id.json with empty value for multi custom field" do
263 263 field = CustomField.find(1)
264 264 field.update_attribute :multiple, true
265 265 issue = Issue.find(3)
266 266 issue.custom_field_values = {1 => ['']}
267 267 issue.save!
268 268
269 269 get '/issues/3.json'
270 270 assert_response :success
271 271 json = ActiveSupport::JSON.decode(response.body)
272 272 custom_fields = json['issue']['custom_fields']
273 273 assert_kind_of Array, custom_fields
274 274 field = custom_fields.detect {|f| f['id'] == 1}
275 275 assert_kind_of Hash, field
276 276 assert_equal [], field['value'].sort
277 277 end
278 278
279 279 test "GET /issues/:id.xml with attachments" do
280 280 get '/issues/3.xml?include=attachments'
281 281
282 282 assert_select 'issue attachments[type=array]' do
283 assert_select 'attachment', 5
284 assert_select 'attachment id', :text => '4' do
285 assert_select '~ filename', :text => 'source.rb'
286 assert_select '~ content_url', :text => 'http://www.example.com/attachments/download/4/source.rb'
283 assert_select 'attachment', 4
284 assert_select 'attachment id', :text => '1' do
285 assert_select '~ filename', :text => 'error281.txt'
286 assert_select '~ content_url', :text => 'http://www.example.com/attachments/download/1/error281.txt'
287 287 end
288 288 end
289 289 end
290 290
291 291 test "GET /issues/:id.xml with subtasks" do
292 292 issue = Issue.generate_with_descendants!(:project_id => 1)
293 293 get "/issues/#{issue.id}.xml?include=children"
294 294
295 295 assert_select 'issue id', :text => issue.id.to_s do
296 296 assert_select '~ children[type=array] > issue', 2
297 297 assert_select '~ children[type=array] > issue > children', 1
298 298 end
299 299 end
300 300
301 301 test "GET /issues/:id.json with subtasks" do
302 302 issue = Issue.generate_with_descendants!(:project_id => 1)
303 303 get "/issues/#{issue.id}.json?include=children"
304 304
305 305 json = ActiveSupport::JSON.decode(response.body)
306 306 assert_equal 2, json['issue']['children'].size
307 307 assert_equal 1, json['issue']['children'].select {|child| child.key?('children')}.size
308 308 end
309 309
310 310 def test_show_should_include_issue_attributes
311 311 get '/issues/1.xml'
312 312 assert_select 'issue>is_private', :text => 'false'
313 313 end
314 314
315 315 test "GET /issues/:id.xml?include=watchers should include watchers" do
316 316 Watcher.create!(:user_id => 3, :watchable => Issue.find(1))
317 317
318 318 get '/issues/1.xml?include=watchers', {}, credentials('jsmith')
319 319
320 320 assert_response :ok
321 321 assert_equal 'application/xml', response.content_type
322 322 assert_select 'issue' do
323 323 assert_select 'watchers', Issue.find(1).watchers.count
324 324 assert_select 'watchers' do
325 325 assert_select 'user[id="3"]'
326 326 end
327 327 end
328 328 end
329 329
330 330 test "POST /issues.xml should create an issue with the attributes" do
331 331
332 332 payload = <<-XML
333 333 <?xml version="1.0" encoding="UTF-8" ?>
334 334 <issue>
335 335 <project_id>1</project_id>
336 336 <tracker_id>2</tracker_id>
337 337 <status_id>3</status_id>
338 338 <subject>API test</subject>
339 339 </issue>
340 340 XML
341 341
342 342 assert_difference('Issue.count') do
343 343 post '/issues.xml', payload, {"CONTENT_TYPE" => 'application/xml'}.merge(credentials('jsmith'))
344 344 end
345 345 issue = Issue.order('id DESC').first
346 346 assert_equal 1, issue.project_id
347 347 assert_equal 2, issue.tracker_id
348 348 assert_equal 3, issue.status_id
349 349 assert_equal 'API test', issue.subject
350 350
351 351 assert_response :created
352 352 assert_equal 'application/xml', @response.content_type
353 353 assert_select 'issue > id', :text => issue.id.to_s
354 354 end
355 355
356 356 test "POST /issues.xml with watcher_user_ids should create issue with watchers" do
357 357 assert_difference('Issue.count') do
358 358 post '/issues.xml',
359 359 {:issue => {:project_id => 1, :subject => 'Watchers',
360 360 :tracker_id => 2, :status_id => 3, :watcher_user_ids => [3, 1]}}, credentials('jsmith')
361 361 assert_response :created
362 362 end
363 363 issue = Issue.order('id desc').first
364 364 assert_equal 2, issue.watchers.size
365 365 assert_equal [1, 3], issue.watcher_user_ids.sort
366 366 end
367 367
368 368 test "POST /issues.xml with failure should return errors" do
369 369 assert_no_difference('Issue.count') do
370 370 post '/issues.xml', {:issue => {:project_id => 1}}, credentials('jsmith')
371 371 end
372 372
373 373 assert_select 'errors error', :text => "Subject cannot be blank"
374 374 end
375 375
376 376 test "POST /issues.json should create an issue with the attributes" do
377 377
378 378 payload = <<-JSON
379 379 {
380 380 "issue": {
381 381 "project_id": "1",
382 382 "tracker_id": "2",
383 383 "status_id": "3",
384 384 "subject": "API test"
385 385 }
386 386 }
387 387 JSON
388 388
389 389 assert_difference('Issue.count') do
390 390 post '/issues.json', payload, {"CONTENT_TYPE" => 'application/json'}.merge(credentials('jsmith'))
391 391 end
392 392
393 393 issue = Issue.order('id DESC').first
394 394 assert_equal 1, issue.project_id
395 395 assert_equal 2, issue.tracker_id
396 396 assert_equal 3, issue.status_id
397 397 assert_equal 'API test', issue.subject
398 398 end
399 399
400 400 test "POST /issues.json with failure should return errors" do
401 401 assert_no_difference('Issue.count') do
402 402 post '/issues.json', {:issue => {:project_id => 1}}, credentials('jsmith')
403 403 end
404 404
405 405 json = ActiveSupport::JSON.decode(response.body)
406 406 assert json['errors'].include?("Subject cannot be blank")
407 407 end
408 408
409 409 test "PUT /issues/:id.xml" do
410 410 assert_difference('Journal.count') do
411 411 put '/issues/6.xml',
412 412 {:issue => {:subject => 'API update', :notes => 'A new note'}},
413 413 credentials('jsmith')
414 414 end
415 415
416 416 issue = Issue.find(6)
417 417 assert_equal "API update", issue.subject
418 418 journal = Journal.last
419 419 assert_equal "A new note", journal.notes
420 420 end
421 421
422 422 test "PUT /issues/:id.xml with custom fields" do
423 423 put '/issues/3.xml',
424 424 {:issue => {:custom_fields => [
425 425 {'id' => '1', 'value' => 'PostgreSQL' },
426 426 {'id' => '2', 'value' => '150'}
427 427 ]}},
428 428 credentials('jsmith')
429 429
430 430 issue = Issue.find(3)
431 431 assert_equal '150', issue.custom_value_for(2).value
432 432 assert_equal 'PostgreSQL', issue.custom_value_for(1).value
433 433 end
434 434
435 435 test "PUT /issues/:id.xml with multi custom fields" do
436 436 field = CustomField.find(1)
437 437 field.update_attribute :multiple, true
438 438
439 439 put '/issues/3.xml',
440 440 {:issue => {:custom_fields => [
441 441 {'id' => '1', 'value' => ['MySQL', 'PostgreSQL'] },
442 442 {'id' => '2', 'value' => '150'}
443 443 ]}},
444 444 credentials('jsmith')
445 445
446 446 issue = Issue.find(3)
447 447 assert_equal '150', issue.custom_value_for(2).value
448 448 assert_equal ['MySQL', 'PostgreSQL'], issue.custom_field_value(1).sort
449 449 end
450 450
451 451 test "PUT /issues/:id.xml with project change" do
452 452 put '/issues/3.xml',
453 453 {:issue => {:project_id => 2, :subject => 'Project changed'}},
454 454 credentials('jsmith')
455 455
456 456 issue = Issue.find(3)
457 457 assert_equal 2, issue.project_id
458 458 assert_equal 'Project changed', issue.subject
459 459 end
460 460
461 461 test "PUT /issues/:id.xml with failed update" do
462 462 put '/issues/6.xml', {:issue => {:subject => ''}}, credentials('jsmith')
463 463
464 464 assert_response :unprocessable_entity
465 465 assert_select 'errors error', :text => "Subject cannot be blank"
466 466 end
467 467
468 468 test "PUT /issues/:id.json" do
469 469 assert_difference('Journal.count') do
470 470 put '/issues/6.json',
471 471 {:issue => {:subject => 'API update', :notes => 'A new note'}},
472 472 credentials('jsmith')
473 473
474 474 assert_response :ok
475 475 assert_equal '', response.body
476 476 end
477 477
478 478 issue = Issue.find(6)
479 479 assert_equal "API update", issue.subject
480 480 journal = Journal.last
481 481 assert_equal "A new note", journal.notes
482 482 end
483 483
484 484 test "PUT /issues/:id.json with failed update" do
485 485 put '/issues/6.json', {:issue => {:subject => ''}}, credentials('jsmith')
486 486
487 487 assert_response :unprocessable_entity
488 488 json = ActiveSupport::JSON.decode(response.body)
489 489 assert json['errors'].include?("Subject cannot be blank")
490 490 end
491 491
492 492 test "DELETE /issues/:id.xml" do
493 493 assert_difference('Issue.count', -1) do
494 494 delete '/issues/6.xml', {}, credentials('jsmith')
495 495
496 496 assert_response :ok
497 497 assert_equal '', response.body
498 498 end
499 499 assert_nil Issue.find_by_id(6)
500 500 end
501 501
502 502 test "DELETE /issues/:id.json" do
503 503 assert_difference('Issue.count', -1) do
504 504 delete '/issues/6.json', {}, credentials('jsmith')
505 505
506 506 assert_response :ok
507 507 assert_equal '', response.body
508 508 end
509 509 assert_nil Issue.find_by_id(6)
510 510 end
511 511
512 512 test "POST /issues/:id/watchers.xml should add watcher" do
513 513 assert_difference 'Watcher.count' do
514 514 post '/issues/1/watchers.xml', {:user_id => 3}, credentials('jsmith')
515 515
516 516 assert_response :ok
517 517 assert_equal '', response.body
518 518 end
519 519 watcher = Watcher.order('id desc').first
520 520 assert_equal Issue.find(1), watcher.watchable
521 521 assert_equal User.find(3), watcher.user
522 522 end
523 523
524 524 test "DELETE /issues/:id/watchers/:user_id.xml should remove watcher" do
525 525 Watcher.create!(:user_id => 3, :watchable => Issue.find(1))
526 526
527 527 assert_difference 'Watcher.count', -1 do
528 528 delete '/issues/1/watchers/3.xml', {}, credentials('jsmith')
529 529
530 530 assert_response :ok
531 531 assert_equal '', response.body
532 532 end
533 533 assert_equal false, Issue.find(1).watched_by?(User.find(3))
534 534 end
535 535
536 536 def test_create_issue_with_uploaded_file
537 537 token = xml_upload('test_create_with_upload', credentials('jsmith'))
538 538 attachment = Attachment.find_by_token(token)
539 539
540 540 # create the issue with the upload's token
541 541 assert_difference 'Issue.count' do
542 542 post '/issues.xml',
543 543 {:issue => {:project_id => 1, :subject => 'Uploaded file',
544 544 :uploads => [{:token => token, :filename => 'test.txt',
545 545 :content_type => 'text/plain'}]}},
546 546 credentials('jsmith')
547 547 assert_response :created
548 548 end
549 549 issue = Issue.order('id DESC').first
550 550 assert_equal 1, issue.attachments.count
551 551 assert_equal attachment, issue.attachments.first
552 552
553 553 attachment.reload
554 554 assert_equal 'test.txt', attachment.filename
555 555 assert_equal 'text/plain', attachment.content_type
556 556 assert_equal 'test_create_with_upload'.size, attachment.filesize
557 557 assert_equal 2, attachment.author_id
558 558
559 559 # get the issue with its attachments
560 560 get "/issues/#{issue.id}.xml", :include => 'attachments'
561 561 assert_response :success
562 562 xml = Hash.from_xml(response.body)
563 563 attachments = xml['issue']['attachments']
564 564 assert_kind_of Array, attachments
565 565 assert_equal 1, attachments.size
566 566 url = attachments.first['content_url']
567 567 assert_not_nil url
568 568
569 569 # download the attachment
570 570 get url
571 571 assert_response :success
572 572 assert_equal 'test_create_with_upload', response.body
573 573 end
574 574
575 575 def test_create_issue_with_multiple_uploaded_files_as_xml
576 576 token1 = xml_upload('File content 1', credentials('jsmith'))
577 577 token2 = xml_upload('File content 2', credentials('jsmith'))
578 578
579 579 payload = <<-XML
580 580 <?xml version="1.0" encoding="UTF-8" ?>
581 581 <issue>
582 582 <project_id>1</project_id>
583 583 <tracker_id>1</tracker_id>
584 584 <subject>Issue with multiple attachments</subject>
585 585 <uploads type="array">
586 586 <upload>
587 587 <token>#{token1}</token>
588 588 <filename>test1.txt</filename>
589 589 </upload>
590 590 <upload>
591 591 <token>#{token2}</token>
592 592 <filename>test1.txt</filename>
593 593 </upload>
594 594 </uploads>
595 595 </issue>
596 596 XML
597 597
598 598 assert_difference 'Issue.count' do
599 599 post '/issues.xml', payload, {"CONTENT_TYPE" => 'application/xml'}.merge(credentials('jsmith'))
600 600 assert_response :created
601 601 end
602 602 issue = Issue.order('id DESC').first
603 603 assert_equal 2, issue.attachments.count
604 604 end
605 605
606 606 def test_create_issue_with_multiple_uploaded_files_as_json
607 607 token1 = json_upload('File content 1', credentials('jsmith'))
608 608 token2 = json_upload('File content 2', credentials('jsmith'))
609 609
610 610 payload = <<-JSON
611 611 {
612 612 "issue": {
613 613 "project_id": "1",
614 614 "tracker_id": "1",
615 615 "subject": "Issue with multiple attachments",
616 616 "uploads": [
617 617 {"token": "#{token1}", "filename": "test1.txt"},
618 618 {"token": "#{token2}", "filename": "test2.txt"}
619 619 ]
620 620 }
621 621 }
622 622 JSON
623 623
624 624 assert_difference 'Issue.count' do
625 625 post '/issues.json', payload, {"CONTENT_TYPE" => 'application/json'}.merge(credentials('jsmith'))
626 626 assert_response :created
627 627 end
628 628 issue = Issue.order('id DESC').first
629 629 assert_equal 2, issue.attachments.count
630 630 end
631 631
632 632 def test_update_issue_with_uploaded_file
633 633 token = xml_upload('test_upload_with_upload', credentials('jsmith'))
634 634 attachment = Attachment.find_by_token(token)
635 635
636 636 # update the issue with the upload's token
637 637 assert_difference 'Journal.count' do
638 638 put '/issues/1.xml',
639 639 {:issue => {:notes => 'Attachment added',
640 640 :uploads => [{:token => token, :filename => 'test.txt',
641 641 :content_type => 'text/plain'}]}},
642 642 credentials('jsmith')
643 643 assert_response :ok
644 644 assert_equal '', @response.body
645 645 end
646 646
647 647 issue = Issue.find(1)
648 648 assert_include attachment, issue.attachments
649 649 end
650 650 end
General Comments 0
You need to be logged in to leave comments. Login now