##// END OF EJS Templates
Resourcified attachments....
Jean-Philippe Lang -
r7828:885605b439de
parent child
Show More
@@ -1,95 +1,95
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 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 AttachmentsController < ApplicationController
18 class AttachmentsController < ApplicationController
19 before_filter :find_project
19 before_filter :find_project
20 before_filter :file_readable, :read_authorize, :except => :destroy
20 before_filter :file_readable, :read_authorize, :except => :destroy
21 before_filter :delete_authorize, :only => :destroy
21 before_filter :delete_authorize, :only => :destroy
22
22
23 accept_api_auth :show, :download
23 accept_api_auth :show, :download
24
24
25 def show
25 def show
26 respond_to do |format|
26 respond_to do |format|
27 format.html {
27 format.html {
28 if @attachment.is_diff?
28 if @attachment.is_diff?
29 @diff = File.new(@attachment.diskfile, "rb").read
29 @diff = File.new(@attachment.diskfile, "rb").read
30 @diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
30 @diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
31 @diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
31 @diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
32 render :action => 'diff'
32 render :action => 'diff'
33 elsif @attachment.is_text? && @attachment.filesize <= Setting.file_max_size_displayed.to_i.kilobyte
33 elsif @attachment.is_text? && @attachment.filesize <= Setting.file_max_size_displayed.to_i.kilobyte
34 @content = File.new(@attachment.diskfile, "rb").read
34 @content = File.new(@attachment.diskfile, "rb").read
35 render :action => 'file'
35 render :action => 'file'
36 else
36 else
37 download
37 download
38 end
38 end
39 }
39 }
40 format.api
40 format.api
41 end
41 end
42 end
42 end
43
43
44 def download
44 def download
45 if @attachment.container.is_a?(Version) || @attachment.container.is_a?(Project)
45 if @attachment.container.is_a?(Version) || @attachment.container.is_a?(Project)
46 @attachment.increment_download
46 @attachment.increment_download
47 end
47 end
48
48
49 # images are sent inline
49 # images are sent inline
50 send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename),
50 send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename),
51 :type => detect_content_type(@attachment),
51 :type => detect_content_type(@attachment),
52 :disposition => (@attachment.image? ? 'inline' : 'attachment')
52 :disposition => (@attachment.image? ? 'inline' : 'attachment')
53
53
54 end
54 end
55
55
56 verify :method => :post, :only => :destroy
56 verify :method => :delete, :only => :destroy
57 def destroy
57 def destroy
58 # Make sure association callbacks are called
58 # Make sure association callbacks are called
59 @attachment.container.attachments.delete(@attachment)
59 @attachment.container.attachments.delete(@attachment)
60 redirect_to :back
60 redirect_to :back
61 rescue ::ActionController::RedirectBackError
61 rescue ::ActionController::RedirectBackError
62 redirect_to :controller => 'projects', :action => 'show', :id => @project
62 redirect_to :controller => 'projects', :action => 'show', :id => @project
63 end
63 end
64
64
65 private
65 private
66 def find_project
66 def find_project
67 @attachment = Attachment.find(params[:id])
67 @attachment = Attachment.find(params[:id])
68 # Show 404 if the filename in the url is wrong
68 # Show 404 if the filename in the url is wrong
69 raise ActiveRecord::RecordNotFound if params[:filename] && params[:filename] != @attachment.filename
69 raise ActiveRecord::RecordNotFound if params[:filename] && params[:filename] != @attachment.filename
70 @project = @attachment.project
70 @project = @attachment.project
71 rescue ActiveRecord::RecordNotFound
71 rescue ActiveRecord::RecordNotFound
72 render_404
72 render_404
73 end
73 end
74
74
75 # Checks that the file exists and is readable
75 # Checks that the file exists and is readable
76 def file_readable
76 def file_readable
77 @attachment.readable? ? true : render_404
77 @attachment.readable? ? true : render_404
78 end
78 end
79
79
80 def read_authorize
80 def read_authorize
81 @attachment.visible? ? true : deny_access
81 @attachment.visible? ? true : deny_access
82 end
82 end
83
83
84 def delete_authorize
84 def delete_authorize
85 @attachment.deletable? ? true : deny_access
85 @attachment.deletable? ? true : deny_access
86 end
86 end
87
87
88 def detect_content_type(attachment)
88 def detect_content_type(attachment)
89 content_type = attachment.content_type
89 content_type = attachment.content_type
90 if content_type.blank?
90 if content_type.blank?
91 content_type = Redmine::MimeType.of(attachment.filename)
91 content_type = Redmine::MimeType.of(attachment.filename)
92 end
92 end
93 content_type.to_s
93 content_type.to_s
94 end
94 end
95 end
95 end
@@ -1,18 +1,18
1 <div class="attachments">
1 <div class="attachments">
2 <% for attachment in attachments %>
2 <% for attachment in attachments %>
3 <p><%= link_to_attachment attachment, :class => 'icon icon-attachment' -%>
3 <p><%= link_to_attachment attachment, :class => 'icon icon-attachment' -%>
4 <%= h(" - #{attachment.description}") unless attachment.description.blank? %>
4 <%= h(" - #{attachment.description}") unless attachment.description.blank? %>
5 <span class="size">(<%= number_to_human_size attachment.filesize %>)</span>
5 <span class="size">(<%= number_to_human_size attachment.filesize %>)</span>
6 <% if options[:deletable] %>
6 <% if options[:deletable] %>
7 <%= link_to image_tag('delete.png'), {:controller => 'attachments', :action => 'destroy', :id => attachment},
7 <%= link_to image_tag('delete.png'), attachment_path(attachment),
8 :confirm => l(:text_are_you_sure),
8 :confirm => l(:text_are_you_sure),
9 :method => :post,
9 :method => :delete,
10 :class => 'delete',
10 :class => 'delete',
11 :title => l(:button_delete) %>
11 :title => l(:button_delete) %>
12 <% end %>
12 <% end %>
13 <% if options[:author] %>
13 <% if options[:author] %>
14 <span class="author"><%= h(attachment.author) %>, <%= format_time(attachment.created_on) %></span>
14 <span class="author"><%= h(attachment.author) %>, <%= format_time(attachment.created_on) %></span>
15 <% end %>
15 <% end %>
16 </p>
16 </p>
17 <% end %>
17 <% end %>
18 </div>
18 </div>
@@ -1,46 +1,46
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to(l(:label_attachment_new), new_project_file_path(@project), :class => 'icon icon-add') if User.current.allowed_to?(:manage_files, @project) %>
2 <%= link_to(l(:label_attachment_new), new_project_file_path(@project), :class => 'icon icon-add') if User.current.allowed_to?(:manage_files, @project) %>
3 </div>
3 </div>
4
4
5 <h2><%=l(:label_attachment_plural)%></h2>
5 <h2><%=l(:label_attachment_plural)%></h2>
6
6
7 <% delete_allowed = User.current.allowed_to?(:manage_files, @project) %>
7 <% delete_allowed = User.current.allowed_to?(:manage_files, @project) %>
8
8
9 <table class="list files">
9 <table class="list files">
10 <thead><tr>
10 <thead><tr>
11 <%= sort_header_tag('filename', :caption => l(:field_filename)) %>
11 <%= sort_header_tag('filename', :caption => l(:field_filename)) %>
12 <%= sort_header_tag('created_on', :caption => l(:label_date), :default_order => 'desc') %>
12 <%= sort_header_tag('created_on', :caption => l(:label_date), :default_order => 'desc') %>
13 <%= sort_header_tag('size', :caption => l(:field_filesize), :default_order => 'desc') %>
13 <%= sort_header_tag('size', :caption => l(:field_filesize), :default_order => 'desc') %>
14 <%= sort_header_tag('downloads', :caption => l(:label_downloads_abbr), :default_order => 'desc') %>
14 <%= sort_header_tag('downloads', :caption => l(:label_downloads_abbr), :default_order => 'desc') %>
15 <th>MD5</th>
15 <th>MD5</th>
16 <th></th>
16 <th></th>
17 </tr></thead>
17 </tr></thead>
18 <tbody>
18 <tbody>
19 <% @containers.each do |container| %>
19 <% @containers.each do |container| %>
20 <% next if container.attachments.empty? -%>
20 <% next if container.attachments.empty? -%>
21 <% if container.is_a?(Version) -%>
21 <% if container.is_a?(Version) -%>
22 <tr>
22 <tr>
23 <th colspan="6" align="left">
23 <th colspan="6" align="left">
24 <%= link_to(h(container), {:controller => 'versions', :action => 'show', :id => container}, :class => "icon icon-package") %>
24 <%= link_to(h(container), {:controller => 'versions', :action => 'show', :id => container}, :class => "icon icon-package") %>
25 </th>
25 </th>
26 </tr>
26 </tr>
27 <% end -%>
27 <% end -%>
28 <% container.attachments.each do |file| %>
28 <% container.attachments.each do |file| %>
29 <tr class="file <%= cycle("odd", "even") %>">
29 <tr class="file <%= cycle("odd", "even") %>">
30 <td class="filename"><%= link_to_attachment file, :download => true, :title => file.description %></td>
30 <td class="filename"><%= link_to_attachment file, :download => true, :title => file.description %></td>
31 <td class="created_on"><%= format_time(file.created_on) %></td>
31 <td class="created_on"><%= format_time(file.created_on) %></td>
32 <td class="filesize"><%= number_to_human_size(file.filesize) %></td>
32 <td class="filesize"><%= number_to_human_size(file.filesize) %></td>
33 <td class="downloads"><%= file.downloads %></td>
33 <td class="downloads"><%= file.downloads %></td>
34 <td class="digest"><%= file.digest %></td>
34 <td class="digest"><%= file.digest %></td>
35 <td align="center">
35 <td align="center">
36 <%= link_to(image_tag('delete.png'), {:controller => 'attachments', :action => 'destroy', :id => file},
36 <%= link_to(image_tag('delete.png'), attachment_path(file),
37 :confirm => l(:text_are_you_sure), :method => :post) if delete_allowed %>
37 :confirm => l(:text_are_you_sure), :method => :delete) if delete_allowed %>
38 </td>
38 </td>
39 </tr>
39 </tr>
40 <% end
40 <% end
41 reset_cycle %>
41 reset_cycle %>
42 <% end %>
42 <% end %>
43 </tbody>
43 </tbody>
44 </table>
44 </table>
45
45
46 <% html_title(l(:label_attachment_plural)) -%>
46 <% html_title(l(:label_attachment_plural)) -%>
@@ -1,258 +1,258
1 ActionController::Routing::Routes.draw do |map|
1 ActionController::Routing::Routes.draw do |map|
2 # Add your own custom routes here.
2 # Add your own custom routes here.
3 # The priority is based upon order of creation: first created -> highest priority.
3 # The priority is based upon order of creation: first created -> highest priority.
4
4
5 # Here's a sample route:
5 # Here's a sample route:
6 # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
6 # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
7 # Keep in mind you can assign values other than :controller and :action
7 # Keep in mind you can assign values other than :controller and :action
8
8
9 map.home '', :controller => 'welcome'
9 map.home '', :controller => 'welcome'
10
10
11 map.signin 'login', :controller => 'account', :action => 'login'
11 map.signin 'login', :controller => 'account', :action => 'login'
12 map.signout 'logout', :controller => 'account', :action => 'logout'
12 map.signout 'logout', :controller => 'account', :action => 'logout'
13
13
14 map.connect 'roles/workflow/:id/:role_id/:tracker_id', :controller => 'roles', :action => 'workflow'
14 map.connect 'roles/workflow/:id/:role_id/:tracker_id', :controller => 'roles', :action => 'workflow'
15 map.connect 'help/:ctrl/:page', :controller => 'help'
15 map.connect 'help/:ctrl/:page', :controller => 'help'
16
16
17 map.with_options :controller => 'time_entry_reports', :action => 'report',:conditions => {:method => :get} do |time_report|
17 map.with_options :controller => 'time_entry_reports', :action => 'report',:conditions => {:method => :get} do |time_report|
18 time_report.connect 'projects/:project_id/issues/:issue_id/time_entries/report'
18 time_report.connect 'projects/:project_id/issues/:issue_id/time_entries/report'
19 time_report.connect 'projects/:project_id/issues/:issue_id/time_entries/report.:format'
19 time_report.connect 'projects/:project_id/issues/:issue_id/time_entries/report.:format'
20 time_report.connect 'projects/:project_id/time_entries/report'
20 time_report.connect 'projects/:project_id/time_entries/report'
21 time_report.connect 'projects/:project_id/time_entries/report.:format'
21 time_report.connect 'projects/:project_id/time_entries/report.:format'
22 time_report.connect 'time_entries/report'
22 time_report.connect 'time_entries/report'
23 time_report.connect 'time_entries/report.:format'
23 time_report.connect 'time_entries/report.:format'
24 end
24 end
25
25
26 map.bulk_edit_time_entry 'time_entries/bulk_edit',
26 map.bulk_edit_time_entry 'time_entries/bulk_edit',
27 :controller => 'timelog', :action => 'bulk_edit', :conditions => { :method => :get }
27 :controller => 'timelog', :action => 'bulk_edit', :conditions => { :method => :get }
28 map.bulk_update_time_entry 'time_entries/bulk_edit',
28 map.bulk_update_time_entry 'time_entries/bulk_edit',
29 :controller => 'timelog', :action => 'bulk_update', :conditions => { :method => :post }
29 :controller => 'timelog', :action => 'bulk_update', :conditions => { :method => :post }
30 map.time_entries_context_menu '/time_entries/context_menu',
30 map.time_entries_context_menu '/time_entries/context_menu',
31 :controller => 'context_menus', :action => 'time_entries'
31 :controller => 'context_menus', :action => 'time_entries'
32 # TODO: wasteful since this is also nested under issues, projects, and projects/issues
32 # TODO: wasteful since this is also nested under issues, projects, and projects/issues
33 map.resources :time_entries, :controller => 'timelog'
33 map.resources :time_entries, :controller => 'timelog'
34
34
35 map.connect 'projects/:id/wiki', :controller => 'wikis', :action => 'edit', :conditions => {:method => :post}
35 map.connect 'projects/:id/wiki', :controller => 'wikis', :action => 'edit', :conditions => {:method => :post}
36 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :get}
36 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :get}
37 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :post}
37 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :post}
38
38
39 map.with_options :controller => 'messages' do |messages_routes|
39 map.with_options :controller => 'messages' do |messages_routes|
40 messages_routes.with_options :conditions => {:method => :get} do |messages_views|
40 messages_routes.with_options :conditions => {:method => :get} do |messages_views|
41 messages_views.connect 'boards/:board_id/topics/new', :action => 'new'
41 messages_views.connect 'boards/:board_id/topics/new', :action => 'new'
42 messages_views.connect 'boards/:board_id/topics/:id', :action => 'show'
42 messages_views.connect 'boards/:board_id/topics/:id', :action => 'show'
43 messages_views.connect 'boards/:board_id/topics/:id/edit', :action => 'edit'
43 messages_views.connect 'boards/:board_id/topics/:id/edit', :action => 'edit'
44 end
44 end
45 messages_routes.with_options :conditions => {:method => :post} do |messages_actions|
45 messages_routes.with_options :conditions => {:method => :post} do |messages_actions|
46 messages_actions.connect 'boards/:board_id/topics/new', :action => 'new'
46 messages_actions.connect 'boards/:board_id/topics/new', :action => 'new'
47 messages_actions.connect 'boards/:board_id/topics/:id/replies', :action => 'reply'
47 messages_actions.connect 'boards/:board_id/topics/:id/replies', :action => 'reply'
48 messages_actions.connect 'boards/:board_id/topics/:id/:action', :action => /edit|destroy/
48 messages_actions.connect 'boards/:board_id/topics/:id/:action', :action => /edit|destroy/
49 end
49 end
50 end
50 end
51
51
52 map.with_options :controller => 'boards' do |board_routes|
52 map.with_options :controller => 'boards' do |board_routes|
53 board_routes.with_options :conditions => {:method => :get} do |board_views|
53 board_routes.with_options :conditions => {:method => :get} do |board_views|
54 board_views.connect 'projects/:project_id/boards', :action => 'index'
54 board_views.connect 'projects/:project_id/boards', :action => 'index'
55 board_views.connect 'projects/:project_id/boards/new', :action => 'new'
55 board_views.connect 'projects/:project_id/boards/new', :action => 'new'
56 board_views.connect 'projects/:project_id/boards/:id', :action => 'show'
56 board_views.connect 'projects/:project_id/boards/:id', :action => 'show'
57 board_views.connect 'projects/:project_id/boards/:id.:format', :action => 'show'
57 board_views.connect 'projects/:project_id/boards/:id.:format', :action => 'show'
58 board_views.connect 'projects/:project_id/boards/:id/edit', :action => 'edit'
58 board_views.connect 'projects/:project_id/boards/:id/edit', :action => 'edit'
59 end
59 end
60 board_routes.with_options :conditions => {:method => :post} do |board_actions|
60 board_routes.with_options :conditions => {:method => :post} do |board_actions|
61 board_actions.connect 'projects/:project_id/boards', :action => 'new'
61 board_actions.connect 'projects/:project_id/boards', :action => 'new'
62 board_actions.connect 'projects/:project_id/boards/:id/:action', :action => /edit|destroy/
62 board_actions.connect 'projects/:project_id/boards/:id/:action', :action => /edit|destroy/
63 end
63 end
64 end
64 end
65
65
66 map.with_options :controller => 'documents' do |document_routes|
66 map.with_options :controller => 'documents' do |document_routes|
67 document_routes.with_options :conditions => {:method => :get} do |document_views|
67 document_routes.with_options :conditions => {:method => :get} do |document_views|
68 document_views.connect 'projects/:project_id/documents', :action => 'index'
68 document_views.connect 'projects/:project_id/documents', :action => 'index'
69 document_views.connect 'projects/:project_id/documents/new', :action => 'new'
69 document_views.connect 'projects/:project_id/documents/new', :action => 'new'
70 document_views.connect 'documents/:id', :action => 'show'
70 document_views.connect 'documents/:id', :action => 'show'
71 document_views.connect 'documents/:id/edit', :action => 'edit'
71 document_views.connect 'documents/:id/edit', :action => 'edit'
72 end
72 end
73 document_routes.with_options :conditions => {:method => :post} do |document_actions|
73 document_routes.with_options :conditions => {:method => :post} do |document_actions|
74 document_actions.connect 'projects/:project_id/documents', :action => 'new'
74 document_actions.connect 'projects/:project_id/documents', :action => 'new'
75 document_actions.connect 'documents/:id/:action', :action => /destroy|edit/
75 document_actions.connect 'documents/:id/:action', :action => /destroy|edit/
76 end
76 end
77 end
77 end
78
78
79 map.resources :issue_moves, :only => [:new, :create], :path_prefix => '/issues', :as => 'move'
79 map.resources :issue_moves, :only => [:new, :create], :path_prefix => '/issues', :as => 'move'
80 map.resources :queries, :except => [:show]
80 map.resources :queries, :except => [:show]
81
81
82 # Misc issue routes. TODO: move into resources
82 # Misc issue routes. TODO: move into resources
83 map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes', :action => 'issues'
83 map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes', :action => 'issues'
84 map.preview_issue '/issues/preview/:id', :controller => 'previews', :action => 'issue' # TODO: would look nicer as /issues/:id/preview
84 map.preview_issue '/issues/preview/:id', :controller => 'previews', :action => 'issue' # TODO: would look nicer as /issues/:id/preview
85 map.issues_context_menu '/issues/context_menu', :controller => 'context_menus', :action => 'issues'
85 map.issues_context_menu '/issues/context_menu', :controller => 'context_menus', :action => 'issues'
86 map.issue_changes '/issues/changes', :controller => 'journals', :action => 'index'
86 map.issue_changes '/issues/changes', :controller => 'journals', :action => 'index'
87 map.bulk_edit_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_edit', :conditions => { :method => :get }
87 map.bulk_edit_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_edit', :conditions => { :method => :get }
88 map.bulk_update_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_update', :conditions => { :method => :post }
88 map.bulk_update_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_update', :conditions => { :method => :post }
89 map.quoted_issue '/issues/:id/quoted', :controller => 'journals', :action => 'new', :id => /\d+/, :conditions => { :method => :post }
89 map.quoted_issue '/issues/:id/quoted', :controller => 'journals', :action => 'new', :id => /\d+/, :conditions => { :method => :post }
90 map.connect '/issues/:id/destroy', :controller => 'issues', :action => 'destroy', :conditions => { :method => :post } # legacy
90 map.connect '/issues/:id/destroy', :controller => 'issues', :action => 'destroy', :conditions => { :method => :post } # legacy
91
91
92 map.with_options :controller => 'gantts', :action => 'show' do |gantts_routes|
92 map.with_options :controller => 'gantts', :action => 'show' do |gantts_routes|
93 gantts_routes.connect '/projects/:project_id/issues/gantt'
93 gantts_routes.connect '/projects/:project_id/issues/gantt'
94 gantts_routes.connect '/projects/:project_id/issues/gantt.:format'
94 gantts_routes.connect '/projects/:project_id/issues/gantt.:format'
95 gantts_routes.connect '/issues/gantt.:format'
95 gantts_routes.connect '/issues/gantt.:format'
96 end
96 end
97
97
98 map.with_options :controller => 'calendars', :action => 'show' do |calendars_routes|
98 map.with_options :controller => 'calendars', :action => 'show' do |calendars_routes|
99 calendars_routes.connect '/projects/:project_id/issues/calendar'
99 calendars_routes.connect '/projects/:project_id/issues/calendar'
100 calendars_routes.connect '/issues/calendar'
100 calendars_routes.connect '/issues/calendar'
101 end
101 end
102
102
103 map.with_options :controller => 'reports', :conditions => {:method => :get} do |reports|
103 map.with_options :controller => 'reports', :conditions => {:method => :get} do |reports|
104 reports.connect 'projects/:id/issues/report', :action => 'issue_report'
104 reports.connect 'projects/:id/issues/report', :action => 'issue_report'
105 reports.connect 'projects/:id/issues/report/:detail', :action => 'issue_report_details'
105 reports.connect 'projects/:id/issues/report/:detail', :action => 'issue_report_details'
106 end
106 end
107
107
108 # Following two routes conflict with the resources because #index allows POST
108 # Following two routes conflict with the resources because #index allows POST
109 map.connect '/issues', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
109 map.connect '/issues', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
110 map.connect '/issues/create', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
110 map.connect '/issues/create', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
111
111
112 map.resources :issues, :member => { :edit => :post }, :collection => {} do |issues|
112 map.resources :issues, :member => { :edit => :post }, :collection => {} do |issues|
113 issues.resources :time_entries, :controller => 'timelog'
113 issues.resources :time_entries, :controller => 'timelog'
114 issues.resources :relations, :shallow => true, :controller => 'issue_relations', :only => [:index, :show, :create, :destroy]
114 issues.resources :relations, :shallow => true, :controller => 'issue_relations', :only => [:index, :show, :create, :destroy]
115 end
115 end
116
116
117 map.resources :issues, :path_prefix => '/projects/:project_id', :collection => { :create => :post } do |issues|
117 map.resources :issues, :path_prefix => '/projects/:project_id', :collection => { :create => :post } do |issues|
118 issues.resources :time_entries, :controller => 'timelog'
118 issues.resources :time_entries, :controller => 'timelog'
119 end
119 end
120
120
121 map.connect 'projects/:id/members/new', :controller => 'members', :action => 'new'
121 map.connect 'projects/:id/members/new', :controller => 'members', :action => 'new'
122
122
123 map.with_options :controller => 'users' do |users|
123 map.with_options :controller => 'users' do |users|
124 users.connect 'users/:id/edit/:tab', :action => 'edit', :tab => nil, :conditions => {:method => :get}
124 users.connect 'users/:id/edit/:tab', :action => 'edit', :tab => nil, :conditions => {:method => :get}
125
125
126 users.with_options :conditions => {:method => :post} do |user_actions|
126 users.with_options :conditions => {:method => :post} do |user_actions|
127 user_actions.connect 'users/:id/memberships', :action => 'edit_membership'
127 user_actions.connect 'users/:id/memberships', :action => 'edit_membership'
128 user_actions.connect 'users/:id/memberships/:membership_id', :action => 'edit_membership'
128 user_actions.connect 'users/:id/memberships/:membership_id', :action => 'edit_membership'
129 user_actions.connect 'users/:id/memberships/:membership_id/destroy', :action => 'destroy_membership'
129 user_actions.connect 'users/:id/memberships/:membership_id/destroy', :action => 'destroy_membership'
130 end
130 end
131 end
131 end
132
132
133 map.resources :users, :member => {
133 map.resources :users, :member => {
134 :edit_membership => :post,
134 :edit_membership => :post,
135 :destroy_membership => :post
135 :destroy_membership => :post
136 }
136 }
137
137
138 # For nice "roadmap" in the url for the index action
138 # For nice "roadmap" in the url for the index action
139 map.connect 'projects/:project_id/roadmap', :controller => 'versions', :action => 'index'
139 map.connect 'projects/:project_id/roadmap', :controller => 'versions', :action => 'index'
140
140
141 map.all_news 'news', :controller => 'news', :action => 'index'
141 map.all_news 'news', :controller => 'news', :action => 'index'
142 map.formatted_all_news 'news.:format', :controller => 'news', :action => 'index'
142 map.formatted_all_news 'news.:format', :controller => 'news', :action => 'index'
143 map.preview_news '/news/preview', :controller => 'previews', :action => 'news'
143 map.preview_news '/news/preview', :controller => 'previews', :action => 'news'
144 map.connect 'news/:id/comments', :controller => 'comments', :action => 'create', :conditions => {:method => :post}
144 map.connect 'news/:id/comments', :controller => 'comments', :action => 'create', :conditions => {:method => :post}
145 map.connect 'news/:id/comments/:comment_id', :controller => 'comments', :action => 'destroy', :conditions => {:method => :delete}
145 map.connect 'news/:id/comments/:comment_id', :controller => 'comments', :action => 'destroy', :conditions => {:method => :delete}
146
146
147 map.resources :projects, :member => {
147 map.resources :projects, :member => {
148 :copy => [:get, :post],
148 :copy => [:get, :post],
149 :settings => :get,
149 :settings => :get,
150 :modules => :post,
150 :modules => :post,
151 :archive => :post,
151 :archive => :post,
152 :unarchive => :post
152 :unarchive => :post
153 } do |project|
153 } do |project|
154 project.resource :project_enumerations, :as => 'enumerations', :only => [:update, :destroy]
154 project.resource :project_enumerations, :as => 'enumerations', :only => [:update, :destroy]
155 project.resources :files, :only => [:index, :new, :create]
155 project.resources :files, :only => [:index, :new, :create]
156 project.resources :versions, :shallow => true, :collection => {:close_completed => :put}, :member => {:status_by => :post}
156 project.resources :versions, :shallow => true, :collection => {:close_completed => :put}, :member => {:status_by => :post}
157 project.resources :news, :shallow => true
157 project.resources :news, :shallow => true
158 project.resources :time_entries, :controller => 'timelog', :path_prefix => 'projects/:project_id'
158 project.resources :time_entries, :controller => 'timelog', :path_prefix => 'projects/:project_id'
159 project.resources :queries, :only => [:new, :create]
159 project.resources :queries, :only => [:new, :create]
160 project.resources :issue_categories, :shallow => true
160 project.resources :issue_categories, :shallow => true
161
161
162 project.wiki_start_page 'wiki', :controller => 'wiki', :action => 'show', :conditions => {:method => :get}
162 project.wiki_start_page 'wiki', :controller => 'wiki', :action => 'show', :conditions => {:method => :get}
163 project.wiki_index 'wiki/index', :controller => 'wiki', :action => 'index', :conditions => {:method => :get}
163 project.wiki_index 'wiki/index', :controller => 'wiki', :action => 'index', :conditions => {:method => :get}
164 project.wiki_diff 'wiki/:id/diff/:version', :controller => 'wiki', :action => 'diff', :version => nil
164 project.wiki_diff 'wiki/:id/diff/:version', :controller => 'wiki', :action => 'diff', :version => nil
165 project.wiki_diff 'wiki/:id/diff/:version/vs/:version_from', :controller => 'wiki', :action => 'diff'
165 project.wiki_diff 'wiki/:id/diff/:version/vs/:version_from', :controller => 'wiki', :action => 'diff'
166 project.wiki_annotate 'wiki/:id/annotate/:version', :controller => 'wiki', :action => 'annotate'
166 project.wiki_annotate 'wiki/:id/annotate/:version', :controller => 'wiki', :action => 'annotate'
167 project.resources :wiki, :except => [:new, :create], :member => {
167 project.resources :wiki, :except => [:new, :create], :member => {
168 :rename => [:get, :post],
168 :rename => [:get, :post],
169 :history => :get,
169 :history => :get,
170 :preview => :any,
170 :preview => :any,
171 :protect => :post,
171 :protect => :post,
172 :add_attachment => :post
172 :add_attachment => :post
173 }, :collection => {
173 }, :collection => {
174 :export => :get,
174 :export => :get,
175 :date_index => :get
175 :date_index => :get
176 }
176 }
177
177
178 end
178 end
179
179
180 # Destroy uses a get request to prompt the user before the actual DELETE request
180 # Destroy uses a get request to prompt the user before the actual DELETE request
181 map.project_destroy_confirm 'projects/:id/destroy', :controller => 'projects', :action => 'destroy', :conditions => {:method => :get}
181 map.project_destroy_confirm 'projects/:id/destroy', :controller => 'projects', :action => 'destroy', :conditions => {:method => :get}
182
182
183 # TODO: port to be part of the resources route(s)
183 # TODO: port to be part of the resources route(s)
184 map.with_options :controller => 'projects' do |project_mapper|
184 map.with_options :controller => 'projects' do |project_mapper|
185 project_mapper.with_options :conditions => {:method => :get} do |project_views|
185 project_mapper.with_options :conditions => {:method => :get} do |project_views|
186 project_views.connect 'projects/:id/settings/:tab', :controller => 'projects', :action => 'settings'
186 project_views.connect 'projects/:id/settings/:tab', :controller => 'projects', :action => 'settings'
187 project_views.connect 'projects/:project_id/issues/:copy_from/copy', :controller => 'issues', :action => 'new'
187 project_views.connect 'projects/:project_id/issues/:copy_from/copy', :controller => 'issues', :action => 'new'
188 end
188 end
189 end
189 end
190
190
191 map.with_options :controller => 'activities', :action => 'index', :conditions => {:method => :get} do |activity|
191 map.with_options :controller => 'activities', :action => 'index', :conditions => {:method => :get} do |activity|
192 activity.connect 'projects/:id/activity'
192 activity.connect 'projects/:id/activity'
193 activity.connect 'projects/:id/activity.:format'
193 activity.connect 'projects/:id/activity.:format'
194 activity.connect 'activity', :id => nil
194 activity.connect 'activity', :id => nil
195 activity.connect 'activity.:format', :id => nil
195 activity.connect 'activity.:format', :id => nil
196 end
196 end
197
197
198 map.with_options :controller => 'repositories' do |repositories|
198 map.with_options :controller => 'repositories' do |repositories|
199 repositories.with_options :conditions => {:method => :get} do |repository_views|
199 repositories.with_options :conditions => {:method => :get} do |repository_views|
200 repository_views.connect 'projects/:id/repository', :action => 'show'
200 repository_views.connect 'projects/:id/repository', :action => 'show'
201 repository_views.connect 'projects/:id/repository/edit', :action => 'edit'
201 repository_views.connect 'projects/:id/repository/edit', :action => 'edit'
202 repository_views.connect 'projects/:id/repository/statistics', :action => 'stats'
202 repository_views.connect 'projects/:id/repository/statistics', :action => 'stats'
203 repository_views.connect 'projects/:id/repository/revisions', :action => 'revisions'
203 repository_views.connect 'projects/:id/repository/revisions', :action => 'revisions'
204 repository_views.connect 'projects/:id/repository/revisions.:format', :action => 'revisions'
204 repository_views.connect 'projects/:id/repository/revisions.:format', :action => 'revisions'
205 repository_views.connect 'projects/:id/repository/revisions/:rev', :action => 'revision'
205 repository_views.connect 'projects/:id/repository/revisions/:rev', :action => 'revision'
206 repository_views.connect 'projects/:id/repository/revisions/:rev/diff', :action => 'diff'
206 repository_views.connect 'projects/:id/repository/revisions/:rev/diff', :action => 'diff'
207 repository_views.connect 'projects/:id/repository/revisions/:rev/diff.:format', :action => 'diff'
207 repository_views.connect 'projects/:id/repository/revisions/:rev/diff.:format', :action => 'diff'
208 repository_views.connect 'projects/:id/repository/revisions/:rev/raw/*path', :action => 'entry', :format => 'raw', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
208 repository_views.connect 'projects/:id/repository/revisions/:rev/raw/*path', :action => 'entry', :format => 'raw', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
209 repository_views.connect 'projects/:id/repository/revisions/:rev/:action/*path', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
209 repository_views.connect 'projects/:id/repository/revisions/:rev/:action/*path', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
210 repository_views.connect 'projects/:id/repository/raw/*path', :action => 'entry', :format => 'raw'
210 repository_views.connect 'projects/:id/repository/raw/*path', :action => 'entry', :format => 'raw'
211 # TODO: why the following route is required?
211 # TODO: why the following route is required?
212 repository_views.connect 'projects/:id/repository/entry/*path', :action => 'entry'
212 repository_views.connect 'projects/:id/repository/entry/*path', :action => 'entry'
213 repository_views.connect 'projects/:id/repository/:action/*path'
213 repository_views.connect 'projects/:id/repository/:action/*path'
214 end
214 end
215
215
216 repositories.connect 'projects/:id/repository/:action', :conditions => {:method => :post}
216 repositories.connect 'projects/:id/repository/:action', :conditions => {:method => :post}
217 end
217 end
218
218
219 map.connect 'attachments/:id', :controller => 'attachments', :action => 'show', :id => /\d+/
219 map.resources :attachments, :only => [:show, :destroy]
220 map.connect 'attachments/:id.:format', :controller => 'attachments', :action => 'show', :id => /\d+/
220 # additional routes for having the file name at the end of url
221 map.connect 'attachments/:id/:filename', :controller => 'attachments', :action => 'show', :id => /\d+/, :filename => /.*/
221 map.connect 'attachments/:id/:filename', :controller => 'attachments', :action => 'show', :id => /\d+/, :filename => /.*/
222 map.connect 'attachments/download/:id/:filename', :controller => 'attachments', :action => 'download', :id => /\d+/, :filename => /.*/
222 map.connect 'attachments/download/:id/:filename', :controller => 'attachments', :action => 'download', :id => /\d+/, :filename => /.*/
223
223
224 map.resources :groups, :member => {:autocomplete_for_user => :get}
224 map.resources :groups, :member => {:autocomplete_for_user => :get}
225 map.group_users 'groups/:id/users', :controller => 'groups', :action => 'add_users', :id => /\d+/, :conditions => {:method => :post}
225 map.group_users 'groups/:id/users', :controller => 'groups', :action => 'add_users', :id => /\d+/, :conditions => {:method => :post}
226 map.group_user 'groups/:id/users/:user_id', :controller => 'groups', :action => 'remove_user', :id => /\d+/, :conditions => {:method => :delete}
226 map.group_user 'groups/:id/users/:user_id', :controller => 'groups', :action => 'remove_user', :id => /\d+/, :conditions => {:method => :delete}
227
227
228 map.resources :trackers, :except => :show
228 map.resources :trackers, :except => :show
229 map.resources :issue_statuses, :except => :show, :collection => {:update_issue_done_ratio => :post}
229 map.resources :issue_statuses, :except => :show, :collection => {:update_issue_done_ratio => :post}
230
230
231 #left old routes at the bottom for backwards compat
231 #left old routes at the bottom for backwards compat
232 map.connect 'projects/:project_id/issues/:action', :controller => 'issues'
232 map.connect 'projects/:project_id/issues/:action', :controller => 'issues'
233 map.connect 'projects/:project_id/documents/:action', :controller => 'documents'
233 map.connect 'projects/:project_id/documents/:action', :controller => 'documents'
234 map.connect 'projects/:project_id/boards/:action/:id', :controller => 'boards'
234 map.connect 'projects/:project_id/boards/:action/:id', :controller => 'boards'
235 map.connect 'boards/:board_id/topics/:action/:id', :controller => 'messages'
235 map.connect 'boards/:board_id/topics/:action/:id', :controller => 'messages'
236 map.connect 'wiki/:id/:page/:action', :page => nil, :controller => 'wiki'
236 map.connect 'wiki/:id/:page/:action', :page => nil, :controller => 'wiki'
237 map.connect 'projects/:project_id/news/:action', :controller => 'news'
237 map.connect 'projects/:project_id/news/:action', :controller => 'news'
238 map.connect 'projects/:project_id/timelog/:action/:id', :controller => 'timelog', :project_id => /.+/
238 map.connect 'projects/:project_id/timelog/:action/:id', :controller => 'timelog', :project_id => /.+/
239 map.with_options :controller => 'repositories' do |omap|
239 map.with_options :controller => 'repositories' do |omap|
240 omap.repositories_show 'repositories/browse/:id/*path', :action => 'browse'
240 omap.repositories_show 'repositories/browse/:id/*path', :action => 'browse'
241 omap.repositories_changes 'repositories/changes/:id/*path', :action => 'changes'
241 omap.repositories_changes 'repositories/changes/:id/*path', :action => 'changes'
242 omap.repositories_diff 'repositories/diff/:id/*path', :action => 'diff'
242 omap.repositories_diff 'repositories/diff/:id/*path', :action => 'diff'
243 omap.repositories_entry 'repositories/entry/:id/*path', :action => 'entry'
243 omap.repositories_entry 'repositories/entry/:id/*path', :action => 'entry'
244 omap.repositories_entry 'repositories/annotate/:id/*path', :action => 'annotate'
244 omap.repositories_entry 'repositories/annotate/:id/*path', :action => 'annotate'
245 omap.connect 'repositories/revision/:id/:rev', :action => 'revision'
245 omap.connect 'repositories/revision/:id/:rev', :action => 'revision'
246 end
246 end
247
247
248 map.with_options :controller => 'sys' do |sys|
248 map.with_options :controller => 'sys' do |sys|
249 sys.connect 'sys/projects.:format', :action => 'projects', :conditions => {:method => :get}
249 sys.connect 'sys/projects.:format', :action => 'projects', :conditions => {:method => :get}
250 sys.connect 'sys/projects/:id/repository.:format', :action => 'create_project_repository', :conditions => {:method => :post}
250 sys.connect 'sys/projects/:id/repository.:format', :action => 'create_project_repository', :conditions => {:method => :post}
251 end
251 end
252
252
253 # Install the default route as the lowest priority.
253 # Install the default route as the lowest priority.
254 map.connect ':controller/:action/:id'
254 map.connect ':controller/:action/:id'
255 map.connect 'robots.txt', :controller => 'welcome', :action => 'robots'
255 map.connect 'robots.txt', :controller => 'welcome', :action => 'robots'
256 # Used for OpenID
256 # Used for OpenID
257 map.root :controller => 'account', :action => 'login'
257 map.root :controller => 'account', :action => 'login'
258 end
258 end
@@ -1,272 +1,274
1 # encoding: utf-8
1 # encoding: utf-8
2 #
2 #
3 # Redmine - project management software
3 # Redmine - project management software
4 # Copyright (C) 2006-2011 Jean-Philippe Lang
4 # Copyright (C) 2006-2011 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 require File.expand_path('../../test_helper', __FILE__)
20 require File.expand_path('../../test_helper', __FILE__)
21 require 'attachments_controller'
21 require 'attachments_controller'
22
22
23 # Re-raise errors caught by the controller.
23 # Re-raise errors caught by the controller.
24 class AttachmentsController; def rescue_action(e) raise e end; end
24 class AttachmentsController; def rescue_action(e) raise e end; end
25
25
26 class AttachmentsControllerTest < ActionController::TestCase
26 class AttachmentsControllerTest < ActionController::TestCase
27 fixtures :users, :projects, :roles, :members, :member_roles,
27 fixtures :users, :projects, :roles, :members, :member_roles,
28 :enabled_modules, :issues, :trackers, :attachments,
28 :enabled_modules, :issues, :trackers, :attachments,
29 :versions, :wiki_pages, :wikis, :documents
29 :versions, :wiki_pages, :wikis, :documents
30
30
31 def setup
31 def setup
32 @controller = AttachmentsController.new
32 @controller = AttachmentsController.new
33 @request = ActionController::TestRequest.new
33 @request = ActionController::TestRequest.new
34 @response = ActionController::TestResponse.new
34 @response = ActionController::TestResponse.new
35 Attachment.storage_path = "#{Rails.root}/test/fixtures/files"
35 Attachment.storage_path = "#{Rails.root}/test/fixtures/files"
36 User.current = nil
36 User.current = nil
37 end
37 end
38
38
39 def test_show_diff
39 def test_show_diff
40 ['inline', 'sbs'].each do |dt|
40 ['inline', 'sbs'].each do |dt|
41 # 060719210727_changeset_utf8.diff
41 # 060719210727_changeset_utf8.diff
42 get :show, :id => 14, :type => dt
42 get :show, :id => 14, :type => dt
43 assert_response :success
43 assert_response :success
44 assert_template 'diff'
44 assert_template 'diff'
45 assert_equal 'text/html', @response.content_type
45 assert_equal 'text/html', @response.content_type
46 assert_tag 'th',
46 assert_tag 'th',
47 :attributes => {:class => /filename/},
47 :attributes => {:class => /filename/},
48 :content => /issues_controller.rb\t\(rΓ©vision 1484\)/
48 :content => /issues_controller.rb\t\(rΓ©vision 1484\)/
49 assert_tag 'td',
49 assert_tag 'td',
50 :attributes => {:class => /line-code/},
50 :attributes => {:class => /line-code/},
51 :content => /Demande créée avec succès/
51 :content => /Demande créée avec succès/
52 end
52 end
53 set_tmp_attachments_directory
53 set_tmp_attachments_directory
54 end
54 end
55
55
56 def test_show_diff_replcace_cannot_convert_content
56 def test_show_diff_replcace_cannot_convert_content
57 with_settings :repositories_encodings => 'UTF-8' do
57 with_settings :repositories_encodings => 'UTF-8' do
58 ['inline', 'sbs'].each do |dt|
58 ['inline', 'sbs'].each do |dt|
59 # 060719210727_changeset_iso8859-1.diff
59 # 060719210727_changeset_iso8859-1.diff
60 get :show, :id => 5, :type => dt
60 get :show, :id => 5, :type => dt
61 assert_response :success
61 assert_response :success
62 assert_template 'diff'
62 assert_template 'diff'
63 assert_equal 'text/html', @response.content_type
63 assert_equal 'text/html', @response.content_type
64 assert_tag 'th',
64 assert_tag 'th',
65 :attributes => {:class => "filename"},
65 :attributes => {:class => "filename"},
66 :content => /issues_controller.rb\t\(r\?vision 1484\)/
66 :content => /issues_controller.rb\t\(r\?vision 1484\)/
67 assert_tag 'td',
67 assert_tag 'td',
68 :attributes => {:class => /line-code/},
68 :attributes => {:class => /line-code/},
69 :content => /Demande cr\?\?e avec succ\?s/
69 :content => /Demande cr\?\?e avec succ\?s/
70 end
70 end
71 end
71 end
72 set_tmp_attachments_directory
72 set_tmp_attachments_directory
73 end
73 end
74
74
75 def test_show_diff_latin_1
75 def test_show_diff_latin_1
76 with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
76 with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
77 ['inline', 'sbs'].each do |dt|
77 ['inline', 'sbs'].each do |dt|
78 # 060719210727_changeset_iso8859-1.diff
78 # 060719210727_changeset_iso8859-1.diff
79 get :show, :id => 5, :type => dt
79 get :show, :id => 5, :type => dt
80 assert_response :success
80 assert_response :success
81 assert_template 'diff'
81 assert_template 'diff'
82 assert_equal 'text/html', @response.content_type
82 assert_equal 'text/html', @response.content_type
83 assert_tag 'th',
83 assert_tag 'th',
84 :attributes => {:class => "filename"},
84 :attributes => {:class => "filename"},
85 :content => /issues_controller.rb\t\(rΓ©vision 1484\)/
85 :content => /issues_controller.rb\t\(rΓ©vision 1484\)/
86 assert_tag 'td',
86 assert_tag 'td',
87 :attributes => {:class => /line-code/},
87 :attributes => {:class => /line-code/},
88 :content => /Demande créée avec succès/
88 :content => /Demande créée avec succès/
89 end
89 end
90 end
90 end
91 set_tmp_attachments_directory
91 set_tmp_attachments_directory
92 end
92 end
93
93
94 def test_show_text_file
94 def test_show_text_file
95 get :show, :id => 4
95 get :show, :id => 4
96 assert_response :success
96 assert_response :success
97 assert_template 'file'
97 assert_template 'file'
98 assert_equal 'text/html', @response.content_type
98 assert_equal 'text/html', @response.content_type
99 set_tmp_attachments_directory
99 set_tmp_attachments_directory
100 end
100 end
101
101
102 def test_show_text_file_utf_8
102 def test_show_text_file_utf_8
103 set_tmp_attachments_directory
103 set_tmp_attachments_directory
104 a = Attachment.new(:container => Issue.find(1),
104 a = Attachment.new(:container => Issue.find(1),
105 :file => uploaded_test_file("japanese-utf-8.txt", "text/plain"),
105 :file => uploaded_test_file("japanese-utf-8.txt", "text/plain"),
106 :author => User.find(1))
106 :author => User.find(1))
107 assert a.save
107 assert a.save
108 assert_equal 'japanese-utf-8.txt', a.filename
108 assert_equal 'japanese-utf-8.txt', a.filename
109
109
110 str_japanese = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"
110 str_japanese = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"
111 str_japanese.force_encoding('UTF-8') if str_japanese.respond_to?(:force_encoding)
111 str_japanese.force_encoding('UTF-8') if str_japanese.respond_to?(:force_encoding)
112
112
113 get :show, :id => a.id
113 get :show, :id => a.id
114 assert_response :success
114 assert_response :success
115 assert_template 'file'
115 assert_template 'file'
116 assert_equal 'text/html', @response.content_type
116 assert_equal 'text/html', @response.content_type
117 assert_tag :tag => 'th',
117 assert_tag :tag => 'th',
118 :content => '1',
118 :content => '1',
119 :attributes => { :class => 'line-num' },
119 :attributes => { :class => 'line-num' },
120 :sibling => { :tag => 'td', :content => /#{str_japanese}/ }
120 :sibling => { :tag => 'td', :content => /#{str_japanese}/ }
121 end
121 end
122
122
123 def test_show_text_file_replcace_cannot_convert_content
123 def test_show_text_file_replcace_cannot_convert_content
124 set_tmp_attachments_directory
124 set_tmp_attachments_directory
125 with_settings :repositories_encodings => 'UTF-8' do
125 with_settings :repositories_encodings => 'UTF-8' do
126 a = Attachment.new(:container => Issue.find(1),
126 a = Attachment.new(:container => Issue.find(1),
127 :file => uploaded_test_file("iso8859-1.txt", "text/plain"),
127 :file => uploaded_test_file("iso8859-1.txt", "text/plain"),
128 :author => User.find(1))
128 :author => User.find(1))
129 assert a.save
129 assert a.save
130 assert_equal 'iso8859-1.txt', a.filename
130 assert_equal 'iso8859-1.txt', a.filename
131
131
132 get :show, :id => a.id
132 get :show, :id => a.id
133 assert_response :success
133 assert_response :success
134 assert_template 'file'
134 assert_template 'file'
135 assert_equal 'text/html', @response.content_type
135 assert_equal 'text/html', @response.content_type
136 assert_tag :tag => 'th',
136 assert_tag :tag => 'th',
137 :content => '7',
137 :content => '7',
138 :attributes => { :class => 'line-num' },
138 :attributes => { :class => 'line-num' },
139 :sibling => { :tag => 'td', :content => /Demande cr\?\?e avec succ\?s/ }
139 :sibling => { :tag => 'td', :content => /Demande cr\?\?e avec succ\?s/ }
140 end
140 end
141 end
141 end
142
142
143 def test_show_text_file_latin_1
143 def test_show_text_file_latin_1
144 set_tmp_attachments_directory
144 set_tmp_attachments_directory
145 with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
145 with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
146 a = Attachment.new(:container => Issue.find(1),
146 a = Attachment.new(:container => Issue.find(1),
147 :file => uploaded_test_file("iso8859-1.txt", "text/plain"),
147 :file => uploaded_test_file("iso8859-1.txt", "text/plain"),
148 :author => User.find(1))
148 :author => User.find(1))
149 assert a.save
149 assert a.save
150 assert_equal 'iso8859-1.txt', a.filename
150 assert_equal 'iso8859-1.txt', a.filename
151
151
152 get :show, :id => a.id
152 get :show, :id => a.id
153 assert_response :success
153 assert_response :success
154 assert_template 'file'
154 assert_template 'file'
155 assert_equal 'text/html', @response.content_type
155 assert_equal 'text/html', @response.content_type
156 assert_tag :tag => 'th',
156 assert_tag :tag => 'th',
157 :content => '7',
157 :content => '7',
158 :attributes => { :class => 'line-num' },
158 :attributes => { :class => 'line-num' },
159 :sibling => { :tag => 'td', :content => /Demande créée avec succès/ }
159 :sibling => { :tag => 'td', :content => /Demande créée avec succès/ }
160 end
160 end
161 end
161 end
162
162
163 def test_show_text_file_should_send_if_too_big
163 def test_show_text_file_should_send_if_too_big
164 Setting.file_max_size_displayed = 512
164 Setting.file_max_size_displayed = 512
165 Attachment.find(4).update_attribute :filesize, 754.kilobyte
165 Attachment.find(4).update_attribute :filesize, 754.kilobyte
166
166
167 get :show, :id => 4
167 get :show, :id => 4
168 assert_response :success
168 assert_response :success
169 assert_equal 'application/x-ruby', @response.content_type
169 assert_equal 'application/x-ruby', @response.content_type
170 set_tmp_attachments_directory
170 set_tmp_attachments_directory
171 end
171 end
172
172
173 def test_show_other
173 def test_show_other
174 get :show, :id => 6
174 get :show, :id => 6
175 assert_response :success
175 assert_response :success
176 assert_equal 'application/octet-stream', @response.content_type
176 assert_equal 'application/octet-stream', @response.content_type
177 set_tmp_attachments_directory
177 set_tmp_attachments_directory
178 end
178 end
179
179
180 def test_show_file_from_private_issue_without_permission
180 def test_show_file_from_private_issue_without_permission
181 get :show, :id => 15
181 get :show, :id => 15
182 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2F15'
182 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2F15'
183 set_tmp_attachments_directory
183 set_tmp_attachments_directory
184 end
184 end
185
185
186 def test_show_file_from_private_issue_with_permission
186 def test_show_file_from_private_issue_with_permission
187 @request.session[:user_id] = 2
187 @request.session[:user_id] = 2
188 get :show, :id => 15
188 get :show, :id => 15
189 assert_response :success
189 assert_response :success
190 assert_tag 'h2', :content => /private.diff/
190 assert_tag 'h2', :content => /private.diff/
191 set_tmp_attachments_directory
191 set_tmp_attachments_directory
192 end
192 end
193
193
194 def test_download_text_file
194 def test_download_text_file
195 get :download, :id => 4
195 get :download, :id => 4
196 assert_response :success
196 assert_response :success
197 assert_equal 'application/x-ruby', @response.content_type
197 assert_equal 'application/x-ruby', @response.content_type
198 set_tmp_attachments_directory
198 set_tmp_attachments_directory
199 end
199 end
200
200
201 def test_download_should_assign_content_type_if_blank
201 def test_download_should_assign_content_type_if_blank
202 Attachment.find(4).update_attribute(:content_type, '')
202 Attachment.find(4).update_attribute(:content_type, '')
203
203
204 get :download, :id => 4
204 get :download, :id => 4
205 assert_response :success
205 assert_response :success
206 assert_equal 'text/x-ruby', @response.content_type
206 assert_equal 'text/x-ruby', @response.content_type
207 set_tmp_attachments_directory
207 set_tmp_attachments_directory
208 end
208 end
209
209
210 def test_download_missing_file
210 def test_download_missing_file
211 get :download, :id => 2
211 get :download, :id => 2
212 assert_response 404
212 assert_response 404
213 set_tmp_attachments_directory
213 set_tmp_attachments_directory
214 end
214 end
215
215
216 def test_anonymous_on_private_private
216 def test_anonymous_on_private_private
217 get :download, :id => 7
217 get :download, :id => 7
218 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2Fdownload%2F7'
218 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2Fdownload%2F7'
219 set_tmp_attachments_directory
219 set_tmp_attachments_directory
220 end
220 end
221
221
222 def test_destroy_issue_attachment
222 def test_destroy_issue_attachment
223 issue = Issue.find(3)
223 issue = Issue.find(3)
224 @request.session[:user_id] = 2
224 @request.session[:user_id] = 2
225
225
226 assert_difference 'issue.attachments.count', -1 do
226 assert_difference 'issue.attachments.count', -1 do
227 post :destroy, :id => 1
227 delete :destroy, :id => 1
228 end
228 end
229 # no referrer
229 # no referrer
230 assert_redirected_to '/projects/ecookbook'
230 assert_redirected_to '/projects/ecookbook'
231 assert_nil Attachment.find_by_id(1)
231 assert_nil Attachment.find_by_id(1)
232 j = issue.journals.find(:first, :order => 'created_on DESC')
232 j = issue.journals.find(:first, :order => 'created_on DESC')
233 assert_equal 'attachment', j.details.first.property
233 assert_equal 'attachment', j.details.first.property
234 assert_equal '1', j.details.first.prop_key
234 assert_equal '1', j.details.first.prop_key
235 assert_equal 'error281.txt', j.details.first.old_value
235 assert_equal 'error281.txt', j.details.first.old_value
236 set_tmp_attachments_directory
236 set_tmp_attachments_directory
237 end
237 end
238
238
239 def test_destroy_wiki_page_attachment
239 def test_destroy_wiki_page_attachment
240 @request.session[:user_id] = 2
240 @request.session[:user_id] = 2
241 assert_difference 'Attachment.count', -1 do
241 assert_difference 'Attachment.count', -1 do
242 post :destroy, :id => 3
242 delete :destroy, :id => 3
243 assert_response 302
243 assert_response 302
244 end
244 end
245 set_tmp_attachments_directory
245 set_tmp_attachments_directory
246 end
246 end
247
247
248 def test_destroy_project_attachment
248 def test_destroy_project_attachment
249 @request.session[:user_id] = 2
249 @request.session[:user_id] = 2
250 assert_difference 'Attachment.count', -1 do
250 assert_difference 'Attachment.count', -1 do
251 post :destroy, :id => 8
251 delete :destroy, :id => 8
252 assert_response 302
252 assert_response 302
253 end
253 end
254 set_tmp_attachments_directory
254 set_tmp_attachments_directory
255 end
255 end
256
256
257 def test_destroy_version_attachment
257 def test_destroy_version_attachment
258 @request.session[:user_id] = 2
258 @request.session[:user_id] = 2
259 assert_difference 'Attachment.count', -1 do
259 assert_difference 'Attachment.count', -1 do
260 post :destroy, :id => 9
260 delete :destroy, :id => 9
261 assert_response 302
261 assert_response 302
262 end
262 end
263 set_tmp_attachments_directory
263 set_tmp_attachments_directory
264 end
264 end
265
265
266 def test_destroy_without_permission
266 def test_destroy_without_permission
267 post :destroy, :id => 3
267 assert_no_difference 'Attachment.count' do
268 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2Fdestroy%2F3'
268 delete :destroy, :id => 3
269 end
270 assert_response 302
269 assert Attachment.find_by_id(3)
271 assert Attachment.find_by_id(3)
270 set_tmp_attachments_directory
272 set_tmp_attachments_directory
271 end
273 end
272 end
274 end
General Comments 0
You need to be logged in to leave comments. Login now