##// END OF EJS Templates
Changed timelogs filters to use non-AJAX requests (#1965)....
Jean-Philippe Lang -
r5177:b0ade644d60c
parent child
Show More
@@ -1,76 +1,73
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'new', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time-add' %>
2 <%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'new', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time-add' %>
3 </div>
3 </div>
4
4
5 <%= render_timelog_breadcrumb %>
5 <%= render_timelog_breadcrumb %>
6
6
7 <h2><%= l(:label_spent_time) %></h2>
7 <h2><%= l(:label_spent_time) %></h2>
8
8
9 <% form_remote_tag(:url => {}, :html => {:method => :get, :id => 'query_form'}, :method => :get, :update => 'content') do %>
9 <% form_tag({:controller => 'time_entry_reports', :action => 'report', :project_id => @project, :issue_id => @issue}, :method => :get, :id => 'query_form') do %>
10 <% @criterias.each do |criteria| %>
10 <% @criterias.each do |criteria| %>
11 <%= hidden_field_tag 'criterias[]', criteria, :id => nil %>
11 <%= hidden_field_tag 'criterias[]', criteria, :id => nil %>
12 <% end %>
12 <% end %>
13 <%# TODO: get rid of the project_id field, that should already be in the URL %>
13 <%# TODO: get rid of the project_id field, that should already be in the URL %>
14 <%= hidden_field_tag('project_id', params[:project_id]) if @project %>
14 <%= hidden_field_tag('project_id', params[:project_id]) if @project %>
15 <%= hidden_field_tag('issue_id', params[:issue_id]) if @issue %>
15 <%= hidden_field_tag('issue_id', params[:issue_id]) if @issue %>
16 <%= render :partial => 'timelog/date_range' %>
16 <%= render :partial => 'timelog/date_range' %>
17
17
18 <p><%= l(:label_details) %>: <%= select_tag 'columns', options_for_select([[l(:label_year), 'year'],
18 <p><%= l(:label_details) %>: <%= select_tag 'columns', options_for_select([[l(:label_year), 'year'],
19 [l(:label_month), 'month'],
19 [l(:label_month), 'month'],
20 [l(:label_week), 'week'],
20 [l(:label_week), 'week'],
21 [l(:label_day_plural).titleize, 'day']], @columns),
21 [l(:label_day_plural).titleize, 'day']], @columns),
22 :onchange => "this.form.onsubmit();" %>
22 :onchange => "this.form.onsubmit();" %>
23
23
24 <%= l(:button_add) %>: <%= select_tag('criterias[]', options_for_select([[]] + (@available_criterias.keys - @criterias).collect{|k| [l_or_humanize(@available_criterias[k][:label]), k]}),
24 <%= l(:button_add) %>: <%= select_tag('criterias[]', options_for_select([[]] + (@available_criterias.keys - @criterias).collect{|k| [l_or_humanize(@available_criterias[k][:label]), k]}),
25 :onchange => "this.form.onsubmit();",
25 :onchange => "this.form.submit();",
26 :style => 'width: 200px',
26 :style => 'width: 200px',
27 :id => nil,
27 :id => nil,
28 :disabled => (@criterias.length >= 3)) %>
28 :disabled => (@criterias.length >= 3)) %>
29 <%= link_to_remote l(:button_clear), {:url => {:project_id => @project, :period_type => params[:period_type], :period => params[:period], :from => @from, :to => @to, :columns => @columns},
29 <%= link_to l(:button_clear), {:project_id => @project, :issue_id => @issue, :period_type => params[:period_type], :period => params[:period], :from => @from, :to => @to, :columns => @columns}, :class => 'icon icon-reload' %></p>
30 :method => :get,
31 :update => 'content'
32 }, :class => 'icon icon-reload' %></p>
33 <% end %>
30 <% end %>
34
31
35 <% unless @criterias.empty? %>
32 <% unless @criterias.empty? %>
36 <div class="total-hours">
33 <div class="total-hours">
37 <p><%= l(:label_total) %>: <%= html_hours(l_hours(@total_hours)) %></p>
34 <p><%= l(:label_total) %>: <%= html_hours(l_hours(@total_hours)) %></p>
38 </div>
35 </div>
39
36
40 <% unless @hours.empty? %>
37 <% unless @hours.empty? %>
41 <table class="list" id="time-report">
38 <table class="list" id="time-report">
42 <thead>
39 <thead>
43 <tr>
40 <tr>
44 <% @criterias.each do |criteria| %>
41 <% @criterias.each do |criteria| %>
45 <th><%= l_or_humanize(@available_criterias[criteria][:label]) %></th>
42 <th><%= l_or_humanize(@available_criterias[criteria][:label]) %></th>
46 <% end %>
43 <% end %>
47 <% columns_width = (40 / (@periods.length+1)).to_i %>
44 <% columns_width = (40 / (@periods.length+1)).to_i %>
48 <% @periods.each do |period| %>
45 <% @periods.each do |period| %>
49 <th class="period" width="<%= columns_width %>%"><%= period %></th>
46 <th class="period" width="<%= columns_width %>%"><%= period %></th>
50 <% end %>
47 <% end %>
51 <th class="total" width="<%= columns_width %>%"><%= l(:label_total) %></th>
48 <th class="total" width="<%= columns_width %>%"><%= l(:label_total) %></th>
52 </tr>
49 </tr>
53 </thead>
50 </thead>
54 <tbody>
51 <tbody>
55 <%= render :partial => 'report_criteria', :locals => {:criterias => @criterias, :hours => @hours, :level => 0} %>
52 <%= render :partial => 'report_criteria', :locals => {:criterias => @criterias, :hours => @hours, :level => 0} %>
56 <tr class="total">
53 <tr class="total">
57 <td><%= l(:label_total) %></td>
54 <td><%= l(:label_total) %></td>
58 <%= '<td></td>' * (@criterias.size - 1) %>
55 <%= '<td></td>' * (@criterias.size - 1) %>
59 <% total = 0 -%>
56 <% total = 0 -%>
60 <% @periods.each do |period| -%>
57 <% @periods.each do |period| -%>
61 <% sum = sum_hours(select_hours(@hours, @columns, period.to_s)); total += sum -%>
58 <% sum = sum_hours(select_hours(@hours, @columns, period.to_s)); total += sum -%>
62 <td class="hours"><%= html_hours("%.2f" % sum) if sum > 0 %></td>
59 <td class="hours"><%= html_hours("%.2f" % sum) if sum > 0 %></td>
63 <% end -%>
60 <% end -%>
64 <td class="hours"><%= html_hours("%.2f" % total) if total > 0 %></td>
61 <td class="hours"><%= html_hours("%.2f" % total) if total > 0 %></td>
65 </tr>
62 </tr>
66 </tbody>
63 </tbody>
67 </table>
64 </table>
68
65
69 <% other_formats_links do |f| %>
66 <% other_formats_links do |f| %>
70 <%= f.link_to 'CSV', :url => params %>
67 <%= f.link_to 'CSV', :url => params %>
71 <% end %>
68 <% end %>
72 <% end %>
69 <% end %>
73 <% end %>
70 <% end %>
74
71
75 <% html_title l(:label_spent_time), l(:label_report) %>
72 <% html_title l(:label_spent_time), l(:label_report) %>
76
73
@@ -1,36 +1,32
1 <fieldset id="date-range" class="collapsible">
1 <fieldset id="date-range" class="collapsible">
2 <legend onclick="toggleFieldset(this);"><%= l(:label_date_range) %></legend>
2 <legend onclick="toggleFieldset(this);"><%= l(:label_date_range) %></legend>
3 <div>
3 <div>
4 <p>
4 <p>
5 <%= radio_button_tag 'period_type', '1', !@free_period %>
5 <%= radio_button_tag 'period_type', '1', !@free_period %>
6 <%= select_tag 'period', options_for_period_select(params[:period]),
6 <%= select_tag 'period', options_for_period_select(params[:period]),
7 :onchange => 'this.form.onsubmit();',
7 :onchange => 'this.form.submit();',
8 :onfocus => '$("period_type_1").checked = true;' %>
8 :onfocus => '$("period_type_1").checked = true;' %>
9 </p>
9 </p>
10 <p>
10 <p>
11 <%= radio_button_tag 'period_type', '2', @free_period %>
11 <%= radio_button_tag 'period_type', '2', @free_period %>
12 <span onclick="$('period_type_2').checked = true;">
12 <span onclick="$('period_type_2').checked = true;">
13 <%= l(:label_date_from_to, :start => (text_field_tag('from', @from, :size => 10) + calendar_for('from')),
13 <%= l(:label_date_from_to, :start => (text_field_tag('from', @from, :size => 10) + calendar_for('from')),
14 :end => (text_field_tag('to', @to, :size => 10) + calendar_for('to'))) %>
14 :end => (text_field_tag('to', @to, :size => 10) + calendar_for('to'))) %>
15 </span>
15 </span>
16 </p>
16 </p>
17 </div>
17 </div>
18 </fieldset>
18 </fieldset>
19 <p class="buttons">
19 <p class="buttons">
20 <%= link_to_remote l(:button_apply),
20 <%= link_to_function l(:button_apply), '$("query_form").submit()', :class => 'icon icon-checked' %>
21 { :url => { },
21 <%= link_to l(:button_clear), {:controller => controller_name, :action => action_name, :project_id => @project, :issue_id => @issue}, :class => 'icon icon-reload' %>
22 :update => "content",
23 :with => "Form.serialize('query_form')",
24 :method => :get
25 }, :class => 'icon icon-checked' %>
26 </p>
22 </p>
27
23
28 <div class="tabs">
24 <div class="tabs">
29 <% url_params = @free_period ? { :from => @from, :to => @to } : { :period => params[:period] } %>
25 <% url_params = @free_period ? { :from => @from, :to => @to } : { :period => params[:period] } %>
30 <ul>
26 <ul>
31 <li><%= link_to(l(:label_details), url_params.merge({:controller => 'timelog', :action => 'index', :project_id => @project, :issue_id => @issue }),
27 <li><%= link_to(l(:label_details), url_params.merge({:controller => 'timelog', :action => 'index', :project_id => @project, :issue_id => @issue }),
32 :class => (@controller.action_name == 'index' ? 'selected' : nil)) %></li>
28 :class => (@controller.action_name == 'index' ? 'selected' : nil)) %></li>
33 <li><%= link_to(l(:label_report), url_params.merge({:controller => 'time_entry_reports', :action => 'report', :project_id => @project, :issue_id => @issue}),
29 <li><%= link_to(l(:label_report), url_params.merge({:controller => 'time_entry_reports', :action => 'report', :project_id => @project, :issue_id => @issue}),
34 :class => (@controller.action_name == 'report' ? 'selected' : nil)) %></li>
30 :class => (@controller.action_name == 'report' ? 'selected' : nil)) %></li>
35 </ul>
31 </ul>
36 </div>
32 </div>
@@ -1,35 +1,31
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'new', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time-add' %>
2 <%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'new', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time-add' %>
3 </div>
3 </div>
4
4
5 <%= render_timelog_breadcrumb %>
5 <%= render_timelog_breadcrumb %>
6
6
7 <h2><%= l(:label_spent_time) %></h2>
7 <h2><%= l(:label_spent_time) %></h2>
8
8
9 <% form_remote_tag( :url => {}, :html => {:method => :get, :id => 'query_form'}, :method => :get, :update => 'content' ) do %>
9 <% form_tag({:controller => 'timelog', :action => 'index', :project_id => @project, :issue_id => @issue}, :method => :get, :id => 'query_form') do %>
10 <%# TOOD: remove the project_id and issue_id hidden fields, that information is
11 already in the URI %>
12 <%= hidden_field_tag('project_id', params[:project_id]) if @project %>
13 <%= hidden_field_tag 'issue_id', params[:issue_id] if @issue %>
14 <%= render :partial => 'date_range' %>
10 <%= render :partial => 'date_range' %>
15 <% end %>
11 <% end %>
16
12
17 <div class="total-hours">
13 <div class="total-hours">
18 <p><%= l(:label_total) %>: <%= html_hours(l_hours(@total_hours)) %></p>
14 <p><%= l(:label_total) %>: <%= html_hours(l_hours(@total_hours)) %></p>
19 </div>
15 </div>
20
16
21 <% unless @entries.empty? %>
17 <% unless @entries.empty? %>
22 <%= render :partial => 'list', :locals => { :entries => @entries }%>
18 <%= render :partial => 'list', :locals => { :entries => @entries }%>
23 <p class="pagination"><%= pagination_links_full @entry_pages, @entry_count %></p>
19 <p class="pagination"><%= pagination_links_full @entry_pages, @entry_count %></p>
24
20
25 <% other_formats_links do |f| %>
21 <% other_formats_links do |f| %>
26 <%= f.link_to 'Atom', :url => params.merge({:issue_id => @issue, :key => User.current.rss_key}) %>
22 <%= f.link_to 'Atom', :url => params.merge({:issue_id => @issue, :key => User.current.rss_key}) %>
27 <%= f.link_to 'CSV', :url => params %>
23 <%= f.link_to 'CSV', :url => params %>
28 <% end %>
24 <% end %>
29 <% end %>
25 <% end %>
30
26
31 <% html_title l(:label_spent_time), l(:label_details) %>
27 <% html_title l(:label_spent_time), l(:label_details) %>
32
28
33 <% content_for :header_tags do %>
29 <% content_for :header_tags do %>
34 <%= auto_discovery_link_tag(:atom, {:issue_id => @issue, :format => 'atom', :key => User.current.rss_key}, :title => l(:label_spent_time)) %>
30 <%= auto_discovery_link_tag(:atom, {:issue_id => @issue, :format => 'atom', :key => User.current.rss_key}, :title => l(:label_spent_time)) %>
35 <% end %>
31 <% end %>
@@ -1,252 +1,253
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.connect 'projects/:project_id/time_entries/report', :controller => 'time_entry_reports', :action => 'report'
18 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'
19 time_report.connect 'projects/:project_id/issues/:issue_id/time_entries/report.:format'
20 time_report.connect 'projects/:project_id/time_entries/report'
21 time_report.connect 'projects/:project_id/time_entries/report.:format'
19 time_report.connect 'time_entries/report'
22 time_report.connect 'time_entries/report'
20 time_report.connect 'time_entries/report.:format'
23 time_report.connect 'time_entries/report.:format'
21 time_report.connect 'projects/:project_id/time_entries/report.:format'
22 end
24 end
23
25
24 # TODO: wasteful since this is also nested under issues, projects, and projects/issues
25 map.resources :time_entries, :controller => 'timelog'
26 map.resources :time_entries, :controller => 'timelog'
26
27
27 map.connect 'projects/:id/wiki', :controller => 'wikis', :action => 'edit', :conditions => {:method => :post}
28 map.connect 'projects/:id/wiki', :controller => 'wikis', :action => 'edit', :conditions => {:method => :post}
28 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :get}
29 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :get}
29 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :post}
30 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :post}
30
31
31 map.with_options :controller => 'messages' do |messages_routes|
32 map.with_options :controller => 'messages' do |messages_routes|
32 messages_routes.with_options :conditions => {:method => :get} do |messages_views|
33 messages_routes.with_options :conditions => {:method => :get} do |messages_views|
33 messages_views.connect 'boards/:board_id/topics/new', :action => 'new'
34 messages_views.connect 'boards/:board_id/topics/new', :action => 'new'
34 messages_views.connect 'boards/:board_id/topics/:id', :action => 'show'
35 messages_views.connect 'boards/:board_id/topics/:id', :action => 'show'
35 messages_views.connect 'boards/:board_id/topics/:id/edit', :action => 'edit'
36 messages_views.connect 'boards/:board_id/topics/:id/edit', :action => 'edit'
36 end
37 end
37 messages_routes.with_options :conditions => {:method => :post} do |messages_actions|
38 messages_routes.with_options :conditions => {:method => :post} do |messages_actions|
38 messages_actions.connect 'boards/:board_id/topics/new', :action => 'new'
39 messages_actions.connect 'boards/:board_id/topics/new', :action => 'new'
39 messages_actions.connect 'boards/:board_id/topics/:id/replies', :action => 'reply'
40 messages_actions.connect 'boards/:board_id/topics/:id/replies', :action => 'reply'
40 messages_actions.connect 'boards/:board_id/topics/:id/:action', :action => /edit|destroy/
41 messages_actions.connect 'boards/:board_id/topics/:id/:action', :action => /edit|destroy/
41 end
42 end
42 end
43 end
43
44
44 map.with_options :controller => 'boards' do |board_routes|
45 map.with_options :controller => 'boards' do |board_routes|
45 board_routes.with_options :conditions => {:method => :get} do |board_views|
46 board_routes.with_options :conditions => {:method => :get} do |board_views|
46 board_views.connect 'projects/:project_id/boards', :action => 'index'
47 board_views.connect 'projects/:project_id/boards', :action => 'index'
47 board_views.connect 'projects/:project_id/boards/new', :action => 'new'
48 board_views.connect 'projects/:project_id/boards/new', :action => 'new'
48 board_views.connect 'projects/:project_id/boards/:id', :action => 'show'
49 board_views.connect 'projects/:project_id/boards/:id', :action => 'show'
49 board_views.connect 'projects/:project_id/boards/:id.:format', :action => 'show'
50 board_views.connect 'projects/:project_id/boards/:id.:format', :action => 'show'
50 board_views.connect 'projects/:project_id/boards/:id/edit', :action => 'edit'
51 board_views.connect 'projects/:project_id/boards/:id/edit', :action => 'edit'
51 end
52 end
52 board_routes.with_options :conditions => {:method => :post} do |board_actions|
53 board_routes.with_options :conditions => {:method => :post} do |board_actions|
53 board_actions.connect 'projects/:project_id/boards', :action => 'new'
54 board_actions.connect 'projects/:project_id/boards', :action => 'new'
54 board_actions.connect 'projects/:project_id/boards/:id/:action', :action => /edit|destroy/
55 board_actions.connect 'projects/:project_id/boards/:id/:action', :action => /edit|destroy/
55 end
56 end
56 end
57 end
57
58
58 map.with_options :controller => 'documents' do |document_routes|
59 map.with_options :controller => 'documents' do |document_routes|
59 document_routes.with_options :conditions => {:method => :get} do |document_views|
60 document_routes.with_options :conditions => {:method => :get} do |document_views|
60 document_views.connect 'projects/:project_id/documents', :action => 'index'
61 document_views.connect 'projects/:project_id/documents', :action => 'index'
61 document_views.connect 'projects/:project_id/documents/new', :action => 'new'
62 document_views.connect 'projects/:project_id/documents/new', :action => 'new'
62 document_views.connect 'documents/:id', :action => 'show'
63 document_views.connect 'documents/:id', :action => 'show'
63 document_views.connect 'documents/:id/edit', :action => 'edit'
64 document_views.connect 'documents/:id/edit', :action => 'edit'
64 end
65 end
65 document_routes.with_options :conditions => {:method => :post} do |document_actions|
66 document_routes.with_options :conditions => {:method => :post} do |document_actions|
66 document_actions.connect 'projects/:project_id/documents', :action => 'new'
67 document_actions.connect 'projects/:project_id/documents', :action => 'new'
67 document_actions.connect 'documents/:id/:action', :action => /destroy|edit/
68 document_actions.connect 'documents/:id/:action', :action => /destroy|edit/
68 end
69 end
69 end
70 end
70
71
71 map.resources :issue_moves, :only => [:new, :create], :path_prefix => '/issues', :as => 'move'
72 map.resources :issue_moves, :only => [:new, :create], :path_prefix => '/issues', :as => 'move'
72
73
73 # Misc issue routes. TODO: move into resources
74 # Misc issue routes. TODO: move into resources
74 map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes', :action => 'issues'
75 map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes', :action => 'issues'
75 map.preview_issue '/issues/preview/:id', :controller => 'previews', :action => 'issue' # TODO: would look nicer as /issues/:id/preview
76 map.preview_issue '/issues/preview/:id', :controller => 'previews', :action => 'issue' # TODO: would look nicer as /issues/:id/preview
76 map.issues_context_menu '/issues/context_menu', :controller => 'context_menus', :action => 'issues'
77 map.issues_context_menu '/issues/context_menu', :controller => 'context_menus', :action => 'issues'
77 map.issue_changes '/issues/changes', :controller => 'journals', :action => 'index'
78 map.issue_changes '/issues/changes', :controller => 'journals', :action => 'index'
78 map.bulk_edit_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_edit', :conditions => { :method => :get }
79 map.bulk_edit_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_edit', :conditions => { :method => :get }
79 map.bulk_update_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_update', :conditions => { :method => :post }
80 map.bulk_update_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_update', :conditions => { :method => :post }
80 map.quoted_issue '/issues/:id/quoted', :controller => 'journals', :action => 'new', :id => /\d+/, :conditions => { :method => :post }
81 map.quoted_issue '/issues/:id/quoted', :controller => 'journals', :action => 'new', :id => /\d+/, :conditions => { :method => :post }
81 map.connect '/issues/:id/destroy', :controller => 'issues', :action => 'destroy', :conditions => { :method => :post } # legacy
82 map.connect '/issues/:id/destroy', :controller => 'issues', :action => 'destroy', :conditions => { :method => :post } # legacy
82
83
83 map.with_options :controller => 'gantts', :action => 'show' do |gantts_routes|
84 map.with_options :controller => 'gantts', :action => 'show' do |gantts_routes|
84 gantts_routes.connect '/projects/:project_id/issues/gantt'
85 gantts_routes.connect '/projects/:project_id/issues/gantt'
85 gantts_routes.connect '/projects/:project_id/issues/gantt.:format'
86 gantts_routes.connect '/projects/:project_id/issues/gantt.:format'
86 gantts_routes.connect '/issues/gantt.:format'
87 gantts_routes.connect '/issues/gantt.:format'
87 end
88 end
88
89
89 map.with_options :controller => 'calendars', :action => 'show' do |calendars_routes|
90 map.with_options :controller => 'calendars', :action => 'show' do |calendars_routes|
90 calendars_routes.connect '/projects/:project_id/issues/calendar'
91 calendars_routes.connect '/projects/:project_id/issues/calendar'
91 calendars_routes.connect '/issues/calendar'
92 calendars_routes.connect '/issues/calendar'
92 end
93 end
93
94
94 map.with_options :controller => 'reports', :conditions => {:method => :get} do |reports|
95 map.with_options :controller => 'reports', :conditions => {:method => :get} do |reports|
95 reports.connect 'projects/:id/issues/report', :action => 'issue_report'
96 reports.connect 'projects/:id/issues/report', :action => 'issue_report'
96 reports.connect 'projects/:id/issues/report/:detail', :action => 'issue_report_details'
97 reports.connect 'projects/:id/issues/report/:detail', :action => 'issue_report_details'
97 end
98 end
98
99
99 # Following two routes conflict with the resources because #index allows POST
100 # Following two routes conflict with the resources because #index allows POST
100 map.connect '/issues', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
101 map.connect '/issues', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
101 map.connect '/issues/create', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
102 map.connect '/issues/create', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
102
103
103 map.resources :issues, :member => { :edit => :post }, :collection => {} do |issues|
104 map.resources :issues, :member => { :edit => :post }, :collection => {} do |issues|
104 issues.resources :time_entries, :controller => 'timelog'
105 issues.resources :time_entries, :controller => 'timelog'
105 end
106 end
106
107
107 map.resources :issues, :path_prefix => '/projects/:project_id', :collection => { :create => :post } do |issues|
108 map.resources :issues, :path_prefix => '/projects/:project_id', :collection => { :create => :post } do |issues|
108 issues.resources :time_entries, :controller => 'timelog'
109 issues.resources :time_entries, :controller => 'timelog'
109 end
110 end
110
111
111 map.with_options :controller => 'issue_relations', :conditions => {:method => :post} do |relations|
112 map.with_options :controller => 'issue_relations', :conditions => {:method => :post} do |relations|
112 relations.connect 'issues/:issue_id/relations/:id', :action => 'new'
113 relations.connect 'issues/:issue_id/relations/:id', :action => 'new'
113 relations.connect 'issues/:issue_id/relations/:id/destroy', :action => 'destroy'
114 relations.connect 'issues/:issue_id/relations/:id/destroy', :action => 'destroy'
114 end
115 end
115
116
116 map.connect 'projects/:id/members/new', :controller => 'members', :action => 'new'
117 map.connect 'projects/:id/members/new', :controller => 'members', :action => 'new'
117
118
118 map.with_options :controller => 'users' do |users|
119 map.with_options :controller => 'users' do |users|
119 users.connect 'users/:id/edit/:tab', :action => 'edit', :tab => nil, :conditions => {:method => :get}
120 users.connect 'users/:id/edit/:tab', :action => 'edit', :tab => nil, :conditions => {:method => :get}
120
121
121 users.with_options :conditions => {:method => :post} do |user_actions|
122 users.with_options :conditions => {:method => :post} do |user_actions|
122 user_actions.connect 'users/:id/memberships', :action => 'edit_membership'
123 user_actions.connect 'users/:id/memberships', :action => 'edit_membership'
123 user_actions.connect 'users/:id/memberships/:membership_id', :action => 'edit_membership'
124 user_actions.connect 'users/:id/memberships/:membership_id', :action => 'edit_membership'
124 user_actions.connect 'users/:id/memberships/:membership_id/destroy', :action => 'destroy_membership'
125 user_actions.connect 'users/:id/memberships/:membership_id/destroy', :action => 'destroy_membership'
125 end
126 end
126 end
127 end
127
128
128 map.resources :users, :member => {
129 map.resources :users, :member => {
129 :edit_membership => :post,
130 :edit_membership => :post,
130 :destroy_membership => :post
131 :destroy_membership => :post
131 }
132 }
132
133
133 # For nice "roadmap" in the url for the index action
134 # For nice "roadmap" in the url for the index action
134 map.connect 'projects/:project_id/roadmap', :controller => 'versions', :action => 'index'
135 map.connect 'projects/:project_id/roadmap', :controller => 'versions', :action => 'index'
135
136
136 map.all_news 'news', :controller => 'news', :action => 'index'
137 map.all_news 'news', :controller => 'news', :action => 'index'
137 map.formatted_all_news 'news.:format', :controller => 'news', :action => 'index'
138 map.formatted_all_news 'news.:format', :controller => 'news', :action => 'index'
138 map.preview_news '/news/preview', :controller => 'previews', :action => 'news'
139 map.preview_news '/news/preview', :controller => 'previews', :action => 'news'
139 map.connect 'news/:id/comments', :controller => 'comments', :action => 'create', :conditions => {:method => :post}
140 map.connect 'news/:id/comments', :controller => 'comments', :action => 'create', :conditions => {:method => :post}
140 map.connect 'news/:id/comments/:comment_id', :controller => 'comments', :action => 'destroy', :conditions => {:method => :delete}
141 map.connect 'news/:id/comments/:comment_id', :controller => 'comments', :action => 'destroy', :conditions => {:method => :delete}
141
142
142 map.resources :projects, :member => {
143 map.resources :projects, :member => {
143 :copy => [:get, :post],
144 :copy => [:get, :post],
144 :settings => :get,
145 :settings => :get,
145 :modules => :post,
146 :modules => :post,
146 :archive => :post,
147 :archive => :post,
147 :unarchive => :post
148 :unarchive => :post
148 } do |project|
149 } do |project|
149 project.resource :project_enumerations, :as => 'enumerations', :only => [:update, :destroy]
150 project.resource :project_enumerations, :as => 'enumerations', :only => [:update, :destroy]
150 project.resources :files, :only => [:index, :new, :create]
151 project.resources :files, :only => [:index, :new, :create]
151 project.resources :versions, :collection => {:close_completed => :put}, :member => {:status_by => :post}
152 project.resources :versions, :collection => {:close_completed => :put}, :member => {:status_by => :post}
152 project.resources :news, :shallow => true
153 project.resources :news, :shallow => true
153 project.resources :time_entries, :controller => 'timelog', :path_prefix => 'projects/:project_id'
154 project.resources :time_entries, :controller => 'timelog', :path_prefix => 'projects/:project_id'
154
155
155 project.wiki_start_page 'wiki', :controller => 'wiki', :action => 'show', :conditions => {:method => :get}
156 project.wiki_start_page 'wiki', :controller => 'wiki', :action => 'show', :conditions => {:method => :get}
156 project.wiki_index 'wiki/index', :controller => 'wiki', :action => 'index', :conditions => {:method => :get}
157 project.wiki_index 'wiki/index', :controller => 'wiki', :action => 'index', :conditions => {:method => :get}
157 project.wiki_diff 'wiki/:id/diff/:version', :controller => 'wiki', :action => 'diff', :version => nil
158 project.wiki_diff 'wiki/:id/diff/:version', :controller => 'wiki', :action => 'diff', :version => nil
158 project.wiki_diff 'wiki/:id/diff/:version/vs/:version_from', :controller => 'wiki', :action => 'diff'
159 project.wiki_diff 'wiki/:id/diff/:version/vs/:version_from', :controller => 'wiki', :action => 'diff'
159 project.wiki_annotate 'wiki/:id/annotate/:version', :controller => 'wiki', :action => 'annotate'
160 project.wiki_annotate 'wiki/:id/annotate/:version', :controller => 'wiki', :action => 'annotate'
160 project.resources :wiki, :except => [:new, :create], :member => {
161 project.resources :wiki, :except => [:new, :create], :member => {
161 :rename => [:get, :post],
162 :rename => [:get, :post],
162 :history => :get,
163 :history => :get,
163 :preview => :any,
164 :preview => :any,
164 :protect => :post,
165 :protect => :post,
165 :add_attachment => :post
166 :add_attachment => :post
166 }, :collection => {
167 }, :collection => {
167 :export => :get,
168 :export => :get,
168 :date_index => :get
169 :date_index => :get
169 }
170 }
170
171
171 end
172 end
172
173
173 # Destroy uses a get request to prompt the user before the actual DELETE request
174 # Destroy uses a get request to prompt the user before the actual DELETE request
174 map.project_destroy_confirm 'projects/:id/destroy', :controller => 'projects', :action => 'destroy', :conditions => {:method => :get}
175 map.project_destroy_confirm 'projects/:id/destroy', :controller => 'projects', :action => 'destroy', :conditions => {:method => :get}
175
176
176 # TODO: port to be part of the resources route(s)
177 # TODO: port to be part of the resources route(s)
177 map.with_options :controller => 'projects' do |project_mapper|
178 map.with_options :controller => 'projects' do |project_mapper|
178 project_mapper.with_options :conditions => {:method => :get} do |project_views|
179 project_mapper.with_options :conditions => {:method => :get} do |project_views|
179 project_views.connect 'projects/:id/settings/:tab', :controller => 'projects', :action => 'settings'
180 project_views.connect 'projects/:id/settings/:tab', :controller => 'projects', :action => 'settings'
180 project_views.connect 'projects/:project_id/issues/:copy_from/copy', :controller => 'issues', :action => 'new'
181 project_views.connect 'projects/:project_id/issues/:copy_from/copy', :controller => 'issues', :action => 'new'
181 end
182 end
182 end
183 end
183
184
184 map.with_options :controller => 'activities', :action => 'index', :conditions => {:method => :get} do |activity|
185 map.with_options :controller => 'activities', :action => 'index', :conditions => {:method => :get} do |activity|
185 activity.connect 'projects/:id/activity'
186 activity.connect 'projects/:id/activity'
186 activity.connect 'projects/:id/activity.:format'
187 activity.connect 'projects/:id/activity.:format'
187 activity.connect 'activity', :id => nil
188 activity.connect 'activity', :id => nil
188 activity.connect 'activity.:format', :id => nil
189 activity.connect 'activity.:format', :id => nil
189 end
190 end
190
191
191
192
192 map.with_options :controller => 'issue_categories' do |categories|
193 map.with_options :controller => 'issue_categories' do |categories|
193 categories.connect 'projects/:project_id/issue_categories/new', :action => 'new'
194 categories.connect 'projects/:project_id/issue_categories/new', :action => 'new'
194 end
195 end
195
196
196 map.with_options :controller => 'repositories' do |repositories|
197 map.with_options :controller => 'repositories' do |repositories|
197 repositories.with_options :conditions => {:method => :get} do |repository_views|
198 repositories.with_options :conditions => {:method => :get} do |repository_views|
198 repository_views.connect 'projects/:id/repository', :action => 'show'
199 repository_views.connect 'projects/:id/repository', :action => 'show'
199 repository_views.connect 'projects/:id/repository/edit', :action => 'edit'
200 repository_views.connect 'projects/:id/repository/edit', :action => 'edit'
200 repository_views.connect 'projects/:id/repository/statistics', :action => 'stats'
201 repository_views.connect 'projects/:id/repository/statistics', :action => 'stats'
201 repository_views.connect 'projects/:id/repository/revisions', :action => 'revisions'
202 repository_views.connect 'projects/:id/repository/revisions', :action => 'revisions'
202 repository_views.connect 'projects/:id/repository/revisions.:format', :action => 'revisions'
203 repository_views.connect 'projects/:id/repository/revisions.:format', :action => 'revisions'
203 repository_views.connect 'projects/:id/repository/revisions/:rev', :action => 'revision'
204 repository_views.connect 'projects/:id/repository/revisions/:rev', :action => 'revision'
204 repository_views.connect 'projects/:id/repository/revisions/:rev/diff', :action => 'diff'
205 repository_views.connect 'projects/:id/repository/revisions/:rev/diff', :action => 'diff'
205 repository_views.connect 'projects/:id/repository/revisions/:rev/diff.:format', :action => 'diff'
206 repository_views.connect 'projects/:id/repository/revisions/:rev/diff.:format', :action => 'diff'
206 repository_views.connect 'projects/:id/repository/revisions/:rev/raw/*path', :action => 'entry', :format => 'raw', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
207 repository_views.connect 'projects/:id/repository/revisions/:rev/raw/*path', :action => 'entry', :format => 'raw', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
207 repository_views.connect 'projects/:id/repository/revisions/:rev/:action/*path', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
208 repository_views.connect 'projects/:id/repository/revisions/:rev/:action/*path', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
208 repository_views.connect 'projects/:id/repository/raw/*path', :action => 'entry', :format => 'raw'
209 repository_views.connect 'projects/:id/repository/raw/*path', :action => 'entry', :format => 'raw'
209 # TODO: why the following route is required?
210 # TODO: why the following route is required?
210 repository_views.connect 'projects/:id/repository/entry/*path', :action => 'entry'
211 repository_views.connect 'projects/:id/repository/entry/*path', :action => 'entry'
211 repository_views.connect 'projects/:id/repository/:action/*path'
212 repository_views.connect 'projects/:id/repository/:action/*path'
212 end
213 end
213
214
214 repositories.connect 'projects/:id/repository/:action', :conditions => {:method => :post}
215 repositories.connect 'projects/:id/repository/:action', :conditions => {:method => :post}
215 end
216 end
216
217
217 map.connect 'attachments/:id', :controller => 'attachments', :action => 'show', :id => /\d+/
218 map.connect 'attachments/:id', :controller => 'attachments', :action => 'show', :id => /\d+/
218 map.connect 'attachments/:id/:filename', :controller => 'attachments', :action => 'show', :id => /\d+/, :filename => /.*/
219 map.connect 'attachments/:id/:filename', :controller => 'attachments', :action => 'show', :id => /\d+/, :filename => /.*/
219 map.connect 'attachments/download/:id/:filename', :controller => 'attachments', :action => 'download', :id => /\d+/, :filename => /.*/
220 map.connect 'attachments/download/:id/:filename', :controller => 'attachments', :action => 'download', :id => /\d+/, :filename => /.*/
220
221
221 map.resources :groups
222 map.resources :groups
222
223
223 #left old routes at the bottom for backwards compat
224 #left old routes at the bottom for backwards compat
224 map.connect 'projects/:project_id/queries/:action', :controller => 'queries'
225 map.connect 'projects/:project_id/queries/:action', :controller => 'queries'
225 map.connect 'projects/:project_id/issues/:action', :controller => 'issues'
226 map.connect 'projects/:project_id/issues/:action', :controller => 'issues'
226 map.connect 'projects/:project_id/documents/:action', :controller => 'documents'
227 map.connect 'projects/:project_id/documents/:action', :controller => 'documents'
227 map.connect 'projects/:project_id/boards/:action/:id', :controller => 'boards'
228 map.connect 'projects/:project_id/boards/:action/:id', :controller => 'boards'
228 map.connect 'boards/:board_id/topics/:action/:id', :controller => 'messages'
229 map.connect 'boards/:board_id/topics/:action/:id', :controller => 'messages'
229 map.connect 'wiki/:id/:page/:action', :page => nil, :controller => 'wiki'
230 map.connect 'wiki/:id/:page/:action', :page => nil, :controller => 'wiki'
230 map.connect 'issues/:issue_id/relations/:action/:id', :controller => 'issue_relations'
231 map.connect 'issues/:issue_id/relations/:action/:id', :controller => 'issue_relations'
231 map.connect 'projects/:project_id/news/:action', :controller => 'news'
232 map.connect 'projects/:project_id/news/:action', :controller => 'news'
232 map.connect 'projects/:project_id/timelog/:action/:id', :controller => 'timelog', :project_id => /.+/
233 map.connect 'projects/:project_id/timelog/:action/:id', :controller => 'timelog', :project_id => /.+/
233 map.with_options :controller => 'repositories' do |omap|
234 map.with_options :controller => 'repositories' do |omap|
234 omap.repositories_show 'repositories/browse/:id/*path', :action => 'browse'
235 omap.repositories_show 'repositories/browse/:id/*path', :action => 'browse'
235 omap.repositories_changes 'repositories/changes/:id/*path', :action => 'changes'
236 omap.repositories_changes 'repositories/changes/:id/*path', :action => 'changes'
236 omap.repositories_diff 'repositories/diff/:id/*path', :action => 'diff'
237 omap.repositories_diff 'repositories/diff/:id/*path', :action => 'diff'
237 omap.repositories_entry 'repositories/entry/:id/*path', :action => 'entry'
238 omap.repositories_entry 'repositories/entry/:id/*path', :action => 'entry'
238 omap.repositories_entry 'repositories/annotate/:id/*path', :action => 'annotate'
239 omap.repositories_entry 'repositories/annotate/:id/*path', :action => 'annotate'
239 omap.connect 'repositories/revision/:id/:rev', :action => 'revision'
240 omap.connect 'repositories/revision/:id/:rev', :action => 'revision'
240 end
241 end
241
242
242 map.with_options :controller => 'sys' do |sys|
243 map.with_options :controller => 'sys' do |sys|
243 sys.connect 'sys/projects.:format', :action => 'projects', :conditions => {:method => :get}
244 sys.connect 'sys/projects.:format', :action => 'projects', :conditions => {:method => :get}
244 sys.connect 'sys/projects/:id/repository.:format', :action => 'create_project_repository', :conditions => {:method => :post}
245 sys.connect 'sys/projects/:id/repository.:format', :action => 'create_project_repository', :conditions => {:method => :post}
245 end
246 end
246
247
247 # Install the default route as the lowest priority.
248 # Install the default route as the lowest priority.
248 map.connect ':controller/:action/:id'
249 map.connect ':controller/:action/:id'
249 map.connect 'robots.txt', :controller => 'welcome', :action => 'robots'
250 map.connect 'robots.txt', :controller => 'welcome', :action => 'robots'
250 # Used for OpenID
251 # Used for OpenID
251 map.root :controller => 'account', :action => 'login'
252 map.root :controller => 'account', :action => 'login'
252 end
253 end
@@ -1,134 +1,140
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 require File.expand_path('../../test_helper', __FILE__)
2 require File.expand_path('../../test_helper', __FILE__)
3
3
4 class TimeEntryReportsControllerTest < ActionController::TestCase
4 class TimeEntryReportsControllerTest < ActionController::TestCase
5 fixtures :projects, :enabled_modules, :roles, :members, :member_roles, :issues, :time_entries, :users, :trackers, :enumerations, :issue_statuses, :custom_fields, :custom_values
5 fixtures :projects, :enabled_modules, :roles, :members, :member_roles, :issues, :time_entries, :users, :trackers, :enumerations, :issue_statuses, :custom_fields, :custom_values
6
6
7 def test_report_no_criteria
7 def test_report_at_project_level
8 get :report, :project_id => 1
8 get :report, :project_id => 'ecookbook'
9 assert_response :success
9 assert_response :success
10 assert_template 'report'
10 assert_template 'report'
11 assert_tag :form,
12 :attributes => {:action => "/projects/ecookbook/time_entries/report", :id => 'query_form'}
11 end
13 end
12
14
13 def test_report_all_projects
15 def test_report_all_projects
14 get :report
16 get :report
15 assert_response :success
17 assert_response :success
16 assert_template 'report'
18 assert_template 'report'
19 assert_tag :form,
20 :attributes => {:action => "/time_entries/report", :id => 'query_form'}
17 end
21 end
18
22
19 def test_report_all_projects_denied
23 def test_report_all_projects_denied
20 r = Role.anonymous
24 r = Role.anonymous
21 r.permissions.delete(:view_time_entries)
25 r.permissions.delete(:view_time_entries)
22 r.permissions_will_change!
26 r.permissions_will_change!
23 r.save
27 r.save
24 get :report
28 get :report
25 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Ftime_entries%2Freport'
29 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Ftime_entries%2Freport'
26 end
30 end
27
31
28 def test_report_all_projects_one_criteria
32 def test_report_all_projects_one_criteria
29 get :report, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criterias => ['project']
33 get :report, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criterias => ['project']
30 assert_response :success
34 assert_response :success
31 assert_template 'report'
35 assert_template 'report'
32 assert_not_nil assigns(:total_hours)
36 assert_not_nil assigns(:total_hours)
33 assert_equal "8.65", "%.2f" % assigns(:total_hours)
37 assert_equal "8.65", "%.2f" % assigns(:total_hours)
34 end
38 end
35
39
36 def test_report_all_time
40 def test_report_all_time
37 get :report, :project_id => 1, :criterias => ['project', 'issue']
41 get :report, :project_id => 1, :criterias => ['project', 'issue']
38 assert_response :success
42 assert_response :success
39 assert_template 'report'
43 assert_template 'report'
40 assert_not_nil assigns(:total_hours)
44 assert_not_nil assigns(:total_hours)
41 assert_equal "162.90", "%.2f" % assigns(:total_hours)
45 assert_equal "162.90", "%.2f" % assigns(:total_hours)
42 end
46 end
43
47
44 def test_report_all_time_by_day
48 def test_report_all_time_by_day
45 get :report, :project_id => 1, :criterias => ['project', 'issue'], :columns => 'day'
49 get :report, :project_id => 1, :criterias => ['project', 'issue'], :columns => 'day'
46 assert_response :success
50 assert_response :success
47 assert_template 'report'
51 assert_template 'report'
48 assert_not_nil assigns(:total_hours)
52 assert_not_nil assigns(:total_hours)
49 assert_equal "162.90", "%.2f" % assigns(:total_hours)
53 assert_equal "162.90", "%.2f" % assigns(:total_hours)
50 assert_tag :tag => 'th', :content => '2007-03-12'
54 assert_tag :tag => 'th', :content => '2007-03-12'
51 end
55 end
52
56
53 def test_report_one_criteria
57 def test_report_one_criteria
54 get :report, :project_id => 1, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criterias => ['project']
58 get :report, :project_id => 1, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criterias => ['project']
55 assert_response :success
59 assert_response :success
56 assert_template 'report'
60 assert_template 'report'
57 assert_not_nil assigns(:total_hours)
61 assert_not_nil assigns(:total_hours)
58 assert_equal "8.65", "%.2f" % assigns(:total_hours)
62 assert_equal "8.65", "%.2f" % assigns(:total_hours)
59 end
63 end
60
64
61 def test_report_two_criterias
65 def test_report_two_criterias
62 get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criterias => ["member", "activity"]
66 get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criterias => ["member", "activity"]
63 assert_response :success
67 assert_response :success
64 assert_template 'report'
68 assert_template 'report'
65 assert_not_nil assigns(:total_hours)
69 assert_not_nil assigns(:total_hours)
66 assert_equal "162.90", "%.2f" % assigns(:total_hours)
70 assert_equal "162.90", "%.2f" % assigns(:total_hours)
67 end
71 end
68
72
69 def test_report_one_day
73 def test_report_one_day
70 get :report, :project_id => 1, :columns => 'day', :from => "2007-03-23", :to => "2007-03-23", :criterias => ["member", "activity"]
74 get :report, :project_id => 1, :columns => 'day', :from => "2007-03-23", :to => "2007-03-23", :criterias => ["member", "activity"]
71 assert_response :success
75 assert_response :success
72 assert_template 'report'
76 assert_template 'report'
73 assert_not_nil assigns(:total_hours)
77 assert_not_nil assigns(:total_hours)
74 assert_equal "4.25", "%.2f" % assigns(:total_hours)
78 assert_equal "4.25", "%.2f" % assigns(:total_hours)
75 end
79 end
76
80
77 def test_report_at_issue_level
81 def test_report_at_issue_level
78 get :report, :project_id => 1, :issue_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criterias => ["member", "activity"]
82 get :report, :project_id => 1, :issue_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criterias => ["member", "activity"]
79 assert_response :success
83 assert_response :success
80 assert_template 'report'
84 assert_template 'report'
81 assert_not_nil assigns(:total_hours)
85 assert_not_nil assigns(:total_hours)
82 assert_equal "154.25", "%.2f" % assigns(:total_hours)
86 assert_equal "154.25", "%.2f" % assigns(:total_hours)
87 assert_tag :form,
88 :attributes => {:action => "/projects/ecookbook/issues/1/time_entries/report", :id => 'query_form'}
83 end
89 end
84
90
85 def test_report_custom_field_criteria
91 def test_report_custom_field_criteria
86 get :report, :project_id => 1, :criterias => ['project', 'cf_1', 'cf_7']
92 get :report, :project_id => 1, :criterias => ['project', 'cf_1', 'cf_7']
87 assert_response :success
93 assert_response :success
88 assert_template 'report'
94 assert_template 'report'
89 assert_not_nil assigns(:total_hours)
95 assert_not_nil assigns(:total_hours)
90 assert_not_nil assigns(:criterias)
96 assert_not_nil assigns(:criterias)
91 assert_equal 3, assigns(:criterias).size
97 assert_equal 3, assigns(:criterias).size
92 assert_equal "162.90", "%.2f" % assigns(:total_hours)
98 assert_equal "162.90", "%.2f" % assigns(:total_hours)
93 # Custom field column
99 # Custom field column
94 assert_tag :tag => 'th', :content => 'Database'
100 assert_tag :tag => 'th', :content => 'Database'
95 # Custom field row
101 # Custom field row
96 assert_tag :tag => 'td', :content => 'MySQL',
102 assert_tag :tag => 'td', :content => 'MySQL',
97 :sibling => { :tag => 'td', :attributes => { :class => 'hours' },
103 :sibling => { :tag => 'td', :attributes => { :class => 'hours' },
98 :child => { :tag => 'span', :attributes => { :class => 'hours hours-int' },
104 :child => { :tag => 'span', :attributes => { :class => 'hours hours-int' },
99 :content => '1' }}
105 :content => '1' }}
100 # Second custom field column
106 # Second custom field column
101 assert_tag :tag => 'th', :content => 'Billable'
107 assert_tag :tag => 'th', :content => 'Billable'
102 end
108 end
103
109
104 def test_report_one_criteria_no_result
110 def test_report_one_criteria_no_result
105 get :report, :project_id => 1, :columns => 'week', :from => "1998-04-01", :to => "1998-04-30", :criterias => ['project']
111 get :report, :project_id => 1, :columns => 'week', :from => "1998-04-01", :to => "1998-04-30", :criterias => ['project']
106 assert_response :success
112 assert_response :success
107 assert_template 'report'
113 assert_template 'report'
108 assert_not_nil assigns(:total_hours)
114 assert_not_nil assigns(:total_hours)
109 assert_equal "0.00", "%.2f" % assigns(:total_hours)
115 assert_equal "0.00", "%.2f" % assigns(:total_hours)
110 end
116 end
111
117
112 def test_report_all_projects_csv_export
118 def test_report_all_projects_csv_export
113 get :report, :columns => 'month', :from => "2007-01-01", :to => "2007-06-30", :criterias => ["project", "member", "activity"], :format => "csv"
119 get :report, :columns => 'month', :from => "2007-01-01", :to => "2007-06-30", :criterias => ["project", "member", "activity"], :format => "csv"
114 assert_response :success
120 assert_response :success
115 assert_equal 'text/csv', @response.content_type
121 assert_equal 'text/csv', @response.content_type
116 lines = @response.body.chomp.split("\n")
122 lines = @response.body.chomp.split("\n")
117 # Headers
123 # Headers
118 assert_equal 'Project,Member,Activity,2007-1,2007-2,2007-3,2007-4,2007-5,2007-6,Total', lines.first
124 assert_equal 'Project,Member,Activity,2007-1,2007-2,2007-3,2007-4,2007-5,2007-6,Total', lines.first
119 # Total row
125 # Total row
120 assert_equal 'Total,"","","","",154.25,8.65,"","",162.90', lines.last
126 assert_equal 'Total,"","","","",154.25,8.65,"","",162.90', lines.last
121 end
127 end
122
128
123 def test_report_csv_export
129 def test_report_csv_export
124 get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-06-30", :criterias => ["project", "member", "activity"], :format => "csv"
130 get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-06-30", :criterias => ["project", "member", "activity"], :format => "csv"
125 assert_response :success
131 assert_response :success
126 assert_equal 'text/csv', @response.content_type
132 assert_equal 'text/csv', @response.content_type
127 lines = @response.body.chomp.split("\n")
133 lines = @response.body.chomp.split("\n")
128 # Headers
134 # Headers
129 assert_equal 'Project,Member,Activity,2007-1,2007-2,2007-3,2007-4,2007-5,2007-6,Total', lines.first
135 assert_equal 'Project,Member,Activity,2007-1,2007-2,2007-3,2007-4,2007-5,2007-6,Total', lines.first
130 # Total row
136 # Total row
131 assert_equal 'Total,"","","","",154.25,8.65,"","",162.90', lines.last
137 assert_equal 'Total,"","","","",154.25,8.65,"","",162.90', lines.last
132 end
138 end
133
139
134 end
140 end
@@ -1,251 +1,265
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 # redMine - project management software
2 # redMine - project management software
3 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 # Copyright (C) 2006-2007 Jean-Philippe Lang
4 #
4 #
5 # This program is free software; you can redistribute it and/or
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
8 # of the License, or (at your option) any later version.
9 #
9 #
10 # This program is distributed in the hope that it will be useful,
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
13 # GNU General Public License for more details.
14 #
14 #
15 # You should have received a copy of the GNU General Public License
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
18
19 require File.expand_path('../../test_helper', __FILE__)
19 require File.expand_path('../../test_helper', __FILE__)
20 require 'timelog_controller'
20 require 'timelog_controller'
21
21
22 # Re-raise errors caught by the controller.
22 # Re-raise errors caught by the controller.
23 class TimelogController; def rescue_action(e) raise e end; end
23 class TimelogController; def rescue_action(e) raise e end; end
24
24
25 class TimelogControllerTest < ActionController::TestCase
25 class TimelogControllerTest < ActionController::TestCase
26 fixtures :projects, :enabled_modules, :roles, :members, :member_roles, :issues, :time_entries, :users, :trackers, :enumerations, :issue_statuses, :custom_fields, :custom_values
26 fixtures :projects, :enabled_modules, :roles, :members, :member_roles, :issues, :time_entries, :users, :trackers, :enumerations, :issue_statuses, :custom_fields, :custom_values
27
27
28 def setup
28 def setup
29 @controller = TimelogController.new
29 @controller = TimelogController.new
30 @request = ActionController::TestRequest.new
30 @request = ActionController::TestRequest.new
31 @response = ActionController::TestResponse.new
31 @response = ActionController::TestResponse.new
32 end
32 end
33
33
34 def test_get_new
34 def test_get_new
35 @request.session[:user_id] = 3
35 @request.session[:user_id] = 3
36 get :new, :project_id => 1
36 get :new, :project_id => 1
37 assert_response :success
37 assert_response :success
38 assert_template 'edit'
38 assert_template 'edit'
39 # Default activity selected
39 # Default activity selected
40 assert_tag :tag => 'option', :attributes => { :selected => 'selected' },
40 assert_tag :tag => 'option', :attributes => { :selected => 'selected' },
41 :content => 'Development'
41 :content => 'Development'
42 end
42 end
43
43
44 def test_get_new_should_only_show_active_time_entry_activities
44 def test_get_new_should_only_show_active_time_entry_activities
45 @request.session[:user_id] = 3
45 @request.session[:user_id] = 3
46 get :new, :project_id => 1
46 get :new, :project_id => 1
47 assert_response :success
47 assert_response :success
48 assert_template 'edit'
48 assert_template 'edit'
49 assert_no_tag :tag => 'option', :content => 'Inactive Activity'
49 assert_no_tag :tag => 'option', :content => 'Inactive Activity'
50
50
51 end
51 end
52
52
53 def test_get_edit_existing_time
53 def test_get_edit_existing_time
54 @request.session[:user_id] = 2
54 @request.session[:user_id] = 2
55 get :edit, :id => 2, :project_id => nil
55 get :edit, :id => 2, :project_id => nil
56 assert_response :success
56 assert_response :success
57 assert_template 'edit'
57 assert_template 'edit'
58 # Default activity selected
58 # Default activity selected
59 assert_tag :tag => 'form', :attributes => { :action => '/projects/ecookbook/time_entries/2' }
59 assert_tag :tag => 'form', :attributes => { :action => '/projects/ecookbook/time_entries/2' }
60 end
60 end
61
61
62 def test_get_edit_with_an_existing_time_entry_with_inactive_activity
62 def test_get_edit_with_an_existing_time_entry_with_inactive_activity
63 te = TimeEntry.find(1)
63 te = TimeEntry.find(1)
64 te.activity = TimeEntryActivity.find_by_name("Inactive Activity")
64 te.activity = TimeEntryActivity.find_by_name("Inactive Activity")
65 te.save!
65 te.save!
66
66
67 @request.session[:user_id] = 1
67 @request.session[:user_id] = 1
68 get :edit, :project_id => 1, :id => 1
68 get :edit, :project_id => 1, :id => 1
69 assert_response :success
69 assert_response :success
70 assert_template 'edit'
70 assert_template 'edit'
71 # Blank option since nothing is pre-selected
71 # Blank option since nothing is pre-selected
72 assert_tag :tag => 'option', :content => '--- Please select ---'
72 assert_tag :tag => 'option', :content => '--- Please select ---'
73 end
73 end
74
74
75 def test_post_create
75 def test_post_create
76 # TODO: should POST to issues’ time log instead of project. change form
76 # TODO: should POST to issues’ time log instead of project. change form
77 # and routing
77 # and routing
78 @request.session[:user_id] = 3
78 @request.session[:user_id] = 3
79 post :create, :project_id => 1,
79 post :create, :project_id => 1,
80 :time_entry => {:comments => 'Some work on TimelogControllerTest',
80 :time_entry => {:comments => 'Some work on TimelogControllerTest',
81 # Not the default activity
81 # Not the default activity
82 :activity_id => '11',
82 :activity_id => '11',
83 :spent_on => '2008-03-14',
83 :spent_on => '2008-03-14',
84 :issue_id => '1',
84 :issue_id => '1',
85 :hours => '7.3'}
85 :hours => '7.3'}
86 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
86 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
87
87
88 i = Issue.find(1)
88 i = Issue.find(1)
89 t = TimeEntry.find_by_comments('Some work on TimelogControllerTest')
89 t = TimeEntry.find_by_comments('Some work on TimelogControllerTest')
90 assert_not_nil t
90 assert_not_nil t
91 assert_equal 11, t.activity_id
91 assert_equal 11, t.activity_id
92 assert_equal 7.3, t.hours
92 assert_equal 7.3, t.hours
93 assert_equal 3, t.user_id
93 assert_equal 3, t.user_id
94 assert_equal i, t.issue
94 assert_equal i, t.issue
95 assert_equal i.project, t.project
95 assert_equal i.project, t.project
96 end
96 end
97
97
98 def test_post_create_with_blank_issue
98 def test_post_create_with_blank_issue
99 # TODO: should POST to issues’ time log instead of project. change form
99 # TODO: should POST to issues’ time log instead of project. change form
100 # and routing
100 # and routing
101 @request.session[:user_id] = 3
101 @request.session[:user_id] = 3
102 post :create, :project_id => 1,
102 post :create, :project_id => 1,
103 :time_entry => {:comments => 'Some work on TimelogControllerTest',
103 :time_entry => {:comments => 'Some work on TimelogControllerTest',
104 # Not the default activity
104 # Not the default activity
105 :activity_id => '11',
105 :activity_id => '11',
106 :issue_id => '',
106 :issue_id => '',
107 :spent_on => '2008-03-14',
107 :spent_on => '2008-03-14',
108 :hours => '7.3'}
108 :hours => '7.3'}
109 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
109 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
110
110
111 t = TimeEntry.find_by_comments('Some work on TimelogControllerTest')
111 t = TimeEntry.find_by_comments('Some work on TimelogControllerTest')
112 assert_not_nil t
112 assert_not_nil t
113 assert_equal 11, t.activity_id
113 assert_equal 11, t.activity_id
114 assert_equal 7.3, t.hours
114 assert_equal 7.3, t.hours
115 assert_equal 3, t.user_id
115 assert_equal 3, t.user_id
116 end
116 end
117
117
118 def test_update
118 def test_update
119 entry = TimeEntry.find(1)
119 entry = TimeEntry.find(1)
120 assert_equal 1, entry.issue_id
120 assert_equal 1, entry.issue_id
121 assert_equal 2, entry.user_id
121 assert_equal 2, entry.user_id
122
122
123 @request.session[:user_id] = 1
123 @request.session[:user_id] = 1
124 put :update, :id => 1,
124 put :update, :id => 1,
125 :time_entry => {:issue_id => '2',
125 :time_entry => {:issue_id => '2',
126 :hours => '8'}
126 :hours => '8'}
127 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
127 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
128 entry.reload
128 entry.reload
129
129
130 assert_equal 8, entry.hours
130 assert_equal 8, entry.hours
131 assert_equal 2, entry.issue_id
131 assert_equal 2, entry.issue_id
132 assert_equal 2, entry.user_id
132 assert_equal 2, entry.user_id
133 end
133 end
134
134
135 def test_destroy
135 def test_destroy
136 @request.session[:user_id] = 2
136 @request.session[:user_id] = 2
137 delete :destroy, :id => 1
137 delete :destroy, :id => 1
138 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
138 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
139 assert_equal I18n.t(:notice_successful_delete), flash[:notice]
139 assert_equal I18n.t(:notice_successful_delete), flash[:notice]
140 assert_nil TimeEntry.find_by_id(1)
140 assert_nil TimeEntry.find_by_id(1)
141 end
141 end
142
142
143 def test_destroy_should_fail
143 def test_destroy_should_fail
144 # simulate that this fails (e.g. due to a plugin), see #5700
144 # simulate that this fails (e.g. due to a plugin), see #5700
145 TimeEntry.class_eval do
145 TimeEntry.class_eval do
146 before_destroy :stop_callback_chain
146 before_destroy :stop_callback_chain
147 def stop_callback_chain ; return false ; end
147 def stop_callback_chain ; return false ; end
148 end
148 end
149
149
150 @request.session[:user_id] = 2
150 @request.session[:user_id] = 2
151 delete :destroy, :id => 1
151 delete :destroy, :id => 1
152 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
152 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
153 assert_equal I18n.t(:notice_unable_delete_time_entry), flash[:error]
153 assert_equal I18n.t(:notice_unable_delete_time_entry), flash[:error]
154 assert_not_nil TimeEntry.find_by_id(1)
154 assert_not_nil TimeEntry.find_by_id(1)
155
155
156 # remove the simulation
156 # remove the simulation
157 TimeEntry.before_destroy.reject! {|callback| callback.method == :stop_callback_chain }
157 TimeEntry.before_destroy.reject! {|callback| callback.method == :stop_callback_chain }
158 end
158 end
159
159
160 def test_index_all_projects
160 def test_index_all_projects
161 get :index
161 get :index
162 assert_response :success
162 assert_response :success
163 assert_template 'index'
163 assert_template 'index'
164 assert_not_nil assigns(:total_hours)
164 assert_not_nil assigns(:total_hours)
165 assert_equal "162.90", "%.2f" % assigns(:total_hours)
165 assert_equal "162.90", "%.2f" % assigns(:total_hours)
166 assert_tag :form,
167 :attributes => {:action => "/time_entries", :id => 'query_form'}
166 end
168 end
167
169
168 def test_index_at_project_level
170 def test_index_at_project_level
169 get :index, :project_id => 1
171 get :index, :project_id => 'ecookbook'
170 assert_response :success
172 assert_response :success
171 assert_template 'index'
173 assert_template 'index'
172 assert_not_nil assigns(:entries)
174 assert_not_nil assigns(:entries)
173 assert_equal 4, assigns(:entries).size
175 assert_equal 4, assigns(:entries).size
174 # project and subproject
176 # project and subproject
175 assert_equal [1, 3], assigns(:entries).collect(&:project_id).uniq.sort
177 assert_equal [1, 3], assigns(:entries).collect(&:project_id).uniq.sort
176 assert_not_nil assigns(:total_hours)
178 assert_not_nil assigns(:total_hours)
177 assert_equal "162.90", "%.2f" % assigns(:total_hours)
179 assert_equal "162.90", "%.2f" % assigns(:total_hours)
178 # display all time by default
180 # display all time by default
179 assert_equal '2007-03-12'.to_date, assigns(:from)
181 assert_equal '2007-03-12'.to_date, assigns(:from)
180 assert_equal '2007-04-22'.to_date, assigns(:to)
182 assert_equal '2007-04-22'.to_date, assigns(:to)
183 assert_tag :form,
184 :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
181 end
185 end
182
186
183 def test_index_at_project_level_with_date_range
187 def test_index_at_project_level_with_date_range
184 get :index, :project_id => 1, :from => '2007-03-20', :to => '2007-04-30'
188 get :index, :project_id => 'ecookbook', :from => '2007-03-20', :to => '2007-04-30'
185 assert_response :success
189 assert_response :success
186 assert_template 'index'
190 assert_template 'index'
187 assert_not_nil assigns(:entries)
191 assert_not_nil assigns(:entries)
188 assert_equal 3, assigns(:entries).size
192 assert_equal 3, assigns(:entries).size
189 assert_not_nil assigns(:total_hours)
193 assert_not_nil assigns(:total_hours)
190 assert_equal "12.90", "%.2f" % assigns(:total_hours)
194 assert_equal "12.90", "%.2f" % assigns(:total_hours)
191 assert_equal '2007-03-20'.to_date, assigns(:from)
195 assert_equal '2007-03-20'.to_date, assigns(:from)
192 assert_equal '2007-04-30'.to_date, assigns(:to)
196 assert_equal '2007-04-30'.to_date, assigns(:to)
197 assert_tag :form,
198 :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
193 end
199 end
194
200
195 def test_index_at_project_level_with_period
201 def test_index_at_project_level_with_period
196 get :index, :project_id => 1, :period => '7_days'
202 get :index, :project_id => 'ecookbook', :period => '7_days'
197 assert_response :success
203 assert_response :success
198 assert_template 'index'
204 assert_template 'index'
199 assert_not_nil assigns(:entries)
205 assert_not_nil assigns(:entries)
200 assert_not_nil assigns(:total_hours)
206 assert_not_nil assigns(:total_hours)
201 assert_equal Date.today - 7, assigns(:from)
207 assert_equal Date.today - 7, assigns(:from)
202 assert_equal Date.today, assigns(:to)
208 assert_equal Date.today, assigns(:to)
209 assert_tag :form,
210 :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
203 end
211 end
204
212
205 def test_index_one_day
213 def test_index_one_day
206 get :index, :project_id => 1, :from => "2007-03-23", :to => "2007-03-23"
214 get :index, :project_id => 'ecookbook', :from => "2007-03-23", :to => "2007-03-23"
207 assert_response :success
215 assert_response :success
208 assert_template 'index'
216 assert_template 'index'
209 assert_not_nil assigns(:total_hours)
217 assert_not_nil assigns(:total_hours)
210 assert_equal "4.25", "%.2f" % assigns(:total_hours)
218 assert_equal "4.25", "%.2f" % assigns(:total_hours)
219 assert_tag :form,
220 :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
211 end
221 end
212
222
213 def test_index_at_issue_level
223 def test_index_at_issue_level
214 get :index, :issue_id => 1
224 get :index, :issue_id => 1
215 assert_response :success
225 assert_response :success
216 assert_template 'index'
226 assert_template 'index'
217 assert_not_nil assigns(:entries)
227 assert_not_nil assigns(:entries)
218 assert_equal 2, assigns(:entries).size
228 assert_equal 2, assigns(:entries).size
219 assert_not_nil assigns(:total_hours)
229 assert_not_nil assigns(:total_hours)
220 assert_equal 154.25, assigns(:total_hours)
230 assert_equal 154.25, assigns(:total_hours)
221 # display all time based on what's been logged
231 # display all time based on what's been logged
222 assert_equal '2007-03-12'.to_date, assigns(:from)
232 assert_equal '2007-03-12'.to_date, assigns(:from)
223 assert_equal '2007-04-22'.to_date, assigns(:to)
233 assert_equal '2007-04-22'.to_date, assigns(:to)
234 # TODO: remove /projects/:project_id/issues/:issue_id/time_entries routes
235 # to use /issues/:issue_id/time_entries
236 assert_tag :form,
237 :attributes => {:action => "/projects/ecookbook/issues/1/time_entries", :id => 'query_form'}
224 end
238 end
225
239
226 def test_index_atom_feed
240 def test_index_atom_feed
227 get :index, :project_id => 1, :format => 'atom'
241 get :index, :project_id => 1, :format => 'atom'
228 assert_response :success
242 assert_response :success
229 assert_equal 'application/atom+xml', @response.content_type
243 assert_equal 'application/atom+xml', @response.content_type
230 assert_not_nil assigns(:items)
244 assert_not_nil assigns(:items)
231 assert assigns(:items).first.is_a?(TimeEntry)
245 assert assigns(:items).first.is_a?(TimeEntry)
232 end
246 end
233
247
234 def test_index_all_projects_csv_export
248 def test_index_all_projects_csv_export
235 Setting.date_format = '%m/%d/%Y'
249 Setting.date_format = '%m/%d/%Y'
236 get :index, :format => 'csv'
250 get :index, :format => 'csv'
237 assert_response :success
251 assert_response :success
238 assert_equal 'text/csv', @response.content_type
252 assert_equal 'text/csv', @response.content_type
239 assert @response.body.include?("Date,User,Activity,Project,Issue,Tracker,Subject,Hours,Comment\n")
253 assert @response.body.include?("Date,User,Activity,Project,Issue,Tracker,Subject,Hours,Comment\n")
240 assert @response.body.include?("\n04/21/2007,redMine Admin,Design,eCookbook,3,Bug,Error 281 when updating a recipe,1.0,\"\"\n")
254 assert @response.body.include?("\n04/21/2007,redMine Admin,Design,eCookbook,3,Bug,Error 281 when updating a recipe,1.0,\"\"\n")
241 end
255 end
242
256
243 def test_index_csv_export
257 def test_index_csv_export
244 Setting.date_format = '%m/%d/%Y'
258 Setting.date_format = '%m/%d/%Y'
245 get :index, :project_id => 1, :format => 'csv'
259 get :index, :project_id => 1, :format => 'csv'
246 assert_response :success
260 assert_response :success
247 assert_equal 'text/csv', @response.content_type
261 assert_equal 'text/csv', @response.content_type
248 assert @response.body.include?("Date,User,Activity,Project,Issue,Tracker,Subject,Hours,Comment\n")
262 assert @response.body.include?("Date,User,Activity,Project,Issue,Tracker,Subject,Hours,Comment\n")
249 assert @response.body.include?("\n04/21/2007,redMine Admin,Design,eCookbook,3,Bug,Error 281 when updating a recipe,1.0,\"\"\n")
263 assert @response.body.include?("\n04/21/2007,redMine Admin,Design,eCookbook,3,Bug,Error 281 when updating a recipe,1.0,\"\"\n")
250 end
264 end
251 end
265 end
General Comments 0
You need to be logged in to leave comments. Login now