@@ -0,0 +1,14 | |||||
|
1 | api.array :files do | |||
|
2 | @containers.each do |container| | |||
|
3 | container.attachments.each do |attachment| | |||
|
4 | api.file do | |||
|
5 | render_api_attachment_attributes(attachment, api) | |||
|
6 | if container.is_a?(Version) | |||
|
7 | api.version :id => container.id, :name => container.name | |||
|
8 | end | |||
|
9 | api.digest attachment.digest | |||
|
10 | api.downloads attachment.downloads | |||
|
11 | end | |||
|
12 | end | |||
|
13 | end | |||
|
14 | end |
@@ -0,0 +1,115 | |||||
|
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>file>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 |
@@ -1,62 +1,76 | |||||
1 | # Redmine - project management software |
|
1 | # Redmine - project management software | |
2 | # Copyright (C) 2006-2016 Jean-Philippe Lang |
|
2 | # Copyright (C) 2006-2016 Jean-Philippe Lang | |
3 | # |
|
3 | # | |
4 | # This program is free software; you can redistribute it and/or |
|
4 | # This program is free software; you can redistribute it and/or | |
5 | # modify it under the terms of the GNU General Public License |
|
5 | # modify it under the terms of the GNU General Public License | |
6 | # as published by the Free Software Foundation; either version 2 |
|
6 | # as published by the Free Software Foundation; either version 2 | |
7 | # of the License, or (at your option) any later version. |
|
7 | # of the License, or (at your option) any later version. | |
8 | # |
|
8 | # | |
9 | # This program is distributed in the hope that it will be useful, |
|
9 | # This program is distributed in the hope that it will be useful, | |
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | # GNU General Public License for more details. |
|
12 | # GNU General Public License for more details. | |
13 | # |
|
13 | # | |
14 | # You should have received a copy of the GNU General Public License |
|
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 |
|
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. |
|
16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
17 |
|
17 | |||
18 | class FilesController < ApplicationController |
|
18 | class FilesController < ApplicationController | |
19 | menu_item :files |
|
19 | menu_item :files | |
20 |
|
20 | |||
21 | before_action :find_project_by_project_id |
|
21 | before_action :find_project_by_project_id | |
22 | before_action :authorize |
|
22 | before_action :authorize | |
|
23 | accept_api_auth :index, :create | |||
23 |
|
24 | |||
|
25 | helper :attachments | |||
24 | helper :sort |
|
26 | helper :sort | |
25 | include SortHelper |
|
27 | include SortHelper | |
26 |
|
28 | |||
27 | def index |
|
29 | def index | |
28 | sort_init 'filename', 'asc' |
|
30 | sort_init 'filename', 'asc' | |
29 | sort_update 'filename' => "#{Attachment.table_name}.filename", |
|
31 | sort_update 'filename' => "#{Attachment.table_name}.filename", | |
30 | 'created_on' => "#{Attachment.table_name}.created_on", |
|
32 | 'created_on' => "#{Attachment.table_name}.created_on", | |
31 | 'size' => "#{Attachment.table_name}.filesize", |
|
33 | 'size' => "#{Attachment.table_name}.filesize", | |
32 | 'downloads' => "#{Attachment.table_name}.downloads" |
|
34 | 'downloads' => "#{Attachment.table_name}.downloads" | |
33 |
|
35 | |||
34 | @containers = [Project.includes(:attachments). |
|
36 | @containers = [Project.includes(:attachments). | |
35 | references(:attachments).reorder(sort_clause).find(@project.id)] |
|
37 | references(:attachments).reorder(sort_clause).find(@project.id)] | |
36 | @containers += @project.versions.includes(:attachments). |
|
38 | @containers += @project.versions.includes(:attachments). | |
37 | references(:attachments).reorder(sort_clause).to_a.sort.reverse |
|
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 | end |
|
44 | end | |
40 |
|
45 | |||
41 | def new |
|
46 | def new | |
42 | @versions = @project.versions.sort |
|
47 | @versions = @project.versions.sort | |
43 | end |
|
48 | end | |
44 |
|
49 | |||
45 | def create |
|
50 | def create | |
46 | container = (params[:version_id].blank? ? @project : @project.versions.find_by_id(params[:version_id])) |
|
51 | version_id = params[:version_id] || (params[:file] && params[:file][:version_id]) | |
47 | attachments = Attachment.attach_files(container, params[:attachments]) |
|
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 | render_attachment_warning_if_needed(container) |
|
54 | render_attachment_warning_if_needed(container) | |
49 |
|
55 | |||
50 | if attachments[:files].present? |
|
56 | if attachments[:files].present? | |
51 | if Setting.notified_events.include?('file_added') |
|
57 | if Setting.notified_events.include?('file_added') | |
52 | Mailer.attachments_added(attachments[:files]).deliver |
|
58 | Mailer.attachments_added(attachments[:files]).deliver | |
53 | end |
|
59 | end | |
54 | flash[:notice] = l(:label_file_added) |
|
60 | respond_to do |format| | |
55 | redirect_to project_files_path(@project) |
|
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 | else |
|
66 | else | |
57 | flash.now[:error] = l(:label_attachment) + " " + l('activerecord.errors.messages.invalid') |
|
67 | respond_to do |format| | |
58 | new |
|
68 | format.html { | |
59 | render :action => 'new' |
|
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 | end |
|
74 | end | |
61 | end |
|
75 | end | |
62 | end |
|
76 | end |
@@ -1,69 +1,76 | |||||
1 | # encoding: utf-8 |
|
1 | # encoding: utf-8 | |
2 | # |
|
2 | # | |
3 | # Redmine - project management software |
|
3 | # Redmine - project management software | |
4 | # Copyright (C) 2006-2016 Jean-Philippe Lang |
|
4 | # Copyright (C) 2006-2016 Jean-Philippe Lang | |
5 | # |
|
5 | # | |
6 | # This program is free software; you can redistribute it and/or |
|
6 | # This program is free software; you can redistribute it and/or | |
7 | # modify it under the terms of the GNU General Public License |
|
7 | # modify it under the terms of the GNU General Public License | |
8 | # as published by the Free Software Foundation; either version 2 |
|
8 | # as published by the Free Software Foundation; either version 2 | |
9 | # of the License, or (at your option) any later version. |
|
9 | # of the License, or (at your option) any later version. | |
10 | # |
|
10 | # | |
11 | # This program is distributed in the hope that it will be useful, |
|
11 | # This program is distributed in the hope that it will be useful, | |
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | # GNU General Public License for more details. |
|
14 | # GNU General Public License for more details. | |
15 | # |
|
15 | # | |
16 | # You should have received a copy of the GNU General Public License |
|
16 | # You should have received a copy of the GNU General Public License | |
17 | # along with this program; if not, write to the Free Software |
|
17 | # along with this program; if not, write to the Free Software | |
18 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
18 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
19 |
|
19 | |||
20 | module AttachmentsHelper |
|
20 | module AttachmentsHelper | |
21 |
|
21 | |||
22 | def container_attachments_edit_path(container) |
|
22 | def container_attachments_edit_path(container) | |
23 | object_attachments_edit_path container.class.name.underscore.pluralize, container.id |
|
23 | object_attachments_edit_path container.class.name.underscore.pluralize, container.id | |
24 | end |
|
24 | end | |
25 |
|
25 | |||
26 | def container_attachments_path(container) |
|
26 | def container_attachments_path(container) | |
27 | object_attachments_path container.class.name.underscore.pluralize, container.id |
|
27 | object_attachments_path container.class.name.underscore.pluralize, container.id | |
28 | end |
|
28 | end | |
29 |
|
29 | |||
30 | # Displays view/delete links to the attachments of the given object |
|
30 | # Displays view/delete links to the attachments of the given object | |
31 | # Options: |
|
31 | # Options: | |
32 | # :author -- author names are not displayed if set to false |
|
32 | # :author -- author names are not displayed if set to false | |
33 | # :thumbails -- display thumbnails if enabled in settings |
|
33 | # :thumbails -- display thumbnails if enabled in settings | |
34 | def link_to_attachments(container, options = {}) |
|
34 | def link_to_attachments(container, options = {}) | |
35 | options.assert_valid_keys(:author, :thumbnails) |
|
35 | options.assert_valid_keys(:author, :thumbnails) | |
36 |
|
36 | |||
37 | attachments = container.attachments.preload(:author).to_a |
|
37 | attachments = container.attachments.preload(:author).to_a | |
38 | if attachments.any? |
|
38 | if attachments.any? | |
39 | options = { |
|
39 | options = { | |
40 | :editable => container.attachments_editable?, |
|
40 | :editable => container.attachments_editable?, | |
41 | :deletable => container.attachments_deletable?, |
|
41 | :deletable => container.attachments_deletable?, | |
42 | :author => true |
|
42 | :author => true | |
43 | }.merge(options) |
|
43 | }.merge(options) | |
44 | render :partial => 'attachments/links', |
|
44 | render :partial => 'attachments/links', | |
45 | :locals => { |
|
45 | :locals => { | |
46 | :container => container, |
|
46 | :container => container, | |
47 | :attachments => attachments, |
|
47 | :attachments => attachments, | |
48 | :options => options, |
|
48 | :options => options, | |
49 | :thumbnails => (options[:thumbnails] && Setting.thumbnails_enabled?) |
|
49 | :thumbnails => (options[:thumbnails] && Setting.thumbnails_enabled?) | |
50 | } |
|
50 | } | |
51 | end |
|
51 | end | |
52 | end |
|
52 | end | |
53 |
|
53 | |||
54 | def render_api_attachment(attachment, api) |
|
54 | def render_api_attachment(attachment, api, options={}) | |
55 | api.attachment do |
|
55 | api.attachment do | |
56 | api.id attachment.id |
|
56 | render_api_attachment_attributes(attachment, api) | |
57 | api.filename attachment.filename |
|
57 | options.each { |key, value| eval("api.#{key} value") } | |
58 | api.filesize attachment.filesize |
|
|||
59 | api.content_type attachment.content_type |
|
|||
60 | api.description attachment.description |
|
|||
61 | api.content_url download_named_attachment_url(attachment, attachment.filename) |
|
|||
62 | if attachment.thumbnailable? |
|
|||
63 | api.thumbnail_url thumbnail_url(attachment) |
|
|||
64 | end |
|
|||
65 | api.author(:id => attachment.author.id, :name => attachment.author.name) if attachment.author |
|
|||
66 | api.created_on attachment.created_on |
|
|||
67 | end |
|
58 | end | |
68 | end |
|
59 | end | |
|
60 | ||||
|
61 | def render_api_attachment_attributes(attachment, api) | |||
|
62 | api.id attachment.id | |||
|
63 | api.filename attachment.filename | |||
|
64 | api.filesize attachment.filesize | |||
|
65 | api.content_type attachment.content_type | |||
|
66 | api.description attachment.description | |||
|
67 | api.content_url download_named_attachment_url(attachment, attachment.filename) | |||
|
68 | if attachment.thumbnailable? | |||
|
69 | api.thumbnail_url thumbnail_url(attachment) | |||
|
70 | end | |||
|
71 | if attachment.author | |||
|
72 | api.author(:id => attachment.author.id, :name => attachment.author.name) | |||
|
73 | end | |||
|
74 | api.created_on attachment.created_on | |||
|
75 | end | |||
69 | end |
|
76 | end |
@@ -1,160 +1,165 | |||||
1 | # Redmine - project management software |
|
1 | # Redmine - project management software | |
2 | # Copyright (C) 2006-2016 Jean-Philippe Lang |
|
2 | # Copyright (C) 2006-2016 Jean-Philippe Lang | |
3 | # |
|
3 | # | |
4 | # This program is free software; you can redistribute it and/or |
|
4 | # This program is free software; you can redistribute it and/or | |
5 | # modify it under the terms of the GNU General Public License |
|
5 | # modify it under the terms of the GNU General Public License | |
6 | # as published by the Free Software Foundation; either version 2 |
|
6 | # as published by the Free Software Foundation; either version 2 | |
7 | # of the License, or (at your option) any later version. |
|
7 | # of the License, or (at your option) any later version. | |
8 | # |
|
8 | # | |
9 | # This program is distributed in the hope that it will be useful, |
|
9 | # This program is distributed in the hope that it will be useful, | |
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | # GNU General Public License for more details. |
|
12 | # GNU General Public License for more details. | |
13 | # |
|
13 | # | |
14 | # You should have received a copy of the GNU General Public License |
|
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 |
|
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. |
|
16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
17 |
|
17 | |||
18 | require File.expand_path('../../../test_helper', __FILE__) |
|
18 | require File.expand_path('../../../test_helper', __FILE__) | |
19 |
|
19 | |||
20 | class Redmine::ApiTest::ApiRoutingTest < Redmine::ApiTest::Routing |
|
20 | class Redmine::ApiTest::ApiRoutingTest < Redmine::ApiTest::Routing | |
21 |
|
21 | |||
22 | def test_attachments |
|
22 | def test_attachments | |
23 | should_route 'GET /attachments/1' => 'attachments#show', :id => '1' |
|
23 | should_route 'GET /attachments/1' => 'attachments#show', :id => '1' | |
24 | should_route 'PATCH /attachments/1' => 'attachments#update', :id => '1' |
|
24 | should_route 'PATCH /attachments/1' => 'attachments#update', :id => '1' | |
25 | should_route 'DELETE /attachments/1' => 'attachments#destroy', :id => '1' |
|
25 | should_route 'DELETE /attachments/1' => 'attachments#destroy', :id => '1' | |
26 | should_route 'POST /uploads' => 'attachments#upload' |
|
26 | should_route 'POST /uploads' => 'attachments#upload' | |
27 | end |
|
27 | end | |
28 |
|
28 | |||
29 | def test_custom_fields |
|
29 | def test_custom_fields | |
30 | should_route 'GET /custom_fields' => 'custom_fields#index' |
|
30 | should_route 'GET /custom_fields' => 'custom_fields#index' | |
31 | end |
|
31 | end | |
32 |
|
32 | |||
33 | def test_enumerations |
|
33 | def test_enumerations | |
34 | should_route 'GET /enumerations/issue_priorities' => 'enumerations#index', :type => 'issue_priorities' |
|
34 | should_route 'GET /enumerations/issue_priorities' => 'enumerations#index', :type => 'issue_priorities' | |
35 | end |
|
35 | end | |
36 |
|
36 | |||
|
37 | def test_files | |||
|
38 | should_route 'GET /projects/foo/files' => 'files#index', :project_id => 'foo' | |||
|
39 | should_route 'POST /projects/foo/files' => 'files#create', :project_id => 'foo' | |||
|
40 | end | |||
|
41 | ||||
37 | def test_groups |
|
42 | def test_groups | |
38 | should_route 'GET /groups' => 'groups#index' |
|
43 | should_route 'GET /groups' => 'groups#index' | |
39 | should_route 'POST /groups' => 'groups#create' |
|
44 | should_route 'POST /groups' => 'groups#create' | |
40 |
|
45 | |||
41 | should_route 'GET /groups/1' => 'groups#show', :id => '1' |
|
46 | should_route 'GET /groups/1' => 'groups#show', :id => '1' | |
42 | should_route 'PUT /groups/1' => 'groups#update', :id => '1' |
|
47 | should_route 'PUT /groups/1' => 'groups#update', :id => '1' | |
43 | should_route 'DELETE /groups/1' => 'groups#destroy', :id => '1' |
|
48 | should_route 'DELETE /groups/1' => 'groups#destroy', :id => '1' | |
44 | end |
|
49 | end | |
45 |
|
50 | |||
46 | def test_group_users |
|
51 | def test_group_users | |
47 | should_route 'POST /groups/567/users' => 'groups#add_users', :id => '567' |
|
52 | should_route 'POST /groups/567/users' => 'groups#add_users', :id => '567' | |
48 | should_route 'DELETE /groups/567/users/12' => 'groups#remove_user', :id => '567', :user_id => '12' |
|
53 | should_route 'DELETE /groups/567/users/12' => 'groups#remove_user', :id => '567', :user_id => '12' | |
49 | end |
|
54 | end | |
50 |
|
55 | |||
51 | def test_issue_categories |
|
56 | def test_issue_categories | |
52 | should_route 'GET /projects/foo/issue_categories' => 'issue_categories#index', :project_id => 'foo' |
|
57 | should_route 'GET /projects/foo/issue_categories' => 'issue_categories#index', :project_id => 'foo' | |
53 | should_route 'POST /projects/foo/issue_categories' => 'issue_categories#create', :project_id => 'foo' |
|
58 | should_route 'POST /projects/foo/issue_categories' => 'issue_categories#create', :project_id => 'foo' | |
54 |
|
59 | |||
55 | should_route 'GET /issue_categories/1' => 'issue_categories#show', :id => '1' |
|
60 | should_route 'GET /issue_categories/1' => 'issue_categories#show', :id => '1' | |
56 | should_route 'PUT /issue_categories/1' => 'issue_categories#update', :id => '1' |
|
61 | should_route 'PUT /issue_categories/1' => 'issue_categories#update', :id => '1' | |
57 | should_route 'DELETE /issue_categories/1' => 'issue_categories#destroy', :id => '1' |
|
62 | should_route 'DELETE /issue_categories/1' => 'issue_categories#destroy', :id => '1' | |
58 | end |
|
63 | end | |
59 |
|
64 | |||
60 | def test_issue_relations |
|
65 | def test_issue_relations | |
61 | should_route 'GET /issues/1/relations' => 'issue_relations#index', :issue_id => '1' |
|
66 | should_route 'GET /issues/1/relations' => 'issue_relations#index', :issue_id => '1' | |
62 | should_route 'POST /issues/1/relations' => 'issue_relations#create', :issue_id => '1' |
|
67 | should_route 'POST /issues/1/relations' => 'issue_relations#create', :issue_id => '1' | |
63 |
|
68 | |||
64 | should_route 'GET /relations/23' => 'issue_relations#show', :id => '23' |
|
69 | should_route 'GET /relations/23' => 'issue_relations#show', :id => '23' | |
65 | should_route 'DELETE /relations/23' => 'issue_relations#destroy', :id => '23' |
|
70 | should_route 'DELETE /relations/23' => 'issue_relations#destroy', :id => '23' | |
66 | end |
|
71 | end | |
67 |
|
72 | |||
68 | def test_issue_statuses |
|
73 | def test_issue_statuses | |
69 | should_route 'GET /issue_statuses' => 'issue_statuses#index' |
|
74 | should_route 'GET /issue_statuses' => 'issue_statuses#index' | |
70 | end |
|
75 | end | |
71 |
|
76 | |||
72 | def test_issues |
|
77 | def test_issues | |
73 | should_route 'GET /issues' => 'issues#index' |
|
78 | should_route 'GET /issues' => 'issues#index' | |
74 | should_route 'POST /issues' => 'issues#create' |
|
79 | should_route 'POST /issues' => 'issues#create' | |
75 |
|
80 | |||
76 | should_route 'GET /issues/64' => 'issues#show', :id => '64' |
|
81 | should_route 'GET /issues/64' => 'issues#show', :id => '64' | |
77 | should_route 'PUT /issues/64' => 'issues#update', :id => '64' |
|
82 | should_route 'PUT /issues/64' => 'issues#update', :id => '64' | |
78 | should_route 'DELETE /issues/64' => 'issues#destroy', :id => '64' |
|
83 | should_route 'DELETE /issues/64' => 'issues#destroy', :id => '64' | |
79 | end |
|
84 | end | |
80 |
|
85 | |||
81 | def test_issue_watchers |
|
86 | def test_issue_watchers | |
82 | should_route 'POST /issues/12/watchers' => 'watchers#create', :object_type => 'issue', :object_id => '12' |
|
87 | should_route 'POST /issues/12/watchers' => 'watchers#create', :object_type => 'issue', :object_id => '12' | |
83 | should_route 'DELETE /issues/12/watchers/3' => 'watchers#destroy', :object_type => 'issue', :object_id => '12', :user_id => '3' |
|
88 | should_route 'DELETE /issues/12/watchers/3' => 'watchers#destroy', :object_type => 'issue', :object_id => '12', :user_id => '3' | |
84 | end |
|
89 | end | |
85 |
|
90 | |||
86 | def test_memberships |
|
91 | def test_memberships | |
87 | should_route 'GET /projects/5234/memberships' => 'members#index', :project_id => '5234' |
|
92 | should_route 'GET /projects/5234/memberships' => 'members#index', :project_id => '5234' | |
88 | should_route 'POST /projects/5234/memberships' => 'members#create', :project_id => '5234' |
|
93 | should_route 'POST /projects/5234/memberships' => 'members#create', :project_id => '5234' | |
89 |
|
94 | |||
90 | should_route 'GET /memberships/5234' => 'members#show', :id => '5234' |
|
95 | should_route 'GET /memberships/5234' => 'members#show', :id => '5234' | |
91 | should_route 'PUT /memberships/5234' => 'members#update', :id => '5234' |
|
96 | should_route 'PUT /memberships/5234' => 'members#update', :id => '5234' | |
92 | should_route 'DELETE /memberships/5234' => 'members#destroy', :id => '5234' |
|
97 | should_route 'DELETE /memberships/5234' => 'members#destroy', :id => '5234' | |
93 | end |
|
98 | end | |
94 |
|
99 | |||
95 | def test_news |
|
100 | def test_news | |
96 | should_route 'GET /news' => 'news#index' |
|
101 | should_route 'GET /news' => 'news#index' | |
97 | should_route 'GET /projects/567/news' => 'news#index', :project_id => '567' |
|
102 | should_route 'GET /projects/567/news' => 'news#index', :project_id => '567' | |
98 | end |
|
103 | end | |
99 |
|
104 | |||
100 | def test_projects |
|
105 | def test_projects | |
101 | should_route 'GET /projects' => 'projects#index' |
|
106 | should_route 'GET /projects' => 'projects#index' | |
102 | should_route 'POST /projects' => 'projects#create' |
|
107 | should_route 'POST /projects' => 'projects#create' | |
103 |
|
108 | |||
104 | should_route 'GET /projects/1' => 'projects#show', :id => '1' |
|
109 | should_route 'GET /projects/1' => 'projects#show', :id => '1' | |
105 | should_route 'PUT /projects/1' => 'projects#update', :id => '1' |
|
110 | should_route 'PUT /projects/1' => 'projects#update', :id => '1' | |
106 | should_route 'DELETE /projects/1' => 'projects#destroy', :id => '1' |
|
111 | should_route 'DELETE /projects/1' => 'projects#destroy', :id => '1' | |
107 | end |
|
112 | end | |
108 |
|
113 | |||
109 | def test_queries |
|
114 | def test_queries | |
110 | should_route 'GET /queries' => 'queries#index' |
|
115 | should_route 'GET /queries' => 'queries#index' | |
111 | end |
|
116 | end | |
112 |
|
117 | |||
113 | def test_roles |
|
118 | def test_roles | |
114 | should_route 'GET /roles' => 'roles#index' |
|
119 | should_route 'GET /roles' => 'roles#index' | |
115 | should_route 'GET /roles/2' => 'roles#show', :id => '2' |
|
120 | should_route 'GET /roles/2' => 'roles#show', :id => '2' | |
116 | end |
|
121 | end | |
117 |
|
122 | |||
118 | def test_time_entries |
|
123 | def test_time_entries | |
119 | should_route 'GET /time_entries' => 'timelog#index' |
|
124 | should_route 'GET /time_entries' => 'timelog#index' | |
120 | should_route 'POST /time_entries' => 'timelog#create' |
|
125 | should_route 'POST /time_entries' => 'timelog#create' | |
121 |
|
126 | |||
122 | should_route 'GET /time_entries/1' => 'timelog#show', :id => '1' |
|
127 | should_route 'GET /time_entries/1' => 'timelog#show', :id => '1' | |
123 | should_route 'PUT /time_entries/1' => 'timelog#update', :id => '1' |
|
128 | should_route 'PUT /time_entries/1' => 'timelog#update', :id => '1' | |
124 | should_route 'DELETE /time_entries/1' => 'timelog#destroy', :id => '1' |
|
129 | should_route 'DELETE /time_entries/1' => 'timelog#destroy', :id => '1' | |
125 | end |
|
130 | end | |
126 |
|
131 | |||
127 | def test_trackers |
|
132 | def test_trackers | |
128 | should_route 'GET /trackers' => 'trackers#index' |
|
133 | should_route 'GET /trackers' => 'trackers#index' | |
129 | end |
|
134 | end | |
130 |
|
135 | |||
131 | def test_users |
|
136 | def test_users | |
132 | should_route 'GET /users' => 'users#index' |
|
137 | should_route 'GET /users' => 'users#index' | |
133 | should_route 'POST /users' => 'users#create' |
|
138 | should_route 'POST /users' => 'users#create' | |
134 |
|
139 | |||
135 | should_route 'GET /users/44' => 'users#show', :id => '44' |
|
140 | should_route 'GET /users/44' => 'users#show', :id => '44' | |
136 | should_route 'GET /users/current' => 'users#show', :id => 'current' |
|
141 | should_route 'GET /users/current' => 'users#show', :id => 'current' | |
137 | should_route 'PUT /users/44' => 'users#update', :id => '44' |
|
142 | should_route 'PUT /users/44' => 'users#update', :id => '44' | |
138 | should_route 'DELETE /users/44' => 'users#destroy', :id => '44' |
|
143 | should_route 'DELETE /users/44' => 'users#destroy', :id => '44' | |
139 | end |
|
144 | end | |
140 |
|
145 | |||
141 | def test_versions |
|
146 | def test_versions | |
142 | should_route 'GET /projects/foo/versions' => 'versions#index', :project_id => 'foo' |
|
147 | should_route 'GET /projects/foo/versions' => 'versions#index', :project_id => 'foo' | |
143 | should_route 'POST /projects/foo/versions' => 'versions#create', :project_id => 'foo' |
|
148 | should_route 'POST /projects/foo/versions' => 'versions#create', :project_id => 'foo' | |
144 |
|
149 | |||
145 | should_route 'GET /versions/1' => 'versions#show', :id => '1' |
|
150 | should_route 'GET /versions/1' => 'versions#show', :id => '1' | |
146 | should_route 'PUT /versions/1' => 'versions#update', :id => '1' |
|
151 | should_route 'PUT /versions/1' => 'versions#update', :id => '1' | |
147 | should_route 'DELETE /versions/1' => 'versions#destroy', :id => '1' |
|
152 | should_route 'DELETE /versions/1' => 'versions#destroy', :id => '1' | |
148 | end |
|
153 | end | |
149 |
|
154 | |||
150 | def test_wiki |
|
155 | def test_wiki | |
151 | should_route 'GET /projects/567/wiki/index' => 'wiki#index', :project_id => '567' |
|
156 | should_route 'GET /projects/567/wiki/index' => 'wiki#index', :project_id => '567' | |
152 |
|
157 | |||
153 | should_route 'GET /projects/567/wiki/my_page' => 'wiki#show', :project_id => '567', :id => 'my_page' |
|
158 | should_route 'GET /projects/567/wiki/my_page' => 'wiki#show', :project_id => '567', :id => 'my_page' | |
154 | should_route 'GET /projects/567/wiki/my_page' => 'wiki#show', :project_id => '567', :id => 'my_page' |
|
159 | should_route 'GET /projects/567/wiki/my_page' => 'wiki#show', :project_id => '567', :id => 'my_page' | |
155 | should_route 'GET /projects/1/wiki/my_page/2' => 'wiki#show', :project_id => '1', :id => 'my_page', :version => '2' |
|
160 | should_route 'GET /projects/1/wiki/my_page/2' => 'wiki#show', :project_id => '1', :id => 'my_page', :version => '2' | |
156 |
|
161 | |||
157 | should_route 'PUT /projects/567/wiki/my_page' => 'wiki#update', :project_id => '567', :id => 'my_page' |
|
162 | should_route 'PUT /projects/567/wiki/my_page' => 'wiki#update', :project_id => '567', :id => 'my_page' | |
158 | should_route 'DELETE /projects/567/wiki/my_page' => 'wiki#destroy', :project_id => '567', :id => 'my_page' |
|
163 | should_route 'DELETE /projects/567/wiki/my_page' => 'wiki#destroy', :project_id => '567', :id => 'my_page' | |
159 | end |
|
164 | end | |
160 | end |
|
165 | end |
General Comments 0
You need to be logged in to leave comments.
Login now