Patch #19116 » 0001-REST-API-add-files-REST-API_v3.patch
| app/controllers/files_controller.rb | ||
|---|---|---|
| 20 | 20 | |
| 21 | 21 |
before_action :find_project_by_project_id |
| 22 | 22 |
before_action :authorize |
| 23 |
accept_api_auth :index, :create |
|
| 23 | 24 | |
| 25 |
helper :attachments |
|
| 24 | 26 |
helper :sort |
| 25 | 27 |
include SortHelper |
| 26 | 28 | |
| ... | ... | |
| 35 | 37 |
references(:attachments).reorder(sort_clause).find(@project.id)] |
| 36 | 38 |
@containers += @project.versions.includes(:attachments). |
| 37 | 39 |
references(:attachments).reorder(sort_clause).to_a.sort.reverse |
| 38 |
render :layout => !request.xhr? |
|
| 40 |
respond_to do |format| |
|
| 41 |
format.html { render :layout => !request.xhr? }
|
|
| 42 |
format.api |
|
| 43 |
end |
|
| 39 | 44 |
end |
| 40 | 45 | |
| 41 | 46 |
def new |
| ... | ... | |
| 43 | 48 |
end |
| 44 | 49 | |
| 45 | 50 |
def create |
| 46 |
container = (params[:version_id].blank? ? @project : @project.versions.find_by_id(params[:version_id])) |
|
| 47 |
attachments = Attachment.attach_files(container, params[:attachments]) |
|
| 51 |
version_id = params[:version_id] || (params[:file] && params[:file][:version_id]) |
|
| 52 |
container = version_id.blank? ? @project : @project.versions.find_by_id(version_id) |
|
| 53 |
attachments = Attachment.attach_files(container, (params[:attachments] || (params[:file] && params[:file][:token] && params))) |
|
| 48 | 54 |
render_attachment_warning_if_needed(container) |
| 49 | 55 | |
| 50 | 56 |
if attachments[:files].present? |
| 51 | 57 |
if Setting.notified_events.include?('file_added')
|
| 52 | 58 |
Mailer.attachments_added(attachments[:files]).deliver |
| 53 | 59 |
end |
| 54 |
flash[:notice] = l(:label_file_added) |
|
| 55 |
redirect_to project_files_path(@project) |
|
| 60 |
respond_to do |format| |
|
| 61 |
format.html {
|
|
| 62 |
flash[:notice] = l(:label_file_added) |
|
| 63 |
redirect_to project_files_path(@project) } |
|
| 64 |
format.api { render_api_ok }
|
|
| 65 |
end |
|
| 56 | 66 |
else |
| 57 |
flash.now[:error] = l(:label_attachment) + " " + l('activerecord.errors.messages.invalid')
|
|
| 58 |
new |
|
| 59 |
render :action => 'new' |
|
| 67 |
respond_to do |format| |
|
| 68 |
format.html {
|
|
| 69 |
flash.now[:error] = l(:label_attachment) + " " + l('activerecord.errors.messages.invalid')
|
|
| 70 |
new |
|
| 71 |
render :action => 'new' } |
|
| 72 |
format.api { render :status => :bad_request }
|
|
| 73 |
end |
|
| 60 | 74 |
end |
| 61 | 75 |
end |
| 62 | 76 |
end |
| app/helpers/attachments_helper.rb | ||
|---|---|---|
| 51 | 51 |
end |
| 52 | 52 |
end |
| 53 | 53 | |
| 54 |
def render_api_attachment(attachment, api) |
|
| 54 |
def render_api_attachment(attachment, api, options={})
|
|
| 55 | 55 |
api.attachment do |
| 56 | 56 |
api.id attachment.id |
| 57 | 57 |
api.filename attachment.filename |
| ... | ... | |
| 64 | 64 |
end |
| 65 | 65 |
api.author(:id => attachment.author.id, :name => attachment.author.name) if attachment.author |
| 66 | 66 |
api.created_on attachment.created_on |
| 67 |
options.each { |key, value| eval("api.#{key} value") }
|
|
| 67 | 68 |
end |
| 68 | 69 |
end |
| 69 | 70 |
end |
| test/integration/api_test/api_routing_test.rb | ||
|---|---|---|
| 32 | 32 |
should_route 'GET /enumerations/issue_priorities' => 'enumerations#index', :type => 'issue_priorities' |
| 33 | 33 |
end |
| 34 | 34 | |
| 35 |
def test_files |
|
| 36 |
should_route 'GET /projects/foo/files' => 'files#index', :project_id => 'foo' |
|
| 37 |
should_route 'POST /projects/foo/files' => 'files#create', :project_id => 'foo' |
|
| 38 |
end |
|
| 39 | ||
| 35 | 40 |
def test_groups |
| 36 | 41 |
should_route 'GET /groups' => 'groups#index' |
| 37 | 42 |
should_route 'POST /groups' => 'groups#create' |
| test/integration/api_test/files_test.rb | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2015 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::FilesTest < Redmine::ApiTest::Base |
|
| 21 |
fixtures :projects, |
|
| 22 |
:users, |
|
| 23 |
:members, |
|
| 24 |
:roles, |
|
| 25 |
:member_roles, |
|
| 26 |
:enabled_modules, |
|
| 27 |
:attachments, |
|
| 28 |
:versions |
|
| 29 | ||
| 30 |
test "GET /projects/:project_id/files.xml should return the list of uploaded files" do |
|
| 31 |
get '/projects/1/files.xml', {}, credentials('jsmith')
|
|
| 32 |
assert_response :success |
|
| 33 |
assert_select 'files attachment id', :text => '8' |
|
| 34 |
end |
|
| 35 | ||
| 36 |
test "POST /projects/:project_id/files.json should create a file" do |
|
| 37 |
set_tmp_attachments_directory |
|
| 38 |
post '/uploads.xml', 'File content', {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
|
|
| 39 |
token = Attachment.last.token |
|
| 40 |
payload = <<-JSON |
|
| 41 |
{ "file": {
|
|
| 42 |
"token": "#{token}"
|
|
| 43 |
} |
|
| 44 |
} |
|
| 45 |
JSON |
|
| 46 |
post '/projects/1/files.json', payload, {"CONTENT_TYPE" => 'application/json'}.merge(credentials('jsmith'))
|
|
| 47 |
assert_response :success |
|
| 48 |
assert_equal 1, Attachment.last.container_id |
|
| 49 |
assert_equal "Project", Attachment.last.container_type |
|
| 50 |
end |
|
| 51 | ||
| 52 |
test "POST /projects/:project_id/files.xml should create a file" do |
|
| 53 |
set_tmp_attachments_directory |
|
| 54 |
post '/uploads.xml', 'File content', {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
|
|
| 55 |
token = Attachment.last.token |
|
| 56 |
payload = <<-XML |
|
| 57 |
<file> |
|
| 58 |
<token>#{token}</token>
|
|
| 59 |
</file> |
|
| 60 |
XML |
|
| 61 |
post '/projects/1/files.xml', payload, {"CONTENT_TYPE" => 'application/xml'}.merge(credentials('jsmith'))
|
|
| 62 |
assert_response :success |
|
| 63 |
assert_equal 1, Attachment.last.container_id |
|
| 64 |
assert_equal "Project", Attachment.last.container_type |
|
| 65 |
end |
|
| 66 | ||
| 67 |
test "POST /projects/:project_id/files.json should refuse requests without the :token parameter" do |
|
| 68 |
payload = <<-JSON |
|
| 69 |
{ "file": {
|
|
| 70 |
"filename": "project_file.zip", |
|
| 71 |
} |
|
| 72 |
} |
|
| 73 |
JSON |
|
| 74 |
post '/projects/1/files.json', payload, {"CONTENT_TYPE" => 'application/json'}.merge(credentials('jsmith'))
|
|
| 75 |
assert_response :bad_request |
|
| 76 |
end |
|
| 77 | ||
| 78 |
test "POST /projects/:project_id/files.json should accept :filename, :description, :content_type as optional parameters" do |
|
| 79 |
set_tmp_attachments_directory |
|
| 80 |
post '/uploads.xml', 'File content', {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
|
|
| 81 |
token = Attachment.last.token |
|
| 82 |
payload = <<-JSON |
|
| 83 |
{ "file": {
|
|
| 84 |
"filename": "New filename", |
|
| 85 |
"description": "New description", |
|
| 86 |
"content_type": "application/txt", |
|
| 87 |
"token": "#{token}"
|
|
| 88 |
} |
|
| 89 |
} |
|
| 90 |
JSON |
|
| 91 |
post '/projects/1/files.json', payload, {"CONTENT_TYPE" => 'application/json'}.merge(credentials('jsmith'))
|
|
| 92 |
assert_response :success |
|
| 93 |
assert_equal "New filename", Attachment.last.filename |
|
| 94 |
assert_equal "New description", Attachment.last.description |
|
| 95 |
assert_equal "application/txt", Attachment.last.content_type |
|
| 96 |
end |
|
| 97 | ||
| 98 |
test "POST /projects/:project_id/files.json should accept :version_id to attach the files to a version" do |
|
| 99 |
set_tmp_attachments_directory |
|
| 100 |
post '/uploads.xml', 'File content', {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
|
|
| 101 |
token = Attachment.last.token |
|
| 102 |
payload = <<-JSON |
|
| 103 |
{ "file": {
|
|
| 104 |
"version_id": 3, |
|
| 105 |
"filename": "New filename", |
|
| 106 |
"description": "New description", |
|
| 107 |
"token": "#{token}"
|
|
| 108 |
} |
|
| 109 |
} |
|
| 110 |
JSON |
|
| 111 |
post '/projects/1/files.json', payload, {"CONTENT_TYPE" => 'application/json'}.merge(credentials('jsmith'))
|
|
| 112 |
assert_equal 3, Attachment.last.container_id |
|
| 113 |
assert_equal "Version", Attachment.last.container_type |
|
| 114 |
end |
|
| 115 |
end |
|
- « Previous
- 1
- 2
- 3
- Next »