assert_response :success
end
+ 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
+
def test_update_issue_with_uploaded_file
set_tmp_attachments_directory
# upload the file
def teardown
Setting.rest_api_enabled = '0'
end
+
+ # Uploads content using the XML API and returns the attachment token
+ def xml_upload(content, credentials)
+ upload('xml', content, credentials)
+ end
+
+ # Uploads content using the JSON API and returns the attachment token
+ def json_upload(content, credentials)
+ upload('json', content, credentials)
+ end
+
+ def upload(format, content, credentials)
+ set_tmp_attachments_directory
+ assert_difference 'Attachment.count' do
+ post "/uploads.#{format}", content, {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials)
+ assert_response :created
+ end
+ data = response_data
+ assert_kind_of Hash, data['upload']
+ token = data['upload']['token']
+ assert_not_nil token
+ token
+ end
+
+ # Parses the response body based on its content type
+ def response_data
+ unless response.content_type.to_s =~ /^application\/(.+)/
+ raise "Unexpected response type: #{response.content_type}"
+ end
+ format = $1
+ case format
+ when 'xml'
+ Hash.from_xml(response.body)
+ when 'json'
+ ActiveSupport::JSON.decode(response.body)
+ else
+ raise "Unknown response format: #{format}"
+ end
+ end
end
class Routing < Redmine::RoutingTest