2010-01-13 19:29:19 +00:00
# Redmine - project management software
2016-03-13 10:30:10 +00:00
# Copyright (C) 2006-2016 Jean-Philippe Lang
2010-01-13 19:29:19 +00:00
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
2011-09-01 00:49:30 +00:00
#
2010-01-13 19:29:19 +00:00
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
2011-09-01 00:49:30 +00:00
#
2010-01-13 19:29:19 +00:00
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
2010-12-12 23:24:34 +00:00
require File . expand_path ( '../../../test_helper' , __FILE__ )
2010-01-13 19:29:19 +00:00
2013-01-22 18:26:04 +00:00
class Redmine :: ApiTest :: IssuesTest < Redmine :: ApiTest :: Base
2010-01-13 19:29:19 +00:00
fixtures :projects ,
:users ,
:roles ,
:members ,
:member_roles ,
:issues ,
:issue_statuses ,
2012-10-09 10:14:14 +00:00
:issue_relations ,
2010-01-13 19:29:19 +00:00
:versions ,
:trackers ,
:projects_trackers ,
:issue_categories ,
:enabled_modules ,
:enumerations ,
:attachments ,
:workflows ,
:custom_fields ,
:custom_values ,
:custom_fields_projects ,
:custom_fields_trackers ,
:time_entries ,
:journals ,
:journal_details ,
2011-07-18 20:53:10 +00:00
:queries ,
:attachments
2010-01-13 19:29:19 +00:00
2014-11-23 20:25:46 +00:00
test " GET /issues.xml should contain metadata " do
get '/issues.xml'
2016-07-21 17:50:00 +00:00
assert_select 'issues[type=array][total_count][limit="25"][offset="0"]'
2014-11-23 20:25:46 +00:00
end
2011-09-01 00:49:30 +00:00
2014-11-23 20:25:46 +00:00
test " GET /issues.xml with nometa param should not contain metadata " do
get '/issues.xml?nometa=1'
assert_select 'issues[type=array]:not([total_count]):not([limit]):not([offset])'
end
2011-09-01 00:49:30 +00:00
2014-11-23 20:25:46 +00:00
test " GET /issues.xml with nometa header should not contain metadata " do
get '/issues.xml' , { } , { 'X-Redmine-Nometa' = > '1' }
assert_select 'issues[type=array]:not([total_count]):not([limit]):not([offset])'
end
2011-09-01 00:49:30 +00:00
2014-11-23 20:25:46 +00:00
test " GET /issues.xml with offset and limit " do
get '/issues.xml?offset=2&limit=3'
2016-07-21 17:50:00 +00:00
assert_select 'issues[type=array][total_count][limit="3"][offset="2"]'
2014-11-23 20:25:46 +00:00
assert_select 'issues issue' , 3
end
2010-12-11 13:13:49 +00:00
2014-11-23 20:25:46 +00:00
test " GET /issues.xml with relations " do
get '/issues.xml?include=relations'
2011-09-01 00:49:30 +00:00
2014-11-23 20:25:46 +00:00
assert_response :success
assert_equal 'application/xml' , @response . content_type
2010-12-11 13:13:49 +00:00
2015-01-17 17:02:55 +00:00
assert_select 'issue id' , :text = > '3' do
2014-11-23 20:25:46 +00:00
assert_select '~ relations relation' , 1
assert_select '~ relations relation[id="2"][issue_id="2"][issue_to_id="3"][relation_type=relates]'
2010-12-11 13:13:49 +00:00
end
2011-09-01 00:49:30 +00:00
2015-01-17 17:02:55 +00:00
assert_select 'issue id' , :text = > '1' do
2014-11-23 20:25:46 +00:00
assert_select '~ relations'
assert_select '~ relations relation' , 0
end
end
2011-09-01 00:49:30 +00:00
2017-03-03 17:18:58 +00:00
test " GET /issues.xml with attachments " do
get '/issues.xml?include=attachments'
assert_response :success
assert_equal 'application/xml' , @response . content_type
assert_select 'issue id' , :text = > '3' do
assert_select '~ attachments attachment' , 4
end
assert_select 'issue id' , :text = > '1' do
assert_select '~ attachments'
assert_select '~ attachments attachment' , 0
end
end
2014-11-23 20:25:46 +00:00
test " GET /issues.xml with invalid query params " do
get '/issues.xml' , { :f = > [ 'start_date' ] , :op = > { :start_date = > '=' } }
2014-11-22 09:38:21 +00:00
2014-11-23 20:25:46 +00:00
assert_response :unprocessable_entity
assert_equal 'application/xml' , @response . content_type
2014-12-21 12:39:48 +00:00
assert_select 'errors error' , :text = > " Start date cannot be blank "
2014-11-23 20:25:46 +00:00
end
2011-09-01 00:49:30 +00:00
2014-11-23 20:25:46 +00:00
test " GET /issues.xml with custom field filter " do
get '/issues.xml' ,
{ :set_filter = > 1 , :f = > [ 'cf_1' ] , :op = > { :cf_1 = > '=' } , :v = > { :cf_1 = > [ 'MySQL' ] } }
2011-09-01 00:49:30 +00:00
2014-11-23 20:25:46 +00:00
expected_ids = Issue . visible .
joins ( :custom_values ) .
where ( :custom_values = > { :custom_field_id = > 1 , :value = > 'MySQL' } ) . map ( & :id )
assert expected_ids . any?
2011-10-05 22:03:19 +00:00
2014-11-23 20:25:46 +00:00
assert_select 'issues > issue > id' , :count = > expected_ids . count do | ids |
ids . each { | id | assert expected_ids . delete ( id . children . first . content . to_i ) }
2011-10-05 22:03:19 +00:00
end
2014-11-23 20:25:46 +00:00
end
2011-10-05 22:03:19 +00:00
2014-11-23 20:25:46 +00:00
test " GET /issues.xml with custom field filter (shorthand method) " do
get '/issues.xml' , { :cf_1 = > 'MySQL' }
2011-10-05 22:03:19 +00:00
2014-11-23 20:25:46 +00:00
expected_ids = Issue . visible .
joins ( :custom_values ) .
where ( :custom_values = > { :custom_field_id = > 1 , :value = > 'MySQL' } ) . map ( & :id )
assert expected_ids . any?
2011-10-05 22:03:19 +00:00
2014-11-23 20:25:46 +00:00
assert_select 'issues > issue > id' , :count = > expected_ids . count do | ids |
ids . each { | id | assert expected_ids . delete ( id . children . first . content . to_i ) }
2011-10-05 22:03:19 +00:00
end
2010-01-13 19:29:19 +00:00
end
2010-06-05 03:52:59 +00:00
2014-09-13 11:22:49 +00:00
def test_index_should_include_issue_attributes
get '/issues.xml'
assert_select 'issues>issue>is_private' , :text = > 'false'
end
2014-01-03 15:54:49 +00:00
def test_index_should_allow_timestamp_filtering
Issue . delete_all
Issue . generate! ( :subject = > '1' ) . update_column ( :updated_on , Time . parse ( " 2014-01-02T10:25:00Z " ) )
Issue . generate! ( :subject = > '2' ) . update_column ( :updated_on , Time . parse ( " 2014-01-02T12:13:00Z " ) )
get '/issues.xml' ,
{ :set_filter = > 1 , :f = > [ 'updated_on' ] , :op = > { :updated_on = > '<=' } ,
:v = > { :updated_on = > [ '2014-01-02T12:00:00Z' ] } }
assert_select 'issues>issue' , :count = > 1
assert_select 'issues>issue>subject' , :text = > '1'
get '/issues.xml' ,
{ :set_filter = > 1 , :f = > [ 'updated_on' ] , :op = > { :updated_on = > '>=' } ,
:v = > { :updated_on = > [ '2014-01-02T12:00:00Z' ] } }
assert_select 'issues>issue' , :count = > 1
assert_select 'issues>issue>subject' , :text = > '2'
get '/issues.xml' ,
{ :set_filter = > 1 , :f = > [ 'updated_on' ] , :op = > { :updated_on = > '>=' } ,
:v = > { :updated_on = > [ '2014-01-02T08:00:00Z' ] } }
assert_select 'issues>issue' , :count = > 2
end
2014-11-23 20:25:46 +00:00
test " GET /issues.xml with filter " do
get '/issues.xml?status_id=5'
2010-06-05 03:52:59 +00:00
2014-11-23 20:25:46 +00:00
expected_ids = Issue . visible . where ( :status_id = > 5 ) . map ( & :id )
assert expected_ids . any?
2011-10-05 22:03:19 +00:00
2014-11-23 20:25:46 +00:00
assert_select 'issues > issue > id' , :count = > expected_ids . count do | ids |
ids . each { | id | assert expected_ids . delete ( id . children . first . content . to_i ) }
2010-06-05 03:52:53 +00:00
end
2010-01-13 19:29:19 +00:00
end
2010-06-05 03:52:53 +00:00
2014-11-23 20:25:46 +00:00
test " GET /issues.json with filter " do
get '/issues.json?status_id=5'
2010-06-05 03:52:59 +00:00
2014-11-23 20:25:46 +00:00
json = ActiveSupport :: JSON . decode ( response . body )
status_ids_used = json [ 'issues' ] . collect { | j | j [ 'status' ] [ 'id' ] }
assert_equal 3 , status_ids_used . length
assert status_ids_used . all? { | id | id == 5 }
2010-06-05 03:52:59 +00:00
end
2014-11-23 20:25:46 +00:00
test " GET /issues/:id.xml with journals " do
2016-05-16 06:25:11 +00:00
Journal . find ( 2 ) . update_attribute ( :private_notes , true )
get '/issues/1.xml?include=journals' , { } , credentials ( 'jsmith' )
2010-06-05 03:52:53 +00:00
2014-11-23 20:25:46 +00:00
assert_select 'issue journals[type=array]' do
assert_select 'journal[id="1"]' do
2016-05-16 06:25:11 +00:00
assert_select 'private_notes' , :text = > 'false'
2014-11-23 20:25:46 +00:00
assert_select 'details[type=array]' do
assert_select 'detail[name=status_id]' do
assert_select 'old_value' , :text = > '1'
assert_select 'new_value' , :text = > '2'
2014-11-22 09:38:21 +00:00
end
2010-12-10 12:22:37 +00:00
end
end
2016-05-16 06:25:11 +00:00
assert_select 'journal[id="2"]' do
assert_select 'private_notes' , :text = > 'true'
assert_select 'details[type=array]'
end
2010-12-10 12:22:37 +00:00
end
2014-11-23 20:25:46 +00:00
end
2011-09-01 00:49:30 +00:00
2015-02-16 17:57:52 +00:00
test " GET /issues/:id.xml with journals should format timestamps in ISO 8601 " do
get '/issues/1.xml?include=journals'
iso_date = / ^ \ d{4}- \ d{2}- \ d{2}T \ d{2}: \ d{2}: \ d{2}Z$ /
assert_select 'issue>created_on' , :text = > iso_date
assert_select 'issue>updated_on' , :text = > iso_date
assert_select 'issue journal>created_on' , :text = > iso_date
end
2014-11-23 20:25:46 +00:00
test " GET /issues/:id.xml with custom fields " do
get '/issues/3.xml'
2011-09-01 00:49:30 +00:00
2014-11-23 20:25:46 +00:00
assert_select 'issue custom_fields[type=array]' do
assert_select 'custom_field[id="1"]' do
assert_select 'value' , :text = > 'MySQL'
2010-12-10 10:12:19 +00:00
end
end
2014-11-23 20:25:46 +00:00
assert_nothing_raised do
Hash . from_xml ( response . body ) . to_xml
end
end
2011-09-01 00:49:30 +00:00
2014-11-23 20:25:46 +00:00
test " GET /issues/:id.xml with multi custom fields " do
field = CustomField . find ( 1 )
field . update_attribute :multiple , true
issue = Issue . find ( 3 )
issue . custom_field_values = { 1 = > [ 'MySQL' , 'Oracle' ] }
issue . save!
2014-11-22 09:38:21 +00:00
2014-11-23 20:25:46 +00:00
get '/issues/3.xml'
assert_response :success
2012-01-29 20:51:48 +00:00
2014-11-23 20:25:46 +00:00
assert_select 'issue custom_fields[type=array]' do
assert_select 'custom_field[id="1"]' do
assert_select 'value[type=array] value' , 2
2012-01-29 20:51:48 +00:00
end
end
2014-11-23 20:25:46 +00:00
xml = Hash . from_xml ( response . body )
custom_fields = xml [ 'issue' ] [ 'custom_fields' ]
assert_kind_of Array , custom_fields
field = custom_fields . detect { | f | f [ 'id' ] == '1' }
assert_kind_of Hash , field
assert_equal [ 'MySQL' , 'Oracle' ] , field [ 'value' ] . sort
end
2012-01-29 20:51:48 +00:00
2014-11-23 20:25:46 +00:00
test " GET /issues/:id.json with multi custom fields " do
field = CustomField . find ( 1 )
field . update_attribute :multiple , true
issue = Issue . find ( 3 )
issue . custom_field_values = { 1 = > [ 'MySQL' , 'Oracle' ] }
issue . save!
get '/issues/3.json'
assert_response :success
json = ActiveSupport :: JSON . decode ( response . body )
custom_fields = json [ 'issue' ] [ 'custom_fields' ]
assert_kind_of Array , custom_fields
field = custom_fields . detect { | f | f [ 'id' ] == 1 }
assert_kind_of Hash , field
assert_equal [ 'MySQL' , 'Oracle' ] , field [ 'value' ] . sort
end
2012-01-29 20:51:48 +00:00
2014-11-23 20:25:46 +00:00
test " GET /issues/:id.xml with empty value for multi custom field " do
field = CustomField . find ( 1 )
field . update_attribute :multiple , true
issue = Issue . find ( 3 )
issue . custom_field_values = { 1 = > [ '' ] }
issue . save!
2014-11-22 09:38:21 +00:00
2014-11-23 20:25:46 +00:00
get '/issues/3.xml'
2012-01-29 20:51:48 +00:00
2014-11-23 20:25:46 +00:00
assert_select 'issue custom_fields[type=array]' do
assert_select 'custom_field[id="1"]' do
assert_select 'value[type=array]:empty'
2012-01-29 20:51:48 +00:00
end
end
2014-11-23 20:25:46 +00:00
xml = Hash . from_xml ( response . body )
custom_fields = xml [ 'issue' ] [ 'custom_fields' ]
assert_kind_of Array , custom_fields
field = custom_fields . detect { | f | f [ 'id' ] == '1' }
assert_kind_of Hash , field
assert_equal [ ] , field [ 'value' ]
end
2012-01-29 20:51:48 +00:00
2014-11-23 20:25:46 +00:00
test " GET /issues/:id.json with empty value for multi custom field " do
field = CustomField . find ( 1 )
field . update_attribute :multiple , true
issue = Issue . find ( 3 )
issue . custom_field_values = { 1 = > [ '' ] }
issue . save!
get '/issues/3.json'
assert_response :success
json = ActiveSupport :: JSON . decode ( response . body )
custom_fields = json [ 'issue' ] [ 'custom_fields' ]
assert_kind_of Array , custom_fields
field = custom_fields . detect { | f | f [ 'id' ] == 1 }
assert_kind_of Hash , field
assert_equal [ ] , field [ 'value' ] . sort
end
test " GET /issues/:id.xml with attachments " do
get '/issues/3.xml?include=attachments'
2011-09-01 00:49:30 +00:00
2014-11-23 20:25:46 +00:00
assert_select 'issue attachments[type=array]' do
2015-01-24 11:27:28 +00:00
assert_select 'attachment' , 4
assert_select 'attachment id' , :text = > '1' do
assert_select '~ filename' , :text = > 'error281.txt'
assert_select '~ content_url' , :text = > 'http://www.example.com/attachments/download/1/error281.txt'
2010-12-04 13:02:14 +00:00
end
2014-11-23 20:25:46 +00:00
end
end
2011-09-01 00:49:30 +00:00
2014-11-23 20:25:46 +00:00
test " GET /issues/:id.xml with subtasks " do
issue = Issue . generate_with_descendants! ( :project_id = > 1 )
get " /issues/ #{ issue . id } .xml?include=children "
2011-09-01 00:49:30 +00:00
2015-01-17 17:02:55 +00:00
assert_select 'issue id' , :text = > issue . id . to_s do
assert_select '~ children[type=array] > issue' , 2
assert_select '~ children[type=array] > issue > children' , 1
2010-12-04 13:02:14 +00:00
end
end
2010-06-05 03:52:59 +00:00
2014-11-23 20:25:46 +00:00
test " GET /issues/:id.json with subtasks " do
issue = Issue . generate_with_descendants! ( :project_id = > 1 )
get " /issues/ #{ issue . id } .json?include=children "
json = ActiveSupport :: JSON . decode ( response . body )
assert_equal 2 , json [ 'issue' ] [ 'children' ] . size
assert_equal 1 , json [ 'issue' ] [ 'children' ] . select { | child | child . key? ( 'children' ) } . size
end
2017-04-05 16:10:16 +00:00
test " GET /issues/:id.json with no spent time should return floats " do
issue = Issue . generate!
get " /issues/ #{ issue . id } .json "
json = ActiveSupport :: JSON . decode ( response . body )
assert_kind_of Float , json [ 'issue' ] [ 'spent_hours' ]
assert_kind_of Float , json [ 'issue' ] [ 'total_spent_hours' ]
end
2014-09-13 11:22:49 +00:00
def test_show_should_include_issue_attributes
get '/issues/1.xml'
assert_select 'issue>is_private' , :text = > 'false'
end
2013-01-30 20:51:21 +00:00
test " GET /issues/:id.xml?include=watchers should include watchers " do
Watcher . create! ( :user_id = > 3 , :watchable = > Issue . find ( 1 ) )
get '/issues/1.xml?include=watchers' , { } , credentials ( 'jsmith' )
assert_response :ok
assert_equal 'application/xml' , response . content_type
assert_select 'issue' do
assert_select 'watchers' , Issue . find ( 1 ) . watchers . count
assert_select 'watchers' do
2015-01-17 17:02:55 +00:00
assert_select 'user[id="3"]'
2013-01-30 20:51:21 +00:00
end
end
end
2015-11-04 18:17:07 +00:00
test " GET /issues/:id.xml should not disclose associated changesets from projects the user has no access to " do
project = Project . generate! ( :is_public = > false )
repository = Repository :: Subversion . create! ( :project = > project , :url = > " svn://localhost " )
Issue . find ( 1 ) . changesets << Changeset . generate! ( :repository = > repository )
assert Issue . find ( 1 ) . changesets . any?
get '/issues/1.xml?include=changesets' , { } , credentials ( 'jsmith' )
# the user jsmith has no permission to view the associated changeset
assert_select 'issue changesets[type=array]' do
assert_select 'changeset' , 0
end
end
2016-03-19 09:05:12 +00:00
test " GET /issues/:id.xml should contains total_estimated_hours and total_spent_hours " do
parent = Issue . find ( 3 )
2016-12-12 21:36:14 +00:00
parent . update_columns :estimated_hours = > 2 . 0
2016-03-19 09:05:12 +00:00
child = Issue . generate! ( :parent_issue_id = > parent . id , :estimated_hours = > 3 . 0 )
TimeEntry . create! ( :project = > child . project , :issue = > child , :user = > child . author , :spent_on = > child . author . today ,
:hours = > '2.5' , :comments = > '' , :activity_id = > TimeEntryActivity . first . id )
get '/issues/3.xml'
assert_equal 'application/xml' , response . content_type
assert_select 'issue' do
assert_select 'estimated_hours' , parent . estimated_hours . to_s
assert_select 'total_estimated_hours' , ( parent . estimated_hours . to_f + 3 . 0 ) . to_s
assert_select 'spent_hours' , parent . spent_hours . to_s
assert_select 'total_spent_hours' , ( parent . spent_hours . to_f + 2 . 5 ) . to_s
end
end
test " GET /issues/:id.xml should contains total_estimated_hours, and should not contains spent_hours and total_spent_hours when permission does not exists " do
parent = Issue . find ( 3 )
2016-12-12 21:36:14 +00:00
parent . update_columns :estimated_hours = > 2 . 0
2016-03-19 09:05:12 +00:00
child = Issue . generate! ( :parent_issue_id = > parent . id , :estimated_hours = > 3 . 0 )
# remove permission!
Role . anonymous . remove_permission! :view_time_entries
#Role.all.each { |role| role.remove_permission! :view_time_entries }
get '/issues/3.xml'
assert_equal 'application/xml' , response . content_type
assert_select 'issue' do
assert_select 'estimated_hours' , parent . estimated_hours . to_s
assert_select 'total_estimated_hours' , ( parent . estimated_hours . to_f + 3 . 0 ) . to_s
assert_select 'spent_hours' , false
assert_select 'total_spent_hours' , false
end
end
2017-01-29 10:31:04 +00:00
test " GET /issues/:id.xml should contains visible spent_hours only " do
user = User . find_by_login ( 'jsmith' )
Role . find ( 1 ) . update ( :time_entries_visibility = > 'own' )
parent = Issue . find ( 3 )
child = Issue . generate! ( :parent_issue_id = > parent . id )
TimeEntry . generate! ( :user = > user , :hours = > 5 . 5 , :issue_id = > parent . id )
TimeEntry . generate! ( :user = > user , :hours = > 2 , :issue_id = > child . id )
TimeEntry . generate! ( :user = > User . find ( 1 ) , :hours = > 100 , :issue_id = > child . id )
get '/issues/3.xml' , { } , credentials ( user . login )
assert_equal 'application/xml' , response . content_type
assert_select 'issue' do
assert_select 'spent_hours' , '5.5'
assert_select 'total_spent_hours' , '7.5'
end
end
2016-03-19 09:05:12 +00:00
test " GET /issues/:id.json should contains total_estimated_hours and total_spent_hours " do
parent = Issue . find ( 3 )
2016-12-12 21:36:14 +00:00
parent . update_columns :estimated_hours = > 2 . 0
2016-03-19 09:05:12 +00:00
child = Issue . generate! ( :parent_issue_id = > parent . id , :estimated_hours = > 3 . 0 )
TimeEntry . create! ( :project = > child . project , :issue = > child , :user = > child . author , :spent_on = > child . author . today ,
:hours = > '2.5' , :comments = > '' , :activity_id = > TimeEntryActivity . first . id )
get '/issues/3.json'
assert_equal 'application/json' , response . content_type
json = ActiveSupport :: JSON . decode ( response . body )
assert_equal parent . estimated_hours , json [ 'issue' ] [ 'estimated_hours' ]
assert_equal ( parent . estimated_hours . to_f + 3 . 0 ) , json [ 'issue' ] [ 'total_estimated_hours' ]
assert_equal parent . spent_hours , json [ 'issue' ] [ 'spent_hours' ]
assert_equal ( parent . spent_hours . to_f + 2 . 5 ) , json [ 'issue' ] [ 'total_spent_hours' ]
end
test " GET /issues/:id.json should contains total_estimated_hours, and should not contains spent_hours and total_spent_hours when permission does not exists " do
parent = Issue . find ( 3 )
2016-12-12 21:36:14 +00:00
parent . update_columns :estimated_hours = > 2 . 0
2016-03-19 09:05:12 +00:00
child = Issue . generate! ( :parent_issue_id = > parent . id , :estimated_hours = > 3 . 0 )
# remove permission!
Role . anonymous . remove_permission! :view_time_entries
#Role.all.each { |role| role.remove_permission! :view_time_entries }
get '/issues/3.json'
assert_equal 'application/json' , response . content_type
json = ActiveSupport :: JSON . decode ( response . body )
assert_equal parent . estimated_hours , json [ 'issue' ] [ 'estimated_hours' ]
assert_equal ( parent . estimated_hours . to_f + 3 . 0 ) , json [ 'issue' ] [ 'total_estimated_hours' ]
2016-12-11 15:26:41 +00:00
assert_nil json [ 'issue' ] [ 'spent_hours' ]
assert_nil json [ 'issue' ] [ 'total_spent_hours' ]
2016-03-19 09:05:12 +00:00
end
2017-01-29 10:31:04 +00:00
test " GET /issues/:id.json should contains visible spent_hours only " do
user = User . find_by_login ( 'jsmith' )
Role . find ( 1 ) . update ( :time_entries_visibility = > 'own' )
parent = Issue . find ( 3 )
child = Issue . generate! ( :parent_issue_id = > parent . id )
TimeEntry . generate! ( :user = > user , :hours = > 5 . 5 , :issue_id = > parent . id )
TimeEntry . generate! ( :user = > user , :hours = > 2 , :issue_id = > child . id )
TimeEntry . generate! ( :user = > User . find ( 1 ) , :hours = > 100 , :issue_id = > child . id )
get '/issues/3.json' , { } , credentials ( user . login )
assert_equal 'application/json' , response . content_type
json = ActiveSupport :: JSON . decode ( response . body )
assert_equal 5 . 5 , json [ 'issue' ] [ 'spent_hours' ]
assert_equal 7 . 5 , json [ 'issue' ] [ 'total_spent_hours' ]
end
2014-11-23 20:25:46 +00:00
test " POST /issues.xml should create an issue with the attributes " do
2014-12-22 13:46:31 +00:00
payload = <<-XML
< ? xml version = " 1.0 " encoding = " UTF-8 " ?>
< issue >
< project_id > 1 < / project_id>
< tracker_id > 2 < / tracker_id>
< status_id > 3 < / status_id>
< subject > API test < / subject>
< / issue>
XML
2014-11-23 20:25:46 +00:00
assert_difference ( 'Issue.count' ) do
2014-12-22 13:46:31 +00:00
post '/issues.xml' , payload , { " CONTENT_TYPE " = > 'application/xml' } . merge ( credentials ( 'jsmith' ) )
2014-11-23 20:25:46 +00:00
end
issue = Issue . order ( 'id DESC' ) . first
assert_equal 1 , issue . project_id
assert_equal 2 , issue . tracker_id
assert_equal 3 , issue . status_id
assert_equal 'API test' , issue . subject
assert_response :created
assert_equal 'application/xml' , @response . content_type
assert_select 'issue > id' , :text = > issue . id . to_s
2010-01-13 19:29:19 +00:00
end
2011-09-01 00:49:30 +00:00
2013-01-30 20:51:21 +00:00
test " POST /issues.xml with watcher_user_ids should create issue with watchers " do
assert_difference ( 'Issue.count' ) do
post '/issues.xml' ,
{ :issue = > { :project_id = > 1 , :subject = > 'Watchers' ,
:tracker_id = > 2 , :status_id = > 3 , :watcher_user_ids = > [ 3 , 1 ] } } , credentials ( 'jsmith' )
assert_response :created
end
issue = Issue . order ( 'id desc' ) . first
assert_equal 2 , issue . watchers . size
assert_equal [ 1 , 3 ] , issue . watcher_user_ids . sort
end
2014-11-23 20:25:46 +00:00
test " POST /issues.xml with failure should return errors " do
assert_no_difference ( 'Issue.count' ) do
post '/issues.xml' , { :issue = > { :project_id = > 1 } } , credentials ( 'jsmith' )
2010-06-05 03:52:59 +00:00
end
2011-09-01 00:49:30 +00:00
2014-12-21 12:39:48 +00:00
assert_select 'errors error' , :text = > " Subject cannot be blank "
2010-06-05 03:52:59 +00:00
end
2011-09-01 00:49:30 +00:00
2014-11-23 20:25:46 +00:00
test " POST /issues.json should create an issue with the attributes " do
2014-12-22 13:46:31 +00:00
payload = <<-JSON
{
" issue " : {
" project_id " : " 1 " ,
" tracker_id " : " 2 " ,
" status_id " : " 3 " ,
" subject " : " API test "
}
}
JSON
2014-11-23 20:25:46 +00:00
assert_difference ( 'Issue.count' ) do
2014-12-22 13:46:31 +00:00
post '/issues.json' , payload , { " CONTENT_TYPE " = > 'application/json' } . merge ( credentials ( 'jsmith' ) )
2010-01-13 19:29:19 +00:00
end
2011-09-01 00:49:30 +00:00
2014-11-23 20:25:46 +00:00
issue = Issue . order ( 'id DESC' ) . first
assert_equal 1 , issue . project_id
assert_equal 2 , issue . tracker_id
assert_equal 3 , issue . status_id
assert_equal 'API test' , issue . subject
2010-01-13 19:29:19 +00:00
end
2011-09-01 00:49:30 +00:00
2016-10-01 09:06:17 +00:00
test " POST /issues.json should accept project identifier as project_id " do
assert_difference ( 'Issue.count' ) do
post '/issues.json' ,
{ :issue = > { :project_id = > 'subproject1' , :tracker_id = > 2 , :subject = > 'Foo' } } ,
credentials ( 'jsmith' )
assert_response :created
end
end
2015-03-14 09:53:36 +00:00
test " POST /issues.json without tracker_id should accept custom fields " do
field = IssueCustomField . generate! (
:field_format = > 'list' ,
:multiple = > true ,
:possible_values = > [ " V1 " , " V2 " , " V3 " ] ,
:default_value = > " V2 " ,
:is_for_all = > true ,
:trackers = > Tracker . all . to_a
)
payload = <<-JSON
{
" issue " : {
" project_id " : " 1 " ,
" subject " : " Multivalued custom field " ,
" custom_field_values " : { " #{ field . id } " : [ " V1 " , " V3 " ] }
}
}
JSON
assert_difference ( 'Issue.count' ) do
post '/issues.json' , payload , { " CONTENT_TYPE " = > 'application/json' } . merge ( credentials ( 'jsmith' ) )
end
assert_response :created
issue = Issue . order ( 'id DESC' ) . first
2015-03-14 12:13:37 +00:00
assert_equal [ " V1 " , " V3 " ] , issue . custom_field_value ( field ) . sort
2015-03-14 09:53:36 +00:00
end
2015-10-30 12:59:48 +00:00
test " POST /issues.json with omitted custom field should set default value " do
field = IssueCustomField . generate! ( :default_value = > " Default " )
issue = new_record ( Issue ) do
post '/issues.json' ,
{ :issue = > { :project_id = > 1 , :subject = > 'API' , :custom_field_values = > { } } } ,
credentials ( 'jsmith' )
end
assert_equal " Default " , issue . custom_field_value ( field )
end
test " POST /issues.json with custom field set to blank should not set default value " do
field = IssueCustomField . generate! ( :default_value = > " Default " )
issue = new_record ( Issue ) do
post '/issues.json' ,
{ :issue = > { :project_id = > 1 , :subject = > 'API' , :custom_field_values = > { field . id . to_s = > " " } } } ,
credentials ( 'jsmith' )
end
assert_equal " " , issue . custom_field_value ( field )
end
2014-11-23 20:25:46 +00:00
test " POST /issues.json with failure should return errors " do
assert_no_difference ( 'Issue.count' ) do
post '/issues.json' , { :issue = > { :project_id = > 1 } } , credentials ( 'jsmith' )
2010-12-10 10:48:16 +00:00
end
2011-09-01 00:49:30 +00:00
2014-11-23 20:25:46 +00:00
json = ActiveSupport :: JSON . decode ( response . body )
2014-12-21 12:39:48 +00:00
assert json [ 'errors' ] . include? ( " Subject cannot be blank " )
2010-12-10 10:48:16 +00:00
end
2011-09-01 00:49:30 +00:00
2015-03-20 10:02:45 +00:00
test " POST /issues.json with invalid project_id should respond with 422 " do
post '/issues.json' , { :issue = > { :project_id = > 999 , :subject = > " API " } } , credentials ( 'jsmith' )
assert_response 422
end
2014-11-23 20:25:46 +00:00
test " PUT /issues/:id.xml " do
assert_difference ( 'Journal.count' ) do
put '/issues/6.xml' ,
{ :issue = > { :subject = > 'API update' , :notes = > 'A new note' } } ,
credentials ( 'jsmith' )
2012-01-29 20:51:48 +00:00
end
2014-11-23 20:25:46 +00:00
issue = Issue . find ( 6 )
assert_equal " API update " , issue . subject
journal = Journal . last
assert_equal " A new note " , journal . notes
2012-01-29 20:51:48 +00:00
end
2014-11-23 20:25:46 +00:00
test " PUT /issues/:id.xml with custom fields " do
put '/issues/3.xml' ,
{ :issue = > { :custom_fields = > [
{ 'id' = > '1' , 'value' = > 'PostgreSQL' } ,
{ 'id' = > '2' , 'value' = > '150' }
] } } ,
credentials ( 'jsmith' )
issue = Issue . find ( 3 )
assert_equal '150' , issue . custom_value_for ( 2 ) . value
assert_equal 'PostgreSQL' , issue . custom_value_for ( 1 ) . value
2012-01-07 12:34:52 +00:00
end
2014-11-23 20:25:46 +00:00
test " PUT /issues/:id.xml with multi custom fields " do
field = CustomField . find ( 1 )
field . update_attribute :multiple , true
2010-11-05 17:49:20 +00:00
2014-11-23 20:25:46 +00:00
put '/issues/3.xml' ,
{ :issue = > { :custom_fields = > [
{ 'id' = > '1' , 'value' = > [ 'MySQL' , 'PostgreSQL' ] } ,
{ 'id' = > '2' , 'value' = > '150' }
] } } ,
credentials ( 'jsmith' )
2010-11-05 17:49:20 +00:00
2014-11-23 20:25:46 +00:00
issue = Issue . find ( 3 )
assert_equal '150' , issue . custom_value_for ( 2 ) . value
assert_equal [ 'MySQL' , 'PostgreSQL' ] , issue . custom_field_value ( 1 ) . sort
2010-06-05 03:52:53 +00:00
end
2014-11-23 20:25:46 +00:00
test " PUT /issues/:id.xml with project change " do
put '/issues/3.xml' ,
{ :issue = > { :project_id = > 2 , :subject = > 'Project changed' } } ,
credentials ( 'jsmith' )
2011-09-01 00:49:30 +00:00
2014-11-23 20:25:46 +00:00
issue = Issue . find ( 3 )
assert_equal 2 , issue . project_id
assert_equal 'Project changed' , issue . subject
end
2010-06-05 03:52:59 +00:00
2015-03-07 07:31:01 +00:00
test " PUT /issues/:id.xml with notes only " do
assert_difference ( 'Journal.count' ) do
put '/issues/6.xml' ,
{ :issue = > { :notes = > 'Notes only' } } ,
credentials ( 'jsmith' )
end
journal = Journal . last
assert_equal " Notes only " , journal . notes
end
2015-10-30 12:59:48 +00:00
test " PUT /issues/:id.json with omitted custom field should not change blank value to default value " do
field = IssueCustomField . generate! ( :default_value = > " Default " )
issue = Issue . generate! ( :project_id = > 1 , :tracker_id = > 1 , :custom_field_values = > { field . id . to_s = > " " } )
assert_equal " " , issue . reload . custom_field_value ( field )
assert_difference ( 'Journal.count' ) do
put " /issues/ #{ issue . id } .json " ,
{ :issue = > { :custom_field_values = > { } , :notes = > 'API' } } ,
credentials ( 'jsmith' )
end
assert_equal " " , issue . reload . custom_field_value ( field )
end
test " PUT /issues/:id.json with custom field set to blank should not change blank value to default value " do
field = IssueCustomField . generate! ( :default_value = > " Default " )
issue = Issue . generate! ( :project_id = > 1 , :tracker_id = > 1 , :custom_field_values = > { field . id . to_s = > " " } )
assert_equal " " , issue . reload . custom_field_value ( field )
assert_difference ( 'Journal.count' ) do
put " /issues/ #{ issue . id } .json " ,
{ :issue = > { :custom_field_values = > { field . id . to_s = > " " } , :notes = > 'API' } } ,
credentials ( 'jsmith' )
end
assert_equal " " , issue . reload . custom_field_value ( field )
end
2015-10-31 09:17:29 +00:00
test " PUT /issues/:id.json with tracker change and omitted custom field specific to that tracker should set default value " do
2015-10-30 12:59:48 +00:00
field = IssueCustomField . generate! ( :default_value = > " Default " , :tracker_ids = > [ 2 ] )
issue = Issue . generate! ( :project_id = > 1 , :tracker_id = > 1 )
assert_difference ( 'Journal.count' ) do
put " /issues/ #{ issue . id } .json " ,
{ :issue = > { :tracker_id = > 2 , :custom_field_values = > { } , :notes = > 'API' } } ,
credentials ( 'jsmith' )
end
assert_equal 2 , issue . reload . tracker_id
2015-10-31 09:17:29 +00:00
assert_equal " Default " , issue . reload . custom_field_value ( field )
2015-10-30 12:59:48 +00:00
end
test " PUT /issues/:id.json with tracker change and custom field specific to that tracker set to blank should not set default value " do
field = IssueCustomField . generate! ( :default_value = > " Default " , :tracker_ids = > [ 2 ] )
issue = Issue . generate! ( :project_id = > 1 , :tracker_id = > 1 )
assert_difference ( 'Journal.count' ) do
put " /issues/ #{ issue . id } .json " ,
{ :issue = > { :tracker_id = > 2 , :custom_field_values = > { field . id . to_s = > " " } , :notes = > 'API' } } ,
credentials ( 'jsmith' )
end
assert_equal 2 , issue . reload . tracker_id
assert_equal " " , issue . reload . custom_field_value ( field )
end
2014-11-23 20:25:46 +00:00
test " PUT /issues/:id.xml with failed update " do
put '/issues/6.xml' , { :issue = > { :subject = > '' } } , credentials ( 'jsmith' )
2010-06-05 03:52:59 +00:00
2014-11-23 20:25:46 +00:00
assert_response :unprocessable_entity
2014-12-21 12:39:48 +00:00
assert_select 'errors error' , :text = > " Subject cannot be blank "
2010-06-05 03:52:59 +00:00
end
2011-09-01 00:49:30 +00:00
2016-12-10 12:02:37 +00:00
test " PUT /issues/:id.xml with invalid assignee should return error " do
user = User . generate!
put '/issues/6.xml' , { :issue = > { :assigned_to_id = > user . id } } , credentials ( 'jsmith' )
assert_response :unprocessable_entity
assert_select 'errors error' , :text = > " Assignee is invalid "
end
2014-11-23 20:25:46 +00:00
test " PUT /issues/:id.json " do
assert_difference ( 'Journal.count' ) do
put '/issues/6.json' ,
{ :issue = > { :subject = > 'API update' , :notes = > 'A new note' } } ,
credentials ( 'jsmith' )
2010-06-05 03:52:59 +00:00
2014-11-23 20:25:46 +00:00
assert_response :ok
assert_equal '' , response . body
2010-06-05 03:52:59 +00:00
end
2014-11-23 20:25:46 +00:00
issue = Issue . find ( 6 )
assert_equal " API update " , issue . subject
journal = Journal . last
assert_equal " A new note " , journal . notes
2010-06-05 03:52:59 +00:00
end
2014-11-23 20:25:46 +00:00
test " PUT /issues/:id.json with failed update " do
put '/issues/6.json' , { :issue = > { :subject = > '' } } , credentials ( 'jsmith' )
2010-06-05 03:52:53 +00:00
2014-11-23 20:25:46 +00:00
assert_response :unprocessable_entity
json = ActiveSupport :: JSON . decode ( response . body )
2014-12-21 12:39:48 +00:00
assert json [ 'errors' ] . include? ( " Subject cannot be blank " )
2014-11-23 20:25:46 +00:00
end
2012-07-14 08:31:45 +00:00
2014-11-23 20:25:46 +00:00
test " DELETE /issues/:id.xml " do
assert_difference ( 'Issue.count' , - 1 ) do
delete '/issues/6.xml' , { } , credentials ( 'jsmith' )
2011-09-01 00:49:30 +00:00
2014-11-23 20:25:46 +00:00
assert_response :ok
assert_equal '' , response . body
2010-06-05 03:52:53 +00:00
end
2014-11-23 20:25:46 +00:00
assert_nil Issue . find_by_id ( 6 )
2010-01-13 19:29:19 +00:00
end
2010-06-05 03:52:59 +00:00
2014-11-23 20:25:46 +00:00
test " DELETE /issues/:id.json " do
assert_difference ( 'Issue.count' , - 1 ) do
delete '/issues/6.json' , { } , credentials ( 'jsmith' )
2012-07-14 08:31:45 +00:00
2014-11-23 20:25:46 +00:00
assert_response :ok
assert_equal '' , response . body
2010-06-05 03:52:59 +00:00
end
2014-11-23 20:25:46 +00:00
assert_nil Issue . find_by_id ( 6 )
2010-06-05 03:52:59 +00:00
end
2012-02-23 10:01:16 +00:00
2013-01-30 20:51:21 +00:00
test " POST /issues/:id/watchers.xml should add watcher " do
assert_difference 'Watcher.count' do
post '/issues/1/watchers.xml' , { :user_id = > 3 } , credentials ( 'jsmith' )
assert_response :ok
assert_equal '' , response . body
end
watcher = Watcher . order ( 'id desc' ) . first
assert_equal Issue . find ( 1 ) , watcher . watchable
assert_equal User . find ( 3 ) , watcher . user
end
test " DELETE /issues/:id/watchers/:user_id.xml should remove watcher " do
Watcher . create! ( :user_id = > 3 , :watchable = > Issue . find ( 1 ) )
assert_difference 'Watcher.count' , - 1 do
delete '/issues/1/watchers/3.xml' , { } , credentials ( 'jsmith' )
assert_response :ok
assert_equal '' , response . body
end
assert_equal false , Issue . find ( 1 ) . watched_by? ( User . find ( 3 ) )
end
2012-02-23 10:01:16 +00:00
def test_create_issue_with_uploaded_file
2014-12-22 14:14:36 +00:00
token = xml_upload ( 'test_create_with_upload' , credentials ( 'jsmith' ) )
attachment = Attachment . find_by_token ( token )
2012-02-23 10:01:16 +00:00
# create the issue with the upload's token
assert_difference 'Issue.count' do
post '/issues.xml' ,
2012-10-09 11:03:20 +00:00
{ :issue = > { :project_id = > 1 , :subject = > 'Uploaded file' ,
:uploads = > [ { :token = > token , :filename = > 'test.txt' ,
:content_type = > 'text/plain' } ] } } ,
credentials ( 'jsmith' )
2012-02-23 10:01:16 +00:00
assert_response :created
end
2014-01-10 08:38:59 +00:00
issue = Issue . order ( 'id DESC' ) . first
2012-02-23 10:01:16 +00:00
assert_equal 1 , issue . attachments . count
assert_equal attachment , issue . attachments . first
attachment . reload
assert_equal 'test.txt' , attachment . filename
assert_equal 'text/plain' , attachment . content_type
assert_equal 'test_create_with_upload' . size , attachment . filesize
assert_equal 2 , attachment . author_id
# get the issue with its attachments
get " /issues/ #{ issue . id } .xml " , :include = > 'attachments'
assert_response :success
xml = Hash . from_xml ( response . body )
attachments = xml [ 'issue' ] [ 'attachments' ]
assert_kind_of Array , attachments
assert_equal 1 , attachments . size
url = attachments . first [ 'content_url' ]
assert_not_nil url
# download the attachment
get url
assert_response :success
2014-12-22 14:14:36 +00:00
assert_equal 'test_create_with_upload' , response . body
2012-02-23 10:01:16 +00:00
end
2014-12-22 13:41:51 +00:00
def test_create_issue_with_multiple_uploaded_files_as_xml
token1 = xml_upload ( 'File content 1' , credentials ( 'jsmith' ) )
token2 = xml_upload ( 'File content 2' , credentials ( 'jsmith' ) )
payload = <<-XML
< ? xml version = " 1.0 " encoding = " UTF-8 " ?>
< issue >
< project_id > 1 < / project_id>
< tracker_id > 1 < / tracker_id>
< subject > Issue with multiple attachments < / subject>
< uploads type = " array " >
< upload >
< token > #{token1}</token>
< filename > test1 . txt < / filename>
< / upload>
< upload >
< token > #{token2}</token>
< filename > test1 . txt < / filename>
< / upload>
< / uploads>
< / issue>
XML
assert_difference 'Issue.count' do
post '/issues.xml' , payload , { " CONTENT_TYPE " = > 'application/xml' } . merge ( credentials ( 'jsmith' ) )
assert_response :created
end
issue = Issue . order ( 'id DESC' ) . first
assert_equal 2 , issue . attachments . count
end
def test_create_issue_with_multiple_uploaded_files_as_json
token1 = json_upload ( 'File content 1' , credentials ( 'jsmith' ) )
token2 = json_upload ( 'File content 2' , credentials ( 'jsmith' ) )
payload = <<-JSON
{
" issue " : {
" project_id " : " 1 " ,
" tracker_id " : " 1 " ,
" subject " : " Issue with multiple attachments " ,
" uploads " : [
{ " token " : " #{ token1 } " , " filename " : " test1.txt " } ,
{ " token " : " #{ token2 } " , " filename " : " test2.txt " }
]
}
}
JSON
assert_difference 'Issue.count' do
post '/issues.json' , payload , { " CONTENT_TYPE " = > 'application/json' } . merge ( credentials ( 'jsmith' ) )
assert_response :created
end
issue = Issue . order ( 'id DESC' ) . first
assert_equal 2 , issue . attachments . count
end
2012-02-23 10:01:16 +00:00
def test_update_issue_with_uploaded_file
2014-12-22 14:14:36 +00:00
token = xml_upload ( 'test_upload_with_upload' , credentials ( 'jsmith' ) )
attachment = Attachment . find_by_token ( token )
2012-02-23 10:01:16 +00:00
# update the issue with the upload's token
assert_difference 'Journal.count' do
put '/issues/1.xml' ,
2012-10-09 11:03:20 +00:00
{ :issue = > { :notes = > 'Attachment added' ,
:uploads = > [ { :token = > token , :filename = > 'test.txt' ,
:content_type = > 'text/plain' } ] } } ,
credentials ( 'jsmith' )
2012-02-23 10:01:16 +00:00
assert_response :ok
2012-07-14 08:13:55 +00:00
assert_equal '' , @response . body
2012-02-23 10:01:16 +00:00
end
issue = Issue . find ( 1 )
assert_include attachment , issue . attachments
end
2010-01-13 19:29:19 +00:00
end