Mercurial > hg > soundsoftware-site
comparison .svn/pristine/63/6337da68aa661918822db9c4ab113e8ae3671adf.svn-base @ 1298:4f746d8966dd redmine_2.3_integration
Merge from redmine-2.3 branch to create new branch redmine-2.3-integration
author | Chris Cannam |
---|---|
date | Fri, 14 Jun 2013 09:28:30 +0100 |
parents | 622f24f53b42 |
children |
comparison
equal
deleted
inserted
replaced
1297:0a574315af3e | 1298:4f746d8966dd |
---|---|
1 # Redmine - project management software | |
2 # Copyright (C) 2006-2013 Jean-Philippe Lang | |
3 # | |
4 # This program is free software; you can redistribute it and/or | |
5 # modify it under the terms of the GNU General Public License | |
6 # as published by the Free Software Foundation; either version 2 | |
7 # of the License, or (at your option) any later version. | |
8 # | |
9 # This program is distributed in the hope that it will be useful, | |
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 # GNU General Public License for more details. | |
13 # | |
14 # You should have received a copy of the GNU General Public License | |
15 # along with this program; if not, write to the Free Software | |
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
17 | |
18 require File.expand_path('../../../test_helper', __FILE__) | |
19 | |
20 class Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base | |
21 fixtures :projects, | |
22 :users, | |
23 :roles, | |
24 :members, | |
25 :member_roles, | |
26 :issues, | |
27 :issue_statuses, | |
28 :issue_relations, | |
29 :versions, | |
30 :trackers, | |
31 :projects_trackers, | |
32 :issue_categories, | |
33 :enabled_modules, | |
34 :enumerations, | |
35 :attachments, | |
36 :workflows, | |
37 :custom_fields, | |
38 :custom_values, | |
39 :custom_fields_projects, | |
40 :custom_fields_trackers, | |
41 :time_entries, | |
42 :journals, | |
43 :journal_details, | |
44 :queries, | |
45 :attachments | |
46 | |
47 def setup | |
48 Setting.rest_api_enabled = '1' | |
49 end | |
50 | |
51 context "/issues" do | |
52 # Use a private project to make sure auth is really working and not just | |
53 # only showing public issues. | |
54 should_allow_api_authentication(:get, "/projects/private-child/issues.xml") | |
55 | |
56 should "contain metadata" do | |
57 get '/issues.xml' | |
58 | |
59 assert_tag :tag => 'issues', | |
60 :attributes => { | |
61 :type => 'array', | |
62 :total_count => assigns(:issue_count), | |
63 :limit => 25, | |
64 :offset => 0 | |
65 } | |
66 end | |
67 | |
68 context "with offset and limit" do | |
69 should "use the params" do | |
70 get '/issues.xml?offset=2&limit=3' | |
71 | |
72 assert_equal 3, assigns(:limit) | |
73 assert_equal 2, assigns(:offset) | |
74 assert_tag :tag => 'issues', :children => {:count => 3, :only => {:tag => 'issue'}} | |
75 end | |
76 end | |
77 | |
78 context "with nometa param" do | |
79 should "not contain metadata" do | |
80 get '/issues.xml?nometa=1' | |
81 | |
82 assert_tag :tag => 'issues', | |
83 :attributes => { | |
84 :type => 'array', | |
85 :total_count => nil, | |
86 :limit => nil, | |
87 :offset => nil | |
88 } | |
89 end | |
90 end | |
91 | |
92 context "with nometa header" do | |
93 should "not contain metadata" do | |
94 get '/issues.xml', {}, {'X-Redmine-Nometa' => '1'} | |
95 | |
96 assert_tag :tag => 'issues', | |
97 :attributes => { | |
98 :type => 'array', | |
99 :total_count => nil, | |
100 :limit => nil, | |
101 :offset => nil | |
102 } | |
103 end | |
104 end | |
105 | |
106 context "with relations" do | |
107 should "display relations" do | |
108 get '/issues.xml?include=relations' | |
109 | |
110 assert_response :success | |
111 assert_equal 'application/xml', @response.content_type | |
112 assert_tag 'relations', | |
113 :parent => {:tag => 'issue', :child => {:tag => 'id', :content => '3'}}, | |
114 :children => {:count => 1}, | |
115 :child => { | |
116 :tag => 'relation', | |
117 :attributes => {:id => '2', :issue_id => '2', :issue_to_id => '3', | |
118 :relation_type => 'relates'} | |
119 } | |
120 assert_tag 'relations', | |
121 :parent => {:tag => 'issue', :child => {:tag => 'id', :content => '1'}}, | |
122 :children => {:count => 0} | |
123 end | |
124 end | |
125 | |
126 context "with invalid query params" do | |
127 should "return errors" do | |
128 get '/issues.xml', {:f => ['start_date'], :op => {:start_date => '='}} | |
129 | |
130 assert_response :unprocessable_entity | |
131 assert_equal 'application/xml', @response.content_type | |
132 assert_tag 'errors', :child => {:tag => 'error', :content => "Start date can't be blank"} | |
133 end | |
134 end | |
135 | |
136 context "with custom field filter" do | |
137 should "show only issues with the custom field value" do | |
138 get '/issues.xml', | |
139 {:set_filter => 1, :f => ['cf_1'], :op => {:cf_1 => '='}, | |
140 :v => {:cf_1 => ['MySQL']}} | |
141 expected_ids = Issue.visible.all( | |
142 :include => :custom_values, | |
143 :conditions => {:custom_values => {:custom_field_id => 1, :value => 'MySQL'}}).map(&:id) | |
144 assert_select 'issues > issue > id', :count => expected_ids.count do |ids| | |
145 ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) } | |
146 end | |
147 end | |
148 end | |
149 | |
150 context "with custom field filter (shorthand method)" do | |
151 should "show only issues with the custom field value" do | |
152 get '/issues.xml', { :cf_1 => 'MySQL' } | |
153 | |
154 expected_ids = Issue.visible.all( | |
155 :include => :custom_values, | |
156 :conditions => {:custom_values => {:custom_field_id => 1, :value => 'MySQL'}}).map(&:id) | |
157 | |
158 assert_select 'issues > issue > id', :count => expected_ids.count do |ids| | |
159 ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) } | |
160 end | |
161 end | |
162 end | |
163 end | |
164 | |
165 context "/index.json" do | |
166 should_allow_api_authentication(:get, "/projects/private-child/issues.json") | |
167 end | |
168 | |
169 context "/index.xml with filter" do | |
170 should "show only issues with the status_id" do | |
171 get '/issues.xml?status_id=5' | |
172 | |
173 expected_ids = Issue.visible.all(:conditions => {:status_id => 5}).map(&:id) | |
174 | |
175 assert_select 'issues > issue > id', :count => expected_ids.count do |ids| | |
176 ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) } | |
177 end | |
178 end | |
179 end | |
180 | |
181 context "/index.json with filter" do | |
182 should "show only issues with the status_id" do | |
183 get '/issues.json?status_id=5' | |
184 | |
185 json = ActiveSupport::JSON.decode(response.body) | |
186 status_ids_used = json['issues'].collect {|j| j['status']['id'] } | |
187 assert_equal 3, status_ids_used.length | |
188 assert status_ids_used.all? {|id| id == 5 } | |
189 end | |
190 | |
191 end | |
192 | |
193 # Issue 6 is on a private project | |
194 context "/issues/6.xml" do | |
195 should_allow_api_authentication(:get, "/issues/6.xml") | |
196 end | |
197 | |
198 context "/issues/6.json" do | |
199 should_allow_api_authentication(:get, "/issues/6.json") | |
200 end | |
201 | |
202 context "GET /issues/:id" do | |
203 context "with journals" do | |
204 context ".xml" do | |
205 should "display journals" do | |
206 get '/issues/1.xml?include=journals' | |
207 | |
208 assert_tag :tag => 'issue', | |
209 :child => { | |
210 :tag => 'journals', | |
211 :attributes => { :type => 'array' }, | |
212 :child => { | |
213 :tag => 'journal', | |
214 :attributes => { :id => '1'}, | |
215 :child => { | |
216 :tag => 'details', | |
217 :attributes => { :type => 'array' }, | |
218 :child => { | |
219 :tag => 'detail', | |
220 :attributes => { :name => 'status_id' }, | |
221 :child => { | |
222 :tag => 'old_value', | |
223 :content => '1', | |
224 :sibling => { | |
225 :tag => 'new_value', | |
226 :content => '2' | |
227 } | |
228 } | |
229 } | |
230 } | |
231 } | |
232 } | |
233 end | |
234 end | |
235 end | |
236 | |
237 context "with custom fields" do | |
238 context ".xml" do | |
239 should "display custom fields" do | |
240 get '/issues/3.xml' | |
241 | |
242 assert_tag :tag => 'issue', | |
243 :child => { | |
244 :tag => 'custom_fields', | |
245 :attributes => { :type => 'array' }, | |
246 :child => { | |
247 :tag => 'custom_field', | |
248 :attributes => { :id => '1'}, | |
249 :child => { | |
250 :tag => 'value', | |
251 :content => 'MySQL' | |
252 } | |
253 } | |
254 } | |
255 | |
256 assert_nothing_raised do | |
257 Hash.from_xml(response.body).to_xml | |
258 end | |
259 end | |
260 end | |
261 end | |
262 | |
263 context "with multi custom fields" do | |
264 setup do | |
265 field = CustomField.find(1) | |
266 field.update_attribute :multiple, true | |
267 issue = Issue.find(3) | |
268 issue.custom_field_values = {1 => ['MySQL', 'Oracle']} | |
269 issue.save! | |
270 end | |
271 | |
272 context ".xml" do | |
273 should "display custom fields" do | |
274 get '/issues/3.xml' | |
275 assert_response :success | |
276 assert_tag :tag => 'issue', | |
277 :child => { | |
278 :tag => 'custom_fields', | |
279 :attributes => { :type => 'array' }, | |
280 :child => { | |
281 :tag => 'custom_field', | |
282 :attributes => { :id => '1'}, | |
283 :child => { | |
284 :tag => 'value', | |
285 :attributes => { :type => 'array' }, | |
286 :children => { :count => 2 } | |
287 } | |
288 } | |
289 } | |
290 | |
291 xml = Hash.from_xml(response.body) | |
292 custom_fields = xml['issue']['custom_fields'] | |
293 assert_kind_of Array, custom_fields | |
294 field = custom_fields.detect {|f| f['id'] == '1'} | |
295 assert_kind_of Hash, field | |
296 assert_equal ['MySQL', 'Oracle'], field['value'].sort | |
297 end | |
298 end | |
299 | |
300 context ".json" do | |
301 should "display custom fields" do | |
302 get '/issues/3.json' | |
303 assert_response :success | |
304 json = ActiveSupport::JSON.decode(response.body) | |
305 custom_fields = json['issue']['custom_fields'] | |
306 assert_kind_of Array, custom_fields | |
307 field = custom_fields.detect {|f| f['id'] == 1} | |
308 assert_kind_of Hash, field | |
309 assert_equal ['MySQL', 'Oracle'], field['value'].sort | |
310 end | |
311 end | |
312 end | |
313 | |
314 context "with empty value for multi custom field" do | |
315 setup do | |
316 field = CustomField.find(1) | |
317 field.update_attribute :multiple, true | |
318 issue = Issue.find(3) | |
319 issue.custom_field_values = {1 => ['']} | |
320 issue.save! | |
321 end | |
322 | |
323 context ".xml" do | |
324 should "display custom fields" do | |
325 get '/issues/3.xml' | |
326 assert_response :success | |
327 assert_tag :tag => 'issue', | |
328 :child => { | |
329 :tag => 'custom_fields', | |
330 :attributes => { :type => 'array' }, | |
331 :child => { | |
332 :tag => 'custom_field', | |
333 :attributes => { :id => '1'}, | |
334 :child => { | |
335 :tag => 'value', | |
336 :attributes => { :type => 'array' }, | |
337 :children => { :count => 0 } | |
338 } | |
339 } | |
340 } | |
341 | |
342 xml = Hash.from_xml(response.body) | |
343 custom_fields = xml['issue']['custom_fields'] | |
344 assert_kind_of Array, custom_fields | |
345 field = custom_fields.detect {|f| f['id'] == '1'} | |
346 assert_kind_of Hash, field | |
347 assert_equal [], field['value'] | |
348 end | |
349 end | |
350 | |
351 context ".json" do | |
352 should "display custom fields" do | |
353 get '/issues/3.json' | |
354 assert_response :success | |
355 json = ActiveSupport::JSON.decode(response.body) | |
356 custom_fields = json['issue']['custom_fields'] | |
357 assert_kind_of Array, custom_fields | |
358 field = custom_fields.detect {|f| f['id'] == 1} | |
359 assert_kind_of Hash, field | |
360 assert_equal [], field['value'].sort | |
361 end | |
362 end | |
363 end | |
364 | |
365 context "with attachments" do | |
366 context ".xml" do | |
367 should "display attachments" do | |
368 get '/issues/3.xml?include=attachments' | |
369 | |
370 assert_tag :tag => 'issue', | |
371 :child => { | |
372 :tag => 'attachments', | |
373 :children => {:count => 5}, | |
374 :child => { | |
375 :tag => 'attachment', | |
376 :child => { | |
377 :tag => 'filename', | |
378 :content => 'source.rb', | |
379 :sibling => { | |
380 :tag => 'content_url', | |
381 :content => 'http://www.example.com/attachments/download/4/source.rb' | |
382 } | |
383 } | |
384 } | |
385 } | |
386 end | |
387 end | |
388 end | |
389 | |
390 context "with subtasks" do | |
391 setup do | |
392 @c1 = Issue.create!( | |
393 :status_id => 1, :subject => "child c1", | |
394 :tracker_id => 1, :project_id => 1, :author_id => 1, | |
395 :parent_issue_id => 1 | |
396 ) | |
397 @c2 = Issue.create!( | |
398 :status_id => 1, :subject => "child c2", | |
399 :tracker_id => 1, :project_id => 1, :author_id => 1, | |
400 :parent_issue_id => 1 | |
401 ) | |
402 @c3 = Issue.create!( | |
403 :status_id => 1, :subject => "child c3", | |
404 :tracker_id => 1, :project_id => 1, :author_id => 1, | |
405 :parent_issue_id => @c1.id | |
406 ) | |
407 end | |
408 | |
409 context ".xml" do | |
410 should "display children" do | |
411 get '/issues/1.xml?include=children' | |
412 | |
413 assert_tag :tag => 'issue', | |
414 :child => { | |
415 :tag => 'children', | |
416 :children => {:count => 2}, | |
417 :child => { | |
418 :tag => 'issue', | |
419 :attributes => {:id => @c1.id.to_s}, | |
420 :child => { | |
421 :tag => 'subject', | |
422 :content => 'child c1', | |
423 :sibling => { | |
424 :tag => 'children', | |
425 :children => {:count => 1}, | |
426 :child => { | |
427 :tag => 'issue', | |
428 :attributes => {:id => @c3.id.to_s} | |
429 } | |
430 } | |
431 } | |
432 } | |
433 } | |
434 end | |
435 | |
436 context ".json" do | |
437 should "display children" do | |
438 get '/issues/1.json?include=children' | |
439 | |
440 json = ActiveSupport::JSON.decode(response.body) | |
441 assert_equal([ | |
442 { | |
443 'id' => @c1.id, 'subject' => 'child c1', 'tracker' => {'id' => 1, 'name' => 'Bug'}, | |
444 'children' => [{'id' => @c3.id, 'subject' => 'child c3', | |
445 'tracker' => {'id' => 1, 'name' => 'Bug'} }] | |
446 }, | |
447 { 'id' => @c2.id, 'subject' => 'child c2', 'tracker' => {'id' => 1, 'name' => 'Bug'} } | |
448 ], | |
449 json['issue']['children']) | |
450 end | |
451 end | |
452 end | |
453 end | |
454 end | |
455 | |
456 test "GET /issues/:id.xml?include=watchers should include watchers" do | |
457 Watcher.create!(:user_id => 3, :watchable => Issue.find(1)) | |
458 | |
459 get '/issues/1.xml?include=watchers', {}, credentials('jsmith') | |
460 | |
461 assert_response :ok | |
462 assert_equal 'application/xml', response.content_type | |
463 assert_select 'issue' do | |
464 assert_select 'watchers', Issue.find(1).watchers.count | |
465 assert_select 'watchers' do | |
466 assert_select 'user[id=3]' | |
467 end | |
468 end | |
469 end | |
470 | |
471 context "POST /issues.xml" do | |
472 should_allow_api_authentication( | |
473 :post, | |
474 '/issues.xml', | |
475 {:issue => {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}}, | |
476 {:success_code => :created} | |
477 ) | |
478 should "create an issue with the attributes" do | |
479 assert_difference('Issue.count') do | |
480 post '/issues.xml', | |
481 {:issue => {:project_id => 1, :subject => 'API test', | |
482 :tracker_id => 2, :status_id => 3}}, credentials('jsmith') | |
483 end | |
484 issue = Issue.first(:order => 'id DESC') | |
485 assert_equal 1, issue.project_id | |
486 assert_equal 2, issue.tracker_id | |
487 assert_equal 3, issue.status_id | |
488 assert_equal 'API test', issue.subject | |
489 | |
490 assert_response :created | |
491 assert_equal 'application/xml', @response.content_type | |
492 assert_tag 'issue', :child => {:tag => 'id', :content => issue.id.to_s} | |
493 end | |
494 end | |
495 | |
496 test "POST /issues.xml with watcher_user_ids should create issue with watchers" do | |
497 assert_difference('Issue.count') do | |
498 post '/issues.xml', | |
499 {:issue => {:project_id => 1, :subject => 'Watchers', | |
500 :tracker_id => 2, :status_id => 3, :watcher_user_ids => [3, 1]}}, credentials('jsmith') | |
501 assert_response :created | |
502 end | |
503 issue = Issue.order('id desc').first | |
504 assert_equal 2, issue.watchers.size | |
505 assert_equal [1, 3], issue.watcher_user_ids.sort | |
506 end | |
507 | |
508 context "POST /issues.xml with failure" do | |
509 should "have an errors tag" do | |
510 assert_no_difference('Issue.count') do | |
511 post '/issues.xml', {:issue => {:project_id => 1}}, credentials('jsmith') | |
512 end | |
513 | |
514 assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"} | |
515 end | |
516 end | |
517 | |
518 context "POST /issues.json" do | |
519 should_allow_api_authentication(:post, | |
520 '/issues.json', | |
521 {:issue => {:project_id => 1, :subject => 'API test', | |
522 :tracker_id => 2, :status_id => 3}}, | |
523 {:success_code => :created}) | |
524 | |
525 should "create an issue with the attributes" do | |
526 assert_difference('Issue.count') do | |
527 post '/issues.json', | |
528 {:issue => {:project_id => 1, :subject => 'API test', | |
529 :tracker_id => 2, :status_id => 3}}, | |
530 credentials('jsmith') | |
531 end | |
532 | |
533 issue = Issue.first(:order => 'id DESC') | |
534 assert_equal 1, issue.project_id | |
535 assert_equal 2, issue.tracker_id | |
536 assert_equal 3, issue.status_id | |
537 assert_equal 'API test', issue.subject | |
538 end | |
539 | |
540 end | |
541 | |
542 context "POST /issues.json with failure" do | |
543 should "have an errors element" do | |
544 assert_no_difference('Issue.count') do | |
545 post '/issues.json', {:issue => {:project_id => 1}}, credentials('jsmith') | |
546 end | |
547 | |
548 json = ActiveSupport::JSON.decode(response.body) | |
549 assert json['errors'].include?("Subject can't be blank") | |
550 end | |
551 end | |
552 | |
553 # Issue 6 is on a private project | |
554 context "PUT /issues/6.xml" do | |
555 setup do | |
556 @parameters = {:issue => {:subject => 'API update', :notes => 'A new note'}} | |
557 end | |
558 | |
559 should_allow_api_authentication(:put, | |
560 '/issues/6.xml', | |
561 {:issue => {:subject => 'API update', :notes => 'A new note'}}, | |
562 {:success_code => :ok}) | |
563 | |
564 should "not create a new issue" do | |
565 assert_no_difference('Issue.count') do | |
566 put '/issues/6.xml', @parameters, credentials('jsmith') | |
567 end | |
568 end | |
569 | |
570 should "create a new journal" do | |
571 assert_difference('Journal.count') do | |
572 put '/issues/6.xml', @parameters, credentials('jsmith') | |
573 end | |
574 end | |
575 | |
576 should "add the note to the journal" do | |
577 put '/issues/6.xml', @parameters, credentials('jsmith') | |
578 | |
579 journal = Journal.last | |
580 assert_equal "A new note", journal.notes | |
581 end | |
582 | |
583 should "update the issue" do | |
584 put '/issues/6.xml', @parameters, credentials('jsmith') | |
585 | |
586 issue = Issue.find(6) | |
587 assert_equal "API update", issue.subject | |
588 end | |
589 | |
590 end | |
591 | |
592 context "PUT /issues/3.xml with custom fields" do | |
593 setup do | |
594 @parameters = { | |
595 :issue => {:custom_fields => [{'id' => '1', 'value' => 'PostgreSQL' }, | |
596 {'id' => '2', 'value' => '150'}]} | |
597 } | |
598 end | |
599 | |
600 should "update custom fields" do | |
601 assert_no_difference('Issue.count') do | |
602 put '/issues/3.xml', @parameters, credentials('jsmith') | |
603 end | |
604 | |
605 issue = Issue.find(3) | |
606 assert_equal '150', issue.custom_value_for(2).value | |
607 assert_equal 'PostgreSQL', issue.custom_value_for(1).value | |
608 end | |
609 end | |
610 | |
611 context "PUT /issues/3.xml with multi custom fields" do | |
612 setup do | |
613 field = CustomField.find(1) | |
614 field.update_attribute :multiple, true | |
615 @parameters = { | |
616 :issue => {:custom_fields => [{'id' => '1', 'value' => ['MySQL', 'PostgreSQL'] }, | |
617 {'id' => '2', 'value' => '150'}]} | |
618 } | |
619 end | |
620 | |
621 should "update custom fields" do | |
622 assert_no_difference('Issue.count') do | |
623 put '/issues/3.xml', @parameters, credentials('jsmith') | |
624 end | |
625 | |
626 issue = Issue.find(3) | |
627 assert_equal '150', issue.custom_value_for(2).value | |
628 assert_equal ['MySQL', 'PostgreSQL'], issue.custom_field_value(1).sort | |
629 end | |
630 end | |
631 | |
632 context "PUT /issues/3.xml with project change" do | |
633 setup do | |
634 @parameters = {:issue => {:project_id => 2, :subject => 'Project changed'}} | |
635 end | |
636 | |
637 should "update project" do | |
638 assert_no_difference('Issue.count') do | |
639 put '/issues/3.xml', @parameters, credentials('jsmith') | |
640 end | |
641 | |
642 issue = Issue.find(3) | |
643 assert_equal 2, issue.project_id | |
644 assert_equal 'Project changed', issue.subject | |
645 end | |
646 end | |
647 | |
648 context "PUT /issues/6.xml with failed update" do | |
649 setup do | |
650 @parameters = {:issue => {:subject => ''}} | |
651 end | |
652 | |
653 should "not create a new issue" do | |
654 assert_no_difference('Issue.count') do | |
655 put '/issues/6.xml', @parameters, credentials('jsmith') | |
656 end | |
657 end | |
658 | |
659 should "not create a new journal" do | |
660 assert_no_difference('Journal.count') do | |
661 put '/issues/6.xml', @parameters, credentials('jsmith') | |
662 end | |
663 end | |
664 | |
665 should "have an errors tag" do | |
666 put '/issues/6.xml', @parameters, credentials('jsmith') | |
667 | |
668 assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"} | |
669 end | |
670 end | |
671 | |
672 context "PUT /issues/6.json" do | |
673 setup do | |
674 @parameters = {:issue => {:subject => 'API update', :notes => 'A new note'}} | |
675 end | |
676 | |
677 should_allow_api_authentication(:put, | |
678 '/issues/6.json', | |
679 {:issue => {:subject => 'API update', :notes => 'A new note'}}, | |
680 {:success_code => :ok}) | |
681 | |
682 should "update the issue" do | |
683 assert_no_difference('Issue.count') do | |
684 assert_difference('Journal.count') do | |
685 put '/issues/6.json', @parameters, credentials('jsmith') | |
686 | |
687 assert_response :ok | |
688 assert_equal '', response.body | |
689 end | |
690 end | |
691 | |
692 issue = Issue.find(6) | |
693 assert_equal "API update", issue.subject | |
694 journal = Journal.last | |
695 assert_equal "A new note", journal.notes | |
696 end | |
697 end | |
698 | |
699 context "PUT /issues/6.json with failed update" do | |
700 should "return errors" do | |
701 assert_no_difference('Issue.count') do | |
702 assert_no_difference('Journal.count') do | |
703 put '/issues/6.json', {:issue => {:subject => ''}}, credentials('jsmith') | |
704 | |
705 assert_response :unprocessable_entity | |
706 end | |
707 end | |
708 | |
709 json = ActiveSupport::JSON.decode(response.body) | |
710 assert json['errors'].include?("Subject can't be blank") | |
711 end | |
712 end | |
713 | |
714 context "DELETE /issues/1.xml" do | |
715 should_allow_api_authentication(:delete, | |
716 '/issues/6.xml', | |
717 {}, | |
718 {:success_code => :ok}) | |
719 | |
720 should "delete the issue" do | |
721 assert_difference('Issue.count', -1) do | |
722 delete '/issues/6.xml', {}, credentials('jsmith') | |
723 | |
724 assert_response :ok | |
725 assert_equal '', response.body | |
726 end | |
727 | |
728 assert_nil Issue.find_by_id(6) | |
729 end | |
730 end | |
731 | |
732 context "DELETE /issues/1.json" do | |
733 should_allow_api_authentication(:delete, | |
734 '/issues/6.json', | |
735 {}, | |
736 {:success_code => :ok}) | |
737 | |
738 should "delete the issue" do | |
739 assert_difference('Issue.count', -1) do | |
740 delete '/issues/6.json', {}, credentials('jsmith') | |
741 | |
742 assert_response :ok | |
743 assert_equal '', response.body | |
744 end | |
745 | |
746 assert_nil Issue.find_by_id(6) | |
747 end | |
748 end | |
749 | |
750 test "POST /issues/:id/watchers.xml should add watcher" do | |
751 assert_difference 'Watcher.count' do | |
752 post '/issues/1/watchers.xml', {:user_id => 3}, credentials('jsmith') | |
753 | |
754 assert_response :ok | |
755 assert_equal '', response.body | |
756 end | |
757 watcher = Watcher.order('id desc').first | |
758 assert_equal Issue.find(1), watcher.watchable | |
759 assert_equal User.find(3), watcher.user | |
760 end | |
761 | |
762 test "DELETE /issues/:id/watchers/:user_id.xml should remove watcher" do | |
763 Watcher.create!(:user_id => 3, :watchable => Issue.find(1)) | |
764 | |
765 assert_difference 'Watcher.count', -1 do | |
766 delete '/issues/1/watchers/3.xml', {}, credentials('jsmith') | |
767 | |
768 assert_response :ok | |
769 assert_equal '', response.body | |
770 end | |
771 assert_equal false, Issue.find(1).watched_by?(User.find(3)) | |
772 end | |
773 | |
774 def test_create_issue_with_uploaded_file | |
775 set_tmp_attachments_directory | |
776 # upload the file | |
777 assert_difference 'Attachment.count' do | |
778 post '/uploads.xml', 'test_create_with_upload', | |
779 {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith')) | |
780 assert_response :created | |
781 end | |
782 xml = Hash.from_xml(response.body) | |
783 token = xml['upload']['token'] | |
784 attachment = Attachment.first(:order => 'id DESC') | |
785 | |
786 # create the issue with the upload's token | |
787 assert_difference 'Issue.count' do | |
788 post '/issues.xml', | |
789 {:issue => {:project_id => 1, :subject => 'Uploaded file', | |
790 :uploads => [{:token => token, :filename => 'test.txt', | |
791 :content_type => 'text/plain'}]}}, | |
792 credentials('jsmith') | |
793 assert_response :created | |
794 end | |
795 issue = Issue.first(:order => 'id DESC') | |
796 assert_equal 1, issue.attachments.count | |
797 assert_equal attachment, issue.attachments.first | |
798 | |
799 attachment.reload | |
800 assert_equal 'test.txt', attachment.filename | |
801 assert_equal 'text/plain', attachment.content_type | |
802 assert_equal 'test_create_with_upload'.size, attachment.filesize | |
803 assert_equal 2, attachment.author_id | |
804 | |
805 # get the issue with its attachments | |
806 get "/issues/#{issue.id}.xml", :include => 'attachments' | |
807 assert_response :success | |
808 xml = Hash.from_xml(response.body) | |
809 attachments = xml['issue']['attachments'] | |
810 assert_kind_of Array, attachments | |
811 assert_equal 1, attachments.size | |
812 url = attachments.first['content_url'] | |
813 assert_not_nil url | |
814 | |
815 # download the attachment | |
816 get url | |
817 assert_response :success | |
818 end | |
819 | |
820 def test_update_issue_with_uploaded_file | |
821 set_tmp_attachments_directory | |
822 # upload the file | |
823 assert_difference 'Attachment.count' do | |
824 post '/uploads.xml', 'test_upload_with_upload', | |
825 {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith')) | |
826 assert_response :created | |
827 end | |
828 xml = Hash.from_xml(response.body) | |
829 token = xml['upload']['token'] | |
830 attachment = Attachment.first(:order => 'id DESC') | |
831 | |
832 # update the issue with the upload's token | |
833 assert_difference 'Journal.count' do | |
834 put '/issues/1.xml', | |
835 {:issue => {:notes => 'Attachment added', | |
836 :uploads => [{:token => token, :filename => 'test.txt', | |
837 :content_type => 'text/plain'}]}}, | |
838 credentials('jsmith') | |
839 assert_response :ok | |
840 assert_equal '', @response.body | |
841 end | |
842 | |
843 issue = Issue.find(1) | |
844 assert_include attachment, issue.attachments | |
845 end | |
846 end |