Mercurial > hg > soundsoftware-site
comparison .svn/pristine/7c/7cc3cd618ee01978917b3155324a8d8f631cb820.svn-base @ 1517:dffacf8a6908 redmine-2.5
Update to Redmine SVN revision 13367 on 2.5-stable branch
author | Chris Cannam |
---|---|
date | Tue, 09 Sep 2014 09:29:00 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1516:b450a9d58aed | 1517:dffacf8a6908 |
---|---|
1 # Redmine - project management software | |
2 # Copyright (C) 2006-2014 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. | |
142 joins(:custom_values). | |
143 where(: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. | |
155 joins(:custom_values). | |
156 where(: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 def test_index_should_allow_timestamp_filtering | |
166 Issue.delete_all | |
167 Issue.generate!(:subject => '1').update_column(:updated_on, Time.parse("2014-01-02T10:25:00Z")) | |
168 Issue.generate!(:subject => '2').update_column(:updated_on, Time.parse("2014-01-02T12:13:00Z")) | |
169 | |
170 get '/issues.xml', | |
171 {:set_filter => 1, :f => ['updated_on'], :op => {:updated_on => '<='}, | |
172 :v => {:updated_on => ['2014-01-02T12:00:00Z']}} | |
173 assert_select 'issues>issue', :count => 1 | |
174 assert_select 'issues>issue>subject', :text => '1' | |
175 | |
176 get '/issues.xml', | |
177 {:set_filter => 1, :f => ['updated_on'], :op => {:updated_on => '>='}, | |
178 :v => {:updated_on => ['2014-01-02T12:00:00Z']}} | |
179 assert_select 'issues>issue', :count => 1 | |
180 assert_select 'issues>issue>subject', :text => '2' | |
181 | |
182 get '/issues.xml', | |
183 {:set_filter => 1, :f => ['updated_on'], :op => {:updated_on => '>='}, | |
184 :v => {:updated_on => ['2014-01-02T08:00:00Z']}} | |
185 assert_select 'issues>issue', :count => 2 | |
186 end | |
187 | |
188 context "/index.json" do | |
189 should_allow_api_authentication(:get, "/projects/private-child/issues.json") | |
190 end | |
191 | |
192 context "/index.xml with filter" do | |
193 should "show only issues with the status_id" do | |
194 get '/issues.xml?status_id=5' | |
195 | |
196 expected_ids = Issue.visible.where(:status_id => 5).map(&:id) | |
197 | |
198 assert_select 'issues > issue > id', :count => expected_ids.count do |ids| | |
199 ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) } | |
200 end | |
201 end | |
202 end | |
203 | |
204 context "/index.json with filter" do | |
205 should "show only issues with the status_id" do | |
206 get '/issues.json?status_id=5' | |
207 | |
208 json = ActiveSupport::JSON.decode(response.body) | |
209 status_ids_used = json['issues'].collect {|j| j['status']['id'] } | |
210 assert_equal 3, status_ids_used.length | |
211 assert status_ids_used.all? {|id| id == 5 } | |
212 end | |
213 | |
214 end | |
215 | |
216 # Issue 6 is on a private project | |
217 context "/issues/6.xml" do | |
218 should_allow_api_authentication(:get, "/issues/6.xml") | |
219 end | |
220 | |
221 context "/issues/6.json" do | |
222 should_allow_api_authentication(:get, "/issues/6.json") | |
223 end | |
224 | |
225 context "GET /issues/:id" do | |
226 context "with journals" do | |
227 context ".xml" do | |
228 should "display journals" do | |
229 get '/issues/1.xml?include=journals' | |
230 | |
231 assert_tag :tag => 'issue', | |
232 :child => { | |
233 :tag => 'journals', | |
234 :attributes => { :type => 'array' }, | |
235 :child => { | |
236 :tag => 'journal', | |
237 :attributes => { :id => '1'}, | |
238 :child => { | |
239 :tag => 'details', | |
240 :attributes => { :type => 'array' }, | |
241 :child => { | |
242 :tag => 'detail', | |
243 :attributes => { :name => 'status_id' }, | |
244 :child => { | |
245 :tag => 'old_value', | |
246 :content => '1', | |
247 :sibling => { | |
248 :tag => 'new_value', | |
249 :content => '2' | |
250 } | |
251 } | |
252 } | |
253 } | |
254 } | |
255 } | |
256 end | |
257 end | |
258 end | |
259 | |
260 context "with custom fields" do | |
261 context ".xml" do | |
262 should "display custom fields" do | |
263 get '/issues/3.xml' | |
264 | |
265 assert_tag :tag => 'issue', | |
266 :child => { | |
267 :tag => 'custom_fields', | |
268 :attributes => { :type => 'array' }, | |
269 :child => { | |
270 :tag => 'custom_field', | |
271 :attributes => { :id => '1'}, | |
272 :child => { | |
273 :tag => 'value', | |
274 :content => 'MySQL' | |
275 } | |
276 } | |
277 } | |
278 | |
279 assert_nothing_raised do | |
280 Hash.from_xml(response.body).to_xml | |
281 end | |
282 end | |
283 end | |
284 end | |
285 | |
286 context "with multi custom fields" do | |
287 setup do | |
288 field = CustomField.find(1) | |
289 field.update_attribute :multiple, true | |
290 issue = Issue.find(3) | |
291 issue.custom_field_values = {1 => ['MySQL', 'Oracle']} | |
292 issue.save! | |
293 end | |
294 | |
295 context ".xml" do | |
296 should "display custom fields" do | |
297 get '/issues/3.xml' | |
298 assert_response :success | |
299 assert_tag :tag => 'issue', | |
300 :child => { | |
301 :tag => 'custom_fields', | |
302 :attributes => { :type => 'array' }, | |
303 :child => { | |
304 :tag => 'custom_field', | |
305 :attributes => { :id => '1'}, | |
306 :child => { | |
307 :tag => 'value', | |
308 :attributes => { :type => 'array' }, | |
309 :children => { :count => 2 } | |
310 } | |
311 } | |
312 } | |
313 | |
314 xml = Hash.from_xml(response.body) | |
315 custom_fields = xml['issue']['custom_fields'] | |
316 assert_kind_of Array, custom_fields | |
317 field = custom_fields.detect {|f| f['id'] == '1'} | |
318 assert_kind_of Hash, field | |
319 assert_equal ['MySQL', 'Oracle'], field['value'].sort | |
320 end | |
321 end | |
322 | |
323 context ".json" do | |
324 should "display custom fields" do | |
325 get '/issues/3.json' | |
326 assert_response :success | |
327 json = ActiveSupport::JSON.decode(response.body) | |
328 custom_fields = json['issue']['custom_fields'] | |
329 assert_kind_of Array, custom_fields | |
330 field = custom_fields.detect {|f| f['id'] == 1} | |
331 assert_kind_of Hash, field | |
332 assert_equal ['MySQL', 'Oracle'], field['value'].sort | |
333 end | |
334 end | |
335 end | |
336 | |
337 context "with empty value for multi custom field" do | |
338 setup do | |
339 field = CustomField.find(1) | |
340 field.update_attribute :multiple, true | |
341 issue = Issue.find(3) | |
342 issue.custom_field_values = {1 => ['']} | |
343 issue.save! | |
344 end | |
345 | |
346 context ".xml" do | |
347 should "display custom fields" do | |
348 get '/issues/3.xml' | |
349 assert_response :success | |
350 assert_tag :tag => 'issue', | |
351 :child => { | |
352 :tag => 'custom_fields', | |
353 :attributes => { :type => 'array' }, | |
354 :child => { | |
355 :tag => 'custom_field', | |
356 :attributes => { :id => '1'}, | |
357 :child => { | |
358 :tag => 'value', | |
359 :attributes => { :type => 'array' }, | |
360 :children => { :count => 0 } | |
361 } | |
362 } | |
363 } | |
364 | |
365 xml = Hash.from_xml(response.body) | |
366 custom_fields = xml['issue']['custom_fields'] | |
367 assert_kind_of Array, custom_fields | |
368 field = custom_fields.detect {|f| f['id'] == '1'} | |
369 assert_kind_of Hash, field | |
370 assert_equal [], field['value'] | |
371 end | |
372 end | |
373 | |
374 context ".json" do | |
375 should "display custom fields" do | |
376 get '/issues/3.json' | |
377 assert_response :success | |
378 json = ActiveSupport::JSON.decode(response.body) | |
379 custom_fields = json['issue']['custom_fields'] | |
380 assert_kind_of Array, custom_fields | |
381 field = custom_fields.detect {|f| f['id'] == 1} | |
382 assert_kind_of Hash, field | |
383 assert_equal [], field['value'].sort | |
384 end | |
385 end | |
386 end | |
387 | |
388 context "with attachments" do | |
389 context ".xml" do | |
390 should "display attachments" do | |
391 get '/issues/3.xml?include=attachments' | |
392 | |
393 assert_tag :tag => 'issue', | |
394 :child => { | |
395 :tag => 'attachments', | |
396 :children => {:count => 5}, | |
397 :child => { | |
398 :tag => 'attachment', | |
399 :child => { | |
400 :tag => 'filename', | |
401 :content => 'source.rb', | |
402 :sibling => { | |
403 :tag => 'content_url', | |
404 :content => 'http://www.example.com/attachments/download/4/source.rb' | |
405 } | |
406 } | |
407 } | |
408 } | |
409 end | |
410 end | |
411 end | |
412 | |
413 context "with subtasks" do | |
414 setup do | |
415 @c1 = Issue.create!( | |
416 :status_id => 1, :subject => "child c1", | |
417 :tracker_id => 1, :project_id => 1, :author_id => 1, | |
418 :parent_issue_id => 1 | |
419 ) | |
420 @c2 = Issue.create!( | |
421 :status_id => 1, :subject => "child c2", | |
422 :tracker_id => 1, :project_id => 1, :author_id => 1, | |
423 :parent_issue_id => 1 | |
424 ) | |
425 @c3 = Issue.create!( | |
426 :status_id => 1, :subject => "child c3", | |
427 :tracker_id => 1, :project_id => 1, :author_id => 1, | |
428 :parent_issue_id => @c1.id | |
429 ) | |
430 end | |
431 | |
432 context ".xml" do | |
433 should "display children" do | |
434 get '/issues/1.xml?include=children' | |
435 | |
436 assert_tag :tag => 'issue', | |
437 :child => { | |
438 :tag => 'children', | |
439 :children => {:count => 2}, | |
440 :child => { | |
441 :tag => 'issue', | |
442 :attributes => {:id => @c1.id.to_s}, | |
443 :child => { | |
444 :tag => 'subject', | |
445 :content => 'child c1', | |
446 :sibling => { | |
447 :tag => 'children', | |
448 :children => {:count => 1}, | |
449 :child => { | |
450 :tag => 'issue', | |
451 :attributes => {:id => @c3.id.to_s} | |
452 } | |
453 } | |
454 } | |
455 } | |
456 } | |
457 end | |
458 | |
459 context ".json" do | |
460 should "display children" do | |
461 get '/issues/1.json?include=children' | |
462 | |
463 json = ActiveSupport::JSON.decode(response.body) | |
464 assert_equal([ | |
465 { | |
466 'id' => @c1.id, 'subject' => 'child c1', 'tracker' => {'id' => 1, 'name' => 'Bug'}, | |
467 'children' => [{'id' => @c3.id, 'subject' => 'child c3', | |
468 'tracker' => {'id' => 1, 'name' => 'Bug'} }] | |
469 }, | |
470 { 'id' => @c2.id, 'subject' => 'child c2', 'tracker' => {'id' => 1, 'name' => 'Bug'} } | |
471 ], | |
472 json['issue']['children']) | |
473 end | |
474 end | |
475 end | |
476 end | |
477 end | |
478 | |
479 test "GET /issues/:id.xml?include=watchers should include watchers" do | |
480 Watcher.create!(:user_id => 3, :watchable => Issue.find(1)) | |
481 | |
482 get '/issues/1.xml?include=watchers', {}, credentials('jsmith') | |
483 | |
484 assert_response :ok | |
485 assert_equal 'application/xml', response.content_type | |
486 assert_select 'issue' do | |
487 assert_select 'watchers', Issue.find(1).watchers.count | |
488 assert_select 'watchers' do | |
489 assert_select 'user[id=3]' | |
490 end | |
491 end | |
492 end | |
493 | |
494 context "POST /issues.xml" do | |
495 should_allow_api_authentication( | |
496 :post, | |
497 '/issues.xml', | |
498 {:issue => {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}}, | |
499 {:success_code => :created} | |
500 ) | |
501 should "create an issue with the attributes" do | |
502 assert_difference('Issue.count') do | |
503 post '/issues.xml', | |
504 {:issue => {:project_id => 1, :subject => 'API test', | |
505 :tracker_id => 2, :status_id => 3}}, credentials('jsmith') | |
506 end | |
507 issue = Issue.order('id DESC').first | |
508 assert_equal 1, issue.project_id | |
509 assert_equal 2, issue.tracker_id | |
510 assert_equal 3, issue.status_id | |
511 assert_equal 'API test', issue.subject | |
512 | |
513 assert_response :created | |
514 assert_equal 'application/xml', @response.content_type | |
515 assert_tag 'issue', :child => {:tag => 'id', :content => issue.id.to_s} | |
516 end | |
517 end | |
518 | |
519 test "POST /issues.xml with watcher_user_ids should create issue with watchers" do | |
520 assert_difference('Issue.count') do | |
521 post '/issues.xml', | |
522 {:issue => {:project_id => 1, :subject => 'Watchers', | |
523 :tracker_id => 2, :status_id => 3, :watcher_user_ids => [3, 1]}}, credentials('jsmith') | |
524 assert_response :created | |
525 end | |
526 issue = Issue.order('id desc').first | |
527 assert_equal 2, issue.watchers.size | |
528 assert_equal [1, 3], issue.watcher_user_ids.sort | |
529 end | |
530 | |
531 context "POST /issues.xml with failure" do | |
532 should "have an errors tag" do | |
533 assert_no_difference('Issue.count') do | |
534 post '/issues.xml', {:issue => {:project_id => 1}}, credentials('jsmith') | |
535 end | |
536 | |
537 assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"} | |
538 end | |
539 end | |
540 | |
541 context "POST /issues.json" do | |
542 should_allow_api_authentication(:post, | |
543 '/issues.json', | |
544 {:issue => {:project_id => 1, :subject => 'API test', | |
545 :tracker_id => 2, :status_id => 3}}, | |
546 {:success_code => :created}) | |
547 | |
548 should "create an issue with the attributes" do | |
549 assert_difference('Issue.count') do | |
550 post '/issues.json', | |
551 {:issue => {:project_id => 1, :subject => 'API test', | |
552 :tracker_id => 2, :status_id => 3}}, | |
553 credentials('jsmith') | |
554 end | |
555 | |
556 issue = Issue.order('id DESC').first | |
557 assert_equal 1, issue.project_id | |
558 assert_equal 2, issue.tracker_id | |
559 assert_equal 3, issue.status_id | |
560 assert_equal 'API test', issue.subject | |
561 end | |
562 | |
563 end | |
564 | |
565 context "POST /issues.json with failure" do | |
566 should "have an errors element" do | |
567 assert_no_difference('Issue.count') do | |
568 post '/issues.json', {:issue => {:project_id => 1}}, credentials('jsmith') | |
569 end | |
570 | |
571 json = ActiveSupport::JSON.decode(response.body) | |
572 assert json['errors'].include?("Subject can't be blank") | |
573 end | |
574 end | |
575 | |
576 # Issue 6 is on a private project | |
577 context "PUT /issues/6.xml" do | |
578 setup do | |
579 @parameters = {:issue => {:subject => 'API update', :notes => 'A new note'}} | |
580 end | |
581 | |
582 should_allow_api_authentication(:put, | |
583 '/issues/6.xml', | |
584 {:issue => {:subject => 'API update', :notes => 'A new note'}}, | |
585 {:success_code => :ok}) | |
586 | |
587 should "not create a new issue" do | |
588 assert_no_difference('Issue.count') do | |
589 put '/issues/6.xml', @parameters, credentials('jsmith') | |
590 end | |
591 end | |
592 | |
593 should "create a new journal" do | |
594 assert_difference('Journal.count') do | |
595 put '/issues/6.xml', @parameters, credentials('jsmith') | |
596 end | |
597 end | |
598 | |
599 should "add the note to the journal" do | |
600 put '/issues/6.xml', @parameters, credentials('jsmith') | |
601 | |
602 journal = Journal.last | |
603 assert_equal "A new note", journal.notes | |
604 end | |
605 | |
606 should "update the issue" do | |
607 put '/issues/6.xml', @parameters, credentials('jsmith') | |
608 | |
609 issue = Issue.find(6) | |
610 assert_equal "API update", issue.subject | |
611 end | |
612 | |
613 end | |
614 | |
615 context "PUT /issues/3.xml with custom fields" do | |
616 setup do | |
617 @parameters = { | |
618 :issue => {:custom_fields => [{'id' => '1', 'value' => 'PostgreSQL' }, | |
619 {'id' => '2', 'value' => '150'}]} | |
620 } | |
621 end | |
622 | |
623 should "update custom fields" do | |
624 assert_no_difference('Issue.count') do | |
625 put '/issues/3.xml', @parameters, credentials('jsmith') | |
626 end | |
627 | |
628 issue = Issue.find(3) | |
629 assert_equal '150', issue.custom_value_for(2).value | |
630 assert_equal 'PostgreSQL', issue.custom_value_for(1).value | |
631 end | |
632 end | |
633 | |
634 context "PUT /issues/3.xml with multi custom fields" do | |
635 setup do | |
636 field = CustomField.find(1) | |
637 field.update_attribute :multiple, true | |
638 @parameters = { | |
639 :issue => {:custom_fields => [{'id' => '1', 'value' => ['MySQL', 'PostgreSQL'] }, | |
640 {'id' => '2', 'value' => '150'}]} | |
641 } | |
642 end | |
643 | |
644 should "update custom fields" do | |
645 assert_no_difference('Issue.count') do | |
646 put '/issues/3.xml', @parameters, credentials('jsmith') | |
647 end | |
648 | |
649 issue = Issue.find(3) | |
650 assert_equal '150', issue.custom_value_for(2).value | |
651 assert_equal ['MySQL', 'PostgreSQL'], issue.custom_field_value(1).sort | |
652 end | |
653 end | |
654 | |
655 context "PUT /issues/3.xml with project change" do | |
656 setup do | |
657 @parameters = {:issue => {:project_id => 2, :subject => 'Project changed'}} | |
658 end | |
659 | |
660 should "update project" do | |
661 assert_no_difference('Issue.count') do | |
662 put '/issues/3.xml', @parameters, credentials('jsmith') | |
663 end | |
664 | |
665 issue = Issue.find(3) | |
666 assert_equal 2, issue.project_id | |
667 assert_equal 'Project changed', issue.subject | |
668 end | |
669 end | |
670 | |
671 context "PUT /issues/6.xml with failed update" do | |
672 setup do | |
673 @parameters = {:issue => {:subject => ''}} | |
674 end | |
675 | |
676 should "not create a new issue" do | |
677 assert_no_difference('Issue.count') do | |
678 put '/issues/6.xml', @parameters, credentials('jsmith') | |
679 end | |
680 end | |
681 | |
682 should "not create a new journal" do | |
683 assert_no_difference('Journal.count') do | |
684 put '/issues/6.xml', @parameters, credentials('jsmith') | |
685 end | |
686 end | |
687 | |
688 should "have an errors tag" do | |
689 put '/issues/6.xml', @parameters, credentials('jsmith') | |
690 | |
691 assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"} | |
692 end | |
693 end | |
694 | |
695 context "PUT /issues/6.json" do | |
696 setup do | |
697 @parameters = {:issue => {:subject => 'API update', :notes => 'A new note'}} | |
698 end | |
699 | |
700 should_allow_api_authentication(:put, | |
701 '/issues/6.json', | |
702 {:issue => {:subject => 'API update', :notes => 'A new note'}}, | |
703 {:success_code => :ok}) | |
704 | |
705 should "update the issue" do | |
706 assert_no_difference('Issue.count') do | |
707 assert_difference('Journal.count') do | |
708 put '/issues/6.json', @parameters, credentials('jsmith') | |
709 | |
710 assert_response :ok | |
711 assert_equal '', response.body | |
712 end | |
713 end | |
714 | |
715 issue = Issue.find(6) | |
716 assert_equal "API update", issue.subject | |
717 journal = Journal.last | |
718 assert_equal "A new note", journal.notes | |
719 end | |
720 end | |
721 | |
722 context "PUT /issues/6.json with failed update" do | |
723 should "return errors" do | |
724 assert_no_difference('Issue.count') do | |
725 assert_no_difference('Journal.count') do | |
726 put '/issues/6.json', {:issue => {:subject => ''}}, credentials('jsmith') | |
727 | |
728 assert_response :unprocessable_entity | |
729 end | |
730 end | |
731 | |
732 json = ActiveSupport::JSON.decode(response.body) | |
733 assert json['errors'].include?("Subject can't be blank") | |
734 end | |
735 end | |
736 | |
737 context "DELETE /issues/1.xml" do | |
738 should_allow_api_authentication(:delete, | |
739 '/issues/6.xml', | |
740 {}, | |
741 {:success_code => :ok}) | |
742 | |
743 should "delete the issue" do | |
744 assert_difference('Issue.count', -1) do | |
745 delete '/issues/6.xml', {}, credentials('jsmith') | |
746 | |
747 assert_response :ok | |
748 assert_equal '', response.body | |
749 end | |
750 | |
751 assert_nil Issue.find_by_id(6) | |
752 end | |
753 end | |
754 | |
755 context "DELETE /issues/1.json" do | |
756 should_allow_api_authentication(:delete, | |
757 '/issues/6.json', | |
758 {}, | |
759 {:success_code => :ok}) | |
760 | |
761 should "delete the issue" do | |
762 assert_difference('Issue.count', -1) do | |
763 delete '/issues/6.json', {}, credentials('jsmith') | |
764 | |
765 assert_response :ok | |
766 assert_equal '', response.body | |
767 end | |
768 | |
769 assert_nil Issue.find_by_id(6) | |
770 end | |
771 end | |
772 | |
773 test "POST /issues/:id/watchers.xml should add watcher" do | |
774 assert_difference 'Watcher.count' do | |
775 post '/issues/1/watchers.xml', {:user_id => 3}, credentials('jsmith') | |
776 | |
777 assert_response :ok | |
778 assert_equal '', response.body | |
779 end | |
780 watcher = Watcher.order('id desc').first | |
781 assert_equal Issue.find(1), watcher.watchable | |
782 assert_equal User.find(3), watcher.user | |
783 end | |
784 | |
785 test "DELETE /issues/:id/watchers/:user_id.xml should remove watcher" do | |
786 Watcher.create!(:user_id => 3, :watchable => Issue.find(1)) | |
787 | |
788 assert_difference 'Watcher.count', -1 do | |
789 delete '/issues/1/watchers/3.xml', {}, credentials('jsmith') | |
790 | |
791 assert_response :ok | |
792 assert_equal '', response.body | |
793 end | |
794 assert_equal false, Issue.find(1).watched_by?(User.find(3)) | |
795 end | |
796 | |
797 def test_create_issue_with_uploaded_file | |
798 set_tmp_attachments_directory | |
799 # upload the file | |
800 assert_difference 'Attachment.count' do | |
801 post '/uploads.xml', 'test_create_with_upload', | |
802 {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith')) | |
803 assert_response :created | |
804 end | |
805 xml = Hash.from_xml(response.body) | |
806 token = xml['upload']['token'] | |
807 attachment = Attachment.order('id DESC').first | |
808 | |
809 # create the issue with the upload's token | |
810 assert_difference 'Issue.count' do | |
811 post '/issues.xml', | |
812 {:issue => {:project_id => 1, :subject => 'Uploaded file', | |
813 :uploads => [{:token => token, :filename => 'test.txt', | |
814 :content_type => 'text/plain'}]}}, | |
815 credentials('jsmith') | |
816 assert_response :created | |
817 end | |
818 issue = Issue.order('id DESC').first | |
819 assert_equal 1, issue.attachments.count | |
820 assert_equal attachment, issue.attachments.first | |
821 | |
822 attachment.reload | |
823 assert_equal 'test.txt', attachment.filename | |
824 assert_equal 'text/plain', attachment.content_type | |
825 assert_equal 'test_create_with_upload'.size, attachment.filesize | |
826 assert_equal 2, attachment.author_id | |
827 | |
828 # get the issue with its attachments | |
829 get "/issues/#{issue.id}.xml", :include => 'attachments' | |
830 assert_response :success | |
831 xml = Hash.from_xml(response.body) | |
832 attachments = xml['issue']['attachments'] | |
833 assert_kind_of Array, attachments | |
834 assert_equal 1, attachments.size | |
835 url = attachments.first['content_url'] | |
836 assert_not_nil url | |
837 | |
838 # download the attachment | |
839 get url | |
840 assert_response :success | |
841 end | |
842 | |
843 def test_update_issue_with_uploaded_file | |
844 set_tmp_attachments_directory | |
845 # upload the file | |
846 assert_difference 'Attachment.count' do | |
847 post '/uploads.xml', 'test_upload_with_upload', | |
848 {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith')) | |
849 assert_response :created | |
850 end | |
851 xml = Hash.from_xml(response.body) | |
852 token = xml['upload']['token'] | |
853 attachment = Attachment.order('id DESC').first | |
854 | |
855 # update the issue with the upload's token | |
856 assert_difference 'Journal.count' do | |
857 put '/issues/1.xml', | |
858 {:issue => {:notes => 'Attachment added', | |
859 :uploads => [{:token => token, :filename => 'test.txt', | |
860 :content_type => 'text/plain'}]}}, | |
861 credentials('jsmith') | |
862 assert_response :ok | |
863 assert_equal '', @response.body | |
864 end | |
865 | |
866 issue = Issue.find(1) | |
867 assert_include attachment, issue.attachments | |
868 end | |
869 end |